@interf/compiler 0.9.5 → 0.13.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 (214) hide show
  1. package/README.md +96 -92
  2. package/TRADEMARKS.md +2 -13
  3. package/agent-skills/interf-actions/SKILL.md +95 -36
  4. package/agent-skills/interf-actions/references/cli.md +118 -51
  5. package/builtin-methods/interf-default/README.md +3 -4
  6. package/builtin-methods/interf-default/compile/stages/shape/SKILL.md +2 -2
  7. package/builtin-methods/interf-default/compile/stages/summarize/SKILL.md +2 -1
  8. package/builtin-methods/interf-default/improve/SKILL.md +1 -1
  9. package/builtin-methods/interf-default/method.json +10 -4
  10. package/builtin-methods/interf-default/method.schema.json +0 -9
  11. package/builtin-methods/interf-default/use/query/SKILL.md +5 -5
  12. package/dist/cli/commands/compile.d.ts +8 -25
  13. package/dist/cli/commands/compile.js +75 -360
  14. package/dist/cli/commands/doctor.js +1 -1
  15. package/dist/cli/commands/login.d.ts +7 -0
  16. package/dist/cli/commands/login.js +39 -0
  17. package/dist/cli/commands/logout.d.ts +2 -0
  18. package/dist/cli/commands/logout.js +16 -0
  19. package/dist/cli/commands/method.d.ts +2 -0
  20. package/dist/cli/commands/method.js +113 -0
  21. package/dist/cli/commands/prep.d.ts +2 -0
  22. package/dist/cli/commands/prep.js +134 -0
  23. package/dist/cli/commands/reset.d.ts +8 -1
  24. package/dist/cli/commands/reset.js +47 -26
  25. package/dist/cli/commands/runs.d.ts +2 -0
  26. package/dist/cli/commands/runs.js +120 -0
  27. package/dist/cli/commands/status.d.ts +6 -1
  28. package/dist/cli/commands/status.js +68 -111
  29. package/dist/cli/commands/test.d.ts +6 -14
  30. package/dist/cli/commands/test.js +65 -181
  31. package/dist/cli/commands/web.d.ts +0 -9
  32. package/dist/cli/commands/web.js +147 -120
  33. package/dist/cli/commands/wizard.d.ts +9 -0
  34. package/dist/cli/commands/wizard.js +442 -0
  35. package/dist/cli/index.d.ts +7 -6
  36. package/dist/cli/index.js +13 -10
  37. package/dist/compiler-ui/404.html +1 -1
  38. package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
  39. package/dist/compiler-ui/__next._full.txt +3 -3
  40. package/dist/compiler-ui/__next._head.txt +1 -1
  41. package/dist/compiler-ui/__next._index.txt +2 -2
  42. package/dist/compiler-ui/__next._tree.txt +2 -2
  43. package/dist/compiler-ui/_next/static/chunks/{18a8f2jkv3z.c.css → 045gole2ojo3g.css} +1 -1
  44. package/dist/compiler-ui/_next/static/chunks/{177mvn4rse235.js → 17t-lulmyawg5.js} +9 -9
  45. package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
  46. package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
  47. package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
  48. package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  49. package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
  50. package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
  51. package/dist/compiler-ui/_not-found.html +1 -1
  52. package/dist/compiler-ui/_not-found.txt +2 -2
  53. package/dist/compiler-ui/index.html +1 -1
  54. package/dist/compiler-ui/index.txt +3 -3
  55. package/dist/packages/agents/lib/shells.d.ts +1 -1
  56. package/dist/packages/agents/lib/shells.js +111 -52
  57. package/dist/packages/agents/lib/user-config.d.ts +4 -2
  58. package/dist/packages/agents/lib/user-config.js +15 -7
  59. package/dist/packages/compiler/compiled-paths.d.ts +9 -2
  60. package/dist/packages/compiler/compiled-paths.js +30 -15
  61. package/dist/packages/compiler/compiled-pipeline.js +23 -3
  62. package/dist/packages/compiler/compiled-stage-plan.js +4 -0
  63. package/dist/packages/compiler/compiled-target.d.ts +1 -1
  64. package/dist/packages/compiler/compiled-target.js +1 -1
  65. package/dist/packages/compiler/index.d.ts +1 -0
  66. package/dist/packages/compiler/index.js +1 -0
  67. package/dist/packages/compiler/lib/schema.d.ts +26 -31
  68. package/dist/packages/compiler/lib/schema.js +1 -12
  69. package/dist/packages/compiler/method-runs.d.ts +2 -3
  70. package/dist/packages/compiler/method-runs.js +2 -3
  71. package/dist/packages/compiler/reset.js +3 -1
  72. package/dist/packages/compiler/runtime-contracts.js +0 -3
  73. package/dist/packages/compiler/runtime-prompt.js +1 -1
  74. package/dist/packages/compiler/source-files.d.ts +46 -0
  75. package/dist/packages/compiler/source-files.js +149 -0
  76. package/dist/packages/compiler/state-artifacts.d.ts +3 -2
  77. package/dist/packages/compiler/state-artifacts.js +4 -3
  78. package/dist/packages/compiler/state-io.d.ts +3 -2
  79. package/dist/packages/compiler/state-io.js +11 -5
  80. package/dist/packages/compiler/state-paths.d.ts +2 -1
  81. package/dist/packages/compiler/state-paths.js +6 -3
  82. package/dist/packages/compiler/state-view.d.ts +3 -2
  83. package/dist/packages/compiler/state-view.js +18 -28
  84. package/dist/packages/compiler/state.d.ts +4 -4
  85. package/dist/packages/compiler/state.js +3 -3
  86. package/dist/packages/contracts/index.d.ts +1 -1
  87. package/dist/packages/contracts/lib/preparation-paths.d.ts +117 -0
  88. package/dist/packages/contracts/lib/preparation-paths.js +177 -0
  89. package/dist/packages/contracts/lib/schema.d.ts +85 -5
  90. package/dist/packages/contracts/lib/schema.js +46 -1
  91. package/dist/packages/execution/lib/schema.d.ts +50 -50
  92. package/dist/packages/execution/lib/schema.js +1 -1
  93. package/dist/packages/local-service/action-definitions.d.ts +14 -14
  94. package/dist/packages/local-service/action-definitions.js +27 -28
  95. package/dist/packages/local-service/action-planner.js +2 -1
  96. package/dist/packages/local-service/client.d.ts +51 -52
  97. package/dist/packages/local-service/client.js +132 -140
  98. package/dist/packages/local-service/connection-config.d.ts +38 -0
  99. package/dist/packages/local-service/connection-config.js +75 -0
  100. package/dist/packages/local-service/index.d.ts +11 -7
  101. package/dist/packages/local-service/index.js +6 -4
  102. package/dist/packages/local-service/instance-paths.d.ts +100 -0
  103. package/dist/packages/local-service/instance-paths.js +165 -0
  104. package/dist/packages/local-service/lib/schema.d.ts +405 -2297
  105. package/dist/packages/local-service/lib/schema.js +146 -62
  106. package/dist/packages/local-service/native-run-handlers.js +3 -3
  107. package/dist/packages/local-service/preparation-store.d.ts +92 -0
  108. package/dist/packages/local-service/preparation-store.js +171 -0
  109. package/dist/packages/local-service/routes.d.ts +33 -16
  110. package/dist/packages/local-service/routes.js +44 -20
  111. package/dist/packages/local-service/run-observability.js +11 -11
  112. package/dist/packages/local-service/runtime-caches.d.ts +76 -0
  113. package/dist/packages/local-service/runtime-caches.js +191 -0
  114. package/dist/packages/local-service/runtime-event-applier.d.ts +12 -0
  115. package/dist/packages/local-service/runtime-event-applier.js +177 -0
  116. package/dist/packages/local-service/runtime-persistence.d.ts +47 -0
  117. package/dist/packages/local-service/runtime-persistence.js +137 -0
  118. package/dist/packages/local-service/runtime-proposal-helpers.d.ts +35 -0
  119. package/dist/packages/local-service/runtime-proposal-helpers.js +251 -0
  120. package/dist/packages/local-service/runtime-resource-builders.d.ts +52 -0
  121. package/dist/packages/local-service/runtime-resource-builders.js +149 -0
  122. package/dist/packages/local-service/runtime.d.ts +197 -43
  123. package/dist/packages/local-service/runtime.js +800 -974
  124. package/dist/packages/local-service/server.d.ts +15 -0
  125. package/dist/packages/local-service/server.js +641 -273
  126. package/dist/packages/local-service/service-registry.d.ts +47 -0
  127. package/dist/packages/local-service/service-registry.js +137 -0
  128. package/dist/packages/method-authoring/method-authoring.d.ts +1 -1
  129. package/dist/packages/method-authoring/method-authoring.js +2 -2
  130. package/dist/packages/method-authoring/method-improvement.js +1 -1
  131. package/dist/packages/method-package/builtin-compiled-method.d.ts +4 -5
  132. package/dist/packages/method-package/builtin-compiled-method.js +8 -14
  133. package/dist/packages/method-package/context-interface.d.ts +4 -40
  134. package/dist/packages/method-package/context-interface.js +1 -23
  135. package/dist/packages/method-package/interf-method-package.d.ts +4 -4
  136. package/dist/packages/method-package/interf-method-package.js +21 -33
  137. package/dist/packages/method-package/local-methods.d.ts +10 -6
  138. package/dist/packages/method-package/local-methods.js +57 -39
  139. package/dist/packages/method-package/method-definitions.d.ts +8 -34
  140. package/dist/packages/method-package/method-definitions.js +49 -37
  141. package/dist/packages/method-package/method-helpers.d.ts +1 -13
  142. package/dist/packages/method-package/method-helpers.js +8 -42
  143. package/dist/packages/method-package/method-stage-runner.js +2 -2
  144. package/dist/packages/method-package/user-methods.d.ts +17 -0
  145. package/dist/packages/method-package/user-methods.js +77 -0
  146. package/dist/packages/project-model/index.d.ts +0 -1
  147. package/dist/packages/project-model/index.js +0 -1
  148. package/dist/packages/project-model/interf-detect.d.ts +8 -3
  149. package/dist/packages/project-model/interf-detect.js +34 -34
  150. package/dist/packages/project-model/interf-scaffold.d.ts +3 -3
  151. package/dist/packages/project-model/interf-scaffold.js +23 -32
  152. package/dist/packages/project-model/lib/schema.js +38 -1
  153. package/dist/packages/project-model/preparation-entries.d.ts +5 -5
  154. package/dist/packages/project-model/preparation-entries.js +14 -14
  155. package/dist/packages/project-model/source-config.d.ts +11 -11
  156. package/dist/packages/project-model/source-config.js +74 -46
  157. package/dist/packages/project-model/source-folders.d.ts +5 -5
  158. package/dist/packages/project-model/source-folders.js +14 -14
  159. package/dist/packages/shared/filesystem.d.ts +7 -0
  160. package/dist/packages/shared/filesystem.js +97 -10
  161. package/dist/packages/testing/lib/schema.d.ts +10 -10
  162. package/dist/packages/testing/lib/schema.js +2 -2
  163. package/dist/packages/testing/readiness-check-run.d.ts +4 -4
  164. package/dist/packages/testing/readiness-check-run.js +36 -36
  165. package/dist/packages/testing/test-execution.js +6 -6
  166. package/dist/packages/testing/test-paths.js +4 -3
  167. package/dist/packages/testing/test-sandbox.d.ts +0 -1
  168. package/dist/packages/testing/test-sandbox.js +14 -30
  169. package/dist/packages/testing/test-targets.d.ts +1 -1
  170. package/dist/packages/testing/test-targets.js +6 -6
  171. package/dist/packages/testing/test.d.ts +1 -1
  172. package/dist/packages/testing/test.js +1 -1
  173. package/package.json +3 -4
  174. package/CHANGELOG.md +0 -93
  175. package/LICENSE +0 -183
  176. package/dist/cli/commands/action-input-cli.d.ts +0 -25
  177. package/dist/cli/commands/action-input-cli.js +0 -73
  178. package/dist/cli/commands/control-path.d.ts +0 -11
  179. package/dist/cli/commands/control-path.js +0 -72
  180. package/dist/cli/commands/create-method-wizard.d.ts +0 -64
  181. package/dist/cli/commands/create-method-wizard.js +0 -434
  182. package/dist/cli/commands/create.d.ts +0 -6
  183. package/dist/cli/commands/create.js +0 -183
  184. package/dist/cli/commands/default.d.ts +0 -2
  185. package/dist/cli/commands/default.js +0 -39
  186. package/dist/cli/commands/executor-flow.d.ts +0 -29
  187. package/dist/cli/commands/executor-flow.js +0 -163
  188. package/dist/cli/commands/init.d.ts +0 -26
  189. package/dist/cli/commands/init.js +0 -771
  190. package/dist/cli/commands/list.d.ts +0 -2
  191. package/dist/cli/commands/list.js +0 -30
  192. package/dist/cli/commands/preparation-action.d.ts +0 -8
  193. package/dist/cli/commands/preparation-action.js +0 -29
  194. package/dist/cli/commands/preparation-picker.d.ts +0 -5
  195. package/dist/cli/commands/preparation-picker.js +0 -36
  196. package/dist/cli/commands/preparation-selection.d.ts +0 -6
  197. package/dist/cli/commands/preparation-selection.js +0 -11
  198. package/dist/cli/commands/service-action-flow.d.ts +0 -9
  199. package/dist/cli/commands/service-action-flow.js +0 -19
  200. package/dist/cli/commands/source-config-wizard.d.ts +0 -51
  201. package/dist/cli/commands/source-config-wizard.js +0 -670
  202. package/dist/cli/commands/verify.d.ts +0 -2
  203. package/dist/cli/commands/verify.js +0 -94
  204. package/dist/packages/compiler/raw-snapshot.d.ts +0 -49
  205. package/dist/packages/compiler/raw-snapshot.js +0 -101
  206. package/dist/packages/method-package/index.d.ts +0 -11
  207. package/dist/packages/method-package/index.js +0 -11
  208. package/dist/packages/method-package/method-stage-policy.d.ts +0 -5
  209. package/dist/packages/method-package/method-stage-policy.js +0 -31
  210. package/dist/packages/project-model/project-paths.d.ts +0 -12
  211. package/dist/packages/project-model/project-paths.js +0 -33
  212. /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_buildManifest.js +0 -0
  213. /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_clientMiddlewareManifest.js +0 -0
  214. /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_ssgManifest.js +0 -0
@@ -1,37 +1,61 @@
1
1
  export const LOCAL_SERVICE_DEFAULT_HOST = "127.0.0.1";
2
2
  export const LOCAL_SERVICE_DEFAULT_PORT = 4873;
3
- export const LOCAL_SERVICE_POINTER_PATH = [
4
- "interf",
5
- ".service",
6
- "local-service.json",
7
- ];
8
3
  export const LOCAL_SERVICE_ROUTES = {
9
4
  root: "/",
10
5
  api: "/v1",
11
6
  health: "/health",
7
+ // 0.13 surface — preparation-keyed.
8
+ instance: "/v1/instance",
12
9
  preparations: "/v1/preparations",
13
- workspaceFiles: "/v1/workspace-files",
14
- sourceFiles: "/v1/source-files",
15
10
  methods: "/v1/methods",
16
- preparationSetups: "/v1/preparation-setups",
17
- preparationChanges: "/v1/preparation-changes",
18
- methodChanges: "/v1/method-changes",
19
- jobs: "/v1/jobs",
20
- readinessCheckDrafts: "/v1/readiness-check-drafts",
21
- methodAuthoringRuns: "/v1/method-authoring-runs",
22
- methodImprovementRuns: "/v1/method-improvement-runs",
23
11
  runs: "/v1/runs",
24
- reset: "/v1/reset",
25
- executor: "/v1/executor",
26
12
  actionProposals: "/v1/action-proposals",
27
- compileRuns: "/v1/compile-runs",
28
- testRuns: "/v1/test-runs",
29
- portableContexts: "/v1/portable-contexts",
30
- readiness: "/v1/readiness",
13
+ executor: "/v1/executor",
31
14
  openPath: "/v1/open-path",
32
15
  };
16
+ /** Preparation-scoped sub-resources (relative to /v1/preparations/<id>/). */
17
+ export const PREPARATION_SUBRESOURCES = {
18
+ compileRuns: "compile-runs",
19
+ testRuns: "test-runs",
20
+ methodAuthoringRuns: "method-authoring-runs",
21
+ methodImprovementRuns: "method-improvement-runs",
22
+ readinessCheckDrafts: "readiness-check-drafts",
23
+ changes: "changes",
24
+ reset: "reset",
25
+ runs: "runs",
26
+ readiness: "readiness",
27
+ sourceFiles: "source-files",
28
+ portableContext: "portable-context",
29
+ };
30
+ /** Run-scoped sub-resources (relative to /v1/runs/<run-id>/). */
31
+ export const RUN_SUBRESOURCES = {
32
+ events: "events",
33
+ cancel: "cancel",
34
+ proof: "proof",
35
+ artifacts: "artifacts",
36
+ };
33
37
  export function buildLocalServiceUrl(options = {}) {
34
38
  const host = options.host ?? LOCAL_SERVICE_DEFAULT_HOST;
35
39
  const port = options.port ?? LOCAL_SERVICE_DEFAULT_PORT;
36
40
  return `http://${host}:${port}`;
37
41
  }
42
+ /** Path builder: /v1/preparations/<id>. */
43
+ export function preparationResourcePath(prepId) {
44
+ return `${LOCAL_SERVICE_ROUTES.preparations}/${encodeURIComponent(prepId)}`;
45
+ }
46
+ /** Path builder: /v1/preparations/<id>/<subresource>. */
47
+ export function preparationSubresourcePath(prepId, sub) {
48
+ return `${preparationResourcePath(prepId)}/${PREPARATION_SUBRESOURCES[sub]}`;
49
+ }
50
+ /** Path builder: /v1/runs/<run-id>. */
51
+ export function runResourcePath(runId) {
52
+ return `${LOCAL_SERVICE_ROUTES.runs}/${encodeURIComponent(runId)}`;
53
+ }
54
+ /** Path builder: /v1/runs/<run-id>/<subresource>. */
55
+ export function runSubresourcePath(runId, sub) {
56
+ return `${runResourcePath(runId)}/${RUN_SUBRESOURCES[sub]}`;
57
+ }
58
+ /** Path builder: /v1/methods/<id>. */
59
+ export function methodResourcePath(methodId) {
60
+ return `${LOCAL_SERVICE_ROUTES.methods}/${encodeURIComponent(methodId)}`;
61
+ }
@@ -276,15 +276,15 @@ export function testRunToObservability(run) {
276
276
  ? run.started_at ?? new Date().toISOString()
277
277
  : undefined);
278
278
  const readinessRun = run.readiness_run;
279
- const raw = readinessRun?.raw ?? null;
279
+ const sourceFiles = readinessRun?.source_files ?? null;
280
280
  const compiled = readinessRun?.compiled ?? null;
281
281
  const proofCandidates = [
282
- raw
282
+ sourceFiles
283
283
  ? {
284
284
  id: `${run.run_id}-source-files`,
285
285
  label: "source files baseline",
286
- ok: raw.ok ?? raw.passed_cases === raw.total_cases,
287
- detail: `${raw.passed_cases}/${raw.total_cases} checks`,
286
+ ok: sourceFiles.ok ?? sourceFiles.passed_cases === sourceFiles.total_cases,
287
+ detail: `${sourceFiles.passed_cases}/${sourceFiles.total_cases} checks`,
288
288
  }
289
289
  : null,
290
290
  compiled
@@ -298,7 +298,7 @@ export function testRunToObservability(run) {
298
298
  ];
299
299
  const proof = proofCandidates.filter((value) => value !== null);
300
300
  const artifacts = uniqueArtifacts([
301
- ...(raw?.run_path ? [{ path: raw.run_path, role: "test", label: "source files readiness run" }] : []),
301
+ ...(sourceFiles?.run_path ? [{ path: sourceFiles.run_path, role: "test", label: "source files readiness run" }] : []),
302
302
  ...(compiled?.run_path ? [{ path: compiled.run_path, role: "test", label: "portable context readiness run" }] : []),
303
303
  ]);
304
304
  let eventIndex = 0;
@@ -323,13 +323,13 @@ export function testRunToObservability(run) {
323
323
  }));
324
324
  }
325
325
  const targetStepCandidates = [
326
- raw
326
+ sourceFiles
327
327
  ? {
328
328
  id: "source-files-baseline",
329
329
  label: "Source files baseline",
330
- status: raw.ok ?? raw.passed_cases === raw.total_cases ? "succeeded" : "failed",
331
- input: raw.target ?? { type: "source-files", path: run.source_path ?? null },
332
- output: raw,
330
+ status: sourceFiles.ok ?? sourceFiles.passed_cases === sourceFiles.total_cases ? "succeeded" : "failed",
331
+ input: sourceFiles.target ?? { type: "source-files", path: run.source_path ?? null },
332
+ output: sourceFiles,
333
333
  }
334
334
  : null,
335
335
  compiled
@@ -402,8 +402,8 @@ export function testRunToObservability(run) {
402
402
  metrics: [
403
403
  { label: "Preparation", value: run.preparation },
404
404
  { label: "Mode", value: run.mode },
405
- { label: "Readiness checks", value: compiled ? `${compiled.passed_cases}/${compiled.total_cases}` : raw ? `${raw.passed_cases}/${raw.total_cases}` : "0/0" },
406
- { label: "Source files", value: raw ? `${raw.passed_cases}/${raw.total_cases}` : "-" },
405
+ { label: "Readiness checks", value: compiled ? `${compiled.passed_cases}/${compiled.total_cases}` : sourceFiles ? `${sourceFiles.passed_cases}/${sourceFiles.total_cases}` : "0/0" },
406
+ { label: "Source files", value: sourceFiles ? `${sourceFiles.passed_cases}/${sourceFiles.total_cases}` : "-" },
407
407
  { label: "Portable context", value: compiled ? `${compiled.passed_cases}/${compiled.total_cases}` : "-" },
408
408
  ],
409
409
  artifacts,
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Runtime read-side caches.
3
+ *
4
+ * The local service runtime fronts a filesystem-backed model: every
5
+ * "list" or "get" call walks `.interf/runtime/...`, parses each JSON
6
+ * record through Zod, and returns the typed shape. Polling clients
7
+ * (Compiler UI, CLI status loops) hit those endpoints multiple times
8
+ * per second; on workspaces with hundreds of compile / test runs this
9
+ * shows up as the dominant CPU cost.
10
+ *
11
+ * The caches here memoize the parsed-and-validated results. Each cache
12
+ * is per-workspace so multi-workspace runtimes do not cross-pollinate,
13
+ * and each cache exposes both a read path (`get(...)`) and an explicit
14
+ * invalidation hook (`invalidate(...)`). The runtime calls
15
+ * `invalidate*` whenever it writes, so the next read repopulates from
16
+ * disk. Invalidation is intentionally broad (per-preparation, not
17
+ * per-record) — staleness is the only correctness bug worth avoiding,
18
+ * and per-record invalidation introduces fan-out without measurably
19
+ * lowering recompute cost.
20
+ */
21
+ /**
22
+ * Per-(workspace, preparation) cache for compile run records, plus a
23
+ * runId -> preparation index so `getCompileRun(runId)` can resolve to
24
+ * the owning preparation without scanning every preparation's runs.
25
+ */
26
+ export declare class RunListingCache<TRecord> {
27
+ /** prepDataDir -> preparation -> records (newest-first sorted). */
28
+ private byWorkspace;
29
+ /** prepDataDir -> runId -> preparation. */
30
+ private runIndex;
31
+ get(prepDataDir: string, preparation: string, fill: () => TRecord[], runIdOf: (record: TRecord) => string): TRecord[];
32
+ /** Look up which preparation owns this runId, if known. */
33
+ preparationFor(prepDataDir: string, runId: string): string | null;
34
+ /** Invalidate a single preparation's cached records and id index. */
35
+ invalidatePreparation(prepDataDir: string, preparation: string): void;
36
+ /** Drop everything for a workspace (e.g. after a reset). */
37
+ invalidateWorkspace(prepDataDir: string): void;
38
+ }
39
+ /**
40
+ * Per-(workspace, preparation) readiness cache. Readiness joins compile
41
+ * runs, test runs, readiness-check runs, and the preparation config; it
42
+ * is computed on every poll. The cache invalidates when the runtime
43
+ * writes any of those underlying objects for a given preparation.
44
+ */
45
+ export declare class ReadinessCache<TReadiness> {
46
+ private byWorkspace;
47
+ get(prepDataDir: string, preparation: string, compute: () => TReadiness): TReadiness;
48
+ invalidatePreparation(prepDataDir: string, preparation: string): void;
49
+ invalidateWorkspace(prepDataDir: string): void;
50
+ }
51
+ /**
52
+ * Source-folder listing cache keyed by `(cacheKey, folderRootMtime)`.
53
+ * `cacheKey` is the slot identifier; `folderPath` is the directory the
54
+ * cache stats for an mtime probe. UI polling is the hot path; CLI
55
+ * commands rarely hit the same path twice in <2s, hence the short TTL
56
+ * fallback.
57
+ */
58
+ export declare class MtimeListingCache<TList> {
59
+ private static readonly TTL_MS;
60
+ private cache;
61
+ get(cacheKey: string, folderPath: string, fill: () => TList): TList;
62
+ invalidate(cacheKey: string): void;
63
+ invalidateAll(): void;
64
+ }
65
+ /**
66
+ * Method-package listing cache keyed by the joined mtimes of the
67
+ * builtin / user / workspace method roots. If any of those ticks (a
68
+ * new local Method, an edit to the user library, etc.) the cache
69
+ * misses and we re-resolve.
70
+ */
71
+ export declare class MethodListingCache<TList> {
72
+ private cache;
73
+ get(cacheKey: string, rootPaths: string[], fill: () => TList): TList;
74
+ invalidate(cacheKey: string): void;
75
+ invalidateAll(): void;
76
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Runtime read-side caches.
3
+ *
4
+ * The local service runtime fronts a filesystem-backed model: every
5
+ * "list" or "get" call walks `.interf/runtime/...`, parses each JSON
6
+ * record through Zod, and returns the typed shape. Polling clients
7
+ * (Compiler UI, CLI status loops) hit those endpoints multiple times
8
+ * per second; on workspaces with hundreds of compile / test runs this
9
+ * shows up as the dominant CPU cost.
10
+ *
11
+ * The caches here memoize the parsed-and-validated results. Each cache
12
+ * is per-workspace so multi-workspace runtimes do not cross-pollinate,
13
+ * and each cache exposes both a read path (`get(...)`) and an explicit
14
+ * invalidation hook (`invalidate(...)`). The runtime calls
15
+ * `invalidate*` whenever it writes, so the next read repopulates from
16
+ * disk. Invalidation is intentionally broad (per-preparation, not
17
+ * per-record) — staleness is the only correctness bug worth avoiding,
18
+ * and per-record invalidation introduces fan-out without measurably
19
+ * lowering recompute cost.
20
+ */
21
+ import { existsSync, statSync } from "node:fs";
22
+ import { resolve } from "node:path";
23
+ /**
24
+ * Per-(workspace, preparation) cache for compile run records, plus a
25
+ * runId -> preparation index so `getCompileRun(runId)` can resolve to
26
+ * the owning preparation without scanning every preparation's runs.
27
+ */
28
+ export class RunListingCache {
29
+ /** prepDataDir -> preparation -> records (newest-first sorted). */
30
+ byWorkspace = new Map();
31
+ /** prepDataDir -> runId -> preparation. */
32
+ runIndex = new Map();
33
+ get(prepDataDir, preparation, fill, runIdOf) {
34
+ const wsKey = resolve(prepDataDir);
35
+ let bucket = this.byWorkspace.get(wsKey);
36
+ if (!bucket) {
37
+ bucket = new Map();
38
+ this.byWorkspace.set(wsKey, bucket);
39
+ }
40
+ const cached = bucket.get(preparation);
41
+ if (cached)
42
+ return cached;
43
+ const fresh = fill();
44
+ bucket.set(preparation, fresh);
45
+ let index = this.runIndex.get(wsKey);
46
+ if (!index) {
47
+ index = new Map();
48
+ this.runIndex.set(wsKey, index);
49
+ }
50
+ for (const record of fresh) {
51
+ index.set(runIdOf(record), preparation);
52
+ }
53
+ return fresh;
54
+ }
55
+ /** Look up which preparation owns this runId, if known. */
56
+ preparationFor(prepDataDir, runId) {
57
+ const wsKey = resolve(prepDataDir);
58
+ return this.runIndex.get(wsKey)?.get(runId) ?? null;
59
+ }
60
+ /** Invalidate a single preparation's cached records and id index. */
61
+ invalidatePreparation(prepDataDir, preparation) {
62
+ const wsKey = resolve(prepDataDir);
63
+ const bucket = this.byWorkspace.get(wsKey);
64
+ if (bucket) {
65
+ bucket.delete(preparation);
66
+ if (bucket.size === 0)
67
+ this.byWorkspace.delete(wsKey);
68
+ }
69
+ const index = this.runIndex.get(wsKey);
70
+ if (index) {
71
+ for (const [runId, owner] of index) {
72
+ if (owner === preparation)
73
+ index.delete(runId);
74
+ }
75
+ if (index.size === 0)
76
+ this.runIndex.delete(wsKey);
77
+ }
78
+ }
79
+ /** Drop everything for a workspace (e.g. after a reset). */
80
+ invalidateWorkspace(prepDataDir) {
81
+ const wsKey = resolve(prepDataDir);
82
+ this.byWorkspace.delete(wsKey);
83
+ this.runIndex.delete(wsKey);
84
+ }
85
+ }
86
+ /**
87
+ * Per-(workspace, preparation) readiness cache. Readiness joins compile
88
+ * runs, test runs, readiness-check runs, and the preparation config; it
89
+ * is computed on every poll. The cache invalidates when the runtime
90
+ * writes any of those underlying objects for a given preparation.
91
+ */
92
+ export class ReadinessCache {
93
+ byWorkspace = new Map();
94
+ get(prepDataDir, preparation, compute) {
95
+ const wsKey = resolve(prepDataDir);
96
+ let bucket = this.byWorkspace.get(wsKey);
97
+ if (!bucket) {
98
+ bucket = new Map();
99
+ this.byWorkspace.set(wsKey, bucket);
100
+ }
101
+ const cached = bucket.get(preparation);
102
+ if (cached !== undefined)
103
+ return cached;
104
+ const fresh = compute();
105
+ bucket.set(preparation, fresh);
106
+ return fresh;
107
+ }
108
+ invalidatePreparation(prepDataDir, preparation) {
109
+ const wsKey = resolve(prepDataDir);
110
+ const bucket = this.byWorkspace.get(wsKey);
111
+ if (bucket) {
112
+ bucket.delete(preparation);
113
+ if (bucket.size === 0)
114
+ this.byWorkspace.delete(wsKey);
115
+ }
116
+ }
117
+ invalidateWorkspace(prepDataDir) {
118
+ this.byWorkspace.delete(resolve(prepDataDir));
119
+ }
120
+ }
121
+ /**
122
+ * Source-folder listing cache keyed by `(cacheKey, folderRootMtime)`.
123
+ * `cacheKey` is the slot identifier; `folderPath` is the directory the
124
+ * cache stats for an mtime probe. UI polling is the hot path; CLI
125
+ * commands rarely hit the same path twice in <2s, hence the short TTL
126
+ * fallback.
127
+ */
128
+ export class MtimeListingCache {
129
+ static TTL_MS = 2000;
130
+ cache = new Map();
131
+ get(cacheKey, folderPath, fill) {
132
+ const now = Date.now();
133
+ const stat = safeStat(folderPath);
134
+ const currentMtime = stat?.mtimeMs ?? 0;
135
+ const entry = this.cache.get(cacheKey);
136
+ if (entry
137
+ && entry.mtimeMs === currentMtime
138
+ && entry.expiresAt > now) {
139
+ return entry.value;
140
+ }
141
+ const value = fill();
142
+ this.cache.set(cacheKey, {
143
+ mtimeMs: currentMtime,
144
+ expiresAt: now + MtimeListingCache.TTL_MS,
145
+ value,
146
+ });
147
+ return value;
148
+ }
149
+ invalidate(cacheKey) {
150
+ this.cache.delete(cacheKey);
151
+ }
152
+ invalidateAll() {
153
+ this.cache.clear();
154
+ }
155
+ }
156
+ /**
157
+ * Method-package listing cache keyed by the joined mtimes of the
158
+ * builtin / user / workspace method roots. If any of those ticks (a
159
+ * new local Method, an edit to the user library, etc.) the cache
160
+ * misses and we re-resolve.
161
+ */
162
+ export class MethodListingCache {
163
+ cache = new Map();
164
+ get(cacheKey, rootPaths, fill) {
165
+ const fingerprint = rootPaths
166
+ .map((path) => `${path}:${safeStat(path)?.mtimeMs ?? 0}`)
167
+ .join("|");
168
+ const entry = this.cache.get(cacheKey);
169
+ if (entry && entry.key === fingerprint)
170
+ return entry.value;
171
+ const value = fill();
172
+ this.cache.set(cacheKey, { key: fingerprint, value });
173
+ return value;
174
+ }
175
+ invalidate(cacheKey) {
176
+ this.cache.delete(cacheKey);
177
+ }
178
+ invalidateAll() {
179
+ this.cache.clear();
180
+ }
181
+ }
182
+ function safeStat(path) {
183
+ try {
184
+ if (!existsSync(path))
185
+ return null;
186
+ return statSync(path);
187
+ }
188
+ catch {
189
+ return null;
190
+ }
191
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Pure event-to-resource transformations for the local service runtime.
3
+ *
4
+ * Each apply function takes the current run resource plus one event and
5
+ * returns the next resource — no side effects, no shared state. This is
6
+ * what lets the runtime coordinator stay small: every other handler can
7
+ * compose these without learning the resource shape.
8
+ */
9
+ import { type CompileRun, type InterfRunEvent } from "../execution/lib/schema.js";
10
+ import { type LocalJobEvent, type LocalJobRunResource } from "./lib/schema.js";
11
+ export declare function applyEventToCompileRun(run: CompileRun, event: InterfRunEvent): CompileRun;
12
+ export declare function applyEventToLocalJob(run: LocalJobRunResource, event: LocalJobEvent): LocalJobRunResource;
@@ -0,0 +1,177 @@
1
+ import { uniqueArtifacts } from "./run-observability.js";
2
+ export function applyEventToCompileRun(run, event) {
3
+ const now = event.timestamp;
4
+ const stageFor = (stageId) => {
5
+ const existing = run.stages.find((stage) => stage.stage_id === stageId);
6
+ if (existing)
7
+ return existing;
8
+ const created = {
9
+ run_id: run.run_id,
10
+ stage_id: stageId,
11
+ status: "queued",
12
+ artifacts: [],
13
+ };
14
+ run.stages.push(created);
15
+ return created;
16
+ };
17
+ const updateStage = (stageId, patch) => {
18
+ const current = stageFor(stageId);
19
+ Object.assign(current, patch);
20
+ };
21
+ switch (event.type) {
22
+ case "run.started":
23
+ return {
24
+ ...run,
25
+ status: "running",
26
+ started_at: run.started_at ?? now,
27
+ events: [...run.events, event],
28
+ };
29
+ case "stage.started":
30
+ updateStage(event.stage_id, {
31
+ status: "running",
32
+ started_at: now,
33
+ stage_index: event.stage_index,
34
+ stage_total: event.stage_total,
35
+ });
36
+ break;
37
+ case "artifact.written": {
38
+ const stage = stageFor(event.stage_id);
39
+ updateStage(event.stage_id, {
40
+ artifacts: uniqueArtifacts([...(stage.artifacts ?? []), event.artifact]),
41
+ });
42
+ break;
43
+ }
44
+ case "proof.updated":
45
+ if (event.stage_id) {
46
+ updateStage(event.stage_id, {
47
+ latest_proof: event.proof,
48
+ });
49
+ }
50
+ return {
51
+ ...run,
52
+ latest_proof: event.proof,
53
+ events: [...run.events, event],
54
+ };
55
+ case "log.appended":
56
+ break;
57
+ case "stage.passed":
58
+ updateStage(event.stage_id, {
59
+ status: "succeeded",
60
+ finished_at: now,
61
+ summary: event.summary ?? null,
62
+ failure: null,
63
+ });
64
+ break;
65
+ case "stage.failed":
66
+ updateStage(event.stage_id, {
67
+ status: "failed",
68
+ finished_at: now,
69
+ summary: event.error,
70
+ failure: event.error,
71
+ });
72
+ break;
73
+ case "run.completed":
74
+ return {
75
+ ...run,
76
+ // Once cancelled, the cancelled status is sticky; the handler may
77
+ // still emit a completion event after the cancel signal has landed.
78
+ status: run.status === "cancelled" ? "cancelled" : "succeeded",
79
+ finished_at: run.finished_at ?? now,
80
+ events: [...run.events, event],
81
+ };
82
+ case "run.failed":
83
+ return {
84
+ ...run,
85
+ status: run.status === "cancelled" ? "cancelled" : "failed",
86
+ finished_at: run.finished_at ?? now,
87
+ events: [...run.events, event],
88
+ };
89
+ case "readiness.updated":
90
+ return {
91
+ ...run,
92
+ readiness: event.readiness,
93
+ events: [...run.events, event],
94
+ };
95
+ default:
96
+ break;
97
+ }
98
+ return {
99
+ ...run,
100
+ events: [...run.events, event],
101
+ };
102
+ }
103
+ export function applyEventToLocalJob(run, event) {
104
+ const stepFor = (stepId) => {
105
+ const existing = run.steps.find((step) => step.id === stepId);
106
+ if (existing)
107
+ return existing;
108
+ const created = {
109
+ id: stepId,
110
+ label: stepId,
111
+ status: "queued",
112
+ };
113
+ run.steps.push(created);
114
+ return created;
115
+ };
116
+ const updateStep = (stepId, patch) => {
117
+ if (!stepId)
118
+ return;
119
+ Object.assign(stepFor(stepId), patch);
120
+ };
121
+ switch (event.type) {
122
+ case "job.started":
123
+ return {
124
+ ...run,
125
+ status: "running",
126
+ started_at: run.started_at ?? event.timestamp,
127
+ events: [...run.events, event],
128
+ };
129
+ case "step.started":
130
+ updateStep(event.step_id, {
131
+ status: "running",
132
+ started_at: event.timestamp,
133
+ ...(event.input ? { input: event.input } : {}),
134
+ });
135
+ break;
136
+ case "step.completed":
137
+ updateStep(event.step_id, {
138
+ status: "succeeded",
139
+ finished_at: event.timestamp,
140
+ summary: event.message ?? null,
141
+ ...(event.output ? { output: event.output } : {}),
142
+ });
143
+ break;
144
+ case "step.failed":
145
+ updateStep(event.step_id, {
146
+ status: "failed",
147
+ finished_at: event.timestamp,
148
+ summary: event.message ?? null,
149
+ ...(event.output ? { output: event.output } : {}),
150
+ });
151
+ break;
152
+ case "job.completed":
153
+ return {
154
+ ...run,
155
+ status: "succeeded",
156
+ finished_at: run.finished_at ?? event.timestamp,
157
+ events: [...run.events, event],
158
+ };
159
+ case "job.failed":
160
+ return {
161
+ ...run,
162
+ status: "failed",
163
+ finished_at: run.finished_at ?? event.timestamp,
164
+ error: event.message ?? "Job failed.",
165
+ events: [...run.events, event],
166
+ };
167
+ case "artifact.written":
168
+ case "log.appended":
169
+ break;
170
+ default:
171
+ break;
172
+ }
173
+ return {
174
+ ...run,
175
+ events: [...run.events, event],
176
+ };
177
+ }
@@ -0,0 +1,47 @@
1
+ import { type CompileRun } from "../execution/lib/schema.js";
2
+ import { type RuntimeRun } from "../compiler/lib/schema.js";
3
+ import { type ActionProposalResource, type LocalJobRunResource, type TestRunResource } from "./lib/schema.js";
4
+ export declare function compileRunsRoot(compiledPath: string): string;
5
+ export declare function compileRunPath(compiledPath: string, runId: string): string;
6
+ export declare function testRunsRoot(compiledPath: string): string;
7
+ export declare function testRunPath(compiledPath: string, runId: string): string;
8
+ export declare function localJobsRoot(rootPath: string): string;
9
+ export declare function localJobPath(rootPath: string, runId: string): string;
10
+ export declare function actionProposalsRoot(rootPath: string): string;
11
+ export declare function actionProposalPath(rootPath: string, proposalId: string): string;
12
+ export declare function readJsonFile(filePath: string): unknown | null;
13
+ export declare function writeJsonFile(filePath: string, value: unknown): void;
14
+ export declare function readJsonOrNull<T>(filePath: string, schema: {
15
+ safeParse(value: unknown): {
16
+ success: true;
17
+ data: T;
18
+ } | {
19
+ success: false;
20
+ };
21
+ }): T | null;
22
+ export declare function listJsonFiles(dirPath: string): string[];
23
+ export declare function readCompileRunAt(filePath: string): CompileRun | null;
24
+ export declare function readTestRunAt(filePath: string): TestRunResource | null;
25
+ export declare function readLocalJobRunAt(filePath: string): LocalJobRunResource | null;
26
+ export declare function readActionProposalAt(filePath: string): ActionProposalResource | null;
27
+ /**
28
+ * Read the per-stage runtime-run history NDJSON. Each line is a `RuntimeRun`
29
+ * record; lines that fail to parse are silently skipped so the runtime can
30
+ * tolerate a partially-written tail without crashing.
31
+ */
32
+ export declare function readRuntimeRunHistory(compiledPath: string): RuntimeRun[];
33
+ /**
34
+ * Sort items newest-first using `started_at` (with a `finished_at` fallback).
35
+ * Used for compile/test run lists where the canonical order is by activity
36
+ * window, not by record-creation time.
37
+ */
38
+ export declare function newestFirst<T extends {
39
+ started_at?: string | null;
40
+ finished_at?: string | null;
41
+ }>(items: T[]): T[];
42
+ /** Sort items newest-first using their `created_at` timestamp. */
43
+ export declare function byCreatedAtDesc<T extends {
44
+ created_at: string;
45
+ }>(items: T[]): T[];
46
+ /** Parse an ISO timestamp into milliseconds; returns 0 for invalid input. */
47
+ export declare function timestampKey(value?: string | null): number;