@slats/claude-assets-sync 0.1.4 → 0.3.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 (239) hide show
  1. package/README.md +89 -581
  2. package/bin/inject-claude-settings.mjs +4 -0
  3. package/dist/claude-hashes.json +20 -0
  4. package/dist/commands/index.d.ts +1 -112
  5. package/dist/commands/runCli/index.d.ts +2 -0
  6. package/dist/commands/runCli/runCli.cjs +53 -0
  7. package/dist/commands/runCli/runCli.d.ts +14 -0
  8. package/dist/commands/runCli/runCli.mjs +51 -0
  9. package/dist/commands/runCli/type.d.ts +19 -0
  10. package/dist/commands/runCli/utils/classifyTarget.cjs +48 -0
  11. package/dist/commands/runCli/utils/classifyTarget.d.ts +19 -0
  12. package/dist/commands/runCli/utils/classifyTarget.mjs +46 -0
  13. package/dist/commands/runCli/utils/injectOne.cjs +47 -0
  14. package/dist/commands/runCli/utils/injectOne.d.ts +3 -0
  15. package/dist/commands/runCli/utils/injectOne.mjs +45 -0
  16. package/dist/commands/runCli/utils/resolvePackage.cjs +77 -0
  17. package/dist/commands/runCli/utils/resolvePackage.d.ts +16 -0
  18. package/dist/commands/runCli/utils/resolvePackage.mjs +74 -0
  19. package/dist/commands/runCli/utils/resolveScopeAlias.cjs +69 -0
  20. package/dist/commands/runCli/utils/resolveScopeAlias.d.ts +2 -0
  21. package/dist/commands/runCli/utils/resolveScopeAlias.mjs +67 -0
  22. package/dist/commands/runCli/utils/resolveScopeFlag.cjs +28 -0
  23. package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +2 -0
  24. package/dist/commands/runCli/utils/resolveScopeFlag.mjs +26 -0
  25. package/dist/commands/runCli/utils/resolveTargets.cjs +40 -0
  26. package/dist/commands/runCli/utils/resolveTargets.d.ts +15 -0
  27. package/dist/commands/runCli/utils/resolveTargets.mjs +38 -0
  28. package/dist/commands/runCli/utils/runInject.cjs +52 -0
  29. package/dist/commands/runCli/utils/runInject.d.ts +3 -0
  30. package/dist/commands/runCli/utils/runInject.mjs +50 -0
  31. package/dist/core/buildPlan/buildPlan.cjs +42 -0
  32. package/dist/core/buildPlan/buildPlan.d.ts +2 -0
  33. package/dist/core/buildPlan/buildPlan.mjs +40 -0
  34. package/dist/core/buildPlan/index.d.ts +2 -0
  35. package/dist/core/buildPlan/type.d.ts +32 -0
  36. package/dist/core/buildPlan/utils/toPosix.cjs +9 -0
  37. package/dist/core/buildPlan/utils/toPosix.d.ts +1 -0
  38. package/dist/core/buildPlan/utils/toPosix.mjs +7 -0
  39. package/dist/core/buildPlan/utils/walkFiles.cjs +25 -0
  40. package/dist/core/buildPlan/utils/walkFiles.d.ts +1 -0
  41. package/dist/core/buildPlan/utils/walkFiles.mjs +23 -0
  42. package/dist/core/hash/hash.cjs +30 -0
  43. package/dist/core/hash/hash.d.ts +4 -0
  44. package/dist/core/hash/hash.mjs +26 -0
  45. package/dist/core/hash/index.d.ts +1 -0
  46. package/dist/core/hashManifest/hashManifest.cjs +27 -0
  47. package/dist/core/hashManifest/hashManifest.d.ts +17 -0
  48. package/dist/core/hashManifest/hashManifest.mjs +23 -0
  49. package/dist/core/hashManifest/index.d.ts +1 -0
  50. package/dist/core/index.d.ts +5 -0
  51. package/dist/core/injectDocs/index.d.ts +2 -0
  52. package/dist/core/injectDocs/injectDocs.cjs +43 -0
  53. package/dist/core/injectDocs/injectDocs.d.ts +2 -0
  54. package/dist/core/injectDocs/injectDocs.mjs +41 -0
  55. package/dist/core/injectDocs/type.d.ts +30 -0
  56. package/dist/core/injectDocs/utils/applyAction.cjs +21 -0
  57. package/dist/core/injectDocs/utils/applyAction.d.ts +2 -0
  58. package/dist/core/injectDocs/utils/applyAction.mjs +19 -0
  59. package/dist/core/injectDocs/utils/emitCiForceList.cjs +10 -0
  60. package/dist/core/injectDocs/utils/emitCiForceList.d.ts +2 -0
  61. package/dist/core/injectDocs/utils/emitCiForceList.mjs +8 -0
  62. package/dist/core/injectDocs/utils/printPlan.cjs +20 -0
  63. package/dist/core/injectDocs/utils/printPlan.d.ts +2 -0
  64. package/dist/core/injectDocs/utils/printPlan.mjs +18 -0
  65. package/dist/core/injectDocs/utils/summarize.cjs +27 -0
  66. package/dist/core/injectDocs/utils/summarize.d.ts +3 -0
  67. package/dist/core/injectDocs/utils/summarize.mjs +25 -0
  68. package/dist/core/scope/index.d.ts +1 -0
  69. package/dist/core/scope/scope.cjs +46 -0
  70. package/dist/core/scope/scope.d.ts +16 -0
  71. package/dist/core/scope/scope.mjs +41 -0
  72. package/dist/core/scope/utils/isDirectory.cjs +14 -0
  73. package/dist/core/scope/utils/isDirectory.d.ts +1 -0
  74. package/dist/core/scope/utils/isDirectory.mjs +12 -0
  75. package/dist/index.cjs +15 -9
  76. package/dist/index.d.ts +3 -5
  77. package/dist/index.mjs +7 -3
  78. package/dist/prompts/confirmForce.cjs +27 -0
  79. package/dist/prompts/confirmForce.d.ts +1 -0
  80. package/dist/prompts/confirmForce.mjs +25 -0
  81. package/dist/prompts/index.d.ts +2 -0
  82. package/dist/prompts/selectScope.cjs +30 -0
  83. package/dist/prompts/selectScope.d.ts +2 -0
  84. package/dist/prompts/selectScope.mjs +28 -0
  85. package/dist/utils/heartbeat.cjs +25 -0
  86. package/dist/utils/heartbeat.d.ts +16 -0
  87. package/dist/utils/heartbeat.mjs +23 -0
  88. package/dist/utils/logger.cjs +7 -0
  89. package/dist/utils/logger.d.ts +8 -0
  90. package/dist/utils/logger.mjs +7 -0
  91. package/dist/utils/types.d.ts +1 -252
  92. package/dist/utils/version.cjs +2 -14
  93. package/dist/utils/version.d.ts +3 -53
  94. package/dist/utils/version.mjs +2 -13
  95. package/docs/bundle-size-decision.md +36 -0
  96. package/docs/claude/skills/claude-docs-asset-wiring/SKILL.md +159 -0
  97. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/claude-md-template.md +86 -0
  98. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/dependency-cruiser.md +54 -0
  99. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/gotchas.md +122 -0
  100. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/package-json-patches.md +145 -0
  101. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/reference-files.md +37 -0
  102. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/smoke-tests.md +111 -0
  103. package/docs/consumer-integration.md +94 -0
  104. package/package.json +24 -16
  105. package/scripts/build-hashes.mjs +30 -0
  106. package/scripts/buildHashes.d.mts +15 -0
  107. package/scripts/buildHashes.mjs +82 -0
  108. package/scripts/claude-build-hashes.mjs +42 -0
  109. package/scripts/inject-version.js +112 -0
  110. package/dist/cli.cjs +0 -8
  111. package/dist/cli.d.ts +0 -1
  112. package/dist/cli.mjs +0 -7
  113. package/dist/commands/add.cjs +0 -80
  114. package/dist/commands/add.d.ts +0 -8
  115. package/dist/commands/add.mjs +0 -78
  116. package/dist/commands/list.cjs +0 -94
  117. package/dist/commands/list.d.ts +0 -15
  118. package/dist/commands/list.mjs +0 -91
  119. package/dist/commands/migrate.cjs +0 -9
  120. package/dist/commands/migrate.d.ts +0 -6
  121. package/dist/commands/migrate.mjs +0 -7
  122. package/dist/commands/remove.cjs +0 -127
  123. package/dist/commands/remove.d.ts +0 -6
  124. package/dist/commands/remove.mjs +0 -105
  125. package/dist/commands/status.cjs +0 -193
  126. package/dist/commands/status.d.ts +0 -6
  127. package/dist/commands/status.mjs +0 -171
  128. package/dist/commands/sync.cjs +0 -28
  129. package/dist/commands/sync.d.ts +0 -6
  130. package/dist/commands/sync.mjs +0 -26
  131. package/dist/commands/types.d.ts +0 -89
  132. package/dist/commands/update.cjs +0 -209
  133. package/dist/commands/update.d.ts +0 -29
  134. package/dist/commands/update.mjs +0 -206
  135. package/dist/components/add/AddCommand.cjs +0 -103
  136. package/dist/components/add/AddCommand.d.ts +0 -14
  137. package/dist/components/add/AddCommand.mjs +0 -101
  138. package/dist/components/add/BulkAddView.cjs +0 -165
  139. package/dist/components/add/BulkAddView.d.ts +0 -11
  140. package/dist/components/add/BulkAddView.mjs +0 -163
  141. package/dist/components/add/index.d.ts +0 -2
  142. package/dist/components/index.d.ts +0 -2
  143. package/dist/components/list/EditableTreeItem.d.ts +0 -13
  144. package/dist/components/list/ListCommand.cjs +0 -651
  145. package/dist/components/list/ListCommand.d.ts +0 -5
  146. package/dist/components/list/ListCommand.mjs +0 -649
  147. package/dist/components/list/SyncedPackageTree.d.ts +0 -14
  148. package/dist/components/list/index.d.ts +0 -10
  149. package/dist/components/list/types.d.ts +0 -14
  150. package/dist/components/primitives/Box.d.ts +0 -4
  151. package/dist/components/primitives/Spinner.d.ts +0 -6
  152. package/dist/components/primitives/Text.d.ts +0 -4
  153. package/dist/components/primitives/index.d.ts +0 -3
  154. package/dist/components/remove/RemoveConfirm.cjs +0 -18
  155. package/dist/components/remove/RemoveConfirm.d.ts +0 -11
  156. package/dist/components/remove/RemoveConfirm.mjs +0 -16
  157. package/dist/components/shared/Confirm.cjs +0 -30
  158. package/dist/components/shared/Confirm.d.ts +0 -8
  159. package/dist/components/shared/Confirm.mjs +0 -28
  160. package/dist/components/shared/MenuItem.cjs +0 -18
  161. package/dist/components/shared/MenuItem.d.ts +0 -7
  162. package/dist/components/shared/MenuItem.mjs +0 -16
  163. package/dist/components/shared/ProgressBar.d.ts +0 -7
  164. package/dist/components/shared/StepRunner.cjs +0 -58
  165. package/dist/components/shared/StepRunner.d.ts +0 -15
  166. package/dist/components/shared/StepRunner.mjs +0 -56
  167. package/dist/components/shared/Table.cjs +0 -19
  168. package/dist/components/shared/Table.d.ts +0 -8
  169. package/dist/components/shared/Table.mjs +0 -17
  170. package/dist/components/shared/index.d.ts +0 -6
  171. package/dist/components/status/PackageStatusCard.d.ts +0 -10
  172. package/dist/components/status/StatusDisplay.cjs +0 -26
  173. package/dist/components/status/StatusDisplay.d.ts +0 -23
  174. package/dist/components/status/StatusDisplay.mjs +0 -24
  175. package/dist/components/status/StatusTreeNode.cjs +0 -40
  176. package/dist/components/status/StatusTreeNode.d.ts +0 -15
  177. package/dist/components/status/StatusTreeNode.mjs +0 -38
  178. package/dist/components/status/index.d.ts +0 -6
  179. package/dist/components/tree/AssetTreeNode.cjs +0 -54
  180. package/dist/components/tree/AssetTreeNode.d.ts +0 -12
  181. package/dist/components/tree/AssetTreeNode.mjs +0 -52
  182. package/dist/components/tree/TreeSelect.cjs +0 -129
  183. package/dist/components/tree/TreeSelect.d.ts +0 -12
  184. package/dist/components/tree/TreeSelect.mjs +0 -127
  185. package/dist/components/tree/index.d.ts +0 -4
  186. package/dist/core/assetStructure.cjs +0 -30
  187. package/dist/core/assetStructure.d.ts +0 -36
  188. package/dist/core/assetStructure.mjs +0 -27
  189. package/dist/core/cli.cjs +0 -106
  190. package/dist/core/cli.d.ts +0 -9
  191. package/dist/core/cli.mjs +0 -103
  192. package/dist/core/constants.cjs +0 -28
  193. package/dist/core/constants.d.ts +0 -94
  194. package/dist/core/constants.mjs +0 -21
  195. package/dist/core/filesystem.cjs +0 -98
  196. package/dist/core/filesystem.d.ts +0 -94
  197. package/dist/core/filesystem.mjs +0 -88
  198. package/dist/core/github.cjs +0 -115
  199. package/dist/core/github.d.ts +0 -61
  200. package/dist/core/github.mjs +0 -107
  201. package/dist/core/io.cjs +0 -46
  202. package/dist/core/io.d.ts +0 -40
  203. package/dist/core/io.mjs +0 -39
  204. package/dist/core/listOperations.cjs +0 -228
  205. package/dist/core/listOperations.d.ts +0 -43
  206. package/dist/core/listOperations.mjs +0 -205
  207. package/dist/core/localSource.cjs +0 -126
  208. package/dist/core/localSource.d.ts +0 -33
  209. package/dist/core/localSource.mjs +0 -120
  210. package/dist/core/migration.cjs +0 -201
  211. package/dist/core/migration.d.ts +0 -57
  212. package/dist/core/migration.mjs +0 -198
  213. package/dist/core/packageScanner.cjs +0 -360
  214. package/dist/core/packageScanner.d.ts +0 -22
  215. package/dist/core/packageScanner.mjs +0 -356
  216. package/dist/core/sync.cjs +0 -400
  217. package/dist/core/sync.d.ts +0 -21
  218. package/dist/core/sync.mjs +0 -397
  219. package/dist/core/syncMeta.cjs +0 -242
  220. package/dist/core/syncMeta.d.ts +0 -75
  221. package/dist/core/syncMeta.mjs +0 -229
  222. package/dist/utils/dependencies.cjs +0 -57
  223. package/dist/utils/dependencies.d.ts +0 -10
  224. package/dist/utils/dependencies.mjs +0 -34
  225. package/dist/utils/nameTransform.cjs +0 -13
  226. package/dist/utils/nameTransform.d.ts +0 -65
  227. package/dist/utils/nameTransform.mjs +0 -11
  228. package/dist/utils/package.cjs +0 -170
  229. package/dist/utils/package.d.ts +0 -105
  230. package/dist/utils/package.mjs +0 -157
  231. package/dist/utils/packageName.cjs +0 -24
  232. package/dist/utils/packageName.d.ts +0 -32
  233. package/dist/utils/packageName.mjs +0 -21
  234. package/dist/utils/paths.cjs +0 -18
  235. package/dist/utils/paths.d.ts +0 -55
  236. package/dist/utils/paths.mjs +0 -15
  237. package/dist/version.cjs +0 -5
  238. package/dist/version.d.ts +0 -5
  239. package/dist/version.mjs +0 -3
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: claude-docs-asset-wiring
3
+ description: "Wire a consumer package's docs/claude assets into the @slats/claude-assets-sync engine. Adds package.json.claude.assetPath, points scripts.build:hashes at claude-build-hashes, declares the engine as a dependency, updates CLAUDE.md, and runs the dispatcher smoke test. Idempotent — asks before clobbering."
4
+ user-invocable: true
5
+ disable-model-invocation: true
6
+ argument-hint: <target-package-path>
7
+ ---
8
+
9
+ # claude-docs-asset-wiring
10
+
11
+ Wire a consumer package's `docs/claude/**` into `@slats/claude-assets-sync`
12
+ so end users can inject those assets via the engine's `inject-claude-settings`
13
+ bin. Reference consumer: `packages/canard/schema-form`.
14
+
15
+ The engine is single-dispatcher. Consumers do NOT ship their own bin stubs
16
+ — they declare `claude.assetPath` in `package.json` and let the engine's
17
+ `claude-build-hashes` bin regenerate `dist/claude-hashes.json` during
18
+ build. `src/core/**` never reads `package.json`; only the engine's `bin/`
19
+ layer resolves a single explicitly-named target.
20
+
21
+ **Outcome**
22
+
23
+ ```bash
24
+ npx -p @slats/claude-assets-sync inject-claude-settings \
25
+ --package=<PACKAGE_NAME> \
26
+ --scope=user|project [--dry-run] [--force]
27
+ ```
28
+
29
+ ## Role
30
+
31
+ You are a monorepo wiring specialist. Execute the 6 steps below as a
32
+ single, idempotent procedure. On any conflicting existing value — ask
33
+ the user before overwriting. Never clobber silently.
34
+
35
+ ## Knowledge Resources
36
+
37
+ Consult these files as needed during execution. Do NOT preload everything;
38
+ load on demand.
39
+
40
+ - `knowledge/reference-files.md` — what the consumer should (and should not) own
41
+ - `knowledge/package-json-patches.md` — every required `package.json` edit, with guard conditions
42
+ - `knowledge/claude-md-template.md` — the `## Claude Docs Injector` section to inject into the target `CLAUDE.md`
43
+ - `knowledge/smoke-tests.md` — E2E 8-path matrix via the engine dispatcher
44
+ - `knowledge/dependency-cruiser.md` — optional CI-time isolation rule
45
+ - `knowledge/gotchas.md` — invariants and pitfalls
46
+
47
+ ## Inputs
48
+
49
+ Resolve these before starting. If any is missing, stop and ask.
50
+
51
+ | Variable | Source |
52
+ |----------------|-----------------------------------------------------------------------------------------------------------|
53
+ | `TARGET_PATH` | Skill argument (e.g. `packages/lerx/promise-modal`). If absent, ask the user. |
54
+ | `PACKAGE_NAME` | `name` field of `${TARGET_PATH}/package.json`. |
55
+ | `SHORTCUT` | Root `package.json` `scripts` entry whose value equals `yarn workspace ${PACKAGE_NAME}`; else unset. |
56
+
57
+ `SHORTCUT` is a convenience only. When unset, fall back to full workspace
58
+ syntax: `yarn workspace ${PACKAGE_NAME} <subcommand>`.
59
+
60
+ ## Pre-Flight
61
+
62
+ Stop and report on any failure. Do not attempt to fix silently.
63
+
64
+ - [ ] `${TARGET_PATH}/docs/claude/skills/<name>/SKILL.md` and `knowledge/*.md` exist — the docs to be injected.
65
+ - [ ] `${TARGET_PATH}/package.json` has `"type": "module"` and `"sideEffects": false`.
66
+ - [ ] Build pipeline uses `rollup -c && yarn build:types` where `build:types` runs `node ../../aileron/script/build/buildTypes.mjs`.
67
+ - [ ] `git status` in `${TARGET_PATH}` is clean. Unrelated changes present → confirm with user before proceeding.
68
+
69
+ ## Steps
70
+
71
+ Execute in order. Each step is idempotent; on conflict, ask rather than overwrite.
72
+
73
+ ### Step 1 — Patch `${TARGET_PATH}/package.json`
74
+
75
+ See `knowledge/package-json-patches.md` for the complete patch list:
76
+
77
+ - `claude.assetPath` — set to `docs/claude` (or the consumer's chosen path).
78
+ - `scripts.build` — ensure the chain ends with `&& yarn build:hashes`.
79
+ - `scripts.build:hashes` — set to `claude-build-hashes` (the engine's bin).
80
+ - `scripts.prepublishOnly` — `yarn build` if not already present.
81
+ - `dependencies."@slats/claude-assets-sync"` — add (NOT `devDependencies`, NOT `peerDependencies`).
82
+ - `files` — ensure `"dist"`, `"docs"`, `"README.md"` are listed. Never include `"bin"` or `"scripts"`.
83
+
84
+ Do NOT add any `bin` entry. Do NOT add `./bin/*` or `./docs/*` to `exports`.
85
+ Do NOT create `bin/` or `scripts/` directories in the consumer.
86
+
87
+ ### Step 2 — Patch `${TARGET_PATH}/CLAUDE.md`
88
+
89
+ If `CLAUDE.md` exists, append or replace the `## Claude Docs Injector`
90
+ section from `knowledge/claude-md-template.md`, substituting
91
+ `${PACKAGE_NAME}`. Skip if `CLAUDE.md` does not exist (do not create one).
92
+
93
+ ### Step 3 — (Optional) Dependency-cruiser isolation gate
94
+
95
+ Skip unless `${TARGET_PATH}/.dependency-cruiser.cjs` already exists or the
96
+ user explicitly asks. See `knowledge/dependency-cruiser.md` for the single
97
+ remaining forbidden rule (`src/**` → `docs/**`) and the `depcheck` script.
98
+
99
+ ### Step 4 — Install and build
100
+
101
+ ```bash
102
+ yarn install
103
+ yarn ${SHORTCUT:-workspace ${PACKAGE_NAME}} build
104
+ ```
105
+
106
+ Expected: `rollup` → `buildTypes` → `claude-build-hashes` succeed, and
107
+ `${TARGET_PATH}/dist/claude-hashes.json` is written.
108
+
109
+ ### Step 5 — E2E smoke via engine dispatcher
110
+
111
+ Run from `/tmp/...`, never from the monorepo root or `${TARGET_PATH}/` —
112
+ `--scope=project` walks `cwd` upward looking for an existing `.claude`,
113
+ which would mutate the real repo's. See `knowledge/smoke-tests.md` for
114
+ the full 8-path matrix, expected exit codes, and rationale.
115
+
116
+ ### Step 6 — Report
117
+
118
+ Summarize:
119
+
120
+ - Files patched vs. skipped (with reason for each skip).
121
+ - Manifest file count from `dist/claude-hashes.json`.
122
+ - Smoke-test exit codes (all 8).
123
+ - Recommendation: commit this change on its own, separate from other work.
124
+
125
+ ## Report Template
126
+
127
+ ```markdown
128
+ ## claude-docs-asset-wiring — ${PACKAGE_NAME}
129
+
130
+ **Files patched**
131
+ - package.json — patched: [claude.assetPath, scripts.build, scripts.build:hashes, dependencies, files]
132
+ - CLAUDE.md — section added | skipped (no CLAUDE.md)
133
+ - .dependency-cruiser.cjs — updated | skipped (not present)
134
+
135
+ **Manifest**
136
+ - dist/claude-hashes.json: <N> files
137
+
138
+ **Smoke tests**
139
+ | # | command | expected | actual |
140
+ |---|-------------------------------------------------------------|----------|--------|
141
+ | 1 | --package=${PACKAGE_NAME} --scope=project --dry-run | 0 | <n> |
142
+ | 2 | --package=${PACKAGE_NAME} --scope=project | 0 | <n> |
143
+ | 3 | --package=${PACKAGE_NAME} --scope=project (up-to-date) | 0 | <n> |
144
+ | 4 | CI=true --package=${PACKAGE_NAME} --scope=project (tampered)| 2 | <n> |
145
+ | 5 | CI=true --package=${PACKAGE_NAME} --scope=project --force | 0 | <n> |
146
+ | 6 | CI=true --package=${PACKAGE_NAME} (missing --scope) | 2 | <n> |
147
+ | 7 | (missing --package) | 2 | <n> |
148
+ | 8 | --package=@does/not-exist | 2 | <n> |
149
+
150
+ **Next**: commit on its own — do not bundle with unrelated changes.
151
+ ```
152
+
153
+ ## Termination Conditions
154
+
155
+ - **Pre-Flight fails** → stop, report the failing check. Do not proceed.
156
+ - **Conflict during patch** → stop, show the diff, ask user whether to overwrite.
157
+ - **Build fails at Step 4** → stop, report error. Do not run smoke tests on a broken build.
158
+ - **Smoke test mismatch** → stop, report the failing path with captured exit code.
159
+ - **All steps pass** → emit the report from the template above.
@@ -0,0 +1,86 @@
1
+ # `CLAUDE.md` — `## Claude Docs Injector` section
2
+
3
+ Reference: `packages/canard/schema-form/CLAUDE.md`.
4
+
5
+ Append the section below to `${TARGET_PATH}/CLAUDE.md` if the file
6
+ exists. Substitute the sample package name in the chosen template
7
+ with `${PACKAGE_NAME}` — six occurrences. Skip the entire step if
8
+ `CLAUDE.md` does not exist (do not create one).
9
+
10
+ The template is intentionally terse: CLI usage + essential isolation
11
+ warnings. Architectural rationale lives in `knowledge/gotchas.md` —
12
+ do not duplicate it into every consumer's `CLAUDE.md`.
13
+
14
+ ---
15
+
16
+ ## Template (Korean — used by all consumers except `@winglet/style-utils`)
17
+
18
+ ````markdown
19
+ ## Claude Docs Injector
20
+
21
+ `docs/claude/**` 자산을 사용자 `.claude/` 에 주입. 엔진: `@slats/claude-assets-sync` (bin: `inject-claude-settings`).
22
+
23
+ ```bash
24
+ # universal — 모든 PM (pnpm strict / yarn-berry PnP 포함)
25
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@canard/schema-form --scope=user
26
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@canard/schema-form --scope=project
27
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@canard/schema-form --scope=user --dry-run
28
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@canard/schema-form --scope=user --force
29
+
30
+ # 간편 — npm / yarn-classic 에서만 (transitive bin hoist 기반)
31
+ npx inject-claude-settings --package=@canard/schema-form --scope=user
32
+ ```
33
+
34
+ ### Isolation Guardrails
35
+
36
+ - `src/**` 는 `docs/**` 와 `@slats/claude-assets-sync` 어느 것도 import 금지.
37
+ - **절대 `exports` 에 `./docs/*` 를 추가하지 말 것.**
38
+ ````
39
+
40
+ ---
41
+
42
+ ## Template (English — `@winglet/style-utils` convention)
43
+
44
+ ````markdown
45
+ ## Claude Docs Injector
46
+
47
+ Inject `docs/claude/**` into the user's `.claude/`. Engine: `@slats/claude-assets-sync` (bin: `inject-claude-settings`).
48
+
49
+ ```bash
50
+ # universal — every PM (pnpm strict / yarn-berry PnP included)
51
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@winglet/style-utils --scope=user
52
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@winglet/style-utils --scope=project
53
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@winglet/style-utils --scope=user --dry-run
54
+ npx -p @slats/claude-assets-sync inject-claude-settings --package=@winglet/style-utils --scope=user --force
55
+
56
+ # simple — npm / yarn-classic only (relies on transitive bin hoist)
57
+ npx inject-claude-settings --package=@winglet/style-utils --scope=user
58
+ ```
59
+
60
+ ### Isolation Guardrails
61
+
62
+ - `src/**` MUST NOT import from `docs/**` or `@slats/claude-assets-sync`.
63
+ - **Never add `./docs/*` to `exports`.**
64
+ ````
65
+
66
+ ---
67
+
68
+ ## Substitution Rules
69
+
70
+ - Replace the sample package name in the chosen template with
71
+ `${PACKAGE_NAME}` — six occurrences.
72
+ - Preserve the Isolation Guardrails bullets verbatim — these are
73
+ the sharp invariants that must stay consistent across consumers.
74
+
75
+ ---
76
+
77
+ ## Placement & Skip Conditions
78
+
79
+ - Append to end of `CLAUDE.md`. Ensure one blank line before the
80
+ injected section.
81
+ - `${TARGET_PATH}/CLAUDE.md` does not exist → skip, report
82
+ "skipped (no CLAUDE.md)".
83
+ - Section already present with identical content → skip, report
84
+ "unchanged".
85
+ - Section present with different content → ask user, do not
86
+ clobber.
@@ -0,0 +1,54 @@
1
+ # Dependency-Cruiser Isolation Rule (optional)
2
+
3
+ Skip this step unless `${TARGET_PATH}/.dependency-cruiser.cjs`
4
+ already exists or the user explicitly asks. This guardrail is a
5
+ CI-time check that the consumer's `src/**` never reaches the
6
+ Claude assets tree.
7
+
8
+ The post-v0.3.0 layout removes the bin stub entirely, so the
9
+ former `src-no-bin` and `src-no-claude-assets-sync` rules are no
10
+ longer load-bearing — the consumer no longer imports any of that
11
+ from anywhere. The one remaining invariant is `src/**` must not
12
+ import from `docs/**`.
13
+
14
+ ## Rule
15
+
16
+ ```javascript
17
+ module.exports = {
18
+ forbidden: [
19
+ {
20
+ name: 'src-no-docs',
21
+ severity: 'error',
22
+ comment:
23
+ 'src/ must not import from docs/. docs/claude/** contains pure markdown ' +
24
+ 'assets meant only for the engine dispatcher, not for the library runtime.',
25
+ from: { path: '^src/' },
26
+ to: { path: '^docs/' },
27
+ },
28
+ ],
29
+ options: {
30
+ doNotFollow: { path: 'node_modules' },
31
+ includeOnly: '^(src|docs)',
32
+ },
33
+ };
34
+ ```
35
+
36
+ ## Optional script
37
+
38
+ ```json
39
+ "scripts": {
40
+ "depcheck": "depcruise src docs --config .dependency-cruiser.cjs --no-progress"
41
+ }
42
+ ```
43
+
44
+ Zero errors expected. Orphan warnings on `docs/**` are
45
+ acceptable — the docs tree never imports anything.
46
+
47
+ ## Legacy rules removed
48
+
49
+ Previous revisions of this skill had three forbidden rules
50
+ (`src-no-bin`, `src-no-docs`, `src-no-claude-assets-sync`), a
51
+ `no-orphans` adjustment excluding `^bin/`, and an `includeOnly`
52
+ covering `^src` and `^bin`. All of those assumed the consumer
53
+ owned a `bin/` directory. The new layout owns no `bin/`, so the
54
+ extra rules are dead. Do not reintroduce them.
@@ -0,0 +1,122 @@
1
+ # Invariants and Gotchas
2
+
3
+ Hard-earned rules. Each one reflects a previous incident or a design
4
+ constraint of the `@slats/claude-assets-sync` engine.
5
+
6
+ ---
7
+
8
+ ## The engine is the only CLI surface
9
+
10
+ `inject-claude-settings` lives in one place: the engine package. No
11
+ consumer has a bin. No consumer has a `bin/` directory. No consumer
12
+ has a `scripts/` directory. If you find yourself "adapting" a stub
13
+ for a new consumer, stop — wiring does not need code; it needs two
14
+ fields in `package.json`.
15
+
16
+ ---
17
+
18
+ ## `claude.assetPath` is the opt-in marker
19
+
20
+ The engine's `claude-build-hashes` bin silently no-ops when
21
+ `claude.assetPath` is missing or not a string. The dispatcher
22
+ (`inject-claude-settings`) exits 2 with a clear error when a target
23
+ lacks the field. Both behaviors are intentional: missing = opt-out.
24
+
25
+ Do not add "helpful" error messages at build time for the opt-out
26
+ case — it would break silently-disabled packages.
27
+
28
+ ---
29
+
30
+ ## `@slats/claude-assets-sync` must be in `dependencies`
31
+
32
+ Not `devDependencies`, not `peerDependencies`. Reasons:
33
+
34
+ 1. Monorepo build chain needs `.bin/claude-build-hashes` resolved,
35
+ which requires the engine as a direct dep of each consumer.
36
+ 2. For end users on npm / yarn-classic, listing the engine in
37
+ `dependencies` makes `inject-claude-settings` transitively
38
+ hoisted into `node_modules/.bin/`, enabling the short
39
+ invocation `npx inject-claude-settings --package=<THIS>`.
40
+ 3. Bundle isolation is enforced by the import graph (`src/**`
41
+ never references the engine), not by dependency-type.
42
+
43
+ Pnpm strict users do not get the transitive hoist and must use the
44
+ universal form `npx -p @slats/claude-assets-sync inject-claude-settings
45
+ --package=<THIS>`. Every consumer's CLAUDE.md documents both paths.
46
+
47
+ ---
48
+
49
+ ## Never add `./bin/*` or `./docs/*` to `exports`
50
+
51
+ The `exports` map in `package.json` controls which subpaths a
52
+ consumer's bundler can resolve. Keeping `./docs/*` out of
53
+ `exports` is what prevents a bundler from deep-importing the docs
54
+ tree into app bundles.
55
+
56
+ ---
57
+
58
+ ## Do not commit `dist/claude-hashes.json`
59
+
60
+ It is a build artifact. The `yarn build` chain regenerates it via
61
+ `build:hashes`. It should be in `.gitignore` (usually via a
62
+ catch-all `dist/` rule). If you see it in `git status`, stop —
63
+ something is misconfigured.
64
+
65
+ ---
66
+
67
+ ## `yarn workspace ${PACKAGE_NAME} build` can fail with `rollup: command not found`
68
+
69
+ Yarn v4 workspace dispatch does not always propagate the
70
+ workspace-local PATH. Prefer `yarn ${SHORTCUT} build` from the
71
+ monorepo root, where `${SHORTCUT}` is the root-level script alias
72
+ (e.g. `yarn schemaForm`, `yarn claudeAssetsSync`).
73
+
74
+ If no shortcut exists, the full form may still work depending on
75
+ yarn version and cache state — but if it fails with `rollup:
76
+ command not found`, add a shortcut to the root `package.json`
77
+ rather than debugging the nested call.
78
+
79
+ ---
80
+
81
+ ## `--scope=project` walks upward
82
+
83
+ `--scope=project` walks `process.cwd()` upward looking for an
84
+ existing `.claude` directory. The first one found is reused; if
85
+ none is found, the engine creates one at `cwd`.
86
+
87
+ Consequence: running the smoke tests from the monorepo root would
88
+ reuse the monorepo's real `.claude`, corrupting it. Always run
89
+ smoke tests from `/tmp/...` with a fresh directory.
90
+
91
+ ---
92
+
93
+ ## Dispatcher exception to the `src/core` purity rule
94
+
95
+ `src/core/**` never reads `package.json` or walks the filesystem.
96
+ The engine's `bin/inject-claude-settings.mjs` and
97
+ `src/commands/runCli/utils/resolvePackage.ts` are allowed to
98
+ `createRequire().resolve(`${name}/package.json`)` for exactly one
99
+ target — the one named in `--package=<name>`. The dispatcher never
100
+ enumerates, never walks `node_modules` for siblings. Preserve this
101
+ boundary: extensions like `--all` or workspace scan require
102
+ explicit re-architecture.
103
+
104
+ ---
105
+
106
+ ## Commit this change alone
107
+
108
+ The change set from this skill touches the consumer's
109
+ `package.json` and possibly its `CLAUDE.md`. It should land in a
110
+ single commit, with no unrelated changes interleaved.
111
+
112
+ Reasons:
113
+
114
+ - Easier to revert as a unit if an issue appears downstream.
115
+ - The CI signal (smoke tests) is bound to the state of these files
116
+ and nothing else.
117
+ - Reviewers can skim-verify against the reference consumer without
118
+ reviewing business logic.
119
+
120
+ If the user asks to bundle with other work, push back once:
121
+ recommend a separate commit. If they still want it bundled,
122
+ proceed but note it in the Step 6 report.
@@ -0,0 +1,145 @@
1
+ # `package.json` Patches
2
+
3
+ All edits below are **additive**. Existing non-conflicting values
4
+ remain untouched. On any conflicting existing value, stop and ask the
5
+ user — do not overwrite.
6
+
7
+ Reference: `packages/canard/schema-form/package.json`.
8
+
9
+ ---
10
+
11
+ ## 1. `claude.assetPath`
12
+
13
+ ```json
14
+ "claude": {
15
+ "assetPath": "docs/claude"
16
+ }
17
+ ```
18
+
19
+ Consumer-side convention — the engine does not enforce it. Relative
20
+ to the consumer's package root. If the field already exists with a
21
+ non-default value, preserve it.
22
+
23
+ A missing or non-string value is an intentional opt-out: the
24
+ dispatcher will exit 2 with a clear error, and `claude-build-hashes`
25
+ will silently no-op. Do not remove the opt-out path.
26
+
27
+ ---
28
+
29
+ ## 2. `scripts.build`
30
+
31
+ Ensure the build chain invokes `yarn build:hashes` at the end:
32
+
33
+ ```json
34
+ "scripts": {
35
+ "build": "rollup -c && yarn build:types && yarn build:hashes"
36
+ }
37
+ ```
38
+
39
+ **Guard against double-append.** If the existing value already
40
+ contains `build:hashes`, leave it alone.
41
+
42
+ ---
43
+
44
+ ## 3. `scripts.build:hashes`
45
+
46
+ Point to the engine's bin (NOT a local stub):
47
+
48
+ ```json
49
+ "scripts": {
50
+ "build:hashes": "claude-build-hashes"
51
+ }
52
+ ```
53
+
54
+ `claude-build-hashes` reads `process.cwd()/package.json` and picks
55
+ up `claude.assetPath`. Works because `@slats/claude-assets-sync` is
56
+ in `dependencies`, so `node_modules/.bin/claude-build-hashes` is
57
+ linked.
58
+
59
+ If a different `build:hashes` script exists, ask.
60
+
61
+ ---
62
+
63
+ ## 4. `scripts.prepublishOnly`
64
+
65
+ ```json
66
+ "scripts": {
67
+ "prepublishOnly": "yarn build"
68
+ }
69
+ ```
70
+
71
+ Guarantees `dist/claude-hashes.json` is regenerated before publish.
72
+ If the target already has a `prepublishOnly` that calls `yarn build`
73
+ (directly or transitively), leave it alone.
74
+
75
+ ---
76
+
77
+ ## 5. `dependencies."@slats/claude-assets-sync"`
78
+
79
+ **Must be in `dependencies`, never `devDependencies` or
80
+ `peerDependencies`.**
81
+
82
+ ```json
83
+ "dependencies": {
84
+ "@slats/claude-assets-sync": "workspace:^"
85
+ }
86
+ ```
87
+
88
+ Reasons:
89
+
90
+ - Monorepo build chain needs `.bin/claude-build-hashes` resolved,
91
+ which requires the engine as a direct dep.
92
+ - On npm / yarn-classic, listing the engine in `dependencies` makes
93
+ `inject-claude-settings` transitively hoisted into
94
+ `node_modules/.bin/` for end users, enabling the short
95
+ invocation `npx inject-claude-settings --package=<THIS>`.
96
+ - Bundle isolation is enforced by the import graph (`src/**` never
97
+ references the engine), not by dependency-type.
98
+
99
+ If the target already has it in `devDependencies` or
100
+ `peerDependencies`, move it to `dependencies`. Do not duplicate.
101
+
102
+ ---
103
+
104
+ ## 6. `files`
105
+
106
+ Ship the published artifact surface. Keep `"dist"`, `"docs"`, and
107
+ `"README.md"` (plus whatever else the package needs). Do NOT
108
+ include `"bin"` or `"scripts"`:
109
+
110
+ ```json
111
+ "files": [
112
+ "dist",
113
+ "docs",
114
+ "README.md"
115
+ ]
116
+ ```
117
+
118
+ If `files` is absent, create it with at least `["dist", "docs", "README.md"]`.
119
+
120
+ ---
121
+
122
+ ## 7. `bin` — MUST be ABSENT
123
+
124
+ Never add a `bin` field. Bin names collide across consumers under
125
+ `node_modules/.bin/` and the engine is the sole CLI surface.
126
+
127
+ ---
128
+
129
+ ## 8. `exports` — never add `./bin/*` or `./docs/*`
130
+
131
+ Exports control which subpaths a consumer's bundler can resolve.
132
+ Keeping `./bin/*` and `./docs/*` out of `exports` is what prevents
133
+ consumer bundlers from pulling the CLI or the asset tree into app
134
+ bundles.
135
+
136
+ ---
137
+
138
+ ## Full Reference
139
+
140
+ See `packages/canard/schema-form/package.json` for the canonical
141
+ shape. The relevant keys are `scripts.build`,
142
+ `scripts.build:hashes`, `scripts.prepublishOnly`,
143
+ `dependencies."@slats/claude-assets-sync"`, `claude.assetPath`, and
144
+ `files`. Everything else in that file is schema-form-specific and
145
+ must not be copied.
@@ -0,0 +1,37 @@
1
+ # Reference Files
2
+
3
+ Consumers do **not** own any runtime files for the injector. The whole
4
+ CLI surface lives in `@slats/claude-assets-sync`. A consumer is wired
5
+ up by editing `package.json` and (optionally) `CLAUDE.md` — nothing
6
+ else.
7
+
8
+ Reference consumer: `packages/canard/schema-form`.
9
+
10
+ ## What the consumer MUST own
11
+
12
+ - `docs/claude/**` — the assets to ship (skills / rules / commands).
13
+ - `package.json.claude.assetPath` — string, usually `"docs/claude"`.
14
+
15
+ ## What the consumer MUST NOT own
16
+
17
+ - Any `bin/` directory or stub file. The engine owns the dispatcher.
18
+ - Any `scripts/build-hashes.mjs` wrapper. Use the engine's
19
+ `claude-build-hashes` bin directly in `scripts.build:hashes`.
20
+ - Any `"bin"` entry in `package.json`.
21
+ - `./bin/*` or `./docs/*` exposed in `exports`. Exposing them would
22
+ let bundlers pull CLI code or the docs tree into app bundles.
23
+
24
+ ## What the engine provides
25
+
26
+ - `inject-claude-settings` bin — dispatcher. Invoked as
27
+ `npx -p @slats/claude-assets-sync inject-claude-settings --package=<name> --scope=<scope>`,
28
+ or (on npm / yarn-classic) `npx inject-claude-settings --package=<name> --scope=<scope>`
29
+ once the engine is installed as a transitive dependency of the
30
+ consumer.
31
+ - `claude-build-hashes` bin — reads `process.cwd()/package.json`,
32
+ picks up `claude.assetPath`, hashes every file beneath it, and
33
+ writes `dist/claude-hashes.json`. Run via `yarn build:hashes` in
34
+ the consumer build chain.
35
+ - `buildHashes()` + `injectDocs()` — headless programmatic APIs.
36
+
37
+ No content mirroring across consumers. No stub drift to manage.