@interf/compiler 0.22.2 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/README.md +119 -282
  2. package/dist/bin-mcp.d.ts +2 -0
  3. package/dist/bin-mcp.js +63 -0
  4. package/dist/bin-runtime.d.ts +2 -0
  5. package/dist/bin-runtime.js +111 -0
  6. package/dist/cli/commands/agents.js +4 -35
  7. package/dist/cli/commands/auth.d.ts +20 -0
  8. package/dist/cli/commands/auth.js +161 -0
  9. package/dist/cli/commands/benchmark.d.ts +9 -0
  10. package/dist/cli/commands/benchmark.js +58 -0
  11. package/dist/cli/commands/build-plan.js +107 -139
  12. package/dist/cli/commands/build.d.ts +3 -4
  13. package/dist/cli/commands/build.js +16 -45
  14. package/dist/cli/commands/doctor.js +3 -3
  15. package/dist/cli/commands/graphs.d.ts +2 -0
  16. package/dist/cli/commands/graphs.js +344 -0
  17. package/dist/cli/commands/login.js +4 -6
  18. package/dist/cli/commands/logout.js +1 -1
  19. package/dist/cli/commands/mcp.d.ts +4 -2
  20. package/dist/cli/commands/mcp.js +846 -232
  21. package/dist/cli/commands/project.d.ts +2 -0
  22. package/dist/cli/commands/project.js +176 -0
  23. package/dist/cli/commands/reset.d.ts +3 -4
  24. package/dist/cli/commands/reset.js +10 -31
  25. package/dist/cli/commands/runs.js +136 -57
  26. package/dist/cli/commands/runtime.d.ts +24 -0
  27. package/dist/cli/commands/runtime.js +373 -0
  28. package/dist/cli/commands/status.d.ts +1 -0
  29. package/dist/cli/commands/status.js +35 -45
  30. package/dist/cli/commands/traces.d.ts +2 -0
  31. package/dist/cli/commands/traces.js +97 -0
  32. package/dist/cli/commands/wizard.js +171 -178
  33. package/dist/cli/index.d.ts +7 -4
  34. package/dist/cli/index.js +13 -7
  35. package/dist/cli/lib/http-client.d.ts +39 -0
  36. package/dist/cli/lib/http-client.js +73 -0
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +2 -2
  39. package/dist/packages/build-plans/authoring/brief.d.ts +538 -0
  40. package/dist/packages/build-plans/authoring/brief.js +89 -0
  41. package/dist/packages/build-plans/authoring/build-plan-authoring.d.ts +52 -11
  42. package/dist/packages/build-plans/authoring/build-plan-authoring.js +493 -46
  43. package/dist/packages/build-plans/authoring/build-plan-edit-session.d.ts +10 -1
  44. package/dist/packages/build-plans/authoring/build-plan-edit-session.js +27 -4
  45. package/dist/packages/build-plans/authoring/build-plan-improvement.d.ts +9 -6
  46. package/dist/packages/build-plans/authoring/build-plan-improvement.js +97 -46
  47. package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.d.ts +1 -0
  48. package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.js +7 -7
  49. package/dist/packages/build-plans/build-plan-resolution.d.ts +1 -1
  50. package/dist/packages/build-plans/build-plan-resolution.js +3 -3
  51. package/dist/packages/build-plans/index.d.ts +1 -1
  52. package/dist/packages/build-plans/index.js +1 -1
  53. package/dist/packages/build-plans/package/build-plan-definitions.d.ts +14 -13
  54. package/dist/packages/build-plans/package/build-plan-definitions.js +45 -42
  55. package/dist/packages/build-plans/package/build-plan-helpers.d.ts +3 -2
  56. package/dist/packages/build-plans/package/build-plan-helpers.js +27 -13
  57. package/dist/packages/build-plans/package/build-plan-review-paths.d.ts +5 -5
  58. package/dist/packages/build-plans/package/build-plan-review-paths.js +15 -15
  59. package/dist/packages/build-plans/package/build-plan-stage-runner.d.ts +5 -4
  60. package/dist/packages/build-plans/package/build-plan-stage-runner.js +23 -11
  61. package/dist/packages/build-plans/package/builtin-build-plan.d.ts +7 -8
  62. package/dist/packages/build-plans/package/builtin-build-plan.js +10 -11
  63. package/dist/packages/build-plans/package/context-interface.d.ts +14 -9
  64. package/dist/packages/build-plans/package/context-interface.js +14 -33
  65. package/dist/packages/build-plans/package/interf-build-plan-package.d.ts +6 -17
  66. package/dist/packages/build-plans/package/interf-build-plan-package.js +68 -64
  67. package/dist/packages/build-plans/package/local-build-plans.d.ts +21 -14
  68. package/dist/packages/build-plans/package/local-build-plans.js +105 -55
  69. package/dist/packages/build-plans/package/user-build-plans.js +1 -1
  70. package/dist/packages/contracts/index.d.ts +5 -2
  71. package/dist/packages/contracts/index.js +3 -1
  72. package/dist/packages/contracts/lib/context-graph-layer.d.ts +161 -0
  73. package/dist/packages/contracts/lib/context-graph-layer.js +216 -0
  74. package/dist/packages/contracts/lib/project-paths.d.ts +144 -0
  75. package/dist/packages/contracts/lib/project-paths.js +220 -0
  76. package/dist/packages/contracts/lib/project-schema.d.ts +423 -0
  77. package/dist/packages/contracts/lib/project-schema.js +138 -0
  78. package/dist/packages/contracts/lib/schema.d.ts +1273 -81
  79. package/dist/packages/contracts/lib/schema.js +675 -79
  80. package/dist/packages/contracts/utils/filesystem.d.ts +1 -0
  81. package/dist/packages/contracts/utils/filesystem.js +29 -1
  82. package/dist/packages/contracts/utils/parse.js +67 -0
  83. package/dist/packages/projects/index.d.ts +6 -0
  84. package/dist/packages/{project → projects}/index.js +0 -3
  85. package/dist/packages/{project → projects}/interf-detect.d.ts +12 -12
  86. package/dist/packages/{project → projects}/interf-detect.js +56 -50
  87. package/dist/packages/projects/interf.d.ts +2 -0
  88. package/dist/packages/projects/interf.js +1 -0
  89. package/dist/packages/projects/lib/schema.d.ts +77 -0
  90. package/dist/packages/projects/lib/schema.js +91 -0
  91. package/dist/packages/projects/source-config.d.ts +53 -0
  92. package/dist/packages/projects/source-config.js +339 -0
  93. package/dist/packages/projects/source-folders.d.ts +11 -0
  94. package/dist/packages/{project → projects}/source-folders.js +26 -26
  95. package/dist/packages/{engine → runtime}/action-planner.d.ts +1 -1
  96. package/dist/packages/{engine → runtime}/action-planner.js +20 -22
  97. package/dist/packages/runtime/action-values.d.ts +1 -0
  98. package/dist/packages/runtime/action-values.js +1 -0
  99. package/dist/packages/runtime/actions/errors.d.ts +2 -0
  100. package/dist/packages/runtime/actions/errors.js +12 -0
  101. package/dist/packages/runtime/actions/fields.d.ts +86 -0
  102. package/dist/packages/runtime/actions/form-builders.d.ts +14 -0
  103. package/dist/packages/runtime/actions/form-builders.js +667 -0
  104. package/dist/packages/runtime/actions/form-validators.d.ts +8 -0
  105. package/dist/packages/runtime/actions/form-validators.js +134 -0
  106. package/dist/packages/runtime/actions/helpers.d.ts +11 -0
  107. package/dist/packages/runtime/actions/helpers.js +80 -0
  108. package/dist/packages/runtime/actions/index.d.ts +8 -0
  109. package/dist/packages/runtime/actions/index.js +11 -0
  110. package/dist/packages/runtime/actions/registry.d.ts +64 -0
  111. package/dist/packages/runtime/actions/registry.js +62 -0
  112. package/dist/packages/runtime/actions/requests.d.ts +45 -0
  113. package/dist/packages/runtime/actions/requests.js +164 -0
  114. package/dist/packages/runtime/actions/schemas.d.ts +161 -0
  115. package/dist/packages/runtime/actions/schemas.js +37 -0
  116. package/dist/packages/runtime/agent-handoff.d.ts +11 -0
  117. package/dist/packages/runtime/agent-handoff.js +102 -0
  118. package/dist/packages/{engine → runtime}/agents/index.d.ts +1 -2
  119. package/dist/packages/{engine → runtime}/agents/index.js +1 -2
  120. package/dist/packages/runtime/agents/lib/args.d.ts +14 -0
  121. package/dist/packages/runtime/agents/lib/args.js +24 -0
  122. package/dist/packages/{engine → runtime}/agents/lib/constants.d.ts +4 -1
  123. package/dist/packages/runtime/agents/lib/constants.js +13 -0
  124. package/dist/packages/runtime/agents/lib/context-graph-bootstrap.d.ts +3 -0
  125. package/dist/packages/{engine/agents/lib/verifiable-context-bootstrap.js → runtime/agents/lib/context-graph-bootstrap.js} +5 -6
  126. package/dist/packages/{engine → runtime}/agents/lib/detection.d.ts +5 -0
  127. package/dist/packages/{engine → runtime}/agents/lib/detection.js +16 -7
  128. package/dist/packages/{engine → runtime}/agents/lib/execution-profile.d.ts +14 -0
  129. package/dist/packages/{engine → runtime}/agents/lib/execution-profile.js +31 -14
  130. package/dist/packages/{engine → runtime}/agents/lib/execution.js +22 -6
  131. package/dist/packages/{engine → runtime}/agents/lib/executors.d.ts +1 -0
  132. package/dist/packages/{engine → runtime}/agents/lib/executors.js +11 -2
  133. package/dist/packages/runtime/agents/lib/logs.d.ts +12 -0
  134. package/dist/packages/runtime/agents/lib/logs.js +41 -0
  135. package/dist/packages/{engine → runtime}/agents/lib/preflight.js +19 -14
  136. package/dist/packages/runtime/agents/lib/render.d.ts +26 -0
  137. package/dist/packages/{engine → runtime}/agents/lib/render.js +48 -22
  138. package/dist/packages/runtime/agents/lib/shell-fs.d.ts +18 -0
  139. package/dist/packages/runtime/agents/lib/shell-fs.js +190 -0
  140. package/dist/packages/runtime/agents/lib/shell-paths.d.ts +16 -0
  141. package/dist/packages/runtime/agents/lib/shell-paths.js +63 -0
  142. package/dist/packages/runtime/agents/lib/shell-projection.d.ts +25 -0
  143. package/dist/packages/runtime/agents/lib/shell-projection.js +314 -0
  144. package/dist/packages/runtime/agents/lib/shell-templates.d.ts +30 -0
  145. package/dist/packages/runtime/agents/lib/shell-templates.js +494 -0
  146. package/dist/packages/runtime/agents/lib/shell-workspace.d.ts +17 -0
  147. package/dist/packages/runtime/agents/lib/shell-workspace.js +70 -0
  148. package/dist/packages/runtime/agents/lib/shells.d.ts +92 -0
  149. package/dist/packages/runtime/agents/lib/shells.js +509 -0
  150. package/dist/packages/runtime/agents/lib/source-context-scan.d.ts +10 -0
  151. package/dist/packages/runtime/agents/lib/source-context-scan.js +388 -0
  152. package/dist/packages/{engine → runtime}/agents/lib/status.js +1 -14
  153. package/dist/packages/runtime/agents/lib/string-utils.d.ts +16 -0
  154. package/dist/packages/runtime/agents/lib/string-utils.js +36 -0
  155. package/dist/packages/{engine → runtime}/agents/lib/types.d.ts +1 -0
  156. package/dist/packages/{engine → runtime}/agents/lib/user-config.d.ts +8 -2
  157. package/dist/packages/{engine → runtime}/agents/lib/user-config.js +8 -2
  158. package/dist/packages/runtime/agents/providers/claude-code.d.ts +13 -0
  159. package/dist/packages/runtime/agents/providers/claude-code.js +45 -0
  160. package/dist/packages/runtime/agents/providers/codex.d.ts +17 -0
  161. package/dist/packages/runtime/agents/providers/codex.js +66 -0
  162. package/dist/packages/runtime/agents/providers/cursor.d.ts +9 -0
  163. package/dist/packages/runtime/agents/providers/cursor.js +24 -0
  164. package/dist/packages/runtime/agents/providers/index.d.ts +9 -0
  165. package/dist/packages/runtime/agents/providers/index.js +31 -0
  166. package/dist/packages/runtime/agents/providers/types.d.ts +50 -0
  167. package/dist/packages/{engine → runtime}/agents/registry.d.ts +13 -2
  168. package/dist/packages/{engine → runtime}/agents/registry.js +48 -10
  169. package/dist/packages/{engine → runtime}/agents/role-executors.d.ts +1 -1
  170. package/dist/packages/{engine → runtime}/agents/role-executors.js +9 -7
  171. package/dist/packages/{engine → runtime}/agents/role-router.js +7 -5
  172. package/dist/packages/runtime/auth/account-context.d.ts +52 -0
  173. package/dist/packages/runtime/auth/account-context.js +68 -0
  174. package/dist/packages/runtime/auth/auth-flow.d.ts +73 -0
  175. package/dist/packages/runtime/auth/auth-flow.js +189 -0
  176. package/dist/packages/runtime/auth/jwt-validator.d.ts +58 -0
  177. package/dist/packages/runtime/auth/jwt-validator.js +86 -0
  178. package/dist/packages/runtime/auth/keychain.d.ts +35 -0
  179. package/dist/packages/runtime/auth/keychain.js +85 -0
  180. package/dist/packages/runtime/auth/session-store.d.ts +38 -0
  181. package/dist/packages/runtime/auth/session-store.js +96 -0
  182. package/dist/packages/runtime/auth/workos-client.d.ts +58 -0
  183. package/dist/packages/runtime/auth/workos-client.js +87 -0
  184. package/dist/packages/runtime/benchmark-question-draft.d.ts +23 -0
  185. package/dist/packages/runtime/benchmark-question-draft.js +153 -0
  186. package/dist/packages/runtime/build/artifact-counts.d.ts +1 -0
  187. package/dist/packages/{engine → runtime}/build/artifact-counts.js +5 -9
  188. package/dist/packages/{engine → runtime}/build/artifact-status.d.ts +6 -6
  189. package/dist/packages/{engine → runtime}/build/artifact-status.js +26 -24
  190. package/dist/packages/runtime/build/atomic-fs.d.ts +3 -0
  191. package/dist/packages/runtime/build/atomic-fs.js +95 -0
  192. package/dist/packages/runtime/build/billing-events.d.ts +78 -0
  193. package/dist/packages/{engine → runtime}/build/billing-events.js +17 -19
  194. package/dist/packages/runtime/build/build-evidence.d.ts +16 -0
  195. package/dist/packages/runtime/build/build-evidence.js +179 -0
  196. package/dist/packages/{engine → runtime}/build/build-pipeline.d.ts +12 -8
  197. package/dist/packages/runtime/build/build-pipeline.js +388 -0
  198. package/dist/packages/{engine → runtime}/build/build-plan-primitives.d.ts +1 -1
  199. package/dist/packages/{engine → runtime}/build/build-plan-primitives.js +0 -1
  200. package/dist/packages/runtime/build/build-plan-runs.d.ts +14 -0
  201. package/dist/packages/runtime/build/build-plan-runs.js +31 -0
  202. package/dist/packages/runtime/build/build-stage-plan.d.ts +16 -0
  203. package/dist/packages/runtime/build/build-stage-plan.js +101 -0
  204. package/dist/packages/{engine → runtime}/build/build-stage-runner.d.ts +2 -1
  205. package/dist/packages/runtime/build/build-stage-runner.js +302 -0
  206. package/dist/packages/{engine → runtime}/build/build-target.d.ts +7 -4
  207. package/dist/packages/runtime/build/build-target.js +40 -0
  208. package/dist/packages/{engine → runtime}/build/check-evaluator.d.ts +14 -16
  209. package/dist/packages/runtime/build/check-evaluator.js +1226 -0
  210. package/dist/packages/runtime/build/context-graph-paths.d.ts +64 -0
  211. package/dist/packages/runtime/build/context-graph-paths.js +160 -0
  212. package/dist/packages/runtime/build/context-graph-schema.d.ts +19 -0
  213. package/dist/packages/runtime/build/context-graph-schema.js +39 -0
  214. package/dist/packages/{engine → runtime}/build/discovery.d.ts +2 -2
  215. package/dist/packages/{engine → runtime}/build/discovery.js +4 -4
  216. package/dist/packages/{engine → runtime}/build/index.d.ts +7 -5
  217. package/dist/packages/{engine → runtime}/build/index.js +7 -5
  218. package/dist/packages/runtime/build/inspect-map.d.ts +10 -0
  219. package/dist/packages/runtime/build/inspect-map.js +270 -0
  220. package/dist/packages/{engine → runtime}/build/lib/schema.d.ts +449 -123
  221. package/dist/packages/runtime/build/lib/schema.js +494 -0
  222. package/dist/packages/runtime/build/native-entrypoint.d.ts +2 -0
  223. package/dist/packages/runtime/build/native-entrypoint.js +286 -0
  224. package/dist/packages/runtime/build/reset.d.ts +2 -0
  225. package/dist/packages/runtime/build/reset.js +62 -0
  226. package/dist/packages/{engine → runtime}/build/runtime-contracts.js +13 -7
  227. package/dist/packages/runtime/build/runtime-inventory.d.ts +7 -0
  228. package/dist/packages/{engine → runtime}/build/runtime-inventory.js +3 -3
  229. package/dist/packages/runtime/build/runtime-log-paths.d.ts +3 -0
  230. package/dist/packages/runtime/build/runtime-log-paths.js +16 -0
  231. package/dist/packages/{engine → runtime}/build/runtime-prompt.js +12 -9
  232. package/dist/packages/{engine → runtime}/build/runtime-reconcile.d.ts +1 -1
  233. package/dist/packages/{engine → runtime}/build/runtime-reconcile.js +25 -21
  234. package/dist/packages/runtime/build/runtime-runs.d.ts +10 -0
  235. package/dist/packages/runtime/build/runtime-runs.js +318 -0
  236. package/dist/packages/{engine → runtime}/build/runtime-types.d.ts +9 -6
  237. package/dist/packages/runtime/build/runtime-types.js +1 -0
  238. package/dist/packages/runtime/build/runtime.d.ts +8 -0
  239. package/dist/packages/runtime/build/runtime.js +7 -0
  240. package/dist/packages/runtime/build/source-files.d.ts +58 -0
  241. package/dist/packages/runtime/build/source-files.js +193 -0
  242. package/dist/packages/runtime/build/source-inventory.d.ts +28 -0
  243. package/dist/packages/runtime/build/source-inventory.js +512 -0
  244. package/dist/packages/runtime/build/source-manifest.d.ts +63 -0
  245. package/dist/packages/runtime/build/source-manifest.js +220 -0
  246. package/dist/packages/runtime/build/stage-evidence.d.ts +22 -0
  247. package/dist/packages/runtime/build/stage-evidence.js +386 -0
  248. package/dist/packages/runtime/build/stage-manifest.d.ts +45 -0
  249. package/dist/packages/runtime/build/stage-manifest.js +1125 -0
  250. package/dist/packages/runtime/build/stage-reuse.d.ts +11 -0
  251. package/dist/packages/runtime/build/stage-reuse.js +154 -0
  252. package/dist/packages/runtime/build/stage-session.d.ts +81 -0
  253. package/dist/packages/runtime/build/stage-session.js +308 -0
  254. package/dist/packages/runtime/build/state-artifacts.d.ts +9 -0
  255. package/dist/packages/runtime/build/state-artifacts.js +14 -0
  256. package/dist/packages/runtime/build/state-health.d.ts +4 -0
  257. package/dist/packages/{engine → runtime}/build/state-health.js +21 -26
  258. package/dist/packages/runtime/build/state-io.d.ts +12 -0
  259. package/dist/packages/runtime/build/state-io.js +118 -0
  260. package/dist/packages/runtime/build/state-view.d.ts +5 -0
  261. package/dist/packages/runtime/build/state-view.js +121 -0
  262. package/dist/packages/runtime/build/state.d.ts +7 -0
  263. package/dist/packages/runtime/build/state.js +12 -0
  264. package/dist/packages/runtime/build/summary-coverage-index.d.ts +21 -0
  265. package/dist/packages/runtime/build/summary-coverage-index.js +189 -0
  266. package/dist/packages/runtime/build/traces.d.ts +30 -0
  267. package/dist/packages/runtime/build/traces.js +133 -0
  268. package/dist/packages/{engine/build/validate-verifiable-context.d.ts → runtime/build/validate-context-graph.d.ts} +6 -6
  269. package/dist/packages/{engine/build/validate-verifiable-context.js → runtime/build/validate-context-graph.js} +49 -36
  270. package/dist/packages/{engine → runtime}/build/validate.d.ts +5 -5
  271. package/dist/packages/{engine → runtime}/build/validate.js +26 -26
  272. package/dist/packages/{engine → runtime}/client.d.ts +18 -18
  273. package/dist/packages/{engine → runtime}/client.js +48 -36
  274. package/dist/packages/{engine → runtime}/connection-config.d.ts +3 -2
  275. package/dist/packages/{engine → runtime}/connection-config.js +9 -8
  276. package/dist/packages/runtime/context-checks.d.ts +10 -0
  277. package/dist/packages/runtime/context-checks.js +127 -0
  278. package/dist/packages/runtime/context-graph-scaffold.d.ts +9 -0
  279. package/dist/packages/runtime/context-graph-scaffold.js +135 -0
  280. package/dist/packages/runtime/context-graph-semantic-graph.d.ts +9 -0
  281. package/dist/packages/runtime/context-graph-semantic-graph.js +416 -0
  282. package/dist/packages/runtime/entitlement-guard.d.ts +43 -0
  283. package/dist/packages/runtime/entitlement-guard.js +70 -0
  284. package/dist/packages/{engine → runtime}/execution/index.d.ts +2 -2
  285. package/dist/packages/{engine → runtime}/execution/index.js +1 -1
  286. package/dist/packages/{engine → runtime}/execution/lib/schema.d.ts +272 -191
  287. package/dist/packages/{engine → runtime}/execution/lib/schema.js +35 -32
  288. package/dist/packages/runtime/index.d.ts +29 -0
  289. package/dist/packages/runtime/index.js +21 -0
  290. package/dist/packages/runtime/instance-paths.d.ts +30 -0
  291. package/dist/packages/runtime/instance-paths.js +29 -0
  292. package/dist/packages/runtime/native-run-handlers.d.ts +63 -0
  293. package/dist/packages/{engine → runtime}/native-run-handlers.js +217 -166
  294. package/dist/packages/runtime/plan-artifact-contract.d.ts +17 -0
  295. package/dist/packages/runtime/plan-artifact-contract.js +42 -0
  296. package/dist/packages/runtime/project-entries.d.ts +11 -0
  297. package/dist/packages/runtime/project-entries.js +49 -0
  298. package/dist/packages/runtime/project-source-state.d.ts +26 -0
  299. package/dist/packages/runtime/project-source-state.js +56 -0
  300. package/dist/packages/runtime/project-store.d.ts +90 -0
  301. package/dist/packages/runtime/project-store.js +195 -0
  302. package/dist/packages/runtime/requested-artifacts.d.ts +7 -0
  303. package/dist/packages/{engine → runtime}/requested-artifacts.js +23 -1
  304. package/dist/packages/{engine → runtime}/run-observability.d.ts +2 -1
  305. package/dist/packages/{engine → runtime}/run-observability.js +174 -87
  306. package/dist/packages/runtime/runtime-action-proposals.d.ts +7 -0
  307. package/dist/packages/runtime/runtime-action-proposals.js +542 -0
  308. package/dist/packages/runtime/runtime-build-plans.d.ts +5 -0
  309. package/dist/packages/runtime/runtime-build-plans.js +175 -0
  310. package/dist/packages/runtime/runtime-build-runs.d.ts +47 -0
  311. package/dist/packages/runtime/runtime-build-runs.js +555 -0
  312. package/dist/packages/runtime/runtime-caches.d.ts +117 -0
  313. package/dist/packages/runtime/runtime-caches.js +266 -0
  314. package/dist/packages/{engine → runtime}/runtime-event-applier.d.ts +3 -1
  315. package/dist/packages/{engine → runtime}/runtime-event-applier.js +53 -17
  316. package/dist/packages/runtime/runtime-executor.d.ts +22 -0
  317. package/dist/packages/runtime/runtime-executor.js +131 -0
  318. package/dist/packages/runtime/runtime-jobs.d.ts +13 -0
  319. package/dist/packages/runtime/runtime-jobs.js +463 -0
  320. package/dist/packages/runtime/runtime-observability.d.ts +11 -0
  321. package/dist/packages/runtime/runtime-observability.js +39 -0
  322. package/dist/packages/{engine → runtime}/runtime-persistence.d.ts +9 -18
  323. package/dist/packages/{engine → runtime}/runtime-persistence.js +25 -25
  324. package/dist/packages/runtime/runtime-project-mutations.d.ts +7 -0
  325. package/dist/packages/runtime/runtime-project-mutations.js +65 -0
  326. package/dist/packages/runtime/runtime-project-reads.d.ts +18 -0
  327. package/dist/packages/runtime/runtime-project-reads.js +574 -0
  328. package/dist/packages/runtime/runtime-proposal-helpers.d.ts +22 -0
  329. package/dist/packages/runtime/runtime-proposal-helpers.js +223 -0
  330. package/dist/packages/{engine → runtime}/runtime-resource-builders.d.ts +23 -16
  331. package/dist/packages/{engine → runtime}/runtime-resource-builders.js +58 -46
  332. package/dist/packages/runtime/runtime-status.d.ts +14 -0
  333. package/dist/packages/runtime/runtime-status.js +15 -0
  334. package/dist/packages/runtime/runtime-verify-runs.d.ts +84 -0
  335. package/dist/packages/runtime/runtime-verify-runs.js +296 -0
  336. package/dist/packages/runtime/runtime.d.ts +1582 -0
  337. package/dist/packages/runtime/runtime.js +431 -0
  338. package/dist/packages/runtime/schemas/actions.d.ts +1206 -0
  339. package/dist/packages/runtime/schemas/actions.js +117 -0
  340. package/dist/packages/runtime/schemas/agents.d.ts +104 -0
  341. package/dist/packages/runtime/schemas/agents.js +74 -0
  342. package/dist/packages/runtime/schemas/build-plans.d.ts +1132 -0
  343. package/dist/packages/runtime/schemas/build-plans.js +141 -0
  344. package/dist/packages/runtime/schemas/context-graphs.d.ts +1522 -0
  345. package/dist/packages/runtime/schemas/context-graphs.js +110 -0
  346. package/dist/packages/runtime/schemas/files.d.ts +227 -0
  347. package/dist/packages/runtime/schemas/files.js +28 -0
  348. package/dist/packages/runtime/schemas/index.d.ts +9 -0
  349. package/dist/packages/runtime/schemas/index.js +13 -0
  350. package/dist/packages/runtime/schemas/instance.d.ts +141 -0
  351. package/dist/packages/runtime/schemas/instance.js +143 -0
  352. package/dist/packages/runtime/schemas/jobs.d.ts +339 -0
  353. package/dist/packages/runtime/schemas/jobs.js +107 -0
  354. package/dist/packages/runtime/schemas/projects.d.ts +366 -0
  355. package/dist/packages/runtime/schemas/projects.js +160 -0
  356. package/dist/packages/runtime/schemas/runs.d.ts +3445 -0
  357. package/dist/packages/runtime/schemas/runs.js +115 -0
  358. package/dist/packages/runtime/service/index.d.ts +3 -0
  359. package/dist/packages/runtime/service/index.js +3 -0
  360. package/dist/packages/runtime/service/openapi.d.ts +7 -0
  361. package/dist/packages/runtime/service/openapi.js +118 -0
  362. package/dist/packages/runtime/service/operations.d.ts +3011 -0
  363. package/dist/packages/runtime/service/operations.js +375 -0
  364. package/dist/packages/runtime/service/routes.d.ts +114 -0
  365. package/dist/packages/runtime/service/routes.js +128 -0
  366. package/dist/packages/runtime/service/server-api-files.d.ts +10 -0
  367. package/dist/packages/runtime/service/server-api-files.js +85 -0
  368. package/dist/packages/runtime/service/server-app-boot.d.ts +4 -0
  369. package/dist/packages/runtime/service/server-app-boot.js +46 -0
  370. package/dist/packages/runtime/service/server-guards.d.ts +63 -0
  371. package/dist/packages/runtime/service/server-guards.js +181 -0
  372. package/dist/packages/runtime/service/server-helpers.d.ts +38 -0
  373. package/dist/packages/runtime/service/server-helpers.js +108 -0
  374. package/dist/packages/runtime/service/server-instance-helpers.d.ts +30 -0
  375. package/dist/packages/runtime/service/server-instance-helpers.js +114 -0
  376. package/dist/packages/runtime/service/server-routes-action-proposals.d.ts +3 -0
  377. package/dist/packages/runtime/service/server-routes-action-proposals.js +45 -0
  378. package/dist/packages/runtime/service/server-routes-agents.d.ts +4 -0
  379. package/dist/packages/runtime/service/server-routes-agents.js +132 -0
  380. package/dist/packages/runtime/service/server-routes-auth.d.ts +33 -0
  381. package/dist/packages/runtime/service/server-routes-auth.js +138 -0
  382. package/dist/packages/runtime/service/server-routes-build-plans.d.ts +3 -0
  383. package/dist/packages/runtime/service/server-routes-build-plans.js +86 -0
  384. package/dist/packages/runtime/service/server-routes-discovery.d.ts +4 -0
  385. package/dist/packages/runtime/service/server-routes-discovery.js +196 -0
  386. package/dist/packages/runtime/service/server-routes-events.d.ts +5 -0
  387. package/dist/packages/runtime/service/server-routes-events.js +99 -0
  388. package/dist/packages/runtime/service/server-routes-project-context.d.ts +9 -0
  389. package/dist/packages/runtime/service/server-routes-project-context.js +287 -0
  390. package/dist/packages/runtime/service/server-routes-project-jobs.d.ts +9 -0
  391. package/dist/packages/runtime/service/server-routes-project-jobs.js +137 -0
  392. package/dist/packages/runtime/service/server-routes-project-runs.d.ts +14 -0
  393. package/dist/packages/runtime/service/server-routes-project-runs.js +88 -0
  394. package/dist/packages/runtime/service/server-routes-projects.d.ts +4 -0
  395. package/dist/packages/runtime/service/server-routes-projects.js +96 -0
  396. package/dist/packages/runtime/service/server-routes-runs.d.ts +3 -0
  397. package/dist/packages/runtime/service/server-routes-runs.js +119 -0
  398. package/dist/packages/runtime/service/server.d.ts +37 -0
  399. package/dist/packages/runtime/service/server.js +300 -0
  400. package/dist/packages/{engine → runtime/service}/service-registry.d.ts +5 -5
  401. package/dist/packages/{engine → runtime/service}/service-registry.js +7 -7
  402. package/dist/packages/runtime/verify/benchmark-run.d.ts +81 -0
  403. package/dist/packages/runtime/verify/benchmark-run.js +303 -0
  404. package/dist/packages/{engine → runtime}/verify/index.d.ts +2 -2
  405. package/dist/packages/{engine → runtime}/verify/index.js +1 -1
  406. package/dist/packages/{engine → runtime}/verify/lib/schema.d.ts +83 -16
  407. package/dist/packages/{engine → runtime}/verify/lib/schema.js +38 -18
  408. package/dist/packages/runtime/verify/test-file-guard.d.ts +2 -0
  409. package/dist/packages/runtime/verify/test-file-guard.js +29 -0
  410. package/dist/packages/{engine → runtime}/verify/verify-execution.d.ts +7 -0
  411. package/dist/packages/{engine → runtime}/verify/verify-execution.js +119 -45
  412. package/dist/packages/{engine → runtime}/verify/verify-paths.d.ts +5 -4
  413. package/dist/packages/runtime/verify/verify-paths.js +65 -0
  414. package/dist/packages/{engine → runtime}/verify/verify-sandbox.d.ts +1 -1
  415. package/dist/packages/runtime/verify/verify-sandbox.js +88 -0
  416. package/dist/packages/{engine → runtime}/verify/verify-specs.d.ts +2 -0
  417. package/dist/packages/runtime/verify/verify-specs.js +126 -0
  418. package/dist/packages/runtime/verify/verify-targets.d.ts +5 -0
  419. package/dist/packages/{engine → runtime}/verify/verify-targets.js +12 -12
  420. package/dist/packages/runtime/verify/verify-types.js +1 -0
  421. package/dist/packages/{engine → runtime}/verify/verify.d.ts +1 -1
  422. package/dist/packages/{engine → runtime}/verify/verify.js +1 -1
  423. package/dist/packages/runtime/wire-schemas.d.ts +18 -0
  424. package/dist/packages/runtime/wire-schemas.js +27 -0
  425. package/package.json +32 -30
  426. package/public-repo/CONTRIBUTING.md +16 -18
  427. package/public-repo/README.md +119 -282
  428. package/public-repo/SECURITY.md +3 -4
  429. package/public-repo/build-plans/interf-default/README.md +24 -16
  430. package/public-repo/build-plans/interf-default/build/stages/entrypoint/SKILL.md +74 -0
  431. package/public-repo/build-plans/interf-default/build/stages/knowledge/SKILL.md +95 -0
  432. package/public-repo/build-plans/interf-default/build/stages/summarize/SKILL.md +49 -4
  433. package/public-repo/build-plans/interf-default/build-plan.json +49 -39
  434. package/public-repo/build-plans/interf-default/build-plan.schema.json +59 -33
  435. package/public-repo/build-plans/interf-default/improve/SKILL.md +3 -3
  436. package/public-repo/build-plans/interf-default/use/query/SKILL.md +18 -11
  437. package/public-repo/openapi/local-service.openapi.json +14227 -0
  438. package/public-repo/skills/interf/SKILL.md +508 -187
  439. package/dist/cli/commands/prep.d.ts +0 -2
  440. package/dist/cli/commands/prep.js +0 -240
  441. package/dist/cli/commands/test.d.ts +0 -10
  442. package/dist/cli/commands/test.js +0 -85
  443. package/dist/cli/commands/web.d.ts +0 -2
  444. package/dist/cli/commands/web.js +0 -286
  445. package/dist/interf-ui/404.html +0 -1
  446. package/dist/interf-ui/__next.__PAGE__.txt +0 -10
  447. package/dist/interf-ui/__next._full.txt +0 -20
  448. package/dist/interf-ui/__next._head.txt +0 -5
  449. package/dist/interf-ui/__next._index.txt +0 -5
  450. package/dist/interf-ui/__next._tree.txt +0 -5
  451. package/dist/interf-ui/_next/static/--reS3xBzM5zc6QxNjZd6/_buildManifest.js +0 -11
  452. package/dist/interf-ui/_next/static/--reS3xBzM5zc6QxNjZd6/_clientMiddlewareManifest.js +0 -1
  453. package/dist/interf-ui/_next/static/--reS3xBzM5zc6QxNjZd6/_ssgManifest.js +0 -1
  454. package/dist/interf-ui/_next/static/chunks/0.tjb6f4golw..css +0 -3
  455. package/dist/interf-ui/_next/static/chunks/03~yq9q893hmn.js +0 -1
  456. package/dist/interf-ui/_next/static/chunks/085-n_jv2ng_q.css +0 -1
  457. package/dist/interf-ui/_next/static/chunks/0dn41fa_zvgsl.js +0 -1
  458. package/dist/interf-ui/_next/static/chunks/0g-ea0zj5d-0k.js +0 -1
  459. package/dist/interf-ui/_next/static/chunks/0gwqglc4iz583.js +0 -1
  460. package/dist/interf-ui/_next/static/chunks/0haldgm65ve6l.js +0 -1
  461. package/dist/interf-ui/_next/static/chunks/0nv3am99vjzn4.js +0 -1
  462. package/dist/interf-ui/_next/static/chunks/0s77gt_o4jwtx.js +0 -1
  463. package/dist/interf-ui/_next/static/chunks/0y5z3t-z1c8ks.js.map +0 -5
  464. package/dist/interf-ui/_next/static/chunks/0~a36ujuzpaz..js +0 -116
  465. package/dist/interf-ui/_next/static/chunks/10jeodxe4nkgj.js +0 -31
  466. package/dist/interf-ui/_next/static/chunks/119h2rouych2t.js +0 -1
  467. package/dist/interf-ui/_next/static/chunks/13c8b~m8knjsf.js +0 -1
  468. package/dist/interf-ui/_next/static/chunks/14dznb2qpt-ho.js +0 -91
  469. package/dist/interf-ui/_next/static/chunks/15z_en80lrq-3.js +0 -5
  470. package/dist/interf-ui/_next/static/chunks/turbopack-0p.pvcjrtq-jh.js +0 -1
  471. package/dist/interf-ui/_next/static/chunks/turbopack-0usj_75.8frlw.js +0 -1
  472. package/dist/interf-ui/_next/static/chunks/turbopack-worker-0sjn--fhq~1cg.js +0 -1
  473. package/dist/interf-ui/_next/static/media/GeistMono_Variable.p.17jn9btb_52pq.woff2 +0 -0
  474. package/dist/interf-ui/_next/static/media/Geist_Variable-s.p.0-te~ja_gpvcf.woff2 +0 -0
  475. package/dist/interf-ui/_next/static/media/worker.102zas1s52_pf.js +0 -109
  476. package/dist/interf-ui/_not-found/__next._full.txt +0 -15
  477. package/dist/interf-ui/_not-found/__next._head.txt +0 -5
  478. package/dist/interf-ui/_not-found/__next._index.txt +0 -5
  479. package/dist/interf-ui/_not-found/__next._not-found.__PAGE__.txt +0 -5
  480. package/dist/interf-ui/_not-found/__next._not-found.txt +0 -5
  481. package/dist/interf-ui/_not-found/__next._tree.txt +0 -2
  482. package/dist/interf-ui/_not-found.html +0 -1
  483. package/dist/interf-ui/_not-found.txt +0 -15
  484. package/dist/interf-ui/index.html +0 -1
  485. package/dist/interf-ui/index.txt +0 -20
  486. package/dist/packages/contracts/lib/preparation-paths.d.ts +0 -117
  487. package/dist/packages/contracts/lib/preparation-paths.js +0 -177
  488. package/dist/packages/engine/action-definitions.d.ts +0 -407
  489. package/dist/packages/engine/action-definitions.js +0 -1158
  490. package/dist/packages/engine/action-values.d.ts +0 -1
  491. package/dist/packages/engine/action-values.js +0 -1
  492. package/dist/packages/engine/agents/lib/args.d.ts +0 -4
  493. package/dist/packages/engine/agents/lib/args.js +0 -52
  494. package/dist/packages/engine/agents/lib/chart-guidance.d.ts +0 -1
  495. package/dist/packages/engine/agents/lib/chart-guidance.js +0 -8
  496. package/dist/packages/engine/agents/lib/constants.js +0 -28
  497. package/dist/packages/engine/agents/lib/logs.d.ts +0 -2
  498. package/dist/packages/engine/agents/lib/logs.js +0 -17
  499. package/dist/packages/engine/agents/lib/render.d.ts +0 -8
  500. package/dist/packages/engine/agents/lib/schema.d.ts +0 -8
  501. package/dist/packages/engine/agents/lib/schema.js +0 -7
  502. package/dist/packages/engine/agents/lib/shells.d.ts +0 -74
  503. package/dist/packages/engine/agents/lib/shells.js +0 -1052
  504. package/dist/packages/engine/agents/lib/verifiable-context-bootstrap.d.ts +0 -3
  505. package/dist/packages/engine/build/artifact-counts.d.ts +0 -1
  506. package/dist/packages/engine/build/billing-events.d.ts +0 -89
  507. package/dist/packages/engine/build/build-pipeline.js +0 -175
  508. package/dist/packages/engine/build/build-plan-runs.d.ts +0 -14
  509. package/dist/packages/engine/build/build-plan-runs.js +0 -31
  510. package/dist/packages/engine/build/build-stage-plan.d.ts +0 -16
  511. package/dist/packages/engine/build/build-stage-plan.js +0 -100
  512. package/dist/packages/engine/build/build-stage-runner.js +0 -94
  513. package/dist/packages/engine/build/build-target.js +0 -16
  514. package/dist/packages/engine/build/check-evaluator.js +0 -298
  515. package/dist/packages/engine/build/lib/schema.js +0 -316
  516. package/dist/packages/engine/build/reset.d.ts +0 -2
  517. package/dist/packages/engine/build/reset.js +0 -74
  518. package/dist/packages/engine/build/runtime-inventory.d.ts +0 -7
  519. package/dist/packages/engine/build/runtime-paths.d.ts +0 -8
  520. package/dist/packages/engine/build/runtime-paths.js +0 -26
  521. package/dist/packages/engine/build/runtime-runs.d.ts +0 -10
  522. package/dist/packages/engine/build/runtime-runs.js +0 -224
  523. package/dist/packages/engine/build/runtime.d.ts +0 -5
  524. package/dist/packages/engine/build/runtime.js +0 -4
  525. package/dist/packages/engine/build/source-files.d.ts +0 -46
  526. package/dist/packages/engine/build/source-files.js +0 -149
  527. package/dist/packages/engine/build/state-artifacts.d.ts +0 -9
  528. package/dist/packages/engine/build/state-artifacts.js +0 -14
  529. package/dist/packages/engine/build/state-health.d.ts +0 -4
  530. package/dist/packages/engine/build/state-io.d.ts +0 -11
  531. package/dist/packages/engine/build/state-io.js +0 -82
  532. package/dist/packages/engine/build/state-paths.d.ts +0 -5
  533. package/dist/packages/engine/build/state-paths.js +0 -16
  534. package/dist/packages/engine/build/state-view.d.ts +0 -5
  535. package/dist/packages/engine/build/state-view.js +0 -94
  536. package/dist/packages/engine/build/state.d.ts +0 -7
  537. package/dist/packages/engine/build/state.js +0 -12
  538. package/dist/packages/engine/build/validate-helpers.d.ts +0 -12
  539. package/dist/packages/engine/build/validate-helpers.js +0 -41
  540. package/dist/packages/engine/build/verifiable-context-paths.d.ts +0 -47
  541. package/dist/packages/engine/build/verifiable-context-paths.js +0 -121
  542. package/dist/packages/engine/build/verifiable-context-schema.d.ts +0 -21
  543. package/dist/packages/engine/build/verifiable-context-schema.js +0 -126
  544. package/dist/packages/engine/cloud-seams.d.ts +0 -115
  545. package/dist/packages/engine/cloud-seams.js +0 -84
  546. package/dist/packages/engine/index.d.ts +0 -22
  547. package/dist/packages/engine/index.js +0 -15
  548. package/dist/packages/engine/instance-paths.d.ts +0 -106
  549. package/dist/packages/engine/instance-paths.js +0 -171
  550. package/dist/packages/engine/lib/schema.d.ts +0 -6304
  551. package/dist/packages/engine/lib/schema.js +0 -730
  552. package/dist/packages/engine/native-run-handlers.d.ts +0 -25
  553. package/dist/packages/engine/preparation-store.d.ts +0 -105
  554. package/dist/packages/engine/preparation-store.js +0 -213
  555. package/dist/packages/engine/readiness-check-draft.d.ts +0 -20
  556. package/dist/packages/engine/readiness-check-draft.js +0 -111
  557. package/dist/packages/engine/requested-artifacts.d.ts +0 -5
  558. package/dist/packages/engine/routes.d.ts +0 -85
  559. package/dist/packages/engine/routes.js +0 -99
  560. package/dist/packages/engine/runtime-caches.d.ts +0 -76
  561. package/dist/packages/engine/runtime-caches.js +0 -191
  562. package/dist/packages/engine/runtime-proposal-helpers.d.ts +0 -35
  563. package/dist/packages/engine/runtime-proposal-helpers.js +0 -247
  564. package/dist/packages/engine/runtime.d.ts +0 -371
  565. package/dist/packages/engine/runtime.js +0 -2463
  566. package/dist/packages/engine/server.d.ts +0 -58
  567. package/dist/packages/engine/server.js +0 -1399
  568. package/dist/packages/engine/verify/readiness-check-run.d.ts +0 -82
  569. package/dist/packages/engine/verify/readiness-check-run.js +0 -265
  570. package/dist/packages/engine/verify/verify-paths.js +0 -61
  571. package/dist/packages/engine/verify/verify-sandbox.js +0 -88
  572. package/dist/packages/engine/verify/verify-specs.js +0 -114
  573. package/dist/packages/engine/verify/verify-targets.d.ts +0 -5
  574. package/dist/packages/engine/wire-schemas.d.ts +0 -547
  575. package/dist/packages/engine/wire-schemas.js +0 -59
  576. package/dist/packages/project/index.d.ts +0 -9
  577. package/dist/packages/project/interf-bootstrap.d.ts +0 -1
  578. package/dist/packages/project/interf-bootstrap.js +0 -1
  579. package/dist/packages/project/interf-scaffold.d.ts +0 -3
  580. package/dist/packages/project/interf-scaffold.js +0 -136
  581. package/dist/packages/project/interf.d.ts +0 -4
  582. package/dist/packages/project/interf.js +0 -3
  583. package/dist/packages/project/lib/schema.d.ts +0 -328
  584. package/dist/packages/project/lib/schema.js +0 -136
  585. package/dist/packages/project/preparation-entries.d.ts +0 -11
  586. package/dist/packages/project/preparation-entries.js +0 -49
  587. package/dist/packages/project/source-config.d.ts +0 -46
  588. package/dist/packages/project/source-config.js +0 -394
  589. package/dist/packages/project/source-folders.d.ts +0 -11
  590. package/public-repo/build-plans/interf-default/build/stages/shape/SKILL.md +0 -27
  591. package/public-repo/build-plans/interf-default/build/stages/structure/SKILL.md +0 -21
  592. package/public-repo/plugins/README.md +0 -9
  593. package/public-repo/plugins/interf/.claude-plugin/plugin.json +0 -21
  594. package/public-repo/plugins/interf/.mcp.json +0 -12
  595. package/public-repo/plugins/interf/README.md +0 -32
  596. package/public-repo/plugins/interf/skills/interf/SKILL.md +0 -376
  597. /package/dist/packages/{engine/agents/lib/types.js → runtime/actions/fields.js} +0 -0
  598. /package/dist/packages/{engine → runtime}/agents/lib/agents.d.ts +0 -0
  599. /package/dist/packages/{engine → runtime}/agents/lib/agents.js +0 -0
  600. /package/dist/packages/{engine → runtime}/agents/lib/execution.d.ts +0 -0
  601. /package/dist/packages/{engine → runtime}/agents/lib/preflight.d.ts +0 -0
  602. /package/dist/packages/{engine → runtime}/agents/lib/status.d.ts +0 -0
  603. /package/dist/packages/{engine/build/runtime-types.js → runtime/agents/lib/types.js} +0 -0
  604. /package/dist/packages/{engine/verify/verify-types.js → runtime/agents/providers/types.js} +0 -0
  605. /package/dist/packages/{engine → runtime}/agents/role-router.d.ts +0 -0
  606. /package/dist/packages/{engine → runtime}/build/build-execution.d.ts +0 -0
  607. /package/dist/packages/{engine → runtime}/build/build-execution.js +0 -0
  608. /package/dist/packages/{engine → runtime}/build/runtime-contracts.d.ts +0 -0
  609. /package/dist/packages/{engine → runtime}/build/runtime-prompt.d.ts +0 -0
  610. /package/dist/packages/{engine → runtime}/execution/adapters.d.ts +0 -0
  611. /package/dist/packages/{engine → runtime}/execution/adapters.js +0 -0
  612. /package/dist/packages/{engine → runtime}/execution/events.d.ts +0 -0
  613. /package/dist/packages/{engine → runtime}/execution/events.js +0 -0
  614. /package/dist/packages/{engine → runtime}/verify/verify-profile-presets.d.ts +0 -0
  615. /package/dist/packages/{engine → runtime}/verify/verify-profile-presets.js +0 -0
  616. /package/dist/packages/{engine → runtime}/verify/verify-types.d.ts +0 -0
@@ -1,52 +1,138 @@
1
1
  /**
2
- * `interf mcp` — Model Context Protocol server.
2
+ * Interf Model Context Protocol server.
3
3
  *
4
4
  * Wraps the local-service HTTP API as a typed agent surface so coding
5
5
  * agents can interact with Interf the same way they call other MCP tools
6
6
  * (instead of shelling out to the CLI).
7
7
  *
8
- * interf mcp # stdio transport (default)
9
- * interf mcp --transport=http --port=4889 # advanced: HTTP transport
8
+ * Packaged Desktop exposes this through `dist/bin-mcp.js`; the CLI subcommand
9
+ * is kept as a hidden developer entrypoint so tests and local hosts can launch
10
+ * the same adapter directly when needed.
10
11
  *
11
12
  * API-backed tools read `~/.interf/connection.json` (the same file every
12
- * other client uses) on each call. The MCP server can start before an
13
- * engine is connected so local plugin hosts such as Cowork can load the
14
- * tool surface first, then call `web_start` or `web_status`. The MCP
15
- * server itself holds no Interf runtime state. The transport options are
16
- * intentionally minimal agents speaking MCP today are stdio-first.
13
+ * other client uses) on each call. In the default headless profile, the
14
+ * MCP server can start before a local service is connected so local plugin hosts
15
+ * can load the tool surface first, then call `runtime_start` or `runtime_status`.
16
+ * In the app profile, lifecycle, inventory, admin, and library-browsing tools
17
+ * are hidden because Interf Desktop owns the running service and the user flow
18
+ * should stay preparation-first: create a Project for the current Source,
19
+ * draft a Build Plan, build a Context Graph, then inspect graph evidence.
20
+ * The MCP server itself holds no Interf runtime state.
17
21
  *
18
22
  * Tool list:
19
- * web_start shell out to `interf web start`
20
- * web_stop shell out to `interf web stop`
21
- * web_status shell out to `interf web status`
22
- * prep_list GET /v1/preparations
23
- * prep_create POST /v1/preparations
24
- * prep_show GET /v1/preparations/{id}
25
- * prep_select_build_plan PATCH /v1/preparations/{id}
26
- * prep_remove DELETE /v1/preparations/{id}
27
- * prep_build POST /v1/preparations/{id}/build-runs
28
- * prep_test POST /v1/preparations/{id}/verify-runs
29
- * build_plan_list GET /v1/build-plans
30
- * build_plan_draft POST /v1/preparations/{id}/build-plan-draft-runs
31
- * build_plan_improve POST /v1/preparations/{id}/build-plan-improvement-runs
32
- * runs_status GET /v1/runs/{run-id}
33
- * runs_watch GET /v1/build-runs/{run-id}/events (snapshot, not SSE)
34
- * runs_cancel POST /v1/build-runs/{run-id}/cancel
35
- * runs_fetch GET /v1/build-runs/{run-id}/artifacts
36
- * instance_status GET /v1/instance
23
+ * runtime_start shell out to `interf runtime start`
24
+ * runtime_stop shell out to `interf runtime stop`
25
+ * runtime_status shell out to `interf runtime status`
26
+ * Desktop app profile tools:
27
+ * create_project, prepare_build_plan, run_build
28
+ * get_instance_status, get_project, get_run_status, get_run_events, get_run_artifacts
29
+ * get_latest_context_graph, get_context_graph_entrypoint, read_context_graph_file
30
+ * get_context_graph_traces, get_context_graph_sessions, get_context_graph_session,
31
+ * get_build_evidence
32
+ *
33
+ * Headless developer profile additionally exposes runtime lifecycle,
34
+ * inventory, Build Plan library, benchmark, cancel, admin, full run event
35
+ * log (runs_events), and execution-session reads (context_graph_sessions,
36
+ * context_graph_session).
37
37
  */
38
38
  import { spawn } from "node:child_process";
39
39
  import { readFileSync } from "node:fs";
40
40
  import { z } from "zod";
41
41
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
42
42
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
43
- import { CONNECT_OR_ERROR_HINT, readActiveConnection, } from "../../packages/engine/connection-config.js";
44
- import { LOCAL_SERVICE_ROUTES, preparationResourcePath, preparationSubresourcePath, runResourcePath, } from "../../packages/engine/routes.js";
45
- import { BuildPlanAuthoringArtifactRequirementSchema, } from "../../packages/engine/lib/schema.js";
46
- import { RequestedArtifactSchema, SourceProfileSchema, } from "../../packages/project/lib/schema.js";
43
+ import { CONNECT_OR_ERROR_HINT, readActiveConnection, } from "../../packages/runtime/connection-config.js";
44
+ import { readServiceRegistry, } from "../../packages/runtime/service/service-registry.js";
45
+ import { callJson, } from "../lib/http-client.js";
46
+ import { slugify } from "../../packages/contracts/utils/naming.js";
47
+ import { LOCAL_SERVICE_ROUTES, buildPlanResourcePath, buildPlanSubresourcePath, projectResourcePath, projectSubresourcePath, runResourcePath, runSubresourcePath, } from "../../packages/runtime/service/routes.js";
48
+ import { BuildPlanAuthoringArtifactRequirementSchema, BuildPlanContextCheckDraftSchema, RequestedArtifactSchema, } from "../../packages/runtime/schemas/index.js";
49
+ import { ArtifactIdSchema, BuildPlanIdSchema, ProjectIdSchema, } from "../../packages/contracts/lib/schema.js";
50
+ import { SourceContextSchema, } from "../../packages/projects/lib/schema.js";
51
+ // ───────────────────────────────────────────────────────────────────────────
52
+ // MCP id input schemas. These reuse the contract ID schemas so the MCP surface
53
+ // accepts exactly the ids the runtime accepts — instead of a looser inline
54
+ // `z.string().min(1)` that would let MCP pass ids the runtime then rejects.
55
+ // `project_id`/`build_plan_id`/`artifact_id` carry the contract regex +
56
+ // reserved-id rules; `run_id`s are opaque underscore-bearing tokens the runtime
57
+ // mints (e.g. `build_<base36>_<base36>`), so there is no stricter contract
58
+ // schema for them — they stay `z.string().min(1)`, defined once here.
59
+ // ───────────────────────────────────────────────────────────────────────────
60
+ const McpProjectIdSchema = ProjectIdSchema.describe("Project id (kebab-case).");
61
+ const McpBuildPlanIdSchema = BuildPlanIdSchema.describe("Build Plan id (kebab-case).");
62
+ const McpArtifactIdSchema = ArtifactIdSchema.describe("Requested output id (kebab-case).");
63
+ const McpRunIdSchema = z.string().min(1).describe("Run id.");
64
+ const INTERF_MCP_INSTRUCTIONS = [
65
+ "WHAT INTERF IS",
66
+ "Interf prepares data for agents. It builds a task-specific Context Graph from a Source (the user's files) — claim nodes, entities, comparison nodes, timelines, coverage indexes — that any agent can read to answer. Source-of-truth stays in the user's files. Interf does NOT answer the user's question; it prepares the structured graph the agent reasons over.",
67
+ "",
68
+ "WHAT YOU PASS, WHAT YOU GET",
69
+ "You pass: the user's intent (the task the graph is for) and optional graph areas you want prepared. You get: a Context Graph the agent reads — home.md as entrypoint, knowledge/ for drilldown, summaries/ as source coverage, source-backed traces for exact values.",
70
+ "",
71
+ "THE WORKFLOW",
72
+ "1. create_project — bind the Source + intent.",
73
+ "2. prepare_build_plan — name the graph areas to prepare (e.g. 'NY rent forecast claim nodes', 'cost comparison nodes', 'decision timeline'). Show the draft to the user. Stop for approval unless they granted end-to-end autonomy.",
74
+ "3. run_build — only after approval. Wait for terminal state; do not auto-retry.",
75
+ "4. get_latest_context_graph — read primary_metrics + home.md, follow traces for exact values, then answer.",
76
+ "",
77
+ "REQUESTED OUTPUTS ARE GRAPH AREAS, NOT ANSWERS",
78
+ "Each requested output is a region of the Context Graph the next agent will traverse (claim nodes, comparison nodes, a timeline, a coverage index). Never name an output 'the answer markdown', 'final report', 'forecast summary', or 'recommended decision' — those replace agent thinking. The agent still reasons; Interf only prepares.",
79
+ "",
80
+ "SOURCING",
81
+ "If the host/user already provides a Source locator, use the whole Source. Don't ask the user to pick files. Don't browse existing Projects like a corpus — create a fresh Project per task unless the user explicitly names one. Project ids are auto-generated.",
82
+ "",
83
+ "EXECUTORS VS MCP",
84
+ "Interf MCP is how this host talks to Interf. The agents listed inside Interf are EXECUTORS that run Build Plan stages; that is a separate setup from this MCP connection.",
85
+ "",
86
+ "FAILURE HANDLING",
87
+ "If any Run fails with 'executor preflight' in the error, the active execution agent CLI is broken on this machine. Tell the user to switch with `interf agents use claude-code` (or another available executor). Do not retry, do not create a new Project. For any other failure, report it and ask before starting another draft or Build.",
88
+ ].join("\n");
89
+ const McpRequestedArtifactSchema = RequestedArtifactSchema.describe("A graph area Interf should prepare in the Context Graph — claim nodes, comparison nodes, a timeline, a coverage index. NOT the user's final answer and NOT a finished report. Each requested output is structured prepared data the NEXT agent will read and reason over. Good titles: 'NY rent forecast claims', 'Bristol vs London cost comparison nodes', 'Q3 decision-timeline signals'. Bad titles: 'NY rent growth answer', 'Final report', 'Forecast summary' — those replace agent thinking instead of preparing data for it. Source-of-truth stays in the user's files; Interf builds the task-specific Context Graph the agent reads.");
90
+ function normalizeRequestedArtifacts(artifacts) {
91
+ if (!artifacts)
92
+ return undefined;
93
+ return artifacts.map((artifact) => RequestedArtifactSchema.parse(artifact));
94
+ }
47
95
  function trimTrailingSlash(value) {
48
96
  return value.replace(/\/+$/, "");
49
97
  }
98
+ function normalizeConnectionUrl(value) {
99
+ return trimTrailingSlash(value.trim());
100
+ }
101
+ function registryTokenForUrl(url) {
102
+ const normalized = normalizeConnectionUrl(url);
103
+ for (const service of readServiceRegistry()) {
104
+ if (normalizeConnectionUrl(service.url) === normalized && service.auth_token) {
105
+ return service.auth_token;
106
+ }
107
+ }
108
+ return null;
109
+ }
110
+ function connectionTokenForUrl(url) {
111
+ const normalized = normalizeConnectionUrl(url);
112
+ const active = readActiveConnection();
113
+ if (!active)
114
+ return null;
115
+ return normalizeConnectionUrl(active.url) === normalized ? active.auth_token : null;
116
+ }
117
+ function encodeRelativePath(value) {
118
+ return value
119
+ .split("/")
120
+ .filter((segment) => segment.length > 0)
121
+ .map((segment) => encodeURIComponent(segment))
122
+ .join("/");
123
+ }
124
+ function contextGraphFilePath(projectId, filePath) {
125
+ return `${projectSubresourcePath(projectId, "contextGraphFile")}?path=${encodeURIComponent(filePath)}`;
126
+ }
127
+ // Exported for the slugify-equivalence regression test. The 18-char clamp keeps
128
+ // the generated base well inside `slugify`'s own 80-char cap, so swapping the
129
+ // former local `slugifyMcpId` (48-char cap) for the shared `slugify` is
130
+ // behavior-preserving for every input.
131
+ export function generatedMcpId(prefix) {
132
+ const base = slugify(prefix).slice(0, 18) || "item";
133
+ const suffix = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
134
+ return `${base}-${suffix}`;
135
+ }
50
136
  function packageVersionFromManifest() {
51
137
  try {
52
138
  const url = new URL("../../../package.json", import.meta.url);
@@ -58,15 +144,28 @@ function packageVersionFromManifest() {
58
144
  return "0.0.0";
59
145
  }
60
146
  }
147
+ // MCP intentionally does NOT use http-client's `resolveConnection`. That helper
148
+ // is the CLI contract: it `process.exit(1)`s when no connection is found, which
149
+ // is correct for a one-shot CLI command but fatal for a long-lived MCP server
150
+ // that must instead return a structured `CONNECT_OR_ERROR_HINT` tool error and
151
+ // stay up. MCP also adds a `--url`-override token discovery step (services.json
152
+ // registry, then the active connection) that the plain CLI override path does
153
+ // not perform. Until http-client exports a shared null-returning variant, this
154
+ // resolution stays here; the underlying `readActiveConnection` precedence is
155
+ // still single-sourced in connection-config.
61
156
  function resolveConnectionOrNull(args) {
157
+ const urlOverride = args.url?.trim();
158
+ const currentLocalToken = urlOverride
159
+ ? registryTokenForUrl(urlOverride) ?? connectionTokenForUrl(urlOverride)
160
+ : null;
62
161
  const conn = readActiveConnection({
63
- urlOverride: args.url ?? null,
64
- authTokenOverride: args.token ?? null,
162
+ urlOverride: urlOverride ?? null,
163
+ authTokenOverride: currentLocalToken ?? args.token ?? null,
65
164
  });
66
165
  if (!conn)
67
166
  return null;
68
167
  return {
69
- url: trimTrailingSlash(conn.url),
168
+ url: normalizeConnectionUrl(conn.url),
70
169
  token: conn.auth_token ?? null,
71
170
  };
72
171
  }
@@ -108,25 +207,12 @@ function runInterfCli(args) {
108
207
  });
109
208
  });
110
209
  }
111
- async function callApi(conn, path, init = {}) {
112
- const headers = new Headers(init.headers ?? {});
113
- if (conn.token)
114
- headers.set("authorization", `Bearer ${conn.token}`);
115
- if (init.body && !headers.has("content-type")) {
116
- headers.set("content-type", "application/json");
117
- }
118
- const response = await fetch(`${conn.url}${path}`, { ...init, headers });
119
- const raw = await response.text();
120
- let body = null;
121
- if (raw.length > 0) {
122
- try {
123
- body = JSON.parse(raw);
124
- }
125
- catch {
126
- body = raw;
127
- }
128
- }
129
- return { status: response.status, body, raw };
210
+ // MCP issues every API call through the shared CLI `callJson` (header-setting +
211
+ // JSON parsing live solely in http-client). `callJson` yields `body: null` on a
212
+ // non-JSON body (vs the former local `callApi`'s `body = raw`); every read site
213
+ // goes through `body ?? raw` or an `isRecord(body)` guard, so behavior holds.
214
+ function mcpApi(conn, path, init = {}) {
215
+ return callJson(`${conn.url}${path}`, conn.token, init);
130
216
  }
131
217
  function toolResultJson(payload) {
132
218
  const text = typeof payload === "string"
@@ -158,268 +244,795 @@ async function callAndReturn(args, path, init = {}) {
158
244
  const conn = resolveConnectionOrNull(args);
159
245
  if (!conn)
160
246
  return toolErrorJson(CONNECT_OR_ERROR_HINT);
161
- const response = await callApi(conn, path, init);
247
+ const response = await mcpApi(conn, path, init);
162
248
  if (response.status >= 200 && response.status < 300) {
163
249
  return toolResultJson(response.body ?? response.raw);
164
250
  }
165
251
  return toolErrorJson(`Local service responded with HTTP ${response.status}.`, response.body ?? response.raw);
166
252
  }
167
- function registerTools(server, connectionArgs) {
168
- // ── Local engine lifecycle ─────────────────────────────────────────────
169
- server.registerTool("web_start", {
170
- title: "Start local Interf engine",
171
- description: "Start the Interf engine in the background on the user's machine. "
172
- + "Use this when no Interf instance is connected yet.",
173
- inputSchema: {
174
- host: z.string().min(1).optional().describe("Host to bind. Defaults to 127.0.0.1."),
175
- port: z.number().int().positive().optional().describe("Port to bind. Defaults to 4873."),
176
- timeout_ms: z.number().int().positive().optional().describe("Startup timeout in milliseconds."),
177
- log: z.string().min(1).optional().describe("Optional path for background engine logs."),
178
- },
179
- }, async (args) => {
180
- const cliArgs = ["web", "start"];
181
- if (args.host)
182
- cliArgs.push("--host", args.host);
183
- if (args.port)
184
- cliArgs.push("--port", String(args.port));
185
- if (args.timeout_ms)
186
- cliArgs.push("--timeout-ms", String(args.timeout_ms));
187
- if (args.log)
188
- cliArgs.push("--log", args.log);
189
- return cliToolResult(await runInterfCli(cliArgs));
190
- });
191
- server.registerTool("web_stop", {
192
- title: "Stop local Interf engine",
193
- description: "Stop the connected Interf engine or the live engine recorded in the "
194
- + "local service registry.",
195
- inputSchema: {
196
- url: z.string().url().optional().describe("Optional engine URL to stop."),
197
- token: z.string().min(1).optional().describe("Optional bearer token."),
198
- },
199
- }, async (args) => {
200
- const cliArgs = ["web", "stop"];
201
- if (args.url)
202
- cliArgs.push("--url", args.url);
203
- if (args.token)
204
- cliArgs.push("--token", args.token);
205
- return cliToolResult(await runInterfCli(cliArgs));
206
- });
207
- server.registerTool("web_status", {
208
- title: "Show local Interf engine status",
209
- description: "Return the connected engine status using the same connection record "
210
- + "as the CLI.",
211
- inputSchema: {
212
- url: z.string().url().optional().describe("Optional engine URL."),
213
- token: z.string().min(1).optional().describe("Optional bearer token."),
214
- },
215
- }, async (args) => {
216
- const cliArgs = ["web", "status"];
217
- if (args.url)
218
- cliArgs.push("--url", args.url);
219
- if (args.token)
220
- cliArgs.push("--token", args.token);
221
- return cliToolResult(await runInterfCli(cliArgs));
253
+ async function callAndProject(args, path, project, init = {}) {
254
+ const conn = resolveConnectionOrNull(args);
255
+ if (!conn)
256
+ return toolErrorJson(CONNECT_OR_ERROR_HINT);
257
+ const response = await mcpApi(conn, path, init);
258
+ if (response.status >= 200 && response.status < 300) {
259
+ return toolResultJson(project(response.body, response.raw));
260
+ }
261
+ return toolErrorJson(`Local service responded with HTTP ${response.status}.`, response.body ?? response.raw);
262
+ }
263
+ function isRecord(value) {
264
+ return typeof value === "object" && value !== null && !Array.isArray(value);
265
+ }
266
+ function readString(record, key) {
267
+ const value = record[key];
268
+ return typeof value === "string" && value.length > 0 ? value : null;
269
+ }
270
+ function readNumber(record, key) {
271
+ const value = record[key];
272
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
273
+ }
274
+ function readArray(record, key) {
275
+ const value = record[key];
276
+ return Array.isArray(value) ? value : [];
277
+ }
278
+ function truncateText(value, max = 360) {
279
+ if (value.length <= max)
280
+ return value;
281
+ return `${value.slice(0, Math.max(0, max - 1))}…`;
282
+ }
283
+ function summarizeMetrics(metrics) {
284
+ return metrics
285
+ .filter(isRecord)
286
+ .map((metric) => ({
287
+ label: readString(metric, "label") ?? "",
288
+ value: String(metric.value ?? ""),
289
+ }))
290
+ .filter((metric) => metric.label.length > 0 && metric.value.length > 0)
291
+ .slice(0, 12);
292
+ }
293
+ function summarizeCollection(items) {
294
+ const statuses = {};
295
+ for (const item of items) {
296
+ if (!isRecord(item))
297
+ continue;
298
+ const status = readString(item, "status");
299
+ if (status)
300
+ statuses[status] = (statuses[status] ?? 0) + 1;
301
+ }
302
+ return {
303
+ total: items.length,
304
+ ...(Object.keys(statuses).length > 0 ? { statuses } : {}),
305
+ };
306
+ }
307
+ function summarizeReadiness(value) {
308
+ if (!isRecord(value))
309
+ return null;
310
+ return {
311
+ status: readString(value, "status"),
312
+ ready: value.ready === true ? true : value.ready === false ? false : undefined,
313
+ checks_passed: readNumber(value, "checks_passed"),
314
+ checks_total: readNumber(value, "checks_total"),
315
+ };
316
+ }
317
+ function summarizeTraceEvent(event) {
318
+ if (!isRecord(event))
319
+ return null;
320
+ const eventData = isRecord(event.eventData) ? event.eventData : {};
321
+ const result = isRecord(eventData.result) ? eventData.result : {};
322
+ const error = isRecord(eventData.error) ? eventData.error : {};
323
+ return {
324
+ event_id: readString(event, "eventId"),
325
+ type: readString(event, "eventType"),
326
+ correlation_id: readString(event, "correlationId"),
327
+ created_at: readString(event, "createdAt"),
328
+ message: readString(eventData, "message") ?? readString(result, "summary") ?? readString(error, "message"),
329
+ };
330
+ }
331
+ function compactTraceStream(stream) {
332
+ if (!isRecord(stream))
333
+ return null;
334
+ const text = readString(stream, "text");
335
+ if (!text)
336
+ return null;
337
+ return {
338
+ stream_id: readString(stream, "streamId"),
339
+ chunk_id: readString(stream, "chunkId"),
340
+ index: readNumber(stream, "index"),
341
+ created_at: readString(stream, "createdAt"),
342
+ text: truncateText(text),
343
+ };
344
+ }
345
+ function latestTraceStream(streams) {
346
+ for (let index = streams.length - 1; index >= 0; index -= 1) {
347
+ const compact = compactTraceStream(streams[index]);
348
+ if (compact)
349
+ return compact;
350
+ }
351
+ return null;
352
+ }
353
+ function compactRunStatus(payload) {
354
+ if (!isRecord(payload))
355
+ return payload;
356
+ const trace = isRecord(payload.trace) ? payload.trace : {};
357
+ const events = readArray(trace, "events");
358
+ const streams = readArray(trace, "streams");
359
+ return {
360
+ kind: "interf-run-status",
361
+ version: 1,
362
+ run_id: readString(payload, "run_id"),
363
+ run_type: readString(payload, "run_type"),
364
+ title: readString(payload, "title"),
365
+ status: readString(payload, "status"),
366
+ project: readString(payload, "project"),
367
+ build_plan: readString(payload, "build_plan"),
368
+ created_at: readString(payload, "created_at"),
369
+ started_at: readString(payload, "started_at"),
370
+ finished_at: readString(payload, "finished_at"),
371
+ metrics: summarizeMetrics(readArray(payload, "metrics")),
372
+ artifacts: summarizeCollection(readArray(payload, "artifacts")),
373
+ checks: summarizeCollection(readArray(payload, "checks")),
374
+ context_checks: summarizeCollection(readArray(payload, "context_checks")),
375
+ readiness: summarizeReadiness(payload.readiness),
376
+ latest_event: events.length > 0 ? summarizeTraceEvent(events[events.length - 1]) : null,
377
+ latest_log: latestTraceStream(streams),
378
+ detail_hint: "Poll this compact status until terminal. If status is failed or cancelled, report it and ask before retrying; use event/log and artifact tools only when debugging or reading finished outputs.",
379
+ };
380
+ }
381
+ function compactRunEvents(payload, options) {
382
+ if (!isRecord(payload))
383
+ return payload;
384
+ const trace = isRecord(payload.trace) ? payload.trace : {};
385
+ const events = readArray(trace, "events");
386
+ const streams = readArray(trace, "streams");
387
+ const recentEvents = events
388
+ .slice(Math.max(0, events.length - options.eventLimit))
389
+ .map(summarizeTraceEvent)
390
+ .filter((event) => event !== null);
391
+ const recentStreams = options.includeStreams
392
+ ? streams
393
+ .slice(Math.max(0, streams.length - options.streamLimit))
394
+ .map(compactTraceStream)
395
+ .filter((stream) => stream !== null)
396
+ : undefined;
397
+ return {
398
+ kind: "interf-run-events",
399
+ version: 1,
400
+ run_id: readString(payload, "run_id"),
401
+ status: readString(payload, "status"),
402
+ event_count: events.length,
403
+ stream_count: streams.length,
404
+ events: recentEvents,
405
+ ...(recentStreams ? { streams: recentStreams } : {}),
406
+ detail_hint: "This is a bounded tail. Use a larger limit only when debugging; use compact run status for polling.",
407
+ };
408
+ }
409
+ async function currentSourcePathForApp(conn) {
410
+ const response = await mcpApi(conn, LOCAL_SERVICE_ROUTES.health);
411
+ if (response.status >= 200 && response.status < 300 && isRecord(response.body)) {
412
+ const sourcePath = readString(response.body, "source_folder_path");
413
+ if (sourcePath)
414
+ return sourcePath;
415
+ }
416
+ const sourceCandidates = await sourceCandidatesForApp(conn);
417
+ return sourceCandidates.length === 1 ? sourceCandidates[0]?.source_path ?? null : null;
418
+ }
419
+ async function sourceCandidatesForApp(conn) {
420
+ const response = await mcpApi(conn, LOCAL_SERVICE_ROUTES.projects);
421
+ if (response.status < 200 || response.status >= 300 || !isRecord(response.body))
422
+ return [];
423
+ const bySource = new Map();
424
+ for (const project of readArray(response.body, "projects").filter(isRecord)) {
425
+ const source = isRecord(project.source) ? project.source : {};
426
+ const sourcePath = readString(source, "locator");
427
+ if (!sourcePath)
428
+ continue;
429
+ const entry = bySource.get(sourcePath) ?? { count: 0, buildPlanIds: new Set() };
430
+ entry.count += 1;
431
+ const buildPlanId = readString(project, "build_plan_id");
432
+ if (buildPlanId)
433
+ entry.buildPlanIds.add(buildPlanId);
434
+ bySource.set(sourcePath, entry);
435
+ }
436
+ return [...bySource.entries()]
437
+ .map(([sourcePath, entry]) => ({
438
+ source_path: sourcePath,
439
+ project_count: entry.count,
440
+ build_plan_ids: [...entry.buildPlanIds].slice(0, 4),
441
+ }))
442
+ .slice(0, 8);
443
+ }
444
+ async function callAppCreateProject(args, request) {
445
+ const conn = resolveConnectionOrNull(args);
446
+ if (!conn)
447
+ return toolErrorJson(CONNECT_OR_ERROR_HINT);
448
+ const sourcePath = request.source_path?.trim() || await currentSourcePathForApp(conn);
449
+ if (!sourcePath) {
450
+ const sourceCandidates = await sourceCandidatesForApp(conn);
451
+ return toolErrorJson("No unambiguous current Source locator is exposed by Interf. If source_candidates contains a Source that clearly matches the user's task, call create_project again with that source_path. Otherwise ask for one Source locator. Do not ask for an existing Project id or ask the user to choose individual files.", { source_candidates: sourceCandidates });
452
+ }
453
+ const id = generatedMcpId("project");
454
+ const intent = request.intent.trim();
455
+ const response = await mcpApi(conn, LOCAL_SERVICE_ROUTES.projects, {
456
+ method: "POST",
457
+ body: JSON.stringify({
458
+ id,
459
+ intent,
460
+ source: { kind: "local-folder", locator: sourcePath },
461
+ }),
222
462
  });
223
- // ── Preparations ────────────────────────────────────────────────────────
224
- server.registerTool("prep_list", {
225
- title: "List preparations",
226
- description: "List every Preparation registered on the connected Interf instance, "
227
- + "with source binding, Build Plan id, and current readiness.",
463
+ if (response.status >= 200 && response.status < 300) {
464
+ return toolResultJson(response.body ?? response.raw);
465
+ }
466
+ return toolErrorJson(`Local service responded with HTTP ${response.status}.`, response.body ?? response.raw);
467
+ }
468
+ function registerAppProfileTools(server, connectionArgs) {
469
+ server.registerTool("create_project", {
470
+ title: "Create Project",
471
+ description: "Workflow step 1. Bind the current Source + the user's intent (the task the Context Graph is for). Project id is auto-generated.",
472
+ inputSchema: {
473
+ intent: z.string().min(1).describe("The task the Context Graph must support — e.g. 'compare NY effective vs blended rent growth for 2026'."),
474
+ source_path: z.string().min(1).optional().describe("Fallback Source locator (absolute folder path on local Desktop). Pass only when Interf does not expose a current Source."),
475
+ },
476
+ }, async (args) => callAppCreateProject(connectionArgs, args));
477
+ server.registerTool("prepare_build_plan", {
478
+ title: "Prepare Build Plan",
479
+ description: "Workflow step 2. Draft the Build Plan from the Project intent + requested graph areas. Stop after this tool and show the draft for user approval (see top-level instructions for failure handling).",
480
+ inputSchema: {
481
+ project_id: McpProjectIdSchema.describe("Project id from create_project."),
482
+ build_plan_id: McpBuildPlanIdSchema.optional().describe("Optional Build Plan id. Omit to auto-generate."),
483
+ label: z.string().min(1).optional().describe("Optional short human label."),
484
+ hint: z.string().min(1).optional().describe("Optional one-line plan hint."),
485
+ intent: z.string().min(1).optional().describe("Question/task the Context Graph must support. Omit to use the Project intent."),
486
+ context_checks: z.array(BuildPlanContextCheckDraftSchema).optional().describe("Optional legacy plain-English checks. Prefer Project intent plus requested outputs and coverage expectations."),
487
+ requested_artifacts: z.array(McpRequestedArtifactSchema).optional().describe("Requested outputs the user approved."),
488
+ source_context: SourceContextSchema.nullable().optional(),
489
+ },
490
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildPlanDraftRuns"), {
491
+ method: "POST",
492
+ body: JSON.stringify((() => {
493
+ const intent = args.intent?.trim();
494
+ const buildPlanId = args.build_plan_id?.trim() || generatedMcpId("plan");
495
+ return {
496
+ build_plan_id: buildPlanId,
497
+ label: args.label?.trim() || buildPlanId,
498
+ hint: args.hint?.trim() || intent || `Build Plan for Project ${args.project_id}`,
499
+ ...(intent ? { intent } : {}),
500
+ ...(args.context_checks ? { checks: args.context_checks } : {}),
501
+ ...(args.requested_artifacts ? { requested_artifacts: normalizeRequestedArtifacts(args.requested_artifacts) } : {}),
502
+ ...(args.source_context !== undefined ? { source_context: args.source_context } : {}),
503
+ };
504
+ })()),
505
+ }));
506
+ server.registerTool("run_build", {
507
+ title: "Run Build",
508
+ description: "Workflow step 3. Run the approved Build Plan and build the Context Graph. Only call after explicit Build Plan approval or explicit end-to-end autonomy. See top-level instructions for failure handling.",
509
+ inputSchema: {
510
+ project_id: McpProjectIdSchema.describe("Project id from create_project."),
511
+ },
512
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildRuns"), { method: "POST", body: "{}" }));
513
+ server.registerTool("get_instance_status", {
514
+ title: "Get Instance Status",
515
+ description: "Read-only helper. Check service health, current Source, active runs, and instance metadata. Not for Project search.",
228
516
  inputSchema: {},
229
- }, async () => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.preparations));
230
- server.registerTool("prep_create", {
231
- title: "Create a preparation",
232
- description: "Create a new Preparation. The Preparation binds a Source, "
233
- + "agent intent, requested Artifacts, and optional Build Plan.",
517
+ }, async () => {
518
+ const conn = resolveConnectionOrNull(connectionArgs);
519
+ if (!conn)
520
+ return toolErrorJson(CONNECT_OR_ERROR_HINT);
521
+ const [health, instance, sourceCandidates] = await Promise.all([
522
+ mcpApi(conn, LOCAL_SERVICE_ROUTES.health),
523
+ mcpApi(conn, LOCAL_SERVICE_ROUTES.instance),
524
+ sourceCandidatesForApp(conn),
525
+ ]);
526
+ if (health.status < 200 || health.status >= 300) {
527
+ return toolErrorJson(`Health responded with HTTP ${health.status}.`, health.body ?? health.raw);
528
+ }
529
+ if (instance.status < 200 || instance.status >= 300) {
530
+ return toolErrorJson(`Instance responded with HTTP ${instance.status}.`, instance.body ?? instance.raw);
531
+ }
532
+ const healthBody = isRecord(health.body) ? health.body : {};
533
+ const instanceBody = isRecord(instance.body) ? instance.body : {};
534
+ const healthSource = readString(healthBody, "source_folder_path");
535
+ const sourcePath = healthSource ?? (sourceCandidates.length === 1 ? sourceCandidates[0]?.source_path ?? null : null);
536
+ return toolResultJson({
537
+ kind: "interf-mcp-status",
538
+ version: 1,
539
+ service_url: readString(healthBody, "service_url") ?? readString(instanceBody, "url"),
540
+ source_path: sourcePath,
541
+ project_count: readNumber(instanceBody, "project_count"),
542
+ active_run_count: readNumber(instanceBody, "active_run_count"),
543
+ agent_count: readNumber(instanceBody, "agent_count"),
544
+ default_agent: readString(instanceBody, "default_agent"),
545
+ source_candidates: sourceCandidates,
546
+ instruction: "For a new file question: use the whole current Source, create_project -> prepare_build_plan -> ask user to review/approve the Build Plan -> run_build -> get_latest_context_graph. If source_path is null but source_candidates has a Source that clearly matches the user's task, pass that source_path to create_project. Do not ask which files inside the Source to use unless the user explicitly narrows scope.",
547
+ });
548
+ });
549
+ server.registerTool("get_project", {
550
+ title: "Get Project",
551
+ description: "Read-only helper. Confirm one Project's Source binding, selected Build Plan, readiness, and latest Context Graph.",
234
552
  inputSchema: {
235
- id: z.string().min(1).describe("Preparation id (kebab-case)."),
553
+ project_id: McpProjectIdSchema,
554
+ },
555
+ }, async (args) => callAndReturn(connectionArgs, projectResourcePath(args.project_id)));
556
+ server.registerTool("get_project_readiness", {
557
+ title: "Get Project Readiness",
558
+ description: "Read-only helper. Return ready/not ready for the latest Context Graph against the Project intent.",
559
+ inputSchema: {
560
+ project_id: McpProjectIdSchema,
561
+ },
562
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "readiness")));
563
+ server.registerTool("get_run_status", {
564
+ title: "Get Run Status",
565
+ description: "Read-only helper. Compact polling receipt for one Run. Use this for repeated status checks.",
566
+ inputSchema: {
567
+ run_id: McpRunIdSchema,
568
+ },
569
+ }, async (args) => callAndProject(connectionArgs, runSubresourcePath(args.run_id, "status"), compactRunStatus));
570
+ server.registerTool("get_run_artifacts", {
571
+ title: "Get Run Outputs",
572
+ description: "Read-only helper. Fetch a finished Run's artifact manifest only when status is terminal or when reviewing a completed Build Plan draft.",
573
+ inputSchema: {
574
+ run_id: McpRunIdSchema,
575
+ },
576
+ }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.runs}/${encodeURIComponent(args.run_id)}/artifacts`));
577
+ server.registerTool("get_latest_context_graph", {
578
+ title: "Get Latest Context Graph",
579
+ description: "Read-only helper. Show the latest Context Graph locator, GraphManifest, primary metrics, entrypoints, and readiness for a Project. Start from home.md next.",
580
+ inputSchema: {
581
+ project_id: McpProjectIdSchema,
582
+ },
583
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraph")));
584
+ server.registerTool("get_context_graph_entrypoint", {
585
+ title: "Get Graph Entrypoint",
586
+ description: "Read-only helper. Return the downstream agent entrypoint for the latest Context Graph. Start from home.md, then follow entrypoint links when useful.",
587
+ inputSchema: {
588
+ project_id: McpProjectIdSchema,
589
+ },
590
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraphEntrypoint")));
591
+ server.registerTool("read_context_graph_file", {
592
+ title: "Read Context Graph File",
593
+ description: "Read one prepared Context Graph file by relative path. Start with home.md; use summaries/ for coverage and knowledge/ for drilldown.",
594
+ inputSchema: {
595
+ project_id: McpProjectIdSchema,
596
+ path: z.string().min(1).describe("Relative path inside the Context Graph."),
597
+ },
598
+ }, async (args) => callAndReturn(connectionArgs, contextGraphFilePath(args.project_id, args.path)));
599
+ server.registerTool("get_context_graph_traces", {
600
+ title: "Get Context Graph Traces",
601
+ description: "Read-only helper. Read source-backed traces for exact values and provenance.",
602
+ inputSchema: {
603
+ project_id: McpProjectIdSchema,
604
+ },
605
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "traces")));
606
+ server.registerTool("get_context_graph_sessions", {
607
+ title: "Get Context Graph Execution Sessions",
608
+ description: "Read-only helper. List the per-stage execution shell sessions for the latest Build run — executor + model, status, attempt, validation attempts, and replay readiness. Pull these to drive the next self-improvement iteration when a stage was weak or failed.",
609
+ inputSchema: {
610
+ project_id: McpProjectIdSchema,
611
+ },
612
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraphSessions")));
613
+ server.registerTool("get_context_graph_session", {
614
+ title: "Get One Context Graph Execution Session",
615
+ description: "Read-only helper. Return one preserved execution shell session by stage_run_id — prompt, event/status log paths, runtime files, artifact mounts, validation attempts, and the terminal verdict. Use it to inspect or replay exactly what a stage attempt did.",
616
+ inputSchema: {
617
+ project_id: McpProjectIdSchema,
618
+ stage_run_id: z.string().min(1).describe("Stage execution session id (stage_run_id) from get_context_graph_sessions."),
619
+ },
620
+ }, async (args) => callAndReturn(connectionArgs, `${projectSubresourcePath(args.project_id, "contextGraphSessions")}/${encodeURIComponent(args.stage_run_id)}`));
621
+ server.registerTool("get_run_events", {
622
+ title: "Get Run Events",
623
+ description: "Read-only helper. Read the durable event log for a Build run: stage start/pass/fail, files processed, artifacts written, evidence, checks, and readiness. Poll get_run_status for progress; read events to inspect or replay what happened.",
624
+ inputSchema: {
625
+ run_id: McpRunIdSchema,
626
+ },
627
+ }, async (args) => callAndReturn(connectionArgs, runSubresourcePath(args.run_id, "events")));
628
+ server.registerTool("get_build_evidence", {
629
+ title: "Get Supplemental Build Diagnostics",
630
+ description: "Read-only helper. Read supplemental diagnostics. Prefer get_latest_context_graph for primary coverage metrics and readiness.",
631
+ inputSchema: {
632
+ project_id: McpProjectIdSchema,
633
+ },
634
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildEvidence")));
635
+ }
636
+ function registerTools(server, connectionArgs) {
637
+ const appProfile = (connectionArgs.profile ?? "headless") === "app";
638
+ if (appProfile) {
639
+ registerAppProfileTools(server, connectionArgs);
640
+ return;
641
+ }
642
+ // ── Local service lifecycle ────────────────────────────────────────────
643
+ if (!appProfile) {
644
+ server.registerTool("runtime_start", {
645
+ title: "Start local Interf service",
646
+ description: "Start the Interf local service in the background on the user's machine. "
647
+ + "Use this when no Interf instance is connected yet.",
648
+ inputSchema: {
649
+ host: z.string().min(1).optional().describe("Host to bind. Defaults to 127.0.0.1."),
650
+ port: z.number().int().positive().optional().describe("Port to bind. Defaults to 4873."),
651
+ timeout_ms: z.number().int().positive().optional().describe("Startup timeout in milliseconds."),
652
+ log: z.string().min(1).optional().describe("Optional path for background service logs."),
653
+ },
654
+ }, async (args) => {
655
+ const cliArgs = ["runtime", "start"];
656
+ if (args.host)
657
+ cliArgs.push("--host", args.host);
658
+ if (args.port)
659
+ cliArgs.push("--port", String(args.port));
660
+ if (args.timeout_ms)
661
+ cliArgs.push("--timeout-ms", String(args.timeout_ms));
662
+ if (args.log)
663
+ cliArgs.push("--log", args.log);
664
+ return cliToolResult(await runInterfCli(cliArgs));
665
+ });
666
+ server.registerTool("runtime_stop", {
667
+ title: "Stop local Interf service",
668
+ description: "Stop the connected Interf local service or the live service recorded in the "
669
+ + "local service registry.",
670
+ inputSchema: {
671
+ url: z.string().url().optional().describe("Optional service URL to stop."),
672
+ token: z.string().min(1).optional().describe("Optional bearer token."),
673
+ },
674
+ }, async (args) => {
675
+ const cliArgs = ["runtime", "stop"];
676
+ if (args.url)
677
+ cliArgs.push("--url", args.url);
678
+ if (args.token)
679
+ cliArgs.push("--token", args.token);
680
+ return cliToolResult(await runInterfCli(cliArgs));
681
+ });
682
+ server.registerTool("runtime_status", {
683
+ title: "Show local Interf service status",
684
+ description: "Return the connected service status using the same connection record "
685
+ + "as the CLI.",
686
+ inputSchema: {
687
+ url: z.string().url().optional().describe("Optional service URL."),
688
+ token: z.string().min(1).optional().describe("Optional bearer token."),
689
+ },
690
+ }, async (args) => {
691
+ const cliArgs = ["runtime", "status"];
692
+ if (args.url)
693
+ cliArgs.push("--url", args.url);
694
+ if (args.token)
695
+ cliArgs.push("--token", args.token);
696
+ return cliToolResult(await runInterfCli(cliArgs));
697
+ });
698
+ }
699
+ // ── Projects ────────────────────────────────────────────────────────────
700
+ if (!appProfile) {
701
+ server.registerTool("project_list", {
702
+ title: "List Projects",
703
+ description: "Developer inventory tool. Do not use this as search over a corpus. "
704
+ + "For user questions over files, create a Project for the current Source unless the user names an existing Project.",
705
+ inputSchema: {},
706
+ }, async () => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.projects));
707
+ }
708
+ server.registerTool("project_create", {
709
+ title: "Create a Project",
710
+ description: "Create a Project for the user's current Source. In the Desktop app profile, this is normally "
711
+ + "the first Interf action for a new user question over files.",
712
+ inputSchema: {
713
+ id: McpProjectIdSchema,
714
+ intent: z.string().min(1).describe("Agent task this Project's Context Graph should support."),
236
715
  source_path: z.string().min(1).describe("Source path visible to the connected instance."),
237
- build_plan_id: z.string().min(1).optional().describe("Optional Build Plan id to select. Select later with prep_select_build_plan if omitted."),
238
- about: z.string().min(1).optional().describe("Optional human-readable description."),
239
- requested_artifacts: z.array(RequestedArtifactSchema).optional().describe("Requested Artifacts the agent/user confirmed for this Preparation."),
240
- source_profile: SourceProfileSchema.optional().describe("Advisory source profile from the agent's inspection before build."),
716
+ ...(!appProfile
717
+ ? {
718
+ build_plan_id: McpBuildPlanIdSchema.optional().describe("Optional Build Plan id to select."),
719
+ }
720
+ : {}),
241
721
  },
242
- }, async (args) => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.preparations, {
722
+ }, async (args) => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.projects, {
243
723
  method: "POST",
244
724
  body: JSON.stringify({
245
725
  id: args.id,
726
+ intent: args.intent,
246
727
  source: { kind: "local-folder", locator: args.source_path },
247
728
  ...(args.build_plan_id ? { build_plan_id: args.build_plan_id } : {}),
248
- ...(args.about ? { about: args.about } : {}),
249
- ...(args.requested_artifacts ? { requested_artifacts: args.requested_artifacts } : {}),
250
- ...(args.source_profile ? { source_profile: args.source_profile } : {}),
251
729
  }),
252
730
  }));
253
- server.registerTool("prep_show", {
254
- title: "Show one preparation",
255
- description: "Return the full resource for one Preparation by id.",
731
+ server.registerTool("project_show", {
732
+ title: "Show one Project",
733
+ description: "Return one Project resource to confirm its Source binding, selected Build Plan, readiness, "
734
+ + "and latest Context Graph before deciding whether it matches the current task.",
256
735
  inputSchema: {
257
- id: z.string().min(1).describe("Preparation id."),
736
+ id: McpProjectIdSchema,
258
737
  },
259
- }, async (args) => callAndReturn(connectionArgs, preparationResourcePath(args.id)));
260
- server.registerTool("prep_select_build_plan", {
261
- title: "Select a Build Plan for a Preparation",
262
- description: "Update the selected Build Plan on a Preparation. Use this to swap "
263
- + "Build Plans between Build runs without rebuilding the Preparation.",
738
+ }, async (args) => callAndReturn(connectionArgs, projectResourcePath(args.id)));
739
+ server.registerTool("project_readiness", {
740
+ title: "Read Project readiness",
741
+ description: "Return the ready/not ready status for this Project's latest Context Graph against the Project intent.",
264
742
  inputSchema: {
265
- id: z.string().min(1).describe("Preparation id."),
266
- build_plan_id: z.string().min(1).describe("Build Plan id to use."),
743
+ id: McpProjectIdSchema,
267
744
  },
268
- }, async (args) => callAndReturn(connectionArgs, preparationResourcePath(args.id), {
269
- method: "PATCH",
270
- body: JSON.stringify({ build_plan_id: args.build_plan_id }),
271
- }));
272
- server.registerTool("prep_remove", {
273
- title: "Remove a preparation",
274
- description: "Delete a Preparation. Verifiable context is removed too.",
745
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.id, "readiness")));
746
+ if (!appProfile) {
747
+ server.registerTool("project_select_build_plan", {
748
+ title: "Select a Build Plan for a Project",
749
+ description: "Developer/admin tool. Update the selected Build Plan on a Project. "
750
+ + "Build Plan draft/improve runs select their resulting Plan automatically.",
751
+ inputSchema: {
752
+ id: McpProjectIdSchema,
753
+ build_plan_id: McpBuildPlanIdSchema.describe("Build Plan id to use."),
754
+ },
755
+ }, async (args) => callAndReturn(connectionArgs, projectResourcePath(args.id), {
756
+ method: "PATCH",
757
+ body: JSON.stringify({ build_plan_id: args.build_plan_id }),
758
+ }));
759
+ server.registerTool("project_remove", {
760
+ title: "Remove a Project",
761
+ description: "Developer/admin tool. Delete a Project and its Context Graph.",
762
+ inputSchema: {
763
+ id: McpProjectIdSchema,
764
+ },
765
+ }, async (args) => callAndReturn(connectionArgs, projectResourcePath(args.id), {
766
+ method: "DELETE",
767
+ }));
768
+ }
769
+ // ── Build + benchmark/evaluation runs ────────────────────────────
770
+ server.registerTool("project_build", {
771
+ title: "Build Context Graph",
772
+ description: "Run the selected Build Plan for a Project and write a task-specific Context Graph. "
773
+ + "Use this only after the user has approved the coverage expectations, requested outputs, and Build Plan, "
774
+ + "unless they explicitly granted autonomy. Returns immediately; poll with runs_status.",
275
775
  inputSchema: {
276
- id: z.string().min(1).describe("Preparation id."),
776
+ id: McpProjectIdSchema,
277
777
  },
278
- }, async (args) => callAndReturn(connectionArgs, preparationResourcePath(args.id), {
279
- method: "DELETE",
280
- }));
281
- // ── Build + readiness-check runs ───────────────────────────────────────
282
- server.registerTool("prep_build", {
283
- title: "Start a Build run",
284
- description: "Run the selected Build Plan for a Preparation. Returns the new Build run "
285
- + "resource immediately; use runs_status to poll progress and "
286
- + "runs_fetch when the run finishes.",
778
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.id, "buildRuns"), { method: "POST", body: "{}" }));
779
+ if (!appProfile) {
780
+ server.registerTool("project_benchmark", {
781
+ title: "Run benchmark/evaluation",
782
+ description: "Developer/evaluation tool. Run the Project's Q&A / fact-check benchmark against the latest Context Graph.",
783
+ inputSchema: {
784
+ id: McpProjectIdSchema,
785
+ },
786
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.id, "verifyRuns"), {
787
+ method: "POST",
788
+ body: JSON.stringify({}),
789
+ }));
790
+ }
791
+ server.registerTool("project_source_files", {
792
+ title: "List Project source files",
793
+ description: "List the Source files bound to a Project to confirm coverage scope. "
794
+ + "This is not an answer source by itself; prepare or inspect a Context Graph before answering.",
287
795
  inputSchema: {
288
- id: z.string().min(1).describe("Preparation id."),
796
+ id: McpProjectIdSchema,
289
797
  },
290
- }, async (args) => callAndReturn(connectionArgs, preparationSubresourcePath(args.id, "buildRuns"), { method: "POST", body: "{}" }));
291
- server.registerTool("prep_test", {
292
- title: "Run readiness checks",
293
- description: "Run the Preparation's readiness checks against the latest verifiable "
294
- + "context.",
798
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.id, "sourceFiles")));
799
+ server.registerTool("context_graph_show", {
800
+ title: "Show latest Context Graph",
801
+ description: "Inspect the latest Context Graph locator/status for a Project. Reuse it only if it was built for the same Source "
802
+ + "and task intent; otherwise improve or draft a Build Plan and rebuild. Read home.md before answering.",
295
803
  inputSchema: {
296
- id: z.string().min(1).describe("Preparation id."),
804
+ project_id: McpProjectIdSchema,
297
805
  },
298
- }, async (args) => callAndReturn(connectionArgs, preparationSubresourcePath(args.id, "verifyRuns"), {
299
- method: "POST",
300
- body: JSON.stringify({}),
301
- }));
806
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraph")));
807
+ server.registerTool("context_graph_entrypoint", {
808
+ title: "Read Context Graph entrypoint",
809
+ description: "Return the downstream entrypoint for the latest Context Graph. Start from home.md before summaries/ or knowledge/.",
810
+ inputSchema: {
811
+ project_id: McpProjectIdSchema,
812
+ },
813
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraphEntrypoint")));
814
+ server.registerTool("context_graph_file_read", {
815
+ title: "Read a Context Graph file",
816
+ description: "Read one prepared Context Graph file by relative path. Start with home.md, "
817
+ + "then use summaries/ for coverage and knowledge/ for drilldown. Do not use this to search unrelated Projects for answers.",
818
+ inputSchema: {
819
+ project_id: McpProjectIdSchema,
820
+ path: z.string().min(1).describe("Relative path inside the Context Graph root."),
821
+ },
822
+ }, async (args) => callAndReturn(connectionArgs, contextGraphFilePath(args.project_id, args.path)));
823
+ server.registerTool("project_traces", {
824
+ title: "Read Project traces",
825
+ description: "Read source-backed traces for the latest Context Graph. Use traces to follow prepared context "
826
+ + "back to the Source for exact values, chart reads, tables, and provenance-sensitive claims.",
827
+ inputSchema: {
828
+ project_id: McpProjectIdSchema,
829
+ },
830
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "traces")));
831
+ server.registerTool("context_graph_sessions", {
832
+ title: "List Context Graph execution sessions",
833
+ description: "List the per-stage execution shell sessions for the latest Build run — executor + model, status, attempt, validation attempts, and replay readiness. Pull these to drive the next self-improvement iteration when a stage was weak or failed.",
834
+ inputSchema: {
835
+ project_id: McpProjectIdSchema,
836
+ },
837
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "contextGraphSessions")));
838
+ server.registerTool("context_graph_session", {
839
+ title: "Get one Context Graph execution session",
840
+ description: "Return one preserved execution shell session by stage_run_id — prompt, event/status log paths, runtime files, artifact mounts, validation attempts, and terminal verdict. Use it to inspect or replay exactly what a stage attempt did.",
841
+ inputSchema: {
842
+ project_id: McpProjectIdSchema,
843
+ stage_run_id: z.string().min(1).describe("Stage execution session id (stage_run_id) from context_graph_sessions."),
844
+ },
845
+ }, async (args) => callAndReturn(connectionArgs, `${projectSubresourcePath(args.project_id, "contextGraphSessions")}/${encodeURIComponent(args.stage_run_id)}`));
846
+ server.registerTool("project_build_evidence", {
847
+ title: "Read Supplemental Build Diagnostics",
848
+ description: "Read the latest supplemental diagnostics resource for a Project. Prefer context_graph_show for primary metrics; if coverage is weak or missing, improve the Build Plan instead of answering.",
849
+ inputSchema: {
850
+ project_id: McpProjectIdSchema,
851
+ },
852
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildEvidence")));
853
+ server.registerTool("project_artifact_show", {
854
+ title: "Show Requested Output",
855
+ description: "Return latest status and contributing evidence for one Build Plan-declared requested output.",
856
+ inputSchema: {
857
+ project_id: McpProjectIdSchema,
858
+ artifact_id: McpArtifactIdSchema.describe("Requested output id."),
859
+ },
860
+ }, async (args) => callAndReturn(connectionArgs, `${projectSubresourcePath(args.project_id, "artifacts")}/${encodeURIComponent(args.artifact_id)}`));
302
861
  // ── Build Plans ────────────────────────────────────────────────────────
303
- server.registerTool("build_plan_list", {
304
- title: "List Build Plans",
305
- description: "List every Build Plan visible to the connected instance: Preparation drafts, "
306
- + "saved Build Plans, and bundled Build Plans.",
307
- inputSchema: {},
308
- }, async () => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.buildPlans));
862
+ if (!appProfile) {
863
+ server.registerTool("build_plan_list", {
864
+ title: "List Build Plans",
865
+ description: "Developer/library tool. Do not treat the Build Plan library as an answer source.",
866
+ inputSchema: {},
867
+ }, async () => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.buildPlans));
868
+ server.registerTool("build_plan_show", {
869
+ title: "Show one Build Plan",
870
+ description: "Developer/library tool. Return one Build Plan resource, including requested outputs, stages, and coverage checks.",
871
+ inputSchema: {
872
+ build_plan_id: McpBuildPlanIdSchema,
873
+ },
874
+ }, async (args) => callAndReturn(connectionArgs, buildPlanResourcePath(args.build_plan_id)));
875
+ server.registerTool("build_plan_file_read", {
876
+ title: "Read a Build Plan file",
877
+ description: "Developer/library tool. Read one file inside a Build Plan package by relative path, such as "
878
+ + "build-plan.json, build-plan.schema.json, or a stage SKILL.md.",
879
+ inputSchema: {
880
+ build_plan_id: McpBuildPlanIdSchema,
881
+ path: z.string().min(1).describe("Relative path inside the Build Plan package."),
882
+ },
883
+ }, async (args) => callAndReturn(connectionArgs, `${buildPlanSubresourcePath(args.build_plan_id, "files")}/${encodeRelativePath(args.path)}`));
884
+ }
309
885
  server.registerTool("build_plan_draft", {
310
886
  title: "Draft a Build Plan",
311
- description: "Run the Build Plan authoring agent for a Preparation. Saved requested "
312
- + "Artifacts are used automatically when omitted from the request.",
887
+ description: "Draft the task-specific Build Plan from the Project intent, requested outputs, and optional coverage expectations. This is the main Interf preparation action before building.",
313
888
  inputSchema: {
314
- prep_id: z.string().min(1).describe("Preparation id."),
315
- source_folder_path: z.string().min(1).describe("Source folder path visible to the connected instance."),
316
- build_plan_id: z.string().min(1).describe("Build Plan id to create."),
889
+ project_id: McpProjectIdSchema,
890
+ build_plan_id: McpBuildPlanIdSchema.describe("Build Plan id to create."),
317
891
  label: z.string().min(1).describe("Human-readable Build Plan label."),
318
892
  hint: z.string().min(1).describe("Short Build Plan hint."),
319
- task_prompt: z.string().min(1).describe("Agent job this Build Plan should support."),
320
- requested_artifacts: z.array(RequestedArtifactSchema).optional(),
321
- source_profile: SourceProfileSchema.nullable().optional(),
322
- artifact_requirements: z.array(BuildPlanAuthoringArtifactRequirementSchema).optional(),
893
+ intent: z.string().min(1).optional().describe("Agent task this Build Plan should support. Omit to use the Project intent."),
894
+ context_checks: z.array(BuildPlanContextCheckDraftSchema).optional().describe("Optional legacy plain-English checks. Prefer Project intent plus requested outputs and coverage expectations."),
895
+ requested_artifacts: z.array(McpRequestedArtifactSchema).optional().describe("Requested outputs the user approved before drafting. Use simple titles, descriptions, and coverage expectations."),
896
+ source_context: SourceContextSchema.nullable().optional(),
897
+ ...(!appProfile
898
+ ? {
899
+ artifact_requirements: z.array(BuildPlanAuthoringArtifactRequirementSchema).optional(),
900
+ }
901
+ : {}),
323
902
  },
324
- }, async (args) => callAndReturn(connectionArgs, preparationSubresourcePath(args.prep_id, "buildPlanDraftRuns"), {
903
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildPlanDraftRuns"), {
325
904
  method: "POST",
326
905
  body: JSON.stringify({
327
- preparation: args.prep_id,
328
- source_folder_path: args.source_folder_path,
906
+ project: args.project_id,
329
907
  build_plan_id: args.build_plan_id,
330
908
  label: args.label,
331
909
  hint: args.hint,
332
- task_prompt: args.task_prompt,
333
- ...(args.requested_artifacts ? { requested_artifacts: args.requested_artifacts } : {}),
334
- ...(args.source_profile !== undefined ? { source_profile: args.source_profile } : {}),
335
- ...(args.artifact_requirements ? { artifact_requirements: args.artifact_requirements } : {}),
910
+ ...(args.intent ? { intent: args.intent } : {}),
911
+ ...(args.context_checks ? { checks: args.context_checks } : {}),
912
+ ...(args.requested_artifacts ? { requested_artifacts: normalizeRequestedArtifacts(args.requested_artifacts) } : {}),
913
+ ...(args.source_context !== undefined ? { source_context: args.source_context } : {}),
914
+ ...(!appProfile && args.artifact_requirements ? { artifact_requirements: args.artifact_requirements } : {}),
336
915
  }),
337
916
  }));
338
917
  server.registerTool("build_plan_improve", {
339
918
  title: "Improve a Build Plan",
340
- description: "Run the Build Plan improvement agent for a Preparation. Iterates on "
341
- + "the selected Build Plan based on requested Artifacts and latest readiness evidence.",
919
+ description: "Improve the selected Build Plan when the current Context Graph is not ready for the user's task, "
920
+ + "for example when coverage is missing, an entrypoint is too coarse, a chart/table was under-extracted, or evidence is missing.",
342
921
  inputSchema: {
343
- prep_id: z.string().min(1).describe("Preparation id."),
344
- source_folder_path: z.string().min(1).describe("Source folder path visible to the connected instance."),
345
- build_plan_id: z.string().min(1).describe("Selected Build Plan id to improve."),
922
+ project_id: McpProjectIdSchema,
923
+ build_plan_id: McpBuildPlanIdSchema.describe("Selected Build Plan id to improve."),
346
924
  label: z.string().min(1).describe("Human-readable Build Plan label."),
347
925
  hint: z.string().min(1).describe("Short Build Plan hint."),
348
- task_prompt: z.string().min(1).describe("Change request or improvement goal."),
349
- requested_artifacts: z.array(RequestedArtifactSchema).optional(),
350
- source_profile: SourceProfileSchema.nullable().optional(),
351
- artifact_requirements: z.array(BuildPlanAuthoringArtifactRequirementSchema).optional(),
926
+ intent: z.string().min(1).optional().describe("Change request or improvement goal. Omit to use the Project intent."),
927
+ context_checks: z.array(BuildPlanContextCheckDraftSchema).optional().describe("Optional legacy plain-English checks. Prefer missing coverage and requested output changes."),
928
+ requested_artifacts: z.array(McpRequestedArtifactSchema).optional().describe("Requested outputs for the improved Plan. Use simple titles, descriptions, and coverage expectations."),
929
+ source_context: SourceContextSchema.nullable().optional(),
930
+ ...(!appProfile
931
+ ? {
932
+ artifact_requirements: z.array(BuildPlanAuthoringArtifactRequirementSchema).optional(),
933
+ }
934
+ : {}),
352
935
  },
353
- }, async (args) => callAndReturn(connectionArgs, preparationSubresourcePath(args.prep_id, "buildPlanImprovementRuns"), {
936
+ }, async (args) => callAndReturn(connectionArgs, projectSubresourcePath(args.project_id, "buildPlanImprovementRuns"), {
354
937
  method: "POST",
355
938
  body: JSON.stringify({
356
- preparation: args.prep_id,
357
- source_folder_path: args.source_folder_path,
939
+ project: args.project_id,
358
940
  build_plan_id: args.build_plan_id,
359
941
  reference_build_plan_id: args.build_plan_id,
360
942
  label: args.label,
361
943
  hint: args.hint,
362
- task_prompt: args.task_prompt,
363
- ...(args.requested_artifacts ? { requested_artifacts: args.requested_artifacts } : {}),
364
- ...(args.source_profile !== undefined ? { source_profile: args.source_profile } : {}),
365
- ...(args.artifact_requirements ? { artifact_requirements: args.artifact_requirements } : {}),
944
+ ...(args.intent ? { intent: args.intent } : {}),
945
+ ...(args.context_checks ? { checks: args.context_checks } : {}),
946
+ ...(args.requested_artifacts ? { requested_artifacts: normalizeRequestedArtifacts(args.requested_artifacts) } : {}),
947
+ ...(args.source_context !== undefined ? { source_context: args.source_context } : {}),
948
+ ...(!appProfile && args.artifact_requirements ? { artifact_requirements: args.artifact_requirements } : {}),
366
949
  }),
367
950
  }));
368
951
  // ── Runs ────────────────────────────────────────────────────────────────
369
952
  server.registerTool("runs_status", {
370
953
  title: "Get run status",
371
- description: "Return the run record for one observable run.",
954
+ description: "Return a compact run-status receipt for polling. This intentionally omits full trace events, "
955
+ + "stream logs, and artifact manifests so repeated polls do not fill the agent context window.",
372
956
  inputSchema: {
373
- run_id: z.string().min(1).describe("Run id."),
957
+ run_id: McpRunIdSchema,
374
958
  },
375
- }, async (args) => callAndReturn(connectionArgs, runResourcePath(args.run_id)));
959
+ }, async (args) => callAndProject(connectionArgs, runSubresourcePath(args.run_id, "status"), compactRunStatus));
376
960
  server.registerTool("runs_watch", {
377
- title: "Read run events",
378
- description: "Read the events log for one run as a snapshot. Returns the same "
379
- + "stream the UI consumes via SSE; agents that need live progress "
380
- + "should poll runs_status until the run reaches a terminal state.",
961
+ title: "Read recent run events",
962
+ description: "Read a bounded tail of run events for debugging or progress detail. Do not use this for polling; "
963
+ + "poll runs_status until the run reaches a terminal state.",
381
964
  inputSchema: {
382
- run_id: z.string().min(1).describe("Run id."),
965
+ run_id: McpRunIdSchema,
966
+ limit: z.number().int().min(1).max(50).default(10).describe("Maximum recent events to return. Defaults to 10; max 50."),
967
+ include_streams: z.boolean().default(false).describe("Include recent log stream chunks. Defaults to false because logs can be verbose."),
968
+ stream_limit: z.number().int().min(1).max(20).default(5).describe("Maximum recent log stream chunks to return when include_streams is true. Defaults to 5; max 20."),
383
969
  },
384
- }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.buildRuns}/${encodeURIComponent(args.run_id)}/events`));
385
- server.registerTool("runs_cancel", {
386
- title: "Cancel a run",
387
- description: "Request cancellation of an in-flight run.",
970
+ }, async (args) => callAndProject(connectionArgs, runResourcePath(args.run_id), (body) => compactRunEvents(body, {
971
+ eventLimit: args.limit,
972
+ includeStreams: args.include_streams,
973
+ streamLimit: args.stream_limit,
974
+ })));
975
+ if (!appProfile) {
976
+ server.registerTool("runs_cancel", {
977
+ title: "Cancel a run",
978
+ description: "Developer/admin tool. Request cancellation of an in-flight run.",
979
+ inputSchema: {
980
+ run_id: McpRunIdSchema,
981
+ },
982
+ }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.runs}/${encodeURIComponent(args.run_id)}/cancel`, { method: "POST", body: "{}" }));
983
+ }
984
+ server.registerTool("runs_events", {
985
+ title: "Read full run event log",
986
+ description: "Return the full durable event log for a Build run: stage start/pass/fail, files processed, "
987
+ + "artifacts written, evidence, checks, and readiness. Use runs_status for polling and runs_watch "
988
+ + "for a bounded tail; use this to inspect or replay the complete sequence.",
388
989
  inputSchema: {
389
- run_id: z.string().min(1).describe("Run id."),
990
+ run_id: McpRunIdSchema,
390
991
  },
391
- }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.buildRuns}/${encodeURIComponent(args.run_id)}/cancel`, { method: "POST", body: "{}" }));
992
+ }, async (args) => callAndReturn(connectionArgs, runSubresourcePath(args.run_id, "events")));
392
993
  server.registerTool("runs_fetch", {
393
994
  title: "Fetch run artifacts",
394
- description: "Return the artifact manifest for a finished run (verifiable context, "
395
- + "proof records, logs, run-scoped audit trail).",
995
+ description: "Return the artifact manifest for a finished run (Context Graph, "
996
+ + "evidence records, logs, run-scoped audit trail).",
396
997
  inputSchema: {
397
- run_id: z.string().min(1).describe("Run id."),
998
+ run_id: McpRunIdSchema,
398
999
  },
399
- }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.buildRuns}/${encodeURIComponent(args.run_id)}/artifacts`));
1000
+ }, async (args) => callAndReturn(connectionArgs, `${LOCAL_SERVICE_ROUTES.runs}/${encodeURIComponent(args.run_id)}/artifacts`));
400
1001
  // ── Instance ────────────────────────────────────────────────────────────
401
1002
  server.registerTool("instance_status", {
402
1003
  title: "Show instance status",
403
- description: "Return the engine's instance resource: started_at, package "
404
- + "version, registered preparations, active runs, idle seconds.",
1004
+ description: "Return the local service instance resource: started_at, registered "
1005
+ + "Projects, active runs, idle seconds.",
405
1006
  inputSchema: {},
406
1007
  }, async () => callAndReturn(connectionArgs, LOCAL_SERVICE_ROUTES.instance));
407
1008
  }
408
- async function startStdioServer(args) {
409
- const server = new McpServer({ name: "interf", version: packageVersionFromManifest() }, { capabilities: { tools: {} } });
1009
+ export async function startInterfMcpServer(args) {
1010
+ if (args.transport && args.transport !== "stdio") {
1011
+ throw new Error("Only the MCP stdio transport is implemented for the local Interf MCP server.");
1012
+ }
1013
+ const server = new McpServer({ name: "interf", version: packageVersionFromManifest() }, {
1014
+ capabilities: { tools: {} },
1015
+ instructions: INTERF_MCP_INSTRUCTIONS,
1016
+ });
410
1017
  registerTools(server, args);
411
1018
  const transport = new StdioServerTransport();
412
1019
  await server.connect(transport);
413
1020
  }
414
1021
  export const mcpCommand = {
415
1022
  command: "mcp",
416
- describe: "Run the Interf Model Context Protocol server (stdio by default).",
1023
+ describe: false,
417
1024
  builder: (yargs) => yargs
418
1025
  .option("transport", {
419
1026
  type: "string",
420
- choices: ["stdio", "http"],
1027
+ choices: ["stdio"],
421
1028
  default: "stdio",
422
1029
  describe: "Transport for the MCP server.",
1030
+ })
1031
+ .option("profile", {
1032
+ type: "string",
1033
+ choices: ["headless", "app"],
1034
+ default: "headless",
1035
+ describe: "Tool profile. App profile hides lifecycle tools because Desktop owns the local service.",
423
1036
  })
424
1037
  .option("url", {
425
1038
  type: "string",
@@ -430,11 +1043,12 @@ export const mcpCommand = {
430
1043
  describe: "Override the active bearer token.",
431
1044
  }),
432
1045
  handler: async (args) => {
433
- if (args.transport && args.transport !== "stdio") {
434
- process.stderr.write("interf mcp: only the stdio transport is implemented today. "
435
- + "Open an issue if you need --transport=http.\n");
1046
+ try {
1047
+ await startInterfMcpServer(args);
1048
+ }
1049
+ catch (error) {
1050
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
436
1051
  process.exit(2);
437
1052
  }
438
- await startStdioServer(args);
439
1053
  },
440
1054
  };