@interf/compiler 0.33.0 → 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 (234) hide show
  1. package/README.md +122 -226
  2. package/dist/cli/commands/agents.js +1 -32
  3. package/dist/cli/commands/benchmark.d.ts +2 -3
  4. package/dist/cli/commands/benchmark.js +1 -31
  5. package/dist/cli/commands/build-plan.js +26 -50
  6. package/dist/cli/commands/build.d.ts +2 -3
  7. package/dist/cli/commands/build.js +1 -31
  8. package/dist/cli/commands/graphs.js +177 -32
  9. package/dist/cli/commands/mcp.d.ts +1 -0
  10. package/dist/cli/commands/mcp.js +223 -126
  11. package/dist/cli/commands/project.js +10 -36
  12. package/dist/cli/commands/reset.d.ts +2 -3
  13. package/dist/cli/commands/reset.js +1 -22
  14. package/dist/cli/commands/runs.js +86 -33
  15. package/dist/cli/commands/status.js +3 -24
  16. package/dist/cli/commands/traces.js +1 -29
  17. package/dist/cli/commands/wizard.js +17 -29
  18. package/dist/cli/lib/http-client.d.ts +39 -0
  19. package/dist/cli/lib/http-client.js +73 -0
  20. package/dist/packages/build-plans/authoring/brief.d.ts +25 -4
  21. package/dist/packages/build-plans/authoring/build-plan-authoring.d.ts +42 -1
  22. package/dist/packages/build-plans/authoring/build-plan-authoring.js +470 -63
  23. package/dist/packages/build-plans/authoring/build-plan-edit-session.d.ts +9 -0
  24. package/dist/packages/build-plans/authoring/build-plan-edit-session.js +27 -10
  25. package/dist/packages/build-plans/authoring/build-plan-improvement.js +62 -8
  26. package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.d.ts +1 -0
  27. package/dist/packages/build-plans/package/build-plan-definitions.d.ts +0 -1
  28. package/dist/packages/build-plans/package/build-plan-definitions.js +5 -3
  29. package/dist/packages/build-plans/package/build-plan-stage-runner.d.ts +1 -0
  30. package/dist/packages/build-plans/package/build-plan-stage-runner.js +2 -1
  31. package/dist/packages/build-plans/package/builtin-build-plan.d.ts +2 -2
  32. package/dist/packages/build-plans/package/builtin-build-plan.js +3 -3
  33. package/dist/packages/build-plans/package/context-interface.d.ts +3 -0
  34. package/dist/packages/build-plans/package/context-interface.js +5 -5
  35. package/dist/packages/build-plans/package/interf-build-plan-package.js +22 -22
  36. package/dist/packages/build-plans/package/local-build-plans.d.ts +10 -5
  37. package/dist/packages/build-plans/package/local-build-plans.js +57 -32
  38. package/dist/packages/contracts/index.d.ts +4 -3
  39. package/dist/packages/contracts/index.js +2 -1
  40. package/dist/packages/contracts/lib/context-graph-layer.d.ts +161 -0
  41. package/dist/packages/contracts/lib/context-graph-layer.js +216 -0
  42. package/dist/packages/contracts/lib/project-paths.d.ts +7 -0
  43. package/dist/packages/contracts/lib/project-paths.js +9 -0
  44. package/dist/packages/contracts/lib/project-schema.d.ts +264 -1
  45. package/dist/packages/contracts/lib/project-schema.js +38 -13
  46. package/dist/packages/contracts/lib/schema.d.ts +556 -23
  47. package/dist/packages/contracts/lib/schema.js +279 -18
  48. package/dist/packages/contracts/utils/filesystem.d.ts +1 -0
  49. package/dist/packages/contracts/utils/filesystem.js +29 -1
  50. package/dist/packages/projects/lib/schema.d.ts +6 -8
  51. package/dist/packages/projects/lib/schema.js +3 -1
  52. package/dist/packages/projects/source-config.d.ts +0 -5
  53. package/dist/packages/projects/source-config.js +9 -22
  54. package/dist/packages/runtime/actions/fields.d.ts +4 -0
  55. package/dist/packages/runtime/actions/form-builders.js +79 -31
  56. package/dist/packages/runtime/actions/form-validators.js +9 -3
  57. package/dist/packages/runtime/actions/helpers.js +3 -3
  58. package/dist/packages/runtime/actions/registry.d.ts +1 -1
  59. package/dist/packages/runtime/actions/registry.js +1 -1
  60. package/dist/packages/runtime/actions/requests.d.ts +1 -1
  61. package/dist/packages/runtime/actions/requests.js +12 -6
  62. package/dist/packages/runtime/actions/schemas.d.ts +7 -0
  63. package/dist/packages/runtime/actions/schemas.js +1 -0
  64. package/dist/packages/runtime/agent-handoff.js +8 -7
  65. package/dist/packages/runtime/agents/lib/execution-profile.d.ts +14 -0
  66. package/dist/packages/runtime/agents/lib/execution-profile.js +23 -0
  67. package/dist/packages/runtime/agents/lib/execution.js +14 -8
  68. package/dist/packages/runtime/agents/lib/executors.d.ts +1 -0
  69. package/dist/packages/runtime/agents/lib/executors.js +11 -2
  70. package/dist/packages/runtime/agents/lib/logs.d.ts +10 -0
  71. package/dist/packages/runtime/agents/lib/logs.js +32 -8
  72. package/dist/packages/runtime/agents/lib/preflight.js +4 -1
  73. package/dist/packages/runtime/agents/lib/render.d.ts +18 -0
  74. package/dist/packages/runtime/agents/lib/render.js +44 -18
  75. package/dist/packages/runtime/agents/lib/shell-templates.js +105 -63
  76. package/dist/packages/runtime/agents/lib/shells.d.ts +29 -0
  77. package/dist/packages/runtime/agents/lib/shells.js +158 -32
  78. package/dist/packages/runtime/agents/lib/source-context-scan.d.ts +10 -0
  79. package/dist/packages/runtime/agents/lib/source-context-scan.js +388 -0
  80. package/dist/packages/runtime/agents/lib/status.js +1 -14
  81. package/dist/packages/runtime/agents/lib/string-utils.d.ts +16 -0
  82. package/dist/packages/runtime/agents/lib/string-utils.js +36 -0
  83. package/dist/packages/runtime/agents/lib/types.d.ts +1 -0
  84. package/dist/packages/runtime/agents/providers/codex.js +2 -0
  85. package/dist/packages/runtime/agents/role-executors.js +2 -1
  86. package/dist/packages/runtime/auth/session-store.js +11 -3
  87. package/dist/packages/runtime/benchmark-question-draft.d.ts +3 -0
  88. package/dist/packages/runtime/benchmark-question-draft.js +57 -28
  89. package/dist/packages/runtime/build/artifact-status.d.ts +1 -1
  90. package/dist/packages/runtime/build/artifact-status.js +1 -1
  91. package/dist/packages/runtime/build/build-evidence.d.ts +2 -1
  92. package/dist/packages/runtime/build/build-evidence.js +11 -5
  93. package/dist/packages/runtime/build/build-pipeline.js +89 -5
  94. package/dist/packages/runtime/build/build-stage-plan.js +3 -1
  95. package/dist/packages/runtime/build/build-stage-runner.js +169 -32
  96. package/dist/packages/runtime/build/build-target.d.ts +3 -0
  97. package/dist/packages/runtime/build/build-target.js +25 -1
  98. package/dist/packages/runtime/build/check-evaluator.d.ts +1 -1
  99. package/dist/packages/runtime/build/check-evaluator.js +655 -4
  100. package/dist/packages/runtime/build/context-graph-paths.d.ts +13 -0
  101. package/dist/packages/runtime/build/context-graph-paths.js +27 -0
  102. package/dist/packages/runtime/build/index.d.ts +2 -2
  103. package/dist/packages/runtime/build/index.js +2 -2
  104. package/dist/packages/runtime/build/inspect-map.d.ts +10 -0
  105. package/dist/packages/runtime/build/inspect-map.js +270 -0
  106. package/dist/packages/runtime/build/lib/schema.d.ts +246 -53
  107. package/dist/packages/runtime/build/lib/schema.js +173 -15
  108. package/dist/packages/runtime/build/native-entrypoint.d.ts +2 -0
  109. package/dist/packages/runtime/build/native-entrypoint.js +286 -0
  110. package/dist/packages/runtime/build/runtime-contracts.js +9 -3
  111. package/dist/packages/runtime/build/runtime-log-paths.d.ts +3 -0
  112. package/dist/packages/runtime/build/runtime-log-paths.js +16 -0
  113. package/dist/packages/runtime/build/runtime-prompt.js +6 -4
  114. package/dist/packages/runtime/build/runtime-runs.js +63 -10
  115. package/dist/packages/runtime/build/runtime-types.d.ts +4 -1
  116. package/dist/packages/runtime/build/runtime.d.ts +3 -1
  117. package/dist/packages/runtime/build/runtime.js +3 -1
  118. package/dist/packages/runtime/build/source-files.js +11 -2
  119. package/dist/packages/runtime/build/source-inventory.d.ts +1 -0
  120. package/dist/packages/runtime/build/source-inventory.js +246 -7
  121. package/dist/packages/runtime/build/source-manifest.d.ts +11 -0
  122. package/dist/packages/runtime/build/source-manifest.js +30 -2
  123. package/dist/packages/runtime/build/stage-evidence.js +80 -11
  124. package/dist/packages/runtime/build/stage-manifest.d.ts +45 -0
  125. package/dist/packages/runtime/build/stage-manifest.js +1125 -0
  126. package/dist/packages/runtime/build/stage-reuse.js +12 -0
  127. package/dist/packages/runtime/build/stage-session.d.ts +81 -0
  128. package/dist/packages/runtime/build/stage-session.js +308 -0
  129. package/dist/packages/runtime/build/state-io.js +10 -11
  130. package/dist/packages/runtime/build/state-view.js +1 -1
  131. package/dist/packages/runtime/build/state.d.ts +1 -1
  132. package/dist/packages/runtime/build/state.js +1 -1
  133. package/dist/packages/runtime/build/summary-coverage-index.d.ts +21 -0
  134. package/dist/packages/runtime/build/summary-coverage-index.js +189 -0
  135. package/dist/packages/runtime/build/traces.js +3 -3
  136. package/dist/packages/runtime/build/validate-context-graph.d.ts +1 -1
  137. package/dist/packages/runtime/build/validate-context-graph.js +5 -5
  138. package/dist/packages/runtime/build/validate.d.ts +1 -1
  139. package/dist/packages/runtime/build/validate.js +1 -1
  140. package/dist/packages/runtime/client.d.ts +3 -3
  141. package/dist/packages/runtime/client.js +8 -13
  142. package/dist/packages/runtime/context-checks.js +13 -0
  143. package/dist/packages/runtime/context-graph-scaffold.js +2 -1
  144. package/dist/packages/runtime/context-graph-semantic-graph.d.ts +9 -0
  145. package/dist/packages/runtime/context-graph-semantic-graph.js +416 -0
  146. package/dist/packages/runtime/execution/lib/schema.d.ts +34 -31
  147. package/dist/packages/runtime/index.d.ts +2 -2
  148. package/dist/packages/runtime/index.js +1 -1
  149. package/dist/packages/runtime/native-run-handlers.d.ts +38 -0
  150. package/dist/packages/runtime/native-run-handlers.js +52 -33
  151. package/dist/packages/runtime/plan-artifact-contract.js +1 -1
  152. package/dist/packages/runtime/project-source-state.d.ts +4 -4
  153. package/dist/packages/runtime/project-source-state.js +5 -2
  154. package/dist/packages/runtime/project-store.d.ts +5 -0
  155. package/dist/packages/runtime/project-store.js +30 -3
  156. package/dist/packages/runtime/requested-artifacts.js +1 -1
  157. package/dist/packages/runtime/run-observability.js +9 -4
  158. package/dist/packages/runtime/runtime-action-proposals.js +3 -3
  159. package/dist/packages/runtime/runtime-build-plans.js +47 -3
  160. package/dist/packages/runtime/runtime-build-runs.js +9 -16
  161. package/dist/packages/runtime/runtime-caches.d.ts +26 -0
  162. package/dist/packages/runtime/runtime-caches.js +47 -0
  163. package/dist/packages/runtime/runtime-jobs.js +6 -6
  164. package/dist/packages/runtime/runtime-project-mutations.js +1 -0
  165. package/dist/packages/runtime/runtime-project-reads.d.ts +4 -1
  166. package/dist/packages/runtime/runtime-project-reads.js +229 -36
  167. package/dist/packages/runtime/runtime-proposal-helpers.js +6 -6
  168. package/dist/packages/runtime/runtime-resource-builders.d.ts +4 -2
  169. package/dist/packages/runtime/runtime-resource-builders.js +16 -14
  170. package/dist/packages/runtime/runtime-status.d.ts +14 -0
  171. package/dist/packages/runtime/runtime-status.js +15 -0
  172. package/dist/packages/runtime/runtime-verify-runs.js +6 -5
  173. package/dist/packages/runtime/runtime.d.ts +439 -22
  174. package/dist/packages/runtime/runtime.js +16 -2
  175. package/dist/packages/runtime/schemas/actions.d.ts +24 -0
  176. package/dist/packages/runtime/schemas/agents.d.ts +28 -0
  177. package/dist/packages/runtime/schemas/agents.js +33 -0
  178. package/dist/packages/runtime/schemas/build-plans.d.ts +181 -8
  179. package/dist/packages/runtime/schemas/build-plans.js +36 -2
  180. package/dist/packages/runtime/schemas/context-graphs.d.ts +1522 -0
  181. package/dist/packages/runtime/schemas/context-graphs.js +110 -0
  182. package/dist/packages/runtime/schemas/files.d.ts +7 -347
  183. package/dist/packages/runtime/schemas/files.js +1 -24
  184. package/dist/packages/runtime/schemas/index.d.ts +1 -0
  185. package/dist/packages/runtime/schemas/index.js +1 -0
  186. package/dist/packages/runtime/schemas/jobs.js +4 -0
  187. package/dist/packages/runtime/schemas/projects.d.ts +48 -21
  188. package/dist/packages/runtime/schemas/projects.js +34 -10
  189. package/dist/packages/runtime/schemas/runs.d.ts +1009 -240
  190. package/dist/packages/runtime/schemas/runs.js +17 -0
  191. package/dist/packages/runtime/service/openapi.js +1 -0
  192. package/dist/packages/runtime/service/operations.d.ts +1666 -145
  193. package/dist/packages/runtime/service/operations.js +147 -17
  194. package/dist/packages/runtime/service/routes.d.ts +11 -3
  195. package/dist/packages/runtime/service/routes.js +11 -3
  196. package/dist/packages/runtime/service/server-app-boot.js +2 -2
  197. package/dist/packages/runtime/service/server-helpers.d.ts +11 -0
  198. package/dist/packages/runtime/service/server-helpers.js +19 -0
  199. package/dist/packages/runtime/service/server-routes-action-proposals.js +4 -2
  200. package/dist/packages/runtime/service/server-routes-agents.js +19 -85
  201. package/dist/packages/runtime/service/server-routes-build-plans.js +14 -11
  202. package/dist/packages/runtime/service/server-routes-project-context.js +102 -7
  203. package/dist/packages/runtime/service/server-routes-project-jobs.js +19 -12
  204. package/dist/packages/runtime/service/server-routes-project-runs.js +5 -2
  205. package/dist/packages/runtime/service/server-routes-projects.js +6 -2
  206. package/dist/packages/runtime/service/server-routes-runs.js +11 -4
  207. package/dist/packages/runtime/verify/lib/schema.js +12 -0
  208. package/dist/packages/runtime/verify/test-file-guard.d.ts +2 -0
  209. package/dist/packages/runtime/verify/test-file-guard.js +29 -0
  210. package/dist/packages/runtime/verify/verify-execution.d.ts +7 -0
  211. package/dist/packages/runtime/verify/verify-execution.js +109 -35
  212. package/dist/packages/runtime/verify/verify-paths.d.ts +1 -0
  213. package/dist/packages/runtime/verify/verify-paths.js +4 -0
  214. package/dist/packages/runtime/verify/verify-specs.js +49 -39
  215. package/dist/packages/runtime/wire-schemas.d.ts +1 -1
  216. package/dist/packages/runtime/wire-schemas.js +1 -1
  217. package/package.json +2 -8
  218. package/public-repo/CONTRIBUTING.md +10 -3
  219. package/public-repo/README.md +122 -226
  220. package/public-repo/build-plans/interf-default/README.md +15 -12
  221. package/public-repo/build-plans/interf-default/build/stages/entrypoint/SKILL.md +74 -0
  222. package/public-repo/build-plans/interf-default/build/stages/knowledge/SKILL.md +95 -0
  223. package/public-repo/build-plans/interf-default/build/stages/summarize/SKILL.md +38 -5
  224. package/public-repo/build-plans/interf-default/build-plan.json +27 -23
  225. package/public-repo/build-plans/interf-default/build-plan.schema.json +24 -20
  226. package/public-repo/build-plans/interf-default/use/query/SKILL.md +8 -7
  227. package/public-repo/openapi/local-service.openapi.json +11637 -4213
  228. package/public-repo/skills/interf/SKILL.md +174 -134
  229. package/dist/packages/runtime/build/runtime-paths.d.ts +0 -8
  230. package/dist/packages/runtime/build/runtime-paths.js +0 -26
  231. package/dist/packages/runtime/build/state-paths.d.ts +0 -7
  232. package/dist/packages/runtime/build/state-paths.js +0 -22
  233. package/public-repo/build-plans/interf-default/build/stages/shape/SKILL.md +0 -34
  234. package/public-repo/build-plans/interf-default/build/stages/structure/SKILL.md +0 -28
@@ -1,15 +1,24 @@
1
1
  import { z } from "zod";
2
- import { TracesSchema } from "../../contracts/lib/project-schema.js";
3
- import { BuildEvidenceResourceSchema, ProjectIdSchema, } from "../../contracts/lib/schema.js";
4
- import { BuildPlanAuthoringCreateRequestSchema, BuildRunCreateRequestSchema, BuildRunResourceSchema, ContextGraphResourceSchema, InstanceResourceSchema, LocalJobRunResourceSchema, LocalServiceHealthSchema, ProjectCreateRequestSchema, ProjectWireShapeSchema, RunArtifactsResponseSchema, RunStatusResourceSchema, SourceFileListResponseSchema, SourceManifestResourceSchema, } from "../schemas/index.js";
2
+ import { ContextGraphHandoffSchema, TracesSchema, } from "../../contracts/lib/project-schema.js";
3
+ import { BuildEvidenceResourceSchema, GraphOutputCountsSchema, GraphManifestStageSummarySchema, GraphReadinessRollupSchema, MetricCountSchema, ProjectIdSchema, ResourceRefSchema, } from "../../contracts/lib/schema.js";
4
+ import { BuildRunResourceSchema, ContextGraphResourceSchema, ContextGraphSessionResponseSchema, ContextGraphSessionsResponseSchema, InstanceResourceSchema, LocalJobRunResourceSchema, LocalServiceHealthSchema, ProjectCreateRequestSchema, ProjectBuildPlanAuthoringCreateRequestSchema, ProjectBuildRunCreateRequestSchema, ProjectListResponseSchema, ProjectResourceSchema, ProjectWireShapeSchema, ReadinessResourceSchema, RunArtifactsResponseSchema, RunEventsResponseSchema, RunStatusResourceSchema, SourceFileListResponseSchema, SourceManifestResourceSchema, } from "../schemas/index.js";
5
5
  const EmptyObjectSchema = z.object({}).strict();
6
6
  const OpenApiDocumentSchema = z.record(z.string(), z.unknown());
7
- const ProjectBuildRunCreateRequestSchema = BuildRunCreateRequestSchema
8
- .omit({ project: true })
9
- .strict();
10
- const PrepareBuildPlanRequestSchema = BuildPlanAuthoringCreateRequestSchema
11
- .omit({ project: true, source_folder_path: true })
12
- .strict();
7
+ const ContextGraphStagesResponseSchema = z.object({
8
+ stages: z.array(GraphManifestStageSummarySchema),
9
+ readiness: GraphReadinessRollupSchema.nullable(),
10
+ primary_metrics: z.array(MetricCountSchema),
11
+ }).strict();
12
+ const ContextGraphResourcesResponseSchema = z.object({
13
+ resources: z.array(ResourceRefSchema),
14
+ entrypoints: z.array(ResourceRefSchema),
15
+ graph_outputs: GraphOutputCountsSchema.nullable(),
16
+ }).strict();
17
+ const ContextGraphResourceRefResponseSchema = z.object({
18
+ resource: ResourceRefSchema,
19
+ stage: GraphManifestStageSummarySchema.nullable(),
20
+ linked_resources: z.array(ResourceRefSchema),
21
+ }).strict();
13
22
  const ProjectIdParameter = {
14
23
  name: "project_id",
15
24
  in: "path",
@@ -31,6 +40,20 @@ const ContextGraphFilePathParameter = {
31
40
  description: "Relative file path inside the latest Context Graph.",
32
41
  schema: z.string().min(1),
33
42
  };
43
+ const ContextGraphResourceIdParameter = {
44
+ name: "resource_id",
45
+ in: "path",
46
+ required: true,
47
+ description: "ResourceRef id from the latest Context Graph manifest.",
48
+ schema: z.string().min(1),
49
+ };
50
+ const StageRunIdParameter = {
51
+ name: "stage_run_id",
52
+ in: "path",
53
+ required: true,
54
+ description: "Stage execution session id from the latest Build run.",
55
+ schema: z.string().min(1),
56
+ };
34
57
  const RunFilePathParameter = {
35
58
  name: "path",
36
59
  in: "query",
@@ -72,13 +95,24 @@ export const SERVICE_OPERATIONS = [
72
95
  response_schema: OpenApiDocumentSchema,
73
96
  success_status: 200,
74
97
  },
98
+ {
99
+ id: "listProjects",
100
+ method: "GET",
101
+ path: "/v1/projects",
102
+ tags: ["Projects"],
103
+ summary: "List Projects",
104
+ description: "Return Projects registered on this instance with Source bindings, intent, Build Plan selection, and Context Graph locators.",
105
+ visibility: "app",
106
+ response_schema: ProjectListResponseSchema,
107
+ success_status: 200,
108
+ },
75
109
  {
76
110
  id: "createProject",
77
111
  method: "POST",
78
112
  path: "/v1/projects",
79
113
  tags: ["Projects"],
80
114
  summary: "Create Project",
81
- description: "Create a Project bound to one Source. Project ids may be generated by clients.",
115
+ description: "Create a Project bound to one Source and one agent task intent. Project ids may be generated by clients.",
82
116
  visibility: "app",
83
117
  workflow_step: 1,
84
118
  request_schema: ProjectCreateRequestSchema,
@@ -94,7 +128,7 @@ export const SERVICE_OPERATIONS = [
94
128
  description: "Read one Project to confirm its Source binding, selected Build Plan, readiness, and latest Context Graph.",
95
129
  visibility: "app",
96
130
  parameters: [ProjectIdParameter],
97
- response_schema: ProjectWireShapeSchema,
131
+ response_schema: ProjectResourceSchema,
98
132
  success_status: 200,
99
133
  },
100
134
  {
@@ -103,11 +137,11 @@ export const SERVICE_OPERATIONS = [
103
137
  path: "/v1/projects/{project_id}/build-plan-drafts",
104
138
  tags: ["Build Plans"],
105
139
  summary: "Prepare Build Plan",
106
- description: "Draft a Build Plan from the approved intent, Context Checks, and requested Artifacts. This does not run a Build.",
140
+ description: "Draft a Build Plan from the Project intent, requested outputs, and coverage expectations. This does not run a Build.",
107
141
  visibility: "app",
108
142
  workflow_step: 2,
109
143
  parameters: [ProjectIdParameter],
110
- request_schema: PrepareBuildPlanRequestSchema,
144
+ request_schema: ProjectBuildPlanAuthoringCreateRequestSchema,
111
145
  response_schema: LocalJobRunResourceSchema,
112
146
  success_status: 202,
113
147
  },
@@ -149,6 +183,18 @@ export const SERVICE_OPERATIONS = [
149
183
  response_schema: RunArtifactsResponseSchema,
150
184
  success_status: 200,
151
185
  },
186
+ {
187
+ id: "getRunEvents",
188
+ method: "GET",
189
+ path: "/v1/runs/{run_id}/events",
190
+ tags: ["Runs"],
191
+ summary: "Get Run events",
192
+ description: "Read the durable event log for a Build run: stage start/pass/fail, files processed, artifacts written, evidence, checks, and readiness. Use compact status for polling; read events to inspect or replay what happened.",
193
+ visibility: "app",
194
+ parameters: [RunIdParameter],
195
+ response_schema: RunEventsResponseSchema,
196
+ success_status: 200,
197
+ },
152
198
  {
153
199
  id: "readRunFile",
154
200
  method: "GET",
@@ -168,12 +214,84 @@ export const SERVICE_OPERATIONS = [
168
214
  path: "/v1/projects/{project_id}/context-graph",
169
215
  tags: ["Context Graphs"],
170
216
  summary: "Get latest Context Graph",
171
- description: "Return the latest successful Context Graph locator and readiness state for a Project. This is a compact locator/status read; read artifacts/ handoff files before answering.",
217
+ description: "Return the latest successful Context Graph locator, GraphManifest, primary metrics, StageManifest summaries, entrypoints, and ready/not ready rollup for a Project.",
172
218
  visibility: "app",
173
219
  parameters: [ProjectIdParameter],
174
220
  response_schema: ContextGraphResourceSchema,
175
221
  success_status: 200,
176
222
  },
223
+ {
224
+ id: "listContextGraphStages",
225
+ method: "GET",
226
+ path: "/v1/projects/{project_id}/context-graph/stages",
227
+ tags: ["Context Graphs"],
228
+ summary: "List Context Graph StageManifests",
229
+ description: "Return StageManifest summaries for the latest Context Graph.",
230
+ visibility: "app",
231
+ parameters: [ProjectIdParameter],
232
+ response_schema: ContextGraphStagesResponseSchema,
233
+ success_status: 200,
234
+ },
235
+ {
236
+ id: "listContextGraphResources",
237
+ method: "GET",
238
+ path: "/v1/projects/{project_id}/context-graph/resources",
239
+ tags: ["Context Graphs"],
240
+ summary: "List Context Graph resources",
241
+ description: "Return the ResourceRef index from the latest GraphManifest.",
242
+ visibility: "app",
243
+ parameters: [ProjectIdParameter],
244
+ response_schema: ContextGraphResourcesResponseSchema,
245
+ success_status: 200,
246
+ },
247
+ {
248
+ id: "listContextGraphSessions",
249
+ method: "GET",
250
+ path: "/v1/projects/{project_id}/context-graph/sessions",
251
+ tags: ["Context Graphs"],
252
+ summary: "List Context Graph execution sessions",
253
+ description: "Return replayable per-stage execution shell sessions for the latest Build run, including workspace, prompt, logs, validation attempts, and stage contract paths.",
254
+ visibility: "app",
255
+ parameters: [ProjectIdParameter],
256
+ response_schema: ContextGraphSessionsResponseSchema,
257
+ success_status: 200,
258
+ },
259
+ {
260
+ id: "getContextGraphResource",
261
+ method: "GET",
262
+ path: "/v1/projects/{project_id}/context-graph/resources/{resource_id}",
263
+ tags: ["Context Graphs"],
264
+ summary: "Get Context Graph resource",
265
+ description: "Return one ResourceRef from the latest GraphManifest for inspector drilldown.",
266
+ visibility: "app",
267
+ parameters: [ProjectIdParameter, ContextGraphResourceIdParameter],
268
+ response_schema: ContextGraphResourceRefResponseSchema,
269
+ success_status: 200,
270
+ },
271
+ {
272
+ id: "getContextGraphSession",
273
+ method: "GET",
274
+ path: "/v1/projects/{project_id}/context-graph/sessions/{stage_run_id}",
275
+ tags: ["Context Graphs"],
276
+ summary: "Get Context Graph execution session",
277
+ description: "Return one replayable stage execution shell session for inspector drilldown.",
278
+ visibility: "app",
279
+ parameters: [ProjectIdParameter, StageRunIdParameter],
280
+ response_schema: ContextGraphSessionResponseSchema,
281
+ success_status: 200,
282
+ },
283
+ {
284
+ id: "getProjectReadiness",
285
+ method: "GET",
286
+ path: "/v1/projects/{project_id}/readiness",
287
+ tags: ["Context Graphs"],
288
+ summary: "Get Project readiness",
289
+ description: "Read the ready/not ready verdict for the latest Context Graph against the Project intent.",
290
+ visibility: "app",
291
+ parameters: [ProjectIdParameter],
292
+ response_schema: ReadinessResourceSchema,
293
+ success_status: 200,
294
+ },
177
295
  {
178
296
  id: "listSourceFiles",
179
297
  method: "GET",
@@ -198,13 +316,25 @@ export const SERVICE_OPERATIONS = [
198
316
  response_schema: SourceManifestResourceSchema,
199
317
  success_status: 200,
200
318
  },
319
+ {
320
+ id: "getContextGraphEntrypoint",
321
+ method: "GET",
322
+ path: "/v1/projects/{project_id}/context-graph/entrypoint",
323
+ tags: ["Context Graphs"],
324
+ summary: "Get Context Graph entrypoint",
325
+ description: "Return the primary downstream entrypoint for the latest Context Graph. Agents should start from home.md.",
326
+ visibility: "app",
327
+ parameters: [ProjectIdParameter],
328
+ response_schema: ContextGraphHandoffSchema,
329
+ success_status: 200,
330
+ },
201
331
  {
202
332
  id: "readContextGraphFile",
203
333
  method: "GET",
204
334
  path: "/v1/projects/{project_id}/context-graph/file",
205
335
  tags: ["Context Graphs"],
206
336
  summary: "Read Context Graph file",
207
- description: "Read one file from the latest Context Graph by relative path. Start with artifacts/ task handoffs; use summaries/ for coverage proof and knowledge/ for drilldown.",
337
+ description: "Read one file from the latest Context Graph by relative path. Start with home.md; use knowledge/ for task-specific notes and summaries/ for source-backed coverage.",
208
338
  visibility: "app",
209
339
  parameters: [ProjectIdParameter, ContextGraphFilePathParameter],
210
340
  response_schema: z.string(),
@@ -228,8 +358,8 @@ export const SERVICE_OPERATIONS = [
228
358
  method: "GET",
229
359
  path: "/v1/projects/{project_id}/context-graph/evidence",
230
360
  tags: ["Context Graphs"],
231
- summary: "Get Build evidence",
232
- description: "Read checks, Artifact diagnostics, and readiness evidence for the latest Context Graph.",
361
+ summary: "Get graph diagnostics",
362
+ description: "Read supplemental diagnostic rows for the latest Context Graph. GraphManifest primary metrics are the authoritative coverage summary.",
233
363
  visibility: "app",
234
364
  parameters: [ProjectIdParameter],
235
365
  response_schema: BuildEvidenceResourceSchema,
@@ -57,15 +57,23 @@ export declare const PROJECT_SUBRESOURCES: {
57
57
  readonly contextGraph: "context-graph";
58
58
  /** First-class traces surface — per-claim provenance back to source. */
59
59
  readonly traces: "context-graph/traces";
60
- /** First-class Checks / Build evidence review resource. */
60
+ /** Stage Manifest summaries for the latest Context Graph. */
61
+ readonly contextGraphStages: "context-graph/stages";
62
+ /** Replayable stage execution shell sessions for the latest Build run. */
63
+ readonly contextGraphSessions: "context-graph/sessions";
64
+ /** ResourceRef index for the latest Context Graph. */
65
+ readonly contextGraphResources: "context-graph/resources";
66
+ /** Supplemental graph diagnostics. Graph Manifest metrics are authoritative. */
61
67
  readonly buildEvidence: "context-graph/evidence";
68
+ /** Primary downstream graph entrypoint. */
69
+ readonly contextGraphEntrypoint: "context-graph/entrypoint";
62
70
  /** Read a single Context Graph file using a query param: `?path=<relpath>`. */
63
71
  readonly contextGraphFile: "context-graph/file";
64
72
  /** Drift state for the Project's Source binding. */
65
73
  readonly sourceState: "source-state";
66
74
  /**
67
- * per-Artifact detail. Returns the latest status, contributing stages,
68
- * and check evidence for a Build Plan-declared Artifact:
75
+ * Per-output detail. Returns the latest status, contributing stages,
76
+ * and diagnostics for a Build Plan-declared requested output:
69
77
  * GET /v1/projects/<id>/artifacts/<artifact-id>
70
78
  */
71
79
  readonly artifacts: "artifacts";
@@ -58,15 +58,23 @@ export const PROJECT_SUBRESOURCES = {
58
58
  contextGraph: "context-graph",
59
59
  /** First-class traces surface — per-claim provenance back to source. */
60
60
  traces: "context-graph/traces",
61
- /** First-class Checks / Build evidence review resource. */
61
+ /** Stage Manifest summaries for the latest Context Graph. */
62
+ contextGraphStages: "context-graph/stages",
63
+ /** Replayable stage execution shell sessions for the latest Build run. */
64
+ contextGraphSessions: "context-graph/sessions",
65
+ /** ResourceRef index for the latest Context Graph. */
66
+ contextGraphResources: "context-graph/resources",
67
+ /** Supplemental graph diagnostics. Graph Manifest metrics are authoritative. */
62
68
  buildEvidence: "context-graph/evidence",
69
+ /** Primary downstream graph entrypoint. */
70
+ contextGraphEntrypoint: "context-graph/entrypoint",
63
71
  /** Read a single Context Graph file using a query param: `?path=<relpath>`. */
64
72
  contextGraphFile: "context-graph/file",
65
73
  /** Drift state for the Project's Source binding. */
66
74
  sourceState: "source-state",
67
75
  /**
68
- * per-Artifact detail. Returns the latest status, contributing stages,
69
- * and check evidence for a Build Plan-declared Artifact:
76
+ * Per-output detail. Returns the latest status, contributing stages,
77
+ * and diagnostics for a Build Plan-declared requested output:
70
78
  * GET /v1/projects/<id>/artifacts/<artifact-id>
71
79
  */
72
80
  artifacts: "artifacts",
@@ -35,12 +35,12 @@ export function sendDesktopAppBoot(req, res, runtime) {
35
35
  <script id="interf-app-boot" type="application/json">${json}</script>
36
36
  </head>
37
37
  <body>
38
- <p>Interf local service is running. Open Interf.app to use the desktop interface.</p>
38
+ <p>Interf local service is running.</p>
39
39
  </body>
40
40
  </html>
41
41
  `);
42
42
  return true;
43
43
  }
44
44
  export function sendServiceNotFound(res) {
45
- sendText(res, 404, "Not found. Open Interf.app for the desktop interface.\n");
45
+ sendText(res, 404, "Not found. Interf local service is running.\n");
46
46
  }
@@ -25,3 +25,14 @@ export declare function sendError(res: ServerResponse, statusCode: number, conte
25
25
  export declare function sendErrorResponse(res: ServerResponse, error: unknown, fallbackStatus?: number): void;
26
26
  export declare function readJsonBody(req: IncomingMessage): Promise<unknown>;
27
27
  export declare function parseRequestUrl(req: IncomingMessage): URL;
28
+ /**
29
+ * Decode a single percent-encoded path segment, or send a structured 400 and
30
+ * return `null`. `decodeURIComponent` throws a `URIError` on malformed input
31
+ * (e.g. a truncated escape like `%E0%A4%A`); left unguarded that crashes the
32
+ * handler into an uncaught 500. Routing every guarded call site through this
33
+ * helper keeps the decode semantics and the 400 message single-sourced.
34
+ *
35
+ * `label` names the id in the error message, e.g. `"Run id"` ->
36
+ * `"Run id is not valid URI-encoded UTF-8."`.
37
+ */
38
+ export declare function decodeOr400(res: ServerResponse, raw: string, label: string): string | null;
@@ -87,3 +87,22 @@ export async function readJsonBody(req) {
87
87
  export function parseRequestUrl(req) {
88
88
  return new URL(req.url ?? "/", "http://127.0.0.1");
89
89
  }
90
+ /**
91
+ * Decode a single percent-encoded path segment, or send a structured 400 and
92
+ * return `null`. `decodeURIComponent` throws a `URIError` on malformed input
93
+ * (e.g. a truncated escape like `%E0%A4%A`); left unguarded that crashes the
94
+ * handler into an uncaught 500. Routing every guarded call site through this
95
+ * helper keeps the decode semantics and the 400 message single-sourced.
96
+ *
97
+ * `label` names the id in the error message, e.g. `"Run id"` ->
98
+ * `"Run id is not valid URI-encoded UTF-8."`.
99
+ */
100
+ export function decodeOr400(res, raw, label) {
101
+ try {
102
+ return decodeURIComponent(raw);
103
+ }
104
+ catch {
105
+ sendError(res, 400, `${label} is not valid URI-encoded UTF-8.`);
106
+ return null;
107
+ }
108
+ }
@@ -1,5 +1,5 @@
1
1
  import { LOCAL_SERVICE_ROUTES } from "./routes.js";
2
- import { readJsonBody, sendError, sendJson, } from "./server-helpers.js";
2
+ import { decodeOr400, readJsonBody, sendError, sendJson, } from "./server-helpers.js";
3
3
  import { listStoredProjects } from "../project-store.js";
4
4
  export async function tryHandleActionProposals(req, res, runtime, path, method) {
5
5
  if (method === "GET" && path === LOCAL_SERVICE_ROUTES.actionProposals) {
@@ -17,7 +17,9 @@ export async function tryHandleActionProposals(req, res, runtime, path, method)
17
17
  }
18
18
  const actionProposalMatch = path.match(/^\/v1\/action-proposals\/([^/]+)(?:\/([^/]+))?$/);
19
19
  if (actionProposalMatch?.[1]) {
20
- const proposalId = decodeURIComponent(actionProposalMatch[1]);
20
+ const proposalId = decodeOr400(res, actionProposalMatch[1], "Action proposal id");
21
+ if (proposalId === null)
22
+ return true;
21
23
  const child = actionProposalMatch[2];
22
24
  const firstProject = listStoredProjects()[0];
23
25
  const projectDataDir = firstProject?.projectDataDir ?? runtime.rootPath;
@@ -1,8 +1,8 @@
1
1
  import { join } from "node:path";
2
- import { InterfMcpHandoffSchema } from "../schemas/index.js";
2
+ import { AgentPrefsPatchSchema, AgentRoleMapPatchSchema, CustomAgentRegisterRequestSchema, InterfMcpHandoffSchema, } from "../schemas/index.js";
3
3
  import { buildInterfMcpHandoff } from "../agent-handoff.js";
4
4
  import { buildLocalServiceUrl, LOCAL_SERVICE_ROUTES } from "./routes.js";
5
- import { readJsonBody, sendError, sendJson, } from "./server-helpers.js";
5
+ import { decodeOr400, readJsonBody, sendError, sendJson, } from "./server-helpers.js";
6
6
  import { packageRoot } from "./server-api-files.js";
7
7
  export async function tryHandleExecutor(req, res, runtime, path, method) {
8
8
  if (method === "GET" && path === LOCAL_SERVICE_ROUTES.executor) {
@@ -24,28 +24,8 @@ export async function tryHandleAgents(req, res, runtime, path, method) {
24
24
  }
25
25
  if (method === "POST") {
26
26
  try {
27
- const body = (await readJsonBody(req));
28
- if (!body || typeof body !== "object") {
29
- sendError(res, 400, "Request body must be a JSON object.");
30
- return true;
31
- }
32
- if (!body.name || typeof body.name !== "string") {
33
- sendError(res, 400, "Missing required field: name");
34
- return true;
35
- }
36
- if (!body.display_name || typeof body.display_name !== "string") {
37
- sendError(res, 400, "Missing required field: display_name");
38
- return true;
39
- }
40
- if (!body.command || typeof body.command !== "string") {
41
- sendError(res, 400, "Missing required field: command");
42
- return true;
43
- }
44
- const updated = runtime.registerCustomAgent({
45
- name: body.name,
46
- display_name: body.display_name,
47
- command: body.command,
48
- });
27
+ const body = CustomAgentRegisterRequestSchema.parse(await readJsonBody(req));
28
+ const updated = runtime.registerCustomAgent(body);
49
29
  sendJson(res, 201, updated);
50
30
  }
51
31
  catch (error) {
@@ -90,19 +70,7 @@ export async function tryHandleAgents(req, res, runtime, path, method) {
90
70
  }
91
71
  if (method === "PATCH") {
92
72
  try {
93
- const body = (await readJsonBody(req));
94
- if (!body || typeof body !== "object") {
95
- sendError(res, 400, "Request body must be a JSON object.");
96
- return true;
97
- }
98
- const patch = {};
99
- for (const [role, value] of Object.entries(body)) {
100
- if (typeof value !== "string") {
101
- sendError(res, 400, `Role-map values must be strings (or "" to clear). Got ${typeof value} for role "${role}".`);
102
- return true;
103
- }
104
- patch[role] = value;
105
- }
73
+ const patch = AgentRoleMapPatchSchema.parse(await readJsonBody(req));
106
74
  const updated = runtime.patchAgentsRoleMap(patch);
107
75
  sendJson(res, 200, updated);
108
76
  }
@@ -117,7 +85,9 @@ export async function tryHandleAgents(req, res, runtime, path, method) {
117
85
  // effort) for built-ins or custom agents alike.
118
86
  const agentMatch = path.match(/^\/v1\/agents\/([^/]+)$/);
119
87
  if (agentMatch?.[1] && method === "DELETE") {
120
- const name = decodeURIComponent(agentMatch[1]);
88
+ const name = decodeOr400(res, agentMatch[1], "Agent name");
89
+ if (name === null)
90
+ return true;
121
91
  try {
122
92
  const updated = runtime.unregisterCustomAgent(name);
123
93
  sendJson(res, 200, updated);
@@ -130,61 +100,25 @@ export async function tryHandleAgents(req, res, runtime, path, method) {
130
100
  return true;
131
101
  }
132
102
  if (agentMatch?.[1] && method === "PATCH") {
133
- const name = decodeURIComponent(agentMatch[1]);
103
+ const name = decodeOr400(res, agentMatch[1], "Agent name");
104
+ if (name === null)
105
+ return true;
134
106
  try {
135
- const body = (await readJsonBody(req));
136
- if (!body || typeof body !== "object") {
137
- sendError(res, 400, "Request body must be a JSON object.");
138
- return true;
139
- }
107
+ const body = AgentPrefsPatchSchema.parse(await readJsonBody(req));
108
+ // Normalize the validated patch into the stored prefs shape, preserving
109
+ // the prior wire tolerance: an empty env_vars map is omitted, and a `""`
110
+ // or `null` model/effort clears that pref.
140
111
  const prefs = {};
141
112
  if ("env_vars" in body) {
142
113
  const value = body.env_vars;
143
- if (value === null || value === undefined) {
144
- // explicit clear — no env_vars in prefs
145
- }
146
- else if (typeof value === "object" && !Array.isArray(value)) {
147
- const entries = {};
148
- for (const [k, v] of Object.entries(value)) {
149
- if (typeof v !== "string") {
150
- sendError(res, 400, `env_vars values must be strings. Got ${typeof v} for "${k}".`);
151
- return true;
152
- }
153
- entries[k] = v;
154
- }
155
- if (Object.keys(entries).length > 0)
156
- prefs.env_vars = entries;
157
- }
158
- else {
159
- sendError(res, 400, "env_vars must be an object of string→string entries.");
160
- return true;
161
- }
114
+ if (value && Object.keys(value).length > 0)
115
+ prefs.env_vars = value;
162
116
  }
163
117
  if ("model" in body) {
164
- const value = body.model;
165
- if (value === null || value === "" || value === undefined) {
166
- prefs.model = null;
167
- }
168
- else if (typeof value === "string") {
169
- prefs.model = value;
170
- }
171
- else {
172
- sendError(res, 400, "model must be a string or null.");
173
- return true;
174
- }
118
+ prefs.model = body.model === "" ? null : body.model ?? null;
175
119
  }
176
120
  if ("effort" in body) {
177
- const value = body.effort;
178
- if (value === null || value === "" || value === undefined) {
179
- prefs.effort = null;
180
- }
181
- else if (typeof value === "string") {
182
- prefs.effort = value;
183
- }
184
- else {
185
- sendError(res, 400, "effort must be a string or null.");
186
- return true;
187
- }
121
+ prefs.effort = body.effort === "" ? null : body.effort ?? null;
188
122
  }
189
123
  const updated = runtime.setAgentPrefs(name, prefs);
190
124
  sendJson(res, 200, updated);
@@ -1,6 +1,6 @@
1
1
  import { BuildPlanSaveRequestSchema } from "../schemas/index.js";
2
2
  import { LOCAL_SERVICE_ROUTES } from "./routes.js";
3
- import { readJsonBody, sendError, sendJson, } from "./server-helpers.js";
3
+ import { decodeOr400, readJsonBody, sendError, sendJson, } from "./server-helpers.js";
4
4
  import { isTraversalRelativePath, safeApiFilePath, sendApiFile, } from "./server-api-files.js";
5
5
  import { findInstanceBuildPlan, listInstanceBuildPlanRuns, listInstanceBuildPlans, resolveInstanceBuildPlanPackageRoot, } from "./server-instance-helpers.js";
6
6
  import { installUserBuildPlan } from "../../build-plans/package/user-build-plans.js";
@@ -30,7 +30,10 @@ export async function tryHandleBuildPlans(req, res, runtime, path, method) {
30
30
  }
31
31
  const buildPlanMatch = path.match(/^\/v1\/build-plans\/([^/]+)$/);
32
32
  if (method === "GET" && buildPlanMatch?.[1]) {
33
- const buildPlanResource = findInstanceBuildPlan(runtime, decodeURIComponent(buildPlanMatch[1]));
33
+ const buildPlanId = decodeOr400(res, buildPlanMatch[1], "Build Plan id");
34
+ if (buildPlanId === null)
35
+ return true;
36
+ const buildPlanResource = findInstanceBuildPlan(runtime, buildPlanId);
34
37
  if (!buildPlanResource)
35
38
  sendError(res, 404, "Build Plan not found.");
36
39
  else
@@ -39,7 +42,10 @@ export async function tryHandleBuildPlans(req, res, runtime, path, method) {
39
42
  }
40
43
  const buildPlanRunsMatch = path.match(/^\/v1\/build-plans\/([^/]+)\/runs$/);
41
44
  if (method === "GET" && buildPlanRunsMatch?.[1]) {
42
- const runs = listInstanceBuildPlanRuns(runtime, decodeURIComponent(buildPlanRunsMatch[1]));
45
+ const buildPlanId = decodeOr400(res, buildPlanRunsMatch[1], "Build Plan id");
46
+ if (buildPlanId === null)
47
+ return true;
48
+ const runs = listInstanceBuildPlanRuns(runtime, buildPlanId);
43
49
  sendJson(res, 200, { runs });
44
50
  return true;
45
51
  }
@@ -51,15 +57,12 @@ export async function tryHandleBuildPlans(req, res, runtime, path, method) {
51
57
  // the resolved root.
52
58
  const buildPlanFilesMatch = path.match(/^\/v1\/build-plans\/([^/]+)\/files\/(.+)$/);
53
59
  if (method === "GET" && buildPlanFilesMatch?.[1] && buildPlanFilesMatch[2]) {
54
- const buildPlanId = decodeURIComponent(buildPlanFilesMatch[1]);
55
- let relPath;
56
- try {
57
- relPath = decodeURIComponent(buildPlanFilesMatch[2]);
58
- }
59
- catch {
60
- sendError(res, 400, "File path is not valid URI-encoded UTF-8.");
60
+ const buildPlanId = decodeOr400(res, buildPlanFilesMatch[1], "Build Plan id");
61
+ if (buildPlanId === null)
62
+ return true;
63
+ const relPath = decodeOr400(res, buildPlanFilesMatch[2], "File path");
64
+ if (relPath === null)
61
65
  return true;
62
- }
63
66
  if (isTraversalRelativePath(relPath)) {
64
67
  sendError(res, 400, "File path escapes Build Plan root.");
65
68
  return true;