@slats/claude-assets-sync 0.1.3 → 0.2.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.
- package/README.md +111 -587
- package/bin/claude-sync.mjs +24 -0
- package/dist/@aileron/declare/index.d.ts +4 -4
- package/dist/claude-hashes.json +20 -0
- package/dist/commands/index.d.ts +1 -112
- package/dist/commands/runCli/index.d.ts +2 -0
- package/dist/commands/runCli/runCli.cjs +31 -0
- package/dist/commands/runCli/runCli.d.ts +10 -0
- package/dist/commands/runCli/runCli.mjs +29 -0
- package/dist/commands/runCli/type.d.ts +28 -0
- package/dist/commands/runCli/utils/injectOne.cjs +48 -0
- package/dist/commands/runCli/utils/injectOne.d.ts +3 -0
- package/dist/commands/runCli/utils/injectOne.mjs +46 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.cjs +28 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +2 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.mjs +26 -0
- package/dist/commands/runCli/utils/runInject.cjs +36 -0
- package/dist/commands/runCli/utils/runInject.d.ts +2 -0
- package/dist/commands/runCli/utils/runInject.mjs +34 -0
- package/dist/core/buildPlan/buildPlan.cjs +42 -0
- package/dist/core/buildPlan/buildPlan.d.ts +2 -0
- package/dist/core/buildPlan/buildPlan.mjs +40 -0
- package/dist/core/buildPlan/index.d.ts +2 -0
- package/dist/core/buildPlan/type.d.ts +32 -0
- package/dist/core/buildPlan/utils/toPosix.cjs +9 -0
- package/dist/core/buildPlan/utils/toPosix.d.ts +1 -0
- package/dist/core/buildPlan/utils/toPosix.mjs +7 -0
- package/dist/core/buildPlan/utils/walkFiles.cjs +25 -0
- package/dist/core/buildPlan/utils/walkFiles.d.ts +1 -0
- package/dist/core/buildPlan/utils/walkFiles.mjs +23 -0
- package/dist/core/hash/hash.cjs +30 -0
- package/dist/core/hash/hash.d.ts +4 -0
- package/dist/core/hash/hash.mjs +26 -0
- package/dist/core/hash/index.d.ts +1 -0
- package/dist/core/hashManifest/hashManifest.cjs +27 -0
- package/dist/core/hashManifest/hashManifest.d.ts +17 -0
- package/dist/core/hashManifest/hashManifest.mjs +23 -0
- package/dist/core/hashManifest/index.d.ts +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/injectDocs/index.d.ts +2 -0
- package/dist/core/injectDocs/injectDocs.cjs +43 -0
- package/dist/core/injectDocs/injectDocs.d.ts +2 -0
- package/dist/core/injectDocs/injectDocs.mjs +41 -0
- package/dist/core/injectDocs/type.d.ts +30 -0
- package/dist/core/injectDocs/utils/applyAction.cjs +21 -0
- package/dist/core/injectDocs/utils/applyAction.d.ts +2 -0
- package/dist/core/injectDocs/utils/applyAction.mjs +19 -0
- package/dist/core/injectDocs/utils/emitCiForceList.cjs +10 -0
- package/dist/core/injectDocs/utils/emitCiForceList.d.ts +2 -0
- package/dist/core/injectDocs/utils/emitCiForceList.mjs +8 -0
- package/dist/core/injectDocs/utils/printPlan.cjs +20 -0
- package/dist/core/injectDocs/utils/printPlan.d.ts +2 -0
- package/dist/core/injectDocs/utils/printPlan.mjs +18 -0
- package/dist/core/injectDocs/utils/summarize.cjs +27 -0
- package/dist/core/injectDocs/utils/summarize.d.ts +3 -0
- package/dist/core/injectDocs/utils/summarize.mjs +25 -0
- package/dist/core/scope/index.d.ts +1 -0
- package/dist/core/scope/scope.cjs +46 -0
- package/dist/core/scope/scope.d.ts +16 -0
- package/dist/core/scope/scope.mjs +41 -0
- package/dist/core/scope/utils/isDirectory.cjs +14 -0
- package/dist/core/scope/utils/isDirectory.d.ts +1 -0
- package/dist/core/scope/utils/isDirectory.mjs +12 -0
- package/dist/index.cjs +15 -9
- package/dist/index.d.ts +3 -5
- package/dist/index.mjs +7 -3
- package/dist/prompts/confirmForce.cjs +27 -0
- package/dist/prompts/confirmForce.d.ts +1 -0
- package/dist/prompts/confirmForce.mjs +25 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/selectScope.cjs +30 -0
- package/dist/prompts/selectScope.d.ts +2 -0
- package/dist/prompts/selectScope.mjs +28 -0
- package/dist/utils/heartbeat.cjs +25 -0
- package/dist/utils/heartbeat.d.ts +16 -0
- package/dist/utils/heartbeat.mjs +23 -0
- package/dist/utils/logger.cjs +7 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.mjs +7 -0
- package/dist/utils/types.d.ts +1 -252
- package/dist/utils/version.cjs +2 -14
- package/dist/utils/version.d.ts +3 -53
- package/dist/utils/version.mjs +2 -13
- package/docs/bundle-size-decision.md +36 -0
- package/docs/claude/skills/claude-sync-applier/SKILL.md +195 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/claude-md-template.md +77 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/dependency-cruiser.md +126 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/gotchas.md +139 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/package-json-patches.md +130 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/reference-files.md +120 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/smoke-tests.md +102 -0
- package/docs/consumer-integration.md +153 -0
- package/package.json +25 -17
- package/scripts/build-hashes.mjs +30 -0
- package/scripts/buildHashes.d.mts +15 -0
- package/scripts/buildHashes.mjs +82 -0
- package/scripts/claude-build-hashes.mjs +42 -0
- package/scripts/inject-version.js +112 -0
- package/dist/cli.cjs +0 -8
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -7
- package/dist/commands/add.cjs +0 -80
- package/dist/commands/add.d.ts +0 -8
- package/dist/commands/add.mjs +0 -78
- package/dist/commands/list.cjs +0 -94
- package/dist/commands/list.d.ts +0 -15
- package/dist/commands/list.mjs +0 -91
- package/dist/commands/migrate.cjs +0 -9
- package/dist/commands/migrate.d.ts +0 -6
- package/dist/commands/migrate.mjs +0 -7
- package/dist/commands/remove.cjs +0 -127
- package/dist/commands/remove.d.ts +0 -6
- package/dist/commands/remove.mjs +0 -105
- package/dist/commands/status.cjs +0 -193
- package/dist/commands/status.d.ts +0 -6
- package/dist/commands/status.mjs +0 -171
- package/dist/commands/sync.cjs +0 -28
- package/dist/commands/sync.d.ts +0 -6
- package/dist/commands/sync.mjs +0 -26
- package/dist/commands/types.d.ts +0 -89
- package/dist/commands/update.cjs +0 -209
- package/dist/commands/update.d.ts +0 -29
- package/dist/commands/update.mjs +0 -206
- package/dist/components/add/AddCommand.cjs +0 -103
- package/dist/components/add/AddCommand.d.ts +0 -14
- package/dist/components/add/AddCommand.mjs +0 -101
- package/dist/components/add/BulkAddView.cjs +0 -165
- package/dist/components/add/BulkAddView.d.ts +0 -11
- package/dist/components/add/BulkAddView.mjs +0 -163
- package/dist/components/add/index.d.ts +0 -2
- package/dist/components/index.d.ts +0 -2
- package/dist/components/list/EditableTreeItem.d.ts +0 -13
- package/dist/components/list/ListCommand.cjs +0 -651
- package/dist/components/list/ListCommand.d.ts +0 -5
- package/dist/components/list/ListCommand.mjs +0 -649
- package/dist/components/list/SyncedPackageTree.d.ts +0 -14
- package/dist/components/list/index.d.ts +0 -10
- package/dist/components/list/types.d.ts +0 -14
- package/dist/components/primitives/Box.d.ts +0 -4
- package/dist/components/primitives/Spinner.d.ts +0 -6
- package/dist/components/primitives/Text.d.ts +0 -4
- package/dist/components/primitives/index.d.ts +0 -3
- package/dist/components/remove/RemoveConfirm.cjs +0 -18
- package/dist/components/remove/RemoveConfirm.d.ts +0 -11
- package/dist/components/remove/RemoveConfirm.mjs +0 -16
- package/dist/components/shared/Confirm.cjs +0 -30
- package/dist/components/shared/Confirm.d.ts +0 -8
- package/dist/components/shared/Confirm.mjs +0 -28
- package/dist/components/shared/MenuItem.cjs +0 -18
- package/dist/components/shared/MenuItem.d.ts +0 -7
- package/dist/components/shared/MenuItem.mjs +0 -16
- package/dist/components/shared/ProgressBar.d.ts +0 -7
- package/dist/components/shared/StepRunner.cjs +0 -58
- package/dist/components/shared/StepRunner.d.ts +0 -15
- package/dist/components/shared/StepRunner.mjs +0 -56
- package/dist/components/shared/Table.cjs +0 -19
- package/dist/components/shared/Table.d.ts +0 -8
- package/dist/components/shared/Table.mjs +0 -17
- package/dist/components/shared/index.d.ts +0 -6
- package/dist/components/status/PackageStatusCard.d.ts +0 -10
- package/dist/components/status/StatusDisplay.cjs +0 -26
- package/dist/components/status/StatusDisplay.d.ts +0 -23
- package/dist/components/status/StatusDisplay.mjs +0 -24
- package/dist/components/status/StatusTreeNode.cjs +0 -40
- package/dist/components/status/StatusTreeNode.d.ts +0 -15
- package/dist/components/status/StatusTreeNode.mjs +0 -38
- package/dist/components/status/index.d.ts +0 -6
- package/dist/components/tree/AssetTreeNode.cjs +0 -54
- package/dist/components/tree/AssetTreeNode.d.ts +0 -12
- package/dist/components/tree/AssetTreeNode.mjs +0 -52
- package/dist/components/tree/TreeSelect.cjs +0 -129
- package/dist/components/tree/TreeSelect.d.ts +0 -12
- package/dist/components/tree/TreeSelect.mjs +0 -127
- package/dist/components/tree/index.d.ts +0 -4
- package/dist/core/assetStructure.cjs +0 -30
- package/dist/core/assetStructure.d.ts +0 -36
- package/dist/core/assetStructure.mjs +0 -27
- package/dist/core/cli.cjs +0 -106
- package/dist/core/cli.d.ts +0 -9
- package/dist/core/cli.mjs +0 -103
- package/dist/core/constants.cjs +0 -28
- package/dist/core/constants.d.ts +0 -94
- package/dist/core/constants.mjs +0 -21
- package/dist/core/filesystem.cjs +0 -98
- package/dist/core/filesystem.d.ts +0 -94
- package/dist/core/filesystem.mjs +0 -88
- package/dist/core/github.cjs +0 -115
- package/dist/core/github.d.ts +0 -61
- package/dist/core/github.mjs +0 -107
- package/dist/core/io.cjs +0 -46
- package/dist/core/io.d.ts +0 -40
- package/dist/core/io.mjs +0 -39
- package/dist/core/listOperations.cjs +0 -228
- package/dist/core/listOperations.d.ts +0 -43
- package/dist/core/listOperations.mjs +0 -205
- package/dist/core/localSource.cjs +0 -126
- package/dist/core/localSource.d.ts +0 -33
- package/dist/core/localSource.mjs +0 -120
- package/dist/core/migration.cjs +0 -201
- package/dist/core/migration.d.ts +0 -57
- package/dist/core/migration.mjs +0 -198
- package/dist/core/packageScanner.cjs +0 -360
- package/dist/core/packageScanner.d.ts +0 -22
- package/dist/core/packageScanner.mjs +0 -356
- package/dist/core/sync.cjs +0 -400
- package/dist/core/sync.d.ts +0 -21
- package/dist/core/sync.mjs +0 -397
- package/dist/core/syncMeta.cjs +0 -242
- package/dist/core/syncMeta.d.ts +0 -75
- package/dist/core/syncMeta.mjs +0 -229
- package/dist/utils/dependencies.cjs +0 -57
- package/dist/utils/dependencies.d.ts +0 -10
- package/dist/utils/dependencies.mjs +0 -34
- package/dist/utils/nameTransform.cjs +0 -13
- package/dist/utils/nameTransform.d.ts +0 -65
- package/dist/utils/nameTransform.mjs +0 -11
- package/dist/utils/package.cjs +0 -170
- package/dist/utils/package.d.ts +0 -105
- package/dist/utils/package.mjs +0 -157
- package/dist/utils/packageName.cjs +0 -24
- package/dist/utils/packageName.d.ts +0 -32
- package/dist/utils/packageName.mjs +0 -21
- package/dist/utils/paths.cjs +0 -18
- package/dist/utils/paths.d.ts +0 -55
- package/dist/utils/paths.mjs +0 -15
- package/dist/version.cjs +0 -5
- package/dist/version.d.ts +0 -5
- package/dist/version.mjs +0 -3
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claude-sync-applier
|
|
3
|
+
description: "Wire the claude-sync CLI onto a consumer package in this monorepo. Copies verbatim bin/claude-sync.mjs and scripts/build-hashes.mjs stubs, patches package.json, updates CLAUDE.md, runs E2E smoke tests, and verifies bundle isolation. Idempotent — asks before clobbering."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
argument-hint: <target-package-path>
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# claude-sync-applier
|
|
10
|
+
|
|
11
|
+
Replicate the `claude-sync` bin setup on a target consumer package. The engine
|
|
12
|
+
is `@slats/claude-assets-sync`; the reference consumer is `packages/canard/schema-form`.
|
|
13
|
+
|
|
14
|
+
The bin stub reads its own `package.json` via `import.meta.url` and hands the
|
|
15
|
+
engine `{ packageRoot, packageName, packageVersion, assetPath }`. Each invocation
|
|
16
|
+
targets exactly one consumer — it does not discover other packages.
|
|
17
|
+
|
|
18
|
+
**Outcome**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx <PACKAGE_NAME> claude-sync --scope=user|project [--dry-run] [--force] [--root=<cwd>]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Role
|
|
25
|
+
|
|
26
|
+
You are a monorepo wiring specialist. Execute the 10 steps below as a single,
|
|
27
|
+
idempotent procedure. On any conflicting existing value — ask the user before
|
|
28
|
+
overwriting. Never clobber silently.
|
|
29
|
+
|
|
30
|
+
## Knowledge Resources
|
|
31
|
+
|
|
32
|
+
Consult these files as needed during execution. Do NOT preload everything;
|
|
33
|
+
load on demand.
|
|
34
|
+
|
|
35
|
+
- `knowledge/reference-files.md` — source stubs (`bin/claude-sync.mjs`, `scripts/build-hashes.mjs`) with expected contents and rationale
|
|
36
|
+
- `knowledge/package-json-patches.md` — every required `package.json` edit, with guard conditions
|
|
37
|
+
- `knowledge/claude-md-template.md` — the `## Claude Docs Injector` section to inject into the target `CLAUDE.md`
|
|
38
|
+
- `knowledge/dependency-cruiser.md` — optional Step 4: three forbidden rules + config shape for static isolation
|
|
39
|
+
- `knowledge/smoke-tests.md` — E2E 6-path matrix with expected exit codes and why
|
|
40
|
+
- `knowledge/gotchas.md` — invariants, isolation guardrails, pitfalls
|
|
41
|
+
|
|
42
|
+
## Inputs
|
|
43
|
+
|
|
44
|
+
Resolve these before starting. If any is missing, stop and ask.
|
|
45
|
+
|
|
46
|
+
| Variable | Source |
|
|
47
|
+
|-------------------|------------------------------------------------------------------------------------------------------|
|
|
48
|
+
| `TARGET_PATH` | Skill argument (e.g. `packages/lerx/promise-modal`). If absent, ask the user. |
|
|
49
|
+
| `PACKAGE_NAME` | `name` field of `${TARGET_PATH}/package.json`. |
|
|
50
|
+
| `SHORTCUT` | Root `package.json` `scripts` entry whose value equals `yarn workspace ${PACKAGE_NAME}`; else unset. |
|
|
51
|
+
|
|
52
|
+
`SHORTCUT` is a convenience only. When unset, fall back to full workspace
|
|
53
|
+
syntax: `yarn workspace ${PACKAGE_NAME} <subcommand>`.
|
|
54
|
+
|
|
55
|
+
## Pre-Flight
|
|
56
|
+
|
|
57
|
+
Stop and report on any failure. Do not attempt to fix silently.
|
|
58
|
+
|
|
59
|
+
- [ ] `${TARGET_PATH}/docs/claude/skills/<name>/SKILL.md` and `knowledge/*.md` exist — the docs to be injected.
|
|
60
|
+
- [ ] `${TARGET_PATH}/package.json` has `"type": "module"` and `"sideEffects": false`.
|
|
61
|
+
- [ ] Build pipeline uses `rollup -c && yarn build:types` where `build:types` runs `node ../../aileron/script/build/buildTypes.mjs`.
|
|
62
|
+
- [ ] `git status` in `${TARGET_PATH}` is clean. Unrelated changes present → confirm with user before proceeding.
|
|
63
|
+
|
|
64
|
+
## Steps
|
|
65
|
+
|
|
66
|
+
Execute in order. Each step is idempotent; on conflict, ask rather than overwrite.
|
|
67
|
+
|
|
68
|
+
### Step 1 — Create `${TARGET_PATH}/bin/claude-sync.mjs`
|
|
69
|
+
|
|
70
|
+
Copy verbatim from the reference consumer. See `knowledge/reference-files.md`
|
|
71
|
+
for the expected content and the source path. `chmod +x` the result.
|
|
72
|
+
|
|
73
|
+
### Step 2 — Create `${TARGET_PATH}/scripts/build-hashes.mjs`
|
|
74
|
+
|
|
75
|
+
Copy verbatim. See `knowledge/reference-files.md`.
|
|
76
|
+
|
|
77
|
+
### Step 3 — Patch `${TARGET_PATH}/package.json`
|
|
78
|
+
|
|
79
|
+
See `knowledge/package-json-patches.md` for the complete patch list:
|
|
80
|
+
|
|
81
|
+
- `bin` entry
|
|
82
|
+
- `files` append
|
|
83
|
+
- `scripts.build` append (guarded)
|
|
84
|
+
- `scripts.build:hashes`
|
|
85
|
+
- `scripts.prepublishOnly`
|
|
86
|
+
- `dependencies."@slats/claude-assets-sync"` (NOT devDependencies)
|
|
87
|
+
- `claude.assetPath` default
|
|
88
|
+
|
|
89
|
+
Do NOT add `./bin/*` to `exports` — ever.
|
|
90
|
+
|
|
91
|
+
### Step 4 — (Optional) dependency-cruiser isolation gate
|
|
92
|
+
|
|
93
|
+
Skip unless `${TARGET_PATH}/.dependency-cruiser.cjs` already exists or the user
|
|
94
|
+
explicitly asks. Legacy `.dependency-cruiser.js` → out of scope; flag to user.
|
|
95
|
+
|
|
96
|
+
When applicable, see `knowledge/dependency-cruiser.md` for the three forbidden
|
|
97
|
+
rules, `no-orphans` adjustment, `includeOnly` expansion, and `depcheck` script.
|
|
98
|
+
|
|
99
|
+
### Step 5 — Patch `${TARGET_PATH}/CLAUDE.md`
|
|
100
|
+
|
|
101
|
+
If `CLAUDE.md` exists, append the `## Claude Docs Injector` section from
|
|
102
|
+
`knowledge/claude-md-template.md`, substituting `@canard/schema-form` →
|
|
103
|
+
`${PACKAGE_NAME}`. Keep the Isolation Guardrails subsection. Skip if
|
|
104
|
+
`CLAUDE.md` does not exist.
|
|
105
|
+
|
|
106
|
+
### Step 6 — Install and build
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
yarn install
|
|
110
|
+
yarn ${SHORTCUT:-workspace ${PACKAGE_NAME}} build
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Expected: `rollup` → `buildTypes` → `build:hashes` succeed, and
|
|
114
|
+
`${TARGET_PATH}/dist/claude-hashes.json` is written.
|
|
115
|
+
|
|
116
|
+
### Step 7 — E2E smoke tests (6 paths)
|
|
117
|
+
|
|
118
|
+
Run from `/tmp/...`, never from the monorepo root or `${TARGET_PATH}/` —
|
|
119
|
+
`--scope=project` walks cwd upward looking for an existing `.claude`, and would
|
|
120
|
+
mutate the real repo's. See `knowledge/smoke-tests.md` for the full 6-path
|
|
121
|
+
matrix, expected exit codes, and rationale.
|
|
122
|
+
|
|
123
|
+
Split into two bash calls (paths 1–3, then 4–6). cwd resets between calls; the
|
|
124
|
+
`[ -d ... ] && find -delete` prefix keeps it idempotent. Never use `rm -rf` or
|
|
125
|
+
unquoted `*` globs.
|
|
126
|
+
|
|
127
|
+
### Step 8 — Bundle isolation grep (must be empty)
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
grep -rE "@slats/claude-assets-sync|docs/claude|claude-sync" \
|
|
131
|
+
${TARGET_PATH}/dist/index.mjs ${TARGET_PATH}/dist/index.cjs
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Pass = exit code 1 (no matches). Any match → stop; CLI has leaked into the
|
|
135
|
+
library bundle. See `knowledge/gotchas.md` for the three-layer isolation model.
|
|
136
|
+
|
|
137
|
+
### Step 9 — depcheck (only if Step 4 ran)
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
yarn ${SHORTCUT:-workspace ${PACKAGE_NAME}} depcheck
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Zero errors. Pre-existing `no-orphans` warnings are acceptable.
|
|
144
|
+
|
|
145
|
+
### Step 10 — Report
|
|
146
|
+
|
|
147
|
+
Summarize:
|
|
148
|
+
|
|
149
|
+
- Files written vs. skipped (with reason for each skip)
|
|
150
|
+
- Manifest file count from `dist/claude-hashes.json`
|
|
151
|
+
- Smoke-test exit codes (all 6)
|
|
152
|
+
- Grep result (expected: no matches)
|
|
153
|
+
- depcheck result (or "static isolation not enforced" if Step 4 skipped)
|
|
154
|
+
- Recommendation: commit this change on its own, separate from other work
|
|
155
|
+
|
|
156
|
+
## Report Template
|
|
157
|
+
|
|
158
|
+
```markdown
|
|
159
|
+
## apply-claude-sync — ${PACKAGE_NAME}
|
|
160
|
+
|
|
161
|
+
**Files**
|
|
162
|
+
- bin/claude-sync.mjs — created | unchanged | asked-user
|
|
163
|
+
- scripts/build-hashes.mjs — created | unchanged | asked-user
|
|
164
|
+
- package.json — patched: [bin, files, scripts.build, …]
|
|
165
|
+
- CLAUDE.md — section added | skipped (no CLAUDE.md)
|
|
166
|
+
- .dependency-cruiser.cjs — updated | skipped (not present)
|
|
167
|
+
|
|
168
|
+
**Manifest**
|
|
169
|
+
- dist/claude-hashes.json: <N> files
|
|
170
|
+
|
|
171
|
+
**Smoke tests**
|
|
172
|
+
| # | command | expected | actual |
|
|
173
|
+
|---|-------------------------------------------------|----------|--------|
|
|
174
|
+
| 1 | --scope=project --dry-run | 0 | <n> |
|
|
175
|
+
| 2 | --scope=project | 0 | <n> |
|
|
176
|
+
| 3 | --scope=project (up-to-date) | 0 | <n> |
|
|
177
|
+
| 4 | CI=true --scope=project (tampered) | 2 | <n> |
|
|
178
|
+
| 5 | CI=true --scope=project --force | 0 | <n> |
|
|
179
|
+
| 6 | CI=true (missing --scope) | 2 | <n> |
|
|
180
|
+
|
|
181
|
+
**Isolation**
|
|
182
|
+
- grep on dist/index.{mjs,cjs}: no matches ✓
|
|
183
|
+
- depcheck: <result | "static isolation not enforced">
|
|
184
|
+
|
|
185
|
+
**Next**: commit on its own — do not bundle with unrelated changes.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Termination Conditions
|
|
189
|
+
|
|
190
|
+
- **Pre-Flight fails** → stop, report the failing check. Do not proceed.
|
|
191
|
+
- **Conflict during patch** → stop, show the diff, ask user whether to overwrite.
|
|
192
|
+
- **Build fails at Step 6** → stop, report error. Do not run smoke tests on a broken build.
|
|
193
|
+
- **Smoke test mismatch** → stop, report the failing path with captured exit code.
|
|
194
|
+
- **Bundle grep finds matches** → stop, report which file leaked. Isolation is broken.
|
|
195
|
+
- **All steps pass** → emit the report from the template above.
|
|
@@ -0,0 +1,77 @@
|
|
|
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 exists.
|
|
6
|
+
Substitute `@canard/schema-form` → `${PACKAGE_NAME}`. Skip the entire step if
|
|
7
|
+
`CLAUDE.md` does not exist (do not create one).
|
|
8
|
+
|
|
9
|
+
The template is intentionally terse: CLI usage + essential isolation warnings.
|
|
10
|
+
Architectural rationale (three-layer isolation model, silent no-op design,
|
|
11
|
+
stub mechanics) lives in this skill's `knowledge/gotchas.md` — do not
|
|
12
|
+
duplicate it into every consumer's `CLAUDE.md`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Template
|
|
17
|
+
|
|
18
|
+
````markdown
|
|
19
|
+
## Claude Docs Injector
|
|
20
|
+
|
|
21
|
+
Thin CLI stub that injects `docs/claude/` assets into the user's `.claude`
|
|
22
|
+
directory. Engine: `@slats/claude-assets-sync`.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx claude-sync --scope=user # ~/.claude
|
|
26
|
+
npx claude-sync --scope=project # nearest existing .claude walking up from cwd
|
|
27
|
+
npx claude-sync --scope=user --dry-run # preview
|
|
28
|
+
npx claude-sync --scope=user --force # overwrite local edits
|
|
29
|
+
|
|
30
|
+
npx -p @canard/schema-form claude-sync --scope=user # transitive-dep context
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Isolation Guardrails
|
|
34
|
+
|
|
35
|
+
- `src/**` MUST NOT import from `bin/**`, `docs/**`, or `@slats/claude-assets-sync`.
|
|
36
|
+
- **Never add `./bin/*` to `exports`.**
|
|
37
|
+
- `yarn depcheck` enforces the isolation in CI.
|
|
38
|
+
````
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Substitution Rules
|
|
43
|
+
|
|
44
|
+
- Replace `@canard/schema-form` with `${PACKAGE_NAME}` (one occurrence, in the
|
|
45
|
+
`npx -p` line).
|
|
46
|
+
- Preserve the Isolation Guardrails bullets verbatim — these are the sharp
|
|
47
|
+
invariants that must stay consistent across consumers.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Placement & Skip Conditions
|
|
52
|
+
|
|
53
|
+
- Append to end of `CLAUDE.md`. Ensure one blank line before the injected
|
|
54
|
+
section.
|
|
55
|
+
- `${TARGET_PATH}/CLAUDE.md` does not exist → skip, report "skipped (no CLAUDE.md)".
|
|
56
|
+
- Section already present with identical content → skip, report "unchanged".
|
|
57
|
+
- Section present with different content → ask user, do not clobber.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## What Was Deliberately Removed
|
|
62
|
+
|
|
63
|
+
If a previous version of this skill injected a longer template, these parts
|
|
64
|
+
were intentionally dropped:
|
|
65
|
+
|
|
66
|
+
- Intro paragraph explaining the stub mechanics — belongs in `gotchas.md`,
|
|
67
|
+
not per-package docs.
|
|
68
|
+
- `--scope=project` cwd-walk blockquote — the comment beside the command is
|
|
69
|
+
enough.
|
|
70
|
+
- Per-package structure list (`bin/`, `scripts/`, `docs/claude/`,
|
|
71
|
+
`claude.assetPath` convention) — mechanical, same across all consumers,
|
|
72
|
+
not useful as per-package documentation.
|
|
73
|
+
- Verbose Isolation Guardrails prose — reduced to three one-line rules.
|
|
74
|
+
|
|
75
|
+
The principle: per-package `CLAUDE.md` should carry only what an agent or
|
|
76
|
+
human needs **specific to this package**. Shared architecture belongs in the
|
|
77
|
+
skill's knowledge files.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Step 4 — dependency-cruiser isolation gate (optional)
|
|
2
|
+
|
|
3
|
+
This step is **only** executed when:
|
|
4
|
+
|
|
5
|
+
- `${TARGET_PATH}/.dependency-cruiser.cjs` already exists (static isolation
|
|
6
|
+
was previously enforced), OR
|
|
7
|
+
- The user explicitly asks for it.
|
|
8
|
+
|
|
9
|
+
Do **not** introduce a new `.dependency-cruiser.cjs` into a target package that
|
|
10
|
+
has not already opted into static analysis — the runtime isolation (import
|
|
11
|
+
graph + `sideEffects: false` + no `bin` in `exports`) is sufficient on its own.
|
|
12
|
+
|
|
13
|
+
**Legacy**: `.dependency-cruiser.js` (not `.cjs`) → out of scope. Flag to user
|
|
14
|
+
and do not rename.
|
|
15
|
+
|
|
16
|
+
Reference: `packages/canard/schema-form/.dependency-cruiser.cjs`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Changes to Apply
|
|
21
|
+
|
|
22
|
+
When applicable, mirror the reference config. Four edits total:
|
|
23
|
+
|
|
24
|
+
### 1. Append three `forbidden` rules
|
|
25
|
+
|
|
26
|
+
Append each with `severity: 'error'`:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
{
|
|
30
|
+
name: 'src-no-bin',
|
|
31
|
+
severity: 'error',
|
|
32
|
+
comment:
|
|
33
|
+
'src/ must not import from bin/. bin/ is a CLI-only entry point and must ' +
|
|
34
|
+
'never leak into the library bundle.',
|
|
35
|
+
from: { path: '^src/' },
|
|
36
|
+
to: { path: '^bin/' },
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'src-no-docs',
|
|
40
|
+
severity: 'error',
|
|
41
|
+
comment:
|
|
42
|
+
'src/ must not import from docs/. docs/claude/** contains pure markdown assets ' +
|
|
43
|
+
'meant only for the inject-docs CLI, not for the library runtime.',
|
|
44
|
+
from: { path: '^src/' },
|
|
45
|
+
to: { path: '^docs/' },
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'src-no-claude-assets-sync',
|
|
49
|
+
severity: 'error',
|
|
50
|
+
comment:
|
|
51
|
+
'@slats/claude-assets-sync is a CLI-only dependency. It is allowed only ' +
|
|
52
|
+
'from bin/. Importing it from src/ would leak the CLI engine into ' +
|
|
53
|
+
'consumer production bundles.',
|
|
54
|
+
from: { path: '^src/' },
|
|
55
|
+
to: { path: 'node_modules/@slats/claude-assets-sync' },
|
|
56
|
+
},
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Place these alongside the existing `forbidden` rules in the reference config.
|
|
60
|
+
Do not duplicate if any of these rule names already exist.
|
|
61
|
+
|
|
62
|
+
### 2. Extend `no-orphans` rule
|
|
63
|
+
|
|
64
|
+
Add `'^bin/'` to the existing `no-orphans` rule's `from.pathNot` array. `bin`
|
|
65
|
+
entry points are orphans by design (they're invoked as executables, not
|
|
66
|
+
imported).
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
from: {
|
|
70
|
+
orphan: true,
|
|
71
|
+
pathNot: [
|
|
72
|
+
'(^|/)[.][^/]+[.](?:js|cjs|mjs|ts|cts|mts|json)$',
|
|
73
|
+
'[.]d[.]ts$',
|
|
74
|
+
'(^|/)tsconfig[.]json$',
|
|
75
|
+
'(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$',
|
|
76
|
+
'^bin/',
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Expand `options.includeOnly`
|
|
82
|
+
|
|
83
|
+
Change to include both `src` and `bin` so dependency-cruiser scans the bin
|
|
84
|
+
entry points as well:
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
includeOnly: ['^src', '^bin'],
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 4. Add `depcheck` script
|
|
91
|
+
|
|
92
|
+
In `${TARGET_PATH}/package.json` `scripts`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
"depcheck": "depcruise src bin --config .dependency-cruiser.cjs --no-progress"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If an existing `depcheck` script points elsewhere, ask the user.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Post-Step Verification
|
|
103
|
+
|
|
104
|
+
After Steps 1–6 complete and this Step 4 has been applied, Step 9 runs:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
yarn ${SHORTCUT:-workspace ${PACKAGE_NAME}} depcheck
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Must exit 0 with no errors. Pre-existing `no-orphans` warnings are acceptable.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Why This Step Is Optional
|
|
115
|
+
|
|
116
|
+
The three-layer isolation works without static analysis:
|
|
117
|
+
|
|
118
|
+
1. Import graph: `src/**` never references `bin/**`, `docs/**`, or
|
|
119
|
+
`@slats/claude-assets-sync`.
|
|
120
|
+
2. `"sideEffects": false` + `"type": "module"` — dead-code elimination of any
|
|
121
|
+
accidental reference.
|
|
122
|
+
3. No `./bin/*` in `exports` — consumer bundlers cannot deep-import into bin.
|
|
123
|
+
|
|
124
|
+
dependency-cruiser adds a fourth layer (CI-time regression detection) but is
|
|
125
|
+
not required for correctness. Don't force-enable it on a package that hasn't
|
|
126
|
+
opted in — it carries real maintenance cost.
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
## Stubs are verbatim
|
|
9
|
+
|
|
10
|
+
The `bin/claude-sync.mjs` and `scripts/build-hashes.mjs` files are
|
|
11
|
+
**identical across all consumers** in this monorepo. No per-package
|
|
12
|
+
substitution. Runtime `import.meta.url` (in the bin) and `process.cwd()` (in
|
|
13
|
+
the build script) discover the package root; package metadata is parsed from
|
|
14
|
+
the adjacent `package.json`.
|
|
15
|
+
|
|
16
|
+
If you find yourself "adapting" the stub for a new consumer, stop — that's a
|
|
17
|
+
sign you misread the design. The engine is generic; the consumer-specific
|
|
18
|
+
convention is the `claude.assetPath` field inside `package.json`.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Silent no-op on missing `claude.assetPath`
|
|
23
|
+
|
|
24
|
+
Both stubs guard with `if (typeof pkg.claude?.assetPath === 'string')`.
|
|
25
|
+
|
|
26
|
+
- Missing field → exit 0, produce no output.
|
|
27
|
+
- Non-string value → exit 0, produce no output.
|
|
28
|
+
|
|
29
|
+
This is the intentional opt-out path: a package can ship the bin and script
|
|
30
|
+
but disable the feature by removing the config field. Do not add "helpful"
|
|
31
|
+
error messages for this case — it would break the opt-out.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## `@slats/claude-assets-sync` must be in `dependencies`
|
|
36
|
+
|
|
37
|
+
**Not** `devDependencies`, **not** `peerDependencies`.
|
|
38
|
+
|
|
39
|
+
Isolation from the library bundle is enforced by:
|
|
40
|
+
|
|
41
|
+
1. The import graph (`src/**` never references the engine), and
|
|
42
|
+
2. Optionally, dependency-cruiser static rules.
|
|
43
|
+
|
|
44
|
+
It is **not** enforced by dependency-type. Placing the engine in
|
|
45
|
+
`devDependencies` would break `npx <pkg> claude-sync` when a downstream
|
|
46
|
+
consumer installs the package — their `npm install` omits dev deps.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Never add `./bin/*` to `exports`
|
|
51
|
+
|
|
52
|
+
The `exports` map in `package.json` controls which subpaths a consumer's
|
|
53
|
+
bundler can resolve. Leaving `./bin/*` out of `exports` is what prevents a
|
|
54
|
+
bundler from deep-importing the CLI by accident.
|
|
55
|
+
|
|
56
|
+
Adding `./bin/claude-sync.mjs` to `exports` — even with `"default"` —
|
|
57
|
+
creates a path for a careless `import "@canard/schema-form/bin/claude-sync"`
|
|
58
|
+
to pull the CLI engine (and `@slats/claude-assets-sync`) into the library
|
|
59
|
+
consumer's production bundle. Three-layer isolation collapses to zero.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Do not commit `dist/claude-hashes.json`
|
|
64
|
+
|
|
65
|
+
It is a build artifact. The `yarn build` chain regenerates it via
|
|
66
|
+
`build:hashes`. It should be in `.gitignore` (usually via a catch-all `dist/`
|
|
67
|
+
rule). If you see it in `git status`, stop — something is misconfigured.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## `yarn workspace ${PACKAGE_NAME} build` can fail with `rollup: command not found`
|
|
72
|
+
|
|
73
|
+
Yarn v4 workspace dispatch does not always propagate the workspace-local
|
|
74
|
+
PATH. Prefer `yarn ${SHORTCUT} build` from the monorepo root, where
|
|
75
|
+
`${SHORTCUT}` is the root-level script alias (e.g. `yarn schemaForm`).
|
|
76
|
+
|
|
77
|
+
If no shortcut exists, the full form `yarn workspace ${PACKAGE_NAME} build`
|
|
78
|
+
may still work depending on yarn version and cache state — but if it fails
|
|
79
|
+
with `rollup: command not found`, add a shortcut to the root `package.json`
|
|
80
|
+
rather than debugging the nested call.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## `--scope=project` walks upward
|
|
85
|
+
|
|
86
|
+
`--scope=project` walks `process.cwd()` upward looking for an existing
|
|
87
|
+
`.claude` directory. The first one found is reused; if none is found, the
|
|
88
|
+
engine creates one at `cwd`.
|
|
89
|
+
|
|
90
|
+
Consequence: running the smoke tests from the monorepo root would reuse the
|
|
91
|
+
monorepo's real `.claude`, corrupting it. Always run smoke tests from
|
|
92
|
+
`/tmp/...` with a fresh directory.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Bin paths are orphans on purpose
|
|
97
|
+
|
|
98
|
+
`bin/claude-sync.mjs` is an executable entry point. It is never imported from
|
|
99
|
+
`src/`. That makes it an orphan in dependency-cruiser's eyes.
|
|
100
|
+
|
|
101
|
+
Step 4 explicitly excludes `^bin/` from the `no-orphans` rule to silence this
|
|
102
|
+
warning. If you add new bin entry points, extend the `pathNot` pattern — do
|
|
103
|
+
not disable the rule wholesale.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Three-layer isolation — why
|
|
108
|
+
|
|
109
|
+
1. **Import graph** — `src/**` never references `bin/**`, `docs/**`, or
|
|
110
|
+
`@slats/claude-assets-sync`. Primary defense.
|
|
111
|
+
2. **`sideEffects: false`** — allows the bundler to tree-shake any accidental
|
|
112
|
+
reference.
|
|
113
|
+
3. **No `./bin/*` in `exports`** — consumer bundlers cannot reach the bin
|
|
114
|
+
through subpath imports.
|
|
115
|
+
4. **(Optional) dependency-cruiser** — CI-time regression check that layer 1
|
|
116
|
+
stays intact.
|
|
117
|
+
|
|
118
|
+
Step 8 (`grep` on `dist/index.{mjs,cjs}`) is the post-build verification that
|
|
119
|
+
all three primary layers held. Any match → one of them is broken.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Commit this change alone
|
|
124
|
+
|
|
125
|
+
The change set from this skill touches `bin/`, `scripts/`, `package.json`,
|
|
126
|
+
and possibly `CLAUDE.md` + `.dependency-cruiser.cjs`. It should land in a
|
|
127
|
+
single commit, with no unrelated changes interleaved.
|
|
128
|
+
|
|
129
|
+
Reasons:
|
|
130
|
+
|
|
131
|
+
- Easier to revert as a unit if an issue appears downstream.
|
|
132
|
+
- The CI signal (smoke tests, bundle grep) is bound to the state of these
|
|
133
|
+
files and nothing else.
|
|
134
|
+
- The change is almost entirely mechanical — reviewers can skim-verify
|
|
135
|
+
against the reference consumer without reviewing business logic.
|
|
136
|
+
|
|
137
|
+
If the user asks to bundle with other work, push back once: recommend a
|
|
138
|
+
separate commit. If they still want it bundled, proceed but note it in the
|
|
139
|
+
Step 10 report.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# `package.json` Patches
|
|
2
|
+
|
|
3
|
+
All edits below are **additive**. Existing non-conflicting values remain
|
|
4
|
+
untouched. On any conflicting existing value, stop and ask the user — do not
|
|
5
|
+
overwrite.
|
|
6
|
+
|
|
7
|
+
Reference: `packages/canard/schema-form/package.json`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. `bin`
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
"bin": {
|
|
15
|
+
"claude-sync": "./bin/claude-sync.mjs"
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If `bin` already exists with other entries, merge in the `claude-sync` key;
|
|
20
|
+
preserve siblings. If `bin.claude-sync` already points elsewhere, ask.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. `files`
|
|
25
|
+
|
|
26
|
+
Append `"bin"` to the `files` array if not already present. Order within the
|
|
27
|
+
array is not load-bearing, but to match the reference:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"docs",
|
|
33
|
+
"bin",
|
|
34
|
+
"README.md"
|
|
35
|
+
]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If `files` is absent, create it with at least `["dist", "bin"]`, preserving
|
|
39
|
+
any conventions already present in sibling packages.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 3. `scripts.build`
|
|
44
|
+
|
|
45
|
+
Append ` && yarn build:hashes` to whatever the package currently has.
|
|
46
|
+
|
|
47
|
+
**Guard against double-append.** If the existing value already ends with
|
|
48
|
+
`yarn build:hashes` or already contains `build:hashes`, leave it alone.
|
|
49
|
+
|
|
50
|
+
Reference value:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
"build": "rollup -c && yarn build:types && yarn build:hashes"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 4. `scripts.build:hashes`
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
"build:hashes": "node scripts/build-hashes.mjs"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If a different `build:hashes` script exists, ask.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 5. `scripts.prepublishOnly`
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
"prepublishOnly": "yarn build"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If the target already has a `prepublishOnly` that calls `yarn build`
|
|
75
|
+
(directly or transitively), leave it alone.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 6. `dependencies."@slats/claude-assets-sync"`
|
|
80
|
+
|
|
81
|
+
**Must be in `dependencies`, never `devDependencies`.**
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"@slats/claude-assets-sync": "workspace:^"
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Rationale: isolation from the library bundle is enforced by the import graph
|
|
90
|
+
(and optionally by dependency-cruiser), not by dependency-type. Placing it in
|
|
91
|
+
`devDependencies` would make `npm install` on a published package fail when a
|
|
92
|
+
consumer runs `npx <pkg> claude-sync`.
|
|
93
|
+
|
|
94
|
+
If the target already has it in `devDependencies`, move it. Do not duplicate.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 7. `claude.assetPath`
|
|
99
|
+
|
|
100
|
+
Default value (used when the field is absent):
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
"claude": {
|
|
104
|
+
"assetPath": "docs/claude"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**If `claude.assetPath` already exists with a non-default value, preserve it.**
|
|
109
|
+
The convention lives in the consumer, not the library.
|
|
110
|
+
|
|
111
|
+
The bin stub guards on `typeof pkg.claude?.assetPath === 'string'` — a missing
|
|
112
|
+
or non-string value is a silent no-op. That is the intentional opt-out path.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Must-NOT
|
|
117
|
+
|
|
118
|
+
- **Never** add `./bin/*` (or any bin path) to the `exports` field. Leaving bin
|
|
119
|
+
subpaths unexported is what prevents a consumer bundler from accidentally
|
|
120
|
+
reaching into the CLI assets via deep imports.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Full Reference
|
|
125
|
+
|
|
126
|
+
See `packages/canard/schema-form/package.json` for the canonical shape. The
|
|
127
|
+
relevant keys are `bin`, `files`, `scripts.build`, `scripts.build:hashes`,
|
|
128
|
+
`scripts.prepublishOnly`, `dependencies."@slats/claude-assets-sync"`, and
|
|
129
|
+
`claude.assetPath`. Everything else in that file is schema-form-specific and
|
|
130
|
+
must not be copied.
|