pi-crew 0.9.25 → 0.9.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-crew",
3
- "version": "0.9.25",
3
+ "version": "0.9.26",
4
4
  "description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
5
5
  "author": "baphuongna",
6
6
  "license": "MIT",
@@ -58,7 +58,7 @@
58
58
  "lint": "biome check --linter-enabled=true --formatter-enabled=false --max-diagnostics=50 --diagnostic-level=error .",
59
59
  "format:check": "biome format .",
60
60
  "test": "npm run test:unit && npm run test:integration",
61
- "test:unit": "node scripts/test-runner.mjs --test-concurrency=4 --test-timeout=300000 --test-force-exit test/unit/*.test.ts",
61
+ "test:unit": "node scripts/test-runner.mjs --test-concurrency=4 --test-timeout=180000 --test-force-exit test/unit/*.test.ts",
62
62
  "test:watch": "tsx --watch --test --test-concurrency=4 --test-timeout=30000 --test-force-exit test/unit/*.test.ts",
63
63
  "test:integration": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=300000 test/integration/*.test.ts",
64
64
  "test:smoke": "node scripts/test-runner.mjs --test-concurrency=1 --test-timeout=180000 test/smoke/*.smoke.ts",
@@ -410,15 +410,18 @@ export function resetEventLogMode(): void {
410
410
  * foreground-control, etc.), prefer this over the sync `appendEvent()`.
411
411
  */
412
412
  export async function appendEventAsync(eventsPath: string, event: AppendTeamEvent): Promise<TeamEvent> {
413
- // Non-terminal events: route through buffer for coalesced writes (20ms default).
414
- // This eliminates per-event fsync + persistSequence overhead for high-frequency events.
415
- // The buffer timer is kept alive (ref'd) so standalone contexts (tests, short-lived
416
- // scripts) get their events flushed before the loop drains no per-event keepAlive
417
- // intervals needed (which previously starved the event loop at high fan-out).
418
- if (!TERMINAL_EVENT_TYPES.has(event.type)) {
419
- return appendEventBuffered(eventsPath, event);
420
- }
421
- // Terminal events: direct async path for immediate durability guarantee
413
+ // FIX (v0.9.26): Do NOT route non-terminal events through appendEventBuffered.
414
+ // The buffer uses a 20ms timer + withEventLogLockAsync (promise chain), while
415
+ // the sync appendEvent path uses withEventLogLockSync (file lock with sleepSync).
416
+ // Mixing these two lock mechanisms on the same eventsPath causes a deadlock:
417
+ // the buffer timer can't fire while sleepSync blocks the event loop, and
418
+ // sleepSync can't acquire the lock while the buffer holds it via the promise
419
+ // chain. This deadlocked adaptive-implementation, implementation-fanout,
420
+ // parallel-research-dynamic, run-analysis, and team-run tests (>300s timeout).
421
+ // Reverted to v0.9.19 behavior: ALL events use the asyncQueues direct path.
422
+ // The buffer (appendEventBuffered) is still available for explicit callers
423
+ // that want coalesced writes (e.g., appendEventFireAndForget), but
424
+ // appendEventAsync itself does NOT buffer.
422
425
  const queueKey = eventsPath;
423
426
  const prev = asyncQueues.get(queueKey) ?? Promise.resolve();
424
427
  const next = prev.then(async (): Promise<TeamEvent> => {