@parall/daemon 1.28.1 → 1.29.0

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.
@@ -1,22 +1,22 @@
1
1
  {
2
- "version": "1.28.1",
3
- "built_at": "2026-05-18T04:21:00.537Z",
2
+ "version": "1.29.0",
3
+ "built_at": "2026-05-19T14:30:48.082Z",
4
4
  "files": {
5
5
  "parall-claude-agent.js": {
6
- "sha256": "1e5145a58354fc6101623958f2e7bff7284cf58d589763506bf9462b6673a945",
7
- "size": 226667
6
+ "sha256": "0d95b5ed05758592e84c2725fc9f0bf21989c99afa0c62be95c392a6f13deb43",
7
+ "size": 228042
8
8
  },
9
9
  "parall-codex-agent.js": {
10
- "sha256": "6eb9f40345f979eef296c1434996ad7bdd37f5541a957c0b641da3b887478c92",
11
- "size": 255262
10
+ "sha256": "ae8a487ca6cc22c34587db800d3cbd4720af2631bcc19648e67aef4c74a83f9e",
11
+ "size": 256766
12
12
  },
13
13
  "parall-daemon.js": {
14
- "sha256": "ce30f1ca9eb12af5571c8378c17f114c6b1d0e30bfb2d9585c5fe0c57c38ac86",
15
- "size": 108511
14
+ "sha256": "358d6eb2a0e22a617b4571e3bba6d63bd2ae00b49736aa3a3ed4264ed0e75125",
15
+ "size": 112667
16
16
  },
17
17
  "parall-openclaw-agent.js": {
18
- "sha256": "1268c9d1b5583c79bffe8d81e027227e23d527e84f909b7d7e0ccef073618a71",
19
- "size": 8230
18
+ "sha256": "d2128b5a15c37c9fe624ed6ba6f1dc15c32235d98795e6171716d9776014aedf",
19
+ "size": 8475
20
20
  }
21
21
  }
22
22
  }
@@ -112,6 +112,9 @@ function buildEventBody(event) {
112
112
  }
113
113
  return lines.join("\n") + buildSendMessageHint(event);
114
114
  }
115
+ function buildEventBodyForForkResult(event) {
116
+ return buildEventBody(event).replace(/\n<system-reminder>[\s\S]*<\/system-reminder>$/, "");
117
+ }
115
118
  function buildSendMessageHint(event) {
116
119
  if (event.noReply)
117
120
  return "";
@@ -143,14 +146,16 @@ function buildForkResultPrefix(results) {
143
146
  if (!results.length)
144
147
  return "";
145
148
  const blocks = results.map((result) => {
146
- const lines = [`[Fork result]`];
147
- lines.push(`[Handled: ${result.sourceEvent.type} \u2014 ${result.sourceEvent.summary}]`);
149
+ const lines = [];
150
+ for (const body of result.eventBodies) {
151
+ lines.push(body);
152
+ }
153
+ lines.push(`[This event was handled by a parallel fork session. Do NOT re-handle, re-reply, or duplicate work for it.]`);
154
+ lines.push(`[Fork summary: ${result.agentSummary ? sanitizeMeta(result.agentSummary) : "No fork summary available \u2014 the fork completed without producing a text summary. Check the target chat/task for any actions the fork already took before acting."}]`);
148
155
  if (result.actions.length)
149
- lines.push(`[Actions: ${result.actions.join("; ")}]`);
150
- if (result.agentSummary)
151
- lines.push(`[Summary: ${sanitizeMeta(result.agentSummary)}]`);
156
+ lines.push(`[Fork actions: ${result.actions.join("; ")}]`);
152
157
  if (result.historyPath)
153
- lines.push(`[History: ${result.historyPath}]`);
158
+ lines.push(`[Fork history: ${result.historyPath}]`);
154
159
  return lines.join("\n");
155
160
  });
156
161
  return blocks.join("\n\n") + "\n\n---\n\n";
@@ -418,11 +423,19 @@ Messages may arrive with a \`[Thread: prll://msg_xxx]\` line in the event block,
418
423
  - Keep thread replies focused on the original topic
419
424
  `;
420
425
 
426
+ // ts/agent-core/dist/logger.js
427
+ function createLogger(prefix) {
428
+ return {
429
+ info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
430
+ warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
431
+ error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`)
432
+ };
433
+ }
434
+
421
435
  // ts/agent-core/dist/gateway-base.js
422
436
  import * as os from "node:os";
423
437
  import * as fs from "node:fs";
424
438
  import * as path from "node:path";
425
- import { randomUUID } from "node:crypto";
426
439
 
427
440
  // ts/sdk/dist/types.js
428
441
  var MENTION_ALL_USER_ID = "all";
@@ -473,7 +486,6 @@ var ENDPOINTS = {
473
486
  CHAT_MESSAGES: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/messages`,
474
487
  // Messages (global, by message ID)
475
488
  MESSAGE: (id) => `${API_BASE}/messages/${id}`,
476
- MESSAGE_PATCHES: (id) => `${API_BASE}/messages/${id}/patches`,
477
489
  MESSAGE_REPLIES: (id) => `${API_BASE}/messages/${id}/replies`,
478
490
  // Upload (org-scoped)
479
491
  UPLOAD_PRESIGN: (orgId) => `${API_BASE}/orgs/${orgId}/upload/presign`,
@@ -500,6 +512,7 @@ var ENDPOINTS = {
500
512
  AGENT_SESSION: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}`,
501
513
  AGENT_SESSION_STEPS: (orgId, agentId, sessionId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps`,
502
514
  AGENT_SESSION_STEP: (orgId, agentId, sessionId, stepId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/sessions/${sessionId}/steps/${stepId}`,
515
+ AGENT_STEP_BY_ID: (orgId, stepId) => `${API_BASE}/orgs/${orgId}/agent-steps/${stepId}`,
503
516
  AGENT_TASKS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/tasks`,
504
517
  AGENT_RUNTIME_AUTH: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/runtime-auth`,
505
518
  AGENT_RUNTIME_AUTH_SESSIONS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/runtime-auth-sessions`,
@@ -524,9 +537,12 @@ var ENDPOINTS = {
524
537
  // Attach/Detach bind an agent to/from a daemon Machine.
525
538
  MACHINE_ATTACH_AGENT: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}`,
526
539
  MACHINE_DETACH_AGENT: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}`,
540
+ MACHINE_LLM_SOURCE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
527
541
  MACHINE_RUNTIME_AUTH: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
528
542
  MACHINE_KEYS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys`,
529
543
  MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
544
+ MACHINE_RUNTIME_AUTH_SESSIONS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions`,
545
+ MACHINE_RUNTIME_AUTH_SESSION_COMPLETE: (orgId, machineId, sessionId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth-sessions/${sessionId}/complete`,
530
546
  // Machine self-control-plane (mck_-scoped). The bearer token implicitly
531
547
  // identifies the Machine, so there is no `:mid` URL parameter — these are
532
548
  // "self" routes called by the daemon for its own host.
@@ -1167,9 +1183,6 @@ var ParallClient = class _ParallClient {
1167
1183
  async deleteMessage(id) {
1168
1184
  return this.request("DELETE", ENDPOINTS.MESSAGE(id));
1169
1185
  }
1170
- async patchMessage(id, req) {
1171
- return this.request("POST", ENDPOINTS.MESSAGE_PATCHES(id), req);
1172
- }
1173
1186
  async getMessageReplies(id, params) {
1174
1187
  return this.request("GET", ENDPOINTS.MESSAGE_REPLIES(id), void 0, params);
1175
1188
  }
@@ -1262,8 +1275,7 @@ var ParallClient = class _ParallClient {
1262
1275
  * @param params.status - Comma-separated status filter (e.g., `'open'`).
1263
1276
  */
1264
1277
  async getAgentSessions(orgId, agentId, params) {
1265
- const res = await this.request("GET", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), void 0, params);
1266
- return res.data;
1278
+ return this.request("GET", ENDPOINTS.AGENT_SESSIONS(orgId, agentId), void 0, params);
1267
1279
  }
1268
1280
  async getAgentSession(orgId, agentId, sessionId) {
1269
1281
  return this.request("GET", ENDPOINTS.AGENT_SESSION(orgId, agentId, sessionId));
@@ -1275,12 +1287,14 @@ var ParallClient = class _ParallClient {
1275
1287
  return this.request("POST", ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), req);
1276
1288
  }
1277
1289
  async getAgentSessionSteps(orgId, agentId, sessionId, params) {
1278
- const res = await this.request("GET", ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), void 0, params);
1279
- return res.data;
1290
+ return this.request("GET", ENDPOINTS.AGENT_SESSION_STEPS(orgId, agentId, sessionId), void 0, params);
1280
1291
  }
1281
1292
  async getAgentSessionStep(orgId, agentId, sessionId, stepId) {
1282
1293
  return this.request("GET", ENDPOINTS.AGENT_SESSION_STEP(orgId, agentId, sessionId, stepId));
1283
1294
  }
1295
+ async getAgentStepById(orgId, stepId) {
1296
+ return this.request("GET", ENDPOINTS.AGENT_STEP_BY_ID(orgId, stepId));
1297
+ }
1284
1298
  // ---- Agent runtime auth (hosted Claude OAuth) ----
1285
1299
  async getAgentRuntimeAuth(orgId, agentId) {
1286
1300
  return this.request("GET", ENDPOINTS.AGENT_RUNTIME_AUTH(orgId, agentId));
@@ -1377,10 +1391,22 @@ var ParallClient = class _ParallClient {
1377
1391
  async detachAgent(orgId, machineId, agentId) {
1378
1392
  return this.request("DELETE", ENDPOINTS.MACHINE_DETACH_AGENT(orgId, machineId, agentId));
1379
1393
  }
1394
+ async patchMachineLLMSource(orgId, machineId, llmSource) {
1395
+ return this.request("PATCH", ENDPOINTS.MACHINE_LLM_SOURCE(orgId, machineId), { llm_source: llmSource });
1396
+ }
1380
1397
  /** Get machine-level runtime auth state. */
1381
1398
  async getMachineRuntimeAuth(orgId, machineId) {
1382
1399
  return this.request("GET", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
1383
1400
  }
1401
+ async startMachineRuntimeAuthSession(orgId, machineId, req = {}) {
1402
+ return this.request("POST", ENDPOINTS.MACHINE_RUNTIME_AUTH_SESSIONS(orgId, machineId), req);
1403
+ }
1404
+ async completeMachineRuntimeAuthSession(orgId, machineId, sessionId, req) {
1405
+ return this.request("POST", ENDPOINTS.MACHINE_RUNTIME_AUTH_SESSION_COMPLETE(orgId, machineId, sessionId), req);
1406
+ }
1407
+ async disconnectMachineRuntimeAuth(orgId, machineId) {
1408
+ return this.request("DELETE", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
1409
+ }
1384
1410
  // ---- Machine self-control-plane (mck_-scoped) ----
1385
1411
  //
1386
1412
  // The four methods below are intended to be called from a daemon-mode
@@ -2312,9 +2338,9 @@ var ParallAgentGateway = class {
2312
2338
  this.SHUTDOWN_DEADLINE_MS = opts.shutdownDeadlineMs ?? 6e4;
2313
2339
  }
2314
2340
  async run(abortSignal) {
2315
- const { ws, log } = this.opts;
2341
+ const { ws, log: log2 } = this.opts;
2316
2342
  ws.onStateChange((state) => {
2317
- log?.info(`parall[${this.opts.accountId}]: connection state \u2192 ${state}`);
2343
+ log2?.info(`parall[${this.opts.accountId}]: connection state \u2192 ${state}`);
2318
2344
  });
2319
2345
  ws.on("hello", async (data) => {
2320
2346
  await this.handleHello(data);
@@ -2727,7 +2753,8 @@ var ParallAgentGateway = class {
2727
2753
  continue;
2728
2754
  }
2729
2755
  if (!binding) {
2730
- throw new Error(`runtime emitted ${runtimeEvent.type} before runtime_session`);
2756
+ const detail = runtimeEvent.type === "error" ? `: ${runtimeEvent.message}` : "";
2757
+ throw new Error(`runtime emitted ${runtimeEvent.type} before runtime_session${detail}`);
2731
2758
  }
2732
2759
  if (!triggerMessageSet) {
2733
2760
  triggerMessageSet = true;
@@ -2842,6 +2869,7 @@ var ParallAgentGateway = class {
2842
2869
  targetId: fork.targetId,
2843
2870
  summary: fork.processedEvents.length === 1 ? `${first.type} from ${first.senderName} in ${first.targetName ?? fork.targetId}` : `${fork.processedEvents.length} events in ${first.targetName ?? fork.targetId}`
2844
2871
  },
2872
+ eventBodies: fork.processedEvents.map((e) => buildEventBodyForForkResult(e)),
2845
2873
  actions: [],
2846
2874
  agentSummary,
2847
2875
  historyPath
@@ -2881,32 +2909,11 @@ var ParallAgentGateway = class {
2881
2909
  return;
2882
2910
  this.draining = true;
2883
2911
  try {
2884
- while (this.dispatchState.mainBuffer.length > 0 || this.dispatchState.pendingForkResults.length > 0) {
2912
+ while (this.dispatchState.mainBuffer.length > 0) {
2885
2913
  if (this.shuttingDown) {
2886
2914
  this.opts.log?.info(`parall[${this.opts.accountId}]: drainMainBuffer halted (shutting down) \u2014 ${this.dispatchState.mainBuffer.length} buffered, ${this.dispatchState.pendingForkResults.length} pending fork results left for catch-up`);
2887
2915
  break;
2888
2916
  }
2889
- if (this.dispatchState.mainBuffer.length === 0 && this.dispatchState.pendingForkResults.length > 0) {
2890
- const pending = this.dispatchState.pendingForkResults.splice(0);
2891
- const forkPrefix2 = buildForkResultPrefix(pending);
2892
- const syntheticEvent = {
2893
- type: "message",
2894
- targetId: "_orchestrator",
2895
- targetType: "system",
2896
- senderId: "system",
2897
- senderName: "system",
2898
- messageId: `synthetic-${this.opts.accountId}-${randomUUID()}`,
2899
- body: "[Orchestrator: fork session(s) completed \u2014 review results above]"
2900
- };
2901
- this.dispatchState.mainCurrentTargetId = void 0;
2902
- this.dispatchState.mainPreDispatchBranchPoint = this.opts.dispatchAdapter.getBranchPoint?.(this.opts.runtimeKey);
2903
- const dispatched2 = await this.runDispatch(syntheticEvent, this.opts.runtimeKey, forkPrefix2 + buildEventBody(syntheticEvent));
2904
- if (!dispatched2) {
2905
- this.dispatchState.pendingForkResults.unshift(...pending);
2906
- break;
2907
- }
2908
- continue;
2909
- }
2910
2917
  const targetId = this.dispatchState.mainBuffer[0].targetId;
2911
2918
  const events = [];
2912
2919
  while (this.dispatchState.mainBuffer[0]?.targetId === targetId) {
@@ -3438,12 +3445,12 @@ var ParallAgentGateway = class {
3438
3445
  }
3439
3446
  }
3440
3447
  async handleHello(data) {
3441
- const { client, config, log } = this.opts;
3448
+ const { client, config, log: log2 } = this.opts;
3442
3449
  this.sessionId = data.session_id ?? "";
3443
3450
  const intervalSec = data.heartbeat_interval > 0 ? data.heartbeat_interval : 30;
3444
3451
  try {
3445
3452
  const count = await fetchAllChats(client, config.org_id, this.chatInfoMap);
3446
- log?.info(`parall[${this.opts.accountId}]: WebSocket connected, ${count} chats cached`);
3453
+ log2?.info(`parall[${this.opts.accountId}]: WebSocket connected, ${count} chats cached`);
3447
3454
  await this.opts.onSessionReady?.({
3448
3455
  activeSessionId: this.activeSessionId,
3449
3456
  ws: this.opts.ws,
@@ -3457,7 +3464,7 @@ var ParallAgentGateway = class {
3457
3464
  const expectedMs = intervalSec * 1e3;
3458
3465
  const drift = now - this.lastHeartbeatAt - expectedMs;
3459
3466
  if (drift > 15e3) {
3460
- log?.warn(`parall[${this.opts.accountId}]: heartbeat drift ${drift}ms \u2014 event loop may be blocked`);
3467
+ log2?.warn(`parall[${this.opts.accountId}]: heartbeat drift ${drift}ms \u2014 event loop may be blocked`);
3461
3468
  }
3462
3469
  this.lastHeartbeatAt = now;
3463
3470
  if (this.opts.ws.state !== "connected")
@@ -3473,10 +3480,10 @@ var ParallAgentGateway = class {
3473
3480
  const isFirstHello = !this.hadSuccessfulHello;
3474
3481
  this.hadSuccessfulHello = true;
3475
3482
  this.catchUpFromDispatch(isFirstHello).catch((err) => {
3476
- log?.warn(`parall[${this.opts.accountId}]: dispatch catch-up failed: ${String(err)}`);
3483
+ log2?.warn(`parall[${this.opts.accountId}]: dispatch catch-up failed: ${String(err)}`);
3477
3484
  });
3478
3485
  } catch (err) {
3479
- log?.error(`parall[${this.opts.accountId}]: failed to fetch chats: ${String(err)}`);
3486
+ log2?.error(`parall[${this.opts.accountId}]: failed to fetch chats: ${String(err)}`);
3480
3487
  }
3481
3488
  }
3482
3489
  // Resolves when in-flight dispatches hit 0 or the deadline elapses.
@@ -3581,7 +3588,7 @@ function extractDefaults(config, runtimeType) {
3581
3588
  return { model, thinkingEffort };
3582
3589
  }
3583
3590
  function createPlatformConfigManager(opts) {
3584
- const { client, stateDir, runtimeType, log } = opts;
3591
+ const { client, stateDir, runtimeType, log: log2 } = opts;
3585
3592
  let cachedVersion;
3586
3593
  let currentDefaults = { model: null, thinkingEffort: null };
3587
3594
  let currentRawConfig = null;
@@ -3598,20 +3605,20 @@ function createPlatformConfigManager(opts) {
3598
3605
  fresh = await client.getPlatformConfig(cachedVersion);
3599
3606
  } catch (err) {
3600
3607
  if (cached) {
3601
- log?.warn(`platform config fetch failed, using cached version ${cachedVersion}: ${String(err)}`);
3608
+ log2?.warn(`platform config fetch failed, using cached version ${cachedVersion}: ${String(err)}`);
3602
3609
  return currentDefaults;
3603
3610
  }
3604
- log?.warn(`platform config fetch failed and no cache available: ${String(err)}`);
3611
+ log2?.warn(`platform config fetch failed and no cache available: ${String(err)}`);
3605
3612
  return currentDefaults;
3606
3613
  }
3607
3614
  if (fresh === null) {
3608
3615
  return currentDefaults;
3609
3616
  }
3610
3617
  if (fresh.schema_version !== void 0 && fresh.schema_version > SUPPORTED_SCHEMA_VERSION) {
3611
- log?.warn(`platform config schema_version ${fresh.schema_version} > supported (${SUPPORTED_SCHEMA_VERSION}), keeping current`);
3618
+ log2?.warn(`platform config schema_version ${fresh.schema_version} > supported (${SUPPORTED_SCHEMA_VERSION}), keeping current`);
3612
3619
  return currentDefaults;
3613
3620
  }
3614
- log?.info(`platform config updated to version ${fresh.version}`);
3621
+ log2?.info(`platform config updated to version ${fresh.version}`);
3615
3622
  saveCache(stateDir, fresh);
3616
3623
  cachedVersion = fresh.version;
3617
3624
  currentRawConfig = fresh.config;
@@ -4187,8 +4194,8 @@ function stepIdFilePathForSession(stateDir, sessionKey) {
4187
4194
  // ts/claude-agent/dist/dispatch.js
4188
4195
  import * as fs5 from "node:fs";
4189
4196
  import * as path6 from "node:path";
4190
- import { randomUUID as randomUUID2 } from "node:crypto";
4191
- import { spawn } from "node:child_process";
4197
+ import { randomUUID } from "node:crypto";
4198
+ import { execSync as execSync2, spawn } from "node:child_process";
4192
4199
 
4193
4200
  // ts/agent-core/dist/internal/attachment-input.js
4194
4201
  import { execSync } from "node:child_process";
@@ -4489,7 +4496,7 @@ function sameFileIdentity(a, b) {
4489
4496
  function sameFile(a, b) {
4490
4497
  return sameFileIdentity(a, b) && a.size === b.size && a.mtimeMs === b.mtimeMs;
4491
4498
  }
4492
- async function cleanupOldAttachmentFiles(rootDir, ttlMs, log, preserveDirs) {
4499
+ async function cleanupOldAttachmentFiles(rootDir, ttlMs, log2, preserveDirs) {
4493
4500
  let entries;
4494
4501
  try {
4495
4502
  entries = await fs4.readdir(rootDir, { withFileTypes: true });
@@ -4511,11 +4518,11 @@ async function cleanupOldAttachmentFiles(rootDir, ttlMs, log, preserveDirs) {
4511
4518
  await fs4.rm(fullPath, { recursive: true, force: true });
4512
4519
  }
4513
4520
  } catch (err) {
4514
- log?.warn?.(`agent-core: failed to clean attachment temp dir ${fullPath}: ${String(err)}`);
4521
+ log2?.warn?.(`agent-core: failed to clean attachment temp dir ${fullPath}: ${String(err)}`);
4515
4522
  }
4516
4523
  }));
4517
4524
  }
4518
- async function pruneAttachmentCache(rootDir, maxBytes, log, preserveDirs) {
4525
+ async function pruneAttachmentCache(rootDir, maxBytes, log2, preserveDirs) {
4519
4526
  if (maxBytes <= 0)
4520
4527
  return;
4521
4528
  let entries;
@@ -4538,7 +4545,7 @@ async function pruneAttachmentCache(rootDir, maxBytes, log, preserveDirs) {
4538
4545
  dirs.push({ path: fullPath, mtimeMs: stat.mtimeMs, size });
4539
4546
  total += size;
4540
4547
  } catch (err) {
4541
- log?.warn?.(`agent-core: failed to inspect attachment cache dir ${fullPath}: ${String(err)}`);
4548
+ log2?.warn?.(`agent-core: failed to inspect attachment cache dir ${fullPath}: ${String(err)}`);
4542
4549
  }
4543
4550
  }
4544
4551
  if (total <= maxBytes)
@@ -4553,7 +4560,7 @@ async function pruneAttachmentCache(rootDir, maxBytes, log, preserveDirs) {
4553
4560
  await fs4.rm(dir.path, { recursive: true, force: true });
4554
4561
  total -= dir.size;
4555
4562
  } catch (err) {
4556
- log?.warn?.(`agent-core: failed to prune attachment cache dir ${dir.path}: ${String(err)}`);
4563
+ log2?.warn?.(`agent-core: failed to prune attachment cache dir ${dir.path}: ${String(err)}`);
4557
4564
  }
4558
4565
  }
4559
4566
  }
@@ -4948,6 +4955,20 @@ async function* parseClaudeStreamJson(readable) {
4948
4955
  }
4949
4956
 
4950
4957
  // ts/claude-agent/dist/dispatch.js
4958
+ var IS_WIN32 = process.platform === "win32";
4959
+ function quoteWin32Arg(arg) {
4960
+ if (!/[\s"&|^<>()]/.test(arg))
4961
+ return arg;
4962
+ return `"${arg.replace(/"/g, '""')}"`;
4963
+ }
4964
+ function killWin32Tree(pid) {
4965
+ try {
4966
+ execSync2(`taskkill /T /F /PID ${pid}`, { windowsHide: true, stdio: "ignore" });
4967
+ return true;
4968
+ } catch {
4969
+ return false;
4970
+ }
4971
+ }
4951
4972
  function buildSpawnEnv(parentEnv, claudeHome, context, opts) {
4952
4973
  const env = { ...parentEnv };
4953
4974
  if (!opts.allowApiKey) {
@@ -5089,12 +5110,12 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5089
5110
  * state.steerReadPending so the next runTurn can drain it instead of
5090
5111
  * silently losing the first event of the subsequent turn.
5091
5112
  */
5092
- async *consumeSteerTurn(sessionKey, log) {
5113
+ async *consumeSteerTurn(sessionKey, log2) {
5093
5114
  const state = this.processes.get(sessionKey);
5094
5115
  if (!state || state.done) {
5095
5116
  throw new Error("claude-agent: process dead during steer consumption");
5096
5117
  }
5097
- const groupKey = randomUUID2();
5118
+ const groupKey = randomUUID();
5098
5119
  const parserNext = state.parser.next();
5099
5120
  const firstRead = await Promise.race([
5100
5121
  parserNext.then((r) => ({ kind: "value", result: r })),
@@ -5102,7 +5123,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5102
5123
  ]);
5103
5124
  if (firstRead.kind === "timeout") {
5104
5125
  state.steerReadPending = parserNext;
5105
- log?.info?.(`claude-agent: steer turn timeout \u2014 steer was incorporated into previous turn`);
5126
+ log2?.info?.(`claude-agent: steer turn timeout \u2014 steer was incorporated into previous turn`);
5106
5127
  return;
5107
5128
  }
5108
5129
  let next = firstRead.result;
@@ -5132,15 +5153,15 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5132
5153
  next = await state.parser.next();
5133
5154
  }
5134
5155
  }
5135
- async *runTurn(sessionKey, promptBody, log) {
5156
+ async *runTurn(sessionKey, promptBody, log2) {
5136
5157
  let state;
5137
5158
  try {
5138
- state = this.ensureProcess(sessionKey, log);
5159
+ state = this.ensureProcess(sessionKey, log2);
5139
5160
  } catch (err) {
5140
5161
  yield { type: "error", message: `Claude spawn failed: ${String(err)}` };
5141
5162
  return;
5142
5163
  }
5143
- const groupKey = randomUUID2();
5164
+ const groupKey = randomUUID();
5144
5165
  let sawError = false;
5145
5166
  try {
5146
5167
  this.writeUserMessage(state.handle, promptBody);
@@ -5178,9 +5199,12 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5178
5199
  if (next.done) {
5179
5200
  state.done = true;
5180
5201
  this.processes.delete(sessionKey);
5202
+ const detail = state.handle.stderrChunks.join("").trim();
5203
+ const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
5204
+ if (detail) {
5205
+ log2?.warn?.(`claude-agent: subprocess stderr: ${detail}`);
5206
+ }
5181
5207
  if (!sawError) {
5182
- const detail = state.handle.stderrChunks.join("").trim();
5183
- const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
5184
5208
  yield {
5185
5209
  type: "error",
5186
5210
  message: detail || `Claude exited with code ${exit.code ?? "unknown"}${exit.signal ? ` (${exit.signal})` : ""}`
@@ -5220,7 +5244,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5220
5244
  yield { ...parsed, groupKey };
5221
5245
  }
5222
5246
  }
5223
- ensureProcess(sessionKey, log) {
5247
+ ensureProcess(sessionKey, log2) {
5224
5248
  if (this.shuttingDown) {
5225
5249
  throw new Error("claude-agent: adapter shutting down, refusing new process");
5226
5250
  }
@@ -5235,21 +5259,22 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5235
5259
  this.processes.delete(sessionKey);
5236
5260
  }
5237
5261
  }
5238
- const handle = this.spawnProcess(sessionKey, log);
5262
+ const handle = this.spawnProcess(sessionKey, log2);
5239
5263
  const parser = parseClaudeStreamJson(handle.proc.stdout);
5240
5264
  const state = { handle, parser, done: false, needsRestart: false };
5241
5265
  this.processes.set(sessionKey, state);
5242
5266
  this.opts.sessionManager.registerProcess(sessionKey, handle);
5243
5267
  return state;
5244
5268
  }
5245
- spawnProcess(sessionKey, log) {
5269
+ spawnProcess(sessionKey, log2) {
5246
5270
  const args = this.buildArgs(sessionKey);
5247
5271
  const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), { allowApiKey: this.opts.allowApiKey, effortLevel: this._effortLevel });
5248
- log?.info(`claude-agent: spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
5249
- const proc = spawn(this.opts.claudeBin, args, {
5272
+ log2?.info(`claude-agent: spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
5273
+ const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
5250
5274
  cwd: this.opts.workspaceDir,
5251
5275
  env,
5252
- stdio: ["pipe", "pipe", "pipe"]
5276
+ stdio: ["pipe", "pipe", "pipe"],
5277
+ shell: IS_WIN32
5253
5278
  });
5254
5279
  if (!proc.stdout || !proc.stderr || !proc.stdin) {
5255
5280
  throw new Error("Claude subprocess did not provide stdio pipes");
@@ -5261,7 +5286,9 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5261
5286
  proc.stdin.on("error", () => {
5262
5287
  proc.stdin.destroy();
5263
5288
  if (proc.exitCode === null && proc.signalCode === null) {
5264
- proc.kill("SIGTERM");
5289
+ if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
5290
+ proc.kill("SIGTERM");
5291
+ }
5265
5292
  }
5266
5293
  });
5267
5294
  const exitPromise = new Promise((resolve3) => {
@@ -5282,7 +5309,9 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5282
5309
  }
5283
5310
  if (state.handle.proc.exitCode === null && state.handle.proc.signalCode === null) {
5284
5311
  try {
5285
- state.handle.proc.kill("SIGTERM");
5312
+ if (!IS_WIN32 || !state.handle.proc.pid || !killWin32Tree(state.handle.proc.pid)) {
5313
+ state.handle.proc.kill("SIGTERM");
5314
+ }
5286
5315
  } catch {
5287
5316
  }
5288
5317
  }
@@ -5300,7 +5329,6 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5300
5329
  }
5301
5330
  buildArgs(sessionKey) {
5302
5331
  const args = [
5303
- "-p",
5304
5332
  "--verbose",
5305
5333
  "--input-format",
5306
5334
  "stream-json",
@@ -5351,7 +5379,7 @@ var ClaudeCodeAdapter = class _ClaudeCodeAdapter {
5351
5379
  // ts/claude-agent/dist/session-manager.js
5352
5380
  import * as fs6 from "node:fs";
5353
5381
  import * as path7 from "node:path";
5354
- import { randomUUID as randomUUID3 } from "node:crypto";
5382
+ import { randomUUID as randomUUID2 } from "node:crypto";
5355
5383
  var ClaudeSessionManager = class _ClaudeSessionManager {
5356
5384
  mainSessionKey;
5357
5385
  stateFilePath;
@@ -5388,7 +5416,7 @@ var ClaudeSessionManager = class _ClaudeSessionManager {
5388
5416
  const parentSessionId = this.sessionIds.get(parentSessionKey);
5389
5417
  if (!parentSessionId)
5390
5418
  return null;
5391
- const sessionKey = `claude-fork:${randomUUID3()}`;
5419
+ const sessionKey = `claude-fork:${randomUUID2()}`;
5392
5420
  this.pendingForkParents.set(sessionKey, parentSessionId);
5393
5421
  return {
5394
5422
  sessionKey,
@@ -5522,7 +5550,7 @@ var ClaudeSessionManager = class _ClaudeSessionManager {
5522
5550
  // ts/claude-agent/dist/workspace.js
5523
5551
  import * as fs7 from "node:fs";
5524
5552
  import * as path8 from "node:path";
5525
- function ensureClaudeWorkspace(workspaceDir, log, agentIdentity) {
5553
+ function ensureClaudeWorkspace(workspaceDir, log2, agentIdentity) {
5526
5554
  const systemPrompt = [
5527
5555
  buildIdentity(agentIdentity),
5528
5556
  BRIDGE_WORKSPACE_INSTRUCTIONS,
@@ -5540,13 +5568,7 @@ function ensureClaudeWorkspace(workspaceDir, log, agentIdentity) {
5540
5568
  }
5541
5569
 
5542
5570
  // ts/claude-agent/dist/index.js
5543
- function createLogger(prefix) {
5544
- return {
5545
- info: (msg) => console.log(`[${prefix}] ${msg}`),
5546
- warn: (msg) => console.warn(`[${prefix}] ${msg}`),
5547
- error: (msg) => console.error(`[${prefix}] ${msg}`)
5548
- };
5549
- }
5571
+ var log = createLogger("claude-agent");
5550
5572
  async function getAgentMeWithLegacyFallback(client, orgId) {
5551
5573
  try {
5552
5574
  return await client.getAgentMe(orgId);
@@ -5560,7 +5582,6 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
5560
5582
  }
5561
5583
  async function main() {
5562
5584
  const config = resolveClaudeAgentConfig(process.env);
5563
- const log = createLogger("claude-agent");
5564
5585
  if (config.allowApiKey && (process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN)) {
5565
5586
  log.warn("PRLL_CLAUDE_ALLOW_API_KEY=1 \u2014 ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN will reach the Claude CLI; billing routes through Anthropic API pay-per-use instead of Claude.ai OAuth.");
5566
5587
  }
@@ -5680,6 +5701,6 @@ async function main() {
5680
5701
  }
5681
5702
  }
5682
5703
  main().catch((err) => {
5683
- console.error(`[claude-agent] fatal: ${String(err)}`);
5704
+ log.error(`fatal: ${String(err)}`);
5684
5705
  process.exitCode = 1;
5685
5706
  });