@slock-ai/daemon 0.56.1-play.20260605140553 → 0.57.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,14 +1,5 @@
1
- import {
2
- DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
3
- buildWebSocketOptions,
4
- daemonFetch,
5
- executeJsonRequest,
6
- executeResponseRequest,
7
- logger
8
- } from "./chunk-M2KQBJR3.js";
9
-
10
1
  // src/core.ts
11
- import path17 from "path";
2
+ import path15 from "path";
12
3
  import os7 from "os";
13
4
  import { createRequire as createRequire2 } from "module";
14
5
  import { accessSync } from "fs";
@@ -1274,10 +1265,10 @@ var DISPLAY_PLAN_CONFIG = {
1274
1265
  };
1275
1266
 
1276
1267
  // src/agentProcessManager.ts
1277
- import { mkdirSync as mkdirSync5, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync7 } from "fs";
1268
+ import { mkdirSync as mkdirSync3, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync4 } from "fs";
1278
1269
  import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2 } from "fs/promises";
1279
1270
  import { createHash as createHash3 } from "crypto";
1280
- import path13 from "path";
1271
+ import path11 from "path";
1281
1272
  import os5 from "os";
1282
1273
 
1283
1274
  // src/drivers/claude.ts
@@ -1989,19 +1980,6 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
1989
1980
  return candidates.filter((candidate) => existsSync(candidate.path));
1990
1981
  }
1991
1982
 
1992
- // src/authEnv.ts
1993
- var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
1994
- var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
1995
- function scrubDaemonAuthEnv(env) {
1996
- delete env[DAEMON_API_KEY_ENV];
1997
- return env;
1998
- }
1999
- function scrubDaemonChildEnv(env) {
2000
- delete env[DAEMON_API_KEY_ENV];
2001
- delete env[SLOCK_AGENT_TOKEN_ENV];
2002
- return env;
2003
- }
2004
-
2005
1983
  // src/agentCredentialProxy.ts
2006
1984
  import { randomBytes } from "crypto";
2007
1985
  import http from "http";
@@ -2331,6 +2309,160 @@ function stripUndefined(value) {
2331
2309
  return value;
2332
2310
  }
2333
2311
 
2312
+ // src/proxy.ts
2313
+ import { HttpsProxyAgent } from "https-proxy-agent";
2314
+ import { ProxyAgent } from "undici";
2315
+ var fetchDispatcherCache = /* @__PURE__ */ new Map();
2316
+ function getFetchPreResponseTimeoutMs(env) {
2317
+ const parsed = Number.parseInt(env.SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS || "", 10);
2318
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 3e4;
2319
+ }
2320
+ function getDefaultPort(protocol) {
2321
+ switch (protocol) {
2322
+ case "https:":
2323
+ case "wss:":
2324
+ return "443";
2325
+ case "http:":
2326
+ case "ws:":
2327
+ return "80";
2328
+ default:
2329
+ return "";
2330
+ }
2331
+ }
2332
+ function hostMatchesNoProxyEntry(hostname, ruleHost) {
2333
+ if (!ruleHost) return false;
2334
+ const normalizedRule = ruleHost.replace(/^\*\./, ".").replace(/^\./, "").toLowerCase();
2335
+ const normalizedHost = hostname.toLowerCase();
2336
+ return normalizedHost === normalizedRule || normalizedHost.endsWith(`.${normalizedRule}`);
2337
+ }
2338
+ function getProxyUrlForTarget(targetUrl, env) {
2339
+ const protocol = new URL(targetUrl).protocol;
2340
+ switch (protocol) {
2341
+ case "wss:":
2342
+ return env.WSS_PROXY || env.wss_proxy || env.HTTPS_PROXY || env.https_proxy || env.ALL_PROXY || env.all_proxy;
2343
+ case "ws:":
2344
+ return env.WS_PROXY || env.ws_proxy || env.HTTP_PROXY || env.http_proxy || env.ALL_PROXY || env.all_proxy;
2345
+ case "https:":
2346
+ return env.HTTPS_PROXY || env.https_proxy || env.ALL_PROXY || env.all_proxy;
2347
+ case "http:":
2348
+ return env.HTTP_PROXY || env.http_proxy || env.ALL_PROXY || env.all_proxy;
2349
+ default:
2350
+ return env.ALL_PROXY || env.all_proxy;
2351
+ }
2352
+ }
2353
+ function shouldBypassProxy(targetUrl, env) {
2354
+ const rawNoProxy = env.NO_PROXY || env.no_proxy;
2355
+ if (!rawNoProxy) return false;
2356
+ const url = new URL(targetUrl);
2357
+ const hostname = url.hostname.toLowerCase();
2358
+ const port = url.port || getDefaultPort(url.protocol);
2359
+ return rawNoProxy.split(",").map((entry) => entry.trim()).filter(Boolean).some((entry) => {
2360
+ if (entry === "*") return true;
2361
+ const [ruleHost, rulePort] = entry.split(":", 2);
2362
+ if (rulePort && rulePort !== port) return false;
2363
+ return hostMatchesNoProxyEntry(hostname, ruleHost);
2364
+ });
2365
+ }
2366
+ function buildWebSocketOptions(wsUrl, env) {
2367
+ const proxyUrl = getProxyUrlForTarget(wsUrl, env);
2368
+ if (!proxyUrl) return void 0;
2369
+ if (shouldBypassProxy(wsUrl, env)) return void 0;
2370
+ return {
2371
+ agent: new HttpsProxyAgent(proxyUrl)
2372
+ };
2373
+ }
2374
+ function resolveProxyUrl(targetUrl, env) {
2375
+ const proxyUrl = getProxyUrlForTarget(targetUrl, env);
2376
+ if (!proxyUrl) return void 0;
2377
+ if (shouldBypassProxy(targetUrl, env)) return void 0;
2378
+ return proxyUrl;
2379
+ }
2380
+ function buildFetchDispatcher(targetUrl, env) {
2381
+ const proxyUrl = resolveProxyUrl(targetUrl, env);
2382
+ if (!proxyUrl) return void 0;
2383
+ const cached = fetchDispatcherCache.get(proxyUrl);
2384
+ if (cached) return cached;
2385
+ const timeoutMs = getFetchPreResponseTimeoutMs(env);
2386
+ const dispatcher = new ProxyAgent({
2387
+ uri: proxyUrl,
2388
+ // All three are pre-response and body-agnostic (see getFetchPreResponseTimeoutMs):
2389
+ // headersTimeout = headers-hang leg; requestTls.timeout = CONNECT-tunnel
2390
+ // establish leg; connect.timeout = socket to the proxy itself (defensive).
2391
+ connect: { timeout: timeoutMs },
2392
+ requestTls: { timeout: timeoutMs },
2393
+ headersTimeout: timeoutMs
2394
+ });
2395
+ fetchDispatcherCache.set(proxyUrl, dispatcher);
2396
+ return dispatcher;
2397
+ }
2398
+ function evictFetchDispatcher(targetUrl, env) {
2399
+ const proxyUrl = resolveProxyUrl(targetUrl, env);
2400
+ if (!proxyUrl) return false;
2401
+ const cached = fetchDispatcherCache.get(proxyUrl);
2402
+ if (!cached) return false;
2403
+ fetchDispatcherCache.delete(proxyUrl);
2404
+ void Promise.resolve().then(() => cached.close()).catch(() => cached.destroy?.(new Error("evicted"))).catch(() => {
2405
+ });
2406
+ return true;
2407
+ }
2408
+
2409
+ // src/daemonFetch.ts
2410
+ function withDaemonFetchProxy(input, init = {}, env = process.env) {
2411
+ const dispatcher = buildFetchDispatcher(input.toString(), env);
2412
+ return dispatcher ? { ...init, dispatcher } : init;
2413
+ }
2414
+ async function daemonFetch(input, init, env = process.env) {
2415
+ try {
2416
+ return await fetch(input, withDaemonFetchProxy(input, init, env));
2417
+ } catch (err) {
2418
+ evictFetchDispatcher(input.toString(), env);
2419
+ throw err;
2420
+ }
2421
+ }
2422
+
2423
+ // src/logger.ts
2424
+ var listeners = /* @__PURE__ */ new Set();
2425
+ function timestamp() {
2426
+ const d = /* @__PURE__ */ new Date();
2427
+ const pad = (n) => String(n).padStart(2, "0");
2428
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
2429
+ }
2430
+ function format(level, msg) {
2431
+ return `${timestamp()} [${level}] ${msg}`;
2432
+ }
2433
+ function emit(event) {
2434
+ for (const listener of listeners) {
2435
+ listener(event);
2436
+ }
2437
+ }
2438
+ function subscribeDaemonLogs(listener) {
2439
+ listeners.add(listener);
2440
+ return () => {
2441
+ listeners.delete(listener);
2442
+ };
2443
+ }
2444
+ var logger = {
2445
+ info(msg) {
2446
+ const line = format("INFO", msg);
2447
+ console.log(line);
2448
+ emit({ level: "INFO", line, message: msg });
2449
+ },
2450
+ warn(msg) {
2451
+ const line = format("WARN", msg);
2452
+ console.warn(line);
2453
+ emit({ level: "WARN", line, message: msg });
2454
+ },
2455
+ error(msg, err) {
2456
+ const line = format("ERROR", msg);
2457
+ if (err) {
2458
+ console.error(line, err);
2459
+ } else {
2460
+ console.error(line);
2461
+ }
2462
+ emit({ level: "ERROR", line, message: msg, error: err });
2463
+ }
2464
+ };
2465
+
2334
2466
  // src/agentCredentialProxy.ts
2335
2467
  var registrations = /* @__PURE__ */ new Map();
2336
2468
  var proxyServerState = null;
@@ -3157,9 +3289,7 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
3157
3289
  var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
3158
3290
  var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
3159
3291
  var RAW_CREDENTIAL_ENV_DENYLIST = [
3160
- "SLOCK_AGENT_TOKEN",
3161
- "SLOCK_AGENT_CREDENTIAL_KEY",
3162
- "SLOCK_AGENT_CREDENTIAL_KEY_FILE"
3292
+ "SLOCK_AGENT_CREDENTIAL_KEY"
3163
3293
  ];
3164
3294
  var cachedOpencliBinPath;
3165
3295
  function resolveOpencliBinPath() {
@@ -3374,7 +3504,7 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(opencliBinPath)} "
3374
3504
  ...agentCredentialProxy ? {} : { SLOCK_AGENT_TOKEN_FILE: tokenFile },
3375
3505
  PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
3376
3506
  };
3377
- scrubDaemonChildEnv(spawnEnv);
3507
+ delete spawnEnv.SLOCK_AGENT_TOKEN;
3378
3508
  for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
3379
3509
  delete spawnEnv[key];
3380
3510
  }
@@ -3803,7 +3933,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn) {
3803
3933
  }
3804
3934
  function resolveCommandOnPath(command, deps = {}) {
3805
3935
  const platform = deps.platform ?? process.platform;
3806
- const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
3936
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
3807
3937
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
3808
3938
  const existsSyncFn = deps.existsSyncFn ?? existsSync2;
3809
3939
  if (platform === "win32") {
@@ -3829,7 +3959,7 @@ function firstExistingPath(candidates, deps = {}) {
3829
3959
  return null;
3830
3960
  }
3831
3961
  function readCommandVersion(command, args = [], deps = {}) {
3832
- const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
3962
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
3833
3963
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
3834
3964
  try {
3835
3965
  const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
@@ -4526,7 +4656,7 @@ var CodexDriver = class {
4526
4656
  };
4527
4657
  communication = {
4528
4658
  chat: "slock_cli",
4529
- runtimeControl: "mcp_runtime_actions"
4659
+ runtimeControl: "none"
4530
4660
  };
4531
4661
  session = {
4532
4662
  recovery: "resume_or_fresh"
@@ -4543,50 +4673,6 @@ var CodexDriver = class {
4543
4673
  probe() {
4544
4674
  return probeCodex();
4545
4675
  }
4546
- buildRuntimeActionsConfigArgs(ctx) {
4547
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
4548
- const command = isTsSource ? "npx" : "node";
4549
- const bridgeArgs = isTsSource ? [
4550
- "tsx",
4551
- ctx.chatBridgePath,
4552
- "--agent-id",
4553
- ctx.agentId,
4554
- "--server-url",
4555
- ctx.config.serverUrl,
4556
- "--auth-token",
4557
- ctx.config.authToken || ctx.daemonApiKey,
4558
- "--runtime",
4559
- this.id,
4560
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
4561
- "--runtime-actions-only"
4562
- ] : [
4563
- ctx.chatBridgePath,
4564
- "--agent-id",
4565
- ctx.agentId,
4566
- "--server-url",
4567
- ctx.config.serverUrl,
4568
- "--auth-token",
4569
- ctx.config.authToken || ctx.daemonApiKey,
4570
- "--runtime",
4571
- this.id,
4572
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
4573
- "--runtime-actions-only"
4574
- ];
4575
- return [
4576
- "-c",
4577
- `mcp_servers.chat.command=${JSON.stringify(command)}`,
4578
- "-c",
4579
- `mcp_servers.chat.args=${JSON.stringify(bridgeArgs)}`,
4580
- "-c",
4581
- "mcp_servers.chat.startup_timeout_sec=30",
4582
- "-c",
4583
- "mcp_servers.chat.tool_timeout_sec=120",
4584
- "-c",
4585
- "mcp_servers.chat.enabled=true",
4586
- "-c",
4587
- "mcp_servers.chat.required=true"
4588
- ];
4589
- }
4590
4676
  buildThreadRequest(ctx) {
4591
4677
  const threadParams = {
4592
4678
  cwd: ctx.workingDirectory,
@@ -4640,7 +4726,6 @@ var CodexDriver = class {
4640
4726
  this.initialTurnStarted = false;
4641
4727
  this.normalizer.reset({ threadId: ctx.config.sessionId || null });
4642
4728
  const args = ["app-server", "--listen", "stdio://"];
4643
- args.push(...this.buildRuntimeActionsConfigArgs(ctx));
4644
4729
  const { command, args: spawnArgs } = resolveCodexSpawn(args);
4645
4730
  const proc = spawn2(command, spawnArgs, {
4646
4731
  cwd: ctx.workingDirectory,
@@ -4927,8 +5012,6 @@ var AntigravityDriver = class {
4927
5012
 
4928
5013
  // src/drivers/copilot.ts
4929
5014
  import { spawn as spawn4 } from "child_process";
4930
- import path6 from "path";
4931
- import { writeFileSync as writeFileSync3 } from "fs";
4932
5015
  async function buildCopilotSpawnEnv(ctx) {
4933
5016
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
4934
5017
  }
@@ -4942,7 +5025,7 @@ var CopilotDriver = class {
4942
5025
  };
4943
5026
  communication = {
4944
5027
  chat: "slock_cli",
4945
- runtimeControl: "mcp_runtime_actions"
5028
+ runtimeControl: "none"
4946
5029
  };
4947
5030
  session = {
4948
5031
  recovery: "resume_or_fresh"
@@ -4957,43 +5040,14 @@ var CopilotDriver = class {
4957
5040
  usesSlockCliForCommunication = true;
4958
5041
  sessionId = null;
4959
5042
  sessionAnnounced = false;
4960
- buildRuntimeActionsMcpConfig(ctx) {
4961
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
4962
- const command = isTsSource ? "npx" : "node";
4963
- const bridgeArgs = isTsSource ? ["tsx", ctx.chatBridgePath] : [ctx.chatBridgePath];
4964
- return JSON.stringify({
4965
- mcpServers: {
4966
- chat: {
4967
- command,
4968
- args: [
4969
- ...bridgeArgs,
4970
- "--agent-id",
4971
- ctx.agentId,
4972
- "--server-url",
4973
- ctx.config.serverUrl,
4974
- "--auth-token",
4975
- ctx.config.authToken || ctx.daemonApiKey,
4976
- "--runtime",
4977
- this.id,
4978
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
4979
- "--runtime-actions-only"
4980
- ]
4981
- }
4982
- }
4983
- });
4984
- }
4985
5043
  async spawn(ctx) {
4986
5044
  this.sessionId = ctx.config.sessionId || null;
4987
5045
  this.sessionAnnounced = false;
4988
- const mcpConfigPath = path6.join(ctx.workingDirectory, ".slock-copilot-mcp.json");
4989
- writeFileSync3(mcpConfigPath, this.buildRuntimeActionsMcpConfig(ctx), "utf8");
4990
5046
  const args = [
4991
5047
  "--output-format",
4992
5048
  "json",
4993
5049
  "--allow-all-tools",
4994
5050
  "--allow-all-paths",
4995
- "--additional-mcp-config",
4996
- `@${mcpConfigPath}`,
4997
5051
  "-p",
4998
5052
  ctx.prompt
4999
5053
  ];
@@ -5102,8 +5156,6 @@ var CopilotDriver = class {
5102
5156
 
5103
5157
  // src/drivers/cursor.ts
5104
5158
  import { spawn as spawn5, spawnSync } from "child_process";
5105
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
5106
- import path7 from "path";
5107
5159
  async function buildCursorSpawnEnv(ctx, deps = {}) {
5108
5160
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" });
5109
5161
  return withWindowsUserEnvironment(spawnEnv, deps);
@@ -5118,7 +5170,7 @@ var CursorDriver = class {
5118
5170
  };
5119
5171
  communication = {
5120
5172
  chat: "slock_cli",
5121
- runtimeControl: "mcp_runtime_actions"
5173
+ runtimeControl: "none"
5122
5174
  };
5123
5175
  session = {
5124
5176
  recovery: "resume_or_fresh"
@@ -5131,38 +5183,7 @@ var CursorDriver = class {
5131
5183
  mcpToolPrefix = "mcp__chat__";
5132
5184
  busyDeliveryMode = "none";
5133
5185
  usesSlockCliForCommunication = true;
5134
- buildRuntimeActionsMcpConfig(ctx) {
5135
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
5136
- const command = isTsSource ? "npx" : "node";
5137
- const bridgeArgs = isTsSource ? ["tsx", ctx.chatBridgePath] : [ctx.chatBridgePath];
5138
- return JSON.stringify({
5139
- mcpServers: {
5140
- chat: {
5141
- command,
5142
- args: [
5143
- ...bridgeArgs,
5144
- "--agent-id",
5145
- ctx.agentId,
5146
- "--server-url",
5147
- ctx.config.serverUrl,
5148
- "--auth-token",
5149
- ctx.config.authToken || ctx.daemonApiKey,
5150
- "--runtime",
5151
- this.id,
5152
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
5153
- "--runtime-actions-only"
5154
- ]
5155
- }
5156
- }
5157
- });
5158
- }
5159
5186
  async spawn(ctx) {
5160
- const cursorDir = path7.join(ctx.workingDirectory, ".cursor");
5161
- if (!existsSync4(cursorDir)) {
5162
- mkdirSync2(cursorDir, { recursive: true });
5163
- }
5164
- const mcpConfigPath = path7.join(cursorDir, "mcp.json");
5165
- writeFileSync4(mcpConfigPath, this.buildRuntimeActionsMcpConfig(ctx), "utf8");
5166
5187
  const args = [
5167
5188
  "--print",
5168
5189
  "--output-format",
@@ -5292,11 +5313,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
5292
5313
  return parseCursorModelsOutput(String(result.stdout || ""));
5293
5314
  }
5294
5315
  function buildCursorModelProbeEnv(deps = {}) {
5295
- return scrubDaemonChildEnv(withWindowsUserEnvironment({
5316
+ return withWindowsUserEnvironment({
5296
5317
  ...deps.env ?? process.env,
5297
5318
  FORCE_COLOR: "0",
5298
5319
  NO_COLOR: "1"
5299
- }, deps));
5320
+ }, deps);
5300
5321
  }
5301
5322
  function runCursorModelsCommand() {
5302
5323
  return spawnSync("cursor-agent", ["models"], {
@@ -5308,8 +5329,8 @@ function runCursorModelsCommand() {
5308
5329
 
5309
5330
  // src/drivers/gemini.ts
5310
5331
  import { execFileSync as execFileSync3, spawn as spawn6 } from "child_process";
5311
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5 } from "fs";
5312
- import path8 from "path";
5332
+ import { existsSync as existsSync4 } from "fs";
5333
+ import path6 from "path";
5313
5334
  async function buildGeminiSpawnEnv(ctx, platform = process.platform) {
5314
5335
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" }, platform);
5315
5336
  const launchEnvVars = runtimeConfigToLaunchFields(ctx.config).envVars;
@@ -5351,9 +5372,9 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
5351
5372
  return { command: resolveCommandOnPath("gemini", deps) ?? "gemini", args: commandArgs };
5352
5373
  }
5353
5374
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
5354
- const existsSyncFn = deps.existsSyncFn ?? existsSync5;
5355
- const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
5356
- const winPath = path8.win32;
5375
+ const existsSyncFn = deps.existsSyncFn ?? existsSync4;
5376
+ const env = deps.env ?? process.env;
5377
+ const winPath = path6.win32;
5357
5378
  let geminiEntry = null;
5358
5379
  try {
5359
5380
  const globalRoot = normalizeExecOutput2(execFileSyncFn("npm", ["root", "-g"], {
@@ -5397,7 +5418,7 @@ var GeminiDriver = class {
5397
5418
  };
5398
5419
  communication = {
5399
5420
  chat: "slock_cli",
5400
- runtimeControl: "mcp_runtime_actions"
5421
+ runtimeControl: "none"
5401
5422
  };
5402
5423
  session = {
5403
5424
  recovery: "resume_or_fresh"
@@ -5415,7 +5436,6 @@ var GeminiDriver = class {
5415
5436
  async spawn(ctx) {
5416
5437
  this.sessionId = ctx.config.sessionId || null;
5417
5438
  this.sessionAnnounced = false;
5418
- this.writeGeminiSettings(ctx);
5419
5439
  const { command, args } = resolveGeminiSpawn(buildGeminiArgs(ctx.config));
5420
5440
  const spawnEnv = await buildGeminiSpawnEnv(ctx);
5421
5441
  const proc = spawn6(command, args, {
@@ -5488,52 +5508,17 @@ var GeminiDriver = class {
5488
5508
  messageNotificationStyle: "poll"
5489
5509
  });
5490
5510
  }
5491
- writeGeminiSettings(ctx) {
5492
- const geminiDir = path8.join(ctx.workingDirectory, ".gemini");
5493
- mkdirSync3(geminiDir, { recursive: true });
5494
- const settingsPath = path8.join(geminiDir, "settings.json");
5495
- writeFileSync5(settingsPath, JSON.stringify(this.buildRuntimeActionsMcpSettings(ctx)), "utf8");
5496
- }
5497
- buildRuntimeActionsMcpSettings(ctx) {
5498
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
5499
- const command = isTsSource ? "npx" : "node";
5500
- const bridgeArgs = isTsSource ? ["tsx", ctx.chatBridgePath] : [ctx.chatBridgePath];
5501
- return {
5502
- mcpServers: {
5503
- chat: {
5504
- command,
5505
- args: [
5506
- ...bridgeArgs,
5507
- "--agent-id",
5508
- ctx.agentId,
5509
- "--server-url",
5510
- ctx.config.serverUrl,
5511
- "--auth-token",
5512
- ctx.config.authToken || ctx.daemonApiKey,
5513
- "--runtime",
5514
- this.id,
5515
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
5516
- "--runtime-actions-only"
5517
- ]
5518
- }
5519
- }
5520
- };
5521
- }
5522
5511
  };
5523
5512
 
5524
5513
  // src/drivers/kimi.ts
5525
5514
  import { randomUUID as randomUUID2 } from "crypto";
5526
5515
  import { spawn as spawn7 } from "child_process";
5527
- import { chmodSync, existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync6 } from "fs";
5516
+ import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
5528
5517
  import os3 from "os";
5529
- import path9 from "path";
5518
+ import path7 from "path";
5530
5519
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
5531
5520
  var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
5532
5521
  var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
5533
- var KIMI_MCP_FILE = ".slock-kimi-mcp.json";
5534
- var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
5535
- var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
5536
- var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
5537
5522
  function parseToolArguments(raw) {
5538
5523
  if (typeof raw !== "string") return raw;
5539
5524
  try {
@@ -5542,73 +5527,6 @@ function parseToolArguments(raw) {
5542
5527
  return raw;
5543
5528
  }
5544
5529
  }
5545
- function readKimiConfigSource(home = os3.homedir(), env = process.env) {
5546
- const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
5547
- if (inlineConfig && inlineConfig.trim()) {
5548
- return {
5549
- raw: inlineConfig,
5550
- explicitPath: null,
5551
- sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
5552
- };
5553
- }
5554
- const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
5555
- const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
5556
- try {
5557
- return {
5558
- raw: readFileSync3(configPath, "utf8"),
5559
- explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
5560
- sourcePath: configPath
5561
- };
5562
- } catch {
5563
- return {
5564
- raw: null,
5565
- explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
5566
- sourcePath: configPath
5567
- };
5568
- }
5569
- }
5570
- function buildKimiSpawnEnv(env = process.env) {
5571
- const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
5572
- delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
5573
- delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
5574
- return scrubDaemonChildEnv(spawnEnv);
5575
- }
5576
- function buildKimiEffectiveEnv(ctx, overrideEnv) {
5577
- return {
5578
- ...process.env,
5579
- ...ctx.config.envVars || {},
5580
- ...overrideEnv || {}
5581
- };
5582
- }
5583
- function buildKimiLaunchOptions(ctx, opts = {}) {
5584
- const env = buildKimiEffectiveEnv(ctx, opts.env);
5585
- const source = readKimiConfigSource(opts.home ?? os3.homedir(), env);
5586
- const args = [];
5587
- let configFilePath = null;
5588
- let configContent = null;
5589
- if (source.explicitPath) {
5590
- configFilePath = source.explicitPath;
5591
- } else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
5592
- configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
5593
- configContent = source.raw;
5594
- if (opts.writeGeneratedConfig !== false) {
5595
- writeFileSync6(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
5596
- chmodSync(configFilePath, 384);
5597
- }
5598
- }
5599
- if (configFilePath) {
5600
- args.push("--config-file", configFilePath);
5601
- }
5602
- if (ctx.config.model && ctx.config.model !== "default") {
5603
- args.push("--model", ctx.config.model);
5604
- }
5605
- return {
5606
- args,
5607
- env: buildKimiSpawnEnv(env),
5608
- configFilePath,
5609
- configContent
5610
- };
5611
- }
5612
5530
  function resolveKimiSpawn(commandArgs, deps = {}) {
5613
5531
  return {
5614
5532
  command: resolveCommandOnPath("kimi", deps) ?? "kimi",
@@ -5625,32 +5543,14 @@ var KimiDriver = class {
5625
5543
  };
5626
5544
  communication = {
5627
5545
  chat: "slock_cli",
5628
- runtimeControl: "mcp_runtime_actions"
5546
+ runtimeControl: "none"
5629
5547
  };
5630
5548
  session = {
5631
5549
  recovery: "resume_or_fresh"
5632
5550
  };
5633
5551
  model = {
5634
5552
  detectedModelsVerifiedAs: "launchable",
5635
- toLaunchSpec: (modelId, ctx, opts) => {
5636
- if (!ctx) return { args: ["--model", modelId] };
5637
- const launchCtx = {
5638
- ...ctx,
5639
- config: {
5640
- ...ctx.config,
5641
- model: modelId
5642
- }
5643
- };
5644
- const launch = buildKimiLaunchOptions(launchCtx, {
5645
- home: opts?.home,
5646
- writeGeneratedConfig: false
5647
- });
5648
- return {
5649
- args: launch.args,
5650
- env: launch.env,
5651
- configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
5652
- };
5653
- }
5553
+ toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
5654
5554
  };
5655
5555
  supportsStdinNotification = true;
5656
5556
  mcpToolPrefix = "";
@@ -5659,70 +5559,38 @@ var KimiDriver = class {
5659
5559
  sessionId = null;
5660
5560
  sessionAnnounced = false;
5661
5561
  promptRequestId = null;
5662
- buildChatBridgeArgs(ctx) {
5663
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
5664
- return [
5665
- ...isTsSource ? ["tsx", ctx.chatBridgePath] : [ctx.chatBridgePath],
5666
- "--agent-id",
5667
- ctx.agentId,
5668
- "--server-url",
5669
- ctx.config.serverUrl,
5670
- "--auth-token",
5671
- ctx.config.authToken || ctx.daemonApiKey,
5672
- "--runtime",
5673
- "kimi",
5674
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
5675
- "--runtime-actions-only"
5676
- ];
5677
- }
5678
5562
  async spawn(ctx) {
5679
5563
  const isResume = !!ctx.config.sessionId;
5680
5564
  this.sessionId = ctx.config.sessionId || randomUUID2();
5681
5565
  this.sessionAnnounced = false;
5682
5566
  this.promptRequestId = randomUUID2();
5683
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
5684
- const command = isTsSource ? "npx" : "node";
5685
- const bridgeArgs = this.buildChatBridgeArgs(ctx);
5686
- const systemPromptPath = path9.join(ctx.workingDirectory, KIMI_SYSTEM_PROMPT_FILE);
5687
- const agentFilePath = path9.join(ctx.workingDirectory, KIMI_AGENT_FILE);
5688
- const mcpConfigPath = path9.join(ctx.workingDirectory, KIMI_MCP_FILE);
5689
- if (!isResume || !existsSync6(systemPromptPath)) {
5690
- writeFileSync6(systemPromptPath, ctx.prompt, "utf8");
5691
- }
5692
- writeFileSync6(agentFilePath, [
5567
+ const systemPromptPath = path7.join(ctx.workingDirectory, KIMI_SYSTEM_PROMPT_FILE);
5568
+ const agentFilePath = path7.join(ctx.workingDirectory, KIMI_AGENT_FILE);
5569
+ if (!isResume || !existsSync5(systemPromptPath)) {
5570
+ writeFileSync3(systemPromptPath, ctx.prompt, "utf8");
5571
+ }
5572
+ writeFileSync3(agentFilePath, [
5693
5573
  "version: 1",
5694
5574
  "agent:",
5695
5575
  " extend: default",
5696
5576
  ` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
5697
5577
  ""
5698
5578
  ].join("\n"), "utf8");
5699
- writeFileSync6(mcpConfigPath, JSON.stringify({
5700
- mcpServers: {
5701
- chat: {
5702
- command,
5703
- args: bridgeArgs
5704
- }
5705
- }
5706
- }), "utf8");
5707
- const launch = buildKimiLaunchOptions(ctx);
5708
5579
  const args = [
5709
5580
  "--wire",
5710
5581
  "--yolo",
5711
5582
  "--agent-file",
5712
5583
  agentFilePath,
5713
- "--mcp-config-file",
5714
- mcpConfigPath,
5715
5584
  "--session",
5716
- this.sessionId,
5717
- ...launch.args
5585
+ this.sessionId
5718
5586
  ];
5719
5587
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
5720
5588
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
5721
5589
  args.push("--model", launchRuntimeFields.model);
5722
5590
  }
5723
5591
  const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
5724
- const spawnTarget = resolveKimiSpawn(args);
5725
- const proc = spawn7(spawnTarget.command, spawnTarget.args, {
5592
+ const launch = resolveKimiSpawn(args);
5593
+ const proc = spawn7(launch.command, launch.args, {
5726
5594
  cwd: ctx.workingDirectory,
5727
5595
  stdio: ["pipe", "pipe", "pipe"],
5728
5596
  env: spawnEnv,
@@ -5730,7 +5598,7 @@ var KimiDriver = class {
5730
5598
  // and has an 8191-character command-line limit. Kimi's official
5731
5599
  // installer/uv entrypoint is an executable, so launch it directly and
5732
5600
  // keep prompts on stdin / files instead of routing through cmd.exe.
5733
- shell: spawnTarget.shell
5601
+ shell: launch.shell
5734
5602
  });
5735
5603
  proc.stdin?.write(JSON.stringify({
5736
5604
  jsonrpc: "2.0",
@@ -5844,9 +5712,14 @@ var KimiDriver = class {
5844
5712
  return detectKimiModels();
5845
5713
  }
5846
5714
  };
5847
- function detectKimiModels(home = os3.homedir(), opts = {}) {
5848
- const raw = readKimiConfigSource(home, opts.env).raw;
5849
- if (raw === null) return null;
5715
+ function detectKimiModels(home = os3.homedir()) {
5716
+ const configPath = path7.join(home, ".kimi", "config.toml");
5717
+ let raw;
5718
+ try {
5719
+ raw = readFileSync3(configPath, "utf8");
5720
+ } catch {
5721
+ return null;
5722
+ }
5850
5723
  const models = [];
5851
5724
  const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
5852
5725
  const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
@@ -5867,9 +5740,9 @@ function detectKimiModels(home = os3.homedir(), opts = {}) {
5867
5740
 
5868
5741
  // src/drivers/opencode.ts
5869
5742
  import { spawn as spawn8, spawnSync as spawnSync2 } from "child_process";
5870
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
5743
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
5871
5744
  import os4 from "os";
5872
- import path10 from "path";
5745
+ import path8 from "path";
5873
5746
  var CHAT_MCP_SERVER_NAME = "chat";
5874
5747
  var CHAT_MCP_TOOL_PREFIX = `${CHAT_MCP_SERVER_NAME}_`;
5875
5748
  var SLOCK_AGENT_NAME = "slock";
@@ -5884,23 +5757,6 @@ var OPENCODE_PROVIDER_LABELS = {
5884
5757
  deepseek: "DeepSeek",
5885
5758
  fusecode: "FuseCode"
5886
5759
  };
5887
- function buildChatBridgeCommand(ctx) {
5888
- const isTsSource = ctx.chatBridgePath.endsWith(".ts");
5889
- return [
5890
- isTsSource ? "npx" : "node",
5891
- ...isTsSource ? ["tsx", ctx.chatBridgePath] : [ctx.chatBridgePath],
5892
- "--agent-id",
5893
- ctx.agentId,
5894
- "--server-url",
5895
- ctx.config.serverUrl,
5896
- "--auth-token",
5897
- ctx.config.authToken || ctx.daemonApiKey,
5898
- "--runtime",
5899
- "opencode",
5900
- ...ctx.launchId ? ["--launch-id", ctx.launchId] : [],
5901
- "--runtime-actions-only"
5902
- ];
5903
- }
5904
5760
  function parseOpenCodeConfigContent(raw) {
5905
5761
  if (!raw) return {};
5906
5762
  try {
@@ -5917,7 +5773,7 @@ function parseUserOpenCodeConfig(ctx) {
5917
5773
  return parseOpenCodeConfigContent(raw);
5918
5774
  }
5919
5775
  function readLocalOpenCodeConfig(home = os4.homedir()) {
5920
- const configPath = path10.join(home, ".config", "opencode", "opencode.json");
5776
+ const configPath = path8.join(home, ".config", "opencode", "opencode.json");
5921
5777
  try {
5922
5778
  return parseOpenCodeConfigContent(readFileSync4(configPath, "utf8"));
5923
5779
  } catch {
@@ -5992,14 +5848,7 @@ function buildOpenCodeConfig(ctx, home = os4.homedir()) {
5992
5848
  prompt: ctx.standingPrompt
5993
5849
  }
5994
5850
  },
5995
- mcp: {
5996
- ...recordField(userConfig.mcp),
5997
- [CHAT_MCP_SERVER_NAME]: {
5998
- type: "local",
5999
- command: buildChatBridgeCommand(ctx),
6000
- enabled: true
6001
- }
6002
- }
5851
+ mcp: recordField(userConfig.mcp)
6003
5852
  };
6004
5853
  }
6005
5854
  async function buildOpenCodeLaunchOptions(ctx, home = os4.homedir(), version = null) {
@@ -6110,7 +5959,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
6110
5959
  const platform = deps.platform ?? process.platform;
6111
5960
  const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
6112
5961
  const result = spawnSyncFn("opencode", ["models"], {
6113
- env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
5962
+ env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
6114
5963
  encoding: "utf8",
6115
5964
  timeout: 5e3,
6116
5965
  shell: platform === "win32"
@@ -6122,11 +5971,11 @@ function runOpenCodeModelsCommand(home, deps = {}) {
6122
5971
  };
6123
5972
  }
6124
5973
  function isWindowsCommandShim(commandPath) {
6125
- const ext = path10.win32.extname(commandPath).toLowerCase();
5974
+ const ext = path8.win32.extname(commandPath).toLowerCase();
6126
5975
  return ext === ".cmd" || ext === ".bat";
6127
5976
  }
6128
5977
  function opencodePackageEntryCandidates(packageRoot) {
6129
- const winPath = path10.win32;
5978
+ const winPath = path8.win32;
6130
5979
  return [
6131
5980
  winPath.join(packageRoot, "bin", "opencode.exe"),
6132
5981
  winPath.join(packageRoot, "bin", "opencode.js"),
@@ -6135,16 +5984,16 @@ function opencodePackageEntryCandidates(packageRoot) {
6135
5984
  ];
6136
5985
  }
6137
5986
  function openCodeSpecForEntry(entry, commandArgs) {
6138
- if (path10.win32.extname(entry).toLowerCase() === ".exe") {
5987
+ if (path8.win32.extname(entry).toLowerCase() === ".exe") {
6139
5988
  return { command: entry, args: commandArgs, shell: false };
6140
5989
  }
6141
5990
  return { command: process.execPath, args: [entry, ...commandArgs], shell: false };
6142
5991
  }
6143
5992
  function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
6144
- const existsSyncFn = deps.existsSyncFn ?? existsSync7;
5993
+ const existsSyncFn = deps.existsSyncFn ?? existsSync6;
6145
5994
  const execFileSyncFn = deps.execFileSyncFn;
6146
5995
  const env = deps.env ?? process.env;
6147
- const winPath = path10.win32;
5996
+ const winPath = path8.win32;
6148
5997
  const candidates = [];
6149
5998
  if (execFileSyncFn) {
6150
5999
  try {
@@ -6172,7 +6021,7 @@ function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
6172
6021
  function extractWindowsShimTargets(commandPath, deps = {}) {
6173
6022
  if (!isWindowsCommandShim(commandPath)) return [];
6174
6023
  const readFileSyncFn = deps.readFileSyncFn ?? readFileSync4;
6175
- const commandDir = path10.win32.dirname(commandPath);
6024
+ const commandDir = path8.win32.dirname(commandPath);
6176
6025
  let raw;
6177
6026
  try {
6178
6027
  raw = String(readFileSyncFn(commandPath, "utf8"));
@@ -6183,7 +6032,7 @@ function extractWindowsShimTargets(commandPath, deps = {}) {
6183
6032
  const dp0Pattern = /%~dp0\\?([^"\r\n]*?opencode\.(?:exe|js|mjs|cjs))/gi;
6184
6033
  for (const match of raw.matchAll(dp0Pattern)) {
6185
6034
  const relative = match[1]?.replace(/^\\+/, "");
6186
- if (relative) candidates.push(path10.win32.normalize(path10.win32.join(commandDir, relative)));
6035
+ if (relative) candidates.push(path8.win32.normalize(path8.win32.join(commandDir, relative)));
6187
6036
  }
6188
6037
  return candidates;
6189
6038
  }
@@ -6197,7 +6046,7 @@ function resolveOpenCodeSpawn(commandArgs, deps = {}) {
6197
6046
  };
6198
6047
  }
6199
6048
  const command = resolveCommandOnPath("opencode", deps);
6200
- if (command && path10.win32.extname(command).toLowerCase() === ".exe") {
6049
+ if (command && path8.win32.extname(command).toLowerCase() === ".exe") {
6201
6050
  return { command, args: commandArgs, shell: false };
6202
6051
  }
6203
6052
  const packageEntry = resolveWindowsOpenCodePackageEntry(command, deps);
@@ -6241,7 +6090,7 @@ var OpenCodeDriver = class {
6241
6090
  };
6242
6091
  communication = {
6243
6092
  chat: "slock_cli",
6244
- runtimeControl: "mcp_runtime_actions"
6093
+ runtimeControl: "none"
6245
6094
  };
6246
6095
  session = {
6247
6096
  recovery: "resume_or_fresh"
@@ -6372,8 +6221,8 @@ var OpenCodeDriver = class {
6372
6221
  // src/drivers/pi.ts
6373
6222
  import { randomUUID as randomUUID3 } from "crypto";
6374
6223
  import { EventEmitter } from "events";
6375
- import { mkdirSync as mkdirSync4, readdirSync } from "fs";
6376
- import path11 from "path";
6224
+ import { mkdirSync as mkdirSync2, readdirSync } from "fs";
6225
+ import path9 from "path";
6377
6226
  import {
6378
6227
  AuthStorage,
6379
6228
  createBashTool,
@@ -6399,7 +6248,7 @@ function createPiSdkEventMappingState(sessionId = null) {
6399
6248
  };
6400
6249
  }
6401
6250
  function buildPiSessionDir(workingDirectory) {
6402
- return path11.join(workingDirectory, PI_SESSION_DIR);
6251
+ return path9.join(workingDirectory, PI_SESSION_DIR);
6403
6252
  }
6404
6253
  async function buildPiSpawnEnv(ctx) {
6405
6254
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
@@ -6421,7 +6270,7 @@ function findPiSessionFile(sessionDir, sessionId) {
6421
6270
  }
6422
6271
  const suffix = `_${sessionId}.jsonl`;
6423
6272
  const match = entries.find((entry) => entry.endsWith(suffix));
6424
- return match ? path11.join(sessionDir, match) : null;
6273
+ return match ? path9.join(sessionDir, match) : null;
6425
6274
  }
6426
6275
  function detectPiModelsFromRegistry(modelRegistry) {
6427
6276
  const models = [];
@@ -6570,13 +6419,15 @@ var PI_RUNTIME_SESSION_DESCRIPTOR = {
6570
6419
  busyDelivery: "direct",
6571
6420
  postTurn: "keep_alive"
6572
6421
  };
6422
+ var PI_IDLE_PROMPT_RETRY_MS = 25;
6423
+ var PI_IDLE_PROMPT_MAX_WAIT_MS = 1e3;
6573
6424
  async function createPiAgentSessionForContext(ctx, sessionId) {
6574
6425
  const sessionDir = buildPiSessionDir(ctx.workingDirectory);
6575
- mkdirSync4(sessionDir, { recursive: true });
6426
+ mkdirSync2(sessionDir, { recursive: true });
6576
6427
  const spawnEnv = await buildPiSpawnEnv(ctx);
6577
6428
  const agentDir = spawnEnv.PI_CODING_AGENT_DIR || getAgentDir();
6578
- const authStorage = AuthStorage.create(path11.join(agentDir, "auth.json"));
6579
- const modelRegistry = ModelRegistry.create(authStorage, path11.join(agentDir, "models.json"));
6429
+ const authStorage = AuthStorage.create(path9.join(agentDir, "auth.json"));
6430
+ const modelRegistry = ModelRegistry.create(authStorage, path9.join(agentDir, "models.json"));
6580
6431
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
6581
6432
  const model = resolvePiModelFromRegistry(launchRuntimeFields.model, modelRegistry);
6582
6433
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default" && !model) {
@@ -6687,7 +6538,8 @@ var PiSdkRuntimeSession = class {
6687
6538
  return { ok: true, acceptedAs: "steer" };
6688
6539
  }
6689
6540
  if (session.isStreaming) {
6690
- return { ok: false, reason: "busy_rejected", error: "Pi session is still streaming" };
6541
+ this.launchPromptAfterStreaming(input.text);
6542
+ return { ok: true, acceptedAs: "prompt" };
6691
6543
  }
6692
6544
  this.launchPrompt(input.text);
6693
6545
  return { ok: true, acceptedAs: "prompt" };
@@ -6729,6 +6581,27 @@ var PiSdkRuntimeSession = class {
6729
6581
  }
6730
6582
  this.deferSdkCall(() => session.prompt(text));
6731
6583
  }
6584
+ launchPromptAfterStreaming(text) {
6585
+ this.deferSdkCall(async () => {
6586
+ const session = this.session;
6587
+ if (!session) return;
6588
+ const ready = await this.waitForStreamingToClear(session);
6589
+ if (this.didClose || this.session !== session) {
6590
+ return;
6591
+ }
6592
+ await (ready ? session.prompt(text) : session.steer(text));
6593
+ });
6594
+ }
6595
+ async waitForStreamingToClear(session) {
6596
+ const deadline = Date.now() + PI_IDLE_PROMPT_MAX_WAIT_MS;
6597
+ while (!this.didClose && this.session === session && session.isStreaming) {
6598
+ if (Date.now() >= deadline) {
6599
+ return false;
6600
+ }
6601
+ await delay(PI_IDLE_PROMPT_RETRY_MS);
6602
+ }
6603
+ return !this.didClose && this.session === session && !session.isStreaming;
6604
+ }
6732
6605
  deferSdkCall(invoke) {
6733
6606
  setImmediate(() => {
6734
6607
  if (this.didClose) return;
@@ -6840,6 +6713,12 @@ var PiDriver = class {
6840
6713
  });
6841
6714
  }
6842
6715
  };
6716
+ function delay(ms) {
6717
+ return new Promise((resolve) => {
6718
+ const timer = setTimeout(resolve, ms);
6719
+ timer.unref?.();
6720
+ });
6721
+ }
6843
6722
 
6844
6723
  // src/drivers/runtimeSession.ts
6845
6724
  import { EventEmitter as EventEmitter2 } from "events";
@@ -6998,7 +6877,7 @@ function getDriver(runtimeId) {
6998
6877
 
6999
6878
  // src/workspaces.ts
7000
6879
  import { readdir, rm, stat } from "fs/promises";
7001
- import path12 from "path";
6880
+ import path10 from "path";
7002
6881
  function isValidWorkspaceDirectoryName(directoryName) {
7003
6882
  return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
7004
6883
  }
@@ -7006,7 +6885,7 @@ function resolveWorkspaceDirectoryPath(dataDir, directoryName) {
7006
6885
  if (!isValidWorkspaceDirectoryName(directoryName)) {
7007
6886
  return null;
7008
6887
  }
7009
- return path12.join(dataDir, directoryName);
6888
+ return path10.join(dataDir, directoryName);
7010
6889
  }
7011
6890
  function emptyWorkspaceDirectorySummary(latestMtime = /* @__PURE__ */ new Date(0)) {
7012
6891
  return {
@@ -7055,7 +6934,7 @@ async function summarizeWorkspaceDirectory(dirPath) {
7055
6934
  return summary;
7056
6935
  }
7057
6936
  const childSummaries = await Promise.all(
7058
- entries.map((entry) => summarizeWorkspaceEntry(path12.join(dirPath, entry.name), entry))
6937
+ entries.map((entry) => summarizeWorkspaceEntry(path10.join(dirPath, entry.name), entry))
7059
6938
  );
7060
6939
  for (const childSummary of childSummaries) {
7061
6940
  summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
@@ -7074,7 +6953,7 @@ async function scanWorkspaceDirectories(dataDir) {
7074
6953
  if (!entry.isDirectory()) {
7075
6954
  return null;
7076
6955
  }
7077
- const dirPath = path12.join(dataDir, entry.name);
6956
+ const dirPath = path10.join(dataDir, entry.name);
7078
6957
  try {
7079
6958
  const summary = await summarizeWorkspaceDirectory(dirPath);
7080
6959
  return {
@@ -7537,12 +7416,12 @@ function findSessionJsonl(root, predicate) {
7537
7416
  for (const entry of entries) {
7538
7417
  if (++visited > maxEntries) return null;
7539
7418
  if (!entry.isFile() || !predicate(entry.name)) continue;
7540
- return path13.join(dir, entry.name);
7419
+ return path11.join(dir, entry.name);
7541
7420
  }
7542
7421
  for (const entry of entries) {
7543
7422
  if (++visited > maxEntries) return null;
7544
7423
  if (!entry.isDirectory()) continue;
7545
- const found = visit(path13.join(dir, entry.name), depth - 1);
7424
+ const found = visit(path11.join(dir, entry.name), depth - 1);
7546
7425
  if (found) return found;
7547
7426
  }
7548
7427
  return null;
@@ -7555,10 +7434,10 @@ function safeSessionFilename(value) {
7555
7434
  }
7556
7435
  function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
7557
7436
  try {
7558
- const dir = path13.join(fallbackDir, ".slock", "runtime-sessions");
7559
- mkdirSync5(dir, { recursive: true });
7560
- const filePath = path13.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
7561
- writeFileSync7(filePath, JSON.stringify({
7437
+ const dir = path11.join(fallbackDir, ".slock", "runtime-sessions");
7438
+ mkdirSync3(dir, { recursive: true });
7439
+ const filePath = path11.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
7440
+ writeFileSync4(filePath, JSON.stringify({
7562
7441
  type: "runtime_session_handoff",
7563
7442
  runtime,
7564
7443
  sessionId,
@@ -7577,7 +7456,7 @@ function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
7577
7456
  }
7578
7457
  }
7579
7458
  function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os5.homedir(), fallbackDir) {
7580
- const directPath = path13.isAbsolute(sessionId) ? sessionId : null;
7459
+ const directPath = path11.isAbsolute(sessionId) ? sessionId : null;
7581
7460
  if (directPath) {
7582
7461
  try {
7583
7462
  if (statSync(directPath).isFile()) {
@@ -7586,7 +7465,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os5.homedir(), f
7586
7465
  } catch {
7587
7466
  }
7588
7467
  }
7589
- const resolvedPath = runtime === "claude" ? findSessionJsonl(path13.join(homeDir, ".claude", "projects"), (filename) => filename === `${sessionId}.jsonl`) : runtime === "codex" ? findSessionJsonl(path13.join(homeDir, ".codex", "sessions"), (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId)) : null;
7468
+ const resolvedPath = runtime === "claude" ? findSessionJsonl(path11.join(homeDir, ".claude", "projects"), (filename) => filename === `${sessionId}.jsonl`) : runtime === "codex" ? findSessionJsonl(path11.join(homeDir, ".codex", "sessions"), (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId)) : null;
7590
7469
  if (!resolvedPath && fallbackDir) {
7591
7470
  const fallback = writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir);
7592
7471
  if (fallback) return fallback;
@@ -8189,8 +8068,7 @@ function runtimeProfileTurnControl(kind, key, source) {
8189
8068
  source,
8190
8069
  keyHash: hashRuntimeProfileKey(key) ?? null,
8191
8070
  keyPresent: Boolean(key),
8192
- injectedAtMs: Date.now(),
8193
- migrationDoneToolObserved: false
8071
+ injectedAtMs: Date.now()
8194
8072
  };
8195
8073
  }
8196
8074
  function pushRecentLines(lines, chunk, maxLines, maxLineLength) {
@@ -8266,6 +8144,9 @@ function classifyStickyTerminalFailure(ap) {
8266
8144
  if (isRuntimeStartTimeoutText(terminalFailure.detail)) return null;
8267
8145
  return null;
8268
8146
  }
8147
+ function isAuthClassTerminalLine(text) {
8148
+ return buildRuntimeErrorDiagnosticEnvelope(text).spanAttrs.runtime_error_action_required === true;
8149
+ }
8269
8150
  function isProviderStreamFailureText(text) {
8270
8151
  return /stream closed before response\.completed|error decoding response body/i.test(text);
8271
8152
  }
@@ -8583,7 +8464,6 @@ var AgentProcessManager = class _AgentProcessManager {
8583
8464
  startingInboxes = /* @__PURE__ */ new Map();
8584
8465
  /** Cached configs for agents whose process exited normally — enables auto-restart on next message */
8585
8466
  idleAgentConfigs = /* @__PURE__ */ new Map();
8586
- chatBridgePath;
8587
8467
  slockCliPath;
8588
8468
  sendToServer;
8589
8469
  daemonApiKey;
@@ -8601,8 +8481,7 @@ var AgentProcessManager = class _AgentProcessManager {
8601
8481
  agentVisibleMessageIds = /* @__PURE__ */ new Map();
8602
8482
  daemonVersion;
8603
8483
  computerVersion;
8604
- constructor(chatBridgePath, sendToServer, daemonApiKey, opts) {
8605
- this.chatBridgePath = chatBridgePath;
8484
+ constructor(sendToServer, daemonApiKey, opts) {
8606
8485
  this.slockCliPath = opts.slockCliPath ?? "";
8607
8486
  this.sendToServer = sendToServer;
8608
8487
  this.daemonApiKey = daemonApiKey;
@@ -9129,7 +9008,7 @@ var AgentProcessManager = class _AgentProcessManager {
9129
9008
  );
9130
9009
  wakeMessage = void 0;
9131
9010
  }
9132
- const agentDataDir = path13.join(this.dataDir, agentId);
9011
+ const agentDataDir = path11.join(this.dataDir, agentId);
9133
9012
  await mkdir(agentDataDir, { recursive: true });
9134
9013
  let runtimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
9135
9014
  const legacyRuntimeProfileControl = runtimeConfig.runtimeProfileControl?.kind === "migration" ? runtimeConfig.runtimeProfileControl : null;
@@ -9143,23 +9022,23 @@ var AgentProcessManager = class _AgentProcessManager {
9143
9022
  );
9144
9023
  runtimeConfig = { ...runtimeConfig, runtimeProfileControl: null };
9145
9024
  }
9146
- const memoryMdPath = path13.join(agentDataDir, "MEMORY.md");
9025
+ const memoryMdPath = path11.join(agentDataDir, "MEMORY.md");
9147
9026
  try {
9148
9027
  await access(memoryMdPath);
9149
9028
  } catch {
9150
9029
  const initialMemoryMd = buildInitialMemoryMd(runtimeConfig);
9151
9030
  await writeFile(memoryMdPath, initialMemoryMd);
9152
9031
  }
9153
- const notesDir = path13.join(agentDataDir, "notes");
9032
+ const notesDir = path11.join(agentDataDir, "notes");
9154
9033
  await mkdir(notesDir, { recursive: true });
9155
9034
  if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
9156
9035
  const seedFiles = buildOnboardingSeedFiles();
9157
9036
  for (const { relativePath, content } of seedFiles) {
9158
- const fullPath = path13.join(agentDataDir, relativePath);
9037
+ const fullPath = path11.join(agentDataDir, relativePath);
9159
9038
  try {
9160
9039
  await access(fullPath);
9161
9040
  } catch {
9162
- await mkdir(path13.dirname(fullPath), { recursive: true });
9041
+ await mkdir(path11.dirname(fullPath), { recursive: true });
9163
9042
  await writeFile(fullPath, content);
9164
9043
  }
9165
9044
  }
@@ -9267,7 +9146,6 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9267
9146
  standingPrompt,
9268
9147
  prompt,
9269
9148
  workingDirectory: agentDataDir,
9270
- chatBridgePath: this.chatBridgePath,
9271
9149
  slockCliPath: this.slockCliPath,
9272
9150
  daemonApiKey: this.daemonApiKey,
9273
9151
  launchId: launchId || null,
@@ -9414,7 +9292,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9414
9292
  const startupTimeoutTermination = ap.expectedTerminationReason === "startup_timeout";
9415
9293
  const expectedTermination = Boolean(ap.expectedTerminationReason);
9416
9294
  const stickyTerminalFailureDetail = classifyStickyTerminalFailure(ap);
9417
- const processEndedCleanly = !stickyTerminalFailureDetail && (finalCode === 0 || expectedTermination && !ap.lastRuntimeError);
9295
+ const processEndedCleanly = !stickyTerminalFailureDetail && !startupTimeoutTermination && (finalCode === 0 || expectedTermination && !ap.lastRuntimeError);
9418
9296
  const terminalFailureDetail = processEndedCleanly ? null : stickyTerminalFailureDetail ?? classifyTerminalFailure(ap);
9419
9297
  const resumeRecoveryReason = resumeSessionRecoveryReason(ap);
9420
9298
  const shouldColdStartResumeSession = resumeRecoveryReason !== null;
@@ -9980,20 +9858,37 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
9980
9858
  }));
9981
9859
  return true;
9982
9860
  }
9983
- ap.inbox.push(message);
9984
- this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
9985
- outcome: "queued_terminal_runtime_error",
9986
- accepted: true,
9987
- process_present: true,
9988
- runtime: ap.config.runtime,
9989
- session_id_present: Boolean(ap.sessionId),
9990
- launchId: ap.launchId || void 0,
9991
- is_idle: ap.isIdle,
9992
- inbox_count: ap.inbox.length
9993
- }));
9994
- this.sendAgentStatus(agentId, "inactive", ap.launchId);
9995
- this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail);
9996
- return true;
9861
+ if (stickyTerminalFailure.actionRequired) {
9862
+ if (ap.lastRuntimeError && isAuthClassTerminalLine(ap.lastRuntimeError)) {
9863
+ ap.lastRuntimeError = null;
9864
+ }
9865
+ ap.recentStderr = ap.recentStderr.filter((line) => !isAuthClassTerminalLine(line));
9866
+ this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
9867
+ outcome: "user_turn_recover_from_sticky_terminal_error",
9868
+ accepted: true,
9869
+ process_present: true,
9870
+ runtime: ap.config.runtime,
9871
+ session_id_present: Boolean(ap.sessionId),
9872
+ launchId: ap.launchId || void 0,
9873
+ is_idle: ap.isIdle,
9874
+ inbox_count: ap.inbox.length
9875
+ }));
9876
+ } else {
9877
+ ap.inbox.push(message);
9878
+ this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
9879
+ outcome: "queued_terminal_runtime_error",
9880
+ accepted: true,
9881
+ process_present: true,
9882
+ runtime: ap.config.runtime,
9883
+ session_id_present: Boolean(ap.sessionId),
9884
+ launchId: ap.launchId || void 0,
9885
+ is_idle: ap.isIdle,
9886
+ inbox_count: ap.inbox.length
9887
+ }));
9888
+ this.sendAgentStatus(agentId, "inactive", ap.launchId);
9889
+ this.broadcastActivity(agentId, "error", stickyTerminalFailure.detail);
9890
+ return true;
9891
+ }
9997
9892
  }
9998
9893
  if (ap.isIdle && ap.driver.supportsStdinNotification && ap.sessionId) {
9999
9894
  if (transientDelivery) {
@@ -10161,7 +10056,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10161
10056
  return true;
10162
10057
  }
10163
10058
  async resetWorkspace(agentId) {
10164
- const agentDataDir = path13.join(this.dataDir, agentId);
10059
+ const agentDataDir = path11.join(this.dataDir, agentId);
10165
10060
  try {
10166
10061
  await rm2(agentDataDir, { recursive: true, force: true });
10167
10062
  logger.info(`[Agent ${agentId}] Workspace reset complete (${agentDataDir})`);
@@ -10222,7 +10117,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10222
10117
  return result;
10223
10118
  }
10224
10119
  buildRuntimeProfileReport(agentId, config, sessionId, launchId) {
10225
- const workspacePath = path13.join(this.dataDir, agentId);
10120
+ const workspacePath = path11.join(this.dataDir, agentId);
10226
10121
  return {
10227
10122
  agentId,
10228
10123
  launchId,
@@ -10481,7 +10376,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10481
10376
  }
10482
10377
  // Workspace file browsing
10483
10378
  async getFileTree(agentId, dirPath) {
10484
- const agentDir = path13.join(this.dataDir, agentId);
10379
+ const agentDir = path11.join(this.dataDir, agentId);
10485
10380
  try {
10486
10381
  await stat2(agentDir);
10487
10382
  } catch {
@@ -10489,8 +10384,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10489
10384
  }
10490
10385
  let targetDir = agentDir;
10491
10386
  if (dirPath) {
10492
- const resolved = path13.resolve(agentDir, dirPath);
10493
- if (!resolved.startsWith(agentDir + path13.sep) && resolved !== agentDir) {
10387
+ const resolved = path11.resolve(agentDir, dirPath);
10388
+ if (!resolved.startsWith(agentDir + path11.sep) && resolved !== agentDir) {
10494
10389
  return [];
10495
10390
  }
10496
10391
  targetDir = resolved;
@@ -10498,14 +10393,14 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10498
10393
  return this.listDirectoryChildren(targetDir, agentDir);
10499
10394
  }
10500
10395
  async readFile(agentId, filePath) {
10501
- const agentDir = path13.join(this.dataDir, agentId);
10502
- const resolved = path13.resolve(agentDir, filePath);
10503
- if (!resolved.startsWith(agentDir + path13.sep) && resolved !== agentDir) {
10396
+ const agentDir = path11.join(this.dataDir, agentId);
10397
+ const resolved = path11.resolve(agentDir, filePath);
10398
+ if (!resolved.startsWith(agentDir + path11.sep) && resolved !== agentDir) {
10504
10399
  throw new Error("Access denied");
10505
10400
  }
10506
10401
  const info = await stat2(resolved);
10507
10402
  if (info.isDirectory()) throw new Error("Cannot read a directory");
10508
- const ext = path13.extname(resolved).toLowerCase();
10403
+ const ext = path11.extname(resolved).toLowerCase();
10509
10404
  if (WORKSPACE_TEXT_EXTENSIONS.has(ext) || ext === "") {
10510
10405
  if (info.size > WORKSPACE_TEXT_FILE_MAX_BYTES) throw new Error("File too large");
10511
10406
  const content = await readFile(resolved, "utf-8");
@@ -10540,13 +10435,13 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10540
10435
  const agent = this.agents.get(agentId);
10541
10436
  const runtime = runtimeHint || agent?.config.runtime || "claude";
10542
10437
  const home = os5.homedir();
10543
- const workspaceDir = path13.join(this.dataDir, agentId);
10438
+ const workspaceDir = path11.join(this.dataDir, agentId);
10544
10439
  const paths = _AgentProcessManager.SKILL_PATHS[runtime] || _AgentProcessManager.SKILL_PATHS.claude;
10545
10440
  const globalResults = await Promise.all(
10546
- paths.global.map((p) => this.scanSkillsDir(path13.join(home, p)))
10441
+ paths.global.map((p) => this.scanSkillsDir(path11.join(home, p)))
10547
10442
  );
10548
10443
  const workspaceResults = await Promise.all(
10549
- paths.workspace.map((p) => this.scanSkillsDir(path13.join(workspaceDir, p)))
10444
+ paths.workspace.map((p) => this.scanSkillsDir(path11.join(workspaceDir, p)))
10550
10445
  );
10551
10446
  const dedup = (skills) => {
10552
10447
  const seen = /* @__PURE__ */ new Set();
@@ -10575,7 +10470,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10575
10470
  const skills = [];
10576
10471
  for (const entry of entries) {
10577
10472
  if (entry.isDirectory() || entry.isSymbolicLink()) {
10578
- const skillMd = path13.join(dir, entry.name, "SKILL.md");
10473
+ const skillMd = path11.join(dir, entry.name, "SKILL.md");
10579
10474
  try {
10580
10475
  const content = await readFile(skillMd, "utf-8");
10581
10476
  const skill = this.parseSkillMd(entry.name, content);
@@ -10586,7 +10481,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10586
10481
  } else if (entry.name.endsWith(".md")) {
10587
10482
  const cmdName = entry.name.replace(/\.md$/, "");
10588
10483
  try {
10589
- const content = await readFile(path13.join(dir, entry.name), "utf-8");
10484
+ const content = await readFile(path11.join(dir, entry.name), "utf-8");
10590
10485
  const skill = this.parseSkillMd(cmdName, content);
10591
10486
  skill.sourcePath = dir;
10592
10487
  skills.push(skill);
@@ -10906,8 +10801,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10906
10801
  runtime_profile_key_hash: control.keyHash || void 0,
10907
10802
  runtime_profile_key_present: control.keyPresent,
10908
10803
  runtime_profile_pending_age_ms: pendingAgeMs,
10909
- runtime_profile_requires_ack: false,
10910
- runtime_profile_migration_done_observed: control.kind === "migration" ? control.migrationDoneToolObserved : void 0
10804
+ runtime_profile_requires_ack: false
10911
10805
  };
10912
10806
  }
10913
10807
  activateRuntimeProfileTurnControl(ap, control) {
@@ -10919,16 +10813,6 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10919
10813
  if (!notification) return null;
10920
10814
  return runtimeProfileTurnControl(notification.kind, notification.key, source);
10921
10815
  }
10922
- noteRuntimeProfileToolCall(agentId, ap, toolName) {
10923
- const control = ap.runtimeProfileTurnControl;
10924
- if (!control || control.kind !== "migration") return;
10925
- if (!toolName.includes("runtime_profile_migration_done")) return;
10926
- control.migrationDoneToolObserved = true;
10927
- this.recordRuntimeTraceEvent(agentId, ap, "runtime_profile.migration_done_tool.observed", {
10928
- ...this.runtimeProfileTurnControlTraceAttrs(control),
10929
- tool: toolName
10930
- });
10931
- }
10932
10816
  finalizeRuntimeProfileTurnControl(agentId, ap, terminal) {
10933
10817
  const control = ap.runtimeProfileTurnControl;
10934
10818
  if (!control) return {};
@@ -10937,7 +10821,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
10937
10821
  return {
10938
10822
  ...attrs,
10939
10823
  runtime_profile_turn_terminal: terminal,
10940
- runtime_profile_turn_outcome: control.kind === "migration" ? control.migrationDoneToolObserved ? "deprecated_migration_done_observed" : "reset_session_notice" : "notice_only"
10824
+ runtime_profile_turn_outcome: control.kind === "migration" ? "reset_session_notice" : "notice_only"
10941
10825
  };
10942
10826
  }
10943
10827
  startRuntimeTrace(agentId, ap, reason, messages, inputTraceAttrs = {}) {
@@ -11342,7 +11226,6 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
11342
11226
  const invocation = normalizeToolDisplayInvocation(event.name, event.input);
11343
11227
  if (ap) {
11344
11228
  const reduction = reduceApmGatedToolUse(ap.gatedSteering, { kind: "tool_call" });
11345
- this.noteRuntimeProfileToolCall(agentId, ap, invocation.toolName);
11346
11229
  this.recordRuntimeTraceEvent(agentId, ap, "tool.call.started", { tool: invocation.toolName });
11347
11230
  this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, {
11348
11231
  event: "tool_call",
@@ -11923,8 +11806,8 @@ ${RESPONSE_TARGET_HINT}`);
11923
11806
  const nodes = [];
11924
11807
  for (const entry of entries) {
11925
11808
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
11926
- const fullPath = path13.join(dir, entry.name);
11927
- const relativePath = path13.relative(rootDir, fullPath);
11809
+ const fullPath = path11.join(dir, entry.name);
11810
+ const relativePath = path11.relative(rootDir, fullPath);
11928
11811
  let info;
11929
11812
  try {
11930
11813
  info = await stat2(fullPath);
@@ -12215,7 +12098,7 @@ var ReminderCache = class {
12215
12098
  logger.warn(`[ReminderCache] Invalid fireAt for ${job.reminderId}: ${job.fireAt}`);
12216
12099
  return null;
12217
12100
  }
12218
- const delay = Math.max(0, Math.min(this.maxDelayMs, fireAt - this.clock.now()));
12101
+ const delay2 = Math.max(0, Math.min(this.maxDelayMs, fireAt - this.clock.now()));
12219
12102
  return this.clock.setTimeout(() => {
12220
12103
  this.entries.delete(job.reminderId);
12221
12104
  try {
@@ -12223,15 +12106,15 @@ var ReminderCache = class {
12223
12106
  } catch (err) {
12224
12107
  logger.error(`[ReminderCache] onFire threw for ${job.reminderId}`, err);
12225
12108
  }
12226
- }, delay);
12109
+ }, delay2);
12227
12110
  }
12228
12111
  };
12229
12112
 
12230
12113
  // src/machineLock.ts
12231
12114
  import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
12232
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync8 } from "fs";
12115
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync5, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
12233
12116
  import os6 from "os";
12234
- import path14 from "path";
12117
+ import path12 from "path";
12235
12118
  var INCOMPLETE_LOCK_STALE_MS = 3e4;
12236
12119
  var DaemonMachineLockConflictError = class extends Error {
12237
12120
  code = "DAEMON_MACHINE_LOCK_HELD";
@@ -12253,7 +12136,7 @@ function resolveDefaultMachineStateRoot() {
12253
12136
  return resolveSlockHomePath("machines");
12254
12137
  }
12255
12138
  function ownerPath(lockDir) {
12256
- return path14.join(lockDir, "owner.json");
12139
+ return path12.join(lockDir, "owner.json");
12257
12140
  }
12258
12141
  function readOwner(lockDir) {
12259
12142
  try {
@@ -12283,13 +12166,13 @@ function acquireDaemonMachineLock(options) {
12283
12166
  const rootDir = options.rootDir ?? resolveDefaultMachineStateRoot();
12284
12167
  const fingerprint = apiKeyFingerprint(options.apiKey);
12285
12168
  const lockId = getDaemonMachineLockId(options.apiKey);
12286
- const machineDir = path14.join(rootDir, lockId);
12287
- const lockDir = path14.join(machineDir, "daemon.lock");
12169
+ const machineDir = path12.join(rootDir, lockId);
12170
+ const lockDir = path12.join(machineDir, "daemon.lock");
12288
12171
  const token = randomUUID4();
12289
- mkdirSync6(machineDir, { recursive: true });
12172
+ mkdirSync4(machineDir, { recursive: true });
12290
12173
  for (let attempt = 0; attempt < 2; attempt += 1) {
12291
12174
  try {
12292
- mkdirSync6(lockDir);
12175
+ mkdirSync4(lockDir);
12293
12176
  const owner = {
12294
12177
  pid: process.pid,
12295
12178
  token,
@@ -12299,7 +12182,7 @@ function acquireDaemonMachineLock(options) {
12299
12182
  apiKeyFingerprint: fingerprint.slice(0, 16)
12300
12183
  };
12301
12184
  try {
12302
- writeFileSync8(ownerPath(lockDir), `${JSON.stringify(owner, null, 2)}
12185
+ writeFileSync5(ownerPath(lockDir), `${JSON.stringify(owner, null, 2)}
12303
12186
  `, { mode: 384 });
12304
12187
  } catch (err) {
12305
12188
  rmSync3(lockDir, { recursive: true, force: true });
@@ -12314,7 +12197,7 @@ function acquireDaemonMachineLock(options) {
12314
12197
  if (currentOwner?.pid === process.pid && currentOwner.token === token) {
12315
12198
  const released = { ...currentOwner, pid: 0 };
12316
12199
  try {
12317
- writeFileSync8(ownerPath(lockDir), `${JSON.stringify(released, null, 2)}
12200
+ writeFileSync5(ownerPath(lockDir), `${JSON.stringify(released, null, 2)}
12318
12201
  `, {
12319
12202
  mode: 384
12320
12203
  });
@@ -12344,8 +12227,8 @@ function acquireDaemonMachineLock(options) {
12344
12227
  }
12345
12228
 
12346
12229
  // src/localTraceSink.ts
12347
- import { appendFileSync, mkdirSync as mkdirSync7, readdirSync as readdirSync3, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync9 } from "fs";
12348
- import path15 from "path";
12230
+ import { appendFileSync, mkdirSync as mkdirSync5, readdirSync as readdirSync3, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
12231
+ import path13 from "path";
12349
12232
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
12350
12233
  var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
12351
12234
  var DEFAULT_MAX_FILES = 8;
@@ -12382,7 +12265,7 @@ var LocalRotatingTraceSink = class {
12382
12265
  currentSize = 0;
12383
12266
  sequence = 0;
12384
12267
  constructor(options) {
12385
- this.traceDir = path15.join(options.machineDir, "traces");
12268
+ this.traceDir = path13.join(options.machineDir, "traces");
12386
12269
  this.maxFileBytes = Math.max(1024, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES));
12387
12270
  const baseAgeMs = Math.max(1e3, Math.floor(options.maxFileAgeMs ?? DEFAULT_MAX_FILE_AGE_MS));
12388
12271
  const ageJitterMs = Math.max(0, Math.floor(options.maxFileAgeJitterMs ?? 0));
@@ -12408,15 +12291,15 @@ var LocalRotatingTraceSink = class {
12408
12291
  return this.currentFile;
12409
12292
  }
12410
12293
  ensureFile(nextBytes) {
12411
- mkdirSync7(this.traceDir, { recursive: true, mode: 448 });
12294
+ mkdirSync5(this.traceDir, { recursive: true, mode: 448 });
12412
12295
  const nowMs = this.nowMsProvider();
12413
12296
  const shouldRotateForAge = this.currentFileOpenedAtMs !== null && nowMs - this.currentFileOpenedAtMs >= this.maxFileAgeMs;
12414
12297
  if (!this.currentFile || this.currentSize + nextBytes > this.maxFileBytes || shouldRotateForAge) {
12415
- this.currentFile = path15.join(
12298
+ this.currentFile = path13.join(
12416
12299
  this.traceDir,
12417
12300
  `daemon-trace-${safeTimestamp(nowMs)}-${process.pid}-${String(this.sequence++).padStart(4, "0")}.jsonl`
12418
12301
  );
12419
- writeFileSync9(this.currentFile, "", { flag: "a", mode: 384 });
12302
+ writeFileSync6(this.currentFile, "", { flag: "a", mode: 384 });
12420
12303
  this.currentSize = statSync3(this.currentFile).size;
12421
12304
  this.currentFileOpenedAtMs = nowMs;
12422
12305
  this.pruneOldFiles();
@@ -12427,7 +12310,7 @@ var LocalRotatingTraceSink = class {
12427
12310
  const excess = files.length - this.maxFiles;
12428
12311
  if (excess <= 0) return;
12429
12312
  for (const file of files.slice(0, excess)) {
12430
- rmSync4(path15.join(this.traceDir, file), { force: true });
12313
+ rmSync4(path13.join(this.traceDir, file), { force: true });
12431
12314
  }
12432
12315
  }
12433
12316
  };
@@ -12518,11 +12401,108 @@ function isDiagnosticErrorAttr(key) {
12518
12401
  import { createHash as createHash6, randomUUID as randomUUID5 } from "crypto";
12519
12402
  import { gzipSync } from "zlib";
12520
12403
  import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
12521
- import path16 from "path";
12404
+ import path14 from "path";
12405
+
12406
+ // src/chatBridgeRequest.ts
12407
+ var DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS = Number.parseInt(
12408
+ process.env.SLOCK_CHAT_BRIDGE_TOOL_TIMEOUT_MS || "",
12409
+ 10
12410
+ ) || 6e4;
12411
+ var ChatBridgeToolTimeoutError = class extends Error {
12412
+ toolName;
12413
+ target;
12414
+ timeoutMs;
12415
+ durationMs;
12416
+ constructor(toolName, target, timeoutMs, durationMs) {
12417
+ super(`${toolName} timed out after ${timeoutMs}ms${target ? ` (target: ${target})` : ""}`);
12418
+ this.name = "ChatBridgeToolTimeoutError";
12419
+ this.toolName = toolName;
12420
+ this.target = target;
12421
+ this.timeoutMs = timeoutMs;
12422
+ this.durationMs = durationMs;
12423
+ }
12424
+ };
12425
+ function describeError(err) {
12426
+ if (err instanceof Error) return `${err.name}: ${err.message}`;
12427
+ return String(err);
12428
+ }
12429
+ async function executeJsonRequest(url, init, {
12430
+ toolName,
12431
+ target = null,
12432
+ timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
12433
+ fetchImpl,
12434
+ now = () => Date.now(),
12435
+ warn = (message) => logger.warn(message)
12436
+ }) {
12437
+ const startedAt = now();
12438
+ const timeoutController = new AbortController();
12439
+ const signals = [timeoutController.signal];
12440
+ if (init.signal) signals.push(init.signal);
12441
+ const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
12442
+ const timeout = setTimeout(() => {
12443
+ timeoutController.abort();
12444
+ }, timeoutMs);
12445
+ timeout.unref?.();
12446
+ try {
12447
+ const response = await fetchImpl(url, { ...init, signal });
12448
+ const data = await response.json();
12449
+ return { response, data, durationMs: now() - startedAt };
12450
+ } catch (err) {
12451
+ const durationMs = now() - startedAt;
12452
+ if (timeoutController.signal.aborted && !init.signal?.aborted) {
12453
+ warn(
12454
+ `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
12455
+ );
12456
+ throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
12457
+ }
12458
+ warn(
12459
+ `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
12460
+ );
12461
+ throw err;
12462
+ } finally {
12463
+ clearTimeout(timeout);
12464
+ }
12465
+ }
12466
+ async function executeResponseRequest(url, init, {
12467
+ toolName,
12468
+ target = null,
12469
+ timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
12470
+ fetchImpl,
12471
+ now = () => Date.now(),
12472
+ warn = (message) => logger.warn(message)
12473
+ }) {
12474
+ const startedAt = now();
12475
+ const timeoutController = new AbortController();
12476
+ const signals = [timeoutController.signal];
12477
+ if (init.signal) signals.push(init.signal);
12478
+ const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
12479
+ const timeout = setTimeout(() => {
12480
+ timeoutController.abort();
12481
+ }, timeoutMs);
12482
+ timeout.unref?.();
12483
+ try {
12484
+ const response = await fetchImpl(url, { ...init, signal });
12485
+ return { response, durationMs: now() - startedAt };
12486
+ } catch (err) {
12487
+ const durationMs = now() - startedAt;
12488
+ if (timeoutController.signal.aborted && !init.signal?.aborted) {
12489
+ warn(
12490
+ `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
12491
+ );
12492
+ throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
12493
+ }
12494
+ warn(
12495
+ `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
12496
+ );
12497
+ throw err;
12498
+ } finally {
12499
+ clearTimeout(timeout);
12500
+ }
12501
+ }
12522
12502
 
12523
12503
  // src/directUploadCapability.ts
12524
- function joinUrl(base, path18) {
12525
- return `${base.replace(/\/+$/, "")}${path18}`;
12504
+ function joinUrl(base, path16) {
12505
+ return `${base.replace(/\/+$/, "")}${path16}`;
12526
12506
  }
12527
12507
  function jsonHeaders(apiKey) {
12528
12508
  return {
@@ -12741,7 +12721,7 @@ var DaemonTraceBundleUploader = class {
12741
12721
  }, nextMs);
12742
12722
  }
12743
12723
  async findUploadCandidates() {
12744
- const traceDir = path16.join(this.options.machineDir, "traces");
12724
+ const traceDir = path14.join(this.options.machineDir, "traces");
12745
12725
  let names;
12746
12726
  try {
12747
12727
  names = await readdir3(traceDir);
@@ -12753,8 +12733,8 @@ var DaemonTraceBundleUploader = class {
12753
12733
  const currentFile = this.options.currentFileProvider?.();
12754
12734
  const candidates = [];
12755
12735
  for (const name of names.filter((entry) => entry.startsWith("daemon-trace-") && entry.endsWith(".jsonl")).sort()) {
12756
- const file = path16.join(traceDir, name);
12757
- if (currentFile && path16.resolve(file) === path16.resolve(currentFile)) continue;
12736
+ const file = path14.join(traceDir, name);
12737
+ if (currentFile && path14.resolve(file) === path14.resolve(currentFile)) continue;
12758
12738
  if (await this.isUploaded(file)) continue;
12759
12739
  try {
12760
12740
  const info = await stat3(file);
@@ -12828,8 +12808,8 @@ var DaemonTraceBundleUploader = class {
12828
12808
  }
12829
12809
  }
12830
12810
  uploadStatePath(file) {
12831
- const stateDir = path16.join(this.options.machineDir, "trace-uploads");
12832
- return path16.join(stateDir, `${path16.basename(file)}.uploaded.json`);
12811
+ const stateDir = path14.join(this.options.machineDir, "trace-uploads");
12812
+ return path14.join(stateDir, `${path14.basename(file)}.uploaded.json`);
12833
12813
  }
12834
12814
  async isUploaded(file) {
12835
12815
  try {
@@ -12841,9 +12821,9 @@ var DaemonTraceBundleUploader = class {
12841
12821
  }
12842
12822
  async markUploaded(file, metadata) {
12843
12823
  const stateFile = this.uploadStatePath(file);
12844
- await mkdir2(path16.dirname(stateFile), { recursive: true, mode: 448 });
12824
+ await mkdir2(path14.dirname(stateFile), { recursive: true, mode: 448 });
12845
12825
  await writeFile2(stateFile, `${JSON.stringify({
12846
- file: path16.basename(file),
12826
+ file: path14.basename(file),
12847
12827
  uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
12848
12828
  ...metadata
12849
12829
  }, null, 2)}
@@ -12865,7 +12845,7 @@ var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
12865
12845
  var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
12866
12846
  var RUNNER_CREDENTIAL_MINT_MAX_ATTEMPTS2 = 3;
12867
12847
  var RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2 = 250;
12868
- var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
12848
+ var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
12869
12849
  var RunnerCredentialMintError2 = class extends Error {
12870
12850
  code;
12871
12851
  retryable;
@@ -12901,9 +12881,9 @@ function runnerCredentialErrorDetail2(error) {
12901
12881
  async function waitForRunnerCredentialRetry2() {
12902
12882
  await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
12903
12883
  }
12904
- function parseDaemonCliArgs(args, env = {}) {
12884
+ function parseDaemonCliArgs(args) {
12905
12885
  let serverUrl = "";
12906
- let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
12886
+ let apiKey = "";
12907
12887
  for (let i = 0; i < args.length; i++) {
12908
12888
  if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
12909
12889
  if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
@@ -12919,24 +12899,14 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
12919
12899
  return "0.0.0-dev";
12920
12900
  }
12921
12901
  }
12922
- function resolveChatBridgePath(moduleUrl = import.meta.url) {
12923
- const dirname = path17.dirname(fileURLToPath(moduleUrl));
12924
- const jsPath = path17.resolve(dirname, "chat-bridge.js");
12925
- try {
12926
- accessSync(jsPath);
12927
- return jsPath;
12928
- } catch {
12929
- return path17.resolve(dirname, "chat-bridge.ts");
12930
- }
12931
- }
12932
12902
  function resolveSlockCliPath(moduleUrl = import.meta.url) {
12933
- const thisDir = path17.dirname(fileURLToPath(moduleUrl));
12934
- const bundledDistPath = path17.resolve(thisDir, "cli", "index.js");
12903
+ const thisDir = path15.dirname(fileURLToPath(moduleUrl));
12904
+ const bundledDistPath = path15.resolve(thisDir, "cli", "index.js");
12935
12905
  try {
12936
12906
  accessSync(bundledDistPath);
12937
12907
  return bundledDistPath;
12938
12908
  } catch {
12939
- const workspaceDistPath = path17.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
12909
+ const workspaceDistPath = path15.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
12940
12910
  accessSync(workspaceDistPath);
12941
12911
  return workspaceDistPath;
12942
12912
  }
@@ -13073,7 +13043,6 @@ var DaemonCore = class {
13073
13043
  // bundle version). Reported in `ready` so the server can surface the
13074
13044
  // Computer's own version (distinct from the underlying daemonVersion).
13075
13045
  computerVersion;
13076
- chatBridgePath;
13077
13046
  slockCliPath;
13078
13047
  slockHome;
13079
13048
  runtimeDetector;
@@ -13089,7 +13058,6 @@ var DaemonCore = class {
13089
13058
  this.options = options;
13090
13059
  this.daemonVersion = options.daemonVersion ?? readDaemonVersion();
13091
13060
  this.computerVersion = (process.env.SLOCK_COMPUTER_VERSION || "").trim() || null;
13092
- this.chatBridgePath = options.chatBridgePath ?? resolveChatBridgePath();
13093
13061
  this.slockCliPath = options.slockCliPath ?? resolveSlockCliPath();
13094
13062
  this.slockHome = resolveSlockHome();
13095
13063
  process.env[SLOCK_HOME_ENV] = this.slockHome;
@@ -13110,7 +13078,7 @@ var DaemonCore = class {
13110
13078
  daemonVersion: this.daemonVersion,
13111
13079
  computerVersion: this.computerVersion
13112
13080
  };
13113
- this.agentManager = options.agentManagerFactory ? options.agentManagerFactory(this.chatBridgePath, (msg) => connection.send(msg), options.apiKey, agentManagerOptions) : new AgentProcessManager(this.chatBridgePath, (msg) => connection.send(msg), options.apiKey, agentManagerOptions);
13081
+ this.agentManager = options.agentManagerFactory ? options.agentManagerFactory((msg) => connection.send(msg), options.apiKey, agentManagerOptions) : new AgentProcessManager((msg) => connection.send(msg), options.apiKey, agentManagerOptions);
13114
13082
  const connectionFactory = options.connectionFactory ?? ((connOptions) => new DaemonConnection(connOptions));
13115
13083
  connection = connectionFactory({
13116
13084
  serverUrl: options.serverUrl,
@@ -13125,7 +13093,7 @@ var DaemonCore = class {
13125
13093
  }
13126
13094
  resolveMachineStateRoot() {
13127
13095
  if (this.options.machineStateDir) return this.options.machineStateDir;
13128
- if (this.options.dataDir) return path17.join(path17.dirname(this.options.dataDir), "machines");
13096
+ if (this.options.dataDir) return path15.join(path15.dirname(this.options.dataDir), "machines");
13129
13097
  return resolveDefaultMachineStateRoot();
13130
13098
  }
13131
13099
  shouldEnableLocalTrace() {
@@ -13151,7 +13119,7 @@ var DaemonCore = class {
13151
13119
  sink: this.localTraceSink
13152
13120
  }));
13153
13121
  this.agentManager.setTracer(this.tracer);
13154
- this.agentManager.setCliTransportTraceDir(path17.join(machineDir, "traces"));
13122
+ this.agentManager.setCliTransportTraceDir(path15.join(machineDir, "traces"));
13155
13123
  }
13156
13124
  installTraceBundleUploader(machineDir) {
13157
13125
  if (!this.shouldEnableLocalTrace()) return;
@@ -13684,15 +13652,13 @@ var DaemonCore = class {
13684
13652
  };
13685
13653
 
13686
13654
  export {
13687
- DAEMON_API_KEY_ENV,
13688
- scrubDaemonAuthEnv,
13655
+ subscribeDaemonLogs,
13689
13656
  resolveWorkspaceDirectoryPath,
13690
13657
  scanWorkspaceDirectories,
13691
13658
  deleteWorkspaceDirectory,
13692
13659
  DAEMON_CLI_USAGE,
13693
13660
  parseDaemonCliArgs,
13694
13661
  readDaemonVersion,
13695
- resolveChatBridgePath,
13696
13662
  resolveSlockCliPath,
13697
13663
  detectRuntimes,
13698
13664
  DaemonCore