@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.
- package/dist/cli.cjs +298 -55
- package/dist/cli.js +298 -55
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.claude/agents/architect.md +70 -0
- package/dist/lite/.claude/agents/builder.md +114 -0
- package/dist/lite/.claude/agents/designer.md +156 -0
- package/dist/lite/.claude/agents/reviewer.md +88 -0
- package/dist/lite/.claude/hooks/bassclef-sync.sh +85 -27
- package/dist/lite/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
- package/dist/lite/.claude/hooks/longrun-prep-render-check.sh +236 -0
- package/dist/lite/.claude/hooks/persona-name-scrub-check.sh +105 -0
- package/dist/lite/.claude/hooks/skill-step-list-check.sh +171 -0
- package/dist/lite/.claude/luminaries/alan-cooper.md +170 -0
- package/dist/lite/.claude/luminaries/alistair-cockburn.md +140 -0
- package/dist/lite/.claude/luminaries/amazon-pr-faq.md +34 -0
- package/dist/lite/.claude/luminaries/andreas-zeller.md +74 -0
- package/dist/lite/.claude/luminaries/ash-maurya.md +121 -0
- package/dist/lite/.claude/luminaries/bill-buxton.md +210 -0
- package/dist/lite/.claude/luminaries/charles-sanders-peirce.md +150 -0
- package/dist/lite/.claude/luminaries/david-ogilvy.md +192 -0
- package/dist/lite/.claude/luminaries/don-norman.md +173 -0
- package/dist/lite/.claude/luminaries/edward-tufte.md +179 -0
- package/dist/lite/.claude/luminaries/eric-evans.md +160 -0
- package/dist/lite/.claude/luminaries/frederick-brooks.md +50 -0
- package/dist/lite/.claude/luminaries/gang-of-four.md +157 -0
- package/dist/lite/.claude/luminaries/glenford-myers.md +230 -0
- package/dist/lite/.claude/luminaries/hunt-thomas.md +115 -0
- package/dist/lite/.claude/luminaries/hyrum-wright.md +94 -0
- package/dist/lite/.claude/luminaries/jason-fried-dhh.md +46 -0
- package/dist/lite/.claude/luminaries/jesse-james-garrett.md +154 -0
- package/dist/lite/.claude/luminaries/john-ousterhout.md +94 -0
- package/dist/lite/.claude/luminaries/karl-popper.md +132 -0
- package/dist/lite/.claude/luminaries/kent-beck.md +168 -0
- package/dist/lite/.claude/luminaries/linus-torvalds.md +218 -0
- package/dist/lite/.claude/luminaries/martin-fowler.md +164 -0
- package/dist/lite/.claude/luminaries/michael-feathers.md +125 -0
- package/dist/lite/.claude/luminaries/michael-nygard.md +118 -0
- package/dist/lite/.claude/luminaries/robert-c-martin.md +164 -0
- package/dist/lite/.claude/luminaries/saltzer-schroeder.md +194 -0
- package/dist/lite/.claude/luminaries/sophia-prater.md +193 -0
- package/dist/lite/.claude/luminaries/stephen-toulmin.md +131 -0
- package/dist/lite/.claude/luminaries/tony-hoare.md +170 -0
- package/dist/lite/.claude/luminaries/vaughn-vernon.md +50 -0
- package/dist/lite/.claude/luminaries/w-edwards-deming.md +158 -0
- package/dist/lite/.claude/rules/accessor-library-discipline.md +110 -0
- package/dist/lite/.claude/rules/adr-discipline.md +96 -0
- package/dist/lite/.claude/rules/api-conventions.md +115 -0
- package/dist/lite/.claude/rules/artifact-ingestion.md +137 -0
- package/dist/lite/.claude/rules/assert-only-after-verify.md +111 -0
- package/dist/lite/.claude/rules/blocked-items.md +139 -0
- package/dist/lite/.claude/rules/bootstrap-pair-discipline.md +106 -0
- package/dist/lite/.claude/rules/branching.md +28 -0
- package/dist/lite/.claude/rules/cold-adopter-harness-discipline.md +93 -0
- package/dist/lite/.claude/rules/commit-conventions.md +22 -0
- package/dist/lite/.claude/rules/compounding-axis-fresh-analysis.md +173 -0
- package/dist/lite/.claude/rules/compounding-sequence-fresh-analysis.md +173 -0
- package/dist/lite/.claude/rules/context-engineering.md +155 -0
- package/dist/lite/.claude/rules/context-management.md +85 -0
- package/dist/lite/.claude/rules/defensive-bash.md +52 -0
- package/dist/lite/.claude/rules/deferred-actions.md +233 -0
- package/dist/lite/.claude/rules/destructive-operations.md +69 -0
- package/dist/lite/.claude/rules/diagnosis.md +38 -0
- package/dist/lite/.claude/rules/github-issue-flash-tweet.md +114 -0
- package/dist/lite/.claude/rules/guardrails.md +73 -0
- package/dist/lite/.claude/rules/hook-wire-on-author.md +77 -0
- package/dist/lite/.claude/rules/identifier-leak-prevention.md +73 -0
- package/dist/lite/.claude/rules/iteration-bet-brief-completeness.md +43 -0
- package/dist/lite/.claude/rules/lite-manifest-schema-change-discipline.md +79 -0
- package/dist/lite/.claude/rules/longrun-prep-plan-doc-compression.md +77 -0
- package/dist/lite/.claude/rules/loop-discipline.md +71 -0
- package/dist/lite/.claude/rules/manual-prod-approval.md +100 -0
- package/dist/lite/.claude/rules/marker-enrichment-discipline.md +72 -0
- package/dist/lite/.claude/rules/mobile-ephemeral-session.md +109 -0
- package/dist/lite/.claude/rules/new-dependency-check.md +44 -0
- package/dist/lite/.claude/rules/oo-ad-entry-point.md +95 -0
- package/dist/lite/.claude/rules/operator-facing-prose.md +177 -0
- package/dist/lite/.claude/rules/option-label-discipline.md +82 -0
- package/dist/lite/.claude/rules/pattern-annotation.md +83 -0
- package/dist/lite/.claude/rules/persona-name-leak-scrub.md +90 -0
- package/dist/lite/.claude/rules/plain-english-discipline.md +132 -0
- package/dist/lite/.claude/rules/plan-enumeration-needs-value-props.md +177 -0
- package/dist/lite/.claude/rules/pr-body-shape.md +195 -0
- package/dist/lite/.claude/rules/pr-strategy.md +142 -0
- package/dist/lite/.claude/rules/pr-title-shape.md +90 -0
- package/dist/lite/.claude/rules/prototype-workflow.md +53 -0
- package/dist/lite/.claude/rules/reserved-skill-names.md +103 -0
- package/dist/lite/.claude/rules/schema-management.md +42 -0
- package/dist/lite/.claude/rules/sdlc-gates.md +149 -0
- package/dist/lite/.claude/rules/security.md +37 -0
- package/dist/lite/.claude/rules/session-artifacts.md +236 -0
- package/dist/lite/.claude/rules/skill-composition-declarations.md +105 -0
- package/dist/lite/.claude/rules/skill-description-clarity.md +196 -0
- package/dist/lite/.claude/rules/skill-procedure-step-list.md +119 -0
- package/dist/lite/.claude/rules/sprint-prep-preset-picker.md +76 -0
- package/dist/lite/.claude/rules/state-schema-validation.md +156 -0
- package/dist/lite/.claude/rules/stuck-signal-diagnostic.md +111 -0
- package/dist/lite/.claude/rules/substrate-config-schema.md +85 -0
- package/dist/lite/.claude/rules/test-list-discipline.md +129 -0
- package/dist/lite/.claude/rules/test-sufficiency.md +186 -0
- package/dist/lite/.claude/rules/testing-tier-config.md +125 -0
- package/dist/lite/.claude/rules/testing.md +38 -0
- package/dist/lite/.claude/rules/turn-estimate-grounding.md +82 -0
- package/dist/lite/.claude/rules/visual-hierarchy.md +427 -0
- package/dist/lite/.claude/rules/we-dont-break-adopters.md +103 -0
- package/dist/lite/.claude/rules/whereami-load-bearing.md +184 -0
- package/dist/lite/.claude/rules/writing-craft-discipline.md +72 -0
- package/dist/lite/.claude/rules/wu-sequencing-compounds.md +119 -0
- package/dist/lite/.claude/skills/build/SKILL.md +640 -0
- package/dist/lite/.claude/skills/chronicle/SKILL.md +55 -0
- package/dist/lite/.claude/skills/clean-artifacts/SKILL.md +249 -0
- package/dist/lite/.claude/skills/decompose/SKILL.md +280 -0
- package/dist/lite/.claude/skills/diagnose/SKILL.md +297 -0
- package/dist/lite/.claude/skills/feynman/SKILL.md +90 -0
- package/dist/lite/.claude/skills/howdoi/SKILL.md +105 -0
- package/dist/lite/.claude/skills/ia-model/SKILL.md +108 -0
- package/dist/lite/.claude/skills/interaction-design/SKILL.md +112 -0
- package/dist/lite/.claude/skills/interpret-input/SKILL.md +180 -0
- package/dist/lite/.claude/skills/journal/SKILL.md +209 -0
- package/dist/lite/.claude/skills/kiss/SKILL.md +449 -0
- package/dist/lite/.claude/skills/launch/SKILL.md +915 -0
- package/dist/lite/.claude/skills/lean-canvas/SKILL.md +332 -0
- package/dist/lite/.claude/skills/longrun/SKILL.md +512 -0
- package/dist/lite/.claude/skills/luminary/SKILL.md +481 -0
- package/dist/lite/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +1640 -0
- package/dist/lite/.claude/skills/pattern-review/SKILL.md +99 -0
- package/dist/lite/.claude/skills/personas/SKILL.md +207 -0
- package/dist/lite/.claude/skills/promote/SKILL.md +283 -0
- package/dist/lite/.claude/skills/requirement/SKILL.md +98 -0
- package/dist/lite/.claude/skills/retro/SKILL.md +117 -0
- package/dist/lite/.claude/skills/riff/SKILL.md +114 -0
- package/dist/lite/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
- package/dist/lite/.claude/skills/session-end/SKILL.md +309 -0
- package/dist/lite/.claude/skills/session-log/SKILL.md +299 -0
- package/dist/lite/.claude/skills/skills/SKILL.md +228 -0
- package/dist/lite/.claude/skills/spec/SKILL.md +105 -0
- package/dist/lite/.claude/skills/sprint/SKILL.md +418 -0
- package/dist/lite/.claude/skills/stage/SKILL.md +384 -0
- package/dist/lite/.claude/skills/state-a-problem/SKILL.md +185 -0
- package/dist/lite/.claude/skills/temperance/SKILL.md +108 -0
- package/dist/lite/.claude/skills/use-case/SKILL.md +417 -0
- package/dist/lite/.claude/skills/user-stories/SKILL.md +268 -0
- package/dist/lite/.claude/skills/value-prop/SKILL.md +251 -0
- package/dist/lite/.claude/skills/verify/SKILL.md +160 -0
- package/dist/lite/.claude/skills/visual-review/SKILL.md +503 -0
- package/dist/lite/.claude/skills/whats-the-plan/SKILL.md +202 -0
- package/dist/lite/.claude/skills/whereami/SKILL.md +307 -0
- package/dist/lite/AGENTS.md +79 -0
- package/dist/lite/CLAUDE-lite.md +85 -0
- package/dist/lite/CODE_OF_CONDUCT.md +28 -0
- package/dist/lite/CONTRIBUTING.md +177 -0
- package/dist/lite/README.md +173 -0
- package/dist/lite/SECURITY.md +19 -0
- package/dist/lite/architecture/decisions/ADR-029-release-pipeline.md +79 -0
- package/dist/lite/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
- package/dist/lite/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
- package/dist/lite/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
- package/dist/lite/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
- package/dist/lite/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
- package/dist/lite/lib/clean-artifacts-sweep.sh +112 -0
- package/dist/lite/lib/code-comment-discipline.sh +144 -0
- package/dist/lite/lib/composer-preflight.sh +459 -0
- package/dist/lite/lib/deferred-actions.sh +146 -0
- package/dist/lite/lib/hook-header-parser.sh +61 -0
- package/dist/lite/lib/hook-heartbeat.sh +152 -0
- package/dist/lite/lib/hook-inject.sh +255 -0
- package/dist/lite/lib/hook-installer.sh +195 -0
- package/dist/lite/lib/luminary-pick.sh +96 -0
- package/dist/lite/lib/output-discipline.sh +143 -0
- package/dist/lite/lib/prose-scan-boundary.sh +171 -0
- package/dist/lite/lib/rewrite-check.sh +214 -0
- package/dist/lite/lib/session-rescue.sh +151 -0
- package/dist/lite/lib/source-graph-walker.sh +277 -0
- package/dist/lite/lib/state.sh +1372 -0
- package/dist/lite/lib/telemetry.sh +205 -0
- package/dist/lite/lib/tier-check.sh +187 -0
- package/dist/lite/lib/tier-dependency-audit.sh +1088 -0
- package/dist/lite/presence/install/bassclef-hook-connect.sh +178 -0
- package/dist/lite/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
- package/dist/lite/presence/install/bassclef-sync.template.sh +2278 -0
- package/dist/lite/presence/install/schedule-auto-save.cron.sh +88 -0
- package/dist/lite/presence/install/schedule-auto-save.taskscheduler.md +122 -0
- package/dist/lite/scripts/aggregate-telemetry.sh +217 -0
- package/dist/lite/scripts/analyze-tier-dependencies.sh +239 -0
- package/dist/lite/scripts/generate-lite-manifest.sh +505 -0
- package/dist/lite/scripts/generate-tier-manifest.sh +28 -0
- package/dist/lite/scripts/intent-drift-check.sh +456 -0
- package/dist/lite/scripts/lite-manifest-drift-check.sh +146 -0
- package/dist/lite/scripts/render-lite-manifest-doc.sh +150 -0
- package/dist/lite/standards/adr-template.md +86 -0
- package/dist/lite/standards/api-conventions/nextjs.md +84 -0
- package/dist/lite/standards/artifact-composition.md +209 -0
- package/dist/lite/standards/bash-hook-safety.md +246 -0
- package/dist/lite/standards/bassclef-configs-schema.md +232 -0
- package/dist/lite/standards/bassclef-evolution.md +143 -0
- package/dist/lite/standards/bassclef-internal-jargon.md +244 -0
- package/dist/lite/standards/bassclef-managed-sentinel.md +96 -0
- package/dist/lite/standards/bassclef-source-config.md +228 -0
- package/dist/lite/standards/branch-stacking.md +408 -0
- package/dist/lite/standards/code-safety-principles.md +176 -0
- package/dist/lite/standards/composer-prerequisites.md +155 -0
- package/dist/lite/standards/deferred-actions-schema.md +204 -0
- package/dist/lite/standards/dependency-discipline/cargo.md +39 -0
- package/dist/lite/standards/dependency-discipline/gem.md +43 -0
- package/dist/lite/standards/dependency-discipline/go-mod.md +41 -0
- package/dist/lite/standards/dependency-discipline/npm.md +42 -0
- package/dist/lite/standards/dependency-discipline/pip.md +42 -0
- package/dist/lite/standards/deployment-topology/ec2-tailscale.md +225 -0
- package/dist/lite/standards/deployment-topology.md +69 -0
- package/dist/lite/standards/docs-sync-allowlist.md +76 -0
- package/dist/lite/standards/domain-and-dns.md +145 -0
- package/dist/lite/standards/frontend-stack.md +67 -0
- package/dist/lite/standards/frontmatter-schema.md +154 -0
- package/dist/lite/standards/graceful-exit.md +227 -0
- package/dist/lite/standards/hook-idempotency.md +102 -0
- package/dist/lite/standards/hook-injection-discipline.md +202 -0
- package/dist/lite/standards/hook-install-class.md +215 -0
- package/dist/lite/standards/input-handler-interface.md +152 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +180 -0
- package/dist/lite/standards/lite-manifest.json +2797 -0
- package/dist/lite/standards/luminary-matching.md +105 -0
- package/dist/lite/standards/luminary-problem-patterns.md +481 -0
- package/dist/lite/standards/migration-discipline/active-record.md +50 -0
- package/dist/lite/standards/migration-discipline/alembic.md +43 -0
- package/dist/lite/standards/migration-discipline/gorm.md +50 -0
- package/dist/lite/standards/migration-discipline/prisma.md +53 -0
- package/dist/lite/standards/migration-discipline/sqlalchemy.md +51 -0
- package/dist/lite/standards/mobile-ephemeral-session.md +167 -0
- package/dist/lite/standards/model-routing-discipline.md +160 -0
- package/dist/lite/standards/ogilvy-writing-rules.md +225 -0
- package/dist/lite/standards/opener-discipline.md +96 -0
- package/dist/lite/standards/operator-facing-prose-discipline.md +201 -0
- package/dist/lite/standards/persona-schema.md +229 -0
- package/dist/lite/standards/pluggable-luminaries.md +323 -0
- package/dist/lite/standards/pr-body-discipline.md +115 -0
- package/dist/lite/standards/preview-state-schema.md +189 -0
- package/dist/lite/standards/project-directory-layout.md +276 -0
- package/dist/lite/standards/release-tagging.md +137 -0
- package/dist/lite/standards/reserved-skill-names.md +120 -0
- package/dist/lite/standards/scannable-multi-option-output.md +265 -0
- package/dist/lite/standards/sdlc-compliance.md +286 -0
- package/dist/lite/standards/sdlc-gates/typescript.md +57 -0
- package/dist/lite/standards/secrets-lifecycle.md +210 -0
- package/dist/lite/standards/security-scanner-adapter.md +145 -0
- package/dist/lite/standards/session-board.md +256 -0
- package/dist/lite/standards/skill-output-discipline.md +121 -0
- package/dist/lite/standards/state-spine-contract.md +255 -0
- package/dist/lite/standards/state-spine.md +511 -0
- package/dist/lite/standards/steering-hints/kiss-words.md +11 -0
- package/dist/lite/standards/substrate-config-schema.md +267 -0
- package/dist/lite/standards/tech-stack-config.md +109 -0
- package/dist/lite/standards/tier-dependency-analysis.md +167 -0
- package/dist/lite/standards/tier-runtime-deps/lite.md +57 -0
- package/dist/lite/standards/tier-tag-schema.md +155 -0
- package/dist/lite/standards/two-layer-config.md +99 -0
- package/dist/lite/standards/use-case-format.md +292 -0
- package/dist/lite/standards/user-story-invest.md +268 -0
- package/dist/lite/standards/velocity-and-appetite.md +229 -0
- package/dist/lite/standards/voice-input-pattern.md +119 -0
- package/dist/lite/standards/whereami-schema.md +301 -0
- package/dist/lite/standards/worktree-management.md +211 -0
- package/dist/lite/standards/writing-guide.md +213 -0
- package/dist/lite/templates/chronicle-template.md +75 -0
- package/dist/lite/templates/deferred-action-template.md +45 -0
- package/dist/lite/templates/memory-proposal-template.md +77 -0
- package/dist/lite/templates/persona-template.md +200 -0
- package/dist/lite/templates/pr-faq.md +45 -0
- package/dist/lite/templates/secret-rotation-template.md +162 -0
- package/dist/lite/templates/spec-template.md +131 -0
- package/dist/lite/templates/use-case-template.md +194 -0
- package/dist/lite/templates/user-story-template.md +107 -0
- package/dist/lite/templates/whereami-template.md +101 -0
- 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 =
|
|
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:
|
|
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/
|
|
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)
|
|
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({
|
|
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
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
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
|
-
|
|
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
|
-
|
|
970
|
+
prompt("bassclef init: continue? (y/N) ");
|
|
843
971
|
const answer = readOneLineFromStdin();
|
|
844
972
|
if (answer === "" || answer === "y" || answer === "Y") return "upgrade-approved";
|
|
845
|
-
|
|
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,
|
|
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
|
-
|
|
1009
|
+
say(` ${"would create".padEnd(14)} ${targetPath}
|
|
882
1010
|
`);
|
|
883
1011
|
}
|
|
884
1012
|
if (wouldCopy.length > 0) {
|
|
885
|
-
|
|
1013
|
+
say(
|
|
886
1014
|
`bassclef init: ${wouldCopy.length} substrate files would be copied.
|
|
887
1015
|
`
|
|
888
1016
|
);
|
|
889
1017
|
}
|
|
890
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1041
|
+
say(`bassclef init: ${parts.join(", ")}.
|
|
914
1042
|
`);
|
|
915
1043
|
const grandTotal = 1 + result.copied.length;
|
|
916
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1066
|
+
say(
|
|
939
1067
|
`bassclef init: Installed ${copiedCount} of ${declaredCount} hooks (${RESOLVED_TIER} tier).${scopeSuffix}
|
|
940
1068
|
`
|
|
941
1069
|
);
|
|
942
1070
|
}
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1251
|
+
say("bassclef init: already initialized. No changes.\n");
|
|
1070
1252
|
} else {
|
|
1071
|
-
|
|
1253
|
+
say(`bassclef init: ${created} config files created, ${unchanged} unchanged.
|
|
1072
1254
|
`);
|
|
1073
1255
|
}
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
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
|
-
|
|
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
|
|
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
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version: "1.
|
|
1
|
+
export declare const version: "1.1.1";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -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.
|