| name | obsidian-arrow-maintenance |
| description | Use when updating or maintaining an EXISTING scaffolded obsidian-arrow project โ refresh managed files with create-obsidian-arrow refresh (scripts, docs, CI, tools, src/main.ts, src/utilities.css, test โ never src/components/), update agent skills with pnpm skills:update, fix skills scoping for nested repos, and re-pull Obsidian styling. |
Maintaining an existing Obsidian Arrow project
How to bring an already-scaffolded project up to date. The scaffolder is
create-only (it refuses a non-empty dir), so updates split into three tracks:
tooling files, agent skills, and styling. None of these touch your
src/components/ or stories/.
For a ready-to-run checklist you can hand to an agent, see
docs/prompts/update-existing.md.
Two CLIs, different roles:
create-obsidian-arrow โ ephemeral lifecycle tool (npx create-obsidian-arrow โฆ).
create <dir> scaffolds a new project; refresh [dir] pulls fresh managed files
from the current template.
oasbox โ the in-project daily driver, installed as a local devDependency by
the scaffold. Run via oasbox generate, oasbox validate, oasbox dev, etc.
Use it for day-to-day authoring; use create-obsidian-arrow refresh only when you
need to pull template updates.
1. Refresh the tooling (scripts, skills files, docs, CI, config)
npx create-obsidian-arrow refresh
npx create-obsidian-arrow refresh --dry-run
Refreshes the managed files from the latest template and merges
package.json scripts + any missing deps.
Managed = scripts/, docs/, .github/, .husky/, biome.json, AGENTS.md,
CLAUDE.md, tools/viewer/, tools/router/, tools/sandbox/, src/main.ts,
src/utilities.css, test/.
Never touches src/components/ (your reusable primitives), src/views/
(your full-pane views), stories/ (your story files), public/, index.html,
vite.config.ts, tsconfig.json, or .gitignore.
stories/ is created automatically on first update if it doesn't exist (empty
placeholder โ the update command never puts content in it). The sub-directories
stories/views/ and stories/components/ are user-created as needed; the update
command does not create them. After it runs: pnpm install && pnpm check.
Removing old src/ infrastructure โ if updating from a pre-0.4.0 project
that had src/viewer/, src/router/, src/sandbox/, those dirs are now
orphaned (update added tools/ but doesn't delete old files). Remove them:
rm -rf src/viewer src/router src/sandbox
DiffViewer โ the CM6 MergeView diff component ships in the scaffold
at src/components/DiffViewer/DiffViewer.ts (with co-located DiffViewer.css).
New projects get it automatically; existing projects can copy it manually from
kylebrodeur/obsidian-arrow-sandbox or run create-obsidian-arrow refresh.
Popover + structural primitives โ the scaffold ships a reusable Popover
primitive (src/components/Popover/ โ shell + controller.ts, with
list/filterable/grouped/action variants and one positioning + dismiss
system) plus the primitives it composes: Button, ListItem, SearchField,
SectionLabel. create-obsidian-arrow refresh delivers these content-safely โ
it adds any you're missing, auto-updates ones you haven't edited (detected by
a canonical hash of every shipped version), and preserves ones you've edited
(reported so you can reconcile). create-obsidian-arrow refresh --force overwrites
them regardless. No hand-copying either way. icons.ts is also seeded by refresh
if missing โ it is the Lucide icon system all primitives depend on. Because you are
expected to extend it with your own icons, the hash diverges after the first addition
and refresh will always preserve your copy (use --force to reset). To add a new
glyph, append one entry to the ICON_MAP in src/components/icons.ts:
import { YourIcon } from "lucide";
"your-icon": YourIcon as unknown as LucideIconData,
Then use it anywhere: ${icon("your-icon")}. It will appear in the Icons reference
page (/reference/icons) automatically. To scaffold a
ready-wired popup, run oasbox generate popover <Name> [--variant list|filterable|grouped|action]. Read
docs/arrow-notes.md for the runtime patterns the
controller relies on (no DOM in reactive(); nextTick not requestAnimationFrame;
always-mount + is-hidden).
2. Update the installed agent skills
pnpm skills:update
Or reinstall the latest straight from the published repo (works from anywhere,
even if the project predates the skill scripts):
npx skills add kylebrodeur/obsidian-arrow-sandbox --all --yes
3. Nested inside another repo? Fix skills scoping
The skills CLI installs project-scope relative to cwd. If this project sits
inside a larger repo and your agent runs from the outer repo, skills installed
here won't be found. Install them where the agent looks:
pnpm skills:install --yes --project-dir=<outer-repo>
pnpm skills:install --yes --global
(SKILLS_PROJECT_DIR / SKILLS_GLOBAL env forms drive the auto postinstall
step, which takes no CLI args.)
4. Re-pull Obsidian styling after Obsidian updates
public/app.css is a local snapshot (git-ignored). If Obsidian updated or the
sandbox renders stale, refresh it:
pnpm pull-css
5. Re-check porting parity
After updating, re-run the porting-parity check so plugin copies still match the
sandbox source (see the arrow-js-obsidian-porting skill):
node scripts/component-hash.mjs --check port-parity.json
6. Export prefixed CSS for the plugin โ pnpm port:css
When components are ready to port, run the CSS prefix pipeline. Requires a
porting.config.json at the project root (copy from porting.config.example.json
and set your plugin's cssPrefix). See the arrow-js-obsidian-porting skill
for setup and viewSubScope docs.
pnpm port:css
This is a one-shot port step โ not part of pnpm ci.