Skip to content

Commit 4b788b3

Browse files
committed
release: prepare 0.2.4
1 parent e7cffb4 commit 4b788b3

6 files changed

Lines changed: 66 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.2.4 — 2026-06-05
44

55
- Added the `parallel-fix` Codex skill and example workflow for proposing independent fixes concurrently, then integrating and verifying serially.
66
- Hardened replay/cache correctness: implicit cwd is now part of cache identity, nested phases inside parallel no longer alias, and failed topology branches keep completed child dependencies for downstream invalidation.

cli/doctor.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,33 @@ function checkBusinessAuditSkill(): Check {
100100
};
101101
}
102102

103+
function checkParallelFixSkill(): Check {
104+
const skillDir = path.join(codexHome(), "skills", "parallel-fix");
105+
const skillPath = path.join(skillDir, "SKILL.md");
106+
const required = [
107+
skillPath,
108+
path.join(skillDir, "references", "fix-method.md"),
109+
path.join(skillDir, "references", "fix-template.workflow.ts"),
110+
path.join(skillDir, "agents", "openai.yaml"),
111+
];
112+
if (existsSync(skillPath)) {
113+
const missing = required.filter((file) => !existsSync(file));
114+
if (!missing.length) return { name: "parallel fix skill", status: "ok", detail: skillPath };
115+
return {
116+
name: "parallel fix skill",
117+
status: "warn",
118+
detail: `stale or incomplete: ${skillDir}`,
119+
next: "Run `codex-flow install-codex`, then restart Codex.",
120+
};
121+
}
122+
return {
123+
name: "parallel fix skill",
124+
status: "warn",
125+
detail: `missing: ${skillPath}`,
126+
next: "Run `codex-flow install-codex`, then restart Codex.",
127+
};
128+
}
129+
103130
async function checkFakeBackend(): Promise<Check> {
104131
let dir: string;
105132
try {
@@ -146,6 +173,7 @@ export async function doctor(argv: string[]): Promise<void> {
146173
checkNode(),
147174
checkSkill(),
148175
checkBusinessAuditSkill(),
176+
checkParallelFixSkill(),
149177
checkCodexCli(),
150178
await checkFakeBackend(),
151179
];

cli/install-codex.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url";
66
const SKILLS = [
77
{ src: "../codex-skill", name: "dynamic-workflow" },
88
{ src: "../codex-skill-business-audit", name: "business-defect-audit" },
9+
{ src: "../codex-skill-parallel-fix", name: "parallel-fix" },
910
];
1011

1112
function codexHome(): string {

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codex-flow",
3-
"version": "0.2.3",
3+
"version": "0.2.4",
44
"description": "Dynamic workflow orchestration for Codex — split complex tasks into parallel, resumable, journaled Codex sub-agents.",
55
"type": "module",
66
"license": "MIT",
@@ -55,6 +55,7 @@
5555
"adapters",
5656
"codex-skill",
5757
"codex-skill-business-audit",
58+
"codex-skill-parallel-fix",
5859
"README.md",
5960
"examples",
6061
"docs",

tests/cli.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ describe("codex-flow cli", () => {
8686
assert.match(text, /name: dynamic-workflow/);
8787
assert.ok(existsSync(path.join(dir, "dynamic-workflow", "references", "engine-api.md")), "reference should be copied");
8888
assert.ok(existsSync(path.join(dir, "dynamic-workflow", "references", "setup.md")), "setup reference should be copied");
89+
assert.ok(existsSync(path.join(dir, "business-defect-audit", "SKILL.md")), "business audit skill should be copied");
90+
assert.ok(existsSync(path.join(dir, "parallel-fix", "SKILL.md")), "parallel fix skill should be copied");
91+
assert.ok(existsSync(path.join(dir, "parallel-fix", "references", "fix-method.md")), "parallel fix reference should be copied");
8992
await rm(dir, { recursive: true, force: true });
9093
});
9194

@@ -205,6 +208,35 @@ describe("codex-flow cli", () => {
205208
await rm(dir, { recursive: true, force: true });
206209
});
207210

211+
it("doctor warns when the bundled parallel fix skill is missing", async () => {
212+
const dir = await mkdtemp(path.join(tmpdir(), "codex-flow-doctor-"));
213+
const dynamicRefs = path.join(dir, "skills", "dynamic-workflow", "references");
214+
const auditRefs = path.join(dir, "skills", "business-defect-audit", "references");
215+
const auditAgents = path.join(dir, "skills", "business-defect-audit", "agents");
216+
await mkdir(dynamicRefs, { recursive: true });
217+
await mkdir(auditRefs, { recursive: true });
218+
await mkdir(auditAgents, { recursive: true });
219+
await writeFile(path.join(dir, "skills", "dynamic-workflow", "SKILL.md"), "---\nname: dynamic-workflow\n---\n", "utf8");
220+
await writeFile(path.join(dynamicRefs, "engine-api.md"), "api\n", "utf8");
221+
await writeFile(path.join(dynamicRefs, "setup.md"), "setup\n", "utf8");
222+
await writeFile(path.join(dir, "skills", "business-defect-audit", "SKILL.md"), "---\nname: business-defect-audit\n---\n", "utf8");
223+
await writeFile(path.join(auditRefs, "audit-method.md"), "method\n", "utf8");
224+
await writeFile(path.join(auditRefs, "audit-template.workflow.ts"), "workflow\n", "utf8");
225+
await writeFile(path.join(auditAgents, "openai.yaml"), "agent\n", "utf8");
226+
227+
const res = spawnSync("node", [binPath, "doctor", "--json"], {
228+
encoding: "utf8",
229+
env: { ...process.env, CODEX_HOME: dir },
230+
});
231+
assert.equal(res.status, 0, res.stderr);
232+
const body = JSON.parse(res.stdout);
233+
const parallelSkill = body.checks.find((check: any) => check.name === "parallel fix skill");
234+
assert.equal(parallelSkill.status, "warn");
235+
assert.match(parallelSkill.detail, /parallel-fix/);
236+
assert.match(parallelSkill.next, /codex-flow install-codex/);
237+
await rm(dir, { recursive: true, force: true });
238+
});
239+
208240
it("doctor and smoke report unavailable temp dirs without crashing", async () => {
209241
const dir = await mkdtemp(path.join(tmpdir(), "codex-flow-temp-"));
210242
const badTmp = path.join(dir, "tmp");

0 commit comments

Comments
 (0)