@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
@@ -11,9 +11,19 @@ export const ProjectIdSchema = z
11
11
  .refine((value) => !RESERVED_PROJECT_IDS.has(value), "Project name is reserved.");
12
12
  export const BuildPlanIdSchema = z.string().regex(InterfIdPattern);
13
13
  /**
14
- * Build Plan-declared artifact identifier. Same shape as `BuildPlanIdSchema`
15
- * but conceptually distinct — it identifies a produced thing inside
16
- * one Build Plan, while `BuildPlanIdSchema` identifies the Build Plan itself.
14
+ * The user's agent task for a Project.
15
+ *
16
+ * Project intent is the compact, durable instruction that explains what
17
+ * the Context Graph must prepare the Source for. Build Plans operationalize
18
+ * this field, but Project owns it.
19
+ */
20
+ export const ProjectIntentSchema = z.string().trim().min(1);
21
+ /**
22
+ * Legacy internal output identifier. Same shape as `BuildPlanIdSchema` but
23
+ * conceptually distinct: it identifies a requested output inside one Build
24
+ * Plan, while `BuildPlanIdSchema` identifies the Build Plan itself.
25
+ *
26
+ * The exported name remains `ArtifactIdSchema` until the ABI rename lands.
17
27
  */
18
28
  export const ArtifactIdSchema = z.string().regex(InterfIdPattern);
19
29
  export const RuntimeStageSchema = z.string().regex(InterfIdPattern);
@@ -64,6 +74,10 @@ export const LocatorSchema = z.object({
64
74
  // `internal/iterations/0.23-service-variant-parking-lot.md`.
65
75
  // ───────────────────────────────────────────────────────────────────────────
66
76
  export const SourceKindSchema = z.enum(["local-folder"]);
77
+ export const SourceBindingSchema = z.object({
78
+ kind: SourceKindSchema,
79
+ locator: z.string().min(1),
80
+ }).strict();
67
81
  export const SourceSchema = z.object({
68
82
  id: z.string().regex(InterfIdPattern),
69
83
  kind: SourceKindSchema,
@@ -94,7 +108,7 @@ export const SourceStateSchema = z.object({
94
108
  files: z.array(SourceFileSchema),
95
109
  }).strict();
96
110
  export const SourceInspectableUnitSchema = z.object({
97
- kind: z.enum(["page", "slide", "sheet", "table", "image", "section"]),
111
+ kind: z.enum(["file", "page", "slide", "sheet", "table", "image", "section"]),
98
112
  index: z.number().int().min(1).optional(),
99
113
  label: z.string().min(1).optional(),
100
114
  }).strict();
@@ -212,16 +226,237 @@ export const StageInputsSchema = z.object({
212
226
  export const SourceBuildMaxAttemptsSchema = z.number().int().min(1).max(5);
213
227
  export const SourceBuildMaxLoopsSchema = z.number().int().min(1).max(3);
214
228
  // ───────────────────────────────────────────────────────────────────────────
215
- // Check / Evidence / Ready the locked verification vocabulary
229
+ // Context Graph manifestscanonical coverage/runtime proof
230
+ // ───────────────────────────────────────────────────────────────────────────
231
+ export const ResourceRoleSchema = z.enum([
232
+ "source",
233
+ "summary",
234
+ "knowledge",
235
+ "entrypoint",
236
+ "diagnostic",
237
+ "other",
238
+ ]);
239
+ export const MetricKeySchema = z.string().regex(/^[a-z][a-z0-9_.:-]*$/);
240
+ export const ResourceRefSchema = z.object({
241
+ id: z.string().min(1),
242
+ role: ResourceRoleSchema,
243
+ kind: z.string().min(1),
244
+ label: z.string().min(1),
245
+ path: z.string().min(1).refine(isInterfRelativePath, {
246
+ message: "Resource paths must stay inside their root (no `..`, no absolute paths).",
247
+ }).optional(),
248
+ locator: z.string().min(1).optional(),
249
+ stage_id: RuntimeStageSchema.optional(),
250
+ source_refs: z.array(z.string().min(1)).default([]),
251
+ links: z.array(z.string().min(1)).default([]),
252
+ required: z.boolean().default(false),
253
+ metadata: z.record(z.string(), z.unknown()).optional(),
254
+ }).strict();
255
+ // metadata.guarantee groups a metric under one honest guarantee: "coverage" (every Source file read), "traceability" (every claim/summary/knowledge node linked). Verification (qa_match) is a separate fallible Check scope, never a coverage/traceability metric and never gates readiness.
256
+ export const MetricCountSchema = z.object({
257
+ key: MetricKeySchema,
258
+ label: z.string().min(1),
259
+ value: z.number().int().min(0),
260
+ total: z.number().int().min(0).optional(),
261
+ unit: z.string().min(1).optional(),
262
+ primary: z.boolean().default(false),
263
+ issue_state: z.enum(["pass", "missing", "review", "fail"]).optional(),
264
+ detail: z.string().min(1).optional(),
265
+ metadata: z.record(z.string(), z.unknown()).optional(),
266
+ }).strict().superRefine((value, ctx) => {
267
+ if (typeof value.total === "number" && value.value > value.total) {
268
+ ctx.addIssue({
269
+ code: z.ZodIssueCode.custom,
270
+ path: ["value"],
271
+ message: "Metric value cannot exceed total.",
272
+ });
273
+ }
274
+ });
275
+ export const ReviewedInputDecisionSchema = z.enum([
276
+ "used",
277
+ "reviewed",
278
+ "missing",
279
+ "blocked",
280
+ "not-relevant",
281
+ ]);
282
+ export const ReviewedInputSchema = z.object({
283
+ resource_id: z.string().min(1),
284
+ decision: ReviewedInputDecisionSchema,
285
+ reason: z.string().min(1).optional(),
286
+ output_resource_ids: z.array(z.string().min(1)).default([]),
287
+ source_refs: z.array(z.string().min(1)).default([]),
288
+ metadata: z.record(z.string(), z.unknown()).optional(),
289
+ }).strict();
290
+ export const MissingInputSchema = z.object({
291
+ resource_id: z.string().min(1),
292
+ status: z.enum(["missing", "blocked", "not-relevant"]),
293
+ reason: z.string().min(1),
294
+ }).strict();
295
+ /**
296
+ * Stage runtime-file contracts: the `expected-inputs.json` and
297
+ * `reviewed-inputs.json` files a stage shell reads and writes. Defined once
298
+ * here so the build engine (stage-manifest writer, native entrypoint reader)
299
+ * and any future client validate against one shape instead of a hand-rolled
300
+ * parallel `interface`.
301
+ */
302
+ export const ExpectedInputsFileSchema = z.object({
303
+ kind: z.literal("interf-stage-expected-inputs"),
304
+ version: z.literal(1),
305
+ generated_at: z.string().min(1),
306
+ stage_id: z.string().min(1),
307
+ expected: z.array(ResourceRefSchema),
308
+ }).strict();
309
+ export const ReviewedInputsFileSchema = z.object({
310
+ kind: z.literal("interf-stage-reviewed-inputs"),
311
+ version: z.literal(1),
312
+ generated_at: z.string().min(1),
313
+ stage_id: z.string().min(1),
314
+ reviewed: z.array(ReviewedInputSchema),
315
+ }).strict();
316
+ export const StageManifestSchema = z.object({
317
+ kind: z.literal("interf-stage-manifest"),
318
+ version: z.literal(1),
319
+ generated_at: z.string().min(1),
320
+ project: ProjectIdSchema,
321
+ run_id: z.string().min(1).nullable(),
322
+ build_plan: BuildPlanIdSchema,
323
+ stage_id: RuntimeStageSchema,
324
+ stage_label: z.string().min(1),
325
+ role: ResourceRoleSchema,
326
+ summary: z.string().min(1),
327
+ input_manifests: z.array(ResourceRefSchema).default([]),
328
+ expected: z.array(ResourceRefSchema).default([]),
329
+ reviewed: z.array(ReviewedInputSchema).default([]),
330
+ referenced: z.array(ResourceRefSchema).default([]),
331
+ missing: z.array(MissingInputSchema).default([]),
332
+ produced: z.array(ResourceRefSchema).default([]),
333
+ metrics: z.array(MetricCountSchema).default([]),
334
+ }).strict().superRefine((value, ctx) => {
335
+ for (const field of ["input_manifests", "expected", "referenced", "produced"]) {
336
+ const seen = new Set();
337
+ for (const [index, resource] of value[field].entries()) {
338
+ if (seen.has(resource.id)) {
339
+ ctx.addIssue({
340
+ code: z.ZodIssueCode.custom,
341
+ path: [field, index, "id"],
342
+ message: `Duplicate resource id: ${resource.id}.`,
343
+ });
344
+ }
345
+ seen.add(resource.id);
346
+ }
347
+ }
348
+ const expectedIds = new Set(value.expected.map((resource) => resource.id));
349
+ const producedIds = new Set(value.produced.map((resource) => resource.id));
350
+ const reviewedIds = new Set(value.reviewed.map((review) => review.resource_id));
351
+ const missingIds = new Set(value.missing.map((entry) => entry.resource_id));
352
+ for (const [index, review] of value.reviewed.entries()) {
353
+ if (!expectedIds.has(review.resource_id)) {
354
+ ctx.addIssue({
355
+ code: z.ZodIssueCode.custom,
356
+ path: ["reviewed", index, "resource_id"],
357
+ message: `Reviewed input "${review.resource_id}" is not in expected inputs.`,
358
+ });
359
+ }
360
+ for (const [outputIndex, outputId] of review.output_resource_ids.entries()) {
361
+ if (!producedIds.has(outputId)) {
362
+ ctx.addIssue({
363
+ code: z.ZodIssueCode.custom,
364
+ path: ["reviewed", index, "output_resource_ids", outputIndex],
365
+ message: `Reviewed input references unknown produced output "${outputId}".`,
366
+ });
367
+ }
368
+ }
369
+ }
370
+ for (const [index, entry] of value.missing.entries()) {
371
+ if (!expectedIds.has(entry.resource_id)) {
372
+ ctx.addIssue({
373
+ code: z.ZodIssueCode.custom,
374
+ path: ["missing", index, "resource_id"],
375
+ message: `Missing input "${entry.resource_id}" is not in expected inputs.`,
376
+ });
377
+ }
378
+ }
379
+ for (const [index, resource] of value.expected.entries()) {
380
+ if (resource.required !== true)
381
+ continue;
382
+ if (!reviewedIds.has(resource.id) && !missingIds.has(resource.id)) {
383
+ ctx.addIssue({
384
+ code: z.ZodIssueCode.custom,
385
+ path: ["expected", index, "id"],
386
+ message: `Required expected input "${resource.id}" must be reviewed or marked missing.`,
387
+ });
388
+ }
389
+ }
390
+ });
391
+ export const GraphManifestStageSummarySchema = z.object({
392
+ stage_id: RuntimeStageSchema,
393
+ stage_label: z.string().min(1),
394
+ role: ResourceRoleSchema,
395
+ manifest_path: z.string().min(1).refine(isInterfRelativePath, {
396
+ message: "Stage manifest paths must stay inside the Context Graph root.",
397
+ }),
398
+ summary: z.string().min(1),
399
+ produced_total: z.number().int().min(0),
400
+ missing_required_total: z.number().int().min(0),
401
+ metrics: z.array(MetricCountSchema).default([]),
402
+ }).strict();
403
+ export const GraphReadinessRollupSchema = z.object({
404
+ status: z.enum(["ready", "not-ready"]),
405
+ ready: z.boolean(),
406
+ summary: z.string().min(1),
407
+ context_graph_path: z.string().min(1).nullable().optional(),
408
+ missing_required_total: z.number().int().min(0),
409
+ missing: z.array(MissingInputSchema).default([]),
410
+ }).strict();
411
+ export const GraphOutputCountsSchema = z.object({
412
+ nodes: z.number().int().min(0),
413
+ edges: z.number().int().min(0),
414
+ notes: z.number().int().min(0),
415
+ links: z.number().int().min(0),
416
+ source_refs: z.number().int().min(0),
417
+ claims: z.number().int().min(0).optional(),
418
+ entities: z.number().int().min(0).optional(),
419
+ }).strict();
420
+ export const GraphManifestSchema = z.object({
421
+ kind: z.literal("interf-graph-manifest"),
422
+ version: z.literal(1),
423
+ generated_at: z.string().min(1),
424
+ project: ProjectIdSchema,
425
+ graph_id: z.string().min(1),
426
+ run_id: z.string().min(1).nullable(),
427
+ build_plan: BuildPlanIdSchema,
428
+ intent: ProjectIntentSchema.nullable(),
429
+ graph_path: z.string().min(1),
430
+ primary_metrics: z.array(MetricCountSchema).default([]),
431
+ stages: z.array(GraphManifestStageSummarySchema).default([]),
432
+ entrypoints: z.array(ResourceRefSchema).default([]),
433
+ resources: z.array(ResourceRefSchema).default([]),
434
+ graph_outputs: GraphOutputCountsSchema,
435
+ readiness: GraphReadinessRollupSchema,
436
+ }).strict().superRefine((value, ctx) => {
437
+ const resourceIds = new Set();
438
+ for (const [index, resource] of value.resources.entries()) {
439
+ if (resourceIds.has(resource.id)) {
440
+ ctx.addIssue({
441
+ code: z.ZodIssueCode.custom,
442
+ path: ["resources", index, "id"],
443
+ message: `Duplicate graph resource id: ${resource.id}.`,
444
+ });
445
+ }
446
+ resourceIds.add(resource.id);
447
+ }
448
+ });
449
+ // ───────────────────────────────────────────────────────────────────────────
450
+ // Check / Diagnostics / Ready — legacy verification primitives
216
451
  //
217
452
  // Three words doing three precise jobs:
218
453
  // - Check: the rule that must pass (with a `kind` and optional params)
219
- // - Evidence: records that a check ran (pass/fail + summary + details)
454
+ // - Diagnostics: records that a check ran (pass/fail + summary + details)
220
455
  // - Ready: aggregate verdict (`ready` or `not_ready`)
221
456
  //
222
457
  // A check has a SCOPE (where it's declared), not a different name:
223
458
  // - stage check — Build Plan-declared per stage; runs end-of-stage
224
- // - Artifact diagnostic — Build Plan-declared per artifact; runs end-of-build
459
+ // - Output diagnostic — Build Plan-declared per requested output; runs end-of-build
225
460
  // - benchmark check — Project-declared Q&A / fact check; runs on `interf benchmark`
226
461
  //
227
462
  // Same `Check` primitive across all three scopes. Same `CheckKind`
@@ -244,6 +479,9 @@ export const SourceBuildMaxLoopsSchema = z.number().int().min(1).max(3);
244
479
  * frontmatter_required_keys — every markdown file has these frontmatter keys (params: { keys: string[] })
245
480
  * frontmatter_nonempty_keys — every markdown file has non-empty values for these frontmatter keys
246
481
  * source_refs_required — every markdown file has non-empty source_refs/source_ref/source_path frontmatter
482
+ * summary_backlinks_present — every summary cited by a note's source_refs is also wikilinked from that layer (no orphaned summaries)
483
+ * knowledge_web_connectivity — every knowledge note links at least one OTHER knowledge note (no disconnected islands in the knowledge web)
484
+ * graph_notes_connected — every markdown note across the WHOLE Context Graph (summaries, knowledge, artifacts, home) is link-connected to at least one other note (no free-floating island anywhere, including uncited summaries)
247
485
  * wikilinks_valid — every wikilink resolves
248
486
  * must_not_contain — file/directory does not contain forbidden phrases (params: { phrases: string[] } or { text: string })
249
487
  * must_contain — file/directory contains required phrases (params: { phrases: string[] } or { text: string })
@@ -260,6 +498,9 @@ export const CHECK_KINDS = [
260
498
  "frontmatter_required_keys",
261
499
  "frontmatter_nonempty_keys",
262
500
  "source_refs_required",
501
+ "summary_backlinks_present",
502
+ "knowledge_web_connectivity",
503
+ "graph_notes_connected",
263
504
  "wikilinks_valid",
264
505
  "must_not_contain",
265
506
  "must_contain",
@@ -326,6 +567,26 @@ export const CHECK_PARAM_CONTRACTS = {
326
567
  },
327
568
  examples: [{ keys: ["source_refs"] }],
328
569
  },
570
+ summary_backlinks_present: {
571
+ params: {
572
+ summaries_dir: "optional summaries directory name; defaults to summaries",
573
+ summary_file: "optional summary filename; defaults to summary.md",
574
+ manifest_file: "optional manifest filename; defaults to manifest.md",
575
+ },
576
+ examples: [{}, { summaries_dir: "summaries" }],
577
+ },
578
+ knowledge_web_connectivity: {
579
+ params: {
580
+ knowledge_dir: "optional knowledge directory; defaults to the artifact's own target path. May only narrow the scan to a path inside that target layer.",
581
+ },
582
+ examples: [{}, { knowledge_dir: "knowledge" }],
583
+ },
584
+ graph_notes_connected: {
585
+ params: {
586
+ graph_root: "optional graph-root-relative directory to scan; defaults to the Context Graph root (every note in every layer). Use to narrow the floor to one layer (e.g. summaries) when a Build Plan splits the connectivity floor across outputs.",
587
+ },
588
+ examples: [{}, { graph_root: "summaries" }],
589
+ },
329
590
  wikilinks_valid: {
330
591
  params: {},
331
592
  examples: [{}],
@@ -393,10 +654,10 @@ export const ContextCheckStatusSchema = z.enum([
393
654
  "skipped",
394
655
  ]);
395
656
  /**
396
- * User-facing Build Plan check: the plain-English assertion the user
397
- * reviews as a Context Check. Requested Artifacts back these checks.
398
- * Deterministic Artifact diagnostics remain nested under Artifacts
399
- * and use `CheckSchema`.
657
+ * Legacy Build Plan check declaration. Current product surfaces should prefer
658
+ * concrete coverage metrics, Stage Manifests, and Graph Manifest readiness.
659
+ * Deterministic output diagnostics remain nested under requested outputs and
660
+ * use `CheckSchema`.
400
661
  */
401
662
  export const ContextCheckDeclarationSchema = z.object({
402
663
  id: z.string().regex(InterfIdPattern),
@@ -457,7 +718,7 @@ export const ArtifactPathShapeSchema = z.object({
457
718
  }).strict();
458
719
  export const ArtifactShapeSchema = ArtifactPathShapeSchema;
459
720
  /**
460
- * Build Plan-declared Artifact — a produced thing.
721
+ * Legacy internal requested-output schema.
461
722
  *
462
723
  * `checks[]` is the locked vocabulary: an array of `Check` (with
463
724
  * `kind` from `CHECK_KINDS`). The runtime evaluates them via the
@@ -484,10 +745,10 @@ export const ArtifactStatusSchema = z.object({
484
745
  summary: z.string().min(1).optional(),
485
746
  }).strict();
486
747
  // ───────────────────────────────────────────────────────────────────────────
487
- // Build evidence — user-visible readiness rows
748
+ // Supplemental graph diagnostics
488
749
  //
489
- // Check rows are the app-facing review primitive for a Build. They
490
- // deliberately keep the surface small:
750
+ // Diagnostic rows are secondary review records for a Build. They deliberately
751
+ // keep the surface small:
491
752
  // assertion label + metric + evidence link/ref + optional issue state
492
753
  //
493
754
  // Denominators are engine-owned (Source inventory or declared Build Plan
@@ -539,7 +800,7 @@ export const BuildEvidenceResourceSchema = z.object({
539
800
  summary: z.string().min(1),
540
801
  rows: z.array(BuildCheckRowSchema).default([]),
541
802
  }).strict();
542
- export const EvidenceCountKeySchema = z.string().regex(/^[a-z][a-z0-9_.:-]*$/);
803
+ export const EvidenceCountKeySchema = MetricKeySchema;
543
804
  export const StageEvidenceSourceRefSchema = z.object({
544
805
  path: z.string().min(1),
545
806
  source_file_id: z.string().min(1).optional(),
@@ -593,7 +854,7 @@ export const StageEvidenceSchema = z.object({
593
854
  // ───────────────────────────────────────────────────────────────────────────
594
855
  // Readiness — project-level aggregate verdict
595
856
  //
596
- // Rolls up Artifact diagnostics, benchmark results, and engine-level gates
857
+ // Rolls up output diagnostics, benchmark results, and engine-level gates
597
858
  // (is the project configured, has a Build, etc.) into a single
598
859
  // `ready` / `not_ready` answer for the ICP.
599
860
  // ───────────────────────────────────────────────────────────────────────────
@@ -621,7 +882,7 @@ export const ReadinessGateSchema = z.enum([
621
882
  * Per-gate status — one row in the readiness summary. A gate is a
622
883
  * high-level layer (is config valid? is the Context Graph built? did
623
884
  * the latest Build succeed?). Gate failures are aggregated alongside
624
- * Artifact diagnostic failures into the overall `Readiness` verdict.
885
+ * output diagnostic failures into the overall `Readiness` verdict.
625
886
  */
626
887
  export const GateStatusSchema = z.object({
627
888
  gate: ReadinessGateSchema,
@@ -1,3 +1,4 @@
1
+ export declare function isFilesystemArtifact(filePath: string): boolean;
1
2
  export declare function countFilesRecursive(dirPath: string): number;
2
3
  export declare function listFilesRecursive(dirPath: string, predicate?: (filePath: string) => boolean): string[];
3
4
  /**
@@ -1,6 +1,34 @@
1
1
  import { existsSync, readdirSync, realpathSync } from "node:fs";
2
2
  import { readdir, realpath } from "node:fs/promises";
3
- import { join } from "node:path";
3
+ import { basename, join } from "node:path";
4
+ /**
5
+ * OS-generated filesystem junk that is provably not user content: macOS
6
+ * `.DS_Store`, AppleDouble resource forks (`._name`), Spotlight/Trash sidecars,
7
+ * Windows `Thumbs.db` / `desktop.ini`. These are filesystem bookkeeping, not
8
+ * Source files, so they must never count as required/expected coverage units —
9
+ * otherwise a macOS Source folder shows "not ready" purely because Finder left
10
+ * a `.DS_Store` behind.
11
+ *
12
+ * This match is by filename only (deterministic, provable), never by an agent's
13
+ * `not-relevant` label. A real content gap an agent skipped is NOT matched here
14
+ * and still counts toward readiness.
15
+ */
16
+ const FILESYSTEM_ARTIFACT_NAMES = new Set([
17
+ ".DS_Store",
18
+ "Thumbs.db",
19
+ "desktop.ini",
20
+ "Icon\r",
21
+ ".localized",
22
+ ]);
23
+ export function isFilesystemArtifact(filePath) {
24
+ const name = basename(filePath.replace(/\\/g, "/"));
25
+ if (FILESYSTEM_ARTIFACT_NAMES.has(name))
26
+ return true;
27
+ // AppleDouble resource forks copied onto non-HFS volumes: `._<realname>`.
28
+ if (name.startsWith("._"))
29
+ return true;
30
+ return false;
31
+ }
4
32
  export function countFilesRecursive(dirPath) {
5
33
  if (!existsSync(dirPath))
6
34
  return 0;
@@ -1,6 +1,4 @@
1
1
  import { z } from "zod";
2
- import { BuildPlanIdSchema, ProjectIdSchema } from "../../contracts/lib/schema.js";
3
- import { RequestedArtifactCheckSchema, RequestedArtifactOutputSchema, RequestedArtifactSchema, SourceContextSchema } from "../../build-plans/authoring/brief.js";
4
2
  export { BuildPlanIdSchema, ProjectIdSchema, } from "../../contracts/lib/schema.js";
5
3
  export declare const BenchmarkCheckSchema: z.ZodObject<{
6
4
  id: z.ZodOptional<z.ZodString>;
@@ -19,6 +17,7 @@ export { RequestedArtifactCheckSchema, RequestedArtifactOutputSchema, RequestedA
19
17
  export declare const ProjectConfigSchema: z.ZodObject<{
20
18
  id: z.ZodOptional<z.ZodString>;
21
19
  name: z.ZodString;
20
+ intent: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
22
21
  path: z.ZodString;
23
22
  build_plan: z.ZodOptional<z.ZodString>;
24
23
  latest_context_graph_run_id: z.ZodOptional<z.ZodString>;
@@ -29,6 +28,7 @@ export declare const SourceFolderBindingSchema: z.ZodObject<{
29
28
  export declare const ContextGraphInterfConfigSchema: z.ZodObject<{
30
29
  type: z.ZodLiteral<"context-graph">;
31
30
  name: z.ZodString;
31
+ intent: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
32
32
  build_plan: z.ZodString;
33
33
  build_plan_origin: z.ZodOptional<z.ZodObject<{
34
34
  selected: z.ZodString;
@@ -43,6 +43,7 @@ export declare const ContextGraphInterfConfigSchema: z.ZodObject<{
43
43
  export declare const InterfConfigSchema: z.ZodObject<{
44
44
  type: z.ZodLiteral<"context-graph">;
45
45
  name: z.ZodString;
46
+ intent: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
46
47
  build_plan: z.ZodString;
47
48
  build_plan_origin: z.ZodOptional<z.ZodObject<{
48
49
  selected: z.ZodString;
@@ -61,19 +62,16 @@ export declare const SourceFolderConfigSchema: z.ZodObject<{
61
62
  projects: z.ZodDefault<z.ZodArray<z.ZodObject<{
62
63
  id: z.ZodOptional<z.ZodString>;
63
64
  name: z.ZodString;
65
+ intent: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
64
66
  path: z.ZodString;
65
67
  build_plan: z.ZodOptional<z.ZodString>;
66
68
  latest_context_graph_run_id: z.ZodOptional<z.ZodString>;
67
69
  }, z.core.$strict>>>;
68
70
  }, z.core.$strict>;
69
71
  export type SourceFolderBinding = z.infer<typeof SourceFolderBindingSchema>;
70
- export type RequestedArtifactCheck = z.infer<typeof RequestedArtifactCheckSchema>;
71
- export type RequestedArtifact = z.infer<typeof RequestedArtifactSchema>;
72
- export type RequestedArtifactOutput = z.infer<typeof RequestedArtifactOutputSchema>;
73
72
  export type BenchmarkCheck = z.infer<typeof BenchmarkCheckSchema>;
74
- export type SourceContext = z.infer<typeof SourceContextSchema>;
75
- export type ProjectId = z.infer<typeof ProjectIdSchema>;
76
- export type BuildPlanId = z.infer<typeof BuildPlanIdSchema>;
77
73
  export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
74
+ export type { RequestedArtifactCheck, RequestedArtifact, RequestedArtifactOutput, SourceContext, } from "../../build-plans/authoring/brief.js";
75
+ export type { ProjectId, BuildPlanId, ProjectIntent, } from "../../contracts/lib/schema.js";
78
76
  export type InterfConfig = z.infer<typeof InterfConfigSchema>;
79
77
  export type SourceFolderConfig = z.infer<typeof SourceFolderConfigSchema>;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { InterfIdPattern, BuildPlanIdSchema, ProjectIdSchema, TestCaseExpectSchema, } from "../../contracts/lib/schema.js";
2
+ import { InterfIdPattern, BuildPlanIdSchema, ProjectIdSchema, ProjectIntentSchema, TestCaseExpectSchema, } from "../../contracts/lib/schema.js";
3
3
  export { BuildPlanIdSchema, ProjectIdSchema, } from "../../contracts/lib/schema.js";
4
4
  /**
5
5
  * Absolute paths that an attacker-controlled config must never reach. The
@@ -52,6 +52,7 @@ export { RequestedArtifactCheckSchema, RequestedArtifactOutputSchema, RequestedA
52
52
  export const ProjectConfigSchema = z.object({
53
53
  id: z.string().regex(InterfIdPattern).optional(),
54
54
  name: ProjectIdSchema,
55
+ intent: ProjectIntentSchema.or(z.literal("")).default(""),
55
56
  path: z
56
57
  .string()
57
58
  .min(1)
@@ -70,6 +71,7 @@ export const SourceFolderBindingSchema = z.object({
70
71
  export const ContextGraphInterfConfigSchema = z.object({
71
72
  type: z.literal("context-graph"),
72
73
  name: ProjectIdSchema,
74
+ intent: ProjectIntentSchema.or(z.literal("")).default(""),
73
75
  build_plan: BuildPlanIdSchema,
74
76
  build_plan_origin: z.object({
75
77
  selected: BuildPlanIdSchema,
@@ -1,6 +1,5 @@
1
1
  import { type InterfConfig, type SourceFolderBinding, type BenchmarkCheck, type ProjectConfig, type SourceFolderConfig } from "./lib/schema.js";
2
2
  import type { TestSpec, TestTargetType } from "../runtime/verify/lib/schema.js";
3
- export declare const SOURCE_FOLDER_CONFIG_PATH = "interf.json";
4
3
  interface LoadedSourceTestSpec extends TestSpec {
5
4
  id: string;
6
5
  filePath: string;
@@ -16,16 +15,13 @@ export { DEFAULT_BUILD_PLAN_ID, buildPlanIdForProjectConfig } from "../build-pla
16
15
  export declare function listProjectConfigs(config: SourceFolderConfig | null): ProjectConfig[];
17
16
  export declare function resolveBuildMaxAttempts(override?: number | null): number | null;
18
17
  export declare function resolveBuildMaxLoops(override?: number | null): number | null;
19
- export declare function getDefaultProjectConfig(config: SourceFolderConfig | null): ProjectConfig | null;
20
18
  export declare function findProjectConfig(config: SourceFolderConfig | null, projectId: string): ProjectConfig | null;
21
- export declare function configuredSourceFolderPath(config: SourceFolderConfig | WritableSourceFolderConfig | null | undefined): string | null;
22
19
  export declare function resolveConfiguredSourceFolderPath(projectDataDir: string, config?: SourceFolderConfig | WritableSourceFolderConfig | null | undefined): string | null;
23
20
  export declare function saveSourceFolderConfig(projectDataDir: string, config: WritableSourceFolderConfig): void;
24
21
  export declare function upsertProjectConfig(projectDataDir: string, projectConfig: ProjectConfig, options?: {
25
22
  matchName?: string;
26
23
  }): void;
27
24
  export declare function markProjectLatestContextGraphRun(projectDataDir: string, projectName: string, runId: string): ProjectConfig;
28
- export declare function removeProjectConfig(projectDataDir: string, projectId: string): boolean;
29
25
  export declare function projectConfigFromInterfConfig(config: InterfConfig, projectPath?: string): ProjectConfig;
30
26
  export declare function loadContextGraphProjectConfig(contextGraphPath: string): ProjectConfig | null;
31
27
  export declare function saveContextGraphInterfConfig(contextGraphPath: string, config: InterfConfig): InterfConfig;
@@ -48,7 +44,6 @@ export declare function writeBenchmarkSpecsForProject(options: {
48
44
  source_files?: string;
49
45
  context_graph?: string;
50
46
  };
51
- export declare function fingerprintTestSpec(spec: Pick<TestSpec, "cases">): string;
52
47
  export declare function fingerprintSavedBenchmarkSpec(options: {
53
48
  projectDataDir: string;
54
49
  projectName: string;
@@ -12,8 +12,7 @@ import { listTestSpecs, writeTestSpec, } from "../runtime/verify/verify-specs.js
12
12
  import { slugify } from "../contracts/utils/naming.js";
13
13
  import { assertPathWithinRoot, isPathWithinRoot } from "../contracts/utils/path-guards.js";
14
14
  import { defaultControlPathForContextGraph, resolveSourceControlPathForContextGraph, contextGraphInterfConfigPath, contextGraphInterfRoot, } from "../runtime/build/context-graph-paths.js";
15
- import { asProjectDataDir, projectConfigPath, PROJECT_CONFIG_FILENAME, } from "../contracts/lib/project-paths.js";
16
- export const SOURCE_FOLDER_CONFIG_PATH = PROJECT_CONFIG_FILENAME;
15
+ import { asProjectDataDir, projectConfigPath, } from "../contracts/lib/project-paths.js";
17
16
  export function sourceFolderConfigPath(projectDataDir) {
18
17
  return projectConfigPath(asProjectDataDir(projectDataDir));
19
18
  }
@@ -85,18 +84,11 @@ export function resolveBuildMaxLoops(override = null) {
85
84
  return 1;
86
85
  return Math.min(3, normalized);
87
86
  }
88
- export function getDefaultProjectConfig(config) {
89
- const projects = listProjectConfigs(config);
90
- return projects[0] ?? null;
91
- }
92
87
  export function findProjectConfig(config, projectId) {
93
88
  return listProjectConfigs(config).find((project) => project.name === projectId) ?? null;
94
89
  }
95
- export function configuredSourceFolderPath(config) {
96
- return config?.source_folder?.path ?? null;
97
- }
98
90
  export function resolveConfiguredSourceFolderPath(projectDataDir, config = loadSourceFolderConfig(projectDataDir)) {
99
- const configuredPath = configuredSourceFolderPath(config);
91
+ const configuredPath = config?.source_folder?.path ?? null;
100
92
  return configuredPath ? resolve(projectDataDir, configuredPath) : null;
101
93
  }
102
94
  function toWritableSourceFolderConfig(config) {
@@ -115,8 +107,12 @@ function toWritableSourceFolderConfig(config) {
115
107
  }
116
108
  function toWritableProjectConfig(project) {
117
109
  const buildPlan = buildPlanIdForProjectConfig(project);
110
+ const intent = typeof project.intent === "string" && project.intent.trim().length > 0
111
+ ? project.intent.trim()
112
+ : "";
118
113
  return {
119
114
  name: project.name,
115
+ intent,
120
116
  path: project.path,
121
117
  ...(buildPlan ? { build_plan: buildPlan } : {}),
122
118
  ...(project.latest_context_graph_run_id ? { latest_context_graph_run_id: project.latest_context_graph_run_id } : {}),
@@ -158,20 +154,10 @@ export function markProjectLatestContextGraphRun(projectDataDir, projectName, ru
158
154
  upsertProjectConfig(projectDataDir, next);
159
155
  return next;
160
156
  }
161
- export function removeProjectConfig(projectDataDir, projectId) {
162
- const existing = loadSourceFolderConfig(projectDataDir);
163
- const projects = listProjectConfigs(existing);
164
- const nextProjects = projects.filter((entry) => entry.name !== projectId);
165
- if (nextProjects.length === projects.length)
166
- return false;
167
- saveSourceFolderConfig(projectDataDir, {
168
- projects: nextProjects,
169
- });
170
- return true;
171
- }
172
157
  export function projectConfigFromInterfConfig(config, projectPath = `./${config.name}`) {
173
158
  return {
174
159
  name: config.name,
160
+ intent: config.intent ?? "",
175
161
  path: projectPath,
176
162
  build_plan: config.build_plan,
177
163
  };
@@ -228,6 +214,7 @@ export function syncContextGraphInterfConfigFromProjectConfig(contextGraphPath,
228
214
  } : {}),
229
215
  type: "context-graph",
230
216
  name: projectConfig.name,
217
+ intent: projectConfig.intent ?? "",
231
218
  build_plan: buildPlanId,
232
219
  build_plan_origin: buildPlanOrigin,
233
220
  source: {
@@ -288,7 +275,7 @@ export function writeBenchmarkSpecsForProject(options) {
288
275
  context_graph: writeTestSpec(options.projectDataDir, { ...baseSpec, type: "context-graph" }, { overwrite: true }),
289
276
  };
290
277
  }
291
- export function fingerprintTestSpec(spec) {
278
+ function fingerprintTestSpec(spec) {
292
279
  const normalized = spec.cases.map((testCase) => ({
293
280
  question: testCase.question.trim(),
294
281
  ...(testCase.file ? { file: testCase.file.trim() } : {}),
@@ -45,6 +45,7 @@ export type CreateProjectActionContext = {
45
45
  buildPlans: BuildPlanActionChoice[];
46
46
  projectDataDir: string;
47
47
  suggestedName: string;
48
+ suggestedIntent?: string;
48
49
  };
49
50
  export type BuildRunActionContext = {
50
51
  buildPlanId: string;
@@ -54,12 +55,14 @@ export type BuildRunActionContext = {
54
55
  export type SelectBuildPlanActionContext = {
55
56
  currentBuildPlanId?: string | null;
56
57
  buildPlans: BuildPlanActionChoice[];
58
+ intent: string;
57
59
  name: string;
58
60
  sourceFolderPath: string;
59
61
  };
60
62
  export type CreateBuildPlanActionContext = {
61
63
  defaultProject: string;
62
64
  existingBuildPlanIds: string[];
65
+ projectIntent?: string | null;
63
66
  suggestedBuildPlanId: string;
64
67
  };
65
68
  export type BuildPlanChangeAction = "modify" | "duplicate" | "remove";
@@ -77,6 +80,7 @@ export type ProjectChangeActionContext = {
77
80
  action: ProjectChangeAction;
78
81
  existingNames: string[];
79
82
  buildPlanId?: string | null;
83
+ intent: string;
80
84
  project: string;
81
85
  sourceFolderPath: string;
82
86
  };