create-obsidian-arrow 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +10 -7
  2. package/index.mjs +29 -10
  3. package/package.json +1 -1
  4. package/template/AGENTS.md +31 -5
  5. package/template/README.md +47 -5
  6. package/template/_gitignore +3 -0
  7. package/template/docs/prompts/agent-setup.md +26 -13
  8. package/template/docs/prompts/update-existing.md +13 -9
  9. package/template/docs/workflow.md +21 -8
  10. package/template/package.json +6 -2
  11. package/template/pnpm-lock.yaml +197 -0
  12. package/template/src/components/DiffViewer.ts +42 -0
  13. package/template/src/components/SettingsPanel.ts +1 -1
  14. package/template/src/main.ts +4 -3
  15. package/template/src/utilities.css +205 -0
  16. package/template/stories/DiffViewer.stories.ts +75 -0
  17. package/template/stories/SettingsPanel.stories.ts +11 -0
  18. package/template/stories/Toggle.stories.ts +28 -0
  19. package/template/test/token-utils.test.mjs +65 -0
  20. package/template/test/viewer-derive.test.mjs +65 -0
  21. package/template/test/viewer-stories.test.mjs +44 -0
  22. package/template/{src → tools}/router/client.ts +15 -2
  23. package/template/tools/router/routeToPage.ts +104 -0
  24. package/template/{src → tools}/sandbox/home.ts +55 -26
  25. package/template/tools/sandbox/sandbox.css +474 -0
  26. package/template/tools/viewer/ClassesPage.ts +37 -0
  27. package/template/tools/viewer/ComponentsIndex.ts +56 -0
  28. package/template/tools/viewer/StoryPage.ts +73 -0
  29. package/template/tools/viewer/TokensPage.ts +82 -0
  30. package/template/tools/viewer/derive.ts +91 -0
  31. package/template/tools/viewer/discovery.ts +64 -0
  32. package/template/tools/viewer/obsidian-classes.ts +269 -0
  33. package/template/tools/viewer/sidebar.ts +55 -0
  34. package/template/tools/viewer/stories.ts +83 -0
  35. package/template/tools/viewer/token-utils.ts +84 -0
  36. package/template/tools/viewer/tokens.ts +30 -0
  37. package/template/src/examples/ExamplesIndex.ts +0 -36
  38. package/template/src/examples/registry.ts +0 -26
  39. package/template/src/router/routeToPage.ts +0 -57
  40. package/template/src/sandbox/sandbox.css +0 -130
  41. /package/template/{src → tools}/sandbox/frame.ts +0 -0
  42. /package/template/{src → tools}/sandbox/layout.ts +0 -0
  43. /package/template/{src → tools}/sandbox/shell.ts +0 -0
  44. /package/template/{src → tools}/sandbox/theme.ts +0 -0
  45. /package/template/{src → tools}/sandbox/toolbar.ts +0 -0
package/README.md CHANGED
@@ -45,9 +45,11 @@ prints this hint when it detects nesting.
45
45
  ## Update an existing project
46
46
 
47
47
  The scaffolder is create-only, but `update` refreshes an existing project's
48
- **managed** tooling (`scripts/`, `skills/`, `docs/`, `.github/`, `.husky/`,
49
- `biome.json`, agent guides) and merges new `package.json` scripts/deps — it never
50
- touches your `src/`, `public/`, `index.html`, or build configs:
48
+ **managed** files (`scripts/`, `docs/`, `.github/`, `.husky/`, `biome.json`,
49
+ agent guides, `tools/viewer/`, `tools/router/`, `tools/sandbox/`, `src/main.ts`,
50
+ `src/utilities.css`, `test/`) and merges new `package.json` scripts/deps
51
+ it never touches `src/components/`, `stories/`, `public/`, `index.html`, or
52
+ build configs:
51
53
 
52
54
  ```sh
53
55
  npx create-obsidian-arrow update # in the project (or: update <dir>)
@@ -68,10 +70,11 @@ node create-obsidian-arrow/index.mjs update ../my-app # update
68
70
  ## What you get
69
71
 
70
72
  A full sandbox: client-only Vite + TS, `@arrow-js/core` + `@arrow-js/framework`
71
- (no SSR), `routeToPage` + Navigation-API router with an `/example` demo, Biome +
72
- husky pre-commit + `node:test` + GitHub Actions CI, a `skills:install` that pulls
73
- the agent skills from the published repo, and the `pull-css` script that extracts
74
- Obsidian's `app.css`.
73
+ (no SSR), `routeToPage` + Navigation-API router, a Storybook-style component
74
+ viewer at `/components` (add `*.stories.ts` files in `stories/`), a live token
75
+ and class reference at `/reference`, Biome + husky pre-commit + `node:test` +
76
+ GitHub Actions CI, a `skills:install` that pulls the agent skills from the
77
+ published repo, and the `pull-css` script that extracts Obsidian's `app.css`.
75
78
 
76
79
  ## Maintaining the template
77
80
 
package/index.mjs CHANGED
@@ -13,9 +13,11 @@
13
13
  * Scaffold copies the vendored template/, restores .gitignore (vendored as
14
14
  * _gitignore), names the project, and runs `git init`.
15
15
  *
16
- * Update refreshes only the *managed* tooling files from the template and merges
17
- * package.json scripts + missing deps it never touches your src/, public/,
18
- * index.html, or the core build configs. Use --dry-run to preview.
16
+ * Update refreshes *managed* files from the template and merges package.json
17
+ * scripts + missing deps. Managed = scripts/, docs/, .github/, .husky/,
18
+ * biome.json, AGENTS.md, CLAUDE.md, tools/, src/main.ts, src/utilities.css,
19
+ * test/. Never touches src/components/, stories/, public/, index.html,
20
+ * vite.config.ts, tsconfig.json, or .gitignore. Use --dry-run first.
19
21
  */
20
22
  import { spawnSync } from "node:child_process";
21
23
  import fs from "node:fs";
@@ -25,12 +27,29 @@ import { fileURLToPath } from "node:url";
25
27
  const here = path.dirname(fileURLToPath(import.meta.url));
26
28
  const templateDir = path.join(here, "template");
27
29
 
28
- // Files/dirs the template owns and `update` may overwrite/merge. Everything else
29
- // (src/, public/, index.html, vite.config.ts, tsconfig.json, lockfile, .gitignore,
30
- // port-parity.json, …) is treated as user-owned and left alone. Skills aren't
31
- // here they're pulled from the published repo via `pnpm skills:update`, not
32
- // vendored into the scaffold.
33
- const MANAGED = ["scripts", "docs", ".github", ".husky", "biome.json", "AGENTS.md", "CLAUDE.md"];
30
+ // Files/dirs the template owns and `update` may overwrite/merge.
31
+ //
32
+ // src/components/ and stories/ are user-owned and never touched.
33
+ // tools/ contains all viewer/router/sandbox infrastructure and IS managed.
34
+ // Everything else (public/, index.html, vite.config.ts, tsconfig.json,
35
+ // lockfile, .gitignore, port-parity.json, …) is also user-owned. Skills aren't here — they're pulled from the published
36
+ // repo via `pnpm skills:update`, not vendored into the scaffold.
37
+ const MANAGED = [
38
+ // Tooling
39
+ "scripts",
40
+ "docs",
41
+ ".github",
42
+ ".husky",
43
+ "biome.json",
44
+ "AGENTS.md",
45
+ "CLAUDE.md",
46
+ // Viewer infrastructure — all managed; src/components/ and stories/ are user-owned
47
+ "tools",
48
+ "src/main.ts",
49
+ "src/utilities.css",
50
+ // Viewer tests
51
+ "test",
52
+ ];
34
53
 
35
54
  const argv = process.argv.slice(2);
36
55
  const dryRun = argv.includes("--dry-run");
@@ -175,7 +194,7 @@ function update(targetArg) {
175
194
  console.log(
176
195
  dryRun
177
196
  ? "\n(dry run — nothing written.)"
178
- : "\nLeft alone: src/, public/, index.html, vite.config.ts, tsconfig.json, .gitignore.\nRun `pnpm install` then `pnpm check`. Update skills separately with `pnpm skills:update`.\n"
197
+ : "\nLeft alone: src/components/, stories/, public/, index.html, vite.config.ts, tsconfig.json, .gitignore.\n(tools/, src/main.ts, src/utilities.css, and test/ were refreshed above.)\nRun `pnpm install` then `pnpm check`. Update skills separately with `pnpm skills:update`.\n"
179
198
  );
180
199
  }
181
200
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-obsidian-arrow",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "Scaffold an Obsidian-styled Arrow.js UI sandbox (pnpm create obsidian-arrow <dir>).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,9 +10,13 @@ This file is the hub — everything else is linked from here:
10
10
 
11
11
  - [`docs/workflow.md`](docs/workflow.md) — fresh-machine → running workflow.
12
12
  - [`skills/`](skills/) — installable domain skills (`pnpm skills:install`):
13
- obsidian-arrow-sandbox, arrow-js-obsidian-templates, arrow-js-obsidian-patterns,
14
- arrow-js-obsidian-porting (sandbox→plugin parity check), obsidian-arrow-maintenance
15
- (updating an existing project).
13
+ - `obsidian-arrow-sandbox` — running the sandbox, CSS scoping, porting basics.
14
+ - `obsidian-arrow-stories` **component + story authoring workflow**: `defineStories` API, variants, children, status flag, DRY patterns, utilities.
15
+ - `obsidian-arrow-css` **CSS decision hierarchy**: Obsidian classes → oas-* utilities → custom CSS; token reference; specificity scoping; overrides via variables; auditing for excess CSS.
16
+ - `arrow-js-obsidian-templates` — Arrow v1.0.6 template syntax + footguns.
17
+ - `arrow-js-obsidian-patterns` — icons, CSS scoping, lifecycle, reactive state.
18
+ - `arrow-js-obsidian-porting` — sandbox→plugin parity check (`component-hash`).
19
+ - `obsidian-arrow-maintenance` — updating an existing project.
16
20
  - [`docs/prompts/`](docs/prompts/) — copy-paste agent prompts: `agent-setup.md`
17
21
  (scaffold + orient) and `update-existing.md` (update tooling + skills, keep src).
18
22
 
@@ -78,6 +82,22 @@ events via `@event` (`@click="${fn}"`), keyed lists via
78
82
  `html\`…\`.key(id)`, async sections via `component(asyncFn, { fallback })` wrapped
79
83
  in `boundary()`.
80
84
 
85
+ ## Conventions
86
+
87
+ - **Check `/reference/classes` first** — Obsidian has semantic classes for most
88
+ common patterns. Use them before writing any custom CSS.
89
+ - **Use `oas-*` utilities second** (`src/utilities.css`) — flex, gap, padding,
90
+ margin, typography, border, overflow helpers built on Obsidian's token scale.
91
+ Prefer `class="oas-flex oas-gap-2"` over `style="display:flex;gap:8px"`.
92
+ - **Custom CSS last** — only when Obsidian has no class and utilities don't cover
93
+ it. Scope under container + element type, use `var(--…)` tokens for values.
94
+ - Add a story by creating `stories/MyThing.stories.ts` — stories live in the
95
+ top-level `stories/` directory (not in `src/`). Import via
96
+ `"../tools/viewer/stories"` and `"../src/components/MyThing"`. See the
97
+ `obsidian-arrow-stories` skill for the full `defineStories` API (variants,
98
+ children, status, notes). Browse live tokens at `/reference`, curated classes
99
+ at `/reference/classes`.
100
+
81
101
  ## CSS scoping
82
102
 
83
103
  - Use Obsidian's own classes (`.setting-item`, `.clickable-icon`,
@@ -86,7 +106,7 @@ in `boundary()`.
86
106
  - Scope any custom rule under a container class + element type (e.g.
87
107
  `.oas-frame button.oas-theme-toggle`) so it beats Obsidian's global
88
108
  `button:not(.clickable-icon)` rule and never leaks. Sandbox-only chrome lives
89
- in `src/sandbox/sandbox.css`; component styling stays on Obsidian classes.
109
+ in `tools/sandbox/sandbox.css`; component styling stays on Obsidian classes.
90
110
 
91
111
  ## Verify before claiming done
92
112
 
@@ -108,4 +128,10 @@ is mechanical: copy the component file into the plugin's view directory and
108
128
  mount it from `ItemView.onOpen()` via `template(this.contentEl)`. If it uses
109
129
  `boundary()`/async components, add `@arrow-js/framework` to the plugin and the
110
130
  `import '@arrow-js/framework'` side-effect import. Strip any sandbox chrome
111
- (`src/sandbox/*`) — that stays here.
131
+ (`tools/sandbox/*`) — that stays here.
132
+
133
+ **Bring `src/utilities.css` along.** Components may use `oas-`-prefixed utility
134
+ classes (flex, gap, padding, typography, border — all built on Obsidian's token
135
+ scale). Copy `src/utilities.css` once into the plugin's styles directory and
136
+ import it there. The `oas-` prefix guarantees no conflict with Obsidian selectors.
137
+ Re-copy when the sandbox file changes (the porting-parity skill covers this).
@@ -24,9 +24,10 @@ Then `cd my-app && pnpm install && pnpm pull-css && pnpm dev`. A freshly
24
24
  scaffolded project passes `pnpm run ci` out of the box. The initializer's
25
25
  template is generated from this repo (`pnpm create:sync`), so it never drifts.
26
26
 
27
- **Update an existing project's tooling** (refreshes the managed files — scripts,
28
- skills, docs, agent guides, CI, `biome.json` and merges new `package.json`
29
- scripts/deps; never touches `src/`, `public/`, `index.html`, or build configs):
27
+ **Update an existing project's tooling** (refreshes managed files — scripts,
28
+ docs, CI, `biome.json`, agent guides, and the viewer/router/sandbox
29
+ infrastructure in `src/` merges new `package.json` scripts/deps; never
30
+ touches `src/components/`, `stories/`, `public/`, `index.html`, or build configs):
30
31
 
31
32
  ```sh
32
33
  npx create-obsidian-arrow update # in the project (or: update <dir>)
@@ -86,12 +87,14 @@ typecheck. CI (`.github/workflows/ci.yml`) runs the `ci` script on push/PR.
86
87
 
87
88
  ## Agent skills
88
89
 
89
- This repo is the source of truth for five [`skills`](https://github.com/vercel-labs/skills)-compatible
90
+ This repo is the source of truth for seven [`skills`](https://github.com/vercel-labs/skills)-compatible
90
91
  skills under [`skills/`](skills/) — it's a skill marketplace. Scaffolds **don't
91
92
  vendor copies**; they pull from this published repo, so installs are always
92
93
  current.
93
94
 
94
- - `obsidian-arrow-sandbox` — running and using this sandbox, and porting to a plugin.
95
+ - `obsidian-arrow-sandbox` — running and using this sandbox, CSS scoping, porting basics.
96
+ - `obsidian-arrow-stories` — **component + story authoring workflow**: the complete `defineStories` API (variants, children, status flag, notes), DRY patterns, utility classes, story viewing, and how to structure sub-components.
97
+ - `obsidian-arrow-css` — **CSS decision hierarchy**: Obsidian classes first, `oas-*` utilities second, custom CSS last; the live token reference (`/reference`), class catalog (`/reference/classes`), specificity scoping, overrides via CSS variables, and auditing components to minimize hand-written CSS.
95
98
  - `arrow-js-obsidian-templates` — Arrow v1.0.6 template rules + footguns.
96
99
  - `arrow-js-obsidian-patterns` — integration patterns: icons (Lucide / data-icon
97
100
  sweep), CSS scoping vs Obsidian globals, mount/unmount lifecycle, reactive state.
@@ -125,6 +128,40 @@ different project root, e.g. an outer repo a scaffold is nested in), `--global`
125
128
  forms `SKILLS_AGENT` / `SKILLS_PROJECT_DIR` / `SKILLS_GLOBAL` (and
126
129
  `SKIP_SKILLS_INSTALL=1`) influence *that* path.
127
130
 
131
+ ## Component viewer & reference
132
+
133
+ **Component viewer (`/components`):** a Storybook-style browser for sandbox
134
+ components. Co-locate a `*.stories.ts` file next to any component and it appears
135
+ in the sidebar and on Home automatically. Stories support named variants,
136
+ drill-in via `children` slugs, and a derived src path shown in the viewer — all
137
+ discovered at build time via `import.meta.glob`.
138
+
139
+ **Reference index (`/reference`):** all `var(--)` tokens parsed live from
140
+ `app.css`, grouped by category (Size & spacing, Radius, Colors, …) with color
141
+ swatches, size bars, a filter input, theme-aware resolved values, and a copy
142
+ button. `/reference/classes` is a curated catalog of Obsidian pattern classes
143
+ with live previews.
144
+
145
+ ### Add a story
146
+
147
+ Create `stories/MyThing.stories.ts` — stories live in the top-level `stories/`
148
+ directory, keeping `src/` purely for component code:
149
+
150
+ ```ts
151
+ import { defineStories } from "../tools/viewer/stories";
152
+ import { MyThing } from "../src/components/MyThing";
153
+
154
+ export default defineStories({
155
+ description: "What it demonstrates.",
156
+ status: "draft",
157
+ variants: { default: () => MyThing() },
158
+ });
159
+ ```
160
+
161
+ It appears in the sidebar and at `/components` automatically; the component path
162
+ shown in the viewer is derived from the filename. Stories are sandbox-only —
163
+ they never port to the plugin.
164
+
128
165
  ## Porting a component into the plugin
129
166
 
130
167
  Components use only Obsidian classes + `var(--…)` tokens and mount via
@@ -133,6 +170,11 @@ copy the component file into the plugin's view directory and mount it from
133
170
  `onOpen()`. If it uses `boundary()`/async components, add `@arrow-js/framework`
134
171
  to the plugin and the `import '@arrow-js/framework'` side-effect import.
135
172
 
173
+ Also copy `src/utilities.css` into the plugin once — components may use `oas-`
174
+ utility classes (flex, gap, padding, typography, border helpers built on
175
+ Obsidian's token scale). The `oas-` prefix means no conflicts with Obsidian's
176
+ own selectors. All ported components in a plugin share one copy of this file.
177
+
136
178
  ## Arrow v1.0.6 footguns (learned the hard way)
137
179
 
138
180
  These are enforced/encoded so they don't regress:
@@ -10,3 +10,6 @@ dist
10
10
  # Obsidian's app.css is proprietary — extract it locally with `pnpm pull-css`,
11
11
  # don't commit/redistribute it.
12
12
  public/app.css
13
+
14
+ # subagent-driven-development scratch (briefs, reports, ledger)
15
+ .superpowers/
@@ -30,7 +30,8 @@ Then:
30
30
  # committed; it's Obsidian's proprietary CSS). Auto-detect is
31
31
  # macOS-only; on Windows/WSL pass --path <obsidian.asar|app.css>
32
32
  # or set OBSIDIAN_ASAR=<path>.
33
- pnpm dev # open the printed URL: / is the examples index, /example the demo.
33
+ pnpm dev # open the printed URL: / is home, /components the story viewer,
34
+ # /reference the Obsidian token/class index.
34
35
  # The toolbar slider/presets + edge drag handle resize the panel.
35
36
  pnpm skills:install --yes # install all agent skills non-interactively, pulled
36
37
  # from the published repo (not vendored) — this loads
@@ -42,11 +43,17 @@ Then:
42
43
  READ FIRST
43
44
  - AGENTS.md (root) — operating guide + docs map (links everything below).
44
45
  - docs/workflow.md — fresh-machine → running workflow.
45
- - skills/*/SKILL.md — obsidian-arrow-sandbox (workflow), arrow-js-obsidian-
46
- templates (template syntax + footguns), arrow-js-obsidian-patterns (icons via
47
- Lucide/data-icon sweep, CSS scoping, mount/unmount lifecycle, reactive state),
48
- arrow-js-obsidian-porting (sandbox→plugin parity check),
49
- obsidian-arrow-maintenance (updating an existing project).
46
+ - skills/*/SKILL.md — seven installable skills:
47
+ obsidian-arrow-sandbox running the sandbox, CSS scoping, porting basics
48
+ obsidian-arrow-stories component + story authoring: defineStories API,
49
+ variants, children, status, DRY patterns, utilities
50
+ obsidian-arrow-css CSS decision hierarchy: Obsidian classes → oas-*
51
+ utilities → custom CSS; token/class reference;
52
+ scoping rules; overrides via variables; CSS audit
53
+ arrow-js-obsidian-templates template syntax + hard footguns
54
+ arrow-js-obsidian-patterns icons, CSS scoping, lifecycle, reactive state
55
+ arrow-js-obsidian-porting sandbox→plugin parity check
56
+ obsidian-arrow-maintenance updating an existing project
50
57
 
51
58
  ARROW v1.0.6 FOOTGUNS — do not relearn these the hard way:
52
59
  1. NO literal HTML comments inside html`` templates — Arrow treats HTML comments
@@ -67,9 +74,11 @@ CONVENTIONS
67
74
  .vertical-tab-*, .modal, .mod-cta) and var(--…) tokens first; add custom CSS
68
75
  only when Obsidian has no class, scoped under a container class + element type
69
76
  (e.g. `.my-panel button.my-action`) so it beats Obsidian's global button rule.
70
- - Sandbox-only chrome lives in src/sandbox/* — it does NOT port to a plugin.
71
- - Add a demo by exporting an Arrow component and registering it in
72
- src/examples/registry.ts (it shows on the index and at its own route).
77
+ - Sandbox-only chrome lives in tools/sandbox/* — it does NOT port to a plugin.
78
+ - Add a story by creating `stories/MyThing.stories.ts` (top-level `stories/`
79
+ dir, NOT in `src/`). Import: `"../tools/viewer/stories"` and
80
+ `"../src/components/MyThing"`. It appears at `/components/<slug>` automatically.
81
+ Browse tokens at `/reference`, curated classes at `/reference/classes`.
73
82
 
74
83
  VERIFY BEFORE CLAIMING DONE
75
84
  - `pnpm typecheck && pnpm test && pnpm lint` (or `pnpm run ci` for the full chain).
@@ -81,15 +90,19 @@ PORTING TO A PLUGIN
81
90
  Copy the component file into the plugin's view dir and mount from
82
91
  ItemView.onOpen() via `template(this.contentEl)`. If it uses boundary()/async
83
92
  components, add @arrow-js/framework to the plugin and the side-effect
84
- `import '@arrow-js/framework'`. Leave src/sandbox/* behind. Guard against drift
85
- with the porting-parity check (see the arrow-js-obsidian-porting skill).
93
+ `import '@arrow-js/framework'`. Also copy src/utilities.css into the plugin once
94
+ (all ported components share it) components may use oas-* utility classes
95
+ (flex, gap, padding, text, border helpers built on Obsidian's token scale).
96
+ Leave tools/sandbox/* behind. Guard against drift with the porting-parity check
97
+ (see the arrow-js-obsidian-porting skill).
86
98
 
87
99
  MAINTENANCE (existing project)
88
- Refresh tooling later with `npx create-obsidian-arrow update` (preserves src/),
100
+ Refresh tooling with `npx create-obsidian-arrow update` (preserves src/components/
101
+ and stories/ — updates viewer, router, sandbox, utilities, and tooling files),
89
102
  update skills with `pnpm skills:update`. See the obsidian-arrow-maintenance skill.
90
103
 
91
104
  Start by scaffolding, running setup steps, then read AGENTS.md and confirm
92
- `pnpm dev` renders /example correctly. Report what you see.
105
+ `pnpm dev` renders correctly at /components and /reference. Report what you see.
93
106
  ```
94
107
 
95
108
  ---
@@ -11,10 +11,12 @@ Update this existing Obsidian Arrow project to the latest tooling and agent
11
11
  skills. Do NOT change any of my source code.
12
12
 
13
13
  HARD CONSTRAINTS
14
- - Never modify src/, public/, index.html, vite.config.ts, tsconfig.json, or my
15
- component/app code. Only managed tooling, skills, and docs may change.
14
+ - Never modify src/components/, stories/, public/, index.html, vite.config.ts,
15
+ tsconfig.json, or my component/app code. Only managed tooling, skills, docs,
16
+ and the viewer/router/sandbox infrastructure in src/ may change.
16
17
  - Preview before applying anything destructive; don't commit unless I ask.
17
- - At the end, prove src/ was untouched (`git diff --stat` shows no src/ changes).
18
+ - At the end, prove src/components/ and stories/ were untouched
19
+ (`git diff --stat` shows no changes to those paths).
18
20
 
19
21
  CONTEXT
20
22
  Scaffolded from create-obsidian-arrow. Tooling + agent skills come from the
@@ -29,12 +31,14 @@ STEPS (in order)
29
31
  project dir. If the OUTER root differs, that's where skills must be installed
30
32
  so the session's skill:// registry (repo-root + global only) can find them.
31
33
 
32
- 2. Refresh tooling — preserves src/
34
+ 2. Refresh tooling — preserves src/components/ only
33
35
  - Preview: npx create-obsidian-arrow update --dry-run
34
36
  - Apply: npx create-obsidian-arrow update
35
37
  - Then: pnpm install
36
- Refreshes scripts/, docs/, .github/, .husky/, biome.json, AGENTS.md, CLAUDE.md
37
- and merges package.json scripts/deps. It never touches src/, public/, or configs.
38
+ Refreshes scripts/, docs/, .github/, .husky/, biome.json, AGENTS.md, CLAUDE.md,
39
+ tools/, src/main.ts, src/utilities.css, test/,
40
+ and merges package.json scripts/deps. It never touches src/components/, public/,
41
+ index.html, vite.config.ts, tsconfig.json, or .gitignore.
38
42
 
39
43
  3. Reset agent skills to the current set
40
44
  - Audit: npx skills list
@@ -60,7 +64,7 @@ STEPS (in order)
60
64
 
61
65
  7. Verify
62
66
  - pnpm run ci (biome + typecheck + tests + build)
63
- - pnpm dev and confirm /example renders with a clean console
67
+ - pnpm dev and confirm /components and /reference render with a clean console
64
68
 
65
69
  REPORT
66
70
  - What `update` changed, which skills are now installed and where, the pull-css
@@ -73,6 +77,6 @@ REPORT
73
77
  - Skills are pulled from the published repo, so step 3 is location-independent for
74
78
  the *source* — only the *install location* matters (run it at the repo root the
75
79
  agent uses; reload after).
76
- - `npx create-obsidian-arrow update` is **create-only-safe**: it refreshes managed
77
- files and merges `package.json`, but never overwrites `src/`, `public/`,
80
+ - `npx create-obsidian-arrow update` refreshes managed files and merges
81
+ `package.json`, but never overwrites `src/components/`, `stories/`, `public/`,
78
82
  `index.html`, or build configs. See the `obsidian-arrow-maintenance` skill.
@@ -25,7 +25,8 @@ pnpm pull-css # macOS: auto-detects /Applications/Obs
25
25
  # or OBSIDIAN_ASAR=<path> pnpm pull-css
26
26
 
27
27
  # 4. Run it
28
- pnpm dev # open the printed URL — / is the index, /example the demo
28
+ pnpm dev # open the printed URL — / is home, /components the story
29
+ # viewer, /reference the token/class index
29
30
  ```
30
31
 
31
32
  `public/app.css` is **git-ignored and never shipped** (it's Obsidian's proprietary
@@ -48,14 +49,22 @@ Then point the agent at [`AGENTS.md`](../AGENTS.md), or brief a fresh agent with
48
49
  `skills` CLI is cwd-relative). To install them at the outer repo instead:
49
50
  `pnpm skills:install --yes --project-dir=<outer-repo>` (or `--global`).
50
51
 
51
- **Refresh an existing project's tooling** (scripts, skills, docs, CI — never your
52
- `src/`): `npx create-obsidian-arrow update` (add `--dry-run` to preview).
52
+ **Refresh an existing project's tooling** (scripts, docs, CI, viewer/router/sandbox
53
+ in `src/` never `src/components/` or `stories/`):
54
+ `npx create-obsidian-arrow update` (add `--dry-run` to preview).
53
55
 
54
56
  ## Build → verify → port loop
55
57
 
56
58
  ```sh
57
- # add a component in src/components/, register it in src/examples/registry.ts
59
+ # 1. Check /reference/classes in the running sandbox does Obsidian have a class
60
+ # for your pattern? Use it before writing custom CSS.
61
+ # 2. Add src/components/MyThing.ts (Arrow component)
62
+ # 3. Add stories/MyThing.stories.ts (story file — lives in stories/, not src/)
58
63
  pnpm dev # iterate with HMR
64
+ # /components → index of all discovered stories
65
+ # /components/my-thing → story for MyThing
66
+ # /reference → live Obsidian token reference
67
+ # /reference/classes → curated class catalog with live previews
59
68
  pnpm run ci # biome + typecheck + tests + build before trusting it
60
69
  ```
61
70
 
@@ -63,10 +72,14 @@ Always confirm the actual render in the browser — Arrow's footguns surface onl
63
72
  at render, so a passing `tsc` is not proof a component works. See the footguns in
64
73
  [`AGENTS.md`](../AGENTS.md) and the `arrow-js-obsidian-templates` skill.
65
74
 
66
- **Port a component into a plugin:** copy the file into the plugin's view directory
67
- and mount it from `ItemView.onOpen()` via `template(this.contentEl)`. If it uses
68
- `boundary()`/async components, add `@arrow-js/framework` to the plugin and the
69
- side-effect `import '@arrow-js/framework'`. Leave `src/sandbox/*` behind.
75
+ For the complete story authoring workflow (`defineStories` API, variants, children,
76
+ status flag, DRY patterns) see the `obsidian-arrow-stories` skill.
77
+
78
+ **Port a component into a plugin:** copy the component file and `src/utilities.css`
79
+ (once, shared by all ports) into the plugin. Mount from `ItemView.onOpen()` via
80
+ `template(this.contentEl)`. If it uses `boundary()`/async, add
81
+ `@arrow-js/framework` and `import '@arrow-js/framework'`. Leave `tools/sandbox/*`
82
+ behind.
70
83
 
71
84
  ## Scaffold vs. clone
72
85
 
@@ -14,7 +14,7 @@
14
14
  "create:sync": "node create-obsidian-arrow/scripts/sync-template.mjs",
15
15
  "lint": "biome check .",
16
16
  "format": "biome check --write .",
17
- "test": "node --test test/*.test.mjs",
17
+ "test": "node --experimental-strip-types --test test/*.test.mjs",
18
18
  "check": "biome check --write . && pnpm typecheck && pnpm test",
19
19
  "ci": "biome ci . && pnpm typecheck && pnpm test && pnpm build",
20
20
  "skills:install": "node scripts/install-skills.mjs --force",
@@ -27,7 +27,11 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@arrow-js/core": "^1.0.6",
30
- "@arrow-js/framework": "^1.0.6"
30
+ "@arrow-js/framework": "^1.0.6",
31
+ "@codemirror/lang-markdown": "^6.5.0",
32
+ "@codemirror/merge": "^6.12.2",
33
+ "@codemirror/state": "^6.7.0",
34
+ "@codemirror/view": "^6.43.4"
31
35
  },
32
36
  "devDependencies": {
33
37
  "@biomejs/biome": "^1.9.4",