@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.cjs
CHANGED
|
@@ -313,14 +313,15 @@ function substrateConfigMdTemplate(pkgVersion) {
|
|
|
313
313
|
].join("\n");
|
|
314
314
|
}
|
|
315
315
|
const MANIFEST_SCHEMA_VERSION = "0.1.0";
|
|
316
|
-
const MANIFEST_SHAPE_VERSION =
|
|
316
|
+
const MANIFEST_SHAPE_VERSION = 3;
|
|
317
|
+
const GENERATED_BY = "@thebassclef/lite";
|
|
317
318
|
function manifestTemplate(input) {
|
|
318
319
|
const value = {
|
|
319
320
|
schema_version: MANIFEST_SHAPE_VERSION,
|
|
320
321
|
$bassclef: {
|
|
321
322
|
template: "init.manifest.json",
|
|
322
323
|
manifest_schema_version: MANIFEST_SCHEMA_VERSION,
|
|
323
|
-
generated_by:
|
|
324
|
+
generated_by: GENERATED_BY,
|
|
324
325
|
generated_by_version: input.pkgVersion
|
|
325
326
|
},
|
|
326
327
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -388,7 +389,7 @@ function readManifest(targetDir) {
|
|
|
388
389
|
if (compareSchemaVersion(schema, MANIFEST_SCHEMA_VERSION) > 0) {
|
|
389
390
|
throw new ManifestReadError(
|
|
390
391
|
"SchemaTooNew",
|
|
391
|
-
`manifest schema version ${schema} is newer than this package understands (${MANIFEST_SCHEMA_VERSION}). Upgrade @thebassclef/
|
|
392
|
+
`manifest schema version ${schema} is newer than this package understands (${MANIFEST_SCHEMA_VERSION}). Upgrade @thebassclef/lite.`
|
|
392
393
|
);
|
|
393
394
|
}
|
|
394
395
|
const obj = parsed;
|
|
@@ -518,6 +519,7 @@ function setExecutable(targetPath) {
|
|
|
518
519
|
}
|
|
519
520
|
node_fs.chmodSync(targetPath, HOOK_EXECUTABLE_MODE);
|
|
520
521
|
}
|
|
522
|
+
const CLAUDE_TARGET_ROOT = ".claude";
|
|
521
523
|
const HOOKS_SUBPATH = ".claude/hooks/";
|
|
522
524
|
const SETTINGS_SUBPATH = ".claude/settings.json";
|
|
523
525
|
const CONFIG_FILES = [
|
|
@@ -540,7 +542,10 @@ function copySubstrate(targetDir, options = {}) {
|
|
|
540
542
|
hookCount: 0,
|
|
541
543
|
wiringVersion: manifest.version
|
|
542
544
|
};
|
|
543
|
-
if (options.dryRun)
|
|
545
|
+
if (options.dryRun) {
|
|
546
|
+
result.wouldCopy = [];
|
|
547
|
+
result.wouldCopyEntries = [];
|
|
548
|
+
}
|
|
544
549
|
const files = walkDistTree(bundleRoot);
|
|
545
550
|
const groups = groupByTopDirectory(files);
|
|
546
551
|
const bundleHookRelPaths = new Set(files.filter(isHookFile));
|
|
@@ -696,6 +701,11 @@ function copyOne(relPath, bundleRoot, options, result, scopeDecision) {
|
|
|
696
701
|
const outputContent = options.transform ? options.transform(adopterRelPath, content) : content;
|
|
697
702
|
if (options.dryRun) {
|
|
698
703
|
result.wouldCopy?.push(adopterRelPath);
|
|
704
|
+
result.wouldCopyEntries?.push({
|
|
705
|
+
path: adopterRelPath,
|
|
706
|
+
scope,
|
|
707
|
+
content_hash_sha256: hashContent(outputContent)
|
|
708
|
+
});
|
|
699
709
|
return "wouldCopy";
|
|
700
710
|
}
|
|
701
711
|
try {
|
|
@@ -705,7 +715,11 @@ function copyOne(relPath, bundleRoot, options, result, scopeDecision) {
|
|
|
705
715
|
setExecutable(targetPath);
|
|
706
716
|
}
|
|
707
717
|
result.copied.push(adopterRelPath);
|
|
708
|
-
result.copiedEntries.push({
|
|
718
|
+
result.copiedEntries.push({
|
|
719
|
+
path: adopterRelPath,
|
|
720
|
+
scope,
|
|
721
|
+
content_hash_sha256: hashContent(outputContent)
|
|
722
|
+
});
|
|
709
723
|
return "copied";
|
|
710
724
|
} catch (e) {
|
|
711
725
|
if (e instanceof WriteError) {
|
|
@@ -782,7 +796,92 @@ function dirExists(p) {
|
|
|
782
796
|
return false;
|
|
783
797
|
}
|
|
784
798
|
}
|
|
799
|
+
const FAMILIES = [
|
|
800
|
+
"skills",
|
|
801
|
+
"rules",
|
|
802
|
+
"agents",
|
|
803
|
+
"luminaries",
|
|
804
|
+
"hooks",
|
|
805
|
+
"libs",
|
|
806
|
+
"adrs",
|
|
807
|
+
"standards",
|
|
808
|
+
"templates",
|
|
809
|
+
"presence-templates",
|
|
810
|
+
"scripts",
|
|
811
|
+
"root-docs",
|
|
812
|
+
"other"
|
|
813
|
+
];
|
|
814
|
+
const UNDER_CLAUDE = `${CLAUDE_TARGET_ROOT}/`;
|
|
815
|
+
const PREFIX_RULES = [
|
|
816
|
+
[`${UNDER_CLAUDE}skills/`, "skills"],
|
|
817
|
+
[`${UNDER_CLAUDE}rules/`, "rules"],
|
|
818
|
+
[`${UNDER_CLAUDE}agents/`, "agents"],
|
|
819
|
+
[`${UNDER_CLAUDE}luminaries/`, "luminaries"],
|
|
820
|
+
[`${UNDER_CLAUDE}hooks/`, "hooks"],
|
|
821
|
+
["lib/", "libs"],
|
|
822
|
+
["architecture/decisions/", "adrs"],
|
|
823
|
+
["standards/", "standards"],
|
|
824
|
+
["templates/", "templates"],
|
|
825
|
+
["presence/install/", "presence-templates"],
|
|
826
|
+
["scripts/", "scripts"]
|
|
827
|
+
];
|
|
828
|
+
function classifyEntry(path) {
|
|
829
|
+
for (const [prefix, family] of PREFIX_RULES) {
|
|
830
|
+
if (path.startsWith(prefix)) return family;
|
|
831
|
+
}
|
|
832
|
+
if (!path.includes("/") && /^[A-Z]/.test(path)) return "root-docs";
|
|
833
|
+
return "other";
|
|
834
|
+
}
|
|
835
|
+
function emptyCatalogCounts() {
|
|
836
|
+
const out = {};
|
|
837
|
+
for (const f of FAMILIES) out[f] = 0;
|
|
838
|
+
return out;
|
|
839
|
+
}
|
|
840
|
+
function buildInitReport(input) {
|
|
841
|
+
const catalog = emptyCatalogCounts();
|
|
842
|
+
let project = 0;
|
|
843
|
+
let user = 0;
|
|
844
|
+
for (const e of input.entries) {
|
|
845
|
+
catalog[classifyEntry(e.path)] += 1;
|
|
846
|
+
if (e.scope === "user") user += 1;
|
|
847
|
+
else project += 1;
|
|
848
|
+
}
|
|
849
|
+
const refused = input.refused.length;
|
|
850
|
+
const errored = input.errored.length;
|
|
851
|
+
const written = input.configs.length + input.entries.length;
|
|
852
|
+
return {
|
|
853
|
+
schema_version: 3,
|
|
854
|
+
tier: input.tier,
|
|
855
|
+
totals: {
|
|
856
|
+
files: written + refused + errored,
|
|
857
|
+
written,
|
|
858
|
+
project,
|
|
859
|
+
user,
|
|
860
|
+
configs: input.configs.length
|
|
861
|
+
},
|
|
862
|
+
catalog,
|
|
863
|
+
hooks: {
|
|
864
|
+
declared: input.hookCount,
|
|
865
|
+
copied: input.declaredHooksCopied,
|
|
866
|
+
files: catalog.hooks
|
|
867
|
+
},
|
|
868
|
+
refused,
|
|
869
|
+
errored,
|
|
870
|
+
failed: refused + errored
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
function renderJsonReport(report, write) {
|
|
874
|
+
write(JSON.stringify(report) + "\n");
|
|
875
|
+
}
|
|
785
876
|
const RESOLVED_TIER = "lite";
|
|
877
|
+
const SAY_HUMAN = (s) => {
|
|
878
|
+
process.stdout.write(s);
|
|
879
|
+
};
|
|
880
|
+
const SAY_QUIET = () => {
|
|
881
|
+
};
|
|
882
|
+
function makeSay(json) {
|
|
883
|
+
return json ? SAY_QUIET : SAY_HUMAN;
|
|
884
|
+
}
|
|
786
885
|
const PLACEHOLDER_FILES = /* @__PURE__ */ new Set([
|
|
787
886
|
"CLAUDE.md",
|
|
788
887
|
"docs/whereami.md",
|
|
@@ -824,7 +923,7 @@ function runInit(argv) {
|
|
|
824
923
|
}
|
|
825
924
|
throw e;
|
|
826
925
|
}
|
|
827
|
-
const advisoryOutcome = maybeEmitUpgradeAdvisory(targetDir, args.yes);
|
|
926
|
+
const advisoryOutcome = maybeEmitUpgradeAdvisory(targetDir, args.yes, args.json);
|
|
828
927
|
if (advisoryOutcome === "refused") return 1;
|
|
829
928
|
const upgradeApproved = advisoryOutcome === "upgrade-approved";
|
|
830
929
|
if (!args.force && !args.dryRun && !upgradeApproved) {
|
|
@@ -846,26 +945,55 @@ function runInit(argv) {
|
|
|
846
945
|
templateVersion: SUBSTRATE_CONFIG_TEMPLATE_VERSION
|
|
847
946
|
}
|
|
848
947
|
];
|
|
948
|
+
const say = makeSay(args.json);
|
|
849
949
|
if (args.dryRun) {
|
|
850
|
-
runDryRun$1(plans);
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
950
|
+
runDryRun$1(plans, say);
|
|
951
|
+
const outcome = dispatchSubstrateCopy(
|
|
952
|
+
targetDir,
|
|
953
|
+
args.force || upgradeApproved,
|
|
954
|
+
args.verbose,
|
|
955
|
+
true,
|
|
956
|
+
args.allowRoot,
|
|
957
|
+
say
|
|
958
|
+
);
|
|
959
|
+
if (args.json) {
|
|
960
|
+
const report = buildInitReport({
|
|
961
|
+
entries: outcome.result?.wouldCopyEntries ?? [],
|
|
962
|
+
configs: plans.map((pl) => ({ path: pl.relativePath })),
|
|
963
|
+
refused: outcome.result?.refused ?? [],
|
|
964
|
+
// A dry run still reads every source file, so it can still fail
|
|
965
|
+
// to read one. Hard-coding this empty hid those failures from
|
|
966
|
+
// the JSON (RFC-0005 A-3).
|
|
967
|
+
errored: outcome.result?.errored ?? [],
|
|
968
|
+
hookCount: outcome.result?.hookCount ?? 0,
|
|
969
|
+
declaredHooksCopied: 0,
|
|
970
|
+
tier: RESOLVED_TIER
|
|
971
|
+
});
|
|
972
|
+
renderJsonReport(report, (t) => {
|
|
973
|
+
process.stdout.write(t);
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
return outcome.code;
|
|
977
|
+
}
|
|
978
|
+
return runReal$1(plans, args.force || upgradeApproved, args.verbose, targetDir, args.allowRoot, args.json, say);
|
|
979
|
+
}
|
|
980
|
+
function maybeEmitUpgradeAdvisory(targetDir, yes, json) {
|
|
981
|
+
const prompt = json ? (t) => {
|
|
982
|
+
process.stderr.write(t);
|
|
983
|
+
} : SAY_HUMAN;
|
|
856
984
|
const manifestPath = node_path.join(targetDir, MANIFEST_RELATIVE_PATH);
|
|
857
985
|
if (!node_fs.existsSync(manifestPath)) return "ok";
|
|
858
986
|
const version = readManifestShapeVersion(targetDir);
|
|
859
987
|
if (version !== null && version >= 2) return "ok";
|
|
860
|
-
|
|
988
|
+
prompt(
|
|
861
989
|
`bassclef init: cli 1.0.1 introduces user-scope hook installation at ~/${HOOKS_SUBPATH}. cli 1.0.0 did not write there.
|
|
862
990
|
`
|
|
863
991
|
);
|
|
864
992
|
if (yes) return "upgrade-approved";
|
|
865
|
-
|
|
993
|
+
prompt("bassclef init: continue? (y/N) ");
|
|
866
994
|
const answer = readOneLineFromStdin();
|
|
867
995
|
if (answer === "" || answer === "y" || answer === "Y") return "upgrade-approved";
|
|
868
|
-
|
|
996
|
+
prompt("bassclef init: aborted by adopter.\n");
|
|
869
997
|
return "refused";
|
|
870
998
|
}
|
|
871
999
|
function readOneLineFromStdin() {
|
|
@@ -877,7 +1005,7 @@ function readOneLineFromStdin() {
|
|
|
877
1005
|
return "";
|
|
878
1006
|
}
|
|
879
1007
|
}
|
|
880
|
-
function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot,
|
|
1008
|
+
function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, say) {
|
|
881
1009
|
const substitute = makePlaceholderTransform(targetDir);
|
|
882
1010
|
let result;
|
|
883
1011
|
try {
|
|
@@ -891,9 +1019,9 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
|
|
|
891
1019
|
if (e instanceof CopyFailure) {
|
|
892
1020
|
process.stderr.write(`bassclef init: ${e.message}
|
|
893
1021
|
`);
|
|
894
|
-
if (e.kind === "ManifestMissing") return 4;
|
|
895
|
-
if (e.kind === "SchemaIncompatible") return 5;
|
|
896
|
-
return 2;
|
|
1022
|
+
if (e.kind === "ManifestMissing") return { code: 4 };
|
|
1023
|
+
if (e.kind === "SchemaIncompatible") return { code: 5 };
|
|
1024
|
+
return { code: 2 };
|
|
897
1025
|
}
|
|
898
1026
|
throw e;
|
|
899
1027
|
}
|
|
@@ -901,23 +1029,23 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
|
|
|
901
1029
|
const wouldCopy = result.wouldCopy ?? [];
|
|
902
1030
|
for (const relativePath of wouldCopy) {
|
|
903
1031
|
const targetPath = node_path.join(targetDir, relativePath);
|
|
904
|
-
|
|
1032
|
+
say(` ${"would create".padEnd(14)} ${targetPath}
|
|
905
1033
|
`);
|
|
906
1034
|
}
|
|
907
1035
|
if (wouldCopy.length > 0) {
|
|
908
|
-
|
|
1036
|
+
say(
|
|
909
1037
|
`bassclef init: ${wouldCopy.length} substrate files would be copied.
|
|
910
1038
|
`
|
|
911
1039
|
);
|
|
912
1040
|
}
|
|
913
|
-
|
|
1041
|
+
say(
|
|
914
1042
|
`bassclef init: ${result.hookCount} hooks armed (${RESOLVED_TIER} tier).
|
|
915
1043
|
`
|
|
916
1044
|
);
|
|
917
|
-
return 0;
|
|
1045
|
+
return { code: 0, result };
|
|
918
1046
|
}
|
|
919
1047
|
if (result.copied.length === 0 && result.refused.length === 0 && result.errored.length === 0) {
|
|
920
|
-
return 0;
|
|
1048
|
+
return { code: 0, result };
|
|
921
1049
|
}
|
|
922
1050
|
const groupCounts = /* @__PURE__ */ new Map();
|
|
923
1051
|
for (const path of result.copied) {
|
|
@@ -926,17 +1054,17 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
|
|
|
926
1054
|
groupCounts.set(top, (groupCounts.get(top) ?? 0) + 1);
|
|
927
1055
|
}
|
|
928
1056
|
for (const [directory, count] of groupCounts) {
|
|
929
|
-
|
|
1057
|
+
say(` ${directory}: ${count} files copied
|
|
930
1058
|
`);
|
|
931
1059
|
}
|
|
932
1060
|
const parts = [];
|
|
933
1061
|
if (result.copied.length > 0) parts.push(`${result.copied.length} substrate files copied`);
|
|
934
1062
|
if (result.refused.length > 0) parts.push(`${result.refused.length} refused`);
|
|
935
1063
|
if (result.errored.length > 0) parts.push(`${result.errored.length} error(s)`);
|
|
936
|
-
|
|
1064
|
+
say(`bassclef init: ${parts.join(", ")}.
|
|
937
1065
|
`);
|
|
938
1066
|
const grandTotal = 1 + result.copied.length;
|
|
939
|
-
|
|
1067
|
+
say(
|
|
940
1068
|
`bassclef init: ${grandTotal} files total (1 config + ${result.copied.length} substrate).
|
|
941
1069
|
`
|
|
942
1070
|
);
|
|
@@ -953,33 +1081,87 @@ function dispatchSubstrateCopy(targetDir, force, verbose, dryRun, allowRoot, jso
|
|
|
953
1081
|
const projectScope = copiedHookEntries.filter((e) => e.scope === "project").length;
|
|
954
1082
|
const scopeSuffix = userScope + projectScope > 0 ? ` ${projectScope} in <repo>/${HOOKS_SUBPATH.replace(/\/$/, "")}, ${userScope} in ~/${HOOKS_SUBPATH.replace(/\/$/, "")}.` : "";
|
|
955
1083
|
if (failedCount > 0) {
|
|
956
|
-
|
|
1084
|
+
say(
|
|
957
1085
|
`bassclef init: Installed ${copiedCount} of ${declaredCount} hooks (${RESOLVED_TIER} tier).${scopeSuffix} ${failedCount} failed — see errors above. Rerun bassclef init to retry.
|
|
958
1086
|
`
|
|
959
1087
|
);
|
|
960
1088
|
} else {
|
|
961
|
-
|
|
1089
|
+
say(
|
|
962
1090
|
`bassclef init: Installed ${copiedCount} of ${declaredCount} hooks (${RESOLVED_TIER} tier).${scopeSuffix}
|
|
963
1091
|
`
|
|
964
1092
|
);
|
|
965
1093
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1094
|
+
const catalogCounts = {
|
|
1095
|
+
skills: 0,
|
|
1096
|
+
rules: 0,
|
|
1097
|
+
agents: 0,
|
|
1098
|
+
luminaries: 0,
|
|
1099
|
+
libs: 0,
|
|
1100
|
+
adrs: 0,
|
|
1101
|
+
standards: 0,
|
|
1102
|
+
templates: 0,
|
|
1103
|
+
"presence-templates": 0,
|
|
1104
|
+
scripts: 0,
|
|
1105
|
+
"root-docs": 0
|
|
1106
|
+
};
|
|
1107
|
+
const SKILLS_PREFIX = `${CLAUDE_TARGET_ROOT}/skills/`;
|
|
1108
|
+
const RULES_PREFIX = `${CLAUDE_TARGET_ROOT}/rules/`;
|
|
1109
|
+
const AGENTS_PREFIX = `${CLAUDE_TARGET_ROOT}/agents/`;
|
|
1110
|
+
const LUMINARIES_PREFIX = `${CLAUDE_TARGET_ROOT}/luminaries/`;
|
|
1111
|
+
const CLAUDE_ROOT_PREFIX = `${CLAUDE_TARGET_ROOT}/`;
|
|
1112
|
+
for (const entry of result.copiedEntries) {
|
|
1113
|
+
if (entry.path.startsWith(SKILLS_PREFIX)) catalogCounts.skills += 1;
|
|
1114
|
+
else if (entry.path.startsWith(RULES_PREFIX)) catalogCounts.rules += 1;
|
|
1115
|
+
else if (entry.path.startsWith(AGENTS_PREFIX)) catalogCounts.agents += 1;
|
|
1116
|
+
else if (entry.path.startsWith(LUMINARIES_PREFIX)) catalogCounts.luminaries += 1;
|
|
1117
|
+
else if (entry.path.startsWith("lib/")) catalogCounts.libs += 1;
|
|
1118
|
+
else if (entry.path.startsWith("architecture/decisions/")) catalogCounts.adrs += 1;
|
|
1119
|
+
else if (entry.path.startsWith("standards/")) catalogCounts.standards += 1;
|
|
1120
|
+
else if (entry.path.startsWith("templates/")) catalogCounts.templates += 1;
|
|
1121
|
+
else if (entry.path.startsWith("presence/install/")) catalogCounts["presence-templates"] += 1;
|
|
1122
|
+
else if (entry.path.startsWith("scripts/")) catalogCounts.scripts += 1;
|
|
1123
|
+
else if (!entry.path.startsWith(CLAUDE_ROOT_PREFIX) && !entry.path.includes("/") && /^[A-Z]/.test(entry.path)) {
|
|
1124
|
+
catalogCounts["root-docs"] += 1;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const claudeCounts = [
|
|
1128
|
+
catalogCounts.skills > 0 ? `${catalogCounts.skills} skills` : null,
|
|
1129
|
+
catalogCounts.rules > 0 ? `${catalogCounts.rules} rules` : null,
|
|
1130
|
+
catalogCounts.agents > 0 ? `${catalogCounts.agents} agents` : null,
|
|
1131
|
+
catalogCounts.luminaries > 0 ? `${catalogCounts.luminaries} luminaries` : null
|
|
1132
|
+
].filter((s) => s !== null);
|
|
1133
|
+
if (claudeCounts.length > 0) {
|
|
1134
|
+
say(
|
|
1135
|
+
`bassclef init: Installed ${claudeCounts.join(", ")} under <repo>/.claude/.
|
|
1136
|
+
`
|
|
1137
|
+
);
|
|
975
1138
|
}
|
|
1139
|
+
const otherCounts = [
|
|
1140
|
+
catalogCounts.libs > 0 ? `${catalogCounts.libs} libs` : null,
|
|
1141
|
+
catalogCounts.adrs > 0 ? `${catalogCounts.adrs} ADRs` : null,
|
|
1142
|
+
catalogCounts.templates > 0 ? `${catalogCounts.templates} templates` : null,
|
|
1143
|
+
catalogCounts["presence-templates"] > 0 ? `${catalogCounts["presence-templates"]} presence-templates` : null,
|
|
1144
|
+
catalogCounts.standards > 0 ? `${catalogCounts.standards} standards` : null,
|
|
1145
|
+
catalogCounts["root-docs"] > 0 ? `${catalogCounts["root-docs"]} root-docs` : null,
|
|
1146
|
+
catalogCounts.scripts > 0 ? `${catalogCounts.scripts} scripts` : null
|
|
1147
|
+
].filter((s) => s !== null);
|
|
1148
|
+
if (otherCounts.length > 0) {
|
|
1149
|
+
say(
|
|
1150
|
+
`bassclef init: Installed ${otherCounts.join(", ")} under <repo>/.
|
|
1151
|
+
`
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
say(
|
|
1155
|
+
`bassclef init: ${result.refused.length} files refused (path collision).` + (result.refused.length > 0 ? ` Use --force to overwrite existing files.` : ``) + `
|
|
1156
|
+
`
|
|
1157
|
+
);
|
|
976
1158
|
if (verbose && result.erroredMessages) {
|
|
977
1159
|
for (const msg of result.erroredMessages) {
|
|
978
1160
|
process.stderr.write(` substrate: ${msg}
|
|
979
1161
|
`);
|
|
980
1162
|
}
|
|
981
1163
|
}
|
|
982
|
-
return result.errored.length > 0 ? 2 : 0;
|
|
1164
|
+
return { code: result.errored.length > 0 ? 2 : 0, result };
|
|
983
1165
|
}
|
|
984
1166
|
function makePlaceholderTransform(targetDir) {
|
|
985
1167
|
const repoName = node_path.basename(targetDir);
|
|
@@ -989,7 +1171,7 @@ function makePlaceholderTransform(targetDir) {
|
|
|
989
1171
|
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);
|
|
990
1172
|
};
|
|
991
1173
|
}
|
|
992
|
-
function runDryRun$1(plans) {
|
|
1174
|
+
function runDryRun$1(plans, say) {
|
|
993
1175
|
for (const p of plans) {
|
|
994
1176
|
let planned;
|
|
995
1177
|
let extra = "";
|
|
@@ -1009,12 +1191,12 @@ function runDryRun$1(plans) {
|
|
|
1009
1191
|
planned = "would skip";
|
|
1010
1192
|
}
|
|
1011
1193
|
}
|
|
1012
|
-
|
|
1194
|
+
say(` ${planned.padEnd(14)} ${p.fullPath}${extra}
|
|
1013
1195
|
`);
|
|
1014
1196
|
}
|
|
1015
1197
|
return 0;
|
|
1016
1198
|
}
|
|
1017
|
-
function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
|
|
1199
|
+
function runReal$1(plans, force, verbose, targetDir, allowRoot, json, say) {
|
|
1018
1200
|
const results = [];
|
|
1019
1201
|
let anyRefused = false;
|
|
1020
1202
|
let anyError = false;
|
|
@@ -1062,7 +1244,7 @@ function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
|
|
|
1062
1244
|
if (r.outcome === "error") label = `error (${r.message ?? "unknown"})`;
|
|
1063
1245
|
else if (r.outcome === "refused") label = "refused";
|
|
1064
1246
|
else label = r.outcome;
|
|
1065
|
-
|
|
1247
|
+
say(` ${label.padEnd(10)} ${r.plan.fullPath}
|
|
1066
1248
|
`);
|
|
1067
1249
|
}
|
|
1068
1250
|
}
|
|
@@ -1084,38 +1266,59 @@ function runReal$1(plans, force, verbose, targetDir, allowRoot, json) {
|
|
|
1084
1266
|
return 2;
|
|
1085
1267
|
}
|
|
1086
1268
|
if (anyRefused && created > 0) {
|
|
1087
|
-
|
|
1269
|
+
say(
|
|
1088
1270
|
`bassclef init: ${created} config files created, ${unchanged} unchanged. Pass --force to overwrite.
|
|
1089
1271
|
`
|
|
1090
1272
|
);
|
|
1091
1273
|
} else if (created === 0 && unchanged === plans.length) {
|
|
1092
|
-
|
|
1274
|
+
say("bassclef init: already initialized. No changes.\n");
|
|
1093
1275
|
} else {
|
|
1094
|
-
|
|
1276
|
+
say(`bassclef init: ${created} config files created, ${unchanged} unchanged.
|
|
1095
1277
|
`);
|
|
1096
1278
|
}
|
|
1097
|
-
const
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1279
|
+
const walker = dispatchSubstrateCopy(targetDir, force, verbose, false, allowRoot, say);
|
|
1280
|
+
const declaredLeaves = readDeclaredCommandLeaves(
|
|
1281
|
+
node_path.join(targetDir, ".claude", "settings.json")
|
|
1282
|
+
);
|
|
1283
|
+
const declaredHooksCopied = (walker.result?.copiedEntries ?? []).filter(
|
|
1284
|
+
(e) => e.path.startsWith(HOOKS_SUBPATH) && e.path.endsWith(".sh") && declaredLeaves.has(node_path.basename(e.path))
|
|
1285
|
+
).length;
|
|
1286
|
+
const report = buildInitReport({
|
|
1287
|
+
entries: walker.result?.copiedEntries ?? [],
|
|
1288
|
+
configs: results.map((r) => ({ path: r.plan.relativePath })),
|
|
1289
|
+
refused: walker.result?.refused ?? [],
|
|
1290
|
+
errored: walker.result?.errored ?? [],
|
|
1291
|
+
hookCount: walker.result?.hookCount ?? 0,
|
|
1292
|
+
declaredHooksCopied,
|
|
1293
|
+
tier: RESOLVED_TIER
|
|
1294
|
+
});
|
|
1295
|
+
writeManifest(targetDir, results, walker.result);
|
|
1296
|
+
if (walker.code === 0) {
|
|
1297
|
+
say(
|
|
1101
1298
|
`bassclef init: your substrate lives under .claude/. Add .claude/ to .gitignore if you have not.
|
|
1102
1299
|
`
|
|
1103
1300
|
);
|
|
1104
1301
|
}
|
|
1105
|
-
|
|
1302
|
+
if (json) {
|
|
1303
|
+
renderJsonReport(report, (t) => {
|
|
1304
|
+
process.stdout.write(t);
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
return walker.code;
|
|
1106
1308
|
}
|
|
1107
1309
|
function shouldRefuseRoot(currentUid, allowRoot) {
|
|
1108
1310
|
if (currentUid === void 0) return false;
|
|
1109
1311
|
if (currentUid !== 0) return false;
|
|
1110
1312
|
return !allowRoot;
|
|
1111
1313
|
}
|
|
1112
|
-
function writeManifest(targetDir, results) {
|
|
1314
|
+
function writeManifest(targetDir, results, walkerResult) {
|
|
1113
1315
|
const entries = results.map((r) => {
|
|
1114
1316
|
const entry = {
|
|
1115
1317
|
path: r.plan.relativePath,
|
|
1116
1318
|
template: r.plan.templateName,
|
|
1117
1319
|
template_version: r.plan.templateVersion,
|
|
1118
|
-
outcome: r.outcome
|
|
1320
|
+
outcome: r.outcome,
|
|
1321
|
+
source: "config-composer"
|
|
1119
1322
|
};
|
|
1120
1323
|
if (r.outcome === "created") {
|
|
1121
1324
|
entry.content_hash_sha256 = hashContent(r.plan.content);
|
|
@@ -1123,6 +1326,38 @@ function writeManifest(targetDir, results) {
|
|
|
1123
1326
|
}
|
|
1124
1327
|
return entry;
|
|
1125
1328
|
});
|
|
1329
|
+
if (walkerResult) {
|
|
1330
|
+
for (const copied of walkerResult.copiedEntries) {
|
|
1331
|
+
entries.push({
|
|
1332
|
+
path: copied.path,
|
|
1333
|
+
template: `bundle:${copied.path}`,
|
|
1334
|
+
template_version: index.version,
|
|
1335
|
+
outcome: "created",
|
|
1336
|
+
source: "bundle",
|
|
1337
|
+
scope: copied.scope,
|
|
1338
|
+
...copied.content_hash_sha256 ? { content_hash_sha256: copied.content_hash_sha256 } : {},
|
|
1339
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
for (const path of walkerResult.refused) {
|
|
1343
|
+
entries.push({
|
|
1344
|
+
path,
|
|
1345
|
+
template: `bundle:${path}`,
|
|
1346
|
+
template_version: index.version,
|
|
1347
|
+
outcome: "refused",
|
|
1348
|
+
source: "bundle"
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
for (const path of walkerResult.errored) {
|
|
1352
|
+
entries.push({
|
|
1353
|
+
path,
|
|
1354
|
+
template: `bundle:${path}`,
|
|
1355
|
+
template_version: index.version,
|
|
1356
|
+
outcome: "error",
|
|
1357
|
+
source: "bundle"
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1126
1361
|
const manifestDir = node_path.join(targetDir, ".bassclef");
|
|
1127
1362
|
const manifestPath = node_path.join(manifestDir, "init.manifest.json");
|
|
1128
1363
|
const content = manifestTemplate({
|
|
@@ -1133,7 +1368,12 @@ function writeManifest(targetDir, results) {
|
|
|
1133
1368
|
try {
|
|
1134
1369
|
mkdirSafely(manifestDir);
|
|
1135
1370
|
writeSafely(manifestPath, content, { force: true });
|
|
1136
|
-
} catch {
|
|
1371
|
+
} catch (e) {
|
|
1372
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
1373
|
+
process.stderr.write(
|
|
1374
|
+
`bassclef init: could not write ${manifestPath} (${reason}). The files were written. Run \`bassclef init --force\` to rebuild the record.
|
|
1375
|
+
`
|
|
1376
|
+
);
|
|
1137
1377
|
}
|
|
1138
1378
|
}
|
|
1139
1379
|
function usage$2() {
|
|
@@ -1584,7 +1824,10 @@ function emitL2Output(decisions, verbose) {
|
|
|
1584
1824
|
}
|
|
1585
1825
|
}
|
|
1586
1826
|
function updateManifestEntry(manifest, path, patch) {
|
|
1587
|
-
const
|
|
1827
|
+
const wantScope = patch.scope;
|
|
1828
|
+
const idx = manifest.files.findIndex(
|
|
1829
|
+
(f) => f.path === path && (wantScope === void 0 || f.scope === wantScope)
|
|
1830
|
+
);
|
|
1588
1831
|
if (idx < 0) {
|
|
1589
1832
|
manifest.files.push({
|
|
1590
1833
|
path,
|