lalph 0.1.54 → 0.1.56
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/dist/cli.mjs +70 -59
- package/package.json +1 -1
- package/src/Github.ts +0 -1
- package/src/Linear.ts +0 -1
- package/src/commands/issue.ts +0 -1
- package/src/commands/plan.ts +10 -21
- package/src/commands/root.ts +21 -30
- package/src/domain/CliAgent.ts +74 -36
- package/src/domain/PrdIssue.ts +0 -3
package/dist/cli.mjs
CHANGED
|
@@ -60374,39 +60374,70 @@ var CliAgent = class extends Class$1 {};
|
|
|
60374
60374
|
const opencode = new CliAgent({
|
|
60375
60375
|
id: "opencode",
|
|
60376
60376
|
name: "opencode",
|
|
60377
|
-
|
|
60378
|
-
|
|
60379
|
-
|
|
60380
|
-
"
|
|
60381
|
-
|
|
60382
|
-
|
|
60383
|
-
|
|
60384
|
-
|
|
60385
|
-
commandPlan: ({ prompt, prdFilePath }) =>
|
|
60386
|
-
|
|
60387
|
-
|
|
60388
|
-
|
|
60377
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60378
|
+
cwd: worktree.directory,
|
|
60379
|
+
extendEnv: true,
|
|
60380
|
+
env: { OPENCODE_PERMISSION: "{\"*\":\"allow\"}" },
|
|
60381
|
+
stdout: outputMode,
|
|
60382
|
+
stderr: outputMode,
|
|
60383
|
+
stdin: "inherit"
|
|
60384
|
+
})`opencode run ${prompt} -f ${prdFilePath}`,
|
|
60385
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60386
|
+
cwd: worktree.directory,
|
|
60387
|
+
extendEnv: true,
|
|
60388
|
+
env: { OPENCODE_PERMISSION: "{\"*\":\"allow\"}" },
|
|
60389
|
+
stdout: outputMode,
|
|
60390
|
+
stderr: outputMode,
|
|
60391
|
+
stdin: "inherit"
|
|
60392
|
+
})`opencode --prompt ${`@${prdFilePath}
|
|
60389
60393
|
|
|
60390
|
-
${prompt}`
|
|
60391
|
-
]
|
|
60394
|
+
${prompt}`}`
|
|
60392
60395
|
});
|
|
60393
60396
|
const claude = new CliAgent({
|
|
60394
60397
|
id: "claude",
|
|
60395
60398
|
name: "Claude Code",
|
|
60396
|
-
|
|
60397
|
-
|
|
60398
|
-
|
|
60399
|
-
|
|
60400
|
-
"
|
|
60401
|
-
|
|
60399
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60400
|
+
cwd: worktree.directory,
|
|
60401
|
+
stdout: outputMode,
|
|
60402
|
+
stderr: outputMode,
|
|
60403
|
+
stdin: "inherit"
|
|
60404
|
+
})`claude --dangerously-skip-permissions -p ${`@${prdFilePath}
|
|
60402
60405
|
|
|
60403
|
-
${prompt}`
|
|
60404
|
-
|
|
60405
|
-
|
|
60406
|
+
${prompt}`}`,
|
|
60407
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60408
|
+
cwd: worktree.directory,
|
|
60409
|
+
stdout: outputMode,
|
|
60410
|
+
stderr: outputMode,
|
|
60411
|
+
stdin: "inherit"
|
|
60412
|
+
})`claude ${`@${prdFilePath}
|
|
60406
60413
|
|
|
60407
|
-
${prompt}`
|
|
60414
|
+
${prompt}`}`
|
|
60408
60415
|
});
|
|
60409
|
-
const
|
|
60416
|
+
const codex = new CliAgent({
|
|
60417
|
+
id: "codex",
|
|
60418
|
+
name: "codex cli",
|
|
60419
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60420
|
+
cwd: worktree.directory,
|
|
60421
|
+
stdout: outputMode,
|
|
60422
|
+
stderr: outputMode,
|
|
60423
|
+
stdin: "inherit"
|
|
60424
|
+
})`codex exec --dangerously-bypass-approvals-and-sandbox ${`@${prdFilePath}
|
|
60425
|
+
|
|
60426
|
+
${prompt}`}`,
|
|
60427
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) => make$21({
|
|
60428
|
+
cwd: worktree.directory,
|
|
60429
|
+
stdout: outputMode,
|
|
60430
|
+
stderr: outputMode,
|
|
60431
|
+
stdin: "inherit"
|
|
60432
|
+
})`codex ${`@${prdFilePath}
|
|
60433
|
+
|
|
60434
|
+
${prompt}`}`
|
|
60435
|
+
});
|
|
60436
|
+
const allCliAgents = [
|
|
60437
|
+
opencode,
|
|
60438
|
+
claude,
|
|
60439
|
+
codex
|
|
60440
|
+
];
|
|
60410
60441
|
|
|
60411
60442
|
//#endregion
|
|
60412
60443
|
//#region src/Settings.ts
|
|
@@ -60466,7 +60497,6 @@ var PrdIssue = class PrdIssue extends Class("PrdIssue")({
|
|
|
60466
60497
|
"done"
|
|
60467
60498
|
]).annotate({ description: "The state of the issue." }),
|
|
60468
60499
|
blockedBy: Array$1(String$1).annotate({ description: "An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on." }),
|
|
60469
|
-
complete: Boolean$2.annotate({ description: "Whether the issue is complete." }),
|
|
60470
60500
|
autoMerge: Boolean$2.annotate({ description: "Whether the issue should be auto-merged when complete. Read-only field" }),
|
|
60471
60501
|
githubPrNumber: NullOr(Finite).annotate({ description: "The created or updated Github pull request number for this task." })
|
|
60472
60502
|
}) {
|
|
@@ -134784,7 +134814,6 @@ const LinearIssueSource = effect(IssueSource, gen(function* () {
|
|
|
134784
134814
|
priority: issue.priority,
|
|
134785
134815
|
estimate: issue.estimate ?? null,
|
|
134786
134816
|
state,
|
|
134787
|
-
complete: state === "in-review" || state === "done",
|
|
134788
134817
|
blockedBy: blockedBy.map((i) => i.identifier),
|
|
134789
134818
|
autoMerge: autoMergeLabelId.pipe(map$11((labelId$1) => issue.labelIds.includes(labelId$1)), getOrElse(() => false)),
|
|
134790
134819
|
githubPrNumber: null
|
|
@@ -141091,7 +141120,6 @@ const GithubIssueSource = effect(IssueSource, gen(function* () {
|
|
|
141091
141120
|
priority: 0,
|
|
141092
141121
|
estimate: null,
|
|
141093
141122
|
state,
|
|
141094
|
-
complete: state === "done" || state === "in-review",
|
|
141095
141123
|
blockedBy: dependencies.map((dep) => `#${dep.number}`),
|
|
141096
141124
|
autoMerge: autoMergeLabelName.pipe(map$11((labelName) => hasLabel(issue.labels, labelName)), getOrElse(() => false)),
|
|
141097
141125
|
githubPrNumber: null
|
|
@@ -141708,14 +141736,7 @@ const run = fnUntraced(function* (options) {
|
|
|
141708
141736
|
const timeUntilDeadline = distanceDuration(deadline, now$2);
|
|
141709
141737
|
return flatMap(sleep(timeUntilDeadline), loop);
|
|
141710
141738
|
});
|
|
141711
|
-
const handle = yield*
|
|
141712
|
-
cwd: worktree.directory,
|
|
141713
|
-
extendEnv: true,
|
|
141714
|
-
env: cliAgent.env,
|
|
141715
|
-
stdout: "pipe",
|
|
141716
|
-
stderr: "pipe",
|
|
141717
|
-
stdin: "inherit"
|
|
141718
|
-
});
|
|
141739
|
+
const handle = yield* command;
|
|
141719
141740
|
yield* handle.all.pipe(runForEachArray((output) => {
|
|
141720
141741
|
lastOutputAt = nowUnsafe();
|
|
141721
141742
|
for (const chunk of output) process.stdout.write(chunk);
|
|
@@ -141726,17 +141747,11 @@ const run = fnUntraced(function* (options) {
|
|
|
141726
141747
|
const currentBranch = (dir) => make$21({ cwd: dir })`git branch --show-current`.pipe(string, flatMap((output) => some(output.trim()).pipe(filter$5((b) => b.length > 0), fromOption)));
|
|
141727
141748
|
if (isSome(options.targetBranch)) yield* exec`git checkout ${`origin/${options.targetBranch.value}`}`;
|
|
141728
141749
|
yield* gen(function* () {
|
|
141729
|
-
|
|
141750
|
+
yield* cliAgent.command({
|
|
141751
|
+
worktree,
|
|
141730
141752
|
prompt: promptGen.promptChoose,
|
|
141731
|
-
prdFilePath: pathService.join(".lalph", "prd.yml")
|
|
141732
|
-
|
|
141733
|
-
yield* make$21(chooseCommand[0], chooseCommand.slice(1), {
|
|
141734
|
-
cwd: worktree.directory,
|
|
141735
|
-
extendEnv: true,
|
|
141736
|
-
env: cliAgent.env,
|
|
141737
|
-
stdout: "inherit",
|
|
141738
|
-
stderr: "inherit",
|
|
141739
|
-
stdin: "inherit"
|
|
141753
|
+
prdFilePath: pathService.join(".lalph", "prd.yml"),
|
|
141754
|
+
outputMode: "inherit"
|
|
141740
141755
|
}).pipe(exitCode, timeoutOrElse({
|
|
141741
141756
|
duration: options.stallTimeout,
|
|
141742
141757
|
onTimeout: () => fail$4(new RunnerStalled())
|
|
@@ -141750,6 +141765,8 @@ const run = fnUntraced(function* (options) {
|
|
|
141750
141765
|
}));
|
|
141751
141766
|
yield* completeWith(options.startedDeferred, void_$1);
|
|
141752
141767
|
const exitCode$1 = yield* execWithStallTimeout(cliAgent.command({
|
|
141768
|
+
worktree,
|
|
141769
|
+
outputMode: "pipe",
|
|
141753
141770
|
prompt: promptGen.prompt({
|
|
141754
141771
|
taskId,
|
|
141755
141772
|
targetBranch: getOrUndefined(options.targetBranch),
|
|
@@ -141758,6 +141775,8 @@ const run = fnUntraced(function* (options) {
|
|
|
141758
141775
|
prdFilePath: pathService.join(".lalph", "prd.yml")
|
|
141759
141776
|
})).pipe(timeout(options.runTimeout), catchTag("TimeoutError", fnUntraced(function* (error$1) {
|
|
141760
141777
|
yield* execWithStallTimeout(cliAgent.command({
|
|
141778
|
+
worktree,
|
|
141779
|
+
outputMode: "pipe",
|
|
141761
141780
|
prompt: promptGen.promptTimeout({ taskId }),
|
|
141762
141781
|
prdFilePath: pathService.join(".lalph", "prd.yml")
|
|
141763
141782
|
}));
|
|
@@ -141786,8 +141805,7 @@ const ChosenTask = fromJsonString(Struct({ id: String$1 }));
|
|
|
141786
141805
|
//#endregion
|
|
141787
141806
|
//#region src/commands/plan.ts
|
|
141788
141807
|
const commandPlan = make$27("plan").pipe(withDescription("Iterate on an issue plan and create PRD tasks"), withHandler(fnUntraced(function* () {
|
|
141789
|
-
const {
|
|
141790
|
-
if (reset$2) yield* resetCurrentIssueSource;
|
|
141808
|
+
const { specsDirectory: specsDirectory$1, targetBranch: targetBranch$1 } = yield* commandRoot;
|
|
141791
141809
|
yield* plan({
|
|
141792
141810
|
specsDirectory: specsDirectory$1,
|
|
141793
141811
|
targetBranch: targetBranch$1
|
|
@@ -141804,17 +141822,11 @@ const plan = fnUntraced(function* (options) {
|
|
|
141804
141822
|
extendEnv: true
|
|
141805
141823
|
})(template, ...args$1).pipe(exitCode);
|
|
141806
141824
|
if (isSome(options.targetBranch)) yield* exec`git checkout ${`origin/${options.targetBranch.value}`}`;
|
|
141807
|
-
const
|
|
141825
|
+
const exitCode$1 = yield* cliAgent.commandPlan({
|
|
141826
|
+
worktree,
|
|
141827
|
+
outputMode: "inherit",
|
|
141808
141828
|
prompt: promptGen.planPrompt(options),
|
|
141809
141829
|
prdFilePath: pathService.join(worktree.directory, ".lalph", "prd.yml")
|
|
141810
|
-
});
|
|
141811
|
-
const exitCode$1 = yield* make$21(cliCommand[0], cliCommand.slice(1), {
|
|
141812
|
-
cwd: worktree.directory,
|
|
141813
|
-
extendEnv: true,
|
|
141814
|
-
env: cliAgent.env,
|
|
141815
|
-
stdout: "inherit",
|
|
141816
|
-
stderr: "inherit",
|
|
141817
|
-
stdin: "inherit"
|
|
141818
141830
|
}).pipe(exitCode);
|
|
141819
141831
|
yield* log$1(`Agent exited with code: ${exitCode$1}`);
|
|
141820
141832
|
if (!worktree.inExisting) yield* fs.copy(pathService.join(worktree.directory, options.specsDirectory), options.specsDirectory, { overwrite: true }).pipe(ignore);
|
|
@@ -141876,7 +141888,6 @@ const commandIssue = make$27("issue").pipe(withDescription("Create a new issue i
|
|
|
141876
141888
|
...frontMatter,
|
|
141877
141889
|
description,
|
|
141878
141890
|
state: "todo",
|
|
141879
|
-
complete: false,
|
|
141880
141891
|
githubPrNumber: null
|
|
141881
141892
|
}));
|
|
141882
141893
|
console.log(`Created issue with ID: ${issueId}`);
|
|
@@ -141920,7 +141931,7 @@ const commandAgent = make$27("agent").pipe(withDescription("Select the CLI agent
|
|
|
141920
141931
|
|
|
141921
141932
|
//#endregion
|
|
141922
141933
|
//#region package.json
|
|
141923
|
-
var version = "0.1.
|
|
141934
|
+
var version = "0.1.56";
|
|
141924
141935
|
|
|
141925
141936
|
//#endregion
|
|
141926
141937
|
//#region src/cli.ts
|
package/package.json
CHANGED
package/src/Github.ts
CHANGED
|
@@ -189,7 +189,6 @@ export const GithubIssueSource = Layer.effect(
|
|
|
189
189
|
priority: 0,
|
|
190
190
|
estimate: null,
|
|
191
191
|
state,
|
|
192
|
-
complete: state === "done" || state === "in-review",
|
|
193
192
|
blockedBy: dependencies.map((dep) => `#${dep.number}`),
|
|
194
193
|
autoMerge: autoMergeLabelName.pipe(
|
|
195
194
|
Option.map((labelName) => hasLabel(issue.labels, labelName)),
|
package/src/Linear.ts
CHANGED
|
@@ -230,7 +230,6 @@ export const LinearIssueSource = Layer.effect(
|
|
|
230
230
|
priority: issue.priority,
|
|
231
231
|
estimate: issue.estimate ?? null,
|
|
232
232
|
state,
|
|
233
|
-
complete: state === "in-review" || state === "done",
|
|
234
233
|
blockedBy: blockedBy.map((i) => i.identifier),
|
|
235
234
|
autoMerge: autoMergeLabelId.pipe(
|
|
236
235
|
Option.map((labelId) => issue.labelIds.includes(labelId)),
|
package/src/commands/issue.ts
CHANGED
package/src/commands/plan.ts
CHANGED
|
@@ -5,17 +5,14 @@ import { ChildProcess } from "effect/unstable/process"
|
|
|
5
5
|
import { Worktree } from "../Worktree.ts"
|
|
6
6
|
import { getOrSelectCliAgent } from "../CliAgent.ts"
|
|
7
7
|
import { Command } from "effect/unstable/cli"
|
|
8
|
-
import {
|
|
8
|
+
import { CurrentIssueSource } from "../IssueSources.ts"
|
|
9
9
|
import { commandRoot } from "./root.ts"
|
|
10
10
|
|
|
11
11
|
export const commandPlan = Command.make("plan").pipe(
|
|
12
12
|
Command.withDescription("Iterate on an issue plan and create PRD tasks"),
|
|
13
13
|
Command.withHandler(
|
|
14
14
|
Effect.fnUntraced(function* () {
|
|
15
|
-
const {
|
|
16
|
-
if (reset) {
|
|
17
|
-
yield* resetCurrentIssueSource
|
|
18
|
-
}
|
|
15
|
+
const { specsDirectory, targetBranch } = yield* commandRoot
|
|
19
16
|
yield* plan({ specsDirectory, targetBranch }).pipe(
|
|
20
17
|
Effect.provide(CurrentIssueSource.layer),
|
|
21
18
|
)
|
|
@@ -47,22 +44,14 @@ const plan = Effect.fnUntraced(
|
|
|
47
44
|
yield* exec`git checkout ${`origin/${options.targetBranch.value}`}`
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
cwd: worktree.directory,
|
|
59
|
-
extendEnv: true,
|
|
60
|
-
env: cliAgent.env,
|
|
61
|
-
stdout: "inherit",
|
|
62
|
-
stderr: "inherit",
|
|
63
|
-
stdin: "inherit",
|
|
64
|
-
},
|
|
65
|
-
).pipe(ChildProcess.exitCode)
|
|
47
|
+
const exitCode = yield* cliAgent
|
|
48
|
+
.commandPlan({
|
|
49
|
+
worktree,
|
|
50
|
+
outputMode: "inherit",
|
|
51
|
+
prompt: promptGen.planPrompt(options),
|
|
52
|
+
prdFilePath: pathService.join(worktree.directory, ".lalph", "prd.yml"),
|
|
53
|
+
})
|
|
54
|
+
.pipe(ChildProcess.exitCode)
|
|
66
55
|
|
|
67
56
|
yield* Effect.log(`Agent exited with code: ${exitCode}`)
|
|
68
57
|
|
package/src/commands/root.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { Worktree } from "../Worktree.ts"
|
|
|
22
22
|
import { getOrSelectCliAgent } from "../CliAgent.ts"
|
|
23
23
|
import { Flag, CliError, Command } from "effect/unstable/cli"
|
|
24
24
|
import { checkForWork } from "../IssueSource.ts"
|
|
25
|
-
import {
|
|
25
|
+
import { CurrentIssueSource } from "../IssueSources.ts"
|
|
26
26
|
|
|
27
27
|
const iterations = Flag.integer("iterations").pipe(
|
|
28
28
|
Flag.withDescription("Number of iterations to run, defaults to unlimited"),
|
|
@@ -215,7 +215,7 @@ const run = Effect.fnUntraced(
|
|
|
215
215
|
})(template, ...args).pipe(ChildProcess.exitCode)
|
|
216
216
|
|
|
217
217
|
const execWithStallTimeout = Effect.fnUntraced(function* (
|
|
218
|
-
command:
|
|
218
|
+
command: ChildProcess.Command,
|
|
219
219
|
) {
|
|
220
220
|
let lastOutputAt = yield* DateTime.now
|
|
221
221
|
|
|
@@ -235,14 +235,7 @@ const run = Effect.fnUntraced(
|
|
|
235
235
|
return Effect.flatMap(Effect.sleep(timeUntilDeadline), loop)
|
|
236
236
|
})
|
|
237
237
|
|
|
238
|
-
const handle = yield*
|
|
239
|
-
cwd: worktree.directory,
|
|
240
|
-
extendEnv: true,
|
|
241
|
-
env: cliAgent.env,
|
|
242
|
-
stdout: "pipe",
|
|
243
|
-
stderr: "pipe",
|
|
244
|
-
stdin: "inherit",
|
|
245
|
-
})
|
|
238
|
+
const handle = yield* command
|
|
246
239
|
|
|
247
240
|
yield* handle.all.pipe(
|
|
248
241
|
Stream.runForEachArray((output) => {
|
|
@@ -275,25 +268,20 @@ const run = Effect.fnUntraced(
|
|
|
275
268
|
}
|
|
276
269
|
|
|
277
270
|
yield* Effect.gen(function* () {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
Effect.timeoutOrElse({
|
|
293
|
-
duration: options.stallTimeout,
|
|
294
|
-
onTimeout: () => Effect.fail(new RunnerStalled()),
|
|
295
|
-
}),
|
|
296
|
-
)
|
|
271
|
+
yield* cliAgent
|
|
272
|
+
.command({
|
|
273
|
+
worktree,
|
|
274
|
+
prompt: promptGen.promptChoose,
|
|
275
|
+
prdFilePath: pathService.join(".lalph", "prd.yml"),
|
|
276
|
+
outputMode: "inherit",
|
|
277
|
+
})
|
|
278
|
+
.pipe(
|
|
279
|
+
ChildProcess.exitCode,
|
|
280
|
+
Effect.timeoutOrElse({
|
|
281
|
+
duration: options.stallTimeout,
|
|
282
|
+
onTimeout: () => Effect.fail(new RunnerStalled()),
|
|
283
|
+
}),
|
|
284
|
+
)
|
|
297
285
|
|
|
298
286
|
const taskJson = yield* fs.readFileString(
|
|
299
287
|
pathService.join(worktree.directory, ".lalph", "task.json"),
|
|
@@ -314,6 +302,8 @@ const run = Effect.fnUntraced(
|
|
|
314
302
|
yield* Deferred.completeWith(options.startedDeferred, Effect.void)
|
|
315
303
|
|
|
316
304
|
const cliCommand = cliAgent.command({
|
|
305
|
+
worktree,
|
|
306
|
+
outputMode: "pipe",
|
|
317
307
|
prompt: promptGen.prompt({
|
|
318
308
|
taskId,
|
|
319
309
|
targetBranch: Option.getOrUndefined(options.targetBranch),
|
|
@@ -328,6 +318,8 @@ const run = Effect.fnUntraced(
|
|
|
328
318
|
"TimeoutError",
|
|
329
319
|
Effect.fnUntraced(function* (error) {
|
|
330
320
|
const timeoutCommand = cliAgent.command({
|
|
321
|
+
worktree,
|
|
322
|
+
outputMode: "pipe",
|
|
331
323
|
prompt: promptGen.promptTimeout({
|
|
332
324
|
taskId,
|
|
333
325
|
}),
|
|
@@ -373,7 +365,6 @@ const run = Effect.fnUntraced(
|
|
|
373
365
|
)
|
|
374
366
|
},
|
|
375
367
|
Effect.scoped,
|
|
376
|
-
// on interrupt or error, revert any state changes made in the PRD
|
|
377
368
|
Effect.provide([PromptGen.layer, Prd.layer]),
|
|
378
369
|
)
|
|
379
370
|
|
package/src/domain/CliAgent.ts
CHANGED
|
@@ -1,59 +1,97 @@
|
|
|
1
1
|
import { Data } from "effect"
|
|
2
|
+
import type { Worktree } from "../Worktree.ts"
|
|
3
|
+
import { ChildProcess } from "effect/unstable/process"
|
|
2
4
|
|
|
3
5
|
export class CliAgent extends Data.Class<{
|
|
4
6
|
id: string
|
|
5
7
|
name: string
|
|
6
8
|
command: (options: {
|
|
9
|
+
readonly worktree: Worktree["Service"]
|
|
10
|
+
readonly outputMode: "pipe" | "inherit"
|
|
7
11
|
readonly prompt: string
|
|
8
12
|
readonly prdFilePath: string
|
|
9
|
-
}) =>
|
|
13
|
+
}) => ChildProcess.Command
|
|
10
14
|
commandPlan: (options: {
|
|
15
|
+
readonly worktree: Worktree["Service"]
|
|
16
|
+
readonly outputMode: "pipe" | "inherit"
|
|
11
17
|
readonly prompt: string
|
|
12
18
|
readonly prdFilePath: string
|
|
13
|
-
}) =>
|
|
14
|
-
env: Record<string, string>
|
|
19
|
+
}) => ChildProcess.Command
|
|
15
20
|
}> {}
|
|
16
21
|
|
|
17
22
|
export const opencode = new CliAgent({
|
|
18
23
|
id: "opencode",
|
|
19
24
|
name: "opencode",
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
26
|
+
ChildProcess.make({
|
|
27
|
+
cwd: worktree.directory,
|
|
28
|
+
extendEnv: true,
|
|
29
|
+
env: {
|
|
30
|
+
OPENCODE_PERMISSION: '{"*":"allow"}',
|
|
31
|
+
},
|
|
32
|
+
stdout: outputMode,
|
|
33
|
+
stderr: outputMode,
|
|
34
|
+
stdin: "inherit",
|
|
35
|
+
})`opencode run ${prompt} -f ${prdFilePath}`,
|
|
36
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
37
|
+
ChildProcess.make({
|
|
38
|
+
cwd: worktree.directory,
|
|
39
|
+
extendEnv: true,
|
|
40
|
+
env: {
|
|
41
|
+
OPENCODE_PERMISSION: '{"*":"allow"}',
|
|
42
|
+
},
|
|
43
|
+
stdout: outputMode,
|
|
44
|
+
stderr: outputMode,
|
|
45
|
+
stdin: "inherit",
|
|
46
|
+
})`opencode --prompt ${`@${prdFilePath}
|
|
47
|
+
|
|
48
|
+
${prompt}`}`,
|
|
37
49
|
})
|
|
38
50
|
|
|
39
51
|
export const claude = new CliAgent({
|
|
40
52
|
id: "claude",
|
|
41
53
|
name: "Claude Code",
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
commandPlan: ({ prompt, prdFilePath }) =>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
55
|
+
ChildProcess.make({
|
|
56
|
+
cwd: worktree.directory,
|
|
57
|
+
stdout: outputMode,
|
|
58
|
+
stderr: outputMode,
|
|
59
|
+
stdin: "inherit",
|
|
60
|
+
})`claude --dangerously-skip-permissions -p ${`@${prdFilePath}
|
|
61
|
+
|
|
62
|
+
${prompt}`}`,
|
|
63
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
64
|
+
ChildProcess.make({
|
|
65
|
+
cwd: worktree.directory,
|
|
66
|
+
stdout: outputMode,
|
|
67
|
+
stderr: outputMode,
|
|
68
|
+
stdin: "inherit",
|
|
69
|
+
})`claude ${`@${prdFilePath}
|
|
70
|
+
|
|
71
|
+
${prompt}`}`,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
export const codex = new CliAgent({
|
|
75
|
+
id: "codex",
|
|
76
|
+
name: "codex cli",
|
|
77
|
+
command: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
78
|
+
ChildProcess.make({
|
|
79
|
+
cwd: worktree.directory,
|
|
80
|
+
stdout: outputMode,
|
|
81
|
+
stderr: outputMode,
|
|
82
|
+
stdin: "inherit",
|
|
83
|
+
})`codex exec --dangerously-bypass-approvals-and-sandbox ${`@${prdFilePath}
|
|
84
|
+
|
|
85
|
+
${prompt}`}`,
|
|
86
|
+
commandPlan: ({ outputMode, prompt, prdFilePath, worktree }) =>
|
|
87
|
+
ChildProcess.make({
|
|
88
|
+
cwd: worktree.directory,
|
|
89
|
+
stdout: outputMode,
|
|
90
|
+
stderr: outputMode,
|
|
91
|
+
stdin: "inherit",
|
|
92
|
+
})`codex ${`@${prdFilePath}
|
|
93
|
+
|
|
94
|
+
${prompt}`}`,
|
|
57
95
|
})
|
|
58
96
|
|
|
59
|
-
export const allCliAgents = [opencode, claude]
|
|
97
|
+
export const allCliAgents = [opencode, claude, codex]
|
package/src/domain/PrdIssue.ts
CHANGED
|
@@ -33,9 +33,6 @@ export class PrdIssue extends Schema.Class<PrdIssue>("PrdIssue")({
|
|
|
33
33
|
description:
|
|
34
34
|
"An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on.",
|
|
35
35
|
}),
|
|
36
|
-
complete: Schema.Boolean.annotate({
|
|
37
|
-
description: "Whether the issue is complete.",
|
|
38
|
-
}),
|
|
39
36
|
autoMerge: Schema.Boolean.annotate({
|
|
40
37
|
description:
|
|
41
38
|
"Whether the issue should be auto-merged when complete. Read-only field",
|