@interf/compiler 0.4.0 → 0.5.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 +71 -69
- 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 +278 -58
- 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/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-layout.d.ts +2 -0
- package/dist/lib/compiled-layout.js +60 -0
- package/dist/lib/compiled-paths.d.ts +41 -0
- package/dist/lib/compiled-paths.js +111 -0
- package/dist/lib/{workspace-raw.d.ts → compiled-raw.d.ts} +8 -7
- 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 +10 -10
- package/dist/lib/interf-detect.js +78 -56
- 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 +13 -0
- package/dist/lib/project-paths.js +29 -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 +9 -6
- package/dist/lib/runtime-reconcile.d.ts +2 -3
- package/dist/lib/runtime-reconcile.js +92 -171
- package/dist/lib/runtime-runs.js +30 -39
- 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 +163 -140
- package/dist/lib/schema.js +163 -124
- package/dist/lib/source-config.d.ts +24 -20
- package/dist/lib/source-config.js +154 -116
- 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 +108 -126
- package/dist/lib/state-io.d.ts +8 -8
- package/dist/lib/state-io.js +77 -50
- 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 +18 -16
- 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 +16 -10
- package/dist/lib/test-sandbox.d.ts +1 -1
- package/dist/lib/test-sandbox.js +38 -31
- 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 +236 -0
- package/dist/lib/validate-helpers.d.ts +0 -8
- package/dist/lib/validate-helpers.js +0 -30
- package/dist/lib/validate.d.ts +4 -4
- package/dist/lib/validate.js +49 -15
- package/dist/lib/workflow-abi.d.ts +37 -46
- package/dist/lib/workflow-abi.js +51 -76
- package/dist/lib/workflow-definitions.d.ts +11 -11
- package/dist/lib/workflow-definitions.js +36 -53
- 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-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 +10 -9
- 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/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
|
@@ -6,9 +6,9 @@ import { isMarkdownFile } from "./util.js";
|
|
|
6
6
|
import { listFilesRecursive } from "./filesystem.js";
|
|
7
7
|
import { warnInterf } from "./logger.js";
|
|
8
8
|
import { readJsonFileUnchecked, readJsonFileWithSchema } from "./parse.js";
|
|
9
|
-
import {
|
|
10
|
-
import { WorkflowCompilerApiSchema, RuntimeContractTypeSchema, RuntimeStageAcceptanceSchema, WorkflowStageZoneAccessSchema,
|
|
11
|
-
import {
|
|
9
|
+
import { listBuiltinCompiledZoneSpecs, } from "./workflow-abi.js";
|
|
10
|
+
import { WorkflowCompilerApiSchema, RuntimeContractTypeSchema, RuntimeStageAcceptanceSchema, WorkflowStageZoneAccessSchema, WorkflowCompiledSchemaSchema, WorkflowIdPattern, } from "./schema.js";
|
|
11
|
+
import { writeCompiledSchemaFile, compiledSchemaFilePath } from "./compiled-schema.js";
|
|
12
12
|
const LocalWorkflowStageDefinitionSchema = z.object({
|
|
13
13
|
id: z.string().regex(WorkflowIdPattern),
|
|
14
14
|
label: z.string().min(1),
|
|
@@ -21,32 +21,13 @@ const LocalWorkflowStageDefinitionSchema = z.object({
|
|
|
21
21
|
});
|
|
22
22
|
const LocalWorkflowDefinitionSchema = z.object({
|
|
23
23
|
id: z.string().regex(WorkflowIdPattern),
|
|
24
|
-
type: z.literal("
|
|
24
|
+
type: z.literal("compiled"),
|
|
25
25
|
compiler_api: WorkflowCompilerApiSchema.optional(),
|
|
26
26
|
label: z.string().min(1),
|
|
27
27
|
hint: z.string().min(1),
|
|
28
28
|
extends: z.string().regex(WorkflowIdPattern).optional(),
|
|
29
29
|
stages: z.array(LocalWorkflowStageDefinitionSchema).min(1).optional(),
|
|
30
30
|
stage_policy_notes: z.record(z.string(), z.array(z.string())).optional(),
|
|
31
|
-
}).superRefine((value, ctx) => {
|
|
32
|
-
const stages = value.stages ?? [];
|
|
33
|
-
if (stages.length === 0)
|
|
34
|
-
return;
|
|
35
|
-
const sequence = validateWorkspaceContractSequence(stages.map((stage) => stage.contract_type));
|
|
36
|
-
if (!sequence.orderValid) {
|
|
37
|
-
ctx.addIssue({
|
|
38
|
-
code: z.ZodIssueCode.custom,
|
|
39
|
-
path: ["stages"],
|
|
40
|
-
message: "Workspace workflow stages must keep non-decreasing order: file-evidence -> knowledge-structure -> query-shape.",
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
for (const missing of sequence.missing) {
|
|
44
|
-
ctx.addIssue({
|
|
45
|
-
code: z.ZodIssueCode.custom,
|
|
46
|
-
path: ["stages"],
|
|
47
|
-
message: `Workspace workflows must include at least one ${missing} stage.`,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
31
|
});
|
|
51
32
|
function workflowRootPath(sourcePath) {
|
|
52
33
|
return join(sourcePath, "interf", "workflows");
|
|
@@ -75,21 +56,21 @@ export function loadWorkflowDefinitionFromDir(dirPath) {
|
|
|
75
56
|
const definition = readJsonFileWithSchema(workflowPath, "local workflow definition", LocalWorkflowDefinitionSchema);
|
|
76
57
|
if (!definition)
|
|
77
58
|
return null;
|
|
78
|
-
const schemaPath =
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
59
|
+
const schemaPath = compiledSchemaFilePath(dirPath);
|
|
60
|
+
const compiledSchema = readJsonFileWithSchema(schemaPath, "compiled schema", WorkflowCompiledSchemaSchema);
|
|
61
|
+
if (!compiledSchema)
|
|
81
62
|
return null;
|
|
82
|
-
if (definition.type !== "
|
|
63
|
+
if (definition.type !== "compiled") {
|
|
83
64
|
warnInterf(`Warning: local workflow definition at ${workflowPath} has unexpected type "${definition.type}".`);
|
|
84
65
|
return null;
|
|
85
66
|
}
|
|
86
67
|
return {
|
|
87
68
|
...definition,
|
|
88
|
-
|
|
69
|
+
compiled_schema: compiledSchema,
|
|
89
70
|
starter_docs: collectStarterDocs(dirPath),
|
|
90
71
|
directoryPath: dirPath,
|
|
91
72
|
workflowPath,
|
|
92
|
-
|
|
73
|
+
compiledSchemaPath: schemaPath,
|
|
93
74
|
};
|
|
94
75
|
}
|
|
95
76
|
export function listLocalWorkflowDefinitions(sourcePath) {
|
|
@@ -167,7 +148,7 @@ function readWorkflowJsonObject(dirPath) {
|
|
|
167
148
|
}
|
|
168
149
|
export function patchWorkflowPackageMetadata(dirPath, options = {}) {
|
|
169
150
|
const workflowPath = join(dirPath, "workflow.json");
|
|
170
|
-
const schemaPath =
|
|
151
|
+
const schemaPath = compiledSchemaFilePath(dirPath);
|
|
171
152
|
const workflowJson = readWorkflowJsonObject(dirPath);
|
|
172
153
|
const normalizedStages = Array.isArray(workflowJson.stages) && workflowJson.stages.length > 0
|
|
173
154
|
? workflowJson.stages
|
|
@@ -177,9 +158,9 @@ export function patchWorkflowPackageMetadata(dirPath, options = {}) {
|
|
|
177
158
|
}
|
|
178
159
|
const nextWorkflowJson = {
|
|
179
160
|
...workflowJson,
|
|
180
|
-
type: "
|
|
161
|
+
type: "compiled",
|
|
181
162
|
compiler_api: workflowJson.compiler_api ?? {
|
|
182
|
-
kind: "
|
|
163
|
+
kind: "compiled",
|
|
183
164
|
version: 1,
|
|
184
165
|
},
|
|
185
166
|
stages: normalizedStages,
|
|
@@ -196,12 +177,12 @@ export function patchWorkflowPackageMetadata(dirPath, options = {}) {
|
|
|
196
177
|
delete nextWorkflowJson.stage_policy_notes;
|
|
197
178
|
}
|
|
198
179
|
writeFileSync(workflowPath, JSON.stringify(nextWorkflowJson, null, 2) + "\n");
|
|
199
|
-
const schemaLabel = `${String(nextWorkflowJson.label ?? workflowJson.label ?? options.id ?? "Workflow")}
|
|
180
|
+
const schemaLabel = `${String(nextWorkflowJson.label ?? workflowJson.label ?? options.id ?? "Workflow")} compiled schema`;
|
|
200
181
|
if (!existsSync(schemaPath)) {
|
|
201
|
-
|
|
182
|
+
writeCompiledSchemaFile(dirPath, normalizedStages, schemaLabel);
|
|
202
183
|
return;
|
|
203
184
|
}
|
|
204
|
-
const rawSchema = readJsonFileUnchecked(schemaPath, "
|
|
185
|
+
const rawSchema = readJsonFileUnchecked(schemaPath, "compiled schema");
|
|
205
186
|
if (!rawSchema || typeof rawSchema !== "object" || Array.isArray(rawSchema))
|
|
206
187
|
return;
|
|
207
188
|
writeFileSync(schemaPath, JSON.stringify({
|
|
@@ -212,11 +193,11 @@ export function patchWorkflowPackageMetadata(dirPath, options = {}) {
|
|
|
212
193
|
export function describeWorkflowPackagePortability(dirPath) {
|
|
213
194
|
const issues = [];
|
|
214
195
|
const workflowPath = join(dirPath, "workflow.json");
|
|
215
|
-
const schemaPath =
|
|
196
|
+
const schemaPath = compiledSchemaFilePath(dirPath);
|
|
216
197
|
if (!existsSync(workflowPath))
|
|
217
198
|
issues.push("missing workflow.json");
|
|
218
199
|
if (!existsSync(schemaPath))
|
|
219
|
-
issues.push("missing
|
|
200
|
+
issues.push("missing compiled.schema.json");
|
|
220
201
|
if (!existsSync(join(dirPath, "README.md")))
|
|
221
202
|
issues.push("missing README.md");
|
|
222
203
|
if (!existsSync(join(dirPath, "improve", "SKILL.md")))
|
|
@@ -271,7 +252,7 @@ export function copyWorkflowPackageDirectory(sourceWorkflowPath, targetWorkflowP
|
|
|
271
252
|
}
|
|
272
253
|
export function validateWorkflowPackage(dirPath) {
|
|
273
254
|
const workflowPath = join(dirPath, "workflow.json");
|
|
274
|
-
const schemaPath =
|
|
255
|
+
const schemaPath = compiledSchemaFilePath(dirPath);
|
|
275
256
|
if (!existsSync(workflowPath)) {
|
|
276
257
|
return {
|
|
277
258
|
ok: false,
|
|
@@ -308,7 +289,7 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
308
289
|
errors.push("workflow.json must declare explicit stages. Legacy inherited packages are not portable.");
|
|
309
290
|
}
|
|
310
291
|
if (!existsSync(schemaPath)) {
|
|
311
|
-
errors.push("Missing
|
|
292
|
+
errors.push("Missing compiled.schema.json.");
|
|
312
293
|
}
|
|
313
294
|
if (!existsSync(join(dirPath, "README.md"))) {
|
|
314
295
|
errors.push("Missing README.md.");
|
|
@@ -319,24 +300,11 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
319
300
|
if (!existsSync(join(dirPath, "use", "query", "SKILL.md"))) {
|
|
320
301
|
errors.push("Missing use/query/SKILL.md.");
|
|
321
302
|
}
|
|
322
|
-
const
|
|
323
|
-
if (!
|
|
324
|
-
errors.push("
|
|
303
|
+
const compiledSchema = readJsonFileWithSchema(schemaPath, "compiled schema", WorkflowCompiledSchemaSchema);
|
|
304
|
+
if (!compiledSchema) {
|
|
305
|
+
errors.push("compiled.schema.json is missing or invalid.");
|
|
325
306
|
}
|
|
326
307
|
if (def.stages && def.stages.length > 0) {
|
|
327
|
-
const contractTypes = def.stages.map((stage) => stage.contract_type);
|
|
328
|
-
const sequence = validateWorkspaceContractSequence(contractTypes);
|
|
329
|
-
if (def.stages.length < 3) {
|
|
330
|
-
errors.push("Workspace workflows must include summarize, structure, and shape stages in order.");
|
|
331
|
-
}
|
|
332
|
-
else if (!sequence.orderValid) {
|
|
333
|
-
errors.push("Workspace workflow stages must keep non-decreasing order: file-evidence -> knowledge-structure -> query-shape.");
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
for (const missing of sequence.missing) {
|
|
337
|
-
errors.push(`Workspace workflows must include at least one ${missing} stage.`);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
308
|
for (const stage of def.stages) {
|
|
341
309
|
const skillDir = typeof stage.skill_dir === "string" && stage.skill_dir.trim().length > 0
|
|
342
310
|
? stage.skill_dir
|
|
@@ -346,12 +314,12 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
346
314
|
}
|
|
347
315
|
}
|
|
348
316
|
}
|
|
349
|
-
if (
|
|
317
|
+
if (compiledSchema) {
|
|
350
318
|
const stages = def.stages ?? [];
|
|
351
319
|
const stageIds = new Set(stages.map((stage) => stage.id));
|
|
352
320
|
const seenPaths = new Map();
|
|
353
321
|
const seenZoneIds = new Set();
|
|
354
|
-
const zoneById = new Map(
|
|
322
|
+
const zoneById = new Map(compiledSchema.zones.map((zone) => [zone.id, zone]));
|
|
355
323
|
const normalizedParts = (value) => value.replaceAll("\\", "/").split("/").filter(Boolean);
|
|
356
324
|
const hasOverlappingPath = (value, other) => {
|
|
357
325
|
const a = normalizedParts(value);
|
|
@@ -360,26 +328,26 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
360
328
|
const longer = a.length <= b.length ? b : a;
|
|
361
329
|
return shorter.every((part, index) => longer[index] === part);
|
|
362
330
|
};
|
|
363
|
-
for (const zone of
|
|
331
|
+
for (const zone of compiledSchema.zones) {
|
|
364
332
|
if (seenZoneIds.has(zone.id)) {
|
|
365
|
-
errors.push(`
|
|
333
|
+
errors.push(`compiled.schema.json repeats zone id "${zone.id}".`);
|
|
366
334
|
}
|
|
367
335
|
seenZoneIds.add(zone.id);
|
|
368
336
|
const existingPathOwner = seenPaths.get(zone.path);
|
|
369
337
|
if (existingPathOwner) {
|
|
370
|
-
errors.push(`
|
|
338
|
+
errors.push(`compiled.schema.json repeats zone path "${zone.path}".`);
|
|
371
339
|
}
|
|
372
340
|
for (const [existingPath, existingZoneId] of seenPaths.entries()) {
|
|
373
341
|
if (existingPath === zone.path)
|
|
374
342
|
continue;
|
|
375
343
|
if (hasOverlappingPath(zone.path, existingPath)) {
|
|
376
|
-
errors.push(`
|
|
344
|
+
errors.push(`compiled.schema.json zones "${zone.id}" and "${existingZoneId}" overlap on path "${zone.path}" / "${existingPath}".`);
|
|
377
345
|
}
|
|
378
346
|
}
|
|
379
347
|
seenPaths.set(zone.path, zone.id);
|
|
380
348
|
for (const owner of zone.owned_by) {
|
|
381
349
|
if (!stageIds.has(owner)) {
|
|
382
|
-
errors.push(`
|
|
350
|
+
errors.push(`compiled.schema.json references unknown stage "${owner}" for zone "${zone.path}".`);
|
|
383
351
|
}
|
|
384
352
|
}
|
|
385
353
|
}
|
|
@@ -396,21 +364,18 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
396
364
|
continue;
|
|
397
365
|
}
|
|
398
366
|
if (!zone.owned_by.includes(stage.id)) {
|
|
399
|
-
errors.push(`Stage "${stage.id}" writes zone "${zoneId}" but that zone is not owned by the stage in
|
|
367
|
+
errors.push(`Stage "${stage.id}" writes zone "${zoneId}" but that zone is not owned by the stage in compiled.schema.json.`);
|
|
400
368
|
}
|
|
401
369
|
}
|
|
402
370
|
}
|
|
403
|
-
for (const requiredZone of
|
|
371
|
+
for (const requiredZone of listBuiltinCompiledZoneSpecs().filter((zone) => zone.id === "raw" || zone.id === "runtime")) {
|
|
404
372
|
const match = zoneById.get(requiredZone.id);
|
|
405
373
|
if (!match) {
|
|
406
|
-
errors.push(`
|
|
374
|
+
errors.push(`compiled.schema.json is missing required zone "${requiredZone.id}".`);
|
|
407
375
|
continue;
|
|
408
376
|
}
|
|
409
|
-
if (match.path !== requiredZone.path) {
|
|
410
|
-
errors.push(`workspace.schema.json zone "${requiredZone.id}" should point at "${requiredZone.path}".`);
|
|
411
|
-
}
|
|
412
377
|
if (match.kind !== requiredZone.kind) {
|
|
413
|
-
errors.push(`
|
|
378
|
+
errors.push(`compiled.schema.json zone "${requiredZone.id}" should be kind "${requiredZone.kind}".`);
|
|
414
379
|
}
|
|
415
380
|
}
|
|
416
381
|
}
|
|
@@ -420,7 +385,7 @@ export function validateWorkflowPackage(dirPath) {
|
|
|
420
385
|
const counts = {
|
|
421
386
|
starter_docs: collectStarterDocs(dirPath).length,
|
|
422
387
|
compile_stage_docs: stageDirs.length,
|
|
423
|
-
|
|
388
|
+
compiled_zones: compiledSchema?.zones.length ?? 0,
|
|
424
389
|
};
|
|
425
390
|
return {
|
|
426
391
|
ok: errors.length === 0,
|
package/dist/lib/obsidian.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function writeObsidianDefaults(dirPath: string, type: "
|
|
1
|
+
export declare function writeObsidianDefaults(dirPath: string, type: "compiled"): void;
|
package/dist/lib/parse.js
CHANGED
|
@@ -30,6 +30,91 @@ export function renderJsonFrontmatter(frontmatter) {
|
|
|
30
30
|
"---",
|
|
31
31
|
].join("\n");
|
|
32
32
|
}
|
|
33
|
+
function parseQuotedString(value) {
|
|
34
|
+
if (value.length < 2)
|
|
35
|
+
return null;
|
|
36
|
+
const quote = value[0];
|
|
37
|
+
if ((quote !== "\"" && quote !== "'") || value[value.length - 1] !== quote)
|
|
38
|
+
return null;
|
|
39
|
+
const inner = value.slice(1, -1);
|
|
40
|
+
if (quote === "\"") {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return inner.replace(/\\'/g, "'");
|
|
49
|
+
}
|
|
50
|
+
function parseYamlScalar(value) {
|
|
51
|
+
const trimmed = value.trim();
|
|
52
|
+
if (trimmed.length === 0)
|
|
53
|
+
return "";
|
|
54
|
+
const quoted = parseQuotedString(trimmed);
|
|
55
|
+
if (quoted !== null)
|
|
56
|
+
return quoted;
|
|
57
|
+
if (trimmed === "true")
|
|
58
|
+
return true;
|
|
59
|
+
if (trimmed === "false")
|
|
60
|
+
return false;
|
|
61
|
+
if (trimmed === "null")
|
|
62
|
+
return null;
|
|
63
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed))
|
|
64
|
+
return Number(trimmed);
|
|
65
|
+
if ((trimmed.startsWith("[") && trimmed.endsWith("]"))
|
|
66
|
+
|| (trimmed.startsWith("{") && trimmed.endsWith("}"))) {
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(trimmed);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return trimmed;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
76
|
+
function parseYamlFrontmatter(frontmatterText) {
|
|
77
|
+
const lines = frontmatterText.split("\n");
|
|
78
|
+
const frontmatter = {};
|
|
79
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
80
|
+
const line = lines[index] ?? "";
|
|
81
|
+
const trimmed = line.trim();
|
|
82
|
+
if (trimmed.length === 0 || trimmed.startsWith("#"))
|
|
83
|
+
continue;
|
|
84
|
+
const match = line.match(/^([A-Za-z0-9_-]+):(?:\s+(.*))?$/);
|
|
85
|
+
if (!match)
|
|
86
|
+
return null;
|
|
87
|
+
const [, key, inlineValue] = match;
|
|
88
|
+
if (!key)
|
|
89
|
+
return null;
|
|
90
|
+
if (inlineValue && inlineValue.trim().length > 0) {
|
|
91
|
+
frontmatter[key] = parseYamlScalar(inlineValue);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const items = [];
|
|
95
|
+
let cursor = index + 1;
|
|
96
|
+
while (cursor < lines.length) {
|
|
97
|
+
const nextLine = lines[cursor] ?? "";
|
|
98
|
+
const nextTrimmed = nextLine.trim();
|
|
99
|
+
if (nextTrimmed.length === 0) {
|
|
100
|
+
cursor += 1;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const itemMatch = nextLine.match(/^\s*-\s+(.*)$/);
|
|
104
|
+
if (!itemMatch || !/^\s+/.test(nextLine))
|
|
105
|
+
break;
|
|
106
|
+
items.push(parseYamlScalar(itemMatch[1] ?? ""));
|
|
107
|
+
cursor += 1;
|
|
108
|
+
}
|
|
109
|
+
if (items.length > 0) {
|
|
110
|
+
frontmatter[key] = items;
|
|
111
|
+
index = cursor - 1;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
frontmatter[key] = "";
|
|
115
|
+
}
|
|
116
|
+
return Object.keys(frontmatter).length > 0 ? frontmatter : null;
|
|
117
|
+
}
|
|
33
118
|
export function parseJsonFrontmatter(content) {
|
|
34
119
|
const normalized = content.replace(/\r\n/g, "\n");
|
|
35
120
|
const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
@@ -49,6 +134,12 @@ export function parseJsonFrontmatter(content) {
|
|
|
49
134
|
};
|
|
50
135
|
}
|
|
51
136
|
catch {
|
|
52
|
-
|
|
137
|
+
const frontmatter = parseYamlFrontmatter(frontmatterText);
|
|
138
|
+
if (!frontmatter)
|
|
139
|
+
return null;
|
|
140
|
+
return {
|
|
141
|
+
frontmatter,
|
|
142
|
+
body,
|
|
143
|
+
};
|
|
53
144
|
}
|
|
54
145
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const PROJECT_INTERF_DIR = "interf";
|
|
2
|
+
export declare const PROJECT_WORKFLOW_DIR = "workflows";
|
|
3
|
+
export declare const PROJECT_COMPILED_DIR = "compiled";
|
|
4
|
+
export declare const PROJECT_TESTS_DIR = "tests";
|
|
5
|
+
export declare function projectInterfRoot(projectPath: string): string;
|
|
6
|
+
export declare function projectWorkflowRoot(projectPath: string): string;
|
|
7
|
+
export declare function datasetArtifactRoot(projectPath: string, datasetName: string): string;
|
|
8
|
+
export declare function compiledCompiledPathForDataset(projectPath: string, datasetName: string): string;
|
|
9
|
+
export declare function datasetTestsRoot(projectPath: string, datasetName: string): string;
|
|
10
|
+
export type DatasetTestTargetLabel = "file-as-is" | "compiled";
|
|
11
|
+
export declare function datasetTestRunsRoot(projectPath: string, datasetName: string, target: DatasetTestTargetLabel): string;
|
|
12
|
+
export declare function datasetLatestTestStatePath(projectPath: string, datasetName: string): string;
|
|
13
|
+
export declare function datasetLatestTestSummaryPath(projectPath: string, datasetName: string): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
export const PROJECT_INTERF_DIR = "interf";
|
|
3
|
+
export const PROJECT_WORKFLOW_DIR = "workflows";
|
|
4
|
+
export const PROJECT_COMPILED_DIR = "compiled";
|
|
5
|
+
export const PROJECT_TESTS_DIR = "tests";
|
|
6
|
+
export function projectInterfRoot(projectPath) {
|
|
7
|
+
return join(projectPath, PROJECT_INTERF_DIR);
|
|
8
|
+
}
|
|
9
|
+
export function projectWorkflowRoot(projectPath) {
|
|
10
|
+
return join(projectInterfRoot(projectPath), PROJECT_WORKFLOW_DIR);
|
|
11
|
+
}
|
|
12
|
+
export function datasetArtifactRoot(projectPath, datasetName) {
|
|
13
|
+
return join(projectInterfRoot(projectPath), datasetName);
|
|
14
|
+
}
|
|
15
|
+
export function compiledCompiledPathForDataset(projectPath, datasetName) {
|
|
16
|
+
return join(datasetArtifactRoot(projectPath, datasetName), PROJECT_COMPILED_DIR);
|
|
17
|
+
}
|
|
18
|
+
export function datasetTestsRoot(projectPath, datasetName) {
|
|
19
|
+
return join(datasetArtifactRoot(projectPath, datasetName), PROJECT_TESTS_DIR);
|
|
20
|
+
}
|
|
21
|
+
export function datasetTestRunsRoot(projectPath, datasetName, target) {
|
|
22
|
+
return join(datasetTestsRoot(projectPath, datasetName), target, "runs");
|
|
23
|
+
}
|
|
24
|
+
export function datasetLatestTestStatePath(projectPath, datasetName) {
|
|
25
|
+
return join(datasetTestsRoot(projectPath, datasetName), "latest.json");
|
|
26
|
+
}
|
|
27
|
+
export function datasetLatestTestSummaryPath(projectPath, datasetName) {
|
|
28
|
+
return join(datasetTestsRoot(projectPath, datasetName), "latest.md");
|
|
29
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import { type RuntimeStageContract } from "./schema.js";
|
|
1
|
+
import { type CompiledState, type RuntimeStageAcceptance, type RuntimeStageContract } from "./schema.js";
|
|
2
2
|
import { type RuntimeStageAcceptanceValidation } from "./runtime-types.js";
|
|
3
|
+
export declare function stageRecordFromState(state: CompiledState | null, stageId: string): Record<string, unknown> | null;
|
|
4
|
+
export declare function validateResolvedStageAcceptance(dirPath: string, options: {
|
|
5
|
+
stageId: string;
|
|
6
|
+
acceptance?: RuntimeStageAcceptance;
|
|
7
|
+
counts?: Record<string, number>;
|
|
8
|
+
}): RuntimeStageAcceptanceValidation;
|
|
3
9
|
export declare function validateStageContractAcceptance(dirPath: string, contract?: RuntimeStageContract | null): RuntimeStageAcceptanceValidation;
|