@parall/claude-agent 1.28.1 → 1.29.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.
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EAER,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EACL,oBAAoB,EAErB,MAAM,sBAAsB,CAAC;AAE9B,KAAK,wBAAwB,GAAG,IAAI,CAClC,iBAAiB,EACf,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,OAAO,GACP,gBAAgB,GAChB,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,oBAAoB,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,iDAAiD;IACjD,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3D,CAAC;AAEF,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,IAAI,EAAE;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,MAAM,CAAC,UAAU,CAuBnB;AAiBD,qBAAa,iBAAkB,YAAW,eAAe;IAO3C,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6B;IAC/D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,YAAY,CAAqB;gBAEZ,IAAI,EAAE,wBAAwB;IAI3D,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAAwB;IAC9D,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAA8B;IAErE,YAAY,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAY7E,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAchE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1C,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IAiCxG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ7D,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ;IAIpC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAQ/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAEvD;;;;;;;;;OASG;YACY,gBAAgB;YAsDhB,OAAO;IAwGtB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,YAAY;IA8CpB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,SAAS;IAyCjB,OAAO,CAAC,uBAAuB;CAkBhC"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,YAAY,EACZ,QAAQ,EAER,YAAY,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EACL,oBAAoB,EAErB,MAAM,sBAAsB,CAAC;AAE9B,KAAK,wBAAwB,GAAG,IAAI,CAClC,iBAAiB,EACf,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,OAAO,GACP,gBAAgB,GAChB,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,oBAAoB,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,iDAAiD;IACjD,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3D,CAAC;AAgBF,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,IAAI,EAAE;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,MAAM,CAAC,UAAU,CAuBnB;AAiBD,qBAAa,iBAAkB,YAAW,eAAe;IAO3C,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6B;IAC/D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,YAAY,CAAqB;gBAEZ,IAAI,EAAE,wBAAwB;IAI3D,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAAwB;IAC9D,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAA8B;IAErE,YAAY,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAY7E,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAchE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1C,QAAQ,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IAiCxG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ7D,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ;IAIpC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAQ/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAEvD;;;;;;;;;OASG;YACY,gBAAgB;YAsDhB,OAAO;IA2GtB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,YAAY;IA+CpB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,SAAS;IAwCjB,OAAO,CAAC,uBAAuB;CAkBhC"}
package/dist/dispatch.js CHANGED
@@ -1,9 +1,24 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
- import { spawn } from "node:child_process";
4
+ import { execSync, spawn } from "node:child_process";
5
5
  import { appendPreparedLocalAttachmentRefs, pinLocalAttachmentPaths, } from "@parall/agent-core/internal/attachment-input";
6
6
  import { parseClaudeStreamJson } from "./output-parser.js";
7
+ const IS_WIN32 = process.platform === "win32";
8
+ function quoteWin32Arg(arg) {
9
+ if (!/[\s"&|^<>()]/.test(arg))
10
+ return arg;
11
+ return `"${arg.replace(/"/g, '""')}"`;
12
+ }
13
+ function killWin32Tree(pid) {
14
+ try {
15
+ execSync(`taskkill /T /F /PID ${pid}`, { windowsHide: true, stdio: "ignore" });
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
7
22
  export function buildSpawnEnv(parentEnv, claudeHome, context, opts) {
8
23
  const env = { ...parentEnv };
9
24
  if (!opts.allowApiKey) {
@@ -245,9 +260,12 @@ export class ClaudeCodeAdapter {
245
260
  if (next.done) {
246
261
  state.done = true;
247
262
  this.processes.delete(sessionKey);
263
+ const detail = state.handle.stderrChunks.join("").trim();
264
+ const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
265
+ if (detail) {
266
+ log?.warn?.(`claude-agent: subprocess stderr: ${detail}`);
267
+ }
248
268
  if (!sawError) {
249
- const detail = state.handle.stderrChunks.join("").trim();
250
- const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null }));
251
269
  yield {
252
270
  type: "error",
253
271
  message: detail
@@ -316,10 +334,11 @@ export class ClaudeCodeAdapter {
316
334
  const args = this.buildArgs(sessionKey);
317
335
  const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), { allowApiKey: this.opts.allowApiKey, effortLevel: this._effortLevel });
318
336
  log?.info(`claude-agent: spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
319
- const proc = spawn(this.opts.claudeBin, args, {
337
+ const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
320
338
  cwd: this.opts.workspaceDir,
321
339
  env,
322
340
  stdio: ["pipe", "pipe", "pipe"],
341
+ shell: IS_WIN32,
323
342
  });
324
343
  if (!proc.stdout || !proc.stderr || !proc.stdin) {
325
344
  throw new Error("Claude subprocess did not provide stdio pipes");
@@ -329,13 +348,11 @@ export class ClaudeCodeAdapter {
329
348
  stderrChunks.push(chunk.toString());
330
349
  });
331
350
  proc.stdin.on("error", () => {
332
- // stdin pipe broken: kill the process so parser.next() sees EOF
333
- // instead of hanging forever on a process that's alive but can't
334
- // accept input. If the process was already exiting (the common
335
- // EPIPE-on-close race), kill is a harmless no-op.
336
351
  proc.stdin.destroy();
337
352
  if (proc.exitCode === null && proc.signalCode === null) {
338
- proc.kill("SIGTERM");
353
+ if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
354
+ proc.kill("SIGTERM");
355
+ }
339
356
  }
340
357
  });
341
358
  const exitPromise = new Promise((resolve) => {
@@ -356,7 +373,9 @@ export class ClaudeCodeAdapter {
356
373
  catch { /* best-effort */ }
357
374
  if (state.handle.proc.exitCode === null && state.handle.proc.signalCode === null) {
358
375
  try {
359
- state.handle.proc.kill("SIGTERM");
376
+ if (!IS_WIN32 || !state.handle.proc.pid || !killWin32Tree(state.handle.proc.pid)) {
377
+ state.handle.proc.kill("SIGTERM");
378
+ }
360
379
  }
361
380
  catch { /* best-effort */ }
362
381
  }
@@ -373,7 +392,6 @@ export class ClaudeCodeAdapter {
373
392
  }
374
393
  buildArgs(sessionKey) {
375
394
  const args = [
376
- "-p",
377
395
  "--verbose",
378
396
  "--input-format",
379
397
  "stream-json",
package/dist/index.js CHANGED
@@ -1,18 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import * as os from "node:os";
3
- import { ParallAgentGateway, createPlatformConfigManager, isPlatformManagedProfile, parseShutdownDeadlineMs } from "@parall/agent-core";
3
+ import { ParallAgentGateway, createPlatformConfigManager, createLogger, isPlatformManagedProfile, parseShutdownDeadlineMs } from "@parall/agent-core";
4
4
  import { ApiError, ParallClient, ParallWs } from "@parall/sdk";
5
5
  import { buildClaudeRuntimeKey, contextFilePathForSession, resolveClaudeAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from "./config.js";
6
6
  import { ClaudeCodeAdapter } from "./dispatch.js";
7
7
  import { ClaudeSessionManager } from "./session-manager.js";
8
8
  import { ensureClaudeWorkspace } from "./workspace.js";
9
- function createLogger(prefix) {
10
- return {
11
- info: (msg) => console.log(`[${prefix}] ${msg}`),
12
- warn: (msg) => console.warn(`[${prefix}] ${msg}`),
13
- error: (msg) => console.error(`[${prefix}] ${msg}`),
14
- };
15
- }
9
+ const log = createLogger("claude-agent");
16
10
  async function getAgentMeWithLegacyFallback(client, orgId) {
17
11
  try {
18
12
  return await client.getAgentMe(orgId);
@@ -27,7 +21,6 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
27
21
  }
28
22
  async function main() {
29
23
  const config = resolveClaudeAgentConfig(process.env);
30
- const log = createLogger("claude-agent");
31
24
  if (config.allowApiKey &&
32
25
  (process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN)) {
33
26
  // Surface the billing path: default is OAuth (Claude.ai subscription); this
@@ -154,6 +147,6 @@ async function main() {
154
147
  }
155
148
  }
156
149
  main().catch((err) => {
157
- console.error(`[claude-agent] fatal: ${String(err)}`);
150
+ log.error(`fatal: ${String(err)}`);
158
151
  process.exitCode = 1;
159
152
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/claude-agent",
3
- "version": "1.28.1",
3
+ "version": "1.29.1",
4
4
  "description": "Claude Code bridge runtime for self-hosted Parall agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -25,9 +25,9 @@
25
25
  "src"
26
26
  ],
27
27
  "dependencies": {
28
- "@parall/agent-core": "1.28.1",
29
- "@parall/sdk": "1.28.1",
30
- "@parall/cli": "1.28.1"
28
+ "@parall/agent-core": "1.29.1",
29
+ "@parall/cli": "1.29.1",
30
+ "@parall/sdk": "1.29.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.0.0",
package/src/dispatch.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
- import { spawn } from "node:child_process";
4
+ import { execSync, spawn } from "node:child_process";
5
5
  import {
6
6
  appendPreparedLocalAttachmentRefs,
7
7
  pinLocalAttachmentPaths,
@@ -43,6 +43,20 @@ type ClaudeCodeAdapterOptions = Pick<
43
43
  stepIdFilePathForSession?: (sessionKey: string) => string;
44
44
  };
45
45
 
46
+ const IS_WIN32 = process.platform === "win32";
47
+
48
+ function quoteWin32Arg(arg: string): string {
49
+ if (!/[\s"&|^<>()]/.test(arg)) return arg;
50
+ return `"${arg.replace(/"/g, '""')}"`;
51
+ }
52
+
53
+ function killWin32Tree(pid: number): boolean {
54
+ try {
55
+ execSync(`taskkill /T /F /PID ${pid}`, { windowsHide: true, stdio: "ignore" });
56
+ return true;
57
+ } catch { return false; }
58
+ }
59
+
46
60
  export function buildSpawnEnv(
47
61
  parentEnv: NodeJS.ProcessEnv,
48
62
  claudeHome: string,
@@ -317,9 +331,12 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
317
331
  if (next.done) {
318
332
  state.done = true;
319
333
  this.processes.delete(sessionKey);
334
+ const detail = state.handle.stderrChunks.join("").trim();
335
+ const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null } as const));
336
+ if (detail) {
337
+ log?.warn?.(`claude-agent: subprocess stderr: ${detail}`);
338
+ }
320
339
  if (!sawError) {
321
- const detail = state.handle.stderrChunks.join("").trim();
322
- const exit = await state.handle.exitPromise.catch(() => ({ code: null, signal: null } as const));
323
340
  yield {
324
341
  type: "error",
325
342
  message: detail
@@ -406,10 +423,13 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
406
423
  `claude-agent: spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`,
407
424
  );
408
425
 
409
- const proc = spawn(this.opts.claudeBin, args, {
426
+ const proc = spawn(
427
+ IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin,
428
+ IS_WIN32 ? args.map(quoteWin32Arg) : args, {
410
429
  cwd: this.opts.workspaceDir,
411
430
  env,
412
431
  stdio: ["pipe", "pipe", "pipe"],
432
+ shell: IS_WIN32,
413
433
  });
414
434
 
415
435
  if (!proc.stdout || !proc.stderr || !proc.stdin) {
@@ -421,13 +441,11 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
421
441
  stderrChunks.push(chunk.toString());
422
442
  });
423
443
  proc.stdin.on("error", () => {
424
- // stdin pipe broken: kill the process so parser.next() sees EOF
425
- // instead of hanging forever on a process that's alive but can't
426
- // accept input. If the process was already exiting (the common
427
- // EPIPE-on-close race), kill is a harmless no-op.
428
444
  proc.stdin.destroy();
429
445
  if (proc.exitCode === null && proc.signalCode === null) {
430
- proc.kill("SIGTERM");
446
+ if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
447
+ proc.kill("SIGTERM");
448
+ }
431
449
  }
432
450
  });
433
451
 
@@ -450,7 +468,9 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
450
468
  } catch { /* best-effort */ }
451
469
  if (state.handle.proc.exitCode === null && state.handle.proc.signalCode === null) {
452
470
  try {
453
- state.handle.proc.kill("SIGTERM");
471
+ if (!IS_WIN32 || !state.handle.proc.pid || !killWin32Tree(state.handle.proc.pid)) {
472
+ state.handle.proc.kill("SIGTERM");
473
+ }
454
474
  } catch { /* best-effort */ }
455
475
  }
456
476
  }
@@ -468,7 +488,6 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
468
488
 
469
489
  private buildArgs(sessionKey: string): string[] {
470
490
  const args = [
471
- "-p",
472
491
  "--verbose",
473
492
  "--input-format",
474
493
  "stream-json",
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import * as os from "node:os";
4
- import { ParallAgentGateway, createPlatformConfigManager, isPlatformManagedProfile, parseShutdownDeadlineMs } from "@parall/agent-core";
4
+ import { ParallAgentGateway, createPlatformConfigManager, createLogger, isPlatformManagedProfile, parseShutdownDeadlineMs } from "@parall/agent-core";
5
5
  import { ApiError, ParallClient, ParallWs } from "@parall/sdk";
6
6
  import {
7
7
  buildClaudeRuntimeKey,
@@ -15,13 +15,7 @@ import { ClaudeCodeAdapter } from "./dispatch.js";
15
15
  import { ClaudeSessionManager } from "./session-manager.js";
16
16
  import { ensureClaudeWorkspace } from "./workspace.js";
17
17
 
18
- function createLogger(prefix: string) {
19
- return {
20
- info: (msg: string) => console.log(`[${prefix}] ${msg}`),
21
- warn: (msg: string) => console.warn(`[${prefix}] ${msg}`),
22
- error: (msg: string) => console.error(`[${prefix}] ${msg}`),
23
- };
24
- }
18
+ const log = createLogger("claude-agent");
25
19
 
26
20
  async function getAgentMeWithLegacyFallback(client: ParallClient, orgId: string) {
27
21
  try {
@@ -37,7 +31,6 @@ async function getAgentMeWithLegacyFallback(client: ParallClient, orgId: string)
37
31
 
38
32
  async function main() {
39
33
  const config = resolveClaudeAgentConfig(process.env);
40
- const log = createLogger("claude-agent");
41
34
 
42
35
  if (
43
36
  config.allowApiKey &&
@@ -179,6 +172,6 @@ async function main() {
179
172
  }
180
173
 
181
174
  main().catch((err) => {
182
- console.error(`[claude-agent] fatal: ${String(err)}`);
175
+ log.error(`fatal: ${String(err)}`);
183
176
  process.exitCode = 1;
184
177
  });