lody 0.77.1 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -60,10 +60,11 @@ import require$$1$5, { Worker as Worker$1 } from "node:worker_threads";
60
60
  import require$$1$6, { fileURLToPath, pathToFileURL } from "node:url";
61
61
  import require$$1$7 from "node:console";
62
62
  import require$$1$8 from "node:dns";
63
- import { C as CodeCollabV2OpenTextRequestSchema, a as CodeCollabV2RefreshTextRequestSchema, b as CodeCollabV2SaveTextRequestSchema, c as CodeCollabV2OpenCurrentDiffRequestSchema, d as CodeCollabV2OpenAllChangesDiffRequestSchema, e as CodeCollabV2OpenTurnDiffRequestSchema, f as CodeCollabV2InitDirectoryRequestSchema, g as CodeCollabV2OpenTextOkSchema, h as CodeCollabV2RefreshTextResponseSchema, i as CodeCollabV2SaveTextResponseSchema, j as CodeCollabV2OpenCurrentDiffResponseSchema, k as CodeCollabV2OpenAllChangesDiffResponseSchema, l as CodeCollabV2OpenTurnDiffResponseSchema, m as CodeCollabV2InitDirectoryOkSchema, n as CodeCollabV2LspUnsupportedSchema, o as CodeCollabV2ErrorSchema, p as CodeCollabV2RpcContentEnvelopeSchema, q as deriveCodeCollabV2ContentKeyId, r as CodeCollabV2ErrorCodeSchema, s as CodeCollabV2RpcResponseSchema, t as deriveCodeCollabV2ContentKeyBytes, u as readCodeCollabFileIndexSignalFromFlock, w as writeCodeCollabFileIndexSignalToFlock, v as writeCodeCollabFileIndexToFlock, x as buildCodeCollabFileIndexState, y as CODE_COLLAB_V2_TEXT_LIMITS, z as CODE_COLLAB_V2_ALL_CHANGES_DIFF_LIMITS, A as computeAllChanges, B as codeCollabFileIndexStatesEqual, D as scanGitDirectoryEntries, E as closeDirectoryQuietly } from "./chunks/directory-handle-BBQKxZ5F.js";
63
+ import { C as CodeCollabV2OpenTextRequestSchema, a as CodeCollabV2RefreshTextRequestSchema, b as CodeCollabV2SaveTextRequestSchema, c as CodeCollabV2OpenCurrentDiffRequestSchema, d as CodeCollabV2OpenAllChangesDiffRequestSchema, e as CodeCollabV2OpenTurnDiffRequestSchema, f as CodeCollabV2InitDirectoryRequestSchema, g as CodeCollabV2OpenTextOkSchema, h as CodeCollabV2RefreshTextResponseSchema, i as CodeCollabV2SaveTextResponseSchema, j as CodeCollabV2OpenCurrentDiffResponseSchema, k as CodeCollabV2OpenAllChangesDiffResponseSchema, l as CodeCollabV2OpenTurnDiffResponseSchema, m as CodeCollabV2InitDirectoryOkSchema, n as CodeCollabV2LspUnsupportedSchema, o as CodeCollabV2ErrorSchema, p as CodeCollabV2RpcContentEnvelopeSchema, q as deriveCodeCollabV2ContentKeyId, r as CodeCollabV2ErrorCodeSchema, s as CodeCollabV2RpcResponseSchema, t as deriveCodeCollabV2ContentKeyBytes, u as readCodeCollabFileIndexSignalFromFlock, w as writeCodeCollabFileIndexSignalToFlock, v as writeCodeCollabFileIndexToFlock, x as buildCodeCollabFileIndexState, y as CODE_COLLAB_V2_TEXT_LIMITS, z as CODE_COLLAB_V2_ALL_CHANGES_DIFF_LIMITS, A as computeAllChanges, B as codeCollabFileIndexStatesEqual, D as scanGitDirectoryEntries, E as closeDirectoryQuietly } from "./chunks/directory-handle-OPjjCl3O.js";
64
64
  import { C as ClientSideConnection, P as PROTOCOL_VERSION, p as packageJson, n as ndJsonStream } from "./chunks/package-qnDHmQq4.js";
65
65
  import { StringDecoder } from "node:string_decoder";
66
66
  import { pipeline, finished } from "node:stream/promises";
67
+ import { r as runtimeManifest } from "./chunks/runtime-manifest-Fr5DEH54.js";
67
68
  import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
68
69
  import { createRequire } from "module";
69
70
  import { c as computeLineCounts, a as countTextLines } from "./chunks/diff-line-counts-bmGB_T-n.js";
@@ -2292,7 +2293,7 @@ Upgrade Node, then re-run: npx lody@latest`;
2292
2293
  return frames;
2293
2294
  };
2294
2295
  }
2295
- const version$8 = "5.38.8";
2296
+ const version$9 = "5.38.8";
2296
2297
  const FeatureFlagError = {
2297
2298
  ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
2298
2299
  FLAG_MISSING: "flag_missing",
@@ -3470,7 +3471,7 @@ Upgrade Node, then re-run: npx lody@latest`;
3470
3471
  return this.options.fetch ? this.options.fetch(url, options) : fetch(url, options);
3471
3472
  }
3472
3473
  getLibraryVersion() {
3473
- return version$8;
3474
+ return version$9;
3474
3475
  }
3475
3476
  getCustomUserAgent() {
3476
3477
  return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
@@ -4319,7 +4320,7 @@ Upgrade Node, then re-run: npx lody@latest`;
4319
4320
  throw new Error(`Unrecognized ${PLATFORM_ENV_VAR} value: ${JSON.stringify(raw2)} (expected "local" or "cloud")`);
4320
4321
  }
4321
4322
  const name$2 = "lody";
4322
- const version$7 = "0.76.0";
4323
+ const version$8 = "0.76.0";
4323
4324
  const normalizeRuntimeEnv = (value) => {
4324
4325
  switch (value?.toLowerCase()) {
4325
4326
  case "dev":
@@ -4568,6 +4569,11 @@ Upgrade Node, then re-run: npx lody@latest`;
4568
4569
  agentType: "kimi",
4569
4570
  displayName: "Kimi Code"
4570
4571
  },
4572
+ {
4573
+ runtimeName: "grok-build",
4574
+ agentType: "grok",
4575
+ displayName: "Grok"
4576
+ },
4571
4577
  {
4572
4578
  runtimeName: "claude-code",
4573
4579
  agentType: "claude",
@@ -4585,7 +4591,7 @@ Upgrade Node, then re-run: npx lody@latest`;
4585
4591
  return false;
4586
4592
  }
4587
4593
  const record2 = value;
4588
- return (record2.codexPath === void 0 || typeof record2.codexPath === "string") && (record2.claudeCodeExecutable === void 0 || typeof record2.claudeCodeExecutable === "string") && (record2.kimiPath === void 0 || typeof record2.kimiPath === "string");
4594
+ return (record2.codexPath === void 0 || typeof record2.codexPath === "string") && (record2.claudeCodeExecutable === void 0 || typeof record2.claudeCodeExecutable === "string") && (record2.kimiPath === void 0 || typeof record2.kimiPath === "string") && (record2.grokPath === void 0 || typeof record2.grokPath === "string");
4589
4595
  };
4590
4596
  const hasBuiltinRuntimeOverrideValues = (runtimeOverrides) => !!runtimeOverrides && Object.values(runtimeOverrides).some((value) => typeof value === "string" && value.trim().length > 0);
4591
4597
  const getBuiltinRuntimeOverrideSourceVersionSuffix = (runtimeOverrides) => hasBuiltinRuntimeOverrideValues(runtimeOverrides) ? `+override:${JSON.stringify(runtimeOverrides)}` : "";
@@ -4619,6 +4625,7 @@ Upgrade Node, then re-run: npx lody@latest`;
4619
4625
  const CODEX_AUTO_REVIEW_MODE_ID = "agent-auto-review";
4620
4626
  const BUILTIN_DEFAULT_MODE_IDS = {
4621
4627
  kimi: "auto",
4628
+ grok: "agent",
4622
4629
  claude: "auto",
4623
4630
  codex: CODEX_AUTO_REVIEW_MODE_ID
4624
4631
  };
@@ -10862,6 +10869,13 @@ Requirements:
10862
10869
  }
10863
10870
  return void 0;
10864
10871
  }
10872
+ function isDirectLocalProject(project, sessionIsWorktree) {
10873
+ if (!project || typeof project !== "object") {
10874
+ return false;
10875
+ }
10876
+ const typedProject = project;
10877
+ return typedProject.kind === "local" && typedProject.useWorktree !== true && sessionIsWorktree !== true;
10878
+ }
10865
10879
  function normalizeProjectRefForDedup(project) {
10866
10880
  if (!project) return null;
10867
10881
  if (project.kind === "github") {
@@ -11236,6 +11250,7 @@ Requirements:
11236
11250
  const WorktreeCleanupScriptConfigSchema = WorktreeSetupScriptConfigSchema;
11237
11251
  _enum$1([
11238
11252
  "kimi",
11253
+ "grok",
11239
11254
  "claude",
11240
11255
  "codex"
11241
11256
  ]);
@@ -11251,7 +11266,8 @@ Requirements:
11251
11266
  const BuiltinRuntimeOverridesSchema = object$1({
11252
11267
  codexPath: string$1().optional(),
11253
11268
  claudeCodeExecutable: string$1().optional(),
11254
- kimiPath: string$1().optional()
11269
+ kimiPath: string$1().optional(),
11270
+ grokPath: string$1().optional()
11255
11271
  }).strict();
11256
11272
  const AcpConfigOptionValueSchema = union$7([
11257
11273
  string$1(),
@@ -14241,32 +14257,16 @@ Requirements:
14241
14257
  }
14242
14258
  }
14243
14259
  },
14244
- {
14245
- id: "grok-build",
14246
- name: "Grok Build",
14247
- version: "1.0.0",
14248
- description: "xAI's coding agent and CLI",
14249
- icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/grok-build.svg",
14250
- distribution: {
14251
- npx: {
14252
- package: "@xai-official/grok@1.0.0",
14253
- args: [
14254
- "agent",
14255
- "stdio"
14256
- ]
14257
- }
14258
- }
14259
- },
14260
14260
  {
14261
14261
  id: "harn",
14262
14262
  name: "Harn",
14263
- version: "0.10.69",
14263
+ version: "0.10.70",
14264
14264
  description: "Harn runs .harn agent pipelines as a native ACP coding agent over stdio.",
14265
14265
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/harn.svg",
14266
14266
  distribution: {
14267
14267
  binary: {
14268
14268
  "darwin-aarch64": {
14269
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.69/harn-aarch64-apple-darwin.tar.gz",
14269
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.70/harn-aarch64-apple-darwin.tar.gz",
14270
14270
  cmd: "./harn",
14271
14271
  args: [
14272
14272
  "serve",
@@ -14274,7 +14274,7 @@ Requirements:
14274
14274
  ]
14275
14275
  },
14276
14276
  "darwin-x86_64": {
14277
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.69/harn-x86_64-apple-darwin.tar.gz",
14277
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.70/harn-x86_64-apple-darwin.tar.gz",
14278
14278
  cmd: "./harn",
14279
14279
  args: [
14280
14280
  "serve",
@@ -14282,7 +14282,7 @@ Requirements:
14282
14282
  ]
14283
14283
  },
14284
14284
  "linux-aarch64": {
14285
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.69/harn-aarch64-unknown-linux-gnu.tar.gz",
14285
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.70/harn-aarch64-unknown-linux-gnu.tar.gz",
14286
14286
  cmd: "./harn",
14287
14287
  args: [
14288
14288
  "serve",
@@ -14290,7 +14290,7 @@ Requirements:
14290
14290
  ]
14291
14291
  },
14292
14292
  "linux-x86_64": {
14293
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.69/harn-x86_64-unknown-linux-gnu.tar.gz",
14293
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.70/harn-x86_64-unknown-linux-gnu.tar.gz",
14294
14294
  cmd: "./harn",
14295
14295
  args: [
14296
14296
  "serve",
@@ -14298,7 +14298,7 @@ Requirements:
14298
14298
  ]
14299
14299
  },
14300
14300
  "windows-x86_64": {
14301
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.69/harn-x86_64-pc-windows-msvc.zip",
14301
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.70/harn-x86_64-pc-windows-msvc.zip",
14302
14302
  cmd: "harn.exe",
14303
14303
  args: [
14304
14304
  "serve",
@@ -23203,10 +23203,18 @@ ${context2.authorReply.trim()}
23203
23203
  const exhaustive = room;
23204
23204
  throw new Error(`Unsupported local data-plane room: ${String(exhaustive)}`);
23205
23205
  }
23206
+ function createUtf8StreamDecoder() {
23207
+ const decoder2 = new TextDecoder("utf-8");
23208
+ return (chunk) => decoder2.decode(chunk, {
23209
+ stream: true
23210
+ });
23211
+ }
23206
23212
  function createJsonLineSplitter(options) {
23213
+ const decodeChunk = createUtf8StreamDecoder();
23207
23214
  let buffer2 = "";
23208
23215
  let discardingOversizedLine = false;
23209
- return (chunk) => {
23216
+ return (input2) => {
23217
+ let chunk = typeof input2 === "string" ? input2 : decodeChunk(input2);
23210
23218
  if (discardingOversizedLine) {
23211
23219
  const newlineIndex2 = chunk.indexOf("\n");
23212
23220
  if (newlineIndex2 < 0) {
@@ -24587,6 +24595,7 @@ ${peerId}`;
24587
24595
  };
24588
24596
  const SUPPORTED_CLI_TYPES = [
24589
24597
  "kimi",
24598
+ "grok",
24590
24599
  "claude",
24591
24600
  "codex"
24592
24601
  ];
@@ -24629,7 +24638,7 @@ ${peerId}`;
24629
24638
  const getSessionIdFromRoomId = (roomId) => isSessionDocRoomId(roomId) ? roomId.slice(SESSION_DOC_PREFIX.length) : null;
24630
24639
  const isMachineDocRoomId = (roomId) => roomId.startsWith(MACHINE_DOC_PREFIX);
24631
24640
  const name$1 = "@lody/cli-cloud";
24632
- const version$6 = "0.77.1";
24641
+ const version$7 = "0.78.0";
24633
24642
  const type$2 = "module";
24634
24643
  const scripts = {
24635
24644
  "dev": "node dev.mjs",
@@ -24646,7 +24655,7 @@ ${peerId}`;
24646
24655
  };
24647
24656
  const pkg = {
24648
24657
  name: name$1,
24649
- version: version$6,
24658
+ version: version$7,
24650
24659
  "private": true,
24651
24660
  type: type$2,
24652
24661
  scripts,
@@ -24782,7 +24791,7 @@ ${peerId}`;
24782
24791
  }
24783
24792
  const runtimeEnv = getRuntimeEnv();
24784
24793
  const apiKey = resolveApiKey();
24785
- const release = `${name$2}@${version$7}`;
24794
+ const release = `${name$2}@${version$8}`;
24786
24795
  const distinctId = resolveDistinctId();
24787
24796
  const errorReportingEnabled = runtimeEnv !== "dev" && !!apiKey;
24788
24797
  let client$1 = null;
@@ -24794,9 +24803,9 @@ ${peerId}`;
24794
24803
  }
24795
24804
  const baseExceptionProps = {
24796
24805
  $lib: "lody-cli",
24797
- $lib_version: version$7,
24806
+ $lib_version: version$8,
24798
24807
  platform: "cli",
24799
- app_version: version$7,
24808
+ app_version: version$8,
24800
24809
  env: runtimeEnv,
24801
24810
  release,
24802
24811
  machine_id: distinctId
@@ -30406,9 +30415,9 @@ ${originalIndentation}`;
30406
30415
  })(common$2);
30407
30416
  return common$2;
30408
30417
  }
30409
- const version$5 = "3.19.0";
30418
+ const version$6 = "3.19.0";
30410
30419
  const require$$2$3 = {
30411
- version: version$5
30420
+ version: version$6
30412
30421
  };
30413
30422
  var transports = {};
30414
30423
  var winstonTransport = {
@@ -111063,6 +111072,17 @@ ${incoming}`).output;
111063
111072
  isCodexAgent() {
111064
111073
  return this.options.agentConfig?.agentType === "codex";
111065
111074
  }
111075
+ getGrokClientIdentifier() {
111076
+ return this.options.agentConfig?.cliType === "builtin" && this.options.agentConfig.agentType === "grok" ? `lody:${this.options.sessionId}` : void 0;
111077
+ }
111078
+ getGrokSessionMeta() {
111079
+ const clientIdentifier = this.getGrokClientIdentifier();
111080
+ return clientIdentifier ? {
111081
+ _meta: {
111082
+ clientIdentifier
111083
+ }
111084
+ } : {};
111085
+ }
111066
111086
  isCurrentAcpSession(acpSessionId) {
111067
111087
  return this.acpSessionId !== null && acpSessionId === this.acpSessionId;
111068
111088
  }
@@ -111080,6 +111100,8 @@ ${incoming}`).output;
111080
111100
  async startSession(stream2, workdir, resumeSessionId, timeoutOptions = {}, startupAbort, resolveSessionStart, forkSessionId, forkSessionTurnId) {
111081
111101
  const connection2 = new ClientSideConnection(() => this, stream2);
111082
111102
  this.connection = connection2;
111103
+ const grokClientIdentifier = this.getGrokClientIdentifier();
111104
+ const grokSessionMeta = this.getGrokSessionMeta();
111083
111105
  this.logger.debug(`[${this.options.sessionId}] Starting ACP client (workdir=${workdir} resumeSessionId=${resumeSessionId ?? "none"} forkSessionId=${forkSessionId ?? "none"})`);
111084
111106
  if (resumeSessionId && forkSessionId) {
111085
111107
  throw new Error("[ACP_SESSION_START_INVALID] resumeSessionId and forkSessionId are exclusive");
@@ -111110,6 +111132,11 @@ ${incoming}`).output;
111110
111132
  try {
111111
111133
  initResponse = await withTimeout$2(withAbort(connection2.initialize({
111112
111134
  protocolVersion: PROTOCOL_VERSION,
111135
+ ...grokClientIdentifier ? {
111136
+ _meta: {
111137
+ clientIdentifier: grokClientIdentifier
111138
+ }
111139
+ } : {},
111113
111140
  clientCapabilities: {
111114
111141
  terminal: this.terminalEnabled,
111115
111142
  plan: {},
@@ -111300,7 +111327,8 @@ ${incoming}`).output;
111300
111327
  const loadResponse = await withTimeout$2(withAbort(connection2.loadSession({
111301
111328
  sessionId: resumeSessionId,
111302
111329
  cwd: workdir,
111303
- mcpServers
111330
+ mcpServers,
111331
+ ...grokSessionMeta
111304
111332
  }), startupAbort), this.logger, "connection.loadSession", this.options.sessionId, ACP_LOAD_SESSION_TIMEOUT_MS);
111305
111333
  const loadDurationMs = performance$1.now() - loadStart;
111306
111334
  sessionResponse = {
@@ -111341,7 +111369,8 @@ ${incoming}`).output;
111341
111369
  const resumeResponse = await withTimeout$2(withAbort(connection2.resumeSession({
111342
111370
  sessionId: resumeSessionId,
111343
111371
  cwd: workdir,
111344
- mcpServers
111372
+ mcpServers,
111373
+ ...grokSessionMeta
111345
111374
  }), startupAbort), this.logger, "connection.resumeSession", this.options.sessionId, ACP_RESUME_SESSION_TIMEOUT_MS);
111346
111375
  const resumeDurationMs = performance$1.now() - resumeStart;
111347
111376
  sessionResponse = {
@@ -111380,7 +111409,8 @@ ${incoming}`).output;
111380
111409
  try {
111381
111410
  sessionResponse = await withTimeout$2(withAbort(connection2.newSession({
111382
111411
  cwd: workdir,
111383
- mcpServers
111412
+ mcpServers,
111413
+ ...grokSessionMeta
111384
111414
  }), startupAbort), this.logger, "connection.newSession", this.options.sessionId, ACP_NEW_SESSION_TIMEOUT_MS);
111385
111415
  } catch (error2) {
111386
111416
  if (isAcpAuthenticationRequired(error2)) {
@@ -111446,7 +111476,8 @@ ${incoming}`).output;
111446
111476
  try {
111447
111477
  return await withTimeout$2(connection2.newSession({
111448
111478
  cwd: workdir,
111449
- mcpServers
111479
+ mcpServers,
111480
+ ...this.getGrokSessionMeta()
111450
111481
  }), this.logger, "connection.newSession.editAndResend", this.options.sessionId, timeoutMs);
111451
111482
  } catch (error2) {
111452
111483
  throw new Error(`[ACP_SESSION_PREPARE_FAILED] ${formatErrorMessage(error2)}`, {
@@ -121098,14 +121129,18 @@ ${error2.message}` : execaMessage;
121098
121129
  highWaterMark
121099
121130
  }));
121100
121131
  }
121101
- const version$4 = "1.4.0";
121132
+ const version$5 = "1.4.0";
121102
121133
  const dependencies$1 = {
121103
121134
  "@openai/codex": "^0.147.0"
121104
121135
  };
121105
121136
  const codexPackageJson = {
121106
- version: version$4,
121137
+ version: version$5,
121107
121138
  dependencies: dependencies$1
121108
121139
  };
121140
+ const version$4 = "0.1.0";
121141
+ const grokPackageJson = {
121142
+ version: version$4
121143
+ };
121109
121144
  const version$3 = "2.1.220";
121110
121145
  const platforms = {
121111
121146
  "darwin-arm64": {
@@ -121256,10 +121291,13 @@ ${error2.message}` : execaMessage;
121256
121291
  const CLAUDE_ACP_ADAPTER_VERSION = packageJson.version;
121257
121292
  const CLAUDE_CODE_RUNTIME_VERSION = claudeSdkManifestJson.version;
121258
121293
  const KIMI_CODE_VERSION = kimiCodePackageJson.version;
121294
+ const GROK_ACP_ADAPTER_VERSION = grokPackageJson.version;
121295
+ const GROK_BUILD_RUNTIME_VERSION = runtimeManifest.officialRuntime.version;
121259
121296
  const KIMI_CODE_MIN_NODE_VERSION = resolveMinimumNodeVersion("@moonshot-ai/kimi-code", kimiCodePackageJson.engines.node);
121260
121297
  const BUILTIN_CODEX_CAPABILITY_SOURCE_VERSION = `builtin-codex-acp:${CODEX_ACP_ADAPTER_VERSION}+codex:${CODEX_RUNTIME_VERSION}`;
121261
121298
  const BUILTIN_CLAUDE_CAPABILITY_SOURCE_VERSION = `builtin-claude-acp:${CLAUDE_ACP_ADAPTER_VERSION}+agent-sdk:${CLAUDE_AGENT_SDK_VERSION}+claude-code:${CLAUDE_CODE_RUNTIME_VERSION}`;
121262
121299
  const BUILTIN_KIMI_CAPABILITY_SOURCE_VERSION = `builtin-kimi:${KIMI_CODE_VERSION}`;
121300
+ const BUILTIN_GROK_CAPABILITY_SOURCE_VERSION = `builtin-grok-acp:${GROK_ACP_ADAPTER_VERSION}+official-grok:${GROK_BUILD_RUNTIME_VERSION}`;
121263
121301
  const RUNTIMES = {
121264
121302
  codex: {
121265
121303
  name: "codex",
@@ -121409,6 +121447,66 @@ ${error2.message}` : execaMessage;
121409
121447
  cmd: "package/dist/main.mjs"
121410
121448
  }
121411
121449
  }
121450
+ },
121451
+ "grok-build": {
121452
+ name: "grok-build",
121453
+ version: GROK_BUILD_RUNTIME_VERSION,
121454
+ platforms: {
121455
+ "darwin-arm64": {
121456
+ fileName: `xai-official-grok-darwin-arm64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121457
+ sha256: "63aa0a0a95e7a555a372f1a501dcf59151376d7e4d900e24e1c591ff6cc8f818",
121458
+ size: 46222120,
121459
+ compression: "zstd",
121460
+ cmd: "grok",
121461
+ executableSha256: "13c7f4f0b9abb00bf38216302ea4bab31f03e13555e3576620eca1de572a8d21",
121462
+ executableSize: 131817232
121463
+ },
121464
+ "darwin-x64": {
121465
+ fileName: `xai-official-grok-darwin-x64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121466
+ sha256: "7bf0af43ba1f3dc8e860e7f887b75966ece7bb6102cc7a3b2fb5af275f757c8a",
121467
+ size: 50590131,
121468
+ compression: "zstd",
121469
+ cmd: "grok",
121470
+ executableSha256: "a82210a961deac9f0cb72ec6c334196abf76a587be4593bc59db2deab85ee6dc",
121471
+ executableSize: 147358e3
121472
+ },
121473
+ "linux-arm64": {
121474
+ fileName: `xai-official-grok-linux-arm64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121475
+ sha256: "c888d404ad218caa251cbdbbd0da5836c807957be5a83fd8ab21b69de93469d9",
121476
+ size: 49704069,
121477
+ compression: "zstd",
121478
+ cmd: "grok",
121479
+ executableSha256: "bb7c51116564a2219f6a49850815060f416918ac407f1f2ba82c53c0b0d4383f",
121480
+ executableSize: 133745832
121481
+ },
121482
+ "linux-x64": {
121483
+ fileName: `xai-official-grok-linux-x64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121484
+ sha256: "7d0bb4309e634e0ecb63403f35fa468120f5ecf2173feb6518371be1633ecd99",
121485
+ size: 53264623,
121486
+ compression: "zstd",
121487
+ cmd: "grok",
121488
+ executableSha256: "28dbc967a5843dae2374b6834dadbab95354e685c7e5c8dc750b92a4e5fc7c3e",
121489
+ executableSize: 163676672
121490
+ },
121491
+ "win32-arm64": {
121492
+ fileName: `xai-official-grok-win32-arm64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121493
+ sha256: "c821de276cb1fa835567bd6c5589709e6ba29182d6b0c9ad7c160cc3df91145c",
121494
+ size: 45241480,
121495
+ compression: "zstd",
121496
+ cmd: "grok.exe",
121497
+ executableSha256: "9d41447b6eee77cfb7359b7f50935ae64b4e7b7e7ef56c40e6d203f5660317e1",
121498
+ executableSize: 121471488
121499
+ },
121500
+ "win32-x64": {
121501
+ fileName: `xai-official-grok-win32-x64-${GROK_BUILD_RUNTIME_VERSION}.tar.zst`,
121502
+ sha256: "5d66d3e0c1e54b050c76b77dfc1dadefbf3e909459a31b4361d8307a671c179c",
121503
+ size: 48124303,
121504
+ compression: "zstd",
121505
+ cmd: "grok.exe",
121506
+ executableSha256: "d546dbc995c2ce9ba97c044d6af6b53f8c11c414a6355bf006802d07c572f406",
121507
+ executableSize: 139903488
121508
+ }
121509
+ }
121412
121510
  }
121413
121511
  };
121414
121512
  function sanitizeSegment(segment) {
@@ -122137,6 +122235,9 @@ ${error2.message}` : execaMessage;
122137
122235
  if (input2.agentType === "kimi") {
122138
122236
  return `${BUILTIN_KIMI_CAPABILITY_SOURCE_VERSION}${runtimeOverrideSuffix}`;
122139
122237
  }
122238
+ if (input2.agentType === "grok") {
122239
+ return `${BUILTIN_GROK_CAPABILITY_SOURCE_VERSION}${runtimeOverrideSuffix}`;
122240
+ }
122140
122241
  }
122141
122242
  return `builtin:${input2.agentType}:unknown`;
122142
122243
  }
@@ -122321,6 +122422,24 @@ ${error2.message}` : execaMessage;
122321
122422
  }
122322
122423
  };
122323
122424
  }
122425
+ if (input2.agentType === "grok") {
122426
+ const overridePath2 = trimRuntimeOverride(input2.runtimeOverrides?.grokPath);
122427
+ const grokPath = overridePath2 ?? await getManagedAgentRuntimeManager().ensureRuntime("grok-build", {
122428
+ onProgress: input2.onManagedRuntimeProgress,
122429
+ signal: input2.signal
122430
+ });
122431
+ return {
122432
+ command: process.execPath,
122433
+ args: [
122434
+ ...resolveCliAdapterEntry("grok-acp"),
122435
+ ...input2.extraArgs ?? []
122436
+ ],
122437
+ env: {
122438
+ GROK_PATH: grokPath,
122439
+ GROK_DISABLE_AUTOUPDATER: "1"
122440
+ }
122441
+ };
122442
+ }
122324
122443
  const overridePath = trimRuntimeOverride(input2.runtimeOverrides?.claudeCodeExecutable);
122325
122444
  const claudePath = overridePath ?? await getManagedAgentRuntimeManager().ensureRuntime("claude-code", {
122326
122445
  onProgress: input2.onManagedRuntimeProgress,
@@ -122368,6 +122487,24 @@ ${error2.message}` : execaMessage;
122368
122487
  ]
122369
122488
  };
122370
122489
  }
122490
+ if (input2.agentType === "grok") {
122491
+ if (input2.action === "status") return null;
122492
+ const overridePath2 = trimRuntimeOverride(input2.runtimeOverrides?.grokPath);
122493
+ const grokPath = overridePath2 ?? await getManagedAgentRuntimeManager().ensureRuntime("grok-build", {
122494
+ onProgress: input2.onManagedRuntimeProgress,
122495
+ signal: input2.signal
122496
+ });
122497
+ return {
122498
+ command: grokPath,
122499
+ args: [
122500
+ "login",
122501
+ "--device-auth"
122502
+ ],
122503
+ env: {
122504
+ GROK_DISABLE_AUTOUPDATER: "1"
122505
+ }
122506
+ };
122507
+ }
122371
122508
  const overridePath = trimRuntimeOverride(input2.runtimeOverrides?.claudeCodeExecutable);
122372
122509
  const claudePath = overridePath ?? await getManagedAgentRuntimeManager().ensureRuntime("claude-code", {
122373
122510
  onProgress: input2.onManagedRuntimeProgress,
@@ -123689,6 +123826,9 @@ enabled = false
123689
123826
  if (agentType === "codex") {
123690
123827
  return url.hostname === "auth.openai.com" && (url.pathname.startsWith("/codex/device") || url.pathname.startsWith("/oauth/authorize"));
123691
123828
  }
123829
+ if (agentType === "grok") {
123830
+ return hasDomain(url.hostname, "accounts.x.ai") && (url.pathname.startsWith("/oauth2/device") || url.pathname.startsWith("/device"));
123831
+ }
123692
123832
  return hasDomain(url.hostname, "kimi.com") && url.pathname.startsWith("/code/authorize_device");
123693
123833
  }
123694
123834
  function findAuthorizationUrl(agentType, output) {
@@ -123758,6 +123898,18 @@ enabled = false
123758
123898
  ]
123759
123899
  }
123760
123900
  ],
123901
+ grok: [
123902
+ {
123903
+ id: "xai-device-login",
123904
+ name: "xAI",
123905
+ description: "Sign in with an xAI account",
123906
+ type: "terminal",
123907
+ args: [
123908
+ "login",
123909
+ "--device-auth"
123910
+ ]
123911
+ }
123912
+ ],
123761
123913
  claude: [
123762
123914
  {
123763
123915
  id: "claude-ai-login",
@@ -123804,7 +123956,7 @@ enabled = false
123804
123956
  status: "unknown"
123805
123957
  };
123806
123958
  }
123807
- if (options.agentType === "kimi" || options.agentType === "codex") {
123959
+ if (options.agentType === "kimi" || options.agentType === "grok" || options.agentType === "codex") {
123808
123960
  return {
123809
123961
  status: "unknown"
123810
123962
  };
@@ -129374,10 +129526,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
129374
129526
  this.captureStatusChanged(options.sessionId, "idle", void 0, "turn_failed");
129375
129527
  }
129376
129528
  formatMemoryPressureFailureMessage(result) {
129377
- const availableMb = Math.round(result.availableMemoryBytes / 1024 / 1024);
129378
- const thresholdMb = Math.round(result.thresholdBytes / 1024 / 1024);
129379
- const commitText = result.availableCommitBytes !== void 0 && (result.pressureReason === "commit" || result.pressureReason === "physical_and_commit") && result.commitThresholdBytes !== void 0 ? ` Commit headroom is ${Math.round(result.availableCommitBytes / 1024 / 1024)}MB (threshold: ${Math.round(result.commitThresholdBytes / 1024 / 1024)}MB).` : "";
129380
- return `The machine is under memory pressure (${availableMb}MB available, ${thresholdMb}MB required to start a turn). The turn was not started; free memory and retry.${commitText}`;
129529
+ if (result.pressureReason === "darwin_pressure_critical") {
129530
+ return "The machine is at critical memory pressure \u2014 macOS is reclaiming memory and terminating processes to keep up. The turn was not started; free memory and retry.";
129531
+ }
129532
+ const mb = (bytes) => `${Math.round(bytes / 1024 / 1024)}MB`;
129533
+ const availableMb = mb(result.availableMemoryBytes);
129534
+ const marginMb = mb(result.thresholdBytes);
129535
+ const commitText = result.availableCommitBytes !== void 0 && (result.pressureReason === "commit" || result.pressureReason === "physical_and_commit") && result.commitThresholdBytes !== void 0 ? ` Commit headroom is ${mb(result.availableCommitBytes)} (safety margin: ${mb(result.commitThresholdBytes)}).` : "";
129536
+ const cgroup = result.cgroup;
129537
+ if (cgroup) {
129538
+ const hostText = result.hostAvailableBytes !== void 0 ? `host available ${mb(result.hostAvailableBytes)}, ` : "";
129539
+ const stallText = cgroup.psiSomeAvg10 !== null ? `stalled ${cgroup.psiSomeAvg10}% of the last 10s on reclaim` : "PSI unavailable; hard headroom is below the floor";
129540
+ return `The machine is under memory pressure and ${stallText}. cgroup ${cgroup.path}: ${mb(cgroup.currentBytes)} of ${mb(cgroup.maxBytes)} used, ${mb(cgroup.hardHeadroomBytes)} unused plus ${mb(cgroup.reclaimableBytes)} reclaimable cache/slab; ${hostText}safety margin ${marginMb}. The turn was not started; free memory and retry.${commitText}`;
129541
+ }
129542
+ return `The machine is under memory pressure (${availableMb} available, safety margin ${marginMb}). The turn was not started; free memory and retry.${commitText}`;
129381
129543
  }
129382
129544
  recordKnownChatFailureAndHaltEffect(options) {
129383
129545
  return this.tryPromise(() => this.recordKnownChatFailure(options)).pipe(flatMap$2(() => fail(new SessionTurnHalted({
@@ -146281,7 +146443,8 @@ ${edit.newString}` : edit.newString;
146281
146443
  }
146282
146444
  const LEGACY_BUILTIN_AGENT_TYPES = /* @__PURE__ */ new Set([
146283
146445
  "claude",
146284
- "codex"
146446
+ "codex",
146447
+ "grok"
146285
146448
  ]);
146286
146449
  function inferAgentConfigCliType(agentType) {
146287
146450
  const normalized = normalizeCliValue(agentType)?.toLowerCase();
@@ -150300,6 +150463,13 @@ ${entry.text}`).join("\n\n");
150300
150463
  if (!githubRepo) {
150301
150464
  return null;
150302
150465
  }
150466
+ let workspace = null;
150467
+ if (project?.kind === "local") {
150468
+ workspace = await this.resolveWorkspaceSessionContext(sessionId, sessionDoc);
150469
+ if (isDirectLocalProject(project, workspace.ownerMeta?.isWorktree)) {
150470
+ return null;
150471
+ }
150472
+ }
150303
150473
  const workdir = session2.getWorkdir();
150304
150474
  const detected = await detectPullRequestForBranch({
150305
150475
  session: session2,
@@ -150311,7 +150481,7 @@ ${entry.text}`).join("\n\n");
150311
150481
  if (!detected) {
150312
150482
  return null;
150313
150483
  }
150314
- const workspace = await this.resolveWorkspaceSessionContext(sessionId, sessionDoc);
150484
+ workspace ??= await this.resolveWorkspaceSessionContext(sessionId, sessionDoc);
150315
150485
  if (workspace.pullRequests.some((pr) => pr.status === "open")) {
150316
150486
  return detected;
150317
150487
  }
@@ -166926,15 +167096,28 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
166926
167096
  }
166927
167097
  const execFileAsync = promisify$1(execFile$1);
166928
167098
  const MEMORY_PROBE_TIMEOUT_MS = 1e3;
167099
+ const DARWIN_PRESSURE_NORMAL = 1;
167100
+ const DARWIN_PRESSURE_WARNING = 2;
167101
+ const DARWIN_PRESSURE_CRITICAL = 4;
166929
167102
  async function getMemoryPressureSnapshot() {
166930
- const windowsStatus = await getWindowsMemoryStatus();
167103
+ const [windowsStatus, darwinPressureLevel] = await Promise.all([
167104
+ getWindowsMemoryStatus(),
167105
+ getDarwinMemoryPressureLevel()
167106
+ ]);
166931
167107
  const systemAvailable = await getSystemAvailableMemoryBytes(windowsStatus);
166932
- const cgroupAvailable = getCgroupAvailableMemoryBytes();
166933
- const availableMemoryBytes = cgroupAvailable !== null ? Math.min(systemAvailable, cgroupAvailable) : systemAvailable;
167108
+ const cgroup = readCgroupMemoryState();
167109
+ const availableMemoryBytes = cgroup !== null ? Math.min(systemAvailable, cgroup.hardHeadroomBytes + cgroup.reclaimableBytes) : systemAvailable;
166934
167110
  const effectiveMemoryLimitBytes = getEffectiveMemoryLimitBytes();
166935
167111
  return {
166936
167112
  availableMemoryBytes,
166937
167113
  effectiveMemoryLimitBytes,
167114
+ ...darwinPressureLevel !== null ? {
167115
+ memoryPressureLevel: darwinPressureLevel
167116
+ } : {},
167117
+ ...cgroup !== null ? {
167118
+ cgroup,
167119
+ hostAvailableBytes: systemAvailable
167120
+ } : {},
166938
167121
  ...windowsStatus ? {
166939
167122
  availableCommitBytes: windowsStatus.availableCommitBytes,
166940
167123
  commitLimitBytes: windowsStatus.commitLimitBytes,
@@ -166944,7 +167127,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
166944
167127
  }
166945
167128
  function getEffectiveMemoryLimitBytes() {
166946
167129
  const totalMem = os__default$1.totalmem();
166947
- const cgroupMax = getCgroupMemoryMaxBytes();
167130
+ const cgroupMax = findTightestCgroupLimit()?.maxBytes ?? null;
166948
167131
  if (cgroupMax !== null) {
166949
167132
  return Math.min(totalMem, cgroupMax);
166950
167133
  }
@@ -167017,6 +167200,34 @@ $mem | ConvertTo-Json -Compress
167017
167200
  return null;
167018
167201
  }
167019
167202
  }
167203
+ async function getDarwinMemoryPressureLevel() {
167204
+ if (process.platform !== "darwin") {
167205
+ return null;
167206
+ }
167207
+ try {
167208
+ const { stdout } = await execFileAsync("sysctl", [
167209
+ "-n",
167210
+ "kern.memorystatus_vm_pressure_level"
167211
+ ], {
167212
+ encoding: "utf8",
167213
+ timeout: MEMORY_PROBE_TIMEOUT_MS
167214
+ });
167215
+ return parseDarwinPressureLevel(String(stdout ?? ""));
167216
+ } catch {
167217
+ return null;
167218
+ }
167219
+ }
167220
+ function parseDarwinPressureLevel(raw2) {
167221
+ const trimmed2 = raw2.trim();
167222
+ if (!/^\d+$/.test(trimmed2)) {
167223
+ return null;
167224
+ }
167225
+ const value = Number.parseInt(trimmed2, 10);
167226
+ if (value === DARWIN_PRESSURE_NORMAL || value === DARWIN_PRESSURE_WARNING || value === DARWIN_PRESSURE_CRITICAL) {
167227
+ return value;
167228
+ }
167229
+ return null;
167230
+ }
167020
167231
  async function getDarwinAvailableMemoryBytes() {
167021
167232
  if (process.platform !== "darwin") {
167022
167233
  return null;
@@ -167064,23 +167275,20 @@ $mem | ConvertTo-Json -Compress
167064
167275
  const availablePages = freePages + speculativePages + purgeablePages + reclaimableCachedPages;
167065
167276
  return availablePages * pageSize;
167066
167277
  }
167067
- function getCgroupMemoryMaxBytes() {
167278
+ function findTightestCgroupLimit() {
167068
167279
  try {
167069
167280
  const cgroupPath = readSelfCgroupPath();
167070
167281
  if (cgroupPath === null) return null;
167071
167282
  let tightest = null;
167072
167283
  let current2 = cgroupPath;
167073
167284
  for (let depth = 0; depth < 20; depth++) {
167074
- const memMaxPath = `/sys/fs/cgroup${current2 === "/" ? "" : current2}/memory.max`;
167075
- const raw2 = readFileSafe(memMaxPath);
167076
- if (raw2 !== null) {
167077
- const trimmed2 = raw2.trim();
167078
- if (trimmed2 !== "max") {
167079
- const value = parseInt(trimmed2, 10);
167080
- if (Number.isFinite(value) && value > 0) {
167081
- tightest = tightest === null ? value : Math.min(tightest, value);
167082
- }
167083
- }
167285
+ const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
167286
+ const value = parseCgroupLimit(readFileSafe(`${prefix}/memory.max`));
167287
+ if (value !== null && (tightest === null || value < tightest.maxBytes)) {
167288
+ tightest = {
167289
+ prefix,
167290
+ maxBytes: value
167291
+ };
167084
167292
  }
167085
167293
  if (current2 === "/" || current2 === "") break;
167086
167294
  const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
@@ -167092,42 +167300,72 @@ $mem | ConvertTo-Json -Compress
167092
167300
  return null;
167093
167301
  }
167094
167302
  }
167095
- function getCgroupAvailableMemoryBytes() {
167096
- try {
167097
- const cgroupPath = readSelfCgroupPath();
167098
- if (cgroupPath === null) return null;
167099
- let tightestMax = null;
167100
- let tightestPath = null;
167101
- let current2 = cgroupPath;
167102
- for (let depth = 0; depth < 20; depth++) {
167103
- const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
167104
- const raw2 = readFileSafe(`${prefix}/memory.max`);
167105
- if (raw2 !== null) {
167106
- const trimmed2 = raw2.trim();
167107
- if (trimmed2 !== "max") {
167108
- const value = parseInt(trimmed2, 10);
167109
- if (Number.isFinite(value) && value > 0) {
167110
- if (tightestMax === null || value < tightestMax) {
167111
- tightestMax = value;
167112
- tightestPath = prefix;
167113
- }
167114
- }
167115
- }
167116
- }
167117
- if (current2 === "/" || current2 === "") break;
167118
- const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
167119
- if (parent === current2) break;
167120
- current2 = parent;
167303
+ function parseCgroupLimit(raw2) {
167304
+ if (raw2 === null) return null;
167305
+ const trimmed2 = raw2.trim();
167306
+ if (trimmed2 === "max") return null;
167307
+ const value = parseInt(trimmed2, 10);
167308
+ return Number.isFinite(value) && value > 0 ? value : null;
167309
+ }
167310
+ function readCgroupMemoryState() {
167311
+ const limit2 = findTightestCgroupLimit();
167312
+ if (limit2 === null) return null;
167313
+ const currentRaw = readFileSafe(`${limit2.prefix}/memory.current`);
167314
+ if (currentRaw === null) return null;
167315
+ const currentBytes = parseInt(currentRaw.trim(), 10);
167316
+ if (!Number.isFinite(currentBytes)) return null;
167317
+ const stat2 = parseCgroupMemoryStat(readFileSafe(`${limit2.prefix}/memory.stat`) ?? "");
167318
+ return {
167319
+ path: limit2.prefix,
167320
+ maxBytes: limit2.maxBytes,
167321
+ highBytes: parseCgroupLimit(readFileSafe(`${limit2.prefix}/memory.high`)),
167322
+ currentBytes,
167323
+ hardHeadroomBytes: Math.max(0, limit2.maxBytes - currentBytes),
167324
+ reclaimableBytes: computeCgroupReclaimableBytes(stat2),
167325
+ stat: stat2,
167326
+ psiSomeAvg10: parseCgroupPressureSomeAvg10(readFileSafe(`${limit2.prefix}/memory.pressure`) ?? ""),
167327
+ events: parseCgroupMemoryEvents(readFileSafe(`${limit2.prefix}/memory.events`) ?? "")
167328
+ };
167329
+ }
167330
+ function parseCgroupMemoryStat(raw2) {
167331
+ const values = /* @__PURE__ */ new Map();
167332
+ for (const line3 of raw2.split("\n")) {
167333
+ const match5 = line3.trim().match(/^([a-z_]+)\s+(\d+)$/);
167334
+ if (match5?.[1] && match5[2]) {
167335
+ values.set(match5[1], parseInt(match5[2], 10));
167121
167336
  }
167122
- if (tightestMax === null || tightestPath === null) return null;
167123
- const currentRaw = readFileSafe(`${tightestPath}/memory.current`);
167124
- if (currentRaw === null) return null;
167125
- const currentUsage = parseInt(currentRaw.trim(), 10);
167126
- if (!Number.isFinite(currentUsage)) return null;
167127
- return Math.max(0, tightestMax - currentUsage);
167128
- } catch {
167129
- return null;
167130
167337
  }
167338
+ return {
167339
+ inactiveFileBytes: values.get("inactive_file") ?? 0,
167340
+ activeFileBytes: values.get("active_file") ?? 0,
167341
+ slabReclaimableBytes: values.get("slab_reclaimable") ?? 0,
167342
+ dirtyBytes: (values.get("file_dirty") ?? 0) + (values.get("file_writeback") ?? 0)
167343
+ };
167344
+ }
167345
+ function computeCgroupReclaimableBytes(stat2) {
167346
+ const cleanInactiveFile = Math.max(0, stat2.inactiveFileBytes - stat2.dirtyBytes);
167347
+ return cleanInactiveFile + Math.floor(stat2.slabReclaimableBytes / 2);
167348
+ }
167349
+ function parseCgroupPressureSomeAvg10(raw2) {
167350
+ const match5 = raw2.match(/^some\s+avg10=([\d.]+)/m);
167351
+ if (!match5?.[1]) return null;
167352
+ const value = Number.parseFloat(match5[1]);
167353
+ return Number.isFinite(value) ? value : null;
167354
+ }
167355
+ function parseCgroupMemoryEvents(raw2) {
167356
+ const read = (key2) => {
167357
+ const match5 = raw2.match(new RegExp(`^${key2}\\s+(\\d+)$`, "m"));
167358
+ if (!match5?.[1]) return null;
167359
+ const value = parseInt(match5[1], 10);
167360
+ return Number.isFinite(value) ? value : null;
167361
+ };
167362
+ const high = read("high");
167363
+ const max2 = read("max");
167364
+ if (high === null || max2 === null) return null;
167365
+ return {
167366
+ high,
167367
+ max: max2
167368
+ };
167131
167369
  }
167132
167370
  function readSelfCgroupPath() {
167133
167371
  try {
@@ -167156,6 +167394,11 @@ $mem | ConvertTo-Json -Compress
167156
167394
  const GIB = 1024 * 1024 * 1024;
167157
167395
  const WINDOWS_COMMIT_THRESHOLD_FLOOR_BYTES = 512 * 1024 * 1024;
167158
167396
  const WINDOWS_COMMIT_THRESHOLD_CEILING_BYTES = 2 * GIB;
167397
+ const DEFAULT_MAX_EVICTIONS_PER_CALL = 3;
167398
+ const DEFAULT_PRESSURE_RECHECK_ATTEMPTS = 2;
167399
+ const DEFAULT_PRESSURE_RECHECK_DELAY_MS = 500;
167400
+ const DEFAULT_PSI_STALL_AVG10 = 10;
167401
+ const DEFAULT_CGROUP_HARD_FLOOR_BYTES = 128 * 1024 * 1024;
167159
167402
  function defaultMemoryThresholdBytes() {
167160
167403
  const tenPercent = Math.floor(getEffectiveMemoryLimitBytes() * 0.1);
167161
167404
  return Math.max(GIB, Math.min(4 * GIB, tenPercent));
@@ -167165,16 +167408,83 @@ $mem | ConvertTo-Json -Compress
167165
167408
  idleTimeoutMs: readEnvNumber$1("LODY_SESSION_GC_IDLE_TIMEOUT_MS", 20 * 60 * 1e3),
167166
167409
  sweepIntervalMs: readEnvNumber$1("LODY_SESSION_GC_SWEEP_INTERVAL_MS", 60 * 1e3),
167167
167410
  enabled: process.env.LODY_SESSION_GC_ENABLED !== "false",
167168
- memoryThresholdBytes: readEnvNumber$1("LODY_SESSION_GC_MEMORY_THRESHOLD_BYTES", defaultMemoryThresholdBytes())
167411
+ memoryThresholdBytes: readEnvNumber$1("LODY_SESSION_GC_MEMORY_THRESHOLD_BYTES", defaultMemoryThresholdBytes()),
167412
+ maxEvictionsPerCall: readEnvNumber$1("LODY_SESSION_GC_MAX_EVICTIONS_PER_CALL", DEFAULT_MAX_EVICTIONS_PER_CALL),
167413
+ pressureRecheckAttempts: readEnvNumber$1("LODY_SESSION_GC_PRESSURE_RECHECK_ATTEMPTS", DEFAULT_PRESSURE_RECHECK_ATTEMPTS),
167414
+ pressureRecheckDelayMs: readEnvNumber$1("LODY_SESSION_GC_PRESSURE_RECHECK_DELAY_MS", DEFAULT_PRESSURE_RECHECK_DELAY_MS)
167169
167415
  };
167170
167416
  }
167171
167417
  function getWindowsCommitThresholdBytes(memoryThresholdBytes) {
167172
167418
  return Math.max(WINDOWS_COMMIT_THRESHOLD_FLOOR_BYTES, Math.min(WINDOWS_COMMIT_THRESHOLD_CEILING_BYTES, memoryThresholdBytes));
167173
167419
  }
167420
+ function evaluateMemoryPressure(snapshot, thresholds2) {
167421
+ if (thresholds2.platform === "darwin") {
167422
+ if (snapshot.memoryPressureLevel === DARWIN_PRESSURE_CRITICAL) {
167423
+ return {
167424
+ evict: true,
167425
+ block: true,
167426
+ reason: "darwin_pressure_critical"
167427
+ };
167428
+ }
167429
+ if (snapshot.memoryPressureLevel === DARWIN_PRESSURE_WARNING) {
167430
+ return {
167431
+ evict: true,
167432
+ block: false,
167433
+ reason: "darwin_pressure_warning"
167434
+ };
167435
+ }
167436
+ return {
167437
+ evict: false,
167438
+ block: false,
167439
+ reason: null
167440
+ };
167441
+ }
167442
+ const commitPressure = snapshot.availableCommitBytes !== void 0 && snapshot.availableCommitBytes < thresholds2.commitThresholdBytes;
167443
+ const cgroup = snapshot.cgroup;
167444
+ if (cgroup) {
167445
+ const hostLow = snapshot.hostAvailableBytes !== void 0 && snapshot.hostAvailableBytes < thresholds2.thresholdBytes;
167446
+ const cgroupLow = cgroup.hardHeadroomBytes + cgroup.reclaimableBytes < thresholds2.thresholdBytes;
167447
+ const stalled = cgroup.psiSomeAvg10 !== null ? cgroup.psiSomeAvg10 >= thresholds2.psiStallAvg10 : cgroup.hardHeadroomBytes < thresholds2.cgroupHardFloorBytes;
167448
+ if (hostLow || cgroupLow && stalled) {
167449
+ return {
167450
+ evict: true,
167451
+ block: true,
167452
+ reason: stalled ? "cgroup_stalled" : "physical"
167453
+ };
167454
+ }
167455
+ if (cgroupLow) {
167456
+ return {
167457
+ evict: true,
167458
+ block: false,
167459
+ reason: "cgroup_low_headroom"
167460
+ };
167461
+ }
167462
+ if (commitPressure) {
167463
+ return {
167464
+ evict: true,
167465
+ block: true,
167466
+ reason: "commit"
167467
+ };
167468
+ }
167469
+ return {
167470
+ evict: false,
167471
+ block: false,
167472
+ reason: null
167473
+ };
167474
+ }
167475
+ const physicalPressure = snapshot.availableMemoryBytes < thresholds2.thresholdBytes;
167476
+ const reason = physicalPressure && commitPressure ? "physical_and_commit" : physicalPressure ? "physical" : commitPressure ? "commit" : null;
167477
+ return {
167478
+ evict: reason !== null,
167479
+ block: reason !== null,
167480
+ reason
167481
+ };
167482
+ }
167174
167483
  class SessionGCManager {
167175
- constructor(config2, deps) {
167484
+ constructor(config2, deps, platform2 = process.platform) {
167176
167485
  this.config = config2;
167177
167486
  this.deps = deps;
167487
+ this.platform = platform2;
167178
167488
  }
167179
167489
  sweepInterval = null;
167180
167490
  start() {
@@ -167182,7 +167492,8 @@ $mem | ConvertTo-Json -Compress
167182
167492
  this.deps.logger.debug("[GC] Session GC is disabled");
167183
167493
  return;
167184
167494
  }
167185
- this.deps.logger.debug(`[GC] Starting session GC (interval=${this.config.sweepIntervalMs}ms, idleTimeout=${this.config.idleTimeoutMs}ms, memoryThreshold=${Math.round(this.config.memoryThresholdBytes / 1024 / 1024)}MB)`);
167495
+ const pressureSignal = this.platform === "darwin" ? "kern.memorystatus_vm_pressure_level" : `available<${Math.round(this.config.memoryThresholdBytes / 1024 / 1024)}MB`;
167496
+ this.deps.logger.debug(`[GC] Starting session GC (interval=${this.config.sweepIntervalMs}ms, idleTimeout=${this.config.idleTimeoutMs}ms, pressureSignal=${pressureSignal}, maxEvictionsPerCall=${this.config.maxEvictionsPerCall})`);
167186
167497
  this.sweepInterval = setInterval(() => void this.sweep(), this.config.sweepIntervalMs);
167187
167498
  }
167188
167499
  stop() {
@@ -167222,48 +167533,39 @@ $mem | ConvertTo-Json -Compress
167222
167533
  async evictForMemoryPressure(excludeSessionId) {
167223
167534
  const thresholdBytes = this.config.memoryThresholdBytes;
167224
167535
  const commitThresholdBytes = getWindowsCommitThresholdBytes(thresholdBytes);
167536
+ const thresholds2 = {
167537
+ platform: this.platform,
167538
+ thresholdBytes,
167539
+ commitThresholdBytes,
167540
+ psiStallAvg10: DEFAULT_PSI_STALL_AVG10,
167541
+ cgroupHardFloorBytes: DEFAULT_CGROUP_HARD_FLOOR_BYTES
167542
+ };
167225
167543
  let memorySnapshot = await this.deps.memoryPressure.getLatest();
167226
- let availableMemory = memorySnapshot.availableMemoryBytes;
167227
- let pressureReason = this.getPressureReason(memorySnapshot, thresholdBytes, commitThresholdBytes);
167228
- if (!this.config.enabled) {
167229
- return {
167230
- availableMemoryBytes: availableMemory,
167231
- thresholdBytes,
167232
- hadMemoryPressure: false,
167233
- stillUnderPressure: false,
167234
- evictedSessionIds: [],
167235
- pressureReason: null,
167236
- ...memorySnapshot.availableCommitBytes !== void 0 ? {
167237
- availableCommitBytes: memorySnapshot.availableCommitBytes,
167238
- commitThresholdBytes,
167239
- commitLimitBytes: memorySnapshot.commitLimitBytes,
167240
- committedBytes: memorySnapshot.committedBytes
167241
- } : {}
167242
- };
167243
- }
167244
- if (pressureReason === null) {
167245
- return {
167246
- availableMemoryBytes: availableMemory,
167544
+ let verdict = evaluateMemoryPressure(memorySnapshot, thresholds2);
167545
+ if (this.config.enabled && verdict.evict) {
167546
+ memorySnapshot = await this.deps.memoryPressure.refresh();
167547
+ verdict = evaluateMemoryPressure(memorySnapshot, thresholds2);
167548
+ }
167549
+ if (!this.config.enabled || !verdict.evict) {
167550
+ return this.buildEvictionResult({
167551
+ snapshot: memorySnapshot,
167247
167552
  thresholdBytes,
167553
+ commitThresholdBytes,
167248
167554
  hadMemoryPressure: false,
167249
- stillUnderPressure: false,
167250
- evictedSessionIds: [],
167251
- pressureReason: null,
167252
- ...memorySnapshot.availableCommitBytes !== void 0 ? {
167253
- availableCommitBytes: memorySnapshot.availableCommitBytes,
167254
- commitThresholdBytes,
167255
- commitLimitBytes: memorySnapshot.commitLimitBytes,
167256
- committedBytes: memorySnapshot.committedBytes
167257
- } : {}
167258
- };
167555
+ verdict: this.config.enabled ? verdict : {
167556
+ evict: false,
167557
+ block: false,
167558
+ reason: null
167559
+ },
167560
+ evictedSessionIds: []
167561
+ });
167259
167562
  }
167260
- const commitText = memorySnapshot.availableCommitBytes !== void 0 ? `, commit headroom ${Math.round(memorySnapshot.availableCommitBytes / 1024 / 1024)}MB (threshold: ${Math.round(commitThresholdBytes / 1024 / 1024)}MB)` : "";
167261
- this.deps.logger.debug(`[GC] Memory pressure detected: ${Math.round(availableMemory / 1024 / 1024)}MB available (threshold: ${Math.round(thresholdBytes / 1024 / 1024)}MB)${commitText}`);
167563
+ this.deps.logger.debug(`[GC] Memory pressure detected (${verdict.reason}): ${this.describeMemoryState(memorySnapshot, thresholdBytes, commitThresholdBytes)}`);
167262
167564
  const sessions = this.getSessionsWithIdleTime();
167263
167565
  sessions.sort((a, b) => b.idleMs - a.idleMs);
167264
167566
  const evictedSessionIds = [];
167265
167567
  for (const { sessionId, idleMs } of sessions) {
167266
- if (pressureReason === null) {
167568
+ if (!verdict.evict || evictedSessionIds.length >= this.config.maxEvictionsPerCall) {
167267
167569
  break;
167268
167570
  }
167269
167571
  if (excludeSessionId && sessionId === excludeSessionId) {
@@ -167280,46 +167582,78 @@ $mem | ConvertTo-Json -Compress
167280
167582
  await this.deps.cleanSession(sessionId);
167281
167583
  evictedSessionIds.push(sessionId);
167282
167584
  memorySnapshot = await this.deps.memoryPressure.refresh();
167283
- availableMemory = memorySnapshot.availableMemoryBytes;
167284
- pressureReason = this.getPressureReason(memorySnapshot, thresholdBytes, commitThresholdBytes);
167585
+ verdict = evaluateMemoryPressure(memorySnapshot, thresholds2);
167285
167586
  } catch (error2) {
167286
167587
  this.deps.logger.error(`[GC] Failed to evict session ${sessionId}: ${formatErrorMessage(error2)}`);
167287
167588
  }
167288
167589
  }
167289
- const stillUnderPressure = pressureReason !== null;
167590
+ for (let attempt = 0; verdict.block && attempt < this.config.pressureRecheckAttempts; attempt++) {
167591
+ await this.sleep(this.config.pressureRecheckDelayMs);
167592
+ memorySnapshot = await this.deps.memoryPressure.refresh();
167593
+ verdict = evaluateMemoryPressure(memorySnapshot, thresholds2);
167594
+ if (!verdict.block) {
167595
+ this.deps.logger.debug(`[GC] Memory pressure cleared on recheck ${attempt + 1}: ${this.describeMemoryState(memorySnapshot, thresholdBytes, commitThresholdBytes)}`);
167596
+ }
167597
+ }
167598
+ const availableMemory = memorySnapshot.availableMemoryBytes;
167599
+ const stillUnderPressure = verdict.block;
167290
167600
  if (evictedSessionIds.length > 0) {
167291
167601
  this.deps.logger.debug(`[GC] Memory pressure eviction complete: evicted ${evictedSessionIds.length} sessions, available memory now ${Math.round(availableMemory / 1024 / 1024)}MB`);
167292
167602
  } else if (stillUnderPressure) {
167293
167603
  this.deps.logger.debug("[GC] Memory pressure persists but no idle sessions were eligible for eviction");
167294
167604
  }
167295
- return {
167296
- availableMemoryBytes: availableMemory,
167605
+ return this.buildEvictionResult({
167606
+ snapshot: memorySnapshot,
167297
167607
  thresholdBytes,
167608
+ commitThresholdBytes,
167298
167609
  hadMemoryPressure: true,
167299
- stillUnderPressure,
167300
- evictedSessionIds,
167301
- pressureReason,
167302
- ...memorySnapshot.availableCommitBytes !== void 0 ? {
167303
- availableCommitBytes: memorySnapshot.availableCommitBytes,
167610
+ verdict,
167611
+ evictedSessionIds
167612
+ });
167613
+ }
167614
+ buildEvictionResult(options) {
167615
+ const { snapshot, thresholdBytes, commitThresholdBytes, verdict } = options;
167616
+ return {
167617
+ availableMemoryBytes: snapshot.availableMemoryBytes,
167618
+ thresholdBytes,
167619
+ hadMemoryPressure: options.hadMemoryPressure,
167620
+ stillUnderPressure: verdict.block,
167621
+ evictedSessionIds: options.evictedSessionIds,
167622
+ pressureReason: verdict.reason,
167623
+ ...snapshot.memoryPressureLevel !== void 0 ? {
167624
+ memoryPressureLevel: snapshot.memoryPressureLevel
167625
+ } : {},
167626
+ ...snapshot.cgroup !== void 0 ? {
167627
+ cgroup: snapshot.cgroup
167628
+ } : {},
167629
+ ...snapshot.hostAvailableBytes !== void 0 ? {
167630
+ hostAvailableBytes: snapshot.hostAvailableBytes
167631
+ } : {},
167632
+ ...snapshot.availableCommitBytes !== void 0 ? {
167633
+ availableCommitBytes: snapshot.availableCommitBytes,
167304
167634
  commitThresholdBytes,
167305
- commitLimitBytes: memorySnapshot.commitLimitBytes,
167306
- committedBytes: memorySnapshot.committedBytes
167635
+ commitLimitBytes: snapshot.commitLimitBytes,
167636
+ committedBytes: snapshot.committedBytes
167307
167637
  } : {}
167308
167638
  };
167309
167639
  }
167310
- getPressureReason(snapshot, thresholdBytes, commitThresholdBytes) {
167311
- const physicalPressure = snapshot.availableMemoryBytes < thresholdBytes;
167312
- const commitPressure = snapshot.availableCommitBytes !== void 0 && snapshot.availableCommitBytes < commitThresholdBytes;
167313
- if (physicalPressure && commitPressure) {
167314
- return "physical_and_commit";
167315
- }
167316
- if (physicalPressure) {
167317
- return "physical";
167640
+ sleep(ms2) {
167641
+ if (this.deps.sleep) return this.deps.sleep(ms2);
167642
+ return new Promise((resolve2) => {
167643
+ setTimeout(resolve2, ms2).unref?.();
167644
+ });
167645
+ }
167646
+ describeMemoryState(snapshot, thresholdBytes, commitThresholdBytes) {
167647
+ if (snapshot.memoryPressureLevel !== void 0) {
167648
+ return `kernel pressure level ${snapshot.memoryPressureLevel}`;
167318
167649
  }
167319
- if (commitPressure) {
167320
- return "commit";
167650
+ const cgroup = snapshot.cgroup;
167651
+ if (cgroup) {
167652
+ const mb = (bytes) => Math.round(bytes / 1024 / 1024);
167653
+ return `cgroup ${cgroup.path}: hard headroom ${mb(cgroup.hardHeadroomBytes)}MB + reclaimable ${mb(cgroup.reclaimableBytes)}MB (of ${mb(cgroup.stat.activeFileBytes)}MB active file cache not counted), host available ${snapshot.hostAvailableBytes !== void 0 ? mb(snapshot.hostAvailableBytes) : "?"}MB, PSI some avg10 ${cgroup.psiSomeAvg10 ?? "?"}, threshold ${mb(thresholdBytes)}MB`;
167321
167654
  }
167322
- return null;
167655
+ const commitText = snapshot.availableCommitBytes !== void 0 ? `, commit headroom ${Math.round(snapshot.availableCommitBytes / 1024 / 1024)}MB (threshold: ${Math.round(commitThresholdBytes / 1024 / 1024)}MB)` : "";
167656
+ return `${Math.round(snapshot.availableMemoryBytes / 1024 / 1024)}MB available (threshold: ${Math.round(thresholdBytes / 1024 / 1024)}MB)${commitText}`;
167323
167657
  }
167324
167658
  async getIdleCandidates() {
167325
167659
  const sessions = this.getSessionsWithIdleTime();
@@ -178050,13 +178384,14 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
178050
178384
  await removeStaleUnixSocket(socketPath, "local_terminal_socket_in_use");
178051
178385
  const server = net.createServer((socket) => {
178052
178386
  let buffer2 = "";
178387
+ const decodeChunk = createUtf8StreamDecoder();
178053
178388
  const state2 = createTerminalSocketState();
178054
178389
  activeClientSockets$1.add(socket);
178055
178390
  const unsubscribe = config2.terminalPtyService.onEvent((event) => {
178056
178391
  publishTerminalEvent(socket, state2, event);
178057
178392
  });
178058
178393
  socket.on("data", (chunk) => {
178059
- buffer2 += chunk.toString("utf8");
178394
+ buffer2 += decodeChunk(chunk);
178060
178395
  if (buffer2.length > MAX_BUFFER_BYTES) {
178061
178396
  send(socket, {
178062
178397
  type: "error",
@@ -178214,7 +178549,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
178214
178549
  });
178215
178550
  }
178216
178551
  });
178217
- socket.on("data", (chunk) => splitLines(chunk.toString("utf8")));
178552
+ socket.on("data", (chunk) => splitLines(chunk));
178218
178553
  socket.setTimeout(CONNECTION_IDLE_TIMEOUT_MS, () => {
178219
178554
  config2.logger.debug(`[loro-data-plane] connection ${connectionId} idle; dropping`);
178220
178555
  socket.destroy();
@@ -179810,6 +180145,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
179810
180145
  continue;
179811
180146
  }
179812
180147
  const runtimeBranch = resolveDiscoveryBranch(ownerMeta) ?? null;
180148
+ const prPollingEnabled = !isDirectLocalProject(ownerMeta.project, ownerMeta.isWorktree);
179813
180149
  entries.set(ownerSessionId, {
179814
180150
  ownerSessionId,
179815
180151
  memberSessionIds: [
@@ -179817,8 +180153,8 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
179817
180153
  ],
179818
180154
  lastMessageAtMs: maxNullable(ownerMeta.lastMessageAt ?? null, sessionId === ownerSessionId ? null : meta.lastMessageAt ?? null),
179819
180155
  runtimeBranch,
179820
- statusTargets: collectStatusTargets(ownerMeta),
179821
- discoveryTarget: collectDiscoveryTarget(ownerMeta, runtimeBranch, discoveryFingerprints[ownerSessionId], resolveGitHubRepo)
180156
+ statusTargets: prPollingEnabled ? collectStatusTargets(ownerMeta) : [],
180157
+ discoveryTarget: prPollingEnabled ? collectDiscoveryTarget(ownerMeta, runtimeBranch, discoveryFingerprints[ownerSessionId], resolveGitHubRepo) : null
179822
180158
  });
179823
180159
  }
179824
180160
  return Array.from(entries.values());
@@ -180760,6 +181096,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
180760
181096
  if (!freshMeta || freshMeta.isArchived || freshMeta.machineId !== runtime.handle.machineId) {
180761
181097
  return failed;
180762
181098
  }
181099
+ if (isDirectLocalProject(freshMeta.project, freshMeta.isWorktree)) {
181100
+ return failed;
181101
+ }
180763
181102
  const freshContext = resolveOwnerRepositoryContext(freshMeta);
180764
181103
  const contextUnchanged = args2.queriedBranch === null || freshContext.repoFullName === repoFullName && freshContext.branch === args2.queriedBranch;
180765
181104
  const discovered = contextUnchanged ? args2.discovered : [];
@@ -185386,10 +185725,11 @@ Shutting down gracefully${reason}...`);
185386
185725
  function logCliDetectionResults(logger2, availability) {
185387
185726
  logger2.debug("Local agent auth detection results:");
185388
185727
  logger2.debug(`kimi: ${availability.kimi || "not found"}`);
185728
+ logger2.debug(`grok: ${availability.grok || "not found"}`);
185389
185729
  logger2.debug(`claude: ${availability.claude || "not found"}`);
185390
185730
  logger2.debug(`codex: ${availability.codex || "not found"}`);
185391
185731
  }
185392
- const startCommand = new Command("start").description("Start agent service in native mode").option("--machine-name <name>", "Machine name to register (defaults to hostname)").option("--cli-types <types...>", "Specify CLI types to register: `kimi`, `claude`, or `codex`", (value, previous) => {
185732
+ const startCommand = new Command("start").description("Start agent service in native mode").option("--machine-name <name>", "Machine name to register (defaults to hostname)").option("--cli-types <types...>", "Specify CLI types to register: `kimi`, `grok`, `claude`, or `codex`", (value, previous) => {
185393
185733
  if (!previous) {
185394
185734
  return [
185395
185735
  value
@@ -185417,7 +185757,7 @@ Shutting down gracefully${reason}...`);
185417
185757
  });
185418
185758
  scrubLocalSupervisorCapabilityEnv();
185419
185759
  await traceAsync(logger2, "startup.process_resource_profile", void 0, async () => normalizeCurrentProcessResourceProfile(logger2));
185420
- for (const diagnostic of getRuntimeDiagnostics(version$7)) {
185760
+ for (const diagnostic of getRuntimeDiagnostics(version$8)) {
185421
185761
  logger2.info(diagnostic);
185422
185762
  }
185423
185763
  if (options.heartbeatLog) {
@@ -185480,6 +185820,7 @@ Shutting down gracefully${reason}...`);
185480
185820
  const cliDetectionStartedAt = Date.now();
185481
185821
  const cliAvailability = {
185482
185822
  kimi: "managed-runtime",
185823
+ grok: "managed-runtime",
185483
185824
  claude: checkClaude(),
185484
185825
  codex: checkCodex()
185485
185826
  };
@@ -185487,6 +185828,7 @@ Shutting down gracefully${reason}...`);
185487
185828
  logCliDetectionResults(logger2, cliAvailability);
185488
185829
  captureAgentServiceEvent("agent_service_cli_detection", {
185489
185830
  kimi_available: true,
185831
+ grok_available: true,
185490
185832
  claude_available: Boolean(cliAvailability.claude),
185491
185833
  codex_available: Boolean(cliAvailability.codex)
185492
185834
  });
@@ -185497,7 +185839,7 @@ Shutting down gracefully${reason}...`);
185497
185839
  availability: cliAvailability
185498
185840
  });
185499
185841
  if (cliSelection.invalid.length > 0) {
185500
- logger2.error(`Unknown CLI types: ${cliSelection.invalid.join(", ")}. Supported values: kimi, claude, codex.`);
185842
+ logger2.error(`Unknown CLI types: ${cliSelection.invalid.join(", ")}. Supported values: kimi, grok, claude, codex.`);
185501
185843
  process.exit(1);
185502
185844
  }
185503
185845
  if (cliSelection.missing.length > 0) {
@@ -213292,7 +213634,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
213292
213634
  data = createReviewBundleSnapshot(bundle);
213293
213635
  }
213294
213636
  const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
213295
- const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-kMY9w9TP.js").then(async (m) => {
213637
+ const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-Bgp2Thsg.js").then(async (m) => {
213296
213638
  await m.__tla;
213297
213639
  return m;
213298
213640
  });
@@ -214490,6 +214832,76 @@ ${result.stdout ?? ""}`;
214490
214832
  return null;
214491
214833
  }
214492
214834
  }
214835
+ function planDaemonAuthPreflight(input2) {
214836
+ const { existingAuth, validation: validation2, interactive } = input2;
214837
+ const login = (reason) => interactive ? {
214838
+ action: "login",
214839
+ reason
214840
+ } : {
214841
+ action: "abort",
214842
+ reason: "login_required_non_interactive",
214843
+ message: reason === "credentials_rejected" ? "This machine is no longer signed in to Lody." : "This machine is not connected to Lody yet."
214844
+ };
214845
+ if (!existingAuth || !validation2) {
214846
+ return login("missing_credentials");
214847
+ }
214848
+ if (validation2.valid) {
214849
+ return {
214850
+ action: "proceed",
214851
+ user: validation2.user
214852
+ };
214853
+ }
214854
+ if (isTokenValidationUnavailable(validation2)) {
214855
+ return {
214856
+ action: "abort",
214857
+ reason: "backend_unreachable",
214858
+ message: validation2.error ?? validation2.reason
214859
+ };
214860
+ }
214861
+ return login("credentials_rejected");
214862
+ }
214863
+ async function ensureDaemonBackendAuth(options) {
214864
+ const { authClient, logger: logger2, machineName } = options;
214865
+ const interactive = options.interactive ?? process.stdout.isTTY === true;
214866
+ const existingAuth = authClient.getAuthInfo();
214867
+ logger2.info("Checking the connection to Lody\u2026");
214868
+ const validation2 = existingAuth ? await authClient.validateToken(existingAuth.token) : null;
214869
+ const plan = planDaemonAuthPreflight({
214870
+ existingAuth,
214871
+ validation: validation2,
214872
+ interactive
214873
+ });
214874
+ if (plan.action === "abort") {
214875
+ return {
214876
+ status: "failed",
214877
+ reason: plan.reason,
214878
+ message: plan.reason === "backend_unreachable" ? `Could not reach Lody to verify this machine's credentials: ${plan.message}` : plan.message
214879
+ };
214880
+ }
214881
+ if (plan.action === "proceed") {
214882
+ logger2.success(`${chalk.green("\u2713")} Connected as ${chalk.cyan(plan.user.name || plan.user.email)}`);
214883
+ return {
214884
+ status: "authenticated",
214885
+ user: plan.user
214886
+ };
214887
+ }
214888
+ logger2.info(plan.reason === "credentials_rejected" ? "This machine is no longer signed in to Lody. Sign in again to connect it." : "This machine is not connected to Lody yet. Sign in to connect it.");
214889
+ const loginResult = await performLogin(authClient, logger2, {
214890
+ machineName
214891
+ });
214892
+ if (!loginResult.success) {
214893
+ return {
214894
+ status: "failed",
214895
+ reason: "login_failed",
214896
+ message: `Login failed: ${loginResult.error}`
214897
+ };
214898
+ }
214899
+ logger2.success(`${chalk.green("\u2713")} Connected as ${chalk.cyan(loginResult.user.name || loginResult.user.email)}`);
214900
+ return {
214901
+ status: "authenticated",
214902
+ user: loginResult.user
214903
+ };
214904
+ }
214493
214905
  function buildDaemonStartPassthroughArgs(options, unknownArgs) {
214494
214906
  const sanitized = [];
214495
214907
  for (let index = 0; index < unknownArgs.length; index += 1) {
@@ -214643,6 +215055,20 @@ ${result.stdout ?? ""}`;
214643
215055
  }
214644
215056
  }
214645
215057
  }
215058
+ function daemonAuthFailureHint(reason) {
215059
+ switch (reason) {
215060
+ case "backend_unreachable":
215061
+ return `Retry once the connection is back, or start anyway with ${chalk.yellow("--skip-auth-check")}.`;
215062
+ case "login_required_non_interactive":
215063
+ return `Run ${chalk.yellow("lody login")} from a terminal, or pass ${chalk.yellow("--auth <cli_token>")}.`;
215064
+ case "login_failed":
215065
+ return `Run ${chalk.yellow("lody login")} and retry.`;
215066
+ default: {
215067
+ const unreachable = reason;
215068
+ return unreachable;
215069
+ }
215070
+ }
215071
+ }
214646
215072
  function printStartTips() {
214647
215073
  console.log(`Use ${chalk.yellow("lody daemon status")} to check status`);
214648
215074
  console.log(`Use ${chalk.yellow("lody daemon stop")} to stop`);
@@ -214663,7 +215089,7 @@ ${result.stdout ?? ""}`;
214663
215089
  }
214664
215090
  return false;
214665
215091
  }
214666
- const daemonCommand = new Command("daemon").description("Run lody as a background daemon service").addCommand(new Command("start").description("Start lody daemon in the background").option("--auth <credential>", "Connect with a CLI API key or machine connection token").option("--machine-name <name>", "Machine name to register (defaults to hostname)").allowUnknownOption(true).action(async (options, cmd) => {
215092
+ const daemonCommand = new Command("daemon").description("Run lody as a background daemon service").addCommand(new Command("start").description("Start lody daemon in the background").option("--auth <credential>", "Connect with a CLI API key or machine connection token").option("--machine-name <name>", "Machine name to register (defaults to hostname)").option("--skip-auth-check", "Skip the backend connectivity and sign-in check before entering daemon mode").allowUnknownOption(true).action(async (options, cmd) => {
214667
215093
  const readiness = await checkDaemonStartReadiness();
214668
215094
  if (await reportDaemonStartBlocked(readiness, {
214669
215095
  restart: false
@@ -214671,20 +215097,46 @@ ${result.stdout ?? ""}`;
214671
215097
  return;
214672
215098
  }
214673
215099
  const passthroughArgs = buildDaemonStartPassthroughArgs(options, cmd.args);
214674
- if (options.auth) {
215100
+ const platformKind = getCliPlatformKind();
215101
+ if (platformKind === "local" && options.auth) {
215102
+ console.error("--auth is not available on the local platform.");
215103
+ await exitDaemonCommand(1);
215104
+ return;
215105
+ }
215106
+ if (platformKind === "cloud" && (options.auth || !options.skipAuthCheck)) {
214675
215107
  createHybridLogger({
214676
215108
  level: "info"
214677
215109
  });
214678
215110
  const logger2 = getLogger("daemon");
214679
215111
  const authClient = new AuthClient(logger2);
214680
- const loginResult = await performLoginWithAuthCredential(authClient, logger2, {
214681
- credential: options.auth,
214682
- machineName: options.machineName
214683
- });
214684
- if (!loginResult.success) {
214685
- console.error(loginResult.error);
214686
- await exitDaemonCommand(1);
214687
- return;
215112
+ if (options.auth) {
215113
+ const loginResult = await performLoginWithAuthCredential(authClient, logger2, {
215114
+ credential: options.auth,
215115
+ machineName: options.machineName
215116
+ });
215117
+ if (!loginResult.success) {
215118
+ captureDaemonEvent("daemon_start_failed", {
215119
+ reason_code: "auth_credential"
215120
+ });
215121
+ console.error(loginResult.error);
215122
+ await exitDaemonCommand(1);
215123
+ return;
215124
+ }
215125
+ } else {
215126
+ const preflight = await ensureDaemonBackendAuth({
215127
+ authClient,
215128
+ logger: logger2,
215129
+ machineName: options.machineName
215130
+ });
215131
+ if (preflight.status === "failed") {
215132
+ captureDaemonEvent("daemon_start_failed", {
215133
+ reason_code: preflight.reason
215134
+ });
215135
+ console.error(preflight.message);
215136
+ console.error(daemonAuthFailureHint(preflight.reason));
215137
+ await exitDaemonCommand(1);
215138
+ return;
215139
+ }
214688
215140
  }
214689
215141
  }
214690
215142
  captureDaemonEvent("daemon_start_requested");
@@ -214868,9 +215320,9 @@ ${result.stdout ?? ""}`;
214868
215320
  const passthroughArgs = cmd.args;
214869
215321
  captureDaemonEvent("daemon_restart_requested");
214870
215322
  const runningProbeHealth = await fetchLocalProbeHealth();
214871
- const versionMismatchHealth = runningProbeHealth && runningProbeHealth.cliVersion !== version$7 ? runningProbeHealth : null;
215323
+ const versionMismatchHealth = runningProbeHealth && runningProbeHealth.cliVersion !== version$8 ? runningProbeHealth : null;
214872
215324
  if (versionMismatchHealth) {
214873
- console.log(`Running daemon uses lody v${versionMismatchHealth.cliVersion}; current CLI is v${version$7}. Restarting with current CLI.`);
215325
+ console.log(`Running daemon uses lody v${versionMismatchHealth.cliVersion}; current CLI is v${version$8}. Restarting with current CLI.`);
214874
215326
  }
214875
215327
  const stopResult = await stopDaemonProcess();
214876
215328
  captureDaemonEvent("daemon_stop_result", {
@@ -215077,7 +215529,7 @@ ${result.stdout ?? ""}`;
215077
215529
  });
215078
215530
  logger2.info(`Daemon watchdog started (PID ${process.pid})`);
215079
215531
  await normalizeCurrentProcessResourceProfile(logger2);
215080
- for (const diagnostic of getRuntimeDiagnostics(version$7)) {
215532
+ for (const diagnostic of getRuntimeDiagnostics(version$8)) {
215081
215533
  logger2.info(diagnostic);
215082
215534
  }
215083
215535
  const passthroughArgs = cmd.args;
@@ -233474,7 +233926,7 @@ ${result.stdout ?? ""}`;
233474
233926
  cliToken: auth.token,
233475
233927
  source: "mcp",
233476
233928
  feedback: args2.feedback,
233477
- cliVersion: version$7
233929
+ cliVersion: version$8
233478
233930
  }));
233479
233931
  } catch (error2) {
233480
233932
  return mcpErrorResult(error2);
@@ -234196,7 +234648,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
234196
234648
  cliToken: auth.token,
234197
234649
  source: "cli",
234198
234650
  feedback,
234199
- cliVersion: version$7
234651
+ cliVersion: version$8
234200
234652
  });
234201
234653
  if (options.json) {
234202
234654
  printJson(result);
@@ -234280,7 +234732,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
234280
234732
  logger: getLogger("http-transport")
234281
234733
  });
234282
234734
  program = new Command();
234283
- program.name("lody").description("Lody Agent CLI tool for managing remote command execution").version(version$7, "-v, --version", "display version number").enablePositionalOptions();
234735
+ program.name("lody").description("Lody Agent CLI tool for managing remote command execution").version(version$8, "-v, --version", "display version number").enablePositionalOptions();
234284
234736
  program.addCommand(loginCommand);
234285
234737
  program.addCommand(logoutCommand);
234286
234738
  program.addCommand(startCommand);