@verboo/code 0.7.10 → 0.7.12

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/dist/cli.mjs +245 -93
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -9712,6 +9712,12 @@ function resetTotalDurationStateAndCost_FOR_TESTS_ONLY() {
9712
9712
  STATE.totalCostUSD = 0;
9713
9713
  }
9714
9714
  function addToTotalCostState(cost, modelUsage, model) {
9715
+ if (!(model in STATE.modelUsage) && Object.keys(STATE.modelUsage).length >= MAX_TRACKED_MODELS) {
9716
+ const oldestKey = Object.keys(STATE.modelUsage)[0];
9717
+ if (oldestKey) {
9718
+ delete STATE.modelUsage[oldestKey];
9719
+ }
9720
+ }
9715
9721
  STATE.modelUsage[model] = modelUsage;
9716
9722
  STATE.totalCostUSD += cost;
9717
9723
  }
@@ -10480,7 +10486,7 @@ function isReplBridgeActive() {
10480
10486
  function getReplBridgeHandle() {
10481
10487
  return null;
10482
10488
  }
10483
- var STATE, sessionSwitched, onSessionSwitch, interactionTimeDirty = false, outputTokensAtTurnStart = 0, currentTurnTokenBudget = null, budgetContinuationCount = 0, scrollDraining = false, scrollDrainTimer, SCROLL_DRAIN_IDLE_MS = 150, EMPTY_SLOW_OPERATIONS;
10489
+ var STATE, sessionSwitched, onSessionSwitch, MAX_TRACKED_MODELS = 200, interactionTimeDirty = false, outputTokensAtTurnStart = 0, currentTurnTokenBudget = null, budgetContinuationCount = 0, scrollDraining = false, scrollDrainTimer, SCROLL_DRAIN_IDLE_MS = 150, EMPTY_SLOW_OPERATIONS;
10484
10490
  var init_state = __esm(() => {
10485
10491
  init_sumBy();
10486
10492
  init_crypto();
@@ -16780,6 +16786,8 @@ function sanitizeEnvironment(env2) {
16780
16786
  if (!env2) {
16781
16787
  return {};
16782
16788
  }
16789
+ const sanitized = {};
16790
+ const droppedKeys = [];
16783
16791
  for (const [key, value] of Object.entries(env2)) {
16784
16792
  if (CONTROL_CHAR_PATTERN.test(key)) {
16785
16793
  return {
@@ -16787,12 +16795,20 @@ function sanitizeEnvironment(env2) {
16787
16795
  };
16788
16796
  }
16789
16797
  if (typeof value === "string" && CONTROL_CHAR_PATTERN.test(value)) {
16790
- return {
16791
- error: "Unsafe environment: control characters are not allowed in values"
16792
- };
16798
+ droppedKeys.push(key);
16799
+ continue;
16800
+ }
16801
+ sanitized[key] = value;
16802
+ }
16803
+ if (droppedKeys.length > 0) {
16804
+ const newKeys = droppedKeys.filter((k) => !warnedDirtyEnvKeys.has(k));
16805
+ if (newKeys.length > 0) {
16806
+ for (const k of newKeys)
16807
+ warnedDirtyEnvKeys.add(k);
16808
+ console.warn(`[verboo] Dropping env var(s) with control characters before spawning child: ${newKeys.join(", ")}. Fix the source (likely your shell rc) to silence this.`);
16793
16809
  }
16794
16810
  }
16795
- return { value: env2 };
16811
+ return { value: sanitized };
16796
16812
  }
16797
16813
  function getErrorMessage(result, errorCode) {
16798
16814
  if (typeof result.signal === "string") {
@@ -16961,7 +16977,7 @@ function execFileNoThrowWithCwd(file, args, {
16961
16977
  });
16962
16978
  });
16963
16979
  }
16964
- var import_cross_spawn2, MS_IN_SECOND2 = 1000, SECONDS_IN_MINUTE2 = 60, DEFAULT_MAX_BUFFER = 1e6, CONTROL_CHAR_PATTERN, SAFE_BARE_EXECUTABLE_PATTERN;
16980
+ var import_cross_spawn2, MS_IN_SECOND2 = 1000, SECONDS_IN_MINUTE2 = 60, DEFAULT_MAX_BUFFER = 1e6, CONTROL_CHAR_PATTERN, SAFE_BARE_EXECUTABLE_PATTERN, warnedDirtyEnvKeys;
16965
16981
  var init_execFileNoThrow = __esm(() => {
16966
16982
  init_cwd2();
16967
16983
  init_log3();
@@ -16969,6 +16985,7 @@ var init_execFileNoThrow = __esm(() => {
16969
16985
  import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
16970
16986
  CONTROL_CHAR_PATTERN = /[\0\r\n]/;
16971
16987
  SAFE_BARE_EXECUTABLE_PATTERN = /^[A-Za-z0-9_.-]+$/;
16988
+ warnedDirtyEnvKeys = new Set;
16972
16989
  });
16973
16990
 
16974
16991
  // src/constants/oauth.ts
@@ -50468,8 +50485,11 @@ function logEvent() {}
50468
50485
 
50469
50486
  // src/utils/fileReadCache.ts
50470
50487
  class FileReadCache {
50471
- cache = new Map;
50472
- maxCacheSize = 1000;
50488
+ cache = new L({
50489
+ max: MAX_CACHE_ENTRIES,
50490
+ maxSize: MAX_CACHE_BYTES,
50491
+ sizeCalculation: (value) => Math.max(1, Buffer.byteLength(value.content))
50492
+ });
50473
50493
  readFile(filePath) {
50474
50494
  const fs2 = getFsImplementation2();
50475
50495
  let stats;
@@ -50496,12 +50516,6 @@ class FileReadCache {
50496
50516
  encoding,
50497
50517
  mtime: stats.mtimeMs
50498
50518
  });
50499
- if (this.cache.size > this.maxCacheSize) {
50500
- const firstKey = this.cache.keys().next().value;
50501
- if (firstKey) {
50502
- this.cache.delete(firstKey);
50503
- }
50504
- }
50505
50519
  return { content, encoding };
50506
50520
  }
50507
50521
  clear() {
@@ -50517,10 +50531,12 @@ class FileReadCache {
50517
50531
  };
50518
50532
  }
50519
50533
  }
50520
- var fileReadCache;
50534
+ var MAX_CACHE_ENTRIES = 1000, MAX_CACHE_BYTES, fileReadCache;
50521
50535
  var init_fileReadCache = __esm(() => {
50536
+ init_index_min();
50522
50537
  init_file();
50523
50538
  init_fsOperations();
50539
+ MAX_CACHE_BYTES = 64 * 1024 * 1024;
50524
50540
  fileReadCache = new FileReadCache;
50525
50541
  });
50526
50542
 
@@ -115502,7 +115518,7 @@ function printStartupScreen(modelOverride) {
115502
115518
  const home = process.env.HOME || process.env.USERPROFILE || "";
115503
115519
  const cwd2 = process.cwd();
115504
115520
  const displayCwd = home && cwd2.startsWith(home) ? `~${cwd2.slice(home.length)}` : cwd2;
115505
- const version2 = "0.7.10";
115521
+ const version2 = "0.7.12";
115506
115522
  const bold2 = `${ESC}1m`;
115507
115523
  const PURPLE = rgb(...ACCENT);
115508
115524
  const SOFT = rgb(...CREAM);
@@ -201938,11 +201954,13 @@ function mapOpenAICompatibilityFailureToAssistantMessage(options2) {
201938
201954
  content: `The selected model (${options2.model}) is not available on this provider. Run ${switchCmd} to choose another model, or verify installed local models (for Ollama: ollama list).`,
201939
201955
  error: "invalid_request"
201940
201956
  });
201941
- case "auth_invalid":
201957
+ case "auth_invalid": {
201958
+ const verbooFirstParty = isVerbooMode() && isFirstPartyAnthropicBaseUrl();
201942
201959
  return createAssistantAPIErrorMessage({
201943
- content: `${API_ERROR_MESSAGE_PREFIX}: Authentication failed for your OpenAI-compatible provider. Verify OPENAI_API_KEY and endpoint-specific auth requirements.`,
201960
+ content: verbooFirstParty ? `${API_ERROR_MESSAGE_PREFIX}: Authentication failed. ${getIsNonInteractiveSession() ? "Run `verboo /login` and retry." : "Please run /login."}` : `${API_ERROR_MESSAGE_PREFIX}: Authentication failed. Verify your provider credentials (OPENAI_API_KEY / ANTHROPIC_BASE_URL / endpoint-specific auth headers).`,
201944
201961
  error: "authentication_failed"
201945
201962
  });
201963
+ }
201946
201964
  case "rate_limited":
201947
201965
  return createAssistantAPIErrorMessage({
201948
201966
  content: `${API_ERROR_MESSAGE_PREFIX}: Provider rate limit reached. Retry in a few seconds.`,
@@ -202039,10 +202057,10 @@ function getRequestTooLargeErrorMessage() {
202039
202057
  return getIsNonInteractiveSession() ? `Request too large (${limits}). Try with a smaller file.` : `Request too large (${limits}). Double press esc to go back and try with a smaller file.`;
202040
202058
  }
202041
202059
  function getTokenRevokedErrorMessage() {
202042
- return getIsNonInteractiveSession() ? "Your account does not have access to Claude. Please login again or contact your administrator." : TOKEN_REVOKED_ERROR_MESSAGE;
202060
+ return getIsNonInteractiveSession() ? `${API_ERROR_MESSAGE_PREFIX}: OAuth token revoked. Run \`verboo /login\` to re-authenticate, or contact your administrator.` : TOKEN_REVOKED_ERROR_MESSAGE;
202043
202061
  }
202044
202062
  function getOauthOrgNotAllowedErrorMessage() {
202045
- return getIsNonInteractiveSession() ? "Your organization does not have access to Claude. Please login again or contact your administrator." : OAUTH_ORG_NOT_ALLOWED_ERROR_MESSAGE;
202063
+ return getIsNonInteractiveSession() ? `${API_ERROR_MESSAGE_PREFIX}: Your organization does not have access to Verboo Code. Run \`verboo /login\` to switch accounts, or contact your administrator.` : OAUTH_ORG_NOT_ALLOWED_ERROR_MESSAGE;
202046
202064
  }
202047
202065
  function isCCRMode() {
202048
202066
  return isEnvTruthy(process.env.CLAUDE_CODE_REMOTE);
@@ -202414,7 +202432,7 @@ Run /share and post the JSON file to ${MACRO.FEEDBACK_CHANNEL}.`;
202414
202432
  }
202415
202433
  return createAssistantAPIErrorMessage({
202416
202434
  error: "authentication_failed",
202417
- content: getIsNonInteractiveSession() ? `Failed to authenticate. ${API_ERROR_MESSAGE_PREFIX}: ${error42.message}` : `Please run /login · ${API_ERROR_MESSAGE_PREFIX}: ${error42.message}`
202435
+ content: getIsNonInteractiveSession() ? `${API_ERROR_MESSAGE_PREFIX}: ${error42.message} · Failed to authenticate. Run \`verboo /login\` to refresh credentials.` : `Please run /login · ${API_ERROR_MESSAGE_PREFIX}: ${error42.message}`
202418
202436
  });
202419
202437
  }
202420
202438
  if (isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) && error42 instanceof Error && error42.message.toLowerCase().includes("model id")) {
@@ -202593,6 +202611,7 @@ var init_errors6 = __esm(() => {
202593
202611
  init_providers();
202594
202612
  init_state();
202595
202613
  init_apiLimits();
202614
+ init_oauth();
202596
202615
  init_envUtils();
202597
202616
  init_format2();
202598
202617
  init_imageResizer();
@@ -376794,7 +376813,7 @@ function getAnthropicEnvMetadata() {
376794
376813
  function getBuildAgeMinutes() {
376795
376814
  if (false)
376796
376815
  ;
376797
- const buildTime = new Date("2026-04-30T11:00:43.858Z").getTime();
376816
+ const buildTime = new Date("2026-05-01T21:13:05.033Z").getTime();
376798
376817
  if (isNaN(buildTime))
376799
376818
  return;
376800
376819
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -410204,6 +410223,15 @@ async function addToPromptHistory(command) {
410204
410223
  sessionId: getSessionId()
410205
410224
  };
410206
410225
  pendingEntries.push(logEntry);
410226
+ if (pendingEntries.length > MAX_PENDING_ENTRIES) {
410227
+ pendingEntries.splice(0, pendingEntries.length - MAX_PENDING_ENTRIES);
410228
+ if (!pendingOverflowWarned) {
410229
+ pendingOverflowWarned = true;
410230
+ logForDebugging2(`History pending queue exceeded ${MAX_PENDING_ENTRIES} entries — dropping oldest. Disk write likely failing.`);
410231
+ }
410232
+ } else if (pendingEntries.length < MAX_PENDING_ENTRIES / 2) {
410233
+ pendingOverflowWarned = false;
410234
+ }
410207
410235
  lastAddedEntry = logEntry;
410208
410236
  currentFlushPromise = flushPromptHistory(0);
410209
410237
  }
@@ -410236,7 +410264,7 @@ function removeLastFromHistory() {
410236
410264
  skippedTimestamps.add(entry.timestamp);
410237
410265
  }
410238
410266
  }
410239
- var MAX_HISTORY_ITEMS = 100, MAX_PASTED_CONTENT_LENGTH = 1024, pendingEntries, isWriting = false, currentFlushPromise = null, cleanupRegistered3 = false, lastAddedEntry = null, skippedTimestamps;
410267
+ var MAX_HISTORY_ITEMS = 100, MAX_PASTED_CONTENT_LENGTH = 1024, pendingEntries, isWriting = false, currentFlushPromise = null, cleanupRegistered3 = false, lastAddedEntry = null, MAX_PENDING_ENTRIES = 1000, pendingOverflowWarned = false, skippedTimestamps;
410240
410268
  var init_history = __esm(() => {
410241
410269
  init_state();
410242
410270
  init_cleanupRegistry();
@@ -417321,7 +417349,7 @@ function buildPrimarySection() {
417321
417349
  }, undefined, false, undefined, this);
417322
417350
  return [{
417323
417351
  label: "Version",
417324
- value: "0.7.10"
417352
+ value: "0.7.12"
417325
417353
  }, {
417326
417354
  label: "Session name",
417327
417355
  value: nameValue
@@ -485271,7 +485299,7 @@ var init_bridge_kick = __esm(() => {
485271
485299
  var call60 = async () => {
485272
485300
  return {
485273
485301
  type: "text",
485274
- value: `${"99.0.0"} (built ${"2026-04-30T11:00:43.858Z"})`
485302
+ value: `${"99.0.0"} (built ${"2026-05-01T21:13:05.033Z"})`
485275
485303
  };
485276
485304
  }, version2, version_default;
485277
485305
  var init_version = __esm(() => {
@@ -517923,6 +517951,25 @@ var init_FileEditToolDiff = __esm(() => {
517923
517951
  // src/hooks/useDiffInIDE.ts
517924
517952
  import { randomUUID as randomUUID33 } from "crypto";
517925
517953
  import { basename as basename50 } from "path";
517954
+ async function runAllPendingDiffCleanups() {
517955
+ const cleanups = Array.from(pendingDiffCleanups);
517956
+ pendingDiffCleanups.clear();
517957
+ for (const fn of cleanups) {
517958
+ try {
517959
+ await fn();
517960
+ } catch (e2) {
517961
+ logError2(e2);
517962
+ }
517963
+ }
517964
+ }
517965
+ function ensureBeforeExitListener() {
517966
+ if (beforeExitListenerInstalled)
517967
+ return;
517968
+ beforeExitListenerInstalled = true;
517969
+ process.on("beforeExit", () => {
517970
+ return runAllPendingDiffCleanups();
517971
+ });
517972
+ }
517926
517973
  function useDiffInIDE({
517927
517974
  onChange,
517928
517975
  toolUseContext,
@@ -518025,11 +518072,12 @@ async function showDiffInIDE(file_path, edits, toolUseContext, tabName) {
518025
518072
  } catch (e2) {
518026
518073
  logError2(e2);
518027
518074
  }
518028
- process.off("beforeExit", cleanup);
518075
+ pendingDiffCleanups.delete(cleanup);
518029
518076
  toolUseContext.abortController.signal.removeEventListener("abort", cleanup);
518030
518077
  }
518031
518078
  toolUseContext.abortController.signal.addEventListener("abort", cleanup);
518032
- process.on("beforeExit", cleanup);
518079
+ pendingDiffCleanups.add(cleanup);
518080
+ ensureBeforeExitListener();
518033
518081
  const ideClient = getConnectedIdeClient(toolUseContext.options.mcpClients);
518034
518082
  try {
518035
518083
  const { updatedFile } = getPatchForEdits({
@@ -518098,7 +518146,7 @@ function isRejectedMessage(data) {
518098
518146
  function isSaveMessage(data) {
518099
518147
  return Array.isArray(data) && data[0]?.type === "text" && data[0].text === "FILE_SAVED" && typeof data[1].text === "string";
518100
518148
  }
518101
- var import_react207;
518149
+ var import_react207, pendingDiffCleanups, beforeExitListenerInstalled = false;
518102
518150
  var init_useDiffInIDE = __esm(() => {
518103
518151
  init_fileRead();
518104
518152
  init_path2();
@@ -518111,6 +518159,7 @@ var init_useDiffInIDE = __esm(() => {
518111
518159
  init_log3();
518112
518160
  init_platform2();
518113
518161
  import_react207 = __toESM(require_react(), 1);
518162
+ pendingDiffCleanups = new Set;
518114
518163
  });
518115
518164
 
518116
518165
  // src/components/ShowInIDEPrompt.tsx
@@ -538038,6 +538087,49 @@ var init_PromptInputFooterLeftSide = __esm(() => {
538038
538087
  });
538039
538088
 
538040
538089
  // src/components/PromptInput/PromptInputFooter.tsx
538090
+ function ContextWindowDisplay({ messages, permissionMode }) {
538091
+ const mainLoopModel = useMainLoopModel();
538092
+ const exceeds200k = doesMostRecentAssistantMessageExceed200k(messages);
538093
+ const runtimeModel = getRuntimeMainLoopModel({ permissionMode, mainLoopModel, exceeds200kTokens: exceeds200k });
538094
+ const usage = getCurrentUsage(messages);
538095
+ const windowSize = getContextWindowForModel(runtimeModel, getSdkBetas());
538096
+ if (!usage) {
538097
+ const emptyBar = "░".repeat(BAR_WIDTH);
538098
+ const windowK2 = formatNumber(windowSize);
538099
+ return /* @__PURE__ */ jsx_dev_runtime429.jsxDEV(ThemedText, {
538100
+ dimColor: true,
538101
+ children: [
538102
+ "ctx [",
538103
+ emptyBar,
538104
+ "] 0/",
538105
+ windowK2,
538106
+ " 0%"
538107
+ ]
538108
+ }, undefined, true, undefined, this);
538109
+ }
538110
+ const { used } = calculateContextPercentages(usage, windowSize);
538111
+ const pct = Math.round(used);
538112
+ const filled = Math.round(pct / 100 * BAR_WIDTH);
538113
+ const bar = "█".repeat(filled) + "░".repeat(BAR_WIDTH - filled);
538114
+ const color3 = pct >= 90 ? "red" : pct >= 70 ? "yellow" : undefined;
538115
+ const inputK = formatNumber(usage.input_tokens);
538116
+ const windowK = formatNumber(windowSize);
538117
+ return /* @__PURE__ */ jsx_dev_runtime429.jsxDEV(ThemedText, {
538118
+ dimColor: true,
538119
+ color: color3,
538120
+ children: [
538121
+ "ctx [",
538122
+ bar,
538123
+ "] ",
538124
+ inputK,
538125
+ "/",
538126
+ windowK,
538127
+ " ",
538128
+ pct,
538129
+ "%"
538130
+ ]
538131
+ }, undefined, true, undefined, this);
538132
+ }
538041
538133
  function PromptInputFooter({
538042
538134
  apiKeyStatus,
538043
538135
  debug,
@@ -538128,6 +538220,10 @@ function PromptInputFooter({
538128
538220
  lastAssistantMessageId,
538129
538221
  vimMode
538130
538222
  }, undefined, false, undefined, this),
538223
+ mode === "prompt" && !exitMessage.show && !isPasting && /* @__PURE__ */ jsx_dev_runtime429.jsxDEV(ContextWindowDisplay, {
538224
+ messages,
538225
+ permissionMode: toolPermissionContext.mode
538226
+ }, undefined, false, undefined, this),
538131
538227
  /* @__PURE__ */ jsx_dev_runtime429.jsxDEV(PromptInputFooterLeftSide, {
538132
538228
  exitMessage,
538133
538229
  vimMode,
@@ -538212,16 +538308,22 @@ function BridgeStatusIndicator({
538212
538308
  ]
538213
538309
  }, undefined, true, undefined, this);
538214
538310
  }
538215
- var import_react252, jsx_dev_runtime429, PromptInputFooter_default;
538311
+ var import_react252, jsx_dev_runtime429, BAR_WIDTH = 20, PromptInputFooter_default;
538216
538312
  var init_PromptInputFooter = __esm(() => {
538217
538313
  init_bridgeEnabled();
538218
538314
  init_bridgeStatusUtil();
538315
+ init_state();
538219
538316
  init_promptOverlayContext();
538317
+ init_useMainLoopModel();
538220
538318
  init_useSettings();
538221
538319
  init_useTerminalSize();
538222
538320
  init_ink2();
538223
538321
  init_AppState();
538322
+ init_context();
538323
+ init_format2();
538224
538324
  init_fullscreen();
538325
+ init_model();
538326
+ init_tokens();
538225
538327
  init_CoordinatorAgentStatus();
538226
538328
  init_StatusLine();
538227
538329
  init_Notifications();
@@ -541123,6 +541225,7 @@ class SessionsWebSocket {
541123
541225
  getAccessToken;
541124
541226
  callbacks;
541125
541227
  ws = null;
541228
+ wsListeners = [];
541126
541229
  state = "closed";
541127
541230
  reconnectAttempts = 0;
541128
541231
  sessionNotFoundRetries = 0;
@@ -541139,6 +541242,7 @@ class SessionsWebSocket {
541139
541242
  logForDebugging2("[SessionsWebSocket] Already connecting");
541140
541243
  return;
541141
541244
  }
541245
+ this.teardownCurrentSocket();
541142
541246
  this.state = "connecting";
541143
541247
  const baseUrl = getOauthConfig().BASE_API_URL.replace("https://", "wss://");
541144
541248
  const url4 = `${baseUrl}/v1/sessions/ws/${this.sessionId}/subscribe?organization_uuid=${this.orgUuid}`;
@@ -541148,6 +541252,22 @@ class SessionsWebSocket {
541148
541252
  Authorization: `Bearer ${accessToken}`,
541149
541253
  "anthropic-version": "2023-06-01"
541150
541254
  };
541255
+ const onOpen = () => {
541256
+ logForDebugging2("[SessionsWebSocket] Connection opened, authenticated via headers");
541257
+ this.state = "connected";
541258
+ this.reconnectAttempts = 0;
541259
+ this.sessionNotFoundRetries = 0;
541260
+ this.startPingInterval();
541261
+ this.callbacks.onConnected?.();
541262
+ };
541263
+ const onError = () => {
541264
+ const err2 = new Error("[SessionsWebSocket] WebSocket error");
541265
+ logError2(err2);
541266
+ this.callbacks.onError?.(err2);
541267
+ };
541268
+ const onPong = () => {
541269
+ logForDebugging2("[SessionsWebSocket] Pong received");
541270
+ };
541151
541271
  if (typeof Bun !== "undefined") {
541152
541272
  const ws = new globalThis.WebSocket(url4, {
541153
541273
  headers,
@@ -541155,30 +541275,26 @@ class SessionsWebSocket {
541155
541275
  tls: getWebSocketTLSOptions() || undefined
541156
541276
  });
541157
541277
  this.ws = ws;
541158
- ws.addEventListener("open", () => {
541159
- logForDebugging2("[SessionsWebSocket] Connection opened, authenticated via headers");
541160
- this.state = "connected";
541161
- this.reconnectAttempts = 0;
541162
- this.sessionNotFoundRetries = 0;
541163
- this.startPingInterval();
541164
- this.callbacks.onConnected?.();
541165
- });
541166
- ws.addEventListener("message", (event) => {
541278
+ const onMessage2 = (event) => {
541167
541279
  const data = typeof event.data === "string" ? event.data : String(event.data);
541168
541280
  this.handleMessage(data);
541169
- });
541170
- ws.addEventListener("error", () => {
541171
- const err2 = new Error("[SessionsWebSocket] WebSocket error");
541172
- logError2(err2);
541173
- this.callbacks.onError?.(err2);
541174
- });
541175
- ws.addEventListener("close", (event) => {
541281
+ };
541282
+ const onClose = (event) => {
541176
541283
  logForDebugging2(`[SessionsWebSocket] Closed: code=${event.code} reason=${event.reason}`);
541177
541284
  this.handleClose(event.code);
541178
- });
541179
- ws.addEventListener("pong", () => {
541180
- logForDebugging2("[SessionsWebSocket] Pong received");
541181
- });
541285
+ };
541286
+ ws.addEventListener("open", onOpen);
541287
+ ws.addEventListener("message", onMessage2);
541288
+ ws.addEventListener("error", onError);
541289
+ ws.addEventListener("close", onClose);
541290
+ ws.addEventListener("pong", onPong);
541291
+ this.wsListeners = [
541292
+ { event: "open", handler: onOpen },
541293
+ { event: "message", handler: onMessage2 },
541294
+ { event: "error", handler: onError },
541295
+ { event: "close", handler: onClose },
541296
+ { event: "pong", handler: onPong }
541297
+ ];
541182
541298
  } else {
541183
541299
  const { default: WS } = await Promise.resolve().then(() => (init_wrapper(), exports_wrapper));
541184
541300
  const ws = new WS(url4, {
@@ -541187,28 +541303,55 @@ class SessionsWebSocket {
541187
541303
  ...getWebSocketTLSOptions()
541188
541304
  });
541189
541305
  this.ws = ws;
541190
- ws.on("open", () => {
541191
- logForDebugging2("[SessionsWebSocket] Connection opened, authenticated via headers");
541192
- this.state = "connected";
541193
- this.reconnectAttempts = 0;
541194
- this.sessionNotFoundRetries = 0;
541195
- this.startPingInterval();
541196
- this.callbacks.onConnected?.();
541197
- });
541198
- ws.on("message", (data) => {
541306
+ const onMessage2 = (data) => {
541199
541307
  this.handleMessage(data.toString());
541200
- });
541201
- ws.on("error", (err2) => {
541308
+ };
541309
+ const onErrorWs = (err2) => {
541202
541310
  logError2(new Error(`[SessionsWebSocket] Error: ${err2.message}`));
541203
541311
  this.callbacks.onError?.(err2);
541204
- });
541205
- ws.on("close", (code, reason) => {
541312
+ };
541313
+ const onCloseWs = (code, reason) => {
541206
541314
  logForDebugging2(`[SessionsWebSocket] Closed: code=${code} reason=${reason.toString()}`);
541207
541315
  this.handleClose(code);
541208
- });
541209
- ws.on("pong", () => {
541210
- logForDebugging2("[SessionsWebSocket] Pong received");
541211
- });
541316
+ };
541317
+ ws.on("open", onOpen);
541318
+ ws.on("message", onMessage2);
541319
+ ws.on("error", onErrorWs);
541320
+ ws.on("close", onCloseWs);
541321
+ ws.on("pong", onPong);
541322
+ this.wsListeners = [
541323
+ { event: "open", handler: onOpen },
541324
+ { event: "message", handler: onMessage2 },
541325
+ { event: "error", handler: onErrorWs },
541326
+ { event: "close", handler: onCloseWs },
541327
+ { event: "pong", handler: onPong }
541328
+ ];
541329
+ }
541330
+ }
541331
+ teardownCurrentSocket() {
541332
+ const ws = this.ws;
541333
+ const listeners = this.wsListeners;
541334
+ this.wsListeners = [];
541335
+ this.ws = null;
541336
+ if (!ws)
541337
+ return;
541338
+ for (const { event, handler: handler7 } of listeners) {
541339
+ try {
541340
+ if (typeof ws.removeEventListener === "function") {
541341
+ ws.removeEventListener(event, handler7);
541342
+ }
541343
+ if (typeof ws.off === "function") {
541344
+ ws.off(event, handler7);
541345
+ }
541346
+ } catch {}
541347
+ }
541348
+ try {
541349
+ ws.close();
541350
+ } catch {}
541351
+ if (typeof ws.terminate === "function") {
541352
+ try {
541353
+ ws.terminate();
541354
+ } catch {}
541212
541355
  }
541213
541356
  }
541214
541357
  handleMessage(data) {
@@ -541228,7 +541371,7 @@ class SessionsWebSocket {
541228
541371
  if (this.state === "closed") {
541229
541372
  return;
541230
541373
  }
541231
- this.ws = null;
541374
+ this.teardownCurrentSocket();
541232
541375
  const previousState = this.state;
541233
541376
  this.state = "closed";
541234
541377
  if (PERMANENT_CLOSE_CODES.has(closeCode)) {
@@ -541310,10 +541453,7 @@ class SessionsWebSocket {
541310
541453
  clearTimeout(this.reconnectTimer);
541311
541454
  this.reconnectTimer = null;
541312
541455
  }
541313
- if (this.ws) {
541314
- this.ws.close();
541315
- this.ws = null;
541316
- }
541456
+ this.teardownCurrentSocket();
541317
541457
  }
541318
541458
  reconnect() {
541319
541459
  logForDebugging2("[SessionsWebSocket] Force reconnecting");
@@ -560929,7 +561069,7 @@ function WelcomeV2() {
560929
561069
  dimColor: true,
560930
561070
  children: [
560931
561071
  "v",
560932
- "0.7.10",
561072
+ "0.7.12",
560933
561073
  " "
560934
561074
  ]
560935
561075
  }, undefined, true, undefined, this)
@@ -561116,7 +561256,7 @@ function WelcomeV2() {
561116
561256
  dimColor: true,
561117
561257
  children: [
561118
561258
  "v",
561119
- "0.7.10",
561259
+ "0.7.12",
561120
561260
  " "
561121
561261
  ]
561122
561262
  }, undefined, true, undefined, this)
@@ -561332,7 +561472,7 @@ function AppleTerminalWelcomeV2(t0) {
561332
561472
  dimColor: true,
561333
561473
  children: [
561334
561474
  "v",
561335
- "0.7.10",
561475
+ "0.7.12",
561336
561476
  " "
561337
561477
  ]
561338
561478
  }, undefined, true, undefined, this);
@@ -561541,7 +561681,7 @@ function AppleTerminalWelcomeV2(t0) {
561541
561681
  dimColor: true,
561542
561682
  children: [
561543
561683
  "v",
561544
- "0.7.10",
561684
+ "0.7.12",
561545
561685
  " "
561546
561686
  ]
561547
561687
  }, undefined, true, undefined, this);
@@ -571727,6 +571867,7 @@ class QueryEngine {
571727
571867
  readFileState;
571728
571868
  discoveredSkillNames = new Set;
571729
571869
  loadedNestedMemoryPaths = new Set;
571870
+ oversizedMessagesWarned = false;
571730
571871
  constructor(config3) {
571731
571872
  this.config = config3;
571732
571873
  this.mutableMessages = config3.initialMessages ?? [];
@@ -571761,6 +571902,17 @@ class QueryEngine {
571761
571902
  orphanedPermission
571762
571903
  } = this.config;
571763
571904
  this.discoveredSkillNames.clear();
571905
+ const MAX_PERMISSION_DENIALS = 500;
571906
+ if (this.permissionDenials.length > MAX_PERMISSION_DENIALS) {
571907
+ this.permissionDenials.splice(0, this.permissionDenials.length - MAX_PERMISSION_DENIALS);
571908
+ }
571909
+ const MUTABLE_MESSAGES_WARN_THRESHOLD = 2000;
571910
+ if (this.mutableMessages.length > MUTABLE_MESSAGES_WARN_THRESHOLD && !this.oversizedMessagesWarned) {
571911
+ this.oversizedMessagesWarned = true;
571912
+ logForDebugging2(`[QueryEngine] mutableMessages large: ${this.mutableMessages.length} entries — enable compaction to keep memory bounded`);
571913
+ } else if (this.mutableMessages.length <= MUTABLE_MESSAGES_WARN_THRESHOLD / 2) {
571914
+ this.oversizedMessagesWarned = false;
571915
+ }
571764
571916
  setCwd(cwd3);
571765
571917
  const persistSession = !isSessionPersistenceDisabled();
571766
571918
  const startTime = Date.now();
@@ -579569,7 +579721,7 @@ __export(exports_update, {
579569
579721
  async function update() {
579570
579722
  if (getAPIProvider() !== "firstParty") {
579571
579723
  writeToStdout(source_default.yellow(`Auto-update is not available for third-party provider builds.
579572
- `) + `Current version: ${"0.7.10"}
579724
+ `) + `Current version: ${"0.7.12"}
579573
579725
 
579574
579726
  ` + `To update, reinstall from npm:
579575
579727
  ` + source_default.bold(` npm install -g ${"@verboo/code"}@latest`) + `
@@ -579580,7 +579732,7 @@ async function update() {
579580
579732
  await gracefulShutdown(0);
579581
579733
  }
579582
579734
  logEvent("tengu_update_check", {});
579583
- writeToStdout(`Current version: ${"0.7.10"}
579735
+ writeToStdout(`Current version: ${"0.7.12"}
579584
579736
  `);
579585
579737
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
579586
579738
  writeToStdout(`Checking for updates to ${channel} version...
@@ -579665,8 +579817,8 @@ async function update() {
579665
579817
  writeToStdout(`Claude is managed by Homebrew.
579666
579818
  `);
579667
579819
  const latest = await getLatestVersion(channel);
579668
- if (latest && !gte("0.7.10", latest)) {
579669
- writeToStdout(`Update available: ${"0.7.10"} → ${latest}
579820
+ if (latest && !gte("0.7.12", latest)) {
579821
+ writeToStdout(`Update available: ${"0.7.12"} → ${latest}
579670
579822
  `);
579671
579823
  writeToStdout(`
579672
579824
  `);
@@ -579682,8 +579834,8 @@ async function update() {
579682
579834
  writeToStdout(`Claude is managed by winget.
579683
579835
  `);
579684
579836
  const latest = await getLatestVersion(channel);
579685
- if (latest && !gte("0.7.10", latest)) {
579686
- writeToStdout(`Update available: ${"0.7.10"} → ${latest}
579837
+ if (latest && !gte("0.7.12", latest)) {
579838
+ writeToStdout(`Update available: ${"0.7.12"} → ${latest}
579687
579839
  `);
579688
579840
  writeToStdout(`
579689
579841
  `);
@@ -579699,8 +579851,8 @@ async function update() {
579699
579851
  writeToStdout(`Claude is managed by apk.
579700
579852
  `);
579701
579853
  const latest = await getLatestVersion(channel);
579702
- if (latest && !gte("0.7.10", latest)) {
579703
- writeToStdout(`Update available: ${"0.7.10"} → ${latest}
579854
+ if (latest && !gte("0.7.12", latest)) {
579855
+ writeToStdout(`Update available: ${"0.7.12"} → ${latest}
579704
579856
  `);
579705
579857
  writeToStdout(`
579706
579858
  `);
@@ -579765,11 +579917,11 @@ async function update() {
579765
579917
  `);
579766
579918
  await gracefulShutdown(1);
579767
579919
  }
579768
- if (result.latestVersion === "0.7.10") {
579769
- writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.10"})`) + `
579920
+ if (result.latestVersion === "0.7.12") {
579921
+ writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.12"})`) + `
579770
579922
  `);
579771
579923
  } else {
579772
- writeToStdout(source_default.green(`Successfully updated from ${"0.7.10"} to version ${result.latestVersion}`) + `
579924
+ writeToStdout(source_default.green(`Successfully updated from ${"0.7.12"} to version ${result.latestVersion}`) + `
579773
579925
  `);
579774
579926
  await regenerateCompletionCache();
579775
579927
  }
@@ -579829,12 +579981,12 @@ async function update() {
579829
579981
  `);
579830
579982
  await gracefulShutdown(1);
579831
579983
  }
579832
- if (latestVersion === "0.7.10") {
579833
- writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.10"})`) + `
579984
+ if (latestVersion === "0.7.12") {
579985
+ writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.12"})`) + `
579834
579986
  `);
579835
579987
  await gracefulShutdown(0);
579836
579988
  }
579837
- writeToStdout(`New version available: ${latestVersion} (current: ${"0.7.10"})
579989
+ writeToStdout(`New version available: ${latestVersion} (current: ${"0.7.12"})
579838
579990
  `);
579839
579991
  writeToStdout(`Installing update...
579840
579992
  `);
@@ -579879,7 +580031,7 @@ async function update() {
579879
580031
  logForDebugging2(`update: Installation status: ${status2}`);
579880
580032
  switch (status2) {
579881
580033
  case "success":
579882
- writeToStdout(source_default.green(`Successfully updated from ${"0.7.10"} to version ${latestVersion}`) + `
580034
+ writeToStdout(source_default.green(`Successfully updated from ${"0.7.12"} to version ${latestVersion}`) + `
579883
580035
  `);
579884
580036
  await regenerateCompletionCache();
579885
580037
  break;
@@ -581932,7 +582084,7 @@ Usage: verboo --remote "your task description"`, () => gracefulShutdown(1));
581932
582084
  pendingHookMessages
581933
582085
  }, renderAndRun);
581934
582086
  }
581935
- }).version(`0.7.10 (${cliDesc})`, "-v, --version", "Output the version number");
582087
+ }).version(`0.7.12 (${cliDesc})`, "-v, --version", "Output the version number");
581936
582088
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
581937
582089
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
581938
582090
  if (canUserConfigureAdvisor()) {
@@ -582500,7 +582652,7 @@ if (false) {}
582500
582652
  async function main2() {
582501
582653
  const args = process.argv.slice(2);
582502
582654
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
582503
- console.log(`${"0.7.10"} (Verboo Code)`);
582655
+ console.log(`${"0.7.12"} (Verboo Code)`);
582504
582656
  return;
582505
582657
  }
582506
582658
  if (args.includes("--provider")) {
@@ -582656,4 +582808,4 @@ async function main2() {
582656
582808
  }
582657
582809
  main2();
582658
582810
 
582659
- //# debugId=3383BFF91396D01764756E2164756E21
582811
+ //# debugId=B566AA3C880BEEFC64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verboo/code",
3
- "version": "0.7.10",
3
+ "version": "0.7.12",
4
4
  "description": "Verboo Code — coding agent for the Verboo platform",
5
5
  "type": "module",
6
6
  "bin": {