lody 0.70.0 → 0.70.2

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
@@ -4190,7 +4190,7 @@ let __tla = Promise.all([
4190
4190
  }
4191
4191
  }
4192
4192
  const name$1 = "lody";
4193
- const version$6 = "0.70.0";
4193
+ const version$6 = "0.70.2";
4194
4194
  const description$1 = "Lody Agent CLI tool for managing remote command execution";
4195
4195
  const type$2 = "module";
4196
4196
  const main$4 = "dist/index.js";
@@ -10039,15 +10039,15 @@ Task description:
10039
10039
  if (typeof value !== "string") {
10040
10040
  return void 0;
10041
10041
  }
10042
- const trimmed = value.trim();
10043
- return trimmed ? trimmed : void 0;
10042
+ const trimmed2 = value.trim();
10043
+ return trimmed2 ? trimmed2 : void 0;
10044
10044
  }
10045
10045
  function getTrimmedRepoFullName(value) {
10046
10046
  if (typeof value !== "string") {
10047
10047
  return void 0;
10048
10048
  }
10049
- const trimmed = value.trim();
10050
- return trimmed ? trimmed : void 0;
10049
+ const trimmed2 = value.trim();
10050
+ return trimmed2 ? trimmed2 : void 0;
10051
10051
  }
10052
10052
  function getProjectRefBranch(project) {
10053
10053
  if (!project || typeof project !== "object") {
@@ -10521,8 +10521,8 @@ Task description:
10521
10521
  if (typeof value !== "string") {
10522
10522
  return void 0;
10523
10523
  }
10524
- const trimmed = value.trim();
10525
- return trimmed ? trimmed : void 0;
10524
+ const trimmed2 = value.trim();
10525
+ return trimmed2 ? trimmed2 : void 0;
10526
10526
  };
10527
10527
  const maybeParseField = (schema2, value, normalize2) => {
10528
10528
  if (typeof value === "undefined") {
@@ -10581,8 +10581,8 @@ Task description:
10581
10581
  normalized.issuePRMentions = issuePRMentions;
10582
10582
  }
10583
10583
  const resume2 = maybeParseField(ACPSessionIdSchema, record2.resume, (parsed) => {
10584
- const trimmed = parsed.trim();
10585
- return trimmed ? trimmed : void 0;
10584
+ const trimmed2 = parsed.trim();
10585
+ return trimmed2 ? trimmed2 : void 0;
10586
10586
  });
10587
10587
  if (resume2) {
10588
10588
  normalized.resume = resume2;
@@ -12178,8 +12178,8 @@ Task description:
12178
12178
  if (typeof value !== "string") {
12179
12179
  return void 0;
12180
12180
  }
12181
- const trimmed = value.trim();
12182
- return trimmed ? trimmed : void 0;
12181
+ const trimmed2 = value.trim();
12182
+ return trimmed2 ? trimmed2 : void 0;
12183
12183
  }
12184
12184
  function isLegacyBuiltinCliType(value) {
12185
12185
  return value !== void 0 && LEGACY_BUILTIN_CLI_TYPES.has(value);
@@ -12490,12 +12490,12 @@ Task description:
12490
12490
  {
12491
12491
  id: "cline",
12492
12492
  name: "Cline",
12493
- version: "3.0.40",
12493
+ version: "3.0.44",
12494
12494
  description: "Autonomous coding agent CLI - capable of creating/editing files, running commands, using the browser, and more",
12495
12495
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/cline.svg",
12496
12496
  distribution: {
12497
12497
  npx: {
12498
- package: "cline@3.0.40",
12498
+ package: "cline@3.0.44",
12499
12499
  args: [
12500
12500
  "--acp"
12501
12501
  ]
@@ -12750,12 +12750,12 @@ Task description:
12750
12750
  {
12751
12751
  id: "dirac",
12752
12752
  name: "Dirac",
12753
- version: "0.4.16",
12753
+ version: "0.4.17",
12754
12754
  description: "Reduces API costs by more than 50%, produces better and faster work. Uses Hash anchored parallel edits, AST manipulation and a whole lot of neat optimizations. Fully Open Source.",
12755
12755
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/dirac.svg",
12756
12756
  distribution: {
12757
12757
  npx: {
12758
- package: "dirac-cli@0.4.16",
12758
+ package: "dirac-cli@0.4.17",
12759
12759
  args: [
12760
12760
  "--acp"
12761
12761
  ]
@@ -12765,12 +12765,12 @@ Task description:
12765
12765
  {
12766
12766
  id: "factory-droid",
12767
12767
  name: "Factory Droid",
12768
- version: "0.172.0",
12768
+ version: "0.174.0",
12769
12769
  description: "Factory Droid - AI coding agent powered by Factory AI",
12770
12770
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/factory-droid.svg",
12771
12771
  distribution: {
12772
12772
  npx: {
12773
- package: "droid@0.172.0",
12773
+ package: "droid@0.174.0",
12774
12774
  args: [
12775
12775
  "exec",
12776
12776
  "--output-format",
@@ -12786,12 +12786,12 @@ Task description:
12786
12786
  {
12787
12787
  id: "fast-agent",
12788
12788
  name: "fast-agent",
12789
- version: "0.9.9",
12789
+ version: "0.9.13",
12790
12790
  description: "Code and build agents with comprehensive multi-provider support",
12791
12791
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/fast-agent.svg",
12792
12792
  distribution: {
12793
12793
  uvx: {
12794
- package: "fast-agent-acp==0.9.9",
12794
+ package: "fast-agent-acp==0.9.13",
12795
12795
  args: [
12796
12796
  "-x"
12797
12797
  ]
@@ -12801,12 +12801,12 @@ Task description:
12801
12801
  {
12802
12802
  id: "gemini",
12803
12803
  name: "Gemini CLI",
12804
- version: "0.50.0",
12804
+ version: "0.51.0",
12805
12805
  description: "Google's official CLI for Gemini",
12806
12806
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/gemini.svg",
12807
12807
  distribution: {
12808
12808
  npx: {
12809
- package: "@google/gemini-cli@0.50.0",
12809
+ package: "@google/gemini-cli@0.51.0",
12810
12810
  args: [
12811
12811
  "--acp"
12812
12812
  ]
@@ -12816,12 +12816,12 @@ Task description:
12816
12816
  {
12817
12817
  id: "github-copilot-cli",
12818
12818
  name: "GitHub Copilot",
12819
- version: "1.0.70",
12819
+ version: "1.0.71",
12820
12820
  description: "GitHub's AI pair programmer",
12821
12821
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/github-copilot-cli.svg",
12822
12822
  distribution: {
12823
12823
  npx: {
12824
- package: "@github/copilot@1.0.70",
12824
+ package: "@github/copilot@1.0.71",
12825
12825
  args: [
12826
12826
  "--acp"
12827
12827
  ]
@@ -12861,12 +12861,12 @@ Task description:
12861
12861
  {
12862
12862
  id: "grok-build",
12863
12863
  name: "Grok Build",
12864
- version: "0.2.101",
12864
+ version: "0.2.102",
12865
12865
  description: "xAI's coding agent and CLI",
12866
12866
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/grok-build.svg",
12867
12867
  distribution: {
12868
12868
  npx: {
12869
- package: "@xai-official/grok@0.2.101",
12869
+ package: "@xai-official/grok@0.2.102",
12870
12870
  args: [
12871
12871
  "agent",
12872
12872
  "stdio"
@@ -12877,13 +12877,13 @@ Task description:
12877
12877
  {
12878
12878
  id: "harn",
12879
12879
  name: "Harn",
12880
- version: "0.10.18",
12880
+ version: "0.10.21",
12881
12881
  description: "Harn runs .harn agent pipelines as a native ACP coding agent over stdio.",
12882
12882
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/harn.svg",
12883
12883
  distribution: {
12884
12884
  binary: {
12885
12885
  "darwin-aarch64": {
12886
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.18/harn-aarch64-apple-darwin.tar.gz",
12886
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.21/harn-aarch64-apple-darwin.tar.gz",
12887
12887
  cmd: "./harn",
12888
12888
  args: [
12889
12889
  "serve",
@@ -12891,7 +12891,7 @@ Task description:
12891
12891
  ]
12892
12892
  },
12893
12893
  "darwin-x86_64": {
12894
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.18/harn-x86_64-apple-darwin.tar.gz",
12894
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.21/harn-x86_64-apple-darwin.tar.gz",
12895
12895
  cmd: "./harn",
12896
12896
  args: [
12897
12897
  "serve",
@@ -12899,7 +12899,7 @@ Task description:
12899
12899
  ]
12900
12900
  },
12901
12901
  "linux-aarch64": {
12902
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.18/harn-aarch64-unknown-linux-gnu.tar.gz",
12902
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.21/harn-aarch64-unknown-linux-gnu.tar.gz",
12903
12903
  cmd: "./harn",
12904
12904
  args: [
12905
12905
  "serve",
@@ -12907,7 +12907,7 @@ Task description:
12907
12907
  ]
12908
12908
  },
12909
12909
  "linux-x86_64": {
12910
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.18/harn-x86_64-unknown-linux-gnu.tar.gz",
12910
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.21/harn-x86_64-unknown-linux-gnu.tar.gz",
12911
12911
  cmd: "./harn",
12912
12912
  args: [
12913
12913
  "serve",
@@ -12915,7 +12915,7 @@ Task description:
12915
12915
  ]
12916
12916
  },
12917
12917
  "windows-x86_64": {
12918
- archive: "https://github.com/burin-labs/harn/releases/download/v0.10.18/harn-x86_64-pc-windows-msvc.zip",
12918
+ archive: "https://github.com/burin-labs/harn/releases/download/v0.10.21/harn-x86_64-pc-windows-msvc.zip",
12919
12919
  cmd: "harn.exe",
12920
12920
  args: [
12921
12921
  "serve",
@@ -12946,47 +12946,47 @@ Task description:
12946
12946
  {
12947
12947
  id: "kilo",
12948
12948
  name: "Kilo",
12949
- version: "7.4.8",
12949
+ version: "7.4.11",
12950
12950
  description: "The open source coding agent",
12951
12951
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/kilo.svg",
12952
12952
  distribution: {
12953
12953
  npx: {
12954
- package: "@kilocode/cli@7.4.8",
12954
+ package: "@kilocode/cli@7.4.11",
12955
12955
  args: [
12956
12956
  "acp"
12957
12957
  ]
12958
12958
  },
12959
12959
  binary: {
12960
12960
  "darwin-aarch64": {
12961
- archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.8/kilo-darwin-arm64.zip",
12961
+ archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.11/kilo-darwin-arm64.zip",
12962
12962
  cmd: "./kilo",
12963
12963
  args: [
12964
12964
  "acp"
12965
12965
  ]
12966
12966
  },
12967
12967
  "darwin-x86_64": {
12968
- archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.8/kilo-darwin-x64.zip",
12968
+ archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.11/kilo-darwin-x64.zip",
12969
12969
  cmd: "./kilo",
12970
12970
  args: [
12971
12971
  "acp"
12972
12972
  ]
12973
12973
  },
12974
12974
  "linux-aarch64": {
12975
- archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.8/kilo-linux-arm64.tar.gz",
12975
+ archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.11/kilo-linux-arm64.tar.gz",
12976
12976
  cmd: "./kilo",
12977
12977
  args: [
12978
12978
  "acp"
12979
12979
  ]
12980
12980
  },
12981
12981
  "linux-x86_64": {
12982
- archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.8/kilo-linux-x64.tar.gz",
12982
+ archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.11/kilo-linux-x64.tar.gz",
12983
12983
  cmd: "./kilo",
12984
12984
  args: [
12985
12985
  "acp"
12986
12986
  ]
12987
12987
  },
12988
12988
  "windows-x86_64": {
12989
- archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.8/kilo-windows-x64.zip",
12989
+ archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.11/kilo-windows-x64.zip",
12990
12990
  cmd: "./kilo.exe",
12991
12991
  args: [
12992
12992
  "acp"
@@ -12995,24 +12995,6 @@ Task description:
12995
12995
  }
12996
12996
  }
12997
12997
  },
12998
- {
12999
- id: "kimi",
13000
- name: "Kimi CLI",
13001
- version: "1.48.0",
13002
- description: "Moonshot AI's coding assistant",
13003
- icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/kimi.svg",
13004
- distribution: {
13005
- local: {
13006
- command: "kimi",
13007
- args: [
13008
- "acp"
13009
- ],
13010
- versionArgs: [
13011
- "-V"
13012
- ]
13013
- }
13014
- }
13015
- },
13016
12998
  {
13017
12999
  id: "kimi-code",
13018
13000
  name: "Kimi Code CLI",
@@ -13052,7 +13034,7 @@ Task description:
13052
13034
  {
13053
13035
  id: "mistral-vibe",
13054
13036
  name: "Mistral Vibe",
13055
- version: "2.19.1",
13037
+ version: "2.20.0",
13056
13038
  description: "Mistral's open-source coding assistant",
13057
13039
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/mistral-vibe.svg",
13058
13040
  distribution: {
@@ -13068,12 +13050,12 @@ Task description:
13068
13050
  {
13069
13051
  id: "nova",
13070
13052
  name: "Nova",
13071
- version: "1.1.25",
13053
+ version: "1.1.27",
13072
13054
  description: "Nova by Compass AI - a fully-fledged software engineer at your command",
13073
13055
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/nova.svg",
13074
13056
  distribution: {
13075
13057
  npx: {
13076
- package: "@compass-ai/nova@1.1.25",
13058
+ package: "@compass-ai/nova@1.1.27",
13077
13059
  args: [
13078
13060
  "acp"
13079
13061
  ]
@@ -13083,7 +13065,7 @@ Task description:
13083
13065
  {
13084
13066
  id: "opencode",
13085
13067
  name: "OpenCode",
13086
- version: "1.18.1",
13068
+ version: "1.18.3",
13087
13069
  description: "The open source coding agent",
13088
13070
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/opencode.svg",
13089
13071
  distribution: {
@@ -13181,12 +13163,12 @@ Task description:
13181
13163
  {
13182
13164
  id: "qwen-code",
13183
13165
  name: "Qwen Code",
13184
- version: "0.19.10",
13166
+ version: "0.19.11",
13185
13167
  description: "Alibaba's Qwen coding assistant",
13186
13168
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/qwen-code.svg",
13187
13169
  distribution: {
13188
13170
  npx: {
13189
- package: "@qwen-code/qwen-code@0.19.10",
13171
+ package: "@qwen-code/qwen-code@0.19.11",
13190
13172
  args: [
13191
13173
  "--acp",
13192
13174
  "--experimental-skills"
@@ -18217,10 +18199,10 @@ ${tailedOutput}` : null;
18217
18199
  return false;
18218
18200
  };
18219
18201
  const normalizeTextInputBlock = (block) => {
18220
- const trimmed = block.text.trim();
18221
- return trimmed ? {
18202
+ const trimmed2 = block.text.trim();
18203
+ return trimmed2 ? {
18222
18204
  type: "text",
18223
- text: trimmed
18205
+ text: trimmed2
18224
18206
  } : null;
18225
18207
  };
18226
18208
  const toImagePayload = (block) => {
@@ -18457,8 +18439,8 @@ ${tailedOutput}` : null;
18457
18439
  };
18458
18440
  };
18459
18441
  const nonEmptyString$1 = (value) => {
18460
- const trimmed = value?.trim();
18461
- return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
18442
+ const trimmed2 = value?.trim();
18443
+ return trimmed2 !== void 0 && trimmed2.length > 0 ? trimmed2 : void 0;
18462
18444
  };
18463
18445
  function buildNeedToDeleteSessionQueueItem(options) {
18464
18446
  const { session, machineMeta, requestedAt } = options;
@@ -19866,8 +19848,8 @@ ${tailedOutput}` : null;
19866
19848
  const isRecord$7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
19867
19849
  const isNonEmptyString$1 = (value) => typeof value === "string" && value.length > 0;
19868
19850
  const nonEmptyString = (value) => {
19869
- const trimmed = value?.trim();
19870
- return trimmed ? trimmed : void 0;
19851
+ const trimmed2 = value?.trim();
19852
+ return trimmed2 ? trimmed2 : void 0;
19871
19853
  };
19872
19854
  const isMissing = (value) => value === void 0 || value === null;
19873
19855
  const isStringRecord$1 = (value) => isRecord$7(value) && Object.values(value).every((entry) => typeof entry === "string");
@@ -20293,11 +20275,11 @@ ${tailedOutput}` : null;
20293
20275
  return Number.isFinite(value) ? value : null;
20294
20276
  }
20295
20277
  if (typeof value !== "string") return null;
20296
- const trimmed = value.trim();
20297
- if (!trimmed) return null;
20298
- const asNumber = Number(trimmed);
20278
+ const trimmed2 = value.trim();
20279
+ if (!trimmed2) return null;
20280
+ const asNumber = Number(trimmed2);
20299
20281
  if (Number.isFinite(asNumber)) return asNumber;
20300
- const parsed = Date.parse(trimmed);
20282
+ const parsed = Date.parse(trimmed2);
20301
20283
  return Number.isNaN(parsed) ? null : parsed;
20302
20284
  }
20303
20285
  function normalizeText(value) {
@@ -20591,11 +20573,11 @@ ${tailedOutput}` : null;
20591
20573
  "d"
20592
20574
  ];
20593
20575
  const getLoroStreamsBaseUrl = (baseUrl) => {
20594
- const trimmed = baseUrl?.trim();
20595
- if (!trimmed) {
20576
+ const trimmed2 = baseUrl?.trim();
20577
+ if (!trimmed2) {
20596
20578
  return DEFAULT_LORO_STREAMS_BASE_URL;
20597
20579
  }
20598
- return trimmed.replace(/\/+$/g, "");
20580
+ return trimmed2.replace(/\/+$/g, "");
20599
20581
  };
20600
20582
  const LORO_STREAMS_PRESENCE_SHARD_IDS = [
20601
20583
  "01",
@@ -43394,16 +43376,16 @@ ${fromBody}`;
43394
43376
  function betterJSONParse(value, options = {}) {
43395
43377
  const { strict = false, warnings = false, reviver, parseDates = true } = options;
43396
43378
  if (typeof value !== "string") return value;
43397
- const trimmed = value.trim();
43398
- if (trimmed.length > 0 && trimmed[0] === '"' && trimmed.endsWith('"') && !trimmed.slice(1, -1).includes('"')) return trimmed.slice(1, -1);
43399
- const lowerValue = trimmed.toLowerCase();
43379
+ const trimmed2 = value.trim();
43380
+ if (trimmed2.length > 0 && trimmed2[0] === '"' && trimmed2.endsWith('"') && !trimmed2.slice(1, -1).includes('"')) return trimmed2.slice(1, -1);
43381
+ const lowerValue = trimmed2.toLowerCase();
43400
43382
  if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) return SPECIAL_VALUES[lowerValue];
43401
- if (!JSON_SIGNATURE.test(trimmed)) {
43383
+ if (!JSON_SIGNATURE.test(trimmed2)) {
43402
43384
  if (strict) throw new SyntaxError("[better-json] Invalid JSON");
43403
43385
  return value;
43404
43386
  }
43405
43387
  if (Object.entries(PROTO_POLLUTION_PATTERNS).some(([key2, pattern2]) => {
43406
- const matches = pattern2.test(trimmed);
43388
+ const matches = pattern2.test(trimmed2);
43407
43389
  if (matches && warnings) console.warn(`[better-json] Detected potential prototype pollution attempt using ${key2} pattern`);
43408
43390
  return matches;
43409
43391
  }) && strict) throw new Error("[better-json] Potential prototype pollution attempt detected");
@@ -43419,7 +43401,7 @@ ${fromBody}`;
43419
43401
  }
43420
43402
  return reviver ? reviver(key2, value2) : value2;
43421
43403
  };
43422
- return JSON.parse(trimmed, secureReviver);
43404
+ return JSON.parse(trimmed2, secureReviver);
43423
43405
  } catch (error2) {
43424
43406
  if (strict) throw error2;
43425
43407
  return value;
@@ -45160,9 +45142,9 @@ ${fromBody}`;
45160
45142
  };
45161
45143
  };
45162
45144
  function normalizeAppBasePath(appBasePath) {
45163
- const trimmed = appBasePath.trim();
45164
- if (!trimmed || trimmed === "/") return "";
45165
- const normalizedSegment = trimmed.replace(/^\/+/, "").replace(/\/+$/, "");
45145
+ const trimmed2 = appBasePath.trim();
45146
+ if (!trimmed2 || trimmed2 === "/") return "";
45147
+ const normalizedSegment = trimmed2.replace(/^\/+/, "").replace(/\/+$/, "");
45166
45148
  if (!normalizedSegment) return "";
45167
45149
  return `/${normalizedSegment}`;
45168
45150
  }
@@ -45300,10 +45282,29 @@ ${fromBody}`;
45300
45282
  return !validation2.valid && validation2.reason !== "invalid";
45301
45283
  }
45302
45284
  function formatUnknownError$3(error2) {
45303
- if (error2 instanceof Error) {
45304
- return `${error2.name}: ${error2.message}`;
45285
+ if (!(error2 instanceof Error)) {
45286
+ return String(error2);
45305
45287
  }
45306
- return String(error2);
45288
+ const parts2 = [
45289
+ `${error2.name}: ${error2.message}`
45290
+ ];
45291
+ let cause = error2.cause;
45292
+ for (let depth = 0; cause !== void 0 && cause !== null && depth < 3; depth += 1) {
45293
+ if (cause instanceof AggregateError && cause.errors.length > 0) {
45294
+ const nested = cause.errors.slice(0, 3).map((entry) => formatUnknownError$3(entry)).join("; ");
45295
+ parts2.push(`caused by ${cause.name}: ${cause.message || "multiple errors"} [${nested}]`);
45296
+ break;
45297
+ }
45298
+ if (cause instanceof Error) {
45299
+ const code2 = cause.code;
45300
+ parts2.push(`caused by ${cause.name}${code2 ? ` (${code2})` : ""}: ${cause.message}`);
45301
+ cause = cause.cause;
45302
+ } else {
45303
+ parts2.push(`caused by ${String(cause)}`);
45304
+ break;
45305
+ }
45306
+ }
45307
+ return parts2.join(" \u2014 ");
45307
45308
  }
45308
45309
  function isRetryableTokenValidationStatus(status) {
45309
45310
  return status === 408 || status === 429 || status >= 500;
@@ -45773,7 +45774,7 @@ ${fromBody}`;
45773
45774
  }
45774
45775
  };
45775
45776
  } catch (error2) {
45776
- getLogger("auth").error(`Token validation failed: ${error2}`);
45777
+ getLogger("auth").error(`Token validation failed: ${formatUnknownError$3(error2)}`);
45777
45778
  return {
45778
45779
  valid: false,
45779
45780
  retryable: true,
@@ -63394,9 +63395,9 @@ stream:${scope2.streamId}`;
63394
63395
  if (urls == null) return;
63395
63396
  const out = [];
63396
63397
  for (const raw2 of urls) {
63397
- const trimmed = raw2.trim();
63398
- if (trimmed.length === 0) continue;
63399
- const url2 = new URL(trimmed);
63398
+ const trimmed2 = raw2.trim();
63399
+ if (trimmed2.length === 0) continue;
63400
+ const url2 = new URL(trimmed2);
63400
63401
  if (url2.protocol !== "http:" && url2.protocol !== "https:") throw new Error(`${label2} shard URL must use http or https`);
63401
63402
  if (url2.pathname !== "/" || url2.search !== "" || url2.hash !== "") throw new Error(`${label2} shard URL must be an origin URL`);
63402
63403
  out.push(url2.origin);
@@ -63969,14 +63970,14 @@ stream:${scope2.streamId}`;
63969
63970
  }
63970
63971
  function parseRetryAfterMs$1(value) {
63971
63972
  if (value == null) return;
63972
- const trimmed = value.trim();
63973
- if (trimmed.length === 0) return;
63974
- const numeric = Number(trimmed);
63973
+ const trimmed2 = value.trim();
63974
+ if (trimmed2.length === 0) return;
63975
+ const numeric = Number(trimmed2);
63975
63976
  if (Number.isFinite(numeric)) {
63976
63977
  if (numeric < 0) return;
63977
63978
  return Math.round(numeric * 1e3);
63978
63979
  }
63979
- const parsed = Date.parse(trimmed);
63980
+ const parsed = Date.parse(trimmed2);
63980
63981
  if (Number.isNaN(parsed)) return;
63981
63982
  const delta = parsed - Date.now();
63982
63983
  return delta > 0 ? delta : void 0;
@@ -100130,11 +100131,11 @@ ${value}`;
100130
100131
  const LORO_RPC_REQUEST_STREAM_SEGMENT = "rpc:req";
100131
100132
  const getLoroMachineRpcRequestStreamId = (workspaceId, machineId) => `${workspaceId}:${LORO_RPC_REQUEST_STREAM_SEGMENT}:${machineId}`;
100132
100133
  const normalizeLoroGatewayBaseUrl = (baseUrl) => {
100133
- const trimmed = baseUrl?.trim();
100134
- if (!trimmed) {
100134
+ const trimmed2 = baseUrl?.trim();
100135
+ if (!trimmed2) {
100135
100136
  return DEFAULT_GATEWAY_BASE_URL;
100136
100137
  }
100137
- return trimmed.replace(/\/+$/g, "");
100138
+ return trimmed2.replace(/\/+$/g, "");
100138
100139
  };
100139
100140
  const LoroStreamsRpcMethodSchema = _enum$1([
100140
100141
  "machine/status",
@@ -102417,11 +102418,11 @@ Saved to: ${args2.relativePath}`;
102417
102418
  The file is not available yet and could not be downloaded; ask the user to resend it if you need its contents.`;
102418
102419
  };
102419
102420
  const resolveContainedUploadPath = async (filePath, workspaceRoot) => {
102420
- const trimmed = filePath.trim();
102421
- if (!trimmed) {
102421
+ const trimmed2 = filePath.trim();
102422
+ if (!trimmed2) {
102422
102423
  throw new Error("File path is empty");
102423
102424
  }
102424
- const candidate = path.isAbsolute(trimmed) ? trimmed : path.resolve(workspaceRoot, trimmed);
102425
+ const candidate = path.isAbsolute(trimmed2) ? trimmed2 : path.resolve(workspaceRoot, trimmed2);
102425
102426
  let realRoot;
102426
102427
  try {
102427
102428
  realRoot = await fs.promises.realpath(workspaceRoot);
@@ -102554,11 +102555,11 @@ The file is not available yet and could not be downloaded; ask the user to resen
102554
102555
  }
102555
102556
  }
102556
102557
  function parseGitRemoteDefaultBranch(raw2, remoteName) {
102557
- const trimmed = raw2.trim();
102558
- if (!trimmed) return null;
102558
+ const trimmed2 = raw2.trim();
102559
+ if (!trimmed2) return null;
102559
102560
  const prefix = `${remoteName}/`;
102560
- if (!trimmed.startsWith(prefix)) return null;
102561
- const name2 = trimmed.slice(prefix.length).trim();
102561
+ if (!trimmed2.startsWith(prefix)) return null;
102562
+ const name2 = trimmed2.slice(prefix.length).trim();
102562
102563
  return name2 || null;
102563
102564
  }
102564
102565
  async function listGitRemotes(rootPath) {
@@ -108000,9 +108001,9 @@ ${incoming}`).output;
108000
108001
  }
108001
108002
  }
108002
108003
  function resolveAcpLauncher(command2) {
108003
- const trimmed = (command2 ?? "").trim().toLowerCase();
108004
- if (trimmed === "npx" || trimmed.endsWith("/npx") || trimmed.endsWith("\\npx")) return "npx";
108005
- if (trimmed === "uvx" || trimmed.endsWith("/uvx") || trimmed.endsWith("\\uvx")) return "uvx";
108004
+ const trimmed2 = (command2 ?? "").trim().toLowerCase();
108005
+ if (trimmed2 === "npx" || trimmed2.endsWith("/npx") || trimmed2.endsWith("\\npx")) return "npx";
108006
+ if (trimmed2 === "uvx" || trimmed2.endsWith("/uvx") || trimmed2.endsWith("\\uvx")) return "uvx";
108006
108007
  return "local";
108007
108008
  }
108008
108009
  function getErrnoCode(error2) {
@@ -108282,9 +108283,9 @@ ${incoming}`).output;
108282
108283
  };
108283
108284
  };
108284
108285
  const sanitizeText = (value, maxLength) => {
108285
- const trimmed = value?.trim();
108286
- if (!trimmed) return void 0;
108287
- return truncate(trimmed, maxLength);
108286
+ const trimmed2 = value?.trim();
108287
+ if (!trimmed2) return void 0;
108288
+ return truncate(trimmed2, maxLength);
108288
108289
  };
108289
108290
  const sanitizeTitleText = (value) => sanitizeText(value?.replace(/\s+/g, " "), MAX_TITLE_LENGTH);
108290
108291
  const truncate = (value, maxLength) => {
@@ -119438,8 +119439,8 @@ ${error2.message}` : execaMessage;
119438
119439
  return segment.replace(/[^a-zA-Z0-9._-]/g, "_");
119439
119440
  }
119440
119441
  function normalizeBaseUrl(value) {
119441
- const trimmed = value?.trim();
119442
- return (trimmed && trimmed.length > 0 ? trimmed : DEFAULT_RUNTIME_BASE_URL).replace(/\/+$/u, "");
119442
+ const trimmed2 = value?.trim();
119443
+ return (trimmed2 && trimmed2.length > 0 ? trimmed2 : DEFAULT_RUNTIME_BASE_URL).replace(/\/+$/u, "");
119443
119444
  }
119444
119445
  function isLocalDevelopmentBaseUrl(value) {
119445
119446
  try {
@@ -120027,6 +120028,7 @@ ${error2.message}` : execaMessage;
120027
120028
  "bin",
120028
120029
  ".claude/local"
120029
120030
  ];
120031
+ const KIMI_CODE_ACP_PATH_RELATIVE_DIR = ".kimi-code/bin";
120030
120032
  const registryAgentsById = Object.fromEntries(REGISTRY_ACP_AGENTS.map((agent2) => [
120031
120033
  agent2.id,
120032
120034
  agent2
@@ -120172,8 +120174,8 @@ ${error2.message}` : execaMessage;
120172
120174
  return pathValue;
120173
120175
  }
120174
120176
  function trimRuntimeOverride(value) {
120175
- const trimmed = value?.trim();
120176
- return trimmed ? resolve$2(expandHomePath(trimmed)) : void 0;
120177
+ const trimmed2 = value?.trim();
120178
+ return trimmed2 ? resolve$2(expandHomePath(trimmed2)) : void 0;
120177
120179
  }
120178
120180
  function resolveCliAdapterEntry(adapter) {
120179
120181
  const argvEntry = process.argv[1] ? resolve$2(process.argv[1]) : void 0;
@@ -120282,14 +120284,18 @@ ${error2.message}` : execaMessage;
120282
120284
  const normalized = normalize(entry);
120283
120285
  return normalized.length > 1 ? normalized.replace(/[\\/]+$/, "") : normalized;
120284
120286
  }
120285
- function getDefaultAcpPathEntries(homeDir = homedir()) {
120287
+ function getDefaultAcpPathEntries(homeDir = homedir(), agentType) {
120286
120288
  if (!homeDir) {
120287
120289
  return [];
120288
120290
  }
120289
- return DEFAULT_ACP_PATH_RELATIVE_DIRS.map((relativeDir) => join$2(homeDir, relativeDir));
120291
+ const relativeDirs = agentType === "kimi" || agentType === "kimi-code" ? [
120292
+ KIMI_CODE_ACP_PATH_RELATIVE_DIR,
120293
+ ...DEFAULT_ACP_PATH_RELATIVE_DIRS
120294
+ ] : DEFAULT_ACP_PATH_RELATIVE_DIRS;
120295
+ return relativeDirs.map((relativeDir) => join$2(homeDir, relativeDir));
120290
120296
  }
120291
- function withDefaultAcpPathEntries(env2) {
120292
- const defaultEntries = getDefaultAcpPathEntries();
120297
+ function withDefaultAcpPathEntries(env2, agentType) {
120298
+ const defaultEntries = getDefaultAcpPathEntries(homedir(), agentType);
120293
120299
  if (defaultEntries.length === 0) {
120294
120300
  return env2;
120295
120301
  }
@@ -121206,7 +121212,7 @@ ${fallbackStderrTail}` : errorMessage;
121206
121212
  CODEX_HOME: path__default.join(options.workdir, ".codex")
121207
121213
  } : baseEnv;
121208
121214
  const loginShellEnv = await getLoginShellEnv();
121209
- const envWithAcpStartup = withoutElectronBootstrapCredentials(withLodyNpmCacheForNpx(launch.command, withDefaultAcpPathEntries(mergeACPProcessEnv(launch, mergeLoginShellEnv(env2, loginShellEnv)))));
121215
+ const envWithAcpStartup = withoutElectronBootstrapCredentials(withLodyNpmCacheForNpx(launch.command, withDefaultAcpPathEntries(mergeACPProcessEnv(launch, mergeLoginShellEnv(env2, loginShellEnv)), options.agentType)));
121210
121216
  const keepCodexHome = env2.LODY_KEEP_CODEX_HOME === "1";
121211
121217
  const defaultCodexHome = path__default.join(os__default.homedir(), ".codex");
121212
121218
  const defaultAuthPath = path__default.join(defaultCodexHome, "auth.json");
@@ -122099,8 +122105,8 @@ ${fallbackStderrTail}` : errorMessage;
122099
122105
  const tryExecTrimmed = async (exec2, command2, args2, workdir) => {
122100
122106
  try {
122101
122107
  const output = await exec2(command2, args2, workdir, false);
122102
- const trimmed = output.trim();
122103
- return trimmed ? trimmed : null;
122108
+ const trimmed2 = output.trim();
122109
+ return trimmed2 ? trimmed2 : null;
122104
122110
  } catch {
122105
122111
  return null;
122106
122112
  }
@@ -123377,8 +123383,8 @@ path=/${options.repoFullName}.git
123377
123383
  return normalized.startsWith("release/") || normalized.startsWith("releases/");
123378
123384
  }
123379
123385
  shouldReuseExistingBaseBranch(branchName) {
123380
- const trimmed = branchName?.trim();
123381
- return !!trimmed && !this.isCommonBaseBranchName(trimmed);
123386
+ const trimmed2 = branchName?.trim();
123387
+ return !!trimmed2 && !this.isCommonBaseBranchName(trimmed2);
123382
123388
  }
123383
123389
  async hasLocalBranch(branchName) {
123384
123390
  const sanitized = branchName.trim();
@@ -123411,19 +123417,19 @@ path=/${options.repoFullName}.git
123411
123417
  if (this.isLocalSharedSource()) {
123412
123418
  return null;
123413
123419
  }
123414
- const trimmed = baseBranch?.trim();
123415
- if (!this.shouldReuseExistingBaseBranch(trimmed)) {
123420
+ const trimmed2 = baseBranch?.trim();
123421
+ if (!this.shouldReuseExistingBaseBranch(trimmed2)) {
123416
123422
  return null;
123417
123423
  }
123418
- if (await this.hasLocalBranch(trimmed)) {
123424
+ if (await this.hasLocalBranch(trimmed2)) {
123419
123425
  return {
123420
- branchName: trimmed
123426
+ branchName: trimmed2
123421
123427
  };
123422
123428
  }
123423
- const remoteBranch = `origin/${trimmed}`;
123429
+ const remoteBranch = `origin/${trimmed2}`;
123424
123430
  if (this.repoUrl && await this.hasCommitish(remoteBranch)) {
123425
123431
  return {
123426
- branchName: trimmed,
123432
+ branchName: trimmed2,
123427
123433
  startPoint: remoteBranch
123428
123434
  };
123429
123435
  }
@@ -124798,8 +124804,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
124798
124804
  baseRef,
124799
124805
  "HEAD"
124800
124806
  ]);
124801
- const trimmed = mergeBase.trim();
124802
- if (trimmed) return trimmed;
124807
+ const trimmed2 = mergeBase.trim();
124808
+ if (trimmed2) return trimmed2;
124803
124809
  } catch {
124804
124810
  return null;
124805
124811
  }
@@ -124861,8 +124867,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
124861
124867
  "rev-parse",
124862
124868
  "HEAD"
124863
124869
  ]);
124864
- const trimmed = hash2.trim();
124865
- return trimmed || null;
124870
+ const trimmed2 = hash2.trim();
124871
+ return trimmed2 || null;
124866
124872
  } catch {
124867
124873
  return null;
124868
124874
  }
@@ -125130,8 +125136,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
125130
125136
  if (typeof rootPath !== "string") {
125131
125137
  return null;
125132
125138
  }
125133
- const trimmed = rootPath.trim();
125134
- return trimmed || null;
125139
+ const trimmed2 = rootPath.trim();
125140
+ return trimmed2 || null;
125135
125141
  }
125136
125142
  async function resolveWorkspaceLocalProject(repo, workspaceId, machineId, localProjectId) {
125137
125143
  const localProjects = await readMachineLocalProjects(repo, workspaceId, machineId);
@@ -125356,9 +125362,9 @@ $mem | ConvertTo-Json -Compress
125356
125362
  const memMaxPath = `/sys/fs/cgroup${current2 === "/" ? "" : current2}/memory.max`;
125357
125363
  const raw2 = readFileSafe(memMaxPath);
125358
125364
  if (raw2 !== null) {
125359
- const trimmed = raw2.trim();
125360
- if (trimmed !== "max") {
125361
- const value = parseInt(trimmed, 10);
125365
+ const trimmed2 = raw2.trim();
125366
+ if (trimmed2 !== "max") {
125367
+ const value = parseInt(trimmed2, 10);
125362
125368
  if (Number.isFinite(value) && value > 0) {
125363
125369
  tightest = tightest === null ? value : Math.min(tightest, value);
125364
125370
  }
@@ -125385,9 +125391,9 @@ $mem | ConvertTo-Json -Compress
125385
125391
  const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
125386
125392
  const raw2 = readFileSafe(`${prefix}/memory.max`);
125387
125393
  if (raw2 !== null) {
125388
- const trimmed = raw2.trim();
125389
- if (trimmed !== "max") {
125390
- const value = parseInt(trimmed, 10);
125394
+ const trimmed2 = raw2.trim();
125395
+ if (trimmed2 !== "max") {
125396
+ const value = parseInt(trimmed2, 10);
125391
125397
  if (Number.isFinite(value) && value > 0) {
125392
125398
  if (tightestMax === null || value < tightestMax) {
125393
125399
  tightestMax = value;
@@ -130333,6 +130339,89 @@ $mem | ConvertTo-Json -Compress
130333
130339
  }
130334
130340
  }
130335
130341
  }
130342
+ function trimmed(value) {
130343
+ if (typeof value !== "string") return void 0;
130344
+ const next2 = value.trim();
130345
+ return next2 ? next2 : void 0;
130346
+ }
130347
+ function isObjectRecord$1(value) {
130348
+ return value !== null && typeof value === "object" && !Array.isArray(value);
130349
+ }
130350
+ function isLocalProjectId(value) {
130351
+ return typeof value === "string" && value.trim().length > 0;
130352
+ }
130353
+ function isSessionDiffStats(value) {
130354
+ if (!isObjectRecord$1(value) || !isObjectRecord$1(value.allChange)) return false;
130355
+ return typeof value.allChange.add === "number" && typeof value.allChange.del === "number";
130356
+ }
130357
+ function readDiffStatsMetadata(value) {
130358
+ if (!isObjectRecord$1(value)) return void 0;
130359
+ return {
130360
+ ...value.project === void 0 ? {} : {
130361
+ project: value.project
130362
+ },
130363
+ ...typeof value.repoFullName === "string" ? {
130364
+ repoFullName: value.repoFullName
130365
+ } : {},
130366
+ ...isSessionDiffStats(value.diffStats) ? {
130367
+ diffStats: value.diffStats
130368
+ } : {},
130369
+ ...value.pullRequests === void 0 ? {} : {
130370
+ pullRequests: value.pullRequests
130371
+ }
130372
+ };
130373
+ }
130374
+ function metaGitHubRepo(meta) {
130375
+ if (!meta) return void 0;
130376
+ return resolveProjectGitHubRepo(meta.project) ?? trimmed(meta.repoFullName);
130377
+ }
130378
+ function localProjectIdFromProject(project) {
130379
+ return project?.kind === "local" ? project.localProjectId : void 0;
130380
+ }
130381
+ function localProjectIdFromMeta(meta) {
130382
+ const project = meta?.project;
130383
+ if (!isObjectRecord$1(project) || project.kind !== "local") return void 0;
130384
+ return isLocalProjectId(project.localProjectId) ? project.localProjectId : void 0;
130385
+ }
130386
+ function resolveDiffStatsTarget(options) {
130387
+ const repoFullName = resolveProjectGitHubRepo(options.project) ?? metaGitHubRepo(options.ownerMeta) ?? metaGitHubRepo(options.activeMeta);
130388
+ if (repoFullName) {
130389
+ return {
130390
+ kind: "github",
130391
+ ownerRoomId: options.ownerRoomId,
130392
+ repoFullName
130393
+ };
130394
+ }
130395
+ const localProjectId = localProjectIdFromProject(options.project) ?? localProjectIdFromMeta(options.ownerMeta) ?? localProjectIdFromMeta(options.activeMeta);
130396
+ if (localProjectId) {
130397
+ return {
130398
+ kind: "local",
130399
+ ownerRoomId: options.ownerRoomId,
130400
+ localProjectId
130401
+ };
130402
+ }
130403
+ return {
130404
+ kind: "unknown",
130405
+ ownerRoomId: options.ownerRoomId,
130406
+ reason: "unresolved-project"
130407
+ };
130408
+ }
130409
+ function resolveCodeCollabAllChangesDiffStatsPatch(options) {
130410
+ if (options.target.kind === "unknown") {
130411
+ return null;
130412
+ }
130413
+ if (options.target.kind === "github" && Array.isArray(options.ownerMeta?.pullRequests) && options.ownerMeta.pullRequests.some((pullRequest) => isObjectRecord$1(pullRequest) && pullRequest.status === "open")) {
130414
+ return null;
130415
+ }
130416
+ const current2 = options.ownerMeta?.diffStats?.allChange;
130417
+ const next2 = options.diffStats.allChange;
130418
+ if (current2?.add === next2.add && current2.del === next2.del) {
130419
+ return null;
130420
+ }
130421
+ return {
130422
+ diffStats: options.diffStats
130423
+ };
130424
+ }
130336
130425
  function isBunProcessVersions(versions) {
130337
130426
  return typeof versions?.bun === "string" && versions.bun.length > 0;
130338
130427
  }
@@ -130706,7 +130795,8 @@ $mem | ConvertTo-Json -Compress
130706
130795
  await this.enqueueSharedStateRefresh(resolved.ownerSessionId, {
130707
130796
  kind: "full",
130708
130797
  resolved,
130709
- forcePublish: options.forcePublish === true
130798
+ forcePublish: options.forcePublish === true,
130799
+ persistAllChangesDiffStats: false
130710
130800
  });
130711
130801
  }
130712
130802
  async refreshSharedStateAfterTurn(request2) {
@@ -130714,7 +130804,8 @@ $mem | ConvertTo-Json -Compress
130714
130804
  await this.enqueueSharedStateRefresh(resolved.ownerSessionId, {
130715
130805
  kind: "turn",
130716
130806
  resolved,
130717
- forcePublish: false
130807
+ forcePublish: false,
130808
+ persistAllChangesDiffStats: true
130718
130809
  });
130719
130810
  }
130720
130811
  async refreshSharedStateNow(resolved, options = {}) {
@@ -130746,7 +130837,9 @@ $mem | ConvertTo-Json -Compress
130746
130837
  void this.ensureWorkspaceWatch(resolved).catch(() => void 0);
130747
130838
  const state2 = this.getOwnerState(resolved.ownerSessionId);
130748
130839
  const fileTreeIndex = buildFileTreePathIndex(state2.fileTree);
130749
- const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex);
130840
+ const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex, {
130841
+ persistAllChangesDiffStats: true
130842
+ });
130750
130843
  if (workerResult) {
130751
130844
  this.logger.info(`[code-collab] file-index turn refresh completed ownerSessionId=${resolved.ownerSessionId} source=${workerResult.allChangesSource} changedPaths=${workerResult.changedPaths} directories=0 durationMs=${Date.now() - startedAtMs} allChangesMs=${workerResult.allChangesMs} scanMs=${workerResult.scanMs} buildMs=${workerResult.buildMs} workerMs=${workerResult.workerMs} paths=${workerResult.pathCount}`);
130752
130845
  return;
@@ -130764,7 +130857,9 @@ $mem | ConvertTo-Json -Compress
130764
130857
  });
130765
130858
  const scanMs2 = Date.now() - scanStartedAtMs2;
130766
130859
  await this.ensureAllChangesFileTreeEntries(resolved, state2, fileTreeIndex);
130767
- await this.publishOwnerState(resolved.ownerSessionId, state2);
130860
+ await this.publishOwnerState(resolved.ownerSessionId, state2, {
130861
+ persistAllChangesDiffStats: true
130862
+ });
130768
130863
  this.logger.info(`[code-collab] file-index turn refresh completed ownerSessionId=${resolved.ownerSessionId} source=git mode=main-thread-full-fallback changedPaths=${Object.keys(state2.allChanges).length} directories=0 durationMs=${Date.now() - startedAtMs} allChangesMs=${allChangesMs} scanMs=${scanMs2} paths=${entries}`);
130769
130864
  return;
130770
130865
  }
@@ -130797,7 +130892,9 @@ $mem | ConvertTo-Json -Compress
130797
130892
  }
130798
130893
  const scanMs = Date.now() - scanStartedAtMs;
130799
130894
  await this.ensureAllChangesFileTreeEntries(resolved, state2, fileTreeIndex);
130800
- await this.publishOwnerState(resolved.ownerSessionId, state2);
130895
+ await this.publishOwnerState(resolved.ownerSessionId, state2, {
130896
+ persistAllChangesDiffStats: true
130897
+ });
130801
130898
  this.logger.info(`[code-collab] file-index turn refresh completed ownerSessionId=${resolved.ownerSessionId} source=${allChangesResult.source} changedPaths=${candidatePaths.length} directories=${directoryPaths.length} durationMs=${Date.now() - startedAtMs} allChangesMs=${allChangesMs} scanMs=${scanMs}`);
130802
130899
  }
130803
130900
  async refreshKnownSharedStates() {
@@ -130820,7 +130917,8 @@ $mem | ConvertTo-Json -Compress
130820
130917
  ...this.stateByOwnerSessionId.entries()
130821
130918
  ].map(async ([ownerSessionId, state2]) => {
130822
130919
  await this.publishOwnerState(ownerSessionId, state2, {
130823
- forcePublish: true
130920
+ forcePublish: true,
130921
+ persistAllChangesDiffStats: true
130824
130922
  });
130825
130923
  }));
130826
130924
  }
@@ -130858,7 +130956,8 @@ $mem | ConvertTo-Json -Compress
130858
130956
  await this.refreshSharedStateAfterTurnNow(refresh.resolved);
130859
130957
  } else {
130860
130958
  await this.refreshSharedStateNow(refresh.resolved, {
130861
- forcePublish: refresh.forcePublish
130959
+ forcePublish: refresh.forcePublish,
130960
+ persistAllChangesDiffStats: refresh.persistAllChangesDiffStats
130862
130961
  });
130863
130962
  }
130864
130963
  } catch (error2) {
@@ -131274,7 +131373,9 @@ $mem | ConvertTo-Json -Compress
131274
131373
  const state2 = this.getOwnerState(resolved.ownerSessionId);
131275
131374
  const fileTreeIndex = buildFileTreePathIndex(state2.fileTree);
131276
131375
  if (resolved.workspacePath.length === 0) {
131277
- const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex);
131376
+ const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex, {
131377
+ persistAllChangesDiffStats: true
131378
+ });
131278
131379
  if (workerResult) {
131279
131380
  this.logger.info(`[code-collab] file-index init-directory completed ownerSessionId=${resolved.ownerSessionId} path=${ROOT_DIRECTORY_REQUEST_PATH} entries=${workerResult.entries} durationMs=${Date.now() - startedAtMs} scanMs=${workerResult.scanMs} allChangesMs=${workerResult.allChangesMs} buildMs=${workerResult.buildMs} workerMs=${workerResult.workerMs} source=${workerResult.allChangesSource} changedPaths=${workerResult.changedPaths} paths=${workerResult.pathCount}`);
131280
131381
  return workerResult.entries;
@@ -131288,7 +131389,8 @@ $mem | ConvertTo-Json -Compress
131288
131389
  });
131289
131390
  const scanMs = Date.now() - scanStartedAtMs;
131290
131391
  await this.computeAllChangesAndPublish(resolved, state2, {
131291
- fileTreeIndex
131392
+ fileTreeIndex,
131393
+ persistAllChangesDiffStats: resolved.workspacePath.length === 0
131292
131394
  });
131293
131395
  this.logger.info(`[code-collab] file-index init-directory completed ownerSessionId=${resolved.ownerSessionId} path=${resolved.workspacePath || ROOT_DIRECTORY_REQUEST_PATH} entries=${publishedEntries} durationMs=${Date.now() - startedAtMs} scanMs=${scanMs}`);
131294
131396
  return publishedEntries;
@@ -131682,7 +131784,7 @@ $mem | ConvertTo-Json -Compress
131682
131784
  const equalityStartedAtMs = Date.now();
131683
131785
  const unchanged = previous && options.forcePublish !== true && codeCollabFileIndexStatesEqual(previous.fileIndex, fileIndex);
131684
131786
  const equalityMs = Date.now() - equalityStartedAtMs;
131685
- if (unchanged) {
131787
+ if (unchanged && options.persistAllChangesDiffStats !== true) {
131686
131788
  this.logger.debug(`[code-collab] file-index publish skipped ownerSessionId=${ownerSessionId} paths=${pathCount} durationMs=${Date.now() - startedAtMs} cloneMs=${metrics.cloneMs ?? 0} buildMs=${metrics.buildMs ?? 0} equalityMs=${equalityMs}${metrics.workerMs === void 0 ? "" : ` workerMs=${metrics.workerMs}`}`);
131687
131789
  return;
131688
131790
  }
@@ -131695,6 +131797,8 @@ $mem | ConvertTo-Json -Compress
131695
131797
  await publishFileIndex({
131696
131798
  ownerSessionId,
131697
131799
  fileIndex,
131800
+ allChangesDiffStats: summarizeFileIndexAllChanges(fileIndex),
131801
+ persistAllChangesDiffStats: options.persistAllChangesDiffStats === true,
131698
131802
  updatedAtMs
131699
131803
  });
131700
131804
  const publishMs = Date.now() - publishStartedAtMs;
@@ -131744,6 +131848,27 @@ $mem | ConvertTo-Json -Compress
131744
131848
  }
131745
131849
  return next2;
131746
131850
  }
131851
+ function summarizeFileIndexAllChanges(fileIndex) {
131852
+ let add2 = 0;
131853
+ let del = 0;
131854
+ for (const value of Object.values(fileIndex)) {
131855
+ const change = value === true || !("change" in value) ? void 0 : value.change;
131856
+ if (change === void 0) {
131857
+ continue;
131858
+ }
131859
+ if (change === true || change.diff === void 0) {
131860
+ return null;
131861
+ }
131862
+ add2 += change.diff[0];
131863
+ del += change.diff[1];
131864
+ }
131865
+ return {
131866
+ allChange: {
131867
+ add: add2,
131868
+ del
131869
+ }
131870
+ };
131871
+ }
131747
131872
  function normalizeWorkspacePath(input2, options = {}) {
131748
131873
  if (input2.length === 0) {
131749
131874
  throw new CodeCollabV2ServiceError("invalid_path", "Path is required.");
@@ -132219,7 +132344,8 @@ $mem | ConvertTo-Json -Compress
132219
132344
  return {
132220
132345
  kind: current2.kind === "full" || next2.kind === "full" ? "full" : "turn",
132221
132346
  resolved: next2.resolved,
132222
- forcePublish: current2.forcePublish || next2.forcePublish
132347
+ forcePublish: current2.forcePublish || next2.forcePublish,
132348
+ persistAllChangesDiffStats: current2.persistAllChangesDiffStats || next2.persistAllChangesDiffStats
132223
132349
  };
132224
132350
  }
132225
132351
  function collectTurnRefreshCandidatePaths(allChanges, diffStorePaths) {
@@ -132495,9 +132621,9 @@ $mem | ConvertTo-Json -Compress
132495
132621
  baseRef,
132496
132622
  "HEAD"
132497
132623
  ]);
132498
- const trimmed = mergeBase.ok ? mergeBase.stdout.trim() : "";
132499
- if (trimmed) {
132500
- return trimmed;
132624
+ const trimmed2 = mergeBase.ok ? mergeBase.stdout.trim() : "";
132625
+ if (trimmed2) {
132626
+ return trimmed2;
132501
132627
  }
132502
132628
  }
132503
132629
  const head2 = await runGit(workspaceRoot, [
@@ -133518,12 +133644,12 @@ $mem | ConvertTo-Json -Compress
133518
133644
  const isSupportedSessionImageMimeType = (mimeType) => SESSION_IMAGE_ALLOWED_MIME_TYPES.includes(mimeType);
133519
133645
  const shouldUploadACPBytesAsImage = (mimeType, sizeBytes) => isSupportedSessionImageMimeType(mimeType) && sizeBytes <= SESSION_IMAGE_MAX_SIZE_BYTES;
133520
133646
  const getACPFileNameFromUri = (uri2) => {
133521
- const trimmed = uri2?.trim();
133522
- if (!trimmed) {
133647
+ const trimmed2 = uri2?.trim();
133648
+ if (!trimmed2) {
133523
133649
  return null;
133524
133650
  }
133525
133651
  try {
133526
- const parsed = new URL(trimmed);
133652
+ const parsed = new URL(trimmed2);
133527
133653
  if (parsed.protocol === "file:") {
133528
133654
  return path__default.basename(fileURLToPath$1(parsed));
133529
133655
  }
@@ -133540,7 +133666,7 @@ $mem | ConvertTo-Json -Compress
133540
133666
  }
133541
133667
  return null;
133542
133668
  } catch {
133543
- const baseName = path__default.basename(trimmed);
133669
+ const baseName = path__default.basename(trimmed2);
133544
133670
  return baseName && baseName !== "/" && baseName !== "." ? baseName : null;
133545
133671
  }
133546
133672
  };
@@ -133555,9 +133681,9 @@ $mem | ConvertTo-Json -Compress
133555
133681
  return fallbackExtension ? `${safeName}.${fallbackExtension}` : safeName;
133556
133682
  };
133557
133683
  const decodeACPBase64Data = (data, label2) => {
133558
- const trimmed = data.trim();
133559
- const commaIndex = trimmed.startsWith("data:") ? trimmed.indexOf(",") : -1;
133560
- const base64 = (commaIndex >= 0 ? trimmed.slice(commaIndex + 1) : trimmed).replace(/\s/g, "");
133684
+ const trimmed2 = data.trim();
133685
+ const commaIndex = trimmed2.startsWith("data:") ? trimmed2.indexOf(",") : -1;
133686
+ const base64 = (commaIndex >= 0 ? trimmed2.slice(commaIndex + 1) : trimmed2).replace(/\s/g, "");
133561
133687
  const bytes = Buffer.from(base64, "base64");
133562
133688
  if (bytes.byteLength <= 0) {
133563
133689
  throw new Error(`${label2} is empty`);
@@ -133676,15 +133802,15 @@ $mem | ConvertTo-Json -Compress
133676
133802
  ];
133677
133803
  };
133678
133804
  const resolveACPResourceLinkLocalPath = (uri2) => {
133679
- const trimmed = uri2.trim();
133680
- if (!trimmed) {
133805
+ const trimmed2 = uri2.trim();
133806
+ if (!trimmed2) {
133681
133807
  return null;
133682
133808
  }
133683
133809
  try {
133684
- const parsed = new URL(trimmed);
133810
+ const parsed = new URL(trimmed2);
133685
133811
  return parsed.protocol === "file:" ? fileURLToPath$1(parsed) : null;
133686
133812
  } catch {
133687
- return trimmed;
133813
+ return trimmed2;
133688
133814
  }
133689
133815
  };
133690
133816
  const shouldTreatACPPathAsImage = (filePath, mimeType) => {
@@ -134342,17 +134468,17 @@ $mem | ConvertTo-Json -Compress
134342
134468
  return code2 === "ENOENT" || code2 === "ENOTDIR";
134343
134469
  }
134344
134470
  function normalizeSkillScanDir(skillDir) {
134345
- const trimmed = skillDir.trim();
134346
- if (!trimmed) {
134471
+ const trimmed2 = skillDir.trim();
134472
+ if (!trimmed2) {
134347
134473
  throw new Error("Skill scan directory is required.");
134348
134474
  }
134349
- if (trimmed.includes("\0")) {
134475
+ if (trimmed2.includes("\0")) {
134350
134476
  throw new Error(`Invalid skill scan directory: ${skillDir}`);
134351
134477
  }
134352
- if (path__default$1.isAbsolute(trimmed)) {
134478
+ if (path__default$1.isAbsolute(trimmed2)) {
134353
134479
  throw new Error(`Skill scan directory must be project-relative: ${skillDir}`);
134354
134480
  }
134355
- const normalized = normalizeProjectRelativePath(trimmed);
134481
+ const normalized = normalizeProjectRelativePath(trimmed2);
134356
134482
  if (!normalized) {
134357
134483
  throw new Error(`Invalid skill scan directory: ${skillDir}`);
134358
134484
  }
@@ -134362,17 +134488,17 @@ $mem | ConvertTo-Json -Compress
134362
134488
  return normalized;
134363
134489
  }
134364
134490
  function normalizeKnownGlobalSkillScanDir(skillDir) {
134365
- const trimmed = skillDir.trim().replace(/\\/g, "/");
134366
- if (!trimmed) {
134491
+ const trimmed2 = skillDir.trim().replace(/\\/g, "/");
134492
+ if (!trimmed2) {
134367
134493
  throw new Error("Global skill scan directory is required.");
134368
134494
  }
134369
- if (trimmed.includes("\0")) {
134495
+ if (trimmed2.includes("\0")) {
134370
134496
  throw new Error(`Invalid global skill scan directory: ${skillDir}`);
134371
134497
  }
134372
- if (!trimmed.startsWith("~/")) {
134498
+ if (!trimmed2.startsWith("~/")) {
134373
134499
  throw new Error(`Global skill scan directory must be home-relative: ${skillDir}`);
134374
134500
  }
134375
- const relativeDir = normalizeSkillScanDir(trimmed.slice(2));
134501
+ const relativeDir = normalizeSkillScanDir(trimmed2.slice(2));
134376
134502
  return {
134377
134503
  displayDir: `~/${relativeDir}`,
134378
134504
  relativeDir
@@ -136108,11 +136234,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
136108
136234
  return `${invalidMessage} (${details.join(", ")}). Response body: ${summarizedBody}`;
136109
136235
  }
136110
136236
  function summarizeInvalidResponseBody(rawBody) {
136111
- const trimmed = rawBody.trim();
136112
- if (!trimmed) {
136237
+ const trimmed2 = rawBody.trim();
136238
+ if (!trimmed2) {
136113
136239
  return null;
136114
136240
  }
136115
- const compact = trimmed.replace(/\s+/g, " ");
136241
+ const compact = trimmed2.replace(/\s+/g, " ");
136116
136242
  const redacted = redactPreviewResponseSecrets(compact);
136117
136243
  if (redacted.length <= INVALID_RESPONSE_BODY_SNIPPET_MAX_CHARS) {
136118
136244
  return redacted;
@@ -136133,19 +136259,19 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
136133
136259
  const PREVIEW_REGISTRY_FILE = path__default.join(os__default.homedir(), ".lody", "preview-tunnels.json");
136134
136260
  const PREVIEW_REGISTRY_FUTURE_SKEW_MS = 6e4;
136135
136261
  const normalizeHost = (host) => {
136136
- const trimmed = host.trim().toLowerCase();
136137
- return trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : trimmed;
136262
+ const trimmed2 = host.trim().toLowerCase();
136263
+ return trimmed2.startsWith("[") && trimmed2.endsWith("]") ? trimmed2.slice(1, -1) : trimmed2;
136138
136264
  };
136139
136265
  const isLoopbackHost = (host) => LOOPBACK_HOSTS.has(normalizeHost(host));
136140
136266
  const normalizePath = (value) => {
136141
- const trimmed = value?.trim();
136142
- if (!trimmed) {
136267
+ const trimmed2 = value?.trim();
136268
+ if (!trimmed2) {
136143
136269
  return void 0;
136144
136270
  }
136145
- if (!trimmed.startsWith("/") || /^https?:\/\//i.test(trimmed) || trimmed.startsWith("//")) {
136271
+ if (!trimmed2.startsWith("/") || /^https?:\/\//i.test(trimmed2) || trimmed2.startsWith("//")) {
136146
136272
  return void 0;
136147
136273
  }
136148
- return trimmed;
136274
+ return trimmed2;
136149
136275
  };
136150
136276
  const normalizeTarget = (target) => {
136151
136277
  if (target.protocol !== "http") {
@@ -137052,7 +137178,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
137052
137178
  provider: args2.provider
137053
137179
  });
137054
137180
  const loginShellEnv = await getLoginShellEnv();
137055
- const env2 = withDefaultAcpPathEntries(mergeLoginShellEnv(launch.env, loginShellEnv));
137181
+ const env2 = withDefaultAcpPathEntries(mergeLoginShellEnv(launch.env, loginShellEnv), args2.provider.agentType);
137056
137182
  const agentProcess = spawnAcpProcess({
137057
137183
  cliType: args2.provider.cliType,
137058
137184
  agentType: args2.provider.agentType,
@@ -138578,6 +138704,13 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
138578
138704
  const syncStartedAtMs = Date.now();
138579
138705
  await handle.syncOnce();
138580
138706
  const syncMs = Date.now() - syncStartedAtMs;
138707
+ if (state2.persistAllChangesDiffStats && state2.allChangesDiffStats) {
138708
+ try {
138709
+ await this.persistCodeCollabAllChangesDiffStats(state2.ownerSessionId, state2.allChangesDiffStats);
138710
+ } catch (error2) {
138711
+ this.logger.debug(`[code-collab-v2] Failed to persist All Changes diffStats ownerSessionId=${state2.ownerSessionId}: ${formatErrorMessage(error2)}`);
138712
+ }
138713
+ }
138581
138714
  this.logger.info(`[code-collab-v2] file-index flock publish completed ownerSessionId=${state2.ownerSessionId} paths=${pathCount} changed=${changed} durationMs=${Date.now() - publishStartedAtMs} openMs=${openMs} writeMs=${writeMs} flushMs=${flushMs} syncMs=${syncMs}`);
138582
138715
  }
138583
138716
  });
@@ -139287,21 +139420,21 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
139287
139420
  this.logger.debug(`[${args2.sessionId}] Codex inline image uploaded (callId=${args2.callId} historyEntryId=${historyEntryId})`);
139288
139421
  }
139289
139422
  resolveCodexGeneratedImagePath(sessionId, savedPath) {
139290
- const trimmed = savedPath?.trim();
139291
- if (!trimmed) {
139423
+ const trimmed2 = savedPath?.trim();
139424
+ if (!trimmed2) {
139292
139425
  return null;
139293
139426
  }
139294
- if (path__default.isAbsolute(trimmed)) {
139295
- return trimmed;
139427
+ if (path__default.isAbsolute(trimmed2)) {
139428
+ return trimmed2;
139296
139429
  }
139297
139430
  try {
139298
139431
  const hostWorkdir = this.sessionManager.getSession(sessionId)?.getHostWorkdir();
139299
139432
  if (!hostWorkdir) {
139300
139433
  return null;
139301
139434
  }
139302
- return path__default.resolve(hostWorkdir, trimmed);
139435
+ return path__default.resolve(hostWorkdir, trimmed2);
139303
139436
  } catch (error2) {
139304
- this.logger.debug(`[${sessionId}] Failed to resolve Codex generated image path ${trimmed}: ${formatErrorMessage(error2)}`);
139437
+ this.logger.debug(`[${sessionId}] Failed to resolve Codex generated image path ${trimmed2}: ${formatErrorMessage(error2)}`);
139305
139438
  return null;
139306
139439
  }
139307
139440
  }
@@ -139638,11 +139771,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
139638
139771
  return serverUrl.endsWith("/") ? serverUrl.slice(0, -1) : serverUrl;
139639
139772
  }
139640
139773
  async validateSessionImageUploadPath(filePath) {
139641
- const trimmed = filePath.trim();
139642
- if (!trimmed) {
139774
+ const trimmed2 = filePath.trim();
139775
+ if (!trimmed2) {
139643
139776
  throw new Error("Image path is empty");
139644
139777
  }
139645
- const absolutePath = path__default.resolve(trimmed);
139778
+ const absolutePath = path__default.resolve(trimmed2);
139646
139779
  let handle;
139647
139780
  try {
139648
139781
  handle = await fs__default.promises.open(absolutePath, fs__default.constants.O_RDONLY | fs__default.constants.O_NOFOLLOW);
@@ -140199,9 +140332,9 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140199
140332
  const visualAnnotationRefTexts = [];
140200
140333
  for (const block of args2.inputBlocks) {
140201
140334
  if (block.type === "text") {
140202
- const trimmed = block.text.trim();
140203
- if (trimmed) {
140204
- textParts.push(trimmed);
140335
+ const trimmed2 = block.text.trim();
140336
+ if (trimmed2) {
140337
+ textParts.push(trimmed2);
140205
140338
  }
140206
140339
  continue;
140207
140340
  }
@@ -140942,14 +141075,14 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140942
141075
  ...getMachineFlockLocalProjects(options.machineFlockRows ?? {})
140943
141076
  };
140944
141077
  const requestRecord = this.toDeleteRequestRecord(options.request);
140945
- const trimmed = (value) => {
141078
+ const trimmed2 = (value) => {
140946
141079
  const v = value?.trim();
140947
141080
  return v ? v : void 0;
140948
141081
  };
140949
- const branchName = trimmed(requestRecord.branchName) ?? trimmed(sessionMeta?.branchName);
140950
- const baseBranchName = trimmed(requestRecord.baseBranchName) ?? trimmed(sessionMeta?.baseBranch);
140951
- const requestLocalProjectId = trimmed(requestRecord.localProjectId);
140952
- const requestOriginalRootPath = trimmed(requestRecord.originalRootPath);
141082
+ const branchName = trimmed2(requestRecord.branchName) ?? trimmed2(sessionMeta?.branchName);
141083
+ const baseBranchName = trimmed2(requestRecord.baseBranchName) ?? trimmed2(sessionMeta?.baseBranch);
141084
+ const requestLocalProjectId = trimmed2(requestRecord.localProjectId);
141085
+ const requestOriginalRootPath = trimmed2(requestRecord.originalRootPath);
140953
141086
  const requestHasLocalTarget = requestLocalProjectId !== void 0 || requestOriginalRootPath !== void 0;
140954
141087
  const isLocalWorktree = sessionMeta?.project?.kind === "local" ? sessionMeta.isWorktree === true || requestRecord.isWorktree === true : requestHasLocalTarget && requestRecord.isWorktree === true;
140955
141088
  if (isLocalWorktree) {
@@ -140972,7 +141105,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140972
141105
  } : {}
140973
141106
  };
140974
141107
  }
140975
- const repoFullName = sessionMeta?.project?.kind === "local" ? void 0 : trimmed(requestRecord.repoFullName) ?? trimmed(sessionMeta?.repoFullName);
141108
+ const repoFullName = sessionMeta?.project?.kind === "local" ? void 0 : trimmed2(requestRecord.repoFullName) ?? trimmed2(sessionMeta?.repoFullName);
140976
141109
  if (!repoFullName) {
140977
141110
  return null;
140978
141111
  }
@@ -142200,6 +142333,27 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
142200
142333
  }
142201
142334
  return metaRecord.meta;
142202
142335
  }
142336
+ async persistCodeCollabAllChangesDiffStats(ownerSessionId, diffStats) {
142337
+ const ownerRoomId = getSessionRoomId(ownerSessionId);
142338
+ const metaRecord = await this.workspaceDocument.repo.getDocMeta(ownerRoomId);
142339
+ if (!metaRecord?.meta || isLoroRepoDocDeleted(metaRecord)) {
142340
+ return;
142341
+ }
142342
+ const ownerMeta = readDiffStatsMetadata(metaRecord.meta);
142343
+ const target = resolveDiffStatsTarget({
142344
+ ownerRoomId,
142345
+ ownerMeta
142346
+ });
142347
+ const patch2 = resolveCodeCollabAllChangesDiffStatsPatch({
142348
+ target,
142349
+ ownerMeta,
142350
+ diffStats
142351
+ });
142352
+ if (!patch2) {
142353
+ return;
142354
+ }
142355
+ await this.workspaceDocument.repo.upsertDocMeta(ownerRoomId, patch2);
142356
+ }
142203
142357
  canWriteCodeCollabOwnerSession(args2) {
142204
142358
  const requester = args2.requestedByUserId?.trim();
142205
142359
  if (!requester) {
@@ -142583,11 +142737,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
142583
142737
  });
142584
142738
  }
142585
142739
  async validateSessionFileUploadPath(filePath, options) {
142586
- const trimmed = filePath.trim();
142587
- if (!trimmed) {
142740
+ const trimmed2 = filePath.trim();
142741
+ if (!trimmed2) {
142588
142742
  throw new Error("File path is empty");
142589
142743
  }
142590
- const absolutePath = options?.containWithin ? await resolveContainedUploadPath(trimmed, options.containWithin) : path__default.resolve(trimmed);
142744
+ const absolutePath = options?.containWithin ? await resolveContainedUploadPath(trimmed2, options.containWithin) : path__default.resolve(trimmed2);
142591
142745
  let handle;
142592
142746
  try {
142593
142747
  handle = await fs__default.promises.open(absolutePath, fs__default.constants.O_RDONLY | fs__default.constants.O_NOFOLLOW);
@@ -152117,12 +152271,12 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152117
152271
  const DEFAULT_AI_GIT_AUTHOR_NAME = "LodyAI";
152118
152272
  const DEFAULT_AI_GIT_AUTHOR_EMAIL = "agent@lody.ai";
152119
152273
  const trimNonEmpty = (value) => {
152120
- const trimmed = value?.trim();
152121
- return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
152274
+ const trimmed2 = value?.trim();
152275
+ return trimmed2 !== void 0 && trimmed2.length > 0 ? trimmed2 : void 0;
152122
152276
  };
152123
152277
  const isUsableEmail = (email) => {
152124
- const trimmed = trimNonEmpty(email);
152125
- return trimmed !== void 0 && !isMissingEmail(trimmed);
152278
+ const trimmed2 = trimNonEmpty(email);
152279
+ return trimmed2 !== void 0 && !isMissingEmail(trimmed2);
152126
152280
  };
152127
152281
  const normalizeName = (name2, email) => {
152128
152282
  if (name2 !== void 0 && !isMissingEmail(name2)) {
@@ -152390,7 +152544,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152390
152544
  const serializedArgs = args2.map((arg) => `'${arg.replace(/'/g, `'"'"'`)}'`).join(" ");
152391
152545
  return `${command2} ${serializedArgs}`;
152392
152546
  }
152393
- buildShellEnv(extraEnv) {
152547
+ buildShellEnv(extraEnv, loginShellEnv = getCachedLoginShellEnvSync()) {
152394
152548
  const configEnv = this.config.env ?? {};
152395
152549
  const workspaceSessionId = this.config.parentSessionId ?? this.sessionId;
152396
152550
  const merged = {
@@ -152404,15 +152558,16 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152404
152558
  LODY_SESSION_ID: this.sessionId,
152405
152559
  LODY_WORKSPACE_SESSION_ID: workspaceSessionId
152406
152560
  };
152407
- const withLoginShell = mergeLoginShellEnv(merged, getCachedLoginShellEnvSync());
152561
+ const withLoginShell = mergeLoginShellEnv(merged, loginShellEnv);
152408
152562
  const agentEnv = shouldScrubClaudeAuthEnv(this.config.agentCliType, this.config.agentType) ? scrubInheritedClaudeAuthEnv(withLoginShell, {
152409
152563
  ...configEnv,
152410
152564
  ...extraEnv
152411
152565
  }) : withLoginShell;
152412
- return withDefaultAcpPathEntries(agentEnv);
152566
+ return withDefaultAcpPathEntries(agentEnv, this.config.agentType);
152413
152567
  }
152414
152568
  async createAgent(callbacks) {
152415
- const env2 = withLodyNpmCacheForNpx(callbacks.command, this.buildShellEnv(callbacks.env));
152569
+ const loginShellEnv = await getLoginShellEnv();
152570
+ const env2 = withLodyNpmCacheForNpx(callbacks.command, this.buildShellEnv(callbacks.env, loginShellEnv));
152416
152571
  const launcher = resolveAcpLauncher(callbacks.command);
152417
152572
  const spawnAnalyticsProps = {
152418
152573
  cliType: callbacks.cliType,
@@ -182945,8 +183100,8 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
182945
183100
  console.log(JSON.stringify(value));
182946
183101
  }
182947
183102
  function normalizeCliValue(value) {
182948
- const trimmed = value?.trim();
182949
- return trimmed || void 0;
183103
+ const trimmed2 = value?.trim();
183104
+ return trimmed2 || void 0;
182950
183105
  }
182951
183106
  function formatWorkspaceCandidates(workspaces) {
182952
183107
  return workspaces.map((workspace) => {
@@ -188478,11 +188633,11 @@ ${entry.text}`).join("\n\n");
188478
188633
  });
188479
188634
  }));
188480
188635
  function encodeExportPathSegment(value, fallback2) {
188481
- const trimmed = value.trim();
188482
- if (!trimmed) {
188636
+ const trimmed2 = value.trim();
188637
+ if (!trimmed2) {
188483
188638
  return fallback2;
188484
188639
  }
188485
- const encoded = encodeURIComponent(trimmed);
188640
+ const encoded = encodeURIComponent(trimmed2);
188486
188641
  return encoded || fallback2;
188487
188642
  }
188488
188643
  function ensurePathWithinBase(baseDir, candidatePath) {
@@ -188508,8 +188663,8 @@ ${entry.text}`).join("\n\n");
188508
188663
  "image/gif": ".gif"
188509
188664
  };
188510
188665
  function normalizeString(value) {
188511
- const trimmed = value?.trim();
188512
- return trimmed || null;
188666
+ const trimmed2 = value?.trim();
188667
+ return trimmed2 || null;
188513
188668
  }
188514
188669
  function cloneItems(items2) {
188515
188670
  if (!Array.isArray(items2)) {
@@ -188662,11 +188817,11 @@ ${entry.text}`).join("\n\n");
188662
188817
  "image/gif": ".gif"
188663
188818
  };
188664
188819
  function sanitizeFileStem(value) {
188665
- const trimmed = value.trim();
188666
- if (!trimmed) {
188820
+ const trimmed2 = value.trim();
188821
+ if (!trimmed2) {
188667
188822
  return "image";
188668
188823
  }
188669
- return trimmed.replace(/[^A-Za-z0-9._-]/g, "_");
188824
+ return trimmed2.replace(/[^A-Za-z0-9._-]/g, "_");
188670
188825
  }
188671
188826
  function resolveOutputPath(baseDir, attachment) {
188672
188827
  const currentRelativePath = attachment.relativePath;
@@ -189232,7 +189387,7 @@ ${entry.text}`).join("\n\n");
189232
189387
  data = createReviewBundleSnapshot(bundle);
189233
189388
  }
189234
189389
  const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
189235
- const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-DYasOJ94.js");
189390
+ const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-BHFYVB1-.js");
189236
189391
  const template = await resolveReviewViewerTemplate();
189237
189392
  const html = injectReviewSnapshot(template, data);
189238
189393
  const outputPath = options.output ? path__default$1.resolve(options.output) : defaultHtmlOutputPath(inputPath);
@@ -206949,8 +207104,8 @@ ${result.stderr}`;
206949
207104
  const postImageUpload = async (request2, localControlPort) => pickResponse(await postSessionControl(request2, localControlPort), "session/image-upload_response", "an image upload response");
206950
207105
  const postFileUpload = async (request2, localControlPort) => pickResponse(await postSessionControl(request2, localControlPort, FILE_UPLOAD_TIMEOUT_MS), "session/file-upload_response", "a file upload response");
206951
207106
  const resolveUploadPath = (filePath, workdir) => {
206952
- const trimmed = filePath.trim();
206953
- return path__default.isAbsolute(trimmed) ? trimmed : path__default.resolve(workdir, trimmed);
207107
+ const trimmed2 = filePath.trim();
207108
+ return path__default.isAbsolute(trimmed2) ? trimmed2 : path__default.resolve(workdir, trimmed2);
206954
207109
  };
206955
207110
  async function runLodyMcpServer() {
206956
207111
  const server = new McpServer({
@@ -207376,6 +207531,72 @@ ${lines2.join("\n")}` : ""}${suffix}`);
207376
207531
  return main.exports;
207377
207532
  }
207378
207533
  var mainExports = requireMain();
207534
+ const VALID_ORDERS = /* @__PURE__ */ new Set([
207535
+ "ipv4first",
207536
+ "ipv6first",
207537
+ "verbatim"
207538
+ ]);
207539
+ const RUNTIME_DEFAULT_VALUES = /* @__PURE__ */ new Set([
207540
+ "node",
207541
+ "native",
207542
+ "default",
207543
+ "verbatim"
207544
+ ]);
207545
+ const DNS_RESULT_ORDER_FLAG = "--dns-result-order";
207546
+ function hasExplicitNodeFlag(execArgv, nodeOptions) {
207547
+ if (execArgv.some((arg) => arg === DNS_RESULT_ORDER_FLAG || arg.startsWith(`${DNS_RESULT_ORDER_FLAG}=`))) {
207548
+ return true;
207549
+ }
207550
+ return typeof nodeOptions === "string" && nodeOptions.includes(DNS_RESULT_ORDER_FLAG);
207551
+ }
207552
+ function resolveDnsResultOrder(env2 = process.env, execArgv = process.execArgv) {
207553
+ if (hasExplicitNodeFlag(execArgv, env2.NODE_OPTIONS)) {
207554
+ return {
207555
+ order: null,
207556
+ reason: "explicit-node-flag"
207557
+ };
207558
+ }
207559
+ const configured = env2.LODY_DNS_RESULT_ORDER?.trim().toLowerCase();
207560
+ if (configured) {
207561
+ if (RUNTIME_DEFAULT_VALUES.has(configured)) {
207562
+ return {
207563
+ order: null,
207564
+ reason: "env-runtime-default"
207565
+ };
207566
+ }
207567
+ if (VALID_ORDERS.has(configured)) {
207568
+ return {
207569
+ order: configured,
207570
+ reason: "env"
207571
+ };
207572
+ }
207573
+ return {
207574
+ order: "ipv4first",
207575
+ reason: "env-invalid"
207576
+ };
207577
+ }
207578
+ return {
207579
+ order: "ipv4first",
207580
+ reason: "default"
207581
+ };
207582
+ }
207583
+ function applyDefaultDnsResultOrder(options = {}) {
207584
+ const logger2 = options.logger ?? getLogger("dns");
207585
+ const resolution = resolveDnsResultOrder(options.env);
207586
+ if (resolution.order === null) {
207587
+ logger2.debug(`[dns] keeping runtime DNS result order (${resolution.reason})`);
207588
+ return;
207589
+ }
207590
+ if (resolution.reason === "env-invalid") {
207591
+ logger2.warn(`[dns] invalid LODY_DNS_RESULT_ORDER value; expected ipv4first|ipv6first|verbatim|node \u2014 falling back to ipv4first`);
207592
+ }
207593
+ try {
207594
+ require$$1$9.setDefaultResultOrder(resolution.order);
207595
+ logger2.debug(`[dns] default DNS result order set to ${resolution.order} (${resolution.reason})`);
207596
+ } catch (error2) {
207597
+ logger2.debug(`[dns] failed to set DNS result order: ${error2 instanceof Error ? error2.message : String(error2)}`);
207598
+ }
207599
+ }
207379
207600
  const cliLogger = getLogger("cli");
207380
207601
  function loadEnvironmentVariables() {
207381
207602
  const runtimeEnv2 = getRuntimeEnv();
@@ -207390,6 +207611,9 @@ ${lines2.join("\n")}` : ""}${suffix}`);
207390
207611
  loadEnv();
207391
207612
  }
207392
207613
  loadEnvironmentVariables();
207614
+ applyDefaultDnsResultOrder({
207615
+ logger: getLogger("dns")
207616
+ });
207393
207617
  installCliHttpGlobalDispatcher({
207394
207618
  logger: getLogger("http-transport")
207395
207619
  });