@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,148 +1,132 @@
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, resolveRequiredCompiledWorkflowFromConfig } 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
30
+ ? resolveRequiredCompiledWorkflowFromConfig(config, `.interf/interf.json for ${dirPath}`)
31
+ : null;
32
+ let workflow = null;
33
+ if (workflowId) {
34
+ try {
35
+ workflow = getActiveCompiledWorkflow(dirPath, workflowId);
36
+ }
37
+ catch {
38
+ workflow = null;
39
+ }
40
+ }
41
+ const stageResults = workflow?.stages.map((stage) => ({
42
+ stage,
43
+ validation: validateCompiledStage(dirPath, stage.id),
44
+ })) ?? [];
45
+ const completedStages = stageResults.filter((entry) => entry.validation.ok).length;
46
+ const firstFailed = stageResults.find((entry) => !entry.validation.ok) ?? null;
47
+ const workflowValidation = validateCompiledWorkflow(dirPath);
48
+ const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(dirPath));
49
+ const zoneMetrics = Object.fromEntries((schema?.zones ?? []).map((zone) => [
50
+ `zone_${zone.id}`,
51
+ countZoneArtifacts(dirPath, zone.path, zone.kind),
52
+ ]));
53
+ let status = "idle";
54
+ let stage = "idle";
55
+ let summary = "Idle — no source files have been compiled yet.";
56
+ const errors = workflowValidation.errors.length;
57
+ if (!validation.config_present || !validation.config_valid || !validation.config_type_match || !validation.workflow_valid || !validation.schema_valid) {
58
+ status = "failed";
59
+ stage = "failed";
60
+ summary = workflowValidation.summary;
61
+ }
62
+ else if (activeRun?.status === "running") {
63
+ status = "running";
64
+ stage = activeRun.stage;
65
+ summary = `Running — ${activeRun.stage_label} via ${activeRun.executor.display_name}. ${activeRun.summary}`;
66
+ }
67
+ else if (sourceTotal === 0 && completedStages === 0) {
68
+ status = "idle";
69
+ stage = "idle";
70
+ summary = "Idle — no source files have been compiled yet.";
71
+ }
72
+ else if (activeRun?.status === "failed") {
73
+ status = "failed";
74
+ stage = activeRun.stage;
75
+ summary = activeRun.error ?? activeRun.summary;
76
+ }
77
+ else if (workflowValidation.ok) {
78
+ status = "compiled";
79
+ stage = "compiled";
80
+ summary = `Compiled — ${completedStages}/${workflow?.stages.length ?? 0} workflow stages satisfied.`;
81
+ }
82
+ else {
83
+ status = "stale";
84
+ stage = firstFailed?.stage.id ?? "compiled";
85
+ summary = firstFailed?.validation.summary ?? workflowValidation.summary;
86
+ }
87
+ const checks = {
88
+ ...validation,
89
+ ...(workflow
90
+ ? Object.fromEntries(workflow.stages.map((workflowStage) => [
91
+ `stage_${workflowStage.id}_ok`,
92
+ stageResults.find((entry) => entry.stage.id === workflowStage.id)?.validation.ok ?? false,
93
+ ]))
94
+ : {}),
95
+ };
55
96
  return {
56
- kind: "workspace-health",
57
- version: 1,
97
+ kind: "compiled-health",
98
+ version: 2,
58
99
  generated_at: now,
59
- target_name: workspaceName,
100
+ target_name: targetName,
60
101
  status,
61
102
  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
- }),
103
+ summary,
74
104
  metrics: {
75
105
  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,
106
+ stage_total: workflow?.stages.length ?? 0,
107
+ completed_stages: completedStages,
108
+ warnings: state?.warning_count ?? 0,
109
+ errors: (state?.error_count ?? 0) + errors,
110
+ ...zoneMetrics,
101
111
  },
112
+ checks,
102
113
  };
103
114
  }
104
- export function resolveWorkspaceStatus(sourceTotal, summarized, toSummarize, toStructure, toShape, errors, state) {
105
- if (errors > 0)
115
+ export function resolveCompiledStatus(..._args) {
116
+ const state = _args[_args.length - 1];
117
+ if (state?.error_count && state.error_count > 0)
106
118
  return "failed";
107
- if (sourceTotal === 0 && summarized === 0 && state.last_summarize === null && state.last_compile === null)
119
+ if (!state?.stages || Object.keys(state.stages).length === 0)
108
120
  return "idle";
109
- if (toSummarize > 0 || toStructure > 0 || toShape > 0)
110
- return "stale";
111
- return "compiled";
121
+ const allSucceeded = Object.values(state.stages).every((stage) => stage.status === "succeeded");
122
+ return allSucceeded ? "compiled" : "stale";
112
123
  }
113
- export function resolveWorkspaceStage(state, sourceTotal, summarized, toSummarize, toStructure, toShape, errors) {
114
- if (errors > 0)
124
+ export function resolveCompiledStage(...args) {
125
+ const state = args[0];
126
+ if (state?.error_count && state.error_count > 0)
115
127
  return "failed";
116
- if (sourceTotal === 0 && summarized === 0 && state.last_summarize === null && state.last_compile === null)
128
+ if (!state?.stages || Object.keys(state.stages).length === 0)
117
129
  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);
130
+ const failedStage = Object.entries(state.stages).find(([, stage]) => stage.status !== "succeeded");
131
+ return failedStage?.[0] ?? "compiled";
148
132
  }
@@ -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,17 +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, CompiledRawSnapshotSchema, CompiledStateSchema, CompiledViewSpecSchema, } from "./schema.js";
5
+ import { emptyCompiledInventory, } from "./runtime-inventory.js";
6
6
  import { healthPath, rawSnapshotPath, statePath, viewSpecPath } from "./state-paths.js";
7
- import { workspaceRuntimeInventoryPath, workspaceRuntimeRoot, } from "./workspace-paths.js";
8
- const NORMALIZABLE_RUNTIME_TIMESTAMP_FIELDS = [
9
- "last_add",
10
- "last_summarize",
11
- "last_structure",
12
- "last_shape",
13
- "last_compile",
14
- ];
7
+ import { compiledRuntimeInventoryPath, compiledRuntimeRoot, } from "./compiled-paths.js";
15
8
  export function loadState(dirPath) {
16
9
  const path = statePath(dirPath);
17
10
  if (!existsSync(path))
@@ -19,132 +12,58 @@ export function loadState(dirPath) {
19
12
  const raw = readJsonFileUnchecked(path, "runtime state");
20
13
  if (raw === null)
21
14
  return null;
22
- const parsed = WorkspaceStateSchema.safeParse(raw);
15
+ const parsed = CompiledStateSchema.safeParse(raw);
23
16
  if (parsed.success) {
24
- const healed = healParsedRuntimeState(dirPath, parsed.data);
25
- if (healed !== null) {
26
- saveState(dirPath, healed);
27
- return healed;
28
- }
29
17
  return parsed.data;
30
18
  }
31
- const normalized = normalizeRuntimeState(raw);
32
- if (normalized !== null) {
33
- saveState(dirPath, normalized);
34
- return normalized;
35
- }
36
19
  warnInterf(`Warning: failed to validate runtime state at ${path}: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
37
20
  return null;
38
21
  }
39
22
  export function saveState(dirPath, state) {
40
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
23
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
41
24
  writeFileSync(statePath(dirPath), JSON.stringify(state, null, 2) + "\n");
42
25
  }
43
- export function loadWorkspaceHealth(dirPath) {
26
+ export function loadCompiledHealth(dirPath) {
44
27
  const path = healthPath(dirPath);
45
28
  if (!existsSync(path))
46
29
  return null;
47
- return readJsonFileWithSchema(path, "workspace health", WorkspaceHealthSchema);
30
+ return readJsonFileWithSchema(path, "compiled health", CompiledHealthSchema);
48
31
  }
49
- export function saveWorkspaceHealth(dirPath, health) {
50
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
32
+ export function saveCompiledHealth(dirPath, health) {
33
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
51
34
  writeFileSync(healthPath(dirPath), JSON.stringify(health, null, 2) + "\n");
52
35
  }
53
- export function loadWorkspaceViewSpec(dirPath) {
36
+ export function loadCompiledViewSpec(dirPath) {
54
37
  const path = viewSpecPath(dirPath);
55
38
  if (!existsSync(path))
56
39
  return null;
57
- return loadViewSpec(path, WorkspaceViewSpecSchema);
40
+ return loadViewSpec(path, CompiledViewSpecSchema);
58
41
  }
59
- export function saveWorkspaceViewSpec(dirPath, viewSpec) {
60
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
42
+ export function saveCompiledViewSpec(dirPath, viewSpec) {
43
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
61
44
  writeFileSync(viewSpecPath(dirPath), JSON.stringify(viewSpec, null, 2) + "\n");
62
45
  }
63
- export function loadWorkspaceRawSnapshot(dirPath) {
46
+ export function loadCompiledRawSnapshot(dirPath) {
64
47
  const path = rawSnapshotPath(dirPath);
65
48
  if (!existsSync(path))
66
49
  return null;
67
- return readJsonFileWithSchema(path, "workspace raw snapshot", WorkspaceRawSnapshotSchema);
50
+ return readJsonFileWithSchema(path, "compiled raw snapshot", CompiledRawSnapshotSchema);
68
51
  }
69
- export function saveEmptyWorkspaceInventory(dirPath) {
70
- mkdirSync(workspaceRuntimeRoot(dirPath), { recursive: true });
71
- writeFileSync(workspaceRuntimeInventoryPath(dirPath), JSON.stringify({ entries: [], total: 0 }, null, 2) + "\n");
52
+ export function saveEmptyCompiledInventory(dirPath) {
53
+ mkdirSync(compiledRuntimeRoot(dirPath), { recursive: true });
54
+ writeFileSync(compiledRuntimeInventoryPath(dirPath), JSON.stringify(emptyCompiledInventory(), null, 2) + "\n");
72
55
  }
73
- export function initWorkspaceState() {
56
+ export function initCompiledState() {
74
57
  return {
75
- version: 1,
58
+ version: 2,
76
59
  pending: [],
77
- summarized: 0,
78
- structured: 0,
79
- shaped: 0,
80
- compiled: 0,
60
+ stages: {},
81
61
  last_add: null,
82
- last_summarize: null,
83
- last_structure: null,
84
- last_shape: null,
85
62
  last_compile: null,
86
- inventory_complete: false,
87
- abstracts_read: 0,
88
- full_reads: 0,
89
- entity_count: 0,
90
- claim_count: 0,
91
63
  warning_count: 0,
92
64
  error_count: 0,
93
65
  };
94
66
  }
95
- function normalizeRuntimeState(raw) {
96
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
97
- return null;
98
- const normalized = { ...raw };
99
- let changed = false;
100
- for (const field of NORMALIZABLE_RUNTIME_TIMESTAMP_FIELDS) {
101
- const timestamp = normalizeRuntimeTimestampField(normalized[field]);
102
- if (timestamp !== undefined && timestamp !== normalized[field]) {
103
- normalized[field] = timestamp;
104
- changed = true;
105
- }
106
- }
107
- if (!changed)
108
- return null;
109
- const parsed = WorkspaceStateSchema.safeParse(normalized);
110
- return parsed.success ? parsed.data : null;
111
- }
112
- function healParsedRuntimeState(dirPath, state) {
113
- if (typeof state.inventory_complete === "boolean")
114
- 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 {
130
- ...state,
131
- inventory_complete: true,
132
- };
133
- }
134
- function normalizeRuntimeTimestampField(value) {
135
- if (typeof value === "string" || value === null)
136
- return value;
137
- if (!value || typeof value !== "object" || Array.isArray(value))
138
- return undefined;
139
- const record = value;
140
- for (const key of ["generated_at", "finished_at", "updated_at", "started_at", "timestamp"]) {
141
- const candidate = record[key];
142
- if (typeof candidate === "string" && candidate.length > 0) {
143
- return candidate;
144
- }
145
- }
146
- return undefined;
147
- }
148
67
  function loadViewSpec(filePath, schema) {
149
68
  try {
150
69
  const raw = JSON.parse(readFileSync(filePath, "utf8"));
@@ -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, resolveRequiredCompiledWorkflowFromConfig } 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 = resolveRequiredCompiledWorkflowFromConfig(config, `.interf/interf.json for ${dirPath}`);
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
- }