crbro-memory 2.4.0 → 2.5.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.
- package/README.md +53 -3
- package/bin/crbro.mjs +234 -0
- package/dist/daemon/daemon.d.ts +25 -0
- package/dist/daemon/daemon.d.ts.map +1 -0
- package/dist/daemon/daemon.js +387 -0
- package/dist/daemon/daemon.js.map +1 -0
- package/dist/daemon/endpoint.d.ts +65 -0
- package/dist/daemon/endpoint.d.ts.map +1 -0
- package/dist/daemon/endpoint.js +308 -0
- package/dist/daemon/endpoint.js.map +1 -0
- package/dist/daemon/lines.d.ts +55 -0
- package/dist/daemon/lines.d.ts.map +1 -0
- package/dist/daemon/lines.js +142 -0
- package/dist/daemon/lines.js.map +1 -0
- package/dist/daemon/proxy.d.ts +55 -0
- package/dist/daemon/proxy.d.ts.map +1 -0
- package/dist/daemon/proxy.js +412 -0
- package/dist/daemon/proxy.js.map +1 -0
- package/dist/engine/backup.d.ts +68 -0
- package/dist/engine/backup.d.ts.map +1 -0
- package/dist/engine/backup.js +224 -0
- package/dist/engine/backup.js.map +1 -0
- package/dist/engine/brain.d.ts.map +1 -1
- package/dist/engine/brain.js +6 -2
- package/dist/engine/brain.js.map +1 -1
- package/dist/engine/cortex.d.ts +76 -2
- package/dist/engine/cortex.d.ts.map +1 -1
- package/dist/engine/cortex.js +169 -9
- package/dist/engine/cortex.js.map +1 -1
- package/dist/engine/dates.d.ts +28 -0
- package/dist/engine/dates.d.ts.map +1 -0
- package/dist/engine/dates.js +121 -0
- package/dist/engine/dates.js.map +1 -0
- package/dist/engine/maintenance.d.ts +85 -0
- package/dist/engine/maintenance.d.ts.map +1 -1
- package/dist/engine/maintenance.js +340 -0
- package/dist/engine/maintenance.js.map +1 -1
- package/dist/engine/triggers.d.ts +46 -0
- package/dist/engine/triggers.d.ts.map +1 -0
- package/dist/engine/triggers.js +201 -0
- package/dist/engine/triggers.js.map +1 -0
- package/dist/index.js +33 -5
- package/dist/index.js.map +1 -1
- package/dist/search/index.d.ts +56 -3
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +249 -12
- package/dist/search/index.js.map +1 -1
- package/dist/server.d.ts +32 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +151 -19
- package/dist/server.js.map +1 -1
- package/hooks/crbro-guard.mjs +157 -0
- package/package.json +1 -1
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── The daemon: one process owns the brain ──────────────────────
|
|
3
|
+
//
|
|
4
|
+
// Until 2.5 every client started its own CRBRO: Claude Code one, Claude
|
|
5
|
+
// Desktop another, Codex a third. Each loaded its own copy of the search
|
|
6
|
+
// index (~40 MB) and of the embedding model (~13 s, ~0.5 GB), each kept that
|
|
7
|
+
// index in memory and wrote it over the others' when it closed — so a line
|
|
8
|
+
// saved in one chat could be invisible in the next — and nothing stopped two
|
|
9
|
+
// different builds from writing the same brain at once. All of it measured
|
|
10
|
+
// on a real machine, not imagined.
|
|
11
|
+
//
|
|
12
|
+
// The daemon is the same server, once: the engines are built one time and
|
|
13
|
+
// every connection gets its own McpServer over them. Clients reach it through
|
|
14
|
+
// a byte-for-byte proxy (proxy.ts), so nothing about MCP changes for them.
|
|
15
|
+
//
|
|
16
|
+
// What it must never do is make the memory less available than it was. So:
|
|
17
|
+
// it is opt-in; a client that cannot reach it serves itself in-process,
|
|
18
|
+
// exactly as before; and a daemon that dies mid-conversation is replaced
|
|
19
|
+
// under the client's feet. Losing the daemon costs speed, never the memory.
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.idleDelayMs = idleDelayMs;
|
|
25
|
+
exports.startDaemon = startDaemon;
|
|
26
|
+
exports.runDaemon = runDaemon;
|
|
27
|
+
const node_net_1 = __importDefault(require("node:net"));
|
|
28
|
+
const node_fs_1 = require("node:fs");
|
|
29
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
30
|
+
const server_js_1 = require("../server.js");
|
|
31
|
+
const cortex_js_1 = require("../engine/cortex.js");
|
|
32
|
+
const lines_js_1 = require("./lines.js");
|
|
33
|
+
const proxy_js_1 = require("./proxy.js");
|
|
34
|
+
const endpoint_js_1 = require("./endpoint.js");
|
|
35
|
+
const HANDSHAKE_TIMEOUT_MS = 5_000;
|
|
36
|
+
const DEFAULT_IDLE_MIN = 20;
|
|
37
|
+
/** setTimeout takes a 32-bit delay: past this it fires at once, and a daemon asked to wait a month exited in a millisecond. */
|
|
38
|
+
const MAX_TIMER_MS = 2_147_000_000;
|
|
39
|
+
const LOG_MAX_BYTES = 512 * 1024;
|
|
40
|
+
/** Refusals written per minute. A local process knocking in a loop must not be able to fill the disk through our log. */
|
|
41
|
+
const REFUSALS_PER_MINUTE = 20;
|
|
42
|
+
/** How long a starter that found the endpoint busy waits for its holder to prove it is a daemon of this brain. */
|
|
43
|
+
const PEER_PROOF_WAIT_MS = 2_500;
|
|
44
|
+
function idleDelayMs(opt, env = process.env) {
|
|
45
|
+
let minutes = opt;
|
|
46
|
+
if (minutes === undefined) {
|
|
47
|
+
const v = Number(env.CRBRO_DAEMON_IDLE_MIN);
|
|
48
|
+
minutes = Number.isFinite(v) && v >= 0 ? v : DEFAULT_IDLE_MIN;
|
|
49
|
+
}
|
|
50
|
+
return Math.min(Math.max(0, minutes) * 60_000, MAX_TIMER_MS);
|
|
51
|
+
}
|
|
52
|
+
async function fileLogger(brainRoot) {
|
|
53
|
+
const file = node_path_1.default.join((0, endpoint_js_1.daemonDir)(brainRoot), 'daemon.log');
|
|
54
|
+
await node_fs_1.promises.mkdir((0, endpoint_js_1.daemonDir)(brainRoot), { recursive: true, mode: 0o700 });
|
|
55
|
+
let written = 0;
|
|
56
|
+
try {
|
|
57
|
+
written = (await node_fs_1.promises.stat(file)).size;
|
|
58
|
+
}
|
|
59
|
+
catch { /* no log yet */ }
|
|
60
|
+
let queue = Promise.resolve();
|
|
61
|
+
return (line) => {
|
|
62
|
+
const text = `${new Date().toISOString()} [${process.pid}] ${line.replace(/[\r\n]+/g, ' ')}\n`;
|
|
63
|
+
queue = queue.then(async () => {
|
|
64
|
+
if (written > LOG_MAX_BYTES) {
|
|
65
|
+
await node_fs_1.promises.rename(file, `${file}.1`).catch(() => undefined);
|
|
66
|
+
written = 0;
|
|
67
|
+
}
|
|
68
|
+
await node_fs_1.promises.appendFile(file, text);
|
|
69
|
+
written += Buffer.byteLength(text);
|
|
70
|
+
}).catch(() => undefined);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Is somebody answering there? 'dead' only when the system says nobody is
|
|
75
|
+
* (refused, or no such file): a timeout is a busy process, not an absent one,
|
|
76
|
+
* and reading it as absent is how a starter deletes a live daemon's socket.
|
|
77
|
+
*/
|
|
78
|
+
function probe(endpoint) {
|
|
79
|
+
return new Promise(resolve => {
|
|
80
|
+
const s = node_net_1.default.connect(endpoint);
|
|
81
|
+
const done = (v) => { s.destroy(); resolve(v); };
|
|
82
|
+
s.once('connect', () => done('alive'));
|
|
83
|
+
s.once('error', err => {
|
|
84
|
+
const code = err.code;
|
|
85
|
+
done(code === 'ECONNREFUSED' || code === 'ENOENT' ? 'dead' : 'unknown');
|
|
86
|
+
});
|
|
87
|
+
setTimeout(() => done('unknown'), 1500).unref();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async function startDaemon(options = {}) {
|
|
91
|
+
const engines = options.engines ?? (0, server_js_1.createEngines)();
|
|
92
|
+
const brainRoot = engines.brain.paths.root;
|
|
93
|
+
const build = options.build ?? (0, endpoint_js_1.buildId)();
|
|
94
|
+
const endpoint = (0, endpoint_js_1.endpointFor)(brainRoot, build);
|
|
95
|
+
const log = options.log ?? await fileLogger(brainRoot);
|
|
96
|
+
const token = (0, endpoint_js_1.newToken)();
|
|
97
|
+
const idleMs = idleDelayMs(options.idleMinutes);
|
|
98
|
+
const config = (0, endpoint_js_1.configFingerprint)();
|
|
99
|
+
await node_fs_1.promises.mkdir((0, endpoint_js_1.daemonDir)(brainRoot), { recursive: true, mode: 0o700 });
|
|
100
|
+
const clients = new Set();
|
|
101
|
+
const conversations = () => [...clients].filter(c => c.server !== null).length;
|
|
102
|
+
let idleTimer = null;
|
|
103
|
+
let stopping = null;
|
|
104
|
+
let resolveStopped;
|
|
105
|
+
const stopped = new Promise(r => { resolveStopped = r; });
|
|
106
|
+
let ownSocket = null;
|
|
107
|
+
// Only conversations move the idle clock. A socket that never proves itself
|
|
108
|
+
// — a status probe, a scanner, another user's process knocking — can neither
|
|
109
|
+
// keep the daemon alive nor push its exit further away.
|
|
110
|
+
const armIdle = () => {
|
|
111
|
+
if (idleTimer) {
|
|
112
|
+
clearTimeout(idleTimer);
|
|
113
|
+
idleTimer = null;
|
|
114
|
+
}
|
|
115
|
+
if (idleMs > 0 && conversations() === 0 && !stopping) {
|
|
116
|
+
idleTimer = setTimeout(() => { if (conversations() === 0)
|
|
117
|
+
void stop('idle');
|
|
118
|
+
else
|
|
119
|
+
armIdle(); }, idleMs);
|
|
120
|
+
idleTimer.unref();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
let refusals = 0;
|
|
124
|
+
let refusalWindow = Date.now();
|
|
125
|
+
const logRefusal = (why) => {
|
|
126
|
+
const now = Date.now();
|
|
127
|
+
if (now - refusalWindow > 60_000) {
|
|
128
|
+
if (refusals > REFUSALS_PER_MINUTE)
|
|
129
|
+
log(`… and ${refusals - REFUSALS_PER_MINUTE} more refusals in that minute`);
|
|
130
|
+
refusals = 0;
|
|
131
|
+
refusalWindow = now;
|
|
132
|
+
}
|
|
133
|
+
if (++refusals <= REFUSALS_PER_MINUTE)
|
|
134
|
+
log(`connection refused: ${why}`);
|
|
135
|
+
};
|
|
136
|
+
const listener = node_net_1.default.createServer({ allowHalfOpen: false }, socket => { accept(socket); });
|
|
137
|
+
function accept(socket) {
|
|
138
|
+
const entry = { socket, server: null };
|
|
139
|
+
clients.add(entry);
|
|
140
|
+
socket.setNoDelay(true);
|
|
141
|
+
let stage = 'hello';
|
|
142
|
+
let nonce = '';
|
|
143
|
+
let resumed = false;
|
|
144
|
+
let transport = null;
|
|
145
|
+
const kill = (why) => {
|
|
146
|
+
if (stage === 'dead')
|
|
147
|
+
return;
|
|
148
|
+
stage = 'dead';
|
|
149
|
+
logRefusal(why);
|
|
150
|
+
socket.destroy();
|
|
151
|
+
};
|
|
152
|
+
const timer = setTimeout(() => { if (stage !== 'mcp')
|
|
153
|
+
kill('handshake timeout'); }, HANDSHAKE_TIMEOUT_MS);
|
|
154
|
+
timer.unref();
|
|
155
|
+
const say = (o) => { if (!socket.destroyed)
|
|
156
|
+
socket.write(`${JSON.stringify(o)}\n`); };
|
|
157
|
+
const reader = new lines_js_1.LineReader(line => {
|
|
158
|
+
if (stage === 'mcp') {
|
|
159
|
+
transport.receive(line);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (stage === 'dead')
|
|
163
|
+
return;
|
|
164
|
+
let m;
|
|
165
|
+
try {
|
|
166
|
+
m = JSON.parse(line);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return kill('not JSON before the handshake');
|
|
170
|
+
}
|
|
171
|
+
if (stage === 'hello') {
|
|
172
|
+
if (m?.crbro !== 'hello' || m.protocol !== endpoint_js_1.DAEMON_PROTOCOL || typeof m.nonce !== 'string' || !/^[0-9a-f]{32,128}$/.test(m.nonce)) {
|
|
173
|
+
return kill('bad hello');
|
|
174
|
+
}
|
|
175
|
+
nonce = (0, endpoint_js_1.newNonce)();
|
|
176
|
+
say({ crbro: 'hello', protocol: endpoint_js_1.DAEMON_PROTOCOL, version: (0, endpoint_js_1.packageVersion)(), build, pid: process.pid, config, proof: (0, endpoint_js_1.proof)(token, 'daemon', m.nonce), nonce });
|
|
177
|
+
stage = 'auth';
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (stage === 'auth') {
|
|
181
|
+
if (m?.crbro !== 'auth' || !(0, endpoint_js_1.sameProof)(String(m.proof || ''), (0, endpoint_js_1.proof)(token, 'client', nonce)))
|
|
182
|
+
return kill('bad proof');
|
|
183
|
+
resumed = m.resumed === true;
|
|
184
|
+
say({ crbro: 'ready' });
|
|
185
|
+
stage = 'first';
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// stage === 'first': a control message, or the first MCP message.
|
|
189
|
+
if (m?.crbro === 'control') {
|
|
190
|
+
clearTimeout(timer);
|
|
191
|
+
if (m.op === 'status') {
|
|
192
|
+
say({ crbro: 'status', pid: process.pid, version: (0, endpoint_js_1.packageVersion)(), build, brain: brainRoot, endpoint, config,
|
|
193
|
+
connections: conversations(), uptime_s: Math.round(process.uptime()), rss_mb: Math.round(process.memoryUsage().rss / 1048576),
|
|
194
|
+
semantic_vectors: engines.searchEngine.semanticCount(), idle_minutes: Math.round(idleMs / 6_000) / 10 });
|
|
195
|
+
socket.end();
|
|
196
|
+
}
|
|
197
|
+
else if (m.op === 'stop') {
|
|
198
|
+
say({ crbro: 'stopping' });
|
|
199
|
+
socket.end();
|
|
200
|
+
void stop('asked to stop');
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
kill('unknown control op');
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// An MCP client. Its own server over the shared engines, and its own
|
|
208
|
+
// session scope: what this conversation writes is this conversation's.
|
|
209
|
+
// `resumed`: the proxy lost a backend mid-conversation and this one
|
|
210
|
+
// starts with an empty tally that the conversation's earlier writes are
|
|
211
|
+
// not in — consolidate says so instead of reporting zeros as the truth.
|
|
212
|
+
clearTimeout(timer);
|
|
213
|
+
const scope = { tally: (0, cortex_js_1.newTally)(), resumed };
|
|
214
|
+
transport = new lines_js_1.SocketServerTransport(socket, fn => cortex_js_1.sessionScope.run(scope, fn));
|
|
215
|
+
const server = (0, server_js_1.createServer)(engines);
|
|
216
|
+
entry.server = server;
|
|
217
|
+
stage = 'mcp';
|
|
218
|
+
armIdle();
|
|
219
|
+
transport.receive(line); // queued: an `initialized` arriving in the same chunk must not overtake `initialize`
|
|
220
|
+
server.connect(transport).then(() => transport.open()).catch(err => kill(`server.connect failed: ${err.message}`));
|
|
221
|
+
}, () => kill('line too long'));
|
|
222
|
+
socket.on('data', chunk => reader.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : chunk));
|
|
223
|
+
socket.on('error', () => { });
|
|
224
|
+
socket.on('close', () => {
|
|
225
|
+
clearTimeout(timer);
|
|
226
|
+
const wasConversation = entry.server !== null;
|
|
227
|
+
clients.delete(entry);
|
|
228
|
+
if (entry.server)
|
|
229
|
+
void entry.server.close().catch(() => undefined);
|
|
230
|
+
if (wasConversation)
|
|
231
|
+
armIdle();
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// ── Listen. One daemon per endpoint: losing the race is not an error. ──
|
|
235
|
+
const listen = () => new Promise((resolve, reject) => {
|
|
236
|
+
const onError = (err) => reject(err);
|
|
237
|
+
listener.once('error', onError);
|
|
238
|
+
listener.listen(endpoint, () => { listener.off('error', onError); resolve(); });
|
|
239
|
+
});
|
|
240
|
+
const blocked = async (reason) => {
|
|
241
|
+
log(`cannot own ${endpoint}: ${reason}`);
|
|
242
|
+
await (0, endpoint_js_1.markBlocked)(brainRoot, build, reason);
|
|
243
|
+
throw new Error(`DAEMON_ENDPOINT_BLOCKED: ${reason}`);
|
|
244
|
+
};
|
|
245
|
+
let state;
|
|
246
|
+
const release = await (0, endpoint_js_1.acquireStartLock)(brainRoot, build);
|
|
247
|
+
// Somebody else is inside the same few lines right now: let them win.
|
|
248
|
+
if (!release)
|
|
249
|
+
throw new Error('DAEMON_ALREADY_RUNNING');
|
|
250
|
+
try {
|
|
251
|
+
try {
|
|
252
|
+
await (0, endpoint_js_1.secureSocketDir)(endpoint);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
await blocked(err.message);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
await listen();
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
if (err.code !== 'EADDRINUSE')
|
|
262
|
+
throw err;
|
|
263
|
+
const holder = await probe(endpoint);
|
|
264
|
+
if (holder !== 'dead') {
|
|
265
|
+
// Somebody answers. A daemon of this brain can prove it — give it the
|
|
266
|
+
// moment it may need between listening and writing its state file.
|
|
267
|
+
const until = Date.now() + PEER_PROOF_WAIT_MS;
|
|
268
|
+
let proven = false;
|
|
269
|
+
while (!proven && Date.now() < until) {
|
|
270
|
+
const link = await (0, proxy_js_1.connectDaemon)(brainRoot, build, { checkConfig: false });
|
|
271
|
+
if (link && link !== 'config-mismatch') {
|
|
272
|
+
link.socket.destroy();
|
|
273
|
+
proven = true;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
await new Promise(r => setTimeout(r, 200));
|
|
277
|
+
}
|
|
278
|
+
if (proven)
|
|
279
|
+
throw new Error('DAEMON_ALREADY_RUNNING');
|
|
280
|
+
await blocked('the endpoint is held by a process that does not prove it is a CRBRO daemon of this brain');
|
|
281
|
+
}
|
|
282
|
+
// Nobody answers and the name is taken: a socket file a crash left behind.
|
|
283
|
+
try {
|
|
284
|
+
if (process.platform !== 'win32')
|
|
285
|
+
await node_fs_1.promises.rm(endpoint, { force: true });
|
|
286
|
+
await listen();
|
|
287
|
+
}
|
|
288
|
+
catch (again) {
|
|
289
|
+
if (again.code === 'EADDRINUSE')
|
|
290
|
+
throw new Error('DAEMON_ALREADY_RUNNING');
|
|
291
|
+
await blocked(`could not take over a dead endpoint: ${again.message}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (process.platform !== 'win32') {
|
|
295
|
+
await node_fs_1.promises.chmod(endpoint, 0o600).catch(() => undefined);
|
|
296
|
+
try {
|
|
297
|
+
const st = await node_fs_1.promises.stat(endpoint);
|
|
298
|
+
ownSocket = { dev: st.dev, ino: st.ino };
|
|
299
|
+
}
|
|
300
|
+
catch { /* not a file we can name */ }
|
|
301
|
+
}
|
|
302
|
+
await (0, endpoint_js_1.clearBlocked)(brainRoot, build);
|
|
303
|
+
state = {
|
|
304
|
+
protocol: endpoint_js_1.DAEMON_PROTOCOL, pid: process.pid, version: (0, endpoint_js_1.packageVersion)(), build, endpoint, token,
|
|
305
|
+
started: new Date().toISOString(), brain: brainRoot,
|
|
306
|
+
};
|
|
307
|
+
await (0, endpoint_js_1.writeState)(brainRoot, state);
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
await release();
|
|
311
|
+
}
|
|
312
|
+
log(`listening on ${endpoint} · ${state.version} (${build}) · brain ${brainRoot} · config ${config} · idle exit ${Math.round(idleMs / 60_000)} min`);
|
|
313
|
+
// The index and the model warm up now, off anybody's critical path: the
|
|
314
|
+
// first client to boot finds them ready, the second never waits at all.
|
|
315
|
+
void engines.searchEngine.init().catch(err => log(`index warm-up failed: ${err.message}`));
|
|
316
|
+
listener.on('error', err => log(`listener error: ${err.message}`));
|
|
317
|
+
armIdle();
|
|
318
|
+
function stop(reason = 'stop') {
|
|
319
|
+
if (stopping)
|
|
320
|
+
return stopping;
|
|
321
|
+
stopping = (async () => {
|
|
322
|
+
log(`stopping: ${reason} · ${conversations()} conversation(s)`);
|
|
323
|
+
if (idleTimer)
|
|
324
|
+
clearTimeout(idleTimer);
|
|
325
|
+
// The state file goes first: a client that arrives now must not find a token for a door that is closing.
|
|
326
|
+
await (0, endpoint_js_1.removeState)(brainRoot, build, process.pid);
|
|
327
|
+
await new Promise(resolve => { listener.close(() => resolve()); for (const c of clients)
|
|
328
|
+
c.socket.destroy(); });
|
|
329
|
+
try {
|
|
330
|
+
await engines.searchEngine.flush();
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
log(`flush failed: ${err.message}`);
|
|
334
|
+
}
|
|
335
|
+
// Unlink only the socket we made. By now a replacement may be listening
|
|
336
|
+
// on the same path, and removing ITS file would strand it: alive,
|
|
337
|
+
// serving, and unreachable.
|
|
338
|
+
if (ownSocket) {
|
|
339
|
+
try {
|
|
340
|
+
const st = await node_fs_1.promises.stat(endpoint);
|
|
341
|
+
if (st.dev === ownSocket.dev && st.ino === ownSocket.ino)
|
|
342
|
+
await node_fs_1.promises.rm(endpoint, { force: true });
|
|
343
|
+
}
|
|
344
|
+
catch { /* already gone */ }
|
|
345
|
+
}
|
|
346
|
+
resolveStopped(reason);
|
|
347
|
+
})();
|
|
348
|
+
return stopping;
|
|
349
|
+
}
|
|
350
|
+
return { endpoint, state, connections: conversations, stop, stopped };
|
|
351
|
+
}
|
|
352
|
+
/** `node dist/index.js --daemon`: run until idle, asked to stop, or signalled. */
|
|
353
|
+
async function runDaemon() {
|
|
354
|
+
// A detached child inherits its parent's working directory, and on Windows a
|
|
355
|
+
// process pins its cwd: the project folder a client was opened in could not
|
|
356
|
+
// be renamed or deleted for as long as the daemon lived.
|
|
357
|
+
try {
|
|
358
|
+
process.chdir(node_path_1.default.parse(process.cwd()).root);
|
|
359
|
+
}
|
|
360
|
+
catch { /* stay where we are */ }
|
|
361
|
+
let handle;
|
|
362
|
+
try {
|
|
363
|
+
handle = await startDaemon();
|
|
364
|
+
}
|
|
365
|
+
catch (err) {
|
|
366
|
+
const msg = err.message || '';
|
|
367
|
+
// Somebody else won the race to be the daemon: exactly what should happen.
|
|
368
|
+
if (msg === 'DAEMON_ALREADY_RUNNING')
|
|
369
|
+
process.exit(0);
|
|
370
|
+
if (msg.startsWith('DAEMON_ENDPOINT_BLOCKED'))
|
|
371
|
+
process.exit(3);
|
|
372
|
+
throw err;
|
|
373
|
+
}
|
|
374
|
+
const bye = (reason) => { void handle.stop(reason).then(() => process.exit(0)); };
|
|
375
|
+
process.on('SIGINT', () => bye('SIGINT'));
|
|
376
|
+
process.on('SIGTERM', () => bye('SIGTERM'));
|
|
377
|
+
process.on('uncaughtException', err => {
|
|
378
|
+
void fileLogger(handle.state.brain).then(log => log(`uncaughtException: ${err.stack || err.message}`));
|
|
379
|
+
bye('uncaughtException');
|
|
380
|
+
});
|
|
381
|
+
process.on('unhandledRejection', err => {
|
|
382
|
+
void fileLogger(handle.state.brain).then(log => log(`unhandledRejection: ${err?.stack || String(err)}`));
|
|
383
|
+
});
|
|
384
|
+
await handle.stopped;
|
|
385
|
+
process.exit(0);
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/daemon/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export declare const DAEMON_PROTOCOL = 1;
|
|
2
|
+
export interface DaemonState {
|
|
3
|
+
protocol: number;
|
|
4
|
+
pid: number;
|
|
5
|
+
version: string;
|
|
6
|
+
build: string;
|
|
7
|
+
endpoint: string;
|
|
8
|
+
token: string;
|
|
9
|
+
started: string;
|
|
10
|
+
brain: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function packageVersion(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Version plus the build's own timestamp. The version alone would let a
|
|
15
|
+
* developer's half-built dist serve the clients that launched the published
|
|
16
|
+
* package; the timestamp alone would not survive a reinstall of the same
|
|
17
|
+
* release on another path. Together: you are served by the code you launched.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildId(): string;
|
|
20
|
+
export declare function daemonDir(brainRoot: string): string;
|
|
21
|
+
/** The pipe or socket path for this brain and build. */
|
|
22
|
+
export declare function endpointFor(brainRoot: string, build?: string): string;
|
|
23
|
+
/** <tmp>/crbro-<uid>: where the socket goes when the brain path is too long for one. */
|
|
24
|
+
export declare function privateTmpDir(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Make the socket's folder and make sure it is ours alone. In the brain that
|
|
27
|
+
* is a given; in tmp somebody else may have made `crbro-<our uid>` first, as a
|
|
28
|
+
* folder they own or as a link to one — and a socket placed there is theirs.
|
|
29
|
+
*/
|
|
30
|
+
export declare function secureSocketDir(endpoint: string): Promise<void>;
|
|
31
|
+
export declare function stateFile(brainRoot: string, build?: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* What a daemon would do differently from the client asking for it. One
|
|
34
|
+
* process serves every client, but each client was configured on its own —
|
|
35
|
+
* CRBRO_BACKUP_DIR pointing at a synced folder in one, CRBRO_SEMANTIC=0 in
|
|
36
|
+
* another — and whose settings win must not depend on who happened to start
|
|
37
|
+
* first. A client whose fingerprint differs from the daemon's serves itself,
|
|
38
|
+
* exactly as it did before daemons: its settings keep meaning what they said.
|
|
39
|
+
*/
|
|
40
|
+
export declare function configFingerprint(env?: NodeJS.ProcessEnv): string;
|
|
41
|
+
/** Written by a daemon that found its endpoint held by something that is not a CRBRO daemon of this brain. */
|
|
42
|
+
export declare function blockedFile(brainRoot: string, build?: string): string;
|
|
43
|
+
export declare function markBlocked(brainRoot: string, build: string, reason: string): Promise<void>;
|
|
44
|
+
/** A marker newer than `since` (ms): the daemon we just asked for could not be had, and waiting will not change it. */
|
|
45
|
+
export declare function blockedSince(brainRoot: string, build: string, since: number): Promise<string | null>;
|
|
46
|
+
export declare function clearBlocked(brainRoot: string, build: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* One daemon at a time through the dangerous part of starting: finding the
|
|
49
|
+
* endpoint busy, deciding the holder is dead, unlinking its socket, listening.
|
|
50
|
+
* Two starters doing that interleaved can each delete the other's live socket.
|
|
51
|
+
* The lock names its holder, so a starter that was killed does not hold it forever.
|
|
52
|
+
*/
|
|
53
|
+
export declare function acquireStartLock(brainRoot: string, build: string): Promise<(() => Promise<void>) | null>;
|
|
54
|
+
export declare function newToken(): string;
|
|
55
|
+
export declare function writeState(brainRoot: string, state: DaemonState): Promise<void>;
|
|
56
|
+
export declare function readState(brainRoot: string, build?: string): Promise<DaemonState | null>;
|
|
57
|
+
export declare function removeState(brainRoot: string, build: string, pid: number): Promise<void>;
|
|
58
|
+
/** Every daemon that left a state file for this brain, whatever its build. */
|
|
59
|
+
export declare function listStates(brainRoot: string): Promise<DaemonState[]>;
|
|
60
|
+
export declare function proof(token: string, role: 'daemon' | 'client', nonce: string): string;
|
|
61
|
+
export declare function sameProof(a: string, b: string): boolean;
|
|
62
|
+
export declare function newNonce(): string;
|
|
63
|
+
export declare function daemonEnabled(brainRoot: string, env?: NodeJS.ProcessEnv): boolean;
|
|
64
|
+
export declare function setDaemonEnabled(brainRoot: string, on: boolean): Promise<void>;
|
|
65
|
+
//# sourceMappingURL=endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../../src/daemon/endpoint.ts"],"names":[],"mappings":"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"}
|