@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.
Files changed (162) hide show
  1. package/README.md +70 -66
  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 +274 -65
  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/{workflow-abi.d.ts → builtin-compiled-workflow.d.ts} +37 -46
  44. package/dist/lib/builtin-compiled-workflow.js +153 -0
  45. package/dist/lib/compiled-compile.d.ts +52 -0
  46. package/dist/lib/compiled-compile.js +274 -0
  47. package/dist/lib/compiled-home.d.ts +5 -0
  48. package/dist/lib/compiled-home.js +32 -0
  49. package/dist/lib/compiled-paths.d.ts +39 -0
  50. package/dist/lib/compiled-paths.js +103 -0
  51. package/dist/lib/{workspace-raw.d.ts → compiled-raw.d.ts} +9 -8
  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 +9 -10
  64. package/dist/lib/interf-detect.js +70 -59
  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 +11 -0
  76. package/dist/lib/project-paths.js +32 -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 +7 -6
  85. package/dist/lib/runtime-reconcile.d.ts +2 -3
  86. package/dist/lib/runtime-reconcile.js +94 -184
  87. package/dist/lib/runtime-runs.js +25 -119
  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 +169 -153
  92. package/dist/lib/schema.js +116 -164
  93. package/dist/lib/source-config.d.ts +24 -20
  94. package/dist/lib/source-config.js +159 -122
  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 +110 -126
  99. package/dist/lib/state-io.d.ts +8 -8
  100. package/dist/lib/state-io.js +21 -102
  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 +19 -21
  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 +26 -11
  113. package/dist/lib/test-sandbox.d.ts +1 -1
  114. package/dist/lib/test-sandbox.js +32 -38
  115. package/dist/lib/test-specs.js +1 -1
  116. package/dist/lib/test-targets.d.ts +2 -2
  117. package/dist/lib/test-targets.js +11 -11
  118. package/dist/lib/test-types.d.ts +1 -1
  119. package/dist/lib/test.d.ts +1 -1
  120. package/dist/lib/test.js +1 -1
  121. package/dist/lib/util.d.ts +2 -0
  122. package/dist/lib/util.js +14 -1
  123. package/dist/lib/validate-compiled.d.ts +27 -0
  124. package/dist/lib/validate-compiled.js +238 -0
  125. package/dist/lib/validate-helpers.d.ts +0 -8
  126. package/dist/lib/validate-helpers.js +0 -30
  127. package/dist/lib/validate.d.ts +6 -4
  128. package/dist/lib/validate.js +76 -27
  129. package/dist/lib/workflow-definitions.d.ts +12 -11
  130. package/dist/lib/workflow-definitions.js +45 -55
  131. package/dist/lib/workflow-helpers.d.ts +2 -3
  132. package/dist/lib/workflow-helpers.js +9 -13
  133. package/dist/lib/workflow-improvement.d.ts +3 -3
  134. package/dist/lib/workflow-improvement.js +48 -48
  135. package/dist/lib/workflow-primitives.d.ts +2 -0
  136. package/dist/lib/workflow-primitives.js +5 -0
  137. package/dist/lib/workflow-review-paths.d.ts +3 -3
  138. package/dist/lib/workflow-review-paths.js +11 -11
  139. package/dist/lib/workflow-stage-runner.d.ts +1 -1
  140. package/dist/lib/workflow-stage-runner.js +8 -8
  141. package/dist/lib/workflows.d.ts +9 -9
  142. package/dist/lib/workflows.js +15 -17
  143. package/package.json +13 -12
  144. package/dist/commands/workspace-flow.d.ts +0 -23
  145. package/dist/commands/workspace-flow.js +0 -109
  146. package/dist/lib/registry.d.ts +0 -16
  147. package/dist/lib/registry.js +0 -65
  148. package/dist/lib/validate-workspace.d.ts +0 -121
  149. package/dist/lib/validate-workspace.js +0 -407
  150. package/dist/lib/workflow-abi.js +0 -181
  151. package/dist/lib/workspace-compile.d.ts +0 -54
  152. package/dist/lib/workspace-compile.js +0 -476
  153. package/dist/lib/workspace-home.d.ts +0 -5
  154. package/dist/lib/workspace-home.js +0 -32
  155. package/dist/lib/workspace-layout.d.ts +0 -2
  156. package/dist/lib/workspace-layout.js +0 -60
  157. package/dist/lib/workspace-paths.d.ts +0 -41
  158. package/dist/lib/workspace-paths.js +0 -107
  159. package/dist/lib/workspace-reset.d.ts +0 -1
  160. package/dist/lib/workspace-reset.js +0 -43
  161. package/dist/lib/workspace-schema.d.ts +0 -17
  162. 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
- }
@@ -1,5 +1,5 @@
1
1
  import { readInterfConfig } from "./interf.js";
2
- export declare function readWorkspaceConfig(dirPath: string): {
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(workspaceRoot: string, noteIndexRoots: string[], linkScanRoots: string[]): number;
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 { validateWorkspace, validateWorkspaceSummarize, validateWorkspaceStructure, validateWorkspaceCompile, } from "./validate-workspace.js";
17
- export type { WorkspaceValidationSummary, WorkspaceSummarizeValidation, WorkspaceStructureValidation, WorkspaceCompileValidation, } from "./validate-workspace.js";
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";
@@ -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 { workspaceInterfConfigPath } from "./workspace-paths.js";
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
- const KNOWLEDGE_RELATIVE_PREFIXES = new Set(["entities", "claims", "indexes"]);
16
- export function readWorkspaceConfig(dirPath) {
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 === "workspace" && typeof value?.source?.path === "string";
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 = countAbstractWords(parsed.frontmatter, parsed.body);
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(workspaceRoot, noteIndexRoots, linkScanRoots) {
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(workspaceRoot, target)) {
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 || "source_file" in frontmatter || "raw" in frontmatter;
142
+ const hasSourceReference = "source" in frontmatter;
136
143
  return hasSourceReference && REQUIRED_DIGEST_FIELDS.every((field) => field in frontmatter);
137
144
  }
138
- function countAbstractWords(frontmatter, body) {
139
- const frontmatterAbstract = typeof frontmatter.abstract === "string" ? frontmatter.abstract : null;
140
- if (frontmatterAbstract && frontmatterAbstract.trim().length > 0) {
141
- return countWords(frontmatterAbstract);
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 match = body.match(/^## Abstract\s+([\s\S]*?)(?:\n## |\n# |$)/m);
144
- if (!match)
145
- return 0;
146
- const abstractText = match[1];
147
- if (!abstractText)
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(abstractText);
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(workspaceRoot, target) {
161
- return linkPathCandidates(workspaceRoot, target).some((candidate) => existsSync(candidate));
182
+ function wikilinkPathExists(compiledRoot, target, zonePathById, knowledgeRelativePrefixes) {
183
+ return linkPathCandidates(compiledRoot, target, zonePathById, knowledgeRelativePrefixes)
184
+ .some((candidate) => existsSync(candidate));
162
185
  }
163
- function linkPathCandidates(workspaceRoot, target) {
186
+ function linkPathCandidates(compiledRoot, target, zonePathById, knowledgeRelativePrefixes) {
164
187
  const candidates = new Set();
165
- addPathCandidate(candidates, join(workspaceRoot, target));
188
+ addPathCandidate(candidates, join(compiledRoot, target));
166
189
  const [firstSegment] = target.split("/");
167
- if (firstSegment && KNOWLEDGE_RELATIVE_PREFIXES.has(firstSegment)) {
168
- addPathCandidate(candidates, join(workspaceRoot, "knowledge", target));
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 { validateWorkspace, validateWorkspaceSummarize, validateWorkspaceStructure, validateWorkspaceCompile, } from "./validate-workspace.js";
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 WorkspaceWorkflowId = string;
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 listWorkspaceWorkflowChoices(sourcePath?: string): WorkflowDefinition<string>[];
47
- export declare function getWorkspaceWorkflow(workflowId: WorkspaceWorkflowId, options?: {
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 getActiveWorkspaceWorkflow(workspacePath: string, fallbackWorkflowId: WorkspaceWorkflowId): WorkflowDefinition<string>;
51
- export declare function resolveWorkspaceWorkflowId(value: unknown): WorkspaceWorkflowId;
52
- export declare function resolveWorkspaceWorkflowFromConfig(config: unknown): WorkspaceWorkflowId;
53
- export declare function formatWorkspaceWorkflowStageStep(workflowId: WorkspaceWorkflowId, stage: string, options?: {
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 getActiveWorkspaceStages(workspacePath: string, fallbackWorkflowId: WorkflowId): string[];
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 getActiveWorkspaceStagePolicyNotes(workspacePath: string, fallbackWorkflowId: WorkflowId, stage: string): string[];
66
- export declare function resolveActiveWorkspaceStageAcceptance(workspacePath: string, fallbackWorkflowId: WorkflowId, stage: string): WorkflowStageDefinition["acceptance"] | undefined;
67
- export declare function formatActiveWorkspaceWorkflowStageStep(workspacePath: string, fallbackWorkflowId: WorkspaceWorkflowId, stage: string): string;
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;