@arcfoundry/core 0.2.2 → 0.2.3
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/dist/agency-execution/contracted-stage-pipeline.js +7 -0
- package/dist/agency-execution/contracted-stage-recording.js +13 -0
- package/dist/agency-execution/finalize.js +8 -1
- package/dist/agency-execution/types.d.ts +2 -0
- package/dist/local-request/delivery-pipeline.d.ts +2 -0
- package/dist/local-request/delivery-pipeline.js +15 -0
- package/dist/local-request/stage-recorder.js +9 -0
- package/dist/local-request/types.d.ts +2 -0
- package/dist/local-request/workflow-phases.js +3 -0
- package/dist/local-request-workflow.js +13 -2
- package/dist/request-workflow.js +11 -2
- package/dist/workflow-orchestration/progress.d.ts +39 -0
- package/dist/workflow-orchestration/progress.js +3 -0
- package/package.json +2 -2
|
@@ -2,6 +2,7 @@ import { executeContractedStage } from "./contracted-stage-execution.js";
|
|
|
2
2
|
import { recordExecutedStageWave } from "./contracted-stage-recording.js";
|
|
3
3
|
import { planStageExecutionWaves } from "./stage-dependency-plan.js";
|
|
4
4
|
import { StageProgressRecorder } from "./stage-progress-recorder.js";
|
|
5
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
5
6
|
export class ContractedOpenCodeStagePipeline {
|
|
6
7
|
context;
|
|
7
8
|
options;
|
|
@@ -13,6 +14,12 @@ export class ContractedOpenCodeStagePipeline {
|
|
|
13
14
|
}
|
|
14
15
|
async execute() {
|
|
15
16
|
for (const wave of planStageExecutionWaves(this.context.workflowContract.stages)) {
|
|
17
|
+
for (const plannedStage of wave) {
|
|
18
|
+
reportWorkflowProgress(this.options.onProgress, {
|
|
19
|
+
type: "stage-started",
|
|
20
|
+
stage: plannedStage,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
16
23
|
const stageResults = await Promise.all(wave.map((plannedStage) => executeContractedStage({ context: this.context, options: this.options, plannedStage })));
|
|
17
24
|
const failed = await recordExecutedStageWave({
|
|
18
25
|
context: this.context,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildStageFailure } from "./contracted-stage-result.js";
|
|
2
2
|
import { stageSucceeded } from "./stage-invocation.js";
|
|
3
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
3
4
|
export async function recordExecutedStageWave(input) {
|
|
4
5
|
for (const { stages } of input.stageResults) {
|
|
5
6
|
for (const stage of stages)
|
|
@@ -8,6 +9,18 @@ export async function recordExecutedStageWave(input) {
|
|
|
8
9
|
for (const { plannedStage, artifactStage } of input.stageResults) {
|
|
9
10
|
if (stageSucceeded(artifactStage)) {
|
|
10
11
|
await input.recorder.recordArtifact(plannedStage, artifactStage);
|
|
12
|
+
reportWorkflowProgress(input.options.onProgress, {
|
|
13
|
+
type: "stage-completed",
|
|
14
|
+
stage: plannedStage,
|
|
15
|
+
result: artifactStage,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
reportWorkflowProgress(input.options.onProgress, {
|
|
20
|
+
type: "stage-failed",
|
|
21
|
+
stage: plannedStage,
|
|
22
|
+
result: artifactStage,
|
|
23
|
+
});
|
|
11
24
|
}
|
|
12
25
|
}
|
|
13
26
|
const failed = input.stageResults.find(({ artifactStage }) => !stageSucceeded(artifactStage));
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { writeAgentStageEvidence } from "./agent-stage-evidence.js";
|
|
2
2
|
import { deliveryStatusFromCommands, resultFromContext } from "./delivery-readiness.js";
|
|
3
3
|
import { commandFailureMessages, runFinalVerificationGates } from "./final-gates.js";
|
|
4
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
4
5
|
import { writeSystemReport } from "./system-report.js";
|
|
5
6
|
export async function finalizeAgencyExecution(context, options) {
|
|
6
|
-
|
|
7
|
+
reportWorkflowProgress(options.onProgress, { type: "final-gates-started" });
|
|
8
|
+
const finalCommands = await runFinalVerificationGates(options.repoRoot, context.evidenceDir);
|
|
9
|
+
for (const command of finalCommands) {
|
|
10
|
+
reportWorkflowProgress(options.onProgress, { type: "final-command-completed", command });
|
|
11
|
+
}
|
|
12
|
+
context.commands.push(...finalCommands);
|
|
7
13
|
const status = deliveryStatusFromCommands(context.commands);
|
|
8
14
|
const systemReport = await writeSystemReport(context.artifactDir, options, {
|
|
9
15
|
gitBefore: context.gitBefore,
|
|
@@ -16,6 +22,7 @@ export async function finalizeAgencyExecution(context, options) {
|
|
|
16
22
|
});
|
|
17
23
|
context.artifacts.push(systemReport);
|
|
18
24
|
await writeAgentStageEvidence(context);
|
|
25
|
+
reportWorkflowProgress(options.onProgress, { type: "completed", status });
|
|
19
26
|
return resultFromContext(context, status);
|
|
20
27
|
}
|
|
21
28
|
export async function finalizeFailedAgencyExecution(context) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type ArtifactType, type CommandEvidence } from "@arcfoundry/schemas";
|
|
2
2
|
import { type OpenCodeStageResult } from "../opencode-runtime/types.js";
|
|
3
|
+
import { type WorkflowProgressReporter } from "../workflow-orchestration/progress.js";
|
|
3
4
|
export type AgencyExecutionOptions = {
|
|
4
5
|
repoRoot: string;
|
|
5
6
|
projectId: string;
|
|
6
7
|
requestId: string;
|
|
7
8
|
clientRequest: string;
|
|
9
|
+
onProgress?: WorkflowProgressReporter;
|
|
8
10
|
};
|
|
9
11
|
export type AgencyExecutionResult = {
|
|
10
12
|
runDir: string;
|
|
@@ -4,6 +4,8 @@ import { type LocalDeliveryStatus } from "./delivery-readiness.js";
|
|
|
4
4
|
export declare class LocalRequestDeliveryPipeline {
|
|
5
5
|
private readonly context;
|
|
6
6
|
private readonly options;
|
|
7
|
+
private reportedCommandCount;
|
|
7
8
|
constructor(context: LocalRunContext, options: LocalAgencyExecutionOptions);
|
|
8
9
|
execute(): Promise<LocalDeliveryStatus>;
|
|
10
|
+
private reportNewCommands;
|
|
9
11
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { writeRequestProject } from "./project-writer.js";
|
|
2
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
2
3
|
import { localDeliveryCommands } from "./delivery-commands.js";
|
|
3
4
|
import { localDeliveryReports } from "./delivery-reports.js";
|
|
4
5
|
import { assessLocalDelivery } from "./delivery-readiness.js";
|
|
@@ -6,6 +7,7 @@ import { localWorkflowStages } from "./workflow-stages.js";
|
|
|
6
7
|
export class LocalRequestDeliveryPipeline {
|
|
7
8
|
context;
|
|
8
9
|
options;
|
|
10
|
+
reportedCommandCount = 0;
|
|
9
11
|
constructor(context, options) {
|
|
10
12
|
this.context = context;
|
|
11
13
|
this.options = options;
|
|
@@ -16,10 +18,14 @@ export class LocalRequestDeliveryPipeline {
|
|
|
16
18
|
const implementation = await writeRequestProject(this.options.repoRoot, this.context.spec);
|
|
17
19
|
await reports.writeImplementation(implementation);
|
|
18
20
|
const commands = localDeliveryCommands(this.context);
|
|
21
|
+
reportWorkflowProgress(this.options.onProgress, { type: "final-gates-started" });
|
|
19
22
|
const installPassed = await commands.runInstall();
|
|
23
|
+
this.reportNewCommands();
|
|
20
24
|
const testsPassed = await commands.runTestAndBuild();
|
|
25
|
+
this.reportNewCommands();
|
|
21
26
|
await reports.writeTest(testsPassed);
|
|
22
27
|
const browserPassed = await commands.runBrowserValidation();
|
|
28
|
+
this.reportNewCommands();
|
|
23
29
|
await reports.writeBrowserValidation({
|
|
24
30
|
acceptanceCriteria,
|
|
25
31
|
browserPassed,
|
|
@@ -30,4 +36,13 @@ export class LocalRequestDeliveryPipeline {
|
|
|
30
36
|
await reports.writeSystemVerification(readiness.status);
|
|
31
37
|
return readiness.status;
|
|
32
38
|
}
|
|
39
|
+
reportNewCommands() {
|
|
40
|
+
for (const command of this.context.commands.slice(this.reportedCommandCount)) {
|
|
41
|
+
reportWorkflowProgress(this.options.onProgress, {
|
|
42
|
+
type: "final-command-completed",
|
|
43
|
+
command,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
this.reportedCommandCount = this.context.commands.length;
|
|
47
|
+
}
|
|
33
48
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ArtifactRunWriter } from "../artifacts/run-writer.js";
|
|
2
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
2
3
|
import { writeLocalStageTranscript } from "./evidence.js";
|
|
3
4
|
export class LocalStageRecorder {
|
|
4
5
|
context;
|
|
@@ -8,6 +9,10 @@ export class LocalStageRecorder {
|
|
|
8
9
|
this.options = options;
|
|
9
10
|
}
|
|
10
11
|
async recordStageAndArtifact(input) {
|
|
12
|
+
reportWorkflowProgress(this.options.onProgress, {
|
|
13
|
+
type: "stage-started",
|
|
14
|
+
stage: { stage: input.stageName, agent: input.agent },
|
|
15
|
+
});
|
|
11
16
|
await writeLocalStageTranscript({
|
|
12
17
|
stages: this.context.agentStages,
|
|
13
18
|
transcriptDir: this.context.paths.transcriptDir,
|
|
@@ -17,6 +22,10 @@ export class LocalStageRecorder {
|
|
|
17
22
|
output: input.output,
|
|
18
23
|
});
|
|
19
24
|
await this.writeArtifacts([this.stageArtifactSpec(input)]);
|
|
25
|
+
reportWorkflowProgress(this.options.onProgress, {
|
|
26
|
+
type: "stage-completed",
|
|
27
|
+
stage: { stage: input.stageName, agent: input.agent },
|
|
28
|
+
});
|
|
20
29
|
}
|
|
21
30
|
async recordStageArtifactSet(specs) {
|
|
22
31
|
for (const spec of specs) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type AgentRole, type CommandEvidence } from "@arcfoundry/schemas";
|
|
2
|
+
import { type WorkflowProgressReporter } from "../workflow-orchestration/progress.js";
|
|
2
3
|
import { type LocalStageOutput } from "./stage-types.js";
|
|
3
4
|
export type LocalAgencyExecutionOptions = {
|
|
4
5
|
repoRoot: string;
|
|
5
6
|
projectId: string;
|
|
6
7
|
requestId: string;
|
|
7
8
|
clientRequest: string;
|
|
9
|
+
onProgress?: WorkflowProgressReporter;
|
|
8
10
|
};
|
|
9
11
|
export type LocalAgentStage = {
|
|
10
12
|
stage: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { writeAgentStageEvidence } from "./agent-stage-evidence.js";
|
|
2
|
+
import { reportWorkflowProgress } from "../workflow-orchestration/progress.js";
|
|
2
3
|
import { LocalRequestDeliveryPipeline } from "./delivery-pipeline.js";
|
|
3
4
|
import { createLocalRunContext } from "./run-context.js";
|
|
4
5
|
import { localWorkflowStages } from "./workflow-stages.js";
|
|
@@ -10,7 +11,9 @@ export class DefaultLocalWorkflowLifecycle {
|
|
|
10
11
|
return createLocalRunContext(options);
|
|
11
12
|
}
|
|
12
13
|
async runConflictGate(context, options) {
|
|
14
|
+
reportWorkflowProgress(options.onProgress, { type: "adr-started" });
|
|
13
15
|
await localWorkflowStages(context, options).writeConflictArtifacts();
|
|
16
|
+
reportWorkflowProgress(options.onProgress, { type: "adr-ready" });
|
|
14
17
|
return context.conflicts.length > 0 ? "blocked" : "continue";
|
|
15
18
|
}
|
|
16
19
|
async executeDelivery(context, options) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { localAgencyExecutionResult } from "./local-request/execution-result.js";
|
|
2
|
+
import { reportWorkflowProgress } from "./workflow-orchestration/progress.js";
|
|
2
3
|
import { localWorkflowLifecycle, } from "./local-request/workflow-phases.js";
|
|
3
4
|
import { GovernedWorkflow } from "./workflow-orchestration/governed-workflow.js";
|
|
4
5
|
export class LocalAgencyWorkflow {
|
|
@@ -9,8 +10,16 @@ export class LocalAgencyWorkflow {
|
|
|
9
10
|
this.lifecycle = dependencies.lifecycle ?? localWorkflowLifecycle();
|
|
10
11
|
}
|
|
11
12
|
async execute() {
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
reportWorkflowProgress(this.options.onProgress, { type: "context-started" });
|
|
14
|
+
const result = await new GovernedWorkflow({
|
|
15
|
+
createContext: async (options) => {
|
|
16
|
+
const context = await this.lifecycle.createContext(options);
|
|
17
|
+
reportWorkflowProgress(options.onProgress, {
|
|
18
|
+
type: "context-ready",
|
|
19
|
+
runDir: context.paths.runDir,
|
|
20
|
+
});
|
|
21
|
+
return context;
|
|
22
|
+
},
|
|
14
23
|
evaluateGovernance: (context, options) => this.lifecycle.runConflictGate(context, options),
|
|
15
24
|
executeDelivery: (context, options) => this.lifecycle.executeDelivery(context, options),
|
|
16
25
|
finalizeDelivery: (context) => this.lifecycle.writeStageEvidence(context),
|
|
@@ -18,6 +27,8 @@ export class LocalAgencyWorkflow {
|
|
|
18
27
|
deliveredStatus: (status) => status,
|
|
19
28
|
result: localAgencyExecutionResult,
|
|
20
29
|
}).execute(this.options);
|
|
30
|
+
reportWorkflowProgress(this.options.onProgress, { type: "completed", status: result.status });
|
|
31
|
+
return result;
|
|
21
32
|
}
|
|
22
33
|
}
|
|
23
34
|
export async function runLocalAgencyExecution(options) {
|
package/dist/request-workflow.js
CHANGED
|
@@ -2,15 +2,24 @@ import { writeAdrRecord, writeConflictReportIfNeeded, } from "./agency-execution
|
|
|
2
2
|
import { createAgencyExecutionContext } from "./agency-execution/execution-context.js";
|
|
3
3
|
import { finalizeAgencyExecution, finalizeFailedAgencyExecution, } from "./agency-execution/finalize.js";
|
|
4
4
|
import { runContractedOpenCodeStages } from "./agency-execution/stage-runner.js";
|
|
5
|
+
import { reportWorkflowProgress } from "./workflow-orchestration/progress.js";
|
|
5
6
|
export async function runAgencyExecution(options) {
|
|
7
|
+
reportWorkflowProgress(options.onProgress, { type: "context-started" });
|
|
6
8
|
const context = await createAgencyExecutionContext(options);
|
|
9
|
+
reportWorkflowProgress(options.onProgress, { type: "context-ready", runDir: context.runDir });
|
|
10
|
+
reportWorkflowProgress(options.onProgress, { type: "adr-started" });
|
|
7
11
|
await writeAdrRecord(context, options);
|
|
12
|
+
reportWorkflowProgress(options.onProgress, { type: "adr-ready" });
|
|
8
13
|
if (await writeConflictReportIfNeeded(context, options)) {
|
|
9
|
-
|
|
14
|
+
const result = await finalizeFailedAgencyExecution(context);
|
|
15
|
+
reportWorkflowProgress(options.onProgress, { type: "completed", status: result.status });
|
|
16
|
+
return result;
|
|
10
17
|
}
|
|
11
18
|
const stageRun = await runContractedOpenCodeStages(context, options);
|
|
12
19
|
if (!stageRun.completed) {
|
|
13
|
-
|
|
20
|
+
const result = await finalizeFailedAgencyExecution(context);
|
|
21
|
+
reportWorkflowProgress(options.onProgress, { type: "completed", status: result.status });
|
|
22
|
+
return result;
|
|
14
23
|
}
|
|
15
24
|
return finalizeAgencyExecution(context, options);
|
|
16
25
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type AgentRole, type CommandEvidence } from "@arcfoundry/schemas";
|
|
2
|
+
export type WorkflowProgressStage = {
|
|
3
|
+
stage: string;
|
|
4
|
+
agent: AgentRole;
|
|
5
|
+
};
|
|
6
|
+
export type WorkflowProgressStageResult = {
|
|
7
|
+
parsingError: string | null;
|
|
8
|
+
};
|
|
9
|
+
export type WorkflowProgressEvent = {
|
|
10
|
+
type: "context-started";
|
|
11
|
+
} | {
|
|
12
|
+
type: "context-ready";
|
|
13
|
+
runDir: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "adr-started";
|
|
16
|
+
} | {
|
|
17
|
+
type: "adr-ready";
|
|
18
|
+
} | {
|
|
19
|
+
type: "stage-started";
|
|
20
|
+
stage: WorkflowProgressStage;
|
|
21
|
+
} | {
|
|
22
|
+
type: "stage-completed";
|
|
23
|
+
stage: WorkflowProgressStage;
|
|
24
|
+
result?: WorkflowProgressStageResult;
|
|
25
|
+
} | {
|
|
26
|
+
type: "stage-failed";
|
|
27
|
+
stage: WorkflowProgressStage;
|
|
28
|
+
result: WorkflowProgressStageResult;
|
|
29
|
+
} | {
|
|
30
|
+
type: "final-gates-started";
|
|
31
|
+
} | {
|
|
32
|
+
type: "final-command-completed";
|
|
33
|
+
command: CommandEvidence;
|
|
34
|
+
} | {
|
|
35
|
+
type: "completed";
|
|
36
|
+
status: "passed" | "failed";
|
|
37
|
+
};
|
|
38
|
+
export type WorkflowProgressReporter = (event: WorkflowProgressEvent) => void;
|
|
39
|
+
export declare function reportWorkflowProgress(reporter: WorkflowProgressReporter | undefined, event: WorkflowProgressEvent): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcfoundry/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Core workflow, governance, artifact, and runtime primitives for Arc Foundry.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"files": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@opencode-ai/sdk": "^1.15.11",
|
|
22
|
-
"@arcfoundry/schemas": "0.2.
|
|
22
|
+
"@arcfoundry/schemas": "0.2.3"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": "^25.9.0"
|