@parall/claude-agent 1.37.0 → 1.38.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.
package/dist/config.d.ts CHANGED
@@ -22,6 +22,13 @@ export declare function resolveWsUrl(apiUrl: string, explicitWsUrl?: string, swi
22
22
  export declare function buildClaudeRuntimeKey(agentUserId: string): string;
23
23
  export declare function sessionStateFilePathForRuntime(stateDir: string, runtimeKey: string): string;
24
24
  export declare function contextFilePathForSession(stateDir: string, sessionKey: string): string;
25
+ /**
26
+ * PRLL_CONTEXT_DIR root: per-lane dispatch context files, keyed by the
27
+ * canonical lane-key (see @parall/agent-core lane-key.ts). Anchored in the
28
+ * per-agent stateDir — never the workspace (workspace paths are
29
+ * user-overridable and not an isolation boundary).
30
+ */
31
+ export declare function dispatchContextDirPath(stateDir: string): string;
25
32
  /** @deprecated Use contextFilePathForSession. */
26
33
  export declare function stepIdFilePathForSession(stateDir: string, sessionKey: string): string;
27
34
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAsBF,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CAgChG;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAMR;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED,iDAAiD;AACjD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAsBF,wBAAgB,wBAAwB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,iBAAiB,CAgChG;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAMR;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAG3F;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,iDAAiD;AACjD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrF"}
package/dist/config.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { dispatchLaneContextDir } from '@parall/agent-core';
1
2
  import * as os from 'node:os';
2
3
  import * as path from 'node:path';
3
4
  function requireEnv(env, name) {
@@ -65,6 +66,15 @@ export function contextFilePathForSession(stateDir, sessionKey) {
65
66
  const fileName = Buffer.from(sessionKey).toString('base64url');
66
67
  return path.join(stateDir, 'dispatch-context', `${fileName}.json`);
67
68
  }
69
+ /**
70
+ * PRLL_CONTEXT_DIR root: per-lane dispatch context files, keyed by the
71
+ * canonical lane-key (see @parall/agent-core lane-key.ts). Anchored in the
72
+ * per-agent stateDir — never the workspace (workspace paths are
73
+ * user-overridable and not an isolation boundary).
74
+ */
75
+ export function dispatchContextDirPath(stateDir) {
76
+ return dispatchLaneContextDir(stateDir);
77
+ }
68
78
  /** @deprecated Use contextFilePathForSession. */
69
79
  export function stepIdFilePathForSession(stateDir, sessionKey) {
70
80
  const fileName = Buffer.from(sessionKey).toString('base64url');
@@ -9,6 +9,15 @@ type ClaudeCodeAdapterOptions = Pick<ClaudeAgentConfig, 'additionalDirs' | 'allo
9
9
  contextFilePathForSession?: (sessionKey: string) => string;
10
10
  /** @deprecated Use contextFilePathForSession. */
11
11
  stepIdFilePathForSession?: (sessionKey: string) => string;
12
+ /**
13
+ * PRLL_CONTEXT_DIR root for per-lane dispatch context files. Like the
14
+ * Parall credentials above, this is bridge-static — the long-lived
15
+ * subprocess env is built ONCE from the placeholder context, so a value
16
+ * only present on per-dispatch DispatchContexts would never reach the
17
+ * CLI and every reply would silently lose its lane binding (turns would
18
+ * resolve no_action instead of reply-effect dedupe).
19
+ */
20
+ contextDirPath?: string;
12
21
  };
13
22
  export declare function buildSpawnEnv(parentEnv: NodeJS.ProcessEnv, claudeHome: string, context: DispatchOpts['context'], opts: {
14
23
  allowApiKey: boolean;
@@ -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,EAAE,oBAAoB,EAA4B,MAAM,sBAAsB,CAAC;AAEtF,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;AAkBF,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,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3E,MAAM,CAAC,UAAU,CA8BnB;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,CAErC;IACD,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;IAED,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,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAYvC,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1C,QAAQ,CAAC,EACd,KAAK,EACL,YAAY,EACZ,UAAU,EACV,OAAO,GACR,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;IA+B7C,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAc7D,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,QAAQ;IAIpC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe;IAQrC,cAAc,IAAI,IAAI;IAQhB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4D;IAE/F;;;;;;;;;OASG;YACY,gBAAgB;YAqEhB,OAAO;IAkHtB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,YAAY;IAuDpB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,SAAS;IAwCjB,OAAO,CAAC,uBAAuB;CAkBhC"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
package/dist/dispatch.js CHANGED
@@ -37,6 +37,10 @@ export function buildSpawnEnv(parentEnv, claudeHome, context, opts) {
37
37
  PRLL_NO_REPLY: context.noReply ? '1' : '',
38
38
  PRLL_CONTEXT_FILE: context.contextFilePath ?? '',
39
39
  PRLL_STEP_ID_FILE: context.stepIdFilePath ?? '',
40
+ // Per-lane dispatch context directory (stable for the bridge's lifetime,
41
+ // so pinning it at spawn is safe even for long-lived subprocesses). The
42
+ // CLI keys into it by send target to derive dispatch effect keys.
43
+ PRLL_CONTEXT_DIR: context.contextDirPath ?? '',
40
44
  };
41
45
  // Pin the wiki workspace to the agent workspace (same convention as the
42
46
  // OpenClaw runtime). Without this, `parall wiki` resolves mounts relative
@@ -491,6 +495,7 @@ export class ClaudeCodeAdapter {
491
495
  noReply: false,
492
496
  contextFilePath: this.opts.contextFilePathForSession?.(sessionKey) ?? '',
493
497
  stepIdFilePath: this.opts.stepIdFilePathForSession?.(sessionKey) ?? '',
498
+ contextDirPath: this.opts.contextDirPath ?? '',
494
499
  client: undefined,
495
500
  };
496
501
  }
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import * as os from 'node:os';
3
3
  import { ParallAgentGateway, createPlatformConfigManager, createLogger, createOtelLogger, childLogger, deriveModelIsPin, resolveRuntimeModel, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, parseProviderConfig, clearAllProviderCreds, llmSource, initAgentTelemetry, } from '@parall/agent-core';
4
4
  import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
5
- import { buildClaudeRuntimeKey, contextFilePathForSession, resolveClaudeAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from './config.js';
5
+ import { buildClaudeRuntimeKey, contextFilePathForSession, dispatchContextDirPath, 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';
@@ -114,6 +114,7 @@ async function main() {
114
114
  orgId: config.orgId,
115
115
  contextFilePathForSession: (sessionKey) => contextFilePathForSession(config.stateDir, sessionKey),
116
116
  stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
117
+ contextDirPath: dispatchContextDirPath(config.stateDir),
117
118
  });
118
119
  if (resolvedEffort) {
119
120
  adapter.updateConfig({ effort: resolvedEffort });
@@ -170,6 +171,7 @@ async function main() {
170
171
  dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
171
172
  contextFilePathForSession: (sessionKey) => contextFilePathForSession(config.stateDir, sessionKey),
172
173
  stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
174
+ dispatchContextDir: dispatchContextDirPath(config.stateDir),
173
175
  onConfigUpdate: refreshPlatformConfig,
174
176
  onSessionReady: refreshPlatformConfig,
175
177
  // Long-lived `claude` subprocesses outlive a single dispatch, so the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/claude-agent",
3
- "version": "1.37.0",
3
+ "version": "1.38.0",
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.37.0",
29
- "@parall/sdk": "1.37.0",
30
- "@parall/cli": "1.37.0"
28
+ "@parall/agent-core": "1.38.0",
29
+ "@parall/cli": "1.38.0",
30
+ "@parall/sdk": "1.38.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.0.0",
package/src/config.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { dispatchLaneContextDir } from '@parall/agent-core';
1
2
  import * as os from 'node:os';
2
3
  import * as path from 'node:path';
3
4
 
@@ -101,6 +102,16 @@ export function contextFilePathForSession(stateDir: string, sessionKey: string):
101
102
  return path.join(stateDir, 'dispatch-context', `${fileName}.json`);
102
103
  }
103
104
 
105
+ /**
106
+ * PRLL_CONTEXT_DIR root: per-lane dispatch context files, keyed by the
107
+ * canonical lane-key (see @parall/agent-core lane-key.ts). Anchored in the
108
+ * per-agent stateDir — never the workspace (workspace paths are
109
+ * user-overridable and not an isolation boundary).
110
+ */
111
+ export function dispatchContextDirPath(stateDir: string): string {
112
+ return dispatchLaneContextDir(stateDir);
113
+ }
114
+
104
115
  /** @deprecated Use contextFilePathForSession. */
105
116
  export function stepIdFilePathForSession(stateDir: string, sessionKey: string): string {
106
117
  const fileName = Buffer.from(sessionKey).toString('base64url');
package/src/dispatch.ts CHANGED
@@ -38,6 +38,15 @@ type ClaudeCodeAdapterOptions = Pick<
38
38
  contextFilePathForSession?: (sessionKey: string) => string;
39
39
  /** @deprecated Use contextFilePathForSession. */
40
40
  stepIdFilePathForSession?: (sessionKey: string) => string;
41
+ /**
42
+ * PRLL_CONTEXT_DIR root for per-lane dispatch context files. Like the
43
+ * Parall credentials above, this is bridge-static — the long-lived
44
+ * subprocess env is built ONCE from the placeholder context, so a value
45
+ * only present on per-dispatch DispatchContexts would never reach the
46
+ * CLI and every reply would silently lose its lane binding (turns would
47
+ * resolve no_action instead of reply-effect dedupe).
48
+ */
49
+ contextDirPath?: string;
41
50
  };
42
51
 
43
52
  const IS_WIN32 = process.platform === 'win32';
@@ -79,6 +88,10 @@ export function buildSpawnEnv(
79
88
  PRLL_NO_REPLY: context.noReply ? '1' : '',
80
89
  PRLL_CONTEXT_FILE: context.contextFilePath ?? '',
81
90
  PRLL_STEP_ID_FILE: context.stepIdFilePath ?? '',
91
+ // Per-lane dispatch context directory (stable for the bridge's lifetime,
92
+ // so pinning it at spawn is safe even for long-lived subprocesses). The
93
+ // CLI keys into it by send target to derive dispatch effect keys.
94
+ PRLL_CONTEXT_DIR: context.contextDirPath ?? '',
82
95
  };
83
96
  // Pin the wiki workspace to the agent workspace (same convention as the
84
97
  // OpenClaw runtime). Without this, `parall wiki` resolves mounts relative
@@ -613,6 +626,7 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
613
626
  noReply: false,
614
627
  contextFilePath: this.opts.contextFilePathForSession?.(sessionKey) ?? '',
615
628
  stepIdFilePath: this.opts.stepIdFilePathForSession?.(sessionKey) ?? '',
629
+ contextDirPath: this.opts.contextDirPath ?? '',
616
630
  client: undefined as unknown as DispatchOpts['context']['client'],
617
631
  };
618
632
  }
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
21
21
  import {
22
22
  buildClaudeRuntimeKey,
23
23
  contextFilePathForSession,
24
+ dispatchContextDirPath,
24
25
  resolveClaudeAgentConfig,
25
26
  resolveWsUrl,
26
27
  sessionStateFilePathForRuntime,
@@ -154,6 +155,7 @@ async function main() {
154
155
  contextFilePathForSession(config.stateDir, sessionKey),
155
156
  stepIdFilePathForSession: (sessionKey) =>
156
157
  stepIdFilePathForSession(config.stateDir, sessionKey),
158
+ contextDirPath: dispatchContextDirPath(config.stateDir),
157
159
  });
158
160
  if (resolvedEffort) {
159
161
  adapter.updateConfig({ effort: resolvedEffort });
@@ -217,6 +219,7 @@ async function main() {
217
219
  contextFilePathForSession(config.stateDir, sessionKey),
218
220
  stepIdFilePathForSession: (sessionKey) =>
219
221
  stepIdFilePathForSession(config.stateDir, sessionKey),
222
+ dispatchContextDir: dispatchContextDirPath(config.stateDir),
220
223
  onConfigUpdate: refreshPlatformConfig,
221
224
  onSessionReady: refreshPlatformConfig,
222
225
  // Long-lived `claude` subprocesses outlive a single dispatch, so the