ultracode-for-codex 0.2.2 → 0.2.4

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 CHANGED
@@ -26,7 +26,7 @@ npm run pack:ultracode-for-codex
26
26
  Install the tarball from a target project:
27
27
 
28
28
  ```bash
29
- npm install --save-dev /path/to/ultracode-for-codex-0.2.2.tgz
29
+ npm install --save-dev /path/to/ultracode-for-codex-0.2.4.tgz
30
30
  ```
31
31
 
32
32
  Run a workflow:
@@ -60,10 +60,15 @@ plugin workflow folders, and built-ins:
60
60
  npm exec -- ultracode-for-codex run \
61
61
  --accept-llm-guide=v1 \
62
62
  --cwd /path/to/target-repo \
63
- --name code-review \
64
- --args '{"prompt":"review correctness risks"}'
63
+ --name task \
64
+ --args '{"prompt":"review correctness risks and propose fixes"}'
65
65
  ```
66
66
 
67
+ The built-in `task` and `code-review` workflows use an LLM planner first, then
68
+ run work phase by phase. Within each phase, multiple focused Codex subagents run
69
+ in parallel by default, followed by phase and final synthesis. The planner may
70
+ choose a single-agent path only when parallel execution would add risk or waste.
71
+
67
72
  ## Settings
68
73
 
69
74
  Package defaults live in `settings.json`:
@@ -98,6 +103,8 @@ Use `--execution attached`, `--progress`, `--permission`, `--retry-limit`, and
98
103
  agent records also include stable agent identity and label fields.
99
104
  - Press `Ctrl-C` once to cancel the active workflow.
100
105
  - Use `--retry-limit <n>` to retry failed workflows inside the same process.
106
+ - `--timeout-ms` is the workflow timeout and the default per-agent silence
107
+ budget; it is not divided by the retry budget.
101
108
  - Use `--permission ask|allow|deny` for project/user/plugin/scriptPath workflow
102
109
  permission reviews.
103
110
  - Use `--progress plain` for human-readable log lines.
@@ -120,8 +127,9 @@ want Codex to auto-load the package boundaries and verification routine.
120
127
  environment.
121
128
  - Codex subagents run against the requested workflow cwd and receive bounded
122
129
  read-only workspace tools for text file reads and directory listings.
123
- - Built-in `code-review` injects deterministic workspace context before calling
124
- its subagent so file-specific prompts carry local evidence into the review.
130
+ - Built-in `task` and `code-review` inject deterministic workspace context into
131
+ planner-selected phase-wise parallel subagents, then synthesize each phase and
132
+ the final result.
125
133
  - Workflow execution is local and command-owned; settings default to OS
126
134
  background execution and `--execution attached` keeps the process connected
127
135
  until completion.
@@ -31,7 +31,7 @@ npm exec -- ultracode-for-codex --llm-guide
31
31
  For source-checkout validation, install the generated tarball instead:
32
32
 
33
33
  ```bash
34
- npm install --save-dev ./ultracode-for-codex-0.2.2.tgz
34
+ npm install --save-dev ./ultracode-for-codex-0.2.4.tgz
35
35
  ```
36
36
 
37
37
  Optional Codex companion skill:
@@ -58,6 +58,12 @@ npm exec -- ultracode-for-codex run \
58
58
  The default run prints a background launch record to stdout. Use
59
59
  `--execution attached` when Codex should read progress until completion.
60
60
 
61
+ Use built-in `task` for general work and `code-review` for review-specific work.
62
+ Both start with an LLM planner, execute phase by phase, run multiple focused
63
+ Codex subagents in parallel within each phase by default, and synthesize phase
64
+ and final results. The planner chooses a single-agent path only when parallel
65
+ execution would add risk or waste.
66
+
61
67
  Settings defaults:
62
68
 
63
69
  ```json
@@ -87,6 +93,8 @@ Useful controls:
87
93
  agent records also include stable agent identity and label fields.
88
94
  - Press `Ctrl-C` once to cancel the running workflow.
89
95
  - Use `--retry-limit <n>` to retry failed runs in the same process.
96
+ - `--timeout-ms` is the workflow timeout and the default per-agent silence
97
+ budget; it is not divided by the retry budget.
90
98
  - Use `--permission ask|allow|deny` for project/user/plugin/scriptPath
91
99
  workflow permission reviews.
92
100
  - Use `--progress plain` for human-readable log lines.
@@ -106,8 +114,9 @@ Useful controls:
106
114
  - Strip direct provider credentials from child CLI environments.
107
115
  - Run Codex subagents against the requested workflow cwd and provide bounded
108
116
  read-only workspace tools for text file reads and directory listings.
109
- - Built-in `code-review` adds deterministic workspace context before the agent
110
- call, prioritizing files explicitly mentioned in the prompt.
117
+ - Built-in `task` and `code-review` add deterministic workspace context to
118
+ planner-selected phase-wise parallel subagents, then synthesize each phase and
119
+ the final result.
111
120
  - Install consumers from a packaged artifact.
112
121
  - Keep `journalPath`, `journal.jsonl`, and journal contents out of CLI output.
113
122
  Local runtime state may still contain runtime-owned
@@ -10,7 +10,6 @@ import { WORKFLOW_JOURNAL_GENESIS_AGENT_CALL_KEY, WORKFLOW_JOURNAL_WRITE_FAILED_
10
10
  const MAX_SCRIPT_BYTES = 64 * 1024;
11
11
  const MAX_AGENT_CALLS = 1000;
12
12
  const MAX_PARALLELISM = 16;
13
- const DEFAULT_AGENT_STALL_TIMEOUT_MS = 180_000;
14
13
  const DEFAULT_AGENT_STALL_RETRY_LIMIT = 5;
15
14
  const DEFAULT_WORKSPACE_CONTEXT_MAX_FILES = 24;
16
15
  const DEFAULT_WORKSPACE_CONTEXT_MAX_FILE_BYTES = 12_000;
@@ -100,39 +99,209 @@ const WORKSPACE_CONTEXT_PRIORITY_FILES = new Set([
100
99
  'tsconfig.json',
101
100
  ]);
102
101
  const DEFAULT_BUILTIN_WORKFLOWS = [
102
+ {
103
+ name: 'task',
104
+ script: phaseWiseBuiltinWorkflowScript({
105
+ name: 'task',
106
+ description: 'Run an LLM-planned phase-wise parallel task workflow',
107
+ defaultPrompt: 'Complete the requested repository task.',
108
+ plannerKind: 'general task',
109
+ plannerGuidance: 'Plan phases that make the work faster and more accurate through parallel agents. Default to phase_parallel. Choose single only for tiny changes, strictly sequential investigations, or one indivisible failure mode.',
110
+ agentGuidance: 'Complete the assigned phase work. Prefer concrete evidence, file paths, commands, and risks over broad narration.',
111
+ finalGuidance: 'Return the completed task result, key evidence, decisions made, verification status, and residual risk.',
112
+ }),
113
+ },
103
114
  {
104
115
  name: 'code-review',
105
- script: `export const meta = {
106
- name: "code-review",
107
- description: "Run a code review workflow"
108
- };
109
- const input = args && typeof args === "object" ? args : {};
110
- const prompt = typeof input.prompt === "string" && input.prompt.trim()
111
- ? input.prompt
112
- : "Review the current repository for correctness risks.";
113
- const context = await workspaceContext({ query: prompt });
114
- return await agent([
115
- prompt,
116
- "",
117
- "Use the deterministic workspace context below as primary evidence. Mention any missing evidence explicitly.",
118
- "",
119
- context
120
- ].join("\\n"), { label: "code-review" });`,
116
+ script: phaseWiseBuiltinWorkflowScript({
117
+ name: 'code-review',
118
+ description: 'Run an LLM-planned phase-wise parallel code review workflow',
119
+ defaultPrompt: 'Review the current repository for correctness risks.',
120
+ plannerKind: 'code review',
121
+ plannerGuidance: 'Plan an effective code review. Default to phase_parallel with multiple focused reviewers per phase. Commonly useful lenses include runtime correctness, security/capability boundaries, API/CLI contracts, persistence/retry/cancel behavior, and test coverage. Choose single only for a tiny scoped diff or one indivisible failure mode.',
122
+ agentGuidance: 'Return material findings only. Prioritize root cause, severity, exact file/line evidence, reproduction or impact, and residual risk.',
123
+ finalGuidance: 'Return findings ordered by severity with exact file/line references. Deduplicate overlaps, preserve dissent or uncertainty, and say clearly if there are no material findings.',
124
+ }),
121
125
  },
122
126
  {
123
127
  name: 'batch',
124
128
  script: `export const meta = {
125
129
  name: "batch",
126
- description: "Run multiple prompts in parallel"
130
+ description: "Run explicitly supplied prompts in one parallel phase"
127
131
  };
128
132
  const input = args && typeof args === "object" ? args : {};
129
133
  const prompts = Array.isArray(input.prompts) ? input.prompts : [];
134
+ phase("Batch");
130
135
  return await parallel(prompts.map((prompt, index) => () => agent(
131
136
  prompt == null ? "" : "" + prompt,
132
137
  { label: "batch-" + (index + 1) }
133
138
  )));`,
134
139
  },
135
140
  ];
141
+ function phaseWiseBuiltinWorkflowScript(input) {
142
+ return `export const meta = {
143
+ name: ${JSON.stringify(input.name)},
144
+ description: ${JSON.stringify(input.description)}
145
+ };
146
+ const workflowInput = args && typeof args === "object" ? args : {};
147
+ const prompt = typeof workflowInput.prompt === "string" && workflowInput.prompt.trim()
148
+ ? workflowInput.prompt
149
+ : ${JSON.stringify(input.defaultPrompt)};
150
+ const context = await workspaceContext({ query: prompt });
151
+ const plan = await agent([
152
+ ${JSON.stringify(`Plan the phase-wise execution strategy for ${input.plannerKind}.`)},
153
+ "",
154
+ ${JSON.stringify(input.plannerGuidance)},
155
+ "A phase runs after previous phase summaries are available. Within each phase, use parallel agents by default.",
156
+ "Return 1 to 4 phases. For ordinary work, prefer 2 phases with 2 to 4 parallel agents each. Use concise stable ids.",
157
+ "",
158
+ "User request:",
159
+ prompt,
160
+ "",
161
+ context
162
+ ].join("\\n"), {
163
+ label: ${JSON.stringify(`${input.name}-planner`)},
164
+ schema: {
165
+ type: "object",
166
+ additionalProperties: false,
167
+ properties: {
168
+ mode: { type: "string", enum: ["phase_parallel", "single"] },
169
+ rationale: { type: "string", minLength: 1 },
170
+ phases: {
171
+ type: "array",
172
+ minItems: 1,
173
+ maxItems: 4,
174
+ items: {
175
+ type: "object",
176
+ additionalProperties: false,
177
+ properties: {
178
+ id: { type: "string", minLength: 1, maxLength: 32 },
179
+ title: { type: "string", minLength: 1, maxLength: 80 },
180
+ goal: { type: "string", minLength: 1, maxLength: 800 },
181
+ agents: {
182
+ type: "array",
183
+ minItems: 1,
184
+ maxItems: 4,
185
+ items: {
186
+ type: "object",
187
+ additionalProperties: false,
188
+ properties: {
189
+ id: { type: "string", minLength: 1, maxLength: 32 },
190
+ title: { type: "string", minLength: 1, maxLength: 80 },
191
+ focus: { type: "string", minLength: 1, maxLength: 800 }
192
+ },
193
+ required: ["id", "title", "focus"]
194
+ }
195
+ }
196
+ },
197
+ required: ["id", "title", "goal", "agents"]
198
+ }
199
+ }
200
+ },
201
+ required: ["mode", "rationale", "phases"]
202
+ }
203
+ });
204
+ const selectedPhases = plan.mode === "single" ? [plan.phases[0]] : plan.phases;
205
+ if (plan.mode === "single") {
206
+ const singlePhase = selectedPhases[0];
207
+ const singleAgent = singlePhase.agents[0];
208
+ phase(singlePhase.title);
209
+ return await agent([
210
+ "Single-agent execution selected by the LLM planner.",
211
+ "Planner rationale: " + plan.rationale,
212
+ "Phase goal: " + singlePhase.goal,
213
+ "Agent focus: " + singleAgent.title + " - " + singleAgent.focus,
214
+ "",
215
+ "Original request:",
216
+ prompt,
217
+ "",
218
+ ${JSON.stringify(input.agentGuidance)},
219
+ "",
220
+ "Use the deterministic workspace context below as primary evidence. Mention any missing evidence explicitly.",
221
+ "",
222
+ context
223
+ ].join("\\n"), { label: ${JSON.stringify(`${input.name}-single`)}, phase: singlePhase.title });
224
+ }
225
+ const phaseOutputs = [];
226
+ const priorSummaries = [];
227
+ for (const phasePlan of selectedPhases) {
228
+ phase(phasePlan.title);
229
+ const agents = phasePlan.agents;
230
+ const agentOutputs = agents.length < 2
231
+ ? [await agent([
232
+ "Parallel phase agent: " + agents[0].title,
233
+ "Phase: " + phasePlan.title,
234
+ "Phase goal: " + phasePlan.goal,
235
+ "Agent focus: " + agents[0].focus,
236
+ "",
237
+ "Previous phase summaries:",
238
+ JSON.stringify(priorSummaries, null, 2),
239
+ "",
240
+ "Original request:",
241
+ prompt,
242
+ "",
243
+ ${JSON.stringify(input.agentGuidance)},
244
+ "",
245
+ "Use the deterministic workspace context below as primary evidence. Mention any missing evidence explicitly.",
246
+ "",
247
+ context
248
+ ].join("\\n"), { label: ${JSON.stringify(`${input.name}-`)} + phasePlan.id + "-" + agents[0].id, phase: phasePlan.title })]
249
+ : await parallel(agents.map((phaseAgent) => () => agent([
250
+ "Parallel phase agent: " + phaseAgent.title,
251
+ "Phase: " + phasePlan.title,
252
+ "Phase goal: " + phasePlan.goal,
253
+ "Agent focus: " + phaseAgent.focus,
254
+ "",
255
+ "Previous phase summaries:",
256
+ JSON.stringify(priorSummaries, null, 2),
257
+ "",
258
+ "Original request:",
259
+ prompt,
260
+ "",
261
+ ${JSON.stringify(input.agentGuidance)},
262
+ "",
263
+ "Use the deterministic workspace context below as primary evidence. Mention any missing evidence explicitly.",
264
+ "",
265
+ context
266
+ ].join("\\n"), { label: ${JSON.stringify(`${input.name}-`)} + phasePlan.id + "-" + phaseAgent.id, phase: phasePlan.title })));
267
+ const phaseSummary = await agent([
268
+ "Synthesize this phase.",
269
+ "Phase: " + phasePlan.title,
270
+ "Phase goal: " + phasePlan.goal,
271
+ "",
272
+ "Original request:",
273
+ prompt,
274
+ "",
275
+ "Agent outputs:",
276
+ JSON.stringify(agentOutputs, null, 2),
277
+ "",
278
+ "Return a concise phase summary with material findings, completed work, open questions, and what the next phase should know."
279
+ ].join("\\n"), { label: ${JSON.stringify(`${input.name}-phase-`)} + phasePlan.id + "-synthesis", phase: phasePlan.title });
280
+ const phaseRecord = {
281
+ id: phasePlan.id,
282
+ title: phasePlan.title,
283
+ goal: phasePlan.goal,
284
+ results: agentOutputs,
285
+ summary: phaseSummary
286
+ };
287
+ phaseOutputs.push(phaseRecord);
288
+ priorSummaries.push({ id: phaseRecord.id, title: phaseRecord.title, summary: phaseRecord.summary });
289
+ }
290
+ return await agent([
291
+ ${JSON.stringify(`Synthesize the phase-wise ${input.plannerKind} workflow into the final result.`)},
292
+ "",
293
+ "Original request:",
294
+ prompt,
295
+ "",
296
+ "Planner rationale:",
297
+ plan.rationale,
298
+ "",
299
+ "Phase outputs:",
300
+ JSON.stringify(phaseOutputs, null, 2),
301
+ "",
302
+ ${JSON.stringify(input.finalGuidance)}
303
+ ].join("\\n"), { label: ${JSON.stringify(`${input.name}-final-synthesis`)} });`;
304
+ }
136
305
  export class WorkflowTaskRegistry {
137
306
  options;
138
307
  tasks = new Map();
@@ -146,7 +315,7 @@ export class WorkflowTaskRegistry {
146
315
  this.options = options;
147
316
  this.stateDir = options.stateDir ?? join(options.cwd ?? process.cwd(), '.ultracode-for-codex');
148
317
  this.agentStallRetryLimit = normalizeAgentStallRetryLimit(options.agentStallRetryLimit);
149
- this.agentStallTimeoutMs = normalizeAgentStallTimeoutMs(options.agentStallTimeoutMs, options.requestTimeoutMs, this.agentStallRetryLimit);
318
+ this.agentStallTimeoutMs = normalizeAgentStallTimeoutMs(options.agentStallTimeoutMs, options.requestTimeoutMs);
150
319
  }
151
320
  async launch(input) {
152
321
  if (this.closed)
@@ -2469,12 +2638,11 @@ function normalizeAgentStallRetryLimit(value) {
2469
2638
  return DEFAULT_AGENT_STALL_RETRY_LIMIT;
2470
2639
  return Math.max(0, Math.floor(value));
2471
2640
  }
2472
- function normalizeAgentStallTimeoutMs(configured, requestTimeoutMs, retryLimit) {
2641
+ function normalizeAgentStallTimeoutMs(configured, requestTimeoutMs) {
2473
2642
  if (configured !== undefined && Number.isFinite(configured) && configured > 0) {
2474
2643
  return Math.max(1, Math.floor(configured));
2475
2644
  }
2476
- const retryAwareTimeout = Math.floor(requestTimeoutMs / Math.max(1, retryLimit + 2));
2477
- return Math.max(1, Math.min(DEFAULT_AGENT_STALL_TIMEOUT_MS, retryAwareTimeout));
2645
+ return Math.max(1, Math.floor(requestTimeoutMs));
2478
2646
  }
2479
2647
  function workflowTaskSnapshot(task) {
2480
2648
  return {
@@ -7,7 +7,7 @@ Date: 2026-06-22
7
7
  This audit checked:
8
8
 
9
9
  - tracked repository files;
10
- - generated npm package contents for `ultracode-for-codex@0.2.2`;
10
+ - generated npm package contents for `ultracode-for-codex@0.2.3`;
11
11
  - the locally installed companion Codex skill.
12
12
 
13
13
  Generated build output and package tarballs were checked as projections of the
@@ -23,7 +23,7 @@ License transition completed:
23
23
 
24
24
  - Apache-2.0 `LICENSE` file is present;
25
25
  - `package.json` and `package-lock.json` declare `Apache-2.0`;
26
- - package version is prepared as `0.2.2` for the license-bearing patch release.
26
+ - package version is prepared as `0.2.3` for the license-bearing patch release.
27
27
 
28
28
  ## Evidence
29
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultracode-for-codex",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Run local Codex-backed workflows from a command-owned CLI runtime.",
5
5
  "keywords": [
6
6
  "codex",
@@ -17,6 +17,12 @@ command process. `settings.json` defaults runs to OS background execution.
17
17
  Attached runs stream stderr JSONL for Codex-readable status, while stdout
18
18
  remains the final workflow result JSON.
19
19
 
20
+ The default Ultracode work shape is phase-wise parallel execution: built-in
21
+ `task` and `code-review` first call a planner agent, then execute each planned
22
+ phase with parallel focused subagents by default, followed by phase and final
23
+ synthesis. A single-agent path is reserved for cases where the planner judges
24
+ parallel execution risky or wasteful.
25
+
20
26
  ## Install And Run
21
27
 
22
28
  Use the npm package for consumer installs.
@@ -35,7 +41,7 @@ For source-checkout validation before publish:
35
41
 
36
42
  ```bash
37
43
  npm run pack:ultracode-for-codex
38
- npm install --save-dev ./artifacts/ultracode-for-codex-0.2.2.tgz
44
+ npm install --save-dev ./artifacts/ultracode-for-codex-0.2.4.tgz
39
45
  ```
40
46
 
41
47
  CLI behavior:
@@ -49,6 +55,8 @@ CLI behavior:
49
55
  with agent identity and label fields on agent records;
50
56
  - `Ctrl-C` cancels the active attached workflow;
51
57
  - `--retry-limit <n>` retries failed workflows inside the same process;
58
+ - `--timeout-ms` is the workflow timeout and the default per-agent silence
59
+ budget; it is not divided by the retry budget.
52
60
  - `--permission ask|allow|deny` handles project/user/plugin/scriptPath reviews.
53
61
  - `--progress plain` switches to human-readable progress lines.
54
62
  - background file locations are controlled by `workflow.background` in
@@ -60,8 +68,8 @@ CLI behavior:
60
68
  - Keep direct provider credentials out of Codex child process environments.
61
69
  - Codex subagents run against the requested workflow cwd and have bounded
62
70
  read-only workspace tools for text file reads and directory listings.
63
- - Built-in `code-review` injects deterministic workspace context and prioritizes
64
- files explicitly mentioned in the prompt.
71
+ - Built-in `task` and `code-review` inject deterministic workspace context into
72
+ planner-selected phase-wise parallel subagents.
65
73
  - Keep workflow execution local and command-owned; settings default to OS
66
74
  background execution and `--execution attached` keeps the process connected
67
75
  until completion.