@cello-protocol/daemon 0.0.50 → 0.0.51

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/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export type { Logger, LockFileContent, IpcRequest, IpcResponse, IpcResponseOk, IpcResponseError, IpcNotification, IpcFrame, AgentState, AgentInfo, ConnectionStatus, ConnectionInfo, DirectorySignalingState, DaemonStatusResponse, DaemonConfig, IManifestProvider, IManifestVersionStore, IManifestPollScheduler, IDirectoryChallengeVerifier, } from "./types.js";
2
2
  export { ErrorCodes } from "./types.js";
3
3
  export { startDaemon, type DaemonHandle } from "./daemon.js";
4
- export { readLock, acquireLock, removeLock, isProcessAlive } from "./lock-file.js";
4
+ export { readLock, acquireLock, removeLock, removeLockIfOwned, isProcessAlive } from "./lock-file.js";
5
+ export { acquireSingletonLock, probeSingletonLock, DaemonAlreadyRunningError, SINGLETON_LOCK_FILENAME, type SingletonLock, } from "./singleton-lock.js";
5
6
  export { loadAgents, type LoadedAgent, type FailedAgent, type AgentLoadResult } from "./agent-loader.js";
6
7
  export { createIpcServer, type IpcServer, type IpcHandler, type IpcServerConfig, type IpcDisconnectHandler } from "./ipc-server.js";
7
8
  export { connectToDaemon, type IpcClient, IpcError } from "./ipc-client.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,eAAe,EACf,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAK7G,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,eAAe,EACf,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtG,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAK7G,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { ErrorCodes } from "./types.js";
2
2
  export { startDaemon } from "./daemon.js";
3
- export { readLock, acquireLock, removeLock, isProcessAlive } from "./lock-file.js";
3
+ export { readLock, acquireLock, removeLock, removeLockIfOwned, isProcessAlive } from "./lock-file.js";
4
+ export { acquireSingletonLock, probeSingletonLock, DaemonAlreadyRunningError, SINGLETON_LOCK_FILENAME, } from "./singleton-lock.js";
4
5
  export { loadAgents } from "./agent-loader.js";
5
6
  export { createIpcServer } from "./ipc-server.js";
6
7
  export { connectToDaemon, IpcError } from "./ipc-client.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAA4D,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAoF,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAA0D,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,qFAAqF;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AASjC,+DAA+D;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAE7G,6FAA6F;AAC7F,+FAA+F;AAC/F,4EAA4E;AAC5E,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,GAGjB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtG,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAA4D,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAoF,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAA0D,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,qFAAqF;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AASjC,+DAA+D;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAE7G,6FAA6F;AAC7F,+FAA+F;AAC/F,4EAA4E;AAC5E,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,GAGjB,MAAM,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ipc-server.d.ts","sourceRoot":"","sources":["../src/ipc-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,KAAK,EAAE,MAAM,EAA2B,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,kBAAkB,IAAI,MAAM,CAAC;IAC7B,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,qFAAqF;IACrF,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,GAAG,OAAO,CAAC;IAC/E,wCAAwC;IACxC,gBAAgB,IAAI,MAAM,EAAE,CAAC;CAC9B;AASD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAChC,SAAS,CAyPX"}
1
+ {"version":3,"file":"ipc-server.d.ts","sourceRoot":"","sources":["../src/ipc-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,KAAK,EAAE,MAAM,EAA2B,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,kBAAkB,IAAI,MAAM,CAAC;IAC7B,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,qFAAqF;IACrF,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,GAAG,OAAO,CAAC;IAC/E,wCAAwC;IACxC,gBAAgB,IAAI,MAAM,EAAE,CAAC;CAC9B;AASD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAChC,SAAS,CA6TX"}
@@ -28,13 +28,42 @@
28
28
  * e. Unlink socket file
29
29
  */
30
30
  import { createServer } from "node:net";
31
- import { chmod, unlink } from "node:fs/promises";
31
+ import { chmod, stat, unlink } from "node:fs/promises";
32
32
  import { randomUUID } from "node:crypto";
33
33
  export function createIpcServer(config, handlers) {
34
34
  const { socketPath, maxConnections, logger } = config;
35
35
  let server = null;
36
36
  const connections = new Map();
37
37
  let stopping = false;
38
+ // DOD-DAEMON-CLEANUP-1 (AC2): the identity — not the path — of the socket THIS server created.
39
+ // dev+ino is the only thing that survives another daemon rebinding the same path.
40
+ let createdSocket = null;
41
+ /**
42
+ * What is sitting at socketPath right now?
43
+ * "ours" — the socket this server created; we may remove it.
44
+ * "gone" — nothing there; nothing to do.
45
+ * "foreign" — a DIFFERENT socket. Another daemon rebound the path. Hands off.
46
+ *
47
+ * The distinction is by inode, not by path. A path tells you a file exists; only the inode tells
48
+ * you it is the same file you made.
49
+ */
50
+ async function socketOwnership() {
51
+ let current;
52
+ try {
53
+ current = await stat(socketPath);
54
+ }
55
+ catch {
56
+ // Nothing at the path (ENOENT is the only realistic case) — there is nothing to own.
57
+ return "gone";
58
+ }
59
+ if (createdSocket === null) {
60
+ // Unreachable: stop() returns early unless the server is listening, and a listening server has
61
+ // been through start(), which sets this or throws. Say so rather than inventing an answer —
62
+ // guessing here is what the whole unit is about.
63
+ throw new Error("ipc server: socket identity unknown — stop() ran without a completed start()");
64
+ }
65
+ return current.dev === createdSocket.dev && current.ino === createdSocket.ino ? "ours" : "foreign";
66
+ }
38
67
  let disconnectHandler = null;
39
68
  function handleConnection(socket) {
40
69
  if (stopping) {
@@ -186,6 +215,18 @@ export function createIpcServer(config, handlers) {
186
215
  });
187
216
  // SI-001: Set socket permissions to owner-only
188
217
  await chmod(socketPath, 0o600);
218
+ // DOD-DAEMON-CLEANUP-1 (AC2): remember WHICH socket we created, by identity — not merely that
219
+ // a file exists at this path. If another daemon later rebinds the path, its listen() replaces
220
+ // the file with a different inode, and stop() must be able to tell the two apart so it does not
221
+ // unlink a socket it does not own.
222
+ //
223
+ // No fallback here, deliberately. Swallowing this stat and leaving the identity unknown would
224
+ // make stop() treat our OWN socket as foreign: it would then never close the server, so the
225
+ // daemon would go on accepting IPC connections into a torn-down handler stack after stop()
226
+ // returned, and would leave its socket behind. A daemon that cannot identify the socket it just
227
+ // bound has no business coming up — and startup failure is already handled cleanly.
228
+ const created = await stat(socketPath);
229
+ createdSocket = { dev: created.dev, ino: created.ino };
189
230
  },
190
231
  async stop() {
191
232
  stopping = true;
@@ -221,19 +262,44 @@ export function createIpcServer(config, handlers) {
221
262
  // Connection may already be closed
222
263
  }
223
264
  }
224
- // Close server and remove socket
225
- await new Promise((resolve) => {
226
- server.close(() => resolve());
227
- });
228
- try {
229
- await unlink(socketPath);
265
+ // DOD-DAEMON-CLEANUP-1 (AC2): decide ownership BEFORE closing, because close() is itself a
266
+ // blind unlink.
267
+ //
268
+ // Node's server.close() removes the unix socket path it bound — by PATH, with no check on what
269
+ // is actually there now. If another daemon has since rebound this path, closing our server
270
+ // deletes THEIR socket, and they are left alive, serving, and unreachable. Guarding our own
271
+ // explicit unlink is not enough; the close would already have done the damage.
272
+ const ownership = await socketOwnership();
273
+ if (ownership === "foreign") {
274
+ // We must not close: that would unlink the healthy daemon's socket out from under it. Drop
275
+ // the handle from the event loop instead and let process exit reclaim the fd. The listening
276
+ // socket is already inert — its path was taken from it, so nothing can reach it. Leaking an
277
+ // unreachable fd for the last moments of a dying process is a trade we make happily against
278
+ // disarming a live peer.
279
+ logger.info("daemon.ipc.socket.not_ours", { socketPath, ourIno: createdSocket?.ino ?? null });
280
+ server.unref();
230
281
  }
231
- catch (err) {
232
- if (err.code !== "ENOENT") {
233
- logger.warn("daemon.ipc.socket.unlink.failed", {
234
- socketPath,
235
- error: err instanceof Error ? err.message : String(err),
236
- });
282
+ else {
283
+ await new Promise((resolve) => {
284
+ server.close(() => resolve());
285
+ });
286
+ // close() normally unlinks the path for us. Re-check rather than assume: only remove the file
287
+ // if it is STILL the socket we created. Between the close and here, the singleton lock is
288
+ // still held (the daemon releases it after this returns), so no successor can have bound the
289
+ // path — but the cost of re-checking is one stat, and the cost of being wrong is the bug this
290
+ // whole unit exists to kill.
291
+ if (await socketOwnership() === "ours") {
292
+ try {
293
+ await unlink(socketPath);
294
+ }
295
+ catch (err) {
296
+ if (err.code !== "ENOENT") {
297
+ logger.warn("daemon.ipc.socket.unlink.failed", {
298
+ socketPath,
299
+ error: err instanceof Error ? err.message : String(err),
300
+ });
301
+ }
302
+ }
237
303
  }
238
304
  }
239
305
  server = null;
@@ -1 +1 @@
1
- {"version":3,"file":"ipc-server.js","sourceRoot":"","sources":["../src/ipc-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ipc-server.js","sourceRoot":"","sources":["../src/ipc-server.ts"],"names":[],"mappings":"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"}
@@ -23,5 +23,17 @@ import type { LockFileContent, Logger } from "./types.js";
23
23
  export declare function readLock(lockPath: string): Promise<LockFileContent | null>;
24
24
  export declare function acquireLock(lockPath: string, content: LockFileContent): Promise<void>;
25
25
  export declare function removeLock(lockPath: string, logger: Logger): Promise<void>;
26
+ /**
27
+ * DOD-DAEMON-CLEANUP-1 (AC1) — remove the lock ONLY if it is still ours.
28
+ *
29
+ * An exiting daemon must not disarm a daemon it does not own. By the time we shut down, a DIFFERENT
30
+ * daemon may have written this lock; deleting it would leave that healthy daemon unreachable
31
+ * (`cello logout` reports "No daemon running") and the next `cello login` would spawn a third beside
32
+ * it. That is the cascade — the obvious recovery action, killing the orphan, propagates the bug.
33
+ *
34
+ * `removeLock` (unconditional) is still correct for the CLI's stale-lock cleanup, where the lock
35
+ * belongs to a process that is provably gone. It is NOT correct on the way out of a live daemon.
36
+ */
37
+ export declare function removeLockIfOwned(lockPath: string, ownPid: number, logger: Logger): Promise<void>;
26
38
  export declare function isProcessAlive(pid: number): boolean;
27
39
  //# sourceMappingURL=lock-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../src/lock-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAwBhF;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3F;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD"}
1
+ {"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../src/lock-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAwBhF;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3F;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD"}
package/dist/lock-file.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * 4. removeLock(path):
20
20
  * - Unlink the file, ignoring ENOENT
21
21
  */
22
- import { readFile, writeFile, rename, unlink } from "node:fs/promises";
22
+ import { readFile, writeFile, rename, stat, unlink } from "node:fs/promises";
23
23
  export async function readLock(lockPath) {
24
24
  let raw;
25
25
  try {
@@ -72,6 +72,41 @@ export async function removeLock(lockPath, logger) {
72
72
  }
73
73
  }
74
74
  }
75
+ /**
76
+ * DOD-DAEMON-CLEANUP-1 (AC1) — remove the lock ONLY if it is still ours.
77
+ *
78
+ * An exiting daemon must not disarm a daemon it does not own. By the time we shut down, a DIFFERENT
79
+ * daemon may have written this lock; deleting it would leave that healthy daemon unreachable
80
+ * (`cello logout` reports "No daemon running") and the next `cello login` would spawn a third beside
81
+ * it. That is the cascade — the obvious recovery action, killing the orphan, propagates the bug.
82
+ *
83
+ * `removeLock` (unconditional) is still correct for the CLI's stale-lock cleanup, where the lock
84
+ * belongs to a process that is provably gone. It is NOT correct on the way out of a live daemon.
85
+ */
86
+ export async function removeLockIfOwned(lockPath, ownPid, logger) {
87
+ const lock = await readLock(lockPath);
88
+ if (lock === null) {
89
+ // readLock returns null for BOTH "absent" and "unparseable" — so this is the one place that
90
+ // cannot tell "nothing to do" from "something is wrong". Distinguish them: a lock file that
91
+ // exists but cannot be read (truncated by a full disk, a partial write) is left alone, because we
92
+ // cannot prove it is ours — but it is said out loud rather than passed over in silence.
93
+ try {
94
+ await stat(lockPath);
95
+ logger.warn("daemon.lock.unreadable", { ownPid, lockPath });
96
+ }
97
+ catch {
98
+ // Genuinely absent. Nothing to remove, nothing to report.
99
+ }
100
+ return;
101
+ }
102
+ if (lock.pid !== ownPid) {
103
+ // SI: a daemon that declines to remove a lock says so. Silence here is what made the live
104
+ // incident so hard to see.
105
+ logger.info("daemon.lock.not_ours", { ownPid, lockPid: lock.pid, lockPath });
106
+ return;
107
+ }
108
+ await removeLock(lockPath, logger);
109
+ }
75
110
  export function isProcessAlive(pid) {
76
111
  try {
77
112
  process.kill(pid, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"lock-file.js","sourceRoot":"","sources":["../src/lock-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGvE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QAC1D,IACE,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAC9B,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;YACrC,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,EAClC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,OAAwB;IAC1E,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,CAAC;YAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;QAClE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,MAAc;IAC/D,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;gBACvC,QAAQ;gBACR,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"lock-file.js","sourceRoot":"","sources":["../src/lock-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * DOD-SINGLE-DAEMON-1 — the daemon singleton, enforced by the kernel.
3
+ *
4
+ * `daemon.lock` is a JSON file, and a file cannot answer "is a daemon running?". Anyone may delete
5
+ * it; a `kill -9` leaves it behind naming a pid that is dead — or, worse, one the OS has since REUSED
6
+ * for an unrelated process, which makes `isProcessAlive()` say "yes" forever. Every stale-lock
7
+ * heuristic ever written is an attempt to guess what only the kernel actually knows.
8
+ *
9
+ * So we ask the kernel. The daemon takes a real POSIX write lock (`fcntl`) on a dedicated file and
10
+ * holds it for its entire lifetime. Two processes cannot hold it at once, and the kernel drops it the
11
+ * instant the holder dies — SIGKILL, panic, `kill -9`, however it goes. There is no stale state to
12
+ * clean up and no recovery step to get wrong.
13
+ *
14
+ * ## Why SQLite is the lock
15
+ *
16
+ * Node has no `flock`. `fs.constants.O_EXLOCK` exists only on macOS/BSD — using it would leave every
17
+ * Linux operator (including the EC2 demo agent) with NO lock at all, which is worse than none because
18
+ * it looks like one. A native `flock` addon (`fs-ext`) compiles from source, and install time is a
19
+ * cost every operator pays on every version bump (see CLAUDE.md — the client is a heavy local node,
20
+ * not a thin wrapper).
21
+ *
22
+ * `@signalapp/sqlcipher` is already a daemon dependency, ships prebuilt (no compile), and SQLite's
23
+ * whole business is taking correct `fcntl` locks on every POSIX platform. `locking_mode = exclusive`
24
+ * plus one header write acquires the exclusive lock and holds it until the connection closes. A
25
+ * second process gets SQLITE_BUSY immediately (`busy_timeout = 0`). SQLite also tracks locks per
26
+ * inode inside the process, so this correctly refuses a second daemon in the SAME process too —
27
+ * which raw `fcntl`, whose locks are per-process, would not.
28
+ *
29
+ * The lock database holds no rows and never will. It is a mutex that happens to be spelled in SQL.
30
+ *
31
+ * ## The division of labour with daemon.lock (AC4)
32
+ *
33
+ * The OS lock DECIDES whether a daemon may start. `daemon.lock` only SUPPLIES METADATA — it is how we
34
+ * learn the holder's pid to name in the error, because `fcntl` will not tell us. If the JSON is
35
+ * missing, stale, or lying, the worst outcome is a less specific error message. It can never admit a
36
+ * second daemon, and it can never wedge a legitimate one out.
37
+ *
38
+ * ## The one constraint
39
+ *
40
+ * `~/.cello` must live on a LOCAL filesystem. POSIX `fcntl` locks are advisory-but-honoured on local
41
+ * filesystems (APFS, ext4, xfs — macOS and the Linux hosts we run on); on NFSv3 without a working
42
+ * `lockd`, and on some 9p/WSL2 setups, they can silently degrade to no-ops. There, two daemons would
43
+ * both "acquire" and the singleton would be absent while appearing present. We do not attempt to
44
+ * detect this — a real self-test needs a second process, which is far too much to do at every startup.
45
+ * The lock path is logged in `daemon.singleton.acquired` so an operator debugging a two-daemon
46
+ * situation can see exactly which file the kernel was asked about.
47
+ */
48
+ import type { Logger } from "./types.js";
49
+ /** The file the kernel lock is taken on. Holds no data — see the note above. */
50
+ export declare const SINGLETON_LOCK_FILENAME = "daemon.singleton";
51
+ export declare class DaemonAlreadyRunningError extends Error {
52
+ /** The pid from `daemon.lock`, or null when that file is absent/unreadable/malformed. */
53
+ readonly holderPid: number | null;
54
+ constructor(holderPid: number | null);
55
+ }
56
+ export interface SingletonLock {
57
+ /** Release the lock. The kernel would do this on process exit anyway; this is for in-process use. */
58
+ release(): void;
59
+ }
60
+ /** The daemon binary's exit code when it loses the singleton race — distinct from 1 = "broken". */
61
+ export declare const EXIT_ALREADY_RUNNING = 3;
62
+ export declare function acquireSingletonLock(celloDir: string, logger: Logger, busyTimeoutMs?: number): SingletonLock;
63
+ /**
64
+ * Is a daemon holding the lock for `celloDir` right now?
65
+ *
66
+ * "held" — a daemon is alive. Connect to it; never spawn beside it.
67
+ * "free" — no daemon is running, whatever `daemon.lock` claims. Spawning is correct.
68
+ * "unknown" — we could not ask the kernel (native module missing, directory unreadable).
69
+ *
70
+ * The third answer is the point. "I could not determine whether a daemon is running" and "no daemon is
71
+ * running" are different facts, and collapsing them into one boolean means the caller spawns on both —
72
+ * so the one case where we are blind becomes the one case we start a second daemon. Callers must
73
+ * refuse to spawn on "unknown" and surface the underlying error instead.
74
+ *
75
+ * Asking the kernel rather than trusting `daemon.lock` is also what makes a REUSED pid harmless: a
76
+ * stale lock file naming a live-but-unrelated process would otherwise wedge `cello login` forever.
77
+ *
78
+ * The probe takes the lock and immediately drops it. The gap between the probe and a subsequent spawn
79
+ * is safe: the daemon we spawn acquires the lock authoritatively and exits EXIT_ALREADY_RUNNING if it
80
+ * loses that race — and the caller reads that exit code as "someone else won, connect to them", never
81
+ * as a failure. Two probes can therefore both say "free" and both spawn, and exactly one daemon
82
+ * survives.
83
+ */
84
+ export declare function probeSingletonLock(celloDir: string, logger: Logger): "held" | "free" | "unknown";
85
+ //# sourceMappingURL=singleton-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton-lock.d.ts","sourceRoot":"","sources":["../src/singleton-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEtB,SAAS,EAAE,MAAM,GAAG,IAAI;CASrC;AAED,MAAM,WAAW,aAAa;IAC5B,qGAAqG;IACrG,OAAO,IAAI,IAAI,CAAC;CACjB;AA0DD,mGAAmG;AACnG,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAgBtC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAuC,GACrD,aAAa,CAyCf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAWhG"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * DOD-SINGLE-DAEMON-1 — the daemon singleton, enforced by the kernel.
3
+ *
4
+ * `daemon.lock` is a JSON file, and a file cannot answer "is a daemon running?". Anyone may delete
5
+ * it; a `kill -9` leaves it behind naming a pid that is dead — or, worse, one the OS has since REUSED
6
+ * for an unrelated process, which makes `isProcessAlive()` say "yes" forever. Every stale-lock
7
+ * heuristic ever written is an attempt to guess what only the kernel actually knows.
8
+ *
9
+ * So we ask the kernel. The daemon takes a real POSIX write lock (`fcntl`) on a dedicated file and
10
+ * holds it for its entire lifetime. Two processes cannot hold it at once, and the kernel drops it the
11
+ * instant the holder dies — SIGKILL, panic, `kill -9`, however it goes. There is no stale state to
12
+ * clean up and no recovery step to get wrong.
13
+ *
14
+ * ## Why SQLite is the lock
15
+ *
16
+ * Node has no `flock`. `fs.constants.O_EXLOCK` exists only on macOS/BSD — using it would leave every
17
+ * Linux operator (including the EC2 demo agent) with NO lock at all, which is worse than none because
18
+ * it looks like one. A native `flock` addon (`fs-ext`) compiles from source, and install time is a
19
+ * cost every operator pays on every version bump (see CLAUDE.md — the client is a heavy local node,
20
+ * not a thin wrapper).
21
+ *
22
+ * `@signalapp/sqlcipher` is already a daemon dependency, ships prebuilt (no compile), and SQLite's
23
+ * whole business is taking correct `fcntl` locks on every POSIX platform. `locking_mode = exclusive`
24
+ * plus one header write acquires the exclusive lock and holds it until the connection closes. A
25
+ * second process gets SQLITE_BUSY immediately (`busy_timeout = 0`). SQLite also tracks locks per
26
+ * inode inside the process, so this correctly refuses a second daemon in the SAME process too —
27
+ * which raw `fcntl`, whose locks are per-process, would not.
28
+ *
29
+ * The lock database holds no rows and never will. It is a mutex that happens to be spelled in SQL.
30
+ *
31
+ * ## The division of labour with daemon.lock (AC4)
32
+ *
33
+ * The OS lock DECIDES whether a daemon may start. `daemon.lock` only SUPPLIES METADATA — it is how we
34
+ * learn the holder's pid to name in the error, because `fcntl` will not tell us. If the JSON is
35
+ * missing, stale, or lying, the worst outcome is a less specific error message. It can never admit a
36
+ * second daemon, and it can never wedge a legitimate one out.
37
+ *
38
+ * ## The one constraint
39
+ *
40
+ * `~/.cello` must live on a LOCAL filesystem. POSIX `fcntl` locks are advisory-but-honoured on local
41
+ * filesystems (APFS, ext4, xfs — macOS and the Linux hosts we run on); on NFSv3 without a working
42
+ * `lockd`, and on some 9p/WSL2 setups, they can silently degrade to no-ops. There, two daemons would
43
+ * both "acquire" and the singleton would be absent while appearing present. We do not attempt to
44
+ * detect this — a real self-test needs a second process, which is far too much to do at every startup.
45
+ * The lock path is logged in `daemon.singleton.acquired` so an operator debugging a two-daemon
46
+ * situation can see exactly which file the kernel was asked about.
47
+ */
48
+ import { join } from "node:path";
49
+ import { readFileSync } from "node:fs";
50
+ import { loadSignalModule } from "./sqlcipher-db.js";
51
+ /** The file the kernel lock is taken on. Holds no data — see the note above. */
52
+ export const SINGLETON_LOCK_FILENAME = "daemon.singleton";
53
+ export class DaemonAlreadyRunningError extends Error {
54
+ /** The pid from `daemon.lock`, or null when that file is absent/unreadable/malformed. */
55
+ holderPid;
56
+ constructor(holderPid) {
57
+ super(holderPid === null
58
+ ? "another daemon is already running (pid unknown — daemon.lock is missing or unreadable)"
59
+ : `another daemon is already running (pid ${holderPid})`);
60
+ this.name = "DaemonAlreadyRunningError";
61
+ this.holderPid = holderPid;
62
+ }
63
+ }
64
+ /**
65
+ * Read the holder's pid from the advisory `daemon.lock`. METADATA ONLY (AC4): this pid is used to
66
+ * write a better error message and for nothing else. It never decides anything, so a stale or absent
67
+ * file costs us a specific error message, never correctness.
68
+ */
69
+ function readHolderPid(celloDir) {
70
+ try {
71
+ const parsed = JSON.parse(readFileSync(join(celloDir, "daemon.lock"), "utf-8"));
72
+ return typeof parsed.pid === "number" ? parsed.pid : null;
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ function isBusy(err) {
79
+ const code = err?.code;
80
+ return typeof code === "string" && code.startsWith("SQLITE_BUSY");
81
+ }
82
+ /**
83
+ * Take the exclusive OS lock for `celloDir`, or throw `DaemonAlreadyRunningError` if another process
84
+ * holds it. Returns a handle that holds the lock until `release()` (or process death).
85
+ *
86
+ * Call this BEFORE opening the database, registering agents, or connecting to the directory (AC2):
87
+ * a daemon that loses the race must do NONE of those things.
88
+ */
89
+ /**
90
+ * How long a STARTING daemon will wait for a contended lock before giving up.
91
+ *
92
+ * Not zero, and the reason is subtle. `probeSingletonLock()` does not read the lock — it TAKES it and
93
+ * drops it. That means a probe (a concurrent `cello login`, a shim, a status check) holds the
94
+ * exclusive lock for the few milliseconds it takes to open the file and write the header. With a zero
95
+ * timeout, a daemon that reaches its acquisition inside that window would get SQLITE_BUSY and exit
96
+ * "another daemon is already running" — when no other daemon exists at all. A read-only question must
97
+ * never be able to kill the thing it is asking about.
98
+ *
99
+ * A genuine second daemon still loses within this bound, which is what AC2's "immediately" is for.
100
+ */
101
+ const DAEMON_ACQUIRE_BUSY_TIMEOUT_MS = 3000;
102
+ /**
103
+ * How long a PROBE waits before concluding the lock is held.
104
+ *
105
+ * Also not zero, and for the mirror of the reason above. A probe takes the lock too, so two probes
106
+ * can collide with each other: a second `cello login`, or the MCP shim autostarting while the
107
+ * operator types `cello login`. With a zero timeout the loser of that collision would report "held"
108
+ * — i.e. "a daemon is already running" — when there is no daemon at all, and the caller would sit in
109
+ * connectWithRetry for ten seconds before failing with a confident lie. That is precisely the class
110
+ * of wrong-but-certain statement this whole story exists to abolish.
111
+ *
112
+ * A REAL daemon holds the lock forever, so waiting a little costs a probe nothing in the case that
113
+ * matters — it still times out and still correctly answers "held". A transient probe-vs-probe
114
+ * collision, meanwhile, resolves in milliseconds. Strictly better than zero in both directions.
115
+ */
116
+ const PROBE_BUSY_TIMEOUT_MS = 500;
117
+ /** The daemon binary's exit code when it loses the singleton race — distinct from 1 = "broken". */
118
+ export const EXIT_ALREADY_RUNNING = 3;
119
+ function openLockDb(lockDbPath) {
120
+ const mod = loadSignalModule();
121
+ const Ctor = mod.Database ?? mod.default;
122
+ try {
123
+ return new Ctor(lockDbPath);
124
+ }
125
+ catch (err) {
126
+ // The file could not be opened at all (permissions, unwritable dir). NOT a contended lock —
127
+ // never let this be mistaken for "a daemon is running".
128
+ throw new Error(`Could not open the daemon singleton lock at ${lockDbPath}: ${err instanceof Error ? err.message : String(err)}`);
129
+ }
130
+ }
131
+ export function acquireSingletonLock(celloDir, logger, busyTimeoutMs = DAEMON_ACQUIRE_BUSY_TIMEOUT_MS) {
132
+ const lockDbPath = join(celloDir, SINGLETON_LOCK_FILENAME);
133
+ const db = openLockDb(lockDbPath);
134
+ try {
135
+ db.pragma(`busy_timeout = ${busyTimeoutMs}`);
136
+ db.pragma("locking_mode = exclusive");
137
+ // SQLite defers the actual lock acquisition until it has a reason to write. `user_version` is a
138
+ // write to the database header — it takes the exclusive lock and stores nothing.
139
+ db.pragma("user_version = 1");
140
+ }
141
+ catch (err) {
142
+ try {
143
+ db.close();
144
+ }
145
+ catch { /* we are already failing; closing is best-effort */ }
146
+ if (isBusy(err)) {
147
+ const holderPid = readHolderPid(celloDir);
148
+ logger.info("daemon.singleton.contended", { holderPid, lockPath: lockDbPath });
149
+ throw new DaemonAlreadyRunningError(holderPid);
150
+ }
151
+ // Some other SQLite failure. Keep the frame — a bare SQLITE_* error here reads as a database
152
+ // problem, when what actually failed was taking the singleton lock.
153
+ throw new Error(`Could not take the daemon singleton lock at ${lockDbPath}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
154
+ }
155
+ logger.info("daemon.singleton.acquired", { pid: process.pid, lockPath: lockDbPath });
156
+ let released = false;
157
+ return {
158
+ release() {
159
+ if (released)
160
+ return;
161
+ released = true;
162
+ try {
163
+ db.close();
164
+ }
165
+ catch (err) {
166
+ logger.warn("daemon.singleton.release.failed", {
167
+ error: err instanceof Error ? err.message : String(err),
168
+ });
169
+ }
170
+ },
171
+ };
172
+ }
173
+ /**
174
+ * Is a daemon holding the lock for `celloDir` right now?
175
+ *
176
+ * "held" — a daemon is alive. Connect to it; never spawn beside it.
177
+ * "free" — no daemon is running, whatever `daemon.lock` claims. Spawning is correct.
178
+ * "unknown" — we could not ask the kernel (native module missing, directory unreadable).
179
+ *
180
+ * The third answer is the point. "I could not determine whether a daemon is running" and "no daemon is
181
+ * running" are different facts, and collapsing them into one boolean means the caller spawns on both —
182
+ * so the one case where we are blind becomes the one case we start a second daemon. Callers must
183
+ * refuse to spawn on "unknown" and surface the underlying error instead.
184
+ *
185
+ * Asking the kernel rather than trusting `daemon.lock` is also what makes a REUSED pid harmless: a
186
+ * stale lock file naming a live-but-unrelated process would otherwise wedge `cello login` forever.
187
+ *
188
+ * The probe takes the lock and immediately drops it. The gap between the probe and a subsequent spawn
189
+ * is safe: the daemon we spawn acquires the lock authoritatively and exits EXIT_ALREADY_RUNNING if it
190
+ * loses that race — and the caller reads that exit code as "someone else won, connect to them", never
191
+ * as a failure. Two probes can therefore both say "free" and both spawn, and exactly one daemon
192
+ * survives.
193
+ */
194
+ export function probeSingletonLock(celloDir, logger) {
195
+ try {
196
+ acquireSingletonLock(celloDir, logger, PROBE_BUSY_TIMEOUT_MS).release();
197
+ return "free";
198
+ }
199
+ catch (err) {
200
+ if (err instanceof DaemonAlreadyRunningError)
201
+ return "held";
202
+ logger.warn("daemon.singleton.probe.failed", {
203
+ error: err instanceof Error ? err.message : String(err),
204
+ });
205
+ return "unknown";
206
+ }
207
+ }
208
+ //# sourceMappingURL=singleton-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton-lock.js","sourceRoot":"","sources":["../src/singleton-lock.ts"],"names":[],"mappings":"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"}