@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.
- package/README.md +96 -92
- package/TRADEMARKS.md +2 -13
- package/agent-skills/interf-actions/SKILL.md +95 -36
- package/agent-skills/interf-actions/references/cli.md +118 -51
- package/builtin-methods/interf-default/README.md +3 -4
- package/builtin-methods/interf-default/compile/stages/shape/SKILL.md +2 -2
- package/builtin-methods/interf-default/compile/stages/summarize/SKILL.md +2 -1
- package/builtin-methods/interf-default/improve/SKILL.md +1 -1
- package/builtin-methods/interf-default/method.json +10 -4
- package/builtin-methods/interf-default/method.schema.json +0 -9
- package/builtin-methods/interf-default/use/query/SKILL.md +5 -5
- package/dist/cli/commands/compile.d.ts +8 -25
- package/dist/cli/commands/compile.js +75 -360
- package/dist/cli/commands/doctor.js +1 -1
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +39 -0
- package/dist/cli/commands/logout.d.ts +2 -0
- package/dist/cli/commands/logout.js +16 -0
- package/dist/cli/commands/method.d.ts +2 -0
- package/dist/cli/commands/method.js +113 -0
- package/dist/cli/commands/prep.d.ts +2 -0
- package/dist/cli/commands/prep.js +134 -0
- package/dist/cli/commands/reset.d.ts +8 -1
- package/dist/cli/commands/reset.js +47 -26
- package/dist/cli/commands/runs.d.ts +2 -0
- package/dist/cli/commands/runs.js +120 -0
- package/dist/cli/commands/status.d.ts +6 -1
- package/dist/cli/commands/status.js +68 -111
- package/dist/cli/commands/test.d.ts +6 -14
- package/dist/cli/commands/test.js +65 -181
- package/dist/cli/commands/web.d.ts +0 -9
- package/dist/cli/commands/web.js +147 -120
- package/dist/cli/commands/wizard.d.ts +9 -0
- package/dist/cli/commands/wizard.js +442 -0
- package/dist/cli/index.d.ts +7 -6
- package/dist/cli/index.js +13 -10
- package/dist/compiler-ui/404.html +1 -1
- package/dist/compiler-ui/__next.__PAGE__.txt +2 -2
- package/dist/compiler-ui/__next._full.txt +3 -3
- package/dist/compiler-ui/__next._head.txt +1 -1
- package/dist/compiler-ui/__next._index.txt +2 -2
- package/dist/compiler-ui/__next._tree.txt +2 -2
- package/dist/compiler-ui/_next/static/chunks/{18a8f2jkv3z.c.css → 045gole2ojo3g.css} +1 -1
- package/dist/compiler-ui/_next/static/chunks/{177mvn4rse235.js → 17t-lulmyawg5.js} +9 -9
- package/dist/compiler-ui/_not-found/__next._full.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._head.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._index.txt +2 -2
- package/dist/compiler-ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._not-found.txt +1 -1
- package/dist/compiler-ui/_not-found/__next._tree.txt +2 -2
- package/dist/compiler-ui/_not-found.html +1 -1
- package/dist/compiler-ui/_not-found.txt +2 -2
- package/dist/compiler-ui/index.html +1 -1
- package/dist/compiler-ui/index.txt +3 -3
- package/dist/packages/agents/lib/shells.d.ts +1 -1
- package/dist/packages/agents/lib/shells.js +111 -52
- package/dist/packages/agents/lib/user-config.d.ts +4 -2
- package/dist/packages/agents/lib/user-config.js +15 -7
- package/dist/packages/compiler/compiled-paths.d.ts +9 -2
- package/dist/packages/compiler/compiled-paths.js +30 -15
- package/dist/packages/compiler/compiled-pipeline.js +23 -3
- package/dist/packages/compiler/compiled-stage-plan.js +4 -0
- package/dist/packages/compiler/compiled-target.d.ts +1 -1
- package/dist/packages/compiler/compiled-target.js +1 -1
- package/dist/packages/compiler/index.d.ts +1 -0
- package/dist/packages/compiler/index.js +1 -0
- package/dist/packages/compiler/lib/schema.d.ts +26 -31
- package/dist/packages/compiler/lib/schema.js +1 -12
- package/dist/packages/compiler/method-runs.d.ts +2 -3
- package/dist/packages/compiler/method-runs.js +2 -3
- package/dist/packages/compiler/reset.js +3 -1
- package/dist/packages/compiler/runtime-contracts.js +0 -3
- package/dist/packages/compiler/runtime-prompt.js +1 -1
- package/dist/packages/compiler/source-files.d.ts +46 -0
- package/dist/packages/compiler/source-files.js +149 -0
- package/dist/packages/compiler/state-artifacts.d.ts +3 -2
- package/dist/packages/compiler/state-artifacts.js +4 -3
- package/dist/packages/compiler/state-io.d.ts +3 -2
- package/dist/packages/compiler/state-io.js +11 -5
- package/dist/packages/compiler/state-paths.d.ts +2 -1
- package/dist/packages/compiler/state-paths.js +6 -3
- package/dist/packages/compiler/state-view.d.ts +3 -2
- package/dist/packages/compiler/state-view.js +18 -28
- package/dist/packages/compiler/state.d.ts +4 -4
- package/dist/packages/compiler/state.js +3 -3
- package/dist/packages/contracts/index.d.ts +1 -1
- package/dist/packages/contracts/lib/preparation-paths.d.ts +117 -0
- package/dist/packages/contracts/lib/preparation-paths.js +177 -0
- package/dist/packages/contracts/lib/schema.d.ts +85 -5
- package/dist/packages/contracts/lib/schema.js +46 -1
- package/dist/packages/execution/lib/schema.d.ts +50 -50
- package/dist/packages/execution/lib/schema.js +1 -1
- package/dist/packages/local-service/action-definitions.d.ts +14 -14
- package/dist/packages/local-service/action-definitions.js +27 -28
- package/dist/packages/local-service/action-planner.js +2 -1
- package/dist/packages/local-service/client.d.ts +51 -52
- package/dist/packages/local-service/client.js +132 -140
- package/dist/packages/local-service/connection-config.d.ts +38 -0
- package/dist/packages/local-service/connection-config.js +75 -0
- package/dist/packages/local-service/index.d.ts +11 -7
- package/dist/packages/local-service/index.js +6 -4
- package/dist/packages/local-service/instance-paths.d.ts +100 -0
- package/dist/packages/local-service/instance-paths.js +165 -0
- package/dist/packages/local-service/lib/schema.d.ts +405 -2297
- package/dist/packages/local-service/lib/schema.js +146 -62
- package/dist/packages/local-service/native-run-handlers.js +3 -3
- package/dist/packages/local-service/preparation-store.d.ts +92 -0
- package/dist/packages/local-service/preparation-store.js +171 -0
- package/dist/packages/local-service/routes.d.ts +33 -16
- package/dist/packages/local-service/routes.js +44 -20
- package/dist/packages/local-service/run-observability.js +11 -11
- package/dist/packages/local-service/runtime-caches.d.ts +76 -0
- package/dist/packages/local-service/runtime-caches.js +191 -0
- package/dist/packages/local-service/runtime-event-applier.d.ts +12 -0
- package/dist/packages/local-service/runtime-event-applier.js +177 -0
- package/dist/packages/local-service/runtime-persistence.d.ts +47 -0
- package/dist/packages/local-service/runtime-persistence.js +137 -0
- package/dist/packages/local-service/runtime-proposal-helpers.d.ts +35 -0
- package/dist/packages/local-service/runtime-proposal-helpers.js +251 -0
- package/dist/packages/local-service/runtime-resource-builders.d.ts +52 -0
- package/dist/packages/local-service/runtime-resource-builders.js +149 -0
- package/dist/packages/local-service/runtime.d.ts +197 -43
- package/dist/packages/local-service/runtime.js +800 -974
- package/dist/packages/local-service/server.d.ts +15 -0
- package/dist/packages/local-service/server.js +641 -273
- package/dist/packages/local-service/service-registry.d.ts +47 -0
- package/dist/packages/local-service/service-registry.js +137 -0
- package/dist/packages/method-authoring/method-authoring.d.ts +1 -1
- package/dist/packages/method-authoring/method-authoring.js +2 -2
- package/dist/packages/method-authoring/method-improvement.js +1 -1
- package/dist/packages/method-package/builtin-compiled-method.d.ts +4 -5
- package/dist/packages/method-package/builtin-compiled-method.js +8 -14
- package/dist/packages/method-package/context-interface.d.ts +4 -40
- package/dist/packages/method-package/context-interface.js +1 -23
- package/dist/packages/method-package/interf-method-package.d.ts +4 -4
- package/dist/packages/method-package/interf-method-package.js +21 -33
- package/dist/packages/method-package/local-methods.d.ts +10 -6
- package/dist/packages/method-package/local-methods.js +57 -39
- package/dist/packages/method-package/method-definitions.d.ts +8 -34
- package/dist/packages/method-package/method-definitions.js +49 -37
- package/dist/packages/method-package/method-helpers.d.ts +1 -13
- package/dist/packages/method-package/method-helpers.js +8 -42
- package/dist/packages/method-package/method-stage-runner.js +2 -2
- package/dist/packages/method-package/user-methods.d.ts +17 -0
- package/dist/packages/method-package/user-methods.js +77 -0
- package/dist/packages/project-model/index.d.ts +0 -1
- package/dist/packages/project-model/index.js +0 -1
- package/dist/packages/project-model/interf-detect.d.ts +8 -3
- package/dist/packages/project-model/interf-detect.js +34 -34
- package/dist/packages/project-model/interf-scaffold.d.ts +3 -3
- package/dist/packages/project-model/interf-scaffold.js +23 -32
- package/dist/packages/project-model/lib/schema.js +38 -1
- package/dist/packages/project-model/preparation-entries.d.ts +5 -5
- package/dist/packages/project-model/preparation-entries.js +14 -14
- package/dist/packages/project-model/source-config.d.ts +11 -11
- package/dist/packages/project-model/source-config.js +74 -46
- package/dist/packages/project-model/source-folders.d.ts +5 -5
- package/dist/packages/project-model/source-folders.js +14 -14
- package/dist/packages/shared/filesystem.d.ts +7 -0
- package/dist/packages/shared/filesystem.js +97 -10
- package/dist/packages/testing/lib/schema.d.ts +10 -10
- package/dist/packages/testing/lib/schema.js +2 -2
- package/dist/packages/testing/readiness-check-run.d.ts +4 -4
- package/dist/packages/testing/readiness-check-run.js +36 -36
- package/dist/packages/testing/test-execution.js +6 -6
- package/dist/packages/testing/test-paths.js +4 -3
- package/dist/packages/testing/test-sandbox.d.ts +0 -1
- package/dist/packages/testing/test-sandbox.js +14 -30
- package/dist/packages/testing/test-targets.d.ts +1 -1
- package/dist/packages/testing/test-targets.js +6 -6
- package/dist/packages/testing/test.d.ts +1 -1
- package/dist/packages/testing/test.js +1 -1
- package/package.json +3 -4
- package/CHANGELOG.md +0 -93
- package/LICENSE +0 -183
- package/dist/cli/commands/action-input-cli.d.ts +0 -25
- package/dist/cli/commands/action-input-cli.js +0 -73
- package/dist/cli/commands/control-path.d.ts +0 -11
- package/dist/cli/commands/control-path.js +0 -72
- package/dist/cli/commands/create-method-wizard.d.ts +0 -64
- package/dist/cli/commands/create-method-wizard.js +0 -434
- package/dist/cli/commands/create.d.ts +0 -6
- package/dist/cli/commands/create.js +0 -183
- package/dist/cli/commands/default.d.ts +0 -2
- package/dist/cli/commands/default.js +0 -39
- package/dist/cli/commands/executor-flow.d.ts +0 -29
- package/dist/cli/commands/executor-flow.js +0 -163
- package/dist/cli/commands/init.d.ts +0 -26
- package/dist/cli/commands/init.js +0 -771
- package/dist/cli/commands/list.d.ts +0 -2
- package/dist/cli/commands/list.js +0 -30
- package/dist/cli/commands/preparation-action.d.ts +0 -8
- package/dist/cli/commands/preparation-action.js +0 -29
- package/dist/cli/commands/preparation-picker.d.ts +0 -5
- package/dist/cli/commands/preparation-picker.js +0 -36
- package/dist/cli/commands/preparation-selection.d.ts +0 -6
- package/dist/cli/commands/preparation-selection.js +0 -11
- package/dist/cli/commands/service-action-flow.d.ts +0 -9
- package/dist/cli/commands/service-action-flow.js +0 -19
- package/dist/cli/commands/source-config-wizard.d.ts +0 -51
- package/dist/cli/commands/source-config-wizard.js +0 -670
- package/dist/cli/commands/verify.d.ts +0 -2
- package/dist/cli/commands/verify.js +0 -94
- package/dist/packages/compiler/raw-snapshot.d.ts +0 -49
- package/dist/packages/compiler/raw-snapshot.js +0 -101
- package/dist/packages/method-package/index.d.ts +0 -11
- package/dist/packages/method-package/index.js +0 -11
- package/dist/packages/method-package/method-stage-policy.d.ts +0 -5
- package/dist/packages/method-package/method-stage-policy.js +0 -31
- package/dist/packages/project-model/project-paths.d.ts +0 -12
- package/dist/packages/project-model/project-paths.js +0 -33
- /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_buildManifest.js +0 -0
- /package/dist/compiler-ui/_next/static/{84FaeF3EzBF9kKTMjSEVN → C6vVfy3aeYuIO3d2AoNvC}/_clientMiddlewareManifest.js +0 -0
- /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
|
-
|
|
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
|
|
279
|
+
const sourceFiles = readinessRun?.source_files ?? null;
|
|
280
280
|
const compiled = readinessRun?.compiled ?? null;
|
|
281
281
|
const proofCandidates = [
|
|
282
|
-
|
|
282
|
+
sourceFiles
|
|
283
283
|
? {
|
|
284
284
|
id: `${run.run_id}-source-files`,
|
|
285
285
|
label: "source files baseline",
|
|
286
|
-
ok:
|
|
287
|
-
detail: `${
|
|
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
|
-
...(
|
|
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
|
-
|
|
326
|
+
sourceFiles
|
|
327
327
|
? {
|
|
328
328
|
id: "source-files-baseline",
|
|
329
329
|
label: "Source files baseline",
|
|
330
|
-
status:
|
|
331
|
-
input:
|
|
332
|
-
output:
|
|
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}` :
|
|
406
|
-
{ label: "Source files", value:
|
|
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;
|