@thebassclef/lite 1.0.4 → 1.1.1

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 (275) hide show
  1. package/dist/cli.cjs +298 -55
  2. package/dist/cli.js +298 -55
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/lite/.claude/agents/architect.md +70 -0
  7. package/dist/lite/.claude/agents/builder.md +114 -0
  8. package/dist/lite/.claude/agents/designer.md +156 -0
  9. package/dist/lite/.claude/agents/reviewer.md +88 -0
  10. package/dist/lite/.claude/hooks/bassclef-sync.sh +85 -27
  11. package/dist/lite/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
  12. package/dist/lite/.claude/hooks/longrun-prep-render-check.sh +236 -0
  13. package/dist/lite/.claude/hooks/persona-name-scrub-check.sh +105 -0
  14. package/dist/lite/.claude/hooks/skill-step-list-check.sh +171 -0
  15. package/dist/lite/.claude/luminaries/alan-cooper.md +170 -0
  16. package/dist/lite/.claude/luminaries/alistair-cockburn.md +140 -0
  17. package/dist/lite/.claude/luminaries/amazon-pr-faq.md +34 -0
  18. package/dist/lite/.claude/luminaries/andreas-zeller.md +74 -0
  19. package/dist/lite/.claude/luminaries/ash-maurya.md +121 -0
  20. package/dist/lite/.claude/luminaries/bill-buxton.md +210 -0
  21. package/dist/lite/.claude/luminaries/charles-sanders-peirce.md +150 -0
  22. package/dist/lite/.claude/luminaries/david-ogilvy.md +192 -0
  23. package/dist/lite/.claude/luminaries/don-norman.md +173 -0
  24. package/dist/lite/.claude/luminaries/edward-tufte.md +179 -0
  25. package/dist/lite/.claude/luminaries/eric-evans.md +160 -0
  26. package/dist/lite/.claude/luminaries/frederick-brooks.md +50 -0
  27. package/dist/lite/.claude/luminaries/gang-of-four.md +157 -0
  28. package/dist/lite/.claude/luminaries/glenford-myers.md +230 -0
  29. package/dist/lite/.claude/luminaries/hunt-thomas.md +115 -0
  30. package/dist/lite/.claude/luminaries/hyrum-wright.md +94 -0
  31. package/dist/lite/.claude/luminaries/jason-fried-dhh.md +46 -0
  32. package/dist/lite/.claude/luminaries/jesse-james-garrett.md +154 -0
  33. package/dist/lite/.claude/luminaries/john-ousterhout.md +94 -0
  34. package/dist/lite/.claude/luminaries/karl-popper.md +132 -0
  35. package/dist/lite/.claude/luminaries/kent-beck.md +168 -0
  36. package/dist/lite/.claude/luminaries/linus-torvalds.md +218 -0
  37. package/dist/lite/.claude/luminaries/martin-fowler.md +164 -0
  38. package/dist/lite/.claude/luminaries/michael-feathers.md +125 -0
  39. package/dist/lite/.claude/luminaries/michael-nygard.md +118 -0
  40. package/dist/lite/.claude/luminaries/robert-c-martin.md +164 -0
  41. package/dist/lite/.claude/luminaries/saltzer-schroeder.md +194 -0
  42. package/dist/lite/.claude/luminaries/sophia-prater.md +193 -0
  43. package/dist/lite/.claude/luminaries/stephen-toulmin.md +131 -0
  44. package/dist/lite/.claude/luminaries/tony-hoare.md +170 -0
  45. package/dist/lite/.claude/luminaries/vaughn-vernon.md +50 -0
  46. package/dist/lite/.claude/luminaries/w-edwards-deming.md +158 -0
  47. package/dist/lite/.claude/rules/accessor-library-discipline.md +110 -0
  48. package/dist/lite/.claude/rules/adr-discipline.md +96 -0
  49. package/dist/lite/.claude/rules/api-conventions.md +115 -0
  50. package/dist/lite/.claude/rules/artifact-ingestion.md +137 -0
  51. package/dist/lite/.claude/rules/assert-only-after-verify.md +111 -0
  52. package/dist/lite/.claude/rules/blocked-items.md +139 -0
  53. package/dist/lite/.claude/rules/bootstrap-pair-discipline.md +106 -0
  54. package/dist/lite/.claude/rules/branching.md +28 -0
  55. package/dist/lite/.claude/rules/cold-adopter-harness-discipline.md +93 -0
  56. package/dist/lite/.claude/rules/commit-conventions.md +22 -0
  57. package/dist/lite/.claude/rules/compounding-axis-fresh-analysis.md +173 -0
  58. package/dist/lite/.claude/rules/compounding-sequence-fresh-analysis.md +173 -0
  59. package/dist/lite/.claude/rules/context-engineering.md +155 -0
  60. package/dist/lite/.claude/rules/context-management.md +85 -0
  61. package/dist/lite/.claude/rules/defensive-bash.md +52 -0
  62. package/dist/lite/.claude/rules/deferred-actions.md +233 -0
  63. package/dist/lite/.claude/rules/destructive-operations.md +69 -0
  64. package/dist/lite/.claude/rules/diagnosis.md +38 -0
  65. package/dist/lite/.claude/rules/github-issue-flash-tweet.md +114 -0
  66. package/dist/lite/.claude/rules/guardrails.md +73 -0
  67. package/dist/lite/.claude/rules/hook-wire-on-author.md +77 -0
  68. package/dist/lite/.claude/rules/identifier-leak-prevention.md +73 -0
  69. package/dist/lite/.claude/rules/iteration-bet-brief-completeness.md +43 -0
  70. package/dist/lite/.claude/rules/lite-manifest-schema-change-discipline.md +79 -0
  71. package/dist/lite/.claude/rules/longrun-prep-plan-doc-compression.md +77 -0
  72. package/dist/lite/.claude/rules/loop-discipline.md +71 -0
  73. package/dist/lite/.claude/rules/manual-prod-approval.md +100 -0
  74. package/dist/lite/.claude/rules/marker-enrichment-discipline.md +72 -0
  75. package/dist/lite/.claude/rules/mobile-ephemeral-session.md +109 -0
  76. package/dist/lite/.claude/rules/new-dependency-check.md +44 -0
  77. package/dist/lite/.claude/rules/oo-ad-entry-point.md +95 -0
  78. package/dist/lite/.claude/rules/operator-facing-prose.md +177 -0
  79. package/dist/lite/.claude/rules/option-label-discipline.md +82 -0
  80. package/dist/lite/.claude/rules/pattern-annotation.md +83 -0
  81. package/dist/lite/.claude/rules/persona-name-leak-scrub.md +90 -0
  82. package/dist/lite/.claude/rules/plain-english-discipline.md +132 -0
  83. package/dist/lite/.claude/rules/plan-enumeration-needs-value-props.md +177 -0
  84. package/dist/lite/.claude/rules/pr-body-shape.md +195 -0
  85. package/dist/lite/.claude/rules/pr-strategy.md +142 -0
  86. package/dist/lite/.claude/rules/pr-title-shape.md +90 -0
  87. package/dist/lite/.claude/rules/prototype-workflow.md +53 -0
  88. package/dist/lite/.claude/rules/reserved-skill-names.md +103 -0
  89. package/dist/lite/.claude/rules/schema-management.md +42 -0
  90. package/dist/lite/.claude/rules/sdlc-gates.md +149 -0
  91. package/dist/lite/.claude/rules/security.md +37 -0
  92. package/dist/lite/.claude/rules/session-artifacts.md +236 -0
  93. package/dist/lite/.claude/rules/skill-composition-declarations.md +105 -0
  94. package/dist/lite/.claude/rules/skill-description-clarity.md +196 -0
  95. package/dist/lite/.claude/rules/skill-procedure-step-list.md +119 -0
  96. package/dist/lite/.claude/rules/sprint-prep-preset-picker.md +76 -0
  97. package/dist/lite/.claude/rules/state-schema-validation.md +156 -0
  98. package/dist/lite/.claude/rules/stuck-signal-diagnostic.md +111 -0
  99. package/dist/lite/.claude/rules/substrate-config-schema.md +85 -0
  100. package/dist/lite/.claude/rules/test-list-discipline.md +129 -0
  101. package/dist/lite/.claude/rules/test-sufficiency.md +186 -0
  102. package/dist/lite/.claude/rules/testing-tier-config.md +125 -0
  103. package/dist/lite/.claude/rules/testing.md +38 -0
  104. package/dist/lite/.claude/rules/turn-estimate-grounding.md +82 -0
  105. package/dist/lite/.claude/rules/visual-hierarchy.md +427 -0
  106. package/dist/lite/.claude/rules/we-dont-break-adopters.md +103 -0
  107. package/dist/lite/.claude/rules/whereami-load-bearing.md +184 -0
  108. package/dist/lite/.claude/rules/writing-craft-discipline.md +72 -0
  109. package/dist/lite/.claude/rules/wu-sequencing-compounds.md +119 -0
  110. package/dist/lite/.claude/skills/build/SKILL.md +640 -0
  111. package/dist/lite/.claude/skills/chronicle/SKILL.md +55 -0
  112. package/dist/lite/.claude/skills/clean-artifacts/SKILL.md +249 -0
  113. package/dist/lite/.claude/skills/decompose/SKILL.md +280 -0
  114. package/dist/lite/.claude/skills/diagnose/SKILL.md +297 -0
  115. package/dist/lite/.claude/skills/feynman/SKILL.md +90 -0
  116. package/dist/lite/.claude/skills/howdoi/SKILL.md +105 -0
  117. package/dist/lite/.claude/skills/ia-model/SKILL.md +108 -0
  118. package/dist/lite/.claude/skills/interaction-design/SKILL.md +112 -0
  119. package/dist/lite/.claude/skills/interpret-input/SKILL.md +180 -0
  120. package/dist/lite/.claude/skills/journal/SKILL.md +209 -0
  121. package/dist/lite/.claude/skills/kiss/SKILL.md +449 -0
  122. package/dist/lite/.claude/skills/launch/SKILL.md +915 -0
  123. package/dist/lite/.claude/skills/lean-canvas/SKILL.md +332 -0
  124. package/dist/lite/.claude/skills/longrun/SKILL.md +512 -0
  125. package/dist/lite/.claude/skills/luminary/SKILL.md +481 -0
  126. package/dist/lite/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
  127. package/dist/lite/.claude/skills/onboard-repo/SKILL.md +1640 -0
  128. package/dist/lite/.claude/skills/pattern-review/SKILL.md +99 -0
  129. package/dist/lite/.claude/skills/personas/SKILL.md +207 -0
  130. package/dist/lite/.claude/skills/promote/SKILL.md +283 -0
  131. package/dist/lite/.claude/skills/requirement/SKILL.md +98 -0
  132. package/dist/lite/.claude/skills/retro/SKILL.md +117 -0
  133. package/dist/lite/.claude/skills/riff/SKILL.md +114 -0
  134. package/dist/lite/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
  135. package/dist/lite/.claude/skills/session-end/SKILL.md +309 -0
  136. package/dist/lite/.claude/skills/session-log/SKILL.md +299 -0
  137. package/dist/lite/.claude/skills/skills/SKILL.md +228 -0
  138. package/dist/lite/.claude/skills/spec/SKILL.md +105 -0
  139. package/dist/lite/.claude/skills/sprint/SKILL.md +418 -0
  140. package/dist/lite/.claude/skills/stage/SKILL.md +384 -0
  141. package/dist/lite/.claude/skills/state-a-problem/SKILL.md +185 -0
  142. package/dist/lite/.claude/skills/temperance/SKILL.md +108 -0
  143. package/dist/lite/.claude/skills/use-case/SKILL.md +417 -0
  144. package/dist/lite/.claude/skills/user-stories/SKILL.md +268 -0
  145. package/dist/lite/.claude/skills/value-prop/SKILL.md +251 -0
  146. package/dist/lite/.claude/skills/verify/SKILL.md +160 -0
  147. package/dist/lite/.claude/skills/visual-review/SKILL.md +503 -0
  148. package/dist/lite/.claude/skills/whats-the-plan/SKILL.md +202 -0
  149. package/dist/lite/.claude/skills/whereami/SKILL.md +307 -0
  150. package/dist/lite/AGENTS.md +79 -0
  151. package/dist/lite/CLAUDE-lite.md +85 -0
  152. package/dist/lite/CODE_OF_CONDUCT.md +28 -0
  153. package/dist/lite/CONTRIBUTING.md +177 -0
  154. package/dist/lite/README.md +173 -0
  155. package/dist/lite/SECURITY.md +19 -0
  156. package/dist/lite/architecture/decisions/ADR-029-release-pipeline.md +79 -0
  157. package/dist/lite/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
  158. package/dist/lite/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
  159. package/dist/lite/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
  160. package/dist/lite/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
  161. package/dist/lite/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
  162. package/dist/lite/lib/clean-artifacts-sweep.sh +112 -0
  163. package/dist/lite/lib/code-comment-discipline.sh +144 -0
  164. package/dist/lite/lib/composer-preflight.sh +459 -0
  165. package/dist/lite/lib/deferred-actions.sh +146 -0
  166. package/dist/lite/lib/hook-header-parser.sh +61 -0
  167. package/dist/lite/lib/hook-heartbeat.sh +152 -0
  168. package/dist/lite/lib/hook-inject.sh +255 -0
  169. package/dist/lite/lib/hook-installer.sh +195 -0
  170. package/dist/lite/lib/luminary-pick.sh +96 -0
  171. package/dist/lite/lib/output-discipline.sh +143 -0
  172. package/dist/lite/lib/prose-scan-boundary.sh +171 -0
  173. package/dist/lite/lib/rewrite-check.sh +214 -0
  174. package/dist/lite/lib/session-rescue.sh +151 -0
  175. package/dist/lite/lib/source-graph-walker.sh +277 -0
  176. package/dist/lite/lib/state.sh +1372 -0
  177. package/dist/lite/lib/telemetry.sh +205 -0
  178. package/dist/lite/lib/tier-check.sh +187 -0
  179. package/dist/lite/lib/tier-dependency-audit.sh +1088 -0
  180. package/dist/lite/presence/install/bassclef-hook-connect.sh +178 -0
  181. package/dist/lite/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
  182. package/dist/lite/presence/install/bassclef-sync.template.sh +2278 -0
  183. package/dist/lite/presence/install/schedule-auto-save.cron.sh +88 -0
  184. package/dist/lite/presence/install/schedule-auto-save.taskscheduler.md +122 -0
  185. package/dist/lite/scripts/aggregate-telemetry.sh +217 -0
  186. package/dist/lite/scripts/analyze-tier-dependencies.sh +239 -0
  187. package/dist/lite/scripts/generate-lite-manifest.sh +505 -0
  188. package/dist/lite/scripts/generate-tier-manifest.sh +28 -0
  189. package/dist/lite/scripts/intent-drift-check.sh +456 -0
  190. package/dist/lite/scripts/lite-manifest-drift-check.sh +146 -0
  191. package/dist/lite/scripts/render-lite-manifest-doc.sh +150 -0
  192. package/dist/lite/standards/adr-template.md +86 -0
  193. package/dist/lite/standards/api-conventions/nextjs.md +84 -0
  194. package/dist/lite/standards/artifact-composition.md +209 -0
  195. package/dist/lite/standards/bash-hook-safety.md +246 -0
  196. package/dist/lite/standards/bassclef-configs-schema.md +232 -0
  197. package/dist/lite/standards/bassclef-evolution.md +143 -0
  198. package/dist/lite/standards/bassclef-internal-jargon.md +244 -0
  199. package/dist/lite/standards/bassclef-managed-sentinel.md +96 -0
  200. package/dist/lite/standards/bassclef-source-config.md +228 -0
  201. package/dist/lite/standards/branch-stacking.md +408 -0
  202. package/dist/lite/standards/code-safety-principles.md +176 -0
  203. package/dist/lite/standards/composer-prerequisites.md +155 -0
  204. package/dist/lite/standards/deferred-actions-schema.md +204 -0
  205. package/dist/lite/standards/dependency-discipline/cargo.md +39 -0
  206. package/dist/lite/standards/dependency-discipline/gem.md +43 -0
  207. package/dist/lite/standards/dependency-discipline/go-mod.md +41 -0
  208. package/dist/lite/standards/dependency-discipline/npm.md +42 -0
  209. package/dist/lite/standards/dependency-discipline/pip.md +42 -0
  210. package/dist/lite/standards/deployment-topology/ec2-tailscale.md +225 -0
  211. package/dist/lite/standards/deployment-topology.md +69 -0
  212. package/dist/lite/standards/docs-sync-allowlist.md +76 -0
  213. package/dist/lite/standards/domain-and-dns.md +145 -0
  214. package/dist/lite/standards/frontend-stack.md +67 -0
  215. package/dist/lite/standards/frontmatter-schema.md +154 -0
  216. package/dist/lite/standards/graceful-exit.md +227 -0
  217. package/dist/lite/standards/hook-idempotency.md +102 -0
  218. package/dist/lite/standards/hook-injection-discipline.md +202 -0
  219. package/dist/lite/standards/hook-install-class.md +215 -0
  220. package/dist/lite/standards/input-handler-interface.md +152 -0
  221. package/dist/lite/standards/lite-manifest-schema-changes.md +180 -0
  222. package/dist/lite/standards/lite-manifest.json +2797 -0
  223. package/dist/lite/standards/luminary-matching.md +105 -0
  224. package/dist/lite/standards/luminary-problem-patterns.md +481 -0
  225. package/dist/lite/standards/migration-discipline/active-record.md +50 -0
  226. package/dist/lite/standards/migration-discipline/alembic.md +43 -0
  227. package/dist/lite/standards/migration-discipline/gorm.md +50 -0
  228. package/dist/lite/standards/migration-discipline/prisma.md +53 -0
  229. package/dist/lite/standards/migration-discipline/sqlalchemy.md +51 -0
  230. package/dist/lite/standards/mobile-ephemeral-session.md +167 -0
  231. package/dist/lite/standards/model-routing-discipline.md +160 -0
  232. package/dist/lite/standards/ogilvy-writing-rules.md +225 -0
  233. package/dist/lite/standards/opener-discipline.md +96 -0
  234. package/dist/lite/standards/operator-facing-prose-discipline.md +201 -0
  235. package/dist/lite/standards/persona-schema.md +229 -0
  236. package/dist/lite/standards/pluggable-luminaries.md +323 -0
  237. package/dist/lite/standards/pr-body-discipline.md +115 -0
  238. package/dist/lite/standards/preview-state-schema.md +189 -0
  239. package/dist/lite/standards/project-directory-layout.md +276 -0
  240. package/dist/lite/standards/release-tagging.md +137 -0
  241. package/dist/lite/standards/reserved-skill-names.md +120 -0
  242. package/dist/lite/standards/scannable-multi-option-output.md +265 -0
  243. package/dist/lite/standards/sdlc-compliance.md +286 -0
  244. package/dist/lite/standards/sdlc-gates/typescript.md +57 -0
  245. package/dist/lite/standards/secrets-lifecycle.md +210 -0
  246. package/dist/lite/standards/security-scanner-adapter.md +145 -0
  247. package/dist/lite/standards/session-board.md +256 -0
  248. package/dist/lite/standards/skill-output-discipline.md +121 -0
  249. package/dist/lite/standards/state-spine-contract.md +255 -0
  250. package/dist/lite/standards/state-spine.md +511 -0
  251. package/dist/lite/standards/steering-hints/kiss-words.md +11 -0
  252. package/dist/lite/standards/substrate-config-schema.md +267 -0
  253. package/dist/lite/standards/tech-stack-config.md +109 -0
  254. package/dist/lite/standards/tier-dependency-analysis.md +167 -0
  255. package/dist/lite/standards/tier-runtime-deps/lite.md +57 -0
  256. package/dist/lite/standards/tier-tag-schema.md +155 -0
  257. package/dist/lite/standards/two-layer-config.md +99 -0
  258. package/dist/lite/standards/use-case-format.md +292 -0
  259. package/dist/lite/standards/user-story-invest.md +268 -0
  260. package/dist/lite/standards/velocity-and-appetite.md +229 -0
  261. package/dist/lite/standards/voice-input-pattern.md +119 -0
  262. package/dist/lite/standards/whereami-schema.md +301 -0
  263. package/dist/lite/standards/worktree-management.md +211 -0
  264. package/dist/lite/standards/writing-guide.md +213 -0
  265. package/dist/lite/templates/chronicle-template.md +75 -0
  266. package/dist/lite/templates/deferred-action-template.md +45 -0
  267. package/dist/lite/templates/memory-proposal-template.md +77 -0
  268. package/dist/lite/templates/persona-template.md +200 -0
  269. package/dist/lite/templates/pr-faq.md +45 -0
  270. package/dist/lite/templates/secret-rotation-template.md +162 -0
  271. package/dist/lite/templates/spec-template.md +131 -0
  272. package/dist/lite/templates/use-case-template.md +194 -0
  273. package/dist/lite/templates/user-story-template.md +107 -0
  274. package/dist/lite/templates/whereami-template.md +101 -0
  275. package/package.json +12 -5
package/dist/cli.js CHANGED
@@ -290,14 +290,15 @@ function substrateConfigMdTemplate(pkgVersion) {
290
290
  ].join("\n");
291
291
  }
292
292
  const MANIFEST_SCHEMA_VERSION = "0.1.0";
293
- const MANIFEST_SHAPE_VERSION = 2;
293
+ const MANIFEST_SHAPE_VERSION = 3;
294
+ const GENERATED_BY = "@thebassclef/lite";
294
295
  function manifestTemplate(input) {
295
296
  const value = {
296
297
  schema_version: MANIFEST_SHAPE_VERSION,
297
298
  $bassclef: {
298
299
  template: "init.manifest.json",
299
300
  manifest_schema_version: MANIFEST_SCHEMA_VERSION,
300
- generated_by: "@thebassclef/core",
301
+ generated_by: GENERATED_BY,
301
302
  generated_by_version: input.pkgVersion
302
303
  },
303
304
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -365,7 +366,7 @@ function readManifest(targetDir) {
365
366
  if (compareSchemaVersion(schema, MANIFEST_SCHEMA_VERSION) > 0) {
366
367
  throw new ManifestReadError(
367
368
  "SchemaTooNew",
368
- `manifest schema version ${schema} is newer than this package understands (${MANIFEST_SCHEMA_VERSION}). Upgrade @thebassclef/core.`
369
+ `manifest schema version ${schema} is newer than this package understands (${MANIFEST_SCHEMA_VERSION}). Upgrade @thebassclef/lite.`
369
370
  );
370
371
  }
371
372
  const obj = parsed;
@@ -495,6 +496,7 @@ function setExecutable(targetPath) {
495
496
  }
496
497
  chmodSync(targetPath, HOOK_EXECUTABLE_MODE);
497
498
  }
499
+ const CLAUDE_TARGET_ROOT = ".claude";
498
500
  const HOOKS_SUBPATH = ".claude/hooks/";
499
501
  const SETTINGS_SUBPATH = ".claude/settings.json";
500
502
  const CONFIG_FILES = [
@@ -517,7 +519,10 @@ function copySubstrate(targetDir, options = {}) {
517
519
  hookCount: 0,
518
520
  wiringVersion: manifest.version
519
521
  };
520
- if (options.dryRun) result.wouldCopy = [];
522
+ if (options.dryRun) {
523
+ result.wouldCopy = [];
524
+ result.wouldCopyEntries = [];
525
+ }
521
526
  const files = walkDistTree(bundleRoot);
522
527
  const groups = groupByTopDirectory(files);
523
528
  const bundleHookRelPaths = new Set(files.filter(isHookFile));
@@ -673,6 +678,11 @@ function copyOne(relPath, bundleRoot, options, result, scopeDecision) {
673
678
  const outputContent = options.transform ? options.transform(adopterRelPath, content) : content;
674
679
  if (options.dryRun) {
675
680
  result.wouldCopy?.push(adopterRelPath);
681
+ result.wouldCopyEntries?.push({
682
+ path: adopterRelPath,
683
+ scope,
684
+ content_hash_sha256: hashContent(outputContent)
685
+ });
676
686
  return "wouldCopy";
677
687
  }
678
688
  try {
@@ -682,7 +692,11 @@ function copyOne(relPath, bundleRoot, options, result, scopeDecision) {
682
692
  setExecutable(targetPath);
683
693
  }
684
694
  result.copied.push(adopterRelPath);
685
- result.copiedEntries.push({ path: adopterRelPath, scope });
695
+ result.copiedEntries.push({
696
+ path: adopterRelPath,
697
+ scope,
698
+ content_hash_sha256: hashContent(outputContent)
699
+ });
686
700
  return "copied";
687
701
  } catch (e) {
688
702
  if (e instanceof WriteError) {
@@ -759,7 +773,92 @@ function dirExists(p) {
759
773
  return false;
760
774
  }
761
775
  }
776
+ const FAMILIES = [
777
+ "skills",
778
+ "rules",
779
+ "agents",
780
+ "luminaries",
781
+ "hooks",
782
+ "libs",
783
+ "adrs",
784
+ "standards",
785
+ "templates",
786
+ "presence-templates",
787
+ "scripts",
788
+ "root-docs",
789
+ "other"
790
+ ];
791
+ const UNDER_CLAUDE = `${CLAUDE_TARGET_ROOT}/`;
792
+ const PREFIX_RULES = [
793
+ [`${UNDER_CLAUDE}skills/`, "skills"],
794
+ [`${UNDER_CLAUDE}rules/`, "rules"],
795
+ [`${UNDER_CLAUDE}agents/`, "agents"],
796
+ [`${UNDER_CLAUDE}luminaries/`, "luminaries"],
797
+ [`${UNDER_CLAUDE}hooks/`, "hooks"],
798
+ ["lib/", "libs"],
799
+ ["architecture/decisions/", "adrs"],
800
+ ["standards/", "standards"],
801
+ ["templates/", "templates"],
802
+ ["presence/install/", "presence-templates"],
803
+ ["scripts/", "scripts"]
804
+ ];
805
+ function classifyEntry(path) {
806
+ for (const [prefix, family] of PREFIX_RULES) {
807
+ if (path.startsWith(prefix)) return family;
808
+ }
809
+ if (!path.includes("/") && /^[A-Z]/.test(path)) return "root-docs";
810
+ return "other";
811
+ }
812
+ function emptyCatalogCounts() {
813
+ const out = {};
814
+ for (const f of FAMILIES) out[f] = 0;
815
+ return out;
816
+ }
817
+ function buildInitReport(input) {
818
+ const catalog = emptyCatalogCounts();
819
+ let project = 0;
820
+ let user = 0;
821
+ for (const e of input.entries) {
822
+ catalog[classifyEntry(e.path)] += 1;
823
+ if (e.scope === "user") user += 1;
824
+ else project += 1;
825
+ }
826
+ const refused = input.refused.length;
827
+ const errored = input.errored.length;
828
+ const written = input.configs.length + input.entries.length;
829
+ return {
830
+ schema_version: 3,
831
+ tier: input.tier,
832
+ totals: {
833
+ files: written + refused + errored,
834
+ written,
835
+ project,
836
+ user,
837
+ configs: input.configs.length
838
+ },
839
+ catalog,
840
+ hooks: {
841
+ declared: input.hookCount,
842
+ copied: input.declaredHooksCopied,
843
+ files: catalog.hooks
844
+ },
845
+ refused,
846
+ errored,
847
+ failed: refused + errored
848
+ };
849
+ }
850
+ function renderJsonReport(report, write) {
851
+ write(JSON.stringify(report) + "\n");
852
+ }
762
853
  const RESOLVED_TIER = "lite";
854
+ const SAY_HUMAN = (s) => {
855
+ process.stdout.write(s);
856
+ };
857
+ const SAY_QUIET = () => {
858
+ };
859
+ function makeSay(json) {
860
+ return json ? SAY_QUIET : SAY_HUMAN;
861
+ }
763
862
  const PLACEHOLDER_FILES = /* @__PURE__ */ new Set([
764
863
  "CLAUDE.md",
765
864
  "docs/whereami.md",
@@ -801,7 +900,7 @@ function runInit(argv) {
801
900
  }
802
901
  throw e;
803
902
  }
804
- const advisoryOutcome = maybeEmitUpgradeAdvisory(targetDir, args.yes);
903
+ const advisoryOutcome = maybeEmitUpgradeAdvisory(targetDir, args.yes, args.json);
805
904
  if (advisoryOutcome === "refused") return 1;
806
905
  const upgradeApproved = advisoryOutcome === "upgrade-approved";
807
906
  if (!args.force && !args.dryRun && !upgradeApproved) {
@@ -823,26 +922,55 @@ function runInit(argv) {
823
922
  templateVersion: SUBSTRATE_CONFIG_TEMPLATE_VERSION
824
923
  }
825
924
  ];
925
+ const say = makeSay(args.json);
826
926
  if (args.dryRun) {
827
- runDryRun$1(plans);
828
- return dispatchSubstrateCopy(targetDir, args.force || upgradeApproved, args.verbose, true, args.allowRoot, args.json);
829
- }
830
- return runReal$1(plans, args.force || upgradeApproved, args.verbose, targetDir, args.allowRoot, args.json);
831
- }
832
- function maybeEmitUpgradeAdvisory(targetDir, yes) {
927
+ runDryRun$1(plans, say);
928
+ const outcome = dispatchSubstrateCopy(
929
+ targetDir,
930
+ args.force || upgradeApproved,
931
+ args.verbose,
932
+ true,
933
+ args.allowRoot,
934
+ say
935
+ );
936
+ if (args.json) {
937
+ const report = buildInitReport({
938
+ entries: outcome.result?.wouldCopyEntries ?? [],
939
+ configs: plans.map((pl) => ({ path: pl.relativePath })),
940
+ refused: outcome.result?.refused ?? [],
941
+ // A dry run still reads every source file, so it can still fail
942
+ // to read one. Hard-coding this empty hid those failures from
943
+ // the JSON (RFC-0005 A-3).
944
+ errored: outcome.result?.errored ?? [],
945
+ hookCount: outcome.result?.hookCount ?? 0,
946
+ declaredHooksCopied: 0,
947
+ tier: RESOLVED_TIER
948
+ });
949
+ renderJsonReport(report, (t) => {
950
+ process.stdout.write(t);
951
+ });
952
+ }
953
+ return outcome.code;
954
+ }
955
+ return runReal$1(plans, args.force || upgradeApproved, args.verbose, targetDir, args.allowRoot, args.json, say);
956
+ }
957
+ function maybeEmitUpgradeAdvisory(targetDir, yes, json) {
958
+ const prompt = json ? (t) => {
959
+ process.stderr.write(t);
960
+ } : SAY_HUMAN;
833
961
  const manifestPath = join(targetDir, MANIFEST_RELATIVE_PATH);
834
962
  if (!existsSync(manifestPath)) return "ok";
835
963
  const version2 = readManifestShapeVersion(targetDir);
836
964
  if (version2 !== null && version2 >= 2) return "ok";
837
- process.stdout.write(
965
+ prompt(
838
966
  `bassclef init: cli 1.0.1 introduces user-scope hook installation at ~/${HOOKS_SUBPATH}. cli 1.0.0 did not write there.
839
967
  `
840
968
  );
841
969
  if (yes) return "upgrade-approved";
842
- process.stdout.write("bassclef init: continue? (y/N) ");
970
+ prompt("bassclef init: continue? (y/N) ");
843
971
  const answer = readOneLineFromStdin();
844
972
  if (answer === "" || answer === "y" || answer === "Y") return "upgrade-approved";
845
- process.stdout.write("bassclef init: aborted by adopter.\n");
973
+ prompt("bassclef init: aborted by adopter.\n");
846
974
  return "refused";
847
975
  }
848
976
  function readOneLineFromStdin() {
@@ -854,7 +982,7 @@ function readOneLineFromStdin() {
854
982
  return "";
855
983
  }
856
984
  }
857
- function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, json) {
985
+ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, say) {
858
986
  const substitute = makePlaceholderTransform(targetDir);
859
987
  let result;
860
988
  try {
@@ -868,9 +996,9 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
868
996
  if (e instanceof CopyFailure) {
869
997
  process.stderr.write(`bassclef init: ${e.message}
870
998
  `);
871
- if (e.kind === "ManifestMissing") return 4;
872
- if (e.kind === "SchemaIncompatible") return 5;
873
- return 2;
999
+ if (e.kind === "ManifestMissing") return { code: 4 };
1000
+ if (e.kind === "SchemaIncompatible") return { code: 5 };
1001
+ return { code: 2 };
874
1002
  }
875
1003
  throw e;
876
1004
  }
@@ -878,23 +1006,23 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
878
1006
  const wouldCopy = result.wouldCopy ?? [];
879
1007
  for (const relativePath of wouldCopy) {
880
1008
  const targetPath = join(targetDir, relativePath);
881
- process.stdout.write(` ${"would create".padEnd(14)} ${targetPath}
1009
+ say(` ${"would create".padEnd(14)} ${targetPath}
882
1010
  `);
883
1011
  }
884
1012
  if (wouldCopy.length > 0) {
885
- process.stdout.write(
1013
+ say(
886
1014
  `bassclef init: ${wouldCopy.length} substrate files would be copied.
887
1015
  `
888
1016
  );
889
1017
  }
890
- process.stdout.write(
1018
+ say(
891
1019
  `bassclef init: ${result.hookCount} hooks armed (${RESOLVED_TIER} tier).
892
1020
  `
893
1021
  );
894
- return 0;
1022
+ return { code: 0, result };
895
1023
  }
896
1024
  if (result.copied.length === 0 && result.refused.length === 0 && result.errored.length === 0) {
897
- return 0;
1025
+ return { code: 0, result };
898
1026
  }
899
1027
  const groupCounts = /* @__PURE__ */ new Map();
900
1028
  for (const path of result.copied) {
@@ -903,17 +1031,17 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
903
1031
  groupCounts.set(top, (groupCounts.get(top) ?? 0) + 1);
904
1032
  }
905
1033
  for (const [directory, count] of groupCounts) {
906
- process.stdout.write(` ${directory}: ${count} files copied
1034
+ say(` ${directory}: ${count} files copied
907
1035
  `);
908
1036
  }
909
1037
  const parts = [];
910
1038
  if (result.copied.length > 0) parts.push(`${result.copied.length} substrate files copied`);
911
1039
  if (result.refused.length > 0) parts.push(`${result.refused.length} refused`);
912
1040
  if (result.errored.length > 0) parts.push(`${result.errored.length} error(s)`);
913
- process.stdout.write(`bassclef init: ${parts.join(", ")}.
1041
+ say(`bassclef init: ${parts.join(", ")}.
914
1042
  `);
915
1043
  const grandTotal = 1 + result.copied.length;
916
- process.stdout.write(
1044
+ say(
917
1045
  `bassclef init: ${grandTotal} files total (1 config + ${result.copied.length} substrate).
918
1046
  `
919
1047
  );
@@ -930,33 +1058,87 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
930
1058
  const projectScope = copiedHookEntries.filter((e) => e.scope === "project").length;
931
1059
  const scopeSuffix = userScope + projectScope > 0 ? ` ${projectScope} in <repo>/${HOOKS_SUBPATH.replace(/\/$/, "")}, ${userScope} in ~/${HOOKS_SUBPATH.replace(/\/$/, "")}.` : "";
932
1060
  if (failedCount > 0) {
933
- process.stdout.write(
1061
+ say(
934
1062
  `bassclef init: Installed ${copiedCount} of ${declaredCount} hooks (${RESOLVED_TIER} tier).${scopeSuffix} ${failedCount} failed — see errors above. Rerun bassclef init to retry.
935
1063
  `
936
1064
  );
937
1065
  } else {
938
- process.stdout.write(
1066
+ say(
939
1067
  `bassclef init: Installed ${copiedCount} of ${declaredCount} hooks (${RESOLVED_TIER} tier).${scopeSuffix}
940
1068
  `
941
1069
  );
942
1070
  }
943
- if (json) {
944
- const report = {
945
- copied: copiedCount,
946
- declared: declaredCount,
947
- failed: failedCount,
948
- scope_counts: { user: userScope, project: projectScope },
949
- tier: RESOLVED_TIER
950
- };
951
- process.stderr.write(JSON.stringify(report) + "\n");
1071
+ const catalogCounts = {
1072
+ skills: 0,
1073
+ rules: 0,
1074
+ agents: 0,
1075
+ luminaries: 0,
1076
+ libs: 0,
1077
+ adrs: 0,
1078
+ standards: 0,
1079
+ templates: 0,
1080
+ "presence-templates": 0,
1081
+ scripts: 0,
1082
+ "root-docs": 0
1083
+ };
1084
+ const SKILLS_PREFIX = `${CLAUDE_TARGET_ROOT}/skills/`;
1085
+ const RULES_PREFIX = `${CLAUDE_TARGET_ROOT}/rules/`;
1086
+ const AGENTS_PREFIX = `${CLAUDE_TARGET_ROOT}/agents/`;
1087
+ const LUMINARIES_PREFIX = `${CLAUDE_TARGET_ROOT}/luminaries/`;
1088
+ const CLAUDE_ROOT_PREFIX = `${CLAUDE_TARGET_ROOT}/`;
1089
+ for (const entry of result.copiedEntries) {
1090
+ if (entry.path.startsWith(SKILLS_PREFIX)) catalogCounts.skills += 1;
1091
+ else if (entry.path.startsWith(RULES_PREFIX)) catalogCounts.rules += 1;
1092
+ else if (entry.path.startsWith(AGENTS_PREFIX)) catalogCounts.agents += 1;
1093
+ else if (entry.path.startsWith(LUMINARIES_PREFIX)) catalogCounts.luminaries += 1;
1094
+ else if (entry.path.startsWith("lib/")) catalogCounts.libs += 1;
1095
+ else if (entry.path.startsWith("architecture/decisions/")) catalogCounts.adrs += 1;
1096
+ else if (entry.path.startsWith("standards/")) catalogCounts.standards += 1;
1097
+ else if (entry.path.startsWith("templates/")) catalogCounts.templates += 1;
1098
+ else if (entry.path.startsWith("presence/install/")) catalogCounts["presence-templates"] += 1;
1099
+ else if (entry.path.startsWith("scripts/")) catalogCounts.scripts += 1;
1100
+ else if (!entry.path.startsWith(CLAUDE_ROOT_PREFIX) && !entry.path.includes("/") && /^[A-Z]/.test(entry.path)) {
1101
+ catalogCounts["root-docs"] += 1;
1102
+ }
1103
+ }
1104
+ const claudeCounts = [
1105
+ catalogCounts.skills > 0 ? `${catalogCounts.skills} skills` : null,
1106
+ catalogCounts.rules > 0 ? `${catalogCounts.rules} rules` : null,
1107
+ catalogCounts.agents > 0 ? `${catalogCounts.agents} agents` : null,
1108
+ catalogCounts.luminaries > 0 ? `${catalogCounts.luminaries} luminaries` : null
1109
+ ].filter((s) => s !== null);
1110
+ if (claudeCounts.length > 0) {
1111
+ say(
1112
+ `bassclef init: Installed ${claudeCounts.join(", ")} under <repo>/.claude/.
1113
+ `
1114
+ );
952
1115
  }
1116
+ const otherCounts = [
1117
+ catalogCounts.libs > 0 ? `${catalogCounts.libs} libs` : null,
1118
+ catalogCounts.adrs > 0 ? `${catalogCounts.adrs} ADRs` : null,
1119
+ catalogCounts.templates > 0 ? `${catalogCounts.templates} templates` : null,
1120
+ catalogCounts["presence-templates"] > 0 ? `${catalogCounts["presence-templates"]} presence-templates` : null,
1121
+ catalogCounts.standards > 0 ? `${catalogCounts.standards} standards` : null,
1122
+ catalogCounts["root-docs"] > 0 ? `${catalogCounts["root-docs"]} root-docs` : null,
1123
+ catalogCounts.scripts > 0 ? `${catalogCounts.scripts} scripts` : null
1124
+ ].filter((s) => s !== null);
1125
+ if (otherCounts.length > 0) {
1126
+ say(
1127
+ `bassclef init: Installed ${otherCounts.join(", ")} under <repo>/.
1128
+ `
1129
+ );
1130
+ }
1131
+ say(
1132
+ `bassclef init: ${result.refused.length} files refused (path collision).` + (result.refused.length > 0 ? ` Use --force to overwrite existing files.` : ``) + `
1133
+ `
1134
+ );
953
1135
  if (verbose && result.erroredMessages) {
954
1136
  for (const msg of result.erroredMessages) {
955
1137
  process.stderr.write(` substrate: ${msg}
956
1138
  `);
957
1139
  }
958
1140
  }
959
- return result.errored.length > 0 ? 2 : 0;
1141
+ return { code: result.errored.length > 0 ? 2 : 0, result };
960
1142
  }
961
1143
  function makePlaceholderTransform(targetDir) {
962
1144
  const repoName = basename$1(targetDir);
@@ -966,7 +1148,7 @@ function makePlaceholderTransform(targetDir) {
966
1148
  return content.replace(/\[REPO_NAME\]/g, repoName).replace(/\[ISO_TIMESTAMP\]/g, timestamp).replace(/\[TIER\]/g, RESOLVED_TIER).replace(/\[Repo name\]/g, repoName).replace(/<tier>/g, RESOLVED_TIER);
967
1149
  };
968
1150
  }
969
- function runDryRun$1(plans) {
1151
+ function runDryRun$1(plans, say) {
970
1152
  for (const p of plans) {
971
1153
  let planned;
972
1154
  let extra = "";
@@ -986,12 +1168,12 @@ function runDryRun$1(plans) {
986
1168
  planned = "would skip";
987
1169
  }
988
1170
  }
989
- process.stdout.write(` ${planned.padEnd(14)} ${p.fullPath}${extra}
1171
+ say(` ${planned.padEnd(14)} ${p.fullPath}${extra}
990
1172
  `);
991
1173
  }
992
1174
  return 0;
993
1175
  }
994
- function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
1176
+ function runReal$1(plans, force, verbose, targetDir, allowRoot, json, say) {
995
1177
  const results = [];
996
1178
  let anyRefused = false;
997
1179
  let anyError = false;
@@ -1039,7 +1221,7 @@ function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
1039
1221
  if (r.outcome === "error") label = `error (${r.message ?? "unknown"})`;
1040
1222
  else if (r.outcome === "refused") label = "refused";
1041
1223
  else label = r.outcome;
1042
- process.stdout.write(` ${label.padEnd(10)} ${r.plan.fullPath}
1224
+ say(` ${label.padEnd(10)} ${r.plan.fullPath}
1043
1225
  `);
1044
1226
  }
1045
1227
  }
@@ -1061,38 +1243,59 @@ function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
1061
1243
  return 2;
1062
1244
  }
1063
1245
  if (anyRefused && created > 0) {
1064
- process.stdout.write(
1246
+ say(
1065
1247
  `bassclef init: ${created} config files created, ${unchanged} unchanged. Pass --force to overwrite.
1066
1248
  `
1067
1249
  );
1068
1250
  } else if (created === 0 && unchanged === plans.length) {
1069
- process.stdout.write("bassclef init: already initialized. No changes.\n");
1251
+ say("bassclef init: already initialized. No changes.\n");
1070
1252
  } else {
1071
- process.stdout.write(`bassclef init: ${created} config files created, ${unchanged} unchanged.
1253
+ say(`bassclef init: ${created} config files created, ${unchanged} unchanged.
1072
1254
  `);
1073
1255
  }
1074
- const walkerExit = dispatchSubstrateCopy(targetDir, force, verbose, false, allowRoot, json);
1075
- writeManifest(targetDir, results);
1076
- if (walkerExit === 0) {
1077
- process.stdout.write(
1256
+ const walker = dispatchSubstrateCopy(targetDir, force, verbose, false, allowRoot, say);
1257
+ const declaredLeaves = readDeclaredCommandLeaves(
1258
+ join(targetDir, ".claude", "settings.json")
1259
+ );
1260
+ const declaredHooksCopied = (walker.result?.copiedEntries ?? []).filter(
1261
+ (e) => e.path.startsWith(HOOKS_SUBPATH) && e.path.endsWith(".sh") && declaredLeaves.has(basename$1(e.path))
1262
+ ).length;
1263
+ const report = buildInitReport({
1264
+ entries: walker.result?.copiedEntries ?? [],
1265
+ configs: results.map((r) => ({ path: r.plan.relativePath })),
1266
+ refused: walker.result?.refused ?? [],
1267
+ errored: walker.result?.errored ?? [],
1268
+ hookCount: walker.result?.hookCount ?? 0,
1269
+ declaredHooksCopied,
1270
+ tier: RESOLVED_TIER
1271
+ });
1272
+ writeManifest(targetDir, results, walker.result);
1273
+ if (walker.code === 0) {
1274
+ say(
1078
1275
  `bassclef init: your substrate lives under .claude/. Add .claude/ to .gitignore if you have not.
1079
1276
  `
1080
1277
  );
1081
1278
  }
1082
- return walkerExit;
1279
+ if (json) {
1280
+ renderJsonReport(report, (t) => {
1281
+ process.stdout.write(t);
1282
+ });
1283
+ }
1284
+ return walker.code;
1083
1285
  }
1084
1286
  function shouldRefuseRoot(currentUid, allowRoot) {
1085
1287
  if (currentUid === void 0) return false;
1086
1288
  if (currentUid !== 0) return false;
1087
1289
  return !allowRoot;
1088
1290
  }
1089
- function writeManifest(targetDir, results) {
1291
+ function writeManifest(targetDir, results, walkerResult) {
1090
1292
  const entries = results.map((r) => {
1091
1293
  const entry = {
1092
1294
  path: r.plan.relativePath,
1093
1295
  template: r.plan.templateName,
1094
1296
  template_version: r.plan.templateVersion,
1095
- outcome: r.outcome
1297
+ outcome: r.outcome,
1298
+ source: "config-composer"
1096
1299
  };
1097
1300
  if (r.outcome === "created") {
1098
1301
  entry.content_hash_sha256 = hashContent(r.plan.content);
@@ -1100,6 +1303,38 @@ function writeManifest(targetDir, results) {
1100
1303
  }
1101
1304
  return entry;
1102
1305
  });
1306
+ if (walkerResult) {
1307
+ for (const copied of walkerResult.copiedEntries) {
1308
+ entries.push({
1309
+ path: copied.path,
1310
+ template: `bundle:${copied.path}`,
1311
+ template_version: version,
1312
+ outcome: "created",
1313
+ source: "bundle",
1314
+ scope: copied.scope,
1315
+ ...copied.content_hash_sha256 ? { content_hash_sha256: copied.content_hash_sha256 } : {},
1316
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
1317
+ });
1318
+ }
1319
+ for (const path of walkerResult.refused) {
1320
+ entries.push({
1321
+ path,
1322
+ template: `bundle:${path}`,
1323
+ template_version: version,
1324
+ outcome: "refused",
1325
+ source: "bundle"
1326
+ });
1327
+ }
1328
+ for (const path of walkerResult.errored) {
1329
+ entries.push({
1330
+ path,
1331
+ template: `bundle:${path}`,
1332
+ template_version: version,
1333
+ outcome: "error",
1334
+ source: "bundle"
1335
+ });
1336
+ }
1337
+ }
1103
1338
  const manifestDir = join(targetDir, ".bassclef");
1104
1339
  const manifestPath = join(manifestDir, "init.manifest.json");
1105
1340
  const content = manifestTemplate({
@@ -1110,7 +1345,12 @@ function writeManifest(targetDir, results) {
1110
1345
  try {
1111
1346
  mkdirSafely(manifestDir);
1112
1347
  writeSafely(manifestPath, content, { force: true });
1113
- } catch {
1348
+ } catch (e) {
1349
+ const reason = e instanceof Error ? e.message : String(e);
1350
+ process.stderr.write(
1351
+ `bassclef init: could not write ${manifestPath} (${reason}). The files were written. Run \`bassclef init --force\` to rebuild the record.
1352
+ `
1353
+ );
1114
1354
  }
1115
1355
  }
1116
1356
  function usage$2() {
@@ -1561,7 +1801,10 @@ function emitL2Output(decisions, verbose) {
1561
1801
  }
1562
1802
  }
1563
1803
  function updateManifestEntry(manifest, path, patch) {
1564
- const idx = manifest.files.findIndex((f) => f.path === path);
1804
+ const wantScope = patch.scope;
1805
+ const idx = manifest.files.findIndex(
1806
+ (f) => f.path === path && (wantScope === void 0 || f.scope === wantScope)
1807
+ );
1565
1808
  if (idx < 0) {
1566
1809
  manifest.files.push({
1567
1810
  path,
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const version = "1.0.4";
3
+ const version = "1.1.1";
4
4
  exports.version = version;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version: "1.0.4";
1
+ export declare const version: "1.1.1";
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "1.0.4";
1
+ const version = "1.1.1";
2
2
  export {
3
3
  version
4
4
  };
@@ -0,0 +1,70 @@
1
+ ---
2
+ tier: lite
3
+ name: Architect
4
+ description: "Opinionated. Builds C4 diagrams, writes ADRs, proves architecture against risks. Prefers boring technology. Documents why, not just what."
5
+ tools: Read, Write, Glob, Grep, WebSearch
6
+ model: claude-sonnet-4-6
7
+ ---
8
+
9
+ You are the Architect. Your discipline is Analysis & Design.
10
+
11
+ ## Persona
12
+ Opinionated. You prefer boring technology. You document *why*, not just *what*. You prove things before committing to them.
13
+
14
+ ## When active
15
+ - Elaboration (primary)
16
+ - Consulted during Construction for ADR violations
17
+
18
+ ## Responsibilities
19
+ - Build C4 Context and Container diagrams
20
+ - Write ADRs for load-bearing decisions
21
+ - Prove or disprove architecture against top technical risks
22
+ - Define component boundaries and interfaces
23
+ - Invoke /architect-review skill at Lifecycle Architecture Milestone gate
24
+ - Invoke /pattern-review skill for pattern review
25
+
26
+ ## Decision authority
27
+ Architecture. You own ADRs. No code without a container it belongs to.
28
+
29
+ ## Handoff
30
+ Accepted ADRs + C4 substrate → Builder picks up.
31
+
32
+ ## Luminaries
33
+
34
+ - **Simon Brown** — *"Architecture should be as easy to explain as it is to code."*
35
+ - C4 Model: Context → Container → Component → Code (four zoom levels)
36
+ - You produce Level 2 component diagrams — the sweet spot for decision-making
37
+ - Diagrams are communication tools, not decoration
38
+
39
+ - **Michael Nygard** — *"Architecture decisions are the ones you wish you could get right early."*
40
+ - Architecture Decision Records: capture the "why," not just the "what"
41
+ - Status lifecycle: proposed → accepted → deprecated → superseded
42
+ - Record context and consequences — future-you will thank present-you
43
+
44
+ - **Robert C. Martin (Uncle Bob)** — *"Architecture is about intent, not frameworks."*
45
+ - SOLID principles: five rules you check every module against
46
+ - The dependency rule: source code dependencies point inward
47
+ - Boundaries protect business rules from infrastructure details
48
+
49
+ - **Eric Evans** — *"The model is the backbone of the design."*
50
+ - Domain-Driven Design: code structure mirrors business domains
51
+ - Bounded Contexts: different parts of the system may model the same concept differently
52
+ - Ubiquitous Language: if the team uses different words for the same thing, the architecture is wrong
53
+
54
+ - **Craig Larman** — *"Models are not right or wrong — they are more or less useful."*
55
+ - Applying UML and Patterns: bridges formal modeling to practical implementation
56
+ - Iterative development: architecture emerges through feedback, not big upfront design
57
+ - Responsibility-Driven Design: assign behavior where the data lives
58
+
59
+ ## Checkpointing
60
+ After completing each major artifact (C4 diagram, ADR, component boundary):
61
+ - Update `docs/whereami.md` with current progress
62
+ - Commit the artifact with conventional commit
63
+ - State what was produced and what's next
64
+
65
+ ## Rules
66
+ - ADR status lifecycle: proposed → accepted → deprecated → superseded
67
+ - Only accepted ADRs govern. Proposed = under consideration.
68
+ - ADR violations are blockers, not suggestions
69
+ - You resolve technical risks. Market risks → PM. UX risks → Designer.
70
+ - You do NOT implement. You architect.