@markjaquith/agency 1.11.1 → 2.1.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 +313 -117
- package/cli.ts +124 -420
- package/index.ts +1 -1
- package/package.json +12 -17
- package/skills/agency/SKILL.md +266 -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 +326 -399
- package/src/commands/work.ts +153 -153
- 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/work-target.test.ts +77 -0
- package/src/workbase/work-target.ts +180 -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 -641
- package/src/commands/push.ts +0 -482
- 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 -1187
- 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,322 +78,144 @@ 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: "Push the emitted branch or fall through to git push",
|
|
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
|
-
gitArgs: args,
|
|
191
|
-
emit: options.emit || options.branch,
|
|
192
|
-
silent: options.silent,
|
|
193
|
-
force: options.force,
|
|
194
|
-
forceWithLease: options["force-with-lease"],
|
|
195
|
-
noVerify: options["no-verify"],
|
|
196
|
-
verbose: options.verbose,
|
|
197
|
-
pr: options.pr,
|
|
198
|
-
}),
|
|
199
|
-
)
|
|
200
|
-
},
|
|
201
|
-
help: pushHelp,
|
|
202
|
-
},
|
|
203
|
-
pull: {
|
|
204
|
-
name: "pull",
|
|
205
|
-
description: "Pull commits from remote emit branch to source",
|
|
206
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
207
|
-
if (options.help) {
|
|
208
|
-
console.log(pullHelp)
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
await runCommand(
|
|
212
|
-
pull({
|
|
213
|
-
remote: options.remote,
|
|
214
|
-
silent: options.silent,
|
|
215
|
-
verbose: options.verbose,
|
|
216
|
-
}),
|
|
217
|
-
)
|
|
218
|
-
},
|
|
219
|
-
help: pullHelp,
|
|
220
|
-
},
|
|
221
|
-
rebase: {
|
|
222
|
-
name: "rebase",
|
|
223
|
-
description: "Rebase source branch onto base branch",
|
|
224
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
225
|
-
if (options.help) {
|
|
226
|
-
console.log(rebaseHelp)
|
|
227
|
-
return
|
|
228
|
-
}
|
|
229
|
-
await runCommand(
|
|
230
|
-
rebase({
|
|
231
|
-
baseBranch: args[0],
|
|
232
|
-
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,
|
|
233
129
|
silent: options.silent,
|
|
234
130
|
verbose: options.verbose,
|
|
235
131
|
}),
|
|
236
132
|
)
|
|
237
133
|
},
|
|
238
|
-
help: rebaseHelp,
|
|
239
134
|
},
|
|
240
|
-
|
|
241
|
-
name: "template",
|
|
242
|
-
description: "Template management commands",
|
|
135
|
+
phase: {
|
|
243
136
|
run: async (args: string[], options: Record<string, any>) => {
|
|
244
|
-
if (options.help)
|
|
245
|
-
console.log(templateHelp)
|
|
246
|
-
return
|
|
247
|
-
}
|
|
137
|
+
if (options.help) return console.log(phaseHelp)
|
|
248
138
|
await runCommand(
|
|
249
|
-
|
|
139
|
+
phase({
|
|
250
140
|
subcommand: args[0],
|
|
251
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,
|
|
252
150
|
silent: options.silent,
|
|
253
151
|
verbose: options.verbose,
|
|
254
|
-
template: options.template,
|
|
255
152
|
}),
|
|
256
153
|
)
|
|
257
154
|
},
|
|
258
|
-
help: templateHelp,
|
|
259
155
|
},
|
|
260
|
-
|
|
261
|
-
name: "base",
|
|
262
|
-
description: "Get or set the base branch",
|
|
156
|
+
repo: {
|
|
263
157
|
run: async (args: string[], options: Record<string, any>) => {
|
|
264
158
|
if (options.help) {
|
|
265
|
-
console.log(
|
|
159
|
+
console.log(repoHelp)
|
|
266
160
|
return
|
|
267
161
|
}
|
|
268
162
|
await runCommand(
|
|
269
|
-
|
|
163
|
+
repo({
|
|
270
164
|
subcommand: args[0],
|
|
271
165
|
args: args.slice(1),
|
|
272
|
-
repo: options.repo,
|
|
273
|
-
silent: options.silent,
|
|
274
|
-
verbose: options.verbose,
|
|
275
|
-
}),
|
|
276
|
-
)
|
|
277
|
-
},
|
|
278
|
-
help: baseHelp,
|
|
279
|
-
},
|
|
280
|
-
switch: {
|
|
281
|
-
name: "switch",
|
|
282
|
-
description: "Toggle between source and emitted branch",
|
|
283
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
284
|
-
if (options.help) {
|
|
285
|
-
console.log(switchHelp)
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
await runCommand(
|
|
289
|
-
switchBranch({ silent: options.silent, verbose: options.verbose }),
|
|
290
|
-
)
|
|
291
|
-
},
|
|
292
|
-
help: switchHelp,
|
|
293
|
-
},
|
|
294
|
-
source: {
|
|
295
|
-
name: "source",
|
|
296
|
-
description: "Switch to source branch from emitted branch",
|
|
297
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
298
|
-
if (options.help) {
|
|
299
|
-
console.log(sourceHelp)
|
|
300
|
-
return
|
|
301
|
-
}
|
|
302
|
-
await runCommand(
|
|
303
|
-
source({ silent: options.silent, verbose: options.verbose }),
|
|
304
|
-
)
|
|
305
|
-
},
|
|
306
|
-
help: sourceHelp,
|
|
307
|
-
},
|
|
308
|
-
merge: {
|
|
309
|
-
name: "merge",
|
|
310
|
-
description: "Merge emitted branch into base branch",
|
|
311
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
312
|
-
if (options.help) {
|
|
313
|
-
console.log(mergeHelp)
|
|
314
|
-
return
|
|
315
|
-
}
|
|
316
|
-
await runCommand(
|
|
317
|
-
merge({
|
|
318
166
|
silent: options.silent,
|
|
319
167
|
verbose: options.verbose,
|
|
320
|
-
|
|
321
|
-
push: options.push,
|
|
168
|
+
json: options.json,
|
|
322
169
|
}),
|
|
323
170
|
)
|
|
324
171
|
},
|
|
325
|
-
help: mergeHelp,
|
|
326
172
|
},
|
|
327
173
|
task: {
|
|
328
|
-
name: "task",
|
|
329
|
-
description: "Task management commands",
|
|
330
174
|
run: async (args: string[], options: Record<string, any>) => {
|
|
331
175
|
if (options.help) {
|
|
332
176
|
console.log(taskHelp)
|
|
333
177
|
return
|
|
334
178
|
}
|
|
335
|
-
// Initialize with optional branch name
|
|
336
|
-
const branch = args[0] || options.emit || options.branch
|
|
337
179
|
await runCommand(
|
|
338
180
|
task({
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
},
|
|
350
|
-
help: taskHelp,
|
|
351
|
-
},
|
|
352
|
-
tasks: {
|
|
353
|
-
name: "tasks",
|
|
354
|
-
description: "List all task branches",
|
|
355
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
356
|
-
if (options.help) {
|
|
357
|
-
console.log(tasksHelp)
|
|
358
|
-
return
|
|
359
|
-
}
|
|
360
|
-
await runCommand(
|
|
361
|
-
tasks({
|
|
362
|
-
silent: options.silent,
|
|
363
|
-
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"],
|
|
364
191
|
json: options.json,
|
|
365
|
-
}),
|
|
366
|
-
)
|
|
367
|
-
},
|
|
368
|
-
help: tasksHelp,
|
|
369
|
-
},
|
|
370
|
-
edit: {
|
|
371
|
-
name: "edit",
|
|
372
|
-
description: "Open TASK.md in system editor",
|
|
373
|
-
run: async (_args: string[], options: Record<string, any>) => {
|
|
374
|
-
if (options.help) {
|
|
375
|
-
console.log(editHelp)
|
|
376
|
-
return
|
|
377
|
-
}
|
|
378
|
-
await runCommand(
|
|
379
|
-
taskEdit({
|
|
380
192
|
silent: options.silent,
|
|
381
193
|
verbose: options.verbose,
|
|
382
194
|
}),
|
|
383
195
|
)
|
|
384
196
|
},
|
|
385
|
-
help: editHelp,
|
|
386
197
|
},
|
|
387
198
|
work: {
|
|
388
|
-
name: "work",
|
|
389
|
-
description: "Start working on TASK.md with OpenCode",
|
|
390
199
|
run: async (args: string[], options: Record<string, any>) => {
|
|
391
200
|
if (options.help) {
|
|
392
201
|
console.log(workHelp)
|
|
393
202
|
return
|
|
394
203
|
}
|
|
395
204
|
|
|
396
|
-
// Extract extra args (anything after --)
|
|
397
|
-
// Note: parseArgs with strict:false and allowPositionals:true will put
|
|
398
|
-
// args after -- in the positionals array
|
|
399
|
-
const extraArgs = args.length > 0 ? args : undefined
|
|
400
|
-
|
|
401
205
|
await runCommand(
|
|
402
206
|
work({
|
|
207
|
+
taskId: args[0],
|
|
208
|
+
phaseId: args[1],
|
|
209
|
+
epicId: options.epic,
|
|
403
210
|
silent: options.silent,
|
|
404
211
|
verbose: options.verbose,
|
|
405
212
|
opencode: options.opencode,
|
|
406
213
|
claude: options.claude,
|
|
407
|
-
extraArgs,
|
|
408
214
|
}),
|
|
409
215
|
)
|
|
410
216
|
},
|
|
411
|
-
help: workHelp,
|
|
412
217
|
},
|
|
413
218
|
status: {
|
|
414
|
-
name: "status",
|
|
415
|
-
description: "Show agency status for this repository",
|
|
416
219
|
run: async (_args: string[], options: Record<string, any>) => {
|
|
417
220
|
if (options.help) {
|
|
418
221
|
console.log(statusHelp)
|
|
@@ -426,66 +229,21 @@ const commands: Record<string, Command> = {
|
|
|
426
229
|
}),
|
|
427
230
|
)
|
|
428
231
|
},
|
|
429
|
-
help: statusHelp,
|
|
430
232
|
},
|
|
431
|
-
|
|
432
|
-
name: "clean",
|
|
433
|
-
description: "Delete branches merged into a specified branch",
|
|
233
|
+
validate: {
|
|
434
234
|
run: async (_args: string[], options: Record<string, any>) => {
|
|
435
235
|
if (options.help) {
|
|
436
|
-
console.log(
|
|
236
|
+
console.log(validateHelp)
|
|
437
237
|
return
|
|
438
238
|
}
|
|
439
239
|
await runCommand(
|
|
440
|
-
|
|
240
|
+
validate({
|
|
441
241
|
silent: options.silent,
|
|
442
242
|
verbose: options.verbose,
|
|
443
|
-
|
|
444
|
-
mergedInto: options["merged-into"],
|
|
445
|
-
}),
|
|
446
|
-
)
|
|
447
|
-
},
|
|
448
|
-
help: cleanHelp,
|
|
449
|
-
},
|
|
450
|
-
loop: {
|
|
451
|
-
name: "loop",
|
|
452
|
-
description: "Run a Ralph Wiggum loop to complete all tasks",
|
|
453
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
454
|
-
if (options.help) {
|
|
455
|
-
console.log(loopHelp)
|
|
456
|
-
return
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Extract extra args (anything after --)
|
|
460
|
-
// Note: parseArgs with strict:false and allowPositionals:true will put
|
|
461
|
-
// args after -- in the positionals array
|
|
462
|
-
const extraArgs = args.length > 0 ? args : undefined
|
|
463
|
-
|
|
464
|
-
await runCommand(
|
|
465
|
-
loop({
|
|
466
|
-
silent: options.silent,
|
|
467
|
-
verbose: options.verbose,
|
|
468
|
-
maxLoops: options["max-loops"],
|
|
469
|
-
minLoops: options["min-loops"],
|
|
470
|
-
opencode: options.opencode,
|
|
471
|
-
claude: options.claude,
|
|
472
|
-
extraArgs,
|
|
243
|
+
json: options.json,
|
|
473
244
|
}),
|
|
474
245
|
)
|
|
475
246
|
},
|
|
476
|
-
help: loopHelp,
|
|
477
|
-
},
|
|
478
|
-
completions: {
|
|
479
|
-
name: "completions",
|
|
480
|
-
description: "Generate shell completion scripts",
|
|
481
|
-
run: async (args: string[], options: Record<string, any>) => {
|
|
482
|
-
if (options.help) {
|
|
483
|
-
console.log(completionsHelp)
|
|
484
|
-
return
|
|
485
|
-
}
|
|
486
|
-
await runCommand(completions(args[0]))
|
|
487
|
-
},
|
|
488
|
-
help: completionsHelp,
|
|
489
247
|
},
|
|
490
248
|
}
|
|
491
249
|
|
|
@@ -496,55 +254,36 @@ agency v${VERSION}
|
|
|
496
254
|
Usage: agency <command> [options]
|
|
497
255
|
|
|
498
256
|
Commands:
|
|
499
|
-
init
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
work
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
view <file> View contents of a file in template
|
|
509
|
-
delete <file> ... Delete files from configured template
|
|
510
|
-
emit [base-branch] Emit a branch with backpack files reverted
|
|
511
|
-
emitted Get the name of the emitted branch
|
|
512
|
-
pr <subcommand> Run gh pr with the emitted branch name
|
|
513
|
-
push [arguments] Push the emitted branch or fall through to git push
|
|
514
|
-
pull Pull commits from remote emit branch to source
|
|
515
|
-
rebase [base-branch] Rebase source branch onto base branch
|
|
516
|
-
base Get or set the base branch
|
|
517
|
-
set <branch> Set the base branch for the current feature branch
|
|
518
|
-
get Get the configured base branch
|
|
519
|
-
switch Toggle between source and emitted branch
|
|
520
|
-
source Switch to source branch from emitted branch
|
|
521
|
-
merge Merge emitted branch into base branch
|
|
522
|
-
status Show agency status for this repository
|
|
523
|
-
completions <shell> Generate bash or zsh completion scripts
|
|
257
|
+
init [path] Initialize an Agency workbase
|
|
258
|
+
epic <subcommand> Manage epics
|
|
259
|
+
phase <subcommand> Manage task phases
|
|
260
|
+
task <subcommand> Manage tasks
|
|
261
|
+
work [task] [phase] Work on an epic, task, or phase
|
|
262
|
+
pr create Create a pull request for an execution unit
|
|
263
|
+
repo <subcommand> Manage workbase repositories
|
|
264
|
+
status Show status for the current workbase
|
|
265
|
+
validate Validate the current workbase
|
|
524
266
|
|
|
525
267
|
Global Options:
|
|
526
268
|
-h, --help Show help for a command
|
|
527
|
-
-
|
|
528
|
-
--no-color Disable color output
|
|
269
|
+
-V, --version Show version number
|
|
529
270
|
-s, --silent Suppress output messages
|
|
530
271
|
-v, --verbose Show verbose output including detailed debugging info
|
|
531
272
|
|
|
532
273
|
Examples:
|
|
533
|
-
agency init # Initialize
|
|
534
|
-
agency task
|
|
535
|
-
agency
|
|
536
|
-
agency emit # Emit a branch (prompts for base branch)
|
|
537
|
-
agency switch # Toggle between source and emitted branch
|
|
274
|
+
agency init # Initialize the current directory
|
|
275
|
+
agency task list # List tasks
|
|
276
|
+
agency work refresh-cli-copy # Start working on a task
|
|
538
277
|
|
|
539
278
|
For more information about a command, run:
|
|
540
279
|
agency <command> --help
|
|
541
280
|
`)
|
|
542
281
|
}
|
|
543
282
|
|
|
544
|
-
// Parse global arguments
|
|
545
283
|
try {
|
|
284
|
+
const args = process.argv.slice(2)
|
|
546
285
|
const { values, positionals } = parseArgs({
|
|
547
|
-
args
|
|
286
|
+
args,
|
|
548
287
|
options: {
|
|
549
288
|
help: {
|
|
550
289
|
type: "boolean",
|
|
@@ -552,21 +291,21 @@ try {
|
|
|
552
291
|
},
|
|
553
292
|
version: {
|
|
554
293
|
type: "boolean",
|
|
555
|
-
short: "
|
|
294
|
+
short: "V",
|
|
556
295
|
},
|
|
557
|
-
|
|
296
|
+
silent: {
|
|
558
297
|
type: "boolean",
|
|
298
|
+
short: "s",
|
|
299
|
+
},
|
|
300
|
+
verbose: {
|
|
301
|
+
type: "boolean",
|
|
302
|
+
short: "v",
|
|
559
303
|
},
|
|
560
304
|
},
|
|
561
305
|
strict: false,
|
|
562
306
|
allowPositionals: true,
|
|
563
307
|
})
|
|
564
308
|
|
|
565
|
-
// Handle --no-color flag
|
|
566
|
-
if (values["no-color"]) {
|
|
567
|
-
setColorsEnabled(false)
|
|
568
|
-
}
|
|
569
|
-
|
|
570
309
|
// Handle global flags
|
|
571
310
|
if (values.version) {
|
|
572
311
|
console.log(`v${VERSION}`)
|
|
@@ -579,13 +318,7 @@ try {
|
|
|
579
318
|
// Show help if no command
|
|
580
319
|
if (!commandName) {
|
|
581
320
|
showMainHelp()
|
|
582
|
-
process.exit(1)
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// Show main help if --help with no command
|
|
586
|
-
if (values.help && !commandName) {
|
|
587
|
-
showMainHelp()
|
|
588
|
-
process.exit(0)
|
|
321
|
+
process.exit(values.help ? 0 : 1)
|
|
589
322
|
}
|
|
590
323
|
|
|
591
324
|
// Check if command exists
|
|
@@ -596,8 +329,11 @@ try {
|
|
|
596
329
|
process.exit(1)
|
|
597
330
|
}
|
|
598
331
|
|
|
599
|
-
|
|
600
|
-
const commandArgs =
|
|
332
|
+
const commandIndex = args.indexOf(commandName)
|
|
333
|
+
const commandArgs = [
|
|
334
|
+
...args.slice(0, commandIndex),
|
|
335
|
+
...args.slice(commandIndex + 1),
|
|
336
|
+
]
|
|
601
337
|
const { values: cmdValues, positionals: cmdPositionals } = parseArgs({
|
|
602
338
|
args: commandArgs,
|
|
603
339
|
options: {
|
|
@@ -609,67 +345,36 @@ try {
|
|
|
609
345
|
type: "boolean",
|
|
610
346
|
short: "s",
|
|
611
347
|
},
|
|
612
|
-
force: {
|
|
613
|
-
type: "boolean",
|
|
614
|
-
short: "f",
|
|
615
|
-
},
|
|
616
|
-
"force-with-lease": {
|
|
617
|
-
type: "boolean",
|
|
618
|
-
},
|
|
619
|
-
"no-verify": {
|
|
620
|
-
type: "boolean",
|
|
621
|
-
},
|
|
622
348
|
verbose: {
|
|
623
349
|
type: "boolean",
|
|
624
350
|
short: "v",
|
|
625
351
|
},
|
|
626
|
-
template: {
|
|
627
|
-
type: "string",
|
|
628
|
-
short: "t",
|
|
629
|
-
},
|
|
630
|
-
emit: {
|
|
631
|
-
type: "string",
|
|
632
|
-
},
|
|
633
352
|
branch: {
|
|
634
353
|
type: "string",
|
|
635
354
|
},
|
|
636
|
-
task: {
|
|
637
|
-
type: "string",
|
|
638
|
-
},
|
|
639
|
-
from: {
|
|
640
|
-
type: "string",
|
|
641
|
-
},
|
|
642
|
-
"from-current": {
|
|
643
|
-
type: "boolean",
|
|
644
|
-
},
|
|
645
|
-
continue: {
|
|
646
|
-
type: "boolean",
|
|
647
|
-
},
|
|
648
355
|
json: {
|
|
649
356
|
type: "boolean",
|
|
650
357
|
},
|
|
651
|
-
|
|
652
|
-
type: "
|
|
653
|
-
},
|
|
654
|
-
pr: {
|
|
655
|
-
type: "boolean",
|
|
656
|
-
},
|
|
657
|
-
squash: {
|
|
658
|
-
type: "boolean",
|
|
659
|
-
},
|
|
660
|
-
push: {
|
|
661
|
-
type: "boolean",
|
|
358
|
+
"ticket-url": {
|
|
359
|
+
type: "string",
|
|
662
360
|
},
|
|
663
|
-
|
|
361
|
+
description: {
|
|
664
362
|
type: "string",
|
|
665
|
-
short: "r",
|
|
666
363
|
},
|
|
667
|
-
|
|
364
|
+
repo: {
|
|
668
365
|
type: "string",
|
|
366
|
+
multiple: true,
|
|
669
367
|
},
|
|
670
|
-
|
|
671
|
-
type: "
|
|
368
|
+
reference: {
|
|
369
|
+
type: "string",
|
|
370
|
+
multiple: true,
|
|
672
371
|
},
|
|
372
|
+
epic: { type: "string" },
|
|
373
|
+
base: { type: "string" },
|
|
374
|
+
"multi-phase": { type: "boolean" },
|
|
375
|
+
"depends-on": { type: "string", multiple: true },
|
|
376
|
+
"first-phase": { type: "string" },
|
|
377
|
+
draft: { type: "boolean" },
|
|
673
378
|
opencode: {
|
|
674
379
|
type: "boolean",
|
|
675
380
|
},
|
|
@@ -681,8 +386,7 @@ try {
|
|
|
681
386
|
allowPositionals: true,
|
|
682
387
|
})
|
|
683
388
|
|
|
684
|
-
|
|
685
|
-
await command.run(cmdPositionals, cmdValues, commandArgs)
|
|
389
|
+
await command.run(cmdPositionals, cmdValues)
|
|
686
390
|
} catch (error) {
|
|
687
391
|
if (error instanceof Error) {
|
|
688
392
|
let message = error.message
|