@remnic/core 9.3.692 → 9.3.694

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 (268) hide show
  1. package/dist/access-boundary.d.ts +6 -6
  2. package/dist/access-boundary.js +11 -9
  3. package/dist/access-cli.js +76 -23
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +5 -5
  6. package/dist/access-http.js +14 -12
  7. package/dist/access-mcp.d.ts +14 -5
  8. package/dist/access-mcp.js +13 -11
  9. package/dist/access-operations.d.ts +54 -7
  10. package/dist/access-operations.js +42 -10
  11. package/dist/{access-service-DvApf9LZ.d.ts → access-service-Ceq4TdPO.d.ts} +180 -3
  12. package/dist/access-service.d.ts +5 -5
  13. package/dist/access-service.js +10 -8
  14. package/dist/access-surface-catalog.d.ts +5 -5
  15. package/dist/access-surface-catalog.js +17 -0
  16. package/dist/access-surface-catalog.js.map +1 -1
  17. package/dist/action-confidence.d.ts +1 -1
  18. package/dist/active-memory-bridge.d.ts +1 -1
  19. package/dist/active-recall.d.ts +1 -1
  20. package/dist/active-recall.js +1 -1
  21. package/dist/behavior-learner.d.ts +1 -1
  22. package/dist/behavior-signals.d.ts +1 -1
  23. package/dist/bootstrap.d.ts +4 -4
  24. package/dist/briefing.d.ts +1 -1
  25. package/dist/briefing.js +3 -3
  26. package/dist/buffer-surprise-report.d.ts +1 -1
  27. package/dist/buffer.d.ts +1 -1
  28. package/dist/calibration.d.ts +1 -1
  29. package/dist/capabilities.d.ts +1 -1
  30. package/dist/{catalog-BEWLjdOr.d.ts → catalog-Tkb991rg.d.ts} +1 -1
  31. package/dist/causal-behavior.d.ts +1 -1
  32. package/dist/causal-consolidation.d.ts +1 -1
  33. package/dist/causal-consolidation.js +4 -4
  34. package/dist/{chunk-ADUAF5EV.js → chunk-24FCDBJV.js} +2 -2
  35. package/dist/{chunk-V56S3A23.js → chunk-5A35EGHM.js} +1092 -29
  36. package/dist/chunk-5A35EGHM.js.map +1 -0
  37. package/dist/{chunk-3VVH6ZQW.js → chunk-5S53ZBPH.js} +2 -2
  38. package/dist/{chunk-DO7MDZMU.js → chunk-6C4WHMKV.js} +123 -7
  39. package/dist/chunk-6C4WHMKV.js.map +1 -0
  40. package/dist/{chunk-2D27ODNX.js → chunk-B55EAZNF.js} +2 -2
  41. package/dist/{chunk-W4MICQIZ.js → chunk-C5AOVGVC.js} +15 -15
  42. package/dist/chunk-CDOIDOTQ.js +381 -0
  43. package/dist/chunk-CDOIDOTQ.js.map +1 -0
  44. package/dist/{chunk-UOCLRM74.js → chunk-D7PQ7HZL.js} +2 -2
  45. package/dist/{chunk-HXNMDPHN.js → chunk-DT2ZGQT7.js} +2 -2
  46. package/dist/{chunk-QFG23CRE.js → chunk-EPVIBPVE.js} +2 -2
  47. package/dist/{chunk-O4ZIV62T.js → chunk-FCH766FX.js} +21 -19
  48. package/dist/chunk-FCH766FX.js.map +1 -0
  49. package/dist/{chunk-7MOTEVAA.js → chunk-HRUULBBV.js} +3 -1
  50. package/dist/chunk-HRUULBBV.js.map +1 -0
  51. package/dist/{chunk-U2OBZSGG.js → chunk-IZLNJYLX.js} +2 -2
  52. package/dist/{chunk-KYH53EFD.js → chunk-JIKBEDSB.js} +6 -6
  53. package/dist/{chunk-3BRA3N5A.js → chunk-KCRV3HVN.js} +2 -2
  54. package/dist/{chunk-AFWEUTMS.js → chunk-MOGFK2DU.js} +2 -2
  55. package/dist/{chunk-SAC5V6JT.js → chunk-MSUA4KAK.js} +2 -2
  56. package/dist/{chunk-VFVG4NS2.js → chunk-NXNUG7IA.js} +2 -2
  57. package/dist/{chunk-66HROLW5.js → chunk-P7IDNF7H.js} +2 -2
  58. package/dist/{chunk-FM7KLRKN.js → chunk-PILLH262.js} +2 -2
  59. package/dist/{chunk-UTUYAPLY.js → chunk-PNW4KKJX.js} +12 -3
  60. package/dist/{chunk-UTUYAPLY.js.map → chunk-PNW4KKJX.js.map} +1 -1
  61. package/dist/{chunk-2EN5WZQB.js → chunk-PQP6MFPL.js} +2 -2
  62. package/dist/chunk-PQP6MFPL.js.map +1 -0
  63. package/dist/{chunk-6C2BMUZA.js → chunk-QXWQ5V24.js} +2 -2
  64. package/dist/{chunk-SEK4XIDN.js → chunk-SJGTY2TW.js} +35 -9
  65. package/dist/chunk-SJGTY2TW.js.map +1 -0
  66. package/dist/{chunk-4IQNAOP3.js → chunk-SN5DFE34.js} +2 -2
  67. package/dist/{chunk-DQHZA7Y3.js → chunk-U62ZGWU7.js} +1 -1
  68. package/dist/chunk-U62ZGWU7.js.map +1 -0
  69. package/dist/{chunk-WIKNVFBS.js → chunk-UX5QTAFE.js} +2 -2
  70. package/dist/chunk-VQ7B2Q6M.js +112 -0
  71. package/dist/chunk-VQ7B2Q6M.js.map +1 -0
  72. package/dist/{chunk-MCV2DD6F.js → chunk-WVTNZUER.js} +2 -2
  73. package/dist/{chunk-ZLXGFAML.js → chunk-YI3KC2B5.js} +2 -2
  74. package/dist/{chunk-W4ELOUNX.js → chunk-YWYZPKK3.js} +2 -2
  75. package/dist/{chunk-NUZ3N445.js → chunk-YXZPKBFW.js} +3 -3
  76. package/dist/{chunk-GCOSQBQ2.js → chunk-ZKD3UVEO.js} +3 -3
  77. package/dist/{cli-BjsY9Le7.d.ts → cli-CxtZyBLl.d.ts} +3 -3
  78. package/dist/cli.d.ts +6 -6
  79. package/dist/cli.js +28 -26
  80. package/dist/coding/optional-coding-graph.js +7 -104
  81. package/dist/coding/optional-coding-graph.js.map +1 -1
  82. package/dist/compounding/engine.d.ts +1 -1
  83. package/dist/compounding/engine.js +3 -3
  84. package/dist/compounding/preference-consolidator.d.ts +1 -1
  85. package/dist/compression-optimizer.d.ts +1 -1
  86. package/dist/config.d.ts +1 -1
  87. package/dist/config.js +1 -1
  88. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  89. package/dist/connectors/codex-materialize-runner.js +3 -3
  90. package/dist/connectors/codex-materialize.d.ts +1 -1
  91. package/dist/connectors/index.d.ts +1 -1
  92. package/dist/connectors/index.js +3 -3
  93. package/dist/consolidation-provenance-check.d.ts +1 -1
  94. package/dist/consolidation-undo.d.ts +1 -1
  95. package/dist/contradiction/index.d.ts +1 -1
  96. package/dist/conversation-index/backend.d.ts +1 -1
  97. package/dist/conversation-index/chunker.d.ts +1 -1
  98. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  99. package/dist/conversation-index/indexer.d.ts +1 -1
  100. package/dist/conversation-index/search.d.ts +1 -1
  101. package/dist/day-summary.d.ts +1 -1
  102. package/dist/delinearize.d.ts +1 -1
  103. package/dist/direct-answer-wiring.d.ts +1 -1
  104. package/dist/direct-answer.d.ts +1 -1
  105. package/dist/embedding-fallback.d.ts +1 -1
  106. package/dist/enrichment/index.d.ts +1 -1
  107. package/dist/entity-retrieval.d.ts +1 -1
  108. package/dist/entity-retrieval.js +3 -3
  109. package/dist/entity-schema.d.ts +1 -1
  110. package/dist/explicit-capture.d.ts +4 -4
  111. package/dist/extraction-judge-telemetry.d.ts +1 -1
  112. package/dist/extraction-judge-training.d.ts +1 -1
  113. package/dist/extraction-judge.d.ts +1 -1
  114. package/dist/extraction.d.ts +1 -1
  115. package/dist/fallback-llm.d.ts +1 -1
  116. package/dist/identity-continuity.d.ts +1 -1
  117. package/dist/importance.d.ts +1 -1
  118. package/dist/index.d.ts +9 -9
  119. package/dist/index.js +37 -36
  120. package/dist/index.js.map +1 -1
  121. package/dist/intent.d.ts +1 -1
  122. package/dist/lcm/engine.d.ts +1 -1
  123. package/dist/lcm/index.d.ts +1 -1
  124. package/dist/lcm/tools.d.ts +1 -1
  125. package/dist/lifecycle.d.ts +1 -1
  126. package/dist/live-connectors-runner.d.ts +1 -1
  127. package/dist/local-llm.d.ts +1 -1
  128. package/dist/maintenance/memory-governance.d.ts +1 -1
  129. package/dist/maintenance/memory-governance.js +3 -3
  130. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  131. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  132. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  133. package/dist/memory-action-policy.d.ts +1 -1
  134. package/dist/memory-cache.d.ts +1 -1
  135. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  136. package/dist/memory-projection-store.d.ts +1 -1
  137. package/dist/memory-provenance.d.ts +1 -1
  138. package/dist/memory-worth-outcomes.d.ts +1 -1
  139. package/dist/models-json.d.ts +1 -1
  140. package/dist/namespaces/migrate.d.ts +2 -2
  141. package/dist/namespaces/migrate.js +4 -4
  142. package/dist/namespaces/principal.d.ts +1 -1
  143. package/dist/namespaces/search.d.ts +1 -1
  144. package/dist/namespaces/storage.d.ts +2 -2
  145. package/dist/namespaces/storage.js +3 -3
  146. package/dist/native-knowledge.d.ts +1 -1
  147. package/dist/operator-toolkit.d.ts +1 -1
  148. package/dist/operator-toolkit.js +9 -9
  149. package/dist/orchestration/maintenance.d.ts +2 -2
  150. package/dist/orchestration/maintenance.js +5 -5
  151. package/dist/{orchestrator-CNJCYjZ1.d.ts → orchestrator-CnbxRQs8.d.ts} +3 -3
  152. package/dist/orchestrator.d.ts +4 -4
  153. package/dist/orchestrator.js +16 -16
  154. package/dist/patterns-cli.d.ts +1 -1
  155. package/dist/policy-runtime.d.ts +1 -1
  156. package/dist/provenance.d.ts +1 -1
  157. package/dist/qmd-recall-cache.d.ts +1 -1
  158. package/dist/qmd.d.ts +1 -1
  159. package/dist/recall-disclosure-escalation.d.ts +1 -1
  160. package/dist/recall-explain-renderer.d.ts +1 -1
  161. package/dist/recall-explain-renderer.js +3 -3
  162. package/dist/recall-planner-llm.d.ts +1 -1
  163. package/dist/recall-state.d.ts +1 -1
  164. package/dist/recall-tag-filter.d.ts +1 -1
  165. package/dist/recall-xray-cli.d.ts +1 -1
  166. package/dist/recall-xray-cli.js +4 -4
  167. package/dist/recall-xray-renderer.d.ts +1 -1
  168. package/dist/recall-xray-renderer.js +3 -3
  169. package/dist/recall-xray.d.ts +1 -1
  170. package/dist/recall-xray.js +2 -2
  171. package/dist/resolve-auth-token.d.ts +1 -1
  172. package/dist/resume-bundles.js +2 -2
  173. package/dist/retrieval-agents.d.ts +1 -1
  174. package/dist/retrieval-tiers.d.ts +1 -1
  175. package/dist/routing/engine.d.ts +1 -1
  176. package/dist/routing/store.d.ts +1 -1
  177. package/dist/schemas.d.ts +28 -28
  178. package/dist/search/embed-helper.d.ts +1 -1
  179. package/dist/search/factory.d.ts +1 -1
  180. package/dist/search/index.d.ts +1 -1
  181. package/dist/search/lancedb-backend.d.ts +1 -1
  182. package/dist/search/meilisearch-backend.d.ts +1 -1
  183. package/dist/search/noop-backend.d.ts +1 -1
  184. package/dist/search/orama-backend.d.ts +1 -1
  185. package/dist/search/port.d.ts +1 -1
  186. package/dist/search/remote-backend.d.ts +1 -1
  187. package/dist/{semantic-consolidation-D5U0Mrdb.d.ts → semantic-consolidation-DXmtQ_4B.d.ts} +1 -1
  188. package/dist/semantic-consolidation.d.ts +2 -2
  189. package/dist/semantic-consolidation.js +4 -4
  190. package/dist/semantic-rule-promotion.js +3 -3
  191. package/dist/semantic-rule-verifier.d.ts +1 -1
  192. package/dist/semantic-rule-verifier.js +3 -3
  193. package/dist/session-observer-bands.d.ts +1 -1
  194. package/dist/session-observer-state.d.ts +1 -1
  195. package/dist/shared-context/manager.d.ts +1 -1
  196. package/dist/signal.d.ts +1 -1
  197. package/dist/storage.d.ts +1 -1
  198. package/dist/storage.js +2 -2
  199. package/dist/summarizer.d.ts +1 -1
  200. package/dist/summary-snapshot.d.ts +1 -1
  201. package/dist/temporal-supersession.d.ts +1 -1
  202. package/dist/temporal-validity.d.ts +1 -1
  203. package/dist/threading.d.ts +1 -1
  204. package/dist/tier-migration.d.ts +1 -1
  205. package/dist/tier-routing.d.ts +1 -1
  206. package/dist/topics.d.ts +1 -1
  207. package/dist/transcript.d.ts +1 -1
  208. package/dist/transfer/types.d.ts +12 -12
  209. package/dist/{types-2NoBoRBM.d.ts → types-CEWBmjCH.d.ts} +14 -0
  210. package/dist/types.d.ts +1 -1
  211. package/dist/types.js +1 -1
  212. package/dist/utility-runtime.d.ts +1 -1
  213. package/dist/verified-recall.js +3 -3
  214. package/package.json +2 -2
  215. package/src/access-boundary.ts +19 -1
  216. package/src/access-cli.ts +65 -2
  217. package/src/access-http.ts +47 -3
  218. package/src/access-mcp.ts +128 -2
  219. package/src/access-operations.ts +305 -0
  220. package/src/access-service.ts +137 -0
  221. package/src/access-surface-catalog.test.ts +1 -1
  222. package/src/access-surface-catalog.ts +17 -0
  223. package/src/cli.ts +2 -0
  224. package/src/coding/architecture-surfaces.test.ts +2 -0
  225. package/src/coding/codegraph-runtime.ts +773 -0
  226. package/src/coding/codegraph-surfaces.test.ts +880 -0
  227. package/src/coding/codegraph-surfaces.ts +771 -0
  228. package/src/coding/coding-knowledge-config.ts +7 -0
  229. package/src/coding/coding-namespace.ts +1 -1
  230. package/src/coding/decision-surfaces.test.ts +2 -0
  231. package/src/coding/session-delta-surfaces.test.ts +385 -0
  232. package/src/coding/session-delta-surfaces.ts +325 -0
  233. package/src/coding/session-delta.test.ts +411 -0
  234. package/src/coding/session-delta.ts +442 -0
  235. package/src/config.test.ts +2 -0
  236. package/src/types.ts +14 -0
  237. package/dist/chunk-2EN5WZQB.js.map +0 -1
  238. package/dist/chunk-7MOTEVAA.js.map +0 -1
  239. package/dist/chunk-DO7MDZMU.js.map +0 -1
  240. package/dist/chunk-DQHZA7Y3.js.map +0 -1
  241. package/dist/chunk-NEILAC3H.js +0 -153
  242. package/dist/chunk-NEILAC3H.js.map +0 -1
  243. package/dist/chunk-O4ZIV62T.js.map +0 -1
  244. package/dist/chunk-SEK4XIDN.js.map +0 -1
  245. package/dist/chunk-V56S3A23.js.map +0 -1
  246. /package/dist/{chunk-ADUAF5EV.js.map → chunk-24FCDBJV.js.map} +0 -0
  247. /package/dist/{chunk-3VVH6ZQW.js.map → chunk-5S53ZBPH.js.map} +0 -0
  248. /package/dist/{chunk-2D27ODNX.js.map → chunk-B55EAZNF.js.map} +0 -0
  249. /package/dist/{chunk-W4MICQIZ.js.map → chunk-C5AOVGVC.js.map} +0 -0
  250. /package/dist/{chunk-UOCLRM74.js.map → chunk-D7PQ7HZL.js.map} +0 -0
  251. /package/dist/{chunk-HXNMDPHN.js.map → chunk-DT2ZGQT7.js.map} +0 -0
  252. /package/dist/{chunk-QFG23CRE.js.map → chunk-EPVIBPVE.js.map} +0 -0
  253. /package/dist/{chunk-U2OBZSGG.js.map → chunk-IZLNJYLX.js.map} +0 -0
  254. /package/dist/{chunk-KYH53EFD.js.map → chunk-JIKBEDSB.js.map} +0 -0
  255. /package/dist/{chunk-3BRA3N5A.js.map → chunk-KCRV3HVN.js.map} +0 -0
  256. /package/dist/{chunk-AFWEUTMS.js.map → chunk-MOGFK2DU.js.map} +0 -0
  257. /package/dist/{chunk-SAC5V6JT.js.map → chunk-MSUA4KAK.js.map} +0 -0
  258. /package/dist/{chunk-VFVG4NS2.js.map → chunk-NXNUG7IA.js.map} +0 -0
  259. /package/dist/{chunk-66HROLW5.js.map → chunk-P7IDNF7H.js.map} +0 -0
  260. /package/dist/{chunk-FM7KLRKN.js.map → chunk-PILLH262.js.map} +0 -0
  261. /package/dist/{chunk-6C2BMUZA.js.map → chunk-QXWQ5V24.js.map} +0 -0
  262. /package/dist/{chunk-4IQNAOP3.js.map → chunk-SN5DFE34.js.map} +0 -0
  263. /package/dist/{chunk-WIKNVFBS.js.map → chunk-UX5QTAFE.js.map} +0 -0
  264. /package/dist/{chunk-MCV2DD6F.js.map → chunk-WVTNZUER.js.map} +0 -0
  265. /package/dist/{chunk-ZLXGFAML.js.map → chunk-YI3KC2B5.js.map} +0 -0
  266. /package/dist/{chunk-W4ELOUNX.js.map → chunk-YWYZPKK3.js.map} +0 -0
  267. /package/dist/{chunk-NUZ3N445.js.map → chunk-YXZPKBFW.js.map} +0 -0
  268. /package/dist/{chunk-GCOSQBQ2.js.map → chunk-ZKD3UVEO.js.map} +0 -0
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-ARV3AUOM.js";
12
12
  import {
13
13
  toRecallExplainJson
14
- } from "./chunk-2D27ODNX.js";
14
+ } from "./chunk-B55EAZNF.js";
15
15
  import {
16
16
  applyTagFilter,
17
17
  normalizeTags,
@@ -23,13 +23,15 @@ import {
23
23
  import {
24
24
  clusterByKey,
25
25
  combineNamespaces,
26
+ defaultGitInvoker,
26
27
  expandScopeProfileReadNamespaces,
27
28
  lcmSessionKeyForNamespace,
28
29
  projectTagProjectId,
29
30
  resolveCodingNamespaceOverlay,
30
31
  resolveGitContext,
31
- resolveScopeProfilePlan
32
- } from "./chunk-7MOTEVAA.js";
32
+ resolveScopeProfilePlan,
33
+ sanitizeFragment
34
+ } from "./chunk-HRUULBBV.js";
33
35
  import {
34
36
  getTrustZoneStoreStatus,
35
37
  isTrustZoneName,
@@ -44,7 +46,7 @@ import {
44
46
  } from "./chunk-FF4KLI5W.js";
45
47
  import {
46
48
  estimateRecallTokens
47
- } from "./chunk-AFWEUTMS.js";
49
+ } from "./chunk-MOGFK2DU.js";
48
50
  import {
49
51
  recordObjectiveStateSnapshotsFromObservedMessages
50
52
  } from "./chunk-BMFZLLNI.js";
@@ -58,7 +60,7 @@ import {
58
60
  listMemoryGovernanceRuns,
59
61
  readMemoryGovernanceRunArtifact,
60
62
  runMemoryGovernance
61
- } from "./chunk-SAC5V6JT.js";
63
+ } from "./chunk-MSUA4KAK.js";
62
64
  import {
63
65
  namespaceCollectionName
64
66
  } from "./chunk-E6BOD3UJ.js";
@@ -101,17 +103,17 @@ import {
101
103
  buildBriefing,
102
104
  parseBriefingFocus,
103
105
  parseBriefingWindow
104
- } from "./chunk-66HROLW5.js";
106
+ } from "./chunk-P7IDNF7H.js";
105
107
  import {
106
108
  parseEntityFile
107
- } from "./chunk-VFVG4NS2.js";
109
+ } from "./chunk-NXNUG7IA.js";
108
110
  import {
109
111
  stripAttributesSuffix
110
112
  } from "./chunk-SVOZFLIQ.js";
111
113
  import {
112
114
  DEFAULT_RECALL_DISCLOSURE,
113
115
  isRecallDisclosure
114
- } from "./chunk-DQHZA7Y3.js";
116
+ } from "./chunk-U62ZGWU7.js";
115
117
  import {
116
118
  normalizeProjectionPreview,
117
119
  normalizeProjectionTags
@@ -173,7 +175,8 @@ import {
173
175
  import { stat as stat2 } from "fs/promises";
174
176
  import * as nodeFs from "fs/promises";
175
177
  import { constants as fsConstants } from "fs";
176
- import { createHash as createHash2 } from "crypto";
178
+ import { readdirSync, unlinkSync } from "fs";
179
+ import { createHash as createHash3 } from "crypto";
177
180
  import { ZodError } from "zod";
178
181
 
179
182
  // src/coding/decision-records.ts
@@ -1137,12 +1140,12 @@ async function findArchitectureCardMemory(storage) {
1137
1140
  });
1138
1141
  return cards[0] ?? null;
1139
1142
  }
1140
- function createArchitectureVersioningHook(enabled, maxVersionsPerPage, sidecarDir, memoryDir, readFile3, writeVersion) {
1143
+ function createArchitectureVersioningHook(enabled, maxVersionsPerPage, sidecarDir, memoryDir, readFile4, writeVersion) {
1141
1144
  return {
1142
1145
  async snapshotIfExists(memory) {
1143
1146
  if (!enabled) return;
1144
1147
  try {
1145
- const fullContent = await readFile3(memory.path);
1148
+ const fullContent = await readFile4(memory.path);
1146
1149
  await writeVersion(
1147
1150
  memory.path,
1148
1151
  fullContent,
@@ -1158,10 +1161,968 @@ function createArchitectureVersioningHook(enabled, maxVersionsPerPage, sidecarDi
1158
1161
  };
1159
1162
  }
1160
1163
 
1161
- // src/procedural/procedure-miner.ts
1162
- import { createHash } from "crypto";
1163
- import { mkdir, rm, stat } from "fs/promises";
1164
+ // src/coding/codegraph-runtime.ts
1164
1165
  import path2 from "path";
1166
+ import { createHash } from "crypto";
1167
+ var CODEGRAPH_SPECIFIER = "@remnic/coding-graph";
1168
+ function codegraphSurfaceVisible(config) {
1169
+ const ck = config.codingKnowledge;
1170
+ if (ck === void 0 || ck === null) return false;
1171
+ return ck.enabled === true && ck.codegraphTools === true;
1172
+ }
1173
+ function resolveCodegraphRoot(config, memoryDir) {
1174
+ const rawDir = config.codingKnowledge.codegraphDbDir.trim();
1175
+ const root = rawDir.length > 0 ? expandTildePath(rawDir) : path2.join(memoryDir, "codegraph");
1176
+ if (!path2.isAbsolute(root)) {
1177
+ throw new CodegraphRuntimeError(
1178
+ "store_error",
1179
+ "codegraph DB root must be an absolute path; set codingKnowledge.codegraphDbDir (or memoryDir) to an absolute path"
1180
+ );
1181
+ }
1182
+ return root;
1183
+ }
1184
+ function resolveCodegraphDbPath(params) {
1185
+ const { config, memoryDir, principal, projectId } = params;
1186
+ const root = resolveCodegraphRoot(config, memoryDir);
1187
+ const principalSafe = sanitizePathSegment(principal);
1188
+ const projectSafe = sanitizePathSegment(projectId);
1189
+ return path2.join(root, principalSafe, `${projectSafe}.sqlite`);
1190
+ }
1191
+ function sanitizePathSegment(input) {
1192
+ const trimmed = (input ?? "").trim();
1193
+ if (trimmed.length === 0) return "_";
1194
+ const sanitized = trimmed.replace(/[^A-Za-z0-9._:-]+/g, "_");
1195
+ return sanitized.replace(/^\.+/, "").replace(/[/\\]+/g, "_") || "_";
1196
+ }
1197
+ var storeCache = /* @__PURE__ */ new Map();
1198
+ var cachedModule;
1199
+ var moduleLoadPromise = null;
1200
+ function storeCacheKey(principalSafe, projectSafe, dbPath) {
1201
+ return `${principalSafe}::${projectSafe}::${dbPath}`;
1202
+ }
1203
+ async function loadCodegraphModule() {
1204
+ if (cachedModule !== void 0) return cachedModule;
1205
+ if (moduleLoadPromise === null) {
1206
+ moduleLoadPromise = (async () => {
1207
+ try {
1208
+ const mod = await import(CODEGRAPH_SPECIFIER);
1209
+ if (mod && typeof mod === "object" && mod.GraphStore && typeof mod.GraphStore.open === "function") {
1210
+ cachedModule = mod;
1211
+ return cachedModule;
1212
+ }
1213
+ cachedModule = null;
1214
+ return null;
1215
+ } catch {
1216
+ cachedModule = null;
1217
+ return null;
1218
+ }
1219
+ })();
1220
+ }
1221
+ return moduleLoadPromise;
1222
+ }
1223
+ async function getCodegraphStore(params) {
1224
+ const { config, memoryDir, principal, projectId, repoRoot } = params;
1225
+ if (!codegraphSurfaceVisible(config)) {
1226
+ throw new CodegraphRuntimeError(
1227
+ "disabled",
1228
+ "codegraph tools are disabled (codingKnowledge.enabled or codingKnowledge.codegraphTools is false)"
1229
+ );
1230
+ }
1231
+ const mod = await loadCodegraphModule();
1232
+ if (mod === null) {
1233
+ throw new CodegraphRuntimeError(
1234
+ "package_missing",
1235
+ "The @remnic/coding-graph package is not installed; install it to use codegraph tools."
1236
+ );
1237
+ }
1238
+ const principalSafe = sanitizePathSegment(principal);
1239
+ const projectSafe = sanitizePathSegment(projectId);
1240
+ const dbPath = resolveCodegraphDbPath({ config, memoryDir, principal, projectId });
1241
+ const key = storeCacheKey(principalSafe, projectSafe, dbPath);
1242
+ const cached = storeCache.get(key);
1243
+ if (cached !== void 0) {
1244
+ if (repoRoot !== void 0 && cached.repoRoot === void 0) {
1245
+ storeCache.delete(key);
1246
+ try {
1247
+ await cached.store.close();
1248
+ } catch {
1249
+ }
1250
+ const store2 = await mod.GraphStore.open({ dbPath, repoRoot });
1251
+ storeCache.set(key, { store: store2, repoRoot, openedAt: Date.now() });
1252
+ return store2;
1253
+ }
1254
+ if (repoRoot !== void 0 && cached.repoRoot !== void 0 && cached.repoRoot !== repoRoot) {
1255
+ throw new CodegraphRuntimeError(
1256
+ "repo_root_conflict",
1257
+ `codegraph store for project ${projectId} is already bound to repo root ${cached.repoRoot}; refusing to rebind to ${repoRoot}`
1258
+ );
1259
+ }
1260
+ return cached.store;
1261
+ }
1262
+ const store = await mod.GraphStore.open({ dbPath, repoRoot });
1263
+ storeCache.set(key, { store, repoRoot, openedAt: Date.now() });
1264
+ return store;
1265
+ }
1266
+ function listCodegraphProjects(params) {
1267
+ const { config, memoryDir, principal, listDir } = params;
1268
+ if (!codegraphSurfaceVisible(config)) return [];
1269
+ let root;
1270
+ try {
1271
+ root = resolveCodegraphRoot(config, memoryDir);
1272
+ } catch {
1273
+ return [];
1274
+ }
1275
+ const principalSafe = sanitizePathSegment(principal);
1276
+ const principalDir = path2.join(root, principalSafe);
1277
+ let entries;
1278
+ try {
1279
+ entries = listDir(principalDir);
1280
+ } catch {
1281
+ return [];
1282
+ }
1283
+ const projects = [];
1284
+ for (const entry of entries) {
1285
+ if (entry.endsWith(".sqlite")) {
1286
+ projects.push(entry.slice(0, -".sqlite".length));
1287
+ }
1288
+ }
1289
+ return projects;
1290
+ }
1291
+ async function deleteCodegraphProject(params) {
1292
+ const { config, memoryDir, principal, projectId, confirm, removeFile } = params;
1293
+ if (!confirm) {
1294
+ throw new CodegraphRuntimeError(
1295
+ "confirm_required",
1296
+ "codegraph_delete_project requires confirm: true; destructive operations are never defaulted to proceed (rule 48)"
1297
+ );
1298
+ }
1299
+ if (!codegraphSurfaceVisible(config)) {
1300
+ throw new CodegraphRuntimeError("disabled", "codegraph tools are disabled");
1301
+ }
1302
+ const principalSafe = sanitizePathSegment(principal);
1303
+ const projectSafe = sanitizePathSegment(projectId);
1304
+ const dbPath = resolveCodegraphDbPath({ config, memoryDir, principal, projectId });
1305
+ const key = storeCacheKey(principalSafe, projectSafe, dbPath);
1306
+ const cached = storeCache.get(key);
1307
+ if (cached !== void 0) {
1308
+ storeCache.delete(key);
1309
+ try {
1310
+ await cached.store.close();
1311
+ } catch {
1312
+ }
1313
+ }
1314
+ let deleted = false;
1315
+ try {
1316
+ removeFile(dbPath);
1317
+ deleted = true;
1318
+ } catch (err) {
1319
+ const code = err?.code;
1320
+ if (code === "ENOENT") {
1321
+ deleted = true;
1322
+ } else {
1323
+ deleted = false;
1324
+ }
1325
+ }
1326
+ return { deleted, projectId };
1327
+ }
1328
+ function makeCodegraphRuntimeDelegates() {
1329
+ return {
1330
+ runReindex: (store, repoRoot, mode) => runCodegraphReindex({ store, repoRoot, mode }),
1331
+ reportIndexStatus: (store, repoRoot) => reportCodegraphIndexStatus({ store, repoRoot }),
1332
+ detectChanges: (store, repoRoot, head) => detectCodegraphChanges({ store, repoRoot, head }),
1333
+ ingestTraces: (store, traces) => ingestCodegraphTraces({ store, traces })
1334
+ };
1335
+ }
1336
+ async function runCodegraphReindex(params) {
1337
+ const mod = await loadCodegraphModule();
1338
+ if (mod === null) {
1339
+ return { ok: false, code: "package_missing", message: "The @remnic/coding-graph package is not installed." };
1340
+ }
1341
+ if (typeof mod.executeReindex !== "function" || typeof mod.defaultCodingGitInvoker !== "function") {
1342
+ return { ok: false, code: "runtime_unavailable", message: "executeReindex is not available in the installed @remnic/coding-graph." };
1343
+ }
1344
+ const git = mod.defaultCodingGitInvoker();
1345
+ let engine;
1346
+ try {
1347
+ if (typeof mod.createCodingGraphEngine !== "function") {
1348
+ return { ok: false, code: "engine_unavailable", message: "createCodingGraphEngine is not exported by @remnic/coding-graph." };
1349
+ }
1350
+ engine = mod.createCodingGraphEngine();
1351
+ } catch (err) {
1352
+ const msg = err instanceof Error ? err.message : String(err);
1353
+ return { ok: false, code: "engine_unavailable", message: `The coding-graph engine is not ready: ${msg}` };
1354
+ }
1355
+ let candidatePaths = [];
1356
+ try {
1357
+ const tracked = git.listTrackedFiles(params.repoRoot);
1358
+ if (tracked.ok) {
1359
+ candidatePaths = tracked.paths;
1360
+ }
1361
+ } catch {
1362
+ }
1363
+ try {
1364
+ const result = await mod.executeReindex({
1365
+ store: params.store,
1366
+ git,
1367
+ repoRoot: params.repoRoot,
1368
+ parseFile: (input) => engine.parseFile(input),
1369
+ candidatePaths
1370
+ });
1371
+ if (result && result.ok === true) {
1372
+ return { ok: true, mode: result.mode ?? "auto", filesIngested: result.filesIngested ?? 0, head: result.head ?? null };
1373
+ }
1374
+ return {
1375
+ ok: false,
1376
+ code: result?.code ?? "store_error",
1377
+ message: result?.message ?? "executeReindex reported a failure."
1378
+ };
1379
+ } catch (err) {
1380
+ const msg = err instanceof Error ? err.message : String(err);
1381
+ return { ok: false, code: "store_error", message: msg };
1382
+ }
1383
+ }
1384
+ async function reportCodegraphIndexStatus(params) {
1385
+ const mod = await loadCodegraphModule();
1386
+ if (mod === null) {
1387
+ return { ok: false, code: "package_missing", message: "The @remnic/coding-graph package is not installed." };
1388
+ }
1389
+ if (typeof mod.getIndexStatus !== "function" || typeof mod.defaultCodingGitInvoker !== "function") {
1390
+ return { ok: false, code: "runtime_unavailable", message: "getIndexStatus is not available in the installed @remnic/coding-graph." };
1391
+ }
1392
+ const git = mod.defaultCodingGitInvoker();
1393
+ try {
1394
+ const status = mod.getIndexStatus(params.store, git, params.repoRoot);
1395
+ return { ok: true, status };
1396
+ } catch (err) {
1397
+ const msg = err instanceof Error ? err.message : String(err);
1398
+ return { ok: false, code: "store_error", message: msg };
1399
+ }
1400
+ }
1401
+ async function detectCodegraphChanges(params) {
1402
+ const mod = await loadCodegraphModule();
1403
+ if (mod === null) {
1404
+ return { ok: false, code: "package_missing", message: "The @remnic/coding-graph package is not installed." };
1405
+ }
1406
+ if (typeof mod.computeBlastRadius !== "function") {
1407
+ return { ok: false, code: "runtime_unavailable", message: "computeBlastRadius is not available in the installed @remnic/coding-graph." };
1408
+ }
1409
+ let engine;
1410
+ try {
1411
+ if (typeof mod.createCodingGraphEngine !== "function") {
1412
+ return { ok: false, code: "engine_unavailable", message: "createCodingGraphEngine is not exported by @remnic/coding-graph." };
1413
+ }
1414
+ engine = mod.createCodingGraphEngine();
1415
+ } catch (err) {
1416
+ const msg = err instanceof Error ? err.message : String(err);
1417
+ return { ok: false, code: "engine_unavailable", message: `The coding-graph engine is not ready: ${msg}` };
1418
+ }
1419
+ void engine;
1420
+ void params;
1421
+ try {
1422
+ const result = mod.computeBlastRadius(params.store, /* @__PURE__ */ new Set());
1423
+ if (result && result.ok === true) {
1424
+ return { ok: true, affected: result.affected ?? [] };
1425
+ }
1426
+ return { ok: false, code: result?.code ?? "store_error", message: "computeBlastRadius reported a failure." };
1427
+ } catch (err) {
1428
+ const msg = err instanceof Error ? err.message : String(err);
1429
+ return { ok: false, code: "store_error", message: msg };
1430
+ }
1431
+ }
1432
+ async function ingestCodegraphTraces(params) {
1433
+ if (typeof params.store.upsertEdges !== "function") {
1434
+ return {
1435
+ ok: false,
1436
+ code: "runtime_unavailable",
1437
+ message: "The installed @remnic/coding-graph does not expose upsertEdges; traces cannot be persisted."
1438
+ };
1439
+ }
1440
+ const edges = [];
1441
+ let accepted = 0;
1442
+ for (const trace of params.traces) {
1443
+ const t = trace;
1444
+ if (typeof t?.caller !== "string" || typeof t?.callee !== "string") {
1445
+ continue;
1446
+ }
1447
+ accepted += 1;
1448
+ edges.push({
1449
+ srcQualifiedName: t.caller,
1450
+ dstQualifiedName: t.callee,
1451
+ type: "HTTP_CALLS",
1452
+ confidence: typeof t.confidence === "number" && t.confidence >= 0 && t.confidence <= 1 ? t.confidence : 0.5,
1453
+ provenance: "trace"
1454
+ });
1455
+ }
1456
+ try {
1457
+ const result = await params.store.upsertEdges(edges);
1458
+ if (result.ok === true) {
1459
+ return { ok: true, accepted, persisted: result.persisted, skipped: result.skipped };
1460
+ }
1461
+ return { ok: false, code: result.code, message: "store.upsertEdges reported a failure." };
1462
+ } catch (err) {
1463
+ const msg = err instanceof Error ? err.message : String(err);
1464
+ return { ok: false, code: "store_error", message: msg };
1465
+ }
1466
+ }
1467
+ function deriveCodegraphProjectId(repoRoot) {
1468
+ return `root:${createHash("sha256").update(repoRoot).digest("hex").slice(0, 16)}`;
1469
+ }
1470
+ function resolveCodegraphProjectId(params) {
1471
+ const { request, getCodingContext } = params;
1472
+ const explicit = typeof request.project === "string" ? request.project.trim() : "";
1473
+ if (explicit.length > 0) return explicit;
1474
+ const sessionKey = typeof request.sessionKey === "string" ? request.sessionKey.trim() : "";
1475
+ if (sessionKey.length > 0) {
1476
+ const cc = getCodingContext(sessionKey);
1477
+ if (cc !== null) return cc.projectId;
1478
+ }
1479
+ const repoRoot = typeof request.repoRoot === "string" ? request.repoRoot.trim() : "";
1480
+ if (repoRoot.length > 0) return deriveCodegraphProjectId(repoRoot);
1481
+ throw new CodegraphRuntimeError(
1482
+ "project_required",
1483
+ "codegraph: project must be supplied explicitly, via a session coding context, or alongside a repoRoot"
1484
+ );
1485
+ }
1486
+ var CodegraphRuntimeError = class extends Error {
1487
+ code;
1488
+ constructor(code, message) {
1489
+ super(message);
1490
+ this.name = "CodegraphRuntimeError";
1491
+ this.code = code;
1492
+ }
1493
+ };
1494
+
1495
+ // src/coding/codegraph-surfaces.ts
1496
+ var CODEGRAPH_TOOL_NAMES = [
1497
+ "index",
1498
+ "list_projects",
1499
+ "delete_project",
1500
+ "index_status",
1501
+ "search_graph",
1502
+ "trace_path",
1503
+ "detect_changes",
1504
+ "query_graph",
1505
+ "get_schema",
1506
+ "get_snippet",
1507
+ "get_architecture",
1508
+ "search_code",
1509
+ "manage_adr",
1510
+ "ingest_traces"
1511
+ ];
1512
+ var TOOL_NAME_SET = new Set(CODEGRAPH_TOOL_NAMES);
1513
+ function isCodegraphToolName(value) {
1514
+ return typeof value === "string" && TOOL_NAME_SET.has(value);
1515
+ }
1516
+ var TRACE_DIRECTIONS = ["inbound", "outbound", "both"];
1517
+ var TRACE_DIRECTION_SET = new Set(TRACE_DIRECTIONS);
1518
+ var INDEX_MODES = ["auto", "full", "incremental"];
1519
+ var INDEX_MODE_SET = new Set(INDEX_MODES);
1520
+ var MANAGE_ADR_SUBCOMMANDS = DECISION_SUBCOMMANDS;
1521
+ async function handleCodegraphTool(request, ctx) {
1522
+ if (!codegraphSurfaceVisible(ctx.config)) {
1523
+ return disabledResponse(request.tool, "codegraph tools are disabled in config");
1524
+ }
1525
+ switch (request.tool) {
1526
+ case "list_projects":
1527
+ return handleListProjects(request, ctx);
1528
+ case "get_schema":
1529
+ return withStore(request, ctx, (store) => handleGetSchema(store, request.tool));
1530
+ case "search_graph":
1531
+ return withStore(request, ctx, (store) => handleSearchGraph(store, request, ctx));
1532
+ case "search_code":
1533
+ return withStore(request, ctx, (store) => handleSearchCode(store, request, ctx));
1534
+ case "trace_path":
1535
+ return withStore(request, ctx, (store) => handleTracePath(store, request, ctx));
1536
+ case "get_snippet":
1537
+ return withStore(request, ctx, (store) => handleGetSnippet(store, request, ctx));
1538
+ case "query_graph":
1539
+ return withStore(request, ctx, (store) => handleQueryGraph(store, request, ctx));
1540
+ case "index_status":
1541
+ return withStore(request, ctx, (store) => handleIndexStatus(store, request, ctx));
1542
+ case "detect_changes":
1543
+ return withStore(request, ctx, (store) => handleDetectChanges(store, request, ctx));
1544
+ case "index":
1545
+ return handleIndex(request, ctx);
1546
+ case "delete_project":
1547
+ return handleDeleteProject(request, ctx);
1548
+ case "get_architecture":
1549
+ return handleGetArchitecture(request, ctx);
1550
+ case "manage_adr":
1551
+ return handleManageAdr(request, ctx);
1552
+ case "ingest_traces":
1553
+ return withStore(request, ctx, (store) => handleIngestTraces(store, request, ctx));
1554
+ default: {
1555
+ const _exhaustive = request.tool;
1556
+ void _exhaustive;
1557
+ ctx.throwInputError(`unknown codegraph tool: ${request.tool}`);
1558
+ }
1559
+ }
1560
+ }
1561
+ function disabledResponse(tool, message) {
1562
+ return { tool, ok: false, code: "disabled", message };
1563
+ }
1564
+ async function withStore(request, ctx, fn) {
1565
+ let store;
1566
+ try {
1567
+ store = await ctx.resolveStore(request);
1568
+ } catch (err) {
1569
+ if (err instanceof CodegraphRuntimeError) {
1570
+ return { tool: request.tool, ok: false, code: err.code, message: err.message };
1571
+ }
1572
+ throw err;
1573
+ }
1574
+ return fn(store);
1575
+ }
1576
+ async function handleListProjects(request, ctx) {
1577
+ const projects = listCodegraphProjects({
1578
+ config: ctx.config,
1579
+ memoryDir: ctx.memoryDir,
1580
+ principal: ctx.principal,
1581
+ listDir: ctx.listDirs
1582
+ });
1583
+ return { tool: request.tool, ok: true, result: { projects } };
1584
+ }
1585
+ async function handleGetSchema(store, tool) {
1586
+ const stats = store.schemaStats();
1587
+ if (!stats.ok) {
1588
+ return { tool, ok: false, code: stats.code, message: "schemaStats failed" };
1589
+ }
1590
+ return { tool, ok: true, result: stats };
1591
+ }
1592
+ async function handleSearchGraph(store, request, ctx) {
1593
+ const query = requireString2(request.query, "query", ctx);
1594
+ const limit = clampPositiveInteger(request.limit, 50, "limit", ctx);
1595
+ const result = store.searchGraph({ namePattern: query, limit });
1596
+ if (!result.ok) {
1597
+ return { tool: request.tool, ok: false, code: result.code, message: "searchGraph failed" };
1598
+ }
1599
+ return { tool: request.tool, ok: true, result };
1600
+ }
1601
+ var SEARCH_CODE_KINDS = ["function", "class", "method"];
1602
+ async function handleSearchCode(store, request, ctx) {
1603
+ const query = requireString2(request.query, "query", ctx);
1604
+ const limit = clampPositiveInteger(request.limit, 50, "limit", ctx);
1605
+ const seen = /* @__PURE__ */ new Set();
1606
+ const merged = [];
1607
+ for (const kind of SEARCH_CODE_KINDS) {
1608
+ if (merged.length >= limit) break;
1609
+ const result = store.searchGraph({ label: kind, namePattern: query, limit });
1610
+ if (!result.ok) {
1611
+ return { tool: request.tool, ok: false, code: result.code, message: "searchGraph failed" };
1612
+ }
1613
+ for (const hit of result.hits) {
1614
+ const id = typeof hit?.nodeId === "string" ? hit.nodeId : JSON.stringify(hit);
1615
+ if (seen.has(id)) continue;
1616
+ seen.add(id);
1617
+ merged.push(hit);
1618
+ if (merged.length >= limit) break;
1619
+ }
1620
+ }
1621
+ return { tool: request.tool, ok: true, result: { hits: merged } };
1622
+ }
1623
+ async function handleTracePath(store, request, ctx) {
1624
+ const start = requireString2(request.start, "start", ctx);
1625
+ const direction = request.direction ?? "outbound";
1626
+ if (!TRACE_DIRECTION_SET.has(direction)) {
1627
+ ctx.throwInputError(
1628
+ `direction must be one of ${TRACE_DIRECTIONS.join(", ")}; got ${JSON.stringify(direction)}`
1629
+ );
1630
+ }
1631
+ const depth = clampPositiveInteger(request.depth ?? 2, 2, "depth", ctx);
1632
+ const storeDirection = direction === "outbound" ? "outgoing" : direction === "inbound" ? "incoming" : direction;
1633
+ const result = store.traverse({ start, direction: storeDirection, maxDepth: depth });
1634
+ if (!result.ok) {
1635
+ return { tool: request.tool, ok: false, code: result.code, message: "traverse failed" };
1636
+ }
1637
+ return { tool: request.tool, ok: true, result };
1638
+ }
1639
+ async function handleGetSnippet(store, request, ctx) {
1640
+ const qualifiedName = requireString2(request.qualifiedName, "qualifiedName", ctx);
1641
+ const result = await store.snippetFor({ qualifiedName });
1642
+ if (!result.ok) {
1643
+ return { tool: request.tool, ok: false, code: result.code, message: "snippetFor failed" };
1644
+ }
1645
+ return { tool: request.tool, ok: true, result };
1646
+ }
1647
+ async function handleQueryGraph(store, request, ctx) {
1648
+ if (typeof request.query === "string" && isLikelyCypher(request.query)) {
1649
+ ctx.throwInputError(
1650
+ "codegraph_query_graph does not accept Cypher text; pass a structured query via structuredQuery (issue #1554 rejection table)"
1651
+ );
1652
+ }
1653
+ if (request.structuredQuery === void 0) {
1654
+ ctx.throwInputError("codegraph_query_graph requires structuredQuery");
1655
+ }
1656
+ const result = store.searchGraph(request.structuredQuery);
1657
+ if (!result.ok) {
1658
+ return { tool: request.tool, ok: false, code: result.code, message: "searchGraph failed" };
1659
+ }
1660
+ return { tool: request.tool, ok: true, result };
1661
+ }
1662
+ async function handleIndexStatus(store, request, ctx) {
1663
+ const repoRoot = resolveRepoRoot(request, ctx);
1664
+ if (!ctx.reportIndexStatus) {
1665
+ return {
1666
+ tool: request.tool,
1667
+ ok: false,
1668
+ code: "runtime_unavailable",
1669
+ message: "index_status requires @remnic/coding-graph; the runtime is unavailable."
1670
+ };
1671
+ }
1672
+ void store;
1673
+ const outcome = await ctx.reportIndexStatus(store, repoRoot);
1674
+ if (!outcome.ok) {
1675
+ return { tool: request.tool, ok: false, code: outcome.code, message: outcome.message };
1676
+ }
1677
+ return { tool: request.tool, ok: true, result: outcome.status };
1678
+ }
1679
+ async function handleDetectChanges(store, request, ctx) {
1680
+ const head = requireString2(request.head, "head", ctx);
1681
+ if (!ctx.detectChanges) {
1682
+ return {
1683
+ tool: request.tool,
1684
+ ok: false,
1685
+ code: "runtime_unavailable",
1686
+ message: "detect_changes requires @remnic/coding-graph; the runtime is unavailable."
1687
+ };
1688
+ }
1689
+ const repoRoot = resolveRepoRoot(request, ctx);
1690
+ void store;
1691
+ const outcome = await ctx.detectChanges(store, repoRoot, head);
1692
+ if (!outcome.ok) {
1693
+ return { tool: request.tool, ok: false, code: outcome.code, message: outcome.message };
1694
+ }
1695
+ return { tool: request.tool, ok: true, result: { head, affected: outcome.affected } };
1696
+ }
1697
+ async function handleIndex(request, ctx) {
1698
+ const repoRoot = requireString2(request.repoRoot, "repoRoot", ctx);
1699
+ const modeRaw = request.mode ?? "auto";
1700
+ if (!INDEX_MODE_SET.has(modeRaw)) {
1701
+ ctx.throwInputError(`mode must be one of ${INDEX_MODES.join(", ")}; got ${JSON.stringify(modeRaw)}`);
1702
+ }
1703
+ const resolveReq = { ...request, repoRoot };
1704
+ let store;
1705
+ try {
1706
+ store = await ctx.resolveStore(resolveReq);
1707
+ } catch (err) {
1708
+ if (err instanceof CodegraphRuntimeError) {
1709
+ return { tool: request.tool, ok: false, code: err.code, message: err.message };
1710
+ }
1711
+ throw err;
1712
+ }
1713
+ if (!ctx.runReindex) {
1714
+ return {
1715
+ tool: request.tool,
1716
+ ok: false,
1717
+ code: "runtime_unavailable",
1718
+ message: "index requires @remnic/coding-graph's reindex executor; the runtime is unavailable."
1719
+ };
1720
+ }
1721
+ const outcome = await ctx.runReindex(store, repoRoot, modeRaw);
1722
+ if (!outcome.ok) {
1723
+ return { tool: request.tool, ok: false, code: outcome.code, message: outcome.message };
1724
+ }
1725
+ const stats = store.schemaStats();
1726
+ return {
1727
+ tool: request.tool,
1728
+ ok: true,
1729
+ result: {
1730
+ repoRoot,
1731
+ mode: outcome.mode,
1732
+ filesIngested: outcome.filesIngested,
1733
+ head: outcome.head,
1734
+ stats
1735
+ }
1736
+ };
1737
+ }
1738
+ async function handleDeleteProject(request, ctx) {
1739
+ const projectId = resolveProjectId(request, ctx);
1740
+ if (request.confirm !== true) {
1741
+ return {
1742
+ tool: request.tool,
1743
+ ok: false,
1744
+ code: "confirm_required",
1745
+ message: "codegraph_delete_project requires confirm: true (rule 48)"
1746
+ };
1747
+ }
1748
+ try {
1749
+ const result = await deleteCodegraphProject({
1750
+ config: ctx.config,
1751
+ memoryDir: ctx.memoryDir,
1752
+ principal: ctx.principal,
1753
+ projectId,
1754
+ confirm: true,
1755
+ removeFile: ctx.removeFile
1756
+ });
1757
+ return { tool: request.tool, ok: true, result };
1758
+ } catch (err) {
1759
+ if (err instanceof CodegraphRuntimeError) {
1760
+ return { tool: request.tool, ok: false, code: err.code, message: err.message };
1761
+ }
1762
+ throw err;
1763
+ }
1764
+ }
1765
+ async function handleGetArchitecture(request, ctx) {
1766
+ const codingContext = resolveCodingContext(request, ctx);
1767
+ const repoRoot = request.repoRoot ?? codingContext.rootPath;
1768
+ const card = await ctx.buildArchitectureCard(repoRoot);
1769
+ let stats;
1770
+ try {
1771
+ const store = await ctx.resolveStore(request);
1772
+ stats = store.schemaStats();
1773
+ } catch (err) {
1774
+ if (err instanceof CodegraphRuntimeError) {
1775
+ stats = { ok: false, code: err.code };
1776
+ } else {
1777
+ throw err;
1778
+ }
1779
+ }
1780
+ return {
1781
+ tool: request.tool,
1782
+ ok: true,
1783
+ result: { card, graphStats: stats }
1784
+ };
1785
+ }
1786
+ async function handleManageAdr(request, ctx) {
1787
+ const subcommand = request.subcommand;
1788
+ if (typeof subcommand !== "string" || !MANAGE_ADR_SUBCOMMANDS.includes(subcommand)) {
1789
+ ctx.throwInputError(
1790
+ `manage_adr subcommand must be one of ${MANAGE_ADR_SUBCOMMANDS.join(", ")}; got ${JSON.stringify(subcommand)}`
1791
+ );
1792
+ }
1793
+ const codingContext = resolveCodingContext(request, ctx);
1794
+ if (!isDecisionRecordSurfaceEnabled(ctx.config.codingKnowledge, codingContext)) {
1795
+ return disabledResponse(
1796
+ request.tool,
1797
+ "manage_adr requires codingKnowledge.enabled + decisionRecords + an attached coding context"
1798
+ );
1799
+ }
1800
+ const decisionRequest = {
1801
+ subcommand,
1802
+ sessionKey: request.sessionKey,
1803
+ id: request.id,
1804
+ title: request.title,
1805
+ status: request.status,
1806
+ context: request.context,
1807
+ decision: request.decision,
1808
+ consequences: request.consequences,
1809
+ entityRefs: request.entityRefs,
1810
+ supersedesId: request.supersedesId
1811
+ };
1812
+ const result = await ctx.delegateDecisionRecord(decisionRequest);
1813
+ return { tool: request.tool, ok: true, result };
1814
+ }
1815
+ async function handleIngestTraces(store, request, ctx) {
1816
+ if (!Array.isArray(request.traces)) {
1817
+ ctx.throwInputError("codegraph_ingest_traces requires traces: an array of call-site observations");
1818
+ }
1819
+ if (!ctx.ingestTraces) {
1820
+ return {
1821
+ tool: request.tool,
1822
+ ok: false,
1823
+ code: "runtime_unavailable",
1824
+ message: "ingest_traces requires @remnic/coding-graph's store write path; the runtime is unavailable."
1825
+ };
1826
+ }
1827
+ const outcome = await ctx.ingestTraces(store, request.traces);
1828
+ if (!outcome.ok) {
1829
+ return { tool: request.tool, ok: false, code: outcome.code, message: outcome.message };
1830
+ }
1831
+ return {
1832
+ tool: request.tool,
1833
+ ok: true,
1834
+ result: {
1835
+ accepted: outcome.accepted,
1836
+ persisted: outcome.persisted
1837
+ }
1838
+ };
1839
+ }
1840
+ function requireString2(value, field, ctx) {
1841
+ if (typeof value !== "string" || value.trim().length === 0) {
1842
+ ctx.throwInputError(`codegraph: ${field} is required and must be a non-empty string`);
1843
+ }
1844
+ return value;
1845
+ }
1846
+ function clampPositiveInteger(value, defaultValue, field, ctx) {
1847
+ if (value === void 0) return defaultValue;
1848
+ if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value) || value < 1) {
1849
+ ctx.throwInputError(`codegraph: ${field} must be a positive integer; got ${JSON.stringify(value)}`);
1850
+ }
1851
+ return Math.min(value, 200);
1852
+ }
1853
+ function resolveCodingContext(request, ctx) {
1854
+ if (!request.sessionKey) {
1855
+ ctx.throwInputError("codegraph tool requires a sessionKey with an attached coding context");
1856
+ }
1857
+ const codingContext = ctx.getCodingContext(request.sessionKey);
1858
+ if (codingContext === null) {
1859
+ ctx.throwInputError(
1860
+ `no coding context attached to session ${request.sessionKey}; attach one via set_coding_context first`
1861
+ );
1862
+ }
1863
+ return codingContext;
1864
+ }
1865
+ function resolveProjectId(request, ctx) {
1866
+ if (typeof request.project === "string" && request.project.trim().length > 0) {
1867
+ return request.project.trim();
1868
+ }
1869
+ return resolveCodingContext(request, ctx).projectId;
1870
+ }
1871
+ function resolveRepoRoot(request, ctx) {
1872
+ if (typeof request.repoRoot === "string" && request.repoRoot.trim().length > 0) {
1873
+ return request.repoRoot.trim();
1874
+ }
1875
+ return resolveCodingContext(request, ctx).rootPath;
1876
+ }
1877
+ function isLikelyCypher(input) {
1878
+ return /^\s*(MATCH|RETURN|WHERE|CREATE|MERGE|DELETE|WITH|OPTIONAL|CALL|YIELD|UNWIND)\b/i.test(input);
1879
+ }
1880
+
1881
+ // src/coding/session-delta.ts
1882
+ import { readFile as readFile2, writeFile, mkdir, rename } from "fs/promises";
1883
+ import path3 from "path";
1884
+ var MAX_DELTA_COMMITS = 20;
1885
+ var MAX_DELTA_FILES = 50;
1886
+ function computeSessionDelta(lastSeen, current) {
1887
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1888
+ const nextState = { head: current.currentHead, at: now };
1889
+ if (lastSeen === null) {
1890
+ return { ok: true, kind: "first_run", nextState };
1891
+ }
1892
+ if (lastSeen.head === current.currentHead) {
1893
+ return { ok: true, kind: "unchanged", nextState };
1894
+ }
1895
+ if (current.commits.length === 0) {
1896
+ return {
1897
+ ok: false,
1898
+ code: "unreachable_head",
1899
+ detail: `prior head ${lastSeen.head} is not an ancestor of current ${current.currentHead}`,
1900
+ nextState
1901
+ };
1902
+ }
1903
+ const commits = capCommits(current.commits, MAX_DELTA_COMMITS);
1904
+ const touchedFiles = capFiles(current.touchedFiles, MAX_DELTA_FILES);
1905
+ return {
1906
+ ok: true,
1907
+ kind: "changed",
1908
+ delta: {
1909
+ commits,
1910
+ touchedFiles,
1911
+ summaryLine: buildSummaryLine(commits.length, touchedFiles.length, lastSeen.at)
1912
+ },
1913
+ nextState
1914
+ };
1915
+ }
1916
+ function capCommits(commits, max) {
1917
+ if (!Number.isFinite(max) || max <= 0) return [];
1918
+ if (commits.length <= max) return commits;
1919
+ return commits.slice(-max);
1920
+ }
1921
+ function capFiles(files, max) {
1922
+ if (!Number.isFinite(max) || max <= 0) return [];
1923
+ if (files.length <= max) return files;
1924
+ return files.slice(0, max);
1925
+ }
1926
+ function buildSummaryLine(commitCount, fileCount, sinceIso) {
1927
+ const since = formatSinceDate(sinceIso);
1928
+ const commitWord = commitCount === 1 ? "commit" : "commits";
1929
+ const fileWord = fileCount === 1 ? "file" : "files";
1930
+ return `Since ${since}: ${commitCount} ${commitWord}, ${fileCount} ${fileWord} touched.`;
1931
+ }
1932
+ function formatSinceDate(iso) {
1933
+ const match = /^(\d{4}-\d{2}-\d{2})/.exec(iso);
1934
+ return match ? match[1] : iso;
1935
+ }
1936
+ var CODING_KNOWLEDGE_STATE_DIR = path3.join("state", "coding-knowledge");
1937
+ function sessionDeltaStatePath(memoryDir, namespace) {
1938
+ const safe = sanitizeFragment(namespace) || "default";
1939
+ return path3.join(memoryDir, CODING_KNOWLEDGE_STATE_DIR, `${safe}.json`);
1940
+ }
1941
+ async function readLastSeenState(statePath) {
1942
+ try {
1943
+ const raw = await readFile2(statePath, "utf8");
1944
+ const parsed = JSON.parse(raw);
1945
+ if (typeof parsed !== "object" || parsed === null) return null;
1946
+ const obj = parsed;
1947
+ const head = typeof obj.head === "string" ? obj.head : null;
1948
+ const at = typeof obj.at === "string" ? obj.at : null;
1949
+ if (!head || !at) return null;
1950
+ return { head, at };
1951
+ } catch {
1952
+ return null;
1953
+ }
1954
+ }
1955
+ async function writeLastSeenState(statePath, state) {
1956
+ if (!state.head || !state.at) {
1957
+ throw new Error(
1958
+ `writeLastSeenState: invalid state (head=${JSON.stringify(state.head)}, at=${JSON.stringify(state.at)})`
1959
+ );
1960
+ }
1961
+ const dir = path3.dirname(statePath);
1962
+ await mkdir(dir, { recursive: true });
1963
+ const tmp = `${statePath}.tmp-${process.pid}-${Date.now()}`;
1964
+ await writeFile(tmp, JSON.stringify(state, null, 2), "utf8");
1965
+ await rename(tmp, statePath);
1966
+ }
1967
+ function resolveSlice(repoRoot, sinceHead, invoker) {
1968
+ const headResult = invoker(repoRoot, ["rev-parse", "HEAD"]);
1969
+ if (headResult.exitCode !== 0) {
1970
+ return {
1971
+ ok: false,
1972
+ code: headResult.stdout.trim().length === 0 ? "no_head" : "git_failed",
1973
+ detail: `rev-parse HEAD exited ${headResult.exitCode}`
1974
+ };
1975
+ }
1976
+ const currentHead = headResult.stdout.trim();
1977
+ if (!currentHead) {
1978
+ return { ok: false, code: "no_head", detail: "rev-parse HEAD returned empty" };
1979
+ }
1980
+ if (!sinceHead) {
1981
+ return { ok: true, slice: { commits: [], touchedFiles: [], currentHead } };
1982
+ }
1983
+ if (sinceHead === currentHead) {
1984
+ return { ok: true, slice: { commits: [], touchedFiles: [], currentHead } };
1985
+ }
1986
+ const SEP = "";
1987
+ const logResult = invoker(repoRoot, [
1988
+ "log",
1989
+ "--reverse",
1990
+ `--pretty=format:%H${SEP}%s`,
1991
+ "--name-only",
1992
+ `${sinceHead}..${currentHead}`
1993
+ ]);
1994
+ if (logResult.exitCode !== 0) {
1995
+ if (logResult.exitCode === 128) {
1996
+ return { ok: true, slice: { commits: [], touchedFiles: [], currentHead } };
1997
+ }
1998
+ return {
1999
+ ok: false,
2000
+ code: "git_failed",
2001
+ detail: "git log exited " + logResult.exitCode + " (transient \u2014 state marker preserved)"
2002
+ };
2003
+ }
2004
+ const { commits, touchedFiles } = parseLogOutput(logResult.stdout, SEP);
2005
+ return { ok: true, slice: { commits, touchedFiles, currentHead } };
2006
+ }
2007
+ function parseLogOutput(stdout, sep2) {
2008
+ const commits = [];
2009
+ const fileSet = /* @__PURE__ */ new Set();
2010
+ const blocks = stdout.split(/\n\s*\n/);
2011
+ for (const block of blocks) {
2012
+ const lines = block.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
2013
+ if (lines.length === 0) continue;
2014
+ const header = lines[0];
2015
+ const sepIdx = header.indexOf(sep2);
2016
+ if (sepIdx >= 0) {
2017
+ const sha = header.slice(0, sepIdx);
2018
+ const subject = header.slice(sepIdx + sep2.length);
2019
+ commits.push({ sha, subject });
2020
+ for (let i = 1; i < lines.length; i += 1) {
2021
+ if (lines[i]) fileSet.add(lines[i]);
2022
+ }
2023
+ } else {
2024
+ for (const line of lines) fileSet.add(line);
2025
+ }
2026
+ }
2027
+ const touchedFiles = [...fileSet].sort((a, b) => a.localeCompare(b));
2028
+ return { commits, touchedFiles };
2029
+ }
2030
+
2031
+ // src/coding/session-delta-surfaces.ts
2032
+ var DELTA_SUBCOMMANDS = ["get"];
2033
+ function isSessionDeltaSurfaceEnabled(config, codingContext) {
2034
+ return config.enabled === true && config.sessionDelta === true && codingContext !== null && codingContext !== void 0;
2035
+ }
2036
+ async function handleCodingDelta(request, ctx) {
2037
+ const codingContext = request.sessionKey ? ctx.getCodingContext(request.sessionKey) : null;
2038
+ if (codingContext === null || !isSessionDeltaSurfaceEnabled(ctx.codingKnowledge, codingContext)) {
2039
+ ctx.throwInputError(
2040
+ "coding_delta requires codingKnowledge.enabled, codingKnowledge.sessionDelta, and an attached coding context"
2041
+ );
2042
+ }
2043
+ switch (request.subcommand) {
2044
+ case "get":
2045
+ return deltaGet(request, ctx, codingContext);
2046
+ }
2047
+ }
2048
+ async function deltaGet(request, ctx, codingContext) {
2049
+ const storage = await ctx.resolveStorage(request);
2050
+ const statePath = sessionDeltaStatePath(storage.memoryDir, storage.namespace);
2051
+ const lastSeen = await readLastSeenState(statePath);
2052
+ const repoRoot = codingContext.rootPath ?? codingContext.projectId;
2053
+ const sliceResult = resolveSlice(
2054
+ repoRoot,
2055
+ lastSeen?.head ?? null,
2056
+ ctx.gitInvoker
2057
+ );
2058
+ if (!sliceResult.ok) {
2059
+ log.warn(
2060
+ `coding_delta/get: slice resolution failed (code=${sliceResult.code}): ${sliceResult.detail}`
2061
+ );
2062
+ return {
2063
+ subcommand: "get",
2064
+ ok: false,
2065
+ code: "git_failed",
2066
+ detail: sliceResult.detail
2067
+ };
2068
+ }
2069
+ const result = computeSessionDelta(lastSeen, sliceResult.slice);
2070
+ let nextState = null;
2071
+ if (result.ok) {
2072
+ nextState = result.nextState;
2073
+ } else if (result.code === "unreachable_head") {
2074
+ nextState = result.nextState;
2075
+ }
2076
+ if (nextState) {
2077
+ try {
2078
+ await writeLastSeenState(statePath, nextState);
2079
+ } catch (err) {
2080
+ log.warn(
2081
+ `coding_delta/get: state write failed for ${statePath}: ${err instanceof Error ? err.message : String(err)}`
2082
+ );
2083
+ }
2084
+ }
2085
+ if (!result.ok) {
2086
+ if (result.code === "unreachable_head") {
2087
+ return {
2088
+ subcommand: "get",
2089
+ ok: false,
2090
+ code: result.code,
2091
+ detail: result.detail,
2092
+ nextState: result.nextState
2093
+ };
2094
+ }
2095
+ return {
2096
+ subcommand: "get",
2097
+ ok: false,
2098
+ code: result.code,
2099
+ detail: result.detail
2100
+ };
2101
+ }
2102
+ switch (result.kind) {
2103
+ case "first_run":
2104
+ return { subcommand: "get", ok: true, kind: "first_run", nextState: result.nextState };
2105
+ case "unchanged":
2106
+ return { subcommand: "get", ok: true, kind: "unchanged", nextState: result.nextState };
2107
+ case "changed":
2108
+ return {
2109
+ subcommand: "get",
2110
+ ok: true,
2111
+ kind: "changed",
2112
+ delta: {
2113
+ commits: result.delta.commits,
2114
+ touchedFiles: result.delta.touchedFiles,
2115
+ summaryLine: result.delta.summaryLine
2116
+ },
2117
+ nextState: result.nextState
2118
+ };
2119
+ }
2120
+ }
2121
+
2122
+ // src/procedural/procedure-miner.ts
2123
+ import { createHash as createHash2 } from "crypto";
2124
+ import { mkdir as mkdir2, rm, stat } from "fs/promises";
2125
+ import path4 from "path";
1165
2126
  var PROCEDURE_CLUSTER_ATTR_MAX = 500;
1166
2127
  var PROCEDURE_CLUSTER_LOCK_STALE_MS = 12e4;
1167
2128
  var PROCEDURE_CLUSTER_LOCK_TIMEOUT_MS = 3e4;
@@ -1172,7 +2133,7 @@ function clusterKey(record) {
1172
2133
  return `${goal}|${refs.join(",")}`;
1173
2134
  }
1174
2135
  function clusterKeyHash(cluster) {
1175
- return createHash("sha256").update(cluster).digest("hex");
2136
+ return createHash2("sha256").update(cluster).digest("hex");
1176
2137
  }
1177
2138
  function isErrnoCode(error, code) {
1178
2139
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
@@ -1181,14 +2142,14 @@ function sleep(ms) {
1181
2142
  return new Promise((resolve2) => setTimeout(resolve2, ms));
1182
2143
  }
1183
2144
  async function acquireClusterWriteLock(memoryDir, clusterHash) {
1184
- const lockRoot = path2.join(path2.resolve(memoryDir), "state", "procedure-miner-locks");
1185
- const lockDir = path2.join(lockRoot, `${clusterHash}.lock`);
1186
- await mkdir(lockRoot, { recursive: true });
2145
+ const lockRoot = path4.join(path4.resolve(memoryDir), "state", "procedure-miner-locks");
2146
+ const lockDir = path4.join(lockRoot, `${clusterHash}.lock`);
2147
+ await mkdir2(lockRoot, { recursive: true });
1187
2148
  const startedAt = Date.now();
1188
2149
  let attempts = 0;
1189
2150
  while (true) {
1190
2151
  try {
1191
- await mkdir(lockDir);
2152
+ await mkdir2(lockDir);
1192
2153
  return async () => {
1193
2154
  await rm(lockDir, { recursive: true, force: true });
1194
2155
  };
@@ -1213,7 +2174,7 @@ async function acquireClusterWriteLock(memoryDir, clusterHash) {
1213
2174
  }
1214
2175
  }
1215
2176
  async function withClusterWriteLock(memoryDir, clusterHash, fn) {
1216
- const inProcessKey = `${path2.resolve(memoryDir)}:${clusterHash}`;
2177
+ const inProcessKey = `${path4.resolve(memoryDir)}:${clusterHash}`;
1217
2178
  const previous = inProcessClusterWriteLocks.get(inProcessKey) ?? Promise.resolve();
1218
2179
  let releaseInProcess;
1219
2180
  const current = previous.catch(() => void 0).then(
@@ -2161,7 +3122,7 @@ var EngramAccessService = class {
2161
3122
  const snapshotForSerialization = {
2162
3123
  sessionKey: options.sessionKey ?? "",
2163
3124
  recordedAt: new Date(options.snapshot.capturedAt).toISOString(),
2164
- queryHash: createHash2("sha256").update(options.query).digest("hex"),
3125
+ queryHash: createHash3("sha256").update(options.query).digest("hex"),
2165
3126
  queryLen: options.query.length,
2166
3127
  memoryIds,
2167
3128
  namespace,
@@ -3770,6 +4731,62 @@ var EngramAccessService = class {
3770
4731
  memory: this.serializeMemory(memory)
3771
4732
  };
3772
4733
  }
4734
+ /**
4735
+ * Codegraph parity tool delegate (issue #1554). All three surfaces (MCP,
4736
+ * HTTP, CLI) arrive here via the codegraph_* boundary operations. The
4737
+ * handler lives in coding/codegraph-surfaces.ts; this method just wires
4738
+ * the context. Memory dir + principal + coding-context lookup come from
4739
+ * the orchestrator/access-service fabric -- no handler-side state.
4740
+ */
4741
+ async codegraphTool(request, authenticatedPrincipal) {
4742
+ const principal = authenticatedPrincipal ?? "default";
4743
+ const memoryDir = this.orchestrator.config.memoryDir;
4744
+ const ctx = {
4745
+ config: this.orchestrator.config,
4746
+ memoryDir,
4747
+ principal,
4748
+ getCodingContext: (sk) => this.orchestrator.getCodingContextForSession(sk),
4749
+ // Project resolution chokepoint lives in codegraph-runtime.ts so every
4750
+ // store-backed tool derives the same id and the tagged error flows back
4751
+ // as a structured response (issue #1554 threads 7/9/11). Thin wiring.
4752
+ resolveStore: async (req) => {
4753
+ const projectId = resolveCodegraphProjectId({
4754
+ request: req,
4755
+ getCodingContext: (sk) => this.orchestrator.getCodingContextForSession(sk)
4756
+ });
4757
+ return getCodegraphStore({
4758
+ config: this.orchestrator.config,
4759
+ memoryDir,
4760
+ principal,
4761
+ projectId,
4762
+ repoRoot: req.repoRoot
4763
+ });
4764
+ },
4765
+ listDirs: (dir) => {
4766
+ try {
4767
+ return readdirSync(dir);
4768
+ } catch {
4769
+ return [];
4770
+ }
4771
+ },
4772
+ removeFile: (filePath) => unlinkSync(filePath),
4773
+ // propagate failures → deleteCodegraphProject classifies (thread 7)
4774
+ throwInputError: (msg) => {
4775
+ throw new EngramAccessInputError(msg);
4776
+ },
4777
+ delegateDecisionRecord: async (decisionRequest) => {
4778
+ return this.codingDecision(decisionRequest, authenticatedPrincipal);
4779
+ },
4780
+ buildArchitectureCard: async (repoRoot) => {
4781
+ return buildArchitectureCard(repoRoot, {
4782
+ llmSummary: this.orchestrator.config.codingKnowledge?.architectureCardLlmSummary === true,
4783
+ summariser: createArchitectureCardSummariser(this.fallbackLlmRef ?? this.localLlmRef)
4784
+ });
4785
+ },
4786
+ ...makeCodegraphRuntimeDelegates()
4787
+ };
4788
+ return handleCodegraphTool(request, ctx);
4789
+ }
3773
4790
  /** Whether the coding_decision tool should appear in tools/list (rule 39). */
3774
4791
  get decisionRecordSurfaceVisible() {
3775
4792
  return this.orchestrator.config.codingKnowledge?.enabled === true && this.orchestrator.config.codingKnowledge?.decisionRecords === true;
@@ -3808,6 +4825,14 @@ var EngramAccessService = class {
3808
4825
  get architectureCardSurfaceVisible() {
3809
4826
  return this.orchestrator.config.codingKnowledge?.enabled === true && this.orchestrator.config.codingKnowledge?.architectureCard === true;
3810
4827
  }
4828
+ /**
4829
+ * Whether the 14 codegraph parity tools should appear in tools/list
4830
+ * (rule 39). Config-only -- runtime availability is checked at call time.
4831
+ * When false the tools array is byte-identical to pre-feature.
4832
+ */
4833
+ get codegraphSurfaceVisible() {
4834
+ return codegraphSurfaceVisible(this.orchestrator.config);
4835
+ }
3811
4836
  /**
3812
4837
  * Thin delegate — handler logic in coding/architecture-surfaces.ts (#1548 PR3).
3813
4838
  * All three surfaces (MCP/HTTP/CLI) arrive here via the boundary operation.
@@ -3849,6 +4874,42 @@ var EngramAccessService = class {
3849
4874
  }
3850
4875
  });
3851
4876
  }
4877
+ /** Whether the coding_delta tool should appear in tools/list (rule 39). */
4878
+ get sessionDeltaSurfaceVisible() {
4879
+ return this.orchestrator.config.codingKnowledge?.enabled === true && this.orchestrator.config.codingKnowledge?.sessionDelta === true;
4880
+ }
4881
+ /**
4882
+ * Thin delegate — handler logic in coding/session-delta-surfaces.ts (#1548 PR4).
4883
+ * All three surfaces (MCP/HTTP/CLI) arrive here via the boundary operation.
4884
+ * Namespace resolution uses the SAME coding-scoped read path as the other
4885
+ * coding surfaces; the delta state file lives under
4886
+ * `<memoryDir>/state/coding-knowledge/<namespace>.json`.
4887
+ */
4888
+ async codingDelta(request, authenticatedPrincipal) {
4889
+ return handleCodingDelta(request, {
4890
+ codingKnowledge: this.orchestrator.config.codingKnowledge,
4891
+ getCodingContext: (sk) => this.orchestrator.getCodingContextForSession(sk),
4892
+ resolveStorage: async (req) => {
4893
+ const ns = await this.resolveCodingScopedReadableNamespace({
4894
+ namespace: req.namespace,
4895
+ sessionKey: req.sessionKey,
4896
+ authenticatedPrincipal
4897
+ });
4898
+ const storage = await this.orchestrator.getStorage(ns);
4899
+ return {
4900
+ memoryDir: storage.dir,
4901
+ namespace: ns
4902
+ };
4903
+ },
4904
+ gitInvoker: (cwd, args) => {
4905
+ const invoker = defaultGitInvoker();
4906
+ return invoker(cwd, args);
4907
+ },
4908
+ throwInputError: (msg) => {
4909
+ throw new EngramAccessInputError(msg);
4910
+ }
4911
+ });
4912
+ }
3852
4913
  async memoryBrowse(request = {}) {
3853
4914
  const resolvedNamespace = this.resolveReadableNamespace(
3854
4915
  request.namespace,
@@ -5898,7 +6959,7 @@ ${next}`);
5898
6959
  sourceSessionKey: request.sessionKey,
5899
6960
  inputSummary: inputSummaryParts.length > 0 ? inputSummaryParts.join(" | ").slice(0, 500) : void 0,
5900
6961
  dryRun: request.dryRun === true,
5901
- promptHash: typeof request.sourcePrompt === "string" && request.sourcePrompt.length > 0 ? createHash2("sha256").update(request.sourcePrompt).digest("hex") : void 0
6962
+ promptHash: typeof request.sourcePrompt === "string" && request.sourcePrompt.length > 0 ? createHash3("sha256").update(request.sourcePrompt).digest("hex") : void 0
5902
6963
  };
5903
6964
  const preview = this.orchestrator.previewMemoryActionEvent(event);
5904
6965
  if (request.dryRun === true) {
@@ -5911,7 +6972,7 @@ ${next}`);
5911
6972
  const resolvedNs = this.resolveWritableNamespace(request.namespace, request.sessionKey, request.principal);
5912
6973
  const storage = await this.orchestrator.getStorage(resolvedNs);
5913
6974
  const storageDir = storage.dir;
5914
- const { writeFile, mkdir: mkdir2 } = await import("fs/promises");
6975
+ const { writeFile: writeFile2, mkdir: mkdir3 } = await import("fs/promises");
5915
6976
  const { join: join2, resolve: resolve2 } = await import("path");
5916
6977
  const safeKey = request.sessionKey.replace(/[^a-zA-Z0-9_-]/g, "_");
5917
6978
  if (!safeKey) throw new EngramAccessInputError("sessionKey is required");
@@ -5920,10 +6981,10 @@ ${next}`);
5920
6981
  if (!resolved.startsWith(resolve2(storageDir))) {
5921
6982
  throw new EngramAccessInputError("Invalid sessionKey");
5922
6983
  }
5923
- await mkdir2(checkpointDir, { recursive: true });
6984
+ await mkdir3(checkpointDir, { recursive: true });
5924
6985
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
5925
6986
  const filePath = join2(checkpointDir, `checkpoint-${ts}.md`);
5926
- await writeFile(filePath, request.context, "utf-8");
6987
+ await writeFile2(filePath, request.context, "utf-8");
5927
6988
  return { saved: true };
5928
6989
  }
5929
6990
  async lcmStatus() {
@@ -6375,7 +7436,7 @@ ${next}`);
6375
7436
  async offlineSyncSnapshot(options = {}) {
6376
7437
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
6377
7438
  const storage = await this.orchestrator.getStorage(resolvedNamespace);
6378
- const storageHash = createHash2("sha256").update(storage.dir).digest("hex").slice(0, 16);
7439
+ const storageHash = createHash3("sha256").update(storage.dir).digest("hex").slice(0, 16);
6379
7440
  const snapshotBuilder = options.includeContent === false && options.baseFiles && options.baseFiles.length > 0 ? buildOfflineSyncSnapshotFromBase : buildOfflineSyncSnapshot;
6380
7441
  const snapshot = await snapshotBuilder({
6381
7442
  root: storage.dir,
@@ -6395,7 +7456,7 @@ ${next}`);
6395
7456
  async offlineSyncSnapshotStream(options = {}) {
6396
7457
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
6397
7458
  const storage = await this.orchestrator.getStorage(resolvedNamespace);
6398
- const storageHash = createHash2("sha256").update(storage.dir).digest("hex").slice(0, 16);
7459
+ const storageHash = createHash3("sha256").update(storage.dir).digest("hex").slice(0, 16);
6399
7460
  return {
6400
7461
  namespace: resolvedNamespace,
6401
7462
  format: OFFLINE_SYNC_SNAPSHOT_FORMAT,
@@ -6416,7 +7477,7 @@ ${next}`);
6416
7477
  async offlineSyncFiles(options) {
6417
7478
  const resolvedNamespace = this.resolveReadableNamespace(options.namespace, options.principal);
6418
7479
  const storage = await this.orchestrator.getStorage(resolvedNamespace);
6419
- const storageHash = createHash2("sha256").update(storage.dir).digest("hex").slice(0, 16);
7480
+ const storageHash = createHash3("sha256").update(storage.dir).digest("hex").slice(0, 16);
6420
7481
  try {
6421
7482
  const snapshot = await buildOfflineSyncSnapshotForPaths({
6422
7483
  root: storage.dir,
@@ -6653,6 +7714,8 @@ ${next}`);
6653
7714
 
6654
7715
  export {
6655
7716
  DECISION_SUBCOMMANDS,
7717
+ isCodegraphToolName,
7718
+ DELTA_SUBCOMMANDS,
6656
7719
  computeProcedureStats,
6657
7720
  formatProcedureStatsText,
6658
7721
  EngramAccessInputError,
@@ -6660,4 +7723,4 @@ export {
6660
7723
  shapeMemorySummary,
6661
7724
  EngramAccessService
6662
7725
  };
6663
- //# sourceMappingURL=chunk-V56S3A23.js.map
7726
+ //# sourceMappingURL=chunk-5A35EGHM.js.map