@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
@@ -1,148 +1,130 @@
1
1
  import { basename, join } from "node:path";
2
2
  import { existsSync } from "node:fs";
3
- import { countFilesRecursive } from "./filesystem.js";
4
- import { discoverSourceFiles } from "./discovery.js";
5
3
  import { readInterfConfig, resolveSourceFolderPath, } from "./interf.js";
4
+ import { discoverSourceFiles } from "./discovery.js";
6
5
  import { loadRuntimeRun } from "./runtime.js";
7
- import { validateWorkspace } from "./validate.js";
8
- import { initWorkspaceState, loadState, } from "./state-io.js";
9
- import { workspaceRuntimeInventoryPath } from "./workspace-paths.js";
10
- export function computeWorkspaceHealth(dirPath) {
11
- const state = {
12
- ...initWorkspaceState(),
13
- ...(loadState(dirPath) ?? {}),
14
- };
15
- const validation = validateWorkspace(dirPath);
6
+ import { loadState } from "./state-io.js";
7
+ import { validateCompiled, validateCompiledStage, validateCompiledWorkflow, } from "./validate.js";
8
+ import { readCompiledSchemaFile } from "./compiled-schema.js";
9
+ import { workflowPackagePathForCompiled } from "./compiled-paths.js";
10
+ import { getActiveCompiledWorkflow, resolveCompiledWorkflowFromConfig } from "./workflow-definitions.js";
11
+ import { listFilesRecursive } from "./filesystem.js";
12
+ function countZoneArtifacts(compiledPath, zonePath, kind) {
13
+ const absolutePath = join(compiledPath, zonePath);
14
+ if (!existsSync(absolutePath))
15
+ return 0;
16
+ if (kind === "file")
17
+ return 1;
18
+ return listFilesRecursive(absolutePath).length;
19
+ }
20
+ export function computeCompiledHealth(dirPath) {
16
21
  const now = new Date().toISOString();
17
22
  const config = readInterfConfig(dirPath);
18
- const workspaceName = config?.name ?? basename(dirPath);
19
- const sourcePath = resolveSourceFolderPath(dirPath, config);
20
- const discovery = discoverSourceFiles(sourcePath, dirPath);
21
- const summariesPresent = existsSync(join(dirPath, "summaries"));
22
- const inventoryPresent = existsSync(workspaceRuntimeInventoryPath(dirPath));
23
- const homePresent = existsSync(join(dirPath, "home.md"));
24
- const outputs = countOutputFiles(dirPath);
25
- const outputsPresent = outputs > 0;
26
- const sourceTotal = discovery.totalCount;
27
- const summarized = summariesPresent ? countFilesRecursive(join(dirPath, "summaries")) : 0;
28
- const sourceCovered = Math.min(sourceTotal, summarized);
29
- const structured = Math.min(summarized, Math.max(state.structured ?? 0, state.compiled ?? 0));
30
- const compiled = Math.min(summarized, Math.max(state.shaped ?? 0, state.compiled ?? 0));
31
- const toSummarize = Math.max(0, sourceTotal - sourceCovered);
32
- const toStructure = Math.max(0, summarized - structured);
33
- const toShape = Math.max(0, structured - compiled);
34
- const warnings = (toSummarize > 0 ? 1 : 0) +
35
- (toStructure > 0 ? 1 : 0) +
36
- (toShape > 0 ? 1 : 0) +
37
- (summarized > sourceTotal && sourceTotal > 0 ? 1 : 0) +
38
- (!outputsPresent && state.last_compile ? 1 : 0) +
39
- validation.invalid_frontmatter +
40
- validation.short_abstracts +
41
- validation.broken_links;
42
- const errors = (!validation.config_present ? 1 : 0) +
43
- (!validation.config_valid && validation.config_present ? 1 : 0) +
44
- (!validation.config_type_match && validation.config_valid ? 1 : 0) +
45
- (state.error_count ?? 0);
23
+ const targetName = config?.name ?? basename(dirPath);
24
+ const sourcePath = config ? resolveSourceFolderPath(dirPath, config) : dirPath;
25
+ const sourceTotal = config ? discoverSourceFiles(sourcePath, dirPath).totalCount : 0;
26
+ const state = loadState(dirPath);
27
+ const validation = validateCompiled(dirPath);
46
28
  const activeRun = loadRuntimeRun(dirPath);
47
- const inferredStage = resolveWorkspaceStage(state, sourceTotal, summarized, toSummarize, toStructure, toShape, errors);
48
- const inferredStatus = resolveWorkspaceStatus(sourceTotal, summarized, toSummarize, toStructure, toShape, errors, state);
49
- const stage = activeRun?.status === "running"
50
- ? activeRun.stage === "summarize" || activeRun.stage === "structure" || activeRun.stage === "shape"
51
- ? activeRun.stage
52
- : inferredStage
53
- : inferredStage;
54
- const status = activeRun?.status === "running" ? "running" : inferredStatus;
29
+ const workflowId = config ? resolveCompiledWorkflowFromConfig(config) : null;
30
+ let workflow = null;
31
+ if (workflowId) {
32
+ try {
33
+ workflow = getActiveCompiledWorkflow(dirPath, workflowId);
34
+ }
35
+ catch {
36
+ workflow = null;
37
+ }
38
+ }
39
+ const stageResults = workflow?.stages.map((stage) => ({
40
+ stage,
41
+ validation: validateCompiledStage(dirPath, stage.id),
42
+ })) ?? [];
43
+ const completedStages = stageResults.filter((entry) => entry.validation.ok).length;
44
+ const firstFailed = stageResults.find((entry) => !entry.validation.ok) ?? null;
45
+ const workflowValidation = validateCompiledWorkflow(dirPath);
46
+ const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
47
+ const zoneMetrics = Object.fromEntries((schema?.zones ?? []).map((zone) => [
48
+ `zone_${zone.id}`,
49
+ countZoneArtifacts(dirPath, zone.path, zone.kind),
50
+ ]));
51
+ let status = "idle";
52
+ let stage = "idle";
53
+ let summary = "Idle — no source files have been compiled yet.";
54
+ const errors = workflowValidation.errors.length;
55
+ if (!validation.config_present || !validation.config_valid || !validation.config_type_match || !validation.workflow_valid || !validation.schema_valid) {
56
+ status = "failed";
57
+ stage = "failed";
58
+ summary = workflowValidation.summary;
59
+ }
60
+ else if (activeRun?.status === "running") {
61
+ status = "running";
62
+ stage = activeRun.stage;
63
+ summary = `Running — ${activeRun.stage_label} via ${activeRun.executor.display_name}. ${activeRun.summary}`;
64
+ }
65
+ else if (sourceTotal === 0 && completedStages === 0) {
66
+ status = "idle";
67
+ stage = "idle";
68
+ summary = "Idle — no source files have been compiled yet.";
69
+ }
70
+ else if (activeRun?.status === "failed") {
71
+ status = "failed";
72
+ stage = activeRun.stage;
73
+ summary = activeRun.error ?? activeRun.summary;
74
+ }
75
+ else if (workflowValidation.ok) {
76
+ status = "compiled";
77
+ stage = "compiled";
78
+ summary = `Compiled — ${completedStages}/${workflow?.stages.length ?? 0} workflow stages satisfied.`;
79
+ }
80
+ else {
81
+ status = "stale";
82
+ stage = firstFailed?.stage.id ?? "compiled";
83
+ summary = firstFailed?.validation.summary ?? workflowValidation.summary;
84
+ }
85
+ const checks = {
86
+ ...validation,
87
+ ...(workflow
88
+ ? Object.fromEntries(workflow.stages.map((workflowStage) => [
89
+ `stage_${workflowStage.id}_ok`,
90
+ stageResults.find((entry) => entry.stage.id === workflowStage.id)?.validation.ok ?? false,
91
+ ]))
92
+ : {}),
93
+ };
55
94
  return {
56
- kind: "workspace-health",
57
- version: 1,
95
+ kind: "compiled-health",
96
+ version: 2,
58
97
  generated_at: now,
59
- target_name: workspaceName,
98
+ target_name: targetName,
60
99
  status,
61
100
  stage,
62
- summary: activeRun?.status === "running"
63
- ? `Running — ${activeRun.stage_label} via ${activeRun.executor.display_name}. ${activeRun.summary}`
64
- : buildWorkspaceSummary(status, stage, {
65
- sourceTotal,
66
- sourceCovered,
67
- summarized,
68
- toSummarize,
69
- structured,
70
- toStructure,
71
- compiled,
72
- toCompile: toShape,
73
- }),
101
+ summary,
74
102
  metrics: {
75
103
  source_total: sourceTotal,
76
- source_covered: sourceCovered,
77
- summarized,
78
- to_summarize: toSummarize,
79
- compiled,
80
- to_compile: toShape,
81
- entities: state.entity_count ?? countFilesRecursive(join(dirPath, "knowledge", "entities")),
82
- claims: state.claim_count ?? countFilesRecursive(join(dirPath, "knowledge", "claims")),
83
- outputs,
84
- invalid_frontmatter: validation.invalid_frontmatter,
85
- short_abstracts: validation.short_abstracts,
86
- broken_links: validation.broken_links,
87
- warnings: (state.warning_count ?? 0) + warnings,
88
- errors,
89
- },
90
- checks: {
91
- config_present: validation.config_present,
92
- config_valid: validation.config_valid,
93
- config_type_match: validation.config_type_match,
94
- summaries_present: summariesPresent,
95
- inventory_present: inventoryPresent,
96
- outputs_present: outputsPresent,
97
- home_present: homePresent,
98
- summary_frontmatter_valid: validation.summary_frontmatter_valid,
99
- abstracts_valid: validation.abstracts_valid,
100
- links_valid: validation.broken_links === 0,
104
+ stage_total: workflow?.stages.length ?? 0,
105
+ completed_stages: completedStages,
106
+ warnings: state?.warning_count ?? 0,
107
+ errors: (state?.error_count ?? 0) + errors,
108
+ ...zoneMetrics,
101
109
  },
110
+ checks,
102
111
  };
103
112
  }
104
- export function resolveWorkspaceStatus(sourceTotal, summarized, toSummarize, toStructure, toShape, errors, state) {
105
- if (errors > 0)
113
+ export function resolveCompiledStatus(..._args) {
114
+ const state = _args[_args.length - 1];
115
+ if (state?.error_count && state.error_count > 0)
106
116
  return "failed";
107
- if (sourceTotal === 0 && summarized === 0 && state.last_summarize === null && state.last_compile === null)
117
+ if (!state?.stages || Object.keys(state.stages).length === 0)
108
118
  return "idle";
109
- if (toSummarize > 0 || toStructure > 0 || toShape > 0)
110
- return "stale";
111
- return "compiled";
119
+ const allSucceeded = Object.values(state.stages).every((stage) => stage.status === "succeeded");
120
+ return allSucceeded ? "compiled" : "stale";
112
121
  }
113
- export function resolveWorkspaceStage(state, sourceTotal, summarized, toSummarize, toStructure, toShape, errors) {
114
- if (errors > 0)
122
+ export function resolveCompiledStage(...args) {
123
+ const state = args[0];
124
+ if (state?.error_count && state.error_count > 0)
115
125
  return "failed";
116
- if (sourceTotal === 0 && summarized === 0 && state.last_summarize === null && state.last_compile === null)
126
+ if (!state?.stages || Object.keys(state.stages).length === 0)
117
127
  return "idle";
118
- if (toSummarize > 0)
119
- return "summarize";
120
- if (toStructure > 0)
121
- return "structure";
122
- if (toShape > 0)
123
- return "shape";
124
- return "compiled";
125
- }
126
- function buildWorkspaceSummary(status, stage, metrics) {
127
- if (status === "failed")
128
- return "Failed — required workspace inputs are missing.";
129
- if (status === "idle")
130
- return "Idle — no source files have been compiled yet.";
131
- if (stage === "summarize") {
132
- return `Stale — ${metrics.toSummarize} source files still need summaries (${metrics.sourceCovered}/${metrics.sourceTotal} summarized).`;
133
- }
134
- if (stage === "structure") {
135
- return `Stale — ${metrics.toStructure} summaries still need cross-file structure (${metrics.structured}/${metrics.summarized} structured).`;
136
- }
137
- if (stage === "shape") {
138
- return `Stale — ${metrics.toCompile} summaries still need final workspace shaping (${metrics.compiled}/${metrics.summarized} shaped).`;
139
- }
140
- return `Compiled — ${metrics.compiled}/${metrics.summarized} summaries compiled, ${metrics.sourceCovered}/${metrics.sourceTotal} source files summarized.`;
141
- }
142
- function countOutputFiles(dirPath) {
143
- return [
144
- join(dirPath, "knowledge", "entities"),
145
- join(dirPath, "knowledge", "claims"),
146
- join(dirPath, "knowledge", "indexes"),
147
- ].reduce((total, dir) => total + countFilesRecursive(dir), 0);
128
+ const failedStage = Object.entries(state.stages).find(([, stage]) => stage.status !== "succeeded");
129
+ return failedStage?.[0] ?? "compiled";
148
130
  }
@@ -1,10 +1,10 @@
1
- import { type WorkspaceHealth, type WorkspaceRawSnapshot, type WorkspaceState, type WorkspaceViewSpec } from "./schema.js";
1
+ import { type CompiledHealth, type CompiledRawSnapshot, type CompiledState, type CompiledViewSpec } from "./schema.js";
2
2
  export declare function loadState<T>(dirPath: string): T | null;
3
3
  export declare function saveState<T>(dirPath: string, state: T): void;
4
- export declare function loadWorkspaceHealth(dirPath: string): WorkspaceHealth | null;
5
- export declare function saveWorkspaceHealth(dirPath: string, health: WorkspaceHealth): void;
6
- export declare function loadWorkspaceViewSpec(dirPath: string): WorkspaceViewSpec | null;
7
- export declare function saveWorkspaceViewSpec(dirPath: string, viewSpec: WorkspaceViewSpec): void;
8
- export declare function loadWorkspaceRawSnapshot(dirPath: string): WorkspaceRawSnapshot | null;
9
- export declare function saveEmptyWorkspaceInventory(dirPath: string): void;
10
- export declare function initWorkspaceState(): WorkspaceState;
4
+ export declare function loadCompiledHealth(dirPath: string): CompiledHealth | null;
5
+ export declare function saveCompiledHealth(dirPath: string, health: CompiledHealth): void;
6
+ export declare function loadCompiledViewSpec(dirPath: string): CompiledViewSpec | null;
7
+ export declare function saveCompiledViewSpec(dirPath: string, viewSpec: CompiledViewSpec): void;
8
+ export declare function loadCompiledRawSnapshot(dirPath: string): CompiledRawSnapshot | null;
9
+ export declare function saveEmptyCompiledInventory(dirPath: string): void;
10
+ export declare function initCompiledState(): CompiledState;
@@ -1,10 +1,10 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
2
  import { warnInterf } from "./logger.js";
3
3
  import { readJsonFileUnchecked, readJsonFileWithSchema } from "./parse.js";
4
- import { WorkspaceHealthSchema, WorkspaceInventorySchema, WorkspaceRawSnapshotSchema, WorkspaceStateSchema, WorkspaceViewSpecSchema, } from "./schema.js";
5
- import { readInventoryFiles, readInventoryTotal } from "./validate-helpers.js";
4
+ import { CompiledHealthSchema, CompiledInventorySchema, CompiledRawSnapshotSchema, CompiledStateSchema, CompiledViewSpecSchema, } from "./schema.js";
5
+ import { compiledInventoryEntryCount, compiledInventoryTotal, emptyCompiledInventory, } from "./runtime-inventory.js";
6
6
  import { healthPath, rawSnapshotPath, statePath, viewSpecPath } from "./state-paths.js";
7
- import { workspaceRuntimeInventoryPath, workspaceRuntimeRoot, } from "./workspace-paths.js";
7
+ import { compiledRuntimeInventoryPath, compiledRuntimeRoot, } from "./compiled-paths.js";
8
8
  const NORMALIZABLE_RUNTIME_TIMESTAMP_FIELDS = [
9
9
  "last_add",
10
10
  "last_summarize",
@@ -19,7 +19,7 @@ export function loadState(dirPath) {
19
19
  const raw = readJsonFileUnchecked(path, "runtime state");
20
20
  if (raw === null)
21
21
  return null;
22
- const parsed = WorkspaceStateSchema.safeParse(raw);
22
+ const parsed = CompiledStateSchema.safeParse(raw);
23
23
  if (parsed.success) {
24
24
  const healed = healParsedRuntimeState(dirPath, parsed.data);
25
25
  if (healed !== null) {
@@ -37,57 +37,46 @@ export function loadState(dirPath) {
37
37
  return null;
38
38
  }
39
39
  export function saveState(dirPath, state) {
40
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
40
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
41
41
  writeFileSync(statePath(dirPath), JSON.stringify(state, null, 2) + "\n");
42
42
  }
43
- export function loadWorkspaceHealth(dirPath) {
43
+ export function loadCompiledHealth(dirPath) {
44
44
  const path = healthPath(dirPath);
45
45
  if (!existsSync(path))
46
46
  return null;
47
- return readJsonFileWithSchema(path, "workspace health", WorkspaceHealthSchema);
47
+ return readJsonFileWithSchema(path, "compiled health", CompiledHealthSchema);
48
48
  }
49
- export function saveWorkspaceHealth(dirPath, health) {
50
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
49
+ export function saveCompiledHealth(dirPath, health) {
50
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
51
51
  writeFileSync(healthPath(dirPath), JSON.stringify(health, null, 2) + "\n");
52
52
  }
53
- export function loadWorkspaceViewSpec(dirPath) {
53
+ export function loadCompiledViewSpec(dirPath) {
54
54
  const path = viewSpecPath(dirPath);
55
55
  if (!existsSync(path))
56
56
  return null;
57
- return loadViewSpec(path, WorkspaceViewSpecSchema);
57
+ return loadViewSpec(path, CompiledViewSpecSchema);
58
58
  }
59
- export function saveWorkspaceViewSpec(dirPath, viewSpec) {
60
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
59
+ export function saveCompiledViewSpec(dirPath, viewSpec) {
60
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
61
61
  writeFileSync(viewSpecPath(dirPath), JSON.stringify(viewSpec, null, 2) + "\n");
62
62
  }
63
- export function loadWorkspaceRawSnapshot(dirPath) {
63
+ export function loadCompiledRawSnapshot(dirPath) {
64
64
  const path = rawSnapshotPath(dirPath);
65
65
  if (!existsSync(path))
66
66
  return null;
67
- return readJsonFileWithSchema(path, "workspace raw snapshot", WorkspaceRawSnapshotSchema);
67
+ return readJsonFileWithSchema(path, "compiled raw snapshot", CompiledRawSnapshotSchema);
68
68
  }
69
- export function saveEmptyWorkspaceInventory(dirPath) {
70
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
71
- writeFileSync(workspaceRuntimeInventoryPath(dirPath), JSON.stringify({ entries: [], total: 0 }, null, 2) + "\n");
69
+ export function saveEmptyCompiledInventory(dirPath) {
70
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
71
+ writeFileSync(compiledRuntimeInventoryPath(dirPath), JSON.stringify(emptyCompiledInventory(), null, 2) + "\n");
72
72
  }
73
- export function initWorkspaceState() {
73
+ export function initCompiledState() {
74
74
  return {
75
- version: 1,
75
+ version: 2,
76
76
  pending: [],
77
- summarized: 0,
78
- structured: 0,
79
- shaped: 0,
80
- compiled: 0,
77
+ stages: {},
81
78
  last_add: null,
82
- last_summarize: null,
83
- last_structure: null,
84
- last_shape: null,
85
79
  last_compile: null,
86
- inventory_complete: false,
87
- abstracts_read: 0,
88
- full_reads: 0,
89
- entity_count: 0,
90
- claim_count: 0,
91
80
  warning_count: 0,
92
81
  error_count: 0,
93
82
  };
@@ -106,30 +95,68 @@ function normalizeRuntimeState(raw) {
106
95
  }
107
96
  if (!changed)
108
97
  return null;
109
- const parsed = WorkspaceStateSchema.safeParse(normalized);
98
+ const parsed = CompiledStateSchema.safeParse(normalized);
110
99
  return parsed.success ? parsed.data : null;
111
100
  }
112
101
  function healParsedRuntimeState(dirPath, state) {
113
- if (typeof state.inventory_complete === "boolean")
102
+ const hasLegacyStageFields = (typeof state.last_summarize === "string" && state.last_summarize.length > 0) ||
103
+ (typeof state.last_structure === "string" && state.last_structure.length > 0) ||
104
+ (typeof state.last_shape === "string" && state.last_shape.length > 0);
105
+ const hasStageMap = Boolean(state.stages) &&
106
+ typeof state.stages === "object" &&
107
+ Object.keys(state.stages ?? {}).length > 0;
108
+ if (state.version >= 2 && (hasStageMap || !hasLegacyStageFields))
114
109
  return null;
115
- if (!Array.isArray(state.pending) || state.pending.length > 0)
116
- return null;
117
- if (typeof state.last_summarize !== "string" || state.last_summarize.length === 0)
118
- return null;
119
- const inventoryPath = workspaceRuntimeInventoryPath(dirPath);
120
- if (!existsSync(inventoryPath))
121
- return null;
122
- const inventory = readJsonFileWithSchema(inventoryPath, "workspace inventory", WorkspaceInventorySchema);
123
- if (inventory === null)
124
- return null;
125
- const inventoryFiles = readInventoryFiles(inventory);
126
- const inventoryTotal = readInventoryTotal(inventory, inventoryFiles);
127
- if (inventoryTotal !== state.summarized || inventoryFiles.files.length !== state.summarized)
128
- return null;
129
- return {
110
+ const next = {
111
+ ...initCompiledState(),
130
112
  ...state,
131
- inventory_complete: true,
113
+ stages: { ...(state.stages ?? {}) },
132
114
  };
115
+ if (typeof state.last_summarize === "string" && state.last_summarize.length > 0) {
116
+ next.stages.summarize = {
117
+ contract_type: "compiled-file-evidence",
118
+ status: "succeeded",
119
+ finished_at: state.last_summarize,
120
+ counts: {
121
+ summarized: state.summarized ?? 0,
122
+ expected_summary_total: state.summarized ?? 0,
123
+ },
124
+ zone_counts: {
125
+ summaries: state.summarized ?? 0,
126
+ },
127
+ };
128
+ }
129
+ if (typeof state.last_structure === "string" && state.last_structure.length > 0) {
130
+ next.stages.structure = {
131
+ contract_type: "compiled-knowledge-structure",
132
+ status: "succeeded",
133
+ finished_at: state.last_structure,
134
+ counts: {
135
+ summary_total: state.structured ?? state.summarized ?? 0,
136
+ },
137
+ };
138
+ }
139
+ if (typeof state.last_shape === "string" && state.last_shape.length > 0) {
140
+ next.stages.shape = {
141
+ contract_type: "compiled-query-shape",
142
+ status: "succeeded",
143
+ finished_at: state.last_shape,
144
+ counts: {
145
+ summary_total: state.shaped ?? state.summarized ?? 0,
146
+ },
147
+ };
148
+ }
149
+ const inventoryPath = compiledRuntimeInventoryPath(dirPath);
150
+ if (existsSync(inventoryPath)) {
151
+ const inventory = readJsonFileWithSchema(inventoryPath, "compiled inventory", CompiledInventorySchema);
152
+ const inventoryTotal = compiledInventoryTotal(inventory);
153
+ if (inventory &&
154
+ inventoryTotal === (state.summarized ?? 0) &&
155
+ compiledInventoryEntryCount(inventory) === (state.summarized ?? 0)) {
156
+ next.inventory_complete = true;
157
+ }
158
+ }
159
+ return next;
133
160
  }
134
161
  function normalizeRuntimeTimestampField(value) {
135
162
  if (typeof value === "string" || value === null)
@@ -1,13 +1,13 @@
1
- import { workspaceRawSnapshotMetadataPath, workspaceRuntimeHealthPath, workspaceRuntimeStatePath, workspaceRuntimeViewSpecPath, } from "./workspace-paths.js";
1
+ import { compiledRawSnapshotMetadataPath, compiledRuntimeHealthPath, compiledRuntimeStatePath, compiledRuntimeViewSpecPath, } from "./compiled-paths.js";
2
2
  export function statePath(dirPath) {
3
- return workspaceRuntimeStatePath(dirPath);
3
+ return compiledRuntimeStatePath(dirPath);
4
4
  }
5
5
  export function healthPath(dirPath) {
6
- return workspaceRuntimeHealthPath(dirPath);
6
+ return compiledRuntimeHealthPath(dirPath);
7
7
  }
8
8
  export function viewSpecPath(dirPath) {
9
- return workspaceRuntimeViewSpecPath(dirPath);
9
+ return compiledRuntimeViewSpecPath(dirPath);
10
10
  }
11
11
  export function rawSnapshotPath(dirPath) {
12
- return workspaceRawSnapshotMetadataPath(dirPath);
12
+ return compiledRawSnapshotMetadataPath(dirPath);
13
13
  }
@@ -1,4 +1,4 @@
1
- import { type WorkspaceRawSnapshot, type WorkspaceViewSpec } from "./schema.js";
2
- export declare function ensureWorkspaceViewSpec(dirPath: string): WorkspaceViewSpec;
3
- export declare function ensureWorkspaceRawSnapshot(dirPath: string): WorkspaceRawSnapshot;
4
- export declare function normalizeWorkspaceViewSpec(existing: WorkspaceViewSpec, defaults?: WorkspaceViewSpec): WorkspaceViewSpec;
1
+ import { type CompiledRawSnapshot, type CompiledViewSpec } from "./schema.js";
2
+ export declare function ensureCompiledViewSpec(dirPath: string): CompiledViewSpec;
3
+ export declare function ensureCompiledRawSnapshot(dirPath: string): CompiledRawSnapshot;
4
+ export declare function normalizeCompiledViewSpec(existing: CompiledViewSpec, defaults?: CompiledViewSpec): CompiledViewSpec;
@@ -2,28 +2,30 @@ import { basename, relative } from "node:path";
2
2
  import { mkdirSync, writeFileSync } from "node:fs";
3
3
  import { discoverSourceFiles } from "./discovery.js";
4
4
  import { readInterfConfig, resolveSourceFolderPath } from "./interf.js";
5
- import { loadWorkspaceViewSpec, saveWorkspaceViewSpec, } from "./state-io.js";
5
+ import { loadCompiledViewSpec, saveCompiledViewSpec, } from "./state-io.js";
6
6
  import { rawSnapshotPath } from "./state-paths.js";
7
- import { workspaceRuntimeRoot } from "./workspace-paths.js";
8
- export function ensureWorkspaceViewSpec(dirPath) {
9
- const existing = loadWorkspaceViewSpec(dirPath);
7
+ import { compiledRuntimeRoot, workflowPackagePathForCompiled } from "./compiled-paths.js";
8
+ import { readCompiledSchemaFile } from "./compiled-schema.js";
9
+ import { getActiveCompiledWorkflow, resolveCompiledWorkflowFromConfig } from "./workflow-definitions.js";
10
+ export function ensureCompiledViewSpec(dirPath) {
11
+ const existing = loadCompiledViewSpec(dirPath);
10
12
  const now = new Date().toISOString();
11
- const workspaceName = readInterfConfig(dirPath)?.name ?? basename(dirPath);
12
- const defaults = buildDefaultWorkspaceViewSpec(workspaceName, now);
13
+ const compiledName = readInterfConfig(dirPath)?.name ?? basename(dirPath);
14
+ const defaults = buildDefaultCompiledViewSpec(dirPath, compiledName, now);
13
15
  if (existing) {
14
- const normalized = normalizeWorkspaceViewSpec(existing, defaults);
16
+ const normalized = normalizeCompiledViewSpec(existing, defaults);
15
17
  if (JSON.stringify(normalized) !== JSON.stringify(existing)) {
16
- saveWorkspaceViewSpec(dirPath, normalized);
18
+ saveCompiledViewSpec(dirPath, normalized);
17
19
  }
18
20
  return normalized;
19
21
  }
20
- saveWorkspaceViewSpec(dirPath, defaults);
22
+ saveCompiledViewSpec(dirPath, defaults);
21
23
  return defaults;
22
24
  }
23
- export function ensureWorkspaceRawSnapshot(dirPath) {
25
+ export function ensureCompiledRawSnapshot(dirPath) {
24
26
  const now = new Date().toISOString();
25
27
  const config = readInterfConfig(dirPath);
26
- const workspaceName = config?.name ?? basename(dirPath);
28
+ const compiledName = config?.name ?? basename(dirPath);
27
29
  const sourcePath = resolveSourceFolderPath(dirPath, config);
28
30
  const discovery = discoverSourceFiles(sourcePath, dirPath);
29
31
  const sampleFiles = [...discovery.sourceFiles]
@@ -31,76 +33,71 @@ export function ensureWorkspaceRawSnapshot(dirPath) {
31
33
  .slice(0, 10);
32
34
  const sourceRoot = relative(dirPath, sourcePath) || ".";
33
35
  const artifact = {
34
- kind: "workspace-raw-snapshot",
36
+ kind: "compiled-raw-snapshot",
35
37
  version: 1,
36
38
  generated_at: now,
37
- target_name: workspaceName,
39
+ target_name: compiledName,
38
40
  source_root: sourceRoot,
39
41
  raw_root: sourceRoot,
40
42
  source_total: discovery.totalCount,
41
43
  sample_files: sampleFiles,
42
44
  };
43
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
45
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
44
46
  writeFileSync(rawSnapshotPath(dirPath), JSON.stringify(artifact, null, 2) + "\n");
45
47
  return artifact;
46
48
  }
47
- export function normalizeWorkspaceViewSpec(existing, defaults = buildDefaultWorkspaceViewSpec(existing.target_name, existing.generated_at)) {
49
+ export function normalizeCompiledViewSpec(existing, defaults) {
50
+ const resolvedDefaults = defaults ?? existing;
48
51
  return {
49
- ...defaults,
52
+ ...resolvedDefaults,
50
53
  ...existing,
51
- cards: normalizeWorkspaceCards(existing.cards, defaults.cards),
52
- sections: Array.isArray(existing.sections) && existing.sections.length > 0 ? existing.sections : defaults.sections,
54
+ cards: Array.isArray(existing.cards) && existing.cards.length > 0
55
+ ? existing.cards.map((card) => {
56
+ if (card.format !== "fraction" || card.denominator_metric)
57
+ return card;
58
+ const defaultCard = resolvedDefaults.cards.find((candidate) => candidate.id === card.id);
59
+ return {
60
+ ...card,
61
+ denominator_metric: defaultCard?.denominator_metric ?? "stage_total",
62
+ };
63
+ })
64
+ : resolvedDefaults.cards,
65
+ sections: Array.isArray(existing.sections) && existing.sections.length > 0 ? existing.sections : resolvedDefaults.sections,
53
66
  graph_scope: Array.isArray(existing.graph_scope) && existing.graph_scope.length > 0
54
67
  ? existing.graph_scope
55
- : defaults.graph_scope,
68
+ : resolvedDefaults.graph_scope,
56
69
  };
57
70
  }
58
- function buildDefaultWorkspaceViewSpec(workspaceName, generatedAt) {
71
+ function buildDefaultCompiledViewSpec(dirPath, compiledName, generatedAt) {
72
+ const config = readInterfConfig(dirPath);
73
+ const workflowId = resolveCompiledWorkflowFromConfig(config);
74
+ const workflow = getActiveCompiledWorkflow(dirPath, workflowId);
75
+ const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
76
+ const zoneDocumentPaths = (schema?.zones ?? [])
77
+ .filter((zone) => zone.kind !== "runtime")
78
+ .map((zone) => zone.path);
79
+ const defaultNote = (schema?.zones ?? []).find((zone) => zone.kind === "file")?.path ?? null;
59
80
  return {
60
- kind: "workspace-view-spec",
61
- version: 1,
81
+ kind: "compiled-view-spec",
82
+ version: 2,
62
83
  generated_at: generatedAt,
63
- target_name: workspaceName,
84
+ target_name: compiledName,
64
85
  health_source: ".interf/runtime/health.json",
65
86
  state_source: ".interf/runtime/state.json",
66
- default_note: "home.md",
67
- graph_scope: ["summaries", "knowledge"],
87
+ default_note: defaultNote,
88
+ graph_scope: zoneDocumentPaths,
68
89
  cards: [
69
90
  { id: "source-total", label: "Source Files", metric: "source_total", format: "number" },
70
- { id: "summarized", label: "Summarized", metric: "source_covered", denominator_metric: "source_total", format: "fraction" },
71
- { id: "to-summarize", label: "To Summarize", metric: "to_summarize", format: "number" },
72
- { id: "compiled", label: "Compiled", metric: "compiled", denominator_metric: "summarized", format: "fraction" },
73
- { id: "entities", label: "Entities", metric: "entities", format: "number" },
74
- { id: "claims", label: "Claims", metric: "claims", format: "number" },
91
+ { id: "stage-total", label: "Stages", metric: "stage_total", format: "number" },
92
+ { id: "completed-stages", label: "Completed", metric: "completed_stages", denominator_metric: "stage_total", format: "fraction" },
75
93
  ],
76
94
  sections: [
77
95
  { id: "status", type: "status", title: "Compile Status", path: ".interf/runtime/health.json" },
78
96
  { id: "cards", type: "cards", title: "Key Metrics", path: ".interf/runtime/health.json" },
79
- { id: "graph", type: "graph", title: "Knowledge Graph", paths: ["summaries", "knowledge"] },
80
- { id: "core-docs", type: "documents", title: "Core Docs", paths: ["home.md", "knowledge/indexes", "knowledge/entities", "knowledge/claims", "summaries"] },
81
- { id: "claims", type: "table", title: "Claims", path: "knowledge/claims" },
97
+ ...(zoneDocumentPaths.length > 0
98
+ ? [{ id: "outputs", type: "documents", title: "Compiled Outputs", paths: zoneDocumentPaths }]
99
+ : []),
100
+ { id: "workflow", type: "documents", title: "Workflow Docs", paths: ["workflow/README.md", ...workflow.stages.map((stage) => `workflow/compile/stages/${stage.skillDir}`)] },
82
101
  ],
83
102
  };
84
103
  }
85
- function normalizeWorkspaceCards(cards, defaults) {
86
- if (!Array.isArray(cards) || cards.length === 0) {
87
- return defaults;
88
- }
89
- return cards.map((card) => {
90
- const matchingDefault = defaults.find((candidate) => candidate.id === card.id);
91
- const normalized = {
92
- ...(matchingDefault ?? {}),
93
- ...card,
94
- };
95
- if (normalized.format === "fraction" &&
96
- typeof normalized.denominator_metric !== "string") {
97
- if (normalized.metric === "compiled") {
98
- normalized.denominator_metric = "summarized";
99
- }
100
- else if (normalized.metric === "source_covered") {
101
- normalized.denominator_metric = "source_total";
102
- }
103
- }
104
- return normalized;
105
- });
106
- }