@veewo/claw 0.2.2 → 0.2.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.
@@ -0,0 +1,363 @@
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import net from "node:net";
4
+ import path from "node:path";
5
+ import { SESSION_PROTOCOL_VERSION, } from "@veewo/claw-client";
6
+ import { ClawError, recoverProjectFocusTransitions, releaseCurrentPlanFocus, resolveProjectContext, writeJsonFileAtomic, } from "@veewo/claw-core";
7
+ import { ClawCommandService } from "./command-service.js";
8
+ import { RegistryFocusSessionStore, SessionRegistryV2, createSessionIdentity, ensurePrivateDirectory, sessionFocusKey, } from "./session-registry-v2.js";
9
+ const MAX_PROTOCOL_LINE_BYTES = 1024 * 1024;
10
+ const SESSION_PASSTHROUGH_ERRORS = new Set([
11
+ "SESSION_NOT_FOUND",
12
+ "SESSION_EXPIRED",
13
+ "SESSION_IDENTITY_INVALID",
14
+ "CURRENT_PLAN_REQUIRED",
15
+ "PLAN_NOT_FOUND",
16
+ "PLAN_NOT_RESUMABLE",
17
+ "PLAN_FOCUS_CONFLICT",
18
+ "PLAN_TRANSITION_CONFLICT",
19
+ "FOCUS_RECOVERY_CONFLICT",
20
+ "SESSION_OPERATION_UNSUPPORTED",
21
+ ]);
22
+ export async function startSessionDaemon(options) {
23
+ const registry = new SessionRegistryV2(options?.runtimeRoot);
24
+ ensurePrivateDirectory(path.join(registry.runtimeRoot, "daemon"));
25
+ const releaseStartLock = acquireStartLock(registry.runtimeRoot);
26
+ registry.recover();
27
+ const focusStore = new RegistryFocusSessionStore(registry);
28
+ const service = new ClawCommandService(registry);
29
+ const token = randomBytes(32).toString("hex");
30
+ const activeSessions = new Map();
31
+ const connections = new Set();
32
+ const server = net.createServer();
33
+ let idleTimer;
34
+ let closing = false;
35
+ const cleanupExpiredSessions = async () => {
36
+ const live = new Set(activeSessions.keys());
37
+ for (const expired of registry.listExpiredRecords(new Date(), live)) {
38
+ if (expired.record.currentPlan) {
39
+ const identity = createSessionIdentity(expired.record.agentSessionId, expired.record.canonicalWorkdir);
40
+ try {
41
+ const project = resolveProjectContext(identity.canonicalWorkdir);
42
+ await releaseCurrentPlanFocus({
43
+ project,
44
+ sessionKey: sessionFocusKey(identity),
45
+ kind: "expire",
46
+ sessionStore: focusStore,
47
+ });
48
+ }
49
+ catch (error) {
50
+ if (error instanceof ClawError)
51
+ continue;
52
+ throw error;
53
+ }
54
+ }
55
+ registry.removeReleasedExpired(expired.sessionKeyHash);
56
+ }
57
+ };
58
+ const scheduleIdle = () => {
59
+ if (idleTimer)
60
+ clearTimeout(idleTimer);
61
+ if (connections.size > 0)
62
+ return;
63
+ const idleTtlMs = options?.idleTtlMs
64
+ ?? Number(process.env.CLAW_SESSION_DAEMON_IDLE_TTL_MS ?? 300_000);
65
+ if (!Number.isFinite(idleTtlMs) || idleTtlMs <= 0)
66
+ return;
67
+ idleTimer = setTimeout(() => {
68
+ void close();
69
+ }, idleTtlMs);
70
+ idleTimer.unref();
71
+ };
72
+ const detach = async (connection) => {
73
+ if (!connection.sessionKeyHash)
74
+ return;
75
+ if (activeSessions.get(connection.sessionKeyHash) === connection) {
76
+ activeSessions.delete(connection.sessionKeyHash);
77
+ try {
78
+ await registry.close(connection.sessionKeyHash);
79
+ }
80
+ catch {
81
+ // Socket teardown must not be blocked by retained-state diagnostics.
82
+ }
83
+ }
84
+ connection.sessionHandle = undefined;
85
+ connection.sessionKeyHash = undefined;
86
+ };
87
+ const close = async () => {
88
+ if (closing)
89
+ return;
90
+ closing = true;
91
+ if (idleTimer)
92
+ clearTimeout(idleTimer);
93
+ await Promise.all([...connections].map((connection) => detach(connection)));
94
+ for (const connection of connections)
95
+ connection.socket.destroy();
96
+ await new Promise((resolve) => server.close(() => resolve()));
97
+ removeOwnedState(registry.runtimeRoot, token);
98
+ };
99
+ server.on("connection", (socket) => {
100
+ socket.setEncoding("utf-8");
101
+ const connection = {
102
+ socket,
103
+ buffer: "",
104
+ chain: Promise.resolve(),
105
+ };
106
+ connections.add(connection);
107
+ if (idleTimer)
108
+ clearTimeout(idleTimer);
109
+ socket.on("data", (chunk) => {
110
+ connection.buffer += String(chunk);
111
+ if (Buffer.byteLength(connection.buffer, "utf-8") > MAX_PROTOCOL_LINE_BYTES) {
112
+ socket.destroy(new Error("Session protocol frame exceeds the 1 MiB limit."));
113
+ return;
114
+ }
115
+ while (true) {
116
+ const lineEnd = connection.buffer.indexOf("\n");
117
+ if (lineEnd < 0)
118
+ break;
119
+ const line = connection.buffer.slice(0, lineEnd).trim();
120
+ connection.buffer = connection.buffer.slice(lineEnd + 1);
121
+ if (!line)
122
+ continue;
123
+ connection.chain = connection.chain.then(async () => {
124
+ const response = await handleLine(line, connection);
125
+ if (!socket.destroyed)
126
+ socket.write(`${JSON.stringify(response)}\n`);
127
+ if (response.ok
128
+ && JSON.parse(line).operation === "session.close"
129
+ && !socket.destroyed) {
130
+ socket.end();
131
+ }
132
+ }).catch(() => {
133
+ socket.destroy();
134
+ });
135
+ }
136
+ });
137
+ socket.on("close", () => {
138
+ connections.delete(connection);
139
+ void detach(connection).finally(scheduleIdle);
140
+ });
141
+ socket.on("error", () => {
142
+ // close owns retained state cleanup.
143
+ });
144
+ });
145
+ const handleLine = async (line, connection) => {
146
+ let request;
147
+ try {
148
+ request = JSON.parse(line);
149
+ }
150
+ catch {
151
+ return errorResponse("", "SESSION_PROTOCOL_INVALID", "Invalid JSONL request.");
152
+ }
153
+ if (request.protocolVersion !== SESSION_PROTOCOL_VERSION) {
154
+ return errorResponse(request.requestId, "SESSION_PROTOCOL_UNSUPPORTED", "Unsupported session protocol version.");
155
+ }
156
+ if (request.token !== token) {
157
+ return errorResponse(request.requestId, "SESSION_AUTH_FAILED", "Invalid session daemon token.");
158
+ }
159
+ try {
160
+ if (request.operation === "session.open") {
161
+ await cleanupExpiredSessions();
162
+ await detach(connection);
163
+ const identity = createSessionIdentity(request.input.agentSessionId, request.input.workdir);
164
+ const active = activeSessions.get(identity.sessionKeyHash);
165
+ if (active && active !== connection) {
166
+ throw new ClawError("PLAN_TRANSITION_CONFLICT", "SESSION_BUSY", {
167
+ code: "SESSION_BUSY",
168
+ sessionKeyHash: identity.sessionKeyHash,
169
+ });
170
+ }
171
+ const opened = await registry.open(request.input.agentSessionId, request.input.workdir, request.input.client);
172
+ connection.sessionHandle = randomUUID();
173
+ connection.sessionKeyHash = identity.sessionKeyHash;
174
+ connection.agentSessionId = identity.agentSessionId;
175
+ connection.canonicalWorkdir = identity.canonicalWorkdir;
176
+ connection.focusKey = sessionFocusKey(identity);
177
+ connection.host = request.input.client.host;
178
+ activeSessions.set(identity.sessionKeyHash, connection);
179
+ try {
180
+ const project = resolveProjectContext(identity.canonicalWorkdir);
181
+ await recoverProjectFocusTransitions({ project, sessionStore: focusStore });
182
+ }
183
+ catch (error) {
184
+ if (error instanceof ClawError && error.code === "FOCUS_RECOVERY_CONFLICT")
185
+ throw error;
186
+ }
187
+ const currentPlan = !opened.created && opened.record.currentPlan
188
+ ? (await service.execute({
189
+ cwd: identity.canonicalWorkdir,
190
+ agentSessionId: identity.agentSessionId,
191
+ sessionKey: sessionFocusKey(identity),
192
+ host: request.input.client.host,
193
+ mode: "session",
194
+ }, {
195
+ operation: "plan.show",
196
+ input: { simple: true },
197
+ })).output
198
+ : undefined;
199
+ return successResponse(request.requestId, {
200
+ sessionHandle: connection.sessionHandle,
201
+ session: opened.record,
202
+ ...(currentPlan ? { currentPlan } : {}),
203
+ });
204
+ }
205
+ assertAttached(request, connection);
206
+ if (request.operation === "session.status") {
207
+ return successResponse(request.requestId, {
208
+ session: registry.read(connection.sessionKeyHash),
209
+ daemon: {
210
+ schemaVersion: state.schemaVersion,
211
+ protocolVersion: state.protocolVersion,
212
+ pid: state.pid,
213
+ host: state.host,
214
+ port: state.port,
215
+ startedAt: state.startedAt,
216
+ },
217
+ });
218
+ }
219
+ if (request.operation === "session.close") {
220
+ const closed = await registry.close(connection.sessionKeyHash);
221
+ activeSessions.delete(connection.sessionKeyHash);
222
+ connection.sessionKeyHash = undefined;
223
+ return successResponse(request.requestId, { session: closed });
224
+ }
225
+ const result = await service.execute({
226
+ cwd: connection.canonicalWorkdir,
227
+ agentSessionId: connection.agentSessionId,
228
+ sessionKey: connection.focusKey,
229
+ host: connection.host,
230
+ mode: "session",
231
+ }, request.input);
232
+ await registry.touch(connection.sessionKeyHash);
233
+ return successResponse(request.requestId, {
234
+ schemaVersion: 1,
235
+ output: result.output,
236
+ ...(result.hostActions?.length ? { hostActions: result.hostActions } : {}),
237
+ ...(result.postCommitEffects?.length ? { postCommitEffects: result.postCommitEffects } : {}),
238
+ ...(result.knowledgeDispatch ? { knowledgeDispatch: result.knowledgeDispatch } : {}),
239
+ });
240
+ }
241
+ catch (error) {
242
+ if (error instanceof ClawError) {
243
+ const code = error.details?.code === "SESSION_BUSY"
244
+ ? "SESSION_BUSY"
245
+ : SESSION_PASSTHROUGH_ERRORS.has(error.code)
246
+ ? error.code
247
+ : "SESSION_COMMAND_FAILED";
248
+ return errorResponse(request.requestId, code, error.message, {
249
+ ...(error.details ?? {}),
250
+ ...(code === "SESSION_COMMAND_FAILED" ? { coreCode: error.code } : {}),
251
+ });
252
+ }
253
+ return errorResponse(request.requestId, "SESSION_INTERNAL_ERROR", error instanceof Error ? error.message : String(error));
254
+ }
255
+ };
256
+ await new Promise((resolve, reject) => {
257
+ server.once("error", reject);
258
+ server.listen(0, "127.0.0.1", () => {
259
+ server.off("error", reject);
260
+ resolve();
261
+ });
262
+ });
263
+ const address = server.address();
264
+ if (!address || typeof address === "string") {
265
+ throw new Error("Session daemon failed to bind a loopback TCP port.");
266
+ }
267
+ const state = {
268
+ schemaVersion: 1,
269
+ protocolVersion: SESSION_PROTOCOL_VERSION,
270
+ pid: process.pid,
271
+ host: "127.0.0.1",
272
+ port: address.port,
273
+ token,
274
+ startedAt: new Date().toISOString(),
275
+ };
276
+ const statePath = path.join(registry.runtimeRoot, "daemon", "state.json");
277
+ writeJsonFileAtomic(statePath, state);
278
+ try {
279
+ fs.chmodSync(statePath, 0o600);
280
+ }
281
+ catch {
282
+ // Windows ACLs are inherited from the user runtime directory.
283
+ }
284
+ releaseStartLock();
285
+ scheduleIdle();
286
+ return { state, close };
287
+ }
288
+ function assertAttached(request, connection) {
289
+ if (!connection.sessionHandle || request.sessionHandle !== connection.sessionHandle) {
290
+ throw new ClawError("PLAN_TRANSITION_CONFLICT", "Invalid or closed session handle.", {
291
+ code: "SESSION_HANDLE_INVALID",
292
+ });
293
+ }
294
+ }
295
+ function successResponse(requestId, output) {
296
+ return { ok: true, requestId, output };
297
+ }
298
+ function errorResponse(requestId, code, message, details) {
299
+ return {
300
+ ok: false,
301
+ requestId,
302
+ error: {
303
+ code,
304
+ message,
305
+ retryable: code === "SESSION_BUSY",
306
+ outcome: "known",
307
+ ...(details ? { details } : {}),
308
+ },
309
+ };
310
+ }
311
+ function acquireStartLock(runtimeRoot) {
312
+ const lockPath = path.join(runtimeRoot, "daemon", "start.lock");
313
+ fs.mkdirSync(path.dirname(lockPath), { recursive: true });
314
+ try {
315
+ fs.writeFileSync(lockPath, JSON.stringify({ pid: process.pid }), { flag: "wx" });
316
+ }
317
+ catch (error) {
318
+ if (error.code !== "EEXIST")
319
+ throw error;
320
+ try {
321
+ const owner = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
322
+ if (owner.pid && isProcessAlive(owner.pid)) {
323
+ throw new Error("Another session daemon is starting.");
324
+ }
325
+ fs.unlinkSync(lockPath);
326
+ fs.writeFileSync(lockPath, JSON.stringify({ pid: process.pid }), { flag: "wx" });
327
+ }
328
+ catch (nested) {
329
+ throw nested;
330
+ }
331
+ }
332
+ return () => {
333
+ try {
334
+ const owner = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
335
+ if (owner.pid === process.pid)
336
+ fs.unlinkSync(lockPath);
337
+ }
338
+ catch {
339
+ // Already released.
340
+ }
341
+ };
342
+ }
343
+ function removeOwnedState(runtimeRoot, token) {
344
+ const statePath = path.join(runtimeRoot, "daemon", "state.json");
345
+ try {
346
+ const state = JSON.parse(fs.readFileSync(statePath, "utf-8"));
347
+ if (state.token === token)
348
+ fs.unlinkSync(statePath);
349
+ }
350
+ catch {
351
+ // Discovery state is already absent or belongs to a replacement daemon.
352
+ }
353
+ }
354
+ function isProcessAlive(pid) {
355
+ try {
356
+ process.kill(pid, 0);
357
+ return true;
358
+ }
359
+ catch (error) {
360
+ return error.code === "EPERM";
361
+ }
362
+ }
363
+ //# sourceMappingURL=session-daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-daemon.js","sourceRoot":"","sources":["../src/session-daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { type FocusSessionRecord, type FocusSessionStore, type PlanRef } from "@veewo/claw-core";
2
+ export declare const SESSION_RECORD_TTL_MS: number;
3
+ export type SessionClientInfo = {
4
+ kind: "terminal" | "node" | "adapter";
5
+ host?: string;
6
+ };
7
+ export type SessionRecordV2 = {
8
+ schemaVersion: 2;
9
+ agentSessionId: string;
10
+ canonicalWorkdir: string;
11
+ state: "live" | "disconnected";
12
+ currentPlan?: PlanRef;
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ lastConnectedAt: string;
16
+ expiresAt: string;
17
+ lastClient?: SessionClientInfo;
18
+ };
19
+ export type SessionIdentityV2 = {
20
+ agentSessionId: string;
21
+ canonicalWorkdir: string;
22
+ sessionKeyHash: string;
23
+ };
24
+ export declare function resolveSessionDaemonRuntimeRoot(env?: NodeJS.ProcessEnv): string;
25
+ export declare function canonicalizeSessionWorkdir(workdir: string): string;
26
+ export declare function createSessionIdentity(agentSessionId: string, workdir: string): SessionIdentityV2;
27
+ export declare function sessionFocusKey(identity: Pick<SessionIdentityV2, "canonicalWorkdir" | "agentSessionId">): string;
28
+ export declare class SessionRegistryV2 {
29
+ readonly runtimeRoot: string;
30
+ constructor(runtimeRoot?: string);
31
+ open(agentSessionId: string, workdir: string, client: SessionClientInfo, now?: Date): Promise<{
32
+ identity: SessionIdentityV2;
33
+ record: SessionRecordV2;
34
+ created: boolean;
35
+ }>;
36
+ close(sessionKeyHash: string, now?: Date): Promise<SessionRecordV2>;
37
+ touch(sessionKeyHash: string, now?: Date): Promise<SessionRecordV2>;
38
+ read(sessionKeyHash: string): SessionRecordV2;
39
+ write(sessionKeyHash: string, record: SessionRecordV2): void;
40
+ recover(now?: Date): {
41
+ normalized: string[];
42
+ removed: string[];
43
+ };
44
+ cleanupExpired(now?: Date, liveSessionKeys?: Set<string>): string[];
45
+ listExpiredRecords(now?: Date, liveSessionKeys?: Set<string>): Array<{
46
+ sessionKeyHash: string;
47
+ record: SessionRecordV2;
48
+ }>;
49
+ removeExpired(sessionKeyHash: string, now?: Date): boolean;
50
+ removeReleasedExpired(sessionKeyHash: string): boolean;
51
+ recordPath(sessionKeyHash: string): string;
52
+ commandQueuePath(sessionKeyHash: string): string;
53
+ sessionDirectory(sessionKeyHash: string): string;
54
+ private listSessionKeys;
55
+ private removeSessionDirectory;
56
+ }
57
+ export declare function ensurePrivateDirectory(directory: string): void;
58
+ export declare class RegistryFocusSessionStore implements FocusSessionStore {
59
+ readonly registry: SessionRegistryV2;
60
+ constructor(registry: SessionRegistryV2);
61
+ read(sessionKeyHash: string): FocusSessionRecord;
62
+ buildPersistedRecord(sessionKeyHash: string, focus: FocusSessionRecord): unknown;
63
+ writePersistedAtomic(sessionKeyHash: string, persistedRecord: unknown): void;
64
+ queuePath(sessionKeyHash: string): string;
65
+ resourcePath(sessionKeyHash: string): string;
66
+ }