localclawd 2.3.3 → 2.3.4

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 (3) hide show
  1. package/README.md +4 -5
  2. package/dist/cli.mjs +269 -146
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -272,10 +272,9 @@ localclawd currently recognizes both native and legacy variable names for the lo
272
272
  - `LOCALCLAWD_USE_VLLM`
273
273
  - `LOCALCLAWD_USE_OLLAMA`
274
274
  - `LOCALCLAWD_USE_OPENAI`
275
- - `LOCALCLAWD_LOCAL_BASE_URL`
276
- - `LOCALCLAWD_LOCAL_MODEL`
277
- - `LOCALCLAWD_LOCAL_API_KEY`
278
- - `LOCALCLAWD_AUTO_COMPACT_WINDOW`
275
+ - `LOCALCLAWD_LOCAL_BASE_URL`
276
+ - `LOCALCLAWD_LOCAL_MODEL`
277
+ - `LOCALCLAWD_LOCAL_API_KEY`
279
278
 
280
279
  Legacy compatibility aliases that still work:
281
280
 
@@ -307,7 +306,7 @@ The native installer places the executable at `~/.local/bin/localclawd` on Unix-
307
306
 
308
307
  ## Compact context window
309
308
 
310
- During first-run setup, localclawd asks for a compact context window cap. Use this when your local model becomes unstable before its advertised maximum context size. You can change it later in `/config` under `Compact context window`.
309
+ During first-run setup, localclawd asks for a project-local compact context window cap. Use this when your local model becomes unstable before its advertised maximum context size. You can change it later in `/config` under `Compact context window` or with `/ctx`.
311
310
 
312
311
  ## Why use it instead of the upstream hosted CLI
313
312
 
package/dist/cli.mjs CHANGED
@@ -35907,13 +35907,22 @@ function reportConfigCacheStats() {
35907
35907
  configCacheHits = 0;
35908
35908
  configCacheMisses = 0;
35909
35909
  }
35910
- function migrateConfigFields(config) {
35911
- if (config.installMethod !== undefined) {
35910
+ function removeLegacyGlobalProjectSettings(config) {
35911
+ const legacyLocalOnlyFields = config;
35912
+ if (legacyLocalOnlyFields.compactContextWindowTokens === undefined) {
35912
35913
  return config;
35913
35914
  }
35914
- const legacy = config;
35915
+ const { compactContextWindowTokens: _legacy, ...rest } = legacyLocalOnlyFields;
35916
+ return rest;
35917
+ }
35918
+ function migrateConfigFields(config) {
35919
+ const normalizedConfig = removeLegacyGlobalProjectSettings(config);
35920
+ if (normalizedConfig.installMethod !== undefined) {
35921
+ return normalizedConfig;
35922
+ }
35923
+ const legacy = normalizedConfig;
35915
35924
  let installMethod = "unknown";
35916
- let autoUpdates = config.autoUpdates ?? true;
35925
+ let autoUpdates = normalizedConfig.autoUpdates ?? true;
35917
35926
  switch (legacy.autoUpdaterStatus) {
35918
35927
  case "migrated":
35919
35928
  installMethod = "local";
@@ -35933,7 +35942,7 @@ function migrateConfigFields(config) {
35933
35942
  break;
35934
35943
  }
35935
35944
  return {
35936
- ...config,
35945
+ ...normalizedConfig,
35937
35946
  installMethod,
35938
35947
  autoUpdates
35939
35948
  };
@@ -36480,8 +36489,6 @@ var init_config = __esm(() => {
36480
36489
  "shiftEnterKeyBindingInstalled",
36481
36490
  "editorMode",
36482
36491
  "hasUsedBackslashReturn",
36483
- "autoCompactEnabled",
36484
- "compactContextWindowTokens",
36485
36492
  "localBackendProvider",
36486
36493
  "localBackendBaseUrl",
36487
36494
  "localBackendModel",
@@ -36517,7 +36524,9 @@ var init_config = __esm(() => {
36517
36524
  PROJECT_CONFIG_KEYS = [
36518
36525
  "allowedTools",
36519
36526
  "hasTrustDialogAccepted",
36520
- "hasCompletedProjectOnboarding"
36527
+ "hasCompletedProjectOnboarding",
36528
+ "compactContextWindowTokens",
36529
+ "autoCompactEnabled"
36521
36530
  ];
36522
36531
  TEST_GLOBAL_CONFIG_FOR_TESTING = {
36523
36532
  ...DEFAULT_GLOBAL_CONFIG,
@@ -88251,7 +88260,7 @@ var init_isEqual = __esm(() => {
88251
88260
 
88252
88261
  // src/utils/userAgent.ts
88253
88262
  function getClaudeCodeUserAgent() {
88254
- return `claude-code/${"2.3.3"}`;
88263
+ return `claude-code/${"2.3.4"}`;
88255
88264
  }
88256
88265
 
88257
88266
  // src/utils/workloadContext.ts
@@ -88273,7 +88282,7 @@ function getUserAgent() {
88273
88282
  const clientApp = process.env.CLAUDE_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.CLAUDE_AGENT_SDK_CLIENT_APP}` : "";
88274
88283
  const workload = getWorkload();
88275
88284
  const workloadSuffix = workload ? `, workload/${workload}` : "";
88276
- return `claude-cli/${"2.3.3"} (${process.env.USER_TYPE}, ${process.env.CLAUDE_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
88285
+ return `claude-cli/${"2.3.4"} (${process.env.USER_TYPE}, ${process.env.CLAUDE_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
88277
88286
  }
88278
88287
  function getMCPUserAgent() {
88279
88288
  const parts = [];
@@ -88287,7 +88296,7 @@ function getMCPUserAgent() {
88287
88296
  parts.push(`client-app/${process.env.CLAUDE_AGENT_SDK_CLIENT_APP}`);
88288
88297
  }
88289
88298
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
88290
- return `claude-code/${"2.3.3"}${suffix}`;
88299
+ return `claude-code/${"2.3.4"}${suffix}`;
88291
88300
  }
88292
88301
  function getWebFetchUserAgent() {
88293
88302
  return `Claude-User (${getClaudeCodeUserAgent()}; +https://support.anthropic.com/)`;
@@ -123552,9 +123561,6 @@ var init_modelCapabilities = __esm(() => {
123552
123561
  });
123553
123562
 
123554
123563
  // src/utils/context.ts
123555
- function getEnvAlias2(localKey, legacyKey) {
123556
- return process.env[localKey] ?? process.env[legacyKey];
123557
- }
123558
123564
  function is1mContextDisabled() {
123559
123565
  return true;
123560
123566
  }
@@ -123584,13 +123590,7 @@ function getLocalProviderContextWindow() {
123584
123590
  return _localProviderContextWindow;
123585
123591
  }
123586
123592
  function getContextWindowForModel(_model, _betas) {
123587
- const envOverrideStr = getEnvAlias2("LOCALCLAWD_MAX_CONTEXT_TOKENS", "CLAUDE_CODE_MAX_CONTEXT_TOKENS");
123588
- if (envOverrideStr) {
123589
- const override = parseContextWindowString(envOverrideStr);
123590
- if (override !== null)
123591
- return override;
123592
- }
123593
- const persisted = getGlobalConfig().compactContextWindowTokens;
123593
+ const persisted = getCurrentProjectConfig().compactContextWindowTokens;
123594
123594
  if (persisted && persisted > 0)
123595
123595
  return persisted;
123596
123596
  if (_localProviderContextWindow && _localProviderContextWindow > 0) {
@@ -158794,7 +158794,7 @@ function getAttributionHeader(fingerprint) {
158794
158794
  if (!isAttributionHeaderEnabled()) {
158795
158795
  return "";
158796
158796
  }
158797
- const version = `${"2.3.3"}.${fingerprint}`;
158797
+ const version = `${"2.3.4"}.${fingerprint}`;
158798
158798
  const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "unknown";
158799
158799
  const cch = "";
158800
158800
  const workload = getWorkload();
@@ -174981,7 +174981,7 @@ var init_metadata = __esm(() => {
174981
174981
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
174982
174982
  WHITESPACE_REGEX = /\s+/;
174983
174983
  getVersionBase = memoize_default(() => {
174984
- const match = "2.3.3".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
174984
+ const match = "2.3.4".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
174985
174985
  return match ? match[0] : undefined;
174986
174986
  });
174987
174987
  buildEnvContext = memoize_default(async () => {
@@ -175021,9 +175021,9 @@ var init_metadata = __esm(() => {
175021
175021
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
175022
175022
  isClaudeCodeAction: isEnvTruthy(process.env.CLAUDE_CODE_ACTION),
175023
175023
  isClaudeAiAuth: isClaudeAISubscriber(),
175024
- version: "2.3.3",
175024
+ version: "2.3.4",
175025
175025
  versionBase: getVersionBase(),
175026
- buildTime: "2026-05-10T20:16:44.115Z",
175026
+ buildTime: "2026-05-10T21:07:59.152Z",
175027
175027
  deploymentEnvironment: env3.detectDeploymentEnvironment(),
175028
175028
  ...isEnvTruthy(process.env.GITHUB_ACTIONS) && {
175029
175029
  githubEventName: process.env.GITHUB_EVENT_NAME,
@@ -200802,6 +200802,29 @@ function createCompactCanUseTool() {
200802
200802
  }
200803
200803
  });
200804
200804
  }
200805
+ function normalizeLocalChatCompletionsUrl(baseUrl) {
200806
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
200807
+ const withV1 = trimmed.endsWith("/v1") ? trimmed : `${trimmed}/v1`;
200808
+ return `${withV1}/chat/completions`;
200809
+ }
200810
+ function isLocalContextOverflowMessage(message) {
200811
+ return LOCAL_CONTEXT_OVERFLOW_PATTERNS.some((pattern) => pattern.test(message));
200812
+ }
200813
+ async function readProviderErrorMessage(response) {
200814
+ try {
200815
+ const payload = await response.clone().json();
200816
+ const message = payload.error?.message ?? payload.message;
200817
+ if (typeof message === "string" && message.trim()) {
200818
+ return message.trim();
200819
+ }
200820
+ } catch {}
200821
+ try {
200822
+ const text = await response.clone().text();
200823
+ if (text.trim())
200824
+ return text.trim();
200825
+ } catch {}
200826
+ return `HTTP ${response.status}`;
200827
+ }
200805
200828
  function serializeMessagesForCleanRoom(messages, maxChars) {
200806
200829
  const parts = [];
200807
200830
  for (const msg of messages) {
@@ -200828,9 +200851,15 @@ ${text}`);
200828
200851
  `);
200829
200852
  if (full.length <= maxChars)
200830
200853
  return full;
200831
- return `[earlier conversation truncated]
200854
+ const headChars = Math.max(1000, Math.floor(maxChars * 0.2));
200855
+ const tailChars = Math.max(1000, maxChars - headChars);
200856
+ return [
200857
+ full.slice(0, headChars),
200858
+ "[middle conversation omitted for local compaction budget]",
200859
+ full.slice(full.length - tailChars)
200860
+ ].join(`
200832
200861
 
200833
- ` + full.slice(full.length - maxChars);
200862
+ `);
200834
200863
  }
200835
200864
  async function tryDirectLocalCompact({
200836
200865
  messages,
@@ -200856,13 +200885,13 @@ ${serialized}
200856
200885
  </conversation>
200857
200886
 
200858
200887
  ${compactPromptText}`;
200859
- const timeoutMs = parseInt(process.env.COMPACT_TIMEOUT_MS || "", 10) || 5 * 60000;
200888
+ const timeoutMs = LOCAL_COMPACT_TIMEOUT_MS;
200860
200889
  const timeoutController = new AbortController;
200861
200890
  const timer = setTimeout(() => timeoutController.abort(new Error("compact timeout")), timeoutMs);
200862
200891
  const onAbort = () => timeoutController.abort(context4.abortController.signal.reason);
200863
200892
  context4.abortController.signal.addEventListener("abort", onAbort, { once: true });
200864
200893
  try {
200865
- const url2 = `${baseUrl.replace(/\/$/, "")}/chat/completions`;
200894
+ const url2 = normalizeLocalChatCompletionsUrl(baseUrl);
200866
200895
  const res = await fetch(url2, {
200867
200896
  method: "POST",
200868
200897
  headers: {
@@ -200882,7 +200911,13 @@ ${compactPromptText}`;
200882
200911
  signal: timeoutController.signal
200883
200912
  });
200884
200913
  if (!res.ok) {
200885
- logForDebugging(`compact direct-local: HTTP ${res.status}`, { level: "warn" });
200914
+ const providerMessage = await readProviderErrorMessage(res);
200915
+ logForDebugging(`compact direct-local: HTTP ${res.status}: ${providerMessage}`, { level: "warn" });
200916
+ if (isLocalContextOverflowMessage(providerMessage)) {
200917
+ return createAssistantAPIErrorMessage({
200918
+ content: `${PROMPT_TOO_LONG_ERROR_MESSAGE}: ${providerMessage}`
200919
+ });
200920
+ }
200886
200921
  return null;
200887
200922
  }
200888
200923
  const data = await res.json();
@@ -200993,10 +201028,14 @@ async function streamCompactSummary({
200993
201028
  preCompactTokenCount
200994
201029
  });
200995
201030
  if (directResp) {
200996
- const directText = getAssistantMessageText(directResp);
200997
- if (directText && !directResp.isApiErrorMessage && !directText.startsWith(PROMPT_TOO_LONG_ERROR_MESSAGE)) {
200998
- return directResp;
200999
- }
201031
+ return directResp;
201032
+ }
201033
+ if (isLocalLLMProviderEnabled()) {
201034
+ logEvent("tengu_compact_failed", {
201035
+ reason: "local_direct_compact_failed",
201036
+ preCompactTokenCount
201037
+ });
201038
+ throw new Error(ERROR_MESSAGE_INCOMPLETE_RESPONSE);
201000
201039
  }
201001
201040
  const cleanRoomFirst = await tryCleanRoomCompactSummary({
201002
201041
  messages,
@@ -201285,7 +201324,7 @@ function shouldExcludeFromPostCompactRestore(filename, agentId) {
201285
201324
  } catch {}
201286
201325
  return false;
201287
201326
  }
201288
- var POST_COMPACT_MAX_FILES_TO_RESTORE = 5, POST_COMPACT_TOKEN_BUDGET = 50000, POST_COMPACT_MAX_TOKENS_PER_FILE = 5000, POST_COMPACT_MAX_TOKENS_PER_SKILL = 5000, POST_COMPACT_SKILLS_TOKEN_BUDGET = 25000, MAX_COMPACT_STREAMING_RETRIES = 2, ERROR_MESSAGE_NOT_ENOUGH_MESSAGES = "Not enough messages to compact.", MAX_PTL_RETRIES = 3, PTL_RETRY_MARKER = "[earlier conversation truncated for compaction retry]", ERROR_MESSAGE_PROMPT_TOO_LONG = "Conversation too long. Press esc twice to go up a few messages and try again.", ERROR_MESSAGE_USER_ABORT = "API Error: Request was aborted.", ERROR_MESSAGE_INCOMPLETE_RESPONSE = "Compaction interrupted · This may be due to network issues — please try again.", SKILL_TRUNCATION_MARKER = `
201327
+ var POST_COMPACT_MAX_FILES_TO_RESTORE = 5, POST_COMPACT_TOKEN_BUDGET = 50000, POST_COMPACT_MAX_TOKENS_PER_FILE = 5000, POST_COMPACT_MAX_TOKENS_PER_SKILL = 5000, POST_COMPACT_SKILLS_TOKEN_BUDGET = 25000, MAX_COMPACT_STREAMING_RETRIES = 2, LOCAL_COMPACT_TIMEOUT_MS = 120000, LOCAL_CONTEXT_OVERFLOW_PATTERNS, ERROR_MESSAGE_NOT_ENOUGH_MESSAGES = "Not enough messages to compact.", MAX_PTL_RETRIES = 3, PTL_RETRY_MARKER = "[earlier conversation truncated for compaction retry]", ERROR_MESSAGE_PROMPT_TOO_LONG = "Conversation too long. Press esc twice to go up a few messages and try again.", ERROR_MESSAGE_USER_ABORT = "API Error: Request was aborted.", ERROR_MESSAGE_INCOMPLETE_RESPONSE = "Compaction interrupted · This may be due to network issues — please try again.", SKILL_TRUNCATION_MARKER = `
201289
201328
 
201290
201329
  [... skill content truncated for compaction; use Read on the skill path if you need the full text]`;
201291
201330
  var init_compact = __esm(() => {
@@ -201325,6 +201364,15 @@ var init_compact = __esm(() => {
201325
201364
  init_internalLogging();
201326
201365
  init_tokenEstimation();
201327
201366
  init_prompt10();
201367
+ LOCAL_CONTEXT_OVERFLOW_PATTERNS = [
201368
+ /prompt is too long/i,
201369
+ /context.{0,20}(length|limit|window).{0,30}exceeded/i,
201370
+ /input.{0,20}(length|limit).{0,30}exceeded/i,
201371
+ /maximum.{0,20}(context|token)/i,
201372
+ /tokens?.{0,20}exceeds?.{0,20}(max|limit|context)/i,
201373
+ /too.{0,5}many.{0,10}tokens/i,
201374
+ /\bKV.{0,10}cache.{0,20}(full|exceeded)/i
201375
+ ];
201328
201376
  });
201329
201377
 
201330
201378
  // src/constants/systemPromptSections.ts
@@ -207640,7 +207688,7 @@ function getTelemetryAttributes() {
207640
207688
  attributes["session.id"] = sessionId;
207641
207689
  }
207642
207690
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
207643
- attributes["app.version"] = "2.3.3";
207691
+ attributes["app.version"] = "2.3.4";
207644
207692
  }
207645
207693
  const oauthAccount = getOauthAccountInfo();
207646
207694
  if (oauthAccount) {
@@ -208092,10 +208140,11 @@ function isAutoCompactEnabled() {
208092
208140
  if (isEnvTruthy(process.env.DISABLE_COMPACT)) {
208093
208141
  return false;
208094
208142
  }
208095
- if (isEnvTruthy(process.env.DISABLE_AUTO_COMPACT)) {
208096
- return false;
208143
+ const projectSetting = getCurrentProjectConfig().autoCompactEnabled;
208144
+ if (typeof projectSetting === "boolean") {
208145
+ return projectSetting;
208097
208146
  }
208098
- return true;
208147
+ return getGlobalConfig().autoCompactEnabled !== false;
208099
208148
  }
208100
208149
  async function shouldAutoCompact(messages, model, querySource, snipTokensFreed = 0) {
208101
208150
  if (querySource === "session_memory" || querySource === "compact" || querySource === "keepgoing_synthesis") {
@@ -208157,6 +208206,7 @@ async function autoCompactIfNeeded(messages, toolUseContext, cacheSafeParams, qu
208157
208206
  var MAX_OUTPUT_TOKENS_FOR_SUMMARY = 20000, AUTOCOMPACT_BUFFER_TOKENS = 13000, WARNING_THRESHOLD_BUFFER_TOKENS = 20000, ERROR_THRESHOLD_BUFFER_TOKENS = 20000, MANUAL_COMPACT_BUFFER_TOKENS = 3000, MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3;
208158
208207
  var init_autoCompact = __esm(() => {
208159
208208
  init_state();
208209
+ init_config();
208160
208210
  init_context();
208161
208211
  init_debug();
208162
208212
  init_envUtils();
@@ -269928,7 +269978,7 @@ function getInstallationEnv() {
269928
269978
  return;
269929
269979
  }
269930
269980
  function getClaudeCodeVersion() {
269931
- return "2.3.3";
269981
+ return "2.3.4";
269932
269982
  }
269933
269983
  async function getInstalledVSCodeExtensionVersion(command) {
269934
269984
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -275202,7 +275252,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
275202
275252
  const client4 = new Client({
275203
275253
  name: "localclawd",
275204
275254
  title: "localclawd",
275205
- version: "2.3.3",
275255
+ version: "2.3.4",
275206
275256
  description: "local-first AI coding tool",
275207
275257
  websiteUrl: PRODUCT_URL
275208
275258
  }, {
@@ -275544,7 +275594,7 @@ var init_client9 = __esm(() => {
275544
275594
  const client4 = new Client({
275545
275595
  name: "localclawd",
275546
275596
  title: "localclawd",
275547
- version: "2.3.3",
275597
+ version: "2.3.4",
275548
275598
  description: "local-first AI coding tool",
275549
275599
  websiteUrl: PRODUCT_URL
275550
275600
  }, {
@@ -289943,7 +289993,7 @@ function computeFingerprint(messageText, version) {
289943
289993
  }
289944
289994
  function computeFingerprintFromMessages(messages) {
289945
289995
  const firstMessageText = extractFirstMessageText(messages);
289946
- return computeFingerprint(firstMessageText, "2.3.3");
289996
+ return computeFingerprint(firstMessageText, "2.3.4");
289947
289997
  }
289948
289998
  var FINGERPRINT_SALT = "59cf53e54c78";
289949
289999
  var init_fingerprint = () => {};
@@ -289985,7 +290035,7 @@ async function sideQuery(opts) {
289985
290035
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
289986
290036
  }
289987
290037
  const messageText = extractFirstUserMessageText(messages);
289988
- const fingerprint = computeFingerprint(messageText, "2.3.3");
290038
+ const fingerprint = computeFingerprint(messageText, "2.3.4");
289989
290039
  const attributionHeader = getAttributionHeader(fingerprint);
289990
290040
  const systemBlocks = [
289991
290041
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -310737,7 +310787,7 @@ var init_user = __esm(() => {
310737
310787
  deviceId,
310738
310788
  sessionId: getSessionId(),
310739
310789
  email: getEmail(),
310740
- appVersion: "2.3.3",
310790
+ appVersion: "2.3.4",
310741
310791
  platform: getHostPlatformForAnalytics(),
310742
310792
  organizationUuid,
310743
310793
  accountUuid,
@@ -311802,7 +311852,7 @@ async function initializeBetaTracing(resource) {
311802
311852
  });
311803
311853
  logs.setGlobalLoggerProvider(loggerProvider);
311804
311854
  setLoggerProvider(loggerProvider);
311805
- const eventLogger = logs.getLogger("com.anthropic.claude_code.events", "2.3.3");
311855
+ const eventLogger = logs.getLogger("com.anthropic.claude_code.events", "2.3.4");
311806
311856
  setEventLogger(eventLogger);
311807
311857
  process.on("beforeExit", async () => {
311808
311858
  await loggerProvider?.forceFlush();
@@ -311842,7 +311892,7 @@ async function initializeTelemetry() {
311842
311892
  const platform2 = getPlatform();
311843
311893
  const baseAttributes = {
311844
311894
  [ATTR_SERVICE_NAME4]: "claude-code",
311845
- [ATTR_SERVICE_VERSION4]: "2.3.3"
311895
+ [ATTR_SERVICE_VERSION4]: "2.3.4"
311846
311896
  };
311847
311897
  if (platform2 === "wsl") {
311848
311898
  const wslVersion = getWslVersion();
@@ -311887,7 +311937,7 @@ async function initializeTelemetry() {
311887
311937
  } catch {}
311888
311938
  };
311889
311939
  registerCleanup(shutdownTelemetry2);
311890
- return meterProvider2.getMeter("com.anthropic.claude_code", "2.3.3");
311940
+ return meterProvider2.getMeter("com.anthropic.claude_code", "2.3.4");
311891
311941
  }
311892
311942
  const meterProvider = new MeterProvider4({
311893
311943
  resource,
@@ -311907,7 +311957,7 @@ async function initializeTelemetry() {
311907
311957
  });
311908
311958
  logs.setGlobalLoggerProvider(loggerProvider);
311909
311959
  setLoggerProvider(loggerProvider);
311910
- const eventLogger = logs.getLogger("com.anthropic.claude_code.events", "2.3.3");
311960
+ const eventLogger = logs.getLogger("com.anthropic.claude_code.events", "2.3.4");
311911
311961
  setEventLogger(eventLogger);
311912
311962
  logForDebugging("[3P telemetry] Event logger set successfully");
311913
311963
  process.on("beforeExit", async () => {
@@ -311969,7 +312019,7 @@ Current timeout: ${timeoutMs}ms
311969
312019
  }
311970
312020
  };
311971
312021
  registerCleanup(shutdownTelemetry);
311972
- return meterProvider.getMeter("com.anthropic.claude_code", "2.3.3");
312022
+ return meterProvider.getMeter("com.anthropic.claude_code", "2.3.4");
311973
312023
  }
311974
312024
  async function flushTelemetry() {
311975
312025
  const meterProvider = getMeterProvider();
@@ -313159,7 +313209,7 @@ function detectLinuxGlobPatternWarnings() {
313159
313209
  }
313160
313210
  async function getDoctorDiagnostic() {
313161
313211
  const installationType = await getCurrentInstallationType();
313162
- const version = typeof MACRO !== "undefined" ? "2.3.3" : "unknown";
313212
+ const version = typeof MACRO !== "undefined" ? "2.3.4" : "unknown";
313163
313213
  const installationPath = await getInstallationPath();
313164
313214
  const invokedBinary = getInvokedBinary();
313165
313215
  const multipleInstallations = await detectMultipleInstallations();
@@ -314100,8 +314150,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
314100
314150
  const maxVersion = await getMaxVersion();
314101
314151
  if (maxVersion && gt(version, maxVersion)) {
314102
314152
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version} to ${maxVersion}`);
314103
- if (gte("2.3.3", maxVersion)) {
314104
- logForDebugging(`Native installer: current version ${"2.3.3"} is already at or above maxVersion ${maxVersion}, skipping update`);
314153
+ if (gte("2.3.4", maxVersion)) {
314154
+ logForDebugging(`Native installer: current version ${"2.3.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
314105
314155
  logEvent("tengu_native_update_skipped_max_version", {
314106
314156
  latency_ms: Date.now() - startTime,
314107
314157
  max_version: maxVersion,
@@ -314112,7 +314162,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
314112
314162
  version = maxVersion;
314113
314163
  }
314114
314164
  }
314115
- if (!forceReinstall && version === "2.3.3" && await versionIsAvailable(version) && await isPossibleLocalClawdBinary(executablePath)) {
314165
+ if (!forceReinstall && version === "2.3.4" && await versionIsAvailable(version) && await isPossibleLocalClawdBinary(executablePath)) {
314116
314166
  logForDebugging(`Found ${version} at ${executablePath}, skipping install`);
314117
314167
  logEvent("tengu_native_update_complete", {
314118
314168
  latency_ms: Date.now() - startTime,
@@ -351907,6 +351957,7 @@ var SUPPORTED_SETTINGS;
351907
351957
  var init_supportedSettings = __esm(() => {
351908
351958
  init_config();
351909
351959
  init_configConstants();
351960
+ init_context();
351910
351961
  init_modelOptions();
351911
351962
  init_validateModel();
351912
351963
  init_theme();
@@ -351936,9 +351987,20 @@ var init_supportedSettings = __esm(() => {
351936
351987
  options: NOTIFICATION_CHANNELS
351937
351988
  },
351938
351989
  autoCompactEnabled: {
351939
- source: "global",
351990
+ source: "project",
351940
351991
  type: "boolean",
351941
- description: "Auto-compact when context is full"
351992
+ description: "Auto-compact when this project approaches its context limit",
351993
+ formatOnRead: (v2) => typeof v2 === "boolean" ? v2 : getGlobalConfig().autoCompactEnabled
351994
+ },
351995
+ compactContextWindowTokens: {
351996
+ source: "project",
351997
+ type: "number",
351998
+ description: "Project-local context window cap used for usage and compaction thresholds",
351999
+ coerceOnWrite: (v2) => {
352000
+ const parsed = typeof v2 === "number" ? Number.isFinite(v2) ? Math.trunc(v2) : null : parseContextWindowString(String(v2));
352001
+ return parsed ? { value: parsed } : { error: "compactContextWindowTokens requires a value like 200k, 1m, or 131072." };
352002
+ },
352003
+ formatOnRead: (v2) => formatCompactContextWindowOption(typeof v2 === "number" ? v2 : undefined)
351942
352004
  },
351943
352005
  autoMemoryEnabled: {
351944
352006
  source: "settings",
@@ -352024,7 +352086,8 @@ var init_supportedSettings = __esm(() => {
352024
352086
  // src/tools/ConfigTool/prompt.ts
352025
352087
  function generatePrompt() {
352026
352088
  const globalSettings = [];
352027
- const projectSettings = [];
352089
+ const userSettings = [];
352090
+ const projectLocalSettings = [];
352028
352091
  for (const [key, config] of Object.entries(SUPPORTED_SETTINGS)) {
352029
352092
  if (key === "model")
352030
352093
  continue;
@@ -352036,12 +352099,16 @@ function generatePrompt() {
352036
352099
  line += `: ${options.map((o) => `"${o}"`).join(", ")}`;
352037
352100
  } else if (config.type === "boolean") {
352038
352101
  line += `: true/false`;
352102
+ } else if (config.type === "number") {
352103
+ line += `: number`;
352039
352104
  }
352040
352105
  line += ` - ${config.description}`;
352041
352106
  if (config.source === "global") {
352042
352107
  globalSettings.push(line);
352108
+ } else if (config.source === "project") {
352109
+ projectLocalSettings.push(line);
352043
352110
  } else {
352044
- projectSettings.push(line);
352111
+ userSettings.push(line);
352045
352112
  }
352046
352113
  }
352047
352114
  const modelSection = generateModelSection();
@@ -352061,8 +352128,12 @@ The following settings are available for you to change:
352061
352128
  ${globalSettings.join(`
352062
352129
  `)}
352063
352130
 
352064
- ### Project Settings (stored in settings.json)
352065
- ${projectSettings.join(`
352131
+ ### User Settings (stored in settings.json)
352132
+ ${userSettings.join(`
352133
+ `)}
352134
+
352135
+ ### Project-Local Settings (stored per project)
352136
+ ${projectLocalSettings.join(`
352066
352137
  `)}
352067
352138
 
352068
352139
  ${modelSection}
@@ -352189,8 +352260,7 @@ function getValue2(source, path10) {
352189
352260
  return;
352190
352261
  return config[key];
352191
352262
  }
352192
- const settings = getInitialSettings();
352193
- let current = settings;
352263
+ let current = source === "project" ? getCurrentProjectConfig() : getInitialSettings();
352194
352264
  for (const key of path10) {
352195
352265
  if (current && typeof current === "object" && key in current) {
352196
352266
  current = current[key];
@@ -352319,9 +352389,23 @@ var init_ConfigTool = __esm(() => {
352319
352389
  };
352320
352390
  }
352321
352391
  let finalValue = value;
352392
+ if (config.coerceOnWrite) {
352393
+ const result = config.coerceOnWrite(finalValue);
352394
+ if ("error" in result) {
352395
+ return {
352396
+ data: {
352397
+ success: false,
352398
+ operation: "set",
352399
+ setting,
352400
+ error: result.error
352401
+ }
352402
+ };
352403
+ }
352404
+ finalValue = result.value;
352405
+ }
352322
352406
  if (config.type === "boolean") {
352323
- if (typeof value === "string") {
352324
- const lower2 = value.toLowerCase().trim();
352407
+ if (typeof finalValue === "string") {
352408
+ const lower2 = finalValue.toLowerCase().trim();
352325
352409
  if (lower2 === "true")
352326
352410
  finalValue = true;
352327
352411
  else if (lower2 === "false")
@@ -352338,6 +352422,21 @@ var init_ConfigTool = __esm(() => {
352338
352422
  };
352339
352423
  }
352340
352424
  }
352425
+ if (config.type === "number") {
352426
+ if (typeof finalValue === "string" && finalValue.trim()) {
352427
+ finalValue = Number(finalValue);
352428
+ }
352429
+ if (typeof finalValue !== "number" || !Number.isFinite(finalValue)) {
352430
+ return {
352431
+ data: {
352432
+ success: false,
352433
+ operation: "set",
352434
+ setting,
352435
+ error: `${setting} requires a finite number.`
352436
+ }
352437
+ };
352438
+ }
352439
+ }
352341
352440
  const options = getOptionsForSetting(setting);
352342
352441
  if (options && !options.includes(String(finalValue))) {
352343
352442
  return {
@@ -352382,6 +352481,23 @@ var init_ConfigTool = __esm(() => {
352382
352481
  return prev;
352383
352482
  return { ...prev, [key]: finalValue };
352384
352483
  });
352484
+ } else if (config.source === "project") {
352485
+ const key = path10[0];
352486
+ if (!key) {
352487
+ return {
352488
+ data: {
352489
+ success: false,
352490
+ operation: "set",
352491
+ setting,
352492
+ error: "Invalid setting path"
352493
+ }
352494
+ };
352495
+ }
352496
+ saveCurrentProjectConfig((prev) => {
352497
+ if (prev[key] === finalValue)
352498
+ return prev;
352499
+ return { ...prev, [key]: finalValue };
352500
+ });
352385
352501
  } else {
352386
352502
  const update = buildNestedObject(path10, finalValue);
352387
352503
  const result = updateSettingsForSource("userSettings", update);
@@ -360387,7 +360503,7 @@ function getAnthropicEnvMetadata() {
360387
360503
  function getBuildAgeMinutes() {
360388
360504
  if (false)
360389
360505
  ;
360390
- const buildTime = new Date("2026-05-10T20:16:44.115Z").getTime();
360506
+ const buildTime = new Date("2026-05-10T21:07:59.152Z").getTime();
360391
360507
  if (isNaN(buildTime))
360392
360508
  return;
360393
360509
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -388416,7 +388532,7 @@ function Feedback({
388416
388532
  platform: env3.platform,
388417
388533
  gitRepo: envInfo.isGit,
388418
388534
  terminal: env3.terminal,
388419
- version: "2.3.3",
388535
+ version: "2.3.4",
388420
388536
  transcript: normalizeMessagesForAPI(messages),
388421
388537
  errors: sanitizedErrors,
388422
388538
  lastApiRequest: getLastAPIRequest(),
@@ -388608,7 +388724,7 @@ function Feedback({
388608
388724
  ", ",
388609
388725
  env3.terminal,
388610
388726
  ", v",
388611
- "2.3.3"
388727
+ "2.3.4"
388612
388728
  ]
388613
388729
  }, undefined, true, undefined, this)
388614
388730
  ]
@@ -388714,7 +388830,7 @@ ${sanitizedDescription}
388714
388830
  ` + `**Environment Info**
388715
388831
  ` + `- Platform: ${env3.platform}
388716
388832
  ` + `- Terminal: ${env3.terminal}
388717
- ` + `- Version: ${"2.3.3"}
388833
+ ` + `- Version: ${"2.3.4"}
388718
388834
  ` + `- Feedback ID: ${feedbackId}
388719
388835
  ` + `
388720
388836
  **Errors**
@@ -391323,7 +391439,7 @@ function buildPrimarySection() {
391323
391439
  }, undefined, false, undefined, this);
391324
391440
  return [{
391325
391441
  label: "Version",
391326
- value: "2.3.3"
391442
+ value: "2.3.4"
391327
391443
  }, {
391328
391444
  label: "Session name",
391329
391445
  value: nameValue
@@ -394542,7 +394658,9 @@ function Config({
394542
394658
  const [, setTheme] = useTheme();
394543
394659
  const themeSetting = useThemeSetting();
394544
394660
  const [globalConfig, setGlobalConfig] = import_react104.useState(getGlobalConfig());
394661
+ const [projectConfig, setProjectConfig] = import_react104.useState(getCurrentProjectConfig());
394545
394662
  const initialConfig = React54.useRef(getGlobalConfig());
394663
+ const initialProjectConfig = React54.useRef(getCurrentProjectConfig());
394546
394664
  const [settingsData, setSettingsData] = import_react104.useState(getInitialSettings());
394547
394665
  const initialSettingsData = React54.useRef(getInitialSettings());
394548
394666
  const [currentOutputStyle, setCurrentOutputStyle] = import_react104.useState(settingsData?.outputStyle || DEFAULT_OUTPUT_STYLE_NAME);
@@ -394670,15 +394788,15 @@ function Config({
394670
394788
  {
394671
394789
  id: "autoCompactEnabled",
394672
394790
  label: "Auto-compact",
394673
- value: globalConfig.autoCompactEnabled,
394791
+ value: projectConfig.autoCompactEnabled ?? globalConfig.autoCompactEnabled,
394674
394792
  type: "boolean",
394675
394793
  onChange(autoCompactEnabled) {
394676
- saveGlobalConfig((current_0) => ({
394794
+ saveCurrentProjectConfig((current_0) => ({
394677
394795
  ...current_0,
394678
394796
  autoCompactEnabled
394679
394797
  }));
394680
- setGlobalConfig({
394681
- ...getGlobalConfig(),
394798
+ setProjectConfig({
394799
+ ...getCurrentProjectConfig(),
394682
394800
  autoCompactEnabled
394683
394801
  });
394684
394802
  logEvent("tengu_auto_compact_setting_changed", {
@@ -394689,17 +394807,17 @@ function Config({
394689
394807
  {
394690
394808
  id: "compactContextWindowTokens",
394691
394809
  label: "Compact context window",
394692
- value: formatCompactContextWindowOption(globalConfig.compactContextWindowTokens),
394810
+ value: formatCompactContextWindowOption(projectConfig.compactContextWindowTokens),
394693
394811
  options: [formatCompactContextWindowOption(undefined), ...COMPACT_CONTEXT_WINDOW_CHOICES.map(formatCompactContextWindowOption)],
394694
394812
  type: "enum",
394695
394813
  onChange(value) {
394696
394814
  const compactContextWindowTokens = COMPACT_CONTEXT_WINDOW_CHOICES.find((tokens) => formatCompactContextWindowOption(tokens) === value);
394697
- saveGlobalConfig((current_0) => ({
394815
+ saveCurrentProjectConfig((current_0) => ({
394698
394816
  ...current_0,
394699
394817
  compactContextWindowTokens
394700
394818
  }));
394701
- setGlobalConfig({
394702
- ...getGlobalConfig(),
394819
+ setProjectConfig({
394820
+ ...getCurrentProjectConfig(),
394703
394821
  compactContextWindowTokens
394704
394822
  });
394705
394823
  logEvent("tengu_compact_context_window_changed", {
@@ -395247,8 +395365,8 @@ function Config({
395247
395365
  id: "showExternalIncludesDialog",
395248
395366
  label: "External LOCALCLAWD.md includes",
395249
395367
  value: (() => {
395250
- const projectConfig = getCurrentProjectConfig();
395251
- if (projectConfig.hasClaudeMdExternalIncludesApproved) {
395368
+ const projectConfig2 = getCurrentProjectConfig();
395369
+ if (projectConfig2.hasClaudeMdExternalIncludesApproved) {
395252
395370
  return "true";
395253
395371
  } else {
395254
395372
  return "false";
@@ -395397,11 +395515,11 @@ function Config({
395397
395515
  if (globalConfig.autoInstallIdeExtension !== initialConfig.current.autoInstallIdeExtension) {
395398
395516
  formattedChanges.push(`${globalConfig.autoInstallIdeExtension ? "Enabled" : "Disabled"} auto-install IDE extension`);
395399
395517
  }
395400
- if (globalConfig.autoCompactEnabled !== initialConfig.current.autoCompactEnabled) {
395401
- formattedChanges.push(`${globalConfig.autoCompactEnabled ? "Enabled" : "Disabled"} auto-compact`);
395518
+ if (projectConfig.autoCompactEnabled !== initialProjectConfig.current.autoCompactEnabled) {
395519
+ formattedChanges.push(`${projectConfig.autoCompactEnabled ?? globalConfig.autoCompactEnabled ? "Enabled" : "Disabled"} auto-compact`);
395402
395520
  }
395403
- if (globalConfig.compactContextWindowTokens !== initialConfig.current.compactContextWindowTokens) {
395404
- formattedChanges.push(`Set compact context window to ${source_default.bold(formatCompactContextWindowOption(globalConfig.compactContextWindowTokens))}`);
395521
+ if (projectConfig.compactContextWindowTokens !== initialProjectConfig.current.compactContextWindowTokens) {
395522
+ formattedChanges.push(`Set compact context window to ${source_default.bold(formatCompactContextWindowOption(projectConfig.compactContextWindowTokens))}`);
395405
395523
  }
395406
395524
  if (globalConfig.respectGitignore !== initialConfig.current.respectGitignore) {
395407
395525
  formattedChanges.push(`${globalConfig.respectGitignore ? "Enabled" : "Disabled"} respect .gitignore in file picker`);
@@ -396004,7 +396122,7 @@ function Config({
396004
396122
  }
396005
396123
  }, undefined, false, undefined, this)
396006
396124
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime176.jsxDEV(ChannelDowngradeDialog, {
396007
- currentVersion: "2.3.3",
396125
+ currentVersion: "2.3.4",
396008
396126
  onChoice: (choice) => {
396009
396127
  setShowSubmenu(null);
396010
396128
  setTabsHidden(false);
@@ -396016,7 +396134,7 @@ function Config({
396016
396134
  autoUpdatesChannel: "stable"
396017
396135
  };
396018
396136
  if (choice === "stay") {
396019
- newSettings.minimumVersion = "2.3.3";
396137
+ newSettings.minimumVersion = "2.3.4";
396020
396138
  }
396021
396139
  updateSettingsForSource("userSettings", newSettings);
396022
396140
  setSettingsData((prev_27) => ({
@@ -411795,7 +411913,7 @@ async function autoDetectProviderContextWindow() {
411795
411913
  return;
411796
411914
  _detected = true;
411797
411915
  try {
411798
- const configured = getGlobalConfig().compactContextWindowTokens;
411916
+ const configured = getCurrentProjectConfig().compactContextWindowTokens;
411799
411917
  if (configured && configured > 0) {
411800
411918
  setLocalProviderContextWindow(configured);
411801
411919
  logForDebugging(`[context] Using persisted context window: ${configured} tokens`);
@@ -411814,8 +411932,11 @@ async function autoDetectProviderContextWindow() {
411814
411932
  }
411815
411933
  if (detected && detected > 0) {
411816
411934
  setLocalProviderContextWindow(detected);
411817
- saveGlobalConfig((c5) => ({ ...c5, compactContextWindowTokens: detected }));
411818
- logForDebugging(`[context] Auto-detected context window from ${provider}: ${detected} tokens (persisted)`);
411935
+ saveCurrentProjectConfig((c5) => ({
411936
+ ...c5,
411937
+ compactContextWindowTokens: detected
411938
+ }));
411939
+ logForDebugging(`[context] Auto-detected context window from ${provider}: ${detected} tokens (persisted for project)`);
411819
411940
  }
411820
411941
  } catch (err2) {
411821
411942
  logForDebugging(`[context] Auto-detect context window failed (non-fatal): ${err2}`);
@@ -411848,7 +411969,11 @@ function barLine(used, total, width = 40) {
411848
411969
  return `[${"█".repeat(filled)}${" ".repeat(empty)}] ${Math.round(pct * 100)}%`;
411849
411970
  }
411850
411971
  function applySize(parsed, model, onDone) {
411851
- saveGlobalConfig((c5) => ({ ...c5, compactContextWindowTokens: parsed }));
411972
+ saveCurrentProjectConfig((c5) => ({ ...c5, compactContextWindowTokens: parsed }));
411973
+ saveGlobalConfig((c5) => {
411974
+ const { compactContextWindowTokens: _legacy, ...rest } = c5;
411975
+ return rest;
411976
+ });
411852
411977
  setLocalProviderContextWindow(parsed);
411853
411978
  onDone([
411854
411979
  `Context window set to ${fmtTokens(parsed)} tokens.`,
@@ -411880,15 +412005,16 @@ var call51 = async (onDone, context7, args) => {
411880
412005
  return applySize(parsed, model, onDone);
411881
412006
  }
411882
412007
  if (sub === "reset") {
412008
+ saveCurrentProjectConfig((c5) => {
412009
+ const { compactContextWindowTokens: _drop, ...rest } = c5;
412010
+ return rest;
412011
+ });
411883
412012
  saveGlobalConfig((c5) => {
411884
412013
  const { compactContextWindowTokens: _drop, ...rest } = c5;
411885
412014
  return rest;
411886
412015
  });
411887
412016
  setLocalProviderContextWindow(null);
411888
412017
  resetContextWindowDetection();
411889
- const hadEnv = process.env.LOCALCLAWD_MAX_CONTEXT_TOKENS || process.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
411890
- delete process.env.LOCALCLAWD_MAX_CONTEXT_TOKENS;
411891
- delete process.env.CLAUDE_CODE_MAX_CONTEXT_TOKENS;
411892
412018
  await autoDetectProviderContextWindow();
411893
412019
  const detected = getLocalProviderContextWindow();
411894
412020
  const effective = getContextWindowForModel(model);
@@ -411898,9 +412024,6 @@ var call51 = async (onDone, context7, args) => {
411898
412024
  `Effective window: ${fmtTokens(getEffectiveContextWindowSize(model))} (minus output reservation).`,
411899
412025
  `Auto-compact threshold: ${fmtTokens(getAutoCompactThreshold(model))}.`
411900
412026
  ];
411901
- if (hadEnv) {
411902
- lines2.push("", "Note: LOCALCLAWD_MAX_CONTEXT_TOKENS / CLAUDE_CODE_MAX_CONTEXT_TOKENS were set in this", "process and have been cleared for this session. Unset them in your shell to make it", "permanent.");
411903
- }
411904
412027
  onDone(lines2.join(`
411905
412028
  `), { display: "system" });
411906
412029
  return null;
@@ -411909,7 +412032,7 @@ var call51 = async (onDone, context7, args) => {
411909
412032
  const toggle = parts[1]?.toLowerCase();
411910
412033
  if (toggle === "on" || toggle === "off") {
411911
412034
  const enable = toggle === "on";
411912
- saveGlobalConfig((c5) => ({ ...c5, autoCompactEnabled: enable }));
412035
+ saveCurrentProjectConfig((c5) => ({ ...c5, autoCompactEnabled: enable }));
411913
412036
  onDone(`Auto-compact ${enable ? "enabled" : "disabled"}.`, { display: "system" });
411914
412037
  return null;
411915
412038
  }
@@ -411919,7 +412042,7 @@ var call51 = async (onDone, context7, args) => {
411919
412042
  const totalWindow = getContextWindowForModel(model);
411920
412043
  const effectiveWindow = getEffectiveContextWindowSize(model);
411921
412044
  const autoCompactThreshold = getAutoCompactThreshold(model);
411922
- const persisted = getGlobalConfig().compactContextWindowTokens;
412045
+ const persisted = getCurrentProjectConfig().compactContextWindowTokens;
411923
412046
  const detectedFromProvider = getLocalProviderContextWindow();
411924
412047
  const tokenUsage = tokenCountWithEstimation(context7.messages);
411925
412048
  const autoCompact = isAutoCompactEnabled();
@@ -413535,7 +413658,7 @@ function Help(t0) {
413535
413658
  let t6;
413536
413659
  if ($2[31] !== tabs) {
413537
413660
  t6 = /* @__PURE__ */ jsx_dev_runtime218.jsxDEV(Tabs, {
413538
- title: `localclawd v${"2.3.3"}`,
413661
+ title: `localclawd v${"2.3.4"}`,
413539
413662
  color: "professionalBlue",
413540
413663
  defaultTab: "general",
413541
413664
  children: tabs
@@ -430797,7 +430920,7 @@ function getRecentReleaseNotes(currentVersion, previousVersion, changelogContent
430797
430920
  }
430798
430921
  return [];
430799
430922
  }
430800
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "2.3.3") {
430923
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "2.3.4") {
430801
430924
  if (process.env.USER_TYPE === "ant") {
430802
430925
  const changelog = MACRO.VERSION_CHANGELOG;
430803
430926
  if (changelog) {
@@ -430824,7 +430947,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "2.3.3") {
430824
430947
  releaseNotes
430825
430948
  };
430826
430949
  }
430827
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "2.3.3") {
430950
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "2.3.4") {
430828
430951
  if (process.env.USER_TYPE === "ant") {
430829
430952
  const changelog = MACRO.VERSION_CHANGELOG;
430830
430953
  if (changelog) {
@@ -430981,7 +431104,7 @@ function getRecentActivitySync() {
430981
431104
  return cachedActivity;
430982
431105
  }
430983
431106
  function getLogoDisplayData() {
430984
- const version = process.env.DEMO_VERSION ?? "2.3.3";
431107
+ const version = process.env.DEMO_VERSION ?? "2.3.4";
430985
431108
  const serverUrl = getDirectConnectServerUrl();
430986
431109
  const displayPath = process.env.DEMO_VERSION ? "/code/claude" : getDisplayPath(getCwd());
430987
431110
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -432081,7 +432204,7 @@ function Logo() {
432081
432204
  if ($2[2] === Symbol.for("react.memo_cache_sentinel")) {
432082
432205
  t2 = () => {
432083
432206
  const currentConfig = getGlobalConfig();
432084
- if (currentConfig.lastReleaseNotesSeen === "2.3.3") {
432207
+ if (currentConfig.lastReleaseNotesSeen === "2.3.4") {
432085
432208
  return;
432086
432209
  }
432087
432210
  saveGlobalConfig(_temp325);
@@ -432740,12 +432863,12 @@ function Logo() {
432740
432863
  return t41;
432741
432864
  }
432742
432865
  function _temp325(current) {
432743
- if (current.lastReleaseNotesSeen === "2.3.3") {
432866
+ if (current.lastReleaseNotesSeen === "2.3.4") {
432744
432867
  return current;
432745
432868
  }
432746
432869
  return {
432747
432870
  ...current,
432748
- lastReleaseNotesSeen: "2.3.3"
432871
+ lastReleaseNotesSeen: "2.3.4"
432749
432872
  };
432750
432873
  }
432751
432874
  function _temp240(s_0) {
@@ -463204,7 +463327,7 @@ async function captureMemoryDiagnostics(trigger, dumpNumber = 0) {
463204
463327
  smapsRollup,
463205
463328
  platform: process.platform,
463206
463329
  nodeVersion: process.version,
463207
- ccVersion: "2.3.3"
463330
+ ccVersion: "2.3.4"
463208
463331
  };
463209
463332
  }
463210
463333
  async function performHeapDump(trigger = "manual", dumpNumber = 0) {
@@ -463789,7 +463912,7 @@ var init_bridge_kick = __esm(() => {
463789
463912
  var call86 = async () => {
463790
463913
  return {
463791
463914
  type: "text",
463792
- value: `${"2.3.3"} (built ${"2026-05-10T20:16:44.115Z"})`
463915
+ value: `${"2.3.4"} (built ${"2026-05-10T21:07:59.152Z"})`
463793
463916
  };
463794
463917
  }, version, version_default;
463795
463918
  var init_version = __esm(() => {
@@ -471733,7 +471856,7 @@ function generateHtmlReport(data, insights) {
471733
471856
  </html>`;
471734
471857
  }
471735
471858
  function buildExportData(data, insights, facets, remoteStats) {
471736
- const version2 = typeof MACRO !== "undefined" ? "2.3.3" : "unknown";
471859
+ const version2 = typeof MACRO !== "undefined" ? "2.3.4" : "unknown";
471737
471860
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
471738
471861
  const facets_summary = {
471739
471862
  total: facets.size,
@@ -475932,7 +476055,7 @@ var init_sessionStorage = __esm(() => {
475932
476055
  init_settings2();
475933
476056
  init_slowOperations();
475934
476057
  init_uuid();
475935
- VERSION6 = typeof MACRO !== "undefined" ? "2.3.3" : "unknown";
476058
+ VERSION6 = typeof MACRO !== "undefined" ? "2.3.4" : "unknown";
475936
476059
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
475937
476060
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
475938
476061
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -477063,7 +477186,7 @@ var init_filesystem = __esm(() => {
477063
477186
  });
477064
477187
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
477065
477188
  const nonce = randomBytes20(16).toString("hex");
477066
- return join154(getClaudeTempDir(), "bundled-skills", "2.3.3", nonce);
477189
+ return join154(getClaudeTempDir(), "bundled-skills", "2.3.4", nonce);
477067
477190
  });
477068
477191
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
477069
477192
  });
@@ -486300,7 +486423,7 @@ function buildSystemInitMessage(inputs) {
486300
486423
  slash_commands: inputs.commands.filter((c5) => c5.userInvocable !== false).map((c5) => c5.name),
486301
486424
  apiKeySource: getAnthropicApiKeyWithSource().source,
486302
486425
  betas: getSdkBetas(),
486303
- claude_code_version: "2.3.3",
486426
+ claude_code_version: "2.3.4",
486304
486427
  output_style: outputStyle2,
486305
486428
  agents: inputs.agents.map((agent) => agent.agentType),
486306
486429
  skills: inputs.skills.filter((s2) => s2.userInvocable !== false).map((skill) => skill.name),
@@ -500457,7 +500580,7 @@ var init_useVoiceEnabled = __esm(() => {
500457
500580
  function getSemverPart(version2) {
500458
500581
  return `${import_semver10.major(version2, { loose: true })}.${import_semver10.minor(version2, { loose: true })}.${import_semver10.patch(version2, { loose: true })}`;
500459
500582
  }
500460
- function useUpdateNotification(updatedVersion, initialVersion = "2.3.3") {
500583
+ function useUpdateNotification(updatedVersion, initialVersion = "2.3.4") {
500461
500584
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react214.useState(() => getSemverPart(initialVersion));
500462
500585
  if (!updatedVersion) {
500463
500586
  return null;
@@ -500497,7 +500620,7 @@ function AutoUpdater({
500497
500620
  return;
500498
500621
  }
500499
500622
  if (false) {}
500500
- const currentVersion = "2.3.3";
500623
+ const currentVersion = "2.3.4";
500501
500624
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
500502
500625
  let latestVersion = await getLatestVersion(channel);
500503
500626
  const isDisabled = isAutoUpdaterDisabled();
@@ -500708,12 +500831,12 @@ function NativeAutoUpdater({
500708
500831
  logEvent("tengu_native_auto_updater_start", {});
500709
500832
  try {
500710
500833
  const maxVersion = await getMaxVersion();
500711
- if (maxVersion && gt("2.3.3", maxVersion)) {
500834
+ if (maxVersion && gt("2.3.4", maxVersion)) {
500712
500835
  const msg = await getMaxVersionMessage();
500713
500836
  setMaxVersionIssue(msg ?? "affects your version");
500714
500837
  }
500715
500838
  const result = await installLatest(channel);
500716
- const currentVersion = "2.3.3";
500839
+ const currentVersion = "2.3.4";
500717
500840
  const latencyMs = Date.now() - startTime;
500718
500841
  if (result.lockFailed) {
500719
500842
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -500848,17 +500971,17 @@ function PackageManagerAutoUpdater(t0) {
500848
500971
  const maxVersion = await getMaxVersion();
500849
500972
  if (maxVersion && latest && gt(latest, maxVersion)) {
500850
500973
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
500851
- if (gte("2.3.3", maxVersion)) {
500852
- logForDebugging(`PackageManagerAutoUpdater: current version ${"2.3.3"} is already at or above maxVersion ${maxVersion}, skipping update`);
500974
+ if (gte("2.3.4", maxVersion)) {
500975
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"2.3.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
500853
500976
  setUpdateAvailable(false);
500854
500977
  return;
500855
500978
  }
500856
500979
  latest = maxVersion;
500857
500980
  }
500858
- const hasUpdate = latest && !gte("2.3.3", latest) && !shouldSkipVersion(latest);
500981
+ const hasUpdate = latest && !gte("2.3.4", latest) && !shouldSkipVersion(latest);
500859
500982
  setUpdateAvailable(!!hasUpdate);
500860
500983
  if (hasUpdate) {
500861
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"2.3.3"} -> ${latest}`);
500984
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"2.3.4"} -> ${latest}`);
500862
500985
  }
500863
500986
  };
500864
500987
  $2[0] = t1;
@@ -500892,7 +501015,7 @@ function PackageManagerAutoUpdater(t0) {
500892
501015
  wrap: "truncate",
500893
501016
  children: [
500894
501017
  "currentVersion: ",
500895
- "2.3.3"
501018
+ "2.3.4"
500896
501019
  ]
500897
501020
  }, undefined, true, undefined, this);
500898
501021
  $2[3] = verbose;
@@ -508452,7 +508575,7 @@ function buildStatusLineCommandInput(permissionMode, exceedsHalfContext, setting
508452
508575
  project_dir: getOriginalCwd(),
508453
508576
  added_dirs: addedDirs
508454
508577
  },
508455
- version: "2.3.3",
508578
+ version: "2.3.4",
508456
508579
  output_style: {
508457
508580
  name: outputStyleName
508458
508581
  },
@@ -520024,7 +520147,7 @@ async function submitTranscriptShare(messages, trigger, appearanceId) {
520024
520147
  } catch {}
520025
520148
  const data = {
520026
520149
  trigger,
520027
- version: "2.3.3",
520150
+ version: "2.3.4",
520028
520151
  platform: process.platform,
520029
520152
  transcript,
520030
520153
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -536997,7 +537120,7 @@ function appendToLog(path17, message) {
536997
537120
  cwd: getFsImplementation().cwd(),
536998
537121
  userType: process.env.USER_TYPE,
536999
537122
  sessionId: getSessionId(),
537000
- version: "2.3.3"
537123
+ version: "2.3.4"
537001
537124
  };
537002
537125
  getLogWriter(path17).write(messageWithTimestamp);
537003
537126
  }
@@ -537256,7 +537379,7 @@ To attach: ${source_default.bold(`tmux attach -t ${tmuxSessionName}`)}`));
537256
537379
  startToolRpcServer();
537257
537380
  startScheduler();
537258
537381
  initSecretStore();
537259
- const persistedCtx = getGlobalConfig().compactContextWindowTokens;
537382
+ const persistedCtx = getCurrentProjectConfig().compactContextWindowTokens;
537260
537383
  if (persistedCtx && persistedCtx > 0) {
537261
537384
  logForDebugging(`[context] Using configured context window: ${persistedCtx} tokens`);
537262
537385
  } else if (isLocalLLMProviderEnabled()) {
@@ -540796,8 +540919,8 @@ async function getEnvLessBridgeConfig() {
540796
540919
  }
540797
540920
  async function checkEnvLessBridgeMinVersion() {
540798
540921
  const cfg = await getEnvLessBridgeConfig();
540799
- if (cfg.min_version && lt("2.3.3", cfg.min_version)) {
540800
- return `Your version of localclawd (${"2.3.3"}) is too old for Remote Control.
540922
+ if (cfg.min_version && lt("2.3.4", cfg.min_version)) {
540923
+ return `Your version of localclawd (${"2.3.4"}) is too old for Remote Control.
540801
540924
  Version ${cfg.min_version} or higher is required. Run \`localclawd update\` to update.`;
540802
540925
  }
540803
540926
  return null;
@@ -541269,7 +541392,7 @@ async function initBridgeCore(params) {
541269
541392
  const rawApi = createBridgeApiClient({
541270
541393
  baseUrl,
541271
541394
  getAccessToken,
541272
- runnerVersion: "2.3.3",
541395
+ runnerVersion: "2.3.4",
541273
541396
  onDebug: logForDebugging,
541274
541397
  onAuth401,
541275
541398
  getTrustedDeviceToken
@@ -546988,7 +547111,7 @@ async function startMCPServer(cwd3, debug4, verbose) {
546988
547111
  setCwd(cwd3);
546989
547112
  const server = new Server({
546990
547113
  name: "claude/tengu",
546991
- version: "2.3.3"
547114
+ version: "2.3.4"
546992
547115
  }, {
546993
547116
  capabilities: {
546994
547117
  tools: {}
@@ -548069,7 +548192,7 @@ function WelcomeLogo() {
548069
548192
  dimColor: true,
548070
548193
  children: [
548071
548194
  "v",
548072
- "2.3.3"
548195
+ "2.3.4"
548073
548196
  ]
548074
548197
  }, undefined, true, undefined, this)
548075
548198
  ]
@@ -548260,7 +548383,7 @@ __export(exports_update, {
548260
548383
  });
548261
548384
  async function update() {
548262
548385
  logEvent("tengu_update_check", {});
548263
- writeToStdout(`Current version: ${"2.3.3"}
548386
+ writeToStdout(`Current version: ${"2.3.4"}
548264
548387
  `);
548265
548388
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
548266
548389
  writeToStdout(`Checking for updates to ${channel} version...
@@ -548335,8 +548458,8 @@ async function update() {
548335
548458
  writeToStdout(`localclawd is managed by Homebrew.
548336
548459
  `);
548337
548460
  const latest = await getLatestVersion(channel);
548338
- if (latest && !gte("2.3.3", latest)) {
548339
- writeToStdout(`Update available: ${"2.3.3"} → ${latest}
548461
+ if (latest && !gte("2.3.4", latest)) {
548462
+ writeToStdout(`Update available: ${"2.3.4"} → ${latest}
548340
548463
  `);
548341
548464
  writeToStdout(`
548342
548465
  `);
@@ -548352,8 +548475,8 @@ async function update() {
548352
548475
  writeToStdout(`localclawd is managed by winget.
548353
548476
  `);
548354
548477
  const latest = await getLatestVersion(channel);
548355
- if (latest && !gte("2.3.3", latest)) {
548356
- writeToStdout(`Update available: ${"2.3.3"} → ${latest}
548478
+ if (latest && !gte("2.3.4", latest)) {
548479
+ writeToStdout(`Update available: ${"2.3.4"} → ${latest}
548357
548480
  `);
548358
548481
  writeToStdout(`
548359
548482
  `);
@@ -548367,8 +548490,8 @@ async function update() {
548367
548490
  writeToStdout(`localclawd is managed by apk.
548368
548491
  `);
548369
548492
  const latest = await getLatestVersion(channel);
548370
- if (latest && !gte("2.3.3", latest)) {
548371
- writeToStdout(`Update available: ${"2.3.3"} → ${latest}
548493
+ if (latest && !gte("2.3.4", latest)) {
548494
+ writeToStdout(`Update available: ${"2.3.4"} → ${latest}
548372
548495
  `);
548373
548496
  writeToStdout(`
548374
548497
  `);
@@ -548433,11 +548556,11 @@ async function update() {
548433
548556
  `);
548434
548557
  await gracefulShutdown(1);
548435
548558
  }
548436
- if (result.latestVersion === "2.3.3") {
548437
- writeToStdout(source_default.green(`localclawd is up to date (${"2.3.3"})`) + `
548559
+ if (result.latestVersion === "2.3.4") {
548560
+ writeToStdout(source_default.green(`localclawd is up to date (${"2.3.4"})`) + `
548438
548561
  `);
548439
548562
  } else {
548440
- writeToStdout(source_default.green(`Successfully updated from ${"2.3.3"} to version ${result.latestVersion}`) + `
548563
+ writeToStdout(source_default.green(`Successfully updated from ${"2.3.4"} to version ${result.latestVersion}`) + `
548441
548564
  `);
548442
548565
  await regenerateCompletionCache();
548443
548566
  }
@@ -548497,12 +548620,12 @@ async function update() {
548497
548620
  `);
548498
548621
  await gracefulShutdown(1);
548499
548622
  }
548500
- if (latestVersion === "2.3.3") {
548501
- writeToStdout(source_default.green(`localclawd is up to date (${"2.3.3"})`) + `
548623
+ if (latestVersion === "2.3.4") {
548624
+ writeToStdout(source_default.green(`localclawd is up to date (${"2.3.4"})`) + `
548502
548625
  `);
548503
548626
  await gracefulShutdown(0);
548504
548627
  }
548505
- writeToStdout(`New version available: ${latestVersion} (current: ${"2.3.3"})
548628
+ writeToStdout(`New version available: ${latestVersion} (current: ${"2.3.4"})
548506
548629
  `);
548507
548630
  writeToStdout(`Installing update...
548508
548631
  `);
@@ -548547,7 +548670,7 @@ async function update() {
548547
548670
  logForDebugging(`update: Installation status: ${status2}`);
548548
548671
  switch (status2) {
548549
548672
  case "success":
548550
- writeToStdout(source_default.green(`Successfully updated from ${"2.3.3"} to version ${latestVersion}`) + `
548673
+ writeToStdout(source_default.green(`Successfully updated from ${"2.3.4"} to version ${latestVersion}`) + `
548551
548674
  `);
548552
548675
  await regenerateCompletionCache();
548553
548676
  break;
@@ -549789,7 +549912,7 @@ Run with --debug for more details.
549789
549912
  }
549790
549913
  }
549791
549914
  logForDiagnosticsNoPII("info", "started", {
549792
- version: "2.3.3",
549915
+ version: "2.3.4",
549793
549916
  is_native_binary: isInBundledMode()
549794
549917
  });
549795
549918
  registerCleanup(async () => {
@@ -550573,7 +550696,7 @@ Usage: localclawd --remote "your task description"`, () => gracefulShutdown(1));
550573
550696
  pendingHookMessages
550574
550697
  }, renderAndRun);
550575
550698
  }
550576
- }).version("2.3.3 (localclawd)", "-v, --version", "Output the version number");
550699
+ }).version("2.3.4 (localclawd)", "-v, --version", "Output the version number");
550577
550700
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
550578
550701
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
550579
550702
  if (canUserConfigureAdvisor()) {
@@ -551087,7 +551210,7 @@ if (false) {}
551087
551210
  async function main2() {
551088
551211
  const args = process.argv.slice(2);
551089
551212
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
551090
- console.log(`${"2.3.3"} (localclawd)`);
551213
+ console.log(`${"2.3.4"} (localclawd)`);
551091
551214
  return;
551092
551215
  }
551093
551216
  const {
@@ -551178,4 +551301,4 @@ localclawd crashed: ${msg}
551178
551301
  process.exit(1);
551179
551302
  });
551180
551303
 
551181
- //# debugId=0B0FA34AFD16289164756E2164756E21
551304
+ //# debugId=A5F8BEA60598962064756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localclawd",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "Local-first coding CLI for vLLM, Ollama, and OpenAI-compatible backends.",
5
5
  "private": false,
6
6
  "type": "module",