@letta-ai/letta-code 0.24.8 → 0.24.10

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.
Files changed (2) hide show
  1. package/letta.js +895 -385
  2. package/package.json +2 -1
package/letta.js CHANGED
@@ -3269,7 +3269,7 @@ var package_default;
3269
3269
  var init_package = __esm(() => {
3270
3270
  package_default = {
3271
3271
  name: "@letta-ai/letta-code",
3272
- version: "0.24.8",
3272
+ version: "0.24.10",
3273
3273
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
3274
3274
  type: "module",
3275
3275
  bin: {
@@ -3310,6 +3310,7 @@ var init_package = __esm(() => {
3310
3310
  "node-pty": "^1.1.0",
3311
3311
  open: "^10.2.0",
3312
3312
  sharp: "^0.34.5",
3313
+ "strip-ansi": "^7.2.0",
3313
3314
  ws: "^8.19.0"
3314
3315
  },
3315
3316
  optionalDependencies: {
@@ -4905,6 +4906,7 @@ function getClientDefaultHeaders() {
4905
4906
  return {
4906
4907
  "X-Letta-Source": "letta-code",
4907
4908
  "User-Agent": `letta-code/${package_default.version}`,
4909
+ "X-Letta-Environment-Device-Id": settingsManager.getOrCreateDeviceId(),
4908
4910
  ...nodeExperiment.source === "override" ? { "x-letta-node": nodeExperiment.enabled ? "1" : "0" } : nodeExperiment.enabled ? { "x-letta-node": "1" } : {}
4909
4911
  };
4910
4912
  }
@@ -4966,7 +4968,7 @@ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, a
4966
4968
  console.error(new Error("getClient() called without credentials").stack);
4967
4969
  throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
4968
4970
  }
4969
- return new Letta({
4971
+ const client = new Letta({
4970
4972
  apiKey,
4971
4973
  baseURL,
4972
4974
  logger: sdkLogger,
@@ -4974,6 +4976,28 @@ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, a
4974
4976
  defaultHeaders: getClientDefaultHeaders(),
4975
4977
  ...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
4976
4978
  });
4979
+ const MESSAGE_CACHE_MAX = 32;
4980
+ const messageCache = new Map;
4981
+ const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
4982
+ client.messages.retrieve = (...args) => {
4983
+ const messageId = args[0];
4984
+ const cached = messageCache.get(messageId);
4985
+ if (cached) {
4986
+ messageCache.delete(messageId);
4987
+ messageCache.set(messageId, cached);
4988
+ return cached;
4989
+ }
4990
+ const promise = origRetrieveMessage(...args);
4991
+ messageCache.set(messageId, promise);
4992
+ if (messageCache.size > MESSAGE_CACHE_MAX) {
4993
+ const oldest = messageCache.keys().next().value;
4994
+ if (oldest !== undefined)
4995
+ messageCache.delete(oldest);
4996
+ }
4997
+ promise.catch(() => messageCache.delete(messageId));
4998
+ return promise;
4999
+ };
5000
+ return client;
4977
5001
  }
4978
5002
  var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, LETTA_MEMFS_GIT_PROXY_BASE_URL_ENV = "LETTA_MEMFS_GIT_PROXY_BASE_URL";
4979
5003
  var init_client2 = __esm(() => {
@@ -9488,46 +9512,6 @@ var init_models2 = __esm(() => {
9488
9512
  parallel_tool_calls: true
9489
9513
  }
9490
9514
  },
9491
- {
9492
- id: "gpt-5.5-pro-medium",
9493
- handle: "openai/gpt-5.5-pro",
9494
- label: "GPT-5.5 Pro",
9495
- description: "GPT-5.5 Pro — max performance variant (med reasoning)",
9496
- updateArgs: {
9497
- reasoning_effort: "medium",
9498
- verbosity: "medium",
9499
- context_window: 272000,
9500
- max_output_tokens: 128000,
9501
- parallel_tool_calls: true
9502
- }
9503
- },
9504
- {
9505
- id: "gpt-5.5-pro-high",
9506
- handle: "openai/gpt-5.5-pro",
9507
- label: "GPT-5.5 Pro",
9508
- description: "GPT-5.5 Pro — max performance variant (high reasoning)",
9509
- updateArgs: {
9510
- reasoning_effort: "high",
9511
- verbosity: "medium",
9512
- context_window: 272000,
9513
- max_output_tokens: 128000,
9514
- parallel_tool_calls: true
9515
- },
9516
- isFeatured: true
9517
- },
9518
- {
9519
- id: "gpt-5.5-pro-xhigh",
9520
- handle: "openai/gpt-5.5-pro",
9521
- label: "GPT-5.5 Pro",
9522
- description: "GPT-5.5 Pro — max performance variant (max reasoning)",
9523
- updateArgs: {
9524
- reasoning_effort: "xhigh",
9525
- verbosity: "medium",
9526
- context_window: 272000,
9527
- max_output_tokens: 128000,
9528
- parallel_tool_calls: true
9529
- }
9530
- },
9531
9515
  {
9532
9516
  id: "gpt-5.4-pro-medium",
9533
9517
  handle: "openai/gpt-5.4-pro",
@@ -29854,7 +29838,7 @@ function ansiRegex({ onlyFirst = false } = {}) {
29854
29838
  return new RegExp(pattern, onlyFirst ? undefined : "g");
29855
29839
  }
29856
29840
 
29857
- // node_modules/strip-ansi/index.js
29841
+ // node_modules/string-width/node_modules/strip-ansi/index.js
29858
29842
  function stripAnsi(string) {
29859
29843
  if (typeof string !== "string") {
29860
29844
  throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
@@ -29994,6 +29978,18 @@ var init_measure_text = __esm(() => {
29994
29978
  measure_text_default = measureText;
29995
29979
  });
29996
29980
 
29981
+ // node_modules/wrap-ansi/node_modules/strip-ansi/index.js
29982
+ function stripAnsi2(string) {
29983
+ if (typeof string !== "string") {
29984
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
29985
+ }
29986
+ return string.replace(regex2, "");
29987
+ }
29988
+ var regex2;
29989
+ var init_strip_ansi2 = __esm(() => {
29990
+ regex2 = ansiRegex();
29991
+ });
29992
+
29997
29993
  // node_modules/ansi-styles/index.js
29998
29994
  function assembleStyles() {
29999
29995
  const codes = new Map;
@@ -30182,7 +30178,7 @@ var ESCAPES, END_CODE = 39, ANSI_ESCAPE_BELL = "\x07", ANSI_CSI = "[", ANSI_OSC
30182
30178
  const characters = [...word];
30183
30179
  let isInsideEscape = false;
30184
30180
  let isInsideLinkEscape = false;
30185
- let visible = stringWidth(stripAnsi(rows.at(-1)));
30181
+ let visible = stringWidth(stripAnsi2(rows.at(-1)));
30186
30182
  for (const [index, character] of characters.entries()) {
30187
30183
  const characterLength = stringWidth(character);
30188
30184
  if (visible + characterLength <= columns) {
@@ -30318,7 +30314,7 @@ var ESCAPES, END_CODE = 39, ANSI_ESCAPE_BELL = "\x07", ANSI_CSI = "[", ANSI_OSC
30318
30314
  };
30319
30315
  var init_wrap_ansi = __esm(() => {
30320
30316
  init_string_width();
30321
- init_strip_ansi();
30317
+ init_strip_ansi2();
30322
30318
  init_ansi_styles();
30323
30319
  ESCAPES = new Set([
30324
30320
  "\x1B",
@@ -31123,8 +31119,8 @@ function indentString(string, count = 1, options = {}) {
31123
31119
  if (count === 0) {
31124
31120
  return string;
31125
31121
  }
31126
- const regex2 = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
31127
- return string.replace(regex2, indent.repeat(count));
31122
+ const regex3 = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
31123
+ return string.replace(regex3, indent.repeat(count));
31128
31124
  }
31129
31125
 
31130
31126
  // node_modules/ink/build/get-max-width.js
@@ -37401,17 +37397,17 @@ var require_picomatch = __commonJS((exports, module) => {
37401
37397
  }
37402
37398
  const opts = options || {};
37403
37399
  const posix = utils.isWindows(options);
37404
- const regex2 = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
37405
- const state = regex2.state;
37406
- delete regex2.state;
37400
+ const regex3 = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
37401
+ const state = regex3.state;
37402
+ delete regex3.state;
37407
37403
  let isIgnored = () => false;
37408
37404
  if (opts.ignore) {
37409
37405
  const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
37410
37406
  isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
37411
37407
  }
37412
37408
  const matcher = (input, returnObject = false) => {
37413
- const { isMatch, match, output } = picomatch.test(input, regex2, options, { glob, posix });
37414
- const result = { glob, state, regex: regex2, posix, input, output, match, isMatch };
37409
+ const { isMatch, match, output } = picomatch.test(input, regex3, options, { glob, posix });
37410
+ const result = { glob, state, regex: regex3, posix, input, output, match, isMatch };
37415
37411
  if (typeof opts.onResult === "function") {
37416
37412
  opts.onResult(result);
37417
37413
  }
@@ -37436,7 +37432,7 @@ var require_picomatch = __commonJS((exports, module) => {
37436
37432
  }
37437
37433
  return matcher;
37438
37434
  };
37439
- picomatch.test = (input, regex2, options, { glob, posix } = {}) => {
37435
+ picomatch.test = (input, regex3, options, { glob, posix } = {}) => {
37440
37436
  if (typeof input !== "string") {
37441
37437
  throw new TypeError("Expected input to be a string");
37442
37438
  }
@@ -37453,16 +37449,16 @@ var require_picomatch = __commonJS((exports, module) => {
37453
37449
  }
37454
37450
  if (match === false || opts.capture === true) {
37455
37451
  if (opts.matchBase === true || opts.basename === true) {
37456
- match = picomatch.matchBase(input, regex2, options, posix);
37452
+ match = picomatch.matchBase(input, regex3, options, posix);
37457
37453
  } else {
37458
- match = regex2.exec(output);
37454
+ match = regex3.exec(output);
37459
37455
  }
37460
37456
  }
37461
37457
  return { isMatch: Boolean(match), match, output };
37462
37458
  };
37463
37459
  picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
37464
- const regex2 = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
37465
- return regex2.test(path2.basename(input));
37460
+ const regex3 = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
37461
+ return regex3.test(path2.basename(input));
37466
37462
  };
37467
37463
  picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
37468
37464
  picomatch.parse = (pattern, options) => {
@@ -37482,11 +37478,11 @@ var require_picomatch = __commonJS((exports, module) => {
37482
37478
  if (state && state.negated === true) {
37483
37479
  source = `^(?!${source}).*$`;
37484
37480
  }
37485
- const regex2 = picomatch.toRegex(source, options);
37481
+ const regex3 = picomatch.toRegex(source, options);
37486
37482
  if (returnState === true) {
37487
- regex2.state = state;
37483
+ regex3.state = state;
37488
37484
  }
37489
- return regex2;
37485
+ return regex3;
37490
37486
  };
37491
37487
  picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
37492
37488
  if (!input || typeof input !== "string") {
@@ -39321,7 +39317,13 @@ async function cloneMemoryRepo(agentId) {
39321
39317
  operation: "clone memory repo (tmp migration)"
39322
39318
  });
39323
39319
  renameSync(join7(tmpDir, ".git"), join7(dir, ".git"));
39324
- await runGit(dir, ["checkout", "--", "."], token);
39320
+ try {
39321
+ await runGit(dir, ["rev-parse", "--verify", "HEAD"], token);
39322
+ await runGit(dir, ["checkout", "--", "."], token);
39323
+ } catch (checkoutErr) {
39324
+ const msg = checkoutErr instanceof Error ? checkoutErr.message : String(checkoutErr);
39325
+ debugLog("memfs-git", `Skipping checkout (likely empty remote, no HEAD yet): ${msg}`);
39326
+ }
39325
39327
  debugLog("memfs-git", "Migrated existing memory directory to git repo");
39326
39328
  } finally {
39327
39329
  if (existsSync8(tmpDir)) {
@@ -40145,12 +40147,14 @@ var init_config = __esm(() => {
40145
40147
  };
40146
40148
  discordConfigCodec = {
40147
40149
  parse(parsed) {
40150
+ const rawAllowedChannels = parsed.allowed_channels;
40148
40151
  return {
40149
40152
  channel: "discord",
40150
40153
  enabled: parsed.enabled !== false,
40151
40154
  token: String(parsed.token ?? ""),
40152
40155
  dmPolicy: parsed.dm_policy ?? "pairing",
40153
- allowedUsers: parsed.allowed_users ?? []
40156
+ allowedUsers: parsed.allowed_users ?? [],
40157
+ allowedChannels: Array.isArray(rawAllowedChannels) ? rawAllowedChannels : undefined
40154
40158
  };
40155
40159
  }
40156
40160
  };
@@ -40183,6 +40187,11 @@ function cloneAccount(account) {
40183
40187
  if (account.channel === "telegram") {
40184
40188
  cloned.binding = { ...account.binding };
40185
40189
  }
40190
+ if (account.channel === "discord" && account.allowedChannels) {
40191
+ cloned.allowedChannels = [
40192
+ ...account.allowedChannels
40193
+ ];
40194
+ }
40186
40195
  return cloned;
40187
40196
  }
40188
40197
  function normalizeLoadedAccount(account) {
@@ -40226,6 +40235,7 @@ function makeDefaultLegacyAccount(channelId) {
40226
40235
  token: config.token,
40227
40236
  dmPolicy: config.dmPolicy,
40228
40237
  allowedUsers: [...config.allowedUsers],
40238
+ allowedChannels: config.allowedChannels ? [...config.allowedChannels] : undefined,
40229
40239
  agentId: null,
40230
40240
  createdAt: now,
40231
40241
  updatedAt: now
@@ -44112,6 +44122,16 @@ var init_plugin2 = __esm(() => {
44112
44122
  };
44113
44123
  });
44114
44124
 
44125
+ // src/channels/discord/channelGating.ts
44126
+ function isDiscordGuildChannelAllowed(params) {
44127
+ const { channelId, parentChannelId, isThread, allowedChannels } = params;
44128
+ if (!allowedChannels || allowedChannels.length === 0) {
44129
+ return true;
44130
+ }
44131
+ const gateChannelId = isThread ? parentChannelId ?? channelId : channelId;
44132
+ return allowedChannels.includes(gateChannelId);
44133
+ }
44134
+
44115
44135
  // src/channels/discord/media.ts
44116
44136
  import { randomUUID as randomUUID6 } from "node:crypto";
44117
44137
  import { mkdirSync as mkdirSync11 } from "node:fs";
@@ -44594,6 +44614,13 @@ function createDiscordAdapter(config) {
44594
44614
  }
44595
44615
  if (!isThread && !wasMentioned)
44596
44616
  return;
44617
+ if (!isDiscordGuildChannelAllowed({
44618
+ channelId: message.channelId,
44619
+ parentChannelId: message.channel.parentId ?? null,
44620
+ isThread,
44621
+ allowedChannels: config.allowedChannels
44622
+ }))
44623
+ return;
44597
44624
  if (markIngressMessageSeen(message.channelId, message.id))
44598
44625
  return;
44599
44626
  let effectiveChatId = message.channelId;
@@ -44657,6 +44684,13 @@ function createDiscordAdapter(config) {
44657
44684
  const isThread = msg.channel && "isThread" in msg.channel && typeof msg.channel.isThread === "function" && msg.channel.isThread();
44658
44685
  if (chatType === "channel" && !isThread)
44659
44686
  return;
44687
+ if (chatType === "channel" && isThread && !isDiscordGuildChannelAllowed({
44688
+ channelId,
44689
+ parentChannelId: msg.channel.parentId ?? null,
44690
+ isThread: true,
44691
+ allowedChannels: config.allowedChannels
44692
+ }))
44693
+ return;
44660
44694
  const inbound = {
44661
44695
  channel: "discord",
44662
44696
  accountId: config.accountId,
@@ -44973,12 +45007,12 @@ Bind to agent ${envAgentId}? [Y/n]: `);
44973
45007
  }
44974
45008
  if (!agentId) {
44975
45009
  const agentInput = await rl.question(`
44976
- Agent ID to bind this bot to (required for @mention routing): `);
45010
+ Agent ID to bind this bot to (required for DM and @mention routing): `);
44977
45011
  agentId = agentInput.trim() || null;
44978
45012
  }
44979
45013
  if (!agentId) {
44980
45014
  console.log(`
44981
- Warning: No agent bound. DM pairing will still work, but guild @mentions won't route until you bind an agent.`);
45015
+ Warning: No agent bound. DM pairing will still work, but open/allowlist DMs and guild @mentions won't route until you bind an agent.`);
44982
45016
  console.log(" You can bind later: letta channels bind --channel discord --agent <id>");
44983
45017
  console.log(` Or set agentId in ~/.letta/channels/discord/accounts.json
44984
45018
  `);
@@ -45829,6 +45863,17 @@ function buildSlackConversationSummary(msg) {
45829
45863
  }
45830
45864
  return `[Slack] Thread${channelLabel || ` ${msg.chatId}`}`;
45831
45865
  }
45866
+ function buildDiscordConversationSummary(msg) {
45867
+ if (msg.chatType === "direct") {
45868
+ return `[Discord] DM with ${msg.senderName?.trim() || msg.senderId}`;
45869
+ }
45870
+ const preview = truncateChannelSummaryPreview(msg.text);
45871
+ const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
45872
+ if (preview) {
45873
+ return `[Discord] Thread${channelLabel}: ${preview}`;
45874
+ }
45875
+ return `[Discord] Thread${channelLabel || ` ${msg.chatId}`}`;
45876
+ }
45832
45877
  function buildChannelTurnSource(route, msg) {
45833
45878
  return {
45834
45879
  channel: msg.channel,
@@ -46212,7 +46257,7 @@ class ChannelRegistry {
46212
46257
  });
46213
46258
  return;
46214
46259
  }
46215
- if (msg.channel === "discord" && config.channel === "discord" && msg.chatType === "channel") {
46260
+ if (msg.channel === "discord" && config.channel === "discord" && (msg.chatType === "channel" || config.dmPolicy !== "pairing")) {
46216
46261
  const discordResult = await this.ensureDiscordRoute(adapter, msg, config);
46217
46262
  if (!discordResult) {
46218
46263
  return;
@@ -46361,7 +46406,7 @@ class ChannelRegistry {
46361
46406
  if (!config.agentId) {
46362
46407
  throw new Error("Discord bot is missing an agent binding.");
46363
46408
  }
46364
- const conversationId = await this.createConversationForAgent(config.agentId, `[Discord] Thread ${msg.chatLabel ?? msg.chatId}`);
46409
+ const conversationId = await this.createConversationForAgent(config.agentId, buildDiscordConversationSummary(msg));
46365
46410
  const now = new Date().toISOString();
46366
46411
  const route = {
46367
46412
  accountId: config.accountId,
@@ -46384,6 +46429,10 @@ class ChannelRegistry {
46384
46429
  ` + "Open Channels > Discord in Letta Code, choose which agent this bot should represent, and try again.");
46385
46430
  return null;
46386
46431
  }
46432
+ if (msg.chatType === "direct" && config.dmPolicy === "allowlist" && !config.allowedUsers.includes(msg.senderId)) {
46433
+ await adapter.sendDirectReply(msg.chatId, "You are not on the allowed users list for this Discord bot.");
46434
+ return null;
46435
+ }
46387
46436
  const accountId = msg.accountId ?? LEGACY_CHANNEL_ACCOUNT_ID;
46388
46437
  const routeThreadId = msg.threadId ?? null;
46389
46438
  let route = getRoute(msg.channel, msg.chatId, accountId, routeThreadId);
@@ -46394,7 +46443,7 @@ class ChannelRegistry {
46394
46443
  if (route) {
46395
46444
  return { route, isFirstRouteTurn: false };
46396
46445
  }
46397
- if (!msg.isMention) {
46446
+ if (msg.chatType === "channel" && !msg.isMention) {
46398
46447
  return null;
46399
46448
  }
46400
46449
  return {
@@ -46494,6 +46543,21 @@ var init_registry = __esm(() => {
46494
46543
  init_xml();
46495
46544
  });
46496
46545
 
46546
+ // node_modules/strip-ansi/index.js
46547
+ function stripAnsi3(string) {
46548
+ if (typeof string !== "string") {
46549
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
46550
+ }
46551
+ if (!string.includes("\x1B") && !string.includes("›")) {
46552
+ return string;
46553
+ }
46554
+ return string.replace(regex3, "");
46555
+ }
46556
+ var regex3;
46557
+ var init_strip_ansi3 = __esm(() => {
46558
+ regex3 = ansiRegex();
46559
+ });
46560
+
46497
46561
  // src/agent/approval-execution.ts
46498
46562
  var exports_approval_execution = {};
46499
46563
  __export(exports_approval_execution, {
@@ -47534,6 +47598,9 @@ var init_session = __esm(() => {
47534
47598
  });
47535
47599
 
47536
47600
  // src/tools/impl/shellLaunchers.ts
47601
+ function isValidEnvAlias(name) {
47602
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
47603
+ }
47537
47604
  function pushUnique(list, seen, entry) {
47538
47605
  if (!entry.length || !entry[0])
47539
47606
  return;
@@ -47550,18 +47617,21 @@ function normalizePowerShellCommand(command) {
47550
47617
  }
47551
47618
  return trimmed;
47552
47619
  }
47553
- function buildPowerShellCommand(command) {
47620
+ function buildPowerShellCommand(command, envAliases = []) {
47554
47621
  const powerShellCommand = normalizePowerShellCommand(command);
47555
- const aliasPrelude = POWERSHELL_ENV_ALIASES.map((name) => `$${name} = $env:${name}`).join("; ");
47622
+ const aliases = [
47623
+ ...new Set([...POWERSHELL_ENV_ALIASES, ...envAliases])
47624
+ ].filter(isValidEnvAlias);
47625
+ const aliasPrelude = aliases.map((name) => `$${name} = $env:${name}`).join("; ");
47556
47626
  return `${aliasPrelude}; ${powerShellCommand}`;
47557
47627
  }
47558
- function windowsLaunchers(command) {
47628
+ function windowsLaunchers(command, envAliases = []) {
47559
47629
  const trimmed = command.trim();
47560
47630
  if (!trimmed)
47561
47631
  return [];
47562
47632
  const launchers = [];
47563
47633
  const seen = new Set;
47564
- const powerShellCommand = buildPowerShellCommand(trimmed);
47634
+ const powerShellCommand = buildPowerShellCommand(trimmed, envAliases);
47565
47635
  pushUnique(launchers, seen, [
47566
47636
  "powershell.exe",
47567
47637
  "-NoProfile",
@@ -47641,7 +47711,7 @@ function unixLaunchers(command, login) {
47641
47711
  }
47642
47712
  function buildShellLaunchers(command, options) {
47643
47713
  const login = options?.login ?? false;
47644
- return process.platform === "win32" ? windowsLaunchers(command) : unixLaunchers(command, login);
47714
+ return process.platform === "win32" ? windowsLaunchers(command, options?.powershellEnvAliases) : unixLaunchers(command, login);
47645
47715
  }
47646
47716
  var SEP2 = "\x00", POWERSHELL_ENV_ALIASES;
47647
47717
  var init_shellLaunchers = __esm(() => {
@@ -48207,8 +48277,8 @@ function matchesTool(pattern, toolName) {
48207
48277
  return true;
48208
48278
  }
48209
48279
  try {
48210
- const regex2 = new RegExp(`^(?:${pattern})$`);
48211
- return regex2.test(toolName);
48280
+ const regex4 = new RegExp(`^(?:${pattern})$`);
48281
+ return regex4.test(toolName);
48212
48282
  } catch (error) {
48213
48283
  debugLog("hooks", `matchesTool: Invalid regex pattern "${pattern}", falling back to exact match`, error);
48214
48284
  return pattern === toolName;
@@ -52123,26 +52193,30 @@ var init_mode = __esm(() => {
52123
52193
  });
52124
52194
 
52125
52195
  // src/tools/secret-substitution.ts
52126
- function substituteSecretsInString(input) {
52127
- const secrets2 = loadSecrets();
52128
- return input.replace(SECRET_PATTERN, (match, name) => {
52129
- const value = secrets2[name];
52130
- return value !== undefined ? value : match;
52131
- });
52132
- }
52133
- function substituteSecretsInArgs(args) {
52134
- const result = {};
52135
- for (const [key, value] of Object.entries(args)) {
52136
- if (typeof value === "string") {
52137
- result[key] = substituteSecretsInString(value);
52138
- } else {
52139
- result[key] = value;
52196
+ function extractSecretEnvFromCommand(command, agentId) {
52197
+ const secrets2 = loadSecrets(agentId);
52198
+ const env3 = {};
52199
+ const scan = (text) => {
52200
+ for (const match of text.matchAll(SECRET_PATTERN)) {
52201
+ const name = match[1];
52202
+ if (name !== undefined && secrets2[name] !== undefined) {
52203
+ env3[name] = secrets2[name];
52204
+ }
52205
+ }
52206
+ };
52207
+ if (typeof command === "string") {
52208
+ scan(command);
52209
+ return env3;
52210
+ }
52211
+ for (const part of command) {
52212
+ if (typeof part === "string") {
52213
+ scan(part);
52140
52214
  }
52141
52215
  }
52142
- return result;
52216
+ return env3;
52143
52217
  }
52144
- function scrubSecretsFromString(input) {
52145
- const secrets2 = loadSecrets();
52218
+ function scrubSecretsFromString(input, agentId) {
52219
+ const secrets2 = loadSecrets(agentId);
52146
52220
  let result = input;
52147
52221
  const entries = Object.entries(secrets2).sort(([, a], [, b]) => b.length - a.length);
52148
52222
  for (const [name, value] of entries) {
@@ -55212,40 +55286,45 @@ function validateWorktreePath(command, cwd2) {
55212
55286
  }
55213
55287
  return null;
55214
55288
  }
55215
- function rebuildCachedLauncher(command) {
55289
+ function rebuildCachedLauncher(command, secretEnv) {
55216
55290
  if (!cachedWorkingLauncher)
55217
55291
  return null;
55218
55292
  const cachedExecutable = cachedWorkingLauncher[0]?.toLowerCase();
55219
55293
  if (!cachedExecutable)
55220
55294
  return null;
55221
- const launchers = buildShellLaunchers(command);
55295
+ const launchers = buildShellLaunchers(command, {
55296
+ powershellEnvAliases: secretEnv ? Object.keys(secretEnv) : undefined
55297
+ });
55222
55298
  return launchers.find((launcher) => launcher[0]?.toLowerCase() === cachedExecutable) ?? null;
55223
55299
  }
55224
- function getBackgroundLauncher(command) {
55225
- const cachedLauncher = rebuildCachedLauncher(command);
55300
+ function getBackgroundLauncher(command, secretEnv) {
55301
+ const cachedLauncher = rebuildCachedLauncher(command, secretEnv);
55226
55302
  if (cachedLauncher)
55227
55303
  return cachedLauncher;
55228
- const launchers = buildShellLaunchers(command);
55304
+ const launchers = buildShellLaunchers(command, {
55305
+ powershellEnvAliases: secretEnv ? Object.keys(secretEnv) : undefined
55306
+ });
55229
55307
  return launchers[0] || [];
55230
55308
  }
55231
55309
  async function spawnCommand(command, options) {
55310
+ const env3 = options.secretEnv ? { ...options.env, ...options.secretEnv } : options.env;
55232
55311
  if (process.platform !== "win32") {
55233
55312
  const executable = process.platform === "darwin" ? "/bin/zsh" : "bash";
55234
55313
  return spawnWithLauncher([executable, "-c", command], {
55235
55314
  cwd: options.cwd,
55236
- env: options.env,
55315
+ env: env3,
55237
55316
  timeoutMs: options.timeout,
55238
55317
  signal: options.signal,
55239
55318
  onOutput: options.onOutput
55240
55319
  });
55241
55320
  }
55242
55321
  if (cachedWorkingLauncher) {
55243
- const newLauncher = rebuildCachedLauncher(command);
55322
+ const newLauncher = rebuildCachedLauncher(command, options.secretEnv);
55244
55323
  if (newLauncher) {
55245
55324
  try {
55246
55325
  const result = await spawnWithLauncher(newLauncher, {
55247
55326
  cwd: options.cwd,
55248
- env: options.env,
55327
+ env: env3,
55249
55328
  timeoutMs: options.timeout,
55250
55329
  signal: options.signal,
55251
55330
  onOutput: options.onOutput
@@ -55260,7 +55339,9 @@ async function spawnCommand(command, options) {
55260
55339
  }
55261
55340
  }
55262
55341
  }
55263
- const launchers = buildShellLaunchers(command);
55342
+ const launchers = buildShellLaunchers(command, {
55343
+ powershellEnvAliases: options.secretEnv ? Object.keys(options.secretEnv) : undefined
55344
+ });
55264
55345
  if (launchers.length === 0) {
55265
55346
  throw new Error("No shell launchers available");
55266
55347
  }
@@ -55270,7 +55351,7 @@ async function spawnCommand(command, options) {
55270
55351
  try {
55271
55352
  const result = await spawnWithLauncher(launcher, {
55272
55353
  cwd: options.cwd,
55273
- env: options.env,
55354
+ env: env3,
55274
55355
  timeoutMs: options.timeout,
55275
55356
  signal: options.signal,
55276
55357
  onOutput: options.onOutput
@@ -55299,7 +55380,8 @@ async function bash(args) {
55299
55380
  description: _description,
55300
55381
  run_in_background = false,
55301
55382
  signal,
55302
- onOutput
55383
+ onOutput,
55384
+ secretEnv
55303
55385
  } = args;
55304
55386
  const userCwd = getCurrentWorkingDirectory();
55305
55387
  const worktreeError = validateWorktreePath(command, userCwd);
@@ -55344,7 +55426,7 @@ async function bash(args) {
55344
55426
  }
55345
55427
  const bashId = getNextBashId();
55346
55428
  const outputFile = createBackgroundOutputFile(bashId);
55347
- const launcher = getBackgroundLauncher(command);
55429
+ const launcher = getBackgroundLauncher(command, secretEnv);
55348
55430
  const [executable, ...launcherArgs] = launcher;
55349
55431
  if (!executable) {
55350
55432
  return {
@@ -55355,7 +55437,7 @@ async function bash(args) {
55355
55437
  const childProcess = spawn4(executable, launcherArgs, {
55356
55438
  shell: false,
55357
55439
  cwd: userCwd,
55358
- env: getShellEnv()
55440
+ env: secretEnv ? { ...getShellEnv(), ...secretEnv } : getShellEnv()
55359
55441
  });
55360
55442
  backgroundProcesses.set(bashId, {
55361
55443
  process: childProcess,
@@ -55432,7 +55514,8 @@ Output file: ${outputFile}`
55432
55514
  env: getShellEnv(),
55433
55515
  timeout: effectiveTimeout,
55434
55516
  signal,
55435
- onOutput
55517
+ onOutput,
55518
+ secretEnv
55436
55519
  });
55437
55520
  let output = stdout;
55438
55521
  if (stderr)
@@ -71559,7 +71642,15 @@ async function runProcess(context3) {
71559
71642
  }
71560
71643
  async function shell(args) {
71561
71644
  validateRequiredParams(args, ["command"], "shell");
71562
- const { command, workdir, timeout_ms, env_overrides, signal, onOutput } = args;
71645
+ const {
71646
+ command,
71647
+ workdir,
71648
+ timeout_ms,
71649
+ env_overrides,
71650
+ secretEnv,
71651
+ signal,
71652
+ onOutput
71653
+ } = args;
71563
71654
  if (!Array.isArray(command) || command.length === 0) {
71564
71655
  throw new Error("command must be a non-empty array of strings");
71565
71656
  }
@@ -71570,7 +71661,8 @@ async function shell(args) {
71570
71661
  cwd: cwd2,
71571
71662
  env: {
71572
71663
  ...getShellEnv(),
71573
- ...env_overrides ?? {}
71664
+ ...env_overrides ?? {},
71665
+ ...secretEnv ?? {}
71574
71666
  },
71575
71667
  timeout,
71576
71668
  signal,
@@ -71702,11 +71794,18 @@ async function shell_command(args) {
71702
71794
  timeout_ms,
71703
71795
  justification,
71704
71796
  signal,
71705
- onOutput
71797
+ onOutput,
71798
+ secretEnv
71706
71799
  } = args;
71707
- const envOverrides = getMemoryGitIdentityEnvOverrides(command, workdir);
71800
+ const envOverrides = {
71801
+ ...getMemoryGitIdentityEnvOverrides(command, workdir),
71802
+ ...secretEnv ?? {}
71803
+ };
71708
71804
  const resolvedWorkdir = resolveShellWorkdir(workdir);
71709
- const launchers = buildShellLaunchers(command, { login });
71805
+ const launchers = buildShellLaunchers(command, {
71806
+ login,
71807
+ powershellEnvAliases: secretEnv ? Object.keys(secretEnv) : undefined
71808
+ });
71710
71809
  if (launchers.length === 0) {
71711
71810
  throw new Error("Command must be a non-empty string");
71712
71811
  }
@@ -71836,7 +71935,8 @@ async function run_shell_command(args) {
71836
71935
  workdir: args.dir_path,
71837
71936
  timeout_ms: args.timeout_ms,
71838
71937
  signal: args.signal,
71839
- onOutput: args.onOutput
71938
+ onOutput: args.onOutput,
71939
+ secretEnv: args.secretEnv
71840
71940
  });
71841
71941
  const message = result.output.trim() || "(Command completed with no output)";
71842
71942
  return { message };
@@ -77988,9 +78088,9 @@ function detectSkillScript(command, workingDir) {
77988
78088
  }
77989
78089
  const normalizedWorkingDir = normalizePathSeparators(workingDir).replace(/\/$/, "");
77990
78090
  const normalizedHomeDir = normalizePathSeparators(homedir18()).replace(/\/$/, "");
77991
- const detect = (source, regex2) => {
78091
+ const detect = (source, regex4) => {
77992
78092
  for (const candidate of pathCandidates) {
77993
- const match3 = candidate.match(regex2);
78093
+ const match3 = candidate.match(regex4);
77994
78094
  if (!match3?.[1]) {
77995
78095
  continue;
77996
78096
  }
@@ -78959,11 +79059,15 @@ async function executeTool(name, args, options) {
78959
79059
  enhancedArgs = {
78960
79060
  ...enhancedArgs,
78961
79061
  onOutput: (chunk, stream2) => {
78962
- options.onOutput?.(scrubSecretsFromString(chunk), stream2);
79062
+ options.onOutput?.(stripAnsi3(scrubSecretsFromString(chunk, scopedAgentId)), stream2);
78963
79063
  }
78964
79064
  };
78965
79065
  }
78966
- enhancedArgs = substituteSecretsInArgs(enhancedArgs);
79066
+ const command = enhancedArgs.command;
79067
+ const secretEnv = typeof command === "string" || Array.isArray(command) && command.every((part) => typeof part === "string") ? extractSecretEnvFromCommand(command, scopedAgentId) : {};
79068
+ if (Object.keys(secretEnv).length > 0) {
79069
+ enhancedArgs = { ...enhancedArgs, secretEnv };
79070
+ }
78967
79071
  }
78968
79072
  if (internalName === "Task") {
78969
79073
  if (options?.toolCallId) {
@@ -79018,16 +79122,17 @@ async function executeTool(name, args, options) {
79018
79122
  const toolStatus = recordResult?.status === "error" ? "error" : "success";
79019
79123
  let flattenedResponse = flattenToolResponse(result);
79020
79124
  if (STREAMING_SHELL_TOOLS.has(internalName)) {
79125
+ const sanitize = (text) => stripAnsi3(scrubSecretsFromString(text, scopedAgentId));
79021
79126
  if (typeof flattenedResponse === "string") {
79022
- flattenedResponse = scrubSecretsFromString(flattenedResponse);
79127
+ flattenedResponse = sanitize(flattenedResponse);
79023
79128
  } else if (Array.isArray(flattenedResponse)) {
79024
- flattenedResponse = flattenedResponse.map((block) => block.type === "text" ? { ...block, text: scrubSecretsFromString(block.text) } : block);
79129
+ flattenedResponse = flattenedResponse.map((block) => block.type === "text" ? { ...block, text: sanitize(block.text) } : block);
79025
79130
  }
79026
79131
  if (stdout) {
79027
79132
  for (let i = 0;i < stdout.length; i++) {
79028
79133
  const line = stdout[i];
79029
79134
  if (line !== undefined) {
79030
- stdout[i] = scrubSecretsFromString(line);
79135
+ stdout[i] = sanitize(line);
79031
79136
  }
79032
79137
  }
79033
79138
  }
@@ -79035,7 +79140,7 @@ async function executeTool(name, args, options) {
79035
79140
  for (let i = 0;i < stderr.length; i++) {
79036
79141
  const line = stderr[i];
79037
79142
  if (line !== undefined) {
79038
- stderr[i] = scrubSecretsFromString(line);
79143
+ stderr[i] = sanitize(line);
79039
79144
  }
79040
79145
  }
79041
79146
  }
@@ -79173,6 +79278,7 @@ function clearToolsWithLock() {
79173
79278
  }
79174
79279
  var TOOL_NAMES, STREAMING_SHELL_TOOLS, FILE_MUTATING_TOOLS, TOOL_NAME_MAPPINGS, ANTHROPIC_DEFAULT_TOOLS, OPENAI_DEFAULT_TOOLS, GEMINI_DEFAULT_TOOLS, OPENAI_PASCAL_TOOLS, GEMINI_PASCAL_TOOLS, REGISTRY_KEY, SWITCH_LOCK_KEY, EXECUTION_CONTEXTS_KEY, toolRegistry, toolExecutionContextCounter = 0, EXTERNAL_TOOLS_KEY, EXTERNAL_EXECUTOR_KEY;
79175
79280
  var init_manager4 = __esm(async () => {
79281
+ init_strip_ansi3();
79176
79282
  init_context();
79177
79283
  init_model2();
79178
79284
  init_subagents();
@@ -79479,6 +79585,7 @@ function toAccountSnapshot(account) {
79479
79585
  running,
79480
79586
  dmPolicy: account.dmPolicy,
79481
79587
  allowedUsers: [...account.allowedUsers],
79588
+ allowedChannels: [...account.allowedChannels ?? []],
79482
79589
  hasToken: account.token.trim().length > 0,
79483
79590
  agentId: account.agentId,
79484
79591
  createdAt: account.createdAt,
@@ -79533,6 +79640,7 @@ function createAccountFromPatch(channelId, accountId, patch) {
79533
79640
  agentId: patch.agentId ?? null,
79534
79641
  dmPolicy: patch.dmPolicy ?? "pairing",
79535
79642
  allowedUsers: patch.allowedUsers ?? [],
79643
+ allowedChannels: patch.allowedChannels ?? [],
79536
79644
  createdAt: now,
79537
79645
  updatedAt: now
79538
79646
  };
@@ -79576,6 +79684,7 @@ function mergeAccountPatch(existing, patch) {
79576
79684
  agentId: patch.agentId ?? existing.agentId,
79577
79685
  dmPolicy: patch.dmPolicy ?? existing.dmPolicy,
79578
79686
  allowedUsers: patch.allowedUsers ?? existing.allowedUsers,
79687
+ allowedChannels: patch.allowedChannels ?? existing.allowedChannels,
79579
79688
  updatedAt: nextUpdatedAt
79580
79689
  };
79581
79690
  }
@@ -79654,6 +79763,7 @@ function getChannelConfigSnapshot(channelId, accountId) {
79654
79763
  enabled: account.enabled,
79655
79764
  dmPolicy: account.dmPolicy,
79656
79765
  allowedUsers: [...account.allowedUsers],
79766
+ allowedChannels: [...account.allowedChannels ?? []],
79657
79767
  hasToken: account.token.trim().length > 0
79658
79768
  };
79659
79769
  }
@@ -79683,6 +79793,7 @@ async function setChannelConfigLive(channelId, patch, accountId) {
79683
79793
  mode: patch.mode,
79684
79794
  dmPolicy: patch.dmPolicy,
79685
79795
  allowedUsers: patch.allowedUsers,
79796
+ allowedChannels: patch.allowedChannels,
79686
79797
  displayName: existing.displayName
79687
79798
  });
79688
79799
  shouldRefreshDisplayName = channelId === "telegram" || channelId === "discord" ? patch.token !== undefined : patch.botToken !== undefined || patch.appToken !== undefined;
@@ -79694,7 +79805,8 @@ async function setChannelConfigLive(channelId, patch, accountId) {
79694
79805
  appToken: patch.appToken,
79695
79806
  mode: patch.mode,
79696
79807
  dmPolicy: patch.dmPolicy,
79697
- allowedUsers: patch.allowedUsers
79808
+ allowedUsers: patch.allowedUsers,
79809
+ allowedChannels: patch.allowedChannels
79698
79810
  }, accountId ? { accountId } : undefined);
79699
79811
  targetAccountId = created.accountId;
79700
79812
  shouldRefreshDisplayName = true;
@@ -89192,8 +89304,29 @@ var init_cwd = __esm(() => {
89192
89304
  init_remote_settings();
89193
89305
  });
89194
89306
 
89195
- // src/websocket/listener/approval.ts
89307
+ // src/websocket/listener/transport.ts
89196
89308
  import WebSocket from "ws";
89309
+
89310
+ class LocalListenerTransport {
89311
+ kind = "local";
89312
+ bufferedAmount = 0;
89313
+ isOpen() {
89314
+ return true;
89315
+ }
89316
+ send(_data) {}
89317
+ }
89318
+ function isListenerTransportOpen(transport) {
89319
+ if ("isOpen" in transport && typeof transport.isOpen === "function") {
89320
+ return transport.isOpen();
89321
+ }
89322
+ return transport.readyState === WebSocket.OPEN;
89323
+ }
89324
+ function getListenerTransportKind(transport) {
89325
+ return "kind" in transport ? transport.kind : "websocket";
89326
+ }
89327
+ var init_transport = () => {};
89328
+
89329
+ // src/websocket/listener/approval.ts
89197
89330
  function rememberPendingApprovalBatchIds(runtime, pendingApprovals, batchId) {
89198
89331
  for (const approval of pendingApprovals) {
89199
89332
  if (approval.toolCallId) {
@@ -89327,7 +89460,7 @@ function rejectPendingApprovalResolvers(runtime, reason) {
89327
89460
  evictConversationRuntimeIfIdle(runtime);
89328
89461
  }
89329
89462
  function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
89330
- if (socket.readyState !== WebSocket.OPEN) {
89463
+ if (!isListenerTransportOpen(socket)) {
89331
89464
  return Promise.reject(new Error("WebSocket not open"));
89332
89465
  }
89333
89466
  const abortSignal = runtime.activeAbortController?.signal ?? null;
@@ -89390,6 +89523,7 @@ function requestApprovalOverWS(runtime, socket, requestId, controlRequest) {
89390
89523
  }
89391
89524
  var init_approval = __esm(async () => {
89392
89525
  init_runtime4();
89526
+ init_transport();
89393
89527
  await init_protocol_outbound();
89394
89528
  });
89395
89529
 
@@ -90328,6 +90462,46 @@ var init_approval_suggestions = __esm(async () => {
90328
90462
  ]);
90329
90463
  });
90330
90464
 
90465
+ // src/websocket/listener/secrets-sync.ts
90466
+ var exports_secrets_sync = {};
90467
+ __export(exports_secrets_sync, {
90468
+ ensureSecretsHydratedForAgent: () => ensureSecretsHydratedForAgent,
90469
+ __testOverrideRefreshSecretsForAgent: () => __testOverrideRefreshSecretsForAgent
90470
+ });
90471
+ function __testOverrideRefreshSecretsForAgent(factory) {
90472
+ _testRefreshSecretsForAgentOverride = factory;
90473
+ }
90474
+ async function refreshSecretsForAgent(agentId) {
90475
+ if (_testRefreshSecretsForAgentOverride) {
90476
+ await _testRefreshSecretsForAgentOverride(agentId);
90477
+ debugLog("secrets-sync", `Refreshed secrets for agent ${agentId}`);
90478
+ return;
90479
+ }
90480
+ const { initSecretsFromServer: initSecretsFromServer2 } = await Promise.resolve().then(() => (init_secretsStore(), exports_secretsStore));
90481
+ await initSecretsFromServer2(agentId);
90482
+ debugLog("secrets-sync", `Refreshed secrets for agent ${agentId}`);
90483
+ }
90484
+ async function ensureSecretsHydratedForAgent(listener, agentId) {
90485
+ const existing = listener.secretsHydrationByAgent.get(agentId);
90486
+ if (existing) {
90487
+ await existing;
90488
+ return;
90489
+ }
90490
+ const promise = refreshSecretsForAgent(agentId).catch((err) => {
90491
+ debugWarn("secrets-sync", `Failed to refresh secrets for agent ${agentId}: ${err instanceof Error ? err.message : String(err)}`);
90492
+ }).finally(() => {
90493
+ if (listener.secretsHydrationByAgent.get(agentId) === promise) {
90494
+ listener.secretsHydrationByAgent.delete(agentId);
90495
+ }
90496
+ });
90497
+ listener.secretsHydrationByAgent.set(agentId, promise);
90498
+ await promise;
90499
+ }
90500
+ var _testRefreshSecretsForAgentOverride = null;
90501
+ var init_secrets_sync = __esm(() => {
90502
+ init_debug();
90503
+ });
90504
+
90331
90505
  // src/websocket/listener/recovery.ts
90332
90506
  function isApprovalToolCallDesyncError(detail) {
90333
90507
  if (isInvalidToolCallIdsError(detail) || isApprovalPendingError(detail)) {
@@ -90668,6 +90842,7 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
90668
90842
  });
90669
90843
  const recoveryAbortController = new AbortController;
90670
90844
  runtime.activeAbortController = recoveryAbortController;
90845
+ await ensureSecretsHydratedForAgent(runtime.listener, recovered.agentId);
90671
90846
  const preparedToolContext = await prepareToolExecutionContextForScope({
90672
90847
  agentId: recovered.agentId,
90673
90848
  conversationId: recovered.conversationId,
@@ -90752,6 +90927,7 @@ var init_recovery = __esm(async () => {
90752
90927
  init_cwd();
90753
90928
  init_permissionMode();
90754
90929
  init_runtime4();
90930
+ init_secrets_sync();
90755
90931
  await __promiseAll([
90756
90932
  init_approval_execution(),
90757
90933
  init_accumulator(),
@@ -91643,8 +91819,8 @@ var init_word = __esm(() => {
91643
91819
  wordDiff = new WordDiff;
91644
91820
  WordsWithSpaceDiff = class WordsWithSpaceDiff extends Diff {
91645
91821
  tokenize(value) {
91646
- const regex2 = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, "ug");
91647
- return value.match(regex2) || [];
91822
+ const regex4 = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, "ug");
91823
+ return value.match(regex4) || [];
91648
91824
  }
91649
91825
  };
91650
91826
  wordsWithSpaceDiff = new WordsWithSpaceDiff;
@@ -93226,7 +93402,6 @@ var init_diffPreview = __esm(() => {
93226
93402
 
93227
93403
  // src/websocket/listener/turn-approval.ts
93228
93404
  import { readFile as readFile12 } from "node:fs/promises";
93229
- import WebSocket2 from "ws";
93230
93405
  function getChannelApprovalSourceScopeKey(source) {
93231
93406
  return [
93232
93407
  source.channel,
@@ -93512,7 +93687,7 @@ async function handleApprovalStop(params) {
93512
93687
  return interruptTermination();
93513
93688
  }
93514
93689
  const onFileWrite = (filePath, content) => {
93515
- if (socket.readyState === WebSocket2.OPEN) {
93690
+ if (isListenerTransportOpen(socket)) {
93516
93691
  socket.send(JSON.stringify({
93517
93692
  type: "file_ops",
93518
93693
  path: filePath,
@@ -93525,6 +93700,9 @@ async function handleApprovalStop(params) {
93525
93700
  };
93526
93701
  let executionResults;
93527
93702
  try {
93703
+ if (agentId) {
93704
+ await ensureSecretsHydratedForAgent(runtime.listener, agentId);
93705
+ }
93528
93706
  executionResults = await executeApprovalBatch(decisions, undefined, {
93529
93707
  toolContextId: turnToolContextId ?? undefined,
93530
93708
  abortSignal: abortController.signal,
@@ -93638,7 +93816,9 @@ var init_turn_approval = __esm(async () => {
93638
93816
  init_diffPreview();
93639
93817
  init_formatDenial();
93640
93818
  init_interactivePolicy();
93819
+ init_secrets_sync();
93641
93820
  init_skill_injection();
93821
+ init_transport();
93642
93822
  await __promiseAll([
93643
93823
  init_approval_execution(),
93644
93824
  init_approval(),
@@ -93877,8 +94057,11 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
93877
94057
  });
93878
94058
  return;
93879
94059
  }
93880
- const { ensureMemfsSyncedForAgent: ensureMemfsSyncedForAgent2 } = await Promise.resolve().then(() => (init_memfs_sync(), exports_memfs_sync));
93881
- await ensureMemfsSyncedForAgent2(runtime.listener, agentId);
94060
+ const [{ ensureMemfsSyncedForAgent: ensureMemfsSyncedForAgent2 }, { ensureSecretsHydratedForAgent: ensureSecretsHydratedForAgent2 }] = await Promise.all([Promise.resolve().then(() => (init_memfs_sync(), exports_memfs_sync)), Promise.resolve().then(() => (init_secrets_sync(), exports_secrets_sync))]);
94061
+ await Promise.all([
94062
+ ensureMemfsSyncedForAgent2(runtime.listener, agentId),
94063
+ ensureSecretsHydratedForAgent2(runtime.listener, agentId)
94064
+ ]);
93882
94065
  setCurrentAgentId(agentId);
93883
94066
  setConversationId2(conversationId);
93884
94067
  if (isDebugEnabled()) {
@@ -94720,7 +94903,6 @@ var init_commands = __esm(async () => {
94720
94903
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync22 } from "node:fs";
94721
94904
  import { dirname as dirname16 } from "node:path";
94722
94905
  import { performance as performance2 } from "node:perf_hooks";
94723
- import WebSocket3 from "ws";
94724
94906
  function getProtocolPerfKey(message) {
94725
94907
  if (message.type === "stream_delta" && "delta" in message) {
94726
94908
  const delta = message.delta;
@@ -94942,10 +95124,11 @@ function buildDeviceStatus(runtime, params) {
94942
95124
  }
94943
95125
  })();
94944
95126
  const systemPromptDoctorState = scopedAgentId ? getSystemPromptDoctorState(scopedAgentId) : null;
95127
+ const transport = listener.transport ?? listener.socket;
94945
95128
  return {
94946
95129
  current_connection_id: listener.connectionId,
94947
95130
  connection_name: listener.connectionName,
94948
- is_online: listener.socket?.readyState === WebSocket3.OPEN,
95131
+ is_online: transport ? isListenerTransportOpen(transport) : false,
94949
95132
  is_processing: !!conversationRuntime?.isProcessing,
94950
95133
  current_permission_mode: conversationPermissionModeState.mode,
94951
95134
  current_working_directory: resolvedCwd,
@@ -95015,7 +95198,7 @@ function setLoopStatus(runtime, status, scope) {
95015
95198
  emitLoopStatusIfOpen(runtime, scope);
95016
95199
  }
95017
95200
  function emitProtocolV2Message(socket, runtime, message, scope) {
95018
- if (socket.readyState !== WebSocket3.OPEN) {
95201
+ if (!isListenerTransportOpen(socket)) {
95019
95202
  return;
95020
95203
  }
95021
95204
  const listener = getListenerRuntime(runtime);
@@ -95083,14 +95266,16 @@ function emitLoopStatusUpdate(socket, runtime, scope) {
95083
95266
  }
95084
95267
  function emitLoopStatusIfOpen(runtime, scope) {
95085
95268
  const listener = getListenerRuntime(runtime);
95086
- if (listener?.socket?.readyState === WebSocket3.OPEN) {
95087
- emitLoopStatusUpdate(listener.socket, runtime, scope);
95269
+ const transport = listener?.transport ?? listener?.socket;
95270
+ if (transport && isListenerTransportOpen(transport)) {
95271
+ emitLoopStatusUpdate(transport, runtime, scope);
95088
95272
  }
95089
95273
  }
95090
95274
  function emitDeviceStatusIfOpen(runtime, scope) {
95091
95275
  const listener = getListenerRuntime(runtime);
95092
- if (listener?.socket?.readyState === WebSocket3.OPEN) {
95093
- emitDeviceStatusUpdate(listener.socket, runtime, scope);
95276
+ const transport = listener?.transport ?? listener?.socket;
95277
+ if (transport && isListenerTransportOpen(transport)) {
95278
+ emitDeviceStatusUpdate(transport, runtime, scope);
95094
95279
  }
95095
95280
  }
95096
95281
  function emitQueueUpdate(socket, runtime, scope) {
@@ -95148,8 +95333,9 @@ function emitDequeuedUserMessage(socket, runtime, incoming, batch) {
95148
95333
  }
95149
95334
  function emitQueueUpdateIfOpen(runtime, scope) {
95150
95335
  const listener = getListenerRuntime(runtime);
95151
- if (listener?.socket?.readyState === WebSocket3.OPEN) {
95152
- emitQueueUpdate(listener.socket, runtime, scope);
95336
+ const transport = listener?.transport ?? listener?.socket;
95337
+ if (transport && isListenerTransportOpen(transport)) {
95338
+ emitQueueUpdate(transport, runtime, scope);
95153
95339
  }
95154
95340
  }
95155
95341
  function emitStateSync(socket, runtime, scope) {
@@ -95204,8 +95390,9 @@ function emitSubagentStateUpdate(socket, runtime, scope) {
95204
95390
  }
95205
95391
  function emitSubagentStateIfOpen(runtime, scope) {
95206
95392
  const listener = getListenerRuntime(runtime);
95207
- if (listener?.socket?.readyState === WebSocket3.OPEN) {
95208
- emitSubagentStateUpdate(listener.socket, runtime, scope);
95393
+ const transport = listener?.transport ?? listener?.socket;
95394
+ if (transport && isListenerTransportOpen(transport)) {
95395
+ emitSubagentStateUpdate(transport, runtime, scope);
95209
95396
  }
95210
95397
  }
95211
95398
  function scheduleQueueEmit(runtime, scope) {
@@ -95301,6 +95488,7 @@ var init_protocol_outbound = __esm(async () => {
95301
95488
  init_cwd();
95302
95489
  init_permissionMode();
95303
95490
  init_runtime4();
95491
+ init_transport();
95304
95492
  await init_commands();
95305
95493
  PROTOCOL_PERF_ENV_VALUES = new Set(["1", "true", "yes"]);
95306
95494
  PROTOCOL_PERF_ENABLED = PROTOCOL_PERF_ENV_VALUES.has((process.env.LETTA_LISTENER_PERF ?? "").toLowerCase());
@@ -95873,7 +96061,7 @@ var init_toolset_labels = __esm(() => {
95873
96061
 
95874
96062
  // src/websocket/terminalHandler.ts
95875
96063
  import * as os4 from "node:os";
95876
- import WebSocket4 from "ws";
96064
+ import WebSocket2 from "ws";
95877
96065
  function getDefaultShell() {
95878
96066
  if (os4.platform() === "win32") {
95879
96067
  return process.env.COMSPEC || "cmd.exe";
@@ -95881,7 +96069,7 @@ function getDefaultShell() {
95881
96069
  return process.env.SHELL || "/bin/zsh";
95882
96070
  }
95883
96071
  function sendTerminalMessage(socket, message) {
95884
- if (socket.readyState === WebSocket4.OPEN) {
96072
+ if (socket.readyState === WebSocket2.OPEN) {
95885
96073
  socket.send(JSON.stringify(message));
95886
96074
  }
95887
96075
  }
@@ -96596,9 +96784,10 @@ function isChannelId(value) {
96596
96784
  function hasValidChannelPolicyFields(config) {
96597
96785
  const hasValidDmPolicy = config.dm_policy === undefined || config.dm_policy === "pairing" || config.dm_policy === "allowlist" || config.dm_policy === "open";
96598
96786
  const hasValidAllowedUsers = config.allowed_users === undefined || Array.isArray(config.allowed_users) && config.allowed_users.every((entry) => typeof entry === "string");
96787
+ const hasValidAllowedChannels = config.allowed_channels === undefined || Array.isArray(config.allowed_channels) && config.allowed_channels.every((entry) => typeof entry === "string");
96599
96788
  const hasValidDisplayName = config.display_name === undefined || typeof config.display_name === "string";
96600
96789
  const hasValidEnabled = config.enabled === undefined || typeof config.enabled === "boolean";
96601
- return hasValidDmPolicy && hasValidAllowedUsers && hasValidDisplayName && hasValidEnabled;
96790
+ return hasValidDmPolicy && hasValidAllowedUsers && hasValidAllowedChannels && hasValidDisplayName && hasValidEnabled;
96602
96791
  }
96603
96792
  function isChannelsListCommand(value) {
96604
96793
  if (!value || typeof value !== "object")
@@ -97025,7 +97214,7 @@ import { execFile as execFile13 } from "node:child_process";
97025
97214
  import { lstat as lstat2, realpath as realpath3, stat as stat6 } from "node:fs/promises";
97026
97215
  import path25 from "node:path";
97027
97216
  import { promisify as promisify11 } from "node:util";
97028
- import WebSocket5 from "ws";
97217
+ import WebSocket3 from "ws";
97029
97218
  async function isGitWorktreeRoot(dir) {
97030
97219
  try {
97031
97220
  const stats = await lstat2(path25.join(dir, ".git"));
@@ -97048,7 +97237,7 @@ function trackListenerError(errorType, error, context3) {
97048
97237
  });
97049
97238
  }
97050
97239
  function safeSocketSend(socket, payload, errorType, context3) {
97051
- if (socket.readyState !== WebSocket5.OPEN) {
97240
+ if (socket.readyState !== WebSocket3.OPEN) {
97052
97241
  return false;
97053
97242
  }
97054
97243
  try {
@@ -97063,6 +97252,22 @@ function safeSocketSend(socket, payload, errorType, context3) {
97063
97252
  return false;
97064
97253
  }
97065
97254
  }
97255
+ function safeTransportSend(transport, payload, errorType, context3) {
97256
+ if (!isListenerTransportOpen(transport)) {
97257
+ return false;
97258
+ }
97259
+ try {
97260
+ const serialized = typeof payload === "string" ? payload : JSON.stringify(payload);
97261
+ transport.send(serialized);
97262
+ return true;
97263
+ } catch (error) {
97264
+ trackListenerError(errorType, error, context3);
97265
+ if (isDebugEnabled()) {
97266
+ console.error(`[Listen] ${context3} send failed:`, error);
97267
+ }
97268
+ return false;
97269
+ }
97270
+ }
97066
97271
  function runDetachedListenerTask(commandName, task2) {
97067
97272
  task2().catch((error) => {
97068
97273
  trackListenerError(`listener_${commandName}_failed`, error, `listener_${commandName}`);
@@ -97844,6 +98049,7 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
97844
98049
  enabled: snapshot.enabled,
97845
98050
  dm_policy: snapshot.dmPolicy,
97846
98051
  allowed_users: snapshot.allowedUsers,
98052
+ allowed_channels: snapshot.allowedChannels,
97847
98053
  has_token: snapshot.hasToken
97848
98054
  };
97849
98055
  }
@@ -97889,6 +98095,7 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
97889
98095
  running: snapshot.running,
97890
98096
  dm_policy: snapshot.dmPolicy,
97891
98097
  allowed_users: snapshot.allowedUsers,
98098
+ allowed_channels: snapshot.allowedChannels,
97892
98099
  has_token: snapshot.hasToken,
97893
98100
  agent_id: snapshot.agentId,
97894
98101
  created_at: snapshot.createdAt,
@@ -98004,7 +98211,8 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
98004
98211
  agentId: "agent_id" in parsed.account ? parsed.account.agent_id : undefined,
98005
98212
  defaultPermissionMode: "default_permission_mode" in parsed.account ? parsed.account.default_permission_mode : undefined,
98006
98213
  dmPolicy: parsed.account.dm_policy,
98007
- allowedUsers: parsed.account.allowed_users
98214
+ allowedUsers: parsed.account.allowed_users,
98215
+ allowedChannels: "allowed_channels" in parsed.account ? parsed.account.allowed_channels : undefined
98008
98216
  }, {
98009
98217
  accountId: "account_id" in parsed.account ? parsed.account.account_id : undefined
98010
98218
  });
@@ -98045,7 +98253,8 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
98045
98253
  agentId: "agent_id" in parsed.patch ? parsed.patch.agent_id : undefined,
98046
98254
  defaultPermissionMode: "default_permission_mode" in parsed.patch ? parsed.patch.default_permission_mode : undefined,
98047
98255
  dmPolicy: parsed.patch.dm_policy,
98048
- allowedUsers: parsed.patch.allowed_users
98256
+ allowedUsers: parsed.patch.allowed_users,
98257
+ allowedChannels: "allowed_channels" in parsed.patch ? parsed.patch.allowed_channels : undefined
98049
98258
  });
98050
98259
  const shouldRefreshDisplayName = !("display_name" in parsed.patch) && (parsed.channel_id === "telegram" ? "token" in parsed.patch : ("bot_token" in parsed.patch) || ("app_token" in parsed.patch));
98051
98260
  const account = shouldRefreshDisplayName ? await refreshChannelAccountDisplayNameLive2(parsed.channel_id, parsed.account_id, { force: true }) : updated;
@@ -98245,7 +98454,8 @@ async function handleChannelsProtocolCommand(parsed, socket, runtime, opts, proc
98245
98454
  appToken: "app_token" in parsed.config ? parsed.config.app_token : undefined,
98246
98455
  mode: "mode" in parsed.config ? parsed.config.mode : undefined,
98247
98456
  dmPolicy: parsed.config.dm_policy,
98248
- allowedUsers: parsed.config.allowed_users
98457
+ allowedUsers: parsed.config.allowed_users,
98458
+ allowedChannels: "allowed_channels" in parsed.config ? parsed.config.allowed_channels : undefined
98249
98459
  }, parsed.account_id);
98250
98460
  if (snapshot.enabled) {
98251
98461
  await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
@@ -98833,13 +99043,17 @@ async function wireChannelIngress(listener, socket, opts, processQueuedTurn) {
98833
99043
  }
98834
99044
  function handleChannelRegistryEvent(event, socket, runtime) {
98835
99045
  if (event.type === "pairings_updated") {
98836
- emitChannelPairingsUpdated(socket, event.channelId);
98837
- emitChannelsUpdated(socket, event.channelId);
99046
+ if (socket instanceof WebSocket3) {
99047
+ emitChannelPairingsUpdated(socket, event.channelId);
99048
+ emitChannelsUpdated(socket, event.channelId);
99049
+ }
98838
99050
  return;
98839
99051
  }
98840
99052
  if (event.type === "targets_updated") {
98841
- emitChannelTargetsUpdated(socket, event.channelId);
98842
- emitChannelsUpdated(socket, event.channelId);
99053
+ if (socket instanceof WebSocket3) {
99054
+ emitChannelTargetsUpdated(socket, event.channelId);
99055
+ emitChannelsUpdated(socket, event.channelId);
99056
+ }
98843
99057
  return;
98844
99058
  }
98845
99059
  const permissionModeState = getOrCreateConversationPermissionModeStateRef(runtime, event.agentId, event.conversationId);
@@ -99184,6 +99398,7 @@ function createRuntime() {
99184
99398
  const bootWorkingDirectory = getCurrentWorkingDirectory();
99185
99399
  return {
99186
99400
  socket: null,
99401
+ transport: null,
99187
99402
  heartbeatInterval: null,
99188
99403
  reconnectTimeout: null,
99189
99404
  intentionallyClosed: false,
@@ -99209,6 +99424,7 @@ function createRuntime() {
99209
99424
  conversationRuntimes: new Map,
99210
99425
  approvalRuntimeKeyByRequestId: new Map,
99211
99426
  memfsSyncedAgents: new Map,
99427
+ secretsHydrationByAgent: new Map,
99212
99428
  lastEmittedStatus: null
99213
99429
  };
99214
99430
  }
@@ -99232,17 +99448,100 @@ function stopRuntime(runtime, suppressCallbacks) {
99232
99448
  runtime.queuedSystemPromptRecompileByConversation.clear();
99233
99449
  stopAllWorktreeWatchers(runtime);
99234
99450
  if (!runtime.socket) {
99451
+ runtime.transport = null;
99235
99452
  return;
99236
99453
  }
99237
99454
  const socket = runtime.socket;
99238
99455
  runtime.socket = null;
99456
+ runtime.transport = null;
99239
99457
  if (suppressCallbacks) {
99240
99458
  socket.removeAllListeners();
99241
99459
  }
99242
- if (socket.readyState === WebSocket5.OPEN || socket.readyState === WebSocket5.CONNECTING) {
99460
+ if (socket.readyState === WebSocket3.OPEN || socket.readyState === WebSocket3.CONNECTING) {
99243
99461
  socket.close();
99244
99462
  }
99245
99463
  }
99464
+ async function startConnectedListenerRuntime(runtime, transport, opts, processQueuedTurn, options = {}) {
99465
+ if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
99466
+ return;
99467
+ }
99468
+ const shouldStartHeartbeat = options.startHeartbeat !== false;
99469
+ const shouldStartCronScheduler = options.startCronScheduler !== false;
99470
+ runtime.transport = transport;
99471
+ safeEmitWsEvent("recv", "lifecycle", {
99472
+ type: getListenerTransportKind(transport) === "websocket" ? "_ws_open" : "_local_open"
99473
+ });
99474
+ runtime.hasSuccessfulConnection = true;
99475
+ runtime.everConnected = true;
99476
+ opts.onConnected(opts.connectionId);
99477
+ if (runtime.conversationRuntimes.size === 0) {
99478
+ emitLoopStatusUpdate(transport, runtime);
99479
+ } else {
99480
+ for (const reminderState of runtime.reminderStateByConversation.values()) {
99481
+ resetSharedReminderState(reminderState);
99482
+ }
99483
+ for (const contextTracker of runtime.contextTrackerByConversation.values()) {
99484
+ resetContextHistory(contextTracker);
99485
+ }
99486
+ for (const conversationRuntime of runtime.conversationRuntimes.values()) {
99487
+ const scope = {
99488
+ agent_id: conversationRuntime.agentId,
99489
+ conversation_id: conversationRuntime.conversationId
99490
+ };
99491
+ emitDeviceStatusUpdate(transport, conversationRuntime, scope);
99492
+ emitLoopStatusUpdate(transport, conversationRuntime, scope);
99493
+ }
99494
+ }
99495
+ runtime._unsubscribeSubagentState?.();
99496
+ runtime._unsubscribeSubagentState = subscribe2(() => {
99497
+ if (runtime.conversationRuntimes.size === 0) {
99498
+ emitSubagentStateIfOpen(runtime);
99499
+ return;
99500
+ }
99501
+ for (const conversationRuntime of runtime.conversationRuntimes.values()) {
99502
+ emitSubagentStateIfOpen(runtime, {
99503
+ agent_id: conversationRuntime.agentId,
99504
+ conversation_id: conversationRuntime.conversationId
99505
+ });
99506
+ }
99507
+ });
99508
+ runtime._unsubscribeSubagentStreamEvents?.();
99509
+ runtime._unsubscribeSubagentStreamEvents = subscribeToStreamEvents((subagentId, event) => {
99510
+ if (!isListenerTransportOpen(transport))
99511
+ return;
99512
+ const subagent = getSubagents().find((entry) => entry.id === subagentId);
99513
+ if (subagent?.silent === true) {
99514
+ return;
99515
+ }
99516
+ emitStreamDelta(transport, runtime, event, subagent?.parentAgentId ? {
99517
+ agent_id: subagent.parentAgentId,
99518
+ conversation_id: subagent.parentConversationId ?? "default"
99519
+ } : undefined, subagentId);
99520
+ });
99521
+ setMessageQueueAdder((queuedMessage) => {
99522
+ const targetRuntime = queuedMessage.agentId && queuedMessage.conversationId ? getOrCreateScopedRuntime(runtime, queuedMessage.agentId, queuedMessage.conversationId) : findFallbackRuntime(runtime);
99523
+ if (!targetRuntime?.queueRuntime) {
99524
+ return;
99525
+ }
99526
+ targetRuntime.queueRuntime.enqueue({
99527
+ kind: "task_notification",
99528
+ source: "task_notification",
99529
+ text: queuedMessage.text,
99530
+ agentId: queuedMessage.agentId ?? targetRuntime.agentId ?? undefined,
99531
+ conversationId: queuedMessage.conversationId ?? targetRuntime.conversationId
99532
+ });
99533
+ scheduleQueuePump(targetRuntime, transport, opts, processQueuedTurn);
99534
+ });
99535
+ if (shouldStartHeartbeat) {
99536
+ runtime.heartbeatInterval = setInterval(() => {
99537
+ safeTransportSend(transport, { type: "ping" }, "listener_ping_send_failed", "listener_heartbeat");
99538
+ }, 30000);
99539
+ }
99540
+ if (shouldStartCronScheduler) {
99541
+ startScheduler(transport, opts, processQueuedTurn);
99542
+ }
99543
+ await wireChannelIngress(runtime, transport, opts, processQueuedTurn);
99544
+ }
99246
99545
  async function startListenerClient(opts) {
99247
99546
  const existingRuntime = getActiveRuntime();
99248
99547
  if (existingRuntime) {
@@ -99257,6 +99556,34 @@ async function startListenerClient(opts) {
99257
99556
  telemetry.init();
99258
99557
  await connectWithRetry(runtime, opts);
99259
99558
  }
99559
+ async function startLocalChannelListener(opts) {
99560
+ const existingRuntime = getActiveRuntime();
99561
+ if (existingRuntime) {
99562
+ stopRuntime(existingRuntime, true);
99563
+ }
99564
+ const runtime = createRuntime();
99565
+ runtime.onWsEvent = opts.onWsEvent;
99566
+ runtime.connectionId = opts.connectionId;
99567
+ runtime.connectionName = opts.connectionName;
99568
+ setActiveRuntime(runtime);
99569
+ telemetry.setSurface("websocket");
99570
+ telemetry.init();
99571
+ try {
99572
+ await loadTools();
99573
+ const transport = new LocalListenerTransport;
99574
+ const processQueuedTurn = async (queuedTurn, dequeuedBatch) => {
99575
+ const scopedRuntime = getOrCreateScopedRuntime(runtime, queuedTurn.agentId, queuedTurn.conversationId);
99576
+ await handleIncomingMessage(queuedTurn, transport, scopedRuntime, opts.onStatusChange, opts.connectionId, dequeuedBatch.batchId);
99577
+ };
99578
+ await startConnectedListenerRuntime(runtime, transport, opts, processQueuedTurn, { startHeartbeat: false, startCronScheduler: true });
99579
+ } catch (error) {
99580
+ stopRuntime(runtime, true);
99581
+ if (getActiveRuntime() === runtime) {
99582
+ setActiveRuntime(null);
99583
+ }
99584
+ opts.onError(error instanceof Error ? error : new Error(String(error)));
99585
+ }
99586
+ }
99260
99587
  async function listDirectoryHybrid(absDir, indexRoot3, includeFiles) {
99261
99588
  let indexedNames;
99262
99589
  const indexedFolders = [];
@@ -99339,7 +99666,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
99339
99666
  const url = new URL(opts.wsUrl);
99340
99667
  url.searchParams.set("deviceId", opts.deviceId);
99341
99668
  url.searchParams.set("connectionName", opts.connectionName);
99342
- const socket = new WebSocket5(url.toString(), {
99669
+ const socket = new WebSocket3(url.toString(), {
99343
99670
  headers: {
99344
99671
  Authorization: `Bearer ${apiKey}`
99345
99672
  }
@@ -99348,83 +99675,13 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
99348
99675
  const watchDebounceTimers = new Map;
99349
99676
  const cancelledWatches = new Set;
99350
99677
  runtime.socket = socket;
99678
+ const transport = socket;
99351
99679
  const processQueuedTurn = async (queuedTurn, dequeuedBatch) => {
99352
99680
  const scopedRuntime = getOrCreateScopedRuntime(runtime, queuedTurn.agentId, queuedTurn.conversationId);
99353
- await handleIncomingMessage(queuedTurn, socket, scopedRuntime, opts.onStatusChange, opts.connectionId, dequeuedBatch.batchId);
99681
+ await handleIncomingMessage(queuedTurn, transport, scopedRuntime, opts.onStatusChange, opts.connectionId, dequeuedBatch.batchId);
99354
99682
  };
99355
99683
  socket.on("open", async () => {
99356
- if (runtime !== getActiveRuntime() || runtime.intentionallyClosed) {
99357
- return;
99358
- }
99359
- safeEmitWsEvent("recv", "lifecycle", { type: "_ws_open" });
99360
- runtime.hasSuccessfulConnection = true;
99361
- runtime.everConnected = true;
99362
- opts.onConnected(opts.connectionId);
99363
- if (runtime.conversationRuntimes.size === 0) {
99364
- emitLoopStatusUpdate(socket, runtime);
99365
- } else {
99366
- for (const reminderState of runtime.reminderStateByConversation.values()) {
99367
- resetSharedReminderState(reminderState);
99368
- }
99369
- for (const contextTracker of runtime.contextTrackerByConversation.values()) {
99370
- resetContextHistory(contextTracker);
99371
- }
99372
- for (const conversationRuntime of runtime.conversationRuntimes.values()) {
99373
- const scope = {
99374
- agent_id: conversationRuntime.agentId,
99375
- conversation_id: conversationRuntime.conversationId
99376
- };
99377
- emitDeviceStatusUpdate(socket, conversationRuntime, scope);
99378
- emitLoopStatusUpdate(socket, conversationRuntime, scope);
99379
- }
99380
- }
99381
- runtime._unsubscribeSubagentState?.();
99382
- runtime._unsubscribeSubagentState = subscribe2(() => {
99383
- if (runtime.conversationRuntimes.size === 0) {
99384
- emitSubagentStateIfOpen(runtime);
99385
- return;
99386
- }
99387
- for (const conversationRuntime of runtime.conversationRuntimes.values()) {
99388
- emitSubagentStateIfOpen(runtime, {
99389
- agent_id: conversationRuntime.agentId,
99390
- conversation_id: conversationRuntime.conversationId
99391
- });
99392
- }
99393
- });
99394
- runtime._unsubscribeSubagentStreamEvents?.();
99395
- runtime._unsubscribeSubagentStreamEvents = subscribeToStreamEvents((subagentId, event) => {
99396
- if (socket.readyState !== WebSocket5.OPEN)
99397
- return;
99398
- const subagent = getSubagents().find((entry) => entry.id === subagentId);
99399
- if (subagent?.silent === true) {
99400
- return;
99401
- }
99402
- emitStreamDelta(socket, runtime, event, subagent?.parentAgentId ? {
99403
- agent_id: subagent.parentAgentId,
99404
- conversation_id: subagent.parentConversationId ?? "default"
99405
- } : undefined, subagentId);
99406
- });
99407
- setMessageQueueAdder((queuedMessage) => {
99408
- const targetRuntime = queuedMessage.agentId && queuedMessage.conversationId ? getOrCreateScopedRuntime(runtime, queuedMessage.agentId, queuedMessage.conversationId) : findFallbackRuntime(runtime);
99409
- if (!targetRuntime?.queueRuntime) {
99410
- return;
99411
- }
99412
- targetRuntime.queueRuntime.enqueue({
99413
- kind: "task_notification",
99414
- source: "task_notification",
99415
- text: queuedMessage.text,
99416
- agentId: queuedMessage.agentId ?? targetRuntime.agentId ?? undefined,
99417
- conversationId: queuedMessage.conversationId ?? targetRuntime.conversationId
99418
- });
99419
- scheduleQueuePump(targetRuntime, socket, opts, processQueuedTurn);
99420
- });
99421
- runtime.heartbeatInterval = setInterval(() => {
99422
- if (socket.readyState === WebSocket5.OPEN) {
99423
- safeSocketSend(socket, { type: "ping" }, "listener_ping_send_failed", "listener_heartbeat");
99424
- }
99425
- }, 30000);
99426
- startScheduler(socket, opts, processQueuedTurn);
99427
- await wireChannelIngress(runtime, socket, opts, processQueuedTurn);
99684
+ await startConnectedListenerRuntime(runtime, transport, opts, processQueuedTurn, { startHeartbeat: true, startCronScheduler: true });
99428
99685
  });
99429
99686
  socket.on("message", async (data) => {
99430
99687
  const raw = data.toString();
@@ -100458,7 +100715,7 @@ async function connectWithRetry(runtime, opts, attempt = 0, startTime = Date.now
100458
100715
  }
100459
100716
  function isListenerActive() {
100460
100717
  const runtime = getActiveRuntime();
100461
- return runtime !== null && runtime.socket !== null;
100718
+ return runtime !== null && runtime.transport !== null;
100462
100719
  }
100463
100720
  function stopListenerClient() {
100464
100721
  const runtime = getActiveRuntime();
@@ -100621,6 +100878,12 @@ function createLegacyTestRuntime() {
100621
100878
  listener.memfsSyncedAgents = value;
100622
100879
  }
100623
100880
  },
100881
+ secretsHydrationByAgent: {
100882
+ get: () => listener.secretsHydrationByAgent,
100883
+ set: (value) => {
100884
+ listener.secretsHydrationByAgent = value;
100885
+ }
100886
+ },
100624
100887
  worktreeWatcherByConversation: {
100625
100888
  get: () => listener.worktreeWatcherByConversation,
100626
100889
  set: (value) => {
@@ -100686,6 +100949,7 @@ var init_client4 = __esm(async () => {
100686
100949
  init_grepInFiles();
100687
100950
  init_permissionMode();
100688
100951
  init_runtime4();
100952
+ init_transport();
100689
100953
  await __promiseAll([
100690
100954
  init_scheduler(),
100691
100955
  init_manager4(),
@@ -100781,6 +101045,7 @@ var init_client4 = __esm(async () => {
100781
101045
  var exports_listen_client = {};
100782
101046
  __export(exports_listen_client, {
100783
101047
  stopListenerClient: () => stopListenerClient,
101048
+ startLocalChannelListener: () => startLocalChannelListener,
100784
101049
  startListenerClient: () => startListenerClient,
100785
101050
  resolvePendingApprovalResolver: () => resolvePendingApprovalResolver,
100786
101051
  requestApprovalOverWS: () => requestApprovalOverWS,
@@ -107737,12 +108002,12 @@ var init_AgentSelector = __esm(async () => {
107737
108002
 
107738
108003
  // node_modules/highlight.js/es/languages/arduino.js
107739
108004
  function cPlusPlus(hljs) {
107740
- const regex2 = hljs.regex;
108005
+ const regex4 = hljs.regex;
107741
108006
  const C_LINE_COMMENT_MODE = hljs.COMMENT("//", "$", { contains: [{ begin: /\\\n/ }] });
107742
108007
  const DECLTYPE_AUTO_RE = "decltype\\(auto\\)";
107743
108008
  const NAMESPACE_RE = "[a-zA-Z_]\\w*::";
107744
108009
  const TEMPLATE_ARGUMENT_RE = "<[^<>]+>";
107745
- const FUNCTION_TYPE_RE = "(?!struct)(" + DECLTYPE_AUTO_RE + "|" + regex2.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex2.optional(TEMPLATE_ARGUMENT_RE) + ")";
108010
+ const FUNCTION_TYPE_RE = "(?!struct)(" + DECLTYPE_AUTO_RE + "|" + regex4.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex4.optional(TEMPLATE_ARGUMENT_RE) + ")";
107746
108011
  const CPP_PRIMITIVE_TYPES = {
107747
108012
  className: "type",
107748
108013
  begin: "\\b[a-z\\d_]*_t\\b"
@@ -107801,10 +108066,10 @@ function cPlusPlus(hljs) {
107801
108066
  };
107802
108067
  const TITLE_MODE = {
107803
108068
  className: "title",
107804
- begin: regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE,
108069
+ begin: regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE,
107805
108070
  relevance: 0
107806
108071
  };
107807
- const FUNCTION_TITLE = regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
108072
+ const FUNCTION_TITLE = regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
107808
108073
  const RESERVED_KEYWORDS = [
107809
108074
  "alignas",
107810
108075
  "alignof",
@@ -108094,7 +108359,7 @@ function cPlusPlus(hljs) {
108094
108359
  keywords: {
108095
108360
  _hint: FUNCTION_HINTS
108096
108361
  },
108097
- begin: regex2.concat(/\b/, /(?!decltype)/, /(?!if)/, /(?!for)/, /(?!switch)/, /(?!while)/, hljs.IDENT_RE, regex2.lookahead(/(<[^<>]+>|)\s*\(/))
108362
+ begin: regex4.concat(/\b/, /(?!decltype)/, /(?!if)/, /(?!for)/, /(?!switch)/, /(?!while)/, hljs.IDENT_RE, regex4.lookahead(/(<[^<>]+>|)\s*\(/))
108098
108363
  };
108099
108364
  const EXPRESSION_CONTAINS = [
108100
108365
  FUNCTION_DISPATCH,
@@ -108636,7 +108901,7 @@ var init_arduino = () => {};
108636
108901
 
108637
108902
  // node_modules/highlight.js/es/languages/bash.js
108638
108903
  function bash2(hljs) {
108639
- const regex2 = hljs.regex;
108904
+ const regex4 = hljs.regex;
108640
108905
  const VAR = {};
108641
108906
  const BRACED_VAR = {
108642
108907
  begin: /\$\{/,
@@ -108652,7 +108917,7 @@ function bash2(hljs) {
108652
108917
  Object.assign(VAR, {
108653
108918
  className: "variable",
108654
108919
  variants: [
108655
- { begin: regex2.concat(/\$[\w\d#@][\w\d_]*/, `(?![\\w\\d])(?![$])`) },
108920
+ { begin: regex4.concat(/\$[\w\d#@][\w\d_]*/, `(?![\\w\\d])(?![$])`) },
108656
108921
  BRACED_VAR
108657
108922
  ]
108658
108923
  });
@@ -109017,12 +109282,12 @@ var init_bash = () => {};
109017
109282
 
109018
109283
  // node_modules/highlight.js/es/languages/c.js
109019
109284
  function c(hljs) {
109020
- const regex2 = hljs.regex;
109285
+ const regex4 = hljs.regex;
109021
109286
  const C_LINE_COMMENT_MODE = hljs.COMMENT("//", "$", { contains: [{ begin: /\\\n/ }] });
109022
109287
  const DECLTYPE_AUTO_RE = "decltype\\(auto\\)";
109023
109288
  const NAMESPACE_RE = "[a-zA-Z_]\\w*::";
109024
109289
  const TEMPLATE_ARGUMENT_RE = "<[^<>]+>";
109025
- const FUNCTION_TYPE_RE = "(" + DECLTYPE_AUTO_RE + "|" + regex2.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex2.optional(TEMPLATE_ARGUMENT_RE) + ")";
109290
+ const FUNCTION_TYPE_RE = "(" + DECLTYPE_AUTO_RE + "|" + regex4.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex4.optional(TEMPLATE_ARGUMENT_RE) + ")";
109026
109291
  const TYPES = {
109027
109292
  className: "type",
109028
109293
  variants: [
@@ -109082,10 +109347,10 @@ function c(hljs) {
109082
109347
  };
109083
109348
  const TITLE_MODE = {
109084
109349
  className: "title",
109085
- begin: regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE,
109350
+ begin: regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE,
109086
109351
  relevance: 0
109087
109352
  };
109088
- const FUNCTION_TITLE = regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
109353
+ const FUNCTION_TITLE = regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
109089
109354
  const C_KEYWORDS = [
109090
109355
  "asm",
109091
109356
  "auto",
@@ -109293,12 +109558,12 @@ var init_c = () => {};
109293
109558
 
109294
109559
  // node_modules/highlight.js/es/languages/cpp.js
109295
109560
  function cpp(hljs) {
109296
- const regex2 = hljs.regex;
109561
+ const regex4 = hljs.regex;
109297
109562
  const C_LINE_COMMENT_MODE = hljs.COMMENT("//", "$", { contains: [{ begin: /\\\n/ }] });
109298
109563
  const DECLTYPE_AUTO_RE = "decltype\\(auto\\)";
109299
109564
  const NAMESPACE_RE = "[a-zA-Z_]\\w*::";
109300
109565
  const TEMPLATE_ARGUMENT_RE = "<[^<>]+>";
109301
- const FUNCTION_TYPE_RE = "(?!struct)(" + DECLTYPE_AUTO_RE + "|" + regex2.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex2.optional(TEMPLATE_ARGUMENT_RE) + ")";
109566
+ const FUNCTION_TYPE_RE = "(?!struct)(" + DECLTYPE_AUTO_RE + "|" + regex4.optional(NAMESPACE_RE) + "[a-zA-Z_]\\w*" + regex4.optional(TEMPLATE_ARGUMENT_RE) + ")";
109302
109567
  const CPP_PRIMITIVE_TYPES = {
109303
109568
  className: "type",
109304
109569
  begin: "\\b[a-z\\d_]*_t\\b"
@@ -109357,10 +109622,10 @@ function cpp(hljs) {
109357
109622
  };
109358
109623
  const TITLE_MODE = {
109359
109624
  className: "title",
109360
- begin: regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE,
109625
+ begin: regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE,
109361
109626
  relevance: 0
109362
109627
  };
109363
- const FUNCTION_TITLE = regex2.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
109628
+ const FUNCTION_TITLE = regex4.optional(NAMESPACE_RE) + hljs.IDENT_RE + "\\s*\\(";
109364
109629
  const RESERVED_KEYWORDS = [
109365
109630
  "alignas",
109366
109631
  "alignof",
@@ -109650,7 +109915,7 @@ function cpp(hljs) {
109650
109915
  keywords: {
109651
109916
  _hint: FUNCTION_HINTS
109652
109917
  },
109653
- begin: regex2.concat(/\b/, /(?!decltype)/, /(?!if)/, /(?!for)/, /(?!switch)/, /(?!while)/, hljs.IDENT_RE, regex2.lookahead(/(<[^<>]+>|)\s*\(/))
109918
+ begin: regex4.concat(/\b/, /(?!decltype)/, /(?!if)/, /(?!for)/, /(?!switch)/, /(?!while)/, hljs.IDENT_RE, regex4.lookahead(/(<[^<>]+>|)\s*\(/))
109654
109919
  };
109655
109920
  const EXPRESSION_CONTAINS = [
109656
109921
  FUNCTION_DISPATCH,
@@ -110196,7 +110461,7 @@ var init_csharp = () => {};
110196
110461
 
110197
110462
  // node_modules/highlight.js/es/languages/css.js
110198
110463
  function css(hljs) {
110199
- const regex2 = hljs.regex;
110464
+ const regex4 = hljs.regex;
110200
110465
  const modes = MODES(hljs);
110201
110466
  const VENDOR_PREFIX = { begin: /-(webkit|moz|ms|o)-(?=[a-z])/ };
110202
110467
  const AT_MODIFIERS = "and or not only";
@@ -110269,7 +110534,7 @@ function css(hljs) {
110269
110534
  ]
110270
110535
  },
110271
110536
  {
110272
- begin: regex2.lookahead(/@/),
110537
+ begin: regex4.lookahead(/@/),
110273
110538
  end: "[{;]",
110274
110539
  relevance: 0,
110275
110540
  illegal: /:/,
@@ -111101,7 +111366,7 @@ var init_css2 = __esm(() => {
111101
111366
 
111102
111367
  // node_modules/highlight.js/es/languages/diff.js
111103
111368
  function diff2(hljs) {
111104
- const regex2 = hljs.regex;
111369
+ const regex4 = hljs.regex;
111105
111370
  return {
111106
111371
  name: "Diff",
111107
111372
  aliases: ["patch"],
@@ -111109,13 +111374,13 @@ function diff2(hljs) {
111109
111374
  {
111110
111375
  className: "meta",
111111
111376
  relevance: 10,
111112
- match: regex2.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/, /^\*\*\* +\d+,\d+ +\*\*\*\*$/, /^--- +\d+,\d+ +----$/)
111377
+ match: regex4.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/, /^\*\*\* +\d+,\d+ +\*\*\*\*$/, /^--- +\d+,\d+ +----$/)
111113
111378
  },
111114
111379
  {
111115
111380
  className: "comment",
111116
111381
  variants: [
111117
111382
  {
111118
- begin: regex2.either(/Index: /, /^index/, /={3,}/, /^-{3}/, /^\*{3} /, /^\+{3}/, /^diff --git/),
111383
+ begin: regex4.either(/Index: /, /^index/, /={3,}/, /^-{3}/, /^\*{3} /, /^\+{3}/, /^diff --git/),
111119
111384
  end: /$/
111120
111385
  },
111121
111386
  { match: /^\*{15}$/ }
@@ -111292,7 +111557,7 @@ var init_go = () => {};
111292
111557
 
111293
111558
  // node_modules/highlight.js/es/languages/graphql.js
111294
111559
  function graphql(hljs) {
111295
- const regex2 = hljs.regex;
111560
+ const regex4 = hljs.regex;
111296
111561
  const GQL_NAME = /[_A-Za-z][_0-9A-Za-z]*/;
111297
111562
  return {
111298
111563
  name: "GraphQL",
@@ -111349,7 +111614,7 @@ function graphql(hljs) {
111349
111614
  },
111350
111615
  {
111351
111616
  scope: "symbol",
111352
- begin: regex2.concat(GQL_NAME, regex2.lookahead(/\s*:/)),
111617
+ begin: regex4.concat(GQL_NAME, regex4.lookahead(/\s*:/)),
111353
111618
  relevance: 0
111354
111619
  }
111355
111620
  ],
@@ -111363,7 +111628,7 @@ var init_graphql = () => {};
111363
111628
 
111364
111629
  // node_modules/highlight.js/es/languages/ini.js
111365
111630
  function ini(hljs) {
111366
- const regex2 = hljs.regex;
111631
+ const regex4 = hljs.regex;
111367
111632
  const NUMBERS = {
111368
111633
  className: "number",
111369
111634
  relevance: 0,
@@ -111434,8 +111699,8 @@ function ini(hljs) {
111434
111699
  const BARE_KEY = /[A-Za-z0-9_-]+/;
111435
111700
  const QUOTED_KEY_DOUBLE_QUOTE = /"(\\"|[^"])*"/;
111436
111701
  const QUOTED_KEY_SINGLE_QUOTE = /'[^']*'/;
111437
- const ANY_KEY = regex2.either(BARE_KEY, QUOTED_KEY_DOUBLE_QUOTE, QUOTED_KEY_SINGLE_QUOTE);
111438
- const DOTTED_KEY = regex2.concat(ANY_KEY, "(\\s*\\.\\s*", ANY_KEY, ")*", regex2.lookahead(/\s*=\s*[^#\s]/));
111702
+ const ANY_KEY = regex4.either(BARE_KEY, QUOTED_KEY_DOUBLE_QUOTE, QUOTED_KEY_SINGLE_QUOTE);
111703
+ const DOTTED_KEY = regex4.concat(ANY_KEY, "(\\s*\\.\\s*", ANY_KEY, ")*", regex4.lookahead(/\s*=\s*[^#\s]/));
111439
111704
  return {
111440
111705
  name: "TOML, also INI",
111441
111706
  aliases: ["toml"],
@@ -111477,7 +111742,7 @@ function recurRegex(re, substitution, depth) {
111477
111742
  });
111478
111743
  }
111479
111744
  function java(hljs) {
111480
- const regex2 = hljs.regex;
111745
+ const regex4 = hljs.regex;
111481
111746
  const JAVA_IDENT_RE = "[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*";
111482
111747
  const GENERIC_IDENT_RE = JAVA_IDENT_RE + recurRegex("(?:<" + JAVA_IDENT_RE + "~~~(?:\\s*,\\s*" + JAVA_IDENT_RE + "~~~)*>)?", /~~~/g, 2);
111483
111748
  const MAIN_KEYWORDS = [
@@ -111622,7 +111887,7 @@ function java(hljs) {
111622
111887
  },
111623
111888
  {
111624
111889
  begin: [
111625
- regex2.concat(/(?!else)/, JAVA_IDENT_RE),
111890
+ regex4.concat(/(?!else)/, JAVA_IDENT_RE),
111626
111891
  /\s+/,
111627
111892
  JAVA_IDENT_RE,
111628
111893
  /\s+/,
@@ -111708,7 +111973,7 @@ var init_java = __esm(() => {
111708
111973
 
111709
111974
  // node_modules/highlight.js/es/languages/javascript.js
111710
111975
  function javascript(hljs) {
111711
- const regex2 = hljs.regex;
111976
+ const regex4 = hljs.regex;
111712
111977
  const hasClosingTag = (match3, { after }) => {
111713
111978
  const tag = "</" + match3[0].slice(1);
111714
111979
  const pos = match3.input.indexOf(tag, after);
@@ -111914,7 +112179,7 @@ function javascript(hljs) {
111914
112179
  /\s+/,
111915
112180
  /extends/,
111916
112181
  /\s+/,
111917
- regex2.concat(IDENT_RE$1, "(", regex2.concat(/\./, IDENT_RE$1), ")*")
112182
+ regex4.concat(IDENT_RE$1, "(", regex4.concat(/\./, IDENT_RE$1), ")*")
111918
112183
  ],
111919
112184
  scope: {
111920
112185
  1: "keyword",
@@ -111938,7 +112203,7 @@ function javascript(hljs) {
111938
112203
  };
111939
112204
  const CLASS_REFERENCE = {
111940
112205
  relevance: 0,
111941
- match: regex2.either(/\bJSON/, /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
112206
+ match: regex4.either(/\bJSON/, /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
111942
112207
  className: "title.class",
111943
112208
  keywords: {
111944
112209
  _: [
@@ -111984,19 +112249,19 @@ function javascript(hljs) {
111984
112249
  className: "variable.constant"
111985
112250
  };
111986
112251
  function noneOf(list) {
111987
- return regex2.concat("(?!", list.join("|"), ")");
112252
+ return regex4.concat("(?!", list.join("|"), ")");
111988
112253
  }
111989
112254
  const FUNCTION_CALL = {
111990
- match: regex2.concat(/\b/, noneOf([
112255
+ match: regex4.concat(/\b/, noneOf([
111991
112256
  ...BUILT_IN_GLOBALS,
111992
112257
  "super",
111993
112258
  "import"
111994
- ].map((x) => `${x}\\s*\\(`)), IDENT_RE$1, regex2.lookahead(/\s*\(/)),
112259
+ ].map((x) => `${x}\\s*\\(`)), IDENT_RE$1, regex4.lookahead(/\s*\(/)),
111995
112260
  className: "title.function",
111996
112261
  relevance: 0
111997
112262
  };
111998
112263
  const PROPERTY_ACCESS = {
111999
- begin: regex2.concat(/\./, regex2.lookahead(regex2.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/))),
112264
+ begin: regex4.concat(/\./, regex4.lookahead(regex4.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/))),
112000
112265
  end: IDENT_RE$1,
112001
112266
  excludeBegin: true,
112002
112267
  keywords: "prototype",
@@ -112030,7 +112295,7 @@ function javascript(hljs) {
112030
112295
  /\s*/,
112031
112296
  /=\s*/,
112032
112297
  /(async\s*)?/,
112033
- regex2.lookahead(FUNC_LEAD_IN_RE)
112298
+ regex4.lookahead(FUNC_LEAD_IN_RE)
112034
112299
  ],
112035
112300
  keywords: "async",
112036
112301
  className: {
@@ -112066,7 +112331,7 @@ function javascript(hljs) {
112066
112331
  CLASS_REFERENCE,
112067
112332
  {
112068
112333
  scope: "attr",
112069
- match: IDENT_RE$1 + regex2.lookahead(":"),
112334
+ match: IDENT_RE$1 + regex4.lookahead(":"),
112070
112335
  relevance: 0
112071
112336
  },
112072
112337
  FUNCTION_VARIABLE,
@@ -113677,7 +113942,7 @@ var init_makefile = () => {};
113677
113942
 
113678
113943
  // node_modules/highlight.js/es/languages/markdown.js
113679
113944
  function markdown(hljs) {
113680
- const regex2 = hljs.regex;
113945
+ const regex4 = hljs.regex;
113681
113946
  const INLINE_HTML = {
113682
113947
  begin: /<\/?[A-Za-z_]/,
113683
113948
  end: ">",
@@ -113751,7 +114016,7 @@ function markdown(hljs) {
113751
114016
  relevance: 2
113752
114017
  },
113753
114018
  {
113754
- begin: regex2.concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
114019
+ begin: regex4.concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
113755
114020
  relevance: 2
113756
114021
  },
113757
114022
  {
@@ -114141,7 +114406,7 @@ var init_objectivec = () => {};
114141
114406
 
114142
114407
  // node_modules/highlight.js/es/languages/perl.js
114143
114408
  function perl(hljs) {
114144
- const regex2 = hljs.regex;
114409
+ const regex4 = hljs.regex;
114145
114410
  const KEYWORDS2 = [
114146
114411
  "abs",
114147
114412
  "accept",
@@ -114401,7 +114666,7 @@ function perl(hljs) {
114401
114666
  variants: [
114402
114667
  { begin: /\$\d/ },
114403
114668
  {
114404
- begin: regex2.concat(/[$%@](?!")(\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/, `(?![A-Za-z])(?![@$%])`)
114669
+ begin: regex4.concat(/[$%@](?!")(\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/, `(?![A-Za-z])(?![@$%])`)
114405
114670
  },
114406
114671
  {
114407
114672
  begin: /[$%@](?!")[^\s\w{=]|\$=/,
@@ -114436,11 +114701,11 @@ function perl(hljs) {
114436
114701
  /#/
114437
114702
  ];
114438
114703
  const PAIRED_DOUBLE_RE = (prefix, open2, close = "\\1") => {
114439
- const middle = close === "\\1" ? close : regex2.concat(close, open2);
114440
- return regex2.concat(regex2.concat("(?:", prefix, ")"), open2, /(?:\\.|[^\\\/])*?/, middle, /(?:\\.|[^\\\/])*?/, close, REGEX_MODIFIERS);
114704
+ const middle = close === "\\1" ? close : regex4.concat(close, open2);
114705
+ return regex4.concat(regex4.concat("(?:", prefix, ")"), open2, /(?:\\.|[^\\\/])*?/, middle, /(?:\\.|[^\\\/])*?/, close, REGEX_MODIFIERS);
114441
114706
  };
114442
114707
  const PAIRED_RE = (prefix, open2, close) => {
114443
- return regex2.concat(regex2.concat("(?:", prefix, ")"), open2, /(?:\\.|[^\\\/])*?/, close, REGEX_MODIFIERS);
114708
+ return regex4.concat(regex4.concat("(?:", prefix, ")"), open2, /(?:\\.|[^\\\/])*?/, close, REGEX_MODIFIERS);
114444
114709
  };
114445
114710
  const PERL_DEFAULT_CONTAINS = [
114446
114711
  VAR,
@@ -114515,7 +114780,7 @@ function perl(hljs) {
114515
114780
  {
114516
114781
  className: "regexp",
114517
114782
  variants: [
114518
- { begin: PAIRED_DOUBLE_RE("s|tr|y", regex2.either(...REGEX_DELIMS, { capture: true })) },
114783
+ { begin: PAIRED_DOUBLE_RE("s|tr|y", regex4.either(...REGEX_DELIMS, { capture: true })) },
114519
114784
  { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\(", "\\)") },
114520
114785
  { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\[", "\\]") },
114521
114786
  { begin: PAIRED_DOUBLE_RE("s|tr|y", "\\{", "\\}") }
@@ -114530,7 +114795,7 @@ function perl(hljs) {
114530
114795
  relevance: 0
114531
114796
  },
114532
114797
  { begin: PAIRED_RE("(?:m|qr)?", /\//, /\//) },
114533
- { begin: PAIRED_RE("m|qr", regex2.either(...REGEX_DELIMS, { capture: true }), /\1/) },
114798
+ { begin: PAIRED_RE("m|qr", regex4.either(...REGEX_DELIMS, { capture: true }), /\1/) },
114534
114799
  { begin: PAIRED_RE("m|qr", /\(/, /\)/) },
114535
114800
  { begin: PAIRED_RE("m|qr", /\[/, /\]/) },
114536
114801
  { begin: PAIRED_RE("m|qr", /\{/, /\}/) }
@@ -114587,11 +114852,11 @@ var init_perl = () => {};
114587
114852
 
114588
114853
  // node_modules/highlight.js/es/languages/php.js
114589
114854
  function php(hljs) {
114590
- const regex2 = hljs.regex;
114855
+ const regex4 = hljs.regex;
114591
114856
  const NOT_PERL_ETC = /(?![A-Za-z0-9])(?![$])/;
114592
- const IDENT_RE2 = regex2.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/, NOT_PERL_ETC);
114593
- const PASCAL_CASE_CLASS_NAME_RE = regex2.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/, NOT_PERL_ETC);
114594
- const UPCASE_NAME_RE = regex2.concat(/[A-Z]+/, NOT_PERL_ETC);
114857
+ const IDENT_RE2 = regex4.concat(/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/, NOT_PERL_ETC);
114858
+ const PASCAL_CASE_CLASS_NAME_RE = regex4.concat(/(\\?[A-Z][a-z0-9_\x7f-\xff]+|\\?[A-Z]+(?=[A-Z][a-z0-9_\x7f-\xff])){1,}/, NOT_PERL_ETC);
114859
+ const UPCASE_NAME_RE = regex4.concat(/[A-Z]+/, NOT_PERL_ETC);
114595
114860
  const VARIABLE = {
114596
114861
  scope: "variable",
114597
114862
  match: "\\$+" + IDENT_RE2
@@ -114870,8 +115135,8 @@ function php(hljs) {
114870
115135
  {
114871
115136
  match: [
114872
115137
  /new/,
114873
- regex2.concat(WHITESPACE, "+"),
114874
- regex2.concat("(?!", normalizeKeywords(BUILT_INS2).join("\\b|"), "\\b)"),
115138
+ regex4.concat(WHITESPACE, "+"),
115139
+ regex4.concat("(?!", normalizeKeywords(BUILT_INS2).join("\\b|"), "\\b)"),
114875
115140
  PASCAL_CASE_CLASS_NAME_RE
114876
115141
  ],
114877
115142
  scope: {
@@ -114880,11 +115145,11 @@ function php(hljs) {
114880
115145
  }
114881
115146
  }
114882
115147
  ] };
114883
- const CONSTANT_REFERENCE = regex2.concat(IDENT_RE2, "\\b(?!\\()");
115148
+ const CONSTANT_REFERENCE = regex4.concat(IDENT_RE2, "\\b(?!\\()");
114884
115149
  const LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON = { variants: [
114885
115150
  {
114886
115151
  match: [
114887
- regex2.concat(/::/, regex2.lookahead(/(?!class\b)/)),
115152
+ regex4.concat(/::/, regex4.lookahead(/(?!class\b)/)),
114888
115153
  CONSTANT_REFERENCE
114889
115154
  ],
114890
115155
  scope: { 2: "variable.constant" }
@@ -114899,7 +115164,7 @@ function php(hljs) {
114899
115164
  {
114900
115165
  match: [
114901
115166
  PASCAL_CASE_CLASS_NAME_RE,
114902
- regex2.concat(/::/, regex2.lookahead(/(?!class\b)/)),
115167
+ regex4.concat(/::/, regex4.lookahead(/(?!class\b)/)),
114903
115168
  CONSTANT_REFERENCE
114904
115169
  ],
114905
115170
  scope: {
@@ -114910,7 +115175,7 @@ function php(hljs) {
114910
115175
  {
114911
115176
  match: [
114912
115177
  PASCAL_CASE_CLASS_NAME_RE,
114913
- regex2.concat("::", regex2.lookahead(/(?!class\b)/))
115178
+ regex4.concat("::", regex4.lookahead(/(?!class\b)/))
114914
115179
  ],
114915
115180
  scope: { 1: "title.class" }
114916
115181
  },
@@ -114928,7 +115193,7 @@ function php(hljs) {
114928
115193
  ] };
114929
115194
  const NAMED_ARGUMENT = {
114930
115195
  scope: "attr",
114931
- match: regex2.concat(IDENT_RE2, regex2.lookahead(":"), regex2.lookahead(/(?!::)/))
115196
+ match: regex4.concat(IDENT_RE2, regex4.lookahead(":"), regex4.lookahead(/(?!::)/))
114932
115197
  };
114933
115198
  const PARAMS_MODE = {
114934
115199
  relevance: 0,
@@ -114949,10 +115214,10 @@ function php(hljs) {
114949
115214
  relevance: 0,
114950
115215
  match: [
114951
115216
  /\b/,
114952
- regex2.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS2).join("\\b|"), "\\b)"),
115217
+ regex4.concat("(?!fn\\b|function\\b|", normalizeKeywords(KWS).join("\\b|"), "|", normalizeKeywords(BUILT_INS2).join("\\b|"), "\\b)"),
114953
115218
  IDENT_RE2,
114954
- regex2.concat(WHITESPACE, "*"),
114955
- regex2.lookahead(/(?=\()/)
115219
+ regex4.concat(WHITESPACE, "*"),
115220
+ regex4.lookahead(/(?=\()/)
114956
115221
  ],
114957
115222
  scope: { 3: "title.function.invoke" },
114958
115223
  contains: [PARAMS_MODE]
@@ -114967,7 +115232,7 @@ function php(hljs) {
114967
115232
  CONSTRUCTOR_CALL
114968
115233
  ];
114969
115234
  const ATTRIBUTES3 = {
114970
- begin: regex2.concat(/#\[\s*\\?/, regex2.either(PASCAL_CASE_CLASS_NAME_RE, UPCASE_NAME_RE)),
115235
+ begin: regex4.concat(/#\[\s*\\?/, regex4.either(PASCAL_CASE_CLASS_NAME_RE, UPCASE_NAME_RE)),
114971
115236
  beginScope: "meta",
114972
115237
  end: /]/,
114973
115238
  endScope: "meta",
@@ -115191,7 +115456,7 @@ var init_plaintext = () => {};
115191
115456
 
115192
115457
  // node_modules/highlight.js/es/languages/python.js
115193
115458
  function python(hljs) {
115194
- const regex2 = hljs.regex;
115459
+ const regex4 = hljs.regex;
115195
115460
  const IDENT_RE2 = /[\p{XID_Start}_]\p{XID_Continue}*/u;
115196
115461
  const RESERVED_WORDS = [
115197
115462
  "and",
@@ -115459,7 +115724,7 @@ function python(hljs) {
115459
115724
  };
115460
115725
  const COMMENT_TYPE = {
115461
115726
  className: "comment",
115462
- begin: regex2.lookahead(/# type:/),
115727
+ begin: regex4.lookahead(/# type:/),
115463
115728
  end: /$/,
115464
115729
  keywords: KEYWORDS2,
115465
115730
  contains: [
@@ -115607,11 +115872,11 @@ var init_python_repl = () => {};
115607
115872
 
115608
115873
  // node_modules/highlight.js/es/languages/r.js
115609
115874
  function r(hljs) {
115610
- const regex2 = hljs.regex;
115875
+ const regex4 = hljs.regex;
115611
115876
  const IDENT_RE2 = /(?:(?:[a-zA-Z]|\.[._a-zA-Z])[._a-zA-Z0-9]*)|\.(?!\d)/;
115612
- const NUMBER_TYPES_RE = regex2.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/, /0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/, /(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/);
115877
+ const NUMBER_TYPES_RE = regex4.either(/0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*[pP][+-]?\d+i?/, /0[xX][0-9a-fA-F]+(?:[pP][+-]?\d+)?[Li]?/, /(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?[Li]?/);
115613
115878
  const OPERATORS_RE = /[=!<>:]=|\|\||&&|:::?|<-|<<-|->>|->|\|>|[-+*\/?!$&|:<=>@^~]|\*\*/;
115614
- const PUNCTUATION_RE = regex2.either(/[()]/, /[{}]/, /\[\[/, /[[\]]/, /\\/, /,/);
115879
+ const PUNCTUATION_RE = regex4.either(/[()]/, /[{}]/, /\[\[/, /[[\]]/, /\\/, /,/);
115615
115880
  return {
115616
115881
  name: "R",
115617
115882
  keywords: {
@@ -115626,7 +115891,7 @@ function r(hljs) {
115626
115891
  scope: "doctag",
115627
115892
  match: /@examples/,
115628
115893
  starts: {
115629
- end: regex2.lookahead(regex2.either(/\n^#'\s*(?=@[a-zA-Z]+)/, /\n^(?!#')/)),
115894
+ end: regex4.lookahead(regex4.either(/\n^#'\s*(?=@[a-zA-Z]+)/, /\n^(?!#')/)),
115630
115895
  endsParent: true
115631
115896
  }
115632
115897
  },
@@ -115771,10 +116036,10 @@ var init_r = () => {};
115771
116036
 
115772
116037
  // node_modules/highlight.js/es/languages/ruby.js
115773
116038
  function ruby(hljs) {
115774
- const regex2 = hljs.regex;
116039
+ const regex4 = hljs.regex;
115775
116040
  const RUBY_METHOD_RE = "([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)";
115776
- const CLASS_NAME_RE = regex2.either(/\b([A-Z]+[a-z0-9]+)+/, /\b([A-Z]+[a-z0-9]+)+[A-Z]+/);
115777
- const CLASS_NAME_WITH_NAMESPACE_RE = regex2.concat(CLASS_NAME_RE, /(::\w+)*/);
116041
+ const CLASS_NAME_RE = regex4.either(/\b([A-Z]+[a-z0-9]+)+/, /\b([A-Z]+[a-z0-9]+)+[A-Z]+/);
116042
+ const CLASS_NAME_WITH_NAMESPACE_RE = regex4.concat(CLASS_NAME_RE, /(::\w+)*/);
115778
116043
  const PSEUDO_KWS = [
115779
116044
  "include",
115780
116045
  "extend",
@@ -115927,7 +116192,7 @@ function ruby(hljs) {
115927
116192
  { begin: /\B\?\\(c|C-)[\x20-\x7e]/ },
115928
116193
  { begin: /\B\?\\?\S/ },
115929
116194
  {
115930
- begin: regex2.concat(/<<[-~]?'?/, regex2.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),
116195
+ begin: regex4.concat(/<<[-~]?'?/, regex4.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),
115931
116196
  contains: [
115932
116197
  hljs.END_SAME_AS_BEGIN({
115933
116198
  begin: /(\w+)/,
@@ -116156,14 +116421,14 @@ var init_ruby = () => {};
116156
116421
 
116157
116422
  // node_modules/highlight.js/es/languages/rust.js
116158
116423
  function rust(hljs) {
116159
- const regex2 = hljs.regex;
116424
+ const regex4 = hljs.regex;
116160
116425
  const RAW_IDENTIFIER = /(r#)?/;
116161
- const UNDERSCORE_IDENT_RE = regex2.concat(RAW_IDENTIFIER, hljs.UNDERSCORE_IDENT_RE);
116162
- const IDENT_RE2 = regex2.concat(RAW_IDENTIFIER, hljs.IDENT_RE);
116426
+ const UNDERSCORE_IDENT_RE = regex4.concat(RAW_IDENTIFIER, hljs.UNDERSCORE_IDENT_RE);
116427
+ const IDENT_RE2 = regex4.concat(RAW_IDENTIFIER, hljs.IDENT_RE);
116163
116428
  const FUNCTION_INVOKE = {
116164
116429
  className: "title.function.invoke",
116165
116430
  relevance: 0,
116166
- begin: regex2.concat(/\b/, /(?!let|for|while|if|else|match\b)/, IDENT_RE2, regex2.lookahead(/\s*\(/))
116431
+ begin: regex4.concat(/\b/, /(?!let|for|while|if|else|match\b)/, IDENT_RE2, regex4.lookahead(/\s*\(/))
116167
116432
  };
116168
116433
  const NUMBER_SUFFIX = "([ui](8|16|32|64|128|size)|f(32|64))?";
116169
116434
  const KEYWORDS2 = [
@@ -117383,7 +117648,7 @@ var init_shell = () => {};
117383
117648
 
117384
117649
  // node_modules/highlight.js/es/languages/sql.js
117385
117650
  function sql(hljs) {
117386
- const regex2 = hljs.regex;
117651
+ const regex4 = hljs.regex;
117387
117652
  const COMMENT_MODE = hljs.COMMENT("--", "$");
117388
117653
  const STRING = {
117389
117654
  scope: "string",
@@ -117957,12 +118222,12 @@ function sql(hljs) {
117957
118222
  relevance: 0
117958
118223
  };
117959
118224
  const FUNCTION_CALL = {
117960
- match: regex2.concat(/\b/, regex2.either(...FUNCTIONS), /\s*\(/),
118225
+ match: regex4.concat(/\b/, regex4.either(...FUNCTIONS), /\s*\(/),
117961
118226
  relevance: 0,
117962
118227
  keywords: { built_in: FUNCTIONS }
117963
118228
  };
117964
118229
  function kws_to_regex(list) {
117965
- return regex2.concat(/\b/, regex2.either(...list.map((kw) => {
118230
+ return regex4.concat(/\b/, regex4.either(...list.map((kw) => {
117966
118231
  return kw.replace(/\s+/, "\\s+");
117967
118232
  })), /\b/);
117968
118233
  }
@@ -118774,7 +119039,7 @@ var init_swift = __esm(() => {
118774
119039
 
118775
119040
  // node_modules/highlight.js/es/languages/typescript.js
118776
119041
  function javascript2(hljs) {
118777
- const regex2 = hljs.regex;
119042
+ const regex4 = hljs.regex;
118778
119043
  const hasClosingTag = (match3, { after }) => {
118779
119044
  const tag = "</" + match3[0].slice(1);
118780
119045
  const pos = match3.input.indexOf(tag, after);
@@ -118980,7 +119245,7 @@ function javascript2(hljs) {
118980
119245
  /\s+/,
118981
119246
  /extends/,
118982
119247
  /\s+/,
118983
- regex2.concat(IDENT_RE$1, "(", regex2.concat(/\./, IDENT_RE$1), ")*")
119248
+ regex4.concat(IDENT_RE$1, "(", regex4.concat(/\./, IDENT_RE$1), ")*")
118984
119249
  ],
118985
119250
  scope: {
118986
119251
  1: "keyword",
@@ -119004,7 +119269,7 @@ function javascript2(hljs) {
119004
119269
  };
119005
119270
  const CLASS_REFERENCE = {
119006
119271
  relevance: 0,
119007
- match: regex2.either(/\bJSON/, /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
119272
+ match: regex4.either(/\bJSON/, /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/, /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/, /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),
119008
119273
  className: "title.class",
119009
119274
  keywords: {
119010
119275
  _: [
@@ -119050,19 +119315,19 @@ function javascript2(hljs) {
119050
119315
  className: "variable.constant"
119051
119316
  };
119052
119317
  function noneOf(list) {
119053
- return regex2.concat("(?!", list.join("|"), ")");
119318
+ return regex4.concat("(?!", list.join("|"), ")");
119054
119319
  }
119055
119320
  const FUNCTION_CALL = {
119056
- match: regex2.concat(/\b/, noneOf([
119321
+ match: regex4.concat(/\b/, noneOf([
119057
119322
  ...BUILT_IN_GLOBALS2,
119058
119323
  "super",
119059
119324
  "import"
119060
- ].map((x) => `${x}\\s*\\(`)), IDENT_RE$1, regex2.lookahead(/\s*\(/)),
119325
+ ].map((x) => `${x}\\s*\\(`)), IDENT_RE$1, regex4.lookahead(/\s*\(/)),
119061
119326
  className: "title.function",
119062
119327
  relevance: 0
119063
119328
  };
119064
119329
  const PROPERTY_ACCESS = {
119065
- begin: regex2.concat(/\./, regex2.lookahead(regex2.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/))),
119330
+ begin: regex4.concat(/\./, regex4.lookahead(regex4.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/))),
119066
119331
  end: IDENT_RE$1,
119067
119332
  excludeBegin: true,
119068
119333
  keywords: "prototype",
@@ -119096,7 +119361,7 @@ function javascript2(hljs) {
119096
119361
  /\s*/,
119097
119362
  /=\s*/,
119098
119363
  /(async\s*)?/,
119099
- regex2.lookahead(FUNC_LEAD_IN_RE)
119364
+ regex4.lookahead(FUNC_LEAD_IN_RE)
119100
119365
  ],
119101
119366
  keywords: "async",
119102
119367
  className: {
@@ -119132,7 +119397,7 @@ function javascript2(hljs) {
119132
119397
  CLASS_REFERENCE,
119133
119398
  {
119134
119399
  scope: "attr",
119135
- match: IDENT_RE$1 + regex2.lookahead(":"),
119400
+ match: IDENT_RE$1 + regex4.lookahead(":"),
119136
119401
  relevance: 0
119137
119402
  },
119138
119403
  FUNCTION_VARIABLE,
@@ -119241,7 +119506,7 @@ function javascript2(hljs) {
119241
119506
  };
119242
119507
  }
119243
119508
  function typescript(hljs) {
119244
- const regex2 = hljs.regex;
119509
+ const regex4 = hljs.regex;
119245
119510
  const tsLanguage = javascript2(hljs);
119246
119511
  const IDENT_RE$1 = IDENT_RE2;
119247
119512
  const TYPES3 = [
@@ -119317,7 +119582,7 @@ function typescript(hljs) {
119317
119582
  Object.assign(tsLanguage.keywords, KEYWORDS$1);
119318
119583
  tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR);
119319
119584
  const ATTRIBUTE_HIGHLIGHT = tsLanguage.contains.find((c2) => c2.scope === "attr");
119320
- const OPTIONAL_KEY_OR_ARGUMENT = Object.assign({}, ATTRIBUTE_HIGHLIGHT, { match: regex2.concat(IDENT_RE$1, regex2.lookahead(/\s*\?:/)) });
119585
+ const OPTIONAL_KEY_OR_ARGUMENT = Object.assign({}, ATTRIBUTE_HIGHLIGHT, { match: regex4.concat(IDENT_RE$1, regex4.lookahead(/\s*\?:/)) });
119321
119586
  tsLanguage.exports.PARAMS_CONTAINS.push([
119322
119587
  tsLanguage.exports.CLASS_REFERENCE,
119323
119588
  ATTRIBUTE_HIGHLIGHT,
@@ -119482,7 +119747,7 @@ var init_typescript2 = __esm(() => {
119482
119747
 
119483
119748
  // node_modules/highlight.js/es/languages/vbnet.js
119484
119749
  function vbnet(hljs) {
119485
- const regex2 = hljs.regex;
119750
+ const regex4 = hljs.regex;
119486
119751
  const CHARACTER = {
119487
119752
  className: "string",
119488
119753
  begin: /"(""|[^/n])"C\b/
@@ -119506,16 +119771,16 @@ function vbnet(hljs) {
119506
119771
  className: "literal",
119507
119772
  variants: [
119508
119773
  {
119509
- begin: regex2.concat(/# */, regex2.either(YYYY_MM_DD, MM_DD_YYYY), / *#/)
119774
+ begin: regex4.concat(/# */, regex4.either(YYYY_MM_DD, MM_DD_YYYY), / *#/)
119510
119775
  },
119511
119776
  {
119512
- begin: regex2.concat(/# */, TIME_24H, / *#/)
119777
+ begin: regex4.concat(/# */, TIME_24H, / *#/)
119513
119778
  },
119514
119779
  {
119515
- begin: regex2.concat(/# */, TIME_12H, / *#/)
119780
+ begin: regex4.concat(/# */, TIME_12H, / *#/)
119516
119781
  },
119517
119782
  {
119518
- begin: regex2.concat(/# */, regex2.either(YYYY_MM_DD, MM_DD_YYYY), / +/, regex2.either(TIME_12H, TIME_24H), / *#/)
119783
+ begin: regex4.concat(/# */, regex4.either(YYYY_MM_DD, MM_DD_YYYY), / +/, regex4.either(TIME_12H, TIME_24H), / *#/)
119519
119784
  }
119520
119785
  ]
119521
119786
  };
@@ -119711,8 +119976,8 @@ var init_wasm = () => {};
119711
119976
 
119712
119977
  // node_modules/highlight.js/es/languages/xml.js
119713
119978
  function xml(hljs) {
119714
- const regex2 = hljs.regex;
119715
- const TAG_NAME_RE = regex2.concat(/[\p{L}_]/u, regex2.optional(/[\p{L}0-9_.-]*:/u), /[\p{L}0-9_.-]*/u);
119979
+ const regex4 = hljs.regex;
119980
+ const TAG_NAME_RE = regex4.concat(/[\p{L}_]/u, regex4.optional(/[\p{L}0-9_.-]*:/u), /[\p{L}0-9_.-]*/u);
119716
119981
  const XML_IDENT_RE = /[\p{L}0-9._:-]+/u;
119717
119982
  const XML_ENTITIES = {
119718
119983
  className: "symbol",
@@ -119875,7 +120140,7 @@ function xml(hljs) {
119875
120140
  },
119876
120141
  {
119877
120142
  className: "tag",
119878
- begin: regex2.concat(/</, regex2.lookahead(regex2.concat(TAG_NAME_RE, regex2.either(/\/>/, />/, /\s/)))),
120143
+ begin: regex4.concat(/</, regex4.lookahead(regex4.concat(TAG_NAME_RE, regex4.either(/\/>/, />/, /\s/)))),
119879
120144
  end: /\/?>/,
119880
120145
  contains: [
119881
120146
  {
@@ -119888,7 +120153,7 @@ function xml(hljs) {
119888
120153
  },
119889
120154
  {
119890
120155
  className: "tag",
119891
- begin: regex2.concat(/<\//, regex2.lookahead(regex2.concat(TAG_NAME_RE, />/))),
120156
+ begin: regex4.concat(/<\//, regex4.lookahead(regex4.concat(TAG_NAME_RE, />/))),
119892
120157
  contains: [
119893
120158
  {
119894
120159
  className: "name",
@@ -120436,10 +120701,10 @@ var require_core = __commonJS((exports, module) => {
120436
120701
  var BACKREF_RE = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
120437
120702
  function _rewriteBackreferences(regexps, { joinWith }) {
120438
120703
  let numCaptures = 0;
120439
- return regexps.map((regex2) => {
120704
+ return regexps.map((regex4) => {
120440
120705
  numCaptures += 1;
120441
120706
  const offset = numCaptures;
120442
- let re = source2(regex2);
120707
+ let re = source2(regex4);
120443
120708
  let out = "";
120444
120709
  while (re.length > 0) {
120445
120710
  const match3 = BACKREF_RE.exec(re);
@@ -129187,6 +129452,7 @@ __export(exports_terminalKeybindingInstaller, {
129187
129452
  installWezTermDeleteFix: () => installWezTermDeleteFix,
129188
129453
  installKeybindingForCurrentTerminal: () => installKeybindingForCurrentTerminal,
129189
129454
  installKeybinding: () => installKeybinding,
129455
+ injectWezTermDeleteFix: () => injectWezTermDeleteFix,
129190
129456
  getWezTermConfigPath: () => getWezTermConfigPath,
129191
129457
  getKeybindingsPath: () => getKeybindingsPath,
129192
129458
  detectTerminalType: () => detectTerminalType
@@ -129402,6 +129668,106 @@ function getWezTermConfigPath() {
129402
129668
  return configPath;
129403
129669
  return join46(homedir32(), ".wezterm.lua");
129404
129670
  }
129671
+ function stripLuaCommentsFromLine(line, blockCommentEnd) {
129672
+ let code = "";
129673
+ let index = 0;
129674
+ let currentBlockCommentEnd = blockCommentEnd;
129675
+ while (index < line.length) {
129676
+ if (currentBlockCommentEnd) {
129677
+ const closeIndex = line.indexOf(currentBlockCommentEnd, index);
129678
+ if (closeIndex === -1) {
129679
+ return { code, blockCommentEnd: currentBlockCommentEnd };
129680
+ }
129681
+ index = closeIndex + currentBlockCommentEnd.length;
129682
+ currentBlockCommentEnd = null;
129683
+ continue;
129684
+ }
129685
+ if (line.startsWith("--", index)) {
129686
+ const longCommentMatch = line.slice(index).match(/^--\[(=*)\[/);
129687
+ if (longCommentMatch) {
129688
+ const equals = longCommentMatch[1] ?? "";
129689
+ currentBlockCommentEnd = `]${equals}]`;
129690
+ index += longCommentMatch[0].length;
129691
+ continue;
129692
+ }
129693
+ break;
129694
+ }
129695
+ code += line.charAt(index);
129696
+ index += 1;
129697
+ }
129698
+ return { code, blockCommentEnd: currentBlockCommentEnd };
129699
+ }
129700
+ function getLuaCodeLines(content) {
129701
+ const lines = [];
129702
+ let start = 0;
129703
+ let blockCommentEnd = null;
129704
+ while (start < content.length) {
129705
+ const newlineIndex = content.indexOf(`
129706
+ `, start);
129707
+ const end = newlineIndex === -1 ? content.length : newlineIndex + 1;
129708
+ const rawLine = content.slice(start, end);
129709
+ const lineEnding = rawLine.endsWith(`\r
129710
+ `) ? `\r
129711
+ ` : rawLine.endsWith(`
129712
+ `) ? `
129713
+ ` : "";
129714
+ const line = lineEnding ? rawLine.slice(0, rawLine.length - lineEnding.length) : rawLine;
129715
+ const stripped = stripLuaCommentsFromLine(line, blockCommentEnd);
129716
+ blockCommentEnd = stripped.blockCommentEnd;
129717
+ lines.push({
129718
+ start,
129719
+ end,
129720
+ line,
129721
+ lineEnding,
129722
+ code: stripped.code
129723
+ });
129724
+ start = end;
129725
+ }
129726
+ return lines;
129727
+ }
129728
+ function findLastMatchingLuaLine(content, pattern) {
129729
+ let result = null;
129730
+ for (const line of getLuaCodeLines(content)) {
129731
+ if (pattern.test(line.code)) {
129732
+ result = line;
129733
+ }
129734
+ }
129735
+ return result;
129736
+ }
129737
+ function hasMatchingLuaLine(content, pattern) {
129738
+ return findLastMatchingLuaLine(content, pattern) !== null;
129739
+ }
129740
+ function replaceLuaLine(content, line, replacement) {
129741
+ return `${content.slice(0, line.start)}${replacement}${line.lineEnding}${content.slice(line.end)}`;
129742
+ }
129743
+ function injectWezTermDeleteFix(content) {
129744
+ let nextContent = content;
129745
+ const returnTableLine = findLastMatchingLuaLine(nextContent, RETURN_TABLE_LINE);
129746
+ if (returnTableLine && !hasMatchingLuaLine(nextContent, LOCAL_CONFIG_LINE)) {
129747
+ nextContent = replaceLuaLine(nextContent, returnTableLine, returnTableLine.line.replace(/return\s*\{/, "local config = {"));
129748
+ if (!hasMatchingLuaLine(nextContent, RETURN_CONFIG_LINE)) {
129749
+ nextContent = `${nextContent.trimEnd()}
129750
+
129751
+ return config
129752
+ `;
129753
+ }
129754
+ }
129755
+ if (!nextContent.trim()) {
129756
+ nextContent = `-- WezTerm configuration
129757
+ local config = {}
129758
+
129759
+ return config
129760
+ `;
129761
+ }
129762
+ const returnConfigLine = findLastMatchingLuaLine(nextContent, RETURN_CONFIG_LINE);
129763
+ if (returnConfigLine) {
129764
+ return `${nextContent.slice(0, returnConfigLine.start)}${WEZTERM_DELETE_FIX}
129765
+ ${nextContent.slice(returnConfigLine.start)}`;
129766
+ }
129767
+ return `${nextContent.trimEnd()}
129768
+ ${WEZTERM_DELETE_FIX}
129769
+ `;
129770
+ }
129405
129771
  function wezTermDeleteFixExists(configPath) {
129406
129772
  if (!existsSync39(configPath))
129407
129773
  return false;
@@ -129425,30 +129791,7 @@ function installWezTermDeleteFix() {
129425
129791
  copyFileSync(configPath, backupPath);
129426
129792
  content = readFileSync26(configPath, { encoding: "utf-8" });
129427
129793
  }
129428
- if (content.includes("return {") && !content.includes("local config")) {
129429
- content = content.replace(/return\s*\{/, "local config = {");
129430
- if (!content.includes("return config")) {
129431
- content = `${content.trimEnd()}
129432
-
129433
- return config
129434
- `;
129435
- }
129436
- }
129437
- if (!content.trim()) {
129438
- content = `-- WezTerm configuration
129439
- local config = {}
129440
-
129441
- return config
129442
- `;
129443
- }
129444
- if (content.includes("return config")) {
129445
- content = content.replace("return config", `${WEZTERM_DELETE_FIX}
129446
- return config`);
129447
- } else {
129448
- content = `${content.trimEnd()}
129449
- ${WEZTERM_DELETE_FIX}
129450
- `;
129451
- }
129794
+ content = injectWezTermDeleteFix(content);
129452
129795
  const parentDir = dirname20(configPath);
129453
129796
  if (!existsSync39(parentDir)) {
129454
129797
  mkdirSync30(parentDir, { recursive: true });
@@ -129477,7 +129820,7 @@ table.insert(keys, {
129477
129820
  action = wezterm.action.SendString '\\x1b[3~',
129478
129821
  })
129479
129822
  config.keys = keys
129480
- `;
129823
+ `, RETURN_CONFIG_LINE, RETURN_TABLE_LINE, LOCAL_CONFIG_LINE;
129481
129824
  var init_terminalKeybindingInstaller = __esm(() => {
129482
129825
  SHIFT_ENTER_KEYBINDING = {
129483
129826
  key: "shift+enter",
@@ -129485,6 +129828,9 @@ var init_terminalKeybindingInstaller = __esm(() => {
129485
129828
  args: { text: "\x1B\r" },
129486
129829
  when: "terminalFocus"
129487
129830
  };
129831
+ RETURN_CONFIG_LINE = /^\s*return\s+config\s*$/;
129832
+ RETURN_TABLE_LINE = /^\s*return\s*\{/;
129833
+ LOCAL_CONFIG_LINE = /^\s*local\s+config\b/;
129488
129834
  });
129489
129835
 
129490
129836
  // src/cli/commands/registry.ts
@@ -134001,8 +134347,8 @@ function findCursorLine(cursorPos, visualLines) {
134001
134347
  function parseOsc8Line(line, keyPrefix) {
134002
134348
  const parts = [];
134003
134349
  let lastIndex = 0;
134004
- const regex2 = new RegExp(OSC8_REGEX.source, "g");
134005
- for (let match3 = regex2.exec(line);match3 !== null; match3 = regex2.exec(line)) {
134350
+ const regex4 = new RegExp(OSC8_REGEX.source, "g");
134351
+ for (let match3 = regex4.exec(line);match3 !== null; match3 = regex4.exec(line)) {
134006
134352
  if (match3.index > lastIndex) {
134007
134353
  parts.push(/* @__PURE__ */ jsx_dev_runtime53.jsxDEV(Text2, {
134008
134354
  children: line.slice(lastIndex, match3.index)
@@ -158996,6 +159342,7 @@ __export(exports_terminalKeybindingInstaller2, {
158996
159342
  installWezTermDeleteFix: () => installWezTermDeleteFix2,
158997
159343
  installKeybindingForCurrentTerminal: () => installKeybindingForCurrentTerminal2,
158998
159344
  installKeybinding: () => installKeybinding2,
159345
+ injectWezTermDeleteFix: () => injectWezTermDeleteFix2,
158999
159346
  getWezTermConfigPath: () => getWezTermConfigPath2,
159000
159347
  getKeybindingsPath: () => getKeybindingsPath2,
159001
159348
  detectTerminalType: () => detectTerminalType2
@@ -159211,6 +159558,106 @@ function getWezTermConfigPath2() {
159211
159558
  return configPath;
159212
159559
  return join54(homedir38(), ".wezterm.lua");
159213
159560
  }
159561
+ function stripLuaCommentsFromLine2(line, blockCommentEnd) {
159562
+ let code = "";
159563
+ let index = 0;
159564
+ let currentBlockCommentEnd = blockCommentEnd;
159565
+ while (index < line.length) {
159566
+ if (currentBlockCommentEnd) {
159567
+ const closeIndex = line.indexOf(currentBlockCommentEnd, index);
159568
+ if (closeIndex === -1) {
159569
+ return { code, blockCommentEnd: currentBlockCommentEnd };
159570
+ }
159571
+ index = closeIndex + currentBlockCommentEnd.length;
159572
+ currentBlockCommentEnd = null;
159573
+ continue;
159574
+ }
159575
+ if (line.startsWith("--", index)) {
159576
+ const longCommentMatch = line.slice(index).match(/^--\[(=*)\[/);
159577
+ if (longCommentMatch) {
159578
+ const equals = longCommentMatch[1] ?? "";
159579
+ currentBlockCommentEnd = `]${equals}]`;
159580
+ index += longCommentMatch[0].length;
159581
+ continue;
159582
+ }
159583
+ break;
159584
+ }
159585
+ code += line.charAt(index);
159586
+ index += 1;
159587
+ }
159588
+ return { code, blockCommentEnd: currentBlockCommentEnd };
159589
+ }
159590
+ function getLuaCodeLines2(content) {
159591
+ const lines = [];
159592
+ let start = 0;
159593
+ let blockCommentEnd = null;
159594
+ while (start < content.length) {
159595
+ const newlineIndex = content.indexOf(`
159596
+ `, start);
159597
+ const end = newlineIndex === -1 ? content.length : newlineIndex + 1;
159598
+ const rawLine = content.slice(start, end);
159599
+ const lineEnding = rawLine.endsWith(`\r
159600
+ `) ? `\r
159601
+ ` : rawLine.endsWith(`
159602
+ `) ? `
159603
+ ` : "";
159604
+ const line = lineEnding ? rawLine.slice(0, rawLine.length - lineEnding.length) : rawLine;
159605
+ const stripped = stripLuaCommentsFromLine2(line, blockCommentEnd);
159606
+ blockCommentEnd = stripped.blockCommentEnd;
159607
+ lines.push({
159608
+ start,
159609
+ end,
159610
+ line,
159611
+ lineEnding,
159612
+ code: stripped.code
159613
+ });
159614
+ start = end;
159615
+ }
159616
+ return lines;
159617
+ }
159618
+ function findLastMatchingLuaLine2(content, pattern) {
159619
+ let result = null;
159620
+ for (const line of getLuaCodeLines2(content)) {
159621
+ if (pattern.test(line.code)) {
159622
+ result = line;
159623
+ }
159624
+ }
159625
+ return result;
159626
+ }
159627
+ function hasMatchingLuaLine2(content, pattern) {
159628
+ return findLastMatchingLuaLine2(content, pattern) !== null;
159629
+ }
159630
+ function replaceLuaLine2(content, line, replacement) {
159631
+ return `${content.slice(0, line.start)}${replacement}${line.lineEnding}${content.slice(line.end)}`;
159632
+ }
159633
+ function injectWezTermDeleteFix2(content) {
159634
+ let nextContent = content;
159635
+ const returnTableLine = findLastMatchingLuaLine2(nextContent, RETURN_TABLE_LINE2);
159636
+ if (returnTableLine && !hasMatchingLuaLine2(nextContent, LOCAL_CONFIG_LINE2)) {
159637
+ nextContent = replaceLuaLine2(nextContent, returnTableLine, returnTableLine.line.replace(/return\s*\{/, "local config = {"));
159638
+ if (!hasMatchingLuaLine2(nextContent, RETURN_CONFIG_LINE2)) {
159639
+ nextContent = `${nextContent.trimEnd()}
159640
+
159641
+ return config
159642
+ `;
159643
+ }
159644
+ }
159645
+ if (!nextContent.trim()) {
159646
+ nextContent = `-- WezTerm configuration
159647
+ local config = {}
159648
+
159649
+ return config
159650
+ `;
159651
+ }
159652
+ const returnConfigLine = findLastMatchingLuaLine2(nextContent, RETURN_CONFIG_LINE2);
159653
+ if (returnConfigLine) {
159654
+ return `${nextContent.slice(0, returnConfigLine.start)}${WEZTERM_DELETE_FIX2}
159655
+ ${nextContent.slice(returnConfigLine.start)}`;
159656
+ }
159657
+ return `${nextContent.trimEnd()}
159658
+ ${WEZTERM_DELETE_FIX2}
159659
+ `;
159660
+ }
159214
159661
  function wezTermDeleteFixExists2(configPath) {
159215
159662
  if (!existsSync46(configPath))
159216
159663
  return false;
@@ -159234,30 +159681,7 @@ function installWezTermDeleteFix2() {
159234
159681
  copyFileSync2(configPath, backupPath);
159235
159682
  content = readFileSync30(configPath, { encoding: "utf-8" });
159236
159683
  }
159237
- if (content.includes("return {") && !content.includes("local config")) {
159238
- content = content.replace(/return\s*\{/, "local config = {");
159239
- if (!content.includes("return config")) {
159240
- content = `${content.trimEnd()}
159241
-
159242
- return config
159243
- `;
159244
- }
159245
- }
159246
- if (!content.trim()) {
159247
- content = `-- WezTerm configuration
159248
- local config = {}
159249
-
159250
- return config
159251
- `;
159252
- }
159253
- if (content.includes("return config")) {
159254
- content = content.replace("return config", `${WEZTERM_DELETE_FIX2}
159255
- return config`);
159256
- } else {
159257
- content = `${content.trimEnd()}
159258
- ${WEZTERM_DELETE_FIX2}
159259
- `;
159260
- }
159684
+ content = injectWezTermDeleteFix2(content);
159261
159685
  const parentDir = dirname23(configPath);
159262
159686
  if (!existsSync46(parentDir)) {
159263
159687
  mkdirSync33(parentDir, { recursive: true });
@@ -159286,7 +159710,7 @@ table.insert(keys, {
159286
159710
  action = wezterm.action.SendString '\\x1b[3~',
159287
159711
  })
159288
159712
  config.keys = keys
159289
- `;
159713
+ `, RETURN_CONFIG_LINE2, RETURN_TABLE_LINE2, LOCAL_CONFIG_LINE2;
159290
159714
  var init_terminalKeybindingInstaller2 = __esm(() => {
159291
159715
  SHIFT_ENTER_KEYBINDING2 = {
159292
159716
  key: "shift+enter",
@@ -159294,6 +159718,9 @@ var init_terminalKeybindingInstaller2 = __esm(() => {
159294
159718
  args: { text: "\x1B\r" },
159295
159719
  when: "terminalFocus"
159296
159720
  };
159721
+ RETURN_CONFIG_LINE2 = /^\s*return\s+config\s*$/;
159722
+ RETURN_TABLE_LINE2 = /^\s*return\s*\{/;
159723
+ LOCAL_CONFIG_LINE2 = /^\s*local\s+config\b/;
159297
159724
  });
159298
159725
 
159299
159726
  // src/settings.ts
@@ -160844,6 +161271,7 @@ function getClientDefaultHeaders2() {
160844
161271
  return {
160845
161272
  "X-Letta-Source": "letta-code",
160846
161273
  "User-Agent": `letta-code/${package_default.version}`,
161274
+ "X-Letta-Environment-Device-Id": settingsManager.getOrCreateDeviceId(),
160847
161275
  ...nodeExperiment.source === "override" ? { "x-letta-node": nodeExperiment.enabled ? "1" : "0" } : nodeExperiment.enabled ? { "x-letta-node": "1" } : {}
160848
161276
  };
160849
161277
  }
@@ -160905,7 +161333,7 @@ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, a
160905
161333
  console.error(new Error("getClient() called without credentials").stack);
160906
161334
  throw new Error("Missing LETTA_API_KEY. Run 'letta' to configure authentication, or set LETTA_API_KEY to your API key.");
160907
161335
  }
160908
- return new Letta({
161336
+ const client = new Letta({
160909
161337
  apiKey,
160910
161338
  baseURL,
160911
161339
  logger: sdkLogger2,
@@ -160913,6 +161341,28 @@ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, a
160913
161341
  defaultHeaders: getClientDefaultHeaders2(),
160914
161342
  ...isTimingsEnabled() && { fetch: createTimingFetch(fetch) }
160915
161343
  });
161344
+ const MESSAGE_CACHE_MAX = 32;
161345
+ const messageCache = new Map;
161346
+ const origRetrieveMessage = client.messages.retrieve.bind(client.messages);
161347
+ client.messages.retrieve = (...args) => {
161348
+ const messageId = args[0];
161349
+ const cached = messageCache.get(messageId);
161350
+ if (cached) {
161351
+ messageCache.delete(messageId);
161352
+ messageCache.set(messageId, cached);
161353
+ return cached;
161354
+ }
161355
+ const promise = origRetrieveMessage(...args);
161356
+ messageCache.set(messageId, promise);
161357
+ if (messageCache.size > MESSAGE_CACHE_MAX) {
161358
+ const oldest = messageCache.keys().next().value;
161359
+ if (oldest !== undefined)
161360
+ messageCache.delete(oldest);
161361
+ }
161362
+ promise.catch(() => messageCache.delete(messageId));
161363
+ return promise;
161364
+ };
161365
+ return client;
160916
161366
  }
160917
161367
 
160918
161368
  // src/agent/context.ts
@@ -165010,6 +165460,23 @@ function getListenerServerUrl(settings) {
165010
165460
  const oauthDeps = getListenerOAuthDeps();
165011
165461
  return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || oauthDeps.LETTA_CLOUD_API_URL;
165012
165462
  }
165463
+ function normalizeListenerBaseUrl(url) {
165464
+ return url.trim().replace(/\/+$/, "");
165465
+ }
165466
+ function isCloudListenerServerUrl(serverUrl) {
165467
+ return normalizeListenerBaseUrl(serverUrl) === normalizeListenerBaseUrl(getListenerOAuthDeps().LETTA_CLOUD_API_URL);
165468
+ }
165469
+ async function resolveListenerStartupMode(channelNames) {
165470
+ const settings = await settingsManager.getSettingsWithSecureTokens();
165471
+ const serverUrl = getListenerServerUrl(settings);
165472
+ if (isCloudListenerServerUrl(serverUrl)) {
165473
+ return { kind: "remote", serverUrl };
165474
+ }
165475
+ if (channelNames.length > 0) {
165476
+ return { kind: "local-channels", serverUrl };
165477
+ }
165478
+ return { kind: "unsupported-self-hosted", serverUrl };
165479
+ }
165013
165480
  async function refreshListenerAccessToken(settings, deviceId, connectionName) {
165014
165481
  const oauthDeps = getListenerOAuthDeps();
165015
165482
  const now = Date.now();
@@ -165065,7 +165532,7 @@ async function resolveListenerRegistrationOptions(deviceId, connectionName) {
165065
165532
  };
165066
165533
  }
165067
165534
  let apiKey = settings.env?.LETTA_API_KEY;
165068
- if (serverUrl === LETTA_CLOUD_API_URL) {
165535
+ if (isCloudListenerServerUrl(serverUrl)) {
165069
165536
  const expiresAt = settings.tokenExpiresAt;
165070
165537
  if (settings.refreshToken && expiresAt) {
165071
165538
  const now = Date.now();
@@ -165190,6 +165657,52 @@ async function runListenSubcommand(argv) {
165190
165657
  console.log(`Log file: ${sessionLog.path}`);
165191
165658
  try {
165192
165659
  const deviceId = settingsManager.getOrCreateDeviceId();
165660
+ const startupMode = await resolveListenerStartupMode(channelNames);
165661
+ if (startupMode.kind === "unsupported-self-hosted") {
165662
+ console.error(`Self-hosted listener registration is not available for ${startupMode.serverUrl}.`);
165663
+ console.error("Start with --channels to run local channel adapters, or unset LETTA_BASE_URL to use Letta API remote environments.");
165664
+ await flushListenerTelemetryEnd("listener_self_hosted_no_channels");
165665
+ return 1;
165666
+ }
165667
+ sessionLog.log(`Session started (debug=${debugMode})`);
165668
+ sessionLog.log(`deviceId: ${deviceId}`);
165669
+ sessionLog.log(`connectionName: ${connectionName}`);
165670
+ if (startupMode.kind === "local-channels") {
165671
+ const connectionId2 = `local-${deviceId}`;
165672
+ sessionLog.log(`Starting local channel listener for ${startupMode.serverUrl}`);
165673
+ sessionLog.log("Skipping environment registration");
165674
+ console.log(`Starting local channel listener for self-hosted server ${startupMode.serverUrl}`);
165675
+ console.log(`Skipping environment registration. Press Ctrl+C to stop.
165676
+ `);
165677
+ const { startLocalChannelListener: startLocalChannelListener2 } = await init_listen_client().then(() => exports_listen_client);
165678
+ await startLocalChannelListener2({
165679
+ connectionId: connectionId2,
165680
+ deviceId,
165681
+ connectionName,
165682
+ onWsEvent: process.env.LETTA_LOG_WS_EVENTS === "1" ? (direction, label, event) => {
165683
+ sessionLog.wsEvent(direction, label, event);
165684
+ } : undefined,
165685
+ onStatusChange: (status) => {
165686
+ sessionLog.log(`status: ${status}`);
165687
+ if (debugMode) {
165688
+ console.log(`[${formatTimestamp3()}] status: ${status}`);
165689
+ }
165690
+ },
165691
+ onConnected: () => {
165692
+ sessionLog.log("Local channel listener ready.");
165693
+ if (debugMode) {
165694
+ console.log(`[${formatTimestamp3()}] Local channel listener ready.`);
165695
+ console.log("");
165696
+ }
165697
+ },
165698
+ onError: (error) => {
165699
+ sessionLog.log(`Error: ${error.message}`);
165700
+ console.error(`[${formatTimestamp3()}] Error: ${error.message}`);
165701
+ exitWithTelemetry(1, "listener_error");
165702
+ }
165703
+ });
165704
+ return new Promise(() => {});
165705
+ }
165193
165706
  let registerOptions;
165194
165707
  try {
165195
165708
  registerOptions = await resolveListenerRegistrationOptions(deviceId, connectionName);
@@ -165204,9 +165717,6 @@ async function runListenSubcommand(argv) {
165204
165717
  await flushListenerTelemetryEnd("listener_oauth_failed");
165205
165718
  return 1;
165206
165719
  }
165207
- sessionLog.log(`Session started (debug=${debugMode})`);
165208
- sessionLog.log(`deviceId: ${deviceId}`);
165209
- sessionLog.log(`connectionName: ${connectionName}`);
165210
165720
  if (debugMode) {
165211
165721
  console.log(`[${formatTimestamp3()}] Registering with ${registerOptions.serverUrl}/v1/environments/register`);
165212
165722
  console.log(`[${formatTimestamp3()}] deviceId: ${deviceId}`);
@@ -169599,4 +170109,4 @@ Error during initialization: ${message}`);
169599
170109
  }
169600
170110
  main();
169601
170111
 
169602
- //# debugId=C84A92912A26F4A364756E2164756E21
170112
+ //# debugId=1F73E48C6C64400464756E2164756E21