substrata-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/bin.js +15 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-5LCVXNHI.js +1279 -0
- package/dist/chunk-5LCVXNHI.js.map +1 -0
- package/dist/chunk-5V44C5UO.js +1589 -0
- package/dist/chunk-5V44C5UO.js.map +1 -0
- package/dist/dist-OCRLBALV.js +293 -0
- package/dist/dist-OCRLBALV.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/wizard/prompts.ts","../src/util.ts","../src/commands/add.ts","../src/render/context.ts","../src/commands/auto-index.ts","../src/commands/context.ts","../src/commands/doctor.ts","../src/commands/hook.ts","../src/commands/index.ts","../src/commands/init.ts","../src/wizard/init-wizard.ts","../src/mcp-clients/claude-code.ts","../src/mcp-clients/json-config.ts","../src/mcp-clients/cursor.ts","../src/mcp-clients/windsurf.ts","../src/mcp-clients/registry.ts","../src/render/table.ts","../src/commands/list.ts","../src/commands/mcp.ts","../src/commands/memory-update.ts","../src/commands/search.ts","../src/commands/show.ts","../src/commands/supersede.ts"],"sourcesContent":["import { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { registerAddCommand } from './commands/add';\nimport { registerContextCommand } from './commands/context';\nimport { registerDoctorCommand } from './commands/doctor';\nimport { registerHookCommand } from './commands/hook';\nimport { registerIndexCommand } from './commands/index';\nimport { registerInitCommand } from './commands/init';\nimport { registerListCommand } from './commands/list';\nimport { registerMcpCommand } from './commands/mcp';\nimport { registerMemoryUpdateCommand } from './commands/memory-update';\nimport { registerSearchCommand } from './commands/search';\nimport { registerShowCommand } from './commands/show';\nimport { registerSupersedeCommand } from './commands/supersede';\nimport { CliError, out } from './util';\nimport { PromptCancelledError } from './wizard/prompts';\n\n/**\n * Build the commander program. Exported for tests: callers can do\n * `buildProgram().parseAsync(['node','substrata', ...])` and inject a cwd via the\n * hidden global `--cwd` option.\n *\n * Exit codes: 0 success, 1 user/expected errors (friendly, no stack), 2 unexpected.\n */\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name('substrata')\n .description('Shared project memory for AI engineering agents')\n .version('0.1.0')\n // Hidden global flag so tests can run commands against a temp dir.\n .option('--cwd <dir>', 'Run as if invoked from this directory')\n .enablePositionalOptions();\n\n // Don't let commander call process.exit() during tests/embedding.\n program.exitOverride();\n\n registerInitCommand(program);\n registerAddCommand(program);\n registerSearchCommand(program);\n registerContextCommand(program);\n registerIndexCommand(program);\n registerListCommand(program);\n registerShowCommand(program);\n registerDoctorCommand(program);\n registerSupersedeCommand(program);\n registerMemoryUpdateCommand(program);\n registerHookCommand(program);\n registerMcpCommand(program);\n\n return program;\n}\n\n/** Map an unknown error to an exit code, printing a friendly message. */\nfunction reportError(err: unknown): number {\n if (err instanceof CliError) {\n out.err(err.message);\n return err.exitCode;\n }\n if (err instanceof PromptCancelledError) {\n out.info('Cancelled.');\n return 1;\n }\n // Commander throws CommanderError for help/version/parse issues.\n const e = err as { code?: string; exitCode?: number; message?: string };\n if (e && typeof e.code === 'string' && e.code.startsWith('commander.')) {\n // help/version are not failures.\n if (e.code === 'commander.helpDisplayed' || e.code === 'commander.version') return 0;\n if (e.message) out.err(e.message);\n return typeof e.exitCode === 'number' ? e.exitCode : 1;\n }\n // Unexpected: surface the message without a stack, exit 2.\n out.err(`Unexpected error: ${(err as Error)?.message ?? String(err)}`);\n process.stderr.write(`${pc.dim('This is a bug — please file an issue.')}\\n`);\n return 2;\n}\n\n/** Parse argv and run. Returns the process exit code (does not call exit). */\nexport async function runCli(argv: string[]): Promise<number> {\n const program = buildProgram();\n try {\n await program.parseAsync(argv);\n return Number(process.exitCode ?? 0);\n } catch (err) {\n return reportError(err);\n }\n}\n","import {\n confirm as clackConfirm,\n isCancel,\n multiselect as clackMultiselect,\n text as clackText,\n type Option,\n} from '@clack/prompts';\n\n/**\n * Thin wrapper over @clack/prompts with a non-TTY guard.\n *\n * When stdout/stdin is not a TTY, or `assumeYes` is set, prompts must NOT render;\n * every prompt resolves to its supplied default. This keeps the wizard usable in\n * pipes/CI (which behave as `--yes`) and in tests without a fake terminal.\n */\n\nlet assumeYesFlag = false;\n\n/** Force non-interactive mode (used by `--yes` and non-TTY detection). */\nexport function setAssumeYes(value: boolean): void {\n assumeYesFlag = value;\n}\n\n/** True when prompts should be skipped (non-TTY or `--yes`). */\nexport function isNonInteractive(): boolean {\n return assumeYesFlag || !process.stdout.isTTY || !process.stdin.isTTY;\n}\n\n/** Raised when a user cancels an interactive prompt (Ctrl-C). */\nexport class PromptCancelledError extends Error {\n constructor() {\n super('Prompt cancelled');\n this.name = 'PromptCancelledError';\n }\n}\n\nfunction guardCancel<T>(value: T | symbol): T {\n if (isCancel(value)) throw new PromptCancelledError();\n return value as T;\n}\n\n/** Free-text prompt. Returns `defaultValue` in non-interactive mode. */\nexport async function promptText(options: {\n message: string;\n defaultValue: string;\n placeholder?: string;\n}): Promise<string> {\n if (isNonInteractive()) return options.defaultValue;\n const result = await clackText({\n message: options.message,\n placeholder: options.placeholder ?? options.defaultValue,\n defaultValue: options.defaultValue,\n initialValue: options.defaultValue,\n });\n const value = guardCancel(result);\n return value.length > 0 ? value : options.defaultValue;\n}\n\n/** Yes/no prompt. Returns `defaultValue` in non-interactive mode. */\nexport async function promptConfirm(options: {\n message: string;\n defaultValue: boolean;\n}): Promise<boolean> {\n if (isNonInteractive()) return options.defaultValue;\n const result = await clackConfirm({\n message: options.message,\n initialValue: options.defaultValue,\n });\n return guardCancel(result);\n}\n\n/** Multi-select prompt. Returns `defaultValues` in non-interactive mode. */\nexport async function promptMultiselect<Value>(options: {\n message: string;\n choices: Array<{ value: Value; label: string; hint?: string }>;\n defaultValues: Value[];\n}): Promise<Value[]> {\n if (isNonInteractive()) return options.defaultValues;\n if (options.choices.length === 0) return [];\n // `Option<Value>` is a conditional type; an unresolved generic can't be\n // simplified by TS, so build the array as the concrete shape and assert.\n const choices = options.choices.map((c) => ({\n value: c.value,\n label: c.label,\n ...(c.hint !== undefined ? { hint: c.hint } : {}),\n })) as Option<Value>[];\n\n const result = await clackMultiselect<Value>({\n message: options.message,\n options: choices,\n initialValues: options.defaultValues,\n required: false,\n });\n return guardCancel(result);\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nimport { loadConfig, type SubstrataConfig } from '@substrata/core';\nimport pc from 'picocolors';\n\n/**\n * Shared CLI helpers: cwd resolution, git shell-outs, attribution precedence,\n * and a typed error class for friendly (exit 1) failures.\n */\n\nconst execFileAsync = promisify(execFile);\n\n/** A user/expected error: printed as a friendly message, no stack, exit code 1. */\nexport class CliError extends Error {\n readonly exitCode: number;\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = 'CliError';\n this.exitCode = exitCode;\n }\n}\n\n/** Resolve the working directory from the hidden global `--cwd` option. */\nexport function resolveCwd(opts: { cwd?: string } | undefined): string {\n return opts?.cwd ? opts.cwd : process.cwd();\n}\n\nexport const out = {\n ok: (msg: string) => process.stdout.write(`${pc.green('✔')} ${msg}\\n`),\n info: (msg: string) => process.stdout.write(`${pc.blue('ℹ')} ${msg}\\n`),\n warn: (msg: string) => process.stderr.write(`${pc.yellow('!')} ${msg}\\n`),\n err: (msg: string) => process.stderr.write(`${pc.red('✖')} ${msg}\\n`),\n plain: (msg: string) => process.stdout.write(`${msg}\\n`),\n};\n\n/** Run a git command in `cwd`; returns trimmed stdout or null on failure. */\nexport async function git(cwd: string, args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync('git', args, { cwd });\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/** True if `cwd` is inside a git work tree. */\nexport async function isGitRepo(cwd: string): Promise<boolean> {\n const result = await git(cwd, ['rev-parse', '--is-inside-work-tree']);\n return result === 'true';\n}\n\nexport type GitContext = {\n branch?: string;\n files: string[];\n commit?: string;\n};\n\n/** Collect branch, changed files (staged + unstaged), and HEAD commit. */\nexport async function collectGitContext(cwd: string): Promise<GitContext> {\n const branch = (await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD'])) ?? undefined;\n const commit = (await git(cwd, ['rev-parse', 'HEAD'])) ?? undefined;\n\n const staged = await git(cwd, ['diff', '--cached', '--name-only']);\n const unstaged = await git(cwd, ['diff', '--name-only']);\n const files = new Set<string>();\n for (const block of [staged, unstaged]) {\n if (!block) continue;\n for (const line of block.split(/\\r?\\n/)) {\n const t = line.trim();\n if (t.length > 0) files.add(t);\n }\n }\n\n return {\n branch: branch && branch !== 'HEAD' ? branch : undefined,\n files: Array.from(files),\n commit,\n };\n}\n\nexport type Attribution = {\n actor: string;\n model?: string;\n requester?: string;\n};\n\n/**\n * Resolve actor / model / requester by the precedence in plan §8.2.\n * actor: --actor → $SUBSTRATA_ACTOR → config.agent.default_actor → \"unknown-agent\"\n * model: --model → $SUBSTRATA_MODEL → config.agent.default_model → omit\n * requester: --requester → $SUBSTRATA_REQUESTER → git user.email → omit\n */\nexport async function resolveAttribution(\n cwd: string,\n config: SubstrataConfig,\n flags: { actor?: string; model?: string; requester?: string },\n): Promise<Attribution> {\n const env = process.env;\n\n const actor = flags.actor || env.SUBSTRATA_ACTOR || config.agent.default_actor || 'unknown-agent';\n\n const model = flags.model || env.SUBSTRATA_MODEL || config.agent.default_model || undefined;\n\n let requester = flags.requester || env.SUBSTRATA_REQUESTER || undefined;\n if (!requester) {\n const email = await git(cwd, ['config', 'user.email']);\n if (email) requester = email;\n }\n\n return { actor, model, requester };\n}\n\n/** Load config, mapping a missing/invalid config to a friendly CliError. */\nexport async function requireConfig(cwd: string): Promise<SubstrataConfig> {\n try {\n return await loadConfig(cwd);\n } catch (err) {\n throw new CliError(\n `${(err as Error).message}\\nRun \\`substrata init\\` to set up this repository.`,\n );\n }\n}\n","import {\n SecretDetectedError,\n supersedeFootprint,\n writeFootprint,\n type RejectedOption,\n type WorkType,\n type WriteFootprintInput,\n} from '@substrata/core';\nimport type { Command } from 'commander';\n\nimport { promptText, isNonInteractive } from '../wizard/prompts';\nimport {\n CliError,\n collectGitContext,\n out,\n requireConfig,\n resolveAttribution,\n resolveCwd,\n} from '../util';\n\n/**\n * `substrata add` — create a footprint, interactive or non-interactive. Resolves\n * actor/model/requester by precedence (plan §8.2), optionally enriches from Git\n * (`--from-git`), runs the secret scan inside core (catching SecretDetectedError\n * to print the §12 refusal), and prints the §12 commit reminder on success.\n */\n\nconst SECURITY_REMINDER =\n 'Reminder: Substrata files are intended to be committed.\\n' +\n 'Do not include secrets, credentials, or sensitive user data.';\n\ntype AddOptions = {\n title?: string;\n purpose?: string;\n actor?: string;\n requester?: string;\n model?: string;\n files?: string;\n tag?: string[];\n workType?: string;\n decision?: string[];\n rejected?: string[];\n notes?: string;\n memory?: string[];\n guidance?: string;\n template?: string;\n supersedes?: string;\n allowSecret?: boolean;\n fromGit?: boolean;\n};\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\nfunction splitCsv(value: string | undefined): string[] {\n if (!value) return [];\n return value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/** Parse a `--rejected \"option:reason\"` value into a structured RejectedOption. */\nfunction parseRejected(values: string[] | undefined): RejectedOption[] {\n if (!values) return [];\n return values.map((v) => {\n const idx = v.indexOf(':');\n if (idx === -1) return { option: v.trim(), reason: '' };\n return { option: v.slice(0, idx).trim(), reason: v.slice(idx + 1).trim() };\n });\n}\n\nconst VALID_WORK_TYPES: ReadonlySet<string> = new Set<WorkType>([\n 'implementation',\n 'implementation_decision',\n 'bug_fix',\n 'refactor',\n 'investigation',\n 'architecture_decision',\n 'test_update',\n 'documentation',\n]);\n\nexport function registerAddCommand(program: Command): void {\n program\n .command('add')\n .description('Create a new footprint')\n .option('--title <title>', 'Footprint title')\n .option('--purpose <text>', 'Why this work was done')\n .option('--actor <id>', 'Agent that performed the work')\n .option('--requester <id>', 'Who requested the work')\n .option('--model <id>', 'Agent model identifier')\n .option('--files <csv>', 'Comma-separated files touched')\n .option('--tag <tag>', 'Tag (repeatable)', collect, [])\n .option('--work-type <type>', 'Footprint work type')\n .option('--decision <text>', 'Decision made (repeatable)', collect, [])\n .option('--rejected <option:reason>', 'Rejected option (repeatable)', collect, [])\n .option('--notes <text>', 'Implementation notes')\n .option('--memory <text>', 'Memory learned (repeatable)', collect, [])\n .option('--guidance <text>', 'Future agent guidance')\n .option('--template <type>', 'Work type template to seed the footprint')\n .option('--supersedes <id>', 'Mark this footprint as superseding an old one')\n .option('--allow-secret', 'Write even if a secret is detected (NOT recommended)')\n .option('--from-git', 'Populate branch/files/commit from Git')\n .action(async (opts: AddOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n const config = await requireConfig(cwd);\n\n const attribution = await resolveAttribution(cwd, config, {\n actor: opts.actor,\n model: opts.model,\n requester: opts.requester,\n });\n\n // Title: required in non-interactive mode; prompted otherwise.\n let title = opts.title;\n if (!title) {\n if (isNonInteractive()) {\n throw new CliError('`--title` is required in non-interactive mode.');\n }\n title = await promptText({ message: 'Title', defaultValue: '' });\n if (!title.trim()) throw new CliError('A title is required.');\n }\n\n const purpose =\n opts.purpose ??\n (isNonInteractive()\n ? undefined\n : (await promptText({ message: 'Purpose', defaultValue: '' })) || undefined);\n\n const workTypeRaw = opts.workType ?? opts.template;\n if (workTypeRaw && !VALID_WORK_TYPES.has(workTypeRaw)) {\n throw new CliError(\n `Invalid work type \"${workTypeRaw}\". Valid: ${Array.from(VALID_WORK_TYPES).join(', ')}.`,\n );\n }\n const workType = workTypeRaw as WorkType | undefined;\n\n let filesTouched = splitCsv(opts.files);\n let repoBranch: string | undefined;\n let commits: string[] | undefined;\n\n if (opts.fromGit) {\n const ctx = await collectGitContext(cwd);\n repoBranch = ctx.branch;\n if (ctx.files.length > 0) {\n filesTouched = Array.from(new Set([...filesTouched, ...ctx.files]));\n }\n if (ctx.commit) commits = [ctx.commit];\n }\n\n const supersedes = opts.supersedes ? [opts.supersedes] : undefined;\n\n const input: WriteFootprintInput & { cwd: string } = {\n cwd,\n title,\n purpose,\n actor: attribution.actor,\n requester: attribution.requester,\n agentModel: attribution.model,\n workType,\n decisions: opts.decision && opts.decision.length > 0 ? opts.decision : undefined,\n rejectedOptions:\n opts.rejected && opts.rejected.length > 0 ? parseRejected(opts.rejected) : undefined,\n implementationNotes: opts.notes,\n memoryLearned: opts.memory && opts.memory.length > 0 ? opts.memory : undefined,\n futureAgentGuidance: opts.guidance,\n filesTouched: filesTouched.length > 0 ? filesTouched : undefined,\n tags: opts.tag && opts.tag.length > 0 ? opts.tag : undefined,\n repo: repoBranch ? { branch: repoBranch } : undefined,\n related: commits ? { commits } : undefined,\n supersedes,\n allowSecret: opts.allowSecret,\n };\n\n let footprint;\n try {\n footprint = await writeFootprint(input);\n } catch (err) {\n if (err instanceof SecretDetectedError) {\n // §12 refusal: print pattern names + line numbers, NEVER values.\n const detail = err.findings.map((f) => ` - ${f.name} at body line ${f.line}`).join('\\n');\n throw new CliError(\n `Refusing to write footprint: ${err.findings.length} potential secret(s) detected\\n${detail}\\n` +\n ' Redact these or pass --allow-secret to override (NOT recommended — footprints are committed).',\n );\n }\n throw err;\n }\n\n // If superseding, also flip the old footprint's status/links.\n if (opts.supersedes) {\n await supersedeFootprint(cwd, opts.supersedes, footprint.frontmatter.id);\n }\n\n out.ok(`Footprint written: ${footprint.frontmatter.id}`);\n out.plain(` ${footprint.filePath}`);\n out.warn(SECURITY_REMINDER);\n });\n}\n","import type { Footprint, MemoryDocument, SearchResult } from '@substrata/core';\n\n/**\n * Build the LLM-friendly `context` output (plan §8.4). Each ranked source is\n * rendered as a numbered point with a one-line statement, an optional Reason,\n * and a Source: path. Sources are added in ranked order until adding the next\n * one would exceed the token budget.\n *\n * Token budget is a documented character approximation: `ceil(chars / 3.5)`.\n * No real tokenizer is bundled (plan §8.4). We round up so the estimate\n * under-fills rather than overflows.\n */\n\nconst CHARS_PER_TOKEN = 3.5;\n\n/** Approximate token count for a string (ceil(chars / 3.5)). */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nexport type ContextSource = {\n id: string;\n title: string;\n filePath: string;\n};\n\nexport type ContextResult = {\n text: string;\n sources: ContextSource[];\n};\n\nconst HEADER = 'Relevant Substrata context:';\nconst APPROX_NOTE = '(Token counts are approximate — estimated, not tokenizer-exact.)';\n\n/** First non-empty line of a block of text, trimmed. */\nfunction firstLine(text: string | undefined): string | undefined {\n if (!text) return undefined;\n for (const line of text.split(/\\r?\\n/)) {\n const t = line.trim();\n if (t.length > 0) return t;\n }\n return undefined;\n}\n\n/**\n * Derive a concise statement + optional reason for a footprint, preferring the\n * most decision-bearing section available.\n */\nfunction footprintPoint(fp: Footprint): { statement: string; reason?: string } {\n const s = fp.sections;\n if (s.decisions && s.decisions.length > 0) {\n const rejected = s.rejectedOptions?.[0];\n return {\n statement: s.decisions[0]!,\n reason: rejected ? `${rejected.option} was rejected — ${rejected.reason}` : undefined,\n };\n }\n if (s.rejectedOptions && s.rejectedOptions.length > 0) {\n const r = s.rejectedOptions[0]!;\n return { statement: `Avoid ${r.option} for ${fp.title}.`, reason: r.reason };\n }\n if (s.futureAgentGuidance) {\n return { statement: firstLine(s.futureAgentGuidance) ?? fp.title };\n }\n if (s.purpose) {\n return { statement: fp.title, reason: firstLine(s.purpose) };\n }\n return { statement: fp.title };\n}\n\n/** Derive a concise statement for a memory document (first bullet or title). */\nfunction memoryPoint(doc: MemoryDocument): { statement: string } {\n for (const line of doc.body.split(/\\r?\\n/)) {\n const t = line.trim();\n if (t.startsWith('- ')) return { statement: t.slice(2).trim() };\n }\n return { statement: doc.title };\n}\n\ntype Resolved = { source: ContextSource; block: string };\n\nfunction blockFor(\n result: SearchResult,\n footprintsById: Map<string, Footprint>,\n memoryById: Map<string, MemoryDocument>,\n index: number,\n): Resolved {\n const fp = footprintsById.get(result.id);\n const mem = memoryById.get(result.id);\n\n let statement: string;\n let reason: string | undefined;\n if (fp) {\n ({ statement, reason } = footprintPoint(fp));\n } else if (mem) {\n ({ statement } = memoryPoint(mem));\n } else {\n statement = result.title || result.id;\n }\n\n const lines = [`${index}. ${statement}`];\n if (reason) lines.push(` Reason: ${reason}`);\n lines.push(` Source: ${result.filePath}`);\n\n return {\n source: { id: result.id, title: result.title, filePath: result.filePath },\n block: lines.join('\\n'),\n };\n}\n\n/**\n * Render ranked results into the LLM-friendly context string within a token\n * budget. Adds sources in order until the next would overflow `maxTokens`.\n */\nexport function renderContext(\n results: SearchResult[],\n footprints: Footprint[],\n memory: MemoryDocument[],\n maxTokens: number,\n): ContextResult {\n const footprintsById = new Map(footprints.map((f) => [f.frontmatter.id, f]));\n const memoryById = new Map(memory.map((m) => [m.frontmatter.id, m]));\n\n const header = `${HEADER}\\n\\n`;\n const footer = `\\n\\n${APPROX_NOTE}`;\n let used = estimateTokens(header) + estimateTokens(footer);\n\n const chosen: ContextSource[] = [];\n const blocks: string[] = [];\n\n let n = 1;\n for (const result of results) {\n const { source, block } = blockFor(result, footprintsById, memoryById, n);\n const blockTokens = estimateTokens(`${block}\\n\\n`);\n if (used + blockTokens > maxTokens && blocks.length > 0) break;\n blocks.push(block);\n chosen.push(source);\n used += blockTokens;\n n += 1;\n }\n\n if (blocks.length === 0) {\n return { text: `${HEADER}\\n\\nNo relevant context found.`, sources: [] };\n }\n\n return { text: `${header}${blocks.join('\\n\\n')}${footer}`, sources: chosen };\n}\n","import { buildIndex, getIndexStatus } from '@substrata/search';\n\nimport { out } from '../util';\n\n/**\n * Shared lazy-index helper for `search` and `context` (plan §8.3/§8.5). Rebuilds\n * a missing or stale index unless `--no-auto-index` was passed. A freshly cloned\n * repo (no index/) \"just works\" on the first query.\n */\nexport async function ensureFreshIndex(cwd: string, autoIndex: boolean): Promise<void> {\n const status = await getIndexStatus(cwd);\n if (status.state === 'fresh') return;\n\n if (!autoIndex) {\n out.info(\n status.state === 'missing'\n ? 'Index missing — run `substrata index` (auto-index disabled).'\n : `Index stale (${status.reason}) — run \\`substrata index\\` (auto-index disabled).`,\n );\n return;\n }\n\n await buildIndex(cwd);\n}\n","import { listFootprints, listMemoryDocuments } from '@substrata/core';\nimport { search } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { renderContext } from '../render/context';\nimport { out, requireConfig, resolveCwd } from '../util';\n\nimport { ensureFreshIndex } from './auto-index';\n\n/**\n * `substrata context <task>` — concise, source-linked context for an agent\n * before work begins. Excludes superseded footprints by DEFAULT (agents should\n * see the current decision). Fits a token budget estimated as ceil(chars/3.5).\n * Auto-(re)builds a stale/missing index like `search` (plan §8.4).\n */\n\ntype ContextOptions = {\n json?: boolean;\n maxTokens?: string;\n files?: string[];\n autoIndex?: boolean;\n};\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\nexport function registerContextCommand(program: Command): void {\n program\n .command('context <task>')\n .description('Return concise, source-linked context for an agent')\n .option('--json', 'Output JSON ({ context, sources })')\n .option('--max-tokens <n>', 'Approximate token budget (chars/3.5)')\n .option('--files <path>', 'Bias toward docs touching this file (repeatable)', collect, [])\n .option('--no-auto-index', 'Do not auto-(re)build a stale/missing index')\n .action(async (task: string, opts: ContextOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n const config = await requireConfig(cwd);\n\n await ensureFreshIndex(cwd, opts.autoIndex !== false);\n\n const maxTokens = opts.maxTokens ? Number(opts.maxTokens) : config.search.max_context_tokens;\n const budget = Number.isFinite(maxTokens) ? maxTokens : config.search.max_context_tokens;\n\n const results = await search(task, {\n cwd,\n limit: config.search.default_limit,\n files: opts.files && opts.files.length > 0 ? opts.files : undefined,\n excludeSuperseded: true,\n });\n\n const [footprints, memory] = await Promise.all([\n listFootprints(cwd),\n listMemoryDocuments(cwd),\n ]);\n\n const rendered = renderContext(results, footprints, memory, budget);\n\n if (opts.json) {\n out.plain(JSON.stringify({ context: rendered.text, sources: rendered.sources }, null, 2));\n return;\n }\n out.plain(rendered.text);\n });\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\n\nimport {\n GITIGNORE_LINES,\n listFootprints,\n listMemoryDocuments,\n loadConfig,\n substrataDir,\n} from '@substrata/core';\nimport { getIndexStatus } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { out, resolveCwd } from '../util';\n\n/**\n * `substrata doctor` — health check (plan §8.8). A missing/stale index is\n * informational (ℹ), not an error. Non-zero exit only for: invalid config,\n * unparseable footprint/memory files, or a gitignore that would commit the DB.\n *\n * Returns the number of hard failures so the program can set the exit code.\n */\nexport async function runDoctor(cwd: string): Promise<number> {\n let failures = 0;\n\n // .substrata exists\n if (existsSync(substrataDir(cwd))) {\n out.ok('.substrata exists');\n } else {\n out.err('.substrata missing — run `substrata init`');\n return 1;\n }\n\n // config valid\n try {\n await loadConfig(cwd);\n out.ok('config valid');\n } catch (err) {\n out.err(`config invalid: ${(err as Error).message}`);\n failures += 1;\n }\n\n // index status (informational only)\n const status = await getIndexStatus(cwd);\n if (status.state === 'fresh') {\n out.ok('index fresh');\n } else if (status.state === 'missing') {\n out.info('index missing — run `substrata index` (or it builds automatically on first search)');\n } else {\n out.info(`index stale (${status.reason}) — run \\`substrata index\\``);\n }\n\n // gitignore covers index/ and cache/ (else the generated DB would be committed)\n const gitignorePath = path.join(cwd, '.gitignore');\n const gitignore = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf8') : '';\n const ignoredLines = new Set(gitignore.split(/\\r?\\n/).map((l) => l.trim()));\n const indexCovered = ignoredLines.has('.substrata/index/') || ignoredLines.has('.substrata/');\n if (indexCovered) {\n out.ok('gitignore covers index/ and cache/');\n } else {\n out.err(`gitignore would commit the generated DB — add: ${GITIGNORE_LINES.join(', ')}`);\n failures += 1;\n }\n\n // footprints parse\n try {\n const footprints = await listFootprints(cwd);\n out.ok(`${footprints.length} footprint file(s) parsed`);\n } catch (err) {\n out.err(`footprint parse error: ${(err as Error).message}`);\n failures += 1;\n }\n\n // memory parses\n try {\n const memory = await listMemoryDocuments(cwd);\n out.ok(`${memory.length} memory file(s) parsed`);\n } catch (err) {\n out.err(`memory parse error: ${(err as Error).message}`);\n failures += 1;\n }\n\n return failures;\n}\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Check repository setup')\n .action(async (_opts: unknown, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n const failures = await runDoctor(cwd);\n if (failures > 0) {\n process.exitCode = 1;\n }\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { installSecretHook, scanForSecrets } from '@substrata/core';\nimport type { Command } from 'commander';\n\nimport { git, out, resolveCwd } from '../util';\n\n/**\n * `substrata hook install` — install the pre-commit secret hook (plan §8.11).\n * `substrata hook run` (and the internal `internal-scan-staged` alias the hook\n * script invokes) — scan staged `.substrata` files and exit 1 on findings.\n */\n\n/**\n * Scan staged `.substrata/**` files for secrets. Returns the number of files\n * with findings (0 = clean). Prints pattern names + line numbers, never values.\n */\nasync function scanStaged(cwd: string): Promise<number> {\n const staged = await git(cwd, ['diff', '--cached', '--name-only']);\n if (!staged) return 0;\n\n const files = staged\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter((l) => l.startsWith('.substrata/') && l.endsWith('.md'));\n\n let flagged = 0;\n for (const rel of files) {\n let content: string;\n try {\n content = await readFile(path.join(cwd, rel), 'utf8');\n } catch {\n continue;\n }\n const findings = scanForSecrets(content);\n if (findings.length > 0) {\n flagged += 1;\n out.err(`${findings.length} potential secret(s) in ${rel}:`);\n for (const f of findings) out.plain(` - ${f.name} at line ${f.line}`);\n }\n }\n return flagged;\n}\n\nexport function registerHookCommand(program: Command): void {\n const hook = program.command('hook').description('Pre-commit secret hook utilities');\n\n hook\n .command('install')\n .description('Install the pre-commit secret scan hook')\n .action(async (_opts: unknown, command: Command) => {\n const cwd = resolveCwd(command.parent?.parent?.opts());\n const result = installSecretHook(cwd);\n if (result.action === 'skip') {\n out.info('Pre-commit hook already installed.');\n } else {\n out.ok(`Pre-commit hook ${result.action === 'create' ? 'installed' : 'updated'}.`);\n }\n });\n\n hook\n .command('run')\n .description('Scan staged .substrata files for secrets')\n .action(async (_opts: unknown, command: Command) => {\n const cwd = resolveCwd(command.parent?.parent?.opts());\n const flagged = await scanStaged(cwd);\n if (flagged > 0) process.exitCode = 1;\n });\n\n // The installed hook script invokes this name directly.\n program\n .command('internal-scan-staged', { hidden: true })\n .action(async (_opts: unknown, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n const flagged = await scanStaged(cwd);\n if (flagged > 0) process.exitCode = 1;\n });\n}\n","import { buildIndex } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { out, requireConfig, resolveCwd } from '../util';\n\n/**\n * `substrata index` / `index --rebuild` — build or rebuild the local FTS index.\n * The MVP indexer always does a full rebuild, so `--rebuild` is accepted for\n * symmetry with the documented flag.\n */\nexport function registerIndexCommand(program: Command): void {\n program\n .command('index')\n .description('Build or rebuild the local search index')\n .option('--rebuild', 'Force a full rebuild of the index')\n .action(async (_opts: { rebuild?: boolean }, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n await requireConfig(cwd);\n await buildIndex(cwd, { rebuild: true });\n out.ok('Index built.');\n });\n}\n","import { readFile, writeFile } from 'node:fs/promises';\n\nimport { configPath } from '@substrata/core';\nimport { buildIndex } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { printResolvedConfig, runInitWizard, type InitFlags } from '../wizard/init-wizard';\nimport { setAssumeYes } from '../wizard/prompts';\nimport { out, resolveCwd } from '../util';\n\nimport { runDoctor } from './doctor';\n\n/**\n * `substrata init` — one-command setup wizard (plan §8.1). Non-TTY/`--yes`\n * accepts all defaults. After applying, runs the embedded doctor health check and\n * builds the initial index (unless `--no-index`).\n */\n\n/** Disable redaction in the written config when `--no-redact` was passed. */\nasync function disableRedaction(cwd: string): Promise<void> {\n const file = configPath(cwd);\n let raw: string;\n try {\n raw = await readFile(file, 'utf8');\n } catch {\n return;\n }\n const next = raw\n .replace(/^(\\s*)redact:\\s*true\\s*$/m, '$1redact: false')\n .replace(/^(\\s*)scan_content:\\s*true\\s*$/m, '$1scan_content: false')\n .replace(/^(\\s*)block_on_secret:\\s*true\\s*$/m, '$1block_on_secret: false');\n if (next !== raw) await writeFile(file, next, 'utf8');\n}\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Set up Substrata in this repository (interactive wizard)')\n .option('--yes', 'Accept all defaults, no prompts')\n .option('--project <name>', 'Project name')\n .option('--actor <id>', 'Default actor')\n .option('--model <id>', 'Default agent model')\n .option('--requester <id>', 'Default requester')\n .option('--no-env', \"Don't touch shell rc; print snippet instead\")\n .option('--no-agents-md', 'Skip AGENTS.md')\n .option('--no-mcp', 'Skip MCP registration')\n .option('--mcp-client <name>', 'Register only this client (repeatable)', collect, [])\n .option('--no-gitignore', \"Don't edit .gitignore\")\n .option('--no-redact', 'Disable security redaction (NOT recommended)')\n .option('--with-hook', 'Install the pre-commit secret hook')\n .option('--no-index', 'Skip building the initial index')\n .option('--print-config', 'Print resolved config.yml without writing anything')\n .action(async (opts: InitCommandOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n\n const flags: InitFlags = {\n yes: opts.yes,\n project: opts.project,\n actor: opts.actor,\n model: opts.model,\n requester: opts.requester,\n env: opts.env,\n agentsMd: opts.agentsMd,\n mcp: opts.mcp,\n mcpClient: opts.mcpClient,\n gitignore: opts.gitignore,\n redact: opts.redact,\n withHook: opts.withHook,\n index: opts.index,\n printConfig: opts.printConfig,\n };\n\n if (flags.printConfig) {\n printResolvedConfig(cwd, flags);\n return;\n }\n\n // Non-TTY contexts behave as --yes (handled inside the prompt wrapper too).\n if (flags.yes) setAssumeYes(true);\n\n const result = await runInitWizard(cwd, flags);\n if (result.aborted) return;\n\n if (flags.redact === false) {\n await disableRedaction(cwd);\n out.warn('Security redaction disabled (--no-redact).');\n }\n\n // Embedded health check (doctor logic).\n out.plain('');\n await runDoctor(cwd);\n\n // Build the initial index unless skipped.\n if (flags.index !== false) {\n await buildIndex(cwd);\n out.ok('Initial index built.');\n }\n });\n}\n\ntype InitCommandOptions = {\n yes?: boolean;\n project?: string;\n actor?: string;\n model?: string;\n requester?: string;\n env?: boolean;\n agentsMd?: boolean;\n mcp?: boolean;\n mcpClient?: string[];\n gitignore?: boolean;\n redact?: boolean;\n withHook?: boolean;\n index?: boolean;\n printConfig?: boolean;\n};\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport path from 'node:path';\n\nimport {\n ensureGitignore,\n initProject,\n installSecretHook,\n renderConfig,\n upsertAgentsMd,\n writeShellEnv,\n type AttributionEnv,\n type ChangeResult,\n} from '@substrata/core';\nimport pc from 'picocolors';\n\nimport {\n detectMcpClients,\n getMcpClient,\n SUBSTRATA_MCP_SPEC,\n type McpClient,\n} from '../mcp-clients/registry';\nimport { git, isGitRepo, out } from '../util';\n\nimport { promptConfirm, promptMultiselect, promptText } from './prompts';\n\n/**\n * The `init` setup wizard (plan §8.1). Collects answers, prints a change plan,\n * and applies nothing until one final confirmation. Idempotent: re-running enters\n * update mode (markers replaced in place; gitignore/MCP de-duplicated).\n */\n\nexport type InitFlags = {\n yes?: boolean;\n project?: string;\n actor?: string;\n model?: string;\n requester?: string;\n env?: boolean; // --no-env => false\n agentsMd?: boolean; // --no-agents-md => false\n mcp?: boolean; // --no-mcp => false\n mcpClient?: string[];\n gitignore?: boolean; // --no-gitignore => false\n redact?: boolean; // --no-redact => false\n withHook?: boolean;\n index?: boolean; // --no-index => false\n printConfig?: boolean;\n};\n\ntype Answers = {\n projectName: string;\n attribution: AttributionEnv;\n writeEnv: boolean;\n rcPath: string;\n redact: boolean;\n withHook: boolean;\n writeAgentsMd: boolean;\n writeGitignore: boolean;\n mcpClients: McpClient[];\n};\n\n/** Detect the user's shell rc file from $SHELL, defaulting to ~/.zshrc. */\nfunction detectShellRc(): string {\n const shell = process.env.SHELL ?? '';\n const home = homedir();\n if (shell.includes('bash')) return path.join(home, '.bashrc');\n return path.join(home, '.zshrc');\n}\n\n/** Default project name: package.json \"name\", else the folder basename. */\nfunction defaultProjectName(cwd: string): string {\n const pkgPath = path.join(cwd, 'package.json');\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as { name?: string };\n if (pkg.name && typeof pkg.name === 'string') {\n return pkg.name.replace(/^@[^/]+\\//, '');\n }\n } catch {\n // ignore malformed package.json\n }\n }\n return path.basename(path.resolve(cwd));\n}\n\n/** Step 0: preflight — git repo check (offer git init), MCP client detection. */\nasync function preflight(cwd: string, flags: InitFlags): Promise<void> {\n if (!(await isGitRepo(cwd))) {\n const doInit = await promptConfirm({\n message: 'This is not a Git repository. Run `git init`?',\n defaultValue: true,\n });\n if (doInit) {\n const result = await git(cwd, ['init']);\n if (result !== null) out.ok('Initialized a Git repository.');\n else out.warn('Could not run `git init`; continuing without Git.');\n }\n }\n void flags;\n}\n\n/** Resolve the set of MCP clients to register, honoring --mcp-client / --no-mcp. */\nasync function resolveMcpClients(cwd: string, flags: InitFlags): Promise<McpClient[]> {\n if (flags.mcp === false) return [];\n\n if (flags.mcpClient && flags.mcpClient.length > 0) {\n const chosen: McpClient[] = [];\n for (const name of flags.mcpClient) {\n const client = getMcpClient(name);\n if (client) chosen.push(client);\n else out.warn(`Unknown MCP client \"${name}\" — skipping.`);\n }\n return chosen;\n }\n\n const detected = await detectMcpClients(cwd);\n if (detected.length === 0) return [];\n\n return promptMultiselect<McpClient>({\n message: 'Register the Substrata MCP server with which clients?',\n choices: detected.map((c) => ({ value: c, label: c.label })),\n defaultValues: detected,\n });\n}\n\n/** Collect all wizard answers (no writes). */\nasync function collectAnswers(cwd: string, flags: InitFlags): Promise<Answers> {\n const projectName =\n flags.project ??\n (await promptText({\n message: 'Project name',\n defaultValue: defaultProjectName(cwd),\n }));\n\n // Agent attribution.\n const actor = await promptText({\n message: 'Default actor (agent id)',\n defaultValue: flags.actor ?? 'unknown-agent',\n });\n const model =\n flags.model ??\n (await promptText({ message: 'Default agent model (optional)', defaultValue: '' }));\n const gitEmail = (await git(cwd, ['config', 'user.email'])) ?? '';\n const requester =\n flags.requester ??\n (await promptText({ message: 'Default requester (optional)', defaultValue: gitEmail }));\n\n const attribution: AttributionEnv = {\n actor: actor || undefined,\n model: model || undefined,\n requester: requester || undefined,\n };\n\n const writeEnv =\n flags.env === false\n ? false\n : await promptConfirm({\n message: 'Persist attribution env vars to your shell rc?',\n defaultValue: true,\n });\n\n const redact =\n flags.redact === false\n ? false\n : await promptConfirm({\n message: 'Enable security redaction + content scan?',\n defaultValue: true,\n });\n\n const withHook =\n flags.withHook === true\n ? true\n : await promptConfirm({\n message: 'Install the pre-commit secret hook?',\n defaultValue: false,\n });\n\n const writeAgentsMd =\n flags.agentsMd === false\n ? false\n : await promptConfirm({\n message: 'Add the Substrata section to AGENTS.md?',\n defaultValue: true,\n });\n\n const writeGitignore = flags.gitignore !== false;\n\n const mcpClients = await resolveMcpClients(cwd, flags);\n\n return {\n projectName,\n attribution,\n writeEnv,\n rcPath: detectShellRc(),\n redact,\n withHook,\n writeAgentsMd,\n writeGitignore,\n mcpClients,\n };\n}\n\n/** Build the full change plan as dry-run ChangeResults (no writes). */\nasync function buildPlan(cwd: string, answers: Answers): Promise<ChangeResult[]> {\n const changes: ChangeResult[] = [];\n\n // Scaffold: simulate by checking what initProject would create.\n // initProject itself is idempotent (skips existing), but it writes; for the\n // plan we describe the scaffold as a single logical step.\n changes.push({\n path: path.join(cwd, '.substrata'),\n action: existsSync(path.join(cwd, '.substrata', 'config.yml')) ? 'skip' : 'create',\n description: 'Substrata scaffold (config, README, footprints, memory, templates)',\n });\n\n if (answers.writeGitignore) {\n changes.push(ensureGitignore(cwd, true));\n }\n\n if (\n answers.writeEnv &&\n (answers.attribution.actor || answers.attribution.model || answers.attribution.requester)\n ) {\n changes.push(writeShellEnv(answers.rcPath, answers.attribution, true));\n }\n\n if (answers.writeAgentsMd) {\n changes.push(upsertAgentsMd(cwd, true));\n }\n\n if (answers.withHook) {\n changes.push(installSecretHook(cwd, true));\n }\n\n for (const client of answers.mcpClients) {\n changes.push(await client.register(cwd, SUBSTRATA_MCP_SPEC, true));\n }\n\n return changes;\n}\n\n/** Apply the plan for real (idempotent writers). Returns applied changes. */\nasync function applyPlan(cwd: string, answers: Answers): Promise<ChangeResult[]> {\n const applied: ChangeResult[] = [];\n\n applied.push(...(await initProject(cwd, { projectName: answers.projectName })));\n\n if (answers.writeGitignore) {\n applied.push(ensureGitignore(cwd, false));\n }\n\n if (\n answers.writeEnv &&\n (answers.attribution.actor || answers.attribution.model || answers.attribution.requester)\n ) {\n applied.push(writeShellEnv(answers.rcPath, answers.attribution, false));\n } else if (!answers.writeEnv) {\n printEnvSnippet(answers.attribution);\n }\n\n if (answers.writeAgentsMd) {\n applied.push(upsertAgentsMd(cwd, false));\n }\n\n if (answers.withHook) {\n applied.push(installSecretHook(cwd, false));\n }\n\n for (const client of answers.mcpClients) {\n const result = await client.register(cwd, SUBSTRATA_MCP_SPEC, false);\n applied.push(result);\n // Windsurf etc. return a skip with a printable snippet in the description.\n if (result.action === 'skip' && result.description.includes('\\n')) {\n out.info(`${client.label}: ${result.description}`);\n }\n }\n\n return applied;\n}\n\n/** Print the export snippet when env persistence is declined (plan §8.1 step 2). */\nfunction printEnvSnippet(attribution: AttributionEnv): void {\n const lines: string[] = [];\n if (attribution.actor) lines.push(`export SUBSTRATA_ACTOR=\"${attribution.actor}\"`);\n if (attribution.model) lines.push(`export SUBSTRATA_MODEL=\"${attribution.model}\"`);\n if (attribution.requester) lines.push(`export SUBSTRATA_REQUESTER=\"${attribution.requester}\"`);\n if (lines.length === 0) return;\n out.info('Add these to your shell rc to attribute footprints:');\n out.plain(lines.map((l) => ` ${l}`).join('\\n'));\n}\n\n/** Render the resolved config.yml without writing (for --print-config). */\nexport function printResolvedConfig(cwd: string, flags: InitFlags): void {\n const name = flags.project ?? defaultProjectName(cwd);\n out.plain(renderConfig(name));\n}\n\nexport type WizardResult = {\n applied: ChangeResult[];\n aborted: boolean;\n};\n\n/** Run the full init wizard. Returns whether the user aborted. */\nexport async function runInitWizard(cwd: string, flags: InitFlags): Promise<WizardResult> {\n const updateMode = existsSync(path.join(cwd, '.substrata', 'config.yml'));\n if (updateMode) {\n out.info('Existing .substrata detected — running in update mode.');\n }\n\n await preflight(cwd, flags);\n const answers = await collectAnswers(cwd, flags);\n\n const plan = await buildPlan(cwd, answers);\n out.plain(pc.bold('\\nPlanned changes:'));\n out.plain(\n plan\n .map((c) => {\n const label =\n c.action === 'create'\n ? pc.green('CREATE')\n : c.action === 'update'\n ? pc.yellow('UPDATE')\n : pc.dim('SKIP ');\n return ` ${label} ${c.path}${c.description ? pc.dim(` — ${c.description.split('\\n')[0]}`) : ''}`;\n })\n .join('\\n'),\n );\n out.plain('');\n\n const confirmed = await promptConfirm({ message: 'Apply these changes?', defaultValue: true });\n if (!confirmed) {\n out.info('Aborted. Nothing was written.');\n return { applied: [], aborted: true };\n }\n\n const applied = await applyPlan(cwd, answers);\n out.ok('Substrata setup applied.');\n\n if (answers.writeEnv) {\n out.info(`Run \\`source ${answers.rcPath}\\` to load attribution env vars.`);\n }\n\n return { applied, aborted: false };\n}\n","import { execFile } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { promisify } from 'node:util';\n\nimport type { ChangeResult } from '@substrata/core';\n\nimport { mergeMcpJson, removeMcpJson } from './json-config';\nimport type { McpClient, McpServerSpec } from './registry';\n\n/**\n * Claude Code MCP client. Detected via the `claude` binary on PATH OR an existing\n * project `.mcp.json`. Registration writes `.mcp.json` directly (rather than\n * shelling to `claude mcp add`) so it is deterministic and testable.\n */\n\nconst execFileAsync = promisify(execFile);\n\nfunction mcpJsonPath(cwd: string): string {\n return path.join(cwd, '.mcp.json');\n}\n\nasync function hasClaudeBinary(): Promise<boolean> {\n try {\n await execFileAsync('which', ['claude']);\n return true;\n } catch {\n return false;\n }\n}\n\nexport const claudeCodeClient: McpClient = {\n name: 'claude',\n label: 'Claude Code',\n\n async detect(cwd: string): Promise<boolean> {\n if (existsSync(mcpJsonPath(cwd))) return true;\n return hasClaudeBinary();\n },\n\n async register(cwd: string, spec: McpServerSpec, dry: boolean = false): Promise<ChangeResult> {\n return mergeMcpJson(mcpJsonPath(cwd), spec, dry);\n },\n\n async unregister(cwd: string, name: string): Promise<void> {\n removeMcpJson(mcpJsonPath(cwd), name);\n },\n};\n","import { lstatSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport path from 'node:path';\n\nimport type { ChangeResult } from '@substrata/core';\n\nimport type { McpServerSpec } from './registry';\n\n/**\n * Shared helper for clients that store MCP servers in a JSON file under an\n * `mcpServers` map (Claude Code `.mcp.json`, Cursor `.cursor/mcp.json`). The\n * write is idempotent: remove-then-add the named entry, preserving other keys.\n */\n\ntype McpJson = {\n mcpServers?: Record<string, { command: string; args?: string[] }>;\n [key: string]: unknown;\n};\n\nfunction isSymlink(filePath: string): boolean {\n try {\n return lstatSync(filePath).isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nfunction readJson(filePath: string): McpJson | null {\n try {\n const raw = readFileSync(filePath, 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n return parsed && typeof parsed === 'object' ? (parsed as McpJson) : {};\n } catch {\n return null;\n }\n}\n\n/** Whether the existing config already contains the spec entry exactly. */\nfunction entryMatches(existing: McpJson | null, spec: McpServerSpec): boolean {\n const entry = existing?.mcpServers?.[spec.name];\n if (!entry) return false;\n return (\n entry.command === spec.command && JSON.stringify(entry.args ?? []) === JSON.stringify(spec.args)\n );\n}\n\n/**\n * Merge the Substrata MCP server into a JSON config file at `filePath`.\n * Remove-then-add semantics keep the result idempotent across reruns.\n */\nexport function mergeMcpJson(\n filePath: string,\n spec: McpServerSpec,\n dry: boolean = false,\n): ChangeResult {\n // Refuse to write through a symlink: a repo-shipped link could redirect the\n // merge into a file outside the repo.\n if (isSymlink(filePath)) {\n return {\n path: filePath,\n action: 'skip',\n description: `refused: ${path.basename(filePath)} is a symlink`,\n };\n }\n const existing = readJson(filePath);\n\n if (entryMatches(existing, spec)) {\n return { path: filePath, action: 'skip', description: 'MCP entry already current' };\n }\n\n const base: McpJson = existing ?? {};\n const servers = { ...(base.mcpServers ?? {}) };\n // Remove-then-add so a drifted entry is replaced wholesale.\n delete servers[spec.name];\n servers[spec.name] = { command: spec.command, args: spec.args };\n\n const next: McpJson = { ...base, mcpServers: servers };\n const contents = `${JSON.stringify(next, null, 2)}\\n`;\n\n if (!dry) {\n mkdirSync(path.dirname(filePath), { recursive: true });\n writeFileSync(filePath, contents, 'utf8');\n }\n\n return {\n path: filePath,\n action: existing === null ? 'create' : 'update',\n description: `register Substrata MCP server (${spec.name})`,\n contents,\n };\n}\n\n/** Remove the named MCP entry from a JSON config file (idempotent). */\nexport function removeMcpJson(filePath: string, name: string): void {\n const existing = readJson(filePath);\n if (!existing?.mcpServers?.[name]) return;\n const servers = { ...existing.mcpServers };\n delete servers[name];\n const next: McpJson = { ...existing, mcpServers: servers };\n writeFileSync(filePath, `${JSON.stringify(next, null, 2)}\\n`, 'utf8');\n}\n","import { existsSync } from 'node:fs';\nimport path from 'node:path';\n\nimport type { ChangeResult } from '@substrata/core';\n\nimport { mergeMcpJson, removeMcpJson } from './json-config';\nimport type { McpClient, McpServerSpec } from './registry';\n\n/**\n * Cursor MCP client. Stores project MCP servers in `.cursor/mcp.json` using the\n * same `mcpServers` map shape as Claude Code. Detected via an existing\n * `.cursor/` directory or `.cursor/mcp.json`.\n */\n\nfunction cursorMcpPath(cwd: string): string {\n return path.join(cwd, '.cursor', 'mcp.json');\n}\n\nexport const cursorClient: McpClient = {\n name: 'cursor',\n label: 'Cursor',\n\n async detect(cwd: string): Promise<boolean> {\n return existsSync(path.join(cwd, '.cursor')) || existsSync(cursorMcpPath(cwd));\n },\n\n async register(cwd: string, spec: McpServerSpec, dry: boolean = false): Promise<ChangeResult> {\n return mergeMcpJson(cursorMcpPath(cwd), spec, dry);\n },\n\n async unregister(cwd: string, name: string): Promise<void> {\n removeMcpJson(cursorMcpPath(cwd), name);\n },\n};\n","import { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport path from 'node:path';\n\nimport type { ChangeResult } from '@substrata/core';\n\nimport type { McpClient, McpServerSpec } from './registry';\n\n/**\n * Windsurf MCP client. Windsurf's MCP config is global per-user\n * (`~/.codeium/windsurf/mcp_config.json`), so registration does NOT edit the\n * user's homedir. Instead it returns a `skip` ChangeResult whose description is a\n * printable snippet + path the user can apply manually.\n */\n\nfunction windsurfConfigPath(): string {\n return path.join(homedir(), '.codeium', 'windsurf', 'mcp_config.json');\n}\n\nfunction snippet(spec: McpServerSpec): string {\n const block = {\n mcpServers: {\n [spec.name]: { command: spec.command, args: spec.args },\n },\n };\n return `${windsurfConfigPath()}\\n${JSON.stringify(block, null, 2)}`;\n}\n\nexport const windsurfClient: McpClient = {\n name: 'windsurf',\n label: 'Windsurf',\n\n async detect(): Promise<boolean> {\n return existsSync(path.join(homedir(), '.codeium', 'windsurf'));\n },\n\n async register(_cwd: string, spec: McpServerSpec): Promise<ChangeResult> {\n // Global config — never write into the user's homedir; print a snippet.\n return {\n path: windsurfConfigPath(),\n action: 'skip',\n description: `add manually (global config):\\n${snippet(spec)}`,\n };\n },\n\n async unregister(): Promise<void> {\n // No-op: Windsurf config is user-global and not managed by Substrata.\n },\n};\n","import type { ChangeResult } from '@substrata/core';\n\nimport { claudeCodeClient } from './claude-code';\nimport { cursorClient } from './cursor';\nimport { windsurfClient } from './windsurf';\n\n/**\n * MCP client registry (plan §14). A small table so new clients can be added\n * without touching the wizard flow. Each client can detect whether it is present,\n * register the Substrata MCP server (idempotent, dry-runnable), and unregister.\n */\n\n/** Spec for the Substrata MCP server entry written into client config. */\nexport type McpServerSpec = {\n /** Logical name of the server entry (the key in the client's config map). */\n name: string;\n command: string;\n args: string[];\n};\n\nexport type McpClient = {\n /** Stable id: \"claude\" | \"cursor\" | \"windsurf\". */\n name: string;\n /** Human-friendly label for prompts. */\n label: string;\n detect(cwd: string): Promise<boolean>;\n register(cwd: string, spec: McpServerSpec, dry?: boolean): Promise<ChangeResult>;\n unregister(cwd: string, name: string): Promise<void>;\n};\n\n/** The default Substrata MCP server spec written into client configs. */\nexport const SUBSTRATA_MCP_SPEC: McpServerSpec = {\n name: 'substrata',\n command: 'npx',\n args: ['-y', 'substrata-cli', 'mcp'],\n};\n\nexport const MCP_CLIENTS: McpClient[] = [claudeCodeClient, cursorClient, windsurfClient];\n\n/** Look up a client by its stable id. */\nexport function getMcpClient(name: string): McpClient | undefined {\n return MCP_CLIENTS.find((c) => c.name === name);\n}\n\n/** Detect which registered clients are present in/around `cwd`. */\nexport async function detectMcpClients(cwd: string): Promise<McpClient[]> {\n const detected: McpClient[] = [];\n for (const client of MCP_CLIENTS) {\n if (await client.detect(cwd)) detected.push(client);\n }\n return detected;\n}\n","import type { SearchResult } from '@substrata/core';\nimport pc from 'picocolors';\n\n/**\n * Human-readable rendering of search results and footprint lists. Output is\n * informative, not noisy: one block per result with id, title, status, tags,\n * path, and a snippet.\n */\n\nfunction statusLabel(status: SearchResult['status']): string {\n switch (status) {\n case 'superseded':\n return pc.yellow('[superseded]');\n case 'deprecated':\n return pc.red('[deprecated]');\n case 'draft':\n return pc.dim('[draft]');\n default:\n return '';\n }\n}\n\n/** Render a list of search results for the terminal. */\nexport function renderSearchResults(results: SearchResult[]): string {\n if (results.length === 0) {\n return pc.dim('No matching footprints or memory found.');\n }\n const blocks = results.map((r, i) => {\n const n = pc.dim(`${i + 1}.`);\n const status = statusLabel(r.status);\n const header = `${n} ${pc.bold(r.title || r.id)}${status ? ` ${status}` : ''}`;\n const lines = [header, ` ${pc.dim('id:')} ${r.id}`, ` ${pc.dim('path:')} ${r.filePath}`];\n if (r.tags.length > 0) lines.push(` ${pc.dim('tags:')} ${r.tags.join(', ')}`);\n if (r.snippet.trim().length > 0) {\n lines.push(` ${pc.dim(r.snippet.replace(/\\s+/g, ' ').trim())}`);\n }\n return lines.join('\\n');\n });\n return blocks.join('\\n\\n');\n}\n\n/** Render footprints (from `list`) as compact rows. */\nexport function renderFootprintList(\n rows: Array<{\n id: string;\n title: string;\n status: SearchResult['status'];\n createdAt?: string;\n tags: string[];\n }>,\n): string {\n if (rows.length === 0) {\n return pc.dim('No footprints found.');\n }\n return rows\n .map((r) => {\n const date = r.createdAt ? r.createdAt.slice(0, 10) : '----------';\n const status = statusLabel(r.status);\n const tags = r.tags.length > 0 ? pc.dim(` (${r.tags.join(', ')})`) : '';\n return `${pc.dim(date)} ${pc.bold(r.title || r.id)}${status ? ` ${status}` : ''}\\n ${pc.dim(r.id)}${tags}`;\n })\n .join('\\n');\n}\n","import { listFootprints, type Footprint } from '@substrata/core';\nimport type { Command } from 'commander';\n\nimport { renderFootprintList } from '../render/table';\nimport { out, requireConfig, resolveCwd } from '../util';\n\n/**\n * `substrata list` — list footprints filtered by tag/file/since. No index needed;\n * reads footprint files directly (plan §8.6).\n */\n\ntype ListOptions = {\n tag?: string;\n file?: string;\n since?: string;\n json?: boolean;\n};\n\nfunction matches(fp: Footprint, opts: ListOptions): boolean {\n if (opts.tag && !(fp.frontmatter.tags ?? []).includes(opts.tag)) return false;\n if (opts.file && !(fp.frontmatter.files_touched ?? []).includes(opts.file)) return false;\n if (opts.since && fp.frontmatter.created_at < opts.since) return false;\n return true;\n}\n\nexport function registerListCommand(program: Command): void {\n program\n .command('list')\n .description('List recent footprints')\n .option('--tag <tag>', 'Only footprints carrying this tag')\n .option('--file <path>', 'Only footprints touching this file')\n .option('--since <date>', 'Only footprints created on/after this ISO date')\n .option('--json', 'Output JSON')\n .action(async (opts: ListOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n await requireConfig(cwd);\n\n const all = await listFootprints(cwd);\n const filtered = all.filter((fp) => matches(fp, opts));\n\n if (opts.json) {\n const rows = filtered.map((fp) => ({\n id: fp.frontmatter.id,\n title: fp.title,\n status: fp.frontmatter.status,\n createdAt: fp.frontmatter.created_at,\n tags: fp.frontmatter.tags ?? [],\n filesTouched: fp.frontmatter.files_touched ?? [],\n filePath: fp.filePath,\n }));\n out.plain(JSON.stringify(rows, null, 2));\n return;\n }\n\n out.plain(\n renderFootprintList(\n filtered.map((fp) => ({\n id: fp.frontmatter.id,\n title: fp.title,\n status: fp.frontmatter.status,\n createdAt: fp.frontmatter.created_at,\n tags: fp.frontmatter.tags ?? [],\n })),\n ),\n );\n });\n}\n","import type { Command } from 'commander';\n\nimport { CliError, resolveCwd } from '../util';\n\n/**\n * `substrata mcp` — run the MCP server (plan §8.12). Dynamically imports\n * `@substrata/mcp-server` (built in parallel) and calls its documented contract:\n * runMcpServer(options?: { cwd?: string }): Promise<void>\n */\n\ntype McpServerModule = {\n runMcpServer: (options?: { cwd?: string }) => Promise<void>;\n};\n\nexport function registerMcpCommand(program: Command): void {\n program\n .command('mcp')\n .description('Run the Substrata MCP server (stdio)')\n .action(async (_opts: unknown, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n let mod: McpServerModule;\n try {\n mod = (await import('@substrata/mcp-server')) as unknown as McpServerModule;\n } catch (err) {\n throw new CliError(`Failed to load @substrata/mcp-server: ${(err as Error).message}`);\n }\n if (typeof mod.runMcpServer !== 'function') {\n throw new CliError('@substrata/mcp-server does not export runMcpServer().');\n }\n await mod.runMcpServer({ cwd });\n });\n}\n","import { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport {\n appendMemoryEntries,\n existingEntryIds,\n listFootprints,\n memoryDir,\n type MemoryEntry,\n} from '@substrata/core';\nimport type { Command } from 'commander';\n\nimport { promptConfirm, isNonInteractive } from '../wizard/prompts';\nimport { out, requireConfig, resolveCwd } from '../util';\n\n/**\n * `substrata memory update` — scan footprints, extract `Memory learned` sections,\n * suggest entries, confirm, and append them before the entries:end marker of\n * `.substrata/memory/conventions.md` (created with frontmatter if missing).\n * Idempotent: entries whose source footprint id already appears are skipped\n * (plan §8.10).\n */\n\nconst CONVENTIONS_FRONTMATTER = `---\nschema_version: 1\nid: mem_repo_conventions\ntype: repo_conventions\ntags:\n - conventions\n---\n\n# Repo conventions\n\nCurated, durable knowledge agents should read often.\n\n<!-- substrata:entries:start -->\n<!-- substrata:entries:end -->\n`;\n\ntype MemoryUpdateOptions = {\n since?: string;\n yes?: boolean;\n};\n\nexport function registerMemoryUpdateCommand(program: Command): void {\n const memory = program.command('memory').description('Curated memory utilities');\n\n memory\n .command('update')\n .description('Suggest and append memory entries from footprints')\n .option('--since <date>', 'Only footprints created on/after this ISO date')\n .option('--yes', 'Append without confirmation')\n .action(async (opts: MemoryUpdateOptions, command: Command) => {\n // `memory` is the parent of `update`; the program is its grandparent.\n const cwd = resolveCwd(command.parent?.parent?.opts());\n await requireConfig(cwd);\n\n const footprints = await listFootprints(cwd);\n const filtered = opts.since\n ? footprints.filter((fp) => fp.frontmatter.created_at >= opts.since!)\n : footprints;\n\n const candidates: MemoryEntry[] = [];\n for (const fp of filtered) {\n const learned = fp.sections.memoryLearned ?? [];\n if (learned.length === 0) continue;\n candidates.push({\n sourceId: fp.frontmatter.id,\n lines: learned.map((l) => `- ${l}`),\n });\n }\n\n if (candidates.length === 0) {\n out.info('No `Memory learned` sections found in the selected footprints.');\n return;\n }\n\n const filePath = path.join(memoryDir(cwd), 'conventions.md');\n\n // Compute which entries are genuinely new (idempotent preview).\n const alreadyPresent = existsSync(filePath)\n ? existingEntryIds(await readFile(filePath, 'utf8'))\n : new Set<string>();\n const fresh = candidates.filter((c) => !alreadyPresent.has(c.sourceId));\n\n if (fresh.length === 0) {\n out.info('All suggested entries are already present. Nothing to do.');\n return;\n }\n\n out.plain('Suggested memory entries:');\n for (const entry of fresh) {\n out.plain(` [${entry.sourceId}]`);\n for (const line of entry.lines) out.plain(` ${line}`);\n }\n\n const confirmed =\n opts.yes || isNonInteractive()\n ? true\n : await promptConfirm({\n message: `Append ${fresh.length} entr${fresh.length === 1 ? 'y' : 'ies'} to conventions.md?`,\n defaultValue: true,\n });\n\n if (!confirmed) {\n out.info('Aborted. Nothing written.');\n return;\n }\n\n if (!existsSync(filePath)) {\n await writeFile(filePath, CONVENTIONS_FRONTMATTER, 'utf8');\n }\n\n const changed = await appendMemoryEntries(filePath, candidates);\n if (changed) {\n out.ok(`Appended ${fresh.length} memory entr${fresh.length === 1 ? 'y' : 'ies'}.`);\n } else {\n out.info('No new entries appended (already present).');\n }\n });\n}\n","import { search } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { renderSearchResults } from '../render/table';\nimport { out, requireConfig, resolveCwd } from '../util';\n\nimport { ensureFreshIndex } from './auto-index';\n\n/**\n * `substrata search <query>` — full-text search over footprints + memory.\n * Auto-(re)builds a stale/missing index unless `--no-auto-index`. By default\n * includes superseded footprints (demoted in ranking) so humans can trace\n * history; `--exclude-superseded` drops them (plan §8.3).\n */\n\ntype SearchOptions = {\n json?: boolean;\n files?: string[];\n tag?: string[];\n limit?: string;\n excludeSuperseded?: boolean;\n autoIndex?: boolean;\n};\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return [...previous, value];\n}\n\nexport function registerSearchCommand(program: Command): void {\n program\n .command('search <query>')\n .description('Search footprints and memory')\n .option('--json', 'Output JSON')\n .option('--files <path>', 'Filter to docs touching this file (repeatable)', collect, [])\n .option('--tag <tag>', 'Filter to docs carrying this tag (repeatable)', collect, [])\n .option('--limit <n>', 'Maximum number of results')\n .option('--exclude-superseded', 'Drop superseded/deprecated footprints')\n .option('--no-auto-index', 'Do not auto-(re)build a stale/missing index')\n .action(async (query: string, opts: SearchOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n const config = await requireConfig(cwd);\n\n await ensureFreshIndex(cwd, opts.autoIndex !== false);\n\n const limit = opts.limit ? Number(opts.limit) : config.search.default_limit;\n const results = await search(query, {\n cwd,\n limit: Number.isFinite(limit) ? limit : config.search.default_limit,\n files: opts.files && opts.files.length > 0 ? opts.files : undefined,\n tags: opts.tag && opts.tag.length > 0 ? opts.tag : undefined,\n excludeSuperseded: opts.excludeSuperseded,\n });\n\n if (opts.json) {\n out.plain(JSON.stringify(results, null, 2));\n return;\n }\n out.plain(renderSearchResults(results));\n });\n}\n","import { findFootprintById } from '@substrata/core';\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { CliError, out, requireConfig, resolveCwd } from '../util';\n\n/**\n * `substrata show <id>` — pretty-print one footprint, or its JSON / path.\n * (plan §8.7)\n */\n\ntype ShowOptions = {\n json?: boolean;\n path?: boolean;\n};\n\nexport function registerShowCommand(program: Command): void {\n program\n .command('show <id>')\n .description('Show one footprint')\n .option('--json', 'Output the parsed footprint as JSON')\n .option('--path', 'Print only the footprint file path')\n .action(async (id: string, opts: ShowOptions, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n await requireConfig(cwd);\n\n const fp = await findFootprintById(cwd, id);\n if (!fp) throw new CliError(`Footprint not found: ${id}`);\n\n if (opts.path) {\n out.plain(fp.filePath);\n return;\n }\n\n if (opts.json) {\n out.plain(\n JSON.stringify(\n {\n id: fp.frontmatter.id,\n title: fp.title,\n filePath: fp.filePath,\n frontmatter: fp.frontmatter,\n sections: fp.sections,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const fm = fp.frontmatter;\n const lines: string[] = [\n pc.bold(fp.title || fm.id),\n `${pc.dim('id:')} ${fm.id}`,\n `${pc.dim('status:')} ${fm.status}`,\n `${pc.dim('work_type:')} ${fm.work_type}`,\n `${pc.dim('actor:')} ${fm.actor}`,\n ];\n if (fm.requester) lines.push(`${pc.dim('requester:')} ${fm.requester}`);\n if (fm.agent_model) lines.push(`${pc.dim('model:')} ${fm.agent_model}`);\n lines.push(`${pc.dim('created:')} ${fm.created_at}`);\n if (fm.tags && fm.tags.length > 0)\n lines.push(`${pc.dim('tags:')} ${fm.tags.join(', ')}`);\n if (fm.files_touched && fm.files_touched.length > 0) {\n lines.push(`${pc.dim('files:')} ${fm.files_touched.join(', ')}`);\n }\n lines.push(`${pc.dim('path:')} ${fp.filePath}`);\n lines.push('');\n lines.push(fp.body.trim());\n out.plain(lines.join('\\n'));\n });\n}\n","import { NotFoundError, supersedeFootprint } from '@substrata/core';\nimport { buildIndex } from '@substrata/search';\nimport type { Command } from 'commander';\n\nimport { CliError, out, requireConfig, resolveCwd } from '../util';\n\n/**\n * `substrata supersede <old-id> --by <new-id>` — mark an old footprint replaced\n * by a new one (frontmatter-only edits), then rebuild the index so ranking\n * reflects the new status (plan §8.9).\n */\nexport function registerSupersedeCommand(program: Command): void {\n program\n .command('supersede <old-id>')\n .description('Mark an old footprint as superseded by a new one')\n .requiredOption('--by <new-id>', 'Id of the footprint that replaces the old one')\n .action(async (oldId: string, opts: { by: string }, command: Command) => {\n const cwd = resolveCwd(command.parent?.opts());\n await requireConfig(cwd);\n\n try {\n await supersedeFootprint(cwd, oldId, opts.by);\n } catch (err) {\n if (err instanceof NotFoundError) throw new CliError(err.message);\n throw err;\n }\n\n await buildIndex(cwd);\n out.ok(`${oldId} superseded by ${opts.by}. Index rebuilt.`);\n });\n}\n"],"mappings":"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","names":["pc","collect","path","path","readFile","existsSync","readFileSync","homedir","path","pc","execFile","existsSync","path","promisify","readFileSync","path","execFileAsync","promisify","execFile","path","existsSync","existsSync","path","path","existsSync","existsSync","path","homedir","path","existsSync","readFileSync","pc","readFile","collect","pc","existsSync","readFile","writeFile","path","path","existsSync","readFile","writeFile","collect","pc","pc","pc"]}
|