@isaacriehm/cairn-core 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/dist/.tsbuildinfo +1 -0
- package/dist/claude/error.d.ts +33 -0
- package/dist/claude/error.js +58 -0
- package/dist/claude/error.js.map +1 -0
- package/dist/claude/index.d.ts +3 -0
- package/dist/claude/index.js +3 -0
- package/dist/claude/index.js.map +1 -0
- package/dist/claude/runner.d.ts +11 -0
- package/dist/claude/runner.js +132 -0
- package/dist/claude/runner.js.map +1 -0
- package/dist/claude/types.d.ts +52 -0
- package/dist/claude/types.js +14 -0
- package/dist/claude/types.js.map +1 -0
- package/dist/context/checkpoint.d.ts +10 -0
- package/dist/context/checkpoint.js +29 -0
- package/dist/context/checkpoint.js.map +1 -0
- package/dist/context/handoff-builder.d.ts +11 -0
- package/dist/context/handoff-builder.js +268 -0
- package/dist/context/handoff-builder.js.map +1 -0
- package/dist/context/index.d.ts +11 -0
- package/dist/context/index.js +11 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/spec-delta.d.ts +47 -0
- package/dist/context/spec-delta.js +237 -0
- package/dist/context/spec-delta.js.map +1 -0
- package/dist/decision-capture/capture.d.ts +57 -0
- package/dist/decision-capture/capture.js +186 -0
- package/dist/decision-capture/capture.js.map +1 -0
- package/dist/decision-capture/extractor.d.ts +20 -0
- package/dist/decision-capture/extractor.js +103 -0
- package/dist/decision-capture/extractor.js.map +1 -0
- package/dist/decision-capture/id.d.ts +21 -0
- package/dist/decision-capture/id.js +60 -0
- package/dist/decision-capture/id.js.map +1 -0
- package/dist/decision-capture/index.d.ts +25 -0
- package/dist/decision-capture/index.js +21 -0
- package/dist/decision-capture/index.js.map +1 -0
- package/dist/decision-capture/prompt.d.ts +15 -0
- package/dist/decision-capture/prompt.js +68 -0
- package/dist/decision-capture/prompt.js.map +1 -0
- package/dist/decision-capture/refinement-prompt.d.ts +25 -0
- package/dist/decision-capture/refinement-prompt.js +146 -0
- package/dist/decision-capture/refinement-prompt.js.map +1 -0
- package/dist/decision-capture/refinement-schema.d.ts +52 -0
- package/dist/decision-capture/refinement-schema.js +61 -0
- package/dist/decision-capture/refinement-schema.js.map +1 -0
- package/dist/decision-capture/refinement.d.ts +60 -0
- package/dist/decision-capture/refinement.js +439 -0
- package/dist/decision-capture/refinement.js.map +1 -0
- package/dist/decision-capture/schema.d.ts +70 -0
- package/dist/decision-capture/schema.js +71 -0
- package/dist/decision-capture/schema.js.map +1 -0
- package/dist/decision-capture/types.d.ts +201 -0
- package/dist/decision-capture/types.js +20 -0
- package/dist/decision-capture/types.js.map +1 -0
- package/dist/decision-capture/writer.d.ts +90 -0
- package/dist/decision-capture/writer.js +267 -0
- package/dist/decision-capture/writer.js.map +1 -0
- package/dist/doctor/index.d.ts +48 -0
- package/dist/doctor/index.js +460 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/events/index.d.ts +15 -0
- package/dist/events/index.js +14 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/paths.d.ts +2 -0
- package/dist/events/paths.js +6 -0
- package/dist/events/paths.js.map +1 -0
- package/dist/events/reader.d.ts +40 -0
- package/dist/events/reader.js +139 -0
- package/dist/events/reader.js.map +1 -0
- package/dist/events/writer.d.ts +61 -0
- package/dist/events/writer.js +68 -0
- package/dist/events/writer.js.map +1 -0
- package/dist/frontend-types.d.ts +243 -0
- package/dist/frontend-types.js +15 -0
- package/dist/frontend-types.js.map +1 -0
- package/dist/gc/apply.d.ts +26 -0
- package/dist/gc/apply.js +48 -0
- package/dist/gc/apply.js.map +1 -0
- package/dist/gc/canary.d.ts +42 -0
- package/dist/gc/canary.js +134 -0
- package/dist/gc/canary.js.map +1 -0
- package/dist/gc/citation-integrity.d.ts +24 -0
- package/dist/gc/citation-integrity.js +151 -0
- package/dist/gc/citation-integrity.js.map +1 -0
- package/dist/gc/classify.d.ts +25 -0
- package/dist/gc/classify.js +89 -0
- package/dist/gc/classify.js.map +1 -0
- package/dist/gc/completion-integrity.d.ts +22 -0
- package/dist/gc/completion-integrity.js +165 -0
- package/dist/gc/completion-integrity.js.map +1 -0
- package/dist/gc/doc-gardening.d.ts +29 -0
- package/dist/gc/doc-gardening.js +146 -0
- package/dist/gc/doc-gardening.js.map +1 -0
- package/dist/gc/frontmatter.d.ts +35 -0
- package/dist/gc/frontmatter.js +105 -0
- package/dist/gc/frontmatter.js.map +1 -0
- package/dist/gc/generator-drift.d.ts +28 -0
- package/dist/gc/generator-drift.js +53 -0
- package/dist/gc/generator-drift.js.map +1 -0
- package/dist/gc/index.d.ts +42 -0
- package/dist/gc/index.js +30 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/gc/quality-update.d.ts +23 -0
- package/dist/gc/quality-update.js +69 -0
- package/dist/gc/quality-update.js.map +1 -0
- package/dist/gc/scope-coverage.d.ts +20 -0
- package/dist/gc/scope-coverage.js +70 -0
- package/dist/gc/scope-coverage.js.map +1 -0
- package/dist/gc/stub-hits.d.ts +31 -0
- package/dist/gc/stub-hits.js +78 -0
- package/dist/gc/stub-hits.js.map +1 -0
- package/dist/gc/sweep.d.ts +56 -0
- package/dist/gc/sweep.js +205 -0
- package/dist/gc/sweep.js.map +1 -0
- package/dist/gc/types.d.ts +129 -0
- package/dist/gc/types.js +26 -0
- package/dist/gc/types.js.map +1 -0
- package/dist/gc/walk-source.d.ts +14 -0
- package/dist/gc/walk-source.js +59 -0
- package/dist/gc/walk-source.js.map +1 -0
- package/dist/ground/drift.d.ts +8 -0
- package/dist/ground/drift.js +23 -0
- package/dist/ground/drift.js.map +1 -0
- package/dist/ground/frontmatter.d.ts +20 -0
- package/dist/ground/frontmatter.js +49 -0
- package/dist/ground/frontmatter.js.map +1 -0
- package/dist/ground/glob.d.ts +10 -0
- package/dist/ground/glob.js +46 -0
- package/dist/ground/glob.js.map +1 -0
- package/dist/ground/index.d.ts +16 -0
- package/dist/ground/index.js +11 -0
- package/dist/ground/index.js.map +1 -0
- package/dist/ground/ledgers.d.ts +18 -0
- package/dist/ground/ledgers.js +103 -0
- package/dist/ground/ledgers.js.map +1 -0
- package/dist/ground/manifest.d.ts +10 -0
- package/dist/ground/manifest.js +88 -0
- package/dist/ground/manifest.js.map +1 -0
- package/dist/ground/paths.d.ts +20 -0
- package/dist/ground/paths.js +61 -0
- package/dist/ground/paths.js.map +1 -0
- package/dist/ground/quality-grades.d.ts +11 -0
- package/dist/ground/quality-grades.js +98 -0
- package/dist/ground/quality-grades.js.map +1 -0
- package/dist/ground/schemas.d.ts +306 -0
- package/dist/ground/schemas.js +188 -0
- package/dist/ground/schemas.js.map +1 -0
- package/dist/ground/scope-index.d.ts +48 -0
- package/dist/ground/scope-index.js +120 -0
- package/dist/ground/scope-index.js.map +1 -0
- package/dist/ground/walk.d.ts +7 -0
- package/dist/ground/walk.js +53 -0
- package/dist/ground/walk.js.map +1 -0
- package/dist/hooks/bypass-detection.d.ts +28 -0
- package/dist/hooks/bypass-detection.js +106 -0
- package/dist/hooks/bypass-detection.js.map +1 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/post-tool-use/allowlist-reader.d.ts +14 -0
- package/dist/hooks/post-tool-use/allowlist-reader.js +69 -0
- package/dist/hooks/post-tool-use/allowlist-reader.js.map +1 -0
- package/dist/hooks/post-tool-use/citation-scanner.d.ts +23 -0
- package/dist/hooks/post-tool-use/citation-scanner.js +59 -0
- package/dist/hooks/post-tool-use/citation-scanner.js.map +1 -0
- package/dist/hooks/post-tool-use/copy-scanner.d.ts +25 -0
- package/dist/hooks/post-tool-use/copy-scanner.js +192 -0
- package/dist/hooks/post-tool-use/copy-scanner.js.map +1 -0
- package/dist/hooks/post-tool-use/index.d.ts +19 -0
- package/dist/hooks/post-tool-use/index.js +15 -0
- package/dist/hooks/post-tool-use/index.js.map +1 -0
- package/dist/hooks/post-tool-use/ledger-cache.d.ts +32 -0
- package/dist/hooks/post-tool-use/ledger-cache.js +236 -0
- package/dist/hooks/post-tool-use/ledger-cache.js.map +1 -0
- package/dist/hooks/post-tool-use/legend-builder.d.ts +15 -0
- package/dist/hooks/post-tool-use/legend-builder.js +84 -0
- package/dist/hooks/post-tool-use/legend-builder.js.map +1 -0
- package/dist/hooks/post-tool-use/read-enricher.d.ts +13 -0
- package/dist/hooks/post-tool-use/read-enricher.js +157 -0
- package/dist/hooks/post-tool-use/read-enricher.js.map +1 -0
- package/dist/hooks/post-tool-use/write-guardian.d.ts +17 -0
- package/dist/hooks/post-tool-use/write-guardian.js +176 -0
- package/dist/hooks/post-tool-use/write-guardian.js.map +1 -0
- package/dist/hooks/read-enrich.d.ts +6 -0
- package/dist/hooks/read-enrich.js +11 -0
- package/dist/hooks/read-enrich.js.map +1 -0
- package/dist/hooks/runners/index.d.ts +12 -0
- package/dist/hooks/runners/index.js +11 -0
- package/dist/hooks/runners/index.js.map +1 -0
- package/dist/hooks/runners/payload.d.ts +32 -0
- package/dist/hooks/runners/payload.js +70 -0
- package/dist/hooks/runners/payload.js.map +1 -0
- package/dist/hooks/runners/session-end.d.ts +7 -0
- package/dist/hooks/runners/session-end.js +42 -0
- package/dist/hooks/runners/session-end.js.map +1 -0
- package/dist/hooks/runners/session-start.d.ts +10 -0
- package/dist/hooks/runners/session-start.js +167 -0
- package/dist/hooks/runners/session-start.js.map +1 -0
- package/dist/hooks/runners/stop.d.ts +18 -0
- package/dist/hooks/runners/stop.js +165 -0
- package/dist/hooks/runners/stop.js.map +1 -0
- package/dist/hooks/session-end.d.ts +5 -0
- package/dist/hooks/session-end.js +10 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/hooks/session-start.d.ts +7 -0
- package/dist/hooks/session-start.js +12 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/hooks/stop.d.ts +5 -0
- package/dist/hooks/stop.js +10 -0
- package/dist/hooks/stop.js.map +1 -0
- package/dist/hooks/write-guard.d.ts +6 -0
- package/dist/hooks/write-guard.js +11 -0
- package/dist/hooks/write-guard.js.map +1 -0
- package/dist/inbox.d.ts +17 -0
- package/dist/inbox.js +30 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/init/baseline-audit.d.ts +71 -0
- package/dist/init/baseline-audit.js +377 -0
- package/dist/init/baseline-audit.js.map +1 -0
- package/dist/init/brand-setup.d.ts +44 -0
- package/dist/init/brand-setup.js +201 -0
- package/dist/init/brand-setup.js.map +1 -0
- package/dist/init/daemon-autostart.d.ts +16 -0
- package/dist/init/daemon-autostart.js +95 -0
- package/dist/init/daemon-autostart.js.map +1 -0
- package/dist/init/detect.d.ts +25 -0
- package/dist/init/detect.js +319 -0
- package/dist/init/detect.js.map +1 -0
- package/dist/init/index.d.ts +32 -0
- package/dist/init/index.js +18 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/ingest-docs.d.ts +74 -0
- package/dist/init/ingest-docs.js +499 -0
- package/dist/init/ingest-docs.js.map +1 -0
- package/dist/init/init.d.ts +165 -0
- package/dist/init/init.js +1166 -0
- package/dist/init/init.js.map +1 -0
- package/dist/init/mapper-legacy.d.ts +148 -0
- package/dist/init/mapper-legacy.js +238 -0
- package/dist/init/mapper-legacy.js.map +1 -0
- package/dist/init/mapper-merge.d.ts +38 -0
- package/dist/init/mapper-merge.js +238 -0
- package/dist/init/mapper-merge.js.map +1 -0
- package/dist/init/mapper-parallel.d.ts +48 -0
- package/dist/init/mapper-parallel.js +409 -0
- package/dist/init/mapper-parallel.js.map +1 -0
- package/dist/init/mapper-prompts.d.ts +135 -0
- package/dist/init/mapper-prompts.js +189 -0
- package/dist/init/mapper-prompts.js.map +1 -0
- package/dist/init/mapper.d.ts +211 -0
- package/dist/init/mapper.js +151 -0
- package/dist/init/mapper.js.map +1 -0
- package/dist/init/module-slicer.d.ts +39 -0
- package/dist/init/module-slicer.js +809 -0
- package/dist/init/module-slicer.js.map +1 -0
- package/dist/init/multi-dev/index.d.ts +2 -0
- package/dist/init/multi-dev/index.js +2 -0
- package/dist/init/multi-dev/index.js.map +1 -0
- package/dist/init/multi-dev/install.d.ts +40 -0
- package/dist/init/multi-dev/install.js +139 -0
- package/dist/init/multi-dev/install.js.map +1 -0
- package/dist/init/preflight-guards.d.ts +42 -0
- package/dist/init/preflight-guards.js +108 -0
- package/dist/init/preflight-guards.js.map +1 -0
- package/dist/init/prompts.d.ts +61 -0
- package/dist/init/prompts.js +66 -0
- package/dist/init/prompts.js.map +1 -0
- package/dist/init/rules-merge/discover.d.ts +21 -0
- package/dist/init/rules-merge/discover.js +78 -0
- package/dist/init/rules-merge/discover.js.map +1 -0
- package/dist/init/rules-merge/index.d.ts +10 -0
- package/dist/init/rules-merge/index.js +6 -0
- package/dist/init/rules-merge/index.js.map +1 -0
- package/dist/init/rules-merge/ingest.d.ts +56 -0
- package/dist/init/rules-merge/ingest.js +336 -0
- package/dist/init/rules-merge/ingest.js.map +1 -0
- package/dist/init/rules-merge/keep-markers.d.ts +39 -0
- package/dist/init/rules-merge/keep-markers.js +97 -0
- package/dist/init/rules-merge/keep-markers.js.map +1 -0
- package/dist/init/rules-merge/parse-sections.d.ts +24 -0
- package/dist/init/rules-merge/parse-sections.js +71 -0
- package/dist/init/rules-merge/parse-sections.js.map +1 -0
- package/dist/init/rules-merge/regenerate.d.ts +33 -0
- package/dist/init/rules-merge/regenerate.js +163 -0
- package/dist/init/rules-merge/regenerate.js.map +1 -0
- package/dist/init/secrets.d.ts +18 -0
- package/dist/init/secrets.js +76 -0
- package/dist/init/secrets.js.map +1 -0
- package/dist/init/seed.d.ts +21 -0
- package/dist/init/seed.js +96 -0
- package/dist/init/seed.js.map +1 -0
- package/dist/init/setup-runners.d.ts +15 -0
- package/dist/init/setup-runners.js +143 -0
- package/dist/init/setup-runners.js.map +1 -0
- package/dist/init/source-comments/classify.d.ts +98 -0
- package/dist/init/source-comments/classify.js +244 -0
- package/dist/init/source-comments/classify.js.map +1 -0
- package/dist/init/source-comments/index.d.ts +8 -0
- package/dist/init/source-comments/index.js +5 -0
- package/dist/init/source-comments/index.js.map +1 -0
- package/dist/init/source-comments/ingest.d.ts +51 -0
- package/dist/init/source-comments/ingest.js +236 -0
- package/dist/init/source-comments/ingest.js.map +1 -0
- package/dist/init/source-comments/strip-replace.d.ts +106 -0
- package/dist/init/source-comments/strip-replace.js +284 -0
- package/dist/init/source-comments/strip-replace.js.map +1 -0
- package/dist/init/source-comments/walker.d.ts +65 -0
- package/dist/init/source-comments/walker.js +777 -0
- package/dist/init/source-comments/walker.js.map +1 -0
- package/dist/init/submodules.d.ts +48 -0
- package/dist/init/submodules.js +149 -0
- package/dist/init/submodules.js.map +1 -0
- package/dist/init/types.d.ts +55 -0
- package/dist/init/types.js +10 -0
- package/dist/init/types.js.map +1 -0
- package/dist/init/visual.d.ts +69 -0
- package/dist/init/visual.js +265 -0
- package/dist/init/visual.js.map +1 -0
- package/dist/init/walker.d.ts +82 -0
- package/dist/init/walker.js +585 -0
- package/dist/init/walker.js.map +1 -0
- package/dist/init/workflow-block.d.ts +34 -0
- package/dist/init/workflow-block.js +110 -0
- package/dist/init/workflow-block.js.map +1 -0
- package/dist/join/index.d.ts +67 -0
- package/dist/join/index.js +256 -0
- package/dist/join/index.js.map +1 -0
- package/dist/lock.d.ts +39 -0
- package/dist/lock.js +129 -0
- package/dist/lock.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.js +78 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/bootstrap-guard.d.ts +29 -0
- package/dist/mcp/bootstrap-guard.js +47 -0
- package/dist/mcp/bootstrap-guard.js.map +1 -0
- package/dist/mcp/context.d.ts +23 -0
- package/dist/mcp/context.js +9 -0
- package/dist/mcp/context.js.map +1 -0
- package/dist/mcp/errors.d.ts +17 -0
- package/dist/mcp/errors.js +23 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/history/index.d.ts +6 -0
- package/dist/mcp/history/index.js +5 -0
- package/dist/mcp/history/index.js.map +1 -0
- package/dist/mcp/history/prompt.d.ts +32 -0
- package/dist/mcp/history/prompt.js +99 -0
- package/dist/mcp/history/prompt.js.map +1 -0
- package/dist/mcp/history/schema.d.ts +58 -0
- package/dist/mcp/history/schema.js +41 -0
- package/dist/mcp/history/schema.js.map +1 -0
- package/dist/mcp/history/summarizer.d.ts +81 -0
- package/dist/mcp/history/summarizer.js +196 -0
- package/dist/mcp/history/summarizer.js.map +1 -0
- package/dist/mcp/history/walker.d.ts +57 -0
- package/dist/mcp/history/walker.js +156 -0
- package/dist/mcp/history/walker.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/path-allowlist.d.ts +29 -0
- package/dist/mcp/path-allowlist.js +71 -0
- package/dist/mcp/path-allowlist.js.map +1 -0
- package/dist/mcp/result.d.ts +8 -0
- package/dist/mcp/result.js +18 -0
- package/dist/mcp/result.js.map +1 -0
- package/dist/mcp/schemas.d.ts +192 -0
- package/dist/mcp/schemas.js +174 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/serve.d.ts +15 -0
- package/dist/mcp/serve.js +71 -0
- package/dist/mcp/serve.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +58 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/telemetry.d.ts +15 -0
- package/dist/mcp/telemetry.js +13 -0
- package/dist/mcp/telemetry.js.map +1 -0
- package/dist/mcp/tools/append-run-note.d.ts +18 -0
- package/dist/mcp/tools/append-run-note.js +47 -0
- package/dist/mcp/tools/append-run-note.js.map +1 -0
- package/dist/mcp/tools/append.d.ts +8 -0
- package/dist/mcp/tools/append.js +37 -0
- package/dist/mcp/tools/append.js.map +1 -0
- package/dist/mcp/tools/archive.d.ts +8 -0
- package/dist/mcp/tools/archive.js +72 -0
- package/dist/mcp/tools/archive.js.map +1 -0
- package/dist/mcp/tools/ask-operator.d.ts +34 -0
- package/dist/mcp/tools/ask-operator.js +97 -0
- package/dist/mcp/tools/ask-operator.js.map +1 -0
- package/dist/mcp/tools/canonical-for-topic.d.ts +6 -0
- package/dist/mcp/tools/canonical-for-topic.js +40 -0
- package/dist/mcp/tools/canonical-for-topic.js.map +1 -0
- package/dist/mcp/tools/decision-get.d.ts +6 -0
- package/dist/mcp/tools/decision-get.js +49 -0
- package/dist/mcp/tools/decision-get.js.map +1 -0
- package/dist/mcp/tools/decisions-for-symbol.d.ts +7 -0
- package/dist/mcp/tools/decisions-for-symbol.js +42 -0
- package/dist/mcp/tools/decisions-for-symbol.js.map +1 -0
- package/dist/mcp/tools/decisions-in-scope.d.ts +7 -0
- package/dist/mcp/tools/decisions-in-scope.js +47 -0
- package/dist/mcp/tools/decisions-in-scope.js.map +1 -0
- package/dist/mcp/tools/drop-task.d.ts +12 -0
- package/dist/mcp/tools/drop-task.js +68 -0
- package/dist/mcp/tools/drop-task.js.map +1 -0
- package/dist/mcp/tools/get-full.d.ts +7 -0
- package/dist/mcp/tools/get-full.js +46 -0
- package/dist/mcp/tools/get-full.js.map +1 -0
- package/dist/mcp/tools/ground-get.d.ts +7 -0
- package/dist/mcp/tools/ground-get.js +77 -0
- package/dist/mcp/tools/ground-get.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +3 -0
- package/dist/mcp/tools/index.js +40 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/invariant-get.d.ts +6 -0
- package/dist/mcp/tools/invariant-get.js +49 -0
- package/dist/mcp/tools/invariant-get.js.map +1 -0
- package/dist/mcp/tools/invariants-in-scope.d.ts +7 -0
- package/dist/mcp/tools/invariants-in-scope.js +62 -0
- package/dist/mcp/tools/invariants-in-scope.js.map +1 -0
- package/dist/mcp/tools/query-history.d.ts +20 -0
- package/dist/mcp/tools/query-history.js +51 -0
- package/dist/mcp/tools/query-history.js.map +1 -0
- package/dist/mcp/tools/record-decision.d.ts +14 -0
- package/dist/mcp/tools/record-decision.js +98 -0
- package/dist/mcp/tools/record-decision.js.map +1 -0
- package/dist/mcp/tools/record-run-event.d.ts +10 -0
- package/dist/mcp/tools/record-run-event.js +32 -0
- package/dist/mcp/tools/record-run-event.js.map +1 -0
- package/dist/mcp/tools/resolve-attention.d.ts +31 -0
- package/dist/mcp/tools/resolve-attention.js +191 -0
- package/dist/mcp/tools/resolve-attention.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +9 -0
- package/dist/mcp/tools/search.js +164 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/tools/supersedes-chain.d.ts +6 -0
- package/dist/mcp/tools/supersedes-chain.js +66 -0
- package/dist/mcp/tools/supersedes-chain.js.map +1 -0
- package/dist/mcp/tools/timeline.d.ts +9 -0
- package/dist/mcp/tools/timeline.js +65 -0
- package/dist/mcp/tools/timeline.js.map +1 -0
- package/dist/mcp/tools/types.d.ts +9 -0
- package/dist/mcp/tools/types.js +2 -0
- package/dist/mcp/tools/types.js.map +1 -0
- package/dist/mirror/clone.d.ts +6 -0
- package/dist/mirror/clone.js +48 -0
- package/dist/mirror/clone.js.map +1 -0
- package/dist/mirror/dirty-overlap.d.ts +13 -0
- package/dist/mirror/dirty-overlap.js +42 -0
- package/dist/mirror/dirty-overlap.js.map +1 -0
- package/dist/mirror/index.d.ts +7 -0
- package/dist/mirror/index.js +7 -0
- package/dist/mirror/index.js.map +1 -0
- package/dist/mirror/paths.d.ts +18 -0
- package/dist/mirror/paths.js +45 -0
- package/dist/mirror/paths.js.map +1 -0
- package/dist/mirror/push.d.ts +9 -0
- package/dist/mirror/push.js +27 -0
- package/dist/mirror/push.js.map +1 -0
- package/dist/mirror/state.d.ts +4 -0
- package/dist/mirror/state.js +36 -0
- package/dist/mirror/state.js.map +1 -0
- package/dist/mirror/sync.d.ts +9 -0
- package/dist/mirror/sync.js +33 -0
- package/dist/mirror/sync.js.map +1 -0
- package/dist/mirror/types.d.ts +77 -0
- package/dist/mirror/types.js +2 -0
- package/dist/mirror/types.js.map +1 -0
- package/dist/paths/index.d.ts +23 -0
- package/dist/paths/index.js +50 -0
- package/dist/paths/index.js.map +1 -0
- package/dist/profiles/index.d.ts +3 -0
- package/dist/profiles/index.js +3 -0
- package/dist/profiles/index.js.map +1 -0
- package/dist/profiles/registry.d.ts +5 -0
- package/dist/profiles/registry.js +31 -0
- package/dist/profiles/registry.js.map +1 -0
- package/dist/profiles/types.d.ts +48 -0
- package/dist/profiles/types.js +11 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/profiles/unknown.d.ts +9 -0
- package/dist/profiles/unknown.js +17 -0
- package/dist/profiles/unknown.js.map +1 -0
- package/dist/prompt.d.ts +19 -0
- package/dist/prompt.js +50 -0
- package/dist/prompt.js.map +1 -0
- package/dist/sensors/attestation.d.ts +44 -0
- package/dist/sensors/attestation.js +262 -0
- package/dist/sensors/attestation.js.map +1 -0
- package/dist/sensors/catalog.d.ts +41 -0
- package/dist/sensors/catalog.js +123 -0
- package/dist/sensors/catalog.js.map +1 -0
- package/dist/sensors/decisions.d.ts +30 -0
- package/dist/sensors/decisions.js +393 -0
- package/dist/sensors/decisions.js.map +1 -0
- package/dist/sensors/diff.d.ts +27 -0
- package/dist/sensors/diff.js +148 -0
- package/dist/sensors/diff.js.map +1 -0
- package/dist/sensors/index.d.ts +13 -0
- package/dist/sensors/index.js +9 -0
- package/dist/sensors/index.js.map +1 -0
- package/dist/sensors/remediation.d.ts +20 -0
- package/dist/sensors/remediation.js +65 -0
- package/dist/sensors/remediation.js.map +1 -0
- package/dist/sensors/runner.d.ts +44 -0
- package/dist/sensors/runner.js +95 -0
- package/dist/sensors/runner.js.map +1 -0
- package/dist/sensors/structural.d.ts +30 -0
- package/dist/sensors/structural.js +204 -0
- package/dist/sensors/structural.js.map +1 -0
- package/dist/sensors/stub-catalog.d.ts +39 -0
- package/dist/sensors/stub-catalog.js +115 -0
- package/dist/sensors/stub-catalog.js.map +1 -0
- package/dist/sensors/types.d.ts +135 -0
- package/dist/sensors/types.js +14 -0
- package/dist/sensors/types.js.map +1 -0
- package/dist/session/events-marker.d.ts +39 -0
- package/dist/session/events-marker.js +74 -0
- package/dist/session/events-marker.js.map +1 -0
- package/dist/session/id.d.ts +83 -0
- package/dist/session/id.js +166 -0
- package/dist/session/id.js.map +1 -0
- package/dist/session/index.d.ts +14 -0
- package/dist/session/index.js +13 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session-start/build.d.ts +53 -0
- package/dist/session-start/build.js +645 -0
- package/dist/session-start/build.js.map +1 -0
- package/dist/session-start/index.d.ts +18 -0
- package/dist/session-start/index.js +18 -0
- package/dist/session-start/index.js.map +1 -0
- package/dist/session-start/templates.d.ts +6 -0
- package/dist/session-start/templates.js +38 -0
- package/dist/session-start/templates.js.map +1 -0
- package/dist/status-line/format.d.ts +14 -0
- package/dist/status-line/format.js +40 -0
- package/dist/status-line/format.js.map +1 -0
- package/dist/status-line/index.d.ts +29 -0
- package/dist/status-line/index.js +14 -0
- package/dist/status-line/index.js.map +1 -0
- package/dist/status-line/reader.d.ts +13 -0
- package/dist/status-line/reader.js +76 -0
- package/dist/status-line/reader.js.map +1 -0
- package/dist/status-line/writer.d.ts +33 -0
- package/dist/status-line/writer.js +72 -0
- package/dist/status-line/writer.js.map +1 -0
- package/dist/tier0/classify.d.ts +10 -0
- package/dist/tier0/classify.js +110 -0
- package/dist/tier0/classify.js.map +1 -0
- package/dist/tier0/index.d.ts +2 -0
- package/dist/tier0/index.js +2 -0
- package/dist/tier0/index.js.map +1 -0
- package/dist/tier0/ollama.d.ts +22 -0
- package/dist/tier0/ollama.js +63 -0
- package/dist/tier0/ollama.js.map +1 -0
- package/dist/tier0/types.d.ts +24 -0
- package/dist/tier0/types.js +9 -0
- package/dist/tier0/types.js.map +1 -0
- package/dist/tightener/index.d.ts +4 -0
- package/dist/tightener/index.js +4 -0
- package/dist/tightener/index.js.map +1 -0
- package/dist/tightener/prompt.d.ts +3 -0
- package/dist/tightener/prompt.js +67 -0
- package/dist/tightener/prompt.js.map +1 -0
- package/dist/tightener/schema.d.ts +68 -0
- package/dist/tightener/schema.js +44 -0
- package/dist/tightener/schema.js.map +1 -0
- package/dist/tightener/tighten.d.ts +2 -0
- package/dist/tightener/tighten.js +66 -0
- package/dist/tightener/tighten.js.map +1 -0
- package/dist/tightener/types.d.ts +74 -0
- package/dist/tightener/types.js +6 -0
- package/dist/tightener/types.js.map +1 -0
- package/dist/voice/index.d.ts +4 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/model.d.ts +23 -0
- package/dist/voice/model.js +46 -0
- package/dist/voice/model.js.map +1 -0
- package/dist/voice/pipe.d.ts +9 -0
- package/dist/voice/pipe.js +47 -0
- package/dist/voice/pipe.js.map +1 -0
- package/dist/voice/transcribe.d.ts +3 -0
- package/dist/voice/transcribe.js +43 -0
- package/dist/voice/transcribe.js.map +1 -0
- package/dist/voice/types.d.ts +26 -0
- package/dist/voice/types.js +9 -0
- package/dist/voice/types.js.map +1 -0
- package/package.json +54 -0
- package/templates/.archive/README.md +67 -0
- package/templates/.cairn/JOIN.md +87 -0
- package/templates/.cairn/config/sensors.yaml +185 -0
- package/templates/.cairn/config/stub-patterns.yaml +231 -0
- package/templates/.cairn/config/trust-policy.yaml +95 -0
- package/templates/.cairn/config/workflow.md +230 -0
- package/templates/.cairn/git-hooks/commit-msg +17 -0
- package/templates/.cairn/git-hooks/post-commit +28 -0
- package/templates/.cairn/git-hooks/pre-commit +24 -0
- package/templates/.cairn/ground/brand/overview.md +24 -0
- package/templates/.cairn/ground/brand/voice.md +20 -0
- package/templates/.cairn/ground/canonical-map/topics.yaml +54 -0
- package/templates/.cairn/ground/capabilities/mcp-tools.yaml +4 -0
- package/templates/.cairn/ground/capabilities/skills.yaml +3 -0
- package/templates/.cairn/ground/capabilities/snippets.yaml +3 -0
- package/templates/.cairn/ground/manifest.yaml +16 -0
- package/templates/.cairn/ground/product/personas.yaml +4 -0
- package/templates/.cairn/ground/product/positioning.md +21 -0
- package/templates/.claude/settings.json +57 -0
- package/templates/.github/workflows/cairn-check.yml +31 -0
- package/templates/.mcp.json +8 -0
- package/templates/README.md +24 -0
package/dist/lock.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-write filesystem lock for `.cairn/` global state.
|
|
3
|
+
*
|
|
4
|
+
* Per docs/PLUGIN_ARCHITECTURE.md §7 (Concurrency): every write to global
|
|
5
|
+
* state (`.cairn/ground/`, `.cairn/baseline/`, `.cairn/inbox/`) is
|
|
6
|
+
* serialized through `.cairn/.write-lock` so concurrent Claude Code
|
|
7
|
+
* sessions don't race. Reads are unlocked. Whole-operation locks
|
|
8
|
+
* (`.gc-lock`, `.audit-lock`) are separate — see acquireOperationLock.
|
|
9
|
+
*
|
|
10
|
+
* Design:
|
|
11
|
+
* - `wx` (O_CREAT | O_EXCL) atomic-create on the lock file. PID written
|
|
12
|
+
* inside so stale-holder detection can recover from crashes.
|
|
13
|
+
* - Stale-lock recovery: if the holder PID is gone, claim the lock.
|
|
14
|
+
* - Polling backoff with deadline. Brief contention; long waits indicate
|
|
15
|
+
* deadlock and surface as timeout errors.
|
|
16
|
+
*/
|
|
17
|
+
import { mkdir, open, readFile, unlink } from "node:fs/promises";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
20
|
+
const DEFAULT_POLL_MS = 50;
|
|
21
|
+
/**
|
|
22
|
+
* Acquire `.cairn/.write-lock` for the lifetime of `fn`. Releases on
|
|
23
|
+
* success or error. Stale locks (holder PID is dead) are reclaimed.
|
|
24
|
+
*/
|
|
25
|
+
export async function withWriteLock(repoRoot, fn, opts = {}) {
|
|
26
|
+
return withLockAtPath(join(repoRoot, ".cairn", ".write-lock"), fn, opts);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Acquire a named operation lock (e.g. `.gc-lock`, `.audit-lock`) for the
|
|
30
|
+
* lifetime of `fn`. If the lock is held, this throws immediately rather
|
|
31
|
+
* than waiting — callers (sweep, audit) use this to bail with "another
|
|
32
|
+
* operation in progress".
|
|
33
|
+
*/
|
|
34
|
+
export async function acquireOperationLock(repoRoot, lockName, fn) {
|
|
35
|
+
const lockPath = join(repoRoot, ".cairn", lockName);
|
|
36
|
+
await mkdir(dirname(lockPath), { recursive: true });
|
|
37
|
+
const acquired = await tryAcquire(lockPath);
|
|
38
|
+
if (!acquired) {
|
|
39
|
+
throw new OperationLockHeldError(lockName, await readHolderPid(lockPath));
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
await unlink(lockPath).catch(() => { });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class OperationLockHeldError extends Error {
|
|
49
|
+
lockName;
|
|
50
|
+
holderPid;
|
|
51
|
+
constructor(lockName, holderPid) {
|
|
52
|
+
super(`operation lock ${lockName} is held${holderPid !== null ? ` by pid ${holderPid}` : ""}`);
|
|
53
|
+
this.lockName = lockName;
|
|
54
|
+
this.holderPid = holderPid;
|
|
55
|
+
this.name = "OperationLockHeldError";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function withLockAtPath(lockPath, fn, opts) {
|
|
59
|
+
await mkdir(dirname(lockPath), { recursive: true });
|
|
60
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
61
|
+
const pollMs = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
62
|
+
const deadline = Date.now() + timeoutMs;
|
|
63
|
+
// Spin until acquired or deadline.
|
|
64
|
+
while (true) {
|
|
65
|
+
if (await tryAcquire(lockPath))
|
|
66
|
+
break;
|
|
67
|
+
if (await reclaimIfStale(lockPath)) {
|
|
68
|
+
if (await tryAcquire(lockPath))
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (Date.now() >= deadline) {
|
|
72
|
+
const holder = await readHolderPid(lockPath);
|
|
73
|
+
throw new Error(`write lock timeout after ${timeoutMs}ms${holder !== null ? ` (held by pid ${holder})` : ""}`);
|
|
74
|
+
}
|
|
75
|
+
await sleep(pollMs);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
return await fn();
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await unlink(lockPath).catch(() => { });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function tryAcquire(lockPath) {
|
|
85
|
+
try {
|
|
86
|
+
const fd = await open(lockPath, "wx");
|
|
87
|
+
await fd.write(`${process.pid}\n`);
|
|
88
|
+
await fd.close();
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
if (err.code === "EEXIST")
|
|
93
|
+
return false;
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function readHolderPid(lockPath) {
|
|
98
|
+
try {
|
|
99
|
+
const body = await readFile(lockPath, "utf8");
|
|
100
|
+
const n = Number.parseInt(body.trim(), 10);
|
|
101
|
+
return Number.isFinite(n) ? n : null;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function reclaimIfStale(lockPath) {
|
|
108
|
+
const pid = await readHolderPid(lockPath);
|
|
109
|
+
if (pid === null)
|
|
110
|
+
return false;
|
|
111
|
+
if (isProcessAlive(pid))
|
|
112
|
+
return false;
|
|
113
|
+
await unlink(lockPath).catch(() => { });
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
function isProcessAlive(pid) {
|
|
117
|
+
try {
|
|
118
|
+
// Sending signal 0 throws if the process doesn't exist.
|
|
119
|
+
process.kill(pid, 0);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
return err.code === "EPERM";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function sleep(ms) {
|
|
127
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=lock.js.map
|
package/dist/lock.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Logger } from "pino";
|
|
2
|
+
export declare function logger(module: string): Logger;
|
|
3
|
+
export declare const rootLogger: Logger;
|
|
4
|
+
/**
|
|
5
|
+
* Redirect all subsequent pino output to `absPath`. Creates parent dirs as
|
|
6
|
+
* needed. Returns the path written to. Subsequent calls swap to the new
|
|
7
|
+
* file (the previous stream stays open for whatever Node's GC decides).
|
|
8
|
+
*/
|
|
9
|
+
export declare function setLogFile(absPath: string): string;
|
|
10
|
+
/** Re-route logger output to stderr. Useful for long-lived daemons. */
|
|
11
|
+
export declare function setLogStderr(): void;
|
|
12
|
+
/** Drop logger output entirely. Used by smokes that don't want noise. */
|
|
13
|
+
export declare function setLogNull(): void;
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createWriteStream, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { Writable } from "node:stream";
|
|
4
|
+
import { pino } from "pino";
|
|
5
|
+
/**
|
|
6
|
+
* Pino destination indirection. By default pino logs go to a black-hole
|
|
7
|
+
* writable so structured log lines never leak into a CLI's terminal output.
|
|
8
|
+
* Init / daemon / watch flows call `setLogFile(path)` early to redirect to
|
|
9
|
+
* a file. Long-lived background processes (daemon) can call `setLogStderr()`
|
|
10
|
+
* to fall back to stderr.
|
|
11
|
+
*
|
|
12
|
+
* Children created via `logger(module)` write to whichever destination is
|
|
13
|
+
* currently active at the time of the write — child references stay valid
|
|
14
|
+
* across redirection.
|
|
15
|
+
*/
|
|
16
|
+
let activeDestination = nullStream();
|
|
17
|
+
const proxyStream = new Writable({
|
|
18
|
+
write(chunk, _encoding, callback) {
|
|
19
|
+
try {
|
|
20
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
|
|
21
|
+
activeDestination.write(buf, () => callback());
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
callback(err instanceof Error ? err : new Error(String(err)));
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const root = pino({
|
|
29
|
+
level: process.env["CAIRN_LOG_LEVEL"] ?? "info",
|
|
30
|
+
base: { pid: process.pid },
|
|
31
|
+
redact: {
|
|
32
|
+
paths: [
|
|
33
|
+
"*.token",
|
|
34
|
+
"*.password",
|
|
35
|
+
"*.secret",
|
|
36
|
+
"*.apiKey",
|
|
37
|
+
"*.api_key",
|
|
38
|
+
"headers.authorization",
|
|
39
|
+
"headers.cookie",
|
|
40
|
+
],
|
|
41
|
+
censor: "[redacted]",
|
|
42
|
+
},
|
|
43
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
44
|
+
}, proxyStream);
|
|
45
|
+
export function logger(module) {
|
|
46
|
+
return root.child({ module });
|
|
47
|
+
}
|
|
48
|
+
export const rootLogger = root;
|
|
49
|
+
/**
|
|
50
|
+
* Redirect all subsequent pino output to `absPath`. Creates parent dirs as
|
|
51
|
+
* needed. Returns the path written to. Subsequent calls swap to the new
|
|
52
|
+
* file (the previous stream stays open for whatever Node's GC decides).
|
|
53
|
+
*/
|
|
54
|
+
export function setLogFile(absPath) {
|
|
55
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
56
|
+
const stream = createWriteStream(absPath, {
|
|
57
|
+
flags: "a",
|
|
58
|
+
encoding: "utf8",
|
|
59
|
+
});
|
|
60
|
+
activeDestination = stream;
|
|
61
|
+
return absPath;
|
|
62
|
+
}
|
|
63
|
+
/** Re-route logger output to stderr. Useful for long-lived daemons. */
|
|
64
|
+
export function setLogStderr() {
|
|
65
|
+
activeDestination = process.stderr;
|
|
66
|
+
}
|
|
67
|
+
/** Drop logger output entirely. Used by smokes that don't want noise. */
|
|
68
|
+
export function setLogNull() {
|
|
69
|
+
activeDestination = nullStream();
|
|
70
|
+
}
|
|
71
|
+
function nullStream() {
|
|
72
|
+
return new Writable({
|
|
73
|
+
write(_chunk, _enc, callback) {
|
|
74
|
+
callback();
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAoB,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAe,MAAM,MAAM,CAAC;AAEzC;;;;;;;;;;GAUG;AAEH,IAAI,iBAAiB,GAA0B,UAAU,EAAE,CAAC;AAE5D,MAAM,WAAW,GAAG,IAAI,QAAQ,CAAC;IAC/B,KAAK,CAAC,KAAsB,EAAE,SAAS,EAAE,QAAQ;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GACP,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACjE,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,IAAI,GAAW,IAAI,CACvB;IACE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM;IAC/C,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;IAC1B,MAAM,EAAE;QACN,KAAK,EAAE;YACL,SAAS;YACT,YAAY;YACZ,UAAU;YACV,UAAU;YACV,WAAW;YACX,uBAAuB;YACvB,gBAAgB;SACjB;QACD,MAAM,EAAE,YAAY;KACrB;IACD,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO;CACzC,EACD,WAAW,CACZ,CAAC;AAEF,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC;AAE/B;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAgB,iBAAiB,CAAC,OAAO,EAAE;QACrD,KAAK,EAAE,GAAG;QACV,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;IACH,iBAAiB,GAAG,MAAM,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY;IAC1B,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;AACrC,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,UAAU;IACxB,iBAAiB,GAAG,UAAU,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,QAAQ,CAAC;QAClB,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YAC1B,QAAQ,EAAE,CAAC;QACb,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap guard for MCP write tools.
|
|
3
|
+
*
|
|
4
|
+
* Spec: PLUGIN_ARCHITECTURE §17 Layer 4 (degraded mode).
|
|
5
|
+
*
|
|
6
|
+
* Each MCP write tool calls `requireBootstrap(repoRoot)` at the top of its
|
|
7
|
+
* executor. When the clone is unbootstrapped, the helper returns a
|
|
8
|
+
* `BOOTSTRAP_REQUIRED` envelope and the tool short-circuits — no lock, no
|
|
9
|
+
* filesystem write. Read tools (decision-get, search, etc.) skip this guard
|
|
10
|
+
* entirely, matching spec §17 "MCP read tools work (read-only)".
|
|
11
|
+
*
|
|
12
|
+
* Bootstrap state is cheap to inspect (one `git config --get`); we don't
|
|
13
|
+
* cache because a session that ran `cairn join` mid-conversation should
|
|
14
|
+
* be able to write on its next call.
|
|
15
|
+
*/
|
|
16
|
+
import { type McpErrorPayload } from "./errors.js";
|
|
17
|
+
/**
|
|
18
|
+
* The guard only blocks when *all three* are true:
|
|
19
|
+
* 1. `<repoRoot>/.git/` exists (otherwise this isn't a real clone)
|
|
20
|
+
* 2. `<repoRoot>/.cairn/config.yaml` exists (otherwise the project
|
|
21
|
+
* isn't actually cairn-adopted yet — `cairn init` will land it)
|
|
22
|
+
* 3. `git config core.hooksPath` is *not* `.cairn/git-hooks`
|
|
23
|
+
*
|
|
24
|
+
* Everything else passes through. This keeps unit / smoke fixtures that
|
|
25
|
+
* scaffold a partial `.cairn/` from being incorrectly degraded; the only
|
|
26
|
+
* scenario that trips the guard is a real adopted project on a clone where
|
|
27
|
+
* `cairn join` hasn't run yet.
|
|
28
|
+
*/
|
|
29
|
+
export declare function requireBootstrap(repoRoot: string): McpErrorPayload | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap guard for MCP write tools.
|
|
3
|
+
*
|
|
4
|
+
* Spec: PLUGIN_ARCHITECTURE §17 Layer 4 (degraded mode).
|
|
5
|
+
*
|
|
6
|
+
* Each MCP write tool calls `requireBootstrap(repoRoot)` at the top of its
|
|
7
|
+
* executor. When the clone is unbootstrapped, the helper returns a
|
|
8
|
+
* `BOOTSTRAP_REQUIRED` envelope and the tool short-circuits — no lock, no
|
|
9
|
+
* filesystem write. Read tools (decision-get, search, etc.) skip this guard
|
|
10
|
+
* entirely, matching spec §17 "MCP read tools work (read-only)".
|
|
11
|
+
*
|
|
12
|
+
* Bootstrap state is cheap to inspect (one `git config --get`); we don't
|
|
13
|
+
* cache because a session that ran `cairn join` mid-conversation should
|
|
14
|
+
* be able to write on its next call.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { inspectJoinState } from "../join/index.js";
|
|
19
|
+
import { mcpError } from "./errors.js";
|
|
20
|
+
/**
|
|
21
|
+
* The guard only blocks when *all three* are true:
|
|
22
|
+
* 1. `<repoRoot>/.git/` exists (otherwise this isn't a real clone)
|
|
23
|
+
* 2. `<repoRoot>/.cairn/config.yaml` exists (otherwise the project
|
|
24
|
+
* isn't actually cairn-adopted yet — `cairn init` will land it)
|
|
25
|
+
* 3. `git config core.hooksPath` is *not* `.cairn/git-hooks`
|
|
26
|
+
*
|
|
27
|
+
* Everything else passes through. This keeps unit / smoke fixtures that
|
|
28
|
+
* scaffold a partial `.cairn/` from being incorrectly degraded; the only
|
|
29
|
+
* scenario that trips the guard is a real adopted project on a clone where
|
|
30
|
+
* `cairn join` hasn't run yet.
|
|
31
|
+
*/
|
|
32
|
+
export function requireBootstrap(repoRoot) {
|
|
33
|
+
if (!existsSync(join(repoRoot, ".git")))
|
|
34
|
+
return null;
|
|
35
|
+
if (!existsSync(join(repoRoot, ".cairn", "config.yaml")))
|
|
36
|
+
return null;
|
|
37
|
+
const state = inspectJoinState({ repoRoot });
|
|
38
|
+
if (state.hooksPathSet)
|
|
39
|
+
return null;
|
|
40
|
+
return mcpError("BOOTSTRAP_REQUIRED", "this clone is not bootstrapped — run `cairn join` (or pick [a] on the inline SessionStart prompt) before cairn write tools engage", {
|
|
41
|
+
project_cairn_version: state.projectCairnVersion,
|
|
42
|
+
hooks_path_value: state.hooksPathValue,
|
|
43
|
+
sessions_dir_ready: state.sessionsDirReady,
|
|
44
|
+
remediation: "cairn join",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=bootstrap-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-guard.js","sourceRoot":"","sources":["../../src/mcp/bootstrap-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,MAAM,KAAK,GAAG,gBAAgB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,QAAQ,CACb,oBAAoB,EACpB,mIAAmI,EACnI;QACE,qBAAqB,EAAE,KAAK,CAAC,mBAAmB;QAChD,gBAAgB,EAAE,KAAK,CAAC,cAAc;QACtC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB;QAC1C,WAAW,EAAE,YAAY;KAC1B,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-server context. Set at server start; passed to every tool handler.
|
|
3
|
+
*
|
|
4
|
+
* The MCP server is started with `--repo-root <path>` (or CAIRN_REPO_ROOT
|
|
5
|
+
* env). All tool handlers operate against this root. The orchestrator pins a
|
|
6
|
+
* mirror checkout SHA and starts a server with that mirror's path as repoRoot.
|
|
7
|
+
*
|
|
8
|
+
* `sessionId` is stamped onto every invalidation event emitted by a write
|
|
9
|
+
* tool. When the plugin spawns the MCP server it forwards Claude Code's
|
|
10
|
+
* session_id; CLI invocations leave it null.
|
|
11
|
+
*/
|
|
12
|
+
export interface McpContext {
|
|
13
|
+
repoRoot: string;
|
|
14
|
+
/** Optional run id — when set, telemetry writes per-run; otherwise, top-level. */
|
|
15
|
+
runId?: string;
|
|
16
|
+
/** Claude Code session id of the spawning client, when known. */
|
|
17
|
+
sessionId?: string | null;
|
|
18
|
+
}
|
|
19
|
+
export declare function createContext(opts: {
|
|
20
|
+
repoRoot: string;
|
|
21
|
+
runId?: string;
|
|
22
|
+
sessionId?: string | null;
|
|
23
|
+
}): McpContext;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
export function createContext(opts) {
|
|
3
|
+
return {
|
|
4
|
+
repoRoot: resolve(opts.repoRoot),
|
|
5
|
+
...(opts.runId !== undefined ? { runId: opts.runId } : {}),
|
|
6
|
+
...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/mcp/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,MAAM,UAAU,aAAa,CAAC,IAI7B;IACC,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error envelope per MCP_SURFACE §"Failure modes".
|
|
3
|
+
*
|
|
4
|
+
* Tools NEVER throw. They return either a success payload or an error envelope
|
|
5
|
+
* shaped as { error: { code, message, details? } }. The envelope is wrapped in
|
|
6
|
+
* the MCP `CallToolResult` content text.
|
|
7
|
+
*/
|
|
8
|
+
export type McpErrorCode = "VALIDATION_FAILED" | "TOOL_NOT_FOUND" | "PATH_OUTSIDE_REPO" | "PATH_HISTORICAL_USE_QUERY_HISTORY" | "PATH_NOT_ALLOWED" | "FILE_NOT_FOUND" | "DAEMON_UNAVAILABLE" | "OPERATION_TIMEOUT" | "DECISION_NOT_FOUND" | "DECISION_ID_TAKEN" | "INVALID_ASSERTION_KIND" | "SUPERSEDES_NOT_FOUND" | "INVARIANT_NOT_FOUND" | "TOPIC_NOT_REGISTERED" | "RUN_NOT_FOUND" | "TASK_NOT_FOUND" | "NOT_ALLOWED" | "NOT_IMPLEMENTED" | "BOOTSTRAP_REQUIRED";
|
|
9
|
+
export interface McpErrorPayload {
|
|
10
|
+
error: {
|
|
11
|
+
code: McpErrorCode;
|
|
12
|
+
message: string;
|
|
13
|
+
details?: unknown;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function mcpError(code: McpErrorCode, message: string, details?: unknown): McpErrorPayload;
|
|
17
|
+
export declare function isMcpError(payload: unknown): payload is McpErrorPayload;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error envelope per MCP_SURFACE §"Failure modes".
|
|
3
|
+
*
|
|
4
|
+
* Tools NEVER throw. They return either a success payload or an error envelope
|
|
5
|
+
* shaped as { error: { code, message, details? } }. The envelope is wrapped in
|
|
6
|
+
* the MCP `CallToolResult` content text.
|
|
7
|
+
*/
|
|
8
|
+
export function mcpError(code, message, details) {
|
|
9
|
+
return {
|
|
10
|
+
error: {
|
|
11
|
+
code,
|
|
12
|
+
message,
|
|
13
|
+
...(details !== undefined ? { details } : {}),
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function isMcpError(payload) {
|
|
18
|
+
return (typeof payload === "object" &&
|
|
19
|
+
payload !== null &&
|
|
20
|
+
"error" in payload &&
|
|
21
|
+
typeof payload.error === "object");
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH,MAAM,UAAU,QAAQ,CACtB,IAAkB,EAClB,OAAe,EACf,OAAiB;IAEjB,OAAO;QACL,KAAK,EAAE;YACL,IAAI;YACJ,OAAO;YACP,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9C;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,CACL,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,KAAK,IAAI;QAChB,OAAO,IAAI,OAAO;QAClB,OAAQ,OAA8B,CAAC,KAAK,KAAK,QAAQ,CAC1D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { walkArchive } from "./walker.js";
|
|
2
|
+
export type { ArchiveFile, WalkArchiveOptions, WalkArchiveResult } from "./walker.js";
|
|
3
|
+
export { HISTORY_SUMMARIZER_SYSTEM_PROMPT, buildHistorySummarizerUserPrompt, CAIRN_HISTORY_SUMMARIZE_PROMPT_ID, CAIRN_HISTORY_SUMMARIZE_VERSION, } from "./prompt.js";
|
|
4
|
+
export { HISTORY_SUMMARIZER_OUTPUT_SCHEMA } from "./schema.js";
|
|
5
|
+
export { runHistorySummarizer, runQueryHistory, } from "./summarizer.js";
|
|
6
|
+
export type { QueryHistoryResponse, RunQueryHistoryArgs, SummarizedClaim, } from "./summarizer.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { walkArchive } from "./walker.js";
|
|
2
|
+
export { HISTORY_SUMMARIZER_SYSTEM_PROMPT, buildHistorySummarizerUserPrompt, CAIRN_HISTORY_SUMMARIZE_PROMPT_ID, CAIRN_HISTORY_SUMMARIZE_VERSION, } from "./prompt.js";
|
|
3
|
+
export { HISTORY_SUMMARIZER_OUTPUT_SCHEMA } from "./schema.js";
|
|
4
|
+
export { runHistorySummarizer, runQueryHistory, } from "./summarizer.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/history/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EAChC,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,oBAAoB,EACpB,eAAe,GAChB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier-1 (Haiku) summarizer prompts for cairn_query_history.
|
|
3
|
+
*
|
|
4
|
+
* Constraint: the LLM emits ONLY structured claims; raw historical
|
|
5
|
+
* content never reaches the agent's context. Each claim cites a
|
|
6
|
+
* concrete source_path + source_lines so the operator (and any future
|
|
7
|
+
* audit) can verify the summary against the original.
|
|
8
|
+
*
|
|
9
|
+
* The prompt id + version are committed in source so a behavior change
|
|
10
|
+
* here is a versioned change in the source tree, not a silent runtime
|
|
11
|
+
* update.
|
|
12
|
+
*/
|
|
13
|
+
import type { ArchiveFile } from "./walker.js";
|
|
14
|
+
export declare const CAIRN_HISTORY_SUMMARIZE_PROMPT_ID = "cairn.history_summarize.v1";
|
|
15
|
+
export declare const CAIRN_HISTORY_SUMMARIZE_VERSION = "v1";
|
|
16
|
+
export declare const HISTORY_SUMMARIZER_SYSTEM_PROMPT = "You are the **history summarizer** for an agent cairn's two-zone read separation. The agent calling you cannot read .archive/ files directly \u2014 by design. You read those files on its behalf and emit a structured response with cited claims. Only your structured response reaches the agent's context.\n\nYour job: read N historical files and the operator's scope question. Produce per-claim records that capture what the historical files said, with full citation, dates, and supersedes-tags pointing at currently-canonical decisions when they exist.\n\n## Hard contract\n\nEvery claim you emit MUST include:\n\n- `claim` \u2014 one-sentence factual statement of what the historical content said. Past-tense. Imperative voice avoided. Example: \"The project considered using a JSONB expression index on commandPayload->>'userId' for dashboard queries.\" NOT \"The project should use a JSONB index\" \u2014 that is current-tense and reads as canon.\n- `as_of` \u2014 ISO date when the source content was authored / valid. Use the file's frontmatter `generated` or `verified-at`, the bucket date in the path (`.archive/2026-05-pre-cairn/`), or the most explicit date you can find in the body. If genuinely unknown, set the bucket date.\n- `source_path` \u2014 the repo-relative path EXACTLY as given in the file headers. Do not invent a path or a hash.\n- `source_lines` \u2014 line range like \"320-410\" or a single line \"47\". Required so the operator can audit your summary by opening the original file.\n- `superseded_by` \u2014 when an accepted decision in the supplied \"Currently-accepted decisions\" list directly relates to the historical claim, set the DEC-NNNN id. Otherwise set null. Do NOT invent decision ids.\n\n## When you should set `no_relevant_history: true`\n\nThe supplied files don't contain anything relevant to the operator's scope question. Better to short-circuit than to fabricate a summary. The cairn returns an empty claims array with a one-line caveat.\n\n## When you should set `summary_caveat`\n\nAnything important about the input that affects how the agent should treat your output:\n- \"Summary covers 8 files; 3 additional matches were truncated.\"\n- \"All claims are from a single bucket dated 2026-04-23; nothing more recent in scope.\"\n\n## What you must NOT do\n\n- Do NOT issue a recommendation. Your output is descriptive (what was said), not prescriptive (what to do).\n- Do NOT phrase claims as if they are current truth. Always past-tense + cited.\n- Do NOT invent paths, line ranges, decision ids, or dates. If you can't find a value, set what's required by schema and skip the claim.\n- Do NOT emit a free-form preamble before the JSON.\n- Do NOT emit fields not in the schema.\n\nOutput ONLY the JSON object.";
|
|
17
|
+
export interface BuildHistoryUserPromptArgs {
|
|
18
|
+
/** Operator's free-text scope description. */
|
|
19
|
+
scope: string;
|
|
20
|
+
/** Repo-relative pathHint glob, when provided. */
|
|
21
|
+
pathHint?: string;
|
|
22
|
+
since?: string;
|
|
23
|
+
until?: string;
|
|
24
|
+
files: ArchiveFile[];
|
|
25
|
+
/** Optional ledger of currently-accepted decisions for supersedes inference. */
|
|
26
|
+
acceptedDecisions: {
|
|
27
|
+
id: string;
|
|
28
|
+
title: string;
|
|
29
|
+
scope_globs?: string[];
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
32
|
+
export declare function buildHistorySummarizerUserPrompt(args: BuildHistoryUserPromptArgs): string;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier-1 (Haiku) summarizer prompts for cairn_query_history.
|
|
3
|
+
*
|
|
4
|
+
* Constraint: the LLM emits ONLY structured claims; raw historical
|
|
5
|
+
* content never reaches the agent's context. Each claim cites a
|
|
6
|
+
* concrete source_path + source_lines so the operator (and any future
|
|
7
|
+
* audit) can verify the summary against the original.
|
|
8
|
+
*
|
|
9
|
+
* The prompt id + version are committed in source so a behavior change
|
|
10
|
+
* here is a versioned change in the source tree, not a silent runtime
|
|
11
|
+
* update.
|
|
12
|
+
*/
|
|
13
|
+
export const CAIRN_HISTORY_SUMMARIZE_PROMPT_ID = "cairn.history_summarize.v1";
|
|
14
|
+
export const CAIRN_HISTORY_SUMMARIZE_VERSION = "v1";
|
|
15
|
+
export const HISTORY_SUMMARIZER_SYSTEM_PROMPT = `You are the **history summarizer** for an agent cairn's two-zone read separation. The agent calling you cannot read .archive/ files directly — by design. You read those files on its behalf and emit a structured response with cited claims. Only your structured response reaches the agent's context.
|
|
16
|
+
|
|
17
|
+
Your job: read N historical files and the operator's scope question. Produce per-claim records that capture what the historical files said, with full citation, dates, and supersedes-tags pointing at currently-canonical decisions when they exist.
|
|
18
|
+
|
|
19
|
+
## Hard contract
|
|
20
|
+
|
|
21
|
+
Every claim you emit MUST include:
|
|
22
|
+
|
|
23
|
+
- \`claim\` — one-sentence factual statement of what the historical content said. Past-tense. Imperative voice avoided. Example: "The project considered using a JSONB expression index on commandPayload->>'userId' for dashboard queries." NOT "The project should use a JSONB index" — that is current-tense and reads as canon.
|
|
24
|
+
- \`as_of\` — ISO date when the source content was authored / valid. Use the file's frontmatter \`generated\` or \`verified-at\`, the bucket date in the path (\`.archive/2026-05-pre-cairn/\`), or the most explicit date you can find in the body. If genuinely unknown, set the bucket date.
|
|
25
|
+
- \`source_path\` — the repo-relative path EXACTLY as given in the file headers. Do not invent a path or a hash.
|
|
26
|
+
- \`source_lines\` — line range like "320-410" or a single line "47". Required so the operator can audit your summary by opening the original file.
|
|
27
|
+
- \`superseded_by\` — when an accepted decision in the supplied "Currently-accepted decisions" list directly relates to the historical claim, set the DEC-NNNN id. Otherwise set null. Do NOT invent decision ids.
|
|
28
|
+
|
|
29
|
+
## When you should set \`no_relevant_history: true\`
|
|
30
|
+
|
|
31
|
+
The supplied files don't contain anything relevant to the operator's scope question. Better to short-circuit than to fabricate a summary. The cairn returns an empty claims array with a one-line caveat.
|
|
32
|
+
|
|
33
|
+
## When you should set \`summary_caveat\`
|
|
34
|
+
|
|
35
|
+
Anything important about the input that affects how the agent should treat your output:
|
|
36
|
+
- "Summary covers 8 files; 3 additional matches were truncated."
|
|
37
|
+
- "All claims are from a single bucket dated 2026-04-23; nothing more recent in scope."
|
|
38
|
+
|
|
39
|
+
## What you must NOT do
|
|
40
|
+
|
|
41
|
+
- Do NOT issue a recommendation. Your output is descriptive (what was said), not prescriptive (what to do).
|
|
42
|
+
- Do NOT phrase claims as if they are current truth. Always past-tense + cited.
|
|
43
|
+
- Do NOT invent paths, line ranges, decision ids, or dates. If you can't find a value, set what's required by schema and skip the claim.
|
|
44
|
+
- Do NOT emit a free-form preamble before the JSON.
|
|
45
|
+
- Do NOT emit fields not in the schema.
|
|
46
|
+
|
|
47
|
+
Output ONLY the JSON object.`;
|
|
48
|
+
const PER_FILE_HEADER_PREVIEW_LINES = 800;
|
|
49
|
+
export function buildHistorySummarizerUserPrompt(args) {
|
|
50
|
+
const sections = [];
|
|
51
|
+
sections.push("## Operator scope question");
|
|
52
|
+
sections.push(args.scope.trim());
|
|
53
|
+
sections.push("");
|
|
54
|
+
sections.push("## Filters applied to the .archive/ walk");
|
|
55
|
+
sections.push(`path_hint: ${args.pathHint ?? "(none — full archive)"}`);
|
|
56
|
+
sections.push(`since: ${args.since ?? "(none — beginning of time)"}`);
|
|
57
|
+
sections.push(`until: ${args.until ?? "(none — present)"}`);
|
|
58
|
+
sections.push(`matched_files: ${args.files.length}`);
|
|
59
|
+
if (args.acceptedDecisions.length > 0) {
|
|
60
|
+
sections.push("");
|
|
61
|
+
sections.push("## Currently-accepted decisions (for supersedes inference)");
|
|
62
|
+
sections.push("Each line: `<DEC-id> — <title> (scope: <globs>)`. If a historical claim directly contradicts or has been replaced by one of these, cite the id in `superseded_by`. Otherwise set null. Do NOT invent ids.");
|
|
63
|
+
sections.push("");
|
|
64
|
+
for (const d of args.acceptedDecisions.slice(0, 30)) {
|
|
65
|
+
const scope = d.scope_globs && d.scope_globs.length > 0 ? d.scope_globs.join(", ") : "(no scope)";
|
|
66
|
+
sections.push(`- **${d.id}** — ${d.title} (scope: ${scope})`);
|
|
67
|
+
}
|
|
68
|
+
if (args.acceptedDecisions.length > 30) {
|
|
69
|
+
sections.push(`…(${args.acceptedDecisions.length - 30} additional accepted decisions omitted)`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
sections.push("");
|
|
73
|
+
sections.push("## Historical files (line-numbered)");
|
|
74
|
+
if (args.files.length === 0) {
|
|
75
|
+
sections.push("(none — return `no_relevant_history: true`)");
|
|
76
|
+
}
|
|
77
|
+
for (const f of args.files) {
|
|
78
|
+
sections.push("");
|
|
79
|
+
sections.push(`### ${f.relPath} (bucket: ${f.bucket}, archive_date: ${f.archiveDate}${f.truncated ? ", TRUNCATED" : ""})`);
|
|
80
|
+
sections.push("```");
|
|
81
|
+
sections.push(numberLines(f.content, PER_FILE_HEADER_PREVIEW_LINES));
|
|
82
|
+
sections.push("```");
|
|
83
|
+
}
|
|
84
|
+
sections.push("");
|
|
85
|
+
sections.push("## Your task");
|
|
86
|
+
sections.push("Emit the JSON object per the schema. Cite source_path EXACTLY as the headers above show. Output ONLY the JSON object.");
|
|
87
|
+
return sections.join("\n");
|
|
88
|
+
}
|
|
89
|
+
function numberLines(text, maxLines) {
|
|
90
|
+
const lines = text.split(/\r?\n/);
|
|
91
|
+
const truncated = lines.length > maxLines;
|
|
92
|
+
const slice = truncated ? lines.slice(0, maxLines) : lines;
|
|
93
|
+
const padWidth = String(slice.length).length;
|
|
94
|
+
const out = slice.map((line, i) => `${String(i + 1).padStart(padWidth, " ")} ${line}`);
|
|
95
|
+
if (truncated)
|
|
96
|
+
out.push(`…[${lines.length - maxLines} more lines elided]`);
|
|
97
|
+
return out.join("\n");
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/mcp/history/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema enforced by `claude --json-schema` for the history
|
|
3
|
+
* summarizer Tier-1 call.
|
|
4
|
+
*
|
|
5
|
+
* Per MCP_SURFACE.md §"cairn_query_history": every claim MUST carry
|
|
6
|
+
* source_path, source_lines, as_of, and a supersedes-tag (string DEC-id
|
|
7
|
+
* or null). The cairn post-resolves currently_canonical_pointer from
|
|
8
|
+
* the decisions ledger after the LLM returns — keeps the LLM's
|
|
9
|
+
* responsibilities tight (cite + summarize) and makes the canonical
|
|
10
|
+
* cross-reference mechanical.
|
|
11
|
+
*/
|
|
12
|
+
export declare const HISTORY_SUMMARIZER_OUTPUT_SCHEMA: {
|
|
13
|
+
readonly type: "object";
|
|
14
|
+
readonly additionalProperties: false;
|
|
15
|
+
readonly properties: {
|
|
16
|
+
readonly claims: {
|
|
17
|
+
readonly type: "array";
|
|
18
|
+
readonly items: {
|
|
19
|
+
readonly type: "object";
|
|
20
|
+
readonly additionalProperties: false;
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly claim: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly minLength: 1;
|
|
25
|
+
};
|
|
26
|
+
readonly as_of: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly minLength: 1;
|
|
29
|
+
};
|
|
30
|
+
readonly source_path: {
|
|
31
|
+
readonly type: "string";
|
|
32
|
+
readonly minLength: 1;
|
|
33
|
+
};
|
|
34
|
+
readonly source_lines: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly minLength: 1;
|
|
37
|
+
};
|
|
38
|
+
readonly superseded_by: {
|
|
39
|
+
readonly anyOf: readonly [{
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
readonly pattern: "^DEC-\\d{4,}$";
|
|
42
|
+
}, {
|
|
43
|
+
readonly type: "null";
|
|
44
|
+
}];
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
readonly required: readonly ["claim", "as_of", "source_path", "source_lines"];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
readonly summary_caveat: {
|
|
51
|
+
readonly type: "string";
|
|
52
|
+
};
|
|
53
|
+
readonly no_relevant_history: {
|
|
54
|
+
readonly type: "boolean";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly required: readonly ["claims"];
|
|
58
|
+
};
|