@vimhead.dev/norn-cli 0.1.0-tip.35359392805.1 → 0.1.0-tip.35436871363.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.
- package/assets/README.md +22 -27
- package/assets/docs/README.md +5 -5
- package/assets/docs/agents.md +48 -9
- package/assets/docs/cli.md +7 -7
- package/assets/docs/composition.md +25 -25
- package/assets/docs/persistence.md +34 -23
- package/assets/docs/projects.md +30 -18
- package/assets/docs/providers.md +3 -3
- package/assets/docs/recovery.md +13 -9
- package/assets/docs/schemas.md +1 -1
- package/assets/docs/workflows.md +105 -12
- package/assets/examples/agent-then-analysis/README.md +10 -10
- package/assets/examples/agent-then-analysis/input.json +1 -1
- package/assets/examples/agent-then-analysis/norn.project.json +1 -1
- package/assets/examples/agent-then-analysis/plugin.ts +57 -68
- package/assets/examples/caller-selected-continuation/README.md +15 -14
- package/assets/examples/caller-selected-continuation/caller.ts +37 -38
- package/assets/examples/caller-selected-continuation/input.json +2 -2
- package/assets/examples/caller-selected-continuation/norn.project.json +1 -1
- package/assets/examples/caller-selected-continuation/producer.ts +19 -24
- package/assets/examples/coordinating-multiple-agents/README.md +27 -17
- package/assets/examples/coordinating-multiple-agents/input.json +1 -1
- package/assets/examples/coordinating-multiple-agents/norn.project.json +1 -1
- package/assets/examples/coordinating-multiple-agents/plugin.ts +79 -60
- package/assets/examples/coordinating-multiple-agents/queue-tools.ts +43 -0
- package/assets/examples/coordinating-multiple-agents/work-queue.ts +60 -65
- package/assets/examples/getting-started/README.md +2 -2
- package/assets/examples/getting-started/norn.project.json +1 -1
- package/assets/examples/getting-started/plugin.ts +20 -26
- package/assets/examples/minimal-workflow/README.md +13 -12
- package/assets/examples/minimal-workflow/norn.project.json +1 -1
- package/assets/examples/minimal-workflow/plugin.ts +14 -25
- package/assets/examples/shared-state/README.md +12 -4
- package/assets/examples/shared-state/input.json +1 -1
- package/assets/examples/shared-state/norn.project.json +1 -1
- package/assets/examples/shared-state/plugin.ts +49 -41
- package/assets/examples/shared-state/shared-state.ts +56 -0
- package/assets/examples/shared-state/state-tools.ts +68 -0
- package/assets/examples/worktree-development-loop/README.md +18 -17
- package/assets/examples/worktree-development-loop/norn.project.json +1 -1
- package/assets/examples/worktree-development-loop/plugin.ts +6 -26
- package/assets/examples/worktree-development-loop/scope.ts +4 -0
- package/assets/examples/worktree-development-loop/workflows/development-loop/execute.ts +14 -15
- package/assets/examples/worktree-development-loop/workflows/development-loop/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/development-loop/repository.ts +5 -3
- package/assets/examples/worktree-development-loop/workflows/development-loop/schema.ts +2 -2
- package/assets/examples/worktree-development-loop/workflows/implementation/execute.ts +35 -33
- package/assets/examples/worktree-development-loop/workflows/implementation/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/implementation/schema.ts +6 -3
- package/assets/examples/worktree-development-loop/workflows/planning/execute.ts +27 -16
- package/assets/examples/worktree-development-loop/workflows/planning/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/planning/schema.ts +4 -2
- package/assets/examples/worktree-development-loop/workflows/review/execute.ts +43 -31
- package/assets/examples/worktree-development-loop/workflows/review/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/review/schema.ts +6 -6
- package/assets/examples/worktree-development-loop/workflows/review-router/execute.ts +50 -44
- package/assets/examples/worktree-development-loop/workflows/review-router/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/review-router/schema.ts +5 -5
- package/assets/package.json +1 -1
- package/assets/packages/cli/src/cli.ts +44 -37
- package/assets/packages/cli/src/client.ts +9 -16
- package/assets/packages/cli/src/documentation-intro.ts +1 -1
- package/assets/packages/cli/src/generated-build-info.ts +2 -2
- package/assets/packages/cli/src/internal/agent-response-tool.ts +3 -3
- package/assets/packages/cli/src/internal/agents.ts +24 -32
- package/assets/packages/cli/src/internal/commands.ts +2 -14
- package/assets/packages/cli/src/internal/engine.ts +63 -101
- package/assets/packages/cli/src/internal/errors.ts +4 -4
- package/assets/packages/cli/src/internal/launch-request.ts +6 -6
- package/assets/packages/cli/src/internal/logs.ts +1 -1
- package/assets/packages/cli/src/internal/run-log.ts +1 -1
- package/assets/packages/cli/src/internal/run-state.ts +38 -23
- package/assets/packages/cli/src/internal/run.ts +4 -62
- package/assets/packages/cli/src/internal/worker-directory.ts +17 -0
- package/assets/packages/cli/src/internal/workflow-registry.ts +126 -111
- package/assets/packages/cli/src/internal/working-directory.ts +6 -0
- package/assets/packages/cli/src/workflow-loader.ts +213 -0
- package/assets/packages/core/src/workflow-transition.ts +2 -2
- package/assets/packages/sdk/src/api.ts +141 -329
- package/assets/packages/sdk/src/index.ts +1 -4
- package/assets/packages/sdk/src/schema.ts +3 -3
- package/assets/tests/workflow-ref.test.ts +53 -55
- package/dist/cli.js +41 -35
- package/dist/client.d.ts +3 -4
- package/dist/client.js +3 -8
- package/dist/documentation-intro.js +1 -1
- package/dist/generated-build-info.d.ts +2 -2
- package/dist/generated-build-info.js +2 -2
- package/dist/internal/agent-response-tool.js +3 -3
- package/dist/internal/agents.d.ts +0 -4
- package/dist/internal/agents.js +30 -46
- package/dist/internal/commands.d.ts +0 -4
- package/dist/internal/commands.js +2 -10
- package/dist/internal/engine.d.ts +4 -8
- package/dist/internal/engine.js +57 -84
- package/dist/internal/errors.d.ts +3 -3
- package/dist/internal/errors.js +1 -1
- package/dist/internal/file-coordinator.d.ts +17 -0
- package/dist/internal/file-coordinator.js +162 -0
- package/dist/internal/launch-request.d.ts +4 -4
- package/dist/internal/launch-request.js +2 -2
- package/dist/internal/logs.d.ts +1 -1
- package/dist/internal/run-log.d.ts +1 -1
- package/dist/internal/run-state.d.ts +11 -8
- package/dist/internal/run-state.js +34 -22
- package/dist/internal/run.d.ts +3 -23
- package/dist/internal/run.js +4 -50
- package/dist/internal/worker-directory.d.ts +1 -0
- package/dist/internal/worker-directory.js +26 -0
- package/dist/internal/workflow-registry.d.ts +35 -17
- package/dist/internal/workflow-registry.js +110 -73
- package/dist/internal/working-directory.d.ts +1 -0
- package/dist/internal/working-directory.js +9 -0
- package/dist/{plugin-loader.d.ts → workflow-loader.d.ts} +7 -8
- package/dist/workflow-loader.js +234 -0
- package/package.json +2 -2
- package/assets/docs/resources.md +0 -61
- package/assets/examples/coordinating-multiple-agents/queue-adapter.ts +0 -51
- package/assets/examples/worktree-development-loop/manifest.ts +0 -26
- package/assets/examples/worktree-development-loop/state.ts +0 -23
- package/assets/examples/worktree-development-loop/workflows/development-loop/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/implementation/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/planning/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review-router/declaration.ts +0 -12
- package/assets/packages/cli/src/internal/artifacts.ts +0 -26
- package/assets/packages/cli/src/internal/resource-bindings.ts +0 -35
- package/assets/packages/cli/src/internal/run-resources.ts +0 -23
- package/assets/packages/cli/src/internal/state-store.ts +0 -83
- package/assets/packages/cli/src/plugin-loader.ts +0 -400
- package/assets/packages/cli/src/resources.ts +0 -69
- package/assets/packages/sdk/src/agent-resource-adapter.ts +0 -11
- package/assets/packages/sdk/src/resources.ts +0 -20
- package/assets/packages/sdk/src/state-adapter.ts +0 -75
- package/dist/internal/artifacts.d.ts +0 -10
- package/dist/internal/artifacts.js +0 -29
- package/dist/internal/resource-bindings.d.ts +0 -13
- package/dist/internal/resource-bindings.js +0 -34
- package/dist/internal/run-resources.d.ts +0 -6
- package/dist/internal/run-resources.js +0 -26
- package/dist/internal/state-store.d.ts +0 -23
- package/dist/internal/state-store.js +0 -103
- package/dist/plugin-loader.js +0 -341
- package/dist/resources.d.ts +0 -11
- package/dist/resources.js +0 -100
- /package/assets/packages/{sdk/src/files.ts → cli/src/internal/file-coordinator.ts} +0 -0
|
@@ -1,38 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { reviewWorkflow } from "../review/execute.ts";
|
|
4
|
+
import type { WorkflowResult } from "@vimhead.dev/norn";
|
|
5
|
+
import { developmentLoopScope } from "../../scope.ts";
|
|
6
|
+
import { implementationArgsSchema } from "./schema.ts";
|
|
3
7
|
import { ensureCommandSucceeded } from "../../shared/commands.ts";
|
|
4
|
-
import { implementationAgentResponseSchema
|
|
8
|
+
import { implementationAgentResponseSchema } from "./schema.ts";
|
|
5
9
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
}
|
|
10
|
+
export const implementationWorkflow = developmentLoopScope.workflow({
|
|
11
|
+
id: "implementation",
|
|
12
|
+
isEntrypoint: false,
|
|
13
|
+
instructions: "Apply one implementation pass in the current repository.",
|
|
14
|
+
args: implementationArgsSchema,
|
|
15
|
+
async execute({ args, paths, run }): Promise<WorkflowResult> {
|
|
16
|
+
const repositoryPath = resolve(paths.workspace, args.repositoryPath);
|
|
17
|
+
const plan = await readFile(join(paths.workspace, args.planPath), "utf8");
|
|
18
|
+
const previousReview = args.previousReviewPath ? await readFile(join(paths.workspace, args.previousReviewPath), "utf8") : undefined;
|
|
19
|
+
const implementation = await run.agents.prompt({
|
|
20
|
+
label: `implementation-${args.iteration}`,
|
|
21
|
+
cwd: repositoryPath,
|
|
22
|
+
tools: ["read", "grep", "find", "ls", "edit", "write", "bash"],
|
|
23
|
+
prompt: buildImplementationPrompt(args.task, plan, args.iteration, previousReview),
|
|
24
|
+
response: implementationAgentResponseSchema,
|
|
25
|
+
});
|
|
26
|
+
const status = await run.commands.run({
|
|
27
|
+
label: `implementation-${args.iteration}-status`,
|
|
28
|
+
cwd: repositoryPath,
|
|
29
|
+
command: "git status --short",
|
|
30
|
+
});
|
|
31
|
+
await ensureCommandSucceeded(status);
|
|
32
|
+
const statusOutput = await run.logs.read(status.stdoutLog);
|
|
33
|
+
await mkdir(join(paths.workspace, "implementation"), { recursive: true });
|
|
34
|
+
await writeFile(join(paths.workspace, `implementation/iteration-${args.iteration}-status.txt`), statusOutput);
|
|
35
|
+
return reviewWorkflow({ ...args, implementationSummary: implementation.summary });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
36
38
|
|
|
37
39
|
function buildImplementationPrompt(task: string, plan: string, iteration: number, previousReview: string | undefined): string {
|
|
38
40
|
return [
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { implementationWorkflow } from "./
|
|
2
|
-
export {
|
|
3
|
-
export { implementationAgentResponseSchema, implementationParamsSchema, type ImplementationParams } from "./schema.ts";
|
|
1
|
+
export { implementationWorkflow } from "./execute.ts";
|
|
2
|
+
export { implementationAgentResponseSchema, implementationArgsSchema, type ImplementationArgs } from "./schema.ts";
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { planningArgsSchema } from "../planning/schema.ts";
|
|
1
2
|
import { Type, type StaticDecode } from "typebox";
|
|
2
3
|
|
|
3
|
-
export const
|
|
4
|
-
|
|
4
|
+
export const implementationArgsSchema = Type.Object({
|
|
5
|
+
...planningArgsSchema.properties,
|
|
5
6
|
iteration: Type.Integer({ minimum: 1 }),
|
|
7
|
+
planPath: Type.String(),
|
|
8
|
+
previousReviewPath: Type.Optional(Type.String()),
|
|
6
9
|
});
|
|
7
10
|
|
|
8
11
|
export const implementationAgentResponseSchema = Type.Object({
|
|
9
12
|
summary: Type.String(),
|
|
10
13
|
});
|
|
11
14
|
|
|
12
|
-
export type
|
|
15
|
+
export type ImplementationArgs = StaticDecode<typeof implementationArgsSchema>;
|
|
@@ -1,20 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { implementationWorkflow } from "../implementation/execute.ts";
|
|
4
|
+
import type { WorkflowResult } from "@vimhead.dev/norn";
|
|
5
|
+
import { developmentLoopScope } from "../../scope.ts";
|
|
6
|
+
import { planningArgsSchema } from "./schema.ts";
|
|
7
|
+
import { planningAgentResponseSchema } from "./schema.ts";
|
|
4
8
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
export const planningWorkflow = developmentLoopScope.workflow({
|
|
10
|
+
id: "planning",
|
|
11
|
+
isEntrypoint: false,
|
|
12
|
+
instructions: "Create an implementation plan for a repository task.",
|
|
13
|
+
args: planningArgsSchema,
|
|
14
|
+
async execute({ args, paths, run }): Promise<WorkflowResult> {
|
|
15
|
+
const repositoryPath = resolve(paths.workspace, args.repositoryPath);
|
|
16
|
+
const planning = await run.agents.prompt({
|
|
17
|
+
label: "planning",
|
|
18
|
+
cwd: repositoryPath,
|
|
19
|
+
tools: ["read", "grep", "find", "ls"],
|
|
20
|
+
prompt: buildPlanningPrompt(args.task),
|
|
21
|
+
response: planningAgentResponseSchema,
|
|
22
|
+
});
|
|
23
|
+
const planPath = "planning/plan.md";
|
|
24
|
+
await mkdir(join(paths.workspace, "planning"), { recursive: true });
|
|
25
|
+
await writeFile(join(paths.workspace, planPath), planning.plan);
|
|
26
|
+
return implementationWorkflow({ ...args, planPath, iteration: 1 });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
18
29
|
|
|
19
30
|
function buildPlanningPrompt(task: string): string {
|
|
20
31
|
return [
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { planningWorkflow } from "./
|
|
2
|
-
export {
|
|
3
|
-
export { planningAgentResponseSchema, planningParamsSchema, type PlanningParams } from "./schema.ts";
|
|
1
|
+
export { planningWorkflow } from "./execute.ts";
|
|
2
|
+
export { planningAgentResponseSchema, planningArgsSchema, type PlanningArgs } from "./schema.ts";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Type, type StaticDecode } from "typebox";
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const planningArgsSchema = Type.Object({
|
|
4
4
|
task: Type.String(),
|
|
5
|
+
repositoryPath: Type.String(),
|
|
6
|
+
maxIterations: Type.Integer({ minimum: 1, maximum: 10 }),
|
|
5
7
|
});
|
|
6
8
|
|
|
7
9
|
export const planningAgentResponseSchema = Type.Object({
|
|
@@ -9,4 +11,4 @@ export const planningAgentResponseSchema = Type.Object({
|
|
|
9
11
|
summary: Type.String(),
|
|
10
12
|
});
|
|
11
13
|
|
|
12
|
-
export type
|
|
14
|
+
export type PlanningArgs = StaticDecode<typeof planningArgsSchema>;
|
|
@@ -1,36 +1,48 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { reviewRouterWorkflow } from "../review-router/execute.ts";
|
|
4
|
+
import type { WorkflowResult } from "@vimhead.dev/norn";
|
|
5
|
+
import { developmentLoopScope } from "../../scope.ts";
|
|
6
|
+
import { reviewArgsSchema } from "./schema.ts";
|
|
3
7
|
import { ensureCommandSucceeded } from "../../shared/commands.ts";
|
|
4
|
-
import { reviewAgentResponseSchema
|
|
8
|
+
import { reviewAgentResponseSchema } from "./schema.ts";
|
|
5
9
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
10
|
+
export const reviewWorkflow = developmentLoopScope.workflow({
|
|
11
|
+
id: "review",
|
|
12
|
+
isEntrypoint: false,
|
|
13
|
+
instructions: "Review the current repository boundary changes.",
|
|
14
|
+
args: reviewArgsSchema,
|
|
15
|
+
async execute({ args, paths, run }): Promise<WorkflowResult> {
|
|
16
|
+
const repositoryPath = resolve(paths.workspace, args.repositoryPath);
|
|
17
|
+
const implementationSummary = args.implementationSummary;
|
|
18
|
+
const plan = await readFile(join(paths.workspace, args.planPath), "utf8");
|
|
19
|
+
const diff = await run.commands.run({
|
|
20
|
+
label: `review-${args.iteration}-diff`,
|
|
21
|
+
cwd: repositoryPath,
|
|
22
|
+
command: "git status --short && git diff --stat HEAD -- . && git diff HEAD -- .",
|
|
23
|
+
});
|
|
24
|
+
await ensureCommandSucceeded(diff);
|
|
25
|
+
const diffOutput = await run.logs.read(diff.stdoutLog);
|
|
26
|
+
await mkdir(join(paths.workspace, "review"), { recursive: true });
|
|
27
|
+
await writeFile(join(paths.workspace, `review/iteration-${args.iteration}-diff.txt`), diffOutput);
|
|
28
|
+
const review = await run.agents.prompt({
|
|
29
|
+
label: `review-${args.iteration}`,
|
|
30
|
+
cwd: repositoryPath,
|
|
31
|
+
tools: ["read", "grep", "find", "ls", "bash"],
|
|
32
|
+
prompt: buildReviewPrompt(args.task, plan, implementationSummary, diffOutput),
|
|
33
|
+
response: reviewAgentResponseSchema,
|
|
34
|
+
});
|
|
35
|
+
const automatedReviewPath = `review/iteration-${args.iteration}-automated.json`;
|
|
36
|
+
await writeFile(join(paths.workspace, automatedReviewPath), JSON.stringify(review, null, 2));
|
|
37
|
+
return reviewRouterWorkflow({
|
|
38
|
+
...args,
|
|
39
|
+
iteration: args.iteration,
|
|
40
|
+
decision: review.decision,
|
|
41
|
+
summary: review.summary,
|
|
42
|
+
automatedReviewPath,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
34
46
|
|
|
35
47
|
function buildReviewPrompt(task: string, plan: string, implementationSummary: string, diff: string): string {
|
|
36
48
|
return [
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export { reviewWorkflow } from "./
|
|
2
|
-
export { executeReviewWorkflow } from "./execute.ts";
|
|
1
|
+
export { reviewWorkflow } from "./execute.ts";
|
|
3
2
|
export {
|
|
4
3
|
reviewAgentResponseSchema,
|
|
5
4
|
reviewDecisionSchema,
|
|
6
|
-
|
|
5
|
+
reviewArgsSchema,
|
|
7
6
|
storedReviewSchema,
|
|
8
|
-
type
|
|
7
|
+
type ReviewArgs,
|
|
9
8
|
type StoredReview,
|
|
10
9
|
} from "./schema.ts";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { implementationArgsSchema } from "../implementation/schema.ts";
|
|
2
2
|
import { Type, type StaticDecode } from "typebox";
|
|
3
3
|
|
|
4
4
|
export const reviewDecisionSchema = Type.Enum(["accept", "revise", "blocked"]);
|
|
5
5
|
|
|
6
|
-
export const
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export const reviewArgsSchema = Type.Object({
|
|
7
|
+
...implementationArgsSchema.properties,
|
|
8
|
+
implementationSummary: Type.String(),
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
export const reviewAgentResponseSchema = Type.Object({
|
|
@@ -16,8 +16,8 @@ export const reviewAgentResponseSchema = Type.Object({
|
|
|
16
16
|
export const storedReviewSchema = Type.Object({
|
|
17
17
|
decision: reviewDecisionSchema,
|
|
18
18
|
summary: Type.String(),
|
|
19
|
-
|
|
19
|
+
reviewPath: Type.String(),
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
export type
|
|
22
|
+
export type ReviewArgs = StaticDecode<typeof reviewArgsSchema>;
|
|
23
23
|
export type StoredReview = StaticDecode<typeof storedReviewSchema>;
|
|
@@ -1,51 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { implementationWorkflow } from "../implementation/execute.ts";
|
|
4
|
+
import type { WorkflowResult } from "@vimhead.dev/norn";
|
|
5
|
+
import { developmentLoopScope } from "../../scope.ts";
|
|
6
|
+
import { reviewRouterArgsSchema } from "./schema.ts";
|
|
3
7
|
import type { StoredReview } from "../review/schema.ts";
|
|
4
|
-
import type { ReviewRouterParams } from "./schema.ts";
|
|
5
8
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
export const reviewRouterWorkflow = developmentLoopScope.workflow({
|
|
10
|
+
id: "reviewRouter",
|
|
11
|
+
isEntrypoint: false,
|
|
12
|
+
instructions: "Route implementation and review iterations based on the latest review decision.",
|
|
13
|
+
gate: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
describe: ({ args }) => `Review iteration ${args.iteration}. Confirm or edit the automated decision before continuing. Plan: ${args.planPath}.`,
|
|
16
|
+
fields: ["decision", "summary"] as const,
|
|
17
|
+
},
|
|
18
|
+
args: reviewRouterArgsSchema,
|
|
19
|
+
async execute({ args, paths, run }): Promise<WorkflowResult> {
|
|
20
|
+
const repositoryPath = args.repositoryPath;
|
|
21
|
+
const planPath = args.planPath;
|
|
22
|
+
const currentIteration = args.iteration;
|
|
23
|
+
const maxIterations = args.maxIterations;
|
|
24
|
+
const task = args.task;
|
|
25
|
+
const reviewPath = `review/iteration-${args.iteration}-decision.json`;
|
|
26
|
+
await mkdir(join(paths.workspace, "review"), { recursive: true });
|
|
27
|
+
await writeFile(
|
|
28
|
+
join(paths.workspace, reviewPath),
|
|
29
|
+
JSON.stringify({ decision: args.decision, summary: args.summary, automatedReviewPath: args.automatedReviewPath }, null, 2),
|
|
30
|
+
);
|
|
31
|
+
const lastReview: StoredReview = { decision: args.decision, summary: args.summary, reviewPath };
|
|
20
32
|
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
if (args.decision === "accept") {
|
|
34
|
+
return run.complete({
|
|
35
|
+
summary: `Implementation accepted after ${currentIteration} iteration(s).`,
|
|
36
|
+
data: { status: "done", repositoryPath, planPath, reviewPath, iterations: currentIteration, lastReview },
|
|
37
|
+
});
|
|
38
|
+
}
|
|
23
39
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
}
|
|
40
|
+
if (args.decision === "blocked") {
|
|
41
|
+
return run.fail({
|
|
42
|
+
summary: args.summary,
|
|
43
|
+
data: { status: "blocked", repositoryPath, planPath, reviewPath, iterations: currentIteration, lastReview },
|
|
44
|
+
});
|
|
45
|
+
}
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
}
|
|
47
|
+
if (currentIteration >= maxIterations) {
|
|
48
|
+
return run.fail({
|
|
49
|
+
summary: `Maximum iteration count reached after ${currentIteration} iteration(s).`,
|
|
50
|
+
data: { status: "needs-attention", repositoryPath, planPath, reviewPath, iterations: currentIteration, lastReview },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
return
|
|
42
|
-
summary: `Maximum iteration count reached after ${currentIteration} iteration(s).`,
|
|
43
|
-
artifacts: { plan: planArtifact, review: reviewArtifact },
|
|
44
|
-
data: { status: "needs-attention", repositoryPath, iterations: currentIteration, lastReview },
|
|
45
|
-
});
|
|
54
|
+
const nextIteration = currentIteration + 1;
|
|
55
|
+
return implementationWorkflow({ task, repositoryPath, maxIterations, planPath, iteration: nextIteration, previousReviewPath: reviewPath });
|
|
46
56
|
}
|
|
47
|
-
|
|
48
|
-
const nextIteration = currentIteration + 1;
|
|
49
|
-
await run.state.set(worktreeDevelopmentLoopManifest.states.developmentLoop.currentIteration, nextIteration);
|
|
50
|
-
return worktreeDevelopmentLoopManifest.workflows.implementation({ task, iteration: nextIteration });
|
|
51
|
-
}
|
|
57
|
+
});
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { reviewRouterWorkflow } from "./
|
|
2
|
-
export {
|
|
3
|
-
export { reviewRouterParamsSchema, type ReviewRouterParams } from "./schema.ts";
|
|
1
|
+
export { reviewRouterWorkflow } from "./execute.ts";
|
|
2
|
+
export { reviewRouterArgsSchema, type ReviewRouterArgs } from "./schema.ts";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { implementationArgsSchema } from "../implementation/schema.ts";
|
|
2
2
|
import { Type, type StaticDecode } from "typebox";
|
|
3
3
|
import { reviewDecisionSchema } from "../review/schema.ts";
|
|
4
4
|
|
|
5
|
-
export const
|
|
6
|
-
|
|
5
|
+
export const reviewRouterArgsSchema = Type.Object({
|
|
6
|
+
...implementationArgsSchema.properties,
|
|
7
7
|
decision: reviewDecisionSchema,
|
|
8
8
|
summary: Type.String(),
|
|
9
|
-
|
|
9
|
+
automatedReviewPath: Type.String(),
|
|
10
10
|
});
|
|
11
11
|
|
|
12
|
-
export type
|
|
12
|
+
export type ReviewRouterArgs = StaticDecode<typeof reviewRouterArgsSchema>;
|
package/assets/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.1.0-tip.
|
|
1
|
+
{"version":"0.1.0-tip.35436871363.1"}
|