@contorium/mcp 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +97 -0
  2. package/bin/contorium-mcp.js +34 -0
  3. package/dist/autoContext.d.ts +2 -0
  4. package/dist/autoContext.js +2 -0
  5. package/dist/bootstrapCli.d.ts +2 -0
  6. package/dist/bootstrapCli.js +21 -0
  7. package/dist/conflicts.d.ts +19 -0
  8. package/dist/conflicts.js +49 -0
  9. package/dist/dashboardEnsure.d.ts +10 -0
  10. package/dist/dashboardEnsure.js +41 -0
  11. package/dist/intelligence.d.ts +16 -0
  12. package/dist/intelligence.js +38 -0
  13. package/dist/intentGraph.d.ts +20 -0
  14. package/dist/intentGraph.js +51 -0
  15. package/dist/mcpBootstrap.d.ts +8 -0
  16. package/dist/mcpBootstrap.js +81 -0
  17. package/dist/memoryStore.d.ts +18 -0
  18. package/dist/memoryStore.js +57 -0
  19. package/dist/paths.d.ts +12 -0
  20. package/dist/paths.js +66 -0
  21. package/dist/runtimeState.d.ts +14 -0
  22. package/dist/runtimeState.js +36 -0
  23. package/dist/server.d.ts +3 -0
  24. package/dist/server.js +567 -0
  25. package/dist/stateBuilder.d.ts +16 -0
  26. package/dist/stateBuilder.js +40 -0
  27. package/dist/understanding.d.ts +1 -0
  28. package/dist/understanding.js +1 -0
  29. package/dist/workspace.d.ts +12 -0
  30. package/dist/workspace.js +40 -0
  31. package/dist/workspaceConfig.d.ts +14 -0
  32. package/dist/workspaceConfig.js +80 -0
  33. package/node_modules/@contora/state-core/dist/adapterSync.d.ts +29 -0
  34. package/node_modules/@contora/state-core/dist/adapterSync.d.ts.map +1 -0
  35. package/node_modules/@contora/state-core/dist/adapterSync.js +142 -0
  36. package/node_modules/@contora/state-core/dist/adapters.d.ts +20 -0
  37. package/node_modules/@contora/state-core/dist/adapters.d.ts.map +1 -0
  38. package/node_modules/@contora/state-core/dist/adapters.js +24 -0
  39. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.d.ts +6 -0
  40. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.d.ts.map +1 -0
  41. package/node_modules/@contora/state-core/dist/bootstrap/bootstrapState.js +116 -0
  42. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.d.ts +18 -0
  43. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.d.ts.map +1 -0
  44. package/node_modules/@contora/state-core/dist/bootstrapArtifacts.js +43 -0
  45. package/node_modules/@contora/state-core/dist/bootstrapState.d.ts +6 -0
  46. package/node_modules/@contora/state-core/dist/bootstrapState.d.ts.map +1 -0
  47. package/node_modules/@contora/state-core/dist/bootstrapState.js +60 -0
  48. package/node_modules/@contora/state-core/dist/dashboardActivity.d.ts +12 -0
  49. package/node_modules/@contora/state-core/dist/dashboardActivity.d.ts.map +1 -0
  50. package/node_modules/@contora/state-core/dist/dashboardActivity.js +58 -0
  51. package/node_modules/@contora/state-core/dist/dualMode.d.ts +11 -0
  52. package/node_modules/@contora/state-core/dist/dualMode.d.ts.map +1 -0
  53. package/node_modules/@contora/state-core/dist/dualMode.js +38 -0
  54. package/node_modules/@contora/state-core/dist/gitScan.d.ts +7 -0
  55. package/node_modules/@contora/state-core/dist/gitScan.d.ts.map +1 -0
  56. package/node_modules/@contora/state-core/dist/gitScan.js +39 -0
  57. package/node_modules/@contora/state-core/dist/index.d.ts +44 -0
  58. package/node_modules/@contora/state-core/dist/index.d.ts.map +1 -0
  59. package/node_modules/@contora/state-core/dist/index.js +141 -0
  60. package/node_modules/@contora/state-core/dist/minimalSnapshot.d.ts +4 -0
  61. package/node_modules/@contora/state-core/dist/minimalSnapshot.d.ts.map +1 -0
  62. package/node_modules/@contora/state-core/dist/minimalSnapshot.js +60 -0
  63. package/node_modules/@contora/state-core/dist/scanner/gitScan.d.ts +7 -0
  64. package/node_modules/@contora/state-core/dist/scanner/gitScan.d.ts.map +1 -0
  65. package/node_modules/@contora/state-core/dist/scanner/gitScan.js +42 -0
  66. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.d.ts +4 -0
  67. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.d.ts.map +1 -0
  68. package/node_modules/@contora/state-core/dist/scanner/workspaceScanner.js +148 -0
  69. package/node_modules/@contora/state-core/dist/semiAutoHandoff.d.ts +46 -0
  70. package/node_modules/@contora/state-core/dist/semiAutoHandoff.d.ts.map +1 -0
  71. package/node_modules/@contora/state-core/dist/semiAutoHandoff.js +227 -0
  72. package/node_modules/@contora/state-core/dist/sourceMetadata.d.ts +4 -0
  73. package/node_modules/@contora/state-core/dist/sourceMetadata.d.ts.map +1 -0
  74. package/node_modules/@contora/state-core/dist/sourceMetadata.js +27 -0
  75. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.d.ts +5 -0
  76. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.d.ts.map +1 -0
  77. package/node_modules/@contora/state-core/dist/state-builder/buildFromScan.js +33 -0
  78. package/node_modules/@contora/state-core/dist/state-builder/normalization.d.ts +5 -0
  79. package/node_modules/@contora/state-core/dist/state-builder/normalization.d.ts.map +1 -0
  80. package/node_modules/@contora/state-core/dist/state-builder/normalization.js +107 -0
  81. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.d.ts +4 -0
  82. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.d.ts.map +1 -0
  83. package/node_modules/@contora/state-core/dist/state-builder/rebuildFromScan.js +22 -0
  84. package/node_modules/@contora/state-core/dist/state-builder/snapshot.d.ts +5 -0
  85. package/node_modules/@contora/state-core/dist/state-builder/snapshot.d.ts.map +1 -0
  86. package/node_modules/@contora/state-core/dist/state-builder/snapshot.js +53 -0
  87. package/node_modules/@contora/state-core/dist/state-builder/store.d.ts +7 -0
  88. package/node_modules/@contora/state-core/dist/state-builder/store.d.ts.map +1 -0
  89. package/node_modules/@contora/state-core/dist/state-builder/store.js +99 -0
  90. package/node_modules/@contora/state-core/dist/state-builder/types.d.ts +18 -0
  91. package/node_modules/@contora/state-core/dist/state-builder/types.d.ts.map +1 -0
  92. package/node_modules/@contora/state-core/dist/state-builder/types.js +20 -0
  93. package/node_modules/@contora/state-core/dist/types.d.ts +42 -0
  94. package/node_modules/@contora/state-core/dist/types.d.ts.map +1 -0
  95. package/node_modules/@contora/state-core/dist/types.js +3 -0
  96. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.d.ts +22 -0
  97. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.d.ts.map +1 -0
  98. package/node_modules/@contora/state-core/dist/understanding/buildUnderstanding.js +87 -0
  99. package/node_modules/@contora/state-core/dist/understanding/changeDetector.d.ts +7 -0
  100. package/node_modules/@contora/state-core/dist/understanding/changeDetector.d.ts.map +1 -0
  101. package/node_modules/@contora/state-core/dist/understanding/changeDetector.js +68 -0
  102. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.d.ts +49 -0
  103. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.d.ts.map +1 -0
  104. package/node_modules/@contora/state-core/dist/understanding/chpHandoff.js +214 -0
  105. package/node_modules/@contora/state-core/dist/understanding/extractor.d.ts +21 -0
  106. package/node_modules/@contora/state-core/dist/understanding/extractor.d.ts.map +1 -0
  107. package/node_modules/@contora/state-core/dist/understanding/extractor.js +173 -0
  108. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.d.ts +30 -0
  109. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.d.ts.map +1 -0
  110. package/node_modules/@contora/state-core/dist/understanding/formatCanonicalExport.js +363 -0
  111. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.d.ts +20 -0
  112. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.d.ts.map +1 -0
  113. package/node_modules/@contora/state-core/dist/understanding/formatHandoff.js +57 -0
  114. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.d.ts +9 -0
  115. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.d.ts.map +1 -0
  116. package/node_modules/@contora/state-core/dist/understanding/graphBuilder.js +107 -0
  117. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.d.ts +12 -0
  118. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.d.ts.map +1 -0
  119. package/node_modules/@contora/state-core/dist/understanding/handoffBuilder.js +101 -0
  120. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.d.ts +5 -0
  121. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.d.ts.map +1 -0
  122. package/node_modules/@contora/state-core/dist/understanding/impactAnalyzer.js +58 -0
  123. package/node_modules/@contora/state-core/dist/understanding/intentFusion.d.ts +9 -0
  124. package/node_modules/@contora/state-core/dist/understanding/intentFusion.d.ts.map +1 -0
  125. package/node_modules/@contora/state-core/dist/understanding/intentFusion.js +54 -0
  126. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.d.ts +24 -0
  127. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.d.ts.map +1 -0
  128. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/closureConstants.js +33 -0
  129. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.d.ts +20 -0
  130. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.d.ts.map +1 -0
  131. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/confidence.js +53 -0
  132. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.d.ts +5 -0
  133. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.d.ts.map +1 -0
  134. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/gitFrequency.js +19 -0
  135. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.d.ts +13 -0
  136. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.d.ts.map +1 -0
  137. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/hotspotBuilder.js +101 -0
  138. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.d.ts +22 -0
  139. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.d.ts.map +1 -0
  140. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/intentFunctionMapper.js +106 -0
  141. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.d.ts +23 -0
  142. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.d.ts.map +1 -0
  143. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/knowledgeGraphBuilder.js +415 -0
  144. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.d.ts +11 -0
  145. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.d.ts.map +1 -0
  146. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/normalize.js +136 -0
  147. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.d.ts +13 -0
  148. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.d.ts.map +1 -0
  149. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/rebuildTrigger.js +34 -0
  150. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.d.ts +17 -0
  151. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.d.ts.map +1 -0
  152. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/snapshotBuilder.js +73 -0
  153. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.d.ts +7 -0
  154. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.d.ts.map +1 -0
  155. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/store.js +127 -0
  156. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.d.ts +116 -0
  157. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.d.ts.map +1 -0
  158. package/node_modules/@contora/state-core/dist/understanding/knowledgeGraph/types.js +6 -0
  159. package/node_modules/@contora/state-core/dist/understanding/miniGraph.d.ts +4 -0
  160. package/node_modules/@contora/state-core/dist/understanding/miniGraph.d.ts.map +1 -0
  161. package/node_modules/@contora/state-core/dist/understanding/miniGraph.js +18 -0
  162. package/node_modules/@contora/state-core/dist/understanding/store.d.ts +24 -0
  163. package/node_modules/@contora/state-core/dist/understanding/store.d.ts.map +1 -0
  164. package/node_modules/@contora/state-core/dist/understanding/store.js +243 -0
  165. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.d.ts +9 -0
  166. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.d.ts.map +1 -0
  167. package/node_modules/@contora/state-core/dist/understanding/symbolValidator.js +51 -0
  168. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.d.ts +3 -0
  169. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.d.ts.map +1 -0
  170. package/node_modules/@contora/state-core/dist/understanding/timelineTracker.js +129 -0
  171. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.d.ts +24 -0
  172. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.d.ts.map +1 -0
  173. package/node_modules/@contora/state-core/dist/understanding/treeSitterParser.js +56 -0
  174. package/node_modules/@contora/state-core/dist/understanding/types.d.ts +136 -0
  175. package/node_modules/@contora/state-core/dist/understanding/types.d.ts.map +1 -0
  176. package/node_modules/@contora/state-core/dist/understanding/types.js +5 -0
  177. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.d.ts +23 -0
  178. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.d.ts.map +1 -0
  179. package/node_modules/@contora/state-core/dist/understanding/understandingGraphBuilder.js +67 -0
  180. package/node_modules/@contora/state-core/dist/version.d.ts +3 -0
  181. package/node_modules/@contora/state-core/dist/version.d.ts.map +1 -0
  182. package/node_modules/@contora/state-core/dist/version.js +21 -0
  183. package/node_modules/@contora/state-core/dist/workspaceScanner.d.ts +4 -0
  184. package/node_modules/@contora/state-core/dist/workspaceScanner.d.ts.map +1 -0
  185. package/node_modules/@contora/state-core/dist/workspaceScanner.js +112 -0
  186. package/node_modules/@contora/state-core/package.json +49 -0
  187. package/package.json +61 -0
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scanWorkspace = scanWorkspace;
37
+ const fs = __importStar(require("node:fs/promises"));
38
+ const path = __importStar(require("node:path"));
39
+ const gitScan_js_1 = require("./gitScan.js");
40
+ const SKIP_DIRS = new Set([
41
+ 'node_modules',
42
+ '.git',
43
+ '.contora',
44
+ '.context-recall',
45
+ 'dist',
46
+ 'out',
47
+ '.vscode',
48
+ 'coverage',
49
+ ]);
50
+ const SKIP_EXT = /\.(png|jpg|jpeg|gif|ico|woff2?|ttf|eot|zip|vsix|map)$/i;
51
+ async function readReadmeHint(root) {
52
+ for (const name of ['README.md', 'readme.md', 'Readme.md']) {
53
+ try {
54
+ const text = await fs.readFile(path.join(root, name), 'utf8');
55
+ for (const line of text.split('\n')) {
56
+ const t = line.replace(/^#+\s*/, '').trim();
57
+ if (t.length >= 12 && !/^contorium|table of contents/i.test(t)) {
58
+ return t.length > 160 ? t.slice(0, 157) + '…' : t;
59
+ }
60
+ }
61
+ }
62
+ catch {
63
+ /* try next */
64
+ }
65
+ }
66
+ return undefined;
67
+ }
68
+ async function listTopLevelModules(root) {
69
+ const out = [];
70
+ try {
71
+ const entries = await fs.readdir(root, { withFileTypes: true });
72
+ for (const e of entries) {
73
+ if (!e.isDirectory() || e.name.startsWith('.') || SKIP_DIRS.has(e.name)) {
74
+ continue;
75
+ }
76
+ out.push(e.name);
77
+ }
78
+ }
79
+ catch {
80
+ return out;
81
+ }
82
+ return out.slice(0, 12);
83
+ }
84
+ async function collectRecentFiles(root, maxFiles, maxDepth) {
85
+ const scored = [];
86
+ async function walk(dir, depth) {
87
+ if (depth > maxDepth || scored.length >= maxFiles * 3) {
88
+ return;
89
+ }
90
+ let entries;
91
+ try {
92
+ entries = await fs.readdir(dir, { withFileTypes: true });
93
+ }
94
+ catch {
95
+ return;
96
+ }
97
+ for (const e of entries) {
98
+ const name = e.name;
99
+ if (name.startsWith('.') && name !== '.env') {
100
+ if (SKIP_DIRS.has(name)) {
101
+ continue;
102
+ }
103
+ }
104
+ const full = path.join(dir, name);
105
+ const rel = path.relative(root, full).replace(/\\/g, '/');
106
+ if (e.isDirectory()) {
107
+ if (!SKIP_DIRS.has(name)) {
108
+ await walk(full, depth + 1);
109
+ }
110
+ continue;
111
+ }
112
+ if (SKIP_EXT.test(name)) {
113
+ continue;
114
+ }
115
+ try {
116
+ const st = await fs.stat(full);
117
+ scored.push({ rel, mtime: st.mtimeMs });
118
+ }
119
+ catch {
120
+ /* skip */
121
+ }
122
+ }
123
+ }
124
+ await walk(root, 0);
125
+ scored.sort((a, b) => b.mtime - a.mtime);
126
+ return scored.slice(0, maxFiles).map((s) => s.rel);
127
+ }
128
+ /** Mode B — workspace filesystem scan (no IDE required). */
129
+ async function scanWorkspace(workspaceRoot) {
130
+ const root = path.resolve(workspaceRoot);
131
+ const now = Date.now();
132
+ const [git, topLevelModules, recentFiles, readmeHint] = await Promise.all([
133
+ (0, gitScan_js_1.scanGitPorcelain)(root),
134
+ listTopLevelModules(root),
135
+ collectRecentFiles(root, 24, 5),
136
+ readReadmeHint(root),
137
+ ]);
138
+ return {
139
+ workspaceRoot: root,
140
+ scannedAt: now,
141
+ topLevelModules,
142
+ recentFiles,
143
+ gitStaged: git.staged,
144
+ gitWorking: git.working,
145
+ readmeHint,
146
+ isGitRepo: git.isRepo,
147
+ };
148
+ }
@@ -0,0 +1,46 @@
1
+ import { type ChpHandoffFormat } from './understanding/chpHandoff.js';
2
+ export type HandoffInjectionStatus = 'pending' | 'injected' | 'skipped';
3
+ export interface HandoffInjectionState {
4
+ runtime_id: string;
5
+ status: HandoffInjectionStatus;
6
+ prompted_at: number;
7
+ resolved_at?: number;
8
+ context_file: string;
9
+ format?: ChpHandoffFormat;
10
+ /** Set on each new AI chat — skip/inject applies to this chat only. */
11
+ chat_session_id?: string;
12
+ }
13
+ export interface PrepareHandoffOptions {
14
+ /** New AI chat (MCP reconnect / new Agent window) — always re-prompt. */
15
+ newChat?: boolean;
16
+ }
17
+ /** Active runtime = bootstrap marker + handoff available. */
18
+ export declare function checkActiveRuntime(workspaceRoot: string): Promise<{
19
+ active: boolean;
20
+ runtime_id?: string;
21
+ }>;
22
+ export declare function readHandoffInjectionState(workspaceRoot: string): Promise<HandoffInjectionState | undefined>;
23
+ export declare function readConfirmedHandoffContext(workspaceRoot: string): Promise<string | undefined>;
24
+ export declare function buildInjectionPromptMessage(projectHint: string, compactLine?: string): string;
25
+ /** Prepare semi-auto injection — pending only, does NOT write context file. */
26
+ export declare function prepareHandoffInjection(workspaceRoot: string, options?: PrepareHandoffOptions): Promise<{
27
+ shouldPrompt: boolean;
28
+ alreadyInjected: boolean;
29
+ prompt?: string;
30
+ state?: HandoffInjectionState;
31
+ compact?: string;
32
+ }>;
33
+ /** User confirmed — write context file and mark injected. */
34
+ export declare function confirmHandoffInjection(workspaceRoot: string, format?: ChpHandoffFormat): Promise<{
35
+ ok: boolean;
36
+ filePath?: string;
37
+ text?: string;
38
+ hint?: string;
39
+ }>;
40
+ /** User declined injection for this runtime session. */
41
+ export declare function skipHandoffInjection(workspaceRoot: string): Promise<{
42
+ ok: boolean;
43
+ }>;
44
+ /** Reset pending state when runtime_id changes (new bootstrap). */
45
+ export declare function syncInjectionWithRuntime(workspaceRoot: string): Promise<void>;
46
+ //# sourceMappingURL=semiAutoHandoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semiAutoHandoff.d.ts","sourceRoot":"","sources":["../src/semiAutoHandoff.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAMzF,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAoBD,6DAA6D;AAC7D,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IACvE,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAWD;AAED,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAE5C;AAED,wBAAsB,2BAA2B,CAC/C,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAU7B;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAU7F;AAED,+EAA+E;AAC/E,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC;IACT,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAuDD;AAED,6DAA6D;AAC7D,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,gBAA6B,GACpC,OAAO,CAAC;IACT,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CA4BD;AAYD,wDAAwD;AACxD,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAgB1F;AAED,mEAAmE;AACnE,wBAAsB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBnF"}
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.checkActiveRuntime = checkActiveRuntime;
37
+ exports.readHandoffInjectionState = readHandoffInjectionState;
38
+ exports.readConfirmedHandoffContext = readConfirmedHandoffContext;
39
+ exports.buildInjectionPromptMessage = buildInjectionPromptMessage;
40
+ exports.prepareHandoffInjection = prepareHandoffInjection;
41
+ exports.confirmHandoffInjection = confirmHandoffInjection;
42
+ exports.skipHandoffInjection = skipHandoffInjection;
43
+ exports.syncInjectionWithRuntime = syncInjectionWithRuntime;
44
+ const fs = __importStar(require("node:fs/promises"));
45
+ const path = __importStar(require("node:path"));
46
+ const chpHandoff_js_1 = require("./understanding/chpHandoff.js");
47
+ const INJECTION_STATE_FILE = 'mcp.handoff-injection.json';
48
+ const CONTEXT_FILE = 'mcp.auto-context.md';
49
+ const BOOTSTRAP_FILE = 'runtime.bootstrap.json';
50
+ function contoraPath(workspaceRoot, name) {
51
+ return path.join(path.resolve(workspaceRoot), '.contora', name);
52
+ }
53
+ async function readJson(filePath) {
54
+ try {
55
+ const raw = await fs.readFile(filePath, 'utf8');
56
+ return JSON.parse(raw);
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ }
62
+ async function writeJson(filePath, data) {
63
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
64
+ await fs.writeFile(filePath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
65
+ }
66
+ /** Active runtime = bootstrap marker + handoff available. */
67
+ async function checkActiveRuntime(workspaceRoot) {
68
+ const root = path.resolve(workspaceRoot);
69
+ const bootstrap = await readJson(contoraPath(root, BOOTSTRAP_FILE));
70
+ if (!bootstrap?.runtime_id) {
71
+ return { active: false };
72
+ }
73
+ const handoff = await (0, chpHandoff_js_1.getProjectHandoff)(root, 'compact');
74
+ if (!handoff.found) {
75
+ return { active: false, runtime_id: bootstrap.runtime_id };
76
+ }
77
+ return { active: true, runtime_id: bootstrap.runtime_id };
78
+ }
79
+ async function readHandoffInjectionState(workspaceRoot) {
80
+ return readJson(contoraPath(workspaceRoot, INJECTION_STATE_FILE));
81
+ }
82
+ async function readConfirmedHandoffContext(workspaceRoot) {
83
+ const state = await readHandoffInjectionState(workspaceRoot);
84
+ if (state?.status !== 'injected') {
85
+ return undefined;
86
+ }
87
+ try {
88
+ return await fs.readFile(contoraPath(workspaceRoot, CONTEXT_FILE), 'utf8');
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ }
94
+ function buildInjectionPromptMessage(projectHint, compactLine) {
95
+ const project = projectHint || 'this project';
96
+ const lines = [
97
+ `[?] Contorium Runtime active for "${project}". Inject current working state? (Y/n)`,
98
+ `Terminal: Enter or i · IDE: click [?] on status bar · Agent: confirm_handoff_injection`,
99
+ ];
100
+ if (compactLine) {
101
+ lines.push(compactLine);
102
+ }
103
+ return lines.join('\n');
104
+ }
105
+ /** Prepare semi-auto injection — pending only, does NOT write context file. */
106
+ async function prepareHandoffInjection(workspaceRoot, options) {
107
+ const root = path.resolve(workspaceRoot);
108
+ const { active, runtime_id } = await checkActiveRuntime(root);
109
+ if (!active || !runtime_id) {
110
+ return { shouldPrompt: false, alreadyInjected: false };
111
+ }
112
+ const existing = await readHandoffInjectionState(root);
113
+ const compact = await (0, chpHandoff_js_1.getProjectHandoff)(root, 'compact');
114
+ const project = path.basename(root);
115
+ const chatSessionId = options?.newChat
116
+ ? `chat-${Date.now()}`
117
+ : existing?.chat_session_id ?? `chat-${Date.now()}`;
118
+ if (options?.newChat) {
119
+ const state = {
120
+ runtime_id,
121
+ status: 'pending',
122
+ prompted_at: Date.now(),
123
+ context_file: `.contora/${CONTEXT_FILE}`,
124
+ chat_session_id: chatSessionId,
125
+ };
126
+ await writeJson(contoraPath(root, INJECTION_STATE_FILE), state);
127
+ return {
128
+ shouldPrompt: true,
129
+ alreadyInjected: false,
130
+ prompt: buildInjectionPromptMessage(project, compact.text),
131
+ state,
132
+ compact: compact.text,
133
+ };
134
+ }
135
+ if (existing?.runtime_id === runtime_id && existing.status === 'injected') {
136
+ return { shouldPrompt: false, alreadyInjected: true, state: existing };
137
+ }
138
+ if (existing?.runtime_id === runtime_id && existing.status === 'skipped') {
139
+ return { shouldPrompt: false, alreadyInjected: false, state: existing };
140
+ }
141
+ const state = {
142
+ runtime_id,
143
+ status: 'pending',
144
+ prompted_at: Date.now(),
145
+ context_file: `.contora/${CONTEXT_FILE}`,
146
+ chat_session_id: chatSessionId,
147
+ };
148
+ await writeJson(contoraPath(root, INJECTION_STATE_FILE), state);
149
+ return {
150
+ shouldPrompt: true,
151
+ alreadyInjected: false,
152
+ prompt: buildInjectionPromptMessage(project, compact.text),
153
+ state,
154
+ compact: compact.text,
155
+ };
156
+ }
157
+ /** User confirmed — write context file and mark injected. */
158
+ async function confirmHandoffInjection(workspaceRoot, format = 'markdown') {
159
+ const root = path.resolve(workspaceRoot);
160
+ const { active, runtime_id } = await checkActiveRuntime(root);
161
+ if (!active || !runtime_id) {
162
+ return { ok: false, hint: 'No active runtime or handoff — save changes or run sync first.' };
163
+ }
164
+ const result = await (0, chpHandoff_js_1.getProjectHandoff)(root, format);
165
+ if (!result.found || !result.text) {
166
+ return { ok: false, hint: 'Handoff not ready.' };
167
+ }
168
+ const contextPath = contoraPath(root, CONTEXT_FILE);
169
+ await fs.writeFile(contextPath, result.text, 'utf8');
170
+ const state = {
171
+ runtime_id,
172
+ status: 'injected',
173
+ prompted_at: (await readHandoffInjectionState(root))?.prompted_at ?? Date.now(),
174
+ resolved_at: Date.now(),
175
+ context_file: `.contora/${CONTEXT_FILE}`,
176
+ format,
177
+ chat_session_id: (await readHandoffInjectionState(root))?.chat_session_id,
178
+ };
179
+ await writeJson(contoraPath(root, INJECTION_STATE_FILE), state);
180
+ await markHandoffInjectionUsed(root, runtime_id);
181
+ return { ok: true, filePath: contextPath, text: result.text };
182
+ }
183
+ async function markHandoffInjectionUsed(workspaceRoot, runtimeId) {
184
+ const handoffPath = contoraPath(workspaceRoot, 'handoff.json');
185
+ const raw = await readJson(handoffPath);
186
+ if (!raw) {
187
+ return;
188
+ }
189
+ raw.last_handoff_used = { runtime_id: runtimeId, at: Date.now() };
190
+ await writeJson(handoffPath, raw);
191
+ }
192
+ /** User declined injection for this runtime session. */
193
+ async function skipHandoffInjection(workspaceRoot) {
194
+ const root = path.resolve(workspaceRoot);
195
+ const { runtime_id } = await checkActiveRuntime(root);
196
+ if (!runtime_id) {
197
+ return { ok: false };
198
+ }
199
+ const state = {
200
+ runtime_id,
201
+ status: 'skipped',
202
+ prompted_at: (await readHandoffInjectionState(root))?.prompted_at ?? Date.now(),
203
+ resolved_at: Date.now(),
204
+ context_file: `.contora/${CONTEXT_FILE}`,
205
+ chat_session_id: (await readHandoffInjectionState(root))?.chat_session_id,
206
+ };
207
+ await writeJson(contoraPath(root, INJECTION_STATE_FILE), state);
208
+ return { ok: true };
209
+ }
210
+ /** Reset pending state when runtime_id changes (new bootstrap). */
211
+ async function syncInjectionWithRuntime(workspaceRoot) {
212
+ const root = path.resolve(workspaceRoot);
213
+ const { runtime_id } = await checkActiveRuntime(root);
214
+ if (!runtime_id) {
215
+ return;
216
+ }
217
+ const existing = await readHandoffInjectionState(root);
218
+ if (existing && existing.runtime_id !== runtime_id) {
219
+ await writeJson(contoraPath(root, INJECTION_STATE_FILE), {
220
+ runtime_id,
221
+ status: 'pending',
222
+ prompted_at: Date.now(),
223
+ context_file: `.contora/${CONTEXT_FILE}`,
224
+ chat_session_id: `chat-${Date.now()}`,
225
+ });
226
+ }
227
+ }
@@ -0,0 +1,4 @@
1
+ import type { AdapterKind, BootstrapStateJson, StateEngineMode, StateSourceMetadata } from './types.js';
2
+ export declare function attachStateSource(state: BootstrapStateJson, mode: StateEngineMode, writer: AdapterKind): BootstrapStateJson;
3
+ export declare function parseStateSource(raw: unknown): StateSourceMetadata | undefined;
4
+ //# sourceMappingURL=sourceMetadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceMetadata.d.ts","sourceRoot":"","sources":["../src/sourceMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAExG,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,WAAW,GAClB,kBAAkB,CAOpB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,mBAAmB,GAAG,SAAS,CAgB9E"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachStateSource = attachStateSource;
4
+ exports.parseStateSource = parseStateSource;
5
+ function attachStateSource(state, mode, writer) {
6
+ const source = {
7
+ mode,
8
+ lastWriter: writer,
9
+ lastUpdated: new Date().toISOString(),
10
+ };
11
+ return { ...state, source };
12
+ }
13
+ function parseStateSource(raw) {
14
+ if (!raw || typeof raw !== 'object') {
15
+ return undefined;
16
+ }
17
+ const o = raw;
18
+ const mode = o.mode;
19
+ const lastWriter = o.lastWriter;
20
+ const lastUpdated = o.lastUpdated;
21
+ if ((mode !== 'event-driven' && mode !== 'scan-driven' && mode !== 'merged') ||
22
+ (lastWriter !== 'ide' && lastWriter !== 'mcp' && lastWriter !== 'cli') ||
23
+ typeof lastUpdated !== 'string') {
24
+ return undefined;
25
+ }
26
+ return { mode, lastWriter, lastUpdated };
27
+ }
@@ -0,0 +1,5 @@
1
+ import type { BootstrapStateJson, WorkspaceScanFacts } from '../types.js';
2
+ import type { ProjectBuiltState } from './types.js';
3
+ /** Scan-driven L2/L4 when no IDE events (MCP / CLI bootstrap). */
4
+ export declare function buildProjectStateFromScan(scan: WorkspaceScanFacts, state?: BootstrapStateJson): ProjectBuiltState;
5
+ //# sourceMappingURL=buildFromScan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildFromScan.d.ts","sourceRoot":"","sources":["../../src/state-builder/buildFromScan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,kEAAkE;AAClE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,kBAAkB,EACxB,KAAK,CAAC,EAAE,kBAAkB,GACzB,iBAAiB,CA8BnB"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildProjectStateFromScan = buildProjectStateFromScan;
4
+ /** Scan-driven L2/L4 when no IDE events (MCP / CLI bootstrap). */
5
+ function buildProjectStateFromScan(scan, state) {
6
+ const modules = [
7
+ ...scan.topLevelModules.slice(0, 6),
8
+ ...scan.recentFiles.slice(0, 4).map((f) => f.split('/').pop() ?? f),
9
+ ];
10
+ const active = [...new Set(modules)].slice(0, 8);
11
+ const goal = scan.readmeHint?.trim() ||
12
+ (active.length ? `develop ${active.slice(0, 2).join(' and ')} areas` : 'ongoing workspace development');
13
+ const gitCount = scan.gitStaged.length + scan.gitWorking.length;
14
+ return {
15
+ version: 1,
16
+ engine_version: 2,
17
+ generatedAt: scan.scannedAt,
18
+ task_anchor: state?.currentTask?.trim() || undefined,
19
+ project_goal: goal,
20
+ current_stage: scan.isGitRepo
21
+ ? 'repository scan (tool-agnostic bootstrap)'
22
+ : 'workspace scan (no git)',
23
+ active_modules: active,
24
+ recent_decisions: [],
25
+ open_problems: gitCount >= 6 ? ['uncommitted changes across workspace'] : ['(light or undirected activity)'],
26
+ completed_milestones: [],
27
+ next_actions: [
28
+ 'review recent file activity',
29
+ ...(scan.isGitRepo ? ['review and commit pending changes'] : []),
30
+ ],
31
+ confidence: 0.35,
32
+ };
33
+ }
@@ -0,0 +1,5 @@
1
+ import type { ProjectBuiltState } from './types.js';
2
+ /** L3 — dedupe, layer split, loop guard, semantic compression. */
3
+ export declare function normalizeProjectBuiltState(raw: ProjectBuiltState, taskAnchor: string): ProjectBuiltState;
4
+ export declare function filterWeakInferenceLines(lines: readonly string[], taskAnchor: string): string[];
5
+ //# sourceMappingURL=normalization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalization.d.ts","sourceRoot":"","sources":["../../src/state-builder/normalization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA2EpD,kEAAkE;AAClE,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,iBAAiB,EACtB,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAsCnB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAc/F"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeProjectBuiltState = normalizeProjectBuiltState;
4
+ exports.filterWeakInferenceLines = filterWeakInferenceLines;
5
+ function normKey(s) {
6
+ return s.trim().toLowerCase().replace(/\s+/g, ' ');
7
+ }
8
+ function dedupeStrings(items, max) {
9
+ const seen = new Set();
10
+ const out = [];
11
+ for (const raw of items) {
12
+ const t = raw.trim();
13
+ if (t.length < 3) {
14
+ continue;
15
+ }
16
+ const k = normKey(t);
17
+ if (seen.has(k)) {
18
+ continue;
19
+ }
20
+ seen.add(k);
21
+ out.push(t);
22
+ if (out.length >= max) {
23
+ break;
24
+ }
25
+ }
26
+ return out;
27
+ }
28
+ function compressSimilarActions(actions, taskAnchor) {
29
+ const taskK = normKey(taskAnchor);
30
+ const out = [];
31
+ const seenRoots = new Set();
32
+ for (const raw of actions) {
33
+ let t = raw.trim();
34
+ if (!t) {
35
+ continue;
36
+ }
37
+ t = t.replace(/^continue:\s*/i, '').trim();
38
+ const k = normKey(t);
39
+ if (taskK.length >= 4 && (k === taskK || k.includes(taskK) || taskK.includes(k))) {
40
+ continue;
41
+ }
42
+ const root = k.slice(0, Math.min(32, k.length));
43
+ if (seenRoots.has(root)) {
44
+ continue;
45
+ }
46
+ seenRoots.add(root);
47
+ out.push(t);
48
+ }
49
+ return out.slice(0, 6);
50
+ }
51
+ function echoesTask(text, taskAnchor) {
52
+ const t = normKey(text);
53
+ const a = normKey(taskAnchor);
54
+ if (!a || a.length < 4) {
55
+ return false;
56
+ }
57
+ return t === a || t.includes(a) || a.includes(t);
58
+ }
59
+ function stripTaskFromGoal(goal, taskAnchor) {
60
+ if (!goal.trim() || echoesTask(goal, taskAnchor)) {
61
+ return '';
62
+ }
63
+ return goal.trim();
64
+ }
65
+ function stripTaskFromStage(stage, taskAnchor) {
66
+ if (!stage.trim() || echoesTask(stage, taskAnchor)) {
67
+ return stage.trim();
68
+ }
69
+ return stage.trim();
70
+ }
71
+ /** L3 — dedupe, layer split, loop guard, semantic compression. */
72
+ function normalizeProjectBuiltState(raw, taskAnchor) {
73
+ const goal = stripTaskFromGoal(raw.project_goal, taskAnchor);
74
+ const stage = stripTaskFromStage(raw.current_stage, taskAnchor);
75
+ const modules = dedupeStrings(raw.active_modules, 8);
76
+ const problems = dedupeStrings(raw.open_problems.filter((p) => !echoesTask(p, taskAnchor)), 6);
77
+ const milestones = dedupeStrings(raw.completed_milestones, 5);
78
+ const decisions = dedupeStrings(raw.recent_decisions.filter((d) => !echoesTask(d, taskAnchor)), 8);
79
+ const next_actions = compressSimilarActions(raw.next_actions.filter((a) => !echoesTask(a, taskAnchor)), taskAnchor);
80
+ const confidence = Math.min(1, raw.confidence * 0.6 +
81
+ (goal ? 0.15 : 0) +
82
+ (modules.length ? 0.15 : 0) +
83
+ (next_actions.length ? 0.1 : 0));
84
+ return {
85
+ ...raw,
86
+ project_goal: goal.slice(0, 240),
87
+ current_stage: stage.slice(0, 120),
88
+ active_modules: modules,
89
+ recent_decisions: decisions,
90
+ open_problems: problems,
91
+ completed_milestones: milestones,
92
+ next_actions,
93
+ confidence: Math.round(confidence * 100) / 100,
94
+ };
95
+ }
96
+ function filterWeakInferenceLines(lines, taskAnchor) {
97
+ return dedupeStrings(lines.filter((l) => {
98
+ const t = l.trim();
99
+ if (t.length < 4) {
100
+ return false;
101
+ }
102
+ if (/^stated focus:/i.test(t)) {
103
+ return false;
104
+ }
105
+ return !echoesTask(t, taskAnchor);
106
+ }), 8);
107
+ }
@@ -0,0 +1,4 @@
1
+ import type { AdapterKind, BootstrapStateJson, WorkspaceScanFacts } from '../types.js';
2
+ /** Unified scan path — MCP / CLI / IDE fallback share one state-builder implementation. */
3
+ export declare function rebuildArtifactsFromScan(workspaceRoot: string, scan: WorkspaceScanFacts, state?: BootstrapStateJson, writer?: AdapterKind): Promise<void>;
4
+ //# sourceMappingURL=rebuildFromScan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuildFromScan.d.ts","sourceRoot":"","sources":["../../src/state-builder/rebuildFromScan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMvF,2FAA2F;AAC3F,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,kBAAkB,EACxB,KAAK,CAAC,EAAE,kBAAkB,EAC1B,MAAM,GAAE,WAAmB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAaf"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rebuildArtifactsFromScan = rebuildArtifactsFromScan;
4
+ const buildUnderstanding_js_1 = require("../understanding/buildUnderstanding.js");
5
+ const buildFromScan_js_1 = require("./buildFromScan.js");
6
+ const snapshot_js_1 = require("./snapshot.js");
7
+ const store_js_1 = require("./store.js");
8
+ /** Unified scan path — MCP / CLI / IDE fallback share one state-builder implementation. */
9
+ async function rebuildArtifactsFromScan(workspaceRoot, scan, state, writer = 'mcp') {
10
+ const built = (0, buildFromScan_js_1.buildProjectStateFromScan)(scan, state);
11
+ let md = (0, snapshot_js_1.formatProjectSnapshotMarkdown)(built);
12
+ if (writer === 'cli' || writer === 'mcp') {
13
+ md += `\n(generated by Contorium scan-driven bootstrap — ${writer} adapter; IDE events may refine this)\n`;
14
+ }
15
+ await (0, store_js_1.writeProjectBuiltState)(workspaceRoot, built, md);
16
+ await (0, buildUnderstanding_js_1.buildAndWriteUnderstandingArtifacts)({
17
+ workspaceRoot,
18
+ state,
19
+ built,
20
+ scan,
21
+ }).catch(() => undefined);
22
+ }
@@ -0,0 +1,5 @@
1
+ import type { ProjectBuiltState } from './types.js';
2
+ /** Human-readable PROJECT SNAPSHOT — shared by IDE, MCP, and CLI. */
3
+ export declare function formatProjectSnapshotMarkdown(state: ProjectBuiltState): string;
4
+ export declare function projectSnapshotBulletLines(state: ProjectBuiltState): string[];
5
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/state-builder/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAcpD,qEAAqE;AACrE,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAsB9E;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAe7E"}