diff --git a/README.ko.md b/README.ko.md index 67dcaf9e..3dd0fd6f 100644 --- a/README.ko.md +++ b/README.ko.md @@ -13,7 +13,7 @@
-
+
diff --git a/README.md b/README.md
index 3ef5130f..7702b2d0 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
-
+
diff --git a/README.zh.md b/README.zh.md
index 2f645a3b..91b72199 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -13,7 +13,7 @@
-
+
diff --git a/plugins/codexclaw/components/subagent-config/dist/spawn-attach-hook.js b/plugins/codexclaw/components/subagent-config/dist/spawn-attach-hook.js
index ca8bb4d0..d04be79a 100644
--- a/plugins/codexclaw/components/subagent-config/dist/spawn-attach-hook.js
+++ b/plugins/codexclaw/components/subagent-config/dist/spawn-attach-hook.js
@@ -968,7 +968,8 @@ function main() {
? denyEnvelope("codexclaw spawn policy input exceeded 4 MiB; refusing to bypass the recursion and trust boundary")
: runSpawnAttachHook(stdin.raw);
if (out) process.stdout.write(out);
- process.exit(0);
+ // Piped stdout is asynchronous on POSIX; let pending writes finish before exiting.
+ process.exitCode = 0;
}
// Only run as a CLI entrypoint, not when imported by tests. Compare via realpath:
diff --git a/plugins/codexclaw/components/subagent-config/src/spawn-attach-hook.ts b/plugins/codexclaw/components/subagent-config/src/spawn-attach-hook.ts
index 05350057..95c756d9 100644
--- a/plugins/codexclaw/components/subagent-config/src/spawn-attach-hook.ts
+++ b/plugins/codexclaw/components/subagent-config/src/spawn-attach-hook.ts
@@ -968,7 +968,8 @@ function main(): void {
? denyEnvelope("codexclaw spawn policy input exceeded 4 MiB; refusing to bypass the recursion and trust boundary")
: runSpawnAttachHook(stdin.raw);
if (out) process.stdout.write(out);
- process.exit(0);
+ // Piped stdout is asynchronous on POSIX; let pending writes finish before exiting.
+ process.exitCode = 0;
}
// Only run as a CLI entrypoint, not when imported by tests. Compare via realpath:
diff --git a/plugins/codexclaw/components/subagent-config/test/spawn-attach-hook.test.ts b/plugins/codexclaw/components/subagent-config/test/spawn-attach-hook.test.ts
index efc73b4d..58a471f0 100644
--- a/plugins/codexclaw/components/subagent-config/test/spawn-attach-hook.test.ts
+++ b/plugins/codexclaw/components/subagent-config/test/spawn-attach-hook.test.ts
@@ -1049,3 +1049,34 @@ test("concise entrypoint is delivered once without recursively inlining its refs
const detail = readFileSync(join(SKILLS_DIR, "dev", "references", "development-practice.md"), "utf8").trim();
assert.ok(!first.includes(detail));
});
+
+test("BUG-R1: CLI source and dist drain large rewritten spawn JSON over a pipe", () => {
+ const SENTINEL = "CXC-STDOUT-DRAIN-SENTINEL-END";
+ const originalMessage = `${"A".repeat(200 * 1024)}${SENTINEL}`;
+ assert.ok(originalMessage.length < 256 * 1024, "spawn message must stay under the normalization cap");
+ const cwd = workspaceWithConfig({
+ executor: { mode: "model", model: "gpt-5.6-luna", effort: "high", promptOverride: null },
+ });
+ const payload = spawnPayloadAt(cwd, { agent_type: "worker", message: originalMessage });
+ try {
+ for (const [label, cli] of [
+ ["source", resolve(here, "../src/spawn-attach-hook.ts")],
+ ["dist", resolve(here, "../dist/spawn-attach-hook.js")],
+ ] as const) {
+ const result = spawnSync(process.execPath, [cli, "hook", "pre-tool-use"], {
+ input: payload,
+ encoding: "utf8",
+ maxBuffer: 2 * 1024 * 1024,
+ });
+ assert.equal(result.status, 0, `${label} exit status`);
+ const parsed = JSON.parse(result.stdout);
+ const ui = parsed.hookSpecificOutput.updatedInput as Record