@thebassclef/lite 0.1.2 → 1.0.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 (293) hide show
  1. package/dist/cli.cjs +238 -127
  2. package/dist/cli.js +240 -129
  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/.bassclef-source.json +10 -0
  7. package/dist/lite/.claude/settings.json +212 -0
  8. package/dist/lite/CLAUDE.md +41 -0
  9. package/dist/lite/gitignore +58 -0
  10. package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
  11. package/dist/lite/whereami.md +24 -0
  12. package/package.json +8 -2
  13. package/substrate/.bassclef/lite-manifest.json +0 -2701
  14. package/substrate/.claude/agents/architect.md +0 -70
  15. package/substrate/.claude/agents/builder.md +0 -114
  16. package/substrate/.claude/agents/designer.md +0 -156
  17. package/substrate/.claude/agents/reviewer.md +0 -88
  18. package/substrate/.claude/hooks/artifact-ingestion-gate.sh +0 -357
  19. package/substrate/.claude/hooks/assert-verify-steering.sh +0 -77
  20. package/substrate/.claude/hooks/bassclef-source-config-validate.sh +0 -215
  21. package/substrate/.claude/hooks/bassclef-sync.sh +0 -634
  22. package/substrate/.claude/hooks/compound-noun-scrub.sh +0 -292
  23. package/substrate/.claude/hooks/kiss-expansion-inject.sh +0 -69
  24. package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
  25. package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -492
  26. package/substrate/.claude/hooks/plain-english-steering.sh +0 -156
  27. package/substrate/.claude/hooks/post-skill-friction-check.sh +0 -177
  28. package/substrate/.claude/hooks/post-skill-telemetry.sh +0 -62
  29. package/substrate/.claude/hooks/pre-build-gate.sh +0 -511
  30. package/substrate/.claude/hooks/pre-commit-gate.sh +0 -451
  31. package/substrate/.claude/hooks/session-end.sh +0 -433
  32. package/substrate/.claude/hooks/session-reflection.sh +0 -303
  33. package/substrate/.claude/hooks/skill-body-grade-gate.sh +0 -219
  34. package/substrate/.claude/hooks/skill-body-intent-drift.sh +0 -107
  35. package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
  36. package/substrate/.claude/hooks/state-validate.sh +0 -271
  37. package/substrate/.claude/hooks/substrate-clarity-gate.sh +0 -1110
  38. package/substrate/.claude/hooks/temperance-gate.sh +0 -147
  39. package/substrate/.claude/hooks/testing-tier-enforce.sh +0 -233
  40. package/substrate/.claude/hooks/turn-prose-grade-measure.sh +0 -219
  41. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +0 -463
  42. package/substrate/.claude/hooks/vocabulary-migration-check.sh +0 -171
  43. package/substrate/.claude/hooks/whereami-utc-gate.sh +0 -142
  44. package/substrate/.claude/luminaries/alan-cooper.md +0 -170
  45. package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
  46. package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
  47. package/substrate/.claude/luminaries/ash-maurya.md +0 -121
  48. package/substrate/.claude/luminaries/bill-buxton.md +0 -210
  49. package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
  50. package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
  51. package/substrate/.claude/luminaries/don-norman.md +0 -173
  52. package/substrate/.claude/luminaries/edward-tufte.md +0 -179
  53. package/substrate/.claude/luminaries/eric-evans.md +0 -160
  54. package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
  55. package/substrate/.claude/luminaries/gang-of-four.md +0 -157
  56. package/substrate/.claude/luminaries/glenford-myers.md +0 -230
  57. package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
  58. package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
  59. package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
  60. package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
  61. package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
  62. package/substrate/.claude/luminaries/karl-popper.md +0 -132
  63. package/substrate/.claude/luminaries/kent-beck.md +0 -168
  64. package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
  65. package/substrate/.claude/luminaries/martin-fowler.md +0 -164
  66. package/substrate/.claude/luminaries/michael-feathers.md +0 -125
  67. package/substrate/.claude/luminaries/michael-nygard.md +0 -118
  68. package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
  69. package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
  70. package/substrate/.claude/luminaries/sophia-prater.md +0 -193
  71. package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
  72. package/substrate/.claude/luminaries/tony-hoare.md +0 -170
  73. package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
  74. package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
  75. package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
  76. package/substrate/.claude/rules/adr-discipline.md +0 -120
  77. package/substrate/.claude/rules/api-conventions.md +0 -125
  78. package/substrate/.claude/rules/artifact-ingestion.md +0 -179
  79. package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
  80. package/substrate/.claude/rules/blocked-items.md +0 -146
  81. package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
  82. package/substrate/.claude/rules/branching.md +0 -28
  83. package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
  84. package/substrate/.claude/rules/commit-conventions.md +0 -22
  85. package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
  86. package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
  87. package/substrate/.claude/rules/context-engineering.md +0 -202
  88. package/substrate/.claude/rules/context-management.md +0 -85
  89. package/substrate/.claude/rules/defensive-bash.md +0 -68
  90. package/substrate/.claude/rules/deferred-actions.md +0 -233
  91. package/substrate/.claude/rules/destructive-operations.md +0 -69
  92. package/substrate/.claude/rules/diagnosis.md +0 -38
  93. package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
  94. package/substrate/.claude/rules/guardrails.md +0 -73
  95. package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
  96. package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
  97. package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
  98. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
  99. package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
  100. package/substrate/.claude/rules/loop-discipline.md +0 -81
  101. package/substrate/.claude/rules/manual-prod-approval.md +0 -100
  102. package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
  103. package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
  104. package/substrate/.claude/rules/new-dependency-check.md +0 -51
  105. package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
  106. package/substrate/.claude/rules/operator-facing-prose.md +0 -196
  107. package/substrate/.claude/rules/option-label-discipline.md +0 -108
  108. package/substrate/.claude/rules/pattern-annotation.md +0 -100
  109. package/substrate/.claude/rules/plain-english-discipline.md +0 -156
  110. package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
  111. package/substrate/.claude/rules/pr-body-shape.md +0 -317
  112. package/substrate/.claude/rules/pr-strategy.md +0 -167
  113. package/substrate/.claude/rules/pr-title-shape.md +0 -161
  114. package/substrate/.claude/rules/prototype-workflow.md +0 -65
  115. package/substrate/.claude/rules/reserved-skill-names.md +0 -123
  116. package/substrate/.claude/rules/schema-management.md +0 -49
  117. package/substrate/.claude/rules/sdlc-gates.md +0 -149
  118. package/substrate/.claude/rules/security.md +0 -37
  119. package/substrate/.claude/rules/session-artifacts.md +0 -236
  120. package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
  121. package/substrate/.claude/rules/skill-description-clarity.md +0 -247
  122. package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
  123. package/substrate/.claude/rules/state-schema-validation.md +0 -162
  124. package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
  125. package/substrate/.claude/rules/substrate-config-schema.md +0 -98
  126. package/substrate/.claude/rules/test-list-discipline.md +0 -175
  127. package/substrate/.claude/rules/test-sufficiency.md +0 -210
  128. package/substrate/.claude/rules/testing-tier-config.md +0 -145
  129. package/substrate/.claude/rules/testing.md +0 -38
  130. package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
  131. package/substrate/.claude/rules/visual-hierarchy.md +0 -437
  132. package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
  133. package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
  134. package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
  135. package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
  136. package/substrate/.claude/skills/build/SKILL.md +0 -640
  137. package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
  138. package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
  139. package/substrate/.claude/skills/decompose/SKILL.md +0 -280
  140. package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
  141. package/substrate/.claude/skills/feynman/SKILL.md +0 -90
  142. package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
  143. package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
  144. package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
  145. package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
  146. package/substrate/.claude/skills/journal/SKILL.md +0 -209
  147. package/substrate/.claude/skills/kiss/SKILL.md +0 -449
  148. package/substrate/.claude/skills/launch/SKILL.md +0 -915
  149. package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
  150. package/substrate/.claude/skills/longrun/SKILL.md +0 -463
  151. package/substrate/.claude/skills/luminary/SKILL.md +0 -481
  152. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
  153. package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
  154. package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
  155. package/substrate/.claude/skills/personas/SKILL.md +0 -207
  156. package/substrate/.claude/skills/promote/SKILL.md +0 -283
  157. package/substrate/.claude/skills/requirement/SKILL.md +0 -98
  158. package/substrate/.claude/skills/retro/SKILL.md +0 -117
  159. package/substrate/.claude/skills/riff/SKILL.md +0 -114
  160. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
  161. package/substrate/.claude/skills/session-end/SKILL.md +0 -309
  162. package/substrate/.claude/skills/session-log/SKILL.md +0 -299
  163. package/substrate/.claude/skills/skills/SKILL.md +0 -228
  164. package/substrate/.claude/skills/spec/SKILL.md +0 -105
  165. package/substrate/.claude/skills/sprint/SKILL.md +0 -392
  166. package/substrate/.claude/skills/stage/SKILL.md +0 -384
  167. package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
  168. package/substrate/.claude/skills/temperance/SKILL.md +0 -108
  169. package/substrate/.claude/skills/use-case/SKILL.md +0 -417
  170. package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
  171. package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
  172. package/substrate/.claude/skills/verify/SKILL.md +0 -160
  173. package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
  174. package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
  175. package/substrate/.claude/skills/whereami/SKILL.md +0 -307
  176. package/substrate/AGENTS.md +0 -79
  177. package/substrate/CLAUDE-lite.md +0 -85
  178. package/substrate/CODE_OF_CONDUCT.md +0 -28
  179. package/substrate/CONTRIBUTING.md +0 -177
  180. package/substrate/README.md +0 -173
  181. package/substrate/SECURITY.md +0 -19
  182. package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
  183. package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
  184. package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
  185. package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
  186. package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
  187. package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
  188. package/substrate/lib/clean-artifacts-sweep.sh +0 -112
  189. package/substrate/lib/code-comment-discipline.sh +0 -144
  190. package/substrate/lib/composer-preflight.sh +0 -459
  191. package/substrate/lib/hook-inject.sh +0 -255
  192. package/substrate/lib/luminary-pick.sh +0 -96
  193. package/substrate/lib/output-discipline.sh +0 -143
  194. package/substrate/lib/prose-scan-boundary.sh +0 -171
  195. package/substrate/lib/rewrite-check.sh +0 -214
  196. package/substrate/lib/state.sh +0 -1372
  197. package/substrate/lib/telemetry.sh +0 -205
  198. package/substrate/lib/tier-check.sh +0 -187
  199. package/substrate/lib/tier-dependency-audit.sh +0 -1088
  200. package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
  201. package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
  202. package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
  203. package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
  204. package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
  205. package/substrate/scripts/aggregate-telemetry.sh +0 -217
  206. package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
  207. package/substrate/scripts/generate-lite-manifest.sh +0 -505
  208. package/substrate/scripts/generate-tier-manifest.sh +0 -28
  209. package/substrate/scripts/intent-drift-check.sh +0 -456
  210. package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
  211. package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
  212. package/substrate/standards/adr-template.md +0 -86
  213. package/substrate/standards/api-conventions/nextjs.md +0 -84
  214. package/substrate/standards/artifact-composition.md +0 -209
  215. package/substrate/standards/bash-hook-safety.md +0 -246
  216. package/substrate/standards/bassclef-configs-schema.md +0 -232
  217. package/substrate/standards/bassclef-evolution.md +0 -143
  218. package/substrate/standards/bassclef-internal-jargon.md +0 -244
  219. package/substrate/standards/bassclef-managed-sentinel.md +0 -96
  220. package/substrate/standards/bassclef-source-config.md +0 -228
  221. package/substrate/standards/branch-stacking.md +0 -408
  222. package/substrate/standards/code-safety-principles.md +0 -176
  223. package/substrate/standards/composer-prerequisites.md +0 -155
  224. package/substrate/standards/deferred-actions-schema.md +0 -204
  225. package/substrate/standards/dependency-discipline/cargo.md +0 -39
  226. package/substrate/standards/dependency-discipline/gem.md +0 -43
  227. package/substrate/standards/dependency-discipline/go-mod.md +0 -41
  228. package/substrate/standards/dependency-discipline/npm.md +0 -42
  229. package/substrate/standards/dependency-discipline/pip.md +0 -42
  230. package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
  231. package/substrate/standards/deployment-topology.md +0 -69
  232. package/substrate/standards/docs-sync-allowlist.md +0 -76
  233. package/substrate/standards/domain-and-dns.md +0 -145
  234. package/substrate/standards/frontend-stack.md +0 -67
  235. package/substrate/standards/frontmatter-schema.md +0 -154
  236. package/substrate/standards/graceful-exit.md +0 -227
  237. package/substrate/standards/hook-idempotency.md +0 -102
  238. package/substrate/standards/hook-injection-discipline.md +0 -202
  239. package/substrate/standards/hook-install-class.md +0 -215
  240. package/substrate/standards/input-handler-interface.md +0 -152
  241. package/substrate/standards/lite-manifest-schema-changes.md +0 -135
  242. package/substrate/standards/luminary-matching.md +0 -105
  243. package/substrate/standards/luminary-problem-patterns.md +0 -481
  244. package/substrate/standards/migration-discipline/active-record.md +0 -50
  245. package/substrate/standards/migration-discipline/alembic.md +0 -43
  246. package/substrate/standards/migration-discipline/gorm.md +0 -50
  247. package/substrate/standards/migration-discipline/prisma.md +0 -53
  248. package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
  249. package/substrate/standards/mobile-ephemeral-session.md +0 -167
  250. package/substrate/standards/model-routing-discipline.md +0 -160
  251. package/substrate/standards/ogilvy-writing-rules.md +0 -225
  252. package/substrate/standards/opener-discipline.md +0 -96
  253. package/substrate/standards/operator-facing-prose-discipline.md +0 -201
  254. package/substrate/standards/persona-schema.md +0 -229
  255. package/substrate/standards/pluggable-luminaries.md +0 -323
  256. package/substrate/standards/pr-body-discipline.md +0 -115
  257. package/substrate/standards/preview-state-schema.md +0 -189
  258. package/substrate/standards/project-directory-layout.md +0 -276
  259. package/substrate/standards/release-tagging.md +0 -137
  260. package/substrate/standards/reserved-skill-names.md +0 -120
  261. package/substrate/standards/scannable-multi-option-output.md +0 -261
  262. package/substrate/standards/sdlc-compliance.md +0 -286
  263. package/substrate/standards/sdlc-gates/typescript.md +0 -57
  264. package/substrate/standards/secrets-lifecycle.md +0 -210
  265. package/substrate/standards/security-scanner-adapter.md +0 -145
  266. package/substrate/standards/session-board.md +0 -256
  267. package/substrate/standards/skill-output-discipline.md +0 -90
  268. package/substrate/standards/state-spine-contract.md +0 -255
  269. package/substrate/standards/state-spine.md +0 -511
  270. package/substrate/standards/steering-hints/kiss-words.md +0 -11
  271. package/substrate/standards/substrate-config-schema.md +0 -267
  272. package/substrate/standards/tech-stack-config.md +0 -109
  273. package/substrate/standards/tier-dependency-analysis.md +0 -167
  274. package/substrate/standards/tier-runtime-deps/lite.md +0 -57
  275. package/substrate/standards/tier-tag-schema.md +0 -155
  276. package/substrate/standards/two-layer-config.md +0 -99
  277. package/substrate/standards/use-case-format.md +0 -292
  278. package/substrate/standards/user-story-invest.md +0 -268
  279. package/substrate/standards/velocity-and-appetite.md +0 -229
  280. package/substrate/standards/voice-input-pattern.md +0 -119
  281. package/substrate/standards/whereami-schema.md +0 -301
  282. package/substrate/standards/worktree-management.md +0 -211
  283. package/substrate/standards/writing-guide.md +0 -213
  284. package/substrate/templates/chronicle-template.md +0 -75
  285. package/substrate/templates/deferred-action-template.md +0 -45
  286. package/substrate/templates/memory-proposal-template.md +0 -77
  287. package/substrate/templates/persona-template.md +0 -200
  288. package/substrate/templates/pr-faq.md +0 -45
  289. package/substrate/templates/secret-rotation-template.md +0 -162
  290. package/substrate/templates/spec-template.md +0 -131
  291. package/substrate/templates/use-case-template.md +0 -194
  292. package/substrate/templates/user-story-template.md +0 -107
  293. package/substrate/templates/whereami-template.md +0 -101
package/dist/cli.js CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { version } from "./index.js";
3
- import { realpathSync, statSync, constants, lstatSync, mkdirSync, accessSync, unlinkSync, openSync, writeSync, closeSync, readFileSync, existsSync } from "node:fs";
4
- import { isAbsolute, resolve, dirname, join } from "node:path";
3
+ import { realpathSync, statSync, constants, lstatSync, mkdirSync, accessSync, unlinkSync, openSync, writeSync, closeSync, readFileSync, readdirSync, existsSync } from "node:fs";
4
+ import { isAbsolute, resolve, dirname, join, relative, basename as basename$1 } from "node:path";
5
5
  import { homedir } from "node:os";
6
6
  import { createHash } from "node:crypto";
7
7
  import { fileURLToPath } from "node:url";
8
- import { createRequire } from "node:module";
9
8
  import { createInterface } from "node:readline/promises";
10
9
  import { stdin, stderr, stdout } from "node:process";
11
10
  const DEFAULTS$2 = {
@@ -220,22 +219,6 @@ function hashContent(content) {
220
219
  normalized = normalized.replace(/\r\n/g, "\n");
221
220
  return createHash("sha256").update(normalized, "utf8").digest("hex");
222
221
  }
223
- const SETTINGS_TEMPLATE_VERSION = "0.0.1";
224
- function settingsJsonTemplate(pkgVersion) {
225
- const value = {
226
- $bassclef: {
227
- template: "settings.json",
228
- template_version: SETTINGS_TEMPLATE_VERSION,
229
- generated_by: "@thebassclef/core",
230
- generated_by_version: pkgVersion
231
- },
232
- permissions: {
233
- additionalDirectories: []
234
- },
235
- hooks: {}
236
- };
237
- return JSON.stringify(value, null, 2) + "\n";
238
- }
239
222
  const SUBSTRATE_CONFIG_TEMPLATE_VERSION = "0.0.1";
240
223
  function substrateConfigMdTemplate(pkgVersion) {
241
224
  return [
@@ -386,129 +369,215 @@ async function computeConfigHashes(targetDir, paths) {
386
369
  }
387
370
  return out;
388
371
  }
389
- const SUBSTRATE_ROOT = "substrate";
390
- const CONFIG_FILES = [
391
- ".claude/settings.json",
392
- "substrate.config.md",
393
- "substrate.secrets.md"
394
- ];
395
- const CURRENT_ENTRY_COUNT = 149;
372
+ const EXPECTED_WIRING_SCHEMA_MAJOR = 2;
373
+ const WIRING_MANIFEST_RELATIVE = "standards/bassclef-wiring-manifest.json";
374
+ class CopyFailure extends Error {
375
+ constructor(kind, message) {
376
+ super(message);
377
+ this.kind = kind;
378
+ this.name = "CopyFailure";
379
+ }
380
+ }
396
381
  function copySubstrate(targetDir, options = {}) {
397
382
  const bundleRoot = resolveBundleRoot(options.bundleRoot);
398
- const manifest = loadBundledManifest(bundleRoot);
383
+ const manifest = readWiringManifest(bundleRoot);
399
384
  const result = {
400
385
  copied: [],
401
386
  refused: [],
402
387
  errored: [],
403
- erroredMessages: []
388
+ erroredMessages: [],
389
+ hookCount: 0,
390
+ wiringVersion: manifest.version
404
391
  };
405
392
  if (options.dryRun) result.wouldCopy = [];
406
- const groups = groupByTopDirectory(manifest.entries);
407
- for (const [directory, entries] of groups) {
393
+ const files = walkDistTree(bundleRoot);
394
+ const groups = groupByTopDirectory(files);
395
+ for (const [directory, groupFiles] of groups) {
408
396
  let completedInGroup = 0;
409
- for (const entry of entries) {
410
- const outcome = copyOne(entry, bundleRoot, targetDir, options, result);
397
+ for (const relPath of groupFiles) {
398
+ const outcome = copyOne(relPath, bundleRoot, targetDir, options, result);
411
399
  if (outcome !== "skipped") completedInGroup += 1;
412
400
  }
413
401
  if (options.onProgress) options.onProgress(directory, completedInGroup);
414
402
  }
403
+ result.hookCount = readHookCount(
404
+ options.dryRun ? join(bundleRoot, ".claude/settings.json") : join(targetDir, ".claude/settings.json")
405
+ );
415
406
  return result;
416
407
  }
417
- function copyOne(entry, bundleRoot, targetDir, options, result) {
418
- const sourcePath = join(bundleRoot, entry.path);
419
- const targetPath = join(targetDir, entry.path);
408
+ function readWiringManifest(bundleRoot) {
409
+ const manifestPath = join(bundleRoot, WIRING_MANIFEST_RELATIVE);
410
+ if (!fileExists(manifestPath)) {
411
+ throw new CopyFailure(
412
+ "ManifestMissing",
413
+ `Wiring manifest missing at ${manifestPath}. Cli built for schema_version ${EXPECTED_WIRING_SCHEMA_MAJOR}.x. Run \`npm install @thebassclef/lite@latest\` to fix.`
414
+ );
415
+ }
416
+ let manifest;
417
+ let raw;
418
+ try {
419
+ raw = readFileSync(manifestPath, "utf8");
420
+ } catch (e) {
421
+ const err = e;
422
+ throw new CopyFailure(
423
+ "ManifestMissing",
424
+ `Wiring manifest at ${manifestPath} unreadable (${err.code ?? "unknown"}). Reinstall @thebassclef/lite to restore the bundle.`
425
+ );
426
+ }
427
+ try {
428
+ manifest = JSON.parse(raw);
429
+ } catch (e) {
430
+ const err = e;
431
+ throw new CopyFailure(
432
+ "SchemaIncompatible",
433
+ `Wiring manifest at ${manifestPath} is not valid JSON: ${err.message}. Reinstall @thebassclef/lite to restore the bundle.`
434
+ );
435
+ }
436
+ if (typeof manifest.version !== "string" || manifest.version.length === 0) {
437
+ throw new CopyFailure(
438
+ "SchemaIncompatible",
439
+ `Wiring manifest at ${manifestPath} missing 'version' field. Cli requires schema_version ${EXPECTED_WIRING_SCHEMA_MAJOR}.x. Reinstall @thebassclef/lite to fix.`
440
+ );
441
+ }
442
+ const major = parseInt(manifest.version.split(".")[0] ?? "0", 10);
443
+ if (major !== EXPECTED_WIRING_SCHEMA_MAJOR) {
444
+ throw new CopyFailure(
445
+ "SchemaIncompatible",
446
+ `Wiring manifest at ${manifestPath} has version ${manifest.version}. Cli built for schema_version ${EXPECTED_WIRING_SCHEMA_MAJOR}.x. Upgrade cli OR downgrade @thebassclef/lite to a compatible version.`
447
+ );
448
+ }
449
+ return { version: manifest.version };
450
+ }
451
+ function walkDistTree(bundleRoot) {
452
+ if (!dirExists(bundleRoot)) {
453
+ throw new CopyFailure(
454
+ "BundleMissing",
455
+ `Bundled substrate missing at ${bundleRoot}. Reinstall @thebassclef/lite to restore the bundle.`
456
+ );
457
+ }
458
+ const results = [];
459
+ function walk(dir) {
460
+ for (const name of readdirSync(dir)) {
461
+ const full = join(dir, name);
462
+ const st = statSync(full);
463
+ if (st.isDirectory()) walk(full);
464
+ else results.push(relative(bundleRoot, full));
465
+ }
466
+ }
467
+ walk(bundleRoot);
468
+ results.sort();
469
+ return results;
470
+ }
471
+ const GITIGNORE_BUNDLE_NAME = "gitignore";
472
+ const GITIGNORE_ADOPTER_NAME = ".gitignore";
473
+ function mapAdopterPath(relPath) {
474
+ if (relPath === GITIGNORE_BUNDLE_NAME) return GITIGNORE_ADOPTER_NAME;
475
+ return relPath;
476
+ }
477
+ function copyOne(relPath, bundleRoot, targetDir, options, result) {
478
+ const sourcePath = join(bundleRoot, relPath);
479
+ const adopterRelPath = mapAdopterPath(relPath);
480
+ const targetPath = join(targetDir, adopterRelPath);
420
481
  let content;
421
482
  try {
422
483
  content = readFileSync(sourcePath, "utf8");
423
484
  } catch (e) {
424
485
  const err = e;
425
- const message = `${entry.path} — cannot read bundled source (${err.code ?? "unknown"}). Reinstall @thebassclef/core to restore the bundle.`;
426
- result.errored.push(entry.path);
427
- result.erroredMessages?.push(message);
428
- return "errored";
429
- }
430
- const declaredHash = stripHashPrefix(entry.content_hash);
431
- const actualHash = sha256Hex(content);
432
- if (declaredHash !== actualHash) {
433
- const message = `${entry.path} — bundled content hash does not match the manifest. Reinstall @thebassclef/core to repair the bundle, then rerun bassclef init --force.`;
434
- result.errored.push(entry.path);
486
+ const message = `${relPath} — cannot read bundled source (${err.code ?? "unknown"}). Reinstall @thebassclef/lite to restore the bundle.`;
487
+ result.errored.push(adopterRelPath);
435
488
  result.erroredMessages?.push(message);
436
489
  return "errored";
437
490
  }
491
+ const outputContent = options.transform ? options.transform(adopterRelPath, content) : content;
438
492
  if (options.dryRun) {
439
- result.wouldCopy?.push(entry.path);
493
+ result.wouldCopy?.push(adopterRelPath);
440
494
  return "wouldCopy";
441
495
  }
442
496
  try {
443
497
  mkdirSafely(dirname(targetPath));
444
- writeSafely(targetPath, content, { force: options.force ?? false });
445
- result.copied.push(entry.path);
498
+ writeSafely(targetPath, outputContent, { force: options.force ?? false });
499
+ result.copied.push(adopterRelPath);
446
500
  return "copied";
447
501
  } catch (e) {
448
502
  if (e instanceof WriteError) {
449
503
  if (e.kind === "AlreadyExists") {
450
- result.refused.push(entry.path);
504
+ result.refused.push(adopterRelPath);
451
505
  return "refused";
452
506
  }
453
507
  if (e.kind === "SymlinkRefused") {
454
- result.refused.push(entry.path);
508
+ result.refused.push(adopterRelPath);
455
509
  return "refused";
456
510
  }
457
- const message = `${entry.path} — write failed (${e.kind}): ${e.message}. Check the target directory exists and is writable, then rerun.`;
458
- result.errored.push(entry.path);
511
+ const message = `${adopterRelPath} — write failed (${e.kind}): ${e.message}. Check the target directory exists and is writable, then rerun.`;
512
+ result.errored.push(adopterRelPath);
459
513
  result.erroredMessages?.push(message);
460
514
  return "errored";
461
515
  }
462
516
  throw e;
463
517
  }
464
518
  }
465
- function loadBundledManifest(bundleRoot) {
466
- const manifestPath = join(bundleRoot, ".bassclef", "lite-manifest.json");
467
- const raw = readFileSync(manifestPath, "utf8");
468
- const parsed = JSON.parse(raw);
469
- if (!Array.isArray(parsed.entries)) {
470
- throw new Error(
471
- `bundled manifest at ${manifestPath} has no entries[] array. Reinstall @thebassclef/core to restore the bundle.`
472
- );
473
- }
474
- return parsed;
475
- }
476
519
  function resolveBundleRoot(explicit) {
477
520
  if (explicit && explicit.length > 0) return resolve(explicit);
478
521
  const thisFile = fileURLToPath(import.meta.url);
479
522
  let dir = dirname(thisFile);
480
523
  for (let i = 0; i < 5; i += 1) {
481
- try {
482
- readFileSync(join(dir, "package.json"), "utf8");
483
- return join(dir, SUBSTRATE_ROOT);
484
- } catch {
485
- const parent = dirname(dir);
486
- if (parent === dir) break;
487
- dir = parent;
524
+ if (fileExists(join(dir, "package.json"))) {
525
+ return join(dir, "dist", "lite");
488
526
  }
527
+ const parent = dirname(dir);
528
+ if (parent === dir) break;
529
+ dir = parent;
489
530
  }
490
- const require2 = createRequire(import.meta.url);
491
- const pkgJsonPath = require2.resolve("@thebassclef/core/package.json");
492
- const pkgRoot = dirname(pkgJsonPath);
493
- return join(pkgRoot, SUBSTRATE_ROOT);
531
+ throw new CopyFailure(
532
+ "BundleMissing",
533
+ `Cannot resolve bundled substrate root — package.json unreachable from ${thisFile}. Reinstall @thebassclef/lite.`
534
+ );
494
535
  }
495
- function groupByTopDirectory(entries) {
536
+ function groupByTopDirectory(files) {
496
537
  const groups = /* @__PURE__ */ new Map();
497
- for (const entry of entries) {
498
- const parts = entry.path.split("/");
538
+ for (const p of files) {
539
+ const parts = p.split("/");
499
540
  const top = parts.length >= 2 ? parts.slice(0, 2).join("/") : parts[0] ?? "";
500
541
  if (!groups.has(top)) groups.set(top, []);
501
- groups.get(top).push(entry);
542
+ groups.get(top).push(p);
502
543
  }
503
544
  return groups;
504
545
  }
505
- function stripHashPrefix(value) {
506
- const prefix = "sha256:";
507
- return value.startsWith(prefix) ? value.slice(prefix.length) : value;
546
+ function readHookCount(settingsPath) {
547
+ try {
548
+ const parsed = JSON.parse(readFileSync(settingsPath, "utf8"));
549
+ let count = 0;
550
+ for (const matcherBlocks of Object.values(parsed.hooks ?? {})) {
551
+ for (const block of matcherBlocks) {
552
+ count += (block.hooks ?? []).length;
553
+ }
554
+ }
555
+ return count;
556
+ } catch {
557
+ return 0;
558
+ }
559
+ }
560
+ function fileExists(p) {
561
+ try {
562
+ return statSync(p).isFile();
563
+ } catch {
564
+ return false;
565
+ }
508
566
  }
509
- function sha256Hex(content) {
510
- return createHash("sha256").update(content).digest("hex");
567
+ function dirExists(p) {
568
+ try {
569
+ return statSync(p).isDirectory();
570
+ } catch {
571
+ return false;
572
+ }
511
573
  }
574
+ const RESOLVED_TIER = "lite";
575
+ const PLACEHOLDER_FILES = /* @__PURE__ */ new Set([
576
+ "CLAUDE.md",
577
+ "docs/whereami.md",
578
+ "whereami.md",
579
+ ".bassclef-source.json"
580
+ ]);
512
581
  function runInit(argv) {
513
582
  let args;
514
583
  try {
@@ -554,14 +623,6 @@ function runInit(argv) {
554
623
  }
555
624
  }
556
625
  const plans = [
557
- {
558
- label: "settings.json",
559
- relativePath: ".claude/settings.json",
560
- fullPath: join(targetDir, ".claude", "settings.json"),
561
- content: settingsJsonTemplate(version),
562
- templateName: "settings.json",
563
- templateVersion: SETTINGS_TEMPLATE_VERSION
564
- },
565
626
  {
566
627
  label: "substrate.config.md",
567
628
  relativePath: "substrate.config.md",
@@ -572,32 +633,51 @@ function runInit(argv) {
572
633
  }
573
634
  ];
574
635
  if (args.dryRun) {
575
- return runDryRun$1(plans);
576
- }
577
- const exitCode = runReal$1(plans, args.force, args.verbose, targetDir);
578
- if (exitCode === 0) {
579
- dispatchSubstrateCopy(targetDir, args.force, args.verbose);
636
+ runDryRun$1(plans);
637
+ return dispatchSubstrateCopy(targetDir, args.force, args.verbose, true);
580
638
  }
581
- return exitCode;
639
+ return runReal$1(plans, args.force, args.verbose, targetDir);
582
640
  }
583
- function dispatchSubstrateCopy(targetDir, force, verbose) {
641
+ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun) {
642
+ const substitute = makePlaceholderTransform(targetDir);
584
643
  let result;
585
644
  try {
586
- result = copySubstrate(targetDir, { force });
645
+ result = copySubstrate(targetDir, {
646
+ force,
647
+ dryRun,
648
+ transform: substitute
649
+ });
587
650
  } catch (e) {
588
- const err = e;
589
- process.stderr.write(
590
- `bassclef init: substrate copy failed — ${err.message}
591
- cause: the installed @thebassclef/core package is missing the bundled substrate manifest.
592
- fix: reinstall with \`npm install -g @thebassclef/core@latest --force\`.
593
- If the reinstall does not help, file an issue at
594
- https://github.com/sunj-labs/bassclef-cli/issues with your package version.
651
+ if (e instanceof CopyFailure) {
652
+ process.stderr.write(`bassclef init: ${e.message}
653
+ `);
654
+ if (e.kind === "ManifestMissing") return 4;
655
+ if (e.kind === "SchemaIncompatible") return 5;
656
+ return 2;
657
+ }
658
+ throw e;
659
+ }
660
+ if (dryRun) {
661
+ const wouldCopy = result.wouldCopy ?? [];
662
+ for (const relativePath of wouldCopy) {
663
+ const targetPath = join(targetDir, relativePath);
664
+ process.stdout.write(` ${"would create".padEnd(14)} ${targetPath}
665
+ `);
666
+ }
667
+ if (wouldCopy.length > 0) {
668
+ process.stdout.write(
669
+ `bassclef init: ${wouldCopy.length} substrate files would be copied.
670
+ `
671
+ );
672
+ }
673
+ process.stdout.write(
674
+ `bassclef init: ${result.hookCount} hooks armed (${RESOLVED_TIER} tier).
595
675
  `
596
676
  );
597
- process.exit(2);
677
+ return 0;
598
678
  }
599
679
  if (result.copied.length === 0 && result.refused.length === 0 && result.errored.length === 0) {
600
- return;
680
+ return 0;
601
681
  }
602
682
  const groupCounts = /* @__PURE__ */ new Map();
603
683
  for (const path of result.copied) {
@@ -615,12 +695,30 @@ function dispatchSubstrateCopy(targetDir, force, verbose) {
615
695
  if (result.errored.length > 0) parts.push(`${result.errored.length} error(s)`);
616
696
  process.stdout.write(`bassclef init: ${parts.join(", ")}.
617
697
  `);
698
+ const grandTotal = 1 + result.copied.length;
699
+ process.stdout.write(
700
+ `bassclef init: ${grandTotal} files total (1 config + ${result.copied.length} substrate).
701
+ `
702
+ );
703
+ process.stdout.write(
704
+ `bassclef init: ${result.hookCount} hooks armed (${RESOLVED_TIER} tier).
705
+ `
706
+ );
618
707
  if (verbose && result.erroredMessages) {
619
708
  for (const msg of result.erroredMessages) {
620
709
  process.stderr.write(` substrate: ${msg}
621
710
  `);
622
711
  }
623
712
  }
713
+ return result.errored.length > 0 ? 2 : 0;
714
+ }
715
+ function makePlaceholderTransform(targetDir) {
716
+ const repoName = basename$1(targetDir);
717
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
718
+ return (relPath, content) => {
719
+ if (!PLACEHOLDER_FILES.has(relPath)) return content;
720
+ 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);
721
+ };
624
722
  }
625
723
  function runDryRun$1(plans) {
626
724
  for (const p of plans) {
@@ -704,8 +802,8 @@ function runReal$1(plans, force, verbose, targetDir) {
704
802
  process.stderr.write(`bassclef init: ${tag}: ${r.message ?? "write failed"}: ${r.plan.fullPath}
705
803
  `);
706
804
  }
707
- writeManifest(targetDir, results);
708
805
  if (anyError) {
806
+ writeManifest(targetDir, results);
709
807
  const parts = [];
710
808
  if (created > 0) parts.push(`${created} created`);
711
809
  if (unchanged > 0) parts.push(`${unchanged} unchanged`);
@@ -716,28 +814,26 @@ function runReal$1(plans, force, verbose, targetDir) {
716
814
  `);
717
815
  return 2;
718
816
  }
719
- if (created === 0 && unchanged === plans.length) {
720
- process.stdout.write("bassclef init: already initialized. No changes.\n");
721
- return 0;
722
- }
723
817
  if (anyRefused && created > 0) {
724
818
  process.stdout.write(
725
- `bassclef init: ${created} created, ${unchanged} unchanged. Pass --force to overwrite.
819
+ `bassclef init: ${created} config files created, ${unchanged} unchanged. Pass --force to overwrite.
726
820
  `
727
821
  );
822
+ } else if (created === 0 && unchanged === plans.length) {
823
+ process.stdout.write("bassclef init: already initialized. No changes.\n");
824
+ } else {
825
+ process.stdout.write(`bassclef init: ${created} config files created, ${unchanged} unchanged.
826
+ `);
827
+ }
828
+ const walkerExit = dispatchSubstrateCopy(targetDir, force, verbose, false);
829
+ writeManifest(targetDir, results);
830
+ if (walkerExit === 0) {
728
831
  process.stdout.write(
729
832
  `bassclef init: your substrate lives under .claude/. Add .claude/ to .gitignore if you have not.
730
833
  `
731
834
  );
732
- return 0;
733
835
  }
734
- process.stdout.write(`bassclef init: ${created} created, ${unchanged} unchanged.
735
- `);
736
- process.stdout.write(
737
- `bassclef init: your substrate lives under .claude/. Add .claude/ to .gitignore if you have not.
738
- `
739
- );
740
- return 0;
836
+ return walkerExit;
741
837
  }
742
838
  function shouldRefuseRoot(currentUid, allowRoot) {
743
839
  if (currentUid === void 0) return false;
@@ -785,10 +881,25 @@ function usage$2() {
785
881
  " --allow-any-dir Allow --dir outside your home directory. Default: refuse.",
786
882
  " --verbose Print per-file result.",
787
883
  "",
884
+ "Exit codes:",
885
+ " 0 — success",
886
+ " 1 — refused by policy (existing file; running as root; outside HOME)",
887
+ " 2 — safety check failed at write (symlink; parent not writable)",
888
+ " 3 — invalid args",
889
+ " 4 — wiring manifest missing from bundled substrate (reinstall @thebassclef/lite)",
890
+ " 5 — wiring manifest schema major version incompatible with this cli",
891
+ "",
788
892
  "Files written under <target>:",
789
- " .claude/settings.json Claude Code settings (minimal, opt-in blocks)",
790
893
  " substrate.config.md Bassclef project manifest",
791
894
  " .bassclef/init.manifest.json Record of what init wrote (used by sync)",
895
+ "",
896
+ " Plus the bundled substrate tree from dist/lite/:",
897
+ " .claude/settings.json Claude Code settings (verbatim from bundle)",
898
+ " CLAUDE.md, whereami.md, .bassclef-source.json, .gitignore",
899
+ " Templates with placeholders substituted",
900
+ "",
901
+ " Run with --dry-run first to preview the full file list before",
902
+ " writing anything to disk.",
792
903
  ""
793
904
  ].join("\n");
794
905
  }
@@ -867,12 +978,6 @@ function parseSyncArgs(argv) {
867
978
  return out;
868
979
  }
869
980
  const TEMPLATES = [
870
- {
871
- templateName: "settings.json",
872
- currentVersion: SETTINGS_TEMPLATE_VERSION,
873
- render: settingsJsonTemplate,
874
- hasMarker: (c) => c.includes('"$bassclef"')
875
- },
876
981
  {
877
982
  templateName: "substrate.config.md",
878
983
  currentVersion: SUBSTRATE_CONFIG_TEMPLATE_VERSION,
@@ -1324,6 +1429,12 @@ async function confirm(question, opts = {}) {
1324
1429
  rl.close();
1325
1430
  }
1326
1431
  }
1432
+ const CONFIG_FILES = [
1433
+ ".claude/settings.json",
1434
+ "substrate.config.md",
1435
+ "substrate.secrets.md"
1436
+ ];
1437
+ const CURRENT_ENTRY_COUNT = 149;
1327
1438
  async function detectAdopterState(targetDir) {
1328
1439
  let manifest;
1329
1440
  try {
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 = "0.1.2";
3
+ const version = "1.0.0";
4
4
  exports.version = version;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version: "0.1.2";
1
+ export declare const version: "1.0.0";
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "0.1.2";
1
+ const version = "1.0.0";
2
2
  export {
3
3
  version
4
4
  };
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://bassclef.sunj-labs/adopter/bassclef-source.schema.json",
3
+ "source_repo": "sunj-labs/bassclef",
4
+ "source_ref": "main",
5
+ "tier": "[TIER]",
6
+ "auto_sync": true,
7
+ "installed_at": "[ISO_TIMESTAMP]",
8
+ "installed_via": "bassclef-cli",
9
+ "notes": "Adopter-owned config. Change `auto_sync` to `false` to pause session-start substrate refresh. Change `tier` to opt into standard or ultra (requires re-run of `bassclef init --tier <T>`). Rename docs at https://github.com/sunj-labs/bassclef."
10
+ }