@interf/compiler 0.5.0 → 0.6.1
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 +126 -188
- package/builtin-workflows/interf/README.md +22 -10
- package/builtin-workflows/interf/compile/stages/shape/SKILL.md +6 -3
- package/builtin-workflows/interf/compile/stages/structure/SKILL.md +3 -0
- package/builtin-workflows/interf/compile/stages/summarize/SKILL.md +18 -2
- package/builtin-workflows/interf/improve/SKILL.md +2 -2
- package/builtin-workflows/interf/workflow.json +18 -4
- package/builtin-workflows/interf/{compiled.schema.json → workflow.schema.json} +9 -2
- package/dist/commands/check-draft.js +3 -3
- package/dist/commands/compile-controller.js +9 -16
- package/dist/commands/compile.d.ts +19 -1
- package/dist/commands/compile.js +98 -28
- package/dist/commands/create-workflow-wizard.d.ts +20 -2
- package/dist/commands/create-workflow-wizard.js +163 -27
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.js +67 -60
- package/dist/commands/dataset-selection.d.ts +6 -0
- package/dist/commands/dataset-selection.js +11 -0
- package/dist/commands/default.js +3 -3
- package/dist/commands/doctor.js +8 -8
- package/dist/commands/executor-flow.d.ts +1 -1
- package/dist/commands/executor-flow.js +5 -2
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +56 -48
- package/dist/commands/list.js +6 -3
- package/dist/commands/reset.js +1 -1
- package/dist/commands/source-config-wizard.d.ts +2 -2
- package/dist/commands/source-config-wizard.js +50 -17
- package/dist/commands/test-flow.js +5 -16
- package/dist/commands/test.d.ts +0 -6
- package/dist/commands/test.js +9 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/agent-args.d.ts +1 -0
- package/dist/lib/agent-args.js +10 -0
- package/dist/lib/agent-execution.js +2 -1
- package/dist/lib/agent-preflight.js +2 -1
- package/dist/lib/agent-shells.d.ts +26 -1
- package/dist/lib/agent-shells.js +214 -40
- package/dist/lib/agents.d.ts +1 -1
- package/dist/lib/agents.js +1 -1
- package/dist/lib/builtin-compiled-workflow.d.ts +38 -0
- package/dist/lib/builtin-compiled-workflow.js +94 -0
- package/dist/lib/compiled-compile.d.ts +0 -4
- package/dist/lib/compiled-compile.js +11 -30
- package/dist/lib/compiled-paths.d.ts +1 -2
- package/dist/lib/compiled-paths.js +8 -13
- package/dist/lib/compiled-raw.d.ts +2 -2
- package/dist/lib/compiled-reset.d.ts +1 -0
- package/dist/lib/compiled-reset.js +42 -14
- package/dist/lib/compiled-schema.d.ts +11 -7
- package/dist/lib/compiled-schema.js +47 -16
- package/dist/lib/discovery.d.ts +1 -1
- package/dist/lib/discovery.js +2 -2
- package/dist/lib/executors.d.ts +1 -1
- package/dist/lib/executors.js +2 -2
- package/dist/lib/interf-detect.d.ts +0 -1
- package/dist/lib/interf-detect.js +7 -18
- package/dist/lib/interf-scaffold.js +4 -11
- package/dist/lib/interf-workflow-package.d.ts +8 -3
- package/dist/lib/interf-workflow-package.js +128 -62
- package/dist/lib/interf.d.ts +1 -1
- package/dist/lib/interf.js +1 -1
- package/dist/lib/local-workflows.d.ts +4 -3
- package/dist/lib/local-workflows.js +127 -104
- package/dist/lib/project-paths.d.ts +2 -4
- package/dist/lib/project-paths.js +13 -10
- package/dist/lib/runtime-acceptance.js +15 -3
- package/dist/lib/runtime-contracts.js +3 -2
- package/dist/lib/runtime-paths.d.ts +1 -0
- package/dist/lib/runtime-paths.js +4 -1
- package/dist/lib/runtime-prompt.js +4 -4
- package/dist/lib/runtime-reconcile.js +90 -64
- package/dist/lib/runtime-runs.js +29 -102
- package/dist/lib/runtime.d.ts +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/schema.d.ts +104 -54
- package/dist/lib/schema.js +32 -116
- package/dist/lib/source-config.js +21 -22
- package/dist/lib/state-health.js +4 -2
- package/dist/lib/state-io.js +2 -110
- package/dist/lib/state-view.js +8 -8
- package/dist/lib/state.d.ts +1 -0
- package/dist/lib/state.js +7 -0
- package/dist/lib/test-execution.js +2 -2
- package/dist/lib/test-paths.js +12 -3
- package/dist/lib/test-sandbox.js +4 -17
- package/dist/lib/test-specs.js +1 -1
- package/dist/lib/validate-compiled.js +13 -8
- package/dist/lib/validate.d.ts +5 -1
- package/dist/lib/validate.js +30 -22
- package/dist/lib/workflow-authoring.d.ts +26 -0
- package/dist/lib/workflow-authoring.js +119 -0
- package/dist/lib/workflow-definitions.d.ts +14 -3
- package/dist/lib/workflow-definitions.js +21 -17
- package/dist/lib/workflow-edit-session.d.ts +16 -0
- package/dist/lib/workflow-edit-session.js +57 -0
- package/dist/lib/workflow-edit-utils.d.ts +10 -0
- package/dist/lib/workflow-edit-utils.js +39 -0
- package/dist/lib/workflow-improvement.js +30 -217
- package/dist/lib/workflow-primitives.d.ts +2 -0
- package/dist/lib/workflow-primitives.js +5 -0
- package/dist/lib/workflow-stage-policy.d.ts +5 -0
- package/dist/lib/workflow-stage-policy.js +31 -0
- package/package.json +7 -8
- package/dist/lib/compiled-layout.d.ts +0 -2
- package/dist/lib/compiled-layout.js +0 -60
- package/dist/lib/obsidian.d.ts +0 -1
- package/dist/lib/obsidian.js +0 -15
- package/dist/lib/summarize-plan.d.ts +0 -17
- package/dist/lib/summarize-plan.js +0 -124
- package/dist/lib/workflow-abi.d.ts +0 -129
- package/dist/lib/workflow-abi.js +0 -156
package/dist/lib/state-health.js
CHANGED
|
@@ -7,7 +7,7 @@ import { loadState } from "./state-io.js";
|
|
|
7
7
|
import { validateCompiled, validateCompiledStage, validateCompiledWorkflow, } from "./validate.js";
|
|
8
8
|
import { readCompiledSchemaFile } from "./compiled-schema.js";
|
|
9
9
|
import { workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
10
|
-
import { getActiveCompiledWorkflow,
|
|
10
|
+
import { getActiveCompiledWorkflow, resolveRequiredCompiledWorkflowFromConfig } from "./workflow-definitions.js";
|
|
11
11
|
import { listFilesRecursive } from "./filesystem.js";
|
|
12
12
|
function countZoneArtifacts(compiledPath, zonePath, kind) {
|
|
13
13
|
const absolutePath = join(compiledPath, zonePath);
|
|
@@ -26,7 +26,9 @@ export function computeCompiledHealth(dirPath) {
|
|
|
26
26
|
const state = loadState(dirPath);
|
|
27
27
|
const validation = validateCompiled(dirPath);
|
|
28
28
|
const activeRun = loadRuntimeRun(dirPath);
|
|
29
|
-
const workflowId = config
|
|
29
|
+
const workflowId = config
|
|
30
|
+
? resolveRequiredCompiledWorkflowFromConfig(config, `.interf/interf.json for ${dirPath}`)
|
|
31
|
+
: null;
|
|
30
32
|
let workflow = null;
|
|
31
33
|
if (workflowId) {
|
|
32
34
|
try {
|
package/dist/lib/state-io.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { warnInterf } from "./logger.js";
|
|
3
3
|
import { readJsonFileUnchecked, readJsonFileWithSchema } from "./parse.js";
|
|
4
|
-
import { CompiledHealthSchema,
|
|
5
|
-
import {
|
|
4
|
+
import { CompiledHealthSchema, CompiledRawSnapshotSchema, CompiledStateSchema, CompiledViewSpecSchema, } from "./schema.js";
|
|
5
|
+
import { emptyCompiledInventory, } from "./runtime-inventory.js";
|
|
6
6
|
import { healthPath, rawSnapshotPath, statePath, viewSpecPath } from "./state-paths.js";
|
|
7
7
|
import { compiledRuntimeInventoryPath, compiledRuntimeRoot, } from "./compiled-paths.js";
|
|
8
|
-
const NORMALIZABLE_RUNTIME_TIMESTAMP_FIELDS = [
|
|
9
|
-
"last_add",
|
|
10
|
-
"last_summarize",
|
|
11
|
-
"last_structure",
|
|
12
|
-
"last_shape",
|
|
13
|
-
"last_compile",
|
|
14
|
-
];
|
|
15
8
|
export function loadState(dirPath) {
|
|
16
9
|
const path = statePath(dirPath);
|
|
17
10
|
if (!existsSync(path))
|
|
@@ -21,18 +14,8 @@ export function loadState(dirPath) {
|
|
|
21
14
|
return null;
|
|
22
15
|
const parsed = CompiledStateSchema.safeParse(raw);
|
|
23
16
|
if (parsed.success) {
|
|
24
|
-
const healed = healParsedRuntimeState(dirPath, parsed.data);
|
|
25
|
-
if (healed !== null) {
|
|
26
|
-
saveState(dirPath, healed);
|
|
27
|
-
return healed;
|
|
28
|
-
}
|
|
29
17
|
return parsed.data;
|
|
30
18
|
}
|
|
31
|
-
const normalized = normalizeRuntimeState(raw);
|
|
32
|
-
if (normalized !== null) {
|
|
33
|
-
saveState(dirPath, normalized);
|
|
34
|
-
return normalized;
|
|
35
|
-
}
|
|
36
19
|
warnInterf(`Warning: failed to validate runtime state at ${path}: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
|
|
37
20
|
return null;
|
|
38
21
|
}
|
|
@@ -81,97 +64,6 @@ export function initCompiledState() {
|
|
|
81
64
|
error_count: 0,
|
|
82
65
|
};
|
|
83
66
|
}
|
|
84
|
-
function normalizeRuntimeState(raw) {
|
|
85
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
86
|
-
return null;
|
|
87
|
-
const normalized = { ...raw };
|
|
88
|
-
let changed = false;
|
|
89
|
-
for (const field of NORMALIZABLE_RUNTIME_TIMESTAMP_FIELDS) {
|
|
90
|
-
const timestamp = normalizeRuntimeTimestampField(normalized[field]);
|
|
91
|
-
if (timestamp !== undefined && timestamp !== normalized[field]) {
|
|
92
|
-
normalized[field] = timestamp;
|
|
93
|
-
changed = true;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (!changed)
|
|
97
|
-
return null;
|
|
98
|
-
const parsed = CompiledStateSchema.safeParse(normalized);
|
|
99
|
-
return parsed.success ? parsed.data : null;
|
|
100
|
-
}
|
|
101
|
-
function healParsedRuntimeState(dirPath, state) {
|
|
102
|
-
const hasLegacyStageFields = (typeof state.last_summarize === "string" && state.last_summarize.length > 0) ||
|
|
103
|
-
(typeof state.last_structure === "string" && state.last_structure.length > 0) ||
|
|
104
|
-
(typeof state.last_shape === "string" && state.last_shape.length > 0);
|
|
105
|
-
const hasStageMap = Boolean(state.stages) &&
|
|
106
|
-
typeof state.stages === "object" &&
|
|
107
|
-
Object.keys(state.stages ?? {}).length > 0;
|
|
108
|
-
if (state.version >= 2 && (hasStageMap || !hasLegacyStageFields))
|
|
109
|
-
return null;
|
|
110
|
-
const next = {
|
|
111
|
-
...initCompiledState(),
|
|
112
|
-
...state,
|
|
113
|
-
stages: { ...(state.stages ?? {}) },
|
|
114
|
-
};
|
|
115
|
-
if (typeof state.last_summarize === "string" && state.last_summarize.length > 0) {
|
|
116
|
-
next.stages.summarize = {
|
|
117
|
-
contract_type: "compiled-file-evidence",
|
|
118
|
-
status: "succeeded",
|
|
119
|
-
finished_at: state.last_summarize,
|
|
120
|
-
counts: {
|
|
121
|
-
summarized: state.summarized ?? 0,
|
|
122
|
-
expected_summary_total: state.summarized ?? 0,
|
|
123
|
-
},
|
|
124
|
-
zone_counts: {
|
|
125
|
-
summaries: state.summarized ?? 0,
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
if (typeof state.last_structure === "string" && state.last_structure.length > 0) {
|
|
130
|
-
next.stages.structure = {
|
|
131
|
-
contract_type: "compiled-knowledge-structure",
|
|
132
|
-
status: "succeeded",
|
|
133
|
-
finished_at: state.last_structure,
|
|
134
|
-
counts: {
|
|
135
|
-
summary_total: state.structured ?? state.summarized ?? 0,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
if (typeof state.last_shape === "string" && state.last_shape.length > 0) {
|
|
140
|
-
next.stages.shape = {
|
|
141
|
-
contract_type: "compiled-query-shape",
|
|
142
|
-
status: "succeeded",
|
|
143
|
-
finished_at: state.last_shape,
|
|
144
|
-
counts: {
|
|
145
|
-
summary_total: state.shaped ?? state.summarized ?? 0,
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
const inventoryPath = compiledRuntimeInventoryPath(dirPath);
|
|
150
|
-
if (existsSync(inventoryPath)) {
|
|
151
|
-
const inventory = readJsonFileWithSchema(inventoryPath, "compiled inventory", CompiledInventorySchema);
|
|
152
|
-
const inventoryTotal = compiledInventoryTotal(inventory);
|
|
153
|
-
if (inventory &&
|
|
154
|
-
inventoryTotal === (state.summarized ?? 0) &&
|
|
155
|
-
compiledInventoryEntryCount(inventory) === (state.summarized ?? 0)) {
|
|
156
|
-
next.inventory_complete = true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return next;
|
|
160
|
-
}
|
|
161
|
-
function normalizeRuntimeTimestampField(value) {
|
|
162
|
-
if (typeof value === "string" || value === null)
|
|
163
|
-
return value;
|
|
164
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
165
|
-
return undefined;
|
|
166
|
-
const record = value;
|
|
167
|
-
for (const key of ["generated_at", "finished_at", "updated_at", "started_at", "timestamp"]) {
|
|
168
|
-
const candidate = record[key];
|
|
169
|
-
if (typeof candidate === "string" && candidate.length > 0) {
|
|
170
|
-
return candidate;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
67
|
function loadViewSpec(filePath, schema) {
|
|
176
68
|
try {
|
|
177
69
|
const raw = JSON.parse(readFileSync(filePath, "utf8"));
|
package/dist/lib/state-view.js
CHANGED
|
@@ -6,7 +6,7 @@ import { loadCompiledViewSpec, saveCompiledViewSpec, } from "./state-io.js";
|
|
|
6
6
|
import { rawSnapshotPath } from "./state-paths.js";
|
|
7
7
|
import { compiledRuntimeRoot, workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
8
8
|
import { readCompiledSchemaFile } from "./compiled-schema.js";
|
|
9
|
-
import { getActiveCompiledWorkflow,
|
|
9
|
+
import { getActiveCompiledWorkflow, resolveRequiredCompiledWorkflowFromConfig } from "./workflow-definitions.js";
|
|
10
10
|
export function ensureCompiledViewSpec(dirPath) {
|
|
11
11
|
const existing = loadCompiledViewSpec(dirPath);
|
|
12
12
|
const now = new Date().toISOString();
|
|
@@ -70,13 +70,13 @@ export function normalizeCompiledViewSpec(existing, defaults) {
|
|
|
70
70
|
}
|
|
71
71
|
function buildDefaultCompiledViewSpec(dirPath, compiledName, generatedAt) {
|
|
72
72
|
const config = readInterfConfig(dirPath);
|
|
73
|
-
const workflowId =
|
|
73
|
+
const workflowId = resolveRequiredCompiledWorkflowFromConfig(config, `.interf/interf.json for ${dirPath}`);
|
|
74
74
|
const workflow = getActiveCompiledWorkflow(dirPath, workflowId);
|
|
75
75
|
const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
|
|
76
|
-
const
|
|
77
|
-
.filter((zone) => zone.kind !== "runtime")
|
|
76
|
+
const outputDocumentPaths = (schema?.zones ?? [])
|
|
77
|
+
.filter((zone) => zone.role === "output" && zone.kind !== "runtime")
|
|
78
78
|
.map((zone) => zone.path);
|
|
79
|
-
const defaultNote = (schema?.zones ?? []).find((zone) => zone.kind === "file")?.path ?? null;
|
|
79
|
+
const defaultNote = (schema?.zones ?? []).find((zone) => zone.role === "output" && zone.kind === "file")?.path ?? null;
|
|
80
80
|
return {
|
|
81
81
|
kind: "compiled-view-spec",
|
|
82
82
|
version: 2,
|
|
@@ -85,7 +85,7 @@ function buildDefaultCompiledViewSpec(dirPath, compiledName, generatedAt) {
|
|
|
85
85
|
health_source: ".interf/runtime/health.json",
|
|
86
86
|
state_source: ".interf/runtime/state.json",
|
|
87
87
|
default_note: defaultNote,
|
|
88
|
-
graph_scope:
|
|
88
|
+
graph_scope: outputDocumentPaths,
|
|
89
89
|
cards: [
|
|
90
90
|
{ id: "source-total", label: "Source Files", metric: "source_total", format: "number" },
|
|
91
91
|
{ id: "stage-total", label: "Stages", metric: "stage_total", format: "number" },
|
|
@@ -94,8 +94,8 @@ function buildDefaultCompiledViewSpec(dirPath, compiledName, generatedAt) {
|
|
|
94
94
|
sections: [
|
|
95
95
|
{ id: "status", type: "status", title: "Compile Status", path: ".interf/runtime/health.json" },
|
|
96
96
|
{ id: "cards", type: "cards", title: "Key Metrics", path: ".interf/runtime/health.json" },
|
|
97
|
-
...(
|
|
98
|
-
? [{ id: "outputs", type: "documents", title: "
|
|
97
|
+
...(outputDocumentPaths.length > 0
|
|
98
|
+
? [{ id: "outputs", type: "documents", title: "Output Zones", paths: outputDocumentPaths }]
|
|
99
99
|
: []),
|
|
100
100
|
{ id: "workflow", type: "documents", title: "Workflow Docs", paths: ["workflow/README.md", ...workflow.stages.map((stage) => `workflow/compile/stages/${stage.skillDir}`)] },
|
|
101
101
|
],
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export { loadState, saveState, loadCompiledHealth, saveCompiledHealth, loadCompi
|
|
|
4
4
|
export { refreshCompiledArtifacts, } from "./state-artifacts.js";
|
|
5
5
|
export { computeCompiledHealth, resolveCompiledStatus, resolveCompiledStage, } from "./state-health.js";
|
|
6
6
|
export { ensureCompiledViewSpec, ensureCompiledRawSnapshot, normalizeCompiledViewSpec, } from "./state-view.js";
|
|
7
|
+
export declare function initializeCompiledRuntimeState(dirPath: string): void;
|
package/dist/lib/state.js
CHANGED
|
@@ -3,3 +3,10 @@ export { loadState, saveState, loadCompiledHealth, saveCompiledHealth, loadCompi
|
|
|
3
3
|
export { refreshCompiledArtifacts, } from "./state-artifacts.js";
|
|
4
4
|
export { computeCompiledHealth, resolveCompiledStatus, resolveCompiledStage, } from "./state-health.js";
|
|
5
5
|
export { ensureCompiledViewSpec, ensureCompiledRawSnapshot, normalizeCompiledViewSpec, } from "./state-view.js";
|
|
6
|
+
import { saveEmptyCompiledInventory, initCompiledState, saveState } from "./state-io.js";
|
|
7
|
+
import { refreshCompiledArtifacts } from "./state-artifacts.js";
|
|
8
|
+
export function initializeCompiledRuntimeState(dirPath) {
|
|
9
|
+
saveState(dirPath, initCompiledState());
|
|
10
|
+
saveEmptyCompiledInventory(dirPath);
|
|
11
|
+
refreshCompiledArtifacts(dirPath, { ensureViewSpec: true });
|
|
12
|
+
}
|
|
@@ -203,7 +203,7 @@ function buildTestQueryPrompt(target, testCase, answerPath, tracePath) {
|
|
|
203
203
|
"Answer the truth-check question the same way you would answer a real user inside this compiled dataset.",
|
|
204
204
|
"Prefer the workflow-declared compiled outputs before raw fallback.",
|
|
205
205
|
"This sandbox is self-contained: the copied compiled dataset has its own sanitized `raw/` fallback via `.interf/interf.json` `source.path`.",
|
|
206
|
-
"The project
|
|
206
|
+
"The original project root is intentionally absent from this sandbox. Work only from this sandboxed compiled dataset and its embedded raw files.",
|
|
207
207
|
]
|
|
208
208
|
: [
|
|
209
209
|
"You are running an Interf baseline test inside an isolated raw test shell.",
|
|
@@ -211,7 +211,7 @@ function buildTestQueryPrompt(target, testCase, answerPath, tracePath) {
|
|
|
211
211
|
"Use the local native `interf-query` skill available in this shell.",
|
|
212
212
|
"There is no compiled dataset in this sandbox.",
|
|
213
213
|
"Answer only from `raw/` inside this shell.",
|
|
214
|
-
"The project
|
|
214
|
+
"The original project root is intentionally absent from this sandbox.",
|
|
215
215
|
];
|
|
216
216
|
return [
|
|
217
217
|
...header,
|
package/dist/lib/test-paths.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { basename, dirname, join } from "node:path";
|
|
3
3
|
import { targetTestRunsRootForCompiled, targetTestSandboxesRootForCompiled, compiledInterfConfigPath, } from "./compiled-paths.js";
|
|
4
4
|
const TEST_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,79}$/;
|
|
5
5
|
export const TEST_SPEC_EXTENSIONS = new Set([".json"]);
|
|
@@ -9,11 +9,17 @@ export function testSpecRootPath(sourcePath) {
|
|
|
9
9
|
export function testSpecTypePath(sourcePath, type) {
|
|
10
10
|
return join(testSpecRootPath(sourcePath), type);
|
|
11
11
|
}
|
|
12
|
+
function isDatasetTestsRootPath(artifactRootPath) {
|
|
13
|
+
return basename(dirname(artifactRootPath)) === "tests";
|
|
14
|
+
}
|
|
12
15
|
export function targetTestRunsPath(compiledPath, type) {
|
|
13
16
|
if (existsSync(compiledInterfConfigPath(compiledPath))) {
|
|
14
17
|
return join(targetTestRunsRootForCompiled(compiledPath), type);
|
|
15
18
|
}
|
|
16
|
-
|
|
19
|
+
if (isDatasetTestsRootPath(compiledPath)) {
|
|
20
|
+
return join(compiledPath, type === "raw" ? "file-as-is" : "compiled", "runs");
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled dataset or interf/tests/<dataset> root.`);
|
|
17
23
|
}
|
|
18
24
|
export function targetTestRunGitignorePath(compiledPath, type) {
|
|
19
25
|
return join(targetTestRunsPath(compiledPath, type), ".gitignore");
|
|
@@ -22,7 +28,10 @@ export function targetTestSandboxesPath(compiledPath, type) {
|
|
|
22
28
|
if (existsSync(compiledInterfConfigPath(compiledPath))) {
|
|
23
29
|
return join(targetTestSandboxesRootForCompiled(compiledPath), type);
|
|
24
30
|
}
|
|
25
|
-
|
|
31
|
+
if (isDatasetTestsRootPath(compiledPath)) {
|
|
32
|
+
return join(compiledPath, type === "raw" ? "file-as-is" : "compiled", "sandboxes");
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`Unsupported test artifact root: ${compiledPath}. Expected a compiled dataset or interf/tests/<dataset> root.`);
|
|
26
35
|
}
|
|
27
36
|
export function targetTestSandboxGitignorePath(compiledPath, type) {
|
|
28
37
|
return join(targetTestSandboxesPath(compiledPath, type), ".gitignore");
|
package/dist/lib/test-sandbox.js
CHANGED
|
@@ -2,10 +2,10 @@ import { cpSync, existsSync, mkdirSync, mkdtempSync, renameSync, rmSync, } from
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { dirname, join, relative, sep } from "node:path";
|
|
4
4
|
import { refreshCompiledBootstrapGuidance } from "./interf-bootstrap.js";
|
|
5
|
-
import { readInterfConfig,
|
|
5
|
+
import { readInterfConfig, resolveCompiledRawPath } from "./interf.js";
|
|
6
6
|
import { projectRawTestQueryShell } from "./agent-shells.js";
|
|
7
7
|
import { compiledCompiledPathForDataset } from "./project-paths.js";
|
|
8
|
-
import {
|
|
8
|
+
import { saveCompiledInterfConfig } from "./source-config.js";
|
|
9
9
|
import { refreshCompiledArtifacts } from "./state.js";
|
|
10
10
|
import { projectRawSnapshot } from "./compiled-raw.js";
|
|
11
11
|
import { testRootForCompiled, stageExecutionShellsRoot, targetTestSandboxesRootForCompiled, workflowImprovementLoopsRoot, compiledQueryAcceptanceRoot, compiledRuntimeLogsRoot, } from "./compiled-paths.js";
|
|
@@ -46,27 +46,14 @@ export function createTestSandbox(target) {
|
|
|
46
46
|
throw new Error(`Sandbox compiled is missing interf.json: ${sandboxTargetPath()}`);
|
|
47
47
|
}
|
|
48
48
|
if (!existsSync(resolveCompiledRawPath(sandboxTargetPath(), sandboxConfig))) {
|
|
49
|
-
|
|
50
|
-
const projectConfig = loadSourceFolderConfig(projectPath);
|
|
51
|
-
const datasetConfig = findSourceDatasetConfig(projectConfig, sandboxConfig.name);
|
|
52
|
-
if (!datasetConfig) {
|
|
53
|
-
throw new Error(`Sandbox compiled is missing a trusted dataset binding for "${sandboxConfig.name}": ${target.path}`);
|
|
54
|
-
}
|
|
55
|
-
const controlSourcePath = resolveSourceDatasetPath(projectPath, datasetConfig);
|
|
56
|
-
projectRawSnapshot({
|
|
57
|
-
sourcePath: controlSourcePath,
|
|
58
|
-
destinationPath: sandboxRawPath(),
|
|
59
|
-
compiledPath: target.path,
|
|
60
|
-
mode: "link-or-copy",
|
|
61
|
-
prune: false,
|
|
62
|
-
preserveTimestamps: false,
|
|
63
|
-
});
|
|
49
|
+
throw new Error(`Sandbox compiled is missing its local raw snapshot: ${sandboxTargetPath()}. Rebuild the compiled dataset before testing it.`);
|
|
64
50
|
}
|
|
65
51
|
saveCompiledInterfConfig(sandboxTargetPath(), {
|
|
66
52
|
...sandboxConfig,
|
|
67
53
|
checks: [],
|
|
68
54
|
source: {
|
|
69
55
|
path: toPortableRelativePath(sandboxTargetPath(), sandboxRawPath()),
|
|
56
|
+
dataset_path: toPortableRelativePath(sandboxTargetPath(), sandboxRawPath()),
|
|
70
57
|
},
|
|
71
58
|
});
|
|
72
59
|
refreshCompiledBootstrapGuidance(sandboxTargetPath());
|
package/dist/lib/test-specs.js
CHANGED
|
@@ -21,7 +21,7 @@ function serializeTestSpec(spec) {
|
|
|
21
21
|
type: spec.type,
|
|
22
22
|
name: spec.name,
|
|
23
23
|
...(spec.description ? { description: spec.description } : {}),
|
|
24
|
-
|
|
24
|
+
cases: spec.cases.map((testCase) => ({
|
|
25
25
|
id: testCase.id,
|
|
26
26
|
question: testCase.question,
|
|
27
27
|
...(testCase.file ? { file: testCase.file } : {}),
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { discoverSourceFiles } from "./discovery.js";
|
|
4
|
-
import { compiledZoneAbsolutePath, findCompiledSchemaZone, readCompiledSchemaFile, } from "./compiled-schema.js";
|
|
4
|
+
import { WORKFLOW_SCHEMA_FILE, compiledZoneAbsolutePath, findCompiledSchemaZone, readCompiledSchemaFile, workflowSchemaExists, } from "./compiled-schema.js";
|
|
5
5
|
import { resolveSourceFolderPath } from "./interf.js";
|
|
6
6
|
import { compiledInterfConfigPath, workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
7
7
|
import { readCompiledConfig } from "./validate.js";
|
|
8
8
|
import { loadState } from "./state.js";
|
|
9
9
|
import { validateResolvedStageAcceptance, stageRecordFromState } from "./runtime-acceptance.js";
|
|
10
|
-
import { getActiveCompiledWorkflow,
|
|
10
|
+
import { getActiveCompiledWorkflow, resolveRequiredCompiledWorkflowFromConfig, } from "./workflow-definitions.js";
|
|
11
11
|
import { listFilesRecursive } from "./filesystem.js";
|
|
12
|
+
function workflowSchemaPresent(dirPath) {
|
|
13
|
+
return workflowSchemaExists(join(dirPath, ".interf", "workflow"));
|
|
14
|
+
}
|
|
12
15
|
function countZoneArtifacts(compiledPath, zonePath, kind) {
|
|
13
16
|
const absolutePath = compiledZoneAbsolutePath(compiledPath, { path: zonePath });
|
|
14
17
|
if (!existsSync(absolutePath))
|
|
@@ -19,7 +22,9 @@ function countZoneArtifacts(compiledPath, zonePath, kind) {
|
|
|
19
22
|
}
|
|
20
23
|
function readWorkflowContext(dirPath) {
|
|
21
24
|
const config = readCompiledConfig(dirPath);
|
|
22
|
-
const workflowId = config.valid
|
|
25
|
+
const workflowId = config.valid
|
|
26
|
+
? resolveRequiredCompiledWorkflowFromConfig(config.value, `.interf/interf.json for ${dirPath}`)
|
|
27
|
+
: null;
|
|
23
28
|
let workflow = null;
|
|
24
29
|
if (workflowId) {
|
|
25
30
|
try {
|
|
@@ -82,7 +87,7 @@ export function validateCompiled(dirPath) {
|
|
|
82
87
|
config_type_match: context.config.typeMatch(),
|
|
83
88
|
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
84
89
|
workflow_valid: context.workflow !== null,
|
|
85
|
-
schema_present:
|
|
90
|
+
schema_present: workflowSchemaPresent(dirPath),
|
|
86
91
|
schema_valid: context.schema !== null,
|
|
87
92
|
};
|
|
88
93
|
}
|
|
@@ -94,7 +99,7 @@ export function validateCompiledStage(dirPath, stageId) {
|
|
|
94
99
|
config_type_match: context.config.typeMatch(),
|
|
95
100
|
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
96
101
|
workflow_valid: context.workflow !== null,
|
|
97
|
-
schema_present:
|
|
102
|
+
schema_present: workflowSchemaPresent(dirPath),
|
|
98
103
|
schema_valid: context.schema !== null,
|
|
99
104
|
};
|
|
100
105
|
const errors = [];
|
|
@@ -109,9 +114,9 @@ export function validateCompiledStage(dirPath, stageId) {
|
|
|
109
114
|
else if (!checks.workflow_valid)
|
|
110
115
|
errors.push("Could not load the active workflow package.");
|
|
111
116
|
if (!checks.schema_present)
|
|
112
|
-
errors.push(
|
|
117
|
+
errors.push(`Missing .interf/workflow/${WORKFLOW_SCHEMA_FILE}.`);
|
|
113
118
|
else if (!checks.schema_valid)
|
|
114
|
-
errors.push(
|
|
119
|
+
errors.push(`Could not parse .interf/workflow/${WORKFLOW_SCHEMA_FILE}.`);
|
|
115
120
|
const workflowStage = context.workflow?.stages.find((stage) => stage.id === stageId) ?? null;
|
|
116
121
|
checks.stage_present = workflowStage !== null;
|
|
117
122
|
if (!checks.stage_present) {
|
|
@@ -176,7 +181,7 @@ export function validateCompiledWorkflow(dirPath) {
|
|
|
176
181
|
config_type_match: context.config.typeMatch(),
|
|
177
182
|
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
178
183
|
workflow_valid: context.workflow !== null,
|
|
179
|
-
schema_present:
|
|
184
|
+
schema_present: workflowSchemaPresent(dirPath),
|
|
180
185
|
schema_valid: context.schema !== null,
|
|
181
186
|
};
|
|
182
187
|
if (!context.workflow) {
|
package/dist/lib/validate.d.ts
CHANGED
|
@@ -5,7 +5,9 @@ export declare function readCompiledConfig(dirPath: string): {
|
|
|
5
5
|
value: ReturnType<typeof readInterfConfig>;
|
|
6
6
|
typeMatch(): boolean;
|
|
7
7
|
};
|
|
8
|
-
export declare function validateSynthFiles(files: string[]
|
|
8
|
+
export declare function validateSynthFiles(files: string[], options?: {
|
|
9
|
+
requiredFrontmatterKeys?: string[];
|
|
10
|
+
}): {
|
|
9
11
|
invalid_frontmatter: number;
|
|
10
12
|
short_abstracts: number;
|
|
11
13
|
};
|
|
@@ -13,5 +15,7 @@ export declare function countBrokenWikilinks(compiledRoot: string, noteIndexRoot
|
|
|
13
15
|
export declare function asNumber(value: unknown): number;
|
|
14
16
|
export declare function isOutputMarkdownFile(filePath: string): boolean;
|
|
15
17
|
export declare function safeReadText(filePath: string): string | null;
|
|
18
|
+
export declare function extractSynthAbstract(frontmatter: Record<string, unknown>, body: string): string | null;
|
|
19
|
+
export declare function countSynthAbstractWords(frontmatter: Record<string, unknown>, body: string): number;
|
|
16
20
|
export { validateCompiled, validateCompiledStage, validateCompiledWorkflow, validateCompiledSummarize, validateCompiledStructure, validateCompiledCompile, } from "./validate-compiled.js";
|
|
17
21
|
export type { CompiledValidationSummary, CompiledStageValidation, CompiledWorkflowValidation, } from "./validate-compiled.js";
|
package/dist/lib/validate.js
CHANGED
|
@@ -7,12 +7,6 @@ import { listFilesRecursive } from "./filesystem.js";
|
|
|
7
7
|
import { readInterfConfig } from "./interf.js";
|
|
8
8
|
import { parseJsonFrontmatter } from "./parse.js";
|
|
9
9
|
import { compiledInterfConfigPath } from "./compiled-paths.js";
|
|
10
|
-
const REQUIRED_DIGEST_FIELDS = [
|
|
11
|
-
"source_kind",
|
|
12
|
-
"evidence_tier",
|
|
13
|
-
"truth_mode",
|
|
14
|
-
"state",
|
|
15
|
-
];
|
|
16
10
|
const MIN_ABSTRACT_WORDS = 5;
|
|
17
11
|
const WIKILINK_PATTERN = /!?\[\[([^[\]]+)\]\]/g;
|
|
18
12
|
export function readCompiledConfig(dirPath) {
|
|
@@ -36,7 +30,7 @@ export function readCompiledConfig(dirPath) {
|
|
|
36
30
|
},
|
|
37
31
|
};
|
|
38
32
|
}
|
|
39
|
-
export function validateSynthFiles(files) {
|
|
33
|
+
export function validateSynthFiles(files, options) {
|
|
40
34
|
let invalidFrontmatter = 0;
|
|
41
35
|
let shortAbstracts = 0;
|
|
42
36
|
for (const filePath of files) {
|
|
@@ -44,11 +38,11 @@ export function validateSynthFiles(files) {
|
|
|
44
38
|
if (content === null)
|
|
45
39
|
continue;
|
|
46
40
|
const parsed = parseJsonFrontmatter(content);
|
|
47
|
-
if (!parsed || !
|
|
41
|
+
if (!parsed || !hasRequiredFrontmatterKeys(parsed.frontmatter, options?.requiredFrontmatterKeys)) {
|
|
48
42
|
invalidFrontmatter += 1;
|
|
49
43
|
continue;
|
|
50
44
|
}
|
|
51
|
-
const abstractWords =
|
|
45
|
+
const abstractWords = countSynthAbstractWords(parsed.frontmatter, parsed.body);
|
|
52
46
|
if (abstractWords < MIN_ABSTRACT_WORDS) {
|
|
53
47
|
shortAbstracts += 1;
|
|
54
48
|
}
|
|
@@ -138,22 +132,36 @@ function dedupeFiles(dirPaths) {
|
|
|
138
132
|
}
|
|
139
133
|
return files;
|
|
140
134
|
}
|
|
141
|
-
function
|
|
142
|
-
|
|
143
|
-
return hasSourceReference && REQUIRED_DIGEST_FIELDS.every((field) => field in frontmatter);
|
|
135
|
+
function hasRequiredFrontmatterKeys(frontmatter, requiredKeys) {
|
|
136
|
+
return (requiredKeys ?? []).every((field) => field in frontmatter);
|
|
144
137
|
}
|
|
145
|
-
function
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
function extractBodyAbstract(body) {
|
|
139
|
+
const lines = body.split(/\r?\n/);
|
|
140
|
+
const abstractHeadingIndex = lines.findIndex((line) => /^#{1,2}\s+Abstract\s*$/.test(line.trim()));
|
|
141
|
+
if (abstractHeadingIndex < 0)
|
|
142
|
+
return null;
|
|
143
|
+
const abstractLines = [];
|
|
144
|
+
for (let index = abstractHeadingIndex + 1; index < lines.length; index += 1) {
|
|
145
|
+
const line = lines[index] ?? "";
|
|
146
|
+
if (/^#{1,2}\s+\S/.test(line.trim()))
|
|
147
|
+
break;
|
|
148
|
+
abstractLines.push(line);
|
|
149
149
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
const abstractText = abstractLines.join("\n").trim();
|
|
151
|
+
return abstractText.length > 0 ? abstractText : null;
|
|
152
|
+
}
|
|
153
|
+
export function extractSynthAbstract(frontmatter, body) {
|
|
154
|
+
const frontmatterAbstract = typeof frontmatter.abstract === "string" ? frontmatter.abstract.trim() : "";
|
|
155
|
+
if (frontmatterAbstract.length > 0) {
|
|
156
|
+
return frontmatterAbstract;
|
|
157
|
+
}
|
|
158
|
+
return extractBodyAbstract(body);
|
|
159
|
+
}
|
|
160
|
+
export function countSynthAbstractWords(frontmatter, body) {
|
|
161
|
+
const abstract = extractSynthAbstract(frontmatter, body);
|
|
162
|
+
if (!abstract)
|
|
155
163
|
return 0;
|
|
156
|
-
return countWords(
|
|
164
|
+
return countWords(abstract);
|
|
157
165
|
}
|
|
158
166
|
function countWords(text) {
|
|
159
167
|
return text
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { WorkflowExecutor } from "./executors.js";
|
|
2
|
+
import { validateWorkflowPackage } from "./local-workflows.js";
|
|
3
|
+
import type { SourceTruthCheck } from "./schema.js";
|
|
4
|
+
import { type WorkflowReporter } from "./workflows.js";
|
|
5
|
+
export interface WorkflowAuthoringRunResult {
|
|
6
|
+
status: "updated" | "no-change" | "invalid" | "executor-failed";
|
|
7
|
+
changed: boolean;
|
|
8
|
+
summary: string;
|
|
9
|
+
validation: ReturnType<typeof validateWorkflowPackage> | null;
|
|
10
|
+
workflowPath: string;
|
|
11
|
+
shellPath: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function runWorkflowAuthoringDraft(options: {
|
|
14
|
+
sourcePath: string;
|
|
15
|
+
datasetPath: string;
|
|
16
|
+
baseWorkflowId: string;
|
|
17
|
+
workflowId: string;
|
|
18
|
+
label: string;
|
|
19
|
+
hint: string;
|
|
20
|
+
taskPrompt: string;
|
|
21
|
+
checks?: SourceTruthCheck[];
|
|
22
|
+
executor: WorkflowExecutor;
|
|
23
|
+
preparePreview?: boolean;
|
|
24
|
+
previewReporter?: WorkflowReporter | null;
|
|
25
|
+
}): Promise<WorkflowAuthoringRunResult>;
|
|
26
|
+
export declare function resolveWorkflowDraftPath(sourcePath: string, workflowId: string): string;
|