@bastani/atomic 0.9.54 → 0.9.55-alpha.1

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +14 -0
  3. package/dist/builtin/intercom/README.md +2 -1
  4. package/dist/builtin/intercom/broker/announce-on-import.ts +5 -0
  5. package/dist/builtin/intercom/broker/broker.ts +28 -0
  6. package/dist/builtin/intercom/broker/client.ts +48 -3
  7. package/dist/builtin/intercom/broker/paths.ts +9 -0
  8. package/dist/builtin/intercom/broker/socket-writes.ts +5 -0
  9. package/dist/builtin/intercom/broker/spawn.ts +58 -6
  10. package/dist/builtin/intercom/broker/start-announcement.ts +77 -0
  11. package/dist/builtin/intercom/broker/startup-timeout.ts +23 -0
  12. package/dist/builtin/intercom/index.bundle.mjs +184 -73
  13. package/dist/builtin/intercom/package.json +1 -1
  14. package/dist/builtin/intercom/recoverable-disconnect.ts +38 -2
  15. package/dist/builtin/mcp/package.json +1 -1
  16. package/dist/builtin/subagents/package.json +1 -1
  17. package/dist/builtin/web-access/package.json +1 -1
  18. package/dist/builtin/workflows/CHANGELOG.md +26 -0
  19. package/dist/builtin/workflows/package.json +1 -1
  20. package/dist/builtin/workflows/src/durable/journal/resolution.d.ts +7 -0
  21. package/dist/builtin/workflows/src/extension/index.bundle.mjs +8458 -7874
  22. package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +687 -111
  23. package/dist/builtin/workflows/src/index.js +834 -264
  24. package/dist/builtin/workflows/src/local-worker-entry.mjs +687 -111
  25. package/dist/builtin/workflows/src/workers/public-options.d.ts +8 -0
  26. package/dist/core/extension-startup-failure.d.ts.map +1 -1
  27. package/dist/core/extension-startup-failure.js +1 -0
  28. package/dist/core/extension-startup-failure.js.map +1 -1
  29. package/dist/core/storage/session/jsonl-session-store.d.ts +27 -0
  30. package/dist/core/storage/session/jsonl-session-store.d.ts.map +1 -1
  31. package/dist/core/storage/session/jsonl-session-store.js +99 -7
  32. package/dist/core/storage/session/jsonl-session-store.js.map +1 -1
  33. package/docs/settings.md +2 -2
  34. package/docs/storage.md +2 -0
  35. package/docs/workflows/api-reference.md +3 -3
  36. package/docs/workflows/operations.md +3 -3
  37. package/npm-shrinkwrap.json +32 -32
  38. package/package.json +3 -3
@@ -22,6 +22,12 @@
22
22
  * A broker that accepts the socket but does not answer a registration in time is
23
23
  * saturated, not gone. Its timeout is recoverable for the same reason, and a
24
24
  * background relay that sees it keeps quiet unless the outage persists.
25
+ *
26
+ * A broker that retires (idle for its window, asked to shut down, or replaced)
27
+ * can end a connection that is still registering. That is a lost race, not a
28
+ * failure of this client: the broker either says so with `broker_retiring`
29
+ * before it closes, or is gone by the time the client looks. The client spawns
30
+ * and connects to the replacement.
25
31
  */
26
32
 
27
33
  import { IntercomLiveRouteRefusedError } from "./live-route-refusal.js";
@@ -61,9 +67,27 @@ export class IntercomBrokerTimeoutError extends Error implements RecoverableDisc
61
67
  }
62
68
  }
63
69
 
70
+ /** The `registration_failed` code a retiring broker answers a registration with before it closes. */
71
+ export const BROKER_RETIRING_CODE = "broker_retiring";
72
+ export const BROKER_RETIRING_REASON = "Intercom broker is retiring; connect to its replacement";
73
+
74
+ /**
75
+ * Raised when the broker a client was registering with retired first: it answered `broker_retiring`, or it ended
76
+ * the connection before answering and no longer answers on its socket. A replacement broker can be spawned and the
77
+ * registration tried again.
78
+ */
79
+ export class IntercomBrokerRetiringError extends Error implements RecoverableDisconnectMarker {
80
+ readonly intercomRecoverableDisconnect = true;
81
+
82
+ constructor(message: string = BROKER_RETIRING_REASON, options?: ErrorOptions) {
83
+ super(message, options);
84
+ this.name = "IntercomBrokerRetiringError";
85
+ }
86
+ }
87
+
64
88
  /**
65
- * True for an `IntercomClientDisconnectedError`, an `IntercomBrokerTimeoutError`, or a transient
66
- * `IntercomLiveRouteRefusedError`, directly or as a bounded `cause` ancestor.
89
+ * True for an `IntercomClientDisconnectedError`, an `IntercomBrokerTimeoutError`, an `IntercomBrokerRetiringError`,
90
+ * or a transient `IntercomLiveRouteRefusedError`, directly or as a bounded `cause` ancestor.
67
91
  */
68
92
  export function isRecoverableIntercomDisconnect(error: unknown): boolean {
69
93
  let current: unknown = error;
@@ -71,6 +95,7 @@ export function isRecoverableIntercomDisconnect(error: unknown): boolean {
71
95
  if (!(current instanceof Error)) return false;
72
96
  if (current instanceof IntercomClientDisconnectedError) return true;
73
97
  if (current instanceof IntercomBrokerTimeoutError) return true;
98
+ if (current instanceof IntercomBrokerRetiringError) return true;
74
99
  if (current instanceof IntercomLiveRouteRefusedError) return current.transient;
75
100
  current = current.cause;
76
101
  }
@@ -87,3 +112,14 @@ export function isIntercomBrokerTimeout(error: unknown): boolean {
87
112
  }
88
113
  return false;
89
114
  }
115
+
116
+ /** True for an `IntercomBrokerRetiringError`, directly or as a bounded `cause` ancestor. */
117
+ export function isIntercomBrokerRetiring(error: unknown): boolean {
118
+ let current: unknown = error;
119
+ for (let depth = 0; depth <= MAX_CAUSE_DEPTH; depth += 1) {
120
+ if (!(current instanceof Error)) return false;
121
+ if (current instanceof IntercomBrokerRetiringError) return true;
122
+ current = current.cause;
123
+ }
124
+ return false;
125
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/mcp",
3
- "version": "0.9.54",
3
+ "version": "0.9.55-alpha.1",
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.54",
3
+ "version": "0.9.55-alpha.1",
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.54",
3
+ "version": "0.9.55-alpha.1",
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": [
@@ -6,6 +6,32 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.55] - 2026-10-30
10
+
11
+ Local worker pools on remote databases, and sturdier start-up on busy and Windows machines.
12
+
13
+ - **Worker pools on any journal:** local worker pools (`workflows.localWorkers`) now run when the workflow journal is a libSQL or Turso database or another journal adapter, not only the default local SQLite file. Runs and events go to the journal; the pool's queue, leases and pooled-stage sessions stay in a local database on your machine ([#4128](https://github.com/bastani-inc/atomic/pull/4128))
14
+ - **Intercom that starts when the machine is busy:** a new broker gets 30 seconds to start (`brokerStartupTimeoutMs`), a broker that crashes at start-up is reported at once on Windows too, and a session that connects as its broker retires reconnects instead of failing ([#4126](https://github.com/bastani-inc/atomic/pull/4126))
15
+ - **Session writes on Windows:** a session lock directory Windows won't remove at once no longer fails a write or holds up the next one for ten seconds ([#4124](https://github.com/bastani-inc/atomic/pull/4124))
16
+ - **libSQL files shared between processes:** a `file:` database opened through `@bastani/atomic-storage-libsql` waits for another process's lock instead of failing
17
+
18
+ ### Added
19
+
20
+ - Local worker pools (`workflows.localWorkers`, `RunOpts.localWorkers`) now work when the workflow journal is not the default local SQLite file: a libSQL or Turso database, any other storage adapter, or a SQLite file with a custom prefix. The workers open the same journal the root uses, and the pool keeps its work queue, leases, admission state and worker logs in a SQLite file under `~/.atomic/workflows/pool/`. A pooled root on such a journal resumes on the machine where it ran; resuming it elsewhere fails with an error naming that machine. A memory journal and a journal passed to the SDK as an object still cannot host workers.
21
+
22
+ ## [0.9.55-alpha.1] - 2026-10-30
23
+
24
+ Local worker pools on remote databases, and sturdier start-up on busy and Windows machines.
25
+
26
+ - **Worker pools on any journal:** local worker pools (`workflows.localWorkers`) now run when the workflow journal is a libSQL or Turso database or another journal adapter, not only the default local SQLite file. Runs and events go to the journal; the pool's queue, leases and pooled-stage sessions stay in a local database on your machine ([#4128](https://github.com/bastani-inc/atomic/pull/4128))
27
+ - **Intercom that starts when the machine is busy:** a new broker gets 30 seconds to start (`brokerStartupTimeoutMs`), a broker that crashes at start-up is reported at once on Windows too, and a session that connects as its broker retires reconnects instead of failing ([#4126](https://github.com/bastani-inc/atomic/pull/4126))
28
+ - **Session writes on Windows:** a session lock directory Windows won't remove at once no longer fails a write or holds up the next one for ten seconds ([#4124](https://github.com/bastani-inc/atomic/pull/4124))
29
+ - **libSQL files shared between processes:** a `file:` database opened through `@bastani/atomic-storage-libsql` waits for another process's lock instead of failing
30
+
31
+ ### Added
32
+
33
+ - Local worker pools (`workflows.localWorkers`, `RunOpts.localWorkers`) now work when the workflow journal is not the default local SQLite file: a libSQL or Turso database, any other storage adapter, or a SQLite file with a custom prefix. The workers open the same journal the root uses, and the pool keeps its work queue, leases, admission state and worker logs in a SQLite file under `~/.atomic/workflows/pool/`. A pooled root on such a journal resumes on the machine where it ran; resuming it elsewhere fails with an error naming that machine. A memory journal and a journal passed to the SDK as an object still cannot host workers.
34
+
9
35
  ## [0.9.52] - 2026-10-29
10
36
 
11
37
  Stage chats show their own status lines, and web search keeps its results.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.54",
3
+ "version": "0.9.55-alpha.1",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [
@@ -19,5 +19,12 @@ export interface RunJournalResolutionOptions {
19
19
  }
20
20
  export declare function selectRunJournal(options?: RunJournalResolutionOptions): StorageSelection | RunJournal;
21
21
  export declare function resolveRunJournal(options?: RunJournalResolutionOptions): Promise<RunJournal>;
22
+ /** The storage selection a journal was opened from, so another process can open the same journal. */
23
+ export interface RunJournalOrigin {
24
+ readonly selection: StorageSelection;
25
+ readonly agentDir: string;
26
+ }
27
+ /** Where a journal came from; undefined for a journal an SDK caller passed as an object, which no other process can open. */
28
+ export declare function runJournalOrigin(journal: RunJournal): RunJournalOrigin | undefined;
22
29
  export declare function openSelectedRunJournal(selection: StorageSelection | RunJournal, agentDir?: string): Promise<RunJournal>;
23
30
  export declare function withRunJournalConfigSource<T>(selection: StorageSelection | RunJournal, open: () => Promise<T>): Promise<T>;