@markjaquith/agency 1.11.0 → 2.0.0
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 +302 -113
- package/cli.ts +123 -415
- package/index.ts +1 -1
- package/package.json +12 -17
- package/skills/agency/SKILL.md +258 -0
- package/src/cli.test.ts +290 -0
- package/src/commands/description.test.ts +103 -0
- package/src/commands/epic.test.ts +103 -0
- package/src/commands/epic.ts +101 -0
- package/src/commands/init.test.ts +42 -290
- package/src/commands/init.ts +15 -123
- package/src/commands/phase.ts +120 -0
- package/src/commands/pr.test.ts +19 -170
- package/src/commands/pr.ts +23 -179
- package/src/commands/repo.test.ts +80 -0
- package/src/commands/repo.ts +83 -0
- package/src/commands/status.test.ts +35 -477
- package/src/commands/status.ts +24 -213
- package/src/commands/task-phase.test.ts +206 -0
- package/src/commands/task.ts +83 -1285
- package/src/commands/validate.test.ts +91 -0
- package/src/commands/validate.ts +50 -0
- package/src/commands/work.test.ts +172 -419
- package/src/commands/work.ts +47 -166
- package/src/services/EpicService.test.ts +71 -0
- package/src/services/EpicService.ts +135 -0
- package/src/services/FileSystemService.ts +61 -92
- package/src/services/PhaseService.ts +323 -0
- package/src/services/PullRequestService.test.ts +386 -0
- package/src/services/PullRequestService.ts +143 -0
- package/src/services/RepositoryService.test.ts +106 -0
- package/src/services/RepositoryService.ts +159 -0
- package/src/services/TaskPhaseService.test.ts +217 -0
- package/src/services/TaskService.ts +192 -0
- package/src/services/WorkbaseService.test.ts +446 -0
- package/src/services/WorkbaseService.ts +493 -0
- package/src/services/WorktreeService.test.ts +599 -0
- package/src/services/WorktreeService.ts +357 -0
- package/src/test-utils.ts +41 -438
- package/src/types.ts +1 -215
- package/src/utils/command.ts +1 -5
- package/src/utils/effect.test.ts +24 -0
- package/src/utils/effect.ts +3 -273
- package/src/utils/process.test.ts +0 -15
- package/src/utils/process.ts +1 -60
- package/src/workbase/frontmatter.test.ts +50 -0
- package/src/workbase/frontmatter.ts +77 -0
- package/src/workbase/repository-reference.test.ts +25 -0
- package/src/workbase/repository-reference.ts +18 -0
- package/src/workbase/schemas.test.ts +146 -0
- package/src/workbase/schemas.ts +78 -0
- package/src/workbase/worktree-command.test.ts +61 -0
- package/src/workbase/worktree-command.ts +52 -0
- package/src/commands/base.test.ts +0 -198
- package/src/commands/base.ts +0 -198
- package/src/commands/clean.test.ts +0 -299
- package/src/commands/clean.ts +0 -274
- package/src/commands/completions.test.ts +0 -51
- package/src/commands/completions.ts +0 -308
- package/src/commands/emit.integration.test.ts +0 -549
- package/src/commands/emit.test.ts +0 -576
- package/src/commands/emit.ts +0 -700
- package/src/commands/emitted.test.ts +0 -226
- package/src/commands/emitted.ts +0 -57
- package/src/commands/loop.test.ts +0 -621
- package/src/commands/loop.ts +0 -406
- package/src/commands/merge.integration.test.ts +0 -195
- package/src/commands/merge.test.ts +0 -246
- package/src/commands/merge.ts +0 -244
- package/src/commands/pull.test.ts +0 -395
- package/src/commands/pull.ts +0 -205
- package/src/commands/push.test.ts +0 -518
- package/src/commands/push.ts +0 -434
- package/src/commands/rebase.test.ts +0 -521
- package/src/commands/rebase.ts +0 -232
- package/src/commands/save.test.ts +0 -247
- package/src/commands/save.ts +0 -162
- package/src/commands/source.test.ts +0 -195
- package/src/commands/source.ts +0 -72
- package/src/commands/switch.test.ts +0 -194
- package/src/commands/switch.ts +0 -84
- package/src/commands/task-branching.test.ts +0 -633
- package/src/commands/task-continue.test.ts +0 -311
- package/src/commands/task-edit.test.ts +0 -235
- package/src/commands/task-main.test.ts +0 -1066
- package/src/commands/task-squash.test.ts +0 -266
- package/src/commands/tasks.test.ts +0 -391
- package/src/commands/tasks.ts +0 -161
- package/src/commands/template-delete.test.ts +0 -178
- package/src/commands/template-delete.ts +0 -98
- package/src/commands/template-list.test.ts +0 -135
- package/src/commands/template-list.ts +0 -87
- package/src/commands/template-view.test.ts +0 -158
- package/src/commands/template-view.ts +0 -86
- package/src/commands/template.test.ts +0 -32
- package/src/commands/template.ts +0 -96
- package/src/commands/use.test.ts +0 -87
- package/src/commands/use.ts +0 -97
- package/src/constants.ts +0 -10
- package/src/errors.ts +0 -17
- package/src/schemas.ts +0 -33
- package/src/services/AgencyMetadataService.ts +0 -311
- package/src/services/ClaudeService.test.ts +0 -184
- package/src/services/ClaudeService.ts +0 -91
- package/src/services/ConfigService.ts +0 -115
- package/src/services/FilterRepoService.ts +0 -164
- package/src/services/FormatterService.test.ts +0 -432
- package/src/services/FormatterService.ts +0 -219
- package/src/services/GitService.ts +0 -1183
- package/src/services/MockFilterRepoService.ts +0 -140
- package/src/services/OpencodeService.ts +0 -263
- package/src/services/PromptService.ts +0 -183
- package/src/services/TemplateService.ts +0 -81
- package/src/types/native-exec.d.ts +0 -8
- package/src/utils/colors.ts +0 -178
- package/src/utils/git-path.ts +0 -6
- package/src/utils/glob.test.ts +0 -161
- package/src/utils/glob.ts +0 -78
- package/src/utils/paths.ts +0 -51
- package/src/utils/pr-branch.test.ts +0 -376
- package/src/utils/pr-branch.ts +0 -508
- package/src/utils/spinner.test.ts +0 -45
- package/src/utils/spinner.ts +0 -96
- package/src/utils/task-parser.test.ts +0 -172
- package/src/utils/task-parser.ts +0 -93
- package/templates/AGENCY.md +0 -22
- package/templates/AGENTS.md +0 -11
- package/templates/CLAUDE.md +0 -3
- package/templates/TASK.md +0 -5
- package/templates/opencode.json +0 -4
package/cli.ts
CHANGED
|
@@ -1,52 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
import { parseArgs } from "util"
|
|
4
|
-
import { Effect, Layer } from "effect"
|
|
5
|
-
import { clean, help as cleanHelp } from "./src/commands/clean"
|
|
4
|
+
import { Effect, Either, Layer } from "effect"
|
|
6
5
|
import { init, help as initHelp } from "./src/commands/init"
|
|
7
|
-
import { task,
|
|
8
|
-
import { tasks, help as tasksHelp } from "./src/commands/tasks"
|
|
9
|
-
import { emit, help as emitHelp } from "./src/commands/emit"
|
|
10
|
-
import { emitted, help as emittedHelp } from "./src/commands/emitted"
|
|
6
|
+
import { task, help as taskHelp } from "./src/commands/task"
|
|
11
7
|
import { pr, help as prHelp } from "./src/commands/pr"
|
|
12
|
-
import { push, help as pushHelp } from "./src/commands/push"
|
|
13
|
-
import { pull, help as pullHelp } from "./src/commands/pull"
|
|
14
|
-
import { rebase, help as rebaseHelp } from "./src/commands/rebase"
|
|
15
|
-
import { base, help as baseHelp } from "./src/commands/base"
|
|
16
|
-
import { switchBranch, help as switchHelp } from "./src/commands/switch"
|
|
17
|
-
import { source, help as sourceHelp } from "./src/commands/source"
|
|
18
|
-
import { merge, help as mergeHelp } from "./src/commands/merge"
|
|
19
|
-
import { template, help as templateHelp } from "./src/commands/template"
|
|
20
8
|
import { work, help as workHelp } from "./src/commands/work"
|
|
21
|
-
import { loop, help as loopHelp } from "./src/commands/loop"
|
|
22
9
|
import { status, help as statusHelp } from "./src/commands/status"
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} from "./src/commands/
|
|
10
|
+
import { validate, help as validateHelp } from "./src/commands/validate"
|
|
11
|
+
import { repo, help as repoHelp } from "./src/commands/repo"
|
|
12
|
+
import { epic, help as epicHelp } from "./src/commands/epic"
|
|
13
|
+
import { phase, help as phaseHelp } from "./src/commands/phase"
|
|
27
14
|
import type { Command } from "./src/types"
|
|
28
|
-
import { setColorsEnabled } from "./src/utils/colors"
|
|
29
|
-
import { GitService } from "./src/services/GitService"
|
|
30
|
-
import { ConfigService } from "./src/services/ConfigService"
|
|
31
15
|
import { FileSystemService } from "./src/services/FileSystemService"
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
16
|
+
import { WorkbaseService } from "./src/services/WorkbaseService"
|
|
17
|
+
import { RepositoryService } from "./src/services/RepositoryService"
|
|
18
|
+
import { EpicService } from "./src/services/EpicService"
|
|
19
|
+
import { TaskService } from "./src/services/TaskService"
|
|
20
|
+
import { PhaseService } from "./src/services/PhaseService"
|
|
21
|
+
import { WorktreeService } from "./src/services/WorktreeService"
|
|
22
|
+
import { PullRequestService } from "./src/services/PullRequestService"
|
|
38
23
|
|
|
39
24
|
// Create CLI layer with all services
|
|
40
25
|
const CliLayer = Layer.mergeAll(
|
|
41
|
-
GitService.Default,
|
|
42
|
-
ConfigService.Default,
|
|
43
26
|
FileSystemService.Default,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
WorkbaseService.Default,
|
|
28
|
+
RepositoryService.Default,
|
|
29
|
+
EpicService.Default,
|
|
30
|
+
TaskService.Default,
|
|
31
|
+
PhaseService.Default,
|
|
32
|
+
WorktreeService.Default,
|
|
33
|
+
PullRequestService.Default,
|
|
50
34
|
)
|
|
51
35
|
|
|
52
36
|
/**
|
|
@@ -61,31 +45,28 @@ async function runCommand<E>(
|
|
|
61
45
|
never
|
|
62
46
|
>
|
|
63
47
|
|
|
64
|
-
|
|
65
|
-
const programWithErrorHandling = Effect.catchAll(providedEffect, (error) => {
|
|
66
|
-
// Convert typed errors to standard Error objects with clear messages
|
|
48
|
+
const toError = (error: unknown) => {
|
|
67
49
|
if (error instanceof Error) {
|
|
68
|
-
return
|
|
50
|
+
return error
|
|
69
51
|
}
|
|
70
|
-
// Handle objects with message property (common pattern for tagged errors)
|
|
71
52
|
if (
|
|
72
53
|
typeof error === "object" &&
|
|
73
54
|
error !== null &&
|
|
74
55
|
"message" in error &&
|
|
75
56
|
typeof error.message === "string"
|
|
76
57
|
) {
|
|
77
|
-
return
|
|
58
|
+
return new Error(error.message)
|
|
78
59
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
})
|
|
60
|
+
return new Error(String(error))
|
|
61
|
+
}
|
|
82
62
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
63
|
+
const result = await Effect.runPromise(
|
|
64
|
+
providedEffect.pipe(
|
|
65
|
+
Effect.catchAllDefect((defect) => Effect.fail(toError(defect))),
|
|
66
|
+
Effect.either,
|
|
67
|
+
),
|
|
86
68
|
)
|
|
87
|
-
|
|
88
|
-
await Effect.runPromise(program)
|
|
69
|
+
if (Either.isLeft(result)) throw toError(result.left)
|
|
89
70
|
}
|
|
90
71
|
|
|
91
72
|
// Read version from package.json
|
|
@@ -97,320 +78,143 @@ const VERSION = packageJson.version
|
|
|
97
78
|
// Define commands
|
|
98
79
|
const commands: Record<string, Command> = {
|
|
99
80
|
init: {
|
|
100
|
-
|
|
101
|
-
description: "Initialize agency with template selection",
|
|
102
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
81
|
+
run: async (args: string[], options: Record<string, any>) => {
|
|
103
82
|
if (options.help) {
|
|
104
83
|
console.log(initHelp)
|
|
105
84
|
return
|
|
106
85
|
}
|
|
107
86
|
await runCommand(
|
|
108
87
|
init({
|
|
109
|
-
|
|
88
|
+
path: args[0],
|
|
89
|
+
json: options.json,
|
|
110
90
|
silent: options.silent,
|
|
111
91
|
verbose: options.verbose,
|
|
112
92
|
}),
|
|
113
93
|
)
|
|
114
94
|
},
|
|
115
|
-
help: initHelp,
|
|
116
95
|
},
|
|
117
|
-
|
|
118
|
-
name: "emit",
|
|
119
|
-
description: "Emit a branch without backpack files",
|
|
96
|
+
epic: {
|
|
120
97
|
run: async (args: string[], options: Record<string, any>) => {
|
|
121
98
|
if (options.help) {
|
|
122
|
-
console.log(
|
|
99
|
+
console.log(epicHelp)
|
|
123
100
|
return
|
|
124
101
|
}
|
|
125
102
|
await runCommand(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
103
|
+
epic({
|
|
104
|
+
subcommand: args[0],
|
|
105
|
+
args: args.slice(1),
|
|
106
|
+
ticketUrl: options["ticket-url"],
|
|
107
|
+
description: options.description,
|
|
108
|
+
repos: options.repo,
|
|
109
|
+
json: options.json,
|
|
129
110
|
silent: options.silent,
|
|
130
|
-
force: options.verbose,
|
|
131
111
|
verbose: options.verbose,
|
|
132
112
|
}),
|
|
133
113
|
)
|
|
134
114
|
},
|
|
135
|
-
help: emitHelp,
|
|
136
|
-
},
|
|
137
|
-
emitted: {
|
|
138
|
-
name: "emitted",
|
|
139
|
-
description: "Get the name of the emitted branch",
|
|
140
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
141
|
-
if (options.help) {
|
|
142
|
-
console.log(emittedHelp)
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
await runCommand(
|
|
146
|
-
emitted({ silent: options.silent, verbose: options.verbose }),
|
|
147
|
-
)
|
|
148
|
-
},
|
|
149
|
-
help: emittedHelp,
|
|
150
115
|
},
|
|
151
116
|
pr: {
|
|
152
|
-
|
|
153
|
-
description: "Run gh pr with the emitted branch name",
|
|
154
|
-
run: async (
|
|
155
|
-
_args: string[],
|
|
156
|
-
options: Record<string, any>,
|
|
157
|
-
rawArgs?: string[],
|
|
158
|
-
) => {
|
|
117
|
+
run: async (args: string[], options: Record<string, any>) => {
|
|
159
118
|
if (options.help) {
|
|
160
119
|
console.log(prHelp)
|
|
161
120
|
return
|
|
162
121
|
}
|
|
163
|
-
// Pass raw args (after filtering agency flags) directly to gh pr
|
|
164
|
-
// This allows flags like --web to pass through without needing --
|
|
165
|
-
const agencyFlags = ["--help", "-h", "--silent", "-s", "--verbose", "-v"]
|
|
166
|
-
const filteredArgs = (rawArgs ?? []).filter(
|
|
167
|
-
(arg) => !agencyFlags.includes(arg),
|
|
168
|
-
)
|
|
169
122
|
await runCommand(
|
|
170
123
|
pr({
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
},
|
|
177
|
-
help: prHelp,
|
|
178
|
-
},
|
|
179
|
-
push: {
|
|
180
|
-
name: "push",
|
|
181
|
-
description: "Emit, push to remote, return to source",
|
|
182
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
183
|
-
if (options.help) {
|
|
184
|
-
console.log(pushHelp)
|
|
185
|
-
return
|
|
186
|
-
}
|
|
187
|
-
await runCommand(
|
|
188
|
-
push({
|
|
189
|
-
baseBranch: args[0],
|
|
190
|
-
emit: options.emit || options.branch,
|
|
191
|
-
silent: options.silent,
|
|
192
|
-
force: options.force,
|
|
193
|
-
noVerify: options["no-verify"],
|
|
194
|
-
verbose: options.verbose,
|
|
195
|
-
pr: options.pr,
|
|
196
|
-
}),
|
|
197
|
-
)
|
|
198
|
-
},
|
|
199
|
-
help: pushHelp,
|
|
200
|
-
},
|
|
201
|
-
pull: {
|
|
202
|
-
name: "pull",
|
|
203
|
-
description: "Pull commits from remote emit branch to source",
|
|
204
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
205
|
-
if (options.help) {
|
|
206
|
-
console.log(pullHelp)
|
|
207
|
-
return
|
|
208
|
-
}
|
|
209
|
-
await runCommand(
|
|
210
|
-
pull({
|
|
211
|
-
remote: options.remote,
|
|
212
|
-
silent: options.silent,
|
|
213
|
-
verbose: options.verbose,
|
|
214
|
-
}),
|
|
215
|
-
)
|
|
216
|
-
},
|
|
217
|
-
help: pullHelp,
|
|
218
|
-
},
|
|
219
|
-
rebase: {
|
|
220
|
-
name: "rebase",
|
|
221
|
-
description: "Rebase source branch onto base branch",
|
|
222
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
223
|
-
if (options.help) {
|
|
224
|
-
console.log(rebaseHelp)
|
|
225
|
-
return
|
|
226
|
-
}
|
|
227
|
-
await runCommand(
|
|
228
|
-
rebase({
|
|
229
|
-
baseBranch: args[0],
|
|
230
|
-
emit: options.emit || options.branch,
|
|
124
|
+
subcommand: args[0],
|
|
125
|
+
taskId: args[1],
|
|
126
|
+
phaseId: args[2],
|
|
127
|
+
draft: options.draft,
|
|
128
|
+
json: options.json,
|
|
231
129
|
silent: options.silent,
|
|
232
130
|
verbose: options.verbose,
|
|
233
131
|
}),
|
|
234
132
|
)
|
|
235
133
|
},
|
|
236
|
-
help: rebaseHelp,
|
|
237
134
|
},
|
|
238
|
-
|
|
239
|
-
name: "template",
|
|
240
|
-
description: "Template management commands",
|
|
135
|
+
phase: {
|
|
241
136
|
run: async (args: string[], options: Record<string, any>) => {
|
|
242
|
-
if (options.help)
|
|
243
|
-
console.log(templateHelp)
|
|
244
|
-
return
|
|
245
|
-
}
|
|
137
|
+
if (options.help) return console.log(phaseHelp)
|
|
246
138
|
await runCommand(
|
|
247
|
-
|
|
139
|
+
phase({
|
|
248
140
|
subcommand: args[0],
|
|
249
141
|
args: args.slice(1),
|
|
142
|
+
description: options.description,
|
|
143
|
+
repo: options.repo?.[0],
|
|
144
|
+
references: options.reference,
|
|
145
|
+
branch: options.branch,
|
|
146
|
+
base: options.base,
|
|
147
|
+
dependsOn: options["depends-on"],
|
|
148
|
+
firstPhase: options["first-phase"],
|
|
149
|
+
json: options.json,
|
|
250
150
|
silent: options.silent,
|
|
251
151
|
verbose: options.verbose,
|
|
252
|
-
template: options.template,
|
|
253
152
|
}),
|
|
254
153
|
)
|
|
255
154
|
},
|
|
256
|
-
help: templateHelp,
|
|
257
155
|
},
|
|
258
|
-
|
|
259
|
-
name: "base",
|
|
260
|
-
description: "Get or set the base branch",
|
|
156
|
+
repo: {
|
|
261
157
|
run: async (args: string[], options: Record<string, any>) => {
|
|
262
158
|
if (options.help) {
|
|
263
|
-
console.log(
|
|
159
|
+
console.log(repoHelp)
|
|
264
160
|
return
|
|
265
161
|
}
|
|
266
162
|
await runCommand(
|
|
267
|
-
|
|
163
|
+
repo({
|
|
268
164
|
subcommand: args[0],
|
|
269
165
|
args: args.slice(1),
|
|
270
|
-
repo: options.repo,
|
|
271
|
-
silent: options.silent,
|
|
272
|
-
verbose: options.verbose,
|
|
273
|
-
}),
|
|
274
|
-
)
|
|
275
|
-
},
|
|
276
|
-
help: baseHelp,
|
|
277
|
-
},
|
|
278
|
-
switch: {
|
|
279
|
-
name: "switch",
|
|
280
|
-
description: "Toggle between source and emitted branch",
|
|
281
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
282
|
-
if (options.help) {
|
|
283
|
-
console.log(switchHelp)
|
|
284
|
-
return
|
|
285
|
-
}
|
|
286
|
-
await runCommand(
|
|
287
|
-
switchBranch({ silent: options.silent, verbose: options.verbose }),
|
|
288
|
-
)
|
|
289
|
-
},
|
|
290
|
-
help: switchHelp,
|
|
291
|
-
},
|
|
292
|
-
source: {
|
|
293
|
-
name: "source",
|
|
294
|
-
description: "Switch to source branch from emitted branch",
|
|
295
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
296
|
-
if (options.help) {
|
|
297
|
-
console.log(sourceHelp)
|
|
298
|
-
return
|
|
299
|
-
}
|
|
300
|
-
await runCommand(
|
|
301
|
-
source({ silent: options.silent, verbose: options.verbose }),
|
|
302
|
-
)
|
|
303
|
-
},
|
|
304
|
-
help: sourceHelp,
|
|
305
|
-
},
|
|
306
|
-
merge: {
|
|
307
|
-
name: "merge",
|
|
308
|
-
description: "Merge emitted branch into base branch",
|
|
309
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
310
|
-
if (options.help) {
|
|
311
|
-
console.log(mergeHelp)
|
|
312
|
-
return
|
|
313
|
-
}
|
|
314
|
-
await runCommand(
|
|
315
|
-
merge({
|
|
316
166
|
silent: options.silent,
|
|
317
167
|
verbose: options.verbose,
|
|
318
|
-
|
|
319
|
-
push: options.push,
|
|
168
|
+
json: options.json,
|
|
320
169
|
}),
|
|
321
170
|
)
|
|
322
171
|
},
|
|
323
|
-
help: mergeHelp,
|
|
324
172
|
},
|
|
325
173
|
task: {
|
|
326
|
-
name: "task",
|
|
327
|
-
description: "Task management commands",
|
|
328
174
|
run: async (args: string[], options: Record<string, any>) => {
|
|
329
175
|
if (options.help) {
|
|
330
176
|
console.log(taskHelp)
|
|
331
177
|
return
|
|
332
178
|
}
|
|
333
|
-
// Initialize with optional branch name
|
|
334
|
-
const branch = args[0] || options.emit || options.branch
|
|
335
179
|
await runCommand(
|
|
336
180
|
task({
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
help: taskHelp,
|
|
349
|
-
},
|
|
350
|
-
tasks: {
|
|
351
|
-
name: "tasks",
|
|
352
|
-
description: "List all task branches",
|
|
353
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
354
|
-
if (options.help) {
|
|
355
|
-
console.log(tasksHelp)
|
|
356
|
-
return
|
|
357
|
-
}
|
|
358
|
-
await runCommand(
|
|
359
|
-
tasks({
|
|
360
|
-
silent: options.silent,
|
|
361
|
-
verbose: options.verbose,
|
|
181
|
+
subcommand: args[0],
|
|
182
|
+
args: args.slice(1),
|
|
183
|
+
ticketUrl: options["ticket-url"],
|
|
184
|
+
description: options.description,
|
|
185
|
+
epic: options.epic,
|
|
186
|
+
repo: options.repo?.[0],
|
|
187
|
+
references: options.reference,
|
|
188
|
+
branch: options.branch,
|
|
189
|
+
base: options.base,
|
|
190
|
+
multiPhase: options["multi-phase"],
|
|
362
191
|
json: options.json,
|
|
363
|
-
}),
|
|
364
|
-
)
|
|
365
|
-
},
|
|
366
|
-
help: tasksHelp,
|
|
367
|
-
},
|
|
368
|
-
edit: {
|
|
369
|
-
name: "edit",
|
|
370
|
-
description: "Open TASK.md in system editor",
|
|
371
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
372
|
-
if (options.help) {
|
|
373
|
-
console.log(editHelp)
|
|
374
|
-
return
|
|
375
|
-
}
|
|
376
|
-
await runCommand(
|
|
377
|
-
taskEdit({
|
|
378
192
|
silent: options.silent,
|
|
379
193
|
verbose: options.verbose,
|
|
380
194
|
}),
|
|
381
195
|
)
|
|
382
196
|
},
|
|
383
|
-
help: editHelp,
|
|
384
197
|
},
|
|
385
198
|
work: {
|
|
386
|
-
name: "work",
|
|
387
|
-
description: "Start working on TASK.md with OpenCode",
|
|
388
199
|
run: async (args: string[], options: Record<string, any>) => {
|
|
389
200
|
if (options.help) {
|
|
390
201
|
console.log(workHelp)
|
|
391
202
|
return
|
|
392
203
|
}
|
|
393
204
|
|
|
394
|
-
// Extract extra args (anything after --)
|
|
395
|
-
// Note: parseArgs with strict:false and allowPositionals:true will put
|
|
396
|
-
// args after -- in the positionals array
|
|
397
|
-
const extraArgs = args.length > 0 ? args : undefined
|
|
398
|
-
|
|
399
205
|
await runCommand(
|
|
400
206
|
work({
|
|
207
|
+
taskId: args[0],
|
|
208
|
+
phaseId: args[1],
|
|
401
209
|
silent: options.silent,
|
|
402
210
|
verbose: options.verbose,
|
|
403
211
|
opencode: options.opencode,
|
|
404
212
|
claude: options.claude,
|
|
405
|
-
extraArgs,
|
|
406
213
|
}),
|
|
407
214
|
)
|
|
408
215
|
},
|
|
409
|
-
help: workHelp,
|
|
410
216
|
},
|
|
411
217
|
status: {
|
|
412
|
-
name: "status",
|
|
413
|
-
description: "Show agency status for this repository",
|
|
414
218
|
run: async (_args: string[], options: Record<string, any>) => {
|
|
415
219
|
if (options.help) {
|
|
416
220
|
console.log(statusHelp)
|
|
@@ -424,66 +228,21 @@ const commands: Record<string, Command> = {
|
|
|
424
228
|
}),
|
|
425
229
|
)
|
|
426
230
|
},
|
|
427
|
-
help: statusHelp,
|
|
428
231
|
},
|
|
429
|
-
|
|
430
|
-
name: "clean",
|
|
431
|
-
description: "Delete branches merged into a specified branch",
|
|
232
|
+
validate: {
|
|
432
233
|
run: async (_args: string[], options: Record<string, any>) => {
|
|
433
234
|
if (options.help) {
|
|
434
|
-
console.log(
|
|
435
|
-
return
|
|
436
|
-
}
|
|
437
|
-
await runCommand(
|
|
438
|
-
clean({
|
|
439
|
-
silent: options.silent,
|
|
440
|
-
verbose: options.verbose,
|
|
441
|
-
dryRun: options["dry-run"],
|
|
442
|
-
mergedInto: options["merged-into"],
|
|
443
|
-
}),
|
|
444
|
-
)
|
|
445
|
-
},
|
|
446
|
-
help: cleanHelp,
|
|
447
|
-
},
|
|
448
|
-
loop: {
|
|
449
|
-
name: "loop",
|
|
450
|
-
description: "Run a Ralph Wiggum loop to complete all tasks",
|
|
451
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
452
|
-
if (options.help) {
|
|
453
|
-
console.log(loopHelp)
|
|
235
|
+
console.log(validateHelp)
|
|
454
236
|
return
|
|
455
237
|
}
|
|
456
|
-
|
|
457
|
-
// Extract extra args (anything after --)
|
|
458
|
-
// Note: parseArgs with strict:false and allowPositionals:true will put
|
|
459
|
-
// args after -- in the positionals array
|
|
460
|
-
const extraArgs = args.length > 0 ? args : undefined
|
|
461
|
-
|
|
462
238
|
await runCommand(
|
|
463
|
-
|
|
239
|
+
validate({
|
|
464
240
|
silent: options.silent,
|
|
465
241
|
verbose: options.verbose,
|
|
466
|
-
|
|
467
|
-
minLoops: options["min-loops"],
|
|
468
|
-
opencode: options.opencode,
|
|
469
|
-
claude: options.claude,
|
|
470
|
-
extraArgs,
|
|
242
|
+
json: options.json,
|
|
471
243
|
}),
|
|
472
244
|
)
|
|
473
245
|
},
|
|
474
|
-
help: loopHelp,
|
|
475
|
-
},
|
|
476
|
-
completions: {
|
|
477
|
-
name: "completions",
|
|
478
|
-
description: "Generate shell completion scripts",
|
|
479
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
480
|
-
if (options.help) {
|
|
481
|
-
console.log(completionsHelp)
|
|
482
|
-
return
|
|
483
|
-
}
|
|
484
|
-
await runCommand(completions(args[0]))
|
|
485
|
-
},
|
|
486
|
-
help: completionsHelp,
|
|
487
246
|
},
|
|
488
247
|
}
|
|
489
248
|
|
|
@@ -494,55 +253,36 @@ agency v${VERSION}
|
|
|
494
253
|
Usage: agency <command> [options]
|
|
495
254
|
|
|
496
255
|
Commands:
|
|
497
|
-
init
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
work
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
view <file> View contents of a file in template
|
|
507
|
-
delete <file> ... Delete files from configured template
|
|
508
|
-
emit [base-branch] Emit a branch with backpack files reverted
|
|
509
|
-
emitted Get the name of the emitted branch
|
|
510
|
-
pr <subcommand> Run gh pr with the emitted branch name
|
|
511
|
-
push [base-branch] Emit, push to remote, return to source
|
|
512
|
-
pull Pull commits from remote emit branch to source
|
|
513
|
-
rebase [base-branch] Rebase source branch onto base branch
|
|
514
|
-
base Get or set the base branch
|
|
515
|
-
set <branch> Set the base branch for the current feature branch
|
|
516
|
-
get Get the configured base branch
|
|
517
|
-
switch Toggle between source and emitted branch
|
|
518
|
-
source Switch to source branch from emitted branch
|
|
519
|
-
merge Merge emitted branch into base branch
|
|
520
|
-
status Show agency status for this repository
|
|
521
|
-
completions <shell> Generate bash or zsh completion scripts
|
|
256
|
+
init [path] Initialize an Agency workbase
|
|
257
|
+
epic <subcommand> Manage epics
|
|
258
|
+
phase <subcommand> Manage task phases
|
|
259
|
+
task <subcommand> Manage tasks
|
|
260
|
+
work <task> [phase] Materialize worktrees and launch an agent
|
|
261
|
+
pr create Create a pull request for an execution unit
|
|
262
|
+
repo <subcommand> Manage workbase repositories
|
|
263
|
+
status Show status for the current workbase
|
|
264
|
+
validate Validate the current workbase
|
|
522
265
|
|
|
523
266
|
Global Options:
|
|
524
267
|
-h, --help Show help for a command
|
|
525
|
-
-
|
|
526
|
-
--no-color Disable color output
|
|
268
|
+
-V, --version Show version number
|
|
527
269
|
-s, --silent Suppress output messages
|
|
528
270
|
-v, --verbose Show verbose output including detailed debugging info
|
|
529
271
|
|
|
530
272
|
Examples:
|
|
531
|
-
agency init # Initialize
|
|
532
|
-
agency task
|
|
533
|
-
agency
|
|
534
|
-
agency emit # Emit a branch (prompts for base branch)
|
|
535
|
-
agency switch # Toggle between source and emitted branch
|
|
273
|
+
agency init # Initialize the current directory
|
|
274
|
+
agency task list # List tasks
|
|
275
|
+
agency work refresh-cli-copy # Start working on a task
|
|
536
276
|
|
|
537
277
|
For more information about a command, run:
|
|
538
278
|
agency <command> --help
|
|
539
279
|
`)
|
|
540
280
|
}
|
|
541
281
|
|
|
542
|
-
// Parse global arguments
|
|
543
282
|
try {
|
|
283
|
+
const args = process.argv.slice(2)
|
|
544
284
|
const { values, positionals } = parseArgs({
|
|
545
|
-
args
|
|
285
|
+
args,
|
|
546
286
|
options: {
|
|
547
287
|
help: {
|
|
548
288
|
type: "boolean",
|
|
@@ -550,21 +290,21 @@ try {
|
|
|
550
290
|
},
|
|
551
291
|
version: {
|
|
552
292
|
type: "boolean",
|
|
553
|
-
short: "
|
|
293
|
+
short: "V",
|
|
554
294
|
},
|
|
555
|
-
|
|
295
|
+
silent: {
|
|
556
296
|
type: "boolean",
|
|
297
|
+
short: "s",
|
|
298
|
+
},
|
|
299
|
+
verbose: {
|
|
300
|
+
type: "boolean",
|
|
301
|
+
short: "v",
|
|
557
302
|
},
|
|
558
303
|
},
|
|
559
304
|
strict: false,
|
|
560
305
|
allowPositionals: true,
|
|
561
306
|
})
|
|
562
307
|
|
|
563
|
-
// Handle --no-color flag
|
|
564
|
-
if (values["no-color"]) {
|
|
565
|
-
setColorsEnabled(false)
|
|
566
|
-
}
|
|
567
|
-
|
|
568
308
|
// Handle global flags
|
|
569
309
|
if (values.version) {
|
|
570
310
|
console.log(`v${VERSION}`)
|
|
@@ -577,13 +317,7 @@ try {
|
|
|
577
317
|
// Show help if no command
|
|
578
318
|
if (!commandName) {
|
|
579
319
|
showMainHelp()
|
|
580
|
-
process.exit(1)
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Show main help if --help with no command
|
|
584
|
-
if (values.help && !commandName) {
|
|
585
|
-
showMainHelp()
|
|
586
|
-
process.exit(0)
|
|
320
|
+
process.exit(values.help ? 0 : 1)
|
|
587
321
|
}
|
|
588
322
|
|
|
589
323
|
// Check if command exists
|
|
@@ -594,8 +328,11 @@ try {
|
|
|
594
328
|
process.exit(1)
|
|
595
329
|
}
|
|
596
330
|
|
|
597
|
-
|
|
598
|
-
const commandArgs =
|
|
331
|
+
const commandIndex = args.indexOf(commandName)
|
|
332
|
+
const commandArgs = [
|
|
333
|
+
...args.slice(0, commandIndex),
|
|
334
|
+
...args.slice(commandIndex + 1),
|
|
335
|
+
]
|
|
599
336
|
const { values: cmdValues, positionals: cmdPositionals } = parseArgs({
|
|
600
337
|
args: commandArgs,
|
|
601
338
|
options: {
|
|
@@ -607,64 +344,36 @@ try {
|
|
|
607
344
|
type: "boolean",
|
|
608
345
|
short: "s",
|
|
609
346
|
},
|
|
610
|
-
force: {
|
|
611
|
-
type: "boolean",
|
|
612
|
-
short: "f",
|
|
613
|
-
},
|
|
614
|
-
"no-verify": {
|
|
615
|
-
type: "boolean",
|
|
616
|
-
},
|
|
617
347
|
verbose: {
|
|
618
348
|
type: "boolean",
|
|
619
349
|
short: "v",
|
|
620
350
|
},
|
|
621
|
-
template: {
|
|
622
|
-
type: "string",
|
|
623
|
-
short: "t",
|
|
624
|
-
},
|
|
625
|
-
emit: {
|
|
626
|
-
type: "string",
|
|
627
|
-
},
|
|
628
351
|
branch: {
|
|
629
352
|
type: "string",
|
|
630
353
|
},
|
|
631
|
-
task: {
|
|
632
|
-
type: "string",
|
|
633
|
-
},
|
|
634
|
-
from: {
|
|
635
|
-
type: "string",
|
|
636
|
-
},
|
|
637
|
-
"from-current": {
|
|
638
|
-
type: "boolean",
|
|
639
|
-
},
|
|
640
|
-
continue: {
|
|
641
|
-
type: "boolean",
|
|
642
|
-
},
|
|
643
354
|
json: {
|
|
644
355
|
type: "boolean",
|
|
645
356
|
},
|
|
646
|
-
|
|
647
|
-
type: "
|
|
648
|
-
},
|
|
649
|
-
pr: {
|
|
650
|
-
type: "boolean",
|
|
651
|
-
},
|
|
652
|
-
squash: {
|
|
653
|
-
type: "boolean",
|
|
654
|
-
},
|
|
655
|
-
push: {
|
|
656
|
-
type: "boolean",
|
|
357
|
+
"ticket-url": {
|
|
358
|
+
type: "string",
|
|
657
359
|
},
|
|
658
|
-
|
|
360
|
+
description: {
|
|
659
361
|
type: "string",
|
|
660
|
-
short: "r",
|
|
661
362
|
},
|
|
662
|
-
|
|
363
|
+
repo: {
|
|
663
364
|
type: "string",
|
|
365
|
+
multiple: true,
|
|
664
366
|
},
|
|
665
|
-
|
|
666
|
-
type: "
|
|
367
|
+
reference: {
|
|
368
|
+
type: "string",
|
|
369
|
+
multiple: true,
|
|
667
370
|
},
|
|
371
|
+
epic: { type: "string" },
|
|
372
|
+
base: { type: "string" },
|
|
373
|
+
"multi-phase": { type: "boolean" },
|
|
374
|
+
"depends-on": { type: "string", multiple: true },
|
|
375
|
+
"first-phase": { type: "string" },
|
|
376
|
+
draft: { type: "boolean" },
|
|
668
377
|
opencode: {
|
|
669
378
|
type: "boolean",
|
|
670
379
|
},
|
|
@@ -676,8 +385,7 @@ try {
|
|
|
676
385
|
allowPositionals: true,
|
|
677
386
|
})
|
|
678
387
|
|
|
679
|
-
|
|
680
|
-
await command.run(cmdPositionals, cmdValues, commandArgs)
|
|
388
|
+
await command.run(cmdPositionals, cmdValues)
|
|
681
389
|
} catch (error) {
|
|
682
390
|
if (error instanceof Error) {
|
|
683
391
|
let message = error.message
|