@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.
Files changed (160) hide show
  1. package/README.md +71 -69
  2. package/builtin-workflows/interf/README.md +6 -6
  3. package/builtin-workflows/interf/compile/stages/shape/SKILL.md +7 -7
  4. package/builtin-workflows/interf/compile/stages/structure/SKILL.md +2 -2
  5. package/builtin-workflows/interf/compile/stages/summarize/SKILL.md +1 -1
  6. package/builtin-workflows/interf/{workspace.schema.json → compiled.schema.json} +5 -5
  7. package/builtin-workflows/interf/improve/SKILL.md +3 -3
  8. package/builtin-workflows/interf/use/query/SKILL.md +2 -2
  9. package/builtin-workflows/interf/workflow.json +42 -31
  10. package/dist/commands/check-draft.d.ts +19 -0
  11. package/dist/commands/check-draft.js +110 -0
  12. package/dist/commands/compile-controller.d.ts +4 -4
  13. package/dist/commands/compile-controller.js +117 -81
  14. package/dist/commands/compile.d.ts +5 -5
  15. package/dist/commands/compile.js +61 -62
  16. package/dist/commands/compiled-flow.d.ts +23 -0
  17. package/dist/commands/compiled-flow.js +112 -0
  18. package/dist/commands/create-workflow-wizard.d.ts +3 -3
  19. package/dist/commands/create-workflow-wizard.js +11 -11
  20. package/dist/commands/create.d.ts +2 -2
  21. package/dist/commands/create.js +50 -57
  22. package/dist/commands/default.js +2 -2
  23. package/dist/commands/executor-flow.d.ts +20 -1
  24. package/dist/commands/executor-flow.js +67 -7
  25. package/dist/commands/init.js +242 -289
  26. package/dist/commands/list.js +14 -10
  27. package/dist/commands/reset.js +6 -6
  28. package/dist/commands/source-config-wizard.d.ts +12 -8
  29. package/dist/commands/source-config-wizard.js +356 -119
  30. package/dist/commands/status.js +49 -26
  31. package/dist/commands/test-flow.d.ts +23 -10
  32. package/dist/commands/test-flow.js +278 -58
  33. package/dist/commands/test.d.ts +7 -1
  34. package/dist/commands/test.js +264 -65
  35. package/dist/commands/verify.js +23 -14
  36. package/dist/index.d.ts +7 -7
  37. package/dist/index.js +4 -4
  38. package/dist/lib/agent-args.js +2 -1
  39. package/dist/lib/agent-constants.js +1 -1
  40. package/dist/lib/agent-render.js +4 -4
  41. package/dist/lib/agent-shells.d.ts +8 -8
  42. package/dist/lib/agent-shells.js +231 -142
  43. package/dist/lib/compiled-compile.d.ts +52 -0
  44. package/dist/lib/compiled-compile.js +274 -0
  45. package/dist/lib/compiled-home.d.ts +5 -0
  46. package/dist/lib/compiled-home.js +32 -0
  47. package/dist/lib/compiled-layout.d.ts +2 -0
  48. package/dist/lib/compiled-layout.js +60 -0
  49. package/dist/lib/compiled-paths.d.ts +41 -0
  50. package/dist/lib/compiled-paths.js +111 -0
  51. package/dist/lib/{workspace-raw.d.ts → compiled-raw.d.ts} +8 -7
  52. package/dist/lib/{workspace-raw.js → compiled-raw.js} +16 -14
  53. package/dist/lib/compiled-reset.d.ts +1 -0
  54. package/dist/lib/compiled-reset.js +44 -0
  55. package/dist/lib/compiled-schema.d.ts +27 -0
  56. package/dist/lib/compiled-schema.js +110 -0
  57. package/dist/lib/config.d.ts +0 -1
  58. package/dist/lib/config.js +0 -1
  59. package/dist/lib/discovery.d.ts +1 -1
  60. package/dist/lib/discovery.js +3 -3
  61. package/dist/lib/interf-bootstrap.d.ts +1 -1
  62. package/dist/lib/interf-bootstrap.js +4 -4
  63. package/dist/lib/interf-detect.d.ts +10 -10
  64. package/dist/lib/interf-detect.js +78 -56
  65. package/dist/lib/interf-scaffold.d.ts +2 -2
  66. package/dist/lib/interf-scaffold.js +90 -57
  67. package/dist/lib/interf-workflow-package.d.ts +3 -3
  68. package/dist/lib/interf-workflow-package.js +30 -30
  69. package/dist/lib/interf.d.ts +5 -5
  70. package/dist/lib/interf.js +4 -4
  71. package/dist/lib/local-workflows.d.ts +4 -4
  72. package/dist/lib/local-workflows.js +35 -70
  73. package/dist/lib/obsidian.d.ts +1 -1
  74. package/dist/lib/parse.js +92 -1
  75. package/dist/lib/project-paths.d.ts +13 -0
  76. package/dist/lib/project-paths.js +29 -0
  77. package/dist/lib/runtime-acceptance.d.ts +7 -1
  78. package/dist/lib/runtime-acceptance.js +194 -59
  79. package/dist/lib/runtime-contracts.d.ts +2 -4
  80. package/dist/lib/runtime-contracts.js +17 -161
  81. package/dist/lib/runtime-inventory.d.ts +7 -0
  82. package/dist/lib/runtime-inventory.js +29 -0
  83. package/dist/lib/runtime-paths.js +5 -5
  84. package/dist/lib/runtime-prompt.js +9 -6
  85. package/dist/lib/runtime-reconcile.d.ts +2 -3
  86. package/dist/lib/runtime-reconcile.js +92 -171
  87. package/dist/lib/runtime-runs.js +30 -39
  88. package/dist/lib/runtime-types.d.ts +10 -19
  89. package/dist/lib/runtime.d.ts +2 -2
  90. package/dist/lib/runtime.js +1 -1
  91. package/dist/lib/schema.d.ts +163 -140
  92. package/dist/lib/schema.js +163 -124
  93. package/dist/lib/source-config.d.ts +24 -20
  94. package/dist/lib/source-config.js +154 -116
  95. package/dist/lib/state-artifacts.d.ts +5 -5
  96. package/dist/lib/state-artifacts.js +8 -8
  97. package/dist/lib/state-health.d.ts +4 -4
  98. package/dist/lib/state-health.js +108 -126
  99. package/dist/lib/state-io.d.ts +8 -8
  100. package/dist/lib/state-io.js +77 -50
  101. package/dist/lib/state-paths.js +5 -5
  102. package/dist/lib/state-view.d.ts +4 -4
  103. package/dist/lib/state-view.js +52 -55
  104. package/dist/lib/state.d.ts +5 -5
  105. package/dist/lib/state.js +4 -4
  106. package/dist/lib/summarize-plan.d.ts +3 -2
  107. package/dist/lib/summarize-plan.js +18 -16
  108. package/dist/lib/test-execution.js +9 -9
  109. package/dist/lib/test-matrices.d.ts +3 -3
  110. package/dist/lib/test-matrices.js +6 -6
  111. package/dist/lib/test-paths.d.ts +4 -4
  112. package/dist/lib/test-paths.js +16 -10
  113. package/dist/lib/test-sandbox.d.ts +1 -1
  114. package/dist/lib/test-sandbox.js +38 -31
  115. package/dist/lib/test-targets.d.ts +2 -2
  116. package/dist/lib/test-targets.js +11 -11
  117. package/dist/lib/test-types.d.ts +1 -1
  118. package/dist/lib/test.d.ts +1 -1
  119. package/dist/lib/test.js +1 -1
  120. package/dist/lib/util.d.ts +2 -0
  121. package/dist/lib/util.js +14 -1
  122. package/dist/lib/validate-compiled.d.ts +27 -0
  123. package/dist/lib/validate-compiled.js +236 -0
  124. package/dist/lib/validate-helpers.d.ts +0 -8
  125. package/dist/lib/validate-helpers.js +0 -30
  126. package/dist/lib/validate.d.ts +4 -4
  127. package/dist/lib/validate.js +49 -15
  128. package/dist/lib/workflow-abi.d.ts +37 -46
  129. package/dist/lib/workflow-abi.js +51 -76
  130. package/dist/lib/workflow-definitions.d.ts +11 -11
  131. package/dist/lib/workflow-definitions.js +36 -53
  132. package/dist/lib/workflow-helpers.d.ts +2 -3
  133. package/dist/lib/workflow-helpers.js +9 -13
  134. package/dist/lib/workflow-improvement.d.ts +3 -3
  135. package/dist/lib/workflow-improvement.js +48 -48
  136. package/dist/lib/workflow-review-paths.d.ts +3 -3
  137. package/dist/lib/workflow-review-paths.js +11 -11
  138. package/dist/lib/workflow-stage-runner.d.ts +1 -1
  139. package/dist/lib/workflow-stage-runner.js +8 -8
  140. package/dist/lib/workflows.d.ts +9 -9
  141. package/dist/lib/workflows.js +15 -17
  142. package/package.json +10 -9
  143. package/dist/commands/workspace-flow.d.ts +0 -23
  144. package/dist/commands/workspace-flow.js +0 -109
  145. package/dist/lib/registry.d.ts +0 -16
  146. package/dist/lib/registry.js +0 -65
  147. package/dist/lib/validate-workspace.d.ts +0 -121
  148. package/dist/lib/validate-workspace.js +0 -407
  149. package/dist/lib/workspace-compile.d.ts +0 -54
  150. package/dist/lib/workspace-compile.js +0 -476
  151. package/dist/lib/workspace-home.d.ts +0 -5
  152. package/dist/lib/workspace-home.js +0 -32
  153. package/dist/lib/workspace-layout.d.ts +0 -2
  154. package/dist/lib/workspace-layout.js +0 -60
  155. package/dist/lib/workspace-paths.d.ts +0 -41
  156. package/dist/lib/workspace-paths.js +0 -107
  157. package/dist/lib/workspace-reset.d.ts +0 -1
  158. package/dist/lib/workspace-reset.js +0 -43
  159. package/dist/lib/workspace-schema.d.ts +0 -17
  160. 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 { listBuiltinWorkspaceZoneSpecs, validateWorkspaceContractSequence, } from "./workflow-abi.js";
10
- import { WorkflowCompilerApiSchema, RuntimeContractTypeSchema, RuntimeStageAcceptanceSchema, WorkflowStageZoneAccessSchema, WorkflowWorkspaceSchemaSchema, WorkflowIdPattern, } from "./schema.js";
11
- import { writeWorkspaceSchemaFile, workspaceSchemaFilePath } from "./workspace-schema.js";
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("workspace"),
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 = workspaceSchemaFilePath(dirPath);
79
- const workspaceSchema = readJsonFileWithSchema(schemaPath, "workspace schema", WorkflowWorkspaceSchemaSchema);
80
- if (!workspaceSchema)
59
+ const schemaPath = compiledSchemaFilePath(dirPath);
60
+ const compiledSchema = readJsonFileWithSchema(schemaPath, "compiled schema", WorkflowCompiledSchemaSchema);
61
+ if (!compiledSchema)
81
62
  return null;
82
- if (definition.type !== "workspace") {
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
- workspace_schema: workspaceSchema,
69
+ compiled_schema: compiledSchema,
89
70
  starter_docs: collectStarterDocs(dirPath),
90
71
  directoryPath: dirPath,
91
72
  workflowPath,
92
- workspaceSchemaPath: schemaPath,
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 = workspaceSchemaFilePath(dirPath);
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: "workspace",
161
+ type: "compiled",
181
162
  compiler_api: workflowJson.compiler_api ?? {
182
- kind: "workspace",
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")} workspace schema`;
180
+ const schemaLabel = `${String(nextWorkflowJson.label ?? workflowJson.label ?? options.id ?? "Workflow")} compiled schema`;
200
181
  if (!existsSync(schemaPath)) {
201
- writeWorkspaceSchemaFile(dirPath, normalizedStages, schemaLabel);
182
+ writeCompiledSchemaFile(dirPath, normalizedStages, schemaLabel);
202
183
  return;
203
184
  }
204
- const rawSchema = readJsonFileUnchecked(schemaPath, "workspace schema");
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 = workspaceSchemaFilePath(dirPath);
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 workspace.schema.json");
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 = workspaceSchemaFilePath(dirPath);
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 workspace.schema.json.");
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 workspaceSchema = readJsonFileWithSchema(schemaPath, "workspace schema", WorkflowWorkspaceSchemaSchema);
323
- if (!workspaceSchema) {
324
- errors.push("workspace.schema.json is missing or invalid.");
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 (workspaceSchema) {
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(workspaceSchema.zones.map((zone) => [zone.id, zone]));
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 workspaceSchema.zones) {
331
+ for (const zone of compiledSchema.zones) {
364
332
  if (seenZoneIds.has(zone.id)) {
365
- errors.push(`workspace.schema.json repeats zone id "${zone.id}".`);
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(`workspace.schema.json repeats zone path "${zone.path}".`);
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(`workspace.schema.json zones "${zone.id}" and "${existingZoneId}" overlap on path "${zone.path}" / "${existingPath}".`);
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(`workspace.schema.json references unknown stage "${owner}" for zone "${zone.path}".`);
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 workspace.schema.json.`);
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 listBuiltinWorkspaceZoneSpecs()) {
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(`workspace.schema.json is missing required zone "${requiredZone.id}".`);
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(`workspace.schema.json zone "${requiredZone.path}" should be kind "${requiredZone.kind}".`);
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
- workspace_zones: workspaceSchema?.zones.length ?? 0,
388
+ compiled_zones: compiledSchema?.zones.length ?? 0,
424
389
  };
425
390
  return {
426
391
  ok: errors.length === 0,
@@ -1 +1 @@
1
- export declare function writeObsidianDefaults(dirPath: string, type: "workspace"): void;
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
- return null;
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;