Problem
The Worker's per-file editor fan-out runs Promise.all(manifest.files.map(runEditor)) (packages/aitm/src/subagents/worker.ts:319) with no concurrency bound. The real harness caps parallel subagents at min(16, cores-2) with a per-call item cap. On a large manifest, aitm fires an unbounded number of concurrent generateText calls, which reliably 429s the provider — directly undercutting the "really big PRs" scenario the fan-out exists for.
What
Bound the fan-out with a small semaphore (p-limit style, portable — no new dep needed), default ~8, configurable. Preserve per-file ordering of results and the existing error handling.
Constraints (per CLAUDE.md)
Portable ESM, strict TS, paired *.test.ts.
Acceptance criteria
- A manifest of N files runs at most
cap editors concurrently; results and error semantics unchanged.
- Cap is configurable with a sane default.
bun test + node --test + biome + tsc all green (both packages).
Found during the post-epic-#100 parity verification pass (B10). P2 follow-up.
Part of #196.
Problem
The Worker's per-file editor fan-out runs
Promise.all(manifest.files.map(runEditor))(packages/aitm/src/subagents/worker.ts:319) with no concurrency bound. The real harness caps parallel subagents atmin(16, cores-2)with a per-call item cap. On a large manifest, aitm fires an unbounded number of concurrentgenerateTextcalls, which reliably 429s the provider — directly undercutting the "really big PRs" scenario the fan-out exists for.What
Bound the fan-out with a small semaphore (p-limit style, portable — no new dep needed), default ~8, configurable. Preserve per-file ordering of results and the existing error handling.
Constraints (per CLAUDE.md)
Portable ESM, strict TS, paired
*.test.ts.Acceptance criteria
capeditors concurrently; results and error semantics unchanged.bun test+node --test+ biome + tsc all green (both packages).Found during the post-epic-#100 parity verification pass (B10). P2 follow-up.
Part of #196.