@botiverse/raft-daemon 1.0.7 → 1.0.8

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
  // src/core.ts
2
- import path23 from "path";
3
- import os8 from "os";
2
+ import path25 from "path";
3
+ import os11 from "os";
4
4
  import { randomUUID as randomUUID9 } from "crypto";
5
5
  import { createRequire as createRequire3 } from "module";
6
6
  import { accessSync, createReadStream as createReadStream4, createWriteStream as createWriteStream2 } from "fs";
@@ -1974,16 +1974,16 @@ var KNOWN_TOOL_ALIASES = {
1974
1974
  collab_tool_call: "collab_tool_call"
1975
1975
  };
1976
1976
  var MCP_CHAT_NAMESPACE_PREFIXES = ["mcp__chat__", "mcp_chat_"];
1977
- function normalizeToolLookupName(toolName) {
1977
+ function normalizeToolLookupName(toolName2) {
1978
1978
  for (const prefix of MCP_CHAT_NAMESPACE_PREFIXES) {
1979
- if (toolName.startsWith(prefix)) {
1980
- return toolName.slice(prefix.length);
1979
+ if (toolName2.startsWith(prefix)) {
1980
+ return toolName2.slice(prefix.length);
1981
1981
  }
1982
1982
  }
1983
- return toolName;
1983
+ return toolName2;
1984
1984
  }
1985
- function stripToolNamespace(toolName) {
1986
- const normalized = normalizeToolLookupName(toolName);
1985
+ function stripToolNamespace(toolName2) {
1986
+ const normalized = normalizeToolLookupName(toolName2);
1987
1987
  return normalized.replace(/^mcp__\w+__/, "");
1988
1988
  }
1989
1989
  function truncateLabel(text, max = 20) {
@@ -1997,8 +1997,8 @@ function formatTaskNumbers(value) {
1997
1997
  function asObject(input) {
1998
1998
  return input && typeof input === "object" ? input : null;
1999
1999
  }
2000
- function resolveToolSemantic(toolName) {
2001
- const normalized = normalizeToolLookupName(toolName);
2000
+ function resolveToolSemantic(toolName2) {
2001
+ const normalized = normalizeToolLookupName(toolName2);
2002
2002
  return KNOWN_TOOL_ALIASES[normalized] ?? null;
2003
2003
  }
2004
2004
  function tokenizeShellCommand(command) {
@@ -2114,8 +2114,8 @@ function readOptionValue(args, flag) {
2114
2114
  function parsePositiveIntegers(args, flag) {
2115
2115
  return readOptionValues(args, flag).map((value) => Number(value)).filter((value) => Number.isFinite(value) && Number.isInteger(value) && value > 0);
2116
2116
  }
2117
- function resolveSlockCliInvocation(toolName, input) {
2118
- if (resolveToolSemantic(toolName) !== "bash") return null;
2117
+ function resolveSlockCliInvocation(toolName2, input) {
2118
+ if (resolveToolSemantic(toolName2) !== "bash") return null;
2119
2119
  const value = asObject(input);
2120
2120
  if (!value || typeof value.command !== "string") return null;
2121
2121
  const tokens = tokenizeShellCommand(value.command);
@@ -2129,7 +2129,7 @@ function resolveSlockCliInvocation(toolName, input) {
2129
2129
  if (isShellExecutableToken(tokens[firstExecutableIndex])) {
2130
2130
  const innerCommand = unwrapShellPayload(tokens, firstExecutableIndex);
2131
2131
  if (innerCommand) {
2132
- return resolveSlockCliInvocation(toolName, { command: innerCommand });
2132
+ return resolveSlockCliInvocation(toolName2, { command: innerCommand });
2133
2133
  }
2134
2134
  }
2135
2135
  const executableIndex = findSlockExecutableIndex(tokens);
@@ -2242,16 +2242,16 @@ function resolveSlockCliInvocation(toolName, input) {
2242
2242
  return null;
2243
2243
  }
2244
2244
  }
2245
- function normalizeToolDisplayInvocation(toolName, input) {
2246
- return resolveSlockCliInvocation(toolName, input) ?? { toolName, input };
2245
+ function normalizeToolDisplayInvocation(toolName2, input) {
2246
+ return resolveSlockCliInvocation(toolName2, input) ?? { toolName: toolName2, input };
2247
2247
  }
2248
- function getToolActivityLabel(toolName) {
2249
- const semantic = resolveToolSemantic(toolName);
2248
+ function getToolActivityLabel(toolName2) {
2249
+ const semantic = resolveToolSemantic(toolName2);
2250
2250
  if (semantic) return TOOL_DISPLAY_METADATA[semantic].activityLabel;
2251
- return `Using ${truncateLabel(stripToolNamespace(toolName))}\u2026`;
2251
+ return `Using ${truncateLabel(stripToolNamespace(toolName2))}\u2026`;
2252
2252
  }
2253
- function summarizeToolInput(toolName, input) {
2254
- const semantic = resolveToolSemantic(toolName);
2253
+ function summarizeToolInput(toolName2, input) {
2254
+ const semantic = resolveToolSemantic(toolName2);
2255
2255
  const value = asObject(input);
2256
2256
  if (!semantic || !value) return "";
2257
2257
  switch (TOOL_DISPLAY_METADATA[semantic].summaryKind) {
@@ -2842,6 +2842,7 @@ var agentApiIntegrationAppUpdateBodySchema = passthroughObject({
2842
2842
  clientKey: z3.string().trim().min(1),
2843
2843
  name: optionalStringSchema,
2844
2844
  description: optionalStringSchema,
2845
+ category: z3.string().trim().min(1).optional(),
2845
2846
  homepageUrl: optionalStringSchema,
2846
2847
  returnUrl: optionalStringSchema,
2847
2848
  agentManifestUrl: optionalStringSchema,
@@ -4242,6 +4243,20 @@ var RAFT_OAUTH_SCOPES_SUPPORTED = Object.keys(RAFT_OAUTH_SCOPE_CATALOG);
4242
4243
  var RAFT_OAUTH_DEFAULT_ALLOWED_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].defaultAllowed);
4243
4244
  var RAFT_OAUTH_PUBLIC_DISCOVERY_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].publicDiscovery);
4244
4245
 
4246
+ // ../shared/src/oauthClientCategories.ts
4247
+ var OAUTH_CLIENT_CATEGORIES = [
4248
+ "AI & Automation",
4249
+ "Communication",
4250
+ "Productivity & Collaboration",
4251
+ "Developer Tools",
4252
+ "Data & Analytics",
4253
+ "Business Ops",
4254
+ "Infrastructure",
4255
+ "Content & Creative",
4256
+ "Other"
4257
+ ];
4258
+ var OAUTH_CLIENT_CATEGORY_SET = new Set(OAUTH_CLIENT_CATEGORIES);
4259
+
4245
4260
  // ../shared/src/testing/failpoints.ts
4246
4261
  var NoopFailpointRegistry = class {
4247
4262
  get enabled() {
@@ -4565,16 +4580,20 @@ var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
4565
4580
  var RUNTIMES = [
4566
4581
  { id: "claude", displayName: "Claude Code", abbreviation: "CC", binary: "claude", supported: true },
4567
4582
  { id: "codex", displayName: "Codex CLI", abbreviation: "CX", binary: "codex", supported: true },
4583
+ { id: "grok", displayName: "Grok Build", abbreviation: "GK", binary: "grok", supported: true },
4568
4584
  { id: "builtin", displayName: "Built-in Pi", abbreviation: "BP", binary: "", supported: true },
4569
4585
  { id: "antigravity", displayName: "Antigravity CLI", abbreviation: "AG", binary: "agy", supported: true },
4570
4586
  // Kimi: prefer the in-process SDK (`kimi-sdk` → "Kimi Code") for new agents.
4571
4587
  // The legacy `kimi` (kimi-cli child-process) entry stays for backward compat
4572
4588
  // with existing `runtime=kimi` agents but is labelled deprecated.
4573
4589
  { id: "kimi-sdk", displayName: "Kimi Code", abbreviation: "KC", binary: "", supported: true },
4574
- { id: "kimi", displayName: "Kimi CLI (deprecated)", abbreviation: "KL", binary: "kimi", supported: true },
4590
+ { id: "kimi", displayName: "Kimi CLI (deprecated)", abbreviation: "KL", binary: "kimi", supported: true, deprecated: true },
4575
4591
  { id: "copilot", displayName: "Copilot CLI", abbreviation: "CP", binary: "copilot", supported: true },
4576
4592
  { id: "cursor", displayName: "Cursor CLI", abbreviation: "CU", binary: "cursor-agent", supported: true },
4577
- { id: "gemini", displayName: "Gemini CLI", abbreviation: "GM", binary: "gemini", supported: true },
4593
+ // Gemini CLI: deprecated no longer maintained upstream, replaced by
4594
+ // Antigravity CLI (`antigravity` → "Antigravity CLI"). Kept for backward
4595
+ // compat with existing `runtime=gemini` agents but hidden from selectors.
4596
+ { id: "gemini", displayName: "Gemini CLI (deprecated)", abbreviation: "GM", binary: "gemini", supported: true, deprecated: true },
4578
4597
  { id: "opencode", displayName: "OpenCode", abbreviation: "OC", binary: "opencode", supported: true },
4579
4598
  { id: "pi", displayName: "Pi", abbreviation: "PI", binary: "pi", supported: true }
4580
4599
  ];
@@ -4629,6 +4648,20 @@ var RUNTIME_MODELS = {
4629
4648
  { id: "gpt-5-codex", label: "GPT-5 Codex" },
4630
4649
  { id: "gpt-5", label: "GPT-5" }
4631
4650
  ],
4651
+ grok: [
4652
+ {
4653
+ id: "grok-4.5",
4654
+ label: "Grok 4.5",
4655
+ supportedReasoningEfforts: ["high", "medium", "low"],
4656
+ defaultReasoningEffort: "high",
4657
+ verified: "launchable"
4658
+ },
4659
+ {
4660
+ id: "grok-composer-2.5-fast",
4661
+ label: "Composer 2.5",
4662
+ verified: "launchable"
4663
+ }
4664
+ ],
4632
4665
  antigravity: [
4633
4666
  { id: "default", label: "AGY configured default", verified: "suggestion_only" }
4634
4667
  ],
@@ -5010,12 +5043,12 @@ var TRIAL_END_DATE = /* @__PURE__ */ new Date("2026-06-23T12:00:00Z");
5010
5043
  var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()) / (24 * 60 * 60 * 1e3);
5011
5044
 
5012
5045
  // src/agentProcessManager.ts
5013
- import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, statSync, writeFileSync as writeFileSync4 } from "fs";
5046
+ import { readFileSync as readFileSync7 } from "fs";
5014
5047
  import { readdir as readdir2, stat as stat2, readFile, rm as rm2, lstat, realpath, open } from "fs/promises";
5015
5048
  import { createHash as createHash3, randomUUID as randomUUID6 } from "crypto";
5016
- import path14 from "path";
5049
+ import path16 from "path";
5017
5050
  import { gzipSync } from "zlib";
5018
- import os6 from "os";
5051
+ import os9 from "os";
5019
5052
 
5020
5053
  // src/proxy.ts
5021
5054
  import { HttpsProxyAgent } from "https-proxy-agent";
@@ -5231,10 +5264,10 @@ var ChatBridgeToolTimeoutError = class extends Error {
5231
5264
  target;
5232
5265
  timeoutMs;
5233
5266
  durationMs;
5234
- constructor(toolName, target, timeoutMs, durationMs) {
5235
- super(`${toolName} timed out after ${timeoutMs}ms${target ? ` (target: ${target})` : ""}`);
5267
+ constructor(toolName2, target, timeoutMs, durationMs) {
5268
+ super(`${toolName2} timed out after ${timeoutMs}ms${target ? ` (target: ${target})` : ""}`);
5236
5269
  this.name = "ChatBridgeToolTimeoutError";
5237
- this.toolName = toolName;
5270
+ this.toolName = toolName2;
5238
5271
  this.target = target;
5239
5272
  this.timeoutMs = timeoutMs;
5240
5273
  this.durationMs = durationMs;
@@ -5245,7 +5278,7 @@ function describeError(err) {
5245
5278
  return String(err);
5246
5279
  }
5247
5280
  async function executeJsonRequest(url, init, {
5248
- toolName,
5281
+ toolName: toolName2,
5249
5282
  target = null,
5250
5283
  timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
5251
5284
  fetchImpl,
@@ -5269,12 +5302,12 @@ async function executeJsonRequest(url, init, {
5269
5302
  const durationMs = now() - startedAt;
5270
5303
  if (timeoutController.signal.aborted && !init.signal?.aborted) {
5271
5304
  warn(
5272
- `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
5305
+ `[ChatBridgeTimeout] tool=${toolName2} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
5273
5306
  );
5274
- throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
5307
+ throw new ChatBridgeToolTimeoutError(toolName2, target, timeoutMs, durationMs);
5275
5308
  }
5276
5309
  warn(
5277
- `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
5310
+ `[ChatBridgeError] tool=${toolName2} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
5278
5311
  );
5279
5312
  throw err;
5280
5313
  } finally {
@@ -5282,7 +5315,7 @@ async function executeJsonRequest(url, init, {
5282
5315
  }
5283
5316
  }
5284
5317
  async function executeResponseRequest(url, init, {
5285
- toolName,
5318
+ toolName: toolName2,
5286
5319
  target = null,
5287
5320
  timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
5288
5321
  fetchImpl,
@@ -5305,12 +5338,12 @@ async function executeResponseRequest(url, init, {
5305
5338
  const durationMs = now() - startedAt;
5306
5339
  if (timeoutController.signal.aborted && !init.signal?.aborted) {
5307
5340
  warn(
5308
- `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
5341
+ `[ChatBridgeTimeout] tool=${toolName2} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
5309
5342
  );
5310
- throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
5343
+ throw new ChatBridgeToolTimeoutError(toolName2, target, timeoutMs, durationMs);
5311
5344
  }
5312
5345
  warn(
5313
- `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
5346
+ `[ChatBridgeError] tool=${toolName2} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
5314
5347
  );
5315
5348
  throw err;
5316
5349
  } finally {
@@ -5319,8 +5352,8 @@ async function executeResponseRequest(url, init, {
5319
5352
  }
5320
5353
 
5321
5354
  // src/directUploadCapability.ts
5322
- function joinUrl(base, path24) {
5323
- return `${base.replace(/\/+$/, "")}${path24}`;
5355
+ function joinUrl(base, path26) {
5356
+ return `${base.replace(/\/+$/, "")}${path26}`;
5324
5357
  }
5325
5358
  function jsonHeaders(apiKey) {
5326
5359
  return {
@@ -9252,7 +9285,7 @@ function codexNotificationDiagnosticEvent(message) {
9252
9285
  return null;
9253
9286
  }
9254
9287
  const sessionId = codexMessageThreadId(message);
9255
- const path24 = boundedString(params.path);
9288
+ const path26 = boundedString(params.path);
9256
9289
  return {
9257
9290
  kind: "runtime_diagnostic",
9258
9291
  severity: "warning",
@@ -9260,7 +9293,7 @@ function codexNotificationDiagnosticEvent(message) {
9260
9293
  itemType: message.method,
9261
9294
  message: diagnosticMessage,
9262
9295
  ...details ? { details } : {},
9263
- ...path24 ? { path: path24 } : {},
9296
+ ...path26 ? { path: path26 } : {},
9264
9297
  ...params.range !== void 0 ? { range: params.range } : {},
9265
9298
  payloadBytes: payloadBytes(params),
9266
9299
  ...sessionId ? { sessionId } : {}
@@ -9625,13 +9658,13 @@ var CodexEventNormalizer = class {
9625
9658
  break;
9626
9659
  case "mcpToolCall":
9627
9660
  if (isStarted) {
9628
- const toolName = codexMcpToolName(item);
9661
+ const toolName2 = codexMcpToolName(item);
9629
9662
  this.turnState.markProgress();
9630
- events.push({ kind: "tool_call", name: toolName, input: item.arguments });
9663
+ events.push({ kind: "tool_call", name: toolName2, input: item.arguments });
9631
9664
  }
9632
9665
  if (isCompleted) {
9633
- const toolName = codexMcpToolName(item);
9634
- events.push({ kind: "tool_output", name: toolName });
9666
+ const toolName2 = codexMcpToolName(item);
9667
+ events.push({ kind: "tool_output", name: toolName2 });
9635
9668
  this.turnState.markToolBoundary();
9636
9669
  }
9637
9670
  break;
@@ -10557,153 +10590,1009 @@ function detectCodexModels(home = resolveCodexHomeRootFromEnv()) {
10557
10590
  return { models, default: defaultModel };
10558
10591
  }
10559
10592
 
10560
- // src/drivers/antigravity.ts
10561
- import { randomUUID } from "crypto";
10562
- import { spawn as spawn3 } from "child_process";
10563
- var DEFAULT_PRINT_TIMEOUT = "30m";
10564
- var ANTIGRAVITY_ENV_OVERRIDES = {
10565
- // `agy` switches to a separate file-based token store when it detects an SSH
10566
- // session. Daemon agents commonly run under SSH-managed hosts, while the
10567
- // human login lives in the normal local Antigravity credential store.
10568
- SSH_CLIENT: void 0,
10569
- SSH_CONNECTION: void 0,
10570
- SSH_TTY: void 0
10571
- };
10572
- function resolveAntigravitySpawn(commandArgs, deps = {}) {
10573
- const command = resolveCommandOnPath("agy", deps) ?? "agy";
10593
+ // src/drivers/grok.ts
10594
+ import { execFileSync as execFileSync3, spawn as spawn3 } from "child_process";
10595
+ import os5 from "os";
10596
+
10597
+ // src/drivers/grokHome.ts
10598
+ import os4 from "os";
10599
+ import path8 from "path";
10600
+ function nonEmptyString3(value) {
10601
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
10602
+ }
10603
+ function resolveGrokHomeFromEnv(env = process.env, opts = {}) {
10604
+ const cwd = opts.cwd ?? process.cwd();
10605
+ const configured = nonEmptyString3(env.GROK_HOME);
10606
+ if (configured) return path8.resolve(cwd, configured);
10607
+ const homeDir = opts.homeDir ?? env.HOME ?? env.USERPROFILE ?? os4.homedir();
10608
+ return path8.join(homeDir, ".grok");
10609
+ }
10610
+
10611
+ // src/drivers/grokEventNormalizer.ts
10612
+ var TERMINAL_TOOL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
10613
+ function parseGrokJsonRpcLine(line) {
10614
+ try {
10615
+ const parsed = JSON.parse(line);
10616
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
10617
+ } catch {
10618
+ return null;
10619
+ }
10620
+ }
10621
+ function nonEmptyString4(value) {
10622
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
10623
+ }
10624
+ function recordValue(value) {
10625
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
10626
+ }
10627
+ function payloadBytes3(value) {
10628
+ try {
10629
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
10630
+ } catch {
10631
+ return void 0;
10632
+ }
10633
+ }
10634
+ function internalProgress(itemType, payload) {
10574
10635
  return {
10575
- command,
10576
- args: commandArgs,
10577
- shell: requiresWindowsShell(command, deps.platform)
10636
+ kind: "internal_progress",
10637
+ source: "grok_acp_notification",
10638
+ itemType,
10639
+ payloadBytes: payloadBytes3(payload)
10578
10640
  };
10579
10641
  }
10580
- function buildAntigravityArgs(ctx) {
10581
- const args = [
10582
- "--print",
10583
- "--print-timeout",
10584
- runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars?.ANTIGRAVITY_PRINT_TIMEOUT || DEFAULT_PRINT_TIMEOUT,
10585
- "--dangerously-skip-permissions"
10586
- ];
10587
- if (ctx.config.sessionId) {
10588
- args.push("--continue");
10642
+ function toolName(update, fallback = "tool") {
10643
+ const meta = recordValue(update._meta);
10644
+ const tool = recordValue(meta?.["x.ai/tool"]);
10645
+ return nonEmptyString4(tool?.name) ?? nonEmptyString4(update.name) ?? nonEmptyString4(update.title) ?? fallback;
10646
+ }
10647
+ function parseAccumulatedArguments(value) {
10648
+ if (!value) return {};
10649
+ try {
10650
+ return JSON.parse(value);
10651
+ } catch {
10652
+ return { arguments: value };
10589
10653
  }
10590
- return args;
10591
10654
  }
10592
- var ERROR_LINE_PREFIX_RE = /^(?:(?:error|fatal|exception|failure):\s*|failed(?:\b|:))/i;
10593
- var ERROR_LINE_PATTERNS = [
10594
- /authentication timed out/i,
10595
- /\bpermission denied\b/i,
10596
- /\bunauthorized\b/i,
10597
- /\brate limit(?:ed)?\b/i,
10598
- /\bserver error\b/i,
10599
- /\bnetwork error\b/i,
10600
- /\brequest timed out\b/i,
10601
- /\btimed out waiting\b/i,
10602
- /\b(?:http|status)\s+(?:401|403|429|500|502|503|504)\b/i
10603
- ];
10604
- function isErrorLine(line) {
10605
- return ERROR_LINE_PREFIX_RE.test(line) || ERROR_LINE_PATTERNS.some((pattern) => pattern.test(line));
10655
+ function numericUsageAttrs(value) {
10656
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
10657
+ const source = value;
10658
+ const mappings = [
10659
+ ["inputTokens", "input_tokens"],
10660
+ ["outputTokens", "output_tokens"],
10661
+ ["totalTokens", "total_tokens"],
10662
+ ["cachedReadTokens", "cached_read_tokens"],
10663
+ ["reasoningTokens", "reasoning_tokens"],
10664
+ ["modelCalls", "model_calls"],
10665
+ ["apiDurationMs", "api_duration_ms"],
10666
+ ["numTurns", "num_turns"]
10667
+ ];
10668
+ const attrs = {};
10669
+ for (const [wireKey, attrKey] of mappings) {
10670
+ const candidate = source[wireKey];
10671
+ if (typeof candidate === "number" && Number.isFinite(candidate)) {
10672
+ attrs[attrKey] = candidate;
10673
+ }
10674
+ }
10675
+ return attrs;
10606
10676
  }
10607
- var AntigravityDriver = class {
10608
- id = "antigravity";
10609
- lifecycle = {
10610
- kind: "per_turn",
10611
- start: "immediate",
10612
- exit: "natural",
10613
- inFlightWake: "spawn_new"
10614
- };
10615
- communication = {
10616
- chat: "slock_cli",
10617
- runtimeControl: "none"
10618
- };
10619
- session = {
10620
- recovery: "resume_or_fresh"
10621
- };
10622
- model = {
10623
- detectedModelsVerifiedAs: "suggestion_only",
10624
- toLaunchSpec: (_modelId) => ({ args: [] })
10625
- };
10626
- supportsStdinNotification = false;
10627
- busyDeliveryMode = "none";
10628
- sessionId = null;
10629
- sessionAnnounced = false;
10630
- probe() {
10631
- const command = resolveCommandOnPath("agy");
10632
- if (!command) return { available: false };
10633
- return {
10634
- available: true,
10635
- version: readCommandVersion(command) ?? void 0
10636
- };
10677
+ var GrokEventNormalizer = class {
10678
+ sessionIdValue = null;
10679
+ nextTurnGeneration = 0;
10680
+ activeTurnGeneration = null;
10681
+ completedTurnGenerations = /* @__PURE__ */ new Set();
10682
+ generationByPromptId = /* @__PURE__ */ new Map();
10683
+ promptIdsByGeneration = /* @__PURE__ */ new Map();
10684
+ toolCalls = /* @__PURE__ */ new Map();
10685
+ toolCallIdsByIndex = /* @__PURE__ */ new Map();
10686
+ reset() {
10687
+ this.sessionIdValue = null;
10688
+ this.nextTurnGeneration = 0;
10689
+ this.activeTurnGeneration = null;
10690
+ this.completedTurnGenerations.clear();
10691
+ this.generationByPromptId.clear();
10692
+ this.promptIdsByGeneration.clear();
10693
+ this.toolCalls.clear();
10694
+ this.toolCallIdsByIndex.clear();
10695
+ }
10696
+ get sessionId() {
10697
+ return this.sessionIdValue;
10637
10698
  }
10638
- async spawn(ctx) {
10639
- this.sessionId = ctx.config.sessionId || randomUUID();
10640
- this.sessionAnnounced = false;
10641
- const { command, args, shell } = resolveAntigravitySpawn(buildAntigravityArgs(ctx));
10642
- const { spawnEnv } = await prepareCliTransport(ctx, {
10643
- NO_COLOR: "1",
10644
- ...ANTIGRAVITY_ENV_OVERRIDES
10645
- });
10646
- const proc = spawn3(command, args, {
10647
- cwd: ctx.workingDirectory,
10648
- stdio: ["pipe", "pipe", "pipe"],
10649
- env: spawnEnv,
10650
- shell
10651
- });
10652
- proc.stdin?.end(ctx.prompt);
10653
- return { process: proc };
10699
+ get canSteerBusy() {
10700
+ return this.activeTurnGeneration !== null;
10701
+ }
10702
+ adoptSession(sessionId) {
10703
+ this.sessionIdValue = sessionId;
10704
+ }
10705
+ beginPrompt() {
10706
+ this.nextTurnGeneration += 1;
10707
+ this.activeTurnGeneration = this.nextTurnGeneration;
10708
+ this.toolCalls.clear();
10709
+ this.toolCallIdsByIndex.clear();
10710
+ return this.nextTurnGeneration;
10711
+ }
10712
+ abortPrompt(generation) {
10713
+ if (this.activeTurnGeneration === generation) {
10714
+ this.activeTurnGeneration = null;
10715
+ }
10716
+ this.forgetPromptIdsForGeneration(generation);
10717
+ }
10718
+ normalizeNotification(message) {
10719
+ const params = message.params ?? {};
10720
+ const notificationSessionId = nonEmptyString4(params.sessionId);
10721
+ if (notificationSessionId) {
10722
+ if (!this.sessionIdValue || notificationSessionId !== this.sessionIdValue) return [];
10723
+ }
10724
+ const update = recordValue(params.update);
10725
+ if (!update) {
10726
+ return message.method ? [internalProgress(message.method, params)] : [];
10727
+ }
10728
+ const updateKind = nonEmptyString4(update.sessionUpdate);
10729
+ if (!updateKind) return [internalProgress(message.method ?? "session/update", update)];
10730
+ switch (updateKind) {
10731
+ case "agent_message_chunk": {
10732
+ const content = recordValue(update.content);
10733
+ const text = content?.type === "text" ? content.text : null;
10734
+ return typeof text === "string" && text.length > 0 ? [{ kind: "text", text }] : [internalProgress(updateKind, update)];
10735
+ }
10736
+ case "agent_thought_chunk": {
10737
+ const content = recordValue(update.content);
10738
+ const text = content?.type === "text" ? content.text : null;
10739
+ return typeof text === "string" && text.length > 0 ? [{ kind: "thinking", text }] : [internalProgress(updateKind, update)];
10740
+ }
10741
+ case "tool_call_delta_chunk": {
10742
+ const index = typeof update.tool_index === "number" ? update.tool_index : null;
10743
+ const wireId = nonEmptyString4(update.tool_call_id);
10744
+ if (index !== null && wireId) this.toolCallIdsByIndex.set(index, wireId);
10745
+ const toolCallId = wireId ?? (index !== null ? this.toolCallIdsByIndex.get(index) ?? null : null);
10746
+ if (toolCallId) {
10747
+ const existing = this.toolCalls.get(toolCallId) ?? {
10748
+ name: toolName(update),
10749
+ arguments: "",
10750
+ callEmitted: false,
10751
+ outputEmitted: false
10752
+ };
10753
+ existing.name = toolName(update, existing.name);
10754
+ if (typeof update.arguments_delta === "string") {
10755
+ existing.arguments += update.arguments_delta;
10756
+ }
10757
+ this.toolCalls.set(toolCallId, existing);
10758
+ }
10759
+ return [internalProgress(updateKind, update)];
10760
+ }
10761
+ case "tool_call": {
10762
+ const toolCallId = nonEmptyString4(update.toolCallId) ?? `anonymous-${this.toolCalls.size + 1}`;
10763
+ const existing = this.toolCalls.get(toolCallId) ?? {
10764
+ name: toolName(update),
10765
+ arguments: "",
10766
+ callEmitted: false,
10767
+ outputEmitted: false
10768
+ };
10769
+ existing.name = toolName(update, existing.name);
10770
+ this.toolCalls.set(toolCallId, existing);
10771
+ if (existing.callEmitted) return [internalProgress(updateKind, update)];
10772
+ existing.callEmitted = true;
10773
+ return [{
10774
+ kind: "tool_call",
10775
+ name: existing.name,
10776
+ input: update.rawInput ?? parseAccumulatedArguments(existing.arguments)
10777
+ }];
10778
+ }
10779
+ case "tool_call_update": {
10780
+ const toolCallId = nonEmptyString4(update.toolCallId);
10781
+ const status = nonEmptyString4(update.status);
10782
+ if (!toolCallId || !status || !TERMINAL_TOOL_STATUSES.has(status)) {
10783
+ return [internalProgress(updateKind, update)];
10784
+ }
10785
+ const existing = this.toolCalls.get(toolCallId) ?? {
10786
+ name: toolName(update),
10787
+ arguments: "",
10788
+ callEmitted: false,
10789
+ outputEmitted: false
10790
+ };
10791
+ this.toolCalls.set(toolCallId, existing);
10792
+ if (existing.outputEmitted) return [internalProgress(updateKind, update)];
10793
+ existing.outputEmitted = true;
10794
+ return [{ kind: "tool_output", name: existing.name }];
10795
+ }
10796
+ case "pending_interaction":
10797
+ return [{
10798
+ kind: "runtime_diagnostic",
10799
+ severity: "warning",
10800
+ source: "grok_acp_notification",
10801
+ itemType: updateKind,
10802
+ message: "Grok Build is waiting for user interaction",
10803
+ payloadBytes: payloadBytes3(update),
10804
+ ...this.sessionIdValue ? { sessionId: this.sessionIdValue } : {}
10805
+ }];
10806
+ case "turn_completed": {
10807
+ const promptId = nonEmptyString4(update.prompt_id);
10808
+ const generation = promptId ? this.generationByPromptId.get(promptId) ?? this.activeTurnGeneration : this.activeTurnGeneration;
10809
+ return this.finishPrompt(generation, {
10810
+ stopReason: update.stop_reason,
10811
+ promptId,
10812
+ agentResult: update.agent_result,
10813
+ usage: update.usage
10814
+ });
10815
+ }
10816
+ default:
10817
+ return [internalProgress(updateKind, update)];
10818
+ }
10654
10819
  }
10655
- parseLine(line) {
10656
- const trimmed = line.trim();
10657
- if (!trimmed) return [];
10820
+ finishPrompt(generation, completion) {
10821
+ if (generation === null || generation === void 0) return [];
10822
+ const promptId = nonEmptyString4(completion.promptId) ?? void 0;
10823
+ if (promptId) this.rememberPromptGeneration(promptId, generation);
10824
+ if (this.completedTurnGenerations.has(generation)) return [];
10825
+ this.completedTurnGenerations.add(generation);
10826
+ if (this.completedTurnGenerations.size > 32) {
10827
+ const oldest = this.completedTurnGenerations.values().next().value;
10828
+ if (oldest !== void 0) {
10829
+ this.completedTurnGenerations.delete(oldest);
10830
+ this.forgetPromptIdsForGeneration(oldest);
10831
+ }
10832
+ }
10833
+ if (this.activeTurnGeneration === generation) {
10834
+ this.activeTurnGeneration = null;
10835
+ }
10836
+ const stopReason = nonEmptyString4(completion.stopReason) ?? "unknown";
10837
+ const agentResult = nonEmptyString4(completion.agentResult);
10658
10838
  const events = [];
10659
- if (!this.sessionAnnounced && this.sessionId) {
10660
- events.push({ kind: "session_init", sessionId: this.sessionId });
10661
- this.sessionAnnounced = true;
10839
+ const usageAttrs = numericUsageAttrs(completion.usage);
10840
+ if (Object.keys(usageAttrs).length > 0) {
10841
+ events.push({
10842
+ kind: "telemetry",
10843
+ name: "token_usage",
10844
+ source: "grok_acp",
10845
+ usageKind: "per_turn",
10846
+ ...this.sessionIdValue ? { sessionId: this.sessionIdValue } : {},
10847
+ ...promptId ? { turnId: promptId } : {},
10848
+ attrs: usageAttrs
10849
+ });
10662
10850
  }
10663
- if (isErrorLine(trimmed)) {
10664
- events.push({ kind: "error", message: trimmed });
10665
- return events;
10851
+ if (stopReason === "error") {
10852
+ events.push({ kind: "error", message: agentResult ?? "Grok Build turn failed" });
10853
+ } else if (stopReason === "cancelled") {
10854
+ events.push({ kind: "error", message: agentResult ?? "Grok Build turn was cancelled" });
10666
10855
  }
10667
- events.push({ kind: "text", text: line });
10856
+ events.push({ kind: "turn_end", ...this.sessionIdValue ? { sessionId: this.sessionIdValue } : {} });
10857
+ this.toolCalls.clear();
10858
+ this.toolCallIdsByIndex.clear();
10668
10859
  return events;
10669
10860
  }
10670
- encodeStdinMessage(_text, _sessionId, _opts) {
10671
- return null;
10672
- }
10673
- buildSystemPrompt(config, _agentId) {
10674
- return buildCliTransportSystemPrompt(config, {
10675
- extraCriticalRules: [],
10676
- postStartupNotes: [
10677
- "**Antigravity runtime note:** Slock launches you as a per-turn process. Complete the current wake using `slock` CLI commands, then stop; the daemon will restart you when new messages arrive."
10678
- ],
10679
- includeStdinNotificationSection: false,
10680
- messageNotificationStyle: "poll"
10681
- });
10861
+ rememberPromptGeneration(promptId, generation) {
10862
+ const existingGeneration = this.generationByPromptId.get(promptId);
10863
+ if (existingGeneration !== void 0) return;
10864
+ this.generationByPromptId.set(promptId, generation);
10865
+ const promptIds = this.promptIdsByGeneration.get(generation) ?? /* @__PURE__ */ new Set();
10866
+ promptIds.add(promptId);
10867
+ this.promptIdsByGeneration.set(generation, promptIds);
10682
10868
  }
10683
- async detectModels() {
10684
- return null;
10869
+ forgetPromptIdsForGeneration(generation) {
10870
+ const promptIds = this.promptIdsByGeneration.get(generation);
10871
+ if (!promptIds) return;
10872
+ for (const promptId of promptIds) {
10873
+ if (this.generationByPromptId.get(promptId) === generation) {
10874
+ this.generationByPromptId.delete(promptId);
10875
+ }
10876
+ }
10877
+ this.promptIdsByGeneration.delete(generation);
10685
10878
  }
10686
10879
  };
10687
10880
 
10688
- // src/drivers/copilot.ts
10689
- import { spawn as spawn4 } from "child_process";
10690
- async function buildCopilotSpawnEnv(ctx) {
10691
- return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
10881
+ // src/drivers/grok.ts
10882
+ var GROK_AGENT_ARGS = ["agent", "--no-leader", "--always-approve", "stdio"];
10883
+ var GROK_AGENT_PROBE_ARGS = ["agent", "stdio", "--help"];
10884
+ var GROK_INTERJECT_METHOD = "_x.ai/interject";
10885
+ var KNOWN_REASONING_EFFORTS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max", "ultra"]);
10886
+ function hasJsonRpcField2(message, field) {
10887
+ return Object.prototype.hasOwnProperty.call(message, field);
10692
10888
  }
10693
- var CopilotDriver = class {
10694
- id = "copilot";
10695
- lifecycle = {
10696
- kind: "per_turn",
10697
- start: "immediate",
10698
- exit: "natural",
10699
- inFlightWake: "spawn_new"
10889
+ function isJsonRpcResponse2(message) {
10890
+ return message.id !== void 0 && (hasJsonRpcField2(message, "result") || hasJsonRpcField2(message, "error"));
10891
+ }
10892
+ function isJsonRpcServerRequest(message) {
10893
+ return message.id !== void 0 && typeof message.method === "string" && !isJsonRpcResponse2(message);
10894
+ }
10895
+ function payloadBytes4(value) {
10896
+ try {
10897
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
10898
+ } catch {
10899
+ return void 0;
10900
+ }
10901
+ }
10902
+ function nonEmptyString5(value) {
10903
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
10904
+ }
10905
+ function recordValue2(value) {
10906
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
10907
+ }
10908
+ function describeProbeFailure(error) {
10909
+ if (error && typeof error === "object") {
10910
+ const candidate = error;
10911
+ if (typeof candidate.status === "number") return `exit status ${candidate.status}`;
10912
+ if (typeof candidate.signal === "string") return `terminated by ${candidate.signal}`;
10913
+ if (typeof candidate.code === "string") return candidate.code;
10914
+ }
10915
+ return "probe failed";
10916
+ }
10917
+ function readGrokVersion(command, shell, deps) {
10918
+ const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
10919
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
10920
+ try {
10921
+ const output = execFileSyncFn(command, ["--version"], {
10922
+ stdio: ["ignore", "pipe", "pipe"],
10923
+ env,
10924
+ timeout: 5e3,
10925
+ shell
10926
+ });
10927
+ return (Buffer.isBuffer(output) ? output.toString("utf8") : String(output ?? "")).trim().split(/\r?\n/)[0] || null;
10928
+ } catch {
10929
+ return null;
10930
+ }
10931
+ }
10932
+ function resolveGrokCommand(deps = {}) {
10933
+ return resolveCommandOnPath("grok", deps);
10934
+ }
10935
+ function resolveGrokSpawn(args, deps = {}) {
10936
+ const command = resolveGrokCommand(deps);
10937
+ if (!command) {
10938
+ throw new Error("Cannot resolve the Grok Build CLI on PATH. Install Grok Build and run `grok login` first.");
10939
+ }
10940
+ const platform = deps.platform ?? process.platform;
10941
+ return {
10942
+ command,
10943
+ args,
10944
+ shell: requiresWindowsShell(command, platform)
10700
10945
  };
10701
- communication = {
10702
- chat: "slock_cli",
10703
- runtimeControl: "none"
10946
+ }
10947
+ function probeGrok(deps = {}) {
10948
+ const command = resolveGrokCommand(deps);
10949
+ if (!command) {
10950
+ return { available: false, diagnostic: "No Grok Build CLI was found on PATH." };
10951
+ }
10952
+ const platform = deps.platform ?? process.platform;
10953
+ const shell = requiresWindowsShell(command, platform);
10954
+ const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
10955
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
10956
+ try {
10957
+ execFileSyncFn(command, [...GROK_AGENT_PROBE_ARGS], {
10958
+ stdio: ["ignore", "pipe", "pipe"],
10959
+ env,
10960
+ timeout: 5e3,
10961
+ shell
10962
+ });
10963
+ } catch (error) {
10964
+ return {
10965
+ available: false,
10966
+ diagnostic: `Grok Build agent stdio probe failed: ${describeProbeFailure(error)}.`
10967
+ };
10968
+ }
10969
+ return {
10970
+ available: true,
10971
+ version: readGrokVersion(command, shell, deps) ?? void 0
10704
10972
  };
10705
- session = {
10706
- recovery: "resume_or_fresh"
10973
+ }
10974
+ function initializeParams() {
10975
+ return {
10976
+ protocolVersion: 1,
10977
+ clientCapabilities: {
10978
+ fs: { readTextFile: false, writeTextFile: false },
10979
+ terminal: false
10980
+ },
10981
+ _meta: {
10982
+ startupHints: {
10983
+ nonInteractive: true,
10984
+ skipGitStatus: true,
10985
+ skipProjectLayout: true
10986
+ },
10987
+ clientType: "raft-daemon",
10988
+ clientVersion: "1.0.0"
10989
+ }
10990
+ };
10991
+ }
10992
+ function isCompatibleInitializeResult2(result) {
10993
+ const value = recordValue2(result);
10994
+ const capabilities = recordValue2(value?.agentCapabilities);
10995
+ return value?.protocolVersion === 1 && capabilities?.loadSession === true;
10996
+ }
10997
+ function initializeFailureMessage() {
10998
+ return "Grok Build ACP initialize response is missing protocolVersion=1 or loadSession support; upgrade Grok Build to a compatible release.";
10999
+ }
11000
+ function sessionIdFromResult(result, requestedSessionId) {
11001
+ const value = recordValue2(result);
11002
+ if (!value) return requestedSessionId ?? null;
11003
+ const meta = recordValue2(value._meta);
11004
+ return nonEmptyString5(value.sessionId) ?? nonEmptyString5(meta?.sessionId) ?? requestedSessionId ?? null;
11005
+ }
11006
+ function grokErrorMessage(message, fallback) {
11007
+ return nonEmptyString5(message.error?.message) ?? fallback;
11008
+ }
11009
+ function isMissingSessionError(error) {
11010
+ if (!error) return false;
11011
+ const code = error.data && typeof error.data === "object" && !Array.isArray(error.data) ? nonEmptyString5(error.data.code) : null;
11012
+ return code === "FS_NOT_FOUND" || /\b(path|session)\b.*\b(not found|missing)\b/i.test(error.message ?? "") || /\bno such file or directory\b/i.test(String(error.data ?? ""));
11013
+ }
11014
+ function recoveryEvents(requestedSessionId) {
11015
+ return {
11016
+ telemetry: {
11017
+ kind: "telemetry",
11018
+ name: "recovery",
11019
+ source: "grok_resume_missing_session",
11020
+ attrs: {
11021
+ resume_error_class: "missing_session",
11022
+ recovery_action: "fallback_fresh_thread"
11023
+ }
11024
+ },
11025
+ recovery: {
11026
+ kind: "runtime_recovery",
11027
+ source: "grok_resume_missing_session",
11028
+ resumeErrorClass: "missing_session",
11029
+ recoveryAction: "fallback_fresh_thread",
11030
+ message: "Grok Build could not resume its previous session; Raft started a fresh Grok session.",
11031
+ details: "Use Raft conversation history and local MEMORY.md/notes as the recovery point; do not assume prior Grok session context is loaded.",
11032
+ ...requestedSessionId ? { requestedSessionId } : {}
11033
+ }
11034
+ };
11035
+ }
11036
+ function prependRecoveryNotice(prompt, recovery) {
11037
+ return `${recovery.message}
11038
+
11039
+ ${recovery.details}
11040
+
11041
+ ${prompt}`;
11042
+ }
11043
+ function modelReasoningEfforts(meta) {
11044
+ const value = recordValue2(meta);
11045
+ if (!value) return { efforts: [] };
11046
+ const efforts = [];
11047
+ let defaultEffort;
11048
+ if (Array.isArray(value.reasoningEfforts)) {
11049
+ for (const entry of value.reasoningEfforts) {
11050
+ const entryRecord = recordValue2(entry);
11051
+ const effort = typeof entry === "string" ? nonEmptyString5(entry) : entryRecord ? nonEmptyString5(entryRecord.id) ?? nonEmptyString5(entryRecord.value) : null;
11052
+ if (!effort || !KNOWN_REASONING_EFFORTS.has(effort) || efforts.includes(effort)) continue;
11053
+ efforts.push(effort);
11054
+ if (entryRecord?.default === true) defaultEffort = effort;
11055
+ }
11056
+ }
11057
+ const current = nonEmptyString5(value.reasoningEffort);
11058
+ if (!defaultEffort && current && efforts.includes(current)) defaultEffort = current;
11059
+ return { efforts, ...defaultEffort ? { defaultEffort } : {} };
11060
+ }
11061
+ function grokModelSetFromInitializeResult(result) {
11062
+ const resultRecord = recordValue2(result);
11063
+ const meta = recordValue2(resultRecord?._meta);
11064
+ const modelState = recordValue2(meta?.modelState);
11065
+ if (!modelState || !Array.isArray(modelState.availableModels)) return null;
11066
+ const models = [];
11067
+ for (const candidate of modelState.availableModels) {
11068
+ const entry = recordValue2(candidate);
11069
+ if (!entry) continue;
11070
+ const id = nonEmptyString5(entry.modelId);
11071
+ if (!id) continue;
11072
+ const { efforts, defaultEffort } = modelReasoningEfforts(entry._meta);
11073
+ models.push({
11074
+ id,
11075
+ label: nonEmptyString5(entry.name) ?? id,
11076
+ verified: "launchable",
11077
+ ...efforts.length > 0 ? { supportedReasoningEfforts: efforts } : {},
11078
+ ...defaultEffort ? { defaultReasoningEffort: defaultEffort } : {}
11079
+ });
11080
+ }
11081
+ if (models.length === 0) return null;
11082
+ const current = nonEmptyString5(modelState.currentModelId);
11083
+ return {
11084
+ models,
11085
+ ...current && models.some((model) => model.id === current) ? { default: current } : {}
11086
+ };
11087
+ }
11088
+ var GrokDriver = class {
11089
+ id = "grok";
11090
+ lifecycle = {
11091
+ kind: "persistent",
11092
+ stdin: "direct",
11093
+ inFlightWake: "steer"
11094
+ };
11095
+ communication = {
11096
+ chat: "slock_cli",
11097
+ runtimeControl: "none"
11098
+ };
11099
+ stdoutChannel = "structured_protocol";
11100
+ session = { recovery: "resume_or_fresh" };
11101
+ model = {
11102
+ detectedModelsVerifiedAs: "launchable",
11103
+ toLaunchSpec: (modelId) => ({ params: { model: modelId } })
11104
+ };
11105
+ startupReadiness = "initial_turn";
11106
+ requiresSessionInitForDelivery = true;
11107
+ supportsStdinNotification = true;
11108
+ busyDeliveryMode = "direct";
11109
+ supportsNativeStandingPrompt = true;
11110
+ process = null;
11111
+ requestId = 0;
11112
+ initializeRequestId = null;
11113
+ pendingSessionRequestId = null;
11114
+ pendingSessionRequestMethod = null;
11115
+ pendingModelRequestId = null;
11116
+ pendingInitialPrompt = null;
11117
+ pendingDeliveryRequests = /* @__PURE__ */ new Map();
11118
+ requestedResumeSessionId = null;
11119
+ freshSessionParams = null;
11120
+ selectedModel = null;
11121
+ selectedReasoningEffort = null;
11122
+ normalizer = new GrokEventNormalizer();
11123
+ grokHomeRoot = null;
11124
+ get currentSessionId() {
11125
+ return this.normalizer.sessionId;
11126
+ }
11127
+ get currentRuntimeHomeDir() {
11128
+ return this.grokHomeRoot;
11129
+ }
11130
+ probe() {
11131
+ return probeGrok();
11132
+ }
11133
+ async spawn(ctx) {
11134
+ const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" });
11135
+ const launchFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
11136
+ this.process = null;
11137
+ this.requestId = 0;
11138
+ this.initializeRequestId = null;
11139
+ this.pendingSessionRequestId = null;
11140
+ this.pendingSessionRequestMethod = null;
11141
+ this.pendingSessionAfterInitialize = null;
11142
+ this.pendingModelRequestId = null;
11143
+ this.pendingInitialPrompt = ctx.prompt;
11144
+ this.pendingDeliveryRequests.clear();
11145
+ this.requestedResumeSessionId = nonEmptyString5(ctx.config.sessionId);
11146
+ this.selectedModel = launchFields.model === "default" ? null : nonEmptyString5(launchFields.model);
11147
+ this.selectedReasoningEffort = nonEmptyString5(launchFields.reasoningEffort);
11148
+ this.normalizer.reset();
11149
+ this.grokHomeRoot = resolveGrokHomeFromEnv(spawnEnv, {
11150
+ cwd: ctx.workingDirectory,
11151
+ homeDir: spawnEnv.HOME ?? spawnEnv.USERPROFILE ?? os5.homedir()
11152
+ });
11153
+ const meta = {
11154
+ systemPromptOverride: ctx.standingPrompt,
11155
+ yoloMode: true,
11156
+ ...this.selectedModel ? { modelId: this.selectedModel } : {}
11157
+ };
11158
+ this.freshSessionParams = {
11159
+ cwd: ctx.workingDirectory,
11160
+ mcpServers: [],
11161
+ _meta: meta
11162
+ };
11163
+ const sessionRequest = this.requestedResumeSessionId ? {
11164
+ method: "session/load",
11165
+ params: {
11166
+ sessionId: this.requestedResumeSessionId,
11167
+ cwd: ctx.workingDirectory,
11168
+ mcpServers: [],
11169
+ _meta: meta
11170
+ }
11171
+ } : { method: "session/new", params: this.freshSessionParams };
11172
+ const launch = resolveGrokSpawn([...GROK_AGENT_ARGS], { env: spawnEnv });
11173
+ const proc = spawn3(launch.command, launch.args, {
11174
+ cwd: ctx.workingDirectory,
11175
+ stdio: ["pipe", "pipe", "pipe"],
11176
+ env: spawnEnv,
11177
+ shell: launch.shell
11178
+ });
11179
+ this.process = proc;
11180
+ queueMicrotask(() => {
11181
+ this.pendingSessionAfterInitialize = sessionRequest;
11182
+ this.initializeRequestId = this.sendRequest("initialize", initializeParams());
11183
+ });
11184
+ return { process: proc };
11185
+ }
11186
+ pendingSessionAfterInitialize = null;
11187
+ parseLine(line) {
11188
+ const message = parseGrokJsonRpcLine(line);
11189
+ if (!message) return [];
11190
+ if (isJsonRpcServerRequest(message)) {
11191
+ this.sendErrorResponse(message.id, `Grok ACP client request "${message.method}" is not supported by the non-interactive Raft daemon`);
11192
+ return [];
11193
+ }
11194
+ if (!isJsonRpcResponse2(message)) {
11195
+ return this.normalizer.normalizeNotification(message);
11196
+ }
11197
+ if (message.id === this.initializeRequestId) {
11198
+ this.initializeRequestId = null;
11199
+ if (hasJsonRpcField2(message, "error")) {
11200
+ this.pendingSessionAfterInitialize = null;
11201
+ return [{
11202
+ kind: "error",
11203
+ message: grokErrorMessage(message, "Grok Build ACP initialize failed"),
11204
+ startupRequestMethod: "initialize"
11205
+ }];
11206
+ }
11207
+ if (!isCompatibleInitializeResult2(message.result)) {
11208
+ this.pendingSessionAfterInitialize = null;
11209
+ return [{ kind: "error", message: initializeFailureMessage(), startupRequestMethod: "initialize" }];
11210
+ }
11211
+ if (this.pendingSessionAfterInitialize) {
11212
+ const pending = this.pendingSessionAfterInitialize;
11213
+ this.pendingSessionAfterInitialize = null;
11214
+ this.sendSessionRequest(pending.method, pending.params);
11215
+ }
11216
+ return [];
11217
+ }
11218
+ if (message.id === this.pendingSessionRequestId) {
11219
+ const requestMethod = this.pendingSessionRequestMethod;
11220
+ this.pendingSessionRequestId = null;
11221
+ this.pendingSessionRequestMethod = null;
11222
+ if (hasJsonRpcField2(message, "error")) {
11223
+ if (requestMethod === "session/load" && isMissingSessionError(message.error) && this.freshSessionParams) {
11224
+ const recovery = recoveryEvents(this.requestedResumeSessionId);
11225
+ if (this.pendingInitialPrompt !== null) {
11226
+ this.pendingInitialPrompt = prependRecoveryNotice(this.pendingInitialPrompt, recovery.recovery);
11227
+ }
11228
+ this.sendSessionRequest("session/new", this.freshSessionParams);
11229
+ return [recovery.telemetry, recovery.recovery];
11230
+ }
11231
+ return [{
11232
+ kind: "error",
11233
+ message: grokErrorMessage(message, "Grok Build session initialization failed"),
11234
+ ...requestMethod ? { startupRequestMethod: requestMethod } : {}
11235
+ }];
11236
+ }
11237
+ const sessionId = sessionIdFromResult(message.result, requestMethod === "session/load" ? this.requestedResumeSessionId : null);
11238
+ if (!sessionId) {
11239
+ return [{
11240
+ kind: "error",
11241
+ message: "Grok Build session response did not include a sessionId.",
11242
+ ...requestMethod ? { startupRequestMethod: requestMethod } : {}
11243
+ }];
11244
+ }
11245
+ this.normalizer.adoptSession(sessionId);
11246
+ const modelId = this.selectedModel;
11247
+ if (modelId) {
11248
+ this.pendingModelRequestId = this.sendRequest("session/set_model", {
11249
+ sessionId,
11250
+ modelId,
11251
+ ...this.selectedReasoningEffort ? { _meta: { reasoningEffort: this.selectedReasoningEffort } } : {}
11252
+ });
11253
+ return [];
11254
+ }
11255
+ return this.startInitialPromptAndAnnounceSession(sessionId);
11256
+ }
11257
+ if (message.id === this.pendingModelRequestId) {
11258
+ this.pendingModelRequestId = null;
11259
+ if (hasJsonRpcField2(message, "error")) {
11260
+ return [{
11261
+ kind: "error",
11262
+ message: grokErrorMessage(message, "Grok Build model selection failed"),
11263
+ startupRequestMethod: "session/set_model"
11264
+ }];
11265
+ }
11266
+ const sessionId = this.normalizer.sessionId;
11267
+ return sessionId ? this.startInitialPromptAndAnnounceSession(sessionId) : [{
11268
+ kind: "error",
11269
+ message: "Grok Build model selection completed before the session became ready.",
11270
+ startupRequestMethod: "session/set_model"
11271
+ }];
11272
+ }
11273
+ if (message.id !== void 0 && this.pendingDeliveryRequests.has(message.id)) {
11274
+ const pending = this.pendingDeliveryRequests.get(message.id);
11275
+ this.pendingDeliveryRequests.delete(message.id);
11276
+ if (hasJsonRpcField2(message, "error")) {
11277
+ if (pending.method === "turn/start") this.normalizer.abortPrompt(pending.generation);
11278
+ const errorMessage = grokErrorMessage(message, "Grok Build ACP delivery failed");
11279
+ if (pending.method === "turn/start" && pending.initial) {
11280
+ return [{ kind: "error", message: errorMessage, startupRequestMethod: "session/prompt" }];
11281
+ }
11282
+ return [{
11283
+ kind: "delivery_error",
11284
+ message: errorMessage,
11285
+ requestMethod: pending.method,
11286
+ source: "grok_acp_response",
11287
+ payloadBytes: payloadBytes4(message.error)
11288
+ }];
11289
+ }
11290
+ if (pending.method === "turn/steer") return [];
11291
+ const result = recordValue2(message.result) ?? {};
11292
+ const meta = recordValue2(result._meta) ?? {};
11293
+ return this.normalizer.finishPrompt(pending.generation, {
11294
+ stopReason: result.stopReason,
11295
+ promptId: meta.promptId,
11296
+ agentResult: result.agentResult ?? meta.agentResult,
11297
+ usage: meta.usage ?? meta
11298
+ });
11299
+ }
11300
+ return [];
11301
+ }
11302
+ encodeStdinMessage(text, sessionId, opts) {
11303
+ const liveSessionId = this.normalizer.sessionId ?? nonEmptyString5(sessionId);
11304
+ if (!liveSessionId) return null;
11305
+ if (!this.normalizer.sessionId) this.normalizer.adoptSession(liveSessionId);
11306
+ if ((opts?.mode ?? "busy") === "busy") {
11307
+ if (!this.normalizer.canSteerBusy) return null;
11308
+ const id2 = this.nextRequestId();
11309
+ this.pendingDeliveryRequests.set(id2, { method: "turn/steer" });
11310
+ return JSON.stringify({
11311
+ jsonrpc: "2.0",
11312
+ id: id2,
11313
+ method: GROK_INTERJECT_METHOD,
11314
+ params: {
11315
+ sessionId: liveSessionId,
11316
+ text,
11317
+ interjectionId: `raft-${id2}`
11318
+ }
11319
+ });
11320
+ }
11321
+ const { id, request } = this.buildPromptRequest(text, liveSessionId, false);
11322
+ this.pendingDeliveryRequests.set(id, request);
11323
+ return JSON.stringify({
11324
+ jsonrpc: "2.0",
11325
+ id,
11326
+ method: "session/prompt",
11327
+ params: {
11328
+ sessionId: liveSessionId,
11329
+ prompt: [{ type: "text", text }]
11330
+ }
11331
+ });
11332
+ }
11333
+ buildSystemPrompt(config, _agentId) {
11334
+ return buildCliTransportSystemPrompt(config, {
11335
+ extraCriticalRules: [],
11336
+ postStartupNotes: [
11337
+ "**IMPORTANT**: Your process stays alive across turns. While you are working, Raft may write batched inbox-count notifications into the current turn; call `raft message check` at natural breakpoints to read the pending messages."
11338
+ ],
11339
+ includeStdinNotificationSection: true,
11340
+ messageNotificationStyle: "direct"
11341
+ });
11342
+ }
11343
+ async detectModels() {
11344
+ return await detectGrokModelsFromAcp();
11345
+ }
11346
+ nextRequestId() {
11347
+ this.requestId += 1;
11348
+ return this.requestId;
11349
+ }
11350
+ sendRequest(method, params) {
11351
+ const id = this.nextRequestId();
11352
+ this.process?.stdin?.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
11353
+ return id;
11354
+ }
11355
+ sendErrorResponse(id, message) {
11356
+ this.process?.stdin?.write(JSON.stringify({
11357
+ jsonrpc: "2.0",
11358
+ id,
11359
+ error: { code: -32601, message }
11360
+ }) + "\n");
11361
+ }
11362
+ sendSessionRequest(method, params) {
11363
+ this.pendingSessionRequestMethod = method;
11364
+ this.pendingSessionRequestId = this.sendRequest(method, params);
11365
+ }
11366
+ buildPromptRequest(text, sessionId, initial) {
11367
+ const id = this.nextRequestId();
11368
+ const generation = this.normalizer.beginPrompt();
11369
+ return {
11370
+ id,
11371
+ request: { method: "turn/start", generation, initial },
11372
+ wire: {
11373
+ jsonrpc: "2.0",
11374
+ id,
11375
+ method: "session/prompt",
11376
+ params: {
11377
+ sessionId,
11378
+ prompt: [{ type: "text", text }]
11379
+ }
11380
+ }
11381
+ };
11382
+ }
11383
+ startInitialPromptAndAnnounceSession(sessionId) {
11384
+ const prompt = this.pendingInitialPrompt;
11385
+ if (prompt === null) return [];
11386
+ this.pendingInitialPrompt = null;
11387
+ const built = this.buildPromptRequest(prompt, sessionId, true);
11388
+ this.pendingDeliveryRequests.set(built.id, built.request);
11389
+ this.process?.stdin?.write(JSON.stringify(built.wire) + "\n");
11390
+ return [{ kind: "session_init", sessionId }];
11391
+ }
11392
+ };
11393
+ async function detectGrokModelsFromAcp(options = {}) {
11394
+ const env = withWindowsUserEnvironment(options.env ?? process.env, { env: options.env ?? process.env });
11395
+ let launch;
11396
+ try {
11397
+ launch = resolveGrokSpawn([...GROK_AGENT_ARGS], { env });
11398
+ } catch {
11399
+ return null;
11400
+ }
11401
+ return await new Promise((resolve) => {
11402
+ const proc = spawn3(launch.command, launch.args, {
11403
+ cwd: options.cwd ?? process.cwd(),
11404
+ stdio: ["pipe", "pipe", "ignore"],
11405
+ env,
11406
+ shell: launch.shell
11407
+ });
11408
+ let settled = false;
11409
+ let buffer = "";
11410
+ const initializeRequestId = 1;
11411
+ const finish = (result) => {
11412
+ if (settled) return;
11413
+ settled = true;
11414
+ clearClockTimeout(timer);
11415
+ proc.kill();
11416
+ resolve(result);
11417
+ };
11418
+ const timer = setClockTimeout(() => finish(null), options.timeoutMs ?? 5e3);
11419
+ proc.once("error", () => finish(null));
11420
+ proc.once("exit", () => finish(null));
11421
+ proc.stdout?.on("data", (chunk) => {
11422
+ if (settled) return;
11423
+ buffer += chunk.toString();
11424
+ for (; ; ) {
11425
+ const newline = buffer.indexOf("\n");
11426
+ if (newline === -1) break;
11427
+ const line = buffer.slice(0, newline).trim();
11428
+ buffer = buffer.slice(newline + 1);
11429
+ if (!line) continue;
11430
+ const message = parseGrokJsonRpcLine(line);
11431
+ if (!message || !isJsonRpcResponse2(message) || message.id !== initializeRequestId) continue;
11432
+ if (!hasJsonRpcField2(message, "result") || !isCompatibleInitializeResult2(message.result)) {
11433
+ finish(null);
11434
+ return;
11435
+ }
11436
+ finish(grokModelSetFromInitializeResult(message.result));
11437
+ return;
11438
+ }
11439
+ });
11440
+ proc.stdin?.write(JSON.stringify({
11441
+ jsonrpc: "2.0",
11442
+ id: initializeRequestId,
11443
+ method: "initialize",
11444
+ params: initializeParams()
11445
+ }) + "\n");
11446
+ });
11447
+ }
11448
+
11449
+ // src/drivers/antigravity.ts
11450
+ import { randomUUID } from "crypto";
11451
+ import { spawn as spawn4 } from "child_process";
11452
+ var DEFAULT_PRINT_TIMEOUT = "30m";
11453
+ var ANTIGRAVITY_ENV_OVERRIDES = {
11454
+ // `agy` switches to a separate file-based token store when it detects an SSH
11455
+ // session. Daemon agents commonly run under SSH-managed hosts, while the
11456
+ // human login lives in the normal local Antigravity credential store.
11457
+ SSH_CLIENT: void 0,
11458
+ SSH_CONNECTION: void 0,
11459
+ SSH_TTY: void 0
11460
+ };
11461
+ function resolveAntigravitySpawn(commandArgs, deps = {}) {
11462
+ const command = resolveCommandOnPath("agy", deps) ?? "agy";
11463
+ return {
11464
+ command,
11465
+ args: commandArgs,
11466
+ shell: requiresWindowsShell(command, deps.platform)
11467
+ };
11468
+ }
11469
+ function buildAntigravityArgs(ctx) {
11470
+ const args = [
11471
+ "--print",
11472
+ "--print-timeout",
11473
+ runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars?.ANTIGRAVITY_PRINT_TIMEOUT || DEFAULT_PRINT_TIMEOUT,
11474
+ "--dangerously-skip-permissions"
11475
+ ];
11476
+ if (ctx.config.sessionId) {
11477
+ args.push("--continue");
11478
+ }
11479
+ return args;
11480
+ }
11481
+ var ERROR_LINE_PREFIX_RE = /^(?:(?:error|fatal|exception|failure):\s*|failed(?:\b|:))/i;
11482
+ var ERROR_LINE_PATTERNS = [
11483
+ /authentication timed out/i,
11484
+ /\bpermission denied\b/i,
11485
+ /\bunauthorized\b/i,
11486
+ /\brate limit(?:ed)?\b/i,
11487
+ /\bserver error\b/i,
11488
+ /\bnetwork error\b/i,
11489
+ /\brequest timed out\b/i,
11490
+ /\btimed out waiting\b/i,
11491
+ /\b(?:http|status)\s+(?:401|403|429|500|502|503|504)\b/i
11492
+ ];
11493
+ function isErrorLine(line) {
11494
+ return ERROR_LINE_PREFIX_RE.test(line) || ERROR_LINE_PATTERNS.some((pattern) => pattern.test(line));
11495
+ }
11496
+ var AntigravityDriver = class {
11497
+ id = "antigravity";
11498
+ lifecycle = {
11499
+ kind: "per_turn",
11500
+ start: "immediate",
11501
+ exit: "natural",
11502
+ inFlightWake: "spawn_new"
11503
+ };
11504
+ communication = {
11505
+ chat: "slock_cli",
11506
+ runtimeControl: "none"
11507
+ };
11508
+ session = {
11509
+ recovery: "resume_or_fresh"
11510
+ };
11511
+ model = {
11512
+ detectedModelsVerifiedAs: "suggestion_only",
11513
+ toLaunchSpec: (_modelId) => ({ args: [] })
11514
+ };
11515
+ supportsStdinNotification = false;
11516
+ busyDeliveryMode = "none";
11517
+ sessionId = null;
11518
+ sessionAnnounced = false;
11519
+ probe() {
11520
+ const command = resolveCommandOnPath("agy");
11521
+ if (!command) return { available: false };
11522
+ return {
11523
+ available: true,
11524
+ version: readCommandVersion(command) ?? void 0
11525
+ };
11526
+ }
11527
+ async spawn(ctx) {
11528
+ this.sessionId = ctx.config.sessionId || randomUUID();
11529
+ this.sessionAnnounced = false;
11530
+ const { command, args, shell } = resolveAntigravitySpawn(buildAntigravityArgs(ctx));
11531
+ const { spawnEnv } = await prepareCliTransport(ctx, {
11532
+ NO_COLOR: "1",
11533
+ ...ANTIGRAVITY_ENV_OVERRIDES
11534
+ });
11535
+ const proc = spawn4(command, args, {
11536
+ cwd: ctx.workingDirectory,
11537
+ stdio: ["pipe", "pipe", "pipe"],
11538
+ env: spawnEnv,
11539
+ shell
11540
+ });
11541
+ proc.stdin?.end(ctx.prompt);
11542
+ return { process: proc };
11543
+ }
11544
+ parseLine(line) {
11545
+ const trimmed = line.trim();
11546
+ if (!trimmed) return [];
11547
+ const events = [];
11548
+ if (!this.sessionAnnounced && this.sessionId) {
11549
+ events.push({ kind: "session_init", sessionId: this.sessionId });
11550
+ this.sessionAnnounced = true;
11551
+ }
11552
+ if (isErrorLine(trimmed)) {
11553
+ events.push({ kind: "error", message: trimmed });
11554
+ return events;
11555
+ }
11556
+ events.push({ kind: "text", text: line });
11557
+ return events;
11558
+ }
11559
+ encodeStdinMessage(_text, _sessionId, _opts) {
11560
+ return null;
11561
+ }
11562
+ buildSystemPrompt(config, _agentId) {
11563
+ return buildCliTransportSystemPrompt(config, {
11564
+ extraCriticalRules: [],
11565
+ postStartupNotes: [
11566
+ "**Antigravity runtime note:** Slock launches you as a per-turn process. Complete the current wake using `slock` CLI commands, then stop; the daemon will restart you when new messages arrive."
11567
+ ],
11568
+ includeStdinNotificationSection: false,
11569
+ messageNotificationStyle: "poll"
11570
+ });
11571
+ }
11572
+ async detectModels() {
11573
+ return null;
11574
+ }
11575
+ };
11576
+
11577
+ // src/drivers/copilot.ts
11578
+ import { spawn as spawn5 } from "child_process";
11579
+ async function buildCopilotSpawnEnv(ctx) {
11580
+ return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
11581
+ }
11582
+ var CopilotDriver = class {
11583
+ id = "copilot";
11584
+ lifecycle = {
11585
+ kind: "per_turn",
11586
+ start: "immediate",
11587
+ exit: "natural",
11588
+ inFlightWake: "spawn_new"
11589
+ };
11590
+ communication = {
11591
+ chat: "slock_cli",
11592
+ runtimeControl: "none"
11593
+ };
11594
+ session = {
11595
+ recovery: "resume_or_fresh"
10707
11596
  };
10708
11597
  model = {
10709
11598
  detectedModelsVerifiedAs: "launchable",
@@ -10735,7 +11624,7 @@ var CopilotDriver = class {
10735
11624
  args.push(`--resume=${ctx.config.sessionId}`);
10736
11625
  }
10737
11626
  const spawnEnv = await buildCopilotSpawnEnv(ctx);
10738
- const proc = spawn4("copilot", args, {
11627
+ const proc = spawn5("copilot", args, {
10739
11628
  cwd: ctx.workingDirectory,
10740
11629
  stdio: ["pipe", "pipe", "pipe"],
10741
11630
  env: spawnEnv,
@@ -10827,7 +11716,7 @@ var CopilotDriver = class {
10827
11716
  };
10828
11717
 
10829
11718
  // src/drivers/cursor.ts
10830
- import { spawn as spawn5, spawnSync } from "child_process";
11719
+ import { spawn as spawn6, spawnSync } from "child_process";
10831
11720
  async function buildCursorSpawnEnv(ctx, deps = {}) {
10832
11721
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" });
10833
11722
  return withWindowsUserEnvironment(spawnEnv, deps);
@@ -10871,7 +11760,7 @@ var CursorDriver = class {
10871
11760
  }
10872
11761
  args.push(ctx.prompt);
10873
11762
  const spawnEnv = await buildCursorSpawnEnv(ctx);
10874
- const proc = spawn5("cursor-agent", args, {
11763
+ const proc = spawn6("cursor-agent", args, {
10875
11764
  cwd: ctx.workingDirectory,
10876
11765
  stdio: ["pipe", "pipe", "pipe"],
10877
11766
  env: spawnEnv,
@@ -10997,9 +11886,9 @@ function runCursorModelsCommand() {
10997
11886
  }
10998
11887
 
10999
11888
  // src/drivers/gemini.ts
11000
- import { execFileSync as execFileSync3, spawn as spawn6 } from "child_process";
11889
+ import { execFileSync as execFileSync4, spawn as spawn7 } from "child_process";
11001
11890
  import { existsSync as existsSync5 } from "fs";
11002
- import path8 from "path";
11891
+ import path9 from "path";
11003
11892
  async function buildGeminiSpawnEnv(ctx, platform = process.platform) {
11004
11893
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" }, platform);
11005
11894
  const launchEnvVars = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars;
@@ -11040,10 +11929,10 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
11040
11929
  if (platform !== "win32") {
11041
11930
  return { command: resolveCommandOnPath("gemini", deps) ?? "gemini", args: commandArgs };
11042
11931
  }
11043
- const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
11932
+ const execFileSyncFn = deps.execFileSyncFn ?? execFileSync4;
11044
11933
  const existsSyncFn = deps.existsSyncFn ?? existsSync5;
11045
11934
  const env = deps.env ?? process.env;
11046
- const winPath = path8.win32;
11935
+ const winPath = path9.win32;
11047
11936
  let geminiEntry = null;
11048
11937
  try {
11049
11938
  const globalRoot = normalizeExecOutput2(execFileSyncFn("npm", ["root", "-g"], {
@@ -11105,7 +11994,7 @@ var GeminiDriver = class {
11105
11994
  this.sessionAnnounced = false;
11106
11995
  const { command, args } = resolveGeminiSpawn(buildGeminiArgs(ctx.config));
11107
11996
  const spawnEnv = await buildGeminiSpawnEnv(ctx);
11108
- const proc = spawn6(command, args, {
11997
+ const proc = spawn7(command, args, {
11109
11998
  cwd: ctx.workingDirectory,
11110
11999
  stdio: ["pipe", "pipe", "pipe"],
11111
12000
  env: spawnEnv,
@@ -11178,10 +12067,10 @@ var GeminiDriver = class {
11178
12067
 
11179
12068
  // src/drivers/kimi.ts
11180
12069
  import { randomUUID as randomUUID2 } from "crypto";
11181
- import { spawn as spawn7 } from "child_process";
12070
+ import { spawn as spawn8 } from "child_process";
11182
12071
  import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
11183
- import os4 from "os";
11184
- import path9 from "path";
12072
+ import os6 from "os";
12073
+ import path10 from "path";
11185
12074
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
11186
12075
  var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
11187
12076
  var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
@@ -11228,8 +12117,8 @@ var KimiDriver = class {
11228
12117
  this.sessionId = ctx.config.sessionId || randomUUID2();
11229
12118
  this.sessionAnnounced = false;
11230
12119
  this.promptRequestId = randomUUID2();
11231
- const systemPromptPath = path9.join(ctx.workingDirectory, KIMI_SYSTEM_PROMPT_FILE);
11232
- const agentFilePath = path9.join(ctx.workingDirectory, KIMI_AGENT_FILE);
12120
+ const systemPromptPath = path10.join(ctx.workingDirectory, KIMI_SYSTEM_PROMPT_FILE);
12121
+ const agentFilePath = path10.join(ctx.workingDirectory, KIMI_AGENT_FILE);
11233
12122
  if (!isResume || !existsSync6(systemPromptPath)) {
11234
12123
  writeFileSync3(systemPromptPath, ctx.prompt, "utf8");
11235
12124
  }
@@ -11254,7 +12143,7 @@ var KimiDriver = class {
11254
12143
  }
11255
12144
  const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
11256
12145
  const launch = resolveKimiSpawn(args);
11257
- const proc = spawn7(launch.command, launch.args, {
12146
+ const proc = spawn8(launch.command, launch.args, {
11258
12147
  cwd: ctx.workingDirectory,
11259
12148
  stdio: ["pipe", "pipe", "pipe"],
11260
12149
  env: spawnEnv,
@@ -11375,8 +12264,8 @@ var KimiDriver = class {
11375
12264
  return detectKimiModels();
11376
12265
  }
11377
12266
  };
11378
- function detectKimiModels(home = os4.homedir()) {
11379
- const configPath = path9.join(home, ".kimi", "config.toml");
12267
+ function detectKimiModels(home = os6.homedir()) {
12268
+ const configPath = path10.join(home, ".kimi", "config.toml");
11380
12269
  let raw;
11381
12270
  try {
11382
12271
  raw = readFileSync3(configPath, "utf8");
@@ -11405,7 +12294,7 @@ function detectKimiModels(home = os4.homedir()) {
11405
12294
  import { randomUUID as randomUUID3 } from "crypto";
11406
12295
  import { EventEmitter } from "events";
11407
12296
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync4 } from "fs";
11408
- import path10 from "path";
12297
+ import path11 from "path";
11409
12298
  import { createRequire as createRequire2 } from "module";
11410
12299
  import {
11411
12300
  createKimiHarness,
@@ -11430,7 +12319,7 @@ function createKimiSdkEventMappingState(sessionId = null) {
11430
12319
  };
11431
12320
  }
11432
12321
  function buildKimiSessionDir(workingDirectory) {
11433
- return path10.join(workingDirectory, KIMI_SESSION_DIR);
12322
+ return path11.join(workingDirectory, KIMI_SESSION_DIR);
11434
12323
  }
11435
12324
  function kimiErrorMessage(error) {
11436
12325
  if (typeof error === "string" && error.trim()) return error.trim();
@@ -11812,7 +12701,7 @@ var KimiSdkRuntimeSession = class {
11812
12701
  };
11813
12702
  function detectKimiSdkModels(home = resolveKimiHome(), ctx = {}) {
11814
12703
  const span = ctx.span;
11815
- const configPath = path10.join(home, "config.toml");
12704
+ const configPath = path11.join(home, "config.toml");
11816
12705
  const homeFromEnv = Boolean(process.env.KIMI_CODE_HOME);
11817
12706
  const emit2 = (outcome, extra = {}) => {
11818
12707
  span?.addEvent("daemon.kimi_sdk.models.config", {
@@ -11925,10 +12814,10 @@ var KimiSdkDriver = class {
11925
12814
  };
11926
12815
 
11927
12816
  // src/drivers/opencode.ts
11928
- import { spawn as spawn8, spawnSync as spawnSync2 } from "child_process";
12817
+ import { spawn as spawn9, spawnSync as spawnSync2 } from "child_process";
11929
12818
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
11930
- import os5 from "os";
11931
- import path11 from "path";
12819
+ import os7 from "os";
12820
+ import path12 from "path";
11932
12821
  var SLOCK_AGENT_NAME = "slock";
11933
12822
  var NO_MESSAGE_PROMPT = "No new messages are pending. Stop now.";
11934
12823
  var FIRST_MESSAGE_TASK_PREFIX = "First message task (system-triggered):";
@@ -11948,8 +12837,8 @@ function parseUserOpenCodeConfig(ctx) {
11948
12837
  const raw = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config)).envVars?.OPENCODE_CONFIG_CONTENT;
11949
12838
  return parseOpenCodeConfigContent(raw);
11950
12839
  }
11951
- function readLocalOpenCodeConfig(home = os5.homedir()) {
11952
- const configPath = path11.join(home, ".config", "opencode", "opencode.json");
12840
+ function readLocalOpenCodeConfig(home = os7.homedir()) {
12841
+ const configPath = path12.join(home, ".config", "opencode", "opencode.json");
11953
12842
  try {
11954
12843
  return parseOpenCodeConfigContent(readFileSync5(configPath, "utf8"));
11955
12844
  } catch {
@@ -12009,7 +12898,7 @@ function mergeOpenCodeConfigs(localConfig, envConfig) {
12009
12898
  }
12010
12899
  };
12011
12900
  }
12012
- function buildOpenCodeConfig(ctx, home = os5.homedir()) {
12901
+ function buildOpenCodeConfig(ctx, home = os7.homedir()) {
12013
12902
  const userConfig = mergeOpenCodeConfigs(readLocalOpenCodeConfig(home), parseUserOpenCodeConfig(ctx));
12014
12903
  const userAgents = recordField(userConfig.agent);
12015
12904
  const userSlockAgent = recordField(userAgents[SLOCK_AGENT_NAME]);
@@ -12027,7 +12916,7 @@ function buildOpenCodeConfig(ctx, home = os5.homedir()) {
12027
12916
  mcp: recordField(userConfig.mcp)
12028
12917
  };
12029
12918
  }
12030
- async function buildOpenCodeLaunchOptions(ctx, home = os5.homedir(), version = null) {
12919
+ async function buildOpenCodeLaunchOptions(ctx, home = os7.homedir(), version = null) {
12031
12920
  const slock = await prepareCliTransport(ctx, { NO_COLOR: "1" });
12032
12921
  const config = buildOpenCodeConfig(ctx, home);
12033
12922
  const env = {
@@ -12076,7 +12965,7 @@ function parseOpenCodeModelsOutput(output) {
12076
12965
  }
12077
12966
  return models.length > 0 ? { models } : null;
12078
12967
  }
12079
- function detectOpenCodeModels(home = os5.homedir(), runCommand = runOpenCodeModelsCommand) {
12968
+ function detectOpenCodeModels(home = os7.homedir(), runCommand = runOpenCodeModelsCommand) {
12080
12969
  const commandResult = runCommand(home);
12081
12970
  if (commandResult.error || commandResult.status !== 0) return null;
12082
12971
  return parseOpenCodeModelsOutput(commandResult.stdout);
@@ -12097,11 +12986,11 @@ function runOpenCodeModelsCommand(home, deps = {}) {
12097
12986
  };
12098
12987
  }
12099
12988
  function isWindowsCommandShim(commandPath) {
12100
- const ext = path11.win32.extname(commandPath).toLowerCase();
12989
+ const ext = path12.win32.extname(commandPath).toLowerCase();
12101
12990
  return ext === ".cmd" || ext === ".bat";
12102
12991
  }
12103
12992
  function opencodePackageEntryCandidates(packageRoot) {
12104
- const winPath = path11.win32;
12993
+ const winPath = path12.win32;
12105
12994
  return [
12106
12995
  winPath.join(packageRoot, "bin", "opencode.exe"),
12107
12996
  winPath.join(packageRoot, "bin", "opencode.js"),
@@ -12110,7 +12999,7 @@ function opencodePackageEntryCandidates(packageRoot) {
12110
12999
  ];
12111
13000
  }
12112
13001
  function openCodeSpecForEntry(entry, commandArgs) {
12113
- if (path11.win32.extname(entry).toLowerCase() === ".exe") {
13002
+ if (path12.win32.extname(entry).toLowerCase() === ".exe") {
12114
13003
  return { command: entry, args: commandArgs, shell: false };
12115
13004
  }
12116
13005
  return { command: process.execPath, args: [entry, ...commandArgs], shell: false };
@@ -12119,7 +13008,7 @@ function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
12119
13008
  const existsSyncFn = deps.existsSyncFn ?? existsSync7;
12120
13009
  const execFileSyncFn = deps.execFileSyncFn;
12121
13010
  const env = deps.env ?? process.env;
12122
- const winPath = path11.win32;
13011
+ const winPath = path12.win32;
12123
13012
  const candidates = [];
12124
13013
  if (execFileSyncFn) {
12125
13014
  try {
@@ -12147,7 +13036,7 @@ function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
12147
13036
  function extractWindowsShimTargets(commandPath, deps = {}) {
12148
13037
  if (!isWindowsCommandShim(commandPath)) return [];
12149
13038
  const readFileSyncFn = deps.readFileSyncFn ?? readFileSync5;
12150
- const commandDir = path11.win32.dirname(commandPath);
13039
+ const commandDir = path12.win32.dirname(commandPath);
12151
13040
  let raw;
12152
13041
  try {
12153
13042
  raw = String(readFileSyncFn(commandPath, "utf8"));
@@ -12158,7 +13047,7 @@ function extractWindowsShimTargets(commandPath, deps = {}) {
12158
13047
  const dp0Pattern = /%~dp0\\?([^"\r\n]*?opencode\.(?:exe|js|mjs|cjs))/gi;
12159
13048
  for (const match of raw.matchAll(dp0Pattern)) {
12160
13049
  const relative = match[1]?.replace(/^\\+/, "");
12161
- if (relative) candidates.push(path11.win32.normalize(path11.win32.join(commandDir, relative)));
13050
+ if (relative) candidates.push(path12.win32.normalize(path12.win32.join(commandDir, relative)));
12162
13051
  }
12163
13052
  return candidates;
12164
13053
  }
@@ -12176,7 +13065,7 @@ function resolveOpenCodeSpawn(commandArgs, deps = {}) {
12176
13065
  };
12177
13066
  }
12178
13067
  const command = resolveCommandOnPath("opencode", deps);
12179
- if (command && path11.win32.extname(command).toLowerCase() === ".exe") {
13068
+ if (command && path12.win32.extname(command).toLowerCase() === ".exe") {
12180
13069
  return { command, args: commandArgs, shell: false };
12181
13070
  }
12182
13071
  const packageEntry = resolveWindowsOpenCodePackageEntry(command, deps);
@@ -12282,9 +13171,9 @@ var OpenCodeDriver = class {
12282
13171
  if (unsupportedMessage) {
12283
13172
  throw new Error(unsupportedMessage);
12284
13173
  }
12285
- const launch = await buildOpenCodeLaunchOptions(ctx, os5.homedir(), version);
13174
+ const launch = await buildOpenCodeLaunchOptions(ctx, os7.homedir(), version);
12286
13175
  const spawnSpec = resolveOpenCodeSpawn(launch.args);
12287
- const proc = spawn8(spawnSpec.command, spawnSpec.args, {
13176
+ const proc = spawn9(spawnSpec.command, spawnSpec.args, {
12288
13177
  cwd: ctx.workingDirectory,
12289
13178
  stdio: ["pipe", "pipe", "pipe"],
12290
13179
  env: launch.env,
@@ -12350,7 +13239,7 @@ var OpenCodeDriver = class {
12350
13239
  import { randomUUID as randomUUID4 } from "crypto";
12351
13240
  import { EventEmitter as EventEmitter2 } from "events";
12352
13241
  import { mkdirSync as mkdirSync3, readdirSync as readdirSync3 } from "fs";
12353
- import path12 from "path";
13242
+ import path13 from "path";
12354
13243
  import {
12355
13244
  createAgentSessionFromServices,
12356
13245
  createAgentSessionServices,
@@ -12363,7 +13252,7 @@ import {
12363
13252
  } from "@earendil-works/pi-coding-agent";
12364
13253
 
12365
13254
  // src/drivers/piCommandTool.ts
12366
- import { spawn as spawn9 } from "child_process";
13255
+ import { spawn as spawn10 } from "child_process";
12367
13256
  import {
12368
13257
  createBashTool
12369
13258
  } from "@earendil-works/pi-coding-agent";
@@ -12384,7 +13273,7 @@ var POWERSHELL_ARGS = [
12384
13273
  ];
12385
13274
  var MAX_TIMEOUT_SECONDS = 2147483647 / 1e3;
12386
13275
  function killWindowsProcessTree(pid) {
12387
- const killer = spawn9("taskkill.exe", ["/F", "/T", "/PID", String(pid)], {
13276
+ const killer = spawn10("taskkill.exe", ["/F", "/T", "/PID", String(pid)], {
12388
13277
  detached: true,
12389
13278
  stdio: "ignore",
12390
13279
  windowsHide: true
@@ -12410,7 +13299,7 @@ function buildPiPowerShellScript(command) {
12410
13299
  ].join("\r\n");
12411
13300
  }
12412
13301
  function createPiPowerShellOperations(deps = {}) {
12413
- const spawnProcess = deps.spawn ?? spawn9;
13302
+ const spawnProcess = deps.spawn ?? spawn10;
12414
13303
  const killProcessTree = deps.killProcessTree ?? killWindowsProcessTree;
12415
13304
  return {
12416
13305
  exec: async (command, cwd, { onData, signal, timeout, env }) => {
@@ -12511,13 +13400,13 @@ function createPiSdkEventMappingState(sessionId = null) {
12511
13400
  };
12512
13401
  }
12513
13402
  function buildPiSessionDir(workingDirectory) {
12514
- return path12.join(workingDirectory, PI_SESSION_DIR);
13403
+ return path13.join(workingDirectory, PI_SESSION_DIR);
12515
13404
  }
12516
13405
  function buildBuiltInSessionDir(workingDirectory) {
12517
- return path12.join(workingDirectory, BUILTIN_SESSION_DIR);
13406
+ return path13.join(workingDirectory, BUILTIN_SESSION_DIR);
12518
13407
  }
12519
13408
  function buildBuiltInAgentDir(workingDirectory) {
12520
- return path12.join(workingDirectory, BUILTIN_AGENT_DIR);
13409
+ return path13.join(workingDirectory, BUILTIN_AGENT_DIR);
12521
13410
  }
12522
13411
  async function buildPiSpawnEnv(ctx) {
12523
13412
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
@@ -12631,7 +13520,7 @@ function findPiSessionFile(sessionDir, sessionId) {
12631
13520
  }
12632
13521
  const suffix = `_${sessionId}.jsonl`;
12633
13522
  const match = entries.find((entry) => entry.endsWith(suffix));
12634
- return match ? path12.join(sessionDir, match) : null;
13523
+ return match ? path13.join(sessionDir, match) : null;
12635
13524
  }
12636
13525
  function detectPiModelsFromRegistry(modelRegistry) {
12637
13526
  const models = [];
@@ -12912,8 +13801,8 @@ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
12912
13801
  const sessionCreateEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
12913
13802
  const services = await withProcessEnvPatch(sessionCreateEnvPatch, async () => {
12914
13803
  const modelRuntime = await ModelRuntime.create({
12915
- authPath: path12.join(agentDir, "auth.json"),
12916
- modelsPath: path12.join(agentDir, "models.json"),
13804
+ authPath: path13.join(agentDir, "auth.json"),
13805
+ modelsPath: path13.join(agentDir, "models.json"),
12917
13806
  allowModelNetwork: false
12918
13807
  });
12919
13808
  await seedPiSessionModelRuntime(modelRuntime, runtimeConfig);
@@ -13521,9 +14410,253 @@ var ChildProcessRuntimeSession = class {
13521
14410
  });
13522
14411
  });
13523
14412
  }
13524
- };
13525
- function createChildProcessRuntimeSession(driver, ctx) {
13526
- return new ChildProcessRuntimeSession(driver, ctx);
14413
+ };
14414
+ function createChildProcessRuntimeSession(driver, ctx) {
14415
+ return new ChildProcessRuntimeSession(driver, ctx);
14416
+ }
14417
+
14418
+ // src/drivers/runtimeArtifacts.ts
14419
+ import {
14420
+ existsSync as existsSync8,
14421
+ mkdirSync as mkdirSync4,
14422
+ readFileSync as readFileSync6,
14423
+ readdirSync as readdirSync4,
14424
+ statSync,
14425
+ writeFileSync as writeFileSync4
14426
+ } from "fs";
14427
+ import os8 from "os";
14428
+ import path14 from "path";
14429
+ function allowedTranscriptRootsForRuntime(runtime, homeDir, workspaceDir) {
14430
+ const roots = [workspaceDir];
14431
+ switch (runtime) {
14432
+ case "claude":
14433
+ roots.push(path14.join(homeDir, ".claude"));
14434
+ break;
14435
+ case "codex":
14436
+ roots.push(homeDir, path14.join(homeDir, ".codex"));
14437
+ break;
14438
+ case "grok":
14439
+ roots.push(homeDir, path14.join(homeDir, ".grok"));
14440
+ break;
14441
+ case "kimi":
14442
+ case "kimi-sdk":
14443
+ roots.push(path14.join(homeDir, ".kimi"));
14444
+ break;
14445
+ case "pi":
14446
+ roots.push(path14.join(homeDir, ".pi"), path14.join(homeDir, ".pi", "agent"));
14447
+ break;
14448
+ }
14449
+ return roots;
14450
+ }
14451
+ function findSessionJsonl(root, predicate) {
14452
+ let visited = 0;
14453
+ const maxEntries = 1e4;
14454
+ const maxDepth = 8;
14455
+ const visit = (dir, depth) => {
14456
+ if (depth < 0 || visited >= maxEntries) return null;
14457
+ let entries;
14458
+ try {
14459
+ entries = readdirSync4(dir, { withFileTypes: true }).sort((a, b) => b.name.localeCompare(a.name));
14460
+ } catch {
14461
+ return null;
14462
+ }
14463
+ for (const entry of entries) {
14464
+ if (++visited > maxEntries) return null;
14465
+ if (!entry.isFile() || !predicate(entry.name)) continue;
14466
+ return path14.join(dir, entry.name);
14467
+ }
14468
+ for (const entry of entries) {
14469
+ if (++visited > maxEntries) return null;
14470
+ if (!entry.isDirectory()) continue;
14471
+ const found = visit(path14.join(dir, entry.name), depth - 1);
14472
+ if (found) return found;
14473
+ }
14474
+ return null;
14475
+ };
14476
+ return visit(root, maxDepth);
14477
+ }
14478
+ function findKimiSdkSessionDir(sessionId, agentId, homeDir) {
14479
+ const indexPath = path14.join(homeDir, ".kimi", "session_index.jsonl");
14480
+ try {
14481
+ const index = readFileSync6(indexPath, "utf8");
14482
+ for (const line of index.split("\n")) {
14483
+ if (!line.trim()) continue;
14484
+ try {
14485
+ const entry = JSON.parse(line);
14486
+ if (entry.sessionId === sessionId && entry.sessionDir && existsSync8(entry.sessionDir)) {
14487
+ return entry.sessionDir;
14488
+ }
14489
+ } catch {
14490
+ }
14491
+ }
14492
+ } catch {
14493
+ }
14494
+ const sessionsRoot = path14.join(homeDir, ".kimi", "sessions");
14495
+ try {
14496
+ const prefix = agentId ? `wd_${agentId}_` : "wd_";
14497
+ for (const entry of readdirSync4(sessionsRoot, { withFileTypes: true })) {
14498
+ if (!entry.isDirectory() || !entry.name.startsWith(prefix)) continue;
14499
+ const candidate = path14.join(sessionsRoot, entry.name, `session_${sessionId}`);
14500
+ if (existsSync8(candidate)) return candidate;
14501
+ }
14502
+ } catch {
14503
+ }
14504
+ return null;
14505
+ }
14506
+ function findGrokSessionTranscript(root, sessionId) {
14507
+ let visited = 0;
14508
+ const maxEntries = 1e4;
14509
+ const maxDepth = 4;
14510
+ const preferredFiles = ["updates.jsonl", "events.jsonl", "chat_history.jsonl"];
14511
+ const visit = (dir, depth) => {
14512
+ if (depth < 0 || visited >= maxEntries) return null;
14513
+ let entries;
14514
+ try {
14515
+ entries = readdirSync4(dir, { withFileTypes: true });
14516
+ } catch {
14517
+ return null;
14518
+ }
14519
+ for (const entry of entries) {
14520
+ if (++visited > maxEntries) return null;
14521
+ if (!entry.isDirectory()) continue;
14522
+ const child = path14.join(dir, entry.name);
14523
+ if (entry.name === sessionId) {
14524
+ for (const filename of preferredFiles) {
14525
+ const candidate = path14.join(child, filename);
14526
+ try {
14527
+ if (statSync(candidate).isFile()) return candidate;
14528
+ } catch {
14529
+ }
14530
+ }
14531
+ }
14532
+ const found = visit(child, depth - 1);
14533
+ if (found) return found;
14534
+ }
14535
+ return null;
14536
+ };
14537
+ return visit(root, maxDepth);
14538
+ }
14539
+ function findPiSessionFile2(sessionId, workingDirectory, homeDir) {
14540
+ if (workingDirectory) {
14541
+ const piSessionsDir = path14.join(workingDirectory, ".pi-sessions");
14542
+ try {
14543
+ const files = readdirSync4(piSessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => ({
14544
+ name: entry.name,
14545
+ path: path14.join(piSessionsDir, entry.name),
14546
+ stat: statSync(path14.join(piSessionsDir, entry.name))
14547
+ })).filter((entry) => entry.stat.isFile() && entry.name.includes(sessionId)).sort((a, b) => b.stat.mtimeMs - a.stat.mtimeMs);
14548
+ if (files[0]) return files[0].path;
14549
+ } catch {
14550
+ }
14551
+ }
14552
+ const legacyRoots = [path14.join(homeDir, ".pi", "agent"), path14.join(homeDir, ".pi")];
14553
+ for (const root of legacyRoots) {
14554
+ const found = findSessionJsonl(root, (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId));
14555
+ if (found) return found;
14556
+ }
14557
+ return null;
14558
+ }
14559
+ function safeSessionFilename(value) {
14560
+ const normalized = value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
14561
+ return normalized || "unknown-session";
14562
+ }
14563
+ function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir, join, resolve) {
14564
+ try {
14565
+ const dir = path14.join(fallbackDir, ".slock", "runtime-sessions");
14566
+ mkdirSync4(dir, { recursive: true });
14567
+ const filePath = path14.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
14568
+ const searchedPaths = resolve?.searchedPaths ?? [];
14569
+ writeFileSync4(filePath, JSON.stringify({
14570
+ type: "runtime_session_handoff",
14571
+ runtime,
14572
+ sessionId,
14573
+ launchId: join?.launchId ?? null,
14574
+ processInstanceId: join?.processInstanceId ?? null,
14575
+ resolveStatus: "transcript_resolve_missing",
14576
+ lookupMethod: resolve?.lookupMethod ?? "none",
14577
+ searchedPaths,
14578
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
14579
+ note: "The native runtime transcript file was not found on this machine; this daemon-created handoff records the runtime session identity + the directories checked for diagnostics."
14580
+ }) + "\n", { mode: 384 });
14581
+ return {
14582
+ label: sessionId,
14583
+ path: filePath,
14584
+ runtime,
14585
+ reachable: true,
14586
+ reason: `native session file path not found; using daemon handoff file; searched=[${searchedPaths.join(", ")}]`
14587
+ };
14588
+ } catch {
14589
+ return null;
14590
+ }
14591
+ }
14592
+ function resolveRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts = {}) {
14593
+ if (config.runtime === "codex") {
14594
+ return resolveCodexHomeRootFromConfig(config, defaultHomeDir, workspacePath, process.env, opts);
14595
+ }
14596
+ if (config.runtime === "grok") {
14597
+ return resolveGrokHomeFromEnv({ ...process.env, ...config.envVars ?? {} }, {
14598
+ cwd: workspacePath,
14599
+ homeDir: defaultHomeDir
14600
+ });
14601
+ }
14602
+ return defaultHomeDir;
14603
+ }
14604
+ function ensureRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts = {}) {
14605
+ const home = resolveRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts);
14606
+ if (config.runtime === "codex" && opts.agentId) mkdirSync4(home, { recursive: true });
14607
+ return home;
14608
+ }
14609
+ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os8.homedir(), fallbackDir, opts) {
14610
+ let resolvedPath = null;
14611
+ let lookupMethod = "none";
14612
+ const searchedPaths = [];
14613
+ if (runtime === "claude") {
14614
+ lookupMethod = "claude_jsonl";
14615
+ const claudeRoot = path14.join(homeDir, ".claude", "projects");
14616
+ searchedPaths.push(claudeRoot);
14617
+ resolvedPath = findSessionJsonl(claudeRoot, (filename) => filename === `${sessionId}.jsonl`);
14618
+ } else if (runtime === "codex") {
14619
+ lookupMethod = "codex_jsonl";
14620
+ for (const root of codexSessionRootCandidates(homeDir)) {
14621
+ searchedPaths.push(root);
14622
+ resolvedPath = findSessionJsonl(root, (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId));
14623
+ if (resolvedPath) break;
14624
+ }
14625
+ } else if (runtime === "grok") {
14626
+ lookupMethod = "grok_session_jsonl";
14627
+ const roots = [.../* @__PURE__ */ new Set([path14.join(homeDir, "sessions"), path14.join(homeDir, ".grok", "sessions")])];
14628
+ for (const root of roots) {
14629
+ searchedPaths.push(root);
14630
+ resolvedPath = findGrokSessionTranscript(root, sessionId);
14631
+ if (resolvedPath) break;
14632
+ }
14633
+ } else if (runtime === "kimi-sdk" || runtime === "kimi") {
14634
+ lookupMethod = "kimi_sdk_index";
14635
+ resolvedPath = findKimiSdkSessionDir(sessionId, opts?.agentId, homeDir);
14636
+ } else if (runtime === "pi") {
14637
+ lookupMethod = "pi_jsonl";
14638
+ resolvedPath = findPiSessionFile2(sessionId, opts?.workingDirectory, homeDir);
14639
+ }
14640
+ if (!resolvedPath && fallbackDir) {
14641
+ const fallback = writeRuntimeSessionHandoff(
14642
+ runtime,
14643
+ sessionId,
14644
+ fallbackDir,
14645
+ { launchId: opts?.launchId, processInstanceId: opts?.processInstanceId },
14646
+ { lookupMethod, searchedPaths }
14647
+ );
14648
+ if (fallback) return { ...fallback, reason: `${fallback.reason}; attempted_lookup=${lookupMethod}` };
14649
+ }
14650
+ const ref = {
14651
+ label: sessionId,
14652
+ path: resolvedPath ?? sessionId,
14653
+ runtime,
14654
+ reachable: Boolean(resolvedPath)
14655
+ };
14656
+ if (!resolvedPath) {
14657
+ ref.reason = `session file path not found; attempted_lookup=${lookupMethod}; searched=[${searchedPaths.join(", ")}]`;
14658
+ }
14659
+ return ref;
13527
14660
  }
13528
14661
 
13529
14662
  // src/drivers/index.ts
@@ -13531,6 +14664,7 @@ var driverFactories = {
13531
14664
  builtin: () => new BuiltInDriver(),
13532
14665
  claude: () => new ClaudeDriver(),
13533
14666
  codex: () => new CodexDriver(),
14667
+ grok: () => new GrokDriver(),
13534
14668
  antigravity: () => new AntigravityDriver(),
13535
14669
  copilot: () => new CopilotDriver(),
13536
14670
  cursor: () => new CursorDriver(),
@@ -13611,22 +14745,22 @@ async function reapOrphanProcesses(pids, logger2, recordTrace) {
13611
14745
 
13612
14746
  // src/workspaces.ts
13613
14747
  import { access, mkdir, readdir, rm, stat, writeFile } from "fs/promises";
13614
- import path13 from "path";
14748
+ import path15 from "path";
13615
14749
  async function initializeAgentWorkspace(workspacePath, initialMemoryMd, seedFiles) {
13616
14750
  await mkdir(workspacePath, { recursive: true });
13617
- const memoryMdPath = path13.join(workspacePath, "MEMORY.md");
14751
+ const memoryMdPath = path15.join(workspacePath, "MEMORY.md");
13618
14752
  try {
13619
14753
  await access(memoryMdPath);
13620
14754
  } catch {
13621
14755
  await writeFile(memoryMdPath, initialMemoryMd);
13622
14756
  }
13623
- await mkdir(path13.join(workspacePath, "notes"), { recursive: true });
14757
+ await mkdir(path15.join(workspacePath, "notes"), { recursive: true });
13624
14758
  for (const { relativePath, content } of seedFiles) {
13625
- const fullPath = path13.join(workspacePath, relativePath);
14759
+ const fullPath = path15.join(workspacePath, relativePath);
13626
14760
  try {
13627
14761
  await access(fullPath);
13628
14762
  } catch {
13629
- await mkdir(path13.dirname(fullPath), { recursive: true });
14763
+ await mkdir(path15.dirname(fullPath), { recursive: true });
13630
14764
  await writeFile(fullPath, content);
13631
14765
  }
13632
14766
  }
@@ -13638,7 +14772,7 @@ function resolveWorkspaceDirectoryPath(dataDir, directoryName) {
13638
14772
  if (!isValidWorkspaceDirectoryName(directoryName)) {
13639
14773
  return null;
13640
14774
  }
13641
- return path13.join(dataDir, directoryName);
14775
+ return path15.join(dataDir, directoryName);
13642
14776
  }
13643
14777
  function emptyWorkspaceDirectorySummary(latestMtime = /* @__PURE__ */ new Date(0)) {
13644
14778
  return {
@@ -13687,7 +14821,7 @@ async function summarizeWorkspaceDirectory(dirPath) {
13687
14821
  return summary;
13688
14822
  }
13689
14823
  const childSummaries = await Promise.all(
13690
- entries.map((entry) => summarizeWorkspaceEntry(path13.join(dirPath, entry.name), entry))
14824
+ entries.map((entry) => summarizeWorkspaceEntry(path15.join(dirPath, entry.name), entry))
13691
14825
  );
13692
14826
  for (const childSummary of childSummaries) {
13693
14827
  summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
@@ -13706,7 +14840,7 @@ async function scanWorkspaceDirectories(dataDir) {
13706
14840
  if (!entry.isDirectory()) {
13707
14841
  return null;
13708
14842
  }
13709
- const dirPath = path13.join(dataDir, entry.name);
14843
+ const dirPath = path15.join(dataDir, entry.name);
13710
14844
  try {
13711
14845
  const summary = await summarizeWorkspaceDirectory(dirPath);
13712
14846
  return {
@@ -14869,6 +16003,8 @@ function runtimeDisplayName(runtimeId) {
14869
16003
  return "Claude Code";
14870
16004
  case "codex":
14871
16005
  return "Codex";
16006
+ case "grok":
16007
+ return "Grok Build";
14872
16008
  case "copilot":
14873
16009
  return "GitHub Copilot CLI";
14874
16010
  case "cursor":
@@ -15240,7 +16376,7 @@ function isWorkspaceNeverVisibleHiddenEntry(name) {
15240
16376
  return WORKSPACE_NEVER_VISIBLE_HIDDEN_NAMES.has(name) || name.startsWith(".slock-");
15241
16377
  }
15242
16378
  function workspacePathParts(relativePath) {
15243
- return relativePath.split(path14.sep).filter(Boolean);
16379
+ return relativePath.split(path16.sep).filter(Boolean);
15244
16380
  }
15245
16381
  function isWorkspaceHiddenPath(relativePath) {
15246
16382
  return workspacePathParts(relativePath).some((part) => part.startsWith("."));
@@ -15305,7 +16441,7 @@ async function waitForRunnerCredentialRetry() {
15305
16441
  function probeSubprocessOsState(pid) {
15306
16442
  if (typeof pid !== "number") return "unknown";
15307
16443
  try {
15308
- const status = readFileSync6(`/proc/${pid}/status`, "utf8");
16444
+ const status = readFileSync7(`/proc/${pid}/status`, "utf8");
15309
16445
  const match = status.match(/^State:\s+(\S)/m);
15310
16446
  if (match) {
15311
16447
  const code = match[1];
@@ -15356,40 +16492,21 @@ function getMessageShortId2(messageId2) {
15356
16492
  var RESPONSE_TARGET_HINT = "Reply in the channel or create/reply in a thread as appropriate; use each message's `target` and `msg` fields to choose the exact target.";
15357
16493
  var SESSION_TRANSCRIPT_MAX_BYTES = 10 * 1024 * 1024;
15358
16494
  function runtimeTier(runtime) {
15359
- const tier1 = /* @__PURE__ */ new Set(["claude", "codex", "kimi-sdk", "kimi", "pi"]);
16495
+ const tier1 = /* @__PURE__ */ new Set(["claude", "codex", "grok", "kimi-sdk", "kimi", "pi"]);
15360
16496
  if (tier1.has(runtime)) return "tier1";
15361
16497
  return "tier2_or_fallback";
15362
16498
  }
15363
16499
  function redactTranscript(text) {
15364
16500
  return text.replace(/sk_(?:agent|machine|computer)_[A-Za-z0-9_-]+/g, "sk_[redacted]").replace(/sap_[A-Za-z0-9_-]+/g, "sap_[redacted]").replace(/Bearer\s+[A-Za-z0-9_\-./+=]+/g, "Bearer [redacted]").replace(/["']?auth[_-]?token["']?\s*[:=]\s*["'][^"']+["']/gi, "[redacted]").replace(/https?:\/\/[^\s\"]+/g, "[url]");
15365
16501
  }
15366
- function allowedTranscriptRootsForRuntime(runtime, homeDir, workspaceDir) {
15367
- const roots = [workspaceDir];
15368
- switch (runtime) {
15369
- case "claude":
15370
- roots.push(path14.join(homeDir, ".claude"));
15371
- break;
15372
- case "codex":
15373
- roots.push(homeDir, path14.join(homeDir, ".codex"));
15374
- break;
15375
- case "kimi":
15376
- case "kimi-sdk":
15377
- roots.push(path14.join(homeDir, ".kimi"));
15378
- break;
15379
- case "pi":
15380
- roots.push(path14.join(homeDir, ".pi"), path14.join(homeDir, ".pi", "agent"));
15381
- break;
15382
- }
15383
- return roots;
15384
- }
15385
16502
  async function isPathWithinAllowedRoots(filePath, roots) {
15386
16503
  const real = await realpath(filePath).catch(() => null);
15387
16504
  if (!real) return false;
15388
16505
  for (const root of roots) {
15389
16506
  const realRoot = await realpath(root).catch(() => null);
15390
16507
  if (!realRoot) continue;
15391
- const rel = path14.relative(realRoot, real);
15392
- if (!rel.startsWith("..") && !path14.isAbsolute(rel)) return true;
16508
+ const rel = path16.relative(realRoot, real);
16509
+ if (!rel.startsWith("..") && !path16.isAbsolute(rel)) return true;
15393
16510
  }
15394
16511
  return false;
15395
16512
  }
@@ -15421,186 +16538,6 @@ async function readAndRedact(filePath, maxBytes) {
15421
16538
  return null;
15422
16539
  }
15423
16540
  }
15424
- function findSessionJsonl(root, predicate) {
15425
- let visited = 0;
15426
- const maxEntries = 1e4;
15427
- const maxDepth = 8;
15428
- const visit = (dir, depth) => {
15429
- if (depth < 0 || visited >= maxEntries) return null;
15430
- let entries;
15431
- try {
15432
- entries = readdirSync4(dir, { withFileTypes: true }).sort((a, b) => b.name.localeCompare(a.name));
15433
- } catch {
15434
- return null;
15435
- }
15436
- for (const entry of entries) {
15437
- if (++visited > maxEntries) return null;
15438
- if (!entry.isFile() || !predicate(entry.name)) continue;
15439
- return path14.join(dir, entry.name);
15440
- }
15441
- for (const entry of entries) {
15442
- if (++visited > maxEntries) return null;
15443
- if (!entry.isDirectory()) continue;
15444
- const found = visit(path14.join(dir, entry.name), depth - 1);
15445
- if (found) return found;
15446
- }
15447
- return null;
15448
- };
15449
- return visit(root, maxDepth);
15450
- }
15451
- function findKimiSdkSessionDir(sessionId, agentId, homeDir) {
15452
- const indexPath = path14.join(homeDir, ".kimi", "session_index.jsonl");
15453
- try {
15454
- const index = readFileSync6(indexPath, "utf8");
15455
- for (const line of index.split("\n")) {
15456
- if (!line.trim()) continue;
15457
- try {
15458
- const entry = JSON.parse(line);
15459
- if (entry.sessionId === sessionId && entry.sessionDir && existsSync8(entry.sessionDir)) {
15460
- return entry.sessionDir;
15461
- }
15462
- } catch {
15463
- }
15464
- }
15465
- } catch {
15466
- }
15467
- const sessionsRoot = path14.join(homeDir, ".kimi", "sessions");
15468
- try {
15469
- const prefix = agentId ? `wd_${agentId}_` : `wd_`;
15470
- for (const entry of readdirSync4(sessionsRoot, { withFileTypes: true })) {
15471
- if (!entry.isDirectory() || !entry.name.startsWith(prefix)) continue;
15472
- const candidate = path14.join(sessionsRoot, entry.name, `session_${sessionId}`);
15473
- if (existsSync8(candidate)) return candidate;
15474
- }
15475
- } catch {
15476
- }
15477
- return null;
15478
- }
15479
- function findPiSessionFile2(sessionId, workingDirectory, homeDir) {
15480
- if (workingDirectory) {
15481
- const piSessionsDir = path14.join(workingDirectory, ".pi-sessions");
15482
- try {
15483
- const files = readdirSync4(piSessionsDir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => ({ name: e.name, path: path14.join(piSessionsDir, e.name), stat: statSync(path14.join(piSessionsDir, e.name)) })).filter((f) => f.stat.isFile() && f.name.includes(sessionId)).sort((a, b) => b.stat.mtimeMs - a.stat.mtimeMs);
15484
- if (files[0]) return files[0].path;
15485
- } catch {
15486
- }
15487
- }
15488
- const legacyRoots = [
15489
- path14.join(homeDir, ".pi", "agent"),
15490
- path14.join(homeDir, ".pi")
15491
- ];
15492
- for (const root of legacyRoots) {
15493
- const found = findSessionJsonl(root, (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId));
15494
- if (found) return found;
15495
- }
15496
- return null;
15497
- }
15498
- function safeSessionFilename(value) {
15499
- const normalized = value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
15500
- return normalized || "unknown-session";
15501
- }
15502
- function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir, join, resolve) {
15503
- try {
15504
- const dir = path14.join(fallbackDir, ".slock", "runtime-sessions");
15505
- mkdirSync4(dir, { recursive: true });
15506
- const filePath = path14.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
15507
- const searchedPaths = resolve?.searchedPaths ?? [];
15508
- writeFileSync4(filePath, JSON.stringify({
15509
- type: "runtime_session_handoff",
15510
- runtime,
15511
- sessionId,
15512
- // Persisted L1<->L2 join keys (#460 V3): without these the
15513
- // session->launch mapping lives only in daemon memory and old L1
15514
- // transcripts can never re-join their launch after restart/adopt.
15515
- // ids-only, closed fields (no content payload).
15516
- launchId: join?.launchId ?? null,
15517
- processInstanceId: join?.processInstanceId ?? null,
15518
- // Negative-space (fruit#0 pt2): a resolve-miss is explicit evidence, not a
15519
- // silent "not found". Recording the lookup method + the directories checked
15520
- // makes "looked in the wrong place" distinguishable from "looked in the right
15521
- // place and it is genuinely absent". ids/paths only — no transcript content.
15522
- resolveStatus: "transcript_resolve_missing",
15523
- lookupMethod: resolve?.lookupMethod ?? "none",
15524
- searchedPaths,
15525
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
15526
- note: "The native runtime transcript file was not found on this machine; this daemon-created handoff records the runtime session identity + the directories checked for diagnostics."
15527
- }) + "\n", { mode: 384 });
15528
- return {
15529
- label: sessionId,
15530
- path: filePath,
15531
- runtime,
15532
- reachable: true,
15533
- reason: `native session file path not found; using daemon handoff file; searched=[${searchedPaths.join(", ")}]`
15534
- };
15535
- } catch {
15536
- return null;
15537
- }
15538
- }
15539
- function resolveRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts = {}) {
15540
- if (config.runtime === "codex") {
15541
- return resolveCodexHomeRootFromConfig(config, defaultHomeDir, workspacePath, process.env, opts);
15542
- }
15543
- return defaultHomeDir;
15544
- }
15545
- function ensureRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts = {}) {
15546
- if (config.runtime === "codex") {
15547
- const home = resolveCodexHomeRootFromConfig(config, defaultHomeDir, workspacePath, process.env, opts);
15548
- if (opts.agentId) {
15549
- mkdirSync4(home, { recursive: true });
15550
- }
15551
- return home;
15552
- }
15553
- return defaultHomeDir;
15554
- }
15555
- function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), fallbackDir, opts) {
15556
- let resolvedPath = null;
15557
- let lookupMethod = "none";
15558
- const searchedPaths = [];
15559
- if (runtime === "claude") {
15560
- lookupMethod = "claude_jsonl";
15561
- const claudeRoot = path14.join(homeDir, ".claude", "projects");
15562
- searchedPaths.push(claudeRoot);
15563
- resolvedPath = findSessionJsonl(claudeRoot, (filename) => filename === `${sessionId}.jsonl`);
15564
- } else if (runtime === "codex") {
15565
- lookupMethod = "codex_jsonl";
15566
- for (const root of codexSessionRootCandidates(homeDir)) {
15567
- searchedPaths.push(root);
15568
- resolvedPath = findSessionJsonl(root, (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId));
15569
- if (resolvedPath) break;
15570
- }
15571
- } else if (runtime === "kimi-sdk" || runtime === "kimi") {
15572
- lookupMethod = "kimi_sdk_index";
15573
- resolvedPath = findKimiSdkSessionDir(sessionId, opts?.agentId, homeDir);
15574
- } else if (runtime === "pi") {
15575
- lookupMethod = "pi_jsonl";
15576
- resolvedPath = findPiSessionFile2(sessionId, opts?.workingDirectory, homeDir);
15577
- }
15578
- if (!resolvedPath && fallbackDir) {
15579
- const fallback = writeRuntimeSessionHandoff(
15580
- runtime,
15581
- sessionId,
15582
- fallbackDir,
15583
- { launchId: opts?.launchId, processInstanceId: opts?.processInstanceId },
15584
- { lookupMethod, searchedPaths }
15585
- );
15586
- if (fallback) {
15587
- return {
15588
- ...fallback,
15589
- reason: `${fallback.reason}; attempted_lookup=${lookupMethod}`
15590
- };
15591
- }
15592
- }
15593
- const ref = {
15594
- label: sessionId,
15595
- path: resolvedPath ?? sessionId,
15596
- runtime,
15597
- reachable: Boolean(resolvedPath)
15598
- };
15599
- if (!resolvedPath) {
15600
- ref.reason = `session file path not found; attempted_lookup=${lookupMethod}; searched=[${searchedPaths.join(", ")}]`;
15601
- }
15602
- return ref;
15603
- }
15604
16541
  function classifySpawnFailure(error) {
15605
16542
  const detail = error instanceof Error ? error.message : String(error);
15606
16543
  const lower = detail.toLowerCase();
@@ -16441,7 +17378,7 @@ function runtimeDiagnosticTitle(event) {
16441
17378
  case "deprecationNotice":
16442
17379
  return "Codex deprecation notice";
16443
17380
  default:
16444
- return "Codex warning";
17381
+ return event.source === "grok_acp_notification" ? "Grok Build warning" : "Codex warning";
16445
17382
  }
16446
17383
  }
16447
17384
  function summarizeDiagnosticRange(range) {
@@ -16495,7 +17432,7 @@ function runtimeRecoveryTrajectoryEntry(event) {
16495
17432
  }
16496
17433
  return {
16497
17434
  kind: "system",
16498
- title: "Codex resume recovery",
17435
+ title: event.source === "grok_resume_missing_session" ? "Grok resume recovery" : "Codex resume recovery",
16499
17436
  text: lines.join("\n")
16500
17437
  };
16501
17438
  }
@@ -16932,9 +17869,9 @@ var AgentProcessManager = class _AgentProcessManager {
16932
17869
  this.sendToServer = sendToServer;
16933
17870
  this.daemonApiKey = daemonApiKey;
16934
17871
  this.serverUrl = opts.serverUrl;
16935
- this.slockHome = opts.slockHome ? path14.resolve(opts.slockHome) : resolveSlockHome();
17872
+ this.slockHome = opts.slockHome ? path16.resolve(opts.slockHome) : resolveSlockHome();
16936
17873
  this.dataDir = opts.dataDir || resolveSlockHomePath("agents", this.slockHome);
16937
- this.runtimeSessionHomeDir = opts.runtimeSessionHomeDir || os6.homedir();
17874
+ this.runtimeSessionHomeDir = opts.runtimeSessionHomeDir || os9.homedir();
16938
17875
  this.driverResolver = opts.driverResolver || getDriver;
16939
17876
  this.defaultAgentEnvVarsProvider = opts.defaultAgentEnvVarsProvider || null;
16940
17877
  this.tracer = opts.tracer ?? noopTracer;
@@ -17303,8 +18240,8 @@ var AgentProcessManager = class _AgentProcessManager {
17303
18240
  broadcastMessageReceivedActivity(agentId) {
17304
18241
  this.broadcastActivity(agentId, "working", "Message received", [], void 0, "message_received");
17305
18242
  }
17306
- toolActivityDetailKind(toolName) {
17307
- switch (resolveToolSemantic(toolName) ?? toolName) {
18243
+ toolActivityDetailKind(toolName2) {
18244
+ switch (resolveToolSemantic(toolName2) ?? toolName2) {
17308
18245
  case "bash":
17309
18246
  return "running_command";
17310
18247
  case "check_messages":
@@ -17716,15 +18653,20 @@ var AgentProcessManager = class _AgentProcessManager {
17716
18653
  ...runtimeDiagnosticTraceAttrs(event)
17717
18654
  });
17718
18655
  }
17719
- /**
17720
- * APM 1.6 6a — surface a generic structured "working" signal from an
17721
- * internal_progress liveness tick during a long turn. Only transitions INTO
17722
- * the runtime-progress state once (idempotent while already in it) so the
17723
- * high-frequency Claude partial-message stream does not spam a rendered status
17724
- * line every tick; the activity heartbeat then keeps the signal live. Carries
17725
- * no raw content — a bounded "Working" detail only. Never marks a subagent.
17726
- */
17727
- maybeBroadcastRuntimeProgressActivity(agentId, ap) {
18656
+ // Project bounded Working liveness without raw content or subagent state.
18657
+ maybeBroadcastRuntimeProgressActivity(agentId, ap, event) {
18658
+ if (this.isApmIdle(ap)) {
18659
+ this.recordDaemonTrace("daemon.runtime.progress.activity.suppressed", {
18660
+ agentId,
18661
+ launchId: ap.launchId || void 0,
18662
+ runtime: ap.config.runtime,
18663
+ outcome: "apm_idle",
18664
+ source: event.source,
18665
+ itemType: event.itemType,
18666
+ payloadBytes: event.payloadBytes
18667
+ });
18668
+ return;
18669
+ }
17728
18670
  const alreadyLive = ap.lastActivityKind === "working" || ap.lastActivityKind === "thinking";
17729
18671
  if (alreadyLive) return;
17730
18672
  this.broadcastActivity(agentId, "working", "Working", [], void 0, "runtime_progress");
@@ -18247,7 +19189,7 @@ var AgentProcessManager = class _AgentProcessManager {
18247
19189
  let pendingStartRebind;
18248
19190
  const originalLaunchId = launchId || null;
18249
19191
  try {
18250
- const agentDataDir = path14.join(this.dataDir, agentId);
19192
+ const agentDataDir = path16.join(this.dataDir, agentId);
18251
19193
  const initialRuntimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
18252
19194
  await initializeAgentWorkspace(
18253
19195
  agentDataDir,
@@ -19783,7 +20725,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
19783
20725
  return true;
19784
20726
  }
19785
20727
  async resetWorkspace(agentId) {
19786
- const agentDataDir = path14.join(this.dataDir, agentId);
20728
+ const agentDataDir = path16.join(this.dataDir, agentId);
19787
20729
  try {
19788
20730
  await rm2(agentDataDir, { recursive: true, force: true });
19789
20731
  logger.info(`[Agent ${agentId}] Workspace reset complete (${agentDataDir})`);
@@ -19865,7 +20807,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
19865
20807
  return result;
19866
20808
  }
19867
20809
  buildRuntimeProfileReport(agentId, config, sessionId, launchId, observedRuntimeHomeDir, processInstanceId) {
19868
- const workspacePath = path14.join(this.dataDir, agentId);
20810
+ const workspacePath = path16.join(this.dataDir, agentId);
19869
20811
  const runtimeHomeDir = observedRuntimeHomeDir || resolveRuntimeHomeDir(config, this.runtimeSessionHomeDir, workspacePath, { agentId, slockHome: this.slockHome });
19870
20812
  return {
19871
20813
  agentId,
@@ -20201,7 +21143,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20201
21143
  }
20202
21144
  // Workspace file browsing
20203
21145
  async getFileTree(agentId, dirPath, includeHidden = false) {
20204
- const agentDir = path14.join(this.dataDir, agentId);
21146
+ const agentDir = path16.join(this.dataDir, agentId);
20205
21147
  try {
20206
21148
  await stat2(agentDir);
20207
21149
  } catch {
@@ -20209,11 +21151,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20209
21151
  }
20210
21152
  let targetDir = agentDir;
20211
21153
  if (dirPath) {
20212
- const resolved = path14.resolve(agentDir, dirPath);
20213
- if (!resolved.startsWith(agentDir + path14.sep) && resolved !== agentDir) {
21154
+ const resolved = path16.resolve(agentDir, dirPath);
21155
+ if (!resolved.startsWith(agentDir + path16.sep) && resolved !== agentDir) {
20214
21156
  return [];
20215
21157
  }
20216
- const relativePath = path14.relative(agentDir, resolved);
21158
+ const relativePath = path16.relative(agentDir, resolved);
20217
21159
  if (isWorkspaceNeverVisibleHiddenPath(relativePath)) {
20218
21160
  return [];
20219
21161
  }
@@ -20225,18 +21167,18 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20225
21167
  return this.listDirectoryChildren(targetDir, agentDir, includeHidden);
20226
21168
  }
20227
21169
  async readFile(agentId, filePath) {
20228
- const agentDir = path14.join(this.dataDir, agentId);
20229
- const resolved = path14.resolve(agentDir, filePath);
20230
- if (!resolved.startsWith(agentDir + path14.sep) && resolved !== agentDir) {
21170
+ const agentDir = path16.join(this.dataDir, agentId);
21171
+ const resolved = path16.resolve(agentDir, filePath);
21172
+ if (!resolved.startsWith(agentDir + path16.sep) && resolved !== agentDir) {
20231
21173
  throw new Error("Access denied");
20232
21174
  }
20233
- const relativePath = path14.relative(agentDir, resolved);
21175
+ const relativePath = path16.relative(agentDir, resolved);
20234
21176
  if (isWorkspaceNeverVisibleHiddenPath(relativePath) || isWorkspaceSecretFilePath(relativePath)) {
20235
21177
  throw new Error("Preview is disabled for sensitive workspace files");
20236
21178
  }
20237
21179
  const info = await stat2(resolved);
20238
21180
  if (info.isDirectory()) throw new Error("Cannot read a directory");
20239
- const ext = path14.extname(resolved).toLowerCase();
21181
+ const ext = path16.extname(resolved).toLowerCase();
20240
21182
  if (WORKSPACE_TEXT_EXTENSIONS.has(ext) || ext === "") {
20241
21183
  if (info.size > WORKSPACE_TEXT_FILE_MAX_BYTES) throw new Error("File too large");
20242
21184
  const content = await readFile(resolved, "utf-8");
@@ -20287,7 +21229,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20287
21229
  };
20288
21230
  }
20289
21231
  const runtime = config.runtime;
20290
- const workspaceDir = path14.join(this.dataDir, agentId);
21232
+ const workspaceDir = path16.join(this.dataDir, agentId);
20291
21233
  const homeDir = agent?.runtime.currentRuntimeHomeDir || ensureRuntimeHomeDir(config, this.runtimeSessionHomeDir, workspaceDir, { agentId, slockHome: this.slockHome });
20292
21234
  if (!actualSessionId) {
20293
21235
  return {
@@ -20328,7 +21270,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20328
21270
  let redacted = false;
20329
21271
  if (ref.reachable && ref.path) {
20330
21272
  try {
20331
- const resolved = path14.resolve(ref.path);
21273
+ const resolved = path16.resolve(ref.path);
20332
21274
  const allowedRoots = allowedTranscriptRootsForRuntime(runtime, homeDir, workspaceDir);
20333
21275
  if (!await isPathWithinAllowedRoots(resolved, allowedRoots)) {
20334
21276
  throw new Error("resolved session path is outside allowed runtime directories");
@@ -20339,7 +21281,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20339
21281
  throw new Error("symbolic links are not allowed");
20340
21282
  }
20341
21283
  if (info.isDirectory()) {
20342
- targetPath = path14.join(resolved, "state.json");
21284
+ targetPath = path16.join(resolved, "state.json");
20343
21285
  }
20344
21286
  if (!await isPathWithinAllowedRoots(targetPath, allowedRoots)) {
20345
21287
  throw new Error("resolved session state path is outside allowed runtime directories");
@@ -20451,17 +21393,17 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20451
21393
  const idle = this.lifecycleRecords.getRestartSnapshot(agentId);
20452
21394
  const config = agent?.config ?? idle?.config ?? null;
20453
21395
  const runtime = runtimeHint || config?.runtime || "claude";
20454
- const workspaceDir = path14.join(this.dataDir, agentId);
20455
- const hostHome = os6.homedir();
21396
+ const workspaceDir = path16.join(this.dataDir, agentId);
21397
+ const hostHome = os9.homedir();
20456
21398
  const home = agent?.runtime.currentRuntimeHomeDir || (config ? ensureRuntimeHomeDir(config, hostHome, workspaceDir, { agentId, slockHome: this.slockHome }) : runtime === "codex" ? resolveCodexHomeRootFromEnv(process.env, { defaultHomeDir: hostHome, cwd: workspaceDir }) : hostHome);
20457
21399
  const paths = _AgentProcessManager.SKILL_PATHS[runtime] || _AgentProcessManager.SKILL_PATHS.claude;
20458
21400
  const globalDirs = runtime === "codex" ? [
20459
- path14.join(home, "skills"),
20460
- path14.join(home, "skills", ".system"),
20461
- path14.join(home, ".agents", "skills"),
20462
- ...hasConfiguredCodexHome(config) ? [] : [path14.join(hostHome, ".agents", "skills")]
20463
- ] : paths.global.map((p) => path14.join(home, p));
20464
- const workspaceDirs = paths.workspace.map((p) => path14.join(workspaceDir, p));
21401
+ path16.join(home, "skills"),
21402
+ path16.join(home, "skills", ".system"),
21403
+ path16.join(home, ".agents", "skills"),
21404
+ ...hasConfiguredCodexHome(config) ? [] : [path16.join(hostHome, ".agents", "skills")]
21405
+ ] : paths.global.map((p) => path16.join(home, p));
21406
+ const workspaceDirs = paths.workspace.map((p) => path16.join(workspaceDir, p));
20465
21407
  const globalResults = await Promise.all(
20466
21408
  globalDirs.map((dir) => this.scanSkillsDir(dir))
20467
21409
  );
@@ -20495,7 +21437,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20495
21437
  const skills = [];
20496
21438
  for (const entry of entries) {
20497
21439
  if (entry.isDirectory() || entry.isSymbolicLink()) {
20498
- const skillMd = path14.join(dir, entry.name, "SKILL.md");
21440
+ const skillMd = path16.join(dir, entry.name, "SKILL.md");
20499
21441
  try {
20500
21442
  const content = await readFile(skillMd, "utf-8");
20501
21443
  const skill = this.parseSkillMd(entry.name, content);
@@ -20506,7 +21448,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
20506
21448
  } else if (entry.name.endsWith(".md")) {
20507
21449
  const cmdName = entry.name.replace(/\.md$/, "");
20508
21450
  try {
20509
- const content = await readFile(path14.join(dir, entry.name), "utf-8");
21451
+ const content = await readFile(path16.join(dir, entry.name), "utf-8");
20510
21452
  const skill = this.parseSkillMd(cmdName, content);
20511
21453
  skill.sourcePath = dir;
20512
21454
  skills.push(skill);
@@ -21722,7 +22664,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
21722
22664
  itemType: event.itemType,
21723
22665
  payloadBytes: event.payloadBytes
21724
22666
  });
21725
- this.maybeBroadcastRuntimeProgressActivity(agentId, ap);
22667
+ this.maybeBroadcastRuntimeProgressActivity(agentId, ap, event);
21726
22668
  return;
21727
22669
  }
21728
22670
  if (event.kind === "subagent_progress") {
@@ -22588,8 +23530,8 @@ ${RESPONSE_TARGET_HINT}`);
22588
23530
  const isHidden = entry.name.startsWith(".");
22589
23531
  if (entry.name === "node_modules") continue;
22590
23532
  if (isHidden && (!includeHidden || isWorkspaceNeverVisibleHiddenEntry(entry.name))) continue;
22591
- const fullPath = path14.join(dir, entry.name);
22592
- const relativePath = path14.relative(rootDir, fullPath);
23533
+ const fullPath = path16.join(dir, entry.name);
23534
+ const relativePath = path16.relative(rootDir, fullPath);
22593
23535
  let info;
22594
23536
  try {
22595
23537
  info = await stat2(fullPath);
@@ -23071,9 +24013,9 @@ var ReminderCache = class {
23071
24013
 
23072
24014
  // src/machineLock.ts
23073
24015
  import { createHash as createHash4, randomUUID as randomUUID7 } from "crypto";
23074
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
23075
- import os7 from "os";
23076
- import path15 from "path";
24016
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
24017
+ import os10 from "os";
24018
+ import path17 from "path";
23077
24019
  var INCOMPLETE_LOCK_STALE_MS = 3e4;
23078
24020
  var DaemonMachineLockConflictError = class extends Error {
23079
24021
  code = "DAEMON_MACHINE_LOCK_HELD";
@@ -23095,11 +24037,11 @@ function resolveDefaultMachineStateRoot() {
23095
24037
  return resolveSlockHomePath("machines");
23096
24038
  }
23097
24039
  function ownerPath(lockDir) {
23098
- return path15.join(lockDir, "owner.json");
24040
+ return path17.join(lockDir, "owner.json");
23099
24041
  }
23100
24042
  function readOwner(lockDir) {
23101
24043
  try {
23102
- return JSON.parse(readFileSync7(ownerPath(lockDir), "utf8"));
24044
+ return JSON.parse(readFileSync8(ownerPath(lockDir), "utf8"));
23103
24045
  } catch {
23104
24046
  return null;
23105
24047
  }
@@ -23125,8 +24067,8 @@ function acquireDaemonMachineLock(options) {
23125
24067
  const rootDir = options.rootDir ?? resolveDefaultMachineStateRoot();
23126
24068
  const fingerprint = apiKeyFingerprint(options.apiKey);
23127
24069
  const lockId = getDaemonMachineLockId(options.apiKey);
23128
- const machineDir = path15.join(rootDir, lockId);
23129
- const lockDir = path15.join(machineDir, "daemon.lock");
24070
+ const machineDir = path17.join(rootDir, lockId);
24071
+ const lockDir = path17.join(machineDir, "daemon.lock");
23130
24072
  const token = randomUUID7();
23131
24073
  mkdirSync5(machineDir, { recursive: true });
23132
24074
  for (let attempt = 0; attempt < 2; attempt += 1) {
@@ -23135,7 +24077,7 @@ function acquireDaemonMachineLock(options) {
23135
24077
  const owner = {
23136
24078
  pid: process.pid,
23137
24079
  token,
23138
- hostname: os7.hostname(),
24080
+ hostname: os10.hostname(),
23139
24081
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
23140
24082
  serverUrl: options.serverUrl,
23141
24083
  apiKeyFingerprint: fingerprint.slice(0, 16)
@@ -23187,7 +24129,7 @@ function acquireDaemonMachineLock(options) {
23187
24129
 
23188
24130
  // ../trace-client/src/localTraceSink.ts
23189
24131
  import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync5, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
23190
- import path16 from "path";
24132
+ import path18 from "path";
23191
24133
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
23192
24134
  var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
23193
24135
  var DEFAULT_MAX_FILES = 8;
@@ -23232,7 +24174,7 @@ var LocalRotatingTraceSink = class {
23232
24174
  currentSize = 0;
23233
24175
  sequence = 0;
23234
24176
  constructor(options) {
23235
- this.traceDir = path16.join(options.machineDir, "traces");
24177
+ this.traceDir = path18.join(options.machineDir, "traces");
23236
24178
  this.maxFileBytes = Math.max(1024, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES));
23237
24179
  const baseAgeMs = Math.max(1e3, Math.floor(options.maxFileAgeMs ?? DEFAULT_MAX_FILE_AGE_MS));
23238
24180
  const ageJitterMs = Math.max(0, Math.floor(options.maxFileAgeJitterMs ?? 0));
@@ -23262,7 +24204,7 @@ var LocalRotatingTraceSink = class {
23262
24204
  const nowMs = this.nowMsProvider();
23263
24205
  const shouldRotateForAge = this.currentFileOpenedAtMs !== null && nowMs - this.currentFileOpenedAtMs >= this.maxFileAgeMs;
23264
24206
  if (!this.currentFile || this.currentSize + nextBytes > this.maxFileBytes || shouldRotateForAge) {
23265
- this.currentFile = path16.join(
24207
+ this.currentFile = path18.join(
23266
24208
  this.traceDir,
23267
24209
  `daemon-trace-${safeTimestamp(nowMs)}-${process.pid}-${String(this.sequence++).padStart(4, "0")}.jsonl`
23268
24210
  );
@@ -23277,7 +24219,7 @@ var LocalRotatingTraceSink = class {
23277
24219
  const excess = files.length - this.maxFiles;
23278
24220
  if (excess <= 0) return;
23279
24221
  for (const file of files.slice(0, excess)) {
23280
- rmSync4(path16.join(this.traceDir, file), { force: true });
24222
+ rmSync4(path18.join(this.traceDir, file), { force: true });
23281
24223
  }
23282
24224
  }
23283
24225
  };
@@ -23454,7 +24396,7 @@ function createTraceClient(options) {
23454
24396
  import { createHash as createHash6, randomUUID as randomUUID8 } from "crypto";
23455
24397
  import { gzipSync as gzipSync2 } from "zlib";
23456
24398
  import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
23457
- import path17 from "path";
24399
+ import path19 from "path";
23458
24400
  var TRACE_UPLOAD_SCOPE = "daemon-trace-bundle:create";
23459
24401
  var DEFAULT_UPLOAD_INTERVAL_MS = 5 * 60 * 1e3;
23460
24402
  var DEFAULT_MIN_FILE_AGE_MS = 60 * 1e3;
@@ -23537,7 +24479,7 @@ var DaemonTraceBundleUploader = class {
23537
24479
  }, nextMs);
23538
24480
  }
23539
24481
  async findUploadCandidates() {
23540
- const traceDir = path17.join(this.options.machineDir, "traces");
24482
+ const traceDir = path19.join(this.options.machineDir, "traces");
23541
24483
  let names;
23542
24484
  try {
23543
24485
  names = await readdir3(traceDir);
@@ -23549,8 +24491,8 @@ var DaemonTraceBundleUploader = class {
23549
24491
  const currentFile = this.options.currentFileProvider?.();
23550
24492
  const candidates = [];
23551
24493
  for (const name of names.filter((entry) => entry.startsWith("daemon-trace-") && entry.endsWith(".jsonl")).sort()) {
23552
- const file = path17.join(traceDir, name);
23553
- if (currentFile && path17.resolve(file) === path17.resolve(currentFile)) continue;
24494
+ const file = path19.join(traceDir, name);
24495
+ if (currentFile && path19.resolve(file) === path19.resolve(currentFile)) continue;
23554
24496
  if (await this.isUploaded(file)) continue;
23555
24497
  try {
23556
24498
  const info = await stat3(file);
@@ -23628,8 +24570,8 @@ var DaemonTraceBundleUploader = class {
23628
24570
  }
23629
24571
  }
23630
24572
  uploadStatePath(file) {
23631
- const stateDir = path17.join(this.options.machineDir, "trace-uploads");
23632
- return path17.join(stateDir, `${path17.basename(file)}.uploaded.json`);
24573
+ const stateDir = path19.join(this.options.machineDir, "trace-uploads");
24574
+ return path19.join(stateDir, `${path19.basename(file)}.uploaded.json`);
23633
24575
  }
23634
24576
  async isUploaded(file) {
23635
24577
  try {
@@ -23641,9 +24583,9 @@ var DaemonTraceBundleUploader = class {
23641
24583
  }
23642
24584
  async markUploaded(file, metadata) {
23643
24585
  const stateFile = this.uploadStatePath(file);
23644
- await mkdir2(path17.dirname(stateFile), { recursive: true, mode: 448 });
24586
+ await mkdir2(path19.dirname(stateFile), { recursive: true, mode: 448 });
23645
24587
  await writeFile2(stateFile, `${JSON.stringify({
23646
- file: path17.basename(file),
24588
+ file: path19.basename(file),
23647
24589
  uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
23648
24590
  ...metadata
23649
24591
  }, null, 2)}
@@ -23661,15 +24603,15 @@ function readPositiveIntegerEnv2(name, fallback) {
23661
24603
  }
23662
24604
 
23663
24605
  // src/computerMigrationGuard.ts
23664
- import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "fs";
23665
- import path18 from "path";
24606
+ import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync10 } from "fs";
24607
+ import path20 from "path";
23666
24608
 
23667
24609
  // src/legacySupervisor.ts
23668
- import { execFileSync as execFileSync4 } from "child_process";
23669
- import { readFileSync as readFileSync8 } from "fs";
24610
+ import { execFileSync as execFileSync5 } from "child_process";
24611
+ import { readFileSync as readFileSync9 } from "fs";
23670
24612
  function execFileText(file, args) {
23671
24613
  try {
23672
- return execFileSync4(file, args, {
24614
+ return execFileSync5(file, args, {
23673
24615
  encoding: "utf8",
23674
24616
  timeout: 1e3,
23675
24617
  maxBuffer: 256 * 1024,
@@ -23681,7 +24623,7 @@ function execFileText(file, args) {
23681
24623
  }
23682
24624
  function readFileText(file) {
23683
24625
  try {
23684
- return readFileSync8(file, "utf8");
24626
+ return readFileSync9(file, "utf8");
23685
24627
  } catch {
23686
24628
  return void 0;
23687
24629
  }
@@ -23849,7 +24791,7 @@ function daemonApiKeyFingerprint(apiKey) {
23849
24791
  return getDaemonMachineLockId(apiKey).slice("machine-".length);
23850
24792
  }
23851
24793
  function findAdoptedComputerForLegacyFingerprint(slockHome, legacyApiKeyFingerprint) {
23852
- const serversDir = path18.join(slockHome, "computer", "servers");
24794
+ const serversDir = path20.join(slockHome, "computer", "servers");
23853
24795
  if (!existsSync9(serversDir)) return null;
23854
24796
  let serverDirs;
23855
24797
  try {
@@ -23858,10 +24800,10 @@ function findAdoptedComputerForLegacyFingerprint(slockHome, legacyApiKeyFingerpr
23858
24800
  return null;
23859
24801
  }
23860
24802
  for (const serverId of serverDirs) {
23861
- const attachmentPath = path18.join(serversDir, serverId, "runner.state.json");
24803
+ const attachmentPath = path20.join(serversDir, serverId, "runner.state.json");
23862
24804
  let raw;
23863
24805
  try {
23864
- raw = readFileSync9(attachmentPath, "utf8");
24806
+ raw = readFileSync10(attachmentPath, "utf8");
23865
24807
  } catch {
23866
24808
  continue;
23867
24809
  }
@@ -24409,7 +25351,7 @@ function onceDrain(res) {
24409
25351
  import { createHash as createHash9 } from "crypto";
24410
25352
  import { createReadStream as createReadStream2, createWriteStream } from "fs";
24411
25353
  import { lstat as lstat3, mkdir as mkdir3, readlink as readlink2, rm as rm3, symlink } from "fs/promises";
24412
- import path20 from "path";
25354
+ import path22 from "path";
24413
25355
  import { Transform } from "stream";
24414
25356
  import { pipeline } from "stream/promises";
24415
25357
  import { createGunzip, createGzip } from "zlib";
@@ -24419,7 +25361,7 @@ import { extract, pack } from "tar-stream";
24419
25361
  import { createHash as createHash8 } from "crypto";
24420
25362
  import { createReadStream } from "fs";
24421
25363
  import { lstat as lstat2, readdir as readdir4, readFile as readFile3, readlink } from "fs/promises";
24422
- import path19 from "path";
25364
+ import path21 from "path";
24423
25365
  var AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION = "agent-bundle/v1";
24424
25366
  var REGENERABLE_DIRECTORY_NAMES = [
24425
25367
  ".cache",
@@ -24443,8 +25385,8 @@ var SECRET_FILE_NAMES = /* @__PURE__ */ new Set([
24443
25385
  ]);
24444
25386
  var ENV_KEY_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
24445
25387
  async function buildAgentMigrationExportManifest(input) {
24446
- const slockHome = path19.resolve(input.slockHome);
24447
- const workspace = path19.resolve(input.workspacePath ?? path19.join(slockHome, "agents", input.agentId));
25388
+ const slockHome = path21.resolve(input.slockHome);
25389
+ const workspace = path21.resolve(input.workspacePath ?? path21.join(slockHome, "agents", input.agentId));
24448
25390
  const proposedIncludes = normalizeProposalPaths(input.cooperativeManifest?.include, workspace, "include");
24449
25391
  const proposedRegenerableExcludes = normalizeProposalPaths(input.cooperativeManifest?.exclude_regenerable, workspace, "exclude_regenerable");
24450
25392
  const cleanedProposal = normalizeProposalPaths(input.cooperativeManifest?.cleaned, workspace, "cleaned");
@@ -24505,7 +25447,7 @@ async function buildAgentMigrationExportManifest(input) {
24505
25447
  };
24506
25448
  }
24507
25449
  async function walkWorkspace(root, relativeDir, proposedRegenerableExcludes, state, opts) {
24508
- const absoluteDir = path19.join(root, relativeDir);
25450
+ const absoluteDir = path21.join(root, relativeDir);
24509
25451
  let entries;
24510
25452
  try {
24511
25453
  entries = await readdir4(absoluteDir, { withFileTypes: true });
@@ -24519,7 +25461,7 @@ async function walkWorkspace(root, relativeDir, proposedRegenerableExcludes, sta
24519
25461
  }
24520
25462
  entries.sort((a, b) => a.name.localeCompare(b.name));
24521
25463
  for (const entry of entries) {
24522
- const relativePath = toPosixPath(path19.join(relativeDir, entry.name));
25464
+ const relativePath = toPosixPath(path21.join(relativeDir, entry.name));
24523
25465
  if (entry.isDirectory()) {
24524
25466
  if (!opts.forceIncludeRegenerable && isRegenerablePath(relativePath)) {
24525
25467
  if (state.explicitIncludePaths.has(relativePath)) {
@@ -24546,7 +25488,7 @@ async function walkWorkspace(root, relativeDir, proposedRegenerableExcludes, sta
24546
25488
  async function includeWorkspacePath(workspaceRelativePath, state, opts) {
24547
25489
  const normalizedRelativePath = normalizeRelativePath(workspaceRelativePath);
24548
25490
  if (state.seenWorkspacePaths.has(normalizedRelativePath)) return;
24549
- const sourcePath = path19.join(state.workspace, normalizedRelativePath);
25491
+ const sourcePath = path21.join(state.workspace, normalizedRelativePath);
24550
25492
  let stat5;
24551
25493
  try {
24552
25494
  stat5 = await lstat2(sourcePath);
@@ -24563,7 +25505,7 @@ async function includeWorkspacePath(workspaceRelativePath, state, opts) {
24563
25505
  state.excludedRegenerable.push({
24564
25506
  path: normalizedRelativePath,
24565
25507
  reason: "cooperative_exclude_regenerable",
24566
- regenerableHint: `${path19.basename(normalizedRelativePath)} is treated as rebuildable/installable state and is not bundled by default`
25508
+ regenerableHint: `${path21.basename(normalizedRelativePath)} is treated as rebuildable/installable state and is not bundled by default`
24567
25509
  });
24568
25510
  return;
24569
25511
  }
@@ -24610,8 +25552,8 @@ async function includeWorkspacePath(workspaceRelativePath, state, opts) {
24610
25552
  async function buildCrossTreeRefs(refs) {
24611
25553
  const result = [];
24612
25554
  for (const ref of refs) {
24613
- const sourcePath = path19.resolve(ref.path);
24614
- const bundlePath = `runtime/${safeBundleSegment(ref.runtime)}/${safeBundleSegment(ref.label)}/${safeBundleSegment(path19.basename(sourcePath) || "session")}`;
25555
+ const sourcePath = path21.resolve(ref.path);
25556
+ const bundlePath = `runtime/${safeBundleSegment(ref.runtime)}/${safeBundleSegment(ref.label)}/${safeBundleSegment(path21.basename(sourcePath) || "session")}`;
24615
25557
  const entry = {
24616
25558
  runtime: ref.runtime,
24617
25559
  label: ref.label,
@@ -24644,7 +25586,7 @@ async function sha256File(filePath) {
24644
25586
  return hash.digest("hex");
24645
25587
  }
24646
25588
  async function detectSecretShapes(sourcePath, relativePath) {
24647
- const basename = path19.basename(relativePath);
25589
+ const basename = path21.basename(relativePath);
24648
25590
  const lowerBasename = basename.toLowerCase();
24649
25591
  const shapes = /* @__PURE__ */ new Set();
24650
25592
  if (SECRET_FILE_NAMES.has(lowerBasename) || lowerBasename.startsWith(".env.")) {
@@ -24677,9 +25619,9 @@ function normalizeProposalPaths(paths, workspace, source) {
24677
25619
  for (const value of paths) {
24678
25620
  const trimmed = value.trim();
24679
25621
  if (!trimmed) continue;
24680
- if (path19.isAbsolute(trimmed)) {
24681
- const relative = path19.relative(workspace, trimmed);
24682
- if (relative.startsWith("..") || path19.isAbsolute(relative)) {
25622
+ if (path21.isAbsolute(trimmed)) {
25623
+ const relative = path21.relative(workspace, trimmed);
25624
+ if (relative.startsWith("..") || path21.isAbsolute(relative)) {
24683
25625
  refusals.push({
24684
25626
  path: trimmed,
24685
25627
  reason: "outside_workspace",
@@ -24711,8 +25653,8 @@ function normalizeProposalPaths(paths, workspace, source) {
24711
25653
  return { paths: [...new Set(result)], refusals };
24712
25654
  }
24713
25655
  function normalizeRelativePath(value) {
24714
- const normalized = path19.normalize(value).replace(/^[\\/]+/, "");
24715
- if (!normalized || normalized === "." || normalized.startsWith("..") || path19.isAbsolute(normalized)) {
25656
+ const normalized = path21.normalize(value).replace(/^[\\/]+/, "");
25657
+ if (!normalized || normalized === "." || normalized.startsWith("..") || path21.isAbsolute(normalized)) {
24716
25658
  throw new Error(`unsafe migration export path: ${value}`);
24717
25659
  }
24718
25660
  return toPosixPath(normalized);
@@ -24731,7 +25673,7 @@ function safeBundleSegment(value) {
24731
25673
  return value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "unknown";
24732
25674
  }
24733
25675
  function toPosixPath(value) {
24734
- return value.split(path19.sep).join("/");
25676
+ return value.split(path21.sep).join("/");
24735
25677
  }
24736
25678
  function sortBundleEntries(entries) {
24737
25679
  return [...entries].sort((a, b) => a.bundlePath.localeCompare(b.bundlePath));
@@ -24760,7 +25702,7 @@ var AgentMigrationObjectStoreBundleTooLargeError = class extends Error {
24760
25702
  };
24761
25703
  async function buildAgentMigrationObjectStoreBundle(input) {
24762
25704
  assertPositiveMaxBytes(input.maxBytes);
24763
- const workspacePath = path20.resolve(input.workspacePath);
25705
+ const workspacePath = path22.resolve(input.workspacePath);
24764
25706
  const manifest = await buildAgentMigrationExportManifest({
24765
25707
  agentId: input.agentId,
24766
25708
  slockHome: input.slockHome,
@@ -24793,8 +25735,8 @@ async function buildAgentMigrationObjectStoreBundle(input) {
24793
25735
  }
24794
25736
  async function stageAgentMigrationObjectStoreBundle(input) {
24795
25737
  assertPositiveMaxBytes(input.maxBytes);
24796
- const stagingWorkspacePath = path20.join(
24797
- path20.resolve(input.slockHome),
25738
+ const stagingWorkspacePath = path22.join(
25739
+ path22.resolve(input.slockHome),
24798
25740
  "migrations",
24799
25741
  sanitizePathSegment(input.sessionId),
24800
25742
  "workspace"
@@ -24866,7 +25808,7 @@ async function writeArchive(tarPack, manifestBuffer, manifest, workspacePath) {
24866
25808
  throw new Error("MIGRATION_OBJECT_STORE_UNSUPPORTED_ENTRY");
24867
25809
  }
24868
25810
  const relativePath = normalizeWorkspaceRelativePath(entry.workspaceRelativePath);
24869
- const sourcePath = path20.resolve(entry.sourcePath);
25811
+ const sourcePath = path22.resolve(entry.sourcePath);
24870
25812
  const archivePath = `${ARCHIVE_WORKSPACE_PREFIX}${relativePath}`;
24871
25813
  if (entry.kind === "symlink") {
24872
25814
  await writeBufferedEntry(tarPack, {
@@ -24916,8 +25858,8 @@ async function handleArchiveEntry(input) {
24916
25858
  const expected = input.getExpectedEntries().get(relativePath);
24917
25859
  if (!expected) throw new Error(`MIGRATION_OBJECT_STORE_ARCHIVE_ENTRY_UNEXPECTED:${relativePath}`);
24918
25860
  input.extractedEntries.add(relativePath);
24919
- const targetPath = path20.join(input.stagingWorkspacePath, relativePath);
24920
- await mkdir3(path20.dirname(targetPath), { recursive: true });
25861
+ const targetPath = path22.join(input.stagingWorkspacePath, relativePath);
25862
+ await mkdir3(path22.dirname(targetPath), { recursive: true });
24921
25863
  if (expected.kind === "symlink") {
24922
25864
  if (input.header.type !== "symlink" || input.header.linkname !== expected.linkTarget) {
24923
25865
  throw new Error(`MIGRATION_OBJECT_STORE_LINK_TARGET_MISMATCH:${relativePath}`);
@@ -25034,8 +25976,8 @@ function encodeAccountingPath(value) {
25034
25976
  return encoded;
25035
25977
  }
25036
25978
  function normalizeWorkspaceRelativePath(relativePath) {
25037
- const normalized = path20.posix.normalize(relativePath.replaceAll("\\", "/"));
25038
- if (normalized === "." || normalized.startsWith("../") || normalized === ".." || path20.isAbsolute(normalized)) {
25979
+ const normalized = path22.posix.normalize(relativePath.replaceAll("\\", "/"));
25980
+ if (normalized === "." || normalized.startsWith("../") || normalized === ".." || path22.isAbsolute(normalized)) {
25039
25981
  throw new Error("MIGRATION_OBJECT_STORE_UNSAFE_PATH");
25040
25982
  }
25041
25983
  return normalized;
@@ -25096,15 +26038,15 @@ function sanitizePathSegment(value) {
25096
26038
  import { createHash as createHash10 } from "crypto";
25097
26039
  import { createReadStream as createReadStream3 } from "fs";
25098
26040
  import { access as access2, cp, lstat as lstat4, mkdir as mkdir4, readlink as readlink3, rename, writeFile as writeFile3 } from "fs/promises";
25099
- import path21 from "path";
26041
+ import path23 from "path";
25100
26042
  async function buildAgentMigrationAdoptPlan(input) {
25101
- const slockHome = path21.resolve(input.slockHome);
26043
+ const slockHome = path23.resolve(input.slockHome);
25102
26044
  let manifest;
25103
26045
  if (input.sourceKind === "orphan_directory" && !input.manifest) {
25104
26046
  manifest = await buildAgentMigrationExportManifest({
25105
26047
  agentId: input.agentId,
25106
26048
  slockHome,
25107
- workspacePath: path21.resolve(input.orphanWorkspacePath),
26049
+ workspacePath: path23.resolve(input.orphanWorkspacePath),
25108
26050
  mode: "forensic",
25109
26051
  now: input.now
25110
26052
  });
@@ -25117,11 +26059,11 @@ async function buildAgentMigrationAdoptPlan(input) {
25117
26059
  manifest,
25118
26060
  expectedAgentId: input.sourceKind === "orphan_directory" ? input.agentId : manifest.agentId
25119
26061
  });
25120
- const sourceWorkspacePath = path21.resolve(
26062
+ const sourceWorkspacePath = path23.resolve(
25121
26063
  input.sourceKind === "staged_bundle" ? input.stagingWorkspacePath : input.orphanWorkspacePath
25122
26064
  );
25123
- const finalWorkspacePath = path21.resolve(input.finalWorkspacePath ?? path21.join(slockHome, "agents", manifest.agentId));
25124
- const reportPath = path21.resolve(input.reportPath ?? path21.join(
26065
+ const finalWorkspacePath = path23.resolve(input.finalWorkspacePath ?? path23.join(slockHome, "agents", manifest.agentId));
26066
+ const reportPath = path23.resolve(input.reportPath ?? path23.join(
25125
26067
  slockHome,
25126
26068
  "migrations",
25127
26069
  sanitizePathSegment2(input.generation.grantKey),
@@ -25246,7 +26188,7 @@ async function verifyManifestFileEntry(sourceWorkspacePath, entry) {
25246
26188
  throw new Error("MIGRATION_MANIFEST_ENTRY_NOT_WORKSPACE");
25247
26189
  }
25248
26190
  const relative = normalizeWorkspaceRelativePath2(entry.workspaceRelativePath);
25249
- const entryPath = path21.join(sourceWorkspacePath, relative);
26191
+ const entryPath = path23.join(sourceWorkspacePath, relative);
25250
26192
  const info = await lstat4(entryPath).catch(() => null);
25251
26193
  if (!info) throw new Error("MIGRATION_MANIFEST_FILE_MISSING");
25252
26194
  if (entry.kind === "symlink") {
@@ -25265,14 +26207,14 @@ async function verifyManifestFileEntry(sourceWorkspacePath, entry) {
25265
26207
  }
25266
26208
  }
25267
26209
  function normalizeWorkspaceRelativePath2(relativePath) {
25268
- const normalized = path21.posix.normalize(relativePath.replaceAll("\\", "/"));
25269
- if (normalized === "." || normalized.startsWith("../") || normalized === ".." || path21.isAbsolute(normalized)) {
26210
+ const normalized = path23.posix.normalize(relativePath.replaceAll("\\", "/"));
26211
+ if (normalized === "." || normalized.startsWith("../") || normalized === ".." || path23.isAbsolute(normalized)) {
25270
26212
  throw new Error("MIGRATION_MANIFEST_UNSAFE_PATH");
25271
26213
  }
25272
26214
  return normalized;
25273
26215
  }
25274
26216
  async function assertFinalWorkspaceAvailable(sourceWorkspacePath, finalWorkspacePath) {
25275
- if (path21.resolve(sourceWorkspacePath) === path21.resolve(finalWorkspacePath)) return;
26217
+ if (path23.resolve(sourceWorkspacePath) === path23.resolve(finalWorkspacePath)) return;
25276
26218
  try {
25277
26219
  await access2(finalWorkspacePath);
25278
26220
  throw new Error("MIGRATION_WORKSPACE_ALREADY_EXISTS");
@@ -25281,9 +26223,9 @@ async function assertFinalWorkspaceAvailable(sourceWorkspacePath, finalWorkspace
25281
26223
  }
25282
26224
  }
25283
26225
  async function placeWorkspace(sourceWorkspacePath, finalWorkspacePath) {
25284
- if (path21.resolve(sourceWorkspacePath) === path21.resolve(finalWorkspacePath)) return;
26226
+ if (path23.resolve(sourceWorkspacePath) === path23.resolve(finalWorkspacePath)) return;
25285
26227
  const stagingPath = `${finalWorkspacePath}.migration-${process.pid}-${Date.now()}`;
25286
- await mkdir4(path21.dirname(finalWorkspacePath), { recursive: true });
26228
+ await mkdir4(path23.dirname(finalWorkspacePath), { recursive: true });
25287
26229
  await cp(sourceWorkspacePath, stagingPath, {
25288
26230
  recursive: true,
25289
26231
  dereference: false,
@@ -25296,7 +26238,7 @@ async function placeWorkspace(sourceWorkspacePath, finalWorkspacePath) {
25296
26238
  async function writeArrivalReport(reportPath, report) {
25297
26239
  const payload = `${canonicalJson3(report)}
25298
26240
  `;
25299
- await mkdir4(path21.dirname(reportPath), { recursive: true });
26241
+ await mkdir4(path23.dirname(reportPath), { recursive: true });
25300
26242
  await writeFile3(reportPath, payload, { mode: 384 });
25301
26243
  return sha256Buffer3(Buffer.from(payload, "utf8"));
25302
26244
  }
@@ -25327,10 +26269,10 @@ function sanitizePathSegment2(value) {
25327
26269
  }
25328
26270
 
25329
26271
  // src/secretFile.ts
25330
- import { chmodSync, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
25331
- import path22 from "path";
26272
+ import { chmodSync, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
26273
+ import path24 from "path";
25332
26274
  function readSecretFileSync(filePath) {
25333
- return readFileSync10(filePath, "utf8").trim();
26275
+ return readFileSync11(filePath, "utf8").trim();
25334
26276
  }
25335
26277
 
25336
26278
  // src/core.ts
@@ -25429,6 +26371,9 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
25429
26371
  "daemon.runtime_profile.report.sent": {
25430
26372
  spanAttrs: ["agentId", "launchId", "runtime", "report_source", "model_present", "session_ref_present", "workspace_ref_present"]
25431
26373
  },
26374
+ "daemon.runtime.progress.activity.suppressed": {
26375
+ spanAttrs: ["agentId", "launchId", "runtime", "outcome", "source", "itemType", "payloadBytes"]
26376
+ },
25432
26377
  "daemon.runtime_models.detect": {
25433
26378
  spanAttrs: ["runtime", "requestId"],
25434
26379
  eventAttrs: {
@@ -25628,13 +26573,13 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
25628
26573
  }
25629
26574
  }
25630
26575
  function resolveSlockCliPath(moduleUrl = import.meta.url) {
25631
- const thisDir = path23.dirname(fileURLToPath(moduleUrl));
25632
- const bundledDistPath = path23.resolve(thisDir, "cli", "index.js");
26576
+ const thisDir = path25.dirname(fileURLToPath(moduleUrl));
26577
+ const bundledDistPath = path25.resolve(thisDir, "cli", "index.js");
25633
26578
  try {
25634
26579
  accessSync(bundledDistPath);
25635
26580
  return bundledDistPath;
25636
26581
  } catch {
25637
- const workspaceDistPath = path23.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
26582
+ const workspaceDistPath = path25.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
25638
26583
  accessSync(workspaceDistPath);
25639
26584
  return workspaceDistPath;
25640
26585
  }
@@ -25648,7 +26593,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
25648
26593
  }
25649
26594
  async function runBundledSlockCli(argv) {
25650
26595
  process.argv = [process.execPath, "slock", ...argv];
25651
- await import("./dist-WZJGFAA7.js");
26596
+ await import("./dist-HDPAZ76N.js");
25652
26597
  }
25653
26598
  function detectRuntimes(tracer = noopTracer) {
25654
26599
  const ids = [];
@@ -25876,7 +26821,7 @@ var DaemonCore = class {
25876
26821
  }
25877
26822
  resolveMachineStateRoot() {
25878
26823
  if (this.options.machineStateDir) return this.options.machineStateDir;
25879
- if (this.options.dataDir) return path23.join(path23.dirname(this.options.dataDir), "machines");
26824
+ if (this.options.dataDir) return path25.join(path25.dirname(this.options.dataDir), "machines");
25880
26825
  return resolveDefaultMachineStateRoot();
25881
26826
  }
25882
26827
  shouldEnableLocalTrace() {
@@ -25904,7 +26849,7 @@ var DaemonCore = class {
25904
26849
  sinks: [this.localTraceSink]
25905
26850
  }));
25906
26851
  this.agentManager.setTracer(this.tracer);
25907
- this.agentManager.setCliTransportTraceDir(path23.join(machineDir, "traces"));
26852
+ this.agentManager.setCliTransportTraceDir(path25.join(machineDir, "traces"));
25908
26853
  }
25909
26854
  installTraceBundleUploader(machineDir) {
25910
26855
  if (!this.shouldEnableLocalTrace()) return;
@@ -26228,11 +27173,11 @@ var DaemonCore = class {
26228
27173
  const built = await buildAgentMigrationObjectStoreBundle({
26229
27174
  agentId: lease.agentId,
26230
27175
  slockHome: this.slockHome,
26231
- workspacePath: path23.join(this.agentsDataDir, lease.agentId),
27176
+ workspacePath: path25.join(this.agentsDataDir, lease.agentId),
26232
27177
  maxBytes: lease.maxBytes
26233
27178
  });
26234
- const spoolDirectory = await mkdtemp(path23.join(os8.tmpdir(), "raft-agent-migration-upload-"));
26235
- const spoolPath = path23.join(spoolDirectory, "bundle.tar.gz");
27179
+ const spoolDirectory = await mkdtemp(path25.join(os11.tmpdir(), "raft-agent-migration-upload-"));
27180
+ const spoolPath = path25.join(spoolDirectory, "bundle.tar.gz");
26236
27181
  let archiveBytes = 0;
26237
27182
  let uploadStatus = 0;
26238
27183
  try {
@@ -26295,7 +27240,7 @@ var DaemonCore = class {
26295
27240
  sourceKind: "staged_bundle",
26296
27241
  slockHome: this.slockHome,
26297
27242
  stagingWorkspacePath: staged.stagingWorkspacePath,
26298
- finalWorkspacePath: path23.join(this.agentsDataDir, lease.agentId),
27243
+ finalWorkspacePath: path25.join(this.agentsDataDir, lease.agentId),
26299
27244
  manifest: staged.manifest,
26300
27245
  manifestSha256: staged.manifestSha256,
26301
27246
  generation: {
@@ -27049,8 +27994,8 @@ var DaemonCore = class {
27049
27994
  ],
27050
27995
  runtimes,
27051
27996
  runningAgents: runningAgentIds,
27052
- hostname: this.options.hostname ?? os8.hostname(),
27053
- os: this.options.osDescription ?? `${os8.platform()} ${os8.arch()}`,
27997
+ hostname: this.options.hostname ?? os11.hostname(),
27998
+ os: this.options.osDescription ?? `${os11.platform()} ${os11.arch()}`,
27054
27999
  daemonVersion: this.daemonVersion,
27055
28000
  ...this.computerVersion ? { computerVersion: this.computerVersion } : {},
27056
28001
  migrationTransport: this.getMigrationTransportReady(),