@interf/compiler 0.6.3 → 0.6.4
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.
- package/README.md +70 -64
- package/dist/cli/commands/check-draft.js +4 -4
- package/dist/cli/commands/compile-controller.js +23 -23
- package/dist/cli/commands/compile.js +2 -2
- package/dist/cli/commands/compiled-flow.js +4 -4
- package/dist/cli/commands/create-workflow-wizard.js +8 -8
- package/dist/cli/commands/create.js +5 -5
- package/dist/cli/commands/default.js +1 -1
- package/dist/cli/commands/init.js +43 -43
- package/dist/cli/commands/list.js +2 -2
- package/dist/cli/commands/reset.js +1 -1
- package/dist/cli/commands/source-config-wizard.d.ts +1 -1
- package/dist/cli/commands/source-config-wizard.js +40 -40
- package/dist/cli/commands/status.js +5 -5
- package/dist/cli/commands/test-flow.js +26 -26
- package/dist/cli/commands/test.js +12 -12
- package/dist/lib/chart-guidance.d.ts +1 -1
- package/dist/lib/chart-guidance.js +1 -8
- package/dist/lib/discovery.d.ts +1 -7
- package/dist/lib/discovery.js +1 -84
- package/dist/lib/filesystem.d.ts +1 -2
- package/dist/lib/filesystem.js +1 -55
- package/dist/lib/logger.d.ts +1 -3
- package/dist/lib/logger.js +1 -10
- package/dist/lib/parse.d.ts +1 -8
- package/dist/lib/parse.js +1 -145
- package/dist/lib/util.d.ts +1 -4
- package/dist/lib/util.js +1 -25
- package/dist/packages/agents/index.d.ts +1 -0
- package/dist/packages/agents/index.js +1 -0
- package/dist/packages/agents/lib/chart-guidance.d.ts +1 -0
- package/dist/packages/agents/lib/chart-guidance.js +8 -0
- package/dist/packages/agents/lib/compiled-bootstrap.d.ts +3 -0
- package/dist/packages/agents/lib/compiled-bootstrap.js +18 -0
- package/dist/packages/agents/lib/executors.d.ts +2 -2
- package/dist/packages/agents/lib/shells.d.ts +3 -1
- package/dist/packages/agents/lib/shells.js +22 -20
- package/dist/packages/agents/lib/user-config.js +1 -1
- package/dist/packages/compiler/compiled-compile.d.ts +4 -48
- package/dist/packages/compiler/compiled-compile.js +4 -256
- package/dist/packages/compiler/compiled-paths.d.ts +40 -0
- package/dist/packages/compiler/compiled-paths.js +106 -0
- package/dist/packages/compiler/compiled-pipeline.d.ts +39 -0
- package/dist/packages/compiler/compiled-pipeline.js +134 -0
- package/dist/packages/compiler/compiled-schema.js +2 -2
- package/dist/packages/compiler/compiled-stage-plan.d.ts +15 -0
- package/dist/packages/compiler/compiled-stage-plan.js +79 -0
- package/dist/packages/compiler/compiled-stage-runner.d.ts +10 -0
- package/dist/packages/compiler/compiled-stage-runner.js +46 -0
- package/dist/packages/compiler/compiled-target.d.ts +11 -0
- package/dist/packages/compiler/compiled-target.js +16 -0
- package/dist/packages/compiler/discovery.d.ts +7 -0
- package/dist/packages/compiler/discovery.js +80 -0
- package/dist/packages/compiler/lib/schema.js +2 -0
- package/dist/packages/compiler/raw-snapshot.d.ts +49 -0
- package/dist/packages/compiler/raw-snapshot.js +102 -0
- package/dist/packages/compiler/reset.d.ts +2 -0
- package/dist/packages/compiler/reset.js +72 -0
- package/dist/packages/compiler/runtime-acceptance.js +3 -3
- package/dist/packages/compiler/runtime-contracts.js +1 -1
- package/dist/packages/compiler/runtime-paths.js +1 -1
- package/dist/packages/compiler/runtime-reconcile.js +3 -3
- package/dist/packages/compiler/runtime-runs.js +2 -2
- package/dist/packages/compiler/state-health.js +3 -3
- package/dist/packages/compiler/state-io.js +3 -3
- package/dist/packages/compiler/state-paths.js +1 -1
- package/dist/packages/compiler/state-view.js +2 -2
- package/dist/packages/compiler/validate-compiled.js +3 -3
- package/dist/packages/compiler/validate.js +4 -4
- package/dist/packages/project-model/compiled-paths.d.ts +1 -40
- package/dist/packages/project-model/compiled-paths.js +1 -106
- package/dist/packages/project-model/compiled-raw.d.ts +1 -49
- package/dist/packages/project-model/compiled-raw.js +1 -102
- package/dist/packages/project-model/compiled-reset.d.ts +1 -2
- package/dist/packages/project-model/compiled-reset.js +1 -72
- package/dist/packages/project-model/interf-bootstrap.d.ts +1 -3
- package/dist/packages/project-model/interf-bootstrap.js +1 -18
- package/dist/packages/project-model/interf-detect.js +4 -4
- package/dist/packages/project-model/interf-scaffold.js +7 -7
- package/dist/packages/project-model/source-config.js +6 -5
- package/dist/packages/shared/file-types.d.ts +1 -0
- package/dist/packages/shared/file-types.js +4 -0
- package/dist/packages/shared/filesystem.d.ts +2 -0
- package/dist/packages/shared/filesystem.js +55 -0
- package/dist/packages/shared/index.d.ts +7 -0
- package/dist/packages/shared/index.js +7 -0
- package/dist/packages/shared/logger.d.ts +3 -0
- package/dist/packages/shared/logger.js +10 -0
- package/dist/packages/shared/naming.d.ts +1 -0
- package/dist/packages/shared/naming.js +8 -0
- package/dist/packages/shared/parse.d.ts +8 -0
- package/dist/packages/shared/parse.js +145 -0
- package/dist/packages/shared/path-guards.d.ts +2 -0
- package/dist/packages/shared/path-guards.js +14 -0
- package/dist/packages/shared/util.d.ts +3 -0
- package/dist/packages/shared/util.js +3 -0
- package/dist/packages/testing/test-execution.js +3 -3
- package/dist/packages/testing/test-paths.js +1 -1
- package/dist/packages/testing/test-sandbox.js +3 -3
- package/dist/packages/testing/test-specs.js +1 -1
- package/dist/packages/workflow-authoring/workflow-authoring.js +5 -4
- package/dist/packages/workflow-authoring/workflow-improvement.js +6 -5
- package/dist/packages/workflow-package/builtin-compiled-workflow.js +1 -1
- package/dist/packages/workflow-package/context-interface.d.ts +96 -0
- package/dist/packages/workflow-package/context-interface.js +146 -0
- package/dist/packages/workflow-package/index.d.ts +2 -0
- package/dist/packages/workflow-package/index.js +2 -0
- package/dist/packages/workflow-package/interf-workflow-package.js +75 -28
- package/dist/packages/workflow-package/local-workflows.d.ts +5 -2
- package/dist/packages/workflow-package/local-workflows.js +15 -13
- package/dist/packages/workflow-package/workflow-definitions.d.ts +11 -7
- package/dist/packages/workflow-package/workflow-definitions.js +10 -3
- package/dist/packages/workflow-package/workflow-helpers.js +4 -4
- package/dist/packages/workflow-package/workflow-review-paths.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type WorkflowExecutor } from "../agents/lib/executors.js";
|
|
2
|
+
import { type WorkflowReporter, type WorkflowStageResult } from "../workflow-package/workflow-helpers.js";
|
|
3
|
+
import { type CompiledStageExecutionDefinition } from "./compiled-target.js";
|
|
4
|
+
export interface CompiledSummarizeResult extends WorkflowStageResult {
|
|
5
|
+
skipped: boolean;
|
|
6
|
+
plan: {
|
|
7
|
+
sourceCount: number;
|
|
8
|
+
summaryCount: number;
|
|
9
|
+
targetCount: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface CompiledCompileResult {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
stageResults: Record<string, WorkflowStageResult>;
|
|
15
|
+
failedStage: string | null;
|
|
16
|
+
}
|
|
17
|
+
export type StageShellRetentionMode = "on-failure" | "always";
|
|
18
|
+
export declare function runCompiledSummarize(options: {
|
|
19
|
+
executor: WorkflowExecutor;
|
|
20
|
+
compiledPath: string;
|
|
21
|
+
reporter?: WorkflowReporter;
|
|
22
|
+
reportSummary?: boolean;
|
|
23
|
+
reportStep?: boolean;
|
|
24
|
+
stageDefinition?: CompiledStageExecutionDefinition;
|
|
25
|
+
fullPass?: boolean;
|
|
26
|
+
}): Promise<CompiledSummarizeResult>;
|
|
27
|
+
export declare function runCompiledCompile(options: {
|
|
28
|
+
executor: WorkflowExecutor;
|
|
29
|
+
compiledPath: string;
|
|
30
|
+
reporter?: WorkflowReporter;
|
|
31
|
+
reportStep?: boolean;
|
|
32
|
+
preserveStageShells?: StageShellRetentionMode;
|
|
33
|
+
}): Promise<WorkflowStageResult>;
|
|
34
|
+
export declare function compileCompiled(options: {
|
|
35
|
+
executor: WorkflowExecutor;
|
|
36
|
+
compiledPath: string;
|
|
37
|
+
reporter?: WorkflowReporter;
|
|
38
|
+
preserveStageShells?: StageShellRetentionMode;
|
|
39
|
+
}): Promise<CompiledCompileResult>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { refreshCompiledBootstrapGuidance, } from "../agents/lib/compiled-bootstrap.js";
|
|
3
|
+
import { validateWorkflowPackage } from "../workflow-package/local-workflows.js";
|
|
4
|
+
import { reportValidationFailure, } from "../workflow-package/workflow-helpers.js";
|
|
5
|
+
import { validateCompiledWorkflow, } from "./validate.js";
|
|
6
|
+
import { pruneStageExecutionShells, } from "../agents/lib/shells.js";
|
|
7
|
+
import { syncCompiledRawSnapshot } from "./raw-snapshot.js";
|
|
8
|
+
import { compiledExecutionStages, resolveCompiledContext, } from "./compiled-target.js";
|
|
9
|
+
import { discoverSourceFiles } from "./discovery.js";
|
|
10
|
+
import { runCompiledStage } from "./compiled-stage-runner.js";
|
|
11
|
+
import { resolveSourceInputPath } from "../project-model/interf-detect.js";
|
|
12
|
+
export async function runCompiledSummarize(options) {
|
|
13
|
+
const context = resolveCompiledContext(options.compiledPath);
|
|
14
|
+
const stageDefinition = options.stageDefinition
|
|
15
|
+
?? compiledExecutionStages(context.workflowId, options.compiledPath).find((stage) => stage.id === "summarize");
|
|
16
|
+
if (!stageDefinition) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
code: 1,
|
|
20
|
+
skipped: true,
|
|
21
|
+
plan: { sourceCount: 0, summaryCount: 0, targetCount: 0 },
|
|
22
|
+
summary: "Workflow does not declare a summarize stage.",
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const sourceCount = discoverSourceFiles(context.sourcePath, options.compiledPath).totalCount;
|
|
26
|
+
const result = await runCompiledStage({
|
|
27
|
+
executor: options.executor,
|
|
28
|
+
compiledPath: options.compiledPath,
|
|
29
|
+
reporter: options.reporter,
|
|
30
|
+
reportStep: options.reportStep,
|
|
31
|
+
stageDefinition,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
...result,
|
|
35
|
+
skipped: false,
|
|
36
|
+
plan: {
|
|
37
|
+
sourceCount,
|
|
38
|
+
summaryCount: 0,
|
|
39
|
+
targetCount: sourceCount,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export async function runCompiledCompile(options) {
|
|
44
|
+
const preserveMode = options.preserveStageShells ?? "on-failure";
|
|
45
|
+
if (preserveMode !== "always") {
|
|
46
|
+
pruneStageExecutionShells(options.compiledPath);
|
|
47
|
+
}
|
|
48
|
+
let lastResult = { ok: true, code: 0 };
|
|
49
|
+
try {
|
|
50
|
+
const context = resolveCompiledContext(options.compiledPath);
|
|
51
|
+
for (const stageDefinition of compiledExecutionStages(context.workflowId, options.compiledPath)) {
|
|
52
|
+
const result = await runCompiledStage({
|
|
53
|
+
executor: options.executor,
|
|
54
|
+
compiledPath: options.compiledPath,
|
|
55
|
+
reporter: options.reporter,
|
|
56
|
+
reportStep: options.reportStep,
|
|
57
|
+
stageDefinition,
|
|
58
|
+
});
|
|
59
|
+
lastResult = result;
|
|
60
|
+
if (!result.ok)
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
return lastResult;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
if (preserveMode !== "always" && lastResult.ok) {
|
|
67
|
+
pruneStageExecutionShells(options.compiledPath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export async function compileCompiled(options) {
|
|
72
|
+
const preserveMode = options.preserveStageShells ?? "on-failure";
|
|
73
|
+
if (preserveMode !== "always") {
|
|
74
|
+
pruneStageExecutionShells(options.compiledPath);
|
|
75
|
+
}
|
|
76
|
+
let result = {
|
|
77
|
+
ok: true,
|
|
78
|
+
stageResults: {},
|
|
79
|
+
failedStage: null,
|
|
80
|
+
};
|
|
81
|
+
try {
|
|
82
|
+
const sourceInputPath = resolveSourceInputPath(options.compiledPath);
|
|
83
|
+
syncCompiledRawSnapshot(options.compiledPath, sourceInputPath);
|
|
84
|
+
refreshCompiledBootstrapGuidance(options.compiledPath);
|
|
85
|
+
const workflowValidation = validateWorkflowPackage(join(options.compiledPath, ".interf", "workflow"));
|
|
86
|
+
if (!workflowValidation.ok) {
|
|
87
|
+
reportValidationFailure(options.reporter, workflowValidation.summary, workflowValidation.errors);
|
|
88
|
+
return {
|
|
89
|
+
...result,
|
|
90
|
+
ok: false,
|
|
91
|
+
failedStage: "workflow",
|
|
92
|
+
stageResults: {
|
|
93
|
+
...result.stageResults,
|
|
94
|
+
workflow: {
|
|
95
|
+
ok: false,
|
|
96
|
+
code: 1,
|
|
97
|
+
summary: workflowValidation.summary,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const context = resolveCompiledContext(options.compiledPath);
|
|
103
|
+
const stages = compiledExecutionStages(context.workflowId, options.compiledPath);
|
|
104
|
+
for (const stageDefinition of stages) {
|
|
105
|
+
const stageResult = await runCompiledStage({
|
|
106
|
+
executor: options.executor,
|
|
107
|
+
compiledPath: options.compiledPath,
|
|
108
|
+
reporter: options.reporter,
|
|
109
|
+
reportStep: true,
|
|
110
|
+
stageDefinition,
|
|
111
|
+
});
|
|
112
|
+
result.stageResults[stageDefinition.id] = stageResult;
|
|
113
|
+
if (!stageResult.ok) {
|
|
114
|
+
result.ok = false;
|
|
115
|
+
result.failedStage = stageDefinition.id;
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const workflowValidationResult = validateCompiledWorkflow(options.compiledPath);
|
|
120
|
+
result.ok = workflowValidationResult.ok;
|
|
121
|
+
result.failedStage = workflowValidationResult.ok ? null : workflowValidationResult.stage;
|
|
122
|
+
result.stageResults.compiled = {
|
|
123
|
+
ok: workflowValidationResult.ok,
|
|
124
|
+
code: workflowValidationResult.ok ? 0 : 1,
|
|
125
|
+
summary: workflowValidationResult.summary,
|
|
126
|
+
};
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
if (preserveMode !== "always" && result.ok) {
|
|
131
|
+
pruneStageExecutionShells(options.compiledPath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
|
-
import { warnInterf } from "
|
|
4
|
-
import { readJsonFileUnchecked } from "
|
|
3
|
+
import { warnInterf } from "../shared/logger.js";
|
|
4
|
+
import { readJsonFileUnchecked } from "../shared/parse.js";
|
|
5
5
|
import { BUILTIN_COMPILED_ZONE_IDS, listBuiltinCompiledZoneSpecs, requiredCompiledZoneOwners, } from "../workflow-package/builtin-compiled-workflow.js";
|
|
6
6
|
import { WorkflowCompiledSchemaSchema, } from "./lib/schema.js";
|
|
7
7
|
export { BUILTIN_COMPILED_ZONE_IDS } from "../workflow-package/builtin-compiled-workflow.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type RuntimeStageContractDraft } from "./runtime.js";
|
|
2
|
+
import { type CompiledWorkflowId, type WorkflowStageDefinition } from "../workflow-package/workflow-definitions.js";
|
|
3
|
+
import { resolveCompiledContext, type CompiledStageExecutionDefinition } from "./compiled-target.js";
|
|
4
|
+
import type { RuntimeStageInstructions } from "./lib/schema.js";
|
|
5
|
+
export declare function resolveStageContractArtifacts(compiledPath: string, stageDefinition: Pick<WorkflowStageDefinition, "id" | "reads" | "writes">): {
|
|
6
|
+
reads: string[];
|
|
7
|
+
writes: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function buildStageCounts(compiledPath: string, stageDefinition: WorkflowStageDefinition): Record<string, number>;
|
|
10
|
+
export declare function buildStageContract(compiledPath: string, workflowId: CompiledWorkflowId, stageDefinition: WorkflowStageDefinition, instructions: RuntimeStageInstructions): RuntimeStageContractDraft;
|
|
11
|
+
export declare function buildCompiledStageExecutionPlan(compiledPath: string, stageDefinition: CompiledStageExecutionDefinition): {
|
|
12
|
+
context: ReturnType<typeof resolveCompiledContext>;
|
|
13
|
+
contract: RuntimeStageContractDraft;
|
|
14
|
+
instructions: RuntimeStageInstructions;
|
|
15
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { buildRuntimeStageContract, } from "./runtime.js";
|
|
3
|
+
import { discoverSourceFiles } from "./discovery.js";
|
|
4
|
+
import { listFilesRecursive } from "../shared/filesystem.js";
|
|
5
|
+
import { compiledContractArtifactPathsForZoneIds, findCompiledSchemaZone, readCompiledSchemaFile, } from "./compiled-schema.js";
|
|
6
|
+
import { buildLocalSkillContractExtension, buildStageInstructions, workflowCompileStageDirectory, } from "../workflow-package/workflow-helpers.js";
|
|
7
|
+
import { getActiveCompiledStagePolicyNotes, resolveActiveCompiledStageAcceptance, } from "../workflow-package/workflow-definitions.js";
|
|
8
|
+
import { workflowPackagePathForCompiled } from "./compiled-paths.js";
|
|
9
|
+
import { readInterfConfig } from "../project-model/interf-detect.js";
|
|
10
|
+
import { resolveCompiledContext, } from "./compiled-target.js";
|
|
11
|
+
function zoneArtifactCount(compiledPath, zonePath, kind) {
|
|
12
|
+
const absolutePath = join(compiledPath, zonePath);
|
|
13
|
+
try {
|
|
14
|
+
if (kind === "file") {
|
|
15
|
+
return listFilesRecursive(absolutePath).length > 0 ? 1 : 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
if (kind === "file")
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
return listFilesRecursive(absolutePath).length;
|
|
23
|
+
}
|
|
24
|
+
export function resolveStageContractArtifacts(compiledPath, stageDefinition) {
|
|
25
|
+
const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(compiledPath));
|
|
26
|
+
if (!schema) {
|
|
27
|
+
throw new Error(`Missing workflow schema for stage "${stageDefinition.id}" at ${workflowPackagePathForCompiled(compiledPath)}.`);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
reads: compiledContractArtifactPathsForZoneIds(schema, stageDefinition.reads),
|
|
31
|
+
writes: compiledContractArtifactPathsForZoneIds(schema, stageDefinition.writes),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function buildStageCounts(compiledPath, stageDefinition) {
|
|
35
|
+
const context = resolveCompiledContext(compiledPath);
|
|
36
|
+
const sourceTotal = discoverSourceFiles(context.sourcePath, compiledPath).totalCount;
|
|
37
|
+
const schema = readCompiledSchemaFile(workflowPackagePathForCompiled(compiledPath));
|
|
38
|
+
const zoneCounts = {};
|
|
39
|
+
if (schema) {
|
|
40
|
+
for (const zoneId of new Set([...stageDefinition.reads, ...stageDefinition.writes])) {
|
|
41
|
+
const zone = findCompiledSchemaZone(schema, zoneId);
|
|
42
|
+
if (!zone)
|
|
43
|
+
continue;
|
|
44
|
+
zoneCounts[zoneId] = zoneArtifactCount(compiledPath, zone.path, zone.kind);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
source_total: sourceTotal,
|
|
49
|
+
read_zone_total: stageDefinition.reads.length,
|
|
50
|
+
write_zone_total: stageDefinition.writes.length,
|
|
51
|
+
...zoneCounts,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function buildStageContract(compiledPath, workflowId, stageDefinition, instructions) {
|
|
55
|
+
const config = readInterfConfig(compiledPath);
|
|
56
|
+
const stageArtifacts = resolveStageContractArtifacts(compiledPath, stageDefinition);
|
|
57
|
+
return buildRuntimeStageContract({
|
|
58
|
+
compiledName: config?.name ?? "compiled",
|
|
59
|
+
stageId: stageDefinition.id,
|
|
60
|
+
stageLabel: stageDefinition.label,
|
|
61
|
+
counts: buildStageCounts(compiledPath, stageDefinition),
|
|
62
|
+
stageReadArtifacts: stageArtifacts.reads,
|
|
63
|
+
stageWriteArtifacts: stageArtifacts.writes,
|
|
64
|
+
workflowNotes: getActiveCompiledStagePolicyNotes(compiledPath, workflowId, stageDefinition.id),
|
|
65
|
+
localSkillDocs: instructions.local_docs,
|
|
66
|
+
instructions,
|
|
67
|
+
acceptance: resolveActiveCompiledStageAcceptance(compiledPath, workflowId, stageDefinition.id),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
export function buildCompiledStageExecutionPlan(compiledPath, stageDefinition) {
|
|
71
|
+
const context = resolveCompiledContext(compiledPath);
|
|
72
|
+
const localSkills = buildLocalSkillContractExtension(compiledPath, [workflowCompileStageDirectory(stageDefinition.skillDir)], "Use them to refine this workflow stage while still honoring the declared reads, writes, and proof rules.");
|
|
73
|
+
const instructions = buildStageInstructions(stageDefinition.skillDir, localSkills);
|
|
74
|
+
return {
|
|
75
|
+
context,
|
|
76
|
+
instructions,
|
|
77
|
+
contract: buildStageContract(compiledPath, context.workflowId, stageDefinition, instructions),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type WorkflowExecutor } from "../agents/lib/executors.js";
|
|
2
|
+
import { type WorkflowReporter, type WorkflowStageResult } from "../workflow-package/workflow-helpers.js";
|
|
3
|
+
import { type CompiledStageExecutionDefinition } from "./compiled-target.js";
|
|
4
|
+
export declare function runCompiledStage(options: {
|
|
5
|
+
executor: WorkflowExecutor;
|
|
6
|
+
compiledPath: string;
|
|
7
|
+
reporter?: WorkflowReporter;
|
|
8
|
+
reportStep?: boolean;
|
|
9
|
+
stageDefinition: CompiledStageExecutionDefinition;
|
|
10
|
+
}): Promise<WorkflowStageResult>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createStageExecutionShell, freezeStageExecutionShell, syncStageExecutionShellWrites, } from "../agents/lib/shells.js";
|
|
2
|
+
import { reconcileCompiledStageRun } from "./runtime-reconcile.js";
|
|
3
|
+
import { refreshCompiledArtifacts } from "./state.js";
|
|
4
|
+
import { validateCompiledStage } from "./validate.js";
|
|
5
|
+
import { executeValidatedStage, } from "../workflow-package/workflow-stage-runner.js";
|
|
6
|
+
import { formatActiveCompiledWorkflowStageStep, } from "../workflow-package/workflow-definitions.js";
|
|
7
|
+
import { reportBlankLine, reportLine, } from "../workflow-package/workflow-helpers.js";
|
|
8
|
+
import { buildCompiledStageExecutionPlan, } from "./compiled-stage-plan.js";
|
|
9
|
+
export async function runCompiledStage(options) {
|
|
10
|
+
const stageDefinition = options.stageDefinition;
|
|
11
|
+
const plan = buildCompiledStageExecutionPlan(options.compiledPath, stageDefinition);
|
|
12
|
+
if (options.reportStep !== false) {
|
|
13
|
+
reportBlankLine(options.reporter);
|
|
14
|
+
reportLine(options.reporter, `${formatActiveCompiledWorkflowStageStep(options.compiledPath, plan.context.workflowId, stageDefinition.id)} (${stageDefinition.description.toLowerCase()})`);
|
|
15
|
+
}
|
|
16
|
+
const shell = createStageExecutionShell(options.compiledPath, plan.context.compiledName, plan.context.workflowId, stageDefinition, plan.contract.artifacts.writes);
|
|
17
|
+
try {
|
|
18
|
+
return await executeValidatedStage({
|
|
19
|
+
executor: options.executor,
|
|
20
|
+
compiledPath: options.compiledPath,
|
|
21
|
+
executionPath: shell.rootPath,
|
|
22
|
+
targetName: plan.context.compiledName,
|
|
23
|
+
workflow: plan.context.workflowId,
|
|
24
|
+
workflowSourcePath: options.compiledPath,
|
|
25
|
+
stageDefinition,
|
|
26
|
+
instructions: plan.instructions,
|
|
27
|
+
summary: `Executing ${stageDefinition.label.toLowerCase()}.`,
|
|
28
|
+
contract: plan.contract,
|
|
29
|
+
statusLines: [
|
|
30
|
+
`Emit exactly one startup line: STATUS: loaded ${stageDefinition.label.toLowerCase()} stage.`,
|
|
31
|
+
"Emit STATUS: reading declared inputs after you confirm the shell contract and local docs.",
|
|
32
|
+
"Emit STATUS: writing declared outputs after the stage starts updating the compiled zones.",
|
|
33
|
+
`Emit DONE: ${stageDefinition.id} complete when the declared outputs and proof are on disk.`,
|
|
34
|
+
],
|
|
35
|
+
reporter: options.reporter,
|
|
36
|
+
completionCheck: () => validateCompiledStage(options.compiledPath, stageDefinition.id).ok,
|
|
37
|
+
syncWrites: () => syncStageExecutionShellWrites(options.compiledPath, shell.rootPath, stageDefinition, plan.contract.artifacts.writes),
|
|
38
|
+
reconcile: () => reconcileCompiledStageRun(options.compiledPath, stageDefinition),
|
|
39
|
+
refreshArtifacts: () => refreshCompiledArtifacts(options.compiledPath, { ensureViewSpec: true }),
|
|
40
|
+
validate: () => validateCompiledStage(options.compiledPath, stageDefinition.id),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
freezeStageExecutionShell(shell.rootPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type WorkflowStageDefinition } from "../workflow-package/workflow-definitions.js";
|
|
2
|
+
import { type CompiledWorkflowId } from "../workflow-package/workflow-definitions.js";
|
|
3
|
+
export interface CompiledStageExecutionDefinition extends WorkflowStageDefinition {
|
|
4
|
+
}
|
|
5
|
+
export declare function resolveCompiledContext(compiledPath: string): {
|
|
6
|
+
compiledName: string;
|
|
7
|
+
sourcePath: string;
|
|
8
|
+
controlPath: string;
|
|
9
|
+
workflowId: CompiledWorkflowId;
|
|
10
|
+
};
|
|
11
|
+
export declare function compiledExecutionStages(workflowId: CompiledWorkflowId, compiledPath: string): CompiledStageExecutionDefinition[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getActiveCompiledWorkflow, resolveRequiredCompiledWorkflowFromConfig, } from "../workflow-package/workflow-definitions.js";
|
|
2
|
+
import { readInterfConfig, resolveSourceFolderPath, resolveSourceControlPath, } from "../project-model/interf-detect.js";
|
|
3
|
+
export function resolveCompiledContext(compiledPath) {
|
|
4
|
+
const config = readInterfConfig(compiledPath);
|
|
5
|
+
const workflowId = resolveRequiredCompiledWorkflowFromConfig(config, `.interf/interf.json for ${compiledPath}`);
|
|
6
|
+
return {
|
|
7
|
+
compiledName: config?.name ?? "compiled",
|
|
8
|
+
sourcePath: resolveSourceFolderPath(compiledPath, config),
|
|
9
|
+
controlPath: resolveSourceControlPath(compiledPath),
|
|
10
|
+
workflowId,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function compiledExecutionStages(workflowId, compiledPath) {
|
|
14
|
+
return getActiveCompiledWorkflow(compiledPath, workflowId)
|
|
15
|
+
.stages;
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface DiscoveryResult {
|
|
2
|
+
sourceFiles: string[];
|
|
3
|
+
totalCount: number;
|
|
4
|
+
ignoredCount: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function discoverSourceFiles(sourcePath: string, compiledPath: string): DiscoveryResult;
|
|
7
|
+
export declare function loadIgnorePatterns(compiledPath: string): string[];
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { listFilesRecursive } from "../shared/filesystem.js";
|
|
4
|
+
const DEFAULT_IGNORE_DIRS = new Set([
|
|
5
|
+
"interf",
|
|
6
|
+
".interf",
|
|
7
|
+
".git",
|
|
8
|
+
".obsidian",
|
|
9
|
+
".claude",
|
|
10
|
+
"node_modules",
|
|
11
|
+
]);
|
|
12
|
+
const DEFAULT_IGNORE_FILES = new Set([
|
|
13
|
+
"interf.json",
|
|
14
|
+
]);
|
|
15
|
+
export function discoverSourceFiles(sourcePath, compiledPath) {
|
|
16
|
+
const userPatterns = loadIgnorePatterns(compiledPath);
|
|
17
|
+
let ignoredCount = 0;
|
|
18
|
+
const allFiles = listFilesRecursive(sourcePath, (filePath) => {
|
|
19
|
+
const rel = relative(sourcePath, filePath);
|
|
20
|
+
if (isIgnored(rel)) {
|
|
21
|
+
ignoredCount++;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (userPatterns.length > 0 && matchesUserPattern(rel, userPatterns)) {
|
|
25
|
+
ignoredCount++;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
});
|
|
30
|
+
const sourceFiles = allFiles
|
|
31
|
+
.map((f) => relative(sourcePath, f))
|
|
32
|
+
.sort((a, b) => a.localeCompare(b));
|
|
33
|
+
return {
|
|
34
|
+
sourceFiles,
|
|
35
|
+
totalCount: sourceFiles.length,
|
|
36
|
+
ignoredCount,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function loadIgnorePatterns(compiledPath) {
|
|
40
|
+
const ignorePath = join(compiledPath, ".interfignore");
|
|
41
|
+
if (!existsSync(ignorePath))
|
|
42
|
+
return [];
|
|
43
|
+
return readFileSync(ignorePath, "utf-8")
|
|
44
|
+
.split("\n")
|
|
45
|
+
.map((line) => line.trim())
|
|
46
|
+
.filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
47
|
+
}
|
|
48
|
+
function isIgnored(relativePath) {
|
|
49
|
+
if (DEFAULT_IGNORE_FILES.has(relativePath))
|
|
50
|
+
return true;
|
|
51
|
+
const segments = relativePath.split("/");
|
|
52
|
+
for (const segment of segments) {
|
|
53
|
+
if (segment.startsWith("."))
|
|
54
|
+
return true;
|
|
55
|
+
if (DEFAULT_IGNORE_DIRS.has(segment))
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
function matchesUserPattern(relativePath, patterns) {
|
|
61
|
+
for (const pattern of patterns) {
|
|
62
|
+
if (matchGlob(relativePath, pattern))
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
function matchGlob(path, pattern) {
|
|
68
|
+
if (pattern.endsWith("/")) {
|
|
69
|
+
const dir = pattern.slice(0, -1);
|
|
70
|
+
return path === dir || path.startsWith(dir + "/") || path.includes("/" + dir + "/");
|
|
71
|
+
}
|
|
72
|
+
if (pattern.startsWith("*.")) {
|
|
73
|
+
return path.endsWith(pattern.slice(1));
|
|
74
|
+
}
|
|
75
|
+
if (!pattern.includes("/") && !pattern.includes("*")) {
|
|
76
|
+
const filename = path.split("/").pop() ?? "";
|
|
77
|
+
return filename === pattern;
|
|
78
|
+
}
|
|
79
|
+
return path === pattern || path.startsWith(pattern + "/");
|
|
80
|
+
}
|
|
@@ -109,6 +109,8 @@ export const WorkflowZoneSchema = z.object({
|
|
|
109
109
|
description: z.string().min(1),
|
|
110
110
|
});
|
|
111
111
|
export const WorkflowCompiledZoneSchema = WorkflowZoneSchema;
|
|
112
|
+
// Persisted schema for the workflow-defined context interface that one
|
|
113
|
+
// compiled context must implement on disk.
|
|
112
114
|
export const WorkflowSchemaSchema = z.object({
|
|
113
115
|
kind: z.literal("workflow-schema"),
|
|
114
116
|
version: z.literal(1),
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { InterfConfig } from "../project-model/lib/schema.js";
|
|
2
|
+
export interface CompiledRawSyncResult {
|
|
3
|
+
sourceTotal: number;
|
|
4
|
+
copied: number;
|
|
5
|
+
removed: number;
|
|
6
|
+
}
|
|
7
|
+
type RawSnapshotMaterializeMode = "copy" | "link-or-copy";
|
|
8
|
+
export declare function resolveCompiledRawPath(compiledPath: string, config?: {
|
|
9
|
+
[x: string]: unknown;
|
|
10
|
+
type: "compiled";
|
|
11
|
+
name: string;
|
|
12
|
+
workflow: string;
|
|
13
|
+
checks: {
|
|
14
|
+
question: string;
|
|
15
|
+
id?: string | undefined;
|
|
16
|
+
answer?: string | undefined;
|
|
17
|
+
expect?: {
|
|
18
|
+
must_include?: string[] | undefined;
|
|
19
|
+
must_include_one_of?: string[][] | undefined;
|
|
20
|
+
must_not_include?: string[] | undefined;
|
|
21
|
+
min_words?: number | undefined;
|
|
22
|
+
max_words?: number | undefined;
|
|
23
|
+
} | undefined;
|
|
24
|
+
strictness?: string | undefined;
|
|
25
|
+
}[];
|
|
26
|
+
source: {
|
|
27
|
+
path: string;
|
|
28
|
+
dataset_path: string;
|
|
29
|
+
control_path?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
about?: string | undefined;
|
|
32
|
+
max_attempts?: number | undefined;
|
|
33
|
+
max_loops?: number | undefined;
|
|
34
|
+
workflow_origin?: {
|
|
35
|
+
selected: string;
|
|
36
|
+
local_draft?: boolean | undefined;
|
|
37
|
+
} | undefined;
|
|
38
|
+
} | null): string;
|
|
39
|
+
export declare function syncCompiledRawSnapshot(compiledPath: string, sourcePath?: string): CompiledRawSyncResult;
|
|
40
|
+
export declare function ensureCompiledRawBinding(compiledPath: string): InterfConfig | null;
|
|
41
|
+
export declare function projectRawSnapshot(options: {
|
|
42
|
+
sourcePath: string;
|
|
43
|
+
destinationPath: string;
|
|
44
|
+
compiledPath: string;
|
|
45
|
+
mode?: RawSnapshotMaterializeMode;
|
|
46
|
+
prune?: boolean;
|
|
47
|
+
preserveTimestamps?: boolean;
|
|
48
|
+
}): CompiledRawSyncResult;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { cpSync, existsSync, linkSync, mkdirSync, rmSync, statSync, } from "node:fs";
|
|
2
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
3
|
+
import { listFilesRecursive } from "../shared/filesystem.js";
|
|
4
|
+
import { assertPathWithinRoot } from "../shared/path-guards.js";
|
|
5
|
+
import { discoverSourceFiles } from "./discovery.js";
|
|
6
|
+
import { defaultControlPathForCompiled } from "./compiled-paths.js";
|
|
7
|
+
import { readInterfConfig, resolveSourceInputPath, } from "../project-model/interf-detect.js";
|
|
8
|
+
import { saveCompiledInterfConfig } from "../project-model/source-config.js";
|
|
9
|
+
export function resolveCompiledRawPath(compiledPath, config = readInterfConfig(compiledPath)) {
|
|
10
|
+
const configuredPath = typeof config?.source?.path === "string" && config.source.path.length > 0
|
|
11
|
+
? config.source.path
|
|
12
|
+
: "raw";
|
|
13
|
+
return assertPathWithinRoot(compiledPath, resolve(compiledPath, configuredPath), "Compiled raw path");
|
|
14
|
+
}
|
|
15
|
+
export function syncCompiledRawSnapshot(compiledPath, sourcePath = resolveSourceInputPath(compiledPath)) {
|
|
16
|
+
ensureCompiledRawBinding(compiledPath);
|
|
17
|
+
const rawPath = resolveCompiledRawPath(compiledPath);
|
|
18
|
+
return projectRawSnapshot({
|
|
19
|
+
sourcePath,
|
|
20
|
+
destinationPath: rawPath,
|
|
21
|
+
compiledPath,
|
|
22
|
+
mode: "copy",
|
|
23
|
+
prune: true,
|
|
24
|
+
preserveTimestamps: true,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function ensureCompiledRawBinding(compiledPath) {
|
|
28
|
+
const config = readInterfConfig(compiledPath);
|
|
29
|
+
if (!config)
|
|
30
|
+
return null;
|
|
31
|
+
if (config.source?.path === "./raw")
|
|
32
|
+
return config;
|
|
33
|
+
const nextConfig = {
|
|
34
|
+
...config,
|
|
35
|
+
source: {
|
|
36
|
+
...(config.source ?? {}),
|
|
37
|
+
path: "./raw",
|
|
38
|
+
control_path: config.source?.control_path ?? defaultControlPathForCompiled(compiledPath),
|
|
39
|
+
...(config.source?.dataset_path ? { dataset_path: config.source.dataset_path } : {}),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return saveCompiledInterfConfig(compiledPath, nextConfig);
|
|
43
|
+
}
|
|
44
|
+
function filesMatch(sourcePath, targetPath) {
|
|
45
|
+
if (!existsSync(targetPath))
|
|
46
|
+
return false;
|
|
47
|
+
try {
|
|
48
|
+
const sourceStat = statSync(sourcePath);
|
|
49
|
+
const targetStat = statSync(targetPath);
|
|
50
|
+
return sourceStat.size === targetStat.size && sourceStat.mtimeMs === targetStat.mtimeMs;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function materializeRawSnapshotFile(sourcePath, targetPath, options) {
|
|
57
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
58
|
+
rmSync(targetPath, { force: true });
|
|
59
|
+
if (options.mode === "link-or-copy") {
|
|
60
|
+
try {
|
|
61
|
+
linkSync(sourcePath, targetPath);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// fall through to copy
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
cpSync(sourcePath, targetPath, { preserveTimestamps: options.preserveTimestamps });
|
|
69
|
+
}
|
|
70
|
+
export function projectRawSnapshot(options) {
|
|
71
|
+
const discovery = discoverSourceFiles(options.sourcePath, options.compiledPath);
|
|
72
|
+
const expectedFiles = new Set(discovery.sourceFiles);
|
|
73
|
+
mkdirSync(options.destinationPath, { recursive: true });
|
|
74
|
+
let removed = 0;
|
|
75
|
+
if (options.prune !== false) {
|
|
76
|
+
for (const existingPath of listFilesRecursive(options.destinationPath)) {
|
|
77
|
+
const relativePath = relative(options.destinationPath, existingPath);
|
|
78
|
+
if (expectedFiles.has(relativePath))
|
|
79
|
+
continue;
|
|
80
|
+
rmSync(existingPath, { force: true });
|
|
81
|
+
removed += 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let copied = 0;
|
|
85
|
+
for (const relativePath of discovery.sourceFiles) {
|
|
86
|
+
const sourceFilePath = join(options.sourcePath, relativePath);
|
|
87
|
+
const targetFilePath = join(options.destinationPath, relativePath);
|
|
88
|
+
if (filesMatch(sourceFilePath, targetFilePath)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
materializeRawSnapshotFile(sourceFilePath, targetFilePath, {
|
|
92
|
+
mode: options.mode ?? "copy",
|
|
93
|
+
preserveTimestamps: options.preserveTimestamps ?? true,
|
|
94
|
+
});
|
|
95
|
+
copied += 1;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
sourceTotal: discovery.totalCount,
|
|
99
|
+
copied,
|
|
100
|
+
removed,
|
|
101
|
+
};
|
|
102
|
+
}
|