orcastrator 0.2.19 → 0.2.23
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 +13 -29
- package/dist/cli/commands/help.d.ts.map +1 -1
- package/dist/cli/commands/help.js +8 -34
- package/dist/cli/commands/resume.d.ts +1 -3
- package/dist/cli/commands/resume.d.ts.map +1 -1
- package/dist/cli/commands/resume.js +3 -19
- package/dist/cli/commands/run-command.test-harness.d.ts.map +1 -1
- package/dist/cli/commands/run-command.test-harness.js +8 -0
- package/dist/cli/commands/run.d.ts +1 -3
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +24 -39
- package/dist/cli/commands/setup.d.ts +4 -8
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +103 -391
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +16 -19
- package/dist/core/planner.d.ts +3 -3
- package/dist/core/planner.d.ts.map +1 -1
- package/dist/core/planner.js +5 -13
- package/dist/core/task-runner.d.ts +5 -2
- package/dist/core/task-runner.d.ts.map +1 -1
- package/dist/core/task-runner.js +3 -16
- package/dist/types/effort.d.ts +0 -3
- package/dist/types/effort.d.ts.map +1 -1
- package/dist/types/effort.js +0 -4
- package/dist/types/index.d.ts +2 -10
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -3
- package/dist/agents/claude/session.d.ts +0 -10
- package/dist/agents/claude/session.d.ts.map +0 -1
- package/dist/agents/claude/session.js +0 -364
- package/dist/types/config-typing.typecheck.js +0 -32
package/README.md
CHANGED
|
@@ -109,7 +109,7 @@ orca pr publish --last
|
|
|
109
109
|
|
|
110
110
|
Orca auto-discovers config in this order:
|
|
111
111
|
|
|
112
|
-
1. `~/.orca/config.js`
|
|
112
|
+
1. Global config: `~/.orca/config.ts` (preferred when both exist) or `~/.orca/config.js`
|
|
113
113
|
2. Project config: `./orca.config.ts` (preferred when both exist) or `./orca.config.js`
|
|
114
114
|
3. `--config <path>` (if passed)
|
|
115
115
|
|
|
@@ -120,20 +120,12 @@ Later entries override earlier ones.
|
|
|
120
120
|
import { defineOrcaConfig } from "orcastrator";
|
|
121
121
|
|
|
122
122
|
export default defineOrcaConfig({
|
|
123
|
-
executor: "codex",
|
|
124
|
-
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
125
|
-
openaiApiKey: process.env.OPENAI_API_KEY,
|
|
123
|
+
executor: "codex", openaiApiKey: process.env.OPENAI_API_KEY,
|
|
126
124
|
runsDir: "./.orca/runs",
|
|
127
125
|
sessionLogs: "./session-logs",
|
|
128
126
|
skills: ["./.orca/skills"],
|
|
129
127
|
maxRetries: 1,
|
|
130
|
-
|
|
131
|
-
model: "claude-sonnet-4-20250514",
|
|
132
|
-
effort: "medium",
|
|
133
|
-
useV2Preview: true,
|
|
134
|
-
maxTurnsPerTask: 12,
|
|
135
|
-
allowTextJsonFallback: false
|
|
136
|
-
},
|
|
128
|
+
|
|
137
129
|
codex: {
|
|
138
130
|
enabled: true,
|
|
139
131
|
model: "gpt-5.3-codex",
|
|
@@ -186,11 +178,10 @@ export default defineOrcaConfig({
|
|
|
186
178
|
|
|
187
179
|
### Config field reference (OrcaConfig)
|
|
188
180
|
|
|
189
|
-
Top-level: `executor`, `
|
|
181
|
+
Top-level: `executor`, `openaiApiKey`, `runsDir`, `sessionLogs`, `skills`, `maxRetries`, `hooks`, `hookCommands`, `pr`, `review`, `codex`.
|
|
190
182
|
|
|
191
183
|
- `pr.enabled`, `pr.requireConfirmation`
|
|
192
184
|
- `maxRetries` is part of `OrcaConfig`; current planner-generated task retries remain fixed in task graph contracts
|
|
193
|
-
- `claude.model`, `claude.effort`, `claude.useV2Preview`, `claude.maxTurnsPerTask`, `claude.allowTextJsonFallback`
|
|
194
185
|
- `codex.enabled`, `codex.model`, `codex.effort`, `codex.command`, `codex.timeoutMs`, `codex.multiAgent`, `codex.perCwdExtraUserRoots`
|
|
195
186
|
- `review.plan.enabled`, `review.plan.onInvalid`
|
|
196
187
|
- `review.execution.enabled`, `review.execution.maxCycles`, `review.execution.onFindings`, `review.execution.validator.auto`, `review.execution.validator.commands`, `review.execution.prompt`
|
|
@@ -229,9 +220,7 @@ Global:
|
|
|
229
220
|
- `--plan <path>`
|
|
230
221
|
- `--config <path>`
|
|
231
222
|
- `--codex-only` (force Codex executor for this run)
|
|
232
|
-
- `--claude-only` (force Claude executor for this run)
|
|
233
223
|
- `--codex-effort <low|medium|high>`
|
|
234
|
-
- `--claude-effort <low|medium|high|max>`
|
|
235
224
|
- `--on-milestone <cmd>`
|
|
236
225
|
- `--on-task-complete <cmd>`
|
|
237
226
|
- `--on-task-fail <cmd>`
|
|
@@ -259,9 +248,7 @@ Global:
|
|
|
259
248
|
- `--last`
|
|
260
249
|
- `--config <path>`
|
|
261
250
|
- `--codex-only`
|
|
262
|
-
- `--claude-only`
|
|
263
251
|
- `--codex-effort <low|medium|high>`
|
|
264
|
-
- `--claude-effort <low|medium|high|max>`
|
|
265
252
|
|
|
266
253
|
`orca cancel`:
|
|
267
254
|
|
|
@@ -297,13 +284,13 @@ Global:
|
|
|
297
284
|
|
|
298
285
|
`orca setup`:
|
|
299
286
|
|
|
300
|
-
-
|
|
287
|
+
- auto-detect is default
|
|
301
288
|
- `--openai-key <key>` — override OpenAI API key (written to config)
|
|
302
|
-
- `--executor <codex
|
|
303
|
-
- `--
|
|
304
|
-
- `--
|
|
305
|
-
- `--project
|
|
306
|
-
- `--
|
|
289
|
+
- `--executor <codex>` — explicitly set executor in written config
|
|
290
|
+
- `--ts` — write TS config output (`~/.orca/config.ts` / `./orca.config.ts`)
|
|
291
|
+
- `--global` — save to global config (`~/.orca/config.js` by default, or `.ts` with `--ts`)
|
|
292
|
+
- `--project` — save to project config (`./orca.config.js` by default, or `.ts` with `--ts`)
|
|
293
|
+
- `--project-config-template` / `--skip-project-config` removed
|
|
307
294
|
|
|
308
295
|
`orca help`:
|
|
309
296
|
|
|
@@ -342,8 +329,8 @@ Run IDs are generated as:
|
|
|
342
329
|
|
|
343
330
|
### Config File Locations
|
|
344
331
|
|
|
345
|
-
- Global: `~/.orca/config.js`
|
|
346
|
-
- Project: `./orca.config.
|
|
332
|
+
- Global: `~/.orca/config.ts` (preferred when both exist) or `~/.orca/config.js`
|
|
333
|
+
- Project: `./orca.config.ts` (preferred when both exist) or `./orca.config.js`
|
|
347
334
|
- Explicit: `--config <path>`
|
|
348
335
|
|
|
349
336
|
### Project Instruction Files
|
|
@@ -351,11 +338,8 @@ Run IDs are generated as:
|
|
|
351
338
|
During planning, Orca automatically injects project instruction files when present:
|
|
352
339
|
|
|
353
340
|
1. `AGENTS.md`
|
|
354
|
-
2. `CLAUDE.md`
|
|
355
|
-
|
|
356
|
-
Files are discovered from the project root (nearest `.git` from the spec/task context) and injected in that order.
|
|
357
341
|
|
|
358
|
-
|
|
342
|
+
Files are discovered from the project root (nearest `.git` from the spec/task context) and injected when present.
|
|
359
343
|
|
|
360
344
|
### Project Skills
|
|
361
345
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/help.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/help.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4EzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiB1D"}
|
|
@@ -11,7 +11,7 @@ function printSection(title, entries) {
|
|
|
11
11
|
console.log("");
|
|
12
12
|
}
|
|
13
13
|
function printStyledHelpPage() {
|
|
14
|
-
console.log("orca — coordinated
|
|
14
|
+
console.log("orca — coordinated codex run harness");
|
|
15
15
|
console.log("");
|
|
16
16
|
printSection("RUNNING", [
|
|
17
17
|
{ command: 'orca "add auth to the app"', description: "run with inline goal" },
|
|
@@ -33,34 +33,15 @@ function printStyledHelpPage() {
|
|
|
33
33
|
{ command: "orca pr publish --run <id>", description: "publish draft → ready for review" },
|
|
34
34
|
{ command: "orca pr status --run <id>", description: "check PR state and CI" }
|
|
35
35
|
]);
|
|
36
|
-
printSection("SETUP", [
|
|
37
|
-
{ command: "orca setup", description: "first-time setup and environment checks" }
|
|
38
|
-
]);
|
|
36
|
+
printSection("SETUP", [{ command: "orca setup", description: "first-time setup and Codex environment checks" }]);
|
|
39
37
|
printSection("FLAGS", [
|
|
40
38
|
{ command: "-p, --prompt <text>", description: "inline task goal (alias: --task)" },
|
|
41
39
|
{ command: "--plan, --spec <path>", description: "path to spec or plan file" },
|
|
42
40
|
{ command: "--run <id>", description: "specify run by ID" },
|
|
43
41
|
{ command: "--last", description: "use the most recent run" },
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
command: "--codex-only",
|
|
50
|
-
description: "override executor to Codex for the current run"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
command: "--claude-only",
|
|
54
|
-
description: "override executor to Claude for the current run"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
command: "--codex-effort <value>",
|
|
58
|
-
description: "override Codex effort for the current run"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
command: "--claude-effort <value>",
|
|
62
|
-
description: "override Claude effort for the current run"
|
|
63
|
-
},
|
|
42
|
+
{ command: "--config <path>", description: "explicit config file (auto-discovered by default)" },
|
|
43
|
+
{ command: "--codex-only", description: "override executor to Codex for the current run" },
|
|
44
|
+
{ command: "--codex-effort <value>", description: "override Codex effort for the current run" },
|
|
64
45
|
{ command: "--full-auto", description: "skip all questions, proceed autonomously" },
|
|
65
46
|
{ command: "--on-complete <cmd>", description: "shell hook on run complete" },
|
|
66
47
|
{ command: "--on-error <cmd>", description: "shell hook on run error" },
|
|
@@ -69,25 +50,18 @@ function printStyledHelpPage() {
|
|
|
69
50
|
]);
|
|
70
51
|
}
|
|
71
52
|
function findCommand(program, pathText) {
|
|
72
|
-
const segments = pathText
|
|
73
|
-
.split(" ")
|
|
74
|
-
.map((segment) => segment.trim())
|
|
75
|
-
.filter((segment) => segment.length > 0);
|
|
53
|
+
const segments = pathText.split(" ").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
76
54
|
let current = program;
|
|
77
55
|
for (const segment of segments) {
|
|
78
56
|
current = current.commands.find((command) => command.name() === segment);
|
|
79
|
-
if (!current)
|
|
57
|
+
if (!current)
|
|
80
58
|
return undefined;
|
|
81
|
-
}
|
|
82
59
|
}
|
|
83
60
|
return current;
|
|
84
61
|
}
|
|
85
62
|
export function registerHelpCommand(program) {
|
|
86
63
|
program.addHelpCommand(false);
|
|
87
|
-
program
|
|
88
|
-
.command("help [command]")
|
|
89
|
-
.description("display help for command")
|
|
90
|
-
.action((commandPath) => {
|
|
64
|
+
program.command("help [command]").description("display help for command").action((commandPath) => {
|
|
91
65
|
if (!commandPath) {
|
|
92
66
|
printStyledHelpPage();
|
|
93
67
|
return;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type Command } from "commander";
|
|
2
|
-
import { type
|
|
2
|
+
import { type CodexEffort } from "../../types/effort.js";
|
|
3
3
|
export interface ResumeCommandOptions {
|
|
4
4
|
run?: string;
|
|
5
5
|
last?: boolean;
|
|
6
6
|
config?: string;
|
|
7
7
|
codexOnly?: boolean;
|
|
8
|
-
claudeOnly?: boolean;
|
|
9
8
|
codexEffort?: CodexEffort;
|
|
10
|
-
claudeEffort?: ClaudeEffort;
|
|
11
9
|
}
|
|
12
10
|
export declare function resumeCommandHandler(options: ResumeCommandOptions): Promise<void>;
|
|
13
11
|
export declare function registerResumeCommand(program: Command): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAM/D,OAAO,
|
|
1
|
+
{"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAM/D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAG3E,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAgDD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEvF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiB5D"}
|
|
@@ -2,7 +2,7 @@ import { InvalidArgumentError } from "commander";
|
|
|
2
2
|
import { resolveConfig } from "../../core/config-loader.js";
|
|
3
3
|
import { runTaskRunner } from "../../core/task-runner.js";
|
|
4
4
|
import { RunStore } from "../../state/store.js";
|
|
5
|
-
import {
|
|
5
|
+
import { parseCodexEffort } from "../../types/effort.js";
|
|
6
6
|
import { getLastRun } from "../../utils/last-run.js";
|
|
7
7
|
function createStore() {
|
|
8
8
|
const runsDir = process.env.ORCA_RUNS_DIR;
|
|
@@ -25,34 +25,20 @@ function parseCodexEffortOption(value) {
|
|
|
25
25
|
throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
function parseClaudeEffortOption(value) {
|
|
29
|
-
try {
|
|
30
|
-
return parseClaudeEffort(value);
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
28
|
function applyExecutorOverrideForResume(config, options) {
|
|
37
29
|
const nextConfig = { ...config };
|
|
38
|
-
if (options.codexOnly
|
|
39
|
-
nextConfig.executor =
|
|
30
|
+
if (options.codexOnly) {
|
|
31
|
+
nextConfig.executor = "codex";
|
|
40
32
|
}
|
|
41
33
|
if (options.codexEffort !== undefined) {
|
|
42
34
|
nextConfig.codex = { ...nextConfig.codex, effort: options.codexEffort };
|
|
43
35
|
}
|
|
44
|
-
if (options.claudeEffort !== undefined) {
|
|
45
|
-
nextConfig.claude = { ...nextConfig.claude, effort: options.claudeEffort };
|
|
46
|
-
}
|
|
47
36
|
if (config === undefined && Object.keys(nextConfig).length === 0) {
|
|
48
37
|
return undefined;
|
|
49
38
|
}
|
|
50
39
|
return nextConfig;
|
|
51
40
|
}
|
|
52
41
|
export async function resumeCommandHandler(options) {
|
|
53
|
-
if (options.codexOnly && options.claudeOnly) {
|
|
54
|
-
throw new Error("--codex-only and --claude-only are mutually exclusive; choose only one executor override.");
|
|
55
|
-
}
|
|
56
42
|
const store = createStore();
|
|
57
43
|
const resolvedConfig = await resolveConfig(options.config);
|
|
58
44
|
const effectiveConfig = applyExecutorOverrideForResume(resolvedConfig, options);
|
|
@@ -116,9 +102,7 @@ export function registerResumeCommand(program) {
|
|
|
116
102
|
.option("--last", "Use the most recent run")
|
|
117
103
|
.option("--config <path>", "Path to orca config file")
|
|
118
104
|
.option("--codex-only", "Force Codex executor for this resumed run (overrides config)")
|
|
119
|
-
.option("--claude-only", "Force Claude executor for this resumed run (overrides config)")
|
|
120
105
|
.option("--codex-effort <value>", "Codex effort override for this resumed run", parseCodexEffortOption)
|
|
121
|
-
.option("--claude-effort <value>", "Claude effort override for this resumed run", parseClaudeEffortOption)
|
|
122
106
|
.action(async (options) => {
|
|
123
107
|
try {
|
|
124
108
|
await resumeCommandHandler(options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-command.test-harness.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run-command.test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvD,KAAK,SAAS,GAAG,cAAc,UAAU,CAAC,CAAC;AAE3C,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,OAAO,CAAC;QAC3B,SAAS,EAAE,SAAS,CAAC;QACrB,cAAc,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QACxC,iBAAiB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAC3C,sBAAsB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAChD,yBAAyB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QACnD,gBAAgB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAC1C,oBAAoB,EAAE,KAAK,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;KACnF,CAAC,CAAC;IACH,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,
|
|
1
|
+
{"version":3,"file":"run-command.test-harness.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run-command.test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvD,KAAK,SAAS,GAAG,cAAc,UAAU,CAAC,CAAC;AAE3C,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,OAAO,CAAC;QAC3B,SAAS,EAAE,SAAS,CAAC;QACrB,cAAc,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QACxC,iBAAiB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAC3C,sBAAsB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAChD,yBAAyB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QACnD,gBAAgB,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;QAC1C,oBAAoB,EAAE,KAAK,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC;KACnF,CAAC,CAAC;IACH,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,CAgJrF"}
|
|
@@ -7,10 +7,12 @@ export function createRunCommandTestHarness(tempPrefix) {
|
|
|
7
7
|
let tempDir = "";
|
|
8
8
|
const originalRunsDir = process.env.ORCA_RUNS_DIR;
|
|
9
9
|
const originalSkipValidators = process.env.ORCA_SKIP_VALIDATORS;
|
|
10
|
+
const originalOpenaiApiKey = process.env.OPENAI_API_KEY;
|
|
10
11
|
beforeEach(async () => {
|
|
11
12
|
tempDir = await mkdtemp(path.join(os.tmpdir(), tempPrefix));
|
|
12
13
|
process.env.ORCA_RUNS_DIR = path.join(tempDir, "runs");
|
|
13
14
|
process.env.ORCA_SKIP_VALIDATORS = "1";
|
|
15
|
+
process.env.OPENAI_API_KEY = "test-openai-key";
|
|
14
16
|
process.exitCode = 0;
|
|
15
17
|
});
|
|
16
18
|
afterEach(async () => {
|
|
@@ -28,6 +30,12 @@ export function createRunCommandTestHarness(tempPrefix) {
|
|
|
28
30
|
else {
|
|
29
31
|
process.env.ORCA_SKIP_VALIDATORS = originalSkipValidators;
|
|
30
32
|
}
|
|
33
|
+
if (originalOpenaiApiKey === undefined) {
|
|
34
|
+
delete process.env.OPENAI_API_KEY;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
process.env.OPENAI_API_KEY = originalOpenaiApiKey;
|
|
38
|
+
}
|
|
31
39
|
await rm(tempDir, { recursive: true, force: true });
|
|
32
40
|
});
|
|
33
41
|
async function loadRunModule() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Command } from "commander";
|
|
2
|
-
import { type
|
|
2
|
+
import { type CodexEffort } from "../../types/effort.js";
|
|
3
3
|
export interface RunCommandOptions {
|
|
4
4
|
spec?: string;
|
|
5
5
|
plan?: string;
|
|
@@ -8,9 +8,7 @@ export interface RunCommandOptions {
|
|
|
8
8
|
goal?: string;
|
|
9
9
|
config?: string;
|
|
10
10
|
codexOnly?: boolean;
|
|
11
|
-
claudeOnly?: boolean;
|
|
12
11
|
codexEffort?: CodexEffort;
|
|
13
|
-
claudeEffort?: ClaudeEffort;
|
|
14
12
|
onMilestone?: string;
|
|
15
13
|
onTaskComplete?: string;
|
|
16
14
|
onTaskFail?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAa/D,OAAO,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAa/D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AA6B3E,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA+CD,wBAAsB,+BAA+B,CAAC,OAAO,GAAE,MAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBnG;AAoND,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2QjF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0DzD"}
|
package/dist/cli/commands/run.js
CHANGED
|
@@ -16,8 +16,9 @@ import { createOpenclawHookHandler, detectOpenclawAvailability } from "../../hoo
|
|
|
16
16
|
import { createStdoutHookHandler } from "../../hooks/adapters/stdout.js";
|
|
17
17
|
import { HookDispatcher } from "../../hooks/dispatcher.js";
|
|
18
18
|
import { RunStore } from "../../state/store.js";
|
|
19
|
-
import {
|
|
19
|
+
import { parseCodexEffort } from "../../types/effort.js";
|
|
20
20
|
import { generateRunId } from "../../utils/ids.js";
|
|
21
|
+
import { readCodexAuthJson } from "./setup.js";
|
|
21
22
|
const exec = promisify(execCallback);
|
|
22
23
|
const ExecutionReviewPayloadSchema = z.object({
|
|
23
24
|
summary: z.string().min(1),
|
|
@@ -53,14 +54,6 @@ function parseCodexEffortOption(value) {
|
|
|
53
54
|
throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
|
-
function parseClaudeEffortOption(value) {
|
|
57
|
-
try {
|
|
58
|
-
return parseClaudeEffort(value);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
57
|
function createStore() {
|
|
65
58
|
const runsDir = process.env.ORCA_RUNS_DIR;
|
|
66
59
|
return runsDir ? new RunStore(runsDir) : new RunStore();
|
|
@@ -75,17 +68,19 @@ async function pathExists(filePath) {
|
|
|
75
68
|
}
|
|
76
69
|
}
|
|
77
70
|
export async function maybeCreateFirstRunGlobalConfig(homedir = os.homedir()) {
|
|
78
|
-
const
|
|
71
|
+
const globalJsConfigPath = path.join(homedir, ".orca", "config.js");
|
|
72
|
+
const globalTsConfigPath = path.join(homedir, ".orca", "config.ts");
|
|
79
73
|
const projectJsConfigPath = path.join(process.cwd(), "orca.config.js");
|
|
80
74
|
const projectTsConfigPath = path.join(process.cwd(), "orca.config.ts");
|
|
81
|
-
const hasAnyConfig = (await pathExists(
|
|
75
|
+
const hasAnyConfig = (await pathExists(globalJsConfigPath))
|
|
76
|
+
|| (await pathExists(globalTsConfigPath))
|
|
82
77
|
|| (await pathExists(projectJsConfigPath))
|
|
83
78
|
|| (await pathExists(projectTsConfigPath));
|
|
84
79
|
if (hasAnyConfig) {
|
|
85
80
|
return;
|
|
86
81
|
}
|
|
87
|
-
await mkdir(path.dirname(
|
|
88
|
-
await writeFile(
|
|
82
|
+
await mkdir(path.dirname(globalJsConfigPath), { recursive: true });
|
|
83
|
+
await writeFile(globalJsConfigPath, "export default {\n executor: \"codex\"\n};\n", "utf8");
|
|
89
84
|
console.log("✓ Created ~/.orca/config.js (first run defaults)");
|
|
90
85
|
}
|
|
91
86
|
function computeFinalStatus(overallStatus, allTasksDone) {
|
|
@@ -108,17 +103,22 @@ function buildCliCommandHooks(options) {
|
|
|
108
103
|
...(options.onError ? { onError: options.onError } : {})
|
|
109
104
|
};
|
|
110
105
|
}
|
|
106
|
+
function isCodexAvailableForRun(env = process.env) {
|
|
107
|
+
const envOpenai = env.ORCA_OPENAI_API_KEY ?? env.OPENAI_API_KEY;
|
|
108
|
+
if (typeof envOpenai === "string" && envOpenai.trim().length > 0) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
const homeDir = typeof env.HOME === "string" && env.HOME.trim().length > 0 ? env.HOME : os.homedir();
|
|
112
|
+
return Boolean(readCodexAuthJson(homeDir));
|
|
113
|
+
}
|
|
111
114
|
function applyExecutorOverrideForRun(config, options) {
|
|
112
115
|
const nextConfig = { ...config };
|
|
113
|
-
if (options.codexOnly
|
|
114
|
-
nextConfig.executor =
|
|
116
|
+
if (options.codexOnly) {
|
|
117
|
+
nextConfig.executor = "codex";
|
|
115
118
|
}
|
|
116
119
|
if (options.codexEffort !== undefined) {
|
|
117
120
|
nextConfig.codex = { ...nextConfig.codex, effort: options.codexEffort };
|
|
118
121
|
}
|
|
119
|
-
if (options.claudeEffort !== undefined) {
|
|
120
|
-
nextConfig.claude = { ...nextConfig.claude, effort: options.claudeEffort };
|
|
121
|
-
}
|
|
122
122
|
if (config === undefined && Object.keys(nextConfig).length === 0) {
|
|
123
123
|
return undefined;
|
|
124
124
|
}
|
|
@@ -249,9 +249,6 @@ async function requestStructuredExecutionReview(runPrompt, cycleIndex, basePromp
|
|
|
249
249
|
};
|
|
250
250
|
}
|
|
251
251
|
export async function runCommandHandler(options) {
|
|
252
|
-
if (options.codexOnly && options.claudeOnly) {
|
|
253
|
-
throw new Error("--codex-only and --claude-only are mutually exclusive; choose only one executor override.");
|
|
254
|
-
}
|
|
255
252
|
const inlineTask = options.task ?? options.prompt ?? options.goal;
|
|
256
253
|
const inputSpecPath = options.spec ?? options.plan;
|
|
257
254
|
if (options.goal !== undefined && (options.task || options.prompt)) {
|
|
@@ -280,6 +277,11 @@ export async function runCommandHandler(options) {
|
|
|
280
277
|
await maybeCreateFirstRunGlobalConfig();
|
|
281
278
|
const orcaConfig = await resolveConfig(options.config);
|
|
282
279
|
const effectiveConfig = applyExecutorOverrideForRun(orcaConfig, options);
|
|
280
|
+
if (!isCodexAvailableForRun()) {
|
|
281
|
+
console.error("Codex is unavailable. Set OPENAI_API_KEY (or ORCA_OPENAI_API_KEY) or configure ~/.codex/auth.json.");
|
|
282
|
+
process.exitCode = 1;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
283
285
|
const runId = generateRunId(specPath);
|
|
284
286
|
console.log(`Run ID: ${runId}`);
|
|
285
287
|
const store = createStore();
|
|
@@ -346,8 +348,7 @@ export async function runCommandHandler(options) {
|
|
|
346
348
|
mode: "run",
|
|
347
349
|
overallStatus: "running"
|
|
348
350
|
});
|
|
349
|
-
|
|
350
|
-
if (executor === "codex") {
|
|
351
|
+
{
|
|
351
352
|
const cwd = process.cwd();
|
|
352
353
|
const multiAgentResult = await ensureCodexMultiAgent(effectiveConfig);
|
|
353
354
|
if (multiAgentResult.action === "created" || multiAgentResult.action === "appended") {
|
|
@@ -441,15 +442,6 @@ export async function runCommandHandler(options) {
|
|
|
441
442
|
await codexSession.disconnect();
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
|
-
else {
|
|
445
|
-
console.log("Phase 4: Skipping Codex consultation because executor is set to Claude.");
|
|
446
|
-
await runTaskRunner({
|
|
447
|
-
runId,
|
|
448
|
-
store,
|
|
449
|
-
...(effectiveConfig ? { config: effectiveConfig } : {}),
|
|
450
|
-
emitHook
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
445
|
const run = await store.getRun(runId);
|
|
454
446
|
if (!run) {
|
|
455
447
|
throw new Error(`Run not found after execution: ${runId}`);
|
|
@@ -483,9 +475,7 @@ export function registerRunCommand(program) {
|
|
|
483
475
|
.option("-p, --prompt <text>", "Inline task text (alias for --task)")
|
|
484
476
|
.option("--config <path>", "Path to orca config file")
|
|
485
477
|
.option("--codex-only", "Force Codex executor for this run (overrides config)")
|
|
486
|
-
.option("--claude-only", "Force Claude executor for this run (overrides config)")
|
|
487
478
|
.option("--codex-effort <value>", "Codex effort override for this run", parseCodexEffortOption)
|
|
488
|
-
.option("--claude-effort <value>", "Claude effort override for this run", parseClaudeEffortOption)
|
|
489
479
|
.option("--on-milestone <cmd>", "Shell hook command for onMilestone")
|
|
490
480
|
.option("--on-task-complete <cmd>", "Shell hook command for onTaskComplete")
|
|
491
481
|
.option("--on-task-fail <cmd>", "Shell hook command for onTaskFail")
|
|
@@ -499,11 +489,6 @@ export function registerRunCommand(program) {
|
|
|
499
489
|
...commandOptions,
|
|
500
490
|
...(goal !== undefined ? { goal } : {})
|
|
501
491
|
};
|
|
502
|
-
if (normalizedOptions.codexOnly && normalizedOptions.claudeOnly) {
|
|
503
|
-
console.error("Error: --codex-only and --claude-only are mutually exclusive; choose only one.");
|
|
504
|
-
process.exitCode = 1;
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
492
|
const inlineTask = normalizedOptions.task ?? normalizedOptions.prompt ?? normalizedOptions.goal;
|
|
508
493
|
const inputSpecPath = normalizedOptions.spec ?? normalizedOptions.plan;
|
|
509
494
|
if (normalizedOptions.goal !== undefined && (normalizedOptions.task || normalizedOptions.prompt)) {
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { type Command } from "commander";
|
|
2
2
|
export interface SetupCommandOptions {
|
|
3
|
-
anthropicKey?: string;
|
|
4
3
|
openaiKey?: string;
|
|
5
4
|
global?: boolean;
|
|
6
5
|
project?: boolean;
|
|
7
|
-
|
|
6
|
+
ts?: boolean;
|
|
7
|
+
executor?: "codex";
|
|
8
8
|
projectConfigTemplate?: boolean;
|
|
9
9
|
skipProjectConfig?: boolean;
|
|
10
10
|
}
|
|
11
|
-
type PackageManager = "brew" | "apt" | "winget";
|
|
12
11
|
type ApiKeyConfig = {
|
|
13
|
-
anthropicApiKey?: string;
|
|
14
12
|
openaiApiKey?: string;
|
|
15
|
-
executor?: "codex"
|
|
13
|
+
executor?: "codex";
|
|
16
14
|
};
|
|
17
15
|
type ResolveApiKeyOptions = {
|
|
18
16
|
openclawConfigPath?: string;
|
|
@@ -21,9 +19,7 @@ type ResolveApiKeyOptions = {
|
|
|
21
19
|
export declare function resolveApiKey(flagValue: string | undefined, envVarName: string, openclawConfigPathOrOptions?: string | ResolveApiKeyOptions, maybeOptions?: ResolveApiKeyOptions): string | undefined;
|
|
22
20
|
export declare function readCodexAuthJson(homedir?: string): string | undefined;
|
|
23
21
|
export declare function readClaudeCodeKeychain(): string | undefined;
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function buildConfigModule({ anthropicApiKey, openaiApiKey, executor }: ApiKeyConfig): string;
|
|
26
|
-
export declare function buildProjectConfigTemplate(): string;
|
|
22
|
+
export declare function buildConfigModule({ openaiApiKey, executor }: ApiKeyConfig): string;
|
|
27
23
|
export declare function setupCommandHandler(options: SetupCommandOptions): Promise<void>;
|
|
28
24
|
export declare function registerSetupCommand(program: Command): void;
|
|
29
25
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAI/D,MAAM,WAAW,mBAAmB;IAClC,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAI/D,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAID,KAAK,YAAY,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAGlE,KAAK,oBAAoB,GAAG;IAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9E,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,EAAE,MAAM,EAClB,2BAA2B,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAC3D,YAAY,CAAC,EAAE,oBAAoB,GAClC,MAAM,GAAG,SAAS,CAsBpB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAqB,GAAG,MAAM,GAAG,SAAS,CAUpF;AAED,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAE3D;AAOD,wBAAgB,iBAAiB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,YAAY,GAAG,MAAM,CAMlF;AA6DD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDrF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAY3D"}
|