@parall/daemon 1.42.1 → 1.43.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,6 +1,6 @@
1
1
  {
2
- "version": "1.42.1",
3
- "built_at": "2026-07-11T03:40:29.108Z",
2
+ "version": "1.43.0",
3
+ "built_at": "2026-07-13T04:04:48.217Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,25 +16,29 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-browser-pod.js": {
19
- "sha256": "4e98a70b593c352f4fa99cd2ff8b350346437942bd1134e3d500211585c5a94a",
20
- "size": 1699246
19
+ "sha256": "464b249ca4be9ed4ebc520220f11b94fe78c4ceedda8cbfd3dee7c7e02ae4c38",
20
+ "size": 1699655
21
+ },
22
+ "parall-channel-exec.js": {
23
+ "sha256": "32c438151df40ccda7491c57bfa0cd9d6c4d762755353c6c751d5793af57b971",
24
+ "size": 7097
21
25
  },
22
26
  "parall-claude-agent.js": {
23
- "sha256": "8d7d9a8c8b6d1d90f7e84489fd05c059c5c5d24d321274ff3916f12454df2e19",
24
- "size": 1626635
27
+ "sha256": "084f01f1e64aa582dde65ee1eaf3d85a99b7960451a55b1157cb2ad61816d7bd",
28
+ "size": 1639412
25
29
  },
26
30
  "parall-codex-agent.js": {
27
- "sha256": "5ab229def8061ab05bc040571d5cb175bb7c9d8fce565682ab04c6b1a81b8649",
28
- "size": 1664012
31
+ "sha256": "4fa941ad4643333e97feb88dd728ec0badebc5cba21206dbe22d08a40cd76cf6",
32
+ "size": 1676742
29
33
  },
30
34
  "parall-daemon.js": {
31
- "sha256": "354bdc719c5bde1e7f4eaae19f1d895fced7b1a6feee8590d727812b6e5fe2f4",
32
- "size": 1719706
35
+ "sha256": "82f1047c975cb47e31063863a752163a756b857c962d63a7df9acbcdfe0c450d",
36
+ "size": 1726872
33
37
  },
34
38
  "parall-openclaw-agent.js": {
35
39
  "sha256": "505433b4bf3a4b8dbb7b96978d8693d6c48079f4513282ff1ee59a6d13b3eddf",
36
40
  "size": 9801
37
41
  }
38
42
  },
39
- "signature": "T/TtjoBJx65Xb8MftcuGyi+F0J8kpPBmzKIl8hMLP+igdhlAzKTLEHvDN4gB72BOd7lUHOFLwufiyyUye/TbCg=="
43
+ "signature": "YRCOk2+FiAfFASvIWGt7sDPkt+iZE1yfUfVnu793pKZhbSmjKedFXwq6WdUM+lpM6WqL09/JPSf9d3gmDNc9AA=="
40
44
  }
@@ -35076,16 +35076,6 @@ function clearAllProviderCreds(env) {
35076
35076
  delete env.PRLL_CLAUDE_ALLOW_API_KEY;
35077
35077
  }
35078
35078
 
35079
- // ts/agent-core/dist/logger.js
35080
- function createLogger(prefix) {
35081
- return {
35082
- info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
35083
- warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
35084
- error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
35085
- child: (sub) => createLogger(`${prefix}:${sub}`)
35086
- };
35087
- }
35088
-
35089
35079
  // ts/sdk/dist/constants.js
35090
35080
  var API_BASE = "/api/v1";
35091
35081
  var WIKI_BASE = "/wiki/v1";
@@ -35443,6 +35433,7 @@ var ParallClient = class _ParallClient {
35443
35433
  setTokens;
35444
35434
  refreshPromise = null;
35445
35435
  swimlaneName;
35436
+ getFeatureFlagOverrides;
35446
35437
  /** Auth endpoints excluded from automatic 401 refresh to prevent recursion. */
35447
35438
  static AUTH_PATHS = /* @__PURE__ */ new Set([
35448
35439
  "/auth/login",
@@ -35473,7 +35464,7 @@ var ParallClient = class _ParallClient {
35473
35464
  return apiError;
35474
35465
  }
35475
35466
  /** Build headers common to all requests (auth, swimlane). */
35476
- buildHeaders(extra) {
35467
+ buildHeaders(path6, extra) {
35477
35468
  const headers = {
35478
35469
  "Content-Type": "application/json",
35479
35470
  ...extra
@@ -35484,6 +35475,11 @@ var ParallClient = class _ParallClient {
35484
35475
  if (this.swimlaneName) {
35485
35476
  headers["X-Prll-Swimlane"] = this.swimlaneName;
35486
35477
  }
35478
+ if (path6.startsWith(API_BASE)) {
35479
+ const overrides = this.getFeatureFlagOverrides?.();
35480
+ if (overrides)
35481
+ headers["X-Prll-FF-Override"] = overrides;
35482
+ }
35487
35483
  return headers;
35488
35484
  }
35489
35485
  constructor(options = {}) {
@@ -35494,6 +35490,7 @@ var ParallClient = class _ParallClient {
35494
35490
  this.getRefreshToken = options.getRefreshToken;
35495
35491
  this.setTokens = options.setTokens;
35496
35492
  this.swimlaneName = options.swimlaneName;
35493
+ this.getFeatureFlagOverrides = options.getFeatureFlagOverrides;
35497
35494
  }
35498
35495
  /**
35499
35496
  * Pick the origin for a request path: wiki-service base for `/wiki/v1`
@@ -35580,7 +35577,7 @@ var ParallClient = class _ParallClient {
35580
35577
  if (qs)
35581
35578
  url += `?${qs}`;
35582
35579
  }
35583
- const headers = this.buildHeaders();
35580
+ const headers = this.buildHeaders(path6);
35584
35581
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
35585
35582
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
35586
35583
  let res;
@@ -35637,7 +35634,7 @@ var ParallClient = class _ParallClient {
35637
35634
  if (!retried) {
35638
35635
  await this.ensureFreshToken(path6);
35639
35636
  }
35640
- const { "Content-Type": _drop, ...headers } = this.buildHeaders();
35637
+ const { "Content-Type": _drop, ...headers } = this.buildHeaders(path6);
35641
35638
  void _drop;
35642
35639
  let res;
35643
35640
  try {
@@ -36482,7 +36479,7 @@ var ParallClient = class _ParallClient {
36482
36479
  if (currentVersion !== void 0) {
36483
36480
  extra["If-None-Match"] = currentVersion;
36484
36481
  }
36485
- const headers = this.buildHeaders(extra);
36482
+ const headers = this.buildHeaders(ENDPOINTS.PLATFORM_CONFIG, extra);
36486
36483
  let res;
36487
36484
  try {
36488
36485
  res = await fetch(url, {
@@ -37266,6 +37263,19 @@ function buildApiError(res, rawErrorBody) {
37266
37263
  return apiError;
37267
37264
  }
37268
37265
 
37266
+ // ts/agent-core/dist/gateway-lane-flow.js
37267
+ var TYPED_BACKOFF_CAP_MS = 5 * 6e4;
37268
+
37269
+ // ts/agent-core/dist/logger.js
37270
+ function createLogger(prefix) {
37271
+ return {
37272
+ info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
37273
+ warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
37274
+ error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
37275
+ child: (sub) => createLogger(`${prefix}:${sub}`)
37276
+ };
37277
+ }
37278
+
37269
37279
  // ts/agent-core/dist/telemetry.js
37270
37280
  import { AsyncLocalStorage } from "node:async_hooks";
37271
37281
  var sessionKeyStorage = new AsyncLocalStorage();
@@ -40441,7 +40451,7 @@ var ClipProcessManager = class {
40441
40451
  * (GetBindings), then forward the invoke through the hub (Invoke) to the bound
40442
40452
  * BrowserProfile's host. No local shortcut, no fallback — unbound is rejected.
40443
40453
  * The execution daemon never verifies clip_token; the hub does.
40444
- * See docs/engineering-design/browser-profile-clip-integration.md §11.3.
40454
+ * See docs/archive/engineering-design/browser-profile-clip-integration.md §11.3.
40445
40455
  */
40446
40456
  async invokeDependency(clipName, command, input, context) {
40447
40457
  if (!isBrowserDependencyName(clipName)) {
@@ -40474,7 +40484,7 @@ var ClipProcessManager = class {
40474
40484
  * synthetic "browser" clip). The hub forwards clip_token as the PLAINTEXT
40475
40485
  * browser_profile_id, which the host daemon uses directly as the bb-browser
40476
40486
  * account. Only daemons that host BrowserProfiles register this capability.
40477
- * See docs/engineering-design/browser-profile-clip-integration.md §11.2.
40487
+ * See docs/archive/engineering-design/browser-profile-clip-integration.md §11.2.
40478
40488
  */
40479
40489
  async invokeBrowserCapability(clipToken, command, input) {
40480
40490
  if (!this.browserProfileManager) {
@@ -0,0 +1,224 @@
1
+ // ts/agent-core/dist/bin/channel-exec.js
2
+ import { spawnSync } from "node:child_process";
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ import { pathToFileURL } from "node:url";
6
+
7
+ // ts/agent-core/dist/channel-capability.js
8
+ var CHANNEL_POINTER_MAGIC = "parall channel capability pointer";
9
+
10
+ // ts/agent-core/dist/channel-token.js
11
+ var ChannelTokenError = class extends Error {
12
+ };
13
+ var MINT_TIMEOUT_MS = 1e4;
14
+ async function mintChannelToken(channelType, env) {
15
+ const apiUrl = (env.PRLL_API_URL || "").replace(/\/+$/, "");
16
+ const apiKey = env.PRLL_API_KEY || "";
17
+ const orgId = env.PRLL_ORG_ID || "";
18
+ if (!apiUrl || !apiKey || !orgId) {
19
+ throw new ChannelTokenError("PRLL_API_URL/PRLL_API_KEY/PRLL_ORG_ID missing from the environment");
20
+ }
21
+ const headers = {
22
+ "Content-Type": "application/json",
23
+ Authorization: `Bearer ${apiKey}`
24
+ };
25
+ const swimlane = (env.PRLL_SWIMLANE_NAME || "").trim();
26
+ if (swimlane)
27
+ headers["X-Prll-Swimlane"] = swimlane;
28
+ const controller = new AbortController();
29
+ const timer = setTimeout(() => controller.abort(), MINT_TIMEOUT_MS);
30
+ let resp;
31
+ try {
32
+ resp = await fetch(`${apiUrl}/api/v1/orgs/${encodeURIComponent(orgId)}/agents/me/channel-token`, {
33
+ method: "POST",
34
+ headers,
35
+ body: JSON.stringify({ channel_type: channelType }),
36
+ signal: controller.signal
37
+ });
38
+ } catch (err) {
39
+ throw new ChannelTokenError(`could not reach the Parall platform to authenticate (${String(err)}); channel actions are unavailable right now`);
40
+ } finally {
41
+ clearTimeout(timer);
42
+ }
43
+ if (!resp.ok) {
44
+ let msg = `platform returned HTTP ${resp.status}`;
45
+ try {
46
+ const body = await resp.json();
47
+ if (body?.error?.message)
48
+ msg = body.error.message;
49
+ } catch {
50
+ }
51
+ throw new ChannelTokenError(msg);
52
+ }
53
+ const minted = await resp.json();
54
+ const nonEmpty = (v) => typeof v === "string" && v.length > 0;
55
+ if (!minted || !nonEmpty(minted.token) || !nonEmpty(minted.app_id) || !nonEmpty(minted.brand)) {
56
+ throw new ChannelTokenError("platform returned an unusable token payload");
57
+ }
58
+ return minted;
59
+ }
60
+
61
+ // ts/agent-core/dist/bin/channel-exec.js
62
+ var CHANNEL_BIN = { feishu: "lark-cli" };
63
+ function fail(prefix, msg, code) {
64
+ try {
65
+ fs.writeSync(2, `${prefix}: ${msg}
66
+ `);
67
+ } catch {
68
+ }
69
+ process.exit(code);
70
+ }
71
+ function parseArgs(argv) {
72
+ const out = { channel: "", skipDir: "", rest: [] };
73
+ for (let i = 0; i < argv.length; i++) {
74
+ const a = argv[i];
75
+ if (a === "--") {
76
+ out.rest = argv.slice(i + 1);
77
+ break;
78
+ }
79
+ if (a === "--channel")
80
+ out.channel = argv[++i] ?? "";
81
+ else if (a === "--skip-dir")
82
+ out.skipDir = argv[++i] ?? "";
83
+ else
84
+ fail("channel-exec", `unknown argument ${a}`, 2);
85
+ }
86
+ if (!out.channel) {
87
+ fail("channel-exec", "usage: channel-exec --channel <type> [--skip-dir <dir>] -- <args\u2026>", 2);
88
+ }
89
+ return out;
90
+ }
91
+ function isCapabilityPointer(candidate) {
92
+ try {
93
+ const fd = fs.openSync(candidate, "r");
94
+ try {
95
+ const buf = Buffer.alloc(256);
96
+ const n = fs.readSync(fd, buf, 0, buf.length, 0);
97
+ return buf.toString("utf8", 0, n).includes(CHANNEL_POINTER_MAGIC);
98
+ } finally {
99
+ fs.closeSync(fd);
100
+ }
101
+ } catch {
102
+ return false;
103
+ }
104
+ }
105
+ function resolveRealBin(bin, skipDir) {
106
+ const isWin = process.platform === "win32";
107
+ const exts = isWin ? [".cmd", ".exe", ".bat"] : [""];
108
+ let skipReal = null;
109
+ if (skipDir) {
110
+ try {
111
+ skipReal = fs.realpathSync(skipDir);
112
+ } catch {
113
+ skipReal = null;
114
+ }
115
+ }
116
+ for (const dir of (process.env.PATH || "").split(path.delimiter)) {
117
+ if (!dir)
118
+ continue;
119
+ let real;
120
+ try {
121
+ real = fs.realpathSync(dir);
122
+ } catch {
123
+ continue;
124
+ }
125
+ if (skipReal && real === skipReal)
126
+ continue;
127
+ for (const ext of exts) {
128
+ const candidate = path.join(dir, bin + ext);
129
+ try {
130
+ if (fs.statSync(candidate).isFile() && !isCapabilityPointer(candidate))
131
+ return candidate;
132
+ } catch {
133
+ }
134
+ }
135
+ }
136
+ return null;
137
+ }
138
+ var FEISHU_OWNED_ENV = [
139
+ // injected (canonical values set below)
140
+ "LARKSUITE_CLI_APP_ID",
141
+ "LARKSUITE_CLI_BRAND",
142
+ "LARKSUITE_CLI_TENANT_ACCESS_TOKEN",
143
+ "LARKSUITE_CLI_DEFAULT_AS",
144
+ "LARKSUITE_CLI_STRICT_MODE",
145
+ // ambient auth bypass inputs that must not reach the child
146
+ "LARKSUITE_CLI_APP_SECRET",
147
+ "LARKSUITE_CLI_USER_ACCESS_TOKEN",
148
+ "LARKSUITE_CLI_AUTH_PROXY",
149
+ "LARKSUITE_CLI_PROXY_KEY"
150
+ ];
151
+ function buildChildEnv(channel, minted) {
152
+ const env = { ...process.env };
153
+ if (channel === "feishu") {
154
+ const owned = new Set(FEISHU_OWNED_ENV);
155
+ for (const key of Object.keys(env)) {
156
+ if (owned.has(key.toUpperCase()))
157
+ delete env[key];
158
+ }
159
+ env.LARKSUITE_CLI_APP_ID = minted.app_id;
160
+ env.LARKSUITE_CLI_BRAND = minted.brand || "feishu";
161
+ env.LARKSUITE_CLI_TENANT_ACCESS_TOKEN = minted.token;
162
+ env.LARKSUITE_CLI_DEFAULT_AS = "bot";
163
+ env.LARKSUITE_CLI_STRICT_MODE = "bot";
164
+ return env;
165
+ }
166
+ fail("channel-exec", `unsupported channel type "${channel}"`, 2);
167
+ }
168
+ var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
169
+ function escapeCmdArgument(arg) {
170
+ let out = `${arg}`;
171
+ out = out.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1");
172
+ out = `"${out}"`;
173
+ out = out.replace(CMD_META_CHARS, "^$1").replace(CMD_META_CHARS, "^$1");
174
+ return out;
175
+ }
176
+ function escapeCmdCommand(command) {
177
+ return command.replace(CMD_META_CHARS, "^$1");
178
+ }
179
+ function runReal(realBin, args, env, prefix) {
180
+ const isWinScript = process.platform === "win32" && /\.(cmd|bat)$/i.test(realBin);
181
+ const result = isWinScript ? spawnSync(process.env.comspec || "cmd.exe", [
182
+ "/d",
183
+ "/s",
184
+ "/c",
185
+ `"${[escapeCmdCommand(realBin), ...args.map(escapeCmdArgument)].join(" ")}"`
186
+ ], { stdio: "inherit", env, windowsVerbatimArguments: true }) : spawnSync(realBin, args, { stdio: "inherit", env });
187
+ if (result.error) {
188
+ fail(prefix, `failed to run ${realBin}: ${String(result.error)}`, 1);
189
+ }
190
+ if (result.signal) {
191
+ process.kill(process.pid, result.signal);
192
+ process.exit(1);
193
+ }
194
+ process.exit(result.status === null ? 1 : result.status);
195
+ }
196
+ async function main() {
197
+ const { channel, skipDir, rest } = parseArgs(process.argv.slice(2));
198
+ const bin = CHANNEL_BIN[channel];
199
+ if (!bin)
200
+ fail("channel-exec", `unsupported channel type "${channel}"`, 2);
201
+ const prefix = bin;
202
+ let minted;
203
+ try {
204
+ minted = await mintChannelToken(channel, process.env);
205
+ } catch (err) {
206
+ if (err instanceof ChannelTokenError)
207
+ fail(prefix, err.message, 1);
208
+ fail(prefix, String(err), 1);
209
+ }
210
+ const real = resolveRealBin(bin, skipDir);
211
+ if (!real) {
212
+ const hint = channel === "feishu" ? "Install it once with:\n npm i -g @larksuite/cli && npx skills add larksuite/cli -y -g" : "Install it and retry.";
213
+ fail(prefix, `the ${bin} binary is not installed. ${hint}`, 127);
214
+ }
215
+ runReal(real, rest, buildChildEnv(channel, minted), prefix);
216
+ }
217
+ var invokedPath = process.argv[1];
218
+ if (invokedPath && import.meta.url === pathToFileURL(invokedPath).href) {
219
+ void main();
220
+ }
221
+ export {
222
+ escapeCmdArgument,
223
+ escapeCmdCommand
224
+ };