@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
@@ -1,407 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { join } from "node:path";
3
- import { countFilesRecursive, listFilesRecursive } from "./filesystem.js";
4
- import { discoverSourceFiles } from "./discovery.js";
5
- import { resolveSourceFolderPath } from "./interf.js";
6
- import { readJsonFileUnchecked } from "./parse.js";
7
- import { workspaceHomeIsShaped } from "./workspace-home.js";
8
- import { WorkspaceInventorySchema, WorkspaceStateSchema, } from "./schema.js";
9
- import { readWorkspaceConfig, validateSynthFiles, countBrokenWikilinks, asNumber, isOutputMarkdownFile, } from "./validate.js";
10
- import { readInventoryFiles, readInventoryTotal, } from "./validate-helpers.js";
11
- import { workspaceInterfConfigPath, workspaceRuntimeRoot, } from "./workspace-paths.js";
12
- export function validateWorkspace(dirPath) {
13
- const config = readWorkspaceConfig(dirPath);
14
- const summaryFiles = listFilesRecursive(join(dirPath, "summaries"), isOutputMarkdownFile);
15
- const summaryValidation = validateSynthFiles(summaryFiles);
16
- const brokenLinks = countBrokenWikilinks(dirPath, [join(dirPath, "summaries"), join(dirPath, "knowledge")], [join(dirPath, "summaries"), join(dirPath, "knowledge")]);
17
- return {
18
- config_present: config.present,
19
- config_valid: config.valid,
20
- config_type_match: config.typeMatch(),
21
- summary_frontmatter_valid: summaryValidation.invalid_frontmatter === 0,
22
- abstracts_valid: summaryValidation.short_abstracts === 0,
23
- invalid_frontmatter: summaryValidation.invalid_frontmatter,
24
- short_abstracts: summaryValidation.short_abstracts,
25
- broken_links: brokenLinks,
26
- };
27
- }
28
- export function validateWorkspaceSummarize(dirPath) {
29
- const config = readWorkspaceConfig(dirPath);
30
- const sourcePath = resolveSourceFolderPath(dirPath, config.value);
31
- const discovery = discoverSourceFiles(sourcePath, dirPath);
32
- const sourceTotal = discovery.totalCount;
33
- const summariesPresent = existsSync(join(dirPath, "summaries"));
34
- const summaryFiles = listFilesRecursive(join(dirPath, "summaries"), isOutputMarkdownFile);
35
- const summaryValidation = validateSynthFiles(summaryFiles);
36
- const summarized = summaryFiles.length;
37
- const runtimeRoot = workspaceRuntimeRoot(dirPath);
38
- const statePath = join(runtimeRoot, "state.json");
39
- const inventoryPath = join(runtimeRoot, "inventory.json");
40
- const statePresent = existsSync(statePath);
41
- const inventoryPresent = existsSync(inventoryPath);
42
- const state = statePresent
43
- ? readJsonFileUnchecked(statePath, "workspace state")
44
- : null;
45
- const inventory = inventoryPresent
46
- ? readJsonFileUnchecked(inventoryPath, "workspace inventory")
47
- : null;
48
- const inventoryValid = inventory !== null && WorkspaceInventorySchema.safeParse(inventory).success;
49
- const inventoryFilesByShape = readInventoryFiles(inventory);
50
- const inventoryFiles = inventoryFilesByShape.files;
51
- const inventoryTotal = readInventoryTotal(inventory, inventoryFilesByShape);
52
- const sourceCovered = Math.min(sourceTotal, summarized);
53
- const toSummarize = Math.max(0, sourceTotal - sourceCovered);
54
- const required = sourceTotal > 0 || summarized > 0;
55
- const checks = {
56
- config_present: config.present,
57
- config_valid: config.valid,
58
- config_type_match: config.typeMatch(),
59
- summaries_present: summariesPresent,
60
- state_present: statePresent,
61
- state_valid: state !== null && WorkspaceStateSchema.safeParse(state).success,
62
- inventory_present: inventoryPresent,
63
- inventory_valid: inventoryValid,
64
- inventory_complete: Boolean(state?.inventory_complete) === true,
65
- inventory_matches_summaries: inventoryValid && inventoryTotal === summarized && inventoryFiles.length === summarized,
66
- state_covers_summaries: asNumber(state?.summarized) >= summarized &&
67
- typeof state?.last_summarize === "string" &&
68
- state.last_summarize.length > 0,
69
- full_source_coverage: toSummarize === 0,
70
- summary_frontmatter_valid: summaryValidation.invalid_frontmatter === 0,
71
- abstracts_valid: summaryValidation.short_abstracts === 0,
72
- };
73
- const errors = [];
74
- if (!checks.config_present)
75
- errors.push(`Missing ${workspaceInterfConfigPath(dirPath)}.`);
76
- else if (!checks.config_valid)
77
- errors.push(`Could not parse ${workspaceInterfConfigPath(dirPath)}.`);
78
- else if (!checks.config_type_match)
79
- errors.push("Config is not a workspace.");
80
- if (required && !checks.summaries_present)
81
- errors.push("Missing summaries/ directory.");
82
- if (required && !checks.state_present)
83
- errors.push("Missing .interf/runtime/state.json.");
84
- else if (required && !checks.state_valid)
85
- errors.push("Could not parse .interf/runtime/state.json.");
86
- if (required && !checks.inventory_present)
87
- errors.push("Missing .interf/runtime/inventory.json.");
88
- else if (required && !checks.inventory_valid)
89
- errors.push("Could not parse .interf/runtime/inventory.json or it has the wrong shape.");
90
- if (required && checks.inventory_present && checks.inventory_valid && !checks.inventory_complete) {
91
- errors.push("state.json does not mark inventory_complete.");
92
- }
93
- if (required && checks.inventory_present && checks.inventory_valid && !checks.inventory_matches_summaries) {
94
- errors.push("Inventory does not match the summary set.");
95
- }
96
- if (required && checks.state_present && checks.state_valid && !checks.state_covers_summaries) {
97
- errors.push("state.json does not prove summarize completion.");
98
- }
99
- if (!checks.full_source_coverage)
100
- errors.push("Not every source file has a summary yet.");
101
- if (!checks.summary_frontmatter_valid)
102
- errors.push("Some summary files have invalid or incomplete frontmatter.");
103
- if (!checks.abstracts_valid)
104
- errors.push("Some summary files are missing a valid abstract block.");
105
- const ok = errors.length === 0;
106
- const summary = !required
107
- ? "Summarize not required yet — no source files discovered."
108
- : ok
109
- ? `Summarize verified — ${sourceCovered}/${sourceTotal} source files are covered by valid summaries.`
110
- : `Summarize failed — ${errors[0] ?? "incomplete summary coverage."}`;
111
- return {
112
- ok,
113
- required,
114
- summary,
115
- counts: {
116
- source_total: sourceTotal,
117
- source_covered: sourceCovered,
118
- summarized,
119
- to_summarize: toSummarize,
120
- invalid_frontmatter: summaryValidation.invalid_frontmatter,
121
- short_abstracts: summaryValidation.short_abstracts,
122
- inventory_total: inventoryTotal,
123
- },
124
- checks,
125
- errors,
126
- };
127
- }
128
- export function validateWorkspaceCompile(dirPath) {
129
- const summarizeValidation = validateWorkspaceSummarize(dirPath);
130
- const structureValidation = validateWorkspaceStructure(dirPath);
131
- const config = readWorkspaceConfig(dirPath);
132
- const runtimeRoot = workspaceRuntimeRoot(dirPath);
133
- const statePath = join(runtimeRoot, "state.json");
134
- const inventoryPath = join(runtimeRoot, "inventory.json");
135
- const statePresent = existsSync(statePath);
136
- const inventoryPresent = existsSync(inventoryPath);
137
- const state = statePresent
138
- ? readJsonFileUnchecked(statePath, "workspace state")
139
- : null;
140
- const inventory = inventoryPresent
141
- ? readJsonFileUnchecked(inventoryPath, "workspace inventory")
142
- : null;
143
- const summarized = countFilesRecursive(join(dirPath, "summaries"));
144
- const structured = Math.max(asNumber(state?.structured), asNumber(state?.compiled));
145
- const shaped = Math.max(asNumber(state?.shaped), asNumber(state?.compiled));
146
- const compiled = asNumber(state?.compiled);
147
- const inventoryFilesByShape = readInventoryFiles(inventory);
148
- const { legacyFiles: legacyInventoryFiles, summaryFiles: summaryInventoryFiles, entryFiles: entryInventoryFiles, files: inventoryFiles, } = inventoryFilesByShape;
149
- const inventoryTotal = readInventoryTotal(inventory, inventoryFilesByShape);
150
- const frontmatterScanned = legacyInventoryFiles.length > 0
151
- ? inventoryFiles.filter((file) => file.frontmatter_scanned === true || file.frontmatter_read === true).length
152
- : summaryInventoryFiles.length > 0
153
- ? inventoryFiles.filter((file) => typeof file.file === "string" && typeof file.source === "string").length
154
- : inventoryFiles.filter((file) => (typeof file.summary === "string" || typeof file.digest === "string") &&
155
- typeof file.source === "string").length;
156
- const abstractsRead = legacyInventoryFiles.length > 0
157
- ? inventoryFiles.filter((file) => file.abstract_read === true).length
158
- : summaryInventoryFiles.length > 0
159
- ? inventoryFiles.filter((file) => file.abstract_read === true ||
160
- (typeof file.abstract === "string" && file.abstract.trim().length > 0) ||
161
- typeof file.status === "string" ||
162
- typeof file.state === "string").length
163
- : inventoryFiles.filter((file) => typeof file.state === "string").length;
164
- const entryAbstractsRead = entryInventoryFiles.length > 0
165
- ? entryInventoryFiles.filter((file) => typeof file.abstract === "string" && file.abstract.trim().length > 0).length
166
- : 0;
167
- const effectiveAbstractsRead = entryInventoryFiles.length > 0 && summaryInventoryFiles.length === 0 && legacyInventoryFiles.length === 0
168
- ? Math.max(abstractsRead, entryAbstractsRead)
169
- : abstractsRead;
170
- const fullReads = asNumber(state?.full_reads);
171
- const entityFiles = countFilesRecursive(join(dirPath, "knowledge", "entities"));
172
- const claimFiles = countFilesRecursive(join(dirPath, "knowledge", "claims"));
173
- const indexFiles = countFilesRecursive(join(dirPath, "knowledge", "indexes"));
174
- const outputs = entityFiles + claimFiles + indexFiles;
175
- const homePresent = existsSync(join(dirPath, "home.md"));
176
- const homeShaped = workspaceHomeIsShaped(dirPath);
177
- const brokenLinks = countBrokenWikilinks(dirPath, [join(dirPath, "summaries"), join(dirPath, "knowledge"), join(dirPath, "home.md")], [join(dirPath, "summaries"), join(dirPath, "knowledge"), join(dirPath, "home.md")]);
178
- const required = structureValidation.required || homePresent || shaped > 0 || compiled > 0 || inventoryPresent;
179
- const checks = {
180
- config_present: config.present,
181
- config_valid: config.valid,
182
- config_type_match: config.typeMatch(),
183
- summarize_complete: summarizeValidation.ok && summarizeValidation.required,
184
- structure_complete: structureValidation.ok && structureValidation.required,
185
- state_present: statePresent,
186
- state_valid: state !== null && WorkspaceStateSchema.safeParse(state).success,
187
- inventory_present: inventoryPresent,
188
- inventory_valid: inventory !== null && WorkspaceInventorySchema.safeParse(inventory).success,
189
- inventory_complete: Boolean(state?.inventory_complete) === true,
190
- inventory_matches_summaries: inventoryTotal === summarized && inventoryFiles.length === summarized,
191
- frontmatter_inventory_complete: frontmatterScanned === summarized,
192
- abstracts_cover_summaries: asNumber(state?.abstracts_read) >= summarized && effectiveAbstractsRead >= summarized,
193
- shaped_complete: shaped >= summarized &&
194
- summarized > 0 &&
195
- typeof state?.last_shape === "string" &&
196
- state.last_shape.length > 0,
197
- compiled_complete: compiled >= summarized &&
198
- summarized > 0 &&
199
- typeof state?.last_compile === "string" &&
200
- state.last_compile.length > 0,
201
- outputs_present: outputs > 0,
202
- home_present: homePresent,
203
- home_shaped: homeShaped,
204
- links_valid: brokenLinks === 0,
205
- };
206
- const errors = [];
207
- if (!checks.config_present)
208
- errors.push(`Missing ${workspaceInterfConfigPath(dirPath)}.`);
209
- else if (!checks.config_valid)
210
- errors.push(`Could not parse ${workspaceInterfConfigPath(dirPath)}.`);
211
- else if (!checks.config_type_match)
212
- errors.push("Config is not a workspace.");
213
- if (!checks.summarize_complete)
214
- errors.push("Workspace summarize is incomplete or invalid.");
215
- if (!checks.structure_complete)
216
- errors.push("Workspace structure is incomplete or invalid.");
217
- if (!checks.state_present)
218
- errors.push("Missing .interf/runtime/state.json.");
219
- else if (!checks.state_valid)
220
- errors.push("Could not parse .interf/runtime/state.json.");
221
- if (!checks.inventory_present)
222
- errors.push("Missing .interf/runtime/inventory.json.");
223
- else if (!checks.inventory_valid)
224
- errors.push("Could not parse .interf/runtime/inventory.json or it has the wrong shape.");
225
- if (checks.inventory_present && checks.inventory_valid && !checks.inventory_complete) {
226
- errors.push("state.json does not mark inventory_complete.");
227
- }
228
- if (checks.inventory_present && checks.inventory_valid && !checks.inventory_matches_summaries) {
229
- errors.push("Inventory does not match the summary set.");
230
- }
231
- if (checks.inventory_present && checks.inventory_valid && !checks.frontmatter_inventory_complete) {
232
- errors.push("Not every summary is marked frontmatter_scanned in inventory.");
233
- }
234
- if (checks.state_present && checks.state_valid && !checks.abstracts_cover_summaries) {
235
- errors.push("Abstract review does not cover the full summary set.");
236
- }
237
- if (checks.state_present && checks.state_valid && !checks.shaped_complete) {
238
- errors.push("state.json does not prove final workspace shaping.");
239
- }
240
- if (checks.state_present && checks.state_valid && !checks.compiled_complete) {
241
- errors.push("state.json compiled count does not cover the full summary set.");
242
- }
243
- if (!checks.outputs_present)
244
- errors.push("Workspace compile outputs are missing or empty.");
245
- if (!checks.home_present)
246
- errors.push("Workspace home.md is missing.");
247
- if (checks.home_present && !checks.home_shaped) {
248
- errors.push("Workspace home.md still contains the uncompiled scaffold placeholder.");
249
- }
250
- if (!checks.links_valid)
251
- errors.push("Some knowledge notes contain broken wikilinks.");
252
- const ok = required ? errors.length === 0 : true;
253
- const summary = !required
254
- ? "Workspace compile not required yet — no summaries exist yet."
255
- : ok
256
- ? `Workspace compile verified — ${compiled}/${summarized} summaries shaped and compiled, ${entityFiles} entities, ${claimFiles} claims.`
257
- : `Workspace compile failed — ${errors[0] ?? "incomplete compile."}`;
258
- return {
259
- ok,
260
- required,
261
- summary,
262
- counts: {
263
- source_total: summarizeValidation.counts.source_total,
264
- summarized,
265
- structured,
266
- shaped,
267
- compiled,
268
- inventory_total: inventoryTotal,
269
- frontmatter_scanned: frontmatterScanned,
270
- abstracts_read: Math.max(asNumber(state?.abstracts_read), effectiveAbstractsRead),
271
- full_reads: fullReads,
272
- entity_files: entityFiles,
273
- claim_files: claimFiles,
274
- index_files: indexFiles,
275
- outputs,
276
- },
277
- checks,
278
- errors,
279
- };
280
- }
281
- export function validateWorkspaceStructure(dirPath) {
282
- const summarizeValidation = validateWorkspaceSummarize(dirPath);
283
- const config = readWorkspaceConfig(dirPath);
284
- const runtimeRoot = workspaceRuntimeRoot(dirPath);
285
- const statePath = join(runtimeRoot, "state.json");
286
- const inventoryPath = join(runtimeRoot, "inventory.json");
287
- const statePresent = existsSync(statePath);
288
- const inventoryPresent = existsSync(inventoryPath);
289
- const state = statePresent
290
- ? readJsonFileUnchecked(statePath, "workspace state")
291
- : null;
292
- const inventory = inventoryPresent
293
- ? readJsonFileUnchecked(inventoryPath, "workspace inventory")
294
- : null;
295
- const summarized = countFilesRecursive(join(dirPath, "summaries"));
296
- const structured = Math.max(asNumber(state?.structured), asNumber(state?.compiled));
297
- const inventoryFilesByShape = readInventoryFiles(inventory);
298
- const { legacyFiles: legacyInventoryFiles, summaryFiles: summaryInventoryFiles, entryFiles: entryInventoryFiles, files: inventoryFiles, } = inventoryFilesByShape;
299
- const inventoryTotal = readInventoryTotal(inventory, inventoryFilesByShape);
300
- const frontmatterScanned = legacyInventoryFiles.length > 0
301
- ? inventoryFiles.filter((file) => file.frontmatter_scanned === true || file.frontmatter_read === true).length
302
- : summaryInventoryFiles.length > 0
303
- ? inventoryFiles.filter((file) => typeof file.file === "string" && typeof file.source === "string").length
304
- : inventoryFiles.filter((file) => (typeof file.summary === "string" || typeof file.digest === "string") &&
305
- typeof file.source === "string").length;
306
- const abstractsRead = legacyInventoryFiles.length > 0
307
- ? inventoryFiles.filter((file) => file.abstract_read === true).length
308
- : summaryInventoryFiles.length > 0
309
- ? inventoryFiles.filter((file) => file.abstract_read === true ||
310
- (typeof file.abstract === "string" && file.abstract.trim().length > 0) ||
311
- typeof file.status === "string" ||
312
- typeof file.state === "string").length
313
- : inventoryFiles.filter((file) => typeof file.state === "string").length;
314
- const entryAbstractsRead = entryInventoryFiles.length > 0
315
- ? entryInventoryFiles.filter((file) => typeof file.abstract === "string" && file.abstract.trim().length > 0).length
316
- : 0;
317
- const effectiveAbstractsRead = entryInventoryFiles.length > 0 && summaryInventoryFiles.length === 0 && legacyInventoryFiles.length === 0
318
- ? Math.max(abstractsRead, entryAbstractsRead)
319
- : abstractsRead;
320
- const entityFiles = countFilesRecursive(join(dirPath, "knowledge", "entities"));
321
- const claimFiles = countFilesRecursive(join(dirPath, "knowledge", "claims"));
322
- const indexFiles = countFilesRecursive(join(dirPath, "knowledge", "indexes"));
323
- const outputs = entityFiles + claimFiles + indexFiles;
324
- const brokenLinks = countBrokenWikilinks(dirPath, [join(dirPath, "summaries"), join(dirPath, "knowledge")], [join(dirPath, "summaries"), join(dirPath, "knowledge")]);
325
- const required = summarizeValidation.required || outputs > 0 || structured > 0 || inventoryPresent;
326
- const checks = {
327
- config_present: config.present,
328
- config_valid: config.valid,
329
- config_type_match: config.typeMatch(),
330
- summarize_complete: summarizeValidation.ok && summarizeValidation.required,
331
- state_present: statePresent,
332
- state_valid: state !== null && WorkspaceStateSchema.safeParse(state).success,
333
- inventory_present: inventoryPresent,
334
- inventory_valid: inventory !== null && WorkspaceInventorySchema.safeParse(inventory).success,
335
- inventory_complete: Boolean(state?.inventory_complete) === true,
336
- inventory_matches_summaries: inventoryTotal === summarized && inventoryFiles.length === summarized,
337
- frontmatter_inventory_complete: frontmatterScanned === summarized,
338
- abstracts_cover_summaries: asNumber(state?.abstracts_read) >= summarized && effectiveAbstractsRead >= summarized,
339
- structured_complete: structured >= summarized &&
340
- summarized > 0 &&
341
- typeof state?.last_structure === "string" &&
342
- state.last_structure.length > 0,
343
- outputs_present: outputs > 0,
344
- links_valid: brokenLinks === 0,
345
- };
346
- const errors = [];
347
- if (!checks.config_present)
348
- errors.push(`Missing ${workspaceInterfConfigPath(dirPath)}.`);
349
- else if (!checks.config_valid)
350
- errors.push(`Could not parse ${workspaceInterfConfigPath(dirPath)}.`);
351
- else if (!checks.config_type_match)
352
- errors.push("Config is not a workspace.");
353
- if (!checks.summarize_complete)
354
- errors.push("Workspace summarize is incomplete or invalid.");
355
- if (!checks.state_present)
356
- errors.push("Missing .interf/runtime/state.json.");
357
- else if (!checks.state_valid)
358
- errors.push("Could not parse .interf/runtime/state.json.");
359
- if (!checks.inventory_present)
360
- errors.push("Missing .interf/runtime/inventory.json.");
361
- else if (!checks.inventory_valid)
362
- errors.push("Could not parse .interf/runtime/inventory.json or it has the wrong shape.");
363
- if (checks.inventory_present && checks.inventory_valid && !checks.inventory_complete) {
364
- errors.push("state.json does not mark inventory_complete.");
365
- }
366
- if (checks.inventory_present && checks.inventory_valid && !checks.inventory_matches_summaries) {
367
- errors.push("Inventory does not match the summary set.");
368
- }
369
- if (checks.inventory_present && checks.inventory_valid && !checks.frontmatter_inventory_complete) {
370
- errors.push("Not every summary is marked frontmatter_scanned in inventory.");
371
- }
372
- if (checks.state_present && checks.state_valid && !checks.abstracts_cover_summaries) {
373
- errors.push("Abstract review does not cover the full summary set.");
374
- }
375
- if (checks.state_present && checks.state_valid && !checks.structured_complete) {
376
- errors.push("state.json does not prove workspace structure completion.");
377
- }
378
- if (!checks.outputs_present)
379
- errors.push("Workspace structure outputs are missing or empty.");
380
- if (!checks.links_valid)
381
- errors.push("Some knowledge notes contain broken wikilinks.");
382
- const ok = required ? errors.length === 0 : true;
383
- const summary = !required
384
- ? "Workspace structure not required yet — no summaries exist yet."
385
- : ok
386
- ? `Workspace structure verified — ${structured}/${summarized} summaries structured, ${entityFiles} entities, ${claimFiles} claims.`
387
- : `Workspace structure failed — ${errors[0] ?? "incomplete structure."}`;
388
- return {
389
- ok,
390
- required,
391
- summary,
392
- counts: {
393
- source_total: summarizeValidation.counts.source_total,
394
- summarized,
395
- structured,
396
- inventory_total: inventoryTotal,
397
- frontmatter_scanned: frontmatterScanned,
398
- abstracts_read: Math.max(asNumber(state?.abstracts_read), effectiveAbstractsRead),
399
- entity_files: entityFiles,
400
- claim_files: claimFiles,
401
- index_files: indexFiles,
402
- outputs,
403
- },
404
- checks,
405
- errors,
406
- };
407
- }
@@ -1,181 +0,0 @@
1
- export const WORKSPACE_CONTRACT_TYPES = [
2
- "workspace-file-evidence",
3
- "workspace-knowledge-structure",
4
- "workspace-query-shape",
5
- ];
6
- export const WORKSPACE_ZONE_KINDS = [
7
- "directory",
8
- "file",
9
- "runtime",
10
- ];
11
- export const WORKSPACE_CONTRACT_FAMILY_METADATA = {
12
- "workspace-file-evidence": {
13
- order: 0,
14
- bundledSkill: "compile/stages/summarize",
15
- },
16
- "workspace-knowledge-structure": {
17
- order: 1,
18
- bundledSkill: "compile/stages/structure",
19
- },
20
- "workspace-query-shape": {
21
- order: 2,
22
- bundledSkill: "compile/stages/shape",
23
- },
24
- };
25
- export const BUILTIN_WORKSPACE_STAGE_IDS = {
26
- SUMMARIZE: "summarize",
27
- STRUCTURE: "structure",
28
- SHAPE: "shape",
29
- };
30
- export const BUILTIN_WORKSPACE_ZONE_IDS = {
31
- RAW: "raw",
32
- SUMMARIES: "summaries",
33
- KNOWLEDGE_ENTITIES: "knowledge-entities",
34
- KNOWLEDGE_CLAIMS: "knowledge-claims",
35
- KNOWLEDGE_INDEXES: "knowledge-indexes",
36
- HOME: "home",
37
- RUNTIME: "runtime",
38
- };
39
- export const BUILTIN_WORKSPACE_ZONE_SPECS = [
40
- {
41
- id: BUILTIN_WORKSPACE_ZONE_IDS.RAW,
42
- path: "raw",
43
- kind: "directory",
44
- required: true,
45
- description: "Workspace-local raw snapshot copied from the dataset for direct evidence and verification.",
46
- },
47
- {
48
- id: BUILTIN_WORKSPACE_ZONE_IDS.SUMMARIES,
49
- path: "summaries",
50
- kind: "directory",
51
- required: true,
52
- description: "Per-file evidence notes produced by file-evidence stages.",
53
- },
54
- {
55
- id: BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_ENTITIES,
56
- path: "knowledge/entities",
57
- kind: "directory",
58
- required: true,
59
- description: "Canonical entity notes produced by knowledge-structure stages.",
60
- },
61
- {
62
- id: BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_CLAIMS,
63
- path: "knowledge/claims",
64
- kind: "directory",
65
- required: true,
66
- description: "Claim notes produced by knowledge-structure stages.",
67
- },
68
- {
69
- id: BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_INDEXES,
70
- path: "knowledge/indexes",
71
- kind: "directory",
72
- required: true,
73
- description: "Retrieval indexes and navigation notes produced by structure and shape stages.",
74
- },
75
- {
76
- id: BUILTIN_WORKSPACE_ZONE_IDS.HOME,
77
- path: "home.md",
78
- kind: "file",
79
- required: true,
80
- description: "Primary entrypoint note for agents using the compiled workspace.",
81
- },
82
- {
83
- id: BUILTIN_WORKSPACE_ZONE_IDS.RUNTIME,
84
- path: ".interf/runtime",
85
- kind: "runtime",
86
- required: true,
87
- description: "CLI-owned runtime state, health, stage contracts, and proof artifacts.",
88
- },
89
- ];
90
- export const BUILTIN_WORKSPACE_STAGE_ACCESS_PATTERNS = [
91
- {
92
- id: BUILTIN_WORKSPACE_STAGE_IDS.SUMMARIZE,
93
- label: "Summarize",
94
- description: "Turn source files into per-file summaries.",
95
- contractType: "workspace-file-evidence",
96
- skillDir: "summarize",
97
- reads: [
98
- BUILTIN_WORKSPACE_ZONE_IDS.RAW,
99
- BUILTIN_WORKSPACE_ZONE_IDS.RUNTIME,
100
- ],
101
- writes: [
102
- BUILTIN_WORKSPACE_ZONE_IDS.SUMMARIES,
103
- ],
104
- },
105
- {
106
- id: BUILTIN_WORKSPACE_STAGE_IDS.STRUCTURE,
107
- label: "Structure",
108
- description: "Build the cross-file knowledge structure from the summaries.",
109
- contractType: "workspace-knowledge-structure",
110
- skillDir: "structure",
111
- reads: [
112
- BUILTIN_WORKSPACE_ZONE_IDS.SUMMARIES,
113
- BUILTIN_WORKSPACE_ZONE_IDS.RUNTIME,
114
- ],
115
- writes: [
116
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_ENTITIES,
117
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_CLAIMS,
118
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_INDEXES,
119
- ],
120
- },
121
- {
122
- id: BUILTIN_WORKSPACE_STAGE_IDS.SHAPE,
123
- label: "Shape",
124
- description: "Shape the final workspace around the saved focus and truth checks.",
125
- contractType: "workspace-query-shape",
126
- skillDir: "shape",
127
- reads: [
128
- BUILTIN_WORKSPACE_ZONE_IDS.RAW,
129
- BUILTIN_WORKSPACE_ZONE_IDS.SUMMARIES,
130
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_ENTITIES,
131
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_CLAIMS,
132
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_INDEXES,
133
- BUILTIN_WORKSPACE_ZONE_IDS.RUNTIME,
134
- ],
135
- writes: [
136
- BUILTIN_WORKSPACE_ZONE_IDS.KNOWLEDGE_INDEXES,
137
- BUILTIN_WORKSPACE_ZONE_IDS.HOME,
138
- ],
139
- },
140
- ];
141
- export function workspaceContractOrder(contractType) {
142
- return WORKSPACE_CONTRACT_FAMILY_METADATA[contractType].order;
143
- }
144
- export function workspaceBundledSkillForContractType(contractType) {
145
- return WORKSPACE_CONTRACT_FAMILY_METADATA[contractType].bundledSkill;
146
- }
147
- export function hasValidWorkspaceContractSequence(contractTypes) {
148
- return contractTypes.every((contractType, index) => index === 0 ||
149
- workspaceContractOrder(contractType) >= workspaceContractOrder(contractTypes[index - 1]));
150
- }
151
- export function listMissingWorkspaceContractTypes(contractTypes) {
152
- return WORKSPACE_CONTRACT_TYPES.filter((contractType) => !contractTypes.includes(contractType));
153
- }
154
- export function validateWorkspaceContractSequence(contractTypes) {
155
- const missing = listMissingWorkspaceContractTypes(contractTypes);
156
- const orderValid = hasValidWorkspaceContractSequence(contractTypes);
157
- return {
158
- ok: missing.length === 0 && orderValid,
159
- orderValid,
160
- missing,
161
- };
162
- }
163
- export function listBuiltinWorkspaceZoneSpecs() {
164
- return BUILTIN_WORKSPACE_ZONE_SPECS.map((zone) => ({ ...zone }));
165
- }
166
- export function listBuiltinWorkspaceFallbackStages() {
167
- return BUILTIN_WORKSPACE_STAGE_ACCESS_PATTERNS.map((stage) => ({
168
- id: stage.id,
169
- contract_type: stage.contractType,
170
- reads: [...stage.reads],
171
- writes: [...stage.writes],
172
- }));
173
- }
174
- export function requiredWorkspaceZoneOwners(stages, zoneId) {
175
- const writerContractTypes = new Set(BUILTIN_WORKSPACE_STAGE_ACCESS_PATTERNS
176
- .filter((stage) => stage.writes.includes(zoneId))
177
- .map((stage) => stage.contractType));
178
- return Array.from(new Set(stages
179
- .filter((stage) => writerContractTypes.has(stage.contractType))
180
- .map((stage) => stage.id)));
181
- }
@@ -1,54 +0,0 @@
1
- import { type WorkflowExecutor } from "./executors.js";
2
- import { type SummarizePlan } from "./summarize-plan.js";
3
- import { type RuntimeStageContractDraft } from "./runtime.js";
4
- import { type RuntimeStageInstructions } from "./schema.js";
5
- import { type WorkspaceWorkflowId, type WorkflowStageDefinition } from "./workflow-definitions.js";
6
- import { type WorkflowReporter, type WorkflowStageResult } from "./workflow-helpers.js";
7
- export interface WorkspaceStageExecutionDefinition extends WorkflowStageDefinition {
8
- contractType: "workspace-file-evidence" | "workspace-knowledge-structure" | "workspace-query-shape";
9
- }
10
- export interface WorkspaceSummarizeResult extends WorkflowStageResult {
11
- skipped: boolean;
12
- plan: SummarizePlan;
13
- }
14
- export interface WorkspaceCompileResult {
15
- ok: boolean;
16
- summarize: WorkspaceSummarizeResult;
17
- structure: WorkflowStageResult | null;
18
- shape: WorkflowStageResult | null;
19
- compile: WorkflowStageResult | null;
20
- failedStage: string | null;
21
- }
22
- export type StageShellRetentionMode = "on-failure" | "always";
23
- export declare function resolveWorkspaceContext(workspacePath: string): {
24
- workspaceName: string;
25
- sourcePath: string;
26
- controlPath: string;
27
- workflowId: WorkspaceWorkflowId;
28
- };
29
- export declare function workspaceExecutionStages(workflowId: WorkspaceWorkflowId, workspacePath: string): WorkspaceStageExecutionDefinition[];
30
- export declare function buildWorkspaceCompileContract(workspacePath: string, workflowId: WorkspaceWorkflowId, summaryCount: number, instructions: RuntimeStageInstructions, stageId?: string, stageSkillDir?: string, shapeInputPath?: string): RuntimeStageContractDraft;
31
- export declare function runWorkspaceSummarize(options: {
32
- executor: WorkflowExecutor;
33
- workspacePath: string;
34
- sourcePath?: string;
35
- reporter?: WorkflowReporter;
36
- reportSummary?: boolean;
37
- reportStep?: boolean;
38
- stageDefinition?: WorkspaceStageExecutionDefinition;
39
- fullPass?: boolean;
40
- }): Promise<WorkspaceSummarizeResult>;
41
- export declare function runWorkspaceCompile(options: {
42
- executor: WorkflowExecutor;
43
- workspacePath: string;
44
- sourcePath?: string;
45
- reporter?: WorkflowReporter;
46
- reportStep?: boolean;
47
- preserveStageShells?: StageShellRetentionMode;
48
- }): Promise<WorkflowStageResult>;
49
- export declare function compileWorkspace(options: {
50
- executor: WorkflowExecutor;
51
- workspacePath: string;
52
- reporter?: WorkflowReporter;
53
- preserveStageShells?: StageShellRetentionMode;
54
- }): Promise<WorkspaceCompileResult>;