lody 0.70.0 → 0.70.1

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.1";
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
  }
@@ -63394,9 +63376,9 @@ stream:${scope2.streamId}`;
63394
63376
  if (urls == null) return;
63395
63377
  const out = [];
63396
63378
  for (const raw2 of urls) {
63397
- const trimmed = raw2.trim();
63398
- if (trimmed.length === 0) continue;
63399
- const url2 = new URL(trimmed);
63379
+ const trimmed2 = raw2.trim();
63380
+ if (trimmed2.length === 0) continue;
63381
+ const url2 = new URL(trimmed2);
63400
63382
  if (url2.protocol !== "http:" && url2.protocol !== "https:") throw new Error(`${label2} shard URL must use http or https`);
63401
63383
  if (url2.pathname !== "/" || url2.search !== "" || url2.hash !== "") throw new Error(`${label2} shard URL must be an origin URL`);
63402
63384
  out.push(url2.origin);
@@ -63969,14 +63951,14 @@ stream:${scope2.streamId}`;
63969
63951
  }
63970
63952
  function parseRetryAfterMs$1(value) {
63971
63953
  if (value == null) return;
63972
- const trimmed = value.trim();
63973
- if (trimmed.length === 0) return;
63974
- const numeric = Number(trimmed);
63954
+ const trimmed2 = value.trim();
63955
+ if (trimmed2.length === 0) return;
63956
+ const numeric = Number(trimmed2);
63975
63957
  if (Number.isFinite(numeric)) {
63976
63958
  if (numeric < 0) return;
63977
63959
  return Math.round(numeric * 1e3);
63978
63960
  }
63979
- const parsed = Date.parse(trimmed);
63961
+ const parsed = Date.parse(trimmed2);
63980
63962
  if (Number.isNaN(parsed)) return;
63981
63963
  const delta = parsed - Date.now();
63982
63964
  return delta > 0 ? delta : void 0;
@@ -100130,11 +100112,11 @@ ${value}`;
100130
100112
  const LORO_RPC_REQUEST_STREAM_SEGMENT = "rpc:req";
100131
100113
  const getLoroMachineRpcRequestStreamId = (workspaceId, machineId) => `${workspaceId}:${LORO_RPC_REQUEST_STREAM_SEGMENT}:${machineId}`;
100132
100114
  const normalizeLoroGatewayBaseUrl = (baseUrl) => {
100133
- const trimmed = baseUrl?.trim();
100134
- if (!trimmed) {
100115
+ const trimmed2 = baseUrl?.trim();
100116
+ if (!trimmed2) {
100135
100117
  return DEFAULT_GATEWAY_BASE_URL;
100136
100118
  }
100137
- return trimmed.replace(/\/+$/g, "");
100119
+ return trimmed2.replace(/\/+$/g, "");
100138
100120
  };
100139
100121
  const LoroStreamsRpcMethodSchema = _enum$1([
100140
100122
  "machine/status",
@@ -102417,11 +102399,11 @@ Saved to: ${args2.relativePath}`;
102417
102399
  The file is not available yet and could not be downloaded; ask the user to resend it if you need its contents.`;
102418
102400
  };
102419
102401
  const resolveContainedUploadPath = async (filePath, workspaceRoot) => {
102420
- const trimmed = filePath.trim();
102421
- if (!trimmed) {
102402
+ const trimmed2 = filePath.trim();
102403
+ if (!trimmed2) {
102422
102404
  throw new Error("File path is empty");
102423
102405
  }
102424
- const candidate = path.isAbsolute(trimmed) ? trimmed : path.resolve(workspaceRoot, trimmed);
102406
+ const candidate = path.isAbsolute(trimmed2) ? trimmed2 : path.resolve(workspaceRoot, trimmed2);
102425
102407
  let realRoot;
102426
102408
  try {
102427
102409
  realRoot = await fs.promises.realpath(workspaceRoot);
@@ -102554,11 +102536,11 @@ The file is not available yet and could not be downloaded; ask the user to resen
102554
102536
  }
102555
102537
  }
102556
102538
  function parseGitRemoteDefaultBranch(raw2, remoteName) {
102557
- const trimmed = raw2.trim();
102558
- if (!trimmed) return null;
102539
+ const trimmed2 = raw2.trim();
102540
+ if (!trimmed2) return null;
102559
102541
  const prefix = `${remoteName}/`;
102560
- if (!trimmed.startsWith(prefix)) return null;
102561
- const name2 = trimmed.slice(prefix.length).trim();
102542
+ if (!trimmed2.startsWith(prefix)) return null;
102543
+ const name2 = trimmed2.slice(prefix.length).trim();
102562
102544
  return name2 || null;
102563
102545
  }
102564
102546
  async function listGitRemotes(rootPath) {
@@ -108000,9 +107982,9 @@ ${incoming}`).output;
108000
107982
  }
108001
107983
  }
108002
107984
  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";
107985
+ const trimmed2 = (command2 ?? "").trim().toLowerCase();
107986
+ if (trimmed2 === "npx" || trimmed2.endsWith("/npx") || trimmed2.endsWith("\\npx")) return "npx";
107987
+ if (trimmed2 === "uvx" || trimmed2.endsWith("/uvx") || trimmed2.endsWith("\\uvx")) return "uvx";
108006
107988
  return "local";
108007
107989
  }
108008
107990
  function getErrnoCode(error2) {
@@ -108282,9 +108264,9 @@ ${incoming}`).output;
108282
108264
  };
108283
108265
  };
108284
108266
  const sanitizeText = (value, maxLength) => {
108285
- const trimmed = value?.trim();
108286
- if (!trimmed) return void 0;
108287
- return truncate(trimmed, maxLength);
108267
+ const trimmed2 = value?.trim();
108268
+ if (!trimmed2) return void 0;
108269
+ return truncate(trimmed2, maxLength);
108288
108270
  };
108289
108271
  const sanitizeTitleText = (value) => sanitizeText(value?.replace(/\s+/g, " "), MAX_TITLE_LENGTH);
108290
108272
  const truncate = (value, maxLength) => {
@@ -119438,8 +119420,8 @@ ${error2.message}` : execaMessage;
119438
119420
  return segment.replace(/[^a-zA-Z0-9._-]/g, "_");
119439
119421
  }
119440
119422
  function normalizeBaseUrl(value) {
119441
- const trimmed = value?.trim();
119442
- return (trimmed && trimmed.length > 0 ? trimmed : DEFAULT_RUNTIME_BASE_URL).replace(/\/+$/u, "");
119423
+ const trimmed2 = value?.trim();
119424
+ return (trimmed2 && trimmed2.length > 0 ? trimmed2 : DEFAULT_RUNTIME_BASE_URL).replace(/\/+$/u, "");
119443
119425
  }
119444
119426
  function isLocalDevelopmentBaseUrl(value) {
119445
119427
  try {
@@ -120027,6 +120009,7 @@ ${error2.message}` : execaMessage;
120027
120009
  "bin",
120028
120010
  ".claude/local"
120029
120011
  ];
120012
+ const KIMI_CODE_ACP_PATH_RELATIVE_DIR = ".kimi-code/bin";
120030
120013
  const registryAgentsById = Object.fromEntries(REGISTRY_ACP_AGENTS.map((agent2) => [
120031
120014
  agent2.id,
120032
120015
  agent2
@@ -120172,8 +120155,8 @@ ${error2.message}` : execaMessage;
120172
120155
  return pathValue;
120173
120156
  }
120174
120157
  function trimRuntimeOverride(value) {
120175
- const trimmed = value?.trim();
120176
- return trimmed ? resolve$2(expandHomePath(trimmed)) : void 0;
120158
+ const trimmed2 = value?.trim();
120159
+ return trimmed2 ? resolve$2(expandHomePath(trimmed2)) : void 0;
120177
120160
  }
120178
120161
  function resolveCliAdapterEntry(adapter) {
120179
120162
  const argvEntry = process.argv[1] ? resolve$2(process.argv[1]) : void 0;
@@ -120282,14 +120265,18 @@ ${error2.message}` : execaMessage;
120282
120265
  const normalized = normalize(entry);
120283
120266
  return normalized.length > 1 ? normalized.replace(/[\\/]+$/, "") : normalized;
120284
120267
  }
120285
- function getDefaultAcpPathEntries(homeDir = homedir()) {
120268
+ function getDefaultAcpPathEntries(homeDir = homedir(), agentType) {
120286
120269
  if (!homeDir) {
120287
120270
  return [];
120288
120271
  }
120289
- return DEFAULT_ACP_PATH_RELATIVE_DIRS.map((relativeDir) => join$2(homeDir, relativeDir));
120272
+ const relativeDirs = agentType === "kimi" || agentType === "kimi-code" ? [
120273
+ KIMI_CODE_ACP_PATH_RELATIVE_DIR,
120274
+ ...DEFAULT_ACP_PATH_RELATIVE_DIRS
120275
+ ] : DEFAULT_ACP_PATH_RELATIVE_DIRS;
120276
+ return relativeDirs.map((relativeDir) => join$2(homeDir, relativeDir));
120290
120277
  }
120291
- function withDefaultAcpPathEntries(env2) {
120292
- const defaultEntries = getDefaultAcpPathEntries();
120278
+ function withDefaultAcpPathEntries(env2, agentType) {
120279
+ const defaultEntries = getDefaultAcpPathEntries(homedir(), agentType);
120293
120280
  if (defaultEntries.length === 0) {
120294
120281
  return env2;
120295
120282
  }
@@ -121206,7 +121193,7 @@ ${fallbackStderrTail}` : errorMessage;
121206
121193
  CODEX_HOME: path__default.join(options.workdir, ".codex")
121207
121194
  } : baseEnv;
121208
121195
  const loginShellEnv = await getLoginShellEnv();
121209
- const envWithAcpStartup = withoutElectronBootstrapCredentials(withLodyNpmCacheForNpx(launch.command, withDefaultAcpPathEntries(mergeACPProcessEnv(launch, mergeLoginShellEnv(env2, loginShellEnv)))));
121196
+ const envWithAcpStartup = withoutElectronBootstrapCredentials(withLodyNpmCacheForNpx(launch.command, withDefaultAcpPathEntries(mergeACPProcessEnv(launch, mergeLoginShellEnv(env2, loginShellEnv)), options.agentType)));
121210
121197
  const keepCodexHome = env2.LODY_KEEP_CODEX_HOME === "1";
121211
121198
  const defaultCodexHome = path__default.join(os__default.homedir(), ".codex");
121212
121199
  const defaultAuthPath = path__default.join(defaultCodexHome, "auth.json");
@@ -122099,8 +122086,8 @@ ${fallbackStderrTail}` : errorMessage;
122099
122086
  const tryExecTrimmed = async (exec2, command2, args2, workdir) => {
122100
122087
  try {
122101
122088
  const output = await exec2(command2, args2, workdir, false);
122102
- const trimmed = output.trim();
122103
- return trimmed ? trimmed : null;
122089
+ const trimmed2 = output.trim();
122090
+ return trimmed2 ? trimmed2 : null;
122104
122091
  } catch {
122105
122092
  return null;
122106
122093
  }
@@ -123377,8 +123364,8 @@ path=/${options.repoFullName}.git
123377
123364
  return normalized.startsWith("release/") || normalized.startsWith("releases/");
123378
123365
  }
123379
123366
  shouldReuseExistingBaseBranch(branchName) {
123380
- const trimmed = branchName?.trim();
123381
- return !!trimmed && !this.isCommonBaseBranchName(trimmed);
123367
+ const trimmed2 = branchName?.trim();
123368
+ return !!trimmed2 && !this.isCommonBaseBranchName(trimmed2);
123382
123369
  }
123383
123370
  async hasLocalBranch(branchName) {
123384
123371
  const sanitized = branchName.trim();
@@ -123411,19 +123398,19 @@ path=/${options.repoFullName}.git
123411
123398
  if (this.isLocalSharedSource()) {
123412
123399
  return null;
123413
123400
  }
123414
- const trimmed = baseBranch?.trim();
123415
- if (!this.shouldReuseExistingBaseBranch(trimmed)) {
123401
+ const trimmed2 = baseBranch?.trim();
123402
+ if (!this.shouldReuseExistingBaseBranch(trimmed2)) {
123416
123403
  return null;
123417
123404
  }
123418
- if (await this.hasLocalBranch(trimmed)) {
123405
+ if (await this.hasLocalBranch(trimmed2)) {
123419
123406
  return {
123420
- branchName: trimmed
123407
+ branchName: trimmed2
123421
123408
  };
123422
123409
  }
123423
- const remoteBranch = `origin/${trimmed}`;
123410
+ const remoteBranch = `origin/${trimmed2}`;
123424
123411
  if (this.repoUrl && await this.hasCommitish(remoteBranch)) {
123425
123412
  return {
123426
- branchName: trimmed,
123413
+ branchName: trimmed2,
123427
123414
  startPoint: remoteBranch
123428
123415
  };
123429
123416
  }
@@ -124798,8 +124785,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
124798
124785
  baseRef,
124799
124786
  "HEAD"
124800
124787
  ]);
124801
- const trimmed = mergeBase.trim();
124802
- if (trimmed) return trimmed;
124788
+ const trimmed2 = mergeBase.trim();
124789
+ if (trimmed2) return trimmed2;
124803
124790
  } catch {
124804
124791
  return null;
124805
124792
  }
@@ -124861,8 +124848,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
124861
124848
  "rev-parse",
124862
124849
  "HEAD"
124863
124850
  ]);
124864
- const trimmed = hash2.trim();
124865
- return trimmed || null;
124851
+ const trimmed2 = hash2.trim();
124852
+ return trimmed2 || null;
124866
124853
  } catch {
124867
124854
  return null;
124868
124855
  }
@@ -125130,8 +125117,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
125130
125117
  if (typeof rootPath !== "string") {
125131
125118
  return null;
125132
125119
  }
125133
- const trimmed = rootPath.trim();
125134
- return trimmed || null;
125120
+ const trimmed2 = rootPath.trim();
125121
+ return trimmed2 || null;
125135
125122
  }
125136
125123
  async function resolveWorkspaceLocalProject(repo, workspaceId, machineId, localProjectId) {
125137
125124
  const localProjects = await readMachineLocalProjects(repo, workspaceId, machineId);
@@ -125356,9 +125343,9 @@ $mem | ConvertTo-Json -Compress
125356
125343
  const memMaxPath = `/sys/fs/cgroup${current2 === "/" ? "" : current2}/memory.max`;
125357
125344
  const raw2 = readFileSafe(memMaxPath);
125358
125345
  if (raw2 !== null) {
125359
- const trimmed = raw2.trim();
125360
- if (trimmed !== "max") {
125361
- const value = parseInt(trimmed, 10);
125346
+ const trimmed2 = raw2.trim();
125347
+ if (trimmed2 !== "max") {
125348
+ const value = parseInt(trimmed2, 10);
125362
125349
  if (Number.isFinite(value) && value > 0) {
125363
125350
  tightest = tightest === null ? value : Math.min(tightest, value);
125364
125351
  }
@@ -125385,9 +125372,9 @@ $mem | ConvertTo-Json -Compress
125385
125372
  const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
125386
125373
  const raw2 = readFileSafe(`${prefix}/memory.max`);
125387
125374
  if (raw2 !== null) {
125388
- const trimmed = raw2.trim();
125389
- if (trimmed !== "max") {
125390
- const value = parseInt(trimmed, 10);
125375
+ const trimmed2 = raw2.trim();
125376
+ if (trimmed2 !== "max") {
125377
+ const value = parseInt(trimmed2, 10);
125391
125378
  if (Number.isFinite(value) && value > 0) {
125392
125379
  if (tightestMax === null || value < tightestMax) {
125393
125380
  tightestMax = value;
@@ -130333,6 +130320,89 @@ $mem | ConvertTo-Json -Compress
130333
130320
  }
130334
130321
  }
130335
130322
  }
130323
+ function trimmed(value) {
130324
+ if (typeof value !== "string") return void 0;
130325
+ const next2 = value.trim();
130326
+ return next2 ? next2 : void 0;
130327
+ }
130328
+ function isObjectRecord$1(value) {
130329
+ return value !== null && typeof value === "object" && !Array.isArray(value);
130330
+ }
130331
+ function isLocalProjectId(value) {
130332
+ return typeof value === "string" && value.trim().length > 0;
130333
+ }
130334
+ function isSessionDiffStats(value) {
130335
+ if (!isObjectRecord$1(value) || !isObjectRecord$1(value.allChange)) return false;
130336
+ return typeof value.allChange.add === "number" && typeof value.allChange.del === "number";
130337
+ }
130338
+ function readDiffStatsMetadata(value) {
130339
+ if (!isObjectRecord$1(value)) return void 0;
130340
+ return {
130341
+ ...value.project === void 0 ? {} : {
130342
+ project: value.project
130343
+ },
130344
+ ...typeof value.repoFullName === "string" ? {
130345
+ repoFullName: value.repoFullName
130346
+ } : {},
130347
+ ...isSessionDiffStats(value.diffStats) ? {
130348
+ diffStats: value.diffStats
130349
+ } : {},
130350
+ ...value.pullRequests === void 0 ? {} : {
130351
+ pullRequests: value.pullRequests
130352
+ }
130353
+ };
130354
+ }
130355
+ function metaGitHubRepo(meta) {
130356
+ if (!meta) return void 0;
130357
+ return resolveProjectGitHubRepo(meta.project) ?? trimmed(meta.repoFullName);
130358
+ }
130359
+ function localProjectIdFromProject(project) {
130360
+ return project?.kind === "local" ? project.localProjectId : void 0;
130361
+ }
130362
+ function localProjectIdFromMeta(meta) {
130363
+ const project = meta?.project;
130364
+ if (!isObjectRecord$1(project) || project.kind !== "local") return void 0;
130365
+ return isLocalProjectId(project.localProjectId) ? project.localProjectId : void 0;
130366
+ }
130367
+ function resolveDiffStatsTarget(options) {
130368
+ const repoFullName = resolveProjectGitHubRepo(options.project) ?? metaGitHubRepo(options.ownerMeta) ?? metaGitHubRepo(options.activeMeta);
130369
+ if (repoFullName) {
130370
+ return {
130371
+ kind: "github",
130372
+ ownerRoomId: options.ownerRoomId,
130373
+ repoFullName
130374
+ };
130375
+ }
130376
+ const localProjectId = localProjectIdFromProject(options.project) ?? localProjectIdFromMeta(options.ownerMeta) ?? localProjectIdFromMeta(options.activeMeta);
130377
+ if (localProjectId) {
130378
+ return {
130379
+ kind: "local",
130380
+ ownerRoomId: options.ownerRoomId,
130381
+ localProjectId
130382
+ };
130383
+ }
130384
+ return {
130385
+ kind: "unknown",
130386
+ ownerRoomId: options.ownerRoomId,
130387
+ reason: "unresolved-project"
130388
+ };
130389
+ }
130390
+ function resolveCodeCollabAllChangesDiffStatsPatch(options) {
130391
+ if (options.target.kind === "unknown") {
130392
+ return null;
130393
+ }
130394
+ if (options.target.kind === "github" && Array.isArray(options.ownerMeta?.pullRequests) && options.ownerMeta.pullRequests.some((pullRequest) => isObjectRecord$1(pullRequest) && pullRequest.status === "open")) {
130395
+ return null;
130396
+ }
130397
+ const current2 = options.ownerMeta?.diffStats?.allChange;
130398
+ const next2 = options.diffStats.allChange;
130399
+ if (current2?.add === next2.add && current2.del === next2.del) {
130400
+ return null;
130401
+ }
130402
+ return {
130403
+ diffStats: options.diffStats
130404
+ };
130405
+ }
130336
130406
  function isBunProcessVersions(versions) {
130337
130407
  return typeof versions?.bun === "string" && versions.bun.length > 0;
130338
130408
  }
@@ -130706,7 +130776,8 @@ $mem | ConvertTo-Json -Compress
130706
130776
  await this.enqueueSharedStateRefresh(resolved.ownerSessionId, {
130707
130777
  kind: "full",
130708
130778
  resolved,
130709
- forcePublish: options.forcePublish === true
130779
+ forcePublish: options.forcePublish === true,
130780
+ persistAllChangesDiffStats: false
130710
130781
  });
130711
130782
  }
130712
130783
  async refreshSharedStateAfterTurn(request2) {
@@ -130714,7 +130785,8 @@ $mem | ConvertTo-Json -Compress
130714
130785
  await this.enqueueSharedStateRefresh(resolved.ownerSessionId, {
130715
130786
  kind: "turn",
130716
130787
  resolved,
130717
- forcePublish: false
130788
+ forcePublish: false,
130789
+ persistAllChangesDiffStats: true
130718
130790
  });
130719
130791
  }
130720
130792
  async refreshSharedStateNow(resolved, options = {}) {
@@ -130746,7 +130818,9 @@ $mem | ConvertTo-Json -Compress
130746
130818
  void this.ensureWorkspaceWatch(resolved).catch(() => void 0);
130747
130819
  const state2 = this.getOwnerState(resolved.ownerSessionId);
130748
130820
  const fileTreeIndex = buildFileTreePathIndex(state2.fileTree);
130749
- const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex);
130821
+ const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex, {
130822
+ persistAllChangesDiffStats: true
130823
+ });
130750
130824
  if (workerResult) {
130751
130825
  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
130826
  return;
@@ -130764,7 +130838,9 @@ $mem | ConvertTo-Json -Compress
130764
130838
  });
130765
130839
  const scanMs2 = Date.now() - scanStartedAtMs2;
130766
130840
  await this.ensureAllChangesFileTreeEntries(resolved, state2, fileTreeIndex);
130767
- await this.publishOwnerState(resolved.ownerSessionId, state2);
130841
+ await this.publishOwnerState(resolved.ownerSessionId, state2, {
130842
+ persistAllChangesDiffStats: true
130843
+ });
130768
130844
  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
130845
  return;
130770
130846
  }
@@ -130797,7 +130873,9 @@ $mem | ConvertTo-Json -Compress
130797
130873
  }
130798
130874
  const scanMs = Date.now() - scanStartedAtMs;
130799
130875
  await this.ensureAllChangesFileTreeEntries(resolved, state2, fileTreeIndex);
130800
- await this.publishOwnerState(resolved.ownerSessionId, state2);
130876
+ await this.publishOwnerState(resolved.ownerSessionId, state2, {
130877
+ persistAllChangesDiffStats: true
130878
+ });
130801
130879
  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
130880
  }
130803
130881
  async refreshKnownSharedStates() {
@@ -130820,7 +130898,8 @@ $mem | ConvertTo-Json -Compress
130820
130898
  ...this.stateByOwnerSessionId.entries()
130821
130899
  ].map(async ([ownerSessionId, state2]) => {
130822
130900
  await this.publishOwnerState(ownerSessionId, state2, {
130823
- forcePublish: true
130901
+ forcePublish: true,
130902
+ persistAllChangesDiffStats: true
130824
130903
  });
130825
130904
  }));
130826
130905
  }
@@ -130858,7 +130937,8 @@ $mem | ConvertTo-Json -Compress
130858
130937
  await this.refreshSharedStateAfterTurnNow(refresh.resolved);
130859
130938
  } else {
130860
130939
  await this.refreshSharedStateNow(refresh.resolved, {
130861
- forcePublish: refresh.forcePublish
130940
+ forcePublish: refresh.forcePublish,
130941
+ persistAllChangesDiffStats: refresh.persistAllChangesDiffStats
130862
130942
  });
130863
130943
  }
130864
130944
  } catch (error2) {
@@ -131274,7 +131354,9 @@ $mem | ConvertTo-Json -Compress
131274
131354
  const state2 = this.getOwnerState(resolved.ownerSessionId);
131275
131355
  const fileTreeIndex = buildFileTreePathIndex(state2.fileTree);
131276
131356
  if (resolved.workspacePath.length === 0) {
131277
- const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex);
131357
+ const workerResult = await this.computeAndPublishFullSharedStateInWorker(resolved, state2, fileTreeIndex, {
131358
+ persistAllChangesDiffStats: true
131359
+ });
131278
131360
  if (workerResult) {
131279
131361
  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
131362
  return workerResult.entries;
@@ -131288,7 +131370,8 @@ $mem | ConvertTo-Json -Compress
131288
131370
  });
131289
131371
  const scanMs = Date.now() - scanStartedAtMs;
131290
131372
  await this.computeAllChangesAndPublish(resolved, state2, {
131291
- fileTreeIndex
131373
+ fileTreeIndex,
131374
+ persistAllChangesDiffStats: resolved.workspacePath.length === 0
131292
131375
  });
131293
131376
  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
131377
  return publishedEntries;
@@ -131682,7 +131765,7 @@ $mem | ConvertTo-Json -Compress
131682
131765
  const equalityStartedAtMs = Date.now();
131683
131766
  const unchanged = previous && options.forcePublish !== true && codeCollabFileIndexStatesEqual(previous.fileIndex, fileIndex);
131684
131767
  const equalityMs = Date.now() - equalityStartedAtMs;
131685
- if (unchanged) {
131768
+ if (unchanged && options.persistAllChangesDiffStats !== true) {
131686
131769
  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
131770
  return;
131688
131771
  }
@@ -131695,6 +131778,8 @@ $mem | ConvertTo-Json -Compress
131695
131778
  await publishFileIndex({
131696
131779
  ownerSessionId,
131697
131780
  fileIndex,
131781
+ allChangesDiffStats: summarizeFileIndexAllChanges(fileIndex),
131782
+ persistAllChangesDiffStats: options.persistAllChangesDiffStats === true,
131698
131783
  updatedAtMs
131699
131784
  });
131700
131785
  const publishMs = Date.now() - publishStartedAtMs;
@@ -131744,6 +131829,27 @@ $mem | ConvertTo-Json -Compress
131744
131829
  }
131745
131830
  return next2;
131746
131831
  }
131832
+ function summarizeFileIndexAllChanges(fileIndex) {
131833
+ let add2 = 0;
131834
+ let del = 0;
131835
+ for (const value of Object.values(fileIndex)) {
131836
+ const change = value === true || !("change" in value) ? void 0 : value.change;
131837
+ if (change === void 0) {
131838
+ continue;
131839
+ }
131840
+ if (change === true || change.diff === void 0) {
131841
+ return null;
131842
+ }
131843
+ add2 += change.diff[0];
131844
+ del += change.diff[1];
131845
+ }
131846
+ return {
131847
+ allChange: {
131848
+ add: add2,
131849
+ del
131850
+ }
131851
+ };
131852
+ }
131747
131853
  function normalizeWorkspacePath(input2, options = {}) {
131748
131854
  if (input2.length === 0) {
131749
131855
  throw new CodeCollabV2ServiceError("invalid_path", "Path is required.");
@@ -132219,7 +132325,8 @@ $mem | ConvertTo-Json -Compress
132219
132325
  return {
132220
132326
  kind: current2.kind === "full" || next2.kind === "full" ? "full" : "turn",
132221
132327
  resolved: next2.resolved,
132222
- forcePublish: current2.forcePublish || next2.forcePublish
132328
+ forcePublish: current2.forcePublish || next2.forcePublish,
132329
+ persistAllChangesDiffStats: current2.persistAllChangesDiffStats || next2.persistAllChangesDiffStats
132223
132330
  };
132224
132331
  }
132225
132332
  function collectTurnRefreshCandidatePaths(allChanges, diffStorePaths) {
@@ -132495,9 +132602,9 @@ $mem | ConvertTo-Json -Compress
132495
132602
  baseRef,
132496
132603
  "HEAD"
132497
132604
  ]);
132498
- const trimmed = mergeBase.ok ? mergeBase.stdout.trim() : "";
132499
- if (trimmed) {
132500
- return trimmed;
132605
+ const trimmed2 = mergeBase.ok ? mergeBase.stdout.trim() : "";
132606
+ if (trimmed2) {
132607
+ return trimmed2;
132501
132608
  }
132502
132609
  }
132503
132610
  const head2 = await runGit(workspaceRoot, [
@@ -133518,12 +133625,12 @@ $mem | ConvertTo-Json -Compress
133518
133625
  const isSupportedSessionImageMimeType = (mimeType) => SESSION_IMAGE_ALLOWED_MIME_TYPES.includes(mimeType);
133519
133626
  const shouldUploadACPBytesAsImage = (mimeType, sizeBytes) => isSupportedSessionImageMimeType(mimeType) && sizeBytes <= SESSION_IMAGE_MAX_SIZE_BYTES;
133520
133627
  const getACPFileNameFromUri = (uri2) => {
133521
- const trimmed = uri2?.trim();
133522
- if (!trimmed) {
133628
+ const trimmed2 = uri2?.trim();
133629
+ if (!trimmed2) {
133523
133630
  return null;
133524
133631
  }
133525
133632
  try {
133526
- const parsed = new URL(trimmed);
133633
+ const parsed = new URL(trimmed2);
133527
133634
  if (parsed.protocol === "file:") {
133528
133635
  return path__default.basename(fileURLToPath$1(parsed));
133529
133636
  }
@@ -133540,7 +133647,7 @@ $mem | ConvertTo-Json -Compress
133540
133647
  }
133541
133648
  return null;
133542
133649
  } catch {
133543
- const baseName = path__default.basename(trimmed);
133650
+ const baseName = path__default.basename(trimmed2);
133544
133651
  return baseName && baseName !== "/" && baseName !== "." ? baseName : null;
133545
133652
  }
133546
133653
  };
@@ -133555,9 +133662,9 @@ $mem | ConvertTo-Json -Compress
133555
133662
  return fallbackExtension ? `${safeName}.${fallbackExtension}` : safeName;
133556
133663
  };
133557
133664
  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, "");
133665
+ const trimmed2 = data.trim();
133666
+ const commaIndex = trimmed2.startsWith("data:") ? trimmed2.indexOf(",") : -1;
133667
+ const base64 = (commaIndex >= 0 ? trimmed2.slice(commaIndex + 1) : trimmed2).replace(/\s/g, "");
133561
133668
  const bytes = Buffer.from(base64, "base64");
133562
133669
  if (bytes.byteLength <= 0) {
133563
133670
  throw new Error(`${label2} is empty`);
@@ -133676,15 +133783,15 @@ $mem | ConvertTo-Json -Compress
133676
133783
  ];
133677
133784
  };
133678
133785
  const resolveACPResourceLinkLocalPath = (uri2) => {
133679
- const trimmed = uri2.trim();
133680
- if (!trimmed) {
133786
+ const trimmed2 = uri2.trim();
133787
+ if (!trimmed2) {
133681
133788
  return null;
133682
133789
  }
133683
133790
  try {
133684
- const parsed = new URL(trimmed);
133791
+ const parsed = new URL(trimmed2);
133685
133792
  return parsed.protocol === "file:" ? fileURLToPath$1(parsed) : null;
133686
133793
  } catch {
133687
- return trimmed;
133794
+ return trimmed2;
133688
133795
  }
133689
133796
  };
133690
133797
  const shouldTreatACPPathAsImage = (filePath, mimeType) => {
@@ -134342,17 +134449,17 @@ $mem | ConvertTo-Json -Compress
134342
134449
  return code2 === "ENOENT" || code2 === "ENOTDIR";
134343
134450
  }
134344
134451
  function normalizeSkillScanDir(skillDir) {
134345
- const trimmed = skillDir.trim();
134346
- if (!trimmed) {
134452
+ const trimmed2 = skillDir.trim();
134453
+ if (!trimmed2) {
134347
134454
  throw new Error("Skill scan directory is required.");
134348
134455
  }
134349
- if (trimmed.includes("\0")) {
134456
+ if (trimmed2.includes("\0")) {
134350
134457
  throw new Error(`Invalid skill scan directory: ${skillDir}`);
134351
134458
  }
134352
- if (path__default$1.isAbsolute(trimmed)) {
134459
+ if (path__default$1.isAbsolute(trimmed2)) {
134353
134460
  throw new Error(`Skill scan directory must be project-relative: ${skillDir}`);
134354
134461
  }
134355
- const normalized = normalizeProjectRelativePath(trimmed);
134462
+ const normalized = normalizeProjectRelativePath(trimmed2);
134356
134463
  if (!normalized) {
134357
134464
  throw new Error(`Invalid skill scan directory: ${skillDir}`);
134358
134465
  }
@@ -134362,17 +134469,17 @@ $mem | ConvertTo-Json -Compress
134362
134469
  return normalized;
134363
134470
  }
134364
134471
  function normalizeKnownGlobalSkillScanDir(skillDir) {
134365
- const trimmed = skillDir.trim().replace(/\\/g, "/");
134366
- if (!trimmed) {
134472
+ const trimmed2 = skillDir.trim().replace(/\\/g, "/");
134473
+ if (!trimmed2) {
134367
134474
  throw new Error("Global skill scan directory is required.");
134368
134475
  }
134369
- if (trimmed.includes("\0")) {
134476
+ if (trimmed2.includes("\0")) {
134370
134477
  throw new Error(`Invalid global skill scan directory: ${skillDir}`);
134371
134478
  }
134372
- if (!trimmed.startsWith("~/")) {
134479
+ if (!trimmed2.startsWith("~/")) {
134373
134480
  throw new Error(`Global skill scan directory must be home-relative: ${skillDir}`);
134374
134481
  }
134375
- const relativeDir = normalizeSkillScanDir(trimmed.slice(2));
134482
+ const relativeDir = normalizeSkillScanDir(trimmed2.slice(2));
134376
134483
  return {
134377
134484
  displayDir: `~/${relativeDir}`,
134378
134485
  relativeDir
@@ -136108,11 +136215,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
136108
136215
  return `${invalidMessage} (${details.join(", ")}). Response body: ${summarizedBody}`;
136109
136216
  }
136110
136217
  function summarizeInvalidResponseBody(rawBody) {
136111
- const trimmed = rawBody.trim();
136112
- if (!trimmed) {
136218
+ const trimmed2 = rawBody.trim();
136219
+ if (!trimmed2) {
136113
136220
  return null;
136114
136221
  }
136115
- const compact = trimmed.replace(/\s+/g, " ");
136222
+ const compact = trimmed2.replace(/\s+/g, " ");
136116
136223
  const redacted = redactPreviewResponseSecrets(compact);
136117
136224
  if (redacted.length <= INVALID_RESPONSE_BODY_SNIPPET_MAX_CHARS) {
136118
136225
  return redacted;
@@ -136133,19 +136240,19 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
136133
136240
  const PREVIEW_REGISTRY_FILE = path__default.join(os__default.homedir(), ".lody", "preview-tunnels.json");
136134
136241
  const PREVIEW_REGISTRY_FUTURE_SKEW_MS = 6e4;
136135
136242
  const normalizeHost = (host) => {
136136
- const trimmed = host.trim().toLowerCase();
136137
- return trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : trimmed;
136243
+ const trimmed2 = host.trim().toLowerCase();
136244
+ return trimmed2.startsWith("[") && trimmed2.endsWith("]") ? trimmed2.slice(1, -1) : trimmed2;
136138
136245
  };
136139
136246
  const isLoopbackHost = (host) => LOOPBACK_HOSTS.has(normalizeHost(host));
136140
136247
  const normalizePath = (value) => {
136141
- const trimmed = value?.trim();
136142
- if (!trimmed) {
136248
+ const trimmed2 = value?.trim();
136249
+ if (!trimmed2) {
136143
136250
  return void 0;
136144
136251
  }
136145
- if (!trimmed.startsWith("/") || /^https?:\/\//i.test(trimmed) || trimmed.startsWith("//")) {
136252
+ if (!trimmed2.startsWith("/") || /^https?:\/\//i.test(trimmed2) || trimmed2.startsWith("//")) {
136146
136253
  return void 0;
136147
136254
  }
136148
- return trimmed;
136255
+ return trimmed2;
136149
136256
  };
136150
136257
  const normalizeTarget = (target) => {
136151
136258
  if (target.protocol !== "http") {
@@ -137052,7 +137159,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
137052
137159
  provider: args2.provider
137053
137160
  });
137054
137161
  const loginShellEnv = await getLoginShellEnv();
137055
- const env2 = withDefaultAcpPathEntries(mergeLoginShellEnv(launch.env, loginShellEnv));
137162
+ const env2 = withDefaultAcpPathEntries(mergeLoginShellEnv(launch.env, loginShellEnv), args2.provider.agentType);
137056
137163
  const agentProcess = spawnAcpProcess({
137057
137164
  cliType: args2.provider.cliType,
137058
137165
  agentType: args2.provider.agentType,
@@ -138578,6 +138685,13 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
138578
138685
  const syncStartedAtMs = Date.now();
138579
138686
  await handle.syncOnce();
138580
138687
  const syncMs = Date.now() - syncStartedAtMs;
138688
+ if (state2.persistAllChangesDiffStats && state2.allChangesDiffStats) {
138689
+ try {
138690
+ await this.persistCodeCollabAllChangesDiffStats(state2.ownerSessionId, state2.allChangesDiffStats);
138691
+ } catch (error2) {
138692
+ this.logger.debug(`[code-collab-v2] Failed to persist All Changes diffStats ownerSessionId=${state2.ownerSessionId}: ${formatErrorMessage(error2)}`);
138693
+ }
138694
+ }
138581
138695
  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
138696
  }
138583
138697
  });
@@ -139287,21 +139401,21 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
139287
139401
  this.logger.debug(`[${args2.sessionId}] Codex inline image uploaded (callId=${args2.callId} historyEntryId=${historyEntryId})`);
139288
139402
  }
139289
139403
  resolveCodexGeneratedImagePath(sessionId, savedPath) {
139290
- const trimmed = savedPath?.trim();
139291
- if (!trimmed) {
139404
+ const trimmed2 = savedPath?.trim();
139405
+ if (!trimmed2) {
139292
139406
  return null;
139293
139407
  }
139294
- if (path__default.isAbsolute(trimmed)) {
139295
- return trimmed;
139408
+ if (path__default.isAbsolute(trimmed2)) {
139409
+ return trimmed2;
139296
139410
  }
139297
139411
  try {
139298
139412
  const hostWorkdir = this.sessionManager.getSession(sessionId)?.getHostWorkdir();
139299
139413
  if (!hostWorkdir) {
139300
139414
  return null;
139301
139415
  }
139302
- return path__default.resolve(hostWorkdir, trimmed);
139416
+ return path__default.resolve(hostWorkdir, trimmed2);
139303
139417
  } catch (error2) {
139304
- this.logger.debug(`[${sessionId}] Failed to resolve Codex generated image path ${trimmed}: ${formatErrorMessage(error2)}`);
139418
+ this.logger.debug(`[${sessionId}] Failed to resolve Codex generated image path ${trimmed2}: ${formatErrorMessage(error2)}`);
139305
139419
  return null;
139306
139420
  }
139307
139421
  }
@@ -139638,11 +139752,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
139638
139752
  return serverUrl.endsWith("/") ? serverUrl.slice(0, -1) : serverUrl;
139639
139753
  }
139640
139754
  async validateSessionImageUploadPath(filePath) {
139641
- const trimmed = filePath.trim();
139642
- if (!trimmed) {
139755
+ const trimmed2 = filePath.trim();
139756
+ if (!trimmed2) {
139643
139757
  throw new Error("Image path is empty");
139644
139758
  }
139645
- const absolutePath = path__default.resolve(trimmed);
139759
+ const absolutePath = path__default.resolve(trimmed2);
139646
139760
  let handle;
139647
139761
  try {
139648
139762
  handle = await fs__default.promises.open(absolutePath, fs__default.constants.O_RDONLY | fs__default.constants.O_NOFOLLOW);
@@ -140199,9 +140313,9 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140199
140313
  const visualAnnotationRefTexts = [];
140200
140314
  for (const block of args2.inputBlocks) {
140201
140315
  if (block.type === "text") {
140202
- const trimmed = block.text.trim();
140203
- if (trimmed) {
140204
- textParts.push(trimmed);
140316
+ const trimmed2 = block.text.trim();
140317
+ if (trimmed2) {
140318
+ textParts.push(trimmed2);
140205
140319
  }
140206
140320
  continue;
140207
140321
  }
@@ -140942,14 +141056,14 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140942
141056
  ...getMachineFlockLocalProjects(options.machineFlockRows ?? {})
140943
141057
  };
140944
141058
  const requestRecord = this.toDeleteRequestRecord(options.request);
140945
- const trimmed = (value) => {
141059
+ const trimmed2 = (value) => {
140946
141060
  const v = value?.trim();
140947
141061
  return v ? v : void 0;
140948
141062
  };
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);
141063
+ const branchName = trimmed2(requestRecord.branchName) ?? trimmed2(sessionMeta?.branchName);
141064
+ const baseBranchName = trimmed2(requestRecord.baseBranchName) ?? trimmed2(sessionMeta?.baseBranch);
141065
+ const requestLocalProjectId = trimmed2(requestRecord.localProjectId);
141066
+ const requestOriginalRootPath = trimmed2(requestRecord.originalRootPath);
140953
141067
  const requestHasLocalTarget = requestLocalProjectId !== void 0 || requestOriginalRootPath !== void 0;
140954
141068
  const isLocalWorktree = sessionMeta?.project?.kind === "local" ? sessionMeta.isWorktree === true || requestRecord.isWorktree === true : requestHasLocalTarget && requestRecord.isWorktree === true;
140955
141069
  if (isLocalWorktree) {
@@ -140972,7 +141086,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
140972
141086
  } : {}
140973
141087
  };
140974
141088
  }
140975
- const repoFullName = sessionMeta?.project?.kind === "local" ? void 0 : trimmed(requestRecord.repoFullName) ?? trimmed(sessionMeta?.repoFullName);
141089
+ const repoFullName = sessionMeta?.project?.kind === "local" ? void 0 : trimmed2(requestRecord.repoFullName) ?? trimmed2(sessionMeta?.repoFullName);
140976
141090
  if (!repoFullName) {
140977
141091
  return null;
140978
141092
  }
@@ -142200,6 +142314,27 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
142200
142314
  }
142201
142315
  return metaRecord.meta;
142202
142316
  }
142317
+ async persistCodeCollabAllChangesDiffStats(ownerSessionId, diffStats) {
142318
+ const ownerRoomId = getSessionRoomId(ownerSessionId);
142319
+ const metaRecord = await this.workspaceDocument.repo.getDocMeta(ownerRoomId);
142320
+ if (!metaRecord?.meta || isLoroRepoDocDeleted(metaRecord)) {
142321
+ return;
142322
+ }
142323
+ const ownerMeta = readDiffStatsMetadata(metaRecord.meta);
142324
+ const target = resolveDiffStatsTarget({
142325
+ ownerRoomId,
142326
+ ownerMeta
142327
+ });
142328
+ const patch2 = resolveCodeCollabAllChangesDiffStatsPatch({
142329
+ target,
142330
+ ownerMeta,
142331
+ diffStats
142332
+ });
142333
+ if (!patch2) {
142334
+ return;
142335
+ }
142336
+ await this.workspaceDocument.repo.upsertDocMeta(ownerRoomId, patch2);
142337
+ }
142203
142338
  canWriteCodeCollabOwnerSession(args2) {
142204
142339
  const requester = args2.requestedByUserId?.trim();
142205
142340
  if (!requester) {
@@ -142583,11 +142718,11 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
142583
142718
  });
142584
142719
  }
142585
142720
  async validateSessionFileUploadPath(filePath, options) {
142586
- const trimmed = filePath.trim();
142587
- if (!trimmed) {
142721
+ const trimmed2 = filePath.trim();
142722
+ if (!trimmed2) {
142588
142723
  throw new Error("File path is empty");
142589
142724
  }
142590
- const absolutePath = options?.containWithin ? await resolveContainedUploadPath(trimmed, options.containWithin) : path__default.resolve(trimmed);
142725
+ const absolutePath = options?.containWithin ? await resolveContainedUploadPath(trimmed2, options.containWithin) : path__default.resolve(trimmed2);
142591
142726
  let handle;
142592
142727
  try {
142593
142728
  handle = await fs__default.promises.open(absolutePath, fs__default.constants.O_RDONLY | fs__default.constants.O_NOFOLLOW);
@@ -152117,12 +152252,12 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152117
152252
  const DEFAULT_AI_GIT_AUTHOR_NAME = "LodyAI";
152118
152253
  const DEFAULT_AI_GIT_AUTHOR_EMAIL = "agent@lody.ai";
152119
152254
  const trimNonEmpty = (value) => {
152120
- const trimmed = value?.trim();
152121
- return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
152255
+ const trimmed2 = value?.trim();
152256
+ return trimmed2 !== void 0 && trimmed2.length > 0 ? trimmed2 : void 0;
152122
152257
  };
152123
152258
  const isUsableEmail = (email) => {
152124
- const trimmed = trimNonEmpty(email);
152125
- return trimmed !== void 0 && !isMissingEmail(trimmed);
152259
+ const trimmed2 = trimNonEmpty(email);
152260
+ return trimmed2 !== void 0 && !isMissingEmail(trimmed2);
152126
152261
  };
152127
152262
  const normalizeName = (name2, email) => {
152128
152263
  if (name2 !== void 0 && !isMissingEmail(name2)) {
@@ -152390,7 +152525,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152390
152525
  const serializedArgs = args2.map((arg) => `'${arg.replace(/'/g, `'"'"'`)}'`).join(" ");
152391
152526
  return `${command2} ${serializedArgs}`;
152392
152527
  }
152393
- buildShellEnv(extraEnv) {
152528
+ buildShellEnv(extraEnv, loginShellEnv = getCachedLoginShellEnvSync()) {
152394
152529
  const configEnv = this.config.env ?? {};
152395
152530
  const workspaceSessionId = this.config.parentSessionId ?? this.sessionId;
152396
152531
  const merged = {
@@ -152404,15 +152539,16 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
152404
152539
  LODY_SESSION_ID: this.sessionId,
152405
152540
  LODY_WORKSPACE_SESSION_ID: workspaceSessionId
152406
152541
  };
152407
- const withLoginShell = mergeLoginShellEnv(merged, getCachedLoginShellEnvSync());
152542
+ const withLoginShell = mergeLoginShellEnv(merged, loginShellEnv);
152408
152543
  const agentEnv = shouldScrubClaudeAuthEnv(this.config.agentCliType, this.config.agentType) ? scrubInheritedClaudeAuthEnv(withLoginShell, {
152409
152544
  ...configEnv,
152410
152545
  ...extraEnv
152411
152546
  }) : withLoginShell;
152412
- return withDefaultAcpPathEntries(agentEnv);
152547
+ return withDefaultAcpPathEntries(agentEnv, this.config.agentType);
152413
152548
  }
152414
152549
  async createAgent(callbacks) {
152415
- const env2 = withLodyNpmCacheForNpx(callbacks.command, this.buildShellEnv(callbacks.env));
152550
+ const loginShellEnv = await getLoginShellEnv();
152551
+ const env2 = withLodyNpmCacheForNpx(callbacks.command, this.buildShellEnv(callbacks.env, loginShellEnv));
152416
152552
  const launcher = resolveAcpLauncher(callbacks.command);
152417
152553
  const spawnAnalyticsProps = {
152418
152554
  cliType: callbacks.cliType,
@@ -182945,8 +183081,8 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
182945
183081
  console.log(JSON.stringify(value));
182946
183082
  }
182947
183083
  function normalizeCliValue(value) {
182948
- const trimmed = value?.trim();
182949
- return trimmed || void 0;
183084
+ const trimmed2 = value?.trim();
183085
+ return trimmed2 || void 0;
182950
183086
  }
182951
183087
  function formatWorkspaceCandidates(workspaces) {
182952
183088
  return workspaces.map((workspace) => {
@@ -188478,11 +188614,11 @@ ${entry.text}`).join("\n\n");
188478
188614
  });
188479
188615
  }));
188480
188616
  function encodeExportPathSegment(value, fallback2) {
188481
- const trimmed = value.trim();
188482
- if (!trimmed) {
188617
+ const trimmed2 = value.trim();
188618
+ if (!trimmed2) {
188483
188619
  return fallback2;
188484
188620
  }
188485
- const encoded = encodeURIComponent(trimmed);
188621
+ const encoded = encodeURIComponent(trimmed2);
188486
188622
  return encoded || fallback2;
188487
188623
  }
188488
188624
  function ensurePathWithinBase(baseDir, candidatePath) {
@@ -188508,8 +188644,8 @@ ${entry.text}`).join("\n\n");
188508
188644
  "image/gif": ".gif"
188509
188645
  };
188510
188646
  function normalizeString(value) {
188511
- const trimmed = value?.trim();
188512
- return trimmed || null;
188647
+ const trimmed2 = value?.trim();
188648
+ return trimmed2 || null;
188513
188649
  }
188514
188650
  function cloneItems(items2) {
188515
188651
  if (!Array.isArray(items2)) {
@@ -188662,11 +188798,11 @@ ${entry.text}`).join("\n\n");
188662
188798
  "image/gif": ".gif"
188663
188799
  };
188664
188800
  function sanitizeFileStem(value) {
188665
- const trimmed = value.trim();
188666
- if (!trimmed) {
188801
+ const trimmed2 = value.trim();
188802
+ if (!trimmed2) {
188667
188803
  return "image";
188668
188804
  }
188669
- return trimmed.replace(/[^A-Za-z0-9._-]/g, "_");
188805
+ return trimmed2.replace(/[^A-Za-z0-9._-]/g, "_");
188670
188806
  }
188671
188807
  function resolveOutputPath(baseDir, attachment) {
188672
188808
  const currentRelativePath = attachment.relativePath;
@@ -189232,7 +189368,7 @@ ${entry.text}`).join("\n\n");
189232
189368
  data = createReviewBundleSnapshot(bundle);
189233
189369
  }
189234
189370
  const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
189235
- const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-DYasOJ94.js");
189371
+ const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-BHFYVB1-.js");
189236
189372
  const template = await resolveReviewViewerTemplate();
189237
189373
  const html = injectReviewSnapshot(template, data);
189238
189374
  const outputPath = options.output ? path__default$1.resolve(options.output) : defaultHtmlOutputPath(inputPath);
@@ -206949,8 +207085,8 @@ ${result.stderr}`;
206949
207085
  const postImageUpload = async (request2, localControlPort) => pickResponse(await postSessionControl(request2, localControlPort), "session/image-upload_response", "an image upload response");
206950
207086
  const postFileUpload = async (request2, localControlPort) => pickResponse(await postSessionControl(request2, localControlPort, FILE_UPLOAD_TIMEOUT_MS), "session/file-upload_response", "a file upload response");
206951
207087
  const resolveUploadPath = (filePath, workdir) => {
206952
- const trimmed = filePath.trim();
206953
- return path__default.isAbsolute(trimmed) ? trimmed : path__default.resolve(workdir, trimmed);
207088
+ const trimmed2 = filePath.trim();
207089
+ return path__default.isAbsolute(trimmed2) ? trimmed2 : path__default.resolve(workdir, trimmed2);
206954
207090
  };
206955
207091
  async function runLodyMcpServer() {
206956
207092
  const server = new McpServer({