@interf/compiler 0.4.1 → 0.5.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 +70 -66
- package/builtin-workflows/interf/README.md +6 -6
- package/builtin-workflows/interf/compile/stages/shape/SKILL.md +7 -7
- package/builtin-workflows/interf/compile/stages/structure/SKILL.md +2 -2
- package/builtin-workflows/interf/compile/stages/summarize/SKILL.md +1 -1
- package/builtin-workflows/interf/{workspace.schema.json → compiled.schema.json} +5 -5
- package/builtin-workflows/interf/improve/SKILL.md +3 -3
- package/builtin-workflows/interf/use/query/SKILL.md +2 -2
- package/builtin-workflows/interf/workflow.json +42 -31
- package/dist/commands/check-draft.d.ts +19 -0
- package/dist/commands/check-draft.js +110 -0
- package/dist/commands/compile-controller.d.ts +4 -4
- package/dist/commands/compile-controller.js +117 -81
- package/dist/commands/compile.d.ts +5 -5
- package/dist/commands/compile.js +61 -62
- package/dist/commands/compiled-flow.d.ts +23 -0
- package/dist/commands/compiled-flow.js +112 -0
- package/dist/commands/create-workflow-wizard.d.ts +3 -3
- package/dist/commands/create-workflow-wizard.js +11 -11
- package/dist/commands/create.d.ts +2 -2
- package/dist/commands/create.js +50 -57
- package/dist/commands/default.js +2 -2
- package/dist/commands/executor-flow.d.ts +20 -1
- package/dist/commands/executor-flow.js +67 -7
- package/dist/commands/init.js +242 -289
- package/dist/commands/list.js +14 -10
- package/dist/commands/reset.js +6 -6
- package/dist/commands/source-config-wizard.d.ts +12 -8
- package/dist/commands/source-config-wizard.js +356 -119
- package/dist/commands/status.js +49 -26
- package/dist/commands/test-flow.d.ts +23 -10
- package/dist/commands/test-flow.js +274 -65
- package/dist/commands/test.d.ts +7 -1
- package/dist/commands/test.js +264 -65
- package/dist/commands/verify.js +23 -14
- package/dist/index.d.ts +7 -7
- package/dist/index.js +4 -4
- package/dist/lib/agent-args.js +2 -1
- package/dist/lib/agent-constants.js +1 -1
- package/dist/lib/agent-render.js +4 -4
- package/dist/lib/agent-shells.d.ts +8 -8
- package/dist/lib/agent-shells.js +231 -142
- package/dist/lib/{workflow-abi.d.ts → builtin-compiled-workflow.d.ts} +37 -46
- package/dist/lib/builtin-compiled-workflow.js +153 -0
- package/dist/lib/compiled-compile.d.ts +52 -0
- package/dist/lib/compiled-compile.js +274 -0
- package/dist/lib/compiled-home.d.ts +5 -0
- package/dist/lib/compiled-home.js +32 -0
- package/dist/lib/compiled-paths.d.ts +39 -0
- package/dist/lib/compiled-paths.js +103 -0
- package/dist/lib/{workspace-raw.d.ts → compiled-raw.d.ts} +9 -8
- package/dist/lib/{workspace-raw.js → compiled-raw.js} +16 -14
- package/dist/lib/compiled-reset.d.ts +1 -0
- package/dist/lib/compiled-reset.js +44 -0
- package/dist/lib/compiled-schema.d.ts +27 -0
- package/dist/lib/compiled-schema.js +110 -0
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/config.js +0 -1
- package/dist/lib/discovery.d.ts +1 -1
- package/dist/lib/discovery.js +3 -3
- package/dist/lib/interf-bootstrap.d.ts +1 -1
- package/dist/lib/interf-bootstrap.js +4 -4
- package/dist/lib/interf-detect.d.ts +9 -10
- package/dist/lib/interf-detect.js +70 -59
- package/dist/lib/interf-scaffold.d.ts +2 -2
- package/dist/lib/interf-scaffold.js +90 -57
- package/dist/lib/interf-workflow-package.d.ts +3 -3
- package/dist/lib/interf-workflow-package.js +30 -30
- package/dist/lib/interf.d.ts +5 -5
- package/dist/lib/interf.js +4 -4
- package/dist/lib/local-workflows.d.ts +4 -4
- package/dist/lib/local-workflows.js +35 -70
- package/dist/lib/obsidian.d.ts +1 -1
- package/dist/lib/parse.js +92 -1
- package/dist/lib/project-paths.d.ts +11 -0
- package/dist/lib/project-paths.js +32 -0
- package/dist/lib/runtime-acceptance.d.ts +7 -1
- package/dist/lib/runtime-acceptance.js +194 -59
- package/dist/lib/runtime-contracts.d.ts +2 -4
- package/dist/lib/runtime-contracts.js +17 -161
- package/dist/lib/runtime-inventory.d.ts +7 -0
- package/dist/lib/runtime-inventory.js +29 -0
- package/dist/lib/runtime-paths.js +5 -5
- package/dist/lib/runtime-prompt.js +7 -6
- package/dist/lib/runtime-reconcile.d.ts +2 -3
- package/dist/lib/runtime-reconcile.js +94 -184
- package/dist/lib/runtime-runs.js +25 -119
- package/dist/lib/runtime-types.d.ts +10 -19
- package/dist/lib/runtime.d.ts +2 -2
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/schema.d.ts +169 -153
- package/dist/lib/schema.js +116 -164
- package/dist/lib/source-config.d.ts +24 -20
- package/dist/lib/source-config.js +159 -122
- package/dist/lib/state-artifacts.d.ts +5 -5
- package/dist/lib/state-artifacts.js +8 -8
- package/dist/lib/state-health.d.ts +4 -4
- package/dist/lib/state-health.js +110 -126
- package/dist/lib/state-io.d.ts +8 -8
- package/dist/lib/state-io.js +21 -102
- package/dist/lib/state-paths.js +5 -5
- package/dist/lib/state-view.d.ts +4 -4
- package/dist/lib/state-view.js +52 -55
- package/dist/lib/state.d.ts +5 -5
- package/dist/lib/state.js +4 -4
- package/dist/lib/summarize-plan.d.ts +3 -2
- package/dist/lib/summarize-plan.js +19 -21
- package/dist/lib/test-execution.js +9 -9
- package/dist/lib/test-matrices.d.ts +3 -3
- package/dist/lib/test-matrices.js +6 -6
- package/dist/lib/test-paths.d.ts +4 -4
- package/dist/lib/test-paths.js +26 -11
- package/dist/lib/test-sandbox.d.ts +1 -1
- package/dist/lib/test-sandbox.js +32 -38
- package/dist/lib/test-specs.js +1 -1
- package/dist/lib/test-targets.d.ts +2 -2
- package/dist/lib/test-targets.js +11 -11
- package/dist/lib/test-types.d.ts +1 -1
- package/dist/lib/test.d.ts +1 -1
- package/dist/lib/test.js +1 -1
- package/dist/lib/util.d.ts +2 -0
- package/dist/lib/util.js +14 -1
- package/dist/lib/validate-compiled.d.ts +27 -0
- package/dist/lib/validate-compiled.js +238 -0
- package/dist/lib/validate-helpers.d.ts +0 -8
- package/dist/lib/validate-helpers.js +0 -30
- package/dist/lib/validate.d.ts +6 -4
- package/dist/lib/validate.js +76 -27
- package/dist/lib/workflow-definitions.d.ts +12 -11
- package/dist/lib/workflow-definitions.js +45 -55
- package/dist/lib/workflow-helpers.d.ts +2 -3
- package/dist/lib/workflow-helpers.js +9 -13
- package/dist/lib/workflow-improvement.d.ts +3 -3
- package/dist/lib/workflow-improvement.js +48 -48
- package/dist/lib/workflow-primitives.d.ts +2 -0
- package/dist/lib/workflow-primitives.js +5 -0
- package/dist/lib/workflow-review-paths.d.ts +3 -3
- package/dist/lib/workflow-review-paths.js +11 -11
- package/dist/lib/workflow-stage-runner.d.ts +1 -1
- package/dist/lib/workflow-stage-runner.js +8 -8
- package/dist/lib/workflows.d.ts +9 -9
- package/dist/lib/workflows.js +15 -17
- package/package.json +13 -12
- package/dist/commands/workspace-flow.d.ts +0 -23
- package/dist/commands/workspace-flow.js +0 -109
- package/dist/lib/registry.d.ts +0 -16
- package/dist/lib/registry.js +0 -65
- package/dist/lib/validate-workspace.d.ts +0 -121
- package/dist/lib/validate-workspace.js +0 -407
- package/dist/lib/workflow-abi.js +0 -181
- package/dist/lib/workspace-compile.d.ts +0 -54
- package/dist/lib/workspace-compile.js +0 -476
- package/dist/lib/workspace-home.d.ts +0 -5
- package/dist/lib/workspace-home.js +0 -32
- package/dist/lib/workspace-layout.d.ts +0 -2
- package/dist/lib/workspace-layout.js +0 -60
- package/dist/lib/workspace-paths.d.ts +0 -41
- package/dist/lib/workspace-paths.js +0 -107
- package/dist/lib/workspace-reset.d.ts +0 -1
- package/dist/lib/workspace-reset.js +0 -43
- package/dist/lib/workspace-schema.d.ts +0 -17
- package/dist/lib/workspace-schema.js +0 -74
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { discoverSourceFiles } from "./discovery.js";
|
|
4
|
+
import { compiledZoneAbsolutePath, findCompiledSchemaZone, readCompiledSchemaFile, } from "./compiled-schema.js";
|
|
5
|
+
import { resolveSourceFolderPath } from "./interf.js";
|
|
6
|
+
import { compiledInterfConfigPath, workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
7
|
+
import { readCompiledConfig } from "./validate.js";
|
|
8
|
+
import { loadState } from "./state.js";
|
|
9
|
+
import { validateResolvedStageAcceptance, stageRecordFromState } from "./runtime-acceptance.js";
|
|
10
|
+
import { getActiveCompiledWorkflow, resolveRequiredCompiledWorkflowFromConfig, } from "./workflow-definitions.js";
|
|
11
|
+
import { listFilesRecursive } from "./filesystem.js";
|
|
12
|
+
function countZoneArtifacts(compiledPath, zonePath, kind) {
|
|
13
|
+
const absolutePath = compiledZoneAbsolutePath(compiledPath, { path: zonePath });
|
|
14
|
+
if (!existsSync(absolutePath))
|
|
15
|
+
return 0;
|
|
16
|
+
if (kind === "file")
|
|
17
|
+
return 1;
|
|
18
|
+
return listFilesRecursive(absolutePath).length;
|
|
19
|
+
}
|
|
20
|
+
function readWorkflowContext(dirPath) {
|
|
21
|
+
const config = readCompiledConfig(dirPath);
|
|
22
|
+
const workflowId = config.valid
|
|
23
|
+
? resolveRequiredCompiledWorkflowFromConfig(config.value, `.interf/interf.json for ${dirPath}`)
|
|
24
|
+
: null;
|
|
25
|
+
let workflow = null;
|
|
26
|
+
if (workflowId) {
|
|
27
|
+
try {
|
|
28
|
+
workflow = getActiveCompiledWorkflow(dirPath, workflowId);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
workflow = null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
|
|
35
|
+
const state = loadState(dirPath);
|
|
36
|
+
const sourceTotal = config.valid
|
|
37
|
+
? discoverSourceFiles(resolveSourceFolderPath(dirPath, config.value), dirPath).totalCount
|
|
38
|
+
: 0;
|
|
39
|
+
return {
|
|
40
|
+
config,
|
|
41
|
+
workflow,
|
|
42
|
+
schema,
|
|
43
|
+
state,
|
|
44
|
+
sourceTotal,
|
|
45
|
+
workflowId,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function stageRequired(sourceTotal, writeCounts, stageRecordPresent) {
|
|
49
|
+
return sourceTotal > 0 || writeCounts > 0 || stageRecordPresent;
|
|
50
|
+
}
|
|
51
|
+
function zoneWriteCount(compiledPath, schema, stage) {
|
|
52
|
+
const zoneCounts = {};
|
|
53
|
+
let total = 0;
|
|
54
|
+
for (const zoneId of stage.writes) {
|
|
55
|
+
const zone = findCompiledSchemaZone(schema, zoneId);
|
|
56
|
+
if (!zone)
|
|
57
|
+
continue;
|
|
58
|
+
const count = countZoneArtifacts(compiledPath, zone.path, zone.kind);
|
|
59
|
+
zoneCounts[zoneId] = count;
|
|
60
|
+
total += count;
|
|
61
|
+
}
|
|
62
|
+
return { total, zoneCounts };
|
|
63
|
+
}
|
|
64
|
+
function mergeValidationCounts(sourceTotal, stageRecord, zoneCounts) {
|
|
65
|
+
const merged = {
|
|
66
|
+
source_total: sourceTotal,
|
|
67
|
+
...zoneCounts,
|
|
68
|
+
};
|
|
69
|
+
const stageCounts = stageRecord?.counts;
|
|
70
|
+
if (stageCounts && typeof stageCounts === "object" && !Array.isArray(stageCounts)) {
|
|
71
|
+
for (const [key, value] of Object.entries(stageCounts)) {
|
|
72
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
73
|
+
merged[key] = value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return merged;
|
|
78
|
+
}
|
|
79
|
+
export function validateCompiled(dirPath) {
|
|
80
|
+
const context = readWorkflowContext(dirPath);
|
|
81
|
+
return {
|
|
82
|
+
config_present: context.config.present,
|
|
83
|
+
config_valid: context.config.valid,
|
|
84
|
+
config_type_match: context.config.typeMatch(),
|
|
85
|
+
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
86
|
+
workflow_valid: context.workflow !== null,
|
|
87
|
+
schema_present: existsSync(join(dirPath, ".interf", "workflow", "compiled.schema.json")),
|
|
88
|
+
schema_valid: context.schema !== null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function validateCompiledStage(dirPath, stageId) {
|
|
92
|
+
const context = readWorkflowContext(dirPath);
|
|
93
|
+
const checks = {
|
|
94
|
+
config_present: context.config.present,
|
|
95
|
+
config_valid: context.config.valid,
|
|
96
|
+
config_type_match: context.config.typeMatch(),
|
|
97
|
+
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
98
|
+
workflow_valid: context.workflow !== null,
|
|
99
|
+
schema_present: existsSync(join(dirPath, ".interf", "workflow", "compiled.schema.json")),
|
|
100
|
+
schema_valid: context.schema !== null,
|
|
101
|
+
};
|
|
102
|
+
const errors = [];
|
|
103
|
+
if (!checks.config_present)
|
|
104
|
+
errors.push(`Missing ${compiledInterfConfigPath(dirPath)}.`);
|
|
105
|
+
else if (!checks.config_valid)
|
|
106
|
+
errors.push(`Could not parse ${compiledInterfConfigPath(dirPath)}.`);
|
|
107
|
+
else if (!checks.config_type_match)
|
|
108
|
+
errors.push("Config is not a compiled dataset.");
|
|
109
|
+
if (!checks.workflow_present)
|
|
110
|
+
errors.push("Missing .interf/workflow/workflow.json.");
|
|
111
|
+
else if (!checks.workflow_valid)
|
|
112
|
+
errors.push("Could not load the active workflow package.");
|
|
113
|
+
if (!checks.schema_present)
|
|
114
|
+
errors.push("Missing .interf/workflow/compiled.schema.json.");
|
|
115
|
+
else if (!checks.schema_valid)
|
|
116
|
+
errors.push("Could not parse .interf/workflow/compiled.schema.json.");
|
|
117
|
+
const workflowStage = context.workflow?.stages.find((stage) => stage.id === stageId) ?? null;
|
|
118
|
+
checks.stage_present = workflowStage !== null;
|
|
119
|
+
if (!checks.stage_present) {
|
|
120
|
+
errors.push(`Workflow does not declare stage "${stageId}".`);
|
|
121
|
+
}
|
|
122
|
+
const stageRecord = stageRecordFromState(context.state, stageId);
|
|
123
|
+
checks.stage_record_present = stageRecord !== null;
|
|
124
|
+
checks.stage_finished = Boolean(stageRecord?.finished_at);
|
|
125
|
+
checks.stage_succeeded = stageRecord?.status === "succeeded";
|
|
126
|
+
const writeCounts = workflowStage && context.schema
|
|
127
|
+
? zoneWriteCount(dirPath, context.schema, workflowStage)
|
|
128
|
+
: { total: 0, zoneCounts: {} };
|
|
129
|
+
const acceptanceCounts = mergeValidationCounts(context.sourceTotal, stageRecord, writeCounts.zoneCounts);
|
|
130
|
+
const required = stageRequired(context.sourceTotal, writeCounts.total, checks.stage_record_present);
|
|
131
|
+
let acceptanceErrors = [];
|
|
132
|
+
if (workflowStage && context.schema) {
|
|
133
|
+
const acceptanceValidation = validateResolvedStageAcceptance(dirPath, {
|
|
134
|
+
stageId,
|
|
135
|
+
acceptance: workflowStage.acceptance,
|
|
136
|
+
counts: acceptanceCounts,
|
|
137
|
+
});
|
|
138
|
+
checks.acceptance_ok = acceptanceValidation.ok;
|
|
139
|
+
acceptanceErrors = acceptanceValidation.failures;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
checks.acceptance_ok = false;
|
|
143
|
+
}
|
|
144
|
+
if (required && checks.stage_record_present && !checks.stage_finished) {
|
|
145
|
+
errors.push(`Stage "${stageId}" has no finished_at proof in runtime state.`);
|
|
146
|
+
}
|
|
147
|
+
if (required && checks.stage_record_present && !checks.stage_succeeded) {
|
|
148
|
+
errors.push(`Stage "${stageId}" is not marked succeeded in runtime state.`);
|
|
149
|
+
}
|
|
150
|
+
if (required) {
|
|
151
|
+
errors.push(...acceptanceErrors);
|
|
152
|
+
}
|
|
153
|
+
const ok = required ? errors.length === 0 : errors.length === 0;
|
|
154
|
+
const summary = !required
|
|
155
|
+
? `Stage "${stageId}" is not required yet.`
|
|
156
|
+
: ok
|
|
157
|
+
? `Stage "${stageId}" verified.`
|
|
158
|
+
: `Stage "${stageId}" failed — ${errors[0] ?? "acceptance not satisfied."}`;
|
|
159
|
+
return {
|
|
160
|
+
ok,
|
|
161
|
+
required,
|
|
162
|
+
stage: stageId,
|
|
163
|
+
summary,
|
|
164
|
+
counts: {
|
|
165
|
+
...acceptanceCounts,
|
|
166
|
+
write_artifacts: writeCounts.total,
|
|
167
|
+
declared_write_zones: workflowStage?.writes.length ?? 0,
|
|
168
|
+
},
|
|
169
|
+
checks,
|
|
170
|
+
errors,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export function validateCompiledWorkflow(dirPath) {
|
|
174
|
+
const context = readWorkflowContext(dirPath);
|
|
175
|
+
const checks = {
|
|
176
|
+
config_present: context.config.present,
|
|
177
|
+
config_valid: context.config.valid,
|
|
178
|
+
config_type_match: context.config.typeMatch(),
|
|
179
|
+
workflow_present: existsSync(join(dirPath, ".interf", "workflow", "workflow.json")),
|
|
180
|
+
workflow_valid: context.workflow !== null,
|
|
181
|
+
schema_present: existsSync(join(dirPath, ".interf", "workflow", "compiled.schema.json")),
|
|
182
|
+
schema_valid: context.schema !== null,
|
|
183
|
+
};
|
|
184
|
+
if (!context.workflow) {
|
|
185
|
+
const errors = ["Could not load the active workflow package."];
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
required: true,
|
|
189
|
+
stage: "workflow",
|
|
190
|
+
summary: `Compiled workflow failed — ${errors[0]}`,
|
|
191
|
+
counts: { source_total: context.sourceTotal, stage_total: 0, completed_stages: 0 },
|
|
192
|
+
checks,
|
|
193
|
+
errors,
|
|
194
|
+
stage_results: {},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const stageResults = {};
|
|
198
|
+
const errors = [];
|
|
199
|
+
let completedStages = 0;
|
|
200
|
+
let failedStage = "compiled";
|
|
201
|
+
for (const stage of context.workflow.stages) {
|
|
202
|
+
const validation = validateCompiledStage(dirPath, stage.id);
|
|
203
|
+
stageResults[stage.id] = validation.ok;
|
|
204
|
+
if (validation.ok) {
|
|
205
|
+
completedStages += 1;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
failedStage = stage.id;
|
|
209
|
+
errors.push(...validation.errors);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
const ok = errors.length === 0;
|
|
213
|
+
return {
|
|
214
|
+
ok,
|
|
215
|
+
required: context.sourceTotal > 0,
|
|
216
|
+
stage: failedStage,
|
|
217
|
+
summary: ok
|
|
218
|
+
? `Compiled workflow verified — ${completedStages}/${context.workflow.stages.length} stages satisfied.`
|
|
219
|
+
: `Compiled workflow failed — ${errors[0] ?? "stage acceptance not satisfied."}`,
|
|
220
|
+
counts: {
|
|
221
|
+
source_total: context.sourceTotal,
|
|
222
|
+
stage_total: context.workflow.stages.length,
|
|
223
|
+
completed_stages: completedStages,
|
|
224
|
+
},
|
|
225
|
+
checks,
|
|
226
|
+
errors,
|
|
227
|
+
stage_results: stageResults,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
export function validateCompiledSummarize(dirPath) {
|
|
231
|
+
return validateCompiledStage(dirPath, "summarize");
|
|
232
|
+
}
|
|
233
|
+
export function validateCompiledStructure(dirPath) {
|
|
234
|
+
return validateCompiledStage(dirPath, "structure");
|
|
235
|
+
}
|
|
236
|
+
export function validateCompiledCompile(dirPath) {
|
|
237
|
+
return validateCompiledWorkflow(dirPath);
|
|
238
|
+
}
|
|
@@ -10,11 +10,3 @@ export declare function isSubset(left: Set<string>, right: Set<string>): boolean
|
|
|
10
10
|
export declare function setsEqual(left: Set<string>, right: Set<string>): boolean;
|
|
11
11
|
export declare function setIntersectionSize(left: Set<string>, right: Set<string>): number;
|
|
12
12
|
export declare function dedupeStrings(values: string[]): string[];
|
|
13
|
-
export interface InventoryFiles {
|
|
14
|
-
legacyFiles: Array<Record<string, unknown>>;
|
|
15
|
-
summaryFiles: Array<Record<string, unknown>>;
|
|
16
|
-
entryFiles: Array<Record<string, unknown>>;
|
|
17
|
-
files: Array<Record<string, unknown>>;
|
|
18
|
-
}
|
|
19
|
-
export declare function readInventoryFiles(inventory: Record<string, unknown> | null): InventoryFiles;
|
|
20
|
-
export declare function readInventoryTotal(inventory: Record<string, unknown> | null, inventoryFiles?: InventoryFiles): number;
|
|
@@ -39,33 +39,3 @@ export function setIntersectionSize(left, right) {
|
|
|
39
39
|
export function dedupeStrings(values) {
|
|
40
40
|
return Array.from(new Set(values));
|
|
41
41
|
}
|
|
42
|
-
function asInventoryEntries(value) {
|
|
43
|
-
if (!Array.isArray(value))
|
|
44
|
-
return [];
|
|
45
|
-
return value.filter((item) => !!item && typeof item === "object" && !Array.isArray(item));
|
|
46
|
-
}
|
|
47
|
-
export function readInventoryFiles(inventory) {
|
|
48
|
-
const legacyFiles = asInventoryEntries(inventory?.files);
|
|
49
|
-
const summaryFiles = asInventoryEntries(inventory?.summaries);
|
|
50
|
-
const entryFiles = asInventoryEntries(inventory?.entries);
|
|
51
|
-
const itemFiles = asInventoryEntries(inventory?.items);
|
|
52
|
-
const normalizedEntryFiles = entryFiles.length > 0 ? entryFiles : itemFiles;
|
|
53
|
-
const files = legacyFiles.length > 0
|
|
54
|
-
? legacyFiles
|
|
55
|
-
: summaryFiles.length > 0
|
|
56
|
-
? summaryFiles
|
|
57
|
-
: normalizedEntryFiles;
|
|
58
|
-
return {
|
|
59
|
-
legacyFiles,
|
|
60
|
-
summaryFiles,
|
|
61
|
-
entryFiles: normalizedEntryFiles,
|
|
62
|
-
files,
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
export function readInventoryTotal(inventory, inventoryFiles) {
|
|
66
|
-
if (typeof inventory?.total === "number")
|
|
67
|
-
return inventory.total;
|
|
68
|
-
if (typeof inventory?.summary_total === "number")
|
|
69
|
-
return inventory.summary_total;
|
|
70
|
-
return (inventoryFiles ?? readInventoryFiles(inventory)).files.length;
|
|
71
|
-
}
|
package/dist/lib/validate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readInterfConfig } from "./interf.js";
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function readCompiledConfig(dirPath: string): {
|
|
3
3
|
present: boolean;
|
|
4
4
|
valid: boolean;
|
|
5
5
|
value: ReturnType<typeof readInterfConfig>;
|
|
@@ -9,9 +9,11 @@ export declare function validateSynthFiles(files: string[]): {
|
|
|
9
9
|
invalid_frontmatter: number;
|
|
10
10
|
short_abstracts: number;
|
|
11
11
|
};
|
|
12
|
-
export declare function countBrokenWikilinks(
|
|
12
|
+
export declare function countBrokenWikilinks(compiledRoot: string, noteIndexRoots: string[], linkScanRoots: string[]): number;
|
|
13
13
|
export declare function asNumber(value: unknown): number;
|
|
14
14
|
export declare function isOutputMarkdownFile(filePath: string): boolean;
|
|
15
15
|
export declare function safeReadText(filePath: string): string | null;
|
|
16
|
-
export
|
|
17
|
-
export
|
|
16
|
+
export declare function extractSynthAbstract(frontmatter: Record<string, unknown>, body: string): string | null;
|
|
17
|
+
export declare function countSynthAbstractWords(frontmatter: Record<string, unknown>, body: string): number;
|
|
18
|
+
export { validateCompiled, validateCompiledStage, validateCompiledWorkflow, validateCompiledSummarize, validateCompiledStructure, validateCompiledCompile, } from "./validate-compiled.js";
|
|
19
|
+
export type { CompiledValidationSummary, CompiledStageValidation, CompiledWorkflowValidation, } from "./validate-compiled.js";
|
package/dist/lib/validate.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync, } from "node:fs";
|
|
2
2
|
import { basename, extname, join } from "node:path";
|
|
3
|
+
import { readCompiledSchemaFile } from "./compiled-schema.js";
|
|
4
|
+
import { compiledKnowledgeRootPath } from "./compiled-schema.js";
|
|
5
|
+
import { workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
3
6
|
import { listFilesRecursive } from "./filesystem.js";
|
|
4
7
|
import { readInterfConfig } from "./interf.js";
|
|
5
8
|
import { parseJsonFrontmatter } from "./parse.js";
|
|
6
|
-
import {
|
|
9
|
+
import { compiledInterfConfigPath } from "./compiled-paths.js";
|
|
7
10
|
const REQUIRED_DIGEST_FIELDS = [
|
|
8
11
|
"source_kind",
|
|
9
12
|
"evidence_tier",
|
|
@@ -12,9 +15,8 @@ const REQUIRED_DIGEST_FIELDS = [
|
|
|
12
15
|
];
|
|
13
16
|
const MIN_ABSTRACT_WORDS = 5;
|
|
14
17
|
const WIKILINK_PATTERN = /!?\[\[([^[\]]+)\]\]/g;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const configPath = workspaceInterfConfigPath(dirPath);
|
|
18
|
+
export function readCompiledConfig(dirPath) {
|
|
19
|
+
const configPath = compiledInterfConfigPath(dirPath);
|
|
18
20
|
const value = readInterfConfig(dirPath);
|
|
19
21
|
const present = existsSync(configPath);
|
|
20
22
|
if (!present) {
|
|
@@ -30,7 +32,7 @@ export function readWorkspaceConfig(dirPath) {
|
|
|
30
32
|
valid: value !== null,
|
|
31
33
|
value,
|
|
32
34
|
typeMatch() {
|
|
33
|
-
return value?.type === "
|
|
35
|
+
return value?.type === "compiled" && typeof value?.source?.path === "string";
|
|
34
36
|
},
|
|
35
37
|
};
|
|
36
38
|
}
|
|
@@ -46,7 +48,7 @@ export function validateSynthFiles(files) {
|
|
|
46
48
|
invalidFrontmatter += 1;
|
|
47
49
|
continue;
|
|
48
50
|
}
|
|
49
|
-
const abstractWords =
|
|
51
|
+
const abstractWords = countSynthAbstractWords(parsed.frontmatter, parsed.body);
|
|
50
52
|
if (abstractWords < MIN_ABSTRACT_WORDS) {
|
|
51
53
|
shortAbstracts += 1;
|
|
52
54
|
}
|
|
@@ -56,7 +58,9 @@ export function validateSynthFiles(files) {
|
|
|
56
58
|
short_abstracts: shortAbstracts,
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
|
-
export function countBrokenWikilinks(
|
|
61
|
+
export function countBrokenWikilinks(compiledRoot, noteIndexRoots, linkScanRoots) {
|
|
62
|
+
const zonePathById = compiledZoneDirectoryPaths(compiledRoot);
|
|
63
|
+
const knowledgeRelativePrefixes = compiledKnowledgeRelativePrefixes(zonePathById);
|
|
60
64
|
const noteIndex = new Set();
|
|
61
65
|
for (const filePath of dedupeFiles(noteIndexRoots)) {
|
|
62
66
|
for (const target of collectWikilinkTargets(filePath)) {
|
|
@@ -77,12 +81,15 @@ export function countBrokenWikilinks(workspaceRoot, noteIndexRoots, linkScanRoot
|
|
|
77
81
|
if (!target)
|
|
78
82
|
continue;
|
|
79
83
|
if (target.includes("/")) {
|
|
80
|
-
if (!wikilinkPathExists(
|
|
84
|
+
if (!wikilinkPathExists(compiledRoot, target, zonePathById, knowledgeRelativePrefixes)) {
|
|
81
85
|
brokenLinks += 1;
|
|
82
86
|
}
|
|
83
87
|
continue;
|
|
84
88
|
}
|
|
85
|
-
if (!noteIndex.has(target.toLowerCase())
|
|
89
|
+
if (!noteIndex.has(target.toLowerCase()) &&
|
|
90
|
+
!noteIndex.has(noteName(target).toLowerCase()) &&
|
|
91
|
+
!wikilinkPathExists(compiledRoot, target, zonePathById, knowledgeRelativePrefixes) &&
|
|
92
|
+
!wikilinkPathExists(compiledRoot, noteName(target), zonePathById, knowledgeRelativePrefixes)) {
|
|
86
93
|
brokenLinks += 1;
|
|
87
94
|
}
|
|
88
95
|
}
|
|
@@ -132,21 +139,36 @@ function dedupeFiles(dirPaths) {
|
|
|
132
139
|
return files;
|
|
133
140
|
}
|
|
134
141
|
function hasRequiredSynthFields(frontmatter) {
|
|
135
|
-
const hasSourceReference = "source" in frontmatter
|
|
142
|
+
const hasSourceReference = "source" in frontmatter;
|
|
136
143
|
return hasSourceReference && REQUIRED_DIGEST_FIELDS.every((field) => field in frontmatter);
|
|
137
144
|
}
|
|
138
|
-
function
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
function extractBodyAbstract(body) {
|
|
146
|
+
const lines = body.split(/\r?\n/);
|
|
147
|
+
const abstractHeadingIndex = lines.findIndex((line) => /^#{1,2}\s+Abstract\s*$/.test(line.trim()));
|
|
148
|
+
if (abstractHeadingIndex < 0)
|
|
149
|
+
return null;
|
|
150
|
+
const abstractLines = [];
|
|
151
|
+
for (let index = abstractHeadingIndex + 1; index < lines.length; index += 1) {
|
|
152
|
+
const line = lines[index] ?? "";
|
|
153
|
+
if (/^#{1,2}\s+\S/.test(line.trim()))
|
|
154
|
+
break;
|
|
155
|
+
abstractLines.push(line);
|
|
142
156
|
}
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
const abstractText = abstractLines.join("\n").trim();
|
|
158
|
+
return abstractText.length > 0 ? abstractText : null;
|
|
159
|
+
}
|
|
160
|
+
export function extractSynthAbstract(frontmatter, body) {
|
|
161
|
+
const frontmatterAbstract = typeof frontmatter.abstract === "string" ? frontmatter.abstract.trim() : "";
|
|
162
|
+
if (frontmatterAbstract.length > 0) {
|
|
163
|
+
return frontmatterAbstract;
|
|
164
|
+
}
|
|
165
|
+
return extractBodyAbstract(body);
|
|
166
|
+
}
|
|
167
|
+
export function countSynthAbstractWords(frontmatter, body) {
|
|
168
|
+
const abstract = extractSynthAbstract(frontmatter, body);
|
|
169
|
+
if (!abstract)
|
|
148
170
|
return 0;
|
|
149
|
-
return countWords(
|
|
171
|
+
return countWords(abstract);
|
|
150
172
|
}
|
|
151
173
|
function countWords(text) {
|
|
152
174
|
return text
|
|
@@ -157,15 +179,23 @@ function countWords(text) {
|
|
|
157
179
|
function noteName(filePath) {
|
|
158
180
|
return basename(filePath, extname(filePath));
|
|
159
181
|
}
|
|
160
|
-
function wikilinkPathExists(
|
|
161
|
-
return linkPathCandidates(
|
|
182
|
+
function wikilinkPathExists(compiledRoot, target, zonePathById, knowledgeRelativePrefixes) {
|
|
183
|
+
return linkPathCandidates(compiledRoot, target, zonePathById, knowledgeRelativePrefixes)
|
|
184
|
+
.some((candidate) => existsSync(candidate));
|
|
162
185
|
}
|
|
163
|
-
function linkPathCandidates(
|
|
186
|
+
function linkPathCandidates(compiledRoot, target, zonePathById, knowledgeRelativePrefixes) {
|
|
164
187
|
const candidates = new Set();
|
|
165
|
-
addPathCandidate(candidates, join(
|
|
188
|
+
addPathCandidate(candidates, join(compiledRoot, target));
|
|
166
189
|
const [firstSegment] = target.split("/");
|
|
167
|
-
if (firstSegment &&
|
|
168
|
-
addPathCandidate(candidates, join(
|
|
190
|
+
if (firstSegment && knowledgeRelativePrefixes.has(firstSegment)) {
|
|
191
|
+
addPathCandidate(candidates, join(compiledKnowledgeRootPath(compiledRoot), target));
|
|
192
|
+
}
|
|
193
|
+
if (firstSegment) {
|
|
194
|
+
const normalizedPrefix = zonePathById.get(firstSegment);
|
|
195
|
+
if (normalizedPrefix) {
|
|
196
|
+
const remainder = target.slice(firstSegment.length).replace(/^\/+/, "");
|
|
197
|
+
addPathCandidate(candidates, join(compiledRoot, normalizedPrefix, remainder));
|
|
198
|
+
}
|
|
169
199
|
}
|
|
170
200
|
return Array.from(candidates);
|
|
171
201
|
}
|
|
@@ -175,6 +205,25 @@ function addPathCandidate(candidates, absolutePath) {
|
|
|
175
205
|
candidates.add(`${absolutePath}.md`);
|
|
176
206
|
}
|
|
177
207
|
}
|
|
208
|
+
function compiledZoneDirectoryPaths(compiledRoot) {
|
|
209
|
+
const workflowRoot = workflowPackagePathForCompiled(compiledRoot);
|
|
210
|
+
const schema = readCompiledSchemaFile(workflowRoot);
|
|
211
|
+
if (!schema)
|
|
212
|
+
return new Map();
|
|
213
|
+
return new Map(schema.zones
|
|
214
|
+
.filter((zone) => zone.kind === "directory")
|
|
215
|
+
.map((zone) => [zone.id, zone.path]));
|
|
216
|
+
}
|
|
217
|
+
function compiledKnowledgeRelativePrefixes(zonePathById) {
|
|
218
|
+
const prefixes = new Set();
|
|
219
|
+
for (const zonePath of zonePathById.values()) {
|
|
220
|
+
const [root, leaf, ...rest] = zonePath.split("/");
|
|
221
|
+
if (root !== "knowledge" || !leaf || rest.length > 0)
|
|
222
|
+
continue;
|
|
223
|
+
prefixes.add(leaf);
|
|
224
|
+
}
|
|
225
|
+
return prefixes;
|
|
226
|
+
}
|
|
178
227
|
function collectWikilinkTargets(filePath) {
|
|
179
228
|
const targets = new Set();
|
|
180
229
|
targets.add(noteName(filePath));
|
|
@@ -204,4 +253,4 @@ function addFrontmatterLinkTarget(targets, value) {
|
|
|
204
253
|
}
|
|
205
254
|
}
|
|
206
255
|
}
|
|
207
|
-
export {
|
|
256
|
+
export { validateCompiled, validateCompiledStage, validateCompiledWorkflow, validateCompiledSummarize, validateCompiledStructure, validateCompiledCompile, } from "./validate-compiled.js";
|
|
@@ -24,7 +24,7 @@ export interface WorkflowDefinition<TId extends string> {
|
|
|
24
24
|
starterDocs?: WorkflowStarterDoc[];
|
|
25
25
|
scope?: "builtin" | "local";
|
|
26
26
|
}
|
|
27
|
-
export type
|
|
27
|
+
export type CompiledWorkflowId = string;
|
|
28
28
|
export declare function standaloneWorkflowDefinitionFromLocalPackage(local: {
|
|
29
29
|
id: string;
|
|
30
30
|
compiler_api?: WorkflowCompilerApi;
|
|
@@ -43,14 +43,15 @@ export declare function standaloneWorkflowDefinitionFromLocalPackage(local: {
|
|
|
43
43
|
stage_policy_notes?: Record<string, string[]>;
|
|
44
44
|
starter_docs: WorkflowStarterDoc[];
|
|
45
45
|
}): WorkflowDefinition<string>;
|
|
46
|
-
export declare function
|
|
47
|
-
export declare function
|
|
46
|
+
export declare function listCompiledWorkflowChoices(sourcePath?: string): WorkflowDefinition<string>[];
|
|
47
|
+
export declare function getCompiledWorkflow(workflowId: CompiledWorkflowId, options?: {
|
|
48
48
|
sourcePath?: string;
|
|
49
49
|
}): WorkflowDefinition<string>;
|
|
50
|
-
export declare function
|
|
51
|
-
export declare function
|
|
52
|
-
export declare function
|
|
53
|
-
export declare function
|
|
50
|
+
export declare function getActiveCompiledWorkflow(compiledPath: string, fallbackWorkflowId: CompiledWorkflowId): WorkflowDefinition<string>;
|
|
51
|
+
export declare function resolveCompiledWorkflowId(value: unknown): CompiledWorkflowId | null;
|
|
52
|
+
export declare function resolveCompiledWorkflowFromConfig(config: unknown): CompiledWorkflowId | null;
|
|
53
|
+
export declare function resolveRequiredCompiledWorkflowFromConfig(config: unknown, label?: string): CompiledWorkflowId;
|
|
54
|
+
export declare function formatCompiledWorkflowStageStep(workflowId: CompiledWorkflowId, stage: string, options?: {
|
|
54
55
|
sourcePath?: string;
|
|
55
56
|
}): string;
|
|
56
57
|
export declare function getWorkflowStageDefinition(workflowId: WorkflowId, stage: string, sourcePath?: string): WorkflowStageDefinition | null;
|
|
@@ -60,8 +61,8 @@ export declare function getWorkflowStagePosition(workflowId: WorkflowId, stage:
|
|
|
60
61
|
stages: string[];
|
|
61
62
|
} | null;
|
|
62
63
|
export declare function getWorkflowStages(workflowId: WorkflowId, sourcePath?: string): string[];
|
|
63
|
-
export declare function
|
|
64
|
+
export declare function getActiveCompiledStages(compiledPath: string, fallbackWorkflowId: WorkflowId): string[];
|
|
64
65
|
export declare function getWorkflowStagePolicyNotes(workflowId: WorkflowId, stage: string, sourcePath?: string): string[];
|
|
65
|
-
export declare function
|
|
66
|
-
export declare function
|
|
67
|
-
export declare function
|
|
66
|
+
export declare function getActiveCompiledStagePolicyNotes(compiledPath: string, fallbackWorkflowId: WorkflowId, stage: string): string[];
|
|
67
|
+
export declare function resolveActiveCompiledStageAcceptance(compiledPath: string, fallbackWorkflowId: WorkflowId, stage: string): WorkflowStageDefinition["acceptance"] | undefined;
|
|
68
|
+
export declare function formatActiveCompiledWorkflowStageStep(compiledPath: string, fallbackWorkflowId: CompiledWorkflowId, stage: string): string;
|