@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
|
@@ -25,9 +25,9 @@ function assertWorkflowReferenceAnnotations(schema: unknown): void {
|
|
|
25
25
|
if (!isPlainObject(schema)) return;
|
|
26
26
|
if (Object.hasOwn(schema, "x-norn-workflow-ref")) {
|
|
27
27
|
const annotation = schema["x-norn-workflow-ref"];
|
|
28
|
-
if (!isPlainObject(annotation) || !Object.hasOwn(annotation, "
|
|
29
|
-
Value.Assert(Meta["https://json-schema.org/draft/2020-12/schema"], annotation.
|
|
30
|
-
assertWorkflowReferenceAnnotations(annotation.
|
|
28
|
+
if (!isPlainObject(annotation) || !Object.hasOwn(annotation, "contributedArgsSchema")) throw new Error("Invalid workflow reference annotation");
|
|
29
|
+
Value.Assert(Meta["https://json-schema.org/draft/2020-12/schema"], annotation.contributedArgsSchema);
|
|
30
|
+
assertWorkflowReferenceAnnotations(annotation.contributedArgsSchema);
|
|
31
31
|
}
|
|
32
32
|
for (const keyword of ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"]) {
|
|
33
33
|
const schemas = schema[keyword];
|
|
@@ -1,39 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { workflow, isWorkflowDeclaration, workflowRefSchema, type NornWorkflowRefSchemaOptions } from "@vimhead.dev/norn";
|
|
2
2
|
import { inspectSchema } from "@vimhead.dev/norn/schema";
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { Value } from "typebox/value";
|
|
6
6
|
import { expect, expectTypeOf, test } from "vitest";
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
id: "refs",
|
|
8
|
+
const target = workflow({
|
|
9
|
+
id: "refs.finish", isEntrypoint: false, args: Type.Object({ report: Type.String() }),
|
|
10
|
+
execute() { throw new Error("A callable must select a transition, not execute it"); },
|
|
10
11
|
});
|
|
11
|
-
const target = manifest.workflows.finish;
|
|
12
12
|
|
|
13
13
|
test("callable declarations retain metadata and construct transitions without execution", () => {
|
|
14
14
|
expectTypeOf(target.id).toEqualTypeOf<"refs.finish">();
|
|
15
15
|
assert.equal(isWorkflowDeclaration(target), true);
|
|
16
|
-
assert.equal(isWorkflowPluginManifest(manifest), true);
|
|
17
16
|
assert.equal(isWorkflowDeclaration(() => undefined), false);
|
|
18
|
-
assert.equal(Value.Check(target.
|
|
19
|
-
assert.deepEqual(target.
|
|
20
|
-
assert.deepEqual(target({ report: "done" }), { type: "next", workflowId: target.id, params: { report: "done" } });
|
|
17
|
+
assert.equal(Value.Check(target.args, { report: "done" }), true);
|
|
18
|
+
assert.deepEqual(target({ report: "done" }), { type: "next", workflowId: target.id, args: { report: "done" } });
|
|
21
19
|
});
|
|
22
20
|
|
|
23
21
|
for (const reference of ["refs.finish", target.id]) {
|
|
24
22
|
test("workflow references decode into contribution-taking transition builders", () => {
|
|
25
23
|
const contributions = Type.Object({ report: Type.String() });
|
|
26
|
-
const options: NornWorkflowRefSchemaOptions<typeof contributions> = {
|
|
24
|
+
const options: NornWorkflowRefSchemaOptions<typeof contributions> = { args: contributions };
|
|
27
25
|
const schema = workflowRefSchema(options);
|
|
28
|
-
assert.deepEqual(Value.Decode(workflowRefSchema({}), reference)({}), { type: "next", workflowId: "refs.finish",
|
|
26
|
+
assert.deepEqual(Value.Decode(workflowRefSchema({}), reference)({}), { type: "next", workflowId: "refs.finish", args: {} });
|
|
29
27
|
interface Report { report: string }
|
|
30
28
|
const report: Report = { report: "done" };
|
|
31
29
|
assert.deepEqual(Value.Decode(schema, reference)(report), target(report));
|
|
32
|
-
const input = { workflow: reference,
|
|
30
|
+
const input = { workflow: reference, forwardArgs: { task: "retain", report: "stale" } };
|
|
33
31
|
const next = Value.Decode(schema, input);
|
|
34
|
-
assert.deepEqual(next({ report: "done" }), { type: "next", workflowId: reference,
|
|
35
|
-
assert.deepEqual(next({ report: "again" }).
|
|
36
|
-
assert.deepEqual(input.
|
|
32
|
+
assert.deepEqual(next({ report: "done" }), { type: "next", workflowId: reference, args: { task: "retain", report: "done" } });
|
|
33
|
+
assert.deepEqual(next({ report: "again" }).args, { task: "retain", report: "again" });
|
|
34
|
+
assert.deepEqual(input.forwardArgs, { task: "retain", report: "stale" });
|
|
37
35
|
assert.throws(() => Reflect.apply(next, undefined, [{}]));
|
|
38
36
|
});
|
|
39
37
|
}
|
|
@@ -46,7 +44,7 @@ test("nullable reference inputs retain their required property and input union",
|
|
|
46
44
|
assert.equal(Value.Check(schema, { next: null }), true);
|
|
47
45
|
assert.equal(Value.Check(schema, { next: "refs.finish" }), true);
|
|
48
46
|
expect(inspected).toHaveProperty("properties.next.anyOf.0.anyOf.0.type", "string");
|
|
49
|
-
expect(inspected).toHaveProperty("properties.next.anyOf.0.anyOf.1.required", ["workflow", "
|
|
47
|
+
expect(inspected).toHaveProperty("properties.next.anyOf.0.anyOf.1.required", ["workflow", "forwardArgs"]);
|
|
50
48
|
});
|
|
51
49
|
|
|
52
50
|
test("optional reference properties remain optional in validation and inspection", () => {
|
|
@@ -58,39 +56,39 @@ test("optional reference properties remain optional in validation and inspection
|
|
|
58
56
|
test("inspection advertises encoded contributions and invocation does not decode them", () => {
|
|
59
57
|
let decodes = 0;
|
|
60
58
|
const contributions = Type.Object({
|
|
61
|
-
records:
|
|
59
|
+
records: Type.String(),
|
|
62
60
|
count: Type.Decode(Type.String(), value => { decodes++; return Number(value); }),
|
|
63
61
|
label: Type.Optional(Type.String({ default: "collected" })),
|
|
64
62
|
});
|
|
65
|
-
const reference = Type.With(workflowRefSchema({
|
|
63
|
+
const reference = Type.With(workflowRefSchema({ args: contributions }), { description: "Continue with the collected records" });
|
|
66
64
|
const schema = Type.Object({ next: reference });
|
|
67
65
|
const inspected = inspectSchema(schema);
|
|
68
|
-
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.
|
|
66
|
+
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.contributedArgsSchema", inspectSchema(contributions));
|
|
69
67
|
expect(inspected).toHaveProperty("properties.next.description", "Continue with the collected records");
|
|
70
68
|
expect(inspected).toHaveProperty("properties.next.anyOf", inspectSchema(workflowRefSchema()).anyOf);
|
|
71
|
-
expect(inspected).toHaveProperty("properties.next.anyOf.1.properties.
|
|
72
|
-
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.
|
|
73
|
-
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.
|
|
74
|
-
const
|
|
75
|
-
const next = Value.Decode(schema, { next: { workflow: "refs.finish",
|
|
76
|
-
const contribution = { records:
|
|
77
|
-
assert.deepEqual(next(contribution).
|
|
69
|
+
expect(inspected).toHaveProperty("properties.next.anyOf.1.properties.forwardArgs.patternProperties", { "^.*$": {} });
|
|
70
|
+
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.contributedArgsSchema.required", ["records", "count"]);
|
|
71
|
+
expect(inspected).toHaveProperty("properties.next.x-norn-workflow-ref.contributedArgsSchema.properties.count.type", "string");
|
|
72
|
+
const forwardArgs = { taskId: "task-42", nested: { labels: ["one", "two"], enabled: false, absent: null } };
|
|
73
|
+
const next = Value.Decode(schema, { next: { workflow: "refs.finish", forwardArgs } }).next;
|
|
74
|
+
const contribution = { records: "records.json", count: "2" };
|
|
75
|
+
assert.deepEqual(next(contribution).args, { ...forwardArgs, ...contribution });
|
|
78
76
|
assert.equal(decodes, 0);
|
|
79
|
-
assert.throws(() => Reflect.apply(next, undefined, [{ records:
|
|
77
|
+
assert.throws(() => Reflect.apply(next, undefined, [{ records: "records.json", count: 2 }]));
|
|
80
78
|
});
|
|
81
79
|
|
|
82
80
|
test("references without contributions advertise an empty object schema", () => {
|
|
83
81
|
const reference = workflowRefSchema();
|
|
84
|
-
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.
|
|
85
|
-
assert.deepEqual(Value.Decode(reference, "refs.finish")({}), { type: "next", workflowId: "refs.finish",
|
|
82
|
+
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.contributedArgsSchema", inspectSchema(Type.Object({})));
|
|
83
|
+
assert.deepEqual(Value.Decode(reference, "refs.finish")({}), { type: "next", workflowId: "refs.finish", args: {} });
|
|
86
84
|
});
|
|
87
85
|
|
|
88
86
|
test("optional, nullable and array references retain annotations and callable codecs", () => {
|
|
89
|
-
const reference = workflowRefSchema({
|
|
87
|
+
const reference = workflowRefSchema({ args: Type.Object({ report: Type.String() }) });
|
|
90
88
|
const schema = Type.Object({ optional: Type.Optional(reference), nullable: Type.Union([reference, Type.Null()]), many: Type.Array(reference) });
|
|
91
89
|
const inspected = inspectSchema(schema);
|
|
92
90
|
for (const path of ["properties.optional", "properties.nullable.anyOf.0", "properties.many.items"]) {
|
|
93
|
-
expect(inspected).toHaveProperty(`${path}.x-norn-workflow-ref.
|
|
91
|
+
expect(inspected).toHaveProperty(`${path}.x-norn-workflow-ref.contributedArgsSchema`, inspectSchema(Type.Object({ report: Type.String() })));
|
|
94
92
|
}
|
|
95
93
|
assert.deepEqual(inspected.required, ["nullable", "many"]);
|
|
96
94
|
const decoded = Value.Decode(schema, { nullable: null, many: ["refs.finish"], optional: "refs.finish" });
|
|
@@ -101,56 +99,56 @@ test("optional, nullable and array references retain annotations and callable co
|
|
|
101
99
|
|
|
102
100
|
test("nested references retain encoded payloads in contributed parameters", () => {
|
|
103
101
|
const finalContributions = Type.Object({ summary: Type.String() });
|
|
104
|
-
const contributions = Type.Object({ records:
|
|
105
|
-
const reference = workflowRefSchema({
|
|
106
|
-
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.
|
|
107
|
-
const
|
|
108
|
-
const transition = Value.Decode(reference, "intermediate")(
|
|
109
|
-
assert.deepEqual(transition.
|
|
110
|
-
assert.deepEqual(Value.Decode(contributions, transition.
|
|
102
|
+
const contributions = Type.Object({ records: Type.String(), next: workflowRefSchema({ args: finalContributions }) });
|
|
103
|
+
const reference = workflowRefSchema({ args: contributions });
|
|
104
|
+
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.contributedArgsSchema.properties.next.x-norn-workflow-ref.contributedArgsSchema", inspectSchema(finalContributions));
|
|
105
|
+
const args = { records: "records.json", next: { workflow: "refs.finish", forwardArgs: { batch: 1 } } };
|
|
106
|
+
const transition = Value.Decode(reference, "intermediate")(args);
|
|
107
|
+
assert.deepEqual(transition.args, args);
|
|
108
|
+
assert.deepEqual(Value.Decode(contributions, transition.args).next({ summary: "done" }).args, { batch: 1, summary: "done" });
|
|
111
109
|
});
|
|
112
110
|
|
|
113
111
|
test("recursive contributions use native TypeBox definitions", () => {
|
|
114
112
|
const contributions = Type.Cyclic({ Contribution: Type.Object({ label: Type.String(), children: Type.Array(Type.Ref("Contribution")) }) }, "Contribution");
|
|
115
|
-
const reference = workflowRefSchema({
|
|
116
|
-
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.
|
|
117
|
-
const
|
|
118
|
-
assert.deepEqual(Value.Decode(reference, "refs.finish")(
|
|
113
|
+
const reference = workflowRefSchema({ args: contributions });
|
|
114
|
+
expect(inspectSchema(reference)).toHaveProperty("x-norn-workflow-ref.contributedArgsSchema", inspectSchema(contributions));
|
|
115
|
+
const args = { label: "root", children: [{ label: "leaf", children: [] }] };
|
|
116
|
+
assert.deepEqual(Value.Decode(reference, "refs.finish")(args).args, args);
|
|
119
117
|
});
|
|
120
118
|
|
|
121
119
|
test("object-valued unions, records, intersections and root codecs can contribute", () => {
|
|
122
|
-
const union = workflowRefSchema({
|
|
123
|
-
assert.deepEqual(Value.Decode(union, "target")({ kind: "error", reason: "failed" }).
|
|
124
|
-
const record = workflowRefSchema({
|
|
125
|
-
assert.deepEqual(Value.Decode(record, "target")({ first: 1 }).
|
|
126
|
-
const intersection = workflowRefSchema({
|
|
127
|
-
assert.deepEqual(Value.Decode(intersection, "target")({ left: "x", right: 2 }).
|
|
128
|
-
const codec = workflowRefSchema({
|
|
129
|
-
assert.deepEqual(Value.Decode(codec, "target")({ text: "encoded" }).
|
|
130
|
-
const unknown = Value.Decode(workflowRefSchema({
|
|
120
|
+
const union = workflowRefSchema({ args: Type.Union([Type.Object({ kind: Type.Literal("ok"), report: Type.String() }), Type.Object({ kind: Type.Literal("error"), reason: Type.String() })]) });
|
|
121
|
+
assert.deepEqual(Value.Decode(union, "target")({ kind: "error", reason: "failed" }).args, { kind: "error", reason: "failed" });
|
|
122
|
+
const record = workflowRefSchema({ args: Type.Record(Type.String(), Type.Integer()) });
|
|
123
|
+
assert.deepEqual(Value.Decode(record, "target")({ first: 1 }).args, { first: 1 });
|
|
124
|
+
const intersection = workflowRefSchema({ args: Type.Intersect([Type.Object({ left: Type.String() }), Type.Object({ right: Type.Integer() })]) });
|
|
125
|
+
assert.deepEqual(Value.Decode(intersection, "target")({ left: "x", right: 2 }).args, { left: "x", right: 2 });
|
|
126
|
+
const codec = workflowRefSchema({ args: Type.Decode(Type.Object({ text: Type.String() }), value => value.text) });
|
|
127
|
+
assert.deepEqual(Value.Decode(codec, "target")({ text: "encoded" }).args, { text: "encoded" });
|
|
128
|
+
const unknown = Value.Decode(workflowRefSchema({ args: Type.Unknown() }), "target");
|
|
131
129
|
for (const value of [null, [], "text", 1]) assert.throws(() => Reflect.apply(unknown, undefined, [value]), /contributions must be objects/);
|
|
132
130
|
for (const value of [new Date(), { callback: () => undefined }]) assert.throws(() => Reflect.apply(unknown, undefined, [value]));
|
|
133
131
|
});
|
|
134
132
|
|
|
135
133
|
test("non-JSON contributions fail explicit inspection without preventing construction", () => {
|
|
136
|
-
const reference = workflowRefSchema({
|
|
134
|
+
const reference = workflowRefSchema({ args: Type.BigInt() });
|
|
137
135
|
assert.equal(typeof Value.Decode(reference, "refs.finish"), "function");
|
|
138
136
|
assert.throws(() => inspectSchema(reference));
|
|
139
|
-
const nested = workflowRefSchema({
|
|
137
|
+
const nested = workflowRefSchema({ args: Type.Object({ next: reference }) });
|
|
140
138
|
assert.throws(() => inspectSchema(Type.Object({ next: Type.Optional(Type.Array(nested)) })));
|
|
141
139
|
});
|
|
142
140
|
|
|
143
141
|
test("inspection traverses schema positions, not defaults, examples or property-name maps", () => {
|
|
144
|
-
const payload = { "x-norn-workflow-ref": {
|
|
142
|
+
const payload = { "x-norn-workflow-ref": { contributedArgsSchema: { type: "bigint" } } };
|
|
145
143
|
const schema = Type.Object({ "x-norn-workflow-ref": Type.String() }, { default: payload, examples: [payload] });
|
|
146
144
|
assert.doesNotThrow(() => inspectSchema(schema));
|
|
147
|
-
const invalid = workflowRefSchema({
|
|
145
|
+
const invalid = workflowRefSchema({ args: Type.BigInt() });
|
|
148
146
|
for (const wrapper of [Type.Record(Type.String(), invalid), Type.Tuple([invalid]), Type.Object({}, { additionalProperties: invalid }), Type.Cyclic({ Root: Type.Object({ child: invalid }) }, "Root")]) {
|
|
149
147
|
assert.throws(() => inspectSchema(wrapper));
|
|
150
148
|
}
|
|
151
149
|
});
|
|
152
150
|
|
|
153
|
-
for (const input of [undefined, null, "", 3, {}, { workflow: "refs.finish" }, { workflow: "",
|
|
151
|
+
for (const input of [undefined, null, "", 3, {}, { workflow: "refs.finish" }, { workflow: "", forwardArgs: {} }, { workflow: "refs.finish", forwardArgs: null }, { workflow: target, forwardArgs: {} }]) {
|
|
154
152
|
test(`reference input schema rejects invalid shape without coercion: ${JSON.stringify(input)}`, () => {
|
|
155
153
|
assert.equal(Value.Check(workflowRefSchema(), input), false);
|
|
156
154
|
});
|
package/dist/cli.js
CHANGED
|
@@ -18,14 +18,16 @@ import { Value } from "typebox/value";
|
|
|
18
18
|
import { NORN_BUILD_INFO } from "./build-info.js";
|
|
19
19
|
import { renderNornDocumentationIntro, resolveDocumentationCacheRoot, resolveNornDocumentation } from "./documentation.js";
|
|
20
20
|
import { NornEngine } from "./internal/engine.js";
|
|
21
|
+
import { resolveNornAgentDirectory } from "./internal/agent-directory.js";
|
|
21
22
|
import { errorMessage, NornProjectLoadError, NornRunStoppedError } from "./internal/errors.js";
|
|
22
23
|
import { clearRunResumeRequest, readRunLaunchRequest, readRunResumeRequest, writeRunLaunchRequest, writeRunResumeRequest } from "./internal/launch-request.js";
|
|
23
24
|
import { readRunMetrics } from "./internal/metrics.js";
|
|
24
25
|
import { getRunLeaseOwner, NornRunLease } from "./internal/run-lease.js";
|
|
25
26
|
import { generateRunName } from "./internal/run-names.js";
|
|
26
|
-
import { getRunInfo, listRuns,
|
|
27
|
+
import { assertRunVersion, getRunInfo, listRuns, mergeInterruptedWorkflowArgs, resolveRunRoot } from "./internal/run-state.js";
|
|
27
28
|
import { NornRunStore } from "./internal/run-store.js";
|
|
28
|
-
import {
|
|
29
|
+
import { prepareRunWorkerDirectory } from "./internal/worker-directory.js";
|
|
30
|
+
import { discoverNornProject, findNornProject, inspectNornWorkflow, loadNornProject, NORN_PROJECT_FILE_NAME } from "./workflow-loader.js";
|
|
29
31
|
var RUNS_ROOT = join(".norn", "runs");
|
|
30
32
|
var RUN_WAIT_INTERVAL_MS = 1e3;
|
|
31
33
|
var CLI_DESCRIPTION = "Norn is a harness-agnostic runtime for agent-driven and code-driven workflows, built primarily for agents. Build workflows with the Norn SDK; use this JSON-native CLI to discover workflows, start or resume runs, inspect evidence, and manage the installed runtime.";
|
|
@@ -112,9 +114,9 @@ var COMMANDS = [
|
|
|
112
114
|
{
|
|
113
115
|
id: "project.inspect",
|
|
114
116
|
path: ["project", "inspect"],
|
|
115
|
-
description: "Use when discovering the active Norn project,
|
|
117
|
+
description: "Use when discovering the active Norn project, configuration, and workflow sources.",
|
|
116
118
|
usage: "norn project inspect",
|
|
117
|
-
output: "JSON object with project metadata under project, isComplete, and
|
|
119
|
+
output: "JSON object with project metadata under project, isComplete, and registration diagnostics. Incomplete discovery does not permit execution.",
|
|
118
120
|
examples: ["norn project inspect"],
|
|
119
121
|
execute: async (args) => {
|
|
120
122
|
assertNoExtraArgs("project inspect", args);
|
|
@@ -127,17 +129,17 @@ var COMMANDS = [
|
|
|
127
129
|
description: "Use when selecting a Norn workflow for a user task; defaults to entrypoint workflows.",
|
|
128
130
|
usage: "norn workflows list [--entrypoints|--all]",
|
|
129
131
|
options: ["--entrypoints: list entrypoint workflows", "--all: include internal workflow steps"],
|
|
130
|
-
output: "JSON object with workflow summaries under workflows, isComplete, and
|
|
132
|
+
output: "JSON object with workflow summaries under workflows, isComplete, and registration diagnostics. Successful discovery can be incomplete; start/resume remain strict.",
|
|
131
133
|
examples: ["norn workflows list", "norn workflows list --all"],
|
|
132
134
|
execute: listWorkflows
|
|
133
135
|
},
|
|
134
136
|
{
|
|
135
137
|
id: "workflows.inspect",
|
|
136
138
|
path: ["workflows", "inspect"],
|
|
137
|
-
description: "Use when reading a workflow's instructions,
|
|
139
|
+
description: "Use when reading a workflow's instructions, args schema, gate contract, and registration source before starting or editing it.",
|
|
138
140
|
usage: "norn workflows inspect <workflow-id>",
|
|
139
141
|
arguments: ["workflow-id: fully qualified workflow id"],
|
|
140
|
-
output: "JSON object with workflow details, isComplete, and
|
|
142
|
+
output: "JSON object with workflow details, isComplete, and registration diagnostics. workflow is null if unavailable in an incomplete catalog or its schema cannot be inspected; an unknown id in a complete catalog is an error.",
|
|
141
143
|
examples: ["norn workflows inspect example.plan"],
|
|
142
144
|
execute: async (args) => {
|
|
143
145
|
const workflowId = requiredArg("workflows inspect", args, 0, "workflow id");
|
|
@@ -148,12 +150,12 @@ var COMMANDS = [
|
|
|
148
150
|
{
|
|
149
151
|
id: "runs.start",
|
|
150
152
|
path: ["runs", "start"],
|
|
151
|
-
description: "Use when starting a Norn workflow run after the workflow id and
|
|
153
|
+
description: "Use when starting a Norn workflow run after the workflow id and args are known.",
|
|
152
154
|
usage: "norn runs start <workflow-id>",
|
|
153
155
|
arguments: ["workflow-id: fully qualified workflow id to start"],
|
|
154
|
-
stdin: 'Optional JSON object: {"
|
|
156
|
+
stdin: 'Optional JSON object: {"args":{...},"config":{"workflowOrScopeId":{...}}}.',
|
|
155
157
|
output: "JSON object with started run info under run.",
|
|
156
|
-
examples: [`printf '{"
|
|
158
|
+
examples: [`printf '{"args":{"task":"Add tests"}}' | norn runs start example.plan`],
|
|
157
159
|
execute: async (args) => {
|
|
158
160
|
const workflowId = requiredArg("runs start", args, 0, "workflow id");
|
|
159
161
|
await startRun(workflowId, args.slice(1));
|
|
@@ -165,9 +167,9 @@ var COMMANDS = [
|
|
|
165
167
|
description: "Use when resuming an interrupted gate or a checkpoint restored for retry.",
|
|
166
168
|
usage: "norn runs resume <run>",
|
|
167
169
|
arguments: ["run: run id, generated name, or run path"],
|
|
168
|
-
stdin: 'Optional JSON object: {"
|
|
170
|
+
stdin: 'Optional JSON object: {"args":{...}}. Interrupted runs require a patch containing only editable gate fields; pending-resume runs do not accept args.',
|
|
169
171
|
output: "JSON object with resumed run info under run.",
|
|
170
|
-
examples: [`printf '{"
|
|
172
|
+
examples: [`printf '{"args":{"decision":"accept"}}' | norn runs resume quiet-river-lantern`],
|
|
171
173
|
execute: async (args) => {
|
|
172
174
|
const run = requiredArg("runs resume", args, 0, "run");
|
|
173
175
|
await resumeRun(run, args.slice(1));
|
|
@@ -686,7 +688,7 @@ async function initProject() {
|
|
|
686
688
|
const projectPath = resolve(projectRoot, NORN_PROJECT_FILE_NAME);
|
|
687
689
|
if (await isFile(projectPath)) throw new Error(`Norn project already exists: ${projectPath}`);
|
|
688
690
|
await mkdir(resolve(projectRoot, RUNS_ROOT), { recursive: true });
|
|
689
|
-
await writeFile(projectPath, `${JSON.stringify({ version: 1,
|
|
691
|
+
await writeFile(projectPath, `${JSON.stringify({ version: 1, workflows: [], includes: [], config: {} }, null, 2)}
|
|
690
692
|
`, "utf8");
|
|
691
693
|
await ensureGitignoreExcludesRunState(projectRoot);
|
|
692
694
|
writeJson({ project: { path: projectPath, root: projectRoot, runsRoot: resolve(projectRoot, RUNS_ROOT) } });
|
|
@@ -699,23 +701,23 @@ async function inspectProject() {
|
|
|
699
701
|
const { project, isComplete, diagnostics } = await discoverNornProject(process.cwd());
|
|
700
702
|
writeJson({ project, isComplete, diagnostics });
|
|
701
703
|
}
|
|
702
|
-
async function startRun(workflowId,
|
|
703
|
-
assertNoStructuredInputArgs("runs start",
|
|
704
|
+
async function startRun(workflowId, commandArgs) {
|
|
705
|
+
assertNoStructuredInputArgs("runs start", commandArgs);
|
|
704
706
|
const project = await loadNornProject(process.cwd());
|
|
705
707
|
const workflow = project.registry.workflowById(workflowId);
|
|
706
708
|
if (!workflow) throw new Error(`Unknown workflow: ${workflowId}`);
|
|
707
709
|
const input = parseStartRunInput(await readStdinJson());
|
|
708
|
-
const
|
|
709
|
-
Value.Decode(workflow.
|
|
710
|
+
const args = input.args === void 0 ? {} : input.args;
|
|
711
|
+
Value.Decode(workflow.args, args);
|
|
710
712
|
const configOverride = input.config;
|
|
711
713
|
const id = randomUUID();
|
|
712
714
|
const name = generateRunName(new Set((await listRuns(project.projectRoot)).map((run) => run.name)));
|
|
713
715
|
const runRoot = resolve(project.projectRoot, RUNS_ROOT, id);
|
|
714
716
|
await mkdir(runRoot, { recursive: true });
|
|
715
717
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
716
|
-
await writeRunLaunchRequest(runRoot, { version:
|
|
718
|
+
await writeRunLaunchRequest(runRoot, { version: 2, type: "run", id, name, workflowId, args, configOverride, createdAt });
|
|
717
719
|
await startDetachedExecuteRun(id, project.projectRoot);
|
|
718
|
-
writeJson({ run: startedRunInfo({ id, name, workflow, runRoot, createdAt }) });
|
|
720
|
+
writeJson({ run: startedRunInfo({ id, name, workflow, runRoot, projectRoot: project.projectRoot, createdAt }) });
|
|
719
721
|
}
|
|
720
722
|
async function resumeRun(run, args) {
|
|
721
723
|
assertNoStructuredInputArgs("runs resume", args);
|
|
@@ -726,8 +728,9 @@ async function resumeRun(run, args) {
|
|
|
726
728
|
let request;
|
|
727
729
|
try {
|
|
728
730
|
const runInfo = await getRunInfo(runRoot);
|
|
729
|
-
|
|
730
|
-
|
|
731
|
+
assertRunVersion(runInfo.version);
|
|
732
|
+
const args2 = await parseResumeArgs(runInfo, input.args);
|
|
733
|
+
request = { version: 2, type: "resume", id: runInfo.id, requestId: randomUUID(), args: args2, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
731
734
|
await writeRunResumeRequest(runRoot, request);
|
|
732
735
|
} finally {
|
|
733
736
|
await lease.release();
|
|
@@ -740,18 +743,18 @@ async function resumeRun(run, args) {
|
|
|
740
743
|
}
|
|
741
744
|
writeJson({ run: await getRunInfo(runRoot) });
|
|
742
745
|
}
|
|
743
|
-
async function
|
|
746
|
+
async function parseResumeArgs(runInfo, args) {
|
|
744
747
|
if (runInfo.status === "interrupted") {
|
|
745
|
-
if (
|
|
748
|
+
if (args === void 0) throw new Error(`Interrupted workflow resume requires args: ${runInfo.name}`);
|
|
746
749
|
if (!runInfo.currentWorkflowId) throw new Error(`Run has no current workflow: ${runInfo.name}`);
|
|
747
750
|
const project = await loadNornProject(process.cwd());
|
|
748
751
|
const workflow = project.registry.workflowById(runInfo.currentWorkflowId);
|
|
749
752
|
if (!workflow) throw new Error(`Unknown workflow for resumed run: ${runInfo.currentWorkflowId}`);
|
|
750
|
-
Value.Decode(workflow.
|
|
751
|
-
return
|
|
753
|
+
Value.Decode(workflow.args, mergeInterruptedWorkflowArgs(runInfo.interruption?.args, args, runInfo.interruption?.fields));
|
|
754
|
+
return args;
|
|
752
755
|
}
|
|
753
756
|
if (runInfo.status === "pendingResume") {
|
|
754
|
-
if (
|
|
757
|
+
if (args !== void 0) throw new Error(`Pending-resume workflows do not accept args: ${runInfo.name}`);
|
|
755
758
|
return void 0;
|
|
756
759
|
}
|
|
757
760
|
throw new Error(`Run must be rolled back before resuming: ${runInfo.name}`);
|
|
@@ -821,13 +824,15 @@ async function executeRun(runId) {
|
|
|
821
824
|
const runRoot = resolve(location.projectRoot, RUNS_ROOT, runId);
|
|
822
825
|
const request = await readOptionalRunLaunchRequest(runRoot) ?? await readRunResumeRequest(runRoot);
|
|
823
826
|
try {
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
|
|
827
|
+
const agentDir = resolveNornAgentDirectory({ home: homedir(), environment: process.env });
|
|
828
|
+
process.chdir(await prepareRunWorkerDirectory(runRoot));
|
|
829
|
+
const project = await loadNornProject(location.projectRoot);
|
|
830
|
+
const engine = new NornEngine({ cwd: project.projectRoot, agentDir, signal: abortController.signal, gateMode: "pause", config: project.projectConfig });
|
|
831
|
+
engine.registerWorkflows(project.definitions);
|
|
827
832
|
if (request.type === "run") {
|
|
828
833
|
const workflow = project.registry.workflowById(request.workflowId);
|
|
829
834
|
if (!workflow) throw new Error(`Unknown workflow: ${request.workflowId}`);
|
|
830
|
-
await engine.runWorkflow(workflow, request.
|
|
835
|
+
await engine.runWorkflow(workflow, request.args, { id: request.id, name: request.name, configOverride: request.configOverride });
|
|
831
836
|
} else {
|
|
832
837
|
await engine.resumeRequestedWorkflow({ runRoot, request });
|
|
833
838
|
}
|
|
@@ -913,10 +918,11 @@ function detachedExecuteRunArgs(runId) {
|
|
|
913
918
|
}
|
|
914
919
|
function startedRunInfo(input) {
|
|
915
920
|
return {
|
|
916
|
-
version:
|
|
921
|
+
version: 2,
|
|
917
922
|
id: input.id,
|
|
918
923
|
name: input.name,
|
|
919
924
|
path: input.runRoot,
|
|
925
|
+
paths: { project: input.projectRoot, workspace: join(input.runRoot, "current", "workspace") },
|
|
920
926
|
entrypointWorkflowId: input.workflow.id,
|
|
921
927
|
currentWorkflowId: input.workflow.id,
|
|
922
928
|
status: "running",
|
|
@@ -963,14 +969,14 @@ async function readStdin() {
|
|
|
963
969
|
function parseStartRunInput(value) {
|
|
964
970
|
if (value === void 0) return {};
|
|
965
971
|
const input = parseStructuredInputObject("runs start", value);
|
|
966
|
-
assertStructuredInputKeys("runs start", input, ["
|
|
967
|
-
return {
|
|
972
|
+
assertStructuredInputKeys("runs start", input, ["args", "config"]);
|
|
973
|
+
return { args: input.args, config: input.config };
|
|
968
974
|
}
|
|
969
975
|
function parseResumeRunInput(value) {
|
|
970
976
|
if (value === void 0) return {};
|
|
971
977
|
const input = parseStructuredInputObject("runs resume", value);
|
|
972
|
-
assertStructuredInputKeys("runs resume", input, ["
|
|
973
|
-
return {
|
|
978
|
+
assertStructuredInputKeys("runs resume", input, ["args"]);
|
|
979
|
+
return { args: input.args };
|
|
974
980
|
}
|
|
975
981
|
function parseStructuredInputObject(command, value) {
|
|
976
982
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${command} reads a JSON object from stdin`);
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeletedNornRunInfo, NornProjectInspection, NornWorkflowCatalogInfo, NornWorkflowInspection, NornRunCheckpoint, NornRunInfo, NornRunMetrics
|
|
1
|
+
import type { DeletedNornRunInfo, NornProjectInspection, NornWorkflowCatalogInfo, NornWorkflowInspection, NornRunCheckpoint, NornRunInfo, NornRunMetrics } from "@vimhead.dev/norn";
|
|
2
2
|
import type { NornRegisteredWorkflow } from "./internal/workflow-registry.ts";
|
|
3
3
|
export { NornProjectLoadError } from "./internal/errors.ts";
|
|
4
4
|
export type NornClientInput = {
|
|
@@ -16,16 +16,15 @@ export type NornClient = {
|
|
|
16
16
|
inspect(workflowId: string): Promise<NornWorkflowInspection>;
|
|
17
17
|
entries(): Promise<readonly NornRegisteredWorkflow[]>;
|
|
18
18
|
};
|
|
19
|
-
readonly state: NornWorkflowStateReader;
|
|
20
19
|
readonly runs: {
|
|
21
20
|
start(input: {
|
|
22
21
|
readonly workflowId: string;
|
|
23
|
-
readonly
|
|
22
|
+
readonly args: unknown;
|
|
24
23
|
readonly configOverride?: unknown;
|
|
25
24
|
}): Promise<NornRunInfo>;
|
|
26
25
|
resume(input: {
|
|
27
26
|
readonly run: string;
|
|
28
|
-
readonly
|
|
27
|
+
readonly args?: unknown;
|
|
29
28
|
}): Promise<NornRunInfo>;
|
|
30
29
|
wait(run: string): Promise<NornRunInfo>;
|
|
31
30
|
list(): Promise<NornRunInfo[]>;
|
package/dist/client.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { createInterface } from "node:readline";
|
|
5
|
-
import { loadNornProject } from "./
|
|
5
|
+
import { loadNornProject } from "./workflow-loader.js";
|
|
6
6
|
import { NornProjectLoadError } from "./internal/errors.js";
|
|
7
7
|
import { NornProjectLoadError as NornProjectLoadError2 } from "./internal/errors.js";
|
|
8
8
|
function createNornClient(input = {}) {
|
|
@@ -17,7 +17,6 @@ function createNornClient(input = {}) {
|
|
|
17
17
|
inspect: async (workflowId) => processRunner.readJson(["workflows", "inspect", workflowId]),
|
|
18
18
|
entries: async () => (await catalog.load()).workflows
|
|
19
19
|
},
|
|
20
|
-
state: catalog.state,
|
|
21
20
|
runs: {
|
|
22
21
|
start: async (startInput) => (await processRunner.readJson(["runs", "start", startInput.workflowId], JSON.stringify(runStartInput(startInput)))).run,
|
|
23
22
|
resume: async (resumeInput) => (await processRunner.readJson(["runs", "resume", resumeInput.run], runResumeStdin(resumeInput))).run,
|
|
@@ -41,10 +40,6 @@ var NornWorkflowCatalog = class {
|
|
|
41
40
|
}
|
|
42
41
|
cwd;
|
|
43
42
|
loaded;
|
|
44
|
-
state = {
|
|
45
|
-
get: async (state) => (await this.load()).state.get(state),
|
|
46
|
-
getOptional: async (state) => (await this.load()).state.getOptional(state)
|
|
47
|
-
};
|
|
48
43
|
load() {
|
|
49
44
|
this.loaded ??= loadNornProject(this.cwd).catch((error) => {
|
|
50
45
|
this.loaded = void 0;
|
|
@@ -104,10 +99,10 @@ var NornProcessRunner = class {
|
|
|
104
99
|
}
|
|
105
100
|
};
|
|
106
101
|
function runStartInput(input) {
|
|
107
|
-
return input.configOverride === void 0 ? {
|
|
102
|
+
return input.configOverride === void 0 ? { args: input.args } : { args: input.args, config: input.configOverride };
|
|
108
103
|
}
|
|
109
104
|
function runResumeStdin(input) {
|
|
110
|
-
return input.
|
|
105
|
+
return input.args === void 0 ? void 0 : JSON.stringify({ args: input.args });
|
|
111
106
|
}
|
|
112
107
|
export {
|
|
113
108
|
NornProjectLoadError2 as NornProjectLoadError,
|
|
@@ -20,7 +20,7 @@ function renderNornDocumentationIntro(input) {
|
|
|
20
20
|
"",
|
|
21
21
|
"Live CLI contracts (argument arrays appended to the runtime argv above):",
|
|
22
22
|
'- ["workflows", "list"] \u2014 currently registered entrypoints.',
|
|
23
|
-
'- ["workflows", "inspect", "<workflow-id>"] \u2014 current instructions,
|
|
23
|
+
'- ["workflows", "inspect", "<workflow-id>"] \u2014 current instructions, args schema, and source.',
|
|
24
24
|
'- ["help"] \u2014 command usage.'
|
|
25
25
|
].join("\n");
|
|
26
26
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const NORN_GENERATED_BUILD_INFO: {
|
|
2
2
|
readonly kind: "npm-registry";
|
|
3
|
-
readonly version: "0.1.0-tip.
|
|
4
|
-
readonly commit: "
|
|
3
|
+
readonly version: "0.1.0-tip.35436871363.1";
|
|
4
|
+
readonly commit: "49b14d0ed0c9633fc6ee530a557ec7babbf52b22";
|
|
5
5
|
readonly packageSpec: "@vimhead.dev/norn-cli@tip";
|
|
6
6
|
readonly upgrade: {
|
|
7
7
|
readonly supported: false;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/generated-build-info.ts
|
|
2
2
|
var NORN_GENERATED_BUILD_INFO = {
|
|
3
3
|
"kind": "npm-registry",
|
|
4
|
-
"version": "0.1.0-tip.
|
|
5
|
-
"commit": "
|
|
4
|
+
"version": "0.1.0-tip.35436871363.1",
|
|
5
|
+
"commit": "49b14d0ed0c9633fc6ee530a557ec7babbf52b22",
|
|
6
6
|
"packageSpec": "@vimhead.dev/norn-cli@tip",
|
|
7
7
|
"upgrade": {
|
|
8
8
|
"supported": false,
|
|
@@ -52,12 +52,12 @@ var NornAgentResponseToolFactory = class {
|
|
|
52
52
|
label: Type.String({ description: "The exact workflow agent label provided in the prompt." }),
|
|
53
53
|
response: Type.Unknown({ description: "The structured response object requested by the workflow." })
|
|
54
54
|
}),
|
|
55
|
-
async execute(_toolCallId,
|
|
55
|
+
async execute(_toolCallId, args) {
|
|
56
56
|
try {
|
|
57
|
-
const captured = responseCollector.capture(
|
|
57
|
+
const captured = responseCollector.capture(args.runId, args.label, args.response);
|
|
58
58
|
return {
|
|
59
59
|
content: [{ type: "text", text: `Recorded workflow agent response for ${captured.label}.` }],
|
|
60
|
-
details: { valid: true, runId:
|
|
60
|
+
details: { valid: true, runId: args.runId, label: captured.label, response: captured.response },
|
|
61
61
|
terminate: true
|
|
62
62
|
};
|
|
63
63
|
} catch (error) {
|
|
@@ -7,9 +7,6 @@ import type { NornRunLogger } from "./run-log.ts";
|
|
|
7
7
|
type NornAgentRunnerInput = {
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly runRoot: string;
|
|
10
|
-
readonly boundaryRoot: string;
|
|
11
|
-
readonly boundaryName: string;
|
|
12
|
-
readonly cwd: string;
|
|
13
10
|
readonly signal?: AbortSignal;
|
|
14
11
|
readonly model?: CreateAgentSessionOptions["model"];
|
|
15
12
|
readonly thinkingLevel?: CreateAgentSessionOptions["thinkingLevel"];
|
|
@@ -24,6 +21,5 @@ export declare class NornAgentRunner {
|
|
|
24
21
|
constructor(input: NornAgentRunnerInput);
|
|
25
22
|
createSession(agentInput: NornAgentCreateSessionInput): Promise<NornAgentSession>;
|
|
26
23
|
prompt<ResponseSchema extends TSchema>(agentInput: NornAgentSinglePromptInput<ResponseSchema>): Promise<StaticDecode<ResponseSchema>>;
|
|
27
|
-
private resolveFromCwd;
|
|
28
24
|
}
|
|
29
25
|
export {};
|