@bastani/atomic 0.9.61-alpha.3 → 0.9.61-alpha.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/CHANGELOG.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Local worker pools that hold up under faults and load, a lighter terminal under heavy workflow load, and workflows that can work in any repository's worktree.
8
8
 
9
- - **One failing child no longer takes down a pool:** a child that fails to dispatch fails alone, a worker or tool process group that survives SIGKILL is a warning rather than a failure, and pool faults replay the child within its three attempts, and a replay blocked by those groups' quarantined permits fails after a bounded wait instead of waiting forever ([#4159](https://github.com/bastani-inc/atomic/pull/4159), [#4170](https://github.com/bastani-inc/atomic/pull/4170))
9
+ - **One failing child no longer takes down a pool:** a child that fails to dispatch fails alone, a worker or tool process group that survives SIGKILL is a warning rather than a failure, and pool faults replay the child within its three attempts, a replay blocked by those groups' quarantined permits fails after a bounded wait instead of waiting forever, and a fenced attempt releases its session permits so its replay never waits on them ([#4159](https://github.com/bastani-inc/atomic/pull/4159), [#4170](https://github.com/bastani-inc/atomic/pull/4170), [#4172](https://github.com/bastani-inc/atomic/pull/4172))
10
10
  - **Local worker pools keep their leases:** a slow journal or root no longer gets every healthy worker killed at once, and a race in lease recovery no longer fails every child of a pool with `stale_work_lease` ([#4165](https://github.com/bastani-inc/atomic/pull/4165))
11
11
  - **A lighter terminal under heavy load:** a workflow run no longer keeps every completed stage's session in memory until it ends, which cut peak heap from 2.8 GB to 0.87 GB in a 600-stage test and shortened GC pauses. Rebuilding the chat no longer flashes "Loading isolated renderer…", and rows keep the state you left them in ([#4166](https://github.com/bastani-inc/atomic/pull/4166), [#4167](https://github.com/bastani-inc/atomic/pull/4167), [#4169](https://github.com/bastani-inc/atomic/pull/4169))
12
12
  - **Broadcasts reach pooled stages at once:** stages on local workers get queued and sticky Intercom messages before their first turn, without a 60 s stall or a warning per stage ([#4164](https://github.com/bastani-inc/atomic/pull/4164))
@@ -38,6 +38,17 @@ Local worker pools that hold up under faults and load, a lighter terminal under
38
38
  - In the interactive TUI, rows that the engine renders, such as tool results and extension messages, keep their last frame when the chat is rebuilt (after compaction, `/reload` or switching sessions), instead of showing `Loading isolated renderer…` until a busy engine renders each one again. A rebuilt chat also no longer leaves the renderers of the rows it replaced running in the engine for the rest of the session, and engine messages reach chat rows through one subscription instead of one per row. ([#4167](https://github.com/bastani-inc/atomic/pull/4167))
39
39
  - A rebuilt chat in the interactive TUI no longer briefly shows a collapsed tool row with its expanded output when the row was collapsed while its expanded frame was still on its way from the engine. Rows the chat drops while the engine connection is backed up also stay released, instead of being rendered again in the engine by a render request that arrived after their disposal. ([#4169](https://github.com/bastani-inc/atomic/pull/4169))
40
40
  - A child on a local worker pool (`workflows.localWorkers`) whose replay needs a tool process permit no longer waits forever when the only capacity left under `admission.limits.process` (or `admission.userLimits.process`) is held by quarantined permits of process groups that survived SIGKILL. Those permits stay quarantined, and capacity held by running work is still waited for as before. A process admission that only quarantined permits block now waits at most 15 seconds for those groups to exit, then fails with the retryable `worker_cleanup_unconfirmed`, naming the groups and the limit. That ends the child's attempt, so it replays within its three attempts and then fails with `worker_retry_limit`, letting the root finish. If the groups exit in time, the replay goes on normally. ([#4170](https://github.com/bastani-inc/atomic/pull/4170))
41
+ - A child on a local worker pool (`workflows.localWorkers`) whose attempt ends on a fault of the pool now gives back the session permits of that attempt's stages when the attempt ends. Before, the attempt's stage sessions stayed open on the worker, and their permits stayed granted until the worker exited or the pool closed. When the child replayed on the same worker under a tight `admission.limits.session` (or `admission.userLimits.session`), the replay could wait for those permits indefinitely, since the worker kept its lease alive. The worker keeps its lease while those sessions close, so a session that takes longer than `leaseMs` to shut down does not get a live worker killed. Permits of tool process groups that survived SIGKILL stay quarantined as before, and an attempt that ended this way still cannot record a result. ([#4172](https://github.com/bastani-inc/atomic/pull/4172))
42
+
43
+ ## [0.9.61-alpha.4] - 2026-11-02
44
+
45
+ Replays on the same local worker no longer wait on their own earlier sessions.
46
+
47
+ - **Fenced attempts release their sessions:** when a local worker ends an attempt as a pool fault, it now closes that attempt's stage sessions first, so their session permits return. A replay on the same worker under a tight `admission.limits.session` no longer waits behind its own earlier attempt indefinitely ([#4172](https://github.com/bastani-inc/atomic/pull/4172))
48
+
49
+ ### Fixed
50
+
51
+ - A child on a local worker pool (`workflows.localWorkers`) whose attempt ends on a fault of the pool now gives back the session permits of that attempt's stages when the attempt ends. Before, the attempt's stage sessions stayed open on the worker, and their permits stayed granted until the worker exited or the pool closed. When the child replayed on the same worker under a tight `admission.limits.session` (or `admission.userLimits.session`), the replay could wait for those permits indefinitely, since the worker kept its lease alive. The worker keeps its lease while those sessions close, so a session that takes longer than `leaseMs` to shut down does not get a live worker killed. Permits of tool process groups that survived SIGKILL stay quarantined as before, and an attempt that ended this way still cannot record a result. ([#4172](https://github.com/bastani-inc/atomic/pull/4172))
41
52
 
42
53
  ## [0.9.61-alpha.3] - 2026-11-02
43
54
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/intercom",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
6
6
  "contributors": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/mcp",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic's pi-compatible MCP integration for server connections, OAuth, tools, resources, and terminal management.",
6
6
  "contributors": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/subagents",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension for delegating tasks to subagents with parallel execution. Fork of: https://github.com/nicobailon/pi-subagents",
6
6
  "contributors": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -81640,6 +81640,30 @@ class WorkAttemptFencedError extends Error {
81640
81640
  this.name = "WorkAttemptFencedError";
81641
81641
  }
81642
81642
  }
81643
+ var FENCED_STAGE_CLOSE_MS = 1e4;
81644
+ async function closeAttemptStages(stageControls, store, renew) {
81645
+ const closing = Promise.allSettled(store.runs().map((run) => stageControls.clear(run.id))).then((results) => {
81646
+ for (const result of results)
81647
+ if (result.status === "rejected")
81648
+ console.warn("atomic-workflows: a fenced attempt's stage session did not close", result.reason);
81649
+ });
81650
+ let renewal;
81651
+ const pulse = () => {
81652
+ renewal ??= renew().then(() => {}, () => {}).finally(() => {
81653
+ renewal = undefined;
81654
+ });
81655
+ };
81656
+ pulse();
81657
+ const heartbeat = setInterval(pulse, WORKER_HEARTBEAT_INTERVAL_MS);
81658
+ const bound = new AbortController;
81659
+ try {
81660
+ await Promise.race([closing, delay4(FENCED_STAGE_CLOSE_MS, undefined, { signal: bound.signal }).catch(() => {})]);
81661
+ } finally {
81662
+ clearInterval(heartbeat);
81663
+ bound.abort();
81664
+ await renewal;
81665
+ }
81666
+ }
81643
81667
  function trackTurnStarts(registry, started) {
81644
81668
  return new Proxy(registry, {
81645
81669
  get(target, key) {
@@ -81800,7 +81824,7 @@ async function runWorker(start) {
81800
81824
  }
81801
81825
  return state;
81802
81826
  };
81803
- const backend = new Proxy(reader, {
81827
+ const attemptBackend = (write) => new Proxy(reader, {
81804
81828
  get(target, key) {
81805
81829
  if (typeof key !== "string" || key === "then" || /^(archive|readSettled|readPending|hasCached|hasPending|getPending)/.test(key))
81806
81830
  return;
@@ -81819,7 +81843,7 @@ async function runWorker(start) {
81819
81843
  if (key === "commitCheckpoint" || key === "commitAdditiveCheckpointBestEffort")
81820
81844
  return async (checkpoint, options) => {
81821
81845
  options?.signal?.throwIfAborted();
81822
- await commit({ kind: "checkpoint", checkpoint });
81846
+ await write({ kind: "checkpoint", checkpoint });
81823
81847
  return true;
81824
81848
  };
81825
81849
  if (typeof key === "string" && reads.has(key)) {
@@ -81890,6 +81914,9 @@ async function runWorker(start) {
81890
81914
  activeController = controller;
81891
81915
  heldAttempt = work;
81892
81916
  const store = createStore();
81917
+ let writable = true;
81918
+ const write = (mutation) => writable ? commit(mutation) : Promise.reject(new WorkAttemptFencedError("Work attempt ended"));
81919
+ const backend = attemptBackend(write);
81893
81920
  currentStore = store;
81894
81921
  const stageUiBroker = new WorkerStageUiBroker(store);
81895
81922
  prompts = { store, broker: stageUiBroker, fail: failablePrompts(store) };
@@ -82036,7 +82063,7 @@ async function runWorker(start) {
82036
82063
  backend: reader,
82037
82064
  store,
82038
82065
  root: start.root,
82039
- commit
82066
+ commit: write
82040
82067
  })
82041
82068
  }
82042
82069
  }));
@@ -82076,6 +82103,8 @@ async function runWorker(start) {
82076
82103
  await renewal;
82077
82104
  await report;
82078
82105
  await controlPulse;
82106
+ await closeAttemptStages(stageControls, store, () => request({ kind: "renew" }));
82107
+ writable = false;
82079
82108
  await request({ kind: "fenced", ...poolFault === undefined ? {} : { fault: poolFault } });
82080
82109
  }
82081
82110
  if (rootLeaseLost)
@@ -81640,6 +81640,30 @@ class WorkAttemptFencedError extends Error {
81640
81640
  this.name = "WorkAttemptFencedError";
81641
81641
  }
81642
81642
  }
81643
+ var FENCED_STAGE_CLOSE_MS = 1e4;
81644
+ async function closeAttemptStages(stageControls, store, renew) {
81645
+ const closing = Promise.allSettled(store.runs().map((run) => stageControls.clear(run.id))).then((results) => {
81646
+ for (const result of results)
81647
+ if (result.status === "rejected")
81648
+ console.warn("atomic-workflows: a fenced attempt's stage session did not close", result.reason);
81649
+ });
81650
+ let renewal;
81651
+ const pulse = () => {
81652
+ renewal ??= renew().then(() => {}, () => {}).finally(() => {
81653
+ renewal = undefined;
81654
+ });
81655
+ };
81656
+ pulse();
81657
+ const heartbeat = setInterval(pulse, WORKER_HEARTBEAT_INTERVAL_MS);
81658
+ const bound = new AbortController;
81659
+ try {
81660
+ await Promise.race([closing, delay4(FENCED_STAGE_CLOSE_MS, undefined, { signal: bound.signal }).catch(() => {})]);
81661
+ } finally {
81662
+ clearInterval(heartbeat);
81663
+ bound.abort();
81664
+ await renewal;
81665
+ }
81666
+ }
81643
81667
  function trackTurnStarts(registry, started) {
81644
81668
  return new Proxy(registry, {
81645
81669
  get(target, key) {
@@ -81800,7 +81824,7 @@ async function runWorker(start) {
81800
81824
  }
81801
81825
  return state;
81802
81826
  };
81803
- const backend = new Proxy(reader, {
81827
+ const attemptBackend = (write) => new Proxy(reader, {
81804
81828
  get(target, key) {
81805
81829
  if (typeof key !== "string" || key === "then" || /^(archive|readSettled|readPending|hasCached|hasPending|getPending)/.test(key))
81806
81830
  return;
@@ -81819,7 +81843,7 @@ async function runWorker(start) {
81819
81843
  if (key === "commitCheckpoint" || key === "commitAdditiveCheckpointBestEffort")
81820
81844
  return async (checkpoint, options) => {
81821
81845
  options?.signal?.throwIfAborted();
81822
- await commit({ kind: "checkpoint", checkpoint });
81846
+ await write({ kind: "checkpoint", checkpoint });
81823
81847
  return true;
81824
81848
  };
81825
81849
  if (typeof key === "string" && reads.has(key)) {
@@ -81890,6 +81914,9 @@ async function runWorker(start) {
81890
81914
  activeController = controller;
81891
81915
  heldAttempt = work;
81892
81916
  const store = createStore();
81917
+ let writable = true;
81918
+ const write = (mutation) => writable ? commit(mutation) : Promise.reject(new WorkAttemptFencedError("Work attempt ended"));
81919
+ const backend = attemptBackend(write);
81893
81920
  currentStore = store;
81894
81921
  const stageUiBroker = new WorkerStageUiBroker(store);
81895
81922
  prompts = { store, broker: stageUiBroker, fail: failablePrompts(store) };
@@ -82036,7 +82063,7 @@ async function runWorker(start) {
82036
82063
  backend: reader,
82037
82064
  store,
82038
82065
  root: start.root,
82039
- commit
82066
+ commit: write
82040
82067
  })
82041
82068
  }
82042
82069
  }));
@@ -82076,6 +82103,8 @@ async function runWorker(start) {
82076
82103
  await renewal;
82077
82104
  await report;
82078
82105
  await controlPulse;
82106
+ await closeAttemptStages(stageControls, store, () => request({ kind: "renew" }));
82107
+ writable = false;
82079
82108
  await request({ kind: "fenced", ...poolFault === undefined ? {} : { fault: poolFault } });
82080
82109
  }
82081
82110
  if (rootLeaseLost)
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bastani/atomic",
9
- "version": "0.9.61-alpha.3",
9
+ "version": "0.9.61-alpha.4",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@bastani/atomic-natives": "0.9.61-alpha.3",
13
- "@bastani/pi-ai": "0.9.61-alpha.3",
12
+ "@bastani/atomic-natives": "0.9.61-alpha.4",
13
+ "@bastani/pi-ai": "0.9.61-alpha.4",
14
14
  "@earendil-works/pi-agent-core": "1.4.0",
15
15
  "@earendil-works/pi-codemode": "1.4.0",
16
16
  "@earendil-works/pi-tui": "1.4.0",
@@ -427,18 +427,18 @@
427
427
  }
428
428
  },
429
429
  "node_modules/@bastani/atomic-natives": {
430
- "version": "0.9.61-alpha.3",
431
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.61-alpha.3.tgz",
430
+ "version": "0.9.61-alpha.4",
431
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.61-alpha.4.tgz",
432
432
  "license": "MIT",
433
433
  "optionalDependencies": {
434
- "@bastani/atomic-natives-darwin-arm64": "0.9.61-alpha.3",
435
- "@bastani/atomic-natives-darwin-x64": "0.9.61-alpha.3",
436
- "@bastani/atomic-natives-linux-arm64-gnu": "0.9.61-alpha.3",
437
- "@bastani/atomic-natives-linux-arm64-musl": "0.9.61-alpha.3",
438
- "@bastani/atomic-natives-linux-x64-gnu": "0.9.61-alpha.3",
439
- "@bastani/atomic-natives-linux-x64-musl": "0.9.61-alpha.3",
440
- "@bastani/atomic-natives-win32-arm64-msvc": "0.9.61-alpha.3",
441
- "@bastani/atomic-natives-win32-x64-msvc": "0.9.61-alpha.3"
434
+ "@bastani/atomic-natives-darwin-arm64": "0.9.61-alpha.4",
435
+ "@bastani/atomic-natives-darwin-x64": "0.9.61-alpha.4",
436
+ "@bastani/atomic-natives-linux-arm64-gnu": "0.9.61-alpha.4",
437
+ "@bastani/atomic-natives-linux-arm64-musl": "0.9.61-alpha.4",
438
+ "@bastani/atomic-natives-linux-x64-gnu": "0.9.61-alpha.4",
439
+ "@bastani/atomic-natives-linux-x64-musl": "0.9.61-alpha.4",
440
+ "@bastani/atomic-natives-win32-arm64-msvc": "0.9.61-alpha.4",
441
+ "@bastani/atomic-natives-win32-x64-msvc": "0.9.61-alpha.4"
442
442
  },
443
443
  "engines": {
444
444
  "bun": ">=1.4.2",
@@ -446,8 +446,8 @@
446
446
  }
447
447
  },
448
448
  "node_modules/@bastani/atomic-natives-darwin-arm64": {
449
- "version": "0.9.61-alpha.3",
450
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.61-alpha.3.tgz",
449
+ "version": "0.9.61-alpha.4",
450
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.61-alpha.4.tgz",
451
451
  "license": "MIT",
452
452
  "os": [
453
453
  "darwin"
@@ -458,8 +458,8 @@
458
458
  "optional": true
459
459
  },
460
460
  "node_modules/@bastani/atomic-natives-darwin-x64": {
461
- "version": "0.9.61-alpha.3",
462
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.61-alpha.3.tgz",
461
+ "version": "0.9.61-alpha.4",
462
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.61-alpha.4.tgz",
463
463
  "license": "MIT",
464
464
  "os": [
465
465
  "darwin"
@@ -470,8 +470,8 @@
470
470
  "optional": true
471
471
  },
472
472
  "node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
473
- "version": "0.9.61-alpha.3",
474
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.61-alpha.3.tgz",
473
+ "version": "0.9.61-alpha.4",
474
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.61-alpha.4.tgz",
475
475
  "license": "MIT",
476
476
  "os": [
477
477
  "linux"
@@ -485,8 +485,8 @@
485
485
  "optional": true
486
486
  },
487
487
  "node_modules/@bastani/atomic-natives-linux-arm64-musl": {
488
- "version": "0.9.61-alpha.3",
489
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.61-alpha.3.tgz",
488
+ "version": "0.9.61-alpha.4",
489
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.61-alpha.4.tgz",
490
490
  "license": "MIT",
491
491
  "os": [
492
492
  "linux"
@@ -500,8 +500,8 @@
500
500
  "optional": true
501
501
  },
502
502
  "node_modules/@bastani/atomic-natives-linux-x64-gnu": {
503
- "version": "0.9.61-alpha.3",
504
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.61-alpha.3.tgz",
503
+ "version": "0.9.61-alpha.4",
504
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.61-alpha.4.tgz",
505
505
  "license": "MIT",
506
506
  "os": [
507
507
  "linux"
@@ -515,8 +515,8 @@
515
515
  "optional": true
516
516
  },
517
517
  "node_modules/@bastani/atomic-natives-linux-x64-musl": {
518
- "version": "0.9.61-alpha.3",
519
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.61-alpha.3.tgz",
518
+ "version": "0.9.61-alpha.4",
519
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.61-alpha.4.tgz",
520
520
  "license": "MIT",
521
521
  "os": [
522
522
  "linux"
@@ -530,8 +530,8 @@
530
530
  "optional": true
531
531
  },
532
532
  "node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
533
- "version": "0.9.61-alpha.3",
534
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.61-alpha.3.tgz",
533
+ "version": "0.9.61-alpha.4",
534
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.61-alpha.4.tgz",
535
535
  "license": "MIT",
536
536
  "os": [
537
537
  "win32"
@@ -542,8 +542,8 @@
542
542
  "optional": true
543
543
  },
544
544
  "node_modules/@bastani/atomic-natives-win32-x64-msvc": {
545
- "version": "0.9.61-alpha.3",
546
- "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.61-alpha.3.tgz",
545
+ "version": "0.9.61-alpha.4",
546
+ "resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.61-alpha.4.tgz",
547
547
  "license": "MIT",
548
548
  "os": [
549
549
  "win32"
@@ -554,8 +554,8 @@
554
554
  "optional": true
555
555
  },
556
556
  "node_modules/@bastani/pi-ai": {
557
- "version": "0.9.61-alpha.3",
558
- "resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.61-alpha.3.tgz",
557
+ "version": "0.9.61-alpha.4",
558
+ "resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.61-alpha.4.tgz",
559
559
  "license": "MIT",
560
560
  "dependencies": {
561
561
  "@anthropic-ai/sdk": "0.129.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.9.61-alpha.3",
3
+ "version": "0.9.61-alpha.4",
4
4
  "description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "atomicConfig": {
@@ -89,8 +89,8 @@
89
89
  "prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
90
90
  },
91
91
  "dependencies": {
92
- "@bastani/atomic-natives": "0.9.61-alpha.3",
93
- "@bastani/pi-ai": "0.9.61-alpha.3",
92
+ "@bastani/atomic-natives": "0.9.61-alpha.4",
93
+ "@bastani/pi-ai": "0.9.61-alpha.4",
94
94
  "@earendil-works/pi-agent-core": "1.4.0",
95
95
  "@earendil-works/pi-codemode": "1.4.0",
96
96
  "@earendil-works/pi-tui": "1.4.0",