@markjaquith/agency 2.72.0 → 2.73.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/README.md +14 -8
- package/index.ts +1 -1
- package/package.json +3 -3
- package/schemas/{agency-kickoff-v1.schema.json → agency-execution-v1.schema.json} +66 -42
- package/src/cli-parser.test.ts +3 -0
- package/src/cli-parser.ts +7 -1
- package/src/cli.test.ts +42 -0
- package/src/commands/task.ts +1 -1
- package/src/commands/work.test.ts +9 -6
- package/src/commands/work.ts +5 -6
- package/src/services/IntegrationService.test.ts +42 -14
- package/src/workbase/AGENTS.md +74 -38
- package/src/workbase/{kickoff-contract.test.ts → execution-contract.test.ts} +45 -29
- package/src/workbase/{kickoff-contract.ts → execution-contract.ts} +46 -85
- package/src/workbase/opencode-file.ts +7 -2
package/README.md
CHANGED
|
@@ -441,7 +441,7 @@ variables. A worker must verify either signal against `agency context . --json`
|
|
|
441
441
|
before acting; a matching worker performs the task directly and must not invoke
|
|
442
442
|
`agency work` for the same target. Managed guidance also fails safe for older
|
|
443
443
|
generated prompts when their document paths, current directory, and active valid
|
|
444
|
-
context all agree.
|
|
444
|
+
context all agree. External session state is not part of this identity contract.
|
|
445
445
|
The managed OpenCode plugin validates the marker against Agency context, binds it
|
|
446
446
|
to the receiving OpenCode session, injects an explicit active-worker system
|
|
447
447
|
instruction, and restores Agency identity for that session's shell environment.
|
|
@@ -860,13 +860,13 @@ includes `selector`, absolute `documentPath`, the document `revision`, full
|
|
|
860
860
|
`validation`, normalized `recalledContext`, and `evidence`. Evidence version 1 is
|
|
861
861
|
an auditable local payload containing the canonical workbase root, target and
|
|
862
862
|
document identities, aggregate workbase revision, configuration revision,
|
|
863
|
-
repository-mapping revision,
|
|
863
|
+
repository-mapping revision, execution-contract version, validity result, recalled
|
|
864
864
|
context, and a digest over those fields. It is not a signature or an authority
|
|
865
865
|
grant. A different workbase, target, document revision, document set,
|
|
866
866
|
configuration, repository mapping, contract version, or payload digest
|
|
867
867
|
invalidates reuse. Older creation output without evidence remains compatible;
|
|
868
868
|
preflight simply validates again. The published machine schema is
|
|
869
|
-
`schemas/agency-
|
|
869
|
+
`schemas/agency-execution-v1.schema.json`.
|
|
870
870
|
|
|
871
871
|
Create investigation-only work with the existing task architecture:
|
|
872
872
|
|
|
@@ -1128,12 +1128,18 @@ promptless by default; use `--auto` to send Agency's generated context prompt.
|
|
|
1128
1128
|
`agency work prepare` resolves an execution unit and creates or reuses its
|
|
1129
1129
|
writable and reference worktrees, or its single pinned review checkout, without
|
|
1130
1130
|
launching an agent or changing status.
|
|
1131
|
+
Managed workbase guidance provides exact fast paths for 15 common intents:
|
|
1132
|
+
single-phase creation; create-and-start; materialization; remote PR sync; phase
|
|
1133
|
+
conversion; archive; review creation and start; status inspection; drop;
|
|
1134
|
+
continuation; publication and PR creation; non-PR completion; initial multi-phase
|
|
1135
|
+
setup; investigation handoff; and review refresh.
|
|
1131
1136
|
Its JSON result includes the workspace, validation result, whether supplied
|
|
1132
1137
|
evidence was `reused` or `refreshed` with stable reason strings, refreshed
|
|
1133
|
-
evidence, and a versioned `agency-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1138
|
+
evidence, and a versioned `agency-execution-v1` contract. The contract reports
|
|
1139
|
+
whether preparation was previewed or applied, a stable target identity, prepared
|
|
1140
|
+
workspace and document paths, and canonical Agency-native commands for starting
|
|
1141
|
+
work and reading context. It does not prescribe how callers present or execute
|
|
1142
|
+
prepared work.
|
|
1137
1143
|
The evidence argument may be an evidence object, task-creation JSON, or a path to
|
|
1138
1144
|
either. Use `--dry-run` to report planned fetch, branch, and worktree changes
|
|
1139
1145
|
without applying them. Validation reuse never skips readiness, active-claim,
|
|
@@ -1142,7 +1148,7 @@ checks.
|
|
|
1142
1148
|
|
|
1143
1149
|
The authoritative implementation locations for this contract are
|
|
1144
1150
|
`src/commands/task.ts` (creation output),
|
|
1145
|
-
`src/workbase/
|
|
1151
|
+
`src/workbase/execution-contract.ts` (evidence and execution schemas),
|
|
1146
1152
|
`src/commands/work.ts` (launch preflight),
|
|
1147
1153
|
`src/services/WorktreeService.ts` (workspace safety), and
|
|
1148
1154
|
`src/workbase/AGENTS.md` (generated OpenCode guidance). These paths are the
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markjaquith/agency",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.73.1",
|
|
4
4
|
"description": "Manage agentic work across repositories with durable workbases",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"./schemas/agency-graph-v1.json": {
|
|
47
47
|
"default": "./schemas/agency-graph-v1.schema.json"
|
|
48
48
|
},
|
|
49
|
-
"./schemas/agency-
|
|
50
|
-
"default": "./schemas/agency-
|
|
49
|
+
"./schemas/agency-execution-v1.json": {
|
|
50
|
+
"default": "./schemas/agency-execution-v1.schema.json"
|
|
51
51
|
},
|
|
52
52
|
"./fixtures/protocol/success.json": {
|
|
53
53
|
"default": "./fixtures/protocol/success.json"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://github.com/markjaquith/agency/schemas/agency-
|
|
4
|
-
"title": "Agency
|
|
3
|
+
"$id": "https://github.com/markjaquith/agency/schemas/agency-execution-v1.schema.json",
|
|
4
|
+
"title": "Agency execution contract v1",
|
|
5
5
|
"oneOf": [
|
|
6
6
|
{ "$ref": "#/$defs/validationEvidence" },
|
|
7
|
-
{ "$ref": "#/$defs/
|
|
7
|
+
{ "$ref": "#/$defs/executionContract" }
|
|
8
8
|
],
|
|
9
9
|
"$defs": {
|
|
10
10
|
"recalledContext": {
|
|
@@ -54,69 +54,93 @@
|
|
|
54
54
|
},
|
|
55
55
|
"additionalProperties": false
|
|
56
56
|
},
|
|
57
|
-
"
|
|
57
|
+
"command": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"required": ["cwd", "argv"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"cwd": { "type": "string" },
|
|
62
|
+
"argv": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"minItems": 1,
|
|
65
|
+
"items": { "type": "string" }
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"additionalProperties": false
|
|
69
|
+
},
|
|
70
|
+
"executionContract": {
|
|
58
71
|
"type": "object",
|
|
59
72
|
"required": [
|
|
60
73
|
"version",
|
|
61
|
-
"
|
|
74
|
+
"capability",
|
|
75
|
+
"mode",
|
|
76
|
+
"executionIdentity",
|
|
62
77
|
"workbaseRoot",
|
|
63
|
-
"target",
|
|
64
|
-
"documentRevision",
|
|
65
78
|
"sourceLocations",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"phaseDocument",
|
|
69
|
-
"preparedCheckout",
|
|
70
|
-
"orchestrator",
|
|
71
|
-
"steps",
|
|
72
|
-
"successFields"
|
|
79
|
+
"workspace",
|
|
80
|
+
"commands"
|
|
73
81
|
],
|
|
74
82
|
"properties": {
|
|
75
83
|
"version": { "const": 1 },
|
|
76
|
-
"
|
|
84
|
+
"capability": { "const": "agency-execution-v1" },
|
|
85
|
+
"mode": { "enum": ["preview", "applied"] },
|
|
86
|
+
"executionIdentity": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"required": ["key", "target", "documentRevision"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"key": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
91
|
+
"target": { "type": "string" },
|
|
92
|
+
"documentRevision": {
|
|
93
|
+
"type": "string",
|
|
94
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"additionalProperties": false
|
|
98
|
+
},
|
|
77
99
|
"workbaseRoot": { "type": "string" },
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
"
|
|
83
|
-
"phaseDocument": { "type": ["string", "null"] },
|
|
84
|
-
"preparedCheckout": { "type": ["string", "null"] },
|
|
85
|
-
"orchestrator": {
|
|
100
|
+
"sourceLocations": {
|
|
101
|
+
"type": "array",
|
|
102
|
+
"items": { "type": "string" }
|
|
103
|
+
},
|
|
104
|
+
"workspace": {
|
|
86
105
|
"type": "object",
|
|
87
106
|
"required": [
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
107
|
+
"state",
|
|
108
|
+
"executionDirectory",
|
|
109
|
+
"taskDocument",
|
|
110
|
+
"phaseDocument",
|
|
111
|
+
"checkoutPath"
|
|
91
112
|
],
|
|
92
113
|
"properties": {
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
114
|
+
"state": { "enum": ["planned", "materialized"] },
|
|
115
|
+
"executionDirectory": { "type": "string" },
|
|
116
|
+
"taskDocument": { "type": "string" },
|
|
117
|
+
"phaseDocument": { "type": ["string", "null"] },
|
|
118
|
+
"checkoutPath": { "type": ["string", "null"] }
|
|
96
119
|
},
|
|
97
120
|
"additionalProperties": false
|
|
98
121
|
},
|
|
99
|
-
"
|
|
122
|
+
"plannedActions": {
|
|
100
123
|
"type": "array",
|
|
101
|
-
"minItems": 6,
|
|
102
124
|
"items": {
|
|
103
125
|
"type": "object",
|
|
104
|
-
"required": ["
|
|
126
|
+
"required": ["kind", "target", "checkoutPath"],
|
|
105
127
|
"properties": {
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"action": { "type": "string" },
|
|
110
|
-
"path": { "type": "string" },
|
|
111
|
-
"retry": { "type": "string" },
|
|
112
|
-
"recovery": { "type": "string" },
|
|
113
|
-
"idempotencyKey": { "type": "string" },
|
|
114
|
-
"exactlyOnce": { "type": "boolean" }
|
|
128
|
+
"kind": { "const": "workspace-materialization" },
|
|
129
|
+
"target": { "type": "string" },
|
|
130
|
+
"checkoutPath": { "type": ["string", "null"] }
|
|
115
131
|
},
|
|
116
132
|
"additionalProperties": false
|
|
117
133
|
}
|
|
118
134
|
},
|
|
119
|
-
"
|
|
135
|
+
"commands": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"required": ["work", "context"],
|
|
138
|
+
"properties": {
|
|
139
|
+
"work": { "$ref": "#/$defs/command" },
|
|
140
|
+
"context": { "$ref": "#/$defs/command" }
|
|
141
|
+
},
|
|
142
|
+
"additionalProperties": false
|
|
143
|
+
}
|
|
120
144
|
},
|
|
121
145
|
"additionalProperties": false
|
|
122
146
|
}
|
package/src/cli-parser.test.ts
CHANGED
|
@@ -229,7 +229,9 @@ describe("strict CLI parsing", () => {
|
|
|
229
229
|
test("parses addressable resource maintenance commands", () => {
|
|
230
230
|
for (const args of [
|
|
231
231
|
["doctor", "--json"],
|
|
232
|
+
["repo", "materialize", "--help"],
|
|
232
233
|
["repo", "show", "agency", "--json"],
|
|
234
|
+
["repo", "materialize", "agency", "--json"],
|
|
233
235
|
["repo", "fetch", "agency"],
|
|
234
236
|
["repo", "remove", "agency"],
|
|
235
237
|
["repo", "unlink", "agency"],
|
|
@@ -270,6 +272,7 @@ describe("strict CLI parsing", () => {
|
|
|
270
272
|
[["integration", "sync", "extra"], "agency integration sync"],
|
|
271
273
|
[["repo", "add", "a", "b", "extra"], "agency repo add"],
|
|
272
274
|
[["repo", "link", "a", "b", "extra"], "agency repo link"],
|
|
275
|
+
[["repo", "materialize", "a", "extra"], "agency repo materialize"],
|
|
273
276
|
[["repo", "list", "extra"], "agency repo list"],
|
|
274
277
|
[
|
|
275
278
|
[
|
package/src/cli-parser.ts
CHANGED
|
@@ -259,7 +259,7 @@ const commands = {
|
|
|
259
259
|
},
|
|
260
260
|
repo: {
|
|
261
261
|
usage:
|
|
262
|
-
"agency repo <setup|add|link|list|show|fetch|remove|unlink|rename|remote|verify>",
|
|
262
|
+
"agency repo <setup|add|link|materialize|list|show|fetch|remove|unlink|rename|remote|verify>",
|
|
263
263
|
options: {
|
|
264
264
|
...outputOptions,
|
|
265
265
|
"dry-run": { type: "boolean" },
|
|
@@ -285,6 +285,12 @@ const commands = {
|
|
|
285
285
|
maxArgs: 2,
|
|
286
286
|
options: ["json"],
|
|
287
287
|
},
|
|
288
|
+
materialize: {
|
|
289
|
+
usage: "agency repo materialize <alias> [--json]",
|
|
290
|
+
minArgs: 1,
|
|
291
|
+
maxArgs: 1,
|
|
292
|
+
options: ["json"],
|
|
293
|
+
},
|
|
288
294
|
list: {
|
|
289
295
|
usage: "agency repo list [--json]",
|
|
290
296
|
minArgs: 0,
|
package/src/cli.test.ts
CHANGED
|
@@ -934,6 +934,48 @@ status: open
|
|
|
934
934
|
})
|
|
935
935
|
})
|
|
936
936
|
|
|
937
|
+
test("materializes a linked repository through the CLI", async () => {
|
|
938
|
+
const parent = await createTempDir()
|
|
939
|
+
tempDirs.push(parent)
|
|
940
|
+
const root = join(parent, "workbase")
|
|
941
|
+
const source = join(parent, "source")
|
|
942
|
+
await runGit(["init", "--initial-branch=main", source])
|
|
943
|
+
await Bun.write(join(source, "README.md"), "materialize\n")
|
|
944
|
+
for (const args of [
|
|
945
|
+
["config", "user.email", "test@example.com"],
|
|
946
|
+
["config", "user.name", "Test"],
|
|
947
|
+
["add", "README.md"],
|
|
948
|
+
["-c", "commit.gpgsign=false", "commit", "-m", "initial"],
|
|
949
|
+
[
|
|
950
|
+
"remote",
|
|
951
|
+
"add",
|
|
952
|
+
"origin",
|
|
953
|
+
"https://example.com/agency-tests/source.git",
|
|
954
|
+
],
|
|
955
|
+
]) {
|
|
956
|
+
await runGit(["-C", source, ...args])
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
parseJson(await runCli(["init", root, "--json"], parent))
|
|
960
|
+
const configPath = join(root, "agency.json")
|
|
961
|
+
await Bun.write(
|
|
962
|
+
configPath,
|
|
963
|
+
JSON.stringify({ ...(await Bun.file(configPath).json()), vcs: "git" }),
|
|
964
|
+
)
|
|
965
|
+
parseJson(await runCli(["repo", "link", "agency", source, "--json"], root))
|
|
966
|
+
const materialized = parseJson(
|
|
967
|
+
await runCli(["repo", "materialize", "agency", "--json"], root),
|
|
968
|
+
)
|
|
969
|
+
|
|
970
|
+
expect(materialized).toMatchObject({
|
|
971
|
+
alias: "agency",
|
|
972
|
+
kind: "bare",
|
|
973
|
+
target: null,
|
|
974
|
+
states: ["declared", "materialized"],
|
|
975
|
+
})
|
|
976
|
+
expect(await Bun.file(join(root, "repos/agency/HEAD")).exists()).toBe(true)
|
|
977
|
+
})
|
|
978
|
+
|
|
937
979
|
test("prepares a workspace and reports a non-mutating dry-run", async () => {
|
|
938
980
|
const parent = await createTempDir()
|
|
939
981
|
tempDirs.push(parent)
|
package/src/commands/task.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { ReviewService } from "../services/ReviewService"
|
|
|
15
15
|
import {
|
|
16
16
|
buildValidationEvidence,
|
|
17
17
|
normalizeRecalledContext,
|
|
18
|
-
} from "../workbase/
|
|
18
|
+
} from "../workbase/execution-contract"
|
|
19
19
|
|
|
20
20
|
interface TaskOptions extends BaseCommandOptions {
|
|
21
21
|
readonly subcommand?: string
|
|
@@ -532,12 +532,15 @@ describe("work command", () => {
|
|
|
532
532
|
const result = JSON.parse(output!)
|
|
533
533
|
expect(result.validationEvidence.status).toBe("refreshed")
|
|
534
534
|
expect(result.validationEvidence.reasons).toEqual(["not-supplied"])
|
|
535
|
-
expect(result.
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
535
|
+
expect(result.execution).toMatchObject({
|
|
536
|
+
capability: "agency-execution-v1",
|
|
537
|
+
mode: "preview",
|
|
538
|
+
executionIdentity: { target: "execution-unit:task/example" },
|
|
539
|
+
workspace: { state: "planned" },
|
|
540
|
+
commands: {
|
|
541
|
+
work: { argv: ["agency", "work", ".", "--auto"] },
|
|
542
|
+
},
|
|
543
|
+
})
|
|
541
544
|
|
|
542
545
|
const [reusedOutput] = await captureLogs(() =>
|
|
543
546
|
harness.runPrepare({
|
package/src/commands/work.ts
CHANGED
|
@@ -31,11 +31,11 @@ import {
|
|
|
31
31
|
} from "../workbase/agent-command"
|
|
32
32
|
import {
|
|
33
33
|
assessValidationEvidence,
|
|
34
|
-
|
|
34
|
+
buildExecutionContract,
|
|
35
35
|
buildValidationEvidence,
|
|
36
36
|
normalizeRecalledContext,
|
|
37
37
|
readValidationEvidence,
|
|
38
|
-
} from "../workbase/
|
|
38
|
+
} from "../workbase/execution-contract"
|
|
39
39
|
|
|
40
40
|
export interface WorkOptions extends BaseCommandOptions {
|
|
41
41
|
readonly directory?: string
|
|
@@ -556,22 +556,21 @@ export const workPrepare = (options: WorkOptions = {}) =>
|
|
|
556
556
|
workspace,
|
|
557
557
|
validation,
|
|
558
558
|
validationEvidence: { ...assessment.disposition, evidence },
|
|
559
|
-
|
|
559
|
+
execution: buildExecutionContract({
|
|
560
560
|
workbaseRoot: root,
|
|
561
561
|
target,
|
|
562
|
-
taskId,
|
|
563
|
-
phaseId: phase?.id,
|
|
564
562
|
taskPath: task.path,
|
|
565
563
|
phasePath: phase?.path,
|
|
566
564
|
checkoutPath: workspace.writablePath ?? workspace.reviewPath,
|
|
567
565
|
documentRevision: document.revision,
|
|
566
|
+
dryRun: options.dryRun === true,
|
|
568
567
|
}),
|
|
569
568
|
}
|
|
570
569
|
if (options.json) {
|
|
571
570
|
log(JSON.stringify(result, null, 2))
|
|
572
571
|
} else {
|
|
573
572
|
log(
|
|
574
|
-
`${workspace.dryRun ? "
|
|
573
|
+
`${workspace.dryRun ? "Workspace plan" : "Workspace ready"}: ${workspace.writablePath ?? workspace.reviewPath}`,
|
|
575
574
|
)
|
|
576
575
|
}
|
|
577
576
|
})
|
|
@@ -156,19 +156,46 @@ describe("IntegrationService", () => {
|
|
|
156
156
|
])
|
|
157
157
|
})
|
|
158
158
|
|
|
159
|
-
test("generates the
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
test("generates the complete Agency command fast paths with precedence", () => {
|
|
160
|
+
const body = managedBody(managedWorkbaseAgents)
|
|
161
|
+
|
|
162
|
+
expect(body.indexOf("## Command Fast Paths")).toBeLessThan(
|
|
163
|
+
body.indexOf("## Bootstrap"),
|
|
162
164
|
)
|
|
163
165
|
expect(managedWorkbaseAgents).toContain(
|
|
166
|
+
"take precedence over separately installed Agency skill guidance",
|
|
167
|
+
)
|
|
168
|
+
for (const recipe of [
|
|
169
|
+
"Create a single-phase task only",
|
|
164
170
|
"agency work prepare <slug> --evidence",
|
|
171
|
+
"Materialize an existing execution unit without starting it",
|
|
172
|
+
"agency sync <task> [phase] --json",
|
|
173
|
+
"agency phase create <task> <new-phase> --first-phase <existing-phase>",
|
|
174
|
+
"agency archive task <task> --dry-run --json",
|
|
175
|
+
"agency task create <slug> --review <alias>",
|
|
176
|
+
"agency status --json",
|
|
177
|
+
"agency task status <task> dropped --if-revision <revision> --json",
|
|
178
|
+
"Continue already materialized work",
|
|
179
|
+
"agency pr create <task> [phase]",
|
|
180
|
+
"agency finish <task> [phase] --session-id <id>",
|
|
181
|
+
"agency task create <slug> --multi-phase",
|
|
182
|
+
"agency task handoff <investigation-task> <new-task>",
|
|
183
|
+
"agency review refresh <task> --if-revision <revision> --json",
|
|
184
|
+
]) {
|
|
185
|
+
expect(managedWorkbaseAgents).toContain(recipe)
|
|
186
|
+
}
|
|
187
|
+
expect(managedWorkbaseAgents).toContain("agency push --json")
|
|
188
|
+
expect(managedWorkbaseAgents).toContain("agency-execution-v1")
|
|
189
|
+
expect(managedWorkbaseAgents).toContain(
|
|
190
|
+
"Never pass `--work` or `--auto` to `agency task create`",
|
|
165
191
|
)
|
|
166
|
-
expect(managedWorkbaseAgents).toContain("agency-kickoff-v1")
|
|
167
192
|
expect(managedWorkbaseAgents).toContain(
|
|
168
|
-
"
|
|
193
|
+
"Use `agency <command> --help` only as a recovery",
|
|
194
|
+
)
|
|
195
|
+
expect(managedWorkbaseAgents).not.toContain("`agency --help`")
|
|
196
|
+
expect(managedWorkbaseAgents).not.toContain(
|
|
197
|
+
"`agency worktree prepare <task>",
|
|
169
198
|
)
|
|
170
|
-
expect(managedWorkbaseAgents).toContain("exactly one final")
|
|
171
|
-
expect(managedWorkbaseAgents).toContain("leave the agent in the")
|
|
172
199
|
})
|
|
173
200
|
|
|
174
201
|
test("generates a dynamic workbase plugin", () => {
|
|
@@ -597,8 +624,10 @@ describe("IntegrationService", () => {
|
|
|
597
624
|
expect(body).toContain("Agency worker launch target: <target>.")
|
|
598
625
|
expect(body).toContain("environment variables and a generated")
|
|
599
626
|
expect(body).toContain("the initial instruction is a generated")
|
|
600
|
-
expect(body).toContain(
|
|
601
|
-
|
|
627
|
+
expect(body).toContain(
|
|
628
|
+
"External session state is never part of worker identity",
|
|
629
|
+
)
|
|
630
|
+
expect(body).toMatch(/If\s+the prompt\s+and context disagree/)
|
|
602
631
|
expect(body).toContain("marks execution work")
|
|
603
632
|
expect(body).toContain("without creating a claim")
|
|
604
633
|
expect(body).toContain("formatting, type checks, build, dead-code checks")
|
|
@@ -657,7 +686,9 @@ describe("IntegrationService", () => {
|
|
|
657
686
|
description:
|
|
658
687
|
"Handles Agency workbase orchestration and workflow operations with the Agency CLI",
|
|
659
688
|
mode: "subagent",
|
|
660
|
-
prompt: expect.
|
|
689
|
+
prompt: expect.stringMatching(
|
|
690
|
+
/agency context \. --json[\s\S]+agency work prepare[\s\S]+never pass `--work` or `--auto`/,
|
|
691
|
+
),
|
|
661
692
|
},
|
|
662
693
|
plan: {
|
|
663
694
|
disable: true,
|
|
@@ -689,10 +720,7 @@ describe("IntegrationService", () => {
|
|
|
689
720
|
expect(config.agent.agency.hidden).toBeUndefined()
|
|
690
721
|
expect(config.agent.agency.steps).toBeUndefined()
|
|
691
722
|
expect(config.agent.agency.prompt).toContain(
|
|
692
|
-
"
|
|
693
|
-
)
|
|
694
|
-
expect(config.agent.agency.prompt).toContain(
|
|
695
|
-
"return without waiting for the task to finish",
|
|
723
|
+
"Return the prepared execution contract to the caller",
|
|
696
724
|
)
|
|
697
725
|
expect(config.agent["agency-plan"].prompt).toContain(
|
|
698
726
|
"Start with `agency context . --json`",
|
package/src/workbase/AGENTS.md
CHANGED
|
@@ -4,6 +4,76 @@ This directory is an Agency workbase. Epics, tasks, and phases are durable
|
|
|
4
4
|
Markdown documents; repository aliases and generated Git worktrees or jj
|
|
5
5
|
workspaces provide code access according to the workbase's `vcs` setting.
|
|
6
6
|
|
|
7
|
+
## Command Fast Paths
|
|
8
|
+
|
|
9
|
+
When a request clearly matches one of these intents, use the exact recipe without
|
|
10
|
+
probing CLI help or listing unrelated workbase state. Substitute known values,
|
|
11
|
+
retain `--if-revision` guards when shown, and do not add flags that are not shown.
|
|
12
|
+
|
|
13
|
+
1. Create a single-phase task only:
|
|
14
|
+
`agency task create <slug> --repo <alias> --base <base> --description <text> --json`.
|
|
15
|
+
Add `--authoritative-source <absolute-path-or-url>` only for already known
|
|
16
|
+
sources. Return the creation result and stop.
|
|
17
|
+
2. Create, materialize, and start a single-phase task: run the create-only command,
|
|
18
|
+
then
|
|
19
|
+
`agency work prepare <slug> --evidence <creation-json-or-path> --json`.
|
|
20
|
+
Return the applied execution contract so the caller can run `commands.work`.
|
|
21
|
+
3. Materialize an existing execution unit without starting it:
|
|
22
|
+
`agency work prepare <task-or-document> --json`. Return the applied execution
|
|
23
|
+
contract and stop. Add `--dry-run` only when the user asks for a preview.
|
|
24
|
+
4. Reconcile remote pull-request state and completion:
|
|
25
|
+
`agency sync <task> [phase] --json`.
|
|
26
|
+
5. Convert an existing single-phase task and add a phase:
|
|
27
|
+
`agency phase create <task> <new-phase> --first-phase <existing-phase> --repo <alias> --branch <branch> --base <base> [--depends-on <existing-phase>] --json`.
|
|
28
|
+
6. Archive terminal work: first run `agency archive task <task> --dry-run --json`,
|
|
29
|
+
`agency archive phase <task> <phase> --dry-run --json`, or
|
|
30
|
+
`agency archive epic <epic> --dry-run --json`; if the preflight is safe,
|
|
31
|
+
repeat the same command without `--dry-run`.
|
|
32
|
+
7. Create and start review work: run either
|
|
33
|
+
`agency task create <slug> --review <alias> --pull-request <url-or-number> --json`
|
|
34
|
+
or `agency task create <slug> --review <alias> --ref <remote-ref> --json`, then
|
|
35
|
+
run `agency work prepare <slug> --evidence <creation-json-or-path> --json` and
|
|
36
|
+
return the applied execution contract so the caller can run `commands.work`.
|
|
37
|
+
8. Inspect one item with `agency context <task-or-document> --json`; inspect the
|
|
38
|
+
whole workbase with `agency status --json`.
|
|
39
|
+
9. Drop work with the current document revision: use
|
|
40
|
+
`agency task status <task> dropped --if-revision <revision> --json` or
|
|
41
|
+
`agency phase status <task> <phase> dropped --if-revision <revision> --json`.
|
|
42
|
+
10. Continue already materialized work: run
|
|
43
|
+
`agency work prepare <task-or-document> --json` and return the applied
|
|
44
|
+
execution contract so the caller can run `commands.work`.
|
|
45
|
+
11. Publish without a pull request from the execution checkout with
|
|
46
|
+
`agency push --json`. Create and record a pull request with
|
|
47
|
+
`agency pr create <task> [phase] [--draft] [--title <title>] [--label <label>] --json`;
|
|
48
|
+
do not run a separate push first because `pr create` owns publication.
|
|
49
|
+
12. Complete genuine non-PR work. For an active claim, run
|
|
50
|
+
`agency finish <task> [phase] --session-id <id> --revision <revision> --outcome done --no-pull-request --summary <text> [--evidence-url <url>]`.
|
|
51
|
+
Without a claim, run
|
|
52
|
+
`agency task status <task> done --if-revision <revision> --no-pull-request --summary <text> [--evidence-url <url>] --json`
|
|
53
|
+
or
|
|
54
|
+
`agency phase status <task> <phase> done --if-revision <revision> --no-pull-request --summary <text> [--evidence-url <url>] --json`.
|
|
55
|
+
13. Create a multi-phase task initially with
|
|
56
|
+
`agency task create <slug> --multi-phase --description <text> --json`, then
|
|
57
|
+
create each execution phase with
|
|
58
|
+
`agency phase create <slug> <phase> --repo <alias> --branch <branch> --base <base> [--depends-on <phase>] --json`.
|
|
59
|
+
14. Hand off an investigation to distinct implementation work with
|
|
60
|
+
`agency task handoff <investigation-task> <new-task> [--source-phase <phase>] --repo <alias> --base <base> --json`, then verify the returned destination with
|
|
61
|
+
`agency context <new-task> --json`. Do not prepare or start it unless requested.
|
|
62
|
+
15. Refresh a pinned review task with the current revision:
|
|
63
|
+
`agency review refresh <task> --if-revision <revision> --json`.
|
|
64
|
+
|
|
65
|
+
Never pass `--work` or `--auto` to `agency task create`. Do not run separate
|
|
66
|
+
`agency validate`, `agency worktree prepare`, `agency graph`, `agency task list`,
|
|
67
|
+
or `agency repo list` commands before these recipes when the required parameters
|
|
68
|
+
are already known. `agency work prepare` owns validation, readiness checks,
|
|
69
|
+
workspace materialization, and the versioned `agency-execution-v1` contract.
|
|
70
|
+
|
|
71
|
+
These fast paths take precedence over separately installed Agency skill guidance.
|
|
72
|
+
Use `agency <command> --help` only as a recovery step when no recipe matches or a
|
|
73
|
+
prescribed command rejects known-current syntax. The caller owns how prepared
|
|
74
|
+
execution is presented and started; Agency returns domain facts and native
|
|
75
|
+
commands without prescribing an execution environment.
|
|
76
|
+
|
|
7
77
|
## Bootstrap
|
|
8
78
|
|
|
9
79
|
Start every session with one read-only command:
|
|
@@ -18,7 +88,8 @@ from directory names or stale prose.
|
|
|
18
88
|
|
|
19
89
|
At the workbase root, use `agency next --json` or `agency graph --json` to choose
|
|
20
90
|
work, then inspect the returned document path or explicit entity selectors. Use
|
|
21
|
-
|
|
91
|
+
the command fast path above whenever the user's intent already identifies the
|
|
92
|
+
operation and required parameters.
|
|
22
93
|
|
|
23
94
|
## Adding a Repository
|
|
24
95
|
|
|
@@ -106,41 +177,6 @@ revision stale, and Agency must not silently rewrite that evidence.
|
|
|
106
177
|
|
|
107
178
|
## Execution
|
|
108
179
|
|
|
109
|
-
### Canonical create and kickoff
|
|
110
|
-
|
|
111
|
-
This Agency recipe takes precedence over generic Herdr defaults whenever the
|
|
112
|
-
request creates, opens, works, launches, starts, or kicks off an Agency item.
|
|
113
|
-
Do not rediscover commands that this recipe or a known-current
|
|
114
|
-
`agency-kickoff-v1` plan supplies.
|
|
115
|
-
|
|
116
|
-
1. Create noninteractively with explicit recalled context when available:
|
|
117
|
-
`agency task create <slug> --context-repo <alias> --context-base <base> --context-slug <slug> --authoritative-source <absolute-path-or-url> --json`.
|
|
118
|
-
Repeat `--authoritative-source` as needed. Supplied context must agree with
|
|
119
|
-
explicit task flags; Agency rejects stale or conflicting values.
|
|
120
|
-
2. For create-only intent, return the creation result and stop. For open intent,
|
|
121
|
-
prepare the task with
|
|
122
|
-
`agency work prepare <slug> --evidence <creation-json> --dry-run --json`, then
|
|
123
|
-
execute the returned plan through `task-document-split` to prepare the
|
|
124
|
-
checkout and open or reuse the background tab. Stop before `agent-start`.
|
|
125
|
-
3. For work/launch/start/kickoff intent, run that same preflight and execute its
|
|
126
|
-
ordered kickoff steps. The plan owns worktree dry-run/preparation, a
|
|
127
|
-
retry-safe background Herdr tab, the side-by-side task document,
|
|
128
|
-
`agency work . --auto`, and exactly one final
|
|
129
|
-
`agency context <document-path> --json` verification.
|
|
130
|
-
4. When the orchestrator has known-current support for the plan's
|
|
131
|
-
`agency-kickoff-v1` capability, execute the supplied actions directly. Do not
|
|
132
|
-
call Herdr help, skill, or CLI discovery. If capability/version evidence is
|
|
133
|
-
absent or stale, discovery is the compatibility path; then resume the same
|
|
134
|
-
idempotency key rather than creating another tab, checkout, or agent.
|
|
135
|
-
5. After the one final context verification succeeds, leave the agent in the
|
|
136
|
-
background and stop. Do not inspect, poll, or babysit it unless the user asks.
|
|
137
|
-
|
|
138
|
-
Validation evidence is a local, auditable optimization, not authority. Preflight
|
|
139
|
-
refreshes it after workbase, target document, configuration, repository mapping,
|
|
140
|
-
payload digest, or kickoff-contract changes. Readiness, claims, repository
|
|
141
|
-
materialization, branch ownership, reference drift, and dirty-workspace checks
|
|
142
|
-
still run on every preparation.
|
|
143
|
-
|
|
144
180
|
For implementation work, read the task and phase prose returned by context,
|
|
145
181
|
change only the writable checkout, keep durable decisions current, and run the
|
|
146
182
|
repository's formatting, type checks, build, dead-code checks, and focused tests.
|
|
@@ -171,8 +207,8 @@ environment variables. If the variables and prompt marker are absent, fail safe
|
|
|
171
207
|
when the initial instruction is a generated `Start`, `Continue`, or `Work on`
|
|
172
208
|
prompt whose absolute document paths match the current directory and the active,
|
|
173
209
|
valid `agency context`: treat the process as the current worker and do not
|
|
174
|
-
recursively launch.
|
|
175
|
-
and context disagree, stop and ask the user rather than launching.
|
|
210
|
+
recursively launch. External session state is never part of worker identity. If
|
|
211
|
+
the prompt and context disagree, stop and ask the user rather than launching.
|
|
176
212
|
|
|
177
213
|
For OpenCode, Agency's managed plugin validates the generated marker against
|
|
178
214
|
`agency context`, binds that identity to the OpenCode session, injects an
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
|
|
2
2
|
import { mkdir } from "node:fs/promises"
|
|
3
|
-
import { join } from "node:path"
|
|
3
|
+
import { dirname, join } from "node:path"
|
|
4
4
|
import { cleanupTempDir, createTempDir, runTestEffect } from "../test-utils"
|
|
5
5
|
import { documentRevision } from "./document-revision"
|
|
6
6
|
import {
|
|
7
7
|
assessValidationEvidence,
|
|
8
|
-
|
|
8
|
+
buildExecutionContract,
|
|
9
9
|
buildValidationEvidence,
|
|
10
|
-
|
|
10
|
+
EXECUTION_SOURCE_LOCATIONS,
|
|
11
11
|
normalizeRecalledContext,
|
|
12
12
|
parseValidationEvidence,
|
|
13
13
|
readValidationEvidence,
|
|
14
|
-
} from "./
|
|
14
|
+
} from "./execution-contract"
|
|
15
15
|
|
|
16
|
-
describe("
|
|
16
|
+
describe("execution contract", () => {
|
|
17
17
|
let root: string
|
|
18
18
|
let taskPath: string
|
|
19
19
|
let taskContent: string
|
|
@@ -102,44 +102,60 @@ describe("kickoff contract", () => {
|
|
|
102
102
|
)
|
|
103
103
|
})
|
|
104
104
|
|
|
105
|
-
test("
|
|
106
|
-
const
|
|
105
|
+
test("describes prepared execution without prescribing orchestration", () => {
|
|
106
|
+
const checkoutPath = join(root, "tasks/example/code/agency")
|
|
107
|
+
const applied = buildExecutionContract({
|
|
107
108
|
workbaseRoot: root,
|
|
108
109
|
target: "execution-unit:task/example",
|
|
109
|
-
taskId: "example",
|
|
110
110
|
taskPath,
|
|
111
|
-
checkoutPath
|
|
111
|
+
checkoutPath,
|
|
112
112
|
documentRevision: "a".repeat(64),
|
|
113
|
+
dryRun: false,
|
|
113
114
|
})
|
|
114
|
-
const
|
|
115
|
+
const phasePath = join(root, "tasks/example/phases/implementation/PHASE.md")
|
|
116
|
+
const preview = buildExecutionContract({
|
|
115
117
|
workbaseRoot: root,
|
|
116
118
|
target: "execution-unit:phase/example/implementation",
|
|
117
|
-
taskId: "example",
|
|
118
|
-
phaseId: "implementation",
|
|
119
119
|
taskPath,
|
|
120
|
-
phasePath
|
|
120
|
+
phasePath,
|
|
121
|
+
checkoutPath: join(
|
|
122
|
+
root,
|
|
123
|
+
"tasks/example/phases/implementation/code/agency",
|
|
124
|
+
),
|
|
121
125
|
documentRevision: "b".repeat(64),
|
|
126
|
+
dryRun: true,
|
|
122
127
|
})
|
|
123
|
-
expect(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
128
|
+
expect(applied).toMatchObject({
|
|
129
|
+
capability: "agency-execution-v1",
|
|
130
|
+
mode: "applied",
|
|
131
|
+
workspace: {
|
|
132
|
+
state: "materialized",
|
|
133
|
+
checkoutPath,
|
|
134
|
+
},
|
|
135
|
+
commands: {
|
|
136
|
+
work: {
|
|
137
|
+
cwd: dirname(taskPath),
|
|
138
|
+
argv: ["agency", "work", ".", "--auto"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
expect(applied.sourceLocations).toEqual(EXECUTION_SOURCE_LOCATIONS)
|
|
143
|
+
expect(preview).toMatchObject({
|
|
144
|
+
mode: "preview",
|
|
145
|
+
workspace: { state: "planned" },
|
|
146
|
+
plannedActions: [{ kind: "workspace-materialization" }],
|
|
147
|
+
commands: {
|
|
148
|
+
context: { cwd: dirname(phasePath) },
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
expect(applied.executionIdentity.key).toBe(
|
|
152
|
+
buildExecutionContract({
|
|
137
153
|
workbaseRoot: root,
|
|
138
154
|
target: "execution-unit:task/example",
|
|
139
|
-
taskId: "example",
|
|
140
155
|
taskPath,
|
|
141
156
|
documentRevision: "a".repeat(64),
|
|
142
|
-
|
|
157
|
+
dryRun: true,
|
|
158
|
+
}).executionIdentity.key,
|
|
143
159
|
)
|
|
144
160
|
})
|
|
145
161
|
})
|
|
@@ -5,11 +5,11 @@ import { FileSystemService } from "../services/FileSystemService"
|
|
|
5
5
|
import { WorkbaseService } from "../services/WorkbaseService"
|
|
6
6
|
import { documentRevision } from "./document-revision"
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const EXECUTION_CONTRACT_VERSION = 1 as const
|
|
9
9
|
|
|
10
|
-
export const
|
|
10
|
+
export const EXECUTION_SOURCE_LOCATIONS = [
|
|
11
11
|
"src/commands/task.ts",
|
|
12
|
-
"src/workbase/
|
|
12
|
+
"src/workbase/execution-contract.ts",
|
|
13
13
|
"src/commands/work.ts",
|
|
14
14
|
"src/services/WorktreeService.ts",
|
|
15
15
|
"src/workbase/AGENTS.md",
|
|
@@ -25,7 +25,7 @@ export const RecalledTaskContext = Schema.Struct({
|
|
|
25
25
|
export type RecalledTaskContext = Schema.Schema.Type<typeof RecalledTaskContext>
|
|
26
26
|
|
|
27
27
|
const ValidationEvidencePayload = Schema.Struct({
|
|
28
|
-
version: Schema.Literal(
|
|
28
|
+
version: Schema.Literal(EXECUTION_CONTRACT_VERSION),
|
|
29
29
|
workbaseRoot: Schema.String,
|
|
30
30
|
target: Schema.String,
|
|
31
31
|
documentPath: Schema.String,
|
|
@@ -166,7 +166,7 @@ export const buildValidationEvidence = (input: {
|
|
|
166
166
|
Effect.gen(function* () {
|
|
167
167
|
const identity = yield* workbaseIdentity(input.startPath)
|
|
168
168
|
const payload = {
|
|
169
|
-
version:
|
|
169
|
+
version: EXECUTION_CONTRACT_VERSION,
|
|
170
170
|
workbaseRoot: identity.root,
|
|
171
171
|
target: input.target,
|
|
172
172
|
documentPath: resolve(input.documentPath),
|
|
@@ -208,7 +208,7 @@ export const readValidationEvidence = (input: string, cwd: string) =>
|
|
|
208
208
|
parsed?.validationEvidence?.evidence ??
|
|
209
209
|
parsed?.evidence ??
|
|
210
210
|
(parsed?.target && parsed?.documentRevision ? parsed : undefined)
|
|
211
|
-
if (!candidate || candidate.version !==
|
|
211
|
+
if (!candidate || candidate.version !== EXECUTION_CONTRACT_VERSION) {
|
|
212
212
|
return undefined
|
|
213
213
|
}
|
|
214
214
|
return parseValidationEvidence(candidate)
|
|
@@ -259,100 +259,61 @@ export const assessValidationEvidence = (input: {
|
|
|
259
259
|
}
|
|
260
260
|
})
|
|
261
261
|
|
|
262
|
-
export const
|
|
262
|
+
export const buildExecutionContract = (input: {
|
|
263
263
|
readonly workbaseRoot: string
|
|
264
264
|
readonly target: string
|
|
265
|
-
readonly taskId: string
|
|
266
|
-
readonly phaseId?: string
|
|
267
265
|
readonly taskPath: string
|
|
268
266
|
readonly phasePath?: string | null
|
|
269
267
|
readonly checkoutPath?: string | null
|
|
270
268
|
readonly documentRevision: string
|
|
269
|
+
readonly dryRun: boolean
|
|
271
270
|
}) => {
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
version: KICKOFF_CONTRACT_VERSION,
|
|
271
|
+
const executionDirectory = dirname(input.phasePath ?? input.taskPath)
|
|
272
|
+
const key = digest({
|
|
273
|
+
version: EXECUTION_CONTRACT_VERSION,
|
|
276
274
|
workbaseRoot: input.workbaseRoot,
|
|
277
275
|
target: input.target,
|
|
278
276
|
})
|
|
277
|
+
const documentPath = input.phasePath ?? input.taskPath
|
|
278
|
+
const mode = input.dryRun ? "preview" : "applied"
|
|
279
279
|
return {
|
|
280
|
-
version:
|
|
281
|
-
|
|
280
|
+
version: EXECUTION_CONTRACT_VERSION,
|
|
281
|
+
capability: "agency-execution-v1" as const,
|
|
282
|
+
mode,
|
|
283
|
+
executionIdentity: {
|
|
284
|
+
key,
|
|
285
|
+
target: input.target,
|
|
286
|
+
documentRevision: input.documentRevision,
|
|
287
|
+
},
|
|
282
288
|
workbaseRoot: input.workbaseRoot,
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
orchestrator: {
|
|
291
|
-
capability: "agency-kickoff-v1",
|
|
292
|
-
knownCurrentCommandsBypassDiscovery: true,
|
|
293
|
-
fallback:
|
|
294
|
-
"Discover Herdr capabilities only when capability/version evidence is absent or stale.",
|
|
289
|
+
sourceLocations: EXECUTION_SOURCE_LOCATIONS,
|
|
290
|
+
workspace: {
|
|
291
|
+
state: input.dryRun ? ("planned" as const) : ("materialized" as const),
|
|
292
|
+
executionDirectory,
|
|
293
|
+
taskDocument: input.taskPath,
|
|
294
|
+
phaseDocument: input.phasePath ?? null,
|
|
295
|
+
checkoutPath: input.checkoutPath ?? null,
|
|
295
296
|
},
|
|
296
|
-
|
|
297
|
-
{
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
id: "worktree-prepare",
|
|
311
|
-
argv: ["agency", "worktree", "prepare", ...selector, "--json"],
|
|
312
|
-
retry: "reuses matching clean workspaces",
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
id: "herdr-tab",
|
|
316
|
-
action: "create-or-reuse-background-tab",
|
|
317
|
-
idempotencyKey,
|
|
318
|
-
recovery:
|
|
319
|
-
"Reuse the tab recorded for this idempotency key; never create a duplicate.",
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
id: "task-document-split",
|
|
323
|
-
action: "open-side-by-side-document",
|
|
324
|
-
path: input.phasePath ?? input.taskPath,
|
|
325
|
-
recovery: "Reuse the existing split when present.",
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
id: "agent-start",
|
|
329
|
-
cwd: taskDirectory,
|
|
297
|
+
...(input.dryRun
|
|
298
|
+
? {
|
|
299
|
+
plannedActions: [
|
|
300
|
+
{
|
|
301
|
+
kind: "workspace-materialization" as const,
|
|
302
|
+
target: input.target,
|
|
303
|
+
checkoutPath: input.checkoutPath ?? null,
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
}
|
|
307
|
+
: {}),
|
|
308
|
+
commands: {
|
|
309
|
+
work: {
|
|
310
|
+
cwd: executionDirectory,
|
|
330
311
|
argv: ["agency", "work", ".", "--auto"],
|
|
331
|
-
recovery:
|
|
332
|
-
"Inspect the recorded tab before retrying; a working agent must not be duplicated.",
|
|
333
312
|
},
|
|
334
|
-
{
|
|
335
|
-
|
|
336
|
-
argv: [
|
|
337
|
-
"agency",
|
|
338
|
-
"context",
|
|
339
|
-
input.phasePath ?? input.taskPath,
|
|
340
|
-
"--json",
|
|
341
|
-
],
|
|
342
|
-
exactlyOnce: true,
|
|
343
|
-
recovery:
|
|
344
|
-
"If verification fails, inspect the existing tab; do not launch another agent.",
|
|
313
|
+
context: {
|
|
314
|
+
cwd: executionDirectory,
|
|
315
|
+
argv: ["agency", "context", documentPath, "--json"],
|
|
345
316
|
},
|
|
346
|
-
|
|
347
|
-
successFields: [
|
|
348
|
-
"target",
|
|
349
|
-
"taskDirectory",
|
|
350
|
-
"taskDocument",
|
|
351
|
-
"preparedCheckout",
|
|
352
|
-
"herdrWorkspace",
|
|
353
|
-
"herdrTab",
|
|
354
|
-
"agentStart",
|
|
355
|
-
"contextVerification",
|
|
356
|
-
],
|
|
317
|
+
},
|
|
357
318
|
}
|
|
358
319
|
}
|
|
@@ -20,6 +20,12 @@ const agencyPlanBashPermissions = {
|
|
|
20
20
|
"agency *": "allow",
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
const agencyAgentPrompt = `You are the Agency workflow specialist. Use the Agency CLI to handle delegated workbase orchestration and workflow operations. Always start with \`agency context . --json\` and follow the managed Agency instructions and reported authority.
|
|
24
|
+
|
|
25
|
+
When the intent and parameters are known, use the matching managed Command Fast Path exactly. The recipes cover creation, preparation, synchronization, phase conversion, archiving, review work, inspection, dropping, continuation, publication, pull requests, non-PR completion, multi-phase setup, investigation handoff, and review refresh. Preparation recipes call \`agency work prepare <task-or-document> --json\`. Do not probe help or list unrelated state, never pass \`--work\` or \`--auto\` to \`agency task create\`, and use \`--dry-run\` only where the recipe or caller requests it. Use CLI discovery only when no fast-path recipe matches or a prescribed command rejects known-current syntax.
|
|
26
|
+
|
|
27
|
+
Return the prepared execution contract to the caller. Agency owns the target, validation, materialized workspace facts, and native commands; the caller owns presentation and process orchestration.`
|
|
28
|
+
|
|
23
29
|
const body = () =>
|
|
24
30
|
`${JSON.stringify(
|
|
25
31
|
{
|
|
@@ -30,8 +36,7 @@ const body = () =>
|
|
|
30
36
|
description:
|
|
31
37
|
"Handles Agency workbase orchestration and workflow operations with the Agency CLI",
|
|
32
38
|
mode: "subagent",
|
|
33
|
-
prompt:
|
|
34
|
-
"You are the Agency workflow specialist. Use the Agency CLI to handle delegated workbase orchestration and workflow operations. Always start with `agency context . --json`, follow the managed Agency instructions and reported authority, use Agency commands for durable mutations, and report the resulting state concisely. When delegated to start or kick off work in another agent, launch it, verify that the agent started successfully, and return without waiting for the task to finish.",
|
|
39
|
+
prompt: agencyAgentPrompt,
|
|
35
40
|
},
|
|
36
41
|
plan: {
|
|
37
42
|
disable: true,
|