@qwen-code/qwen-code 0.15.12-preview.3 → 0.16.0-preview.0

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 (64) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +20 -24
  2. package/bundled/qc-helper/docs/qwen-serve.md +29 -10
  3. package/chunks/{agent-LIAWUWAO.js → agent-ZNQPH67I.js} +15 -15
  4. package/chunks/{anthropicContentGenerator-4QE6LTVV.js → anthropicContentGenerator-ICBDZ6R2.js} +4 -4
  5. package/chunks/{askUserQuestion-QFSCBTUO.js → askUserQuestion-WQILGUSQ.js} +2 -2
  6. package/chunks/{chunk-SQNQIOD5.js → chunk-2B7UBDY5.js} +2 -2
  7. package/chunks/chunk-3MBY4GKN.js +350 -0
  8. package/chunks/{chunk-GC5RXNL2.js → chunk-7QXHXMC6.js} +23 -7
  9. package/chunks/{chunk-XLQ4E5PS.js → chunk-C3LHPHN2.js} +11 -11
  10. package/chunks/{chunk-UXW7MYAW.js → chunk-CW44BRRA.js} +1 -1
  11. package/chunks/{chunk-G27O2LD2.js → chunk-D5NTAHYL.js} +1 -1
  12. package/chunks/{chunk-CBVB66WY.js → chunk-EDYSNFEM.js} +1 -1
  13. package/chunks/{chunk-OCC4MZRS.js → chunk-F23NCRJ2.js} +1 -1
  14. package/chunks/{chunk-FYMSCRHM.js → chunk-FZIUV27X.js} +1 -1
  15. package/chunks/{chunk-5QQ5FGTU.js → chunk-G7YTSRES.js} +1 -1
  16. package/chunks/{chunk-AOJ3BBY7.js → chunk-JHMX4QTD.js} +9 -9
  17. package/chunks/{chunk-TPGOGCWM.js → chunk-JYQUJ5DS.js} +1 -1
  18. package/chunks/{chunk-FKVKVE6N.js → chunk-KXZ4TJB4.js} +1 -1
  19. package/chunks/{chunk-AJSOD5IR.js → chunk-MNPZ2WO6.js} +535 -141
  20. package/chunks/{chunk-BXNCPI75.js → chunk-NAID3ZWF.js} +2 -2
  21. package/chunks/{chunk-JMZQICAL.js → chunk-PPHYLJSS.js} +1 -1
  22. package/chunks/{chunk-CM2IESUE.js → chunk-PR4T27R7.js} +1 -1
  23. package/chunks/{chunk-CAWKL3UC.js → chunk-VTPOO6GV.js} +1 -1
  24. package/chunks/{chunk-GJXIKCKL.js → chunk-XP27SJMH.js} +76 -5
  25. package/chunks/{chunk-B7ZL7HUA.js → chunk-XVHR7ATJ.js} +1 -1
  26. package/chunks/{contextCommand-SVLAZMQL.js → contextCommand-IGBCEXI4.js} +16 -16
  27. package/chunks/{cron-create-WUTD5ZTH.js → cron-create-AVI3Q267.js} +2 -2
  28. package/chunks/{cron-delete-N3UQYCRA.js → cron-delete-ZCEGDXXV.js} +2 -2
  29. package/chunks/{cron-list-Z6RJJ4YH.js → cron-list-VN653OK5.js} +2 -2
  30. package/chunks/{edit-VNAZBIZR.js → edit-74Q4AFHQ.js} +16 -16
  31. package/chunks/{en-NRN4QBAT.js → en-FIUWJSZR.js} +1 -0
  32. package/chunks/{enter-worktree-FOF5YZIV.js → enter-worktree-H72HXC7D.js} +15 -15
  33. package/chunks/{exit-worktree-Y6QVAO3C.js → exit-worktree-FGIQO3S3.js} +15 -15
  34. package/chunks/{exitPlanMode-QZKO7GH7.js → exitPlanMode-NBR2PK2D.js} +15 -15
  35. package/chunks/{geminiContentGenerator-DYHZPKJX.js → geminiContentGenerator-33RP4WKD.js} +3 -3
  36. package/chunks/{glob-G7XATELV.js → glob-WEE3CJL6.js} +15 -15
  37. package/chunks/{grep-4SETMY47.js → grep-DZKSBFZK.js} +15 -15
  38. package/chunks/{keychain-token-storage-DMFP5IJM.js → keychain-token-storage-335UOLJ6.js} +2 -2
  39. package/chunks/{ls-SUILOZZB.js → ls-6F3VSP6S.js} +3 -3
  40. package/chunks/{lsp-6TQBWVMZ.js → lsp-67Y7DJN5.js} +2 -2
  41. package/chunks/{monitor-JTLJBJ7H.js → monitor-EDZWEZVS.js} +15 -15
  42. package/chunks/{openaiContentGenerator-3H7XOZBW.js → openaiContentGenerator-5NQG3W64.js} +10 -10
  43. package/chunks/{qwenContentGenerator-FAU3QPYO.js → qwenContentGenerator-4DPUUS6R.js} +17 -17
  44. package/chunks/{qwenOAuth2-JSQ7EPR3.js → qwenOAuth2-JE7H47TE.js} +3 -3
  45. package/chunks/{read-file-WWUQVNCZ.js → read-file-CQOF7BQ2.js} +7 -7
  46. package/chunks/{ripGrep-WCOAIWL6.js → ripGrep-KR5LKGTI.js} +15 -15
  47. package/chunks/{send-message-Q2JRAC3J.js → send-message-GB4AQZNC.js} +2 -2
  48. package/chunks/{serve-VJEEEXA6.js → serve-GAD2PEST.js} +501 -286
  49. package/chunks/{shell-IAOKGIJ6.js → shell-E2HMCBGR.js} +15 -15
  50. package/chunks/{skill-NHW6222K.js → skill-KDZH6UZ6.js} +9 -9
  51. package/chunks/{src-OWV5HVQQ.js → src-LY4RU5AI.js} +17 -15
  52. package/chunks/{syntheticOutput-S4DRGMQM.js → syntheticOutput-HFL3DE7R.js} +3 -3
  53. package/chunks/{task-stop-7THHVAQS.js → task-stop-ZQF26RXS.js} +2 -2
  54. package/chunks/{todoWrite-WKUGUTPX.js → todoWrite-U4SC643O.js} +3 -3
  55. package/chunks/{tool-search-MSJ6SXLI.js → tool-search-U4XQVLFU.js} +7 -7
  56. package/chunks/{web-fetch-OZE6ZQUF.js → web-fetch-BRWZ4WSE.js} +4 -4
  57. package/chunks/{write-file-RKCENFZ5.js → write-file-NBLRMNGB.js} +16 -16
  58. package/chunks/{zh-TW-XZEHEV5S.js → zh-TW-552S24LR.js} +1 -0
  59. package/chunks/{zh-RN3JULHO.js → zh-V32QONGV.js} +1 -0
  60. package/cli.js +598 -59
  61. package/locales/en.js +2 -0
  62. package/locales/zh-TW.js +1 -0
  63. package/locales/zh.js +1 -0
  64. package/package.json +2 -2
@@ -39,11 +39,11 @@ import {
39
39
  } from "./chunk-TW522KN6.js";
40
40
  import {
41
41
  runSideQuery
42
- } from "./chunk-JMZQICAL.js";
42
+ } from "./chunk-PPHYLJSS.js";
43
43
  import {
44
44
  escapeSystemReminderTags,
45
45
  escapeXml
46
- } from "./chunk-5QQ5FGTU.js";
46
+ } from "./chunk-G7YTSRES.js";
47
47
  import {
48
48
  DefaultHookOutput,
49
49
  HOOKS_CONFIG_FIELDS,
@@ -55,14 +55,14 @@ import {
55
55
  StopHookOutput,
56
56
  createHookOutput,
57
57
  getHookKey
58
- } from "./chunk-B7ZL7HUA.js";
58
+ } from "./chunk-XVHR7ATJ.js";
59
59
  import {
60
60
  DEFAULT_FILE_FILTERING_OPTIONS
61
61
  } from "./chunk-77WXWU44.js";
62
62
  import {
63
63
  BaseTokenStorage,
64
64
  KeychainTokenStorage
65
- } from "./chunk-OCC4MZRS.js";
65
+ } from "./chunk-F23NCRJ2.js";
66
66
  import {
67
67
  AUTH_ENV_MAPPINGS,
68
68
  ApiResponseEvent,
@@ -154,7 +154,7 @@ import {
154
154
  subagentNameContext,
155
155
  truncateToolOutput,
156
156
  uiTelemetryService
157
- } from "./chunk-XLQ4E5PS.js";
157
+ } from "./chunk-C3LHPHN2.js";
158
158
  import {
159
159
  DEFAULT_QWEN_EMBEDDING_MODEL,
160
160
  DEFAULT_QWEN_MODEL
@@ -167,12 +167,12 @@ import {
167
167
  getAutoMemoryMetadataPath,
168
168
  getAutoMemoryRoot,
169
169
  isAutoMemPath
170
- } from "./chunk-CM2IESUE.js";
170
+ } from "./chunk-PR4T27R7.js";
171
171
  import {
172
172
  DEFAULT_TOKEN_LIMIT,
173
173
  ESCALATED_MAX_TOKENS,
174
174
  tokenLimit
175
- } from "./chunk-UXW7MYAW.js";
175
+ } from "./chunk-CW44BRRA.js";
176
176
  import {
177
177
  FinishReason,
178
178
  createModelContent,
@@ -182,7 +182,7 @@ import {
182
182
  } from "./chunk-T4VD6OJ4.js";
183
183
  import {
184
184
  STRUCTURED_OUTPUT_REDACTED_ARGS
185
- } from "./chunk-TPGOGCWM.js";
185
+ } from "./chunk-JYQUJ5DS.js";
186
186
  import {
187
187
  AgentStatistics,
188
188
  BaseDeclarativeTool,
@@ -197,7 +197,7 @@ import {
197
197
  isTool,
198
198
  require_ajv,
199
199
  require_dist
200
- } from "./chunk-FYMSCRHM.js";
200
+ } from "./chunk-FZIUV27X.js";
201
201
  import {
202
202
  PATH_ARG_KEYS,
203
203
  QWEN_DIR,
@@ -216,7 +216,7 @@ import {
216
216
  setDebugLogSession,
217
217
  toFriendlyError,
218
218
  unescapePath
219
- } from "./chunk-GJXIKCKL.js";
219
+ } from "./chunk-XP27SJMH.js";
220
220
  import {
221
221
  require_undici
222
222
  } from "./chunk-E7E2MFYM.js";
@@ -32315,6 +32315,19 @@ function stripThoughtsFromContent(content) {
32315
32315
  };
32316
32316
  }
32317
32317
  __name(stripThoughtsFromContent, "stripThoughtsFromContent");
32318
+ function appendApiHistoryRecord(history, record2) {
32319
+ if (!record2.message) return;
32320
+ const message = structuredClone(record2.message);
32321
+ if (record2.subtype === "mid_turn_user_message") {
32322
+ const previous = history.at(-1);
32323
+ if (previous?.role === "user") {
32324
+ previous.parts = [...previous.parts ?? [], ...message.parts ?? []];
32325
+ return;
32326
+ }
32327
+ }
32328
+ history.push(message);
32329
+ }
32330
+ __name(appendApiHistoryRecord, "appendApiHistoryRecord");
32318
32331
  function buildApiHistoryFromConversation(conversation, options2 = {}) {
32319
32332
  const { stripThoughtsFromHistory = false } = options2;
32320
32333
  const { messages } = conversation;
@@ -32334,16 +32347,17 @@ function buildApiHistoryFromConversation(conversation, options2 = {}) {
32334
32347
  for (let i2 = lastCompressionIndex + 1; i2 < messages.length; i2++) {
32335
32348
  const record2 = messages[i2];
32336
32349
  if (record2.type === "system") continue;
32337
- if (record2.message) {
32338
- baseHistory.push(structuredClone(record2.message));
32339
- }
32350
+ appendApiHistoryRecord(baseHistory, record2);
32340
32351
  }
32341
32352
  if (stripThoughtsFromHistory) {
32342
32353
  return baseHistory.map(stripThoughtsFromContent).filter((content) => content !== null);
32343
32354
  }
32344
32355
  return baseHistory;
32345
32356
  }
32346
- const result = messages.map((record2) => record2.message).filter((message) => message !== void 0).map((message) => structuredClone(message));
32357
+ const result = [];
32358
+ for (const record2 of messages) {
32359
+ appendApiHistoryRecord(result, record2);
32360
+ }
32347
32361
  if (stripThoughtsFromHistory) {
32348
32362
  return result.map(stripThoughtsFromContent).filter((content) => content !== null);
32349
32363
  }
@@ -32972,6 +32986,26 @@ var ChatRecordingService = class {
32972
32986
  debugLogger12.error("Error saving user message:", error);
32973
32987
  }
32974
32988
  }
32989
+ /**
32990
+ * Records a user message drained while tool results are being submitted.
32991
+ *
32992
+ * The model sees these as extra user-role parts in the same API Content as
32993
+ * tool results. Keeping a distinct subtype lets resume reconstruct that shape
32994
+ * instead of replaying consecutive user-role entries.
32995
+ */
32996
+ recordMidTurnUserMessage(message, displayText) {
32997
+ try {
32998
+ const record2 = {
32999
+ ...this.createBaseRecord("user"),
33000
+ subtype: "mid_turn_user_message",
33001
+ message: createUserContent(message),
33002
+ systemPayload: displayText ? { displayText } : void 0
33003
+ };
33004
+ this.appendRecord(record2);
33005
+ } catch (error) {
33006
+ debugLogger12.error("Error saving mid-turn user message:", error);
33007
+ }
33008
+ }
32975
33009
  /**
32976
33010
  * Records a cron-fired prompt.
32977
33011
  * Stored as a user-role message with subtype 'cron' so the UI
@@ -33216,7 +33250,7 @@ var ChatRecordingService = class {
33216
33250
  let prevUuid = this.config.getResumedSessionData()?.lastCompletedUuid !== void 0 ? null : this.lastRecordUuid;
33217
33251
  for (let i2 = 0; i2 < messages.length; i2++) {
33218
33252
  const record2 = messages[i2];
33219
- if (record2.type === "user" && record2.subtype !== "notification" && record2.subtype !== "cron") {
33253
+ if (record2.type === "user" && record2.subtype !== "notification" && record2.subtype !== "cron" && record2.subtype !== "mid_turn_user_message") {
33220
33254
  this.turnParentUuids.push(prevUuid);
33221
33255
  }
33222
33256
  prevUuid = record2.uuid;
@@ -45577,7 +45611,7 @@ var createErrorResponse = /* @__PURE__ */ __name((request, error, errorType) =>
45577
45611
  contentLength: error.message.length
45578
45612
  }), "createErrorResponse");
45579
45613
  function isConcurrencySafe(call) {
45580
- if (call.request.name === ToolNames.AGENT) return true;
45614
+ if (canonicalToolName(call.request.name) === ToolNames.AGENT) return true;
45581
45615
  if (call.tool.kind === "execute" /* Execute */) {
45582
45616
  const command = call.request.args.command;
45583
45617
  if (typeof command !== "string") return false;
@@ -45914,10 +45948,11 @@ var CoreToolScheduler = class {
45914
45948
  }
45915
45949
  const newToolCalls = [];
45916
45950
  for (const reqInfo of requestsToProcess) {
45951
+ const canonicalName = canonicalToolName(reqInfo.name);
45917
45952
  const pm = this.config.getPermissionManager?.();
45918
- if (pm && !await pm.isToolEnabled(reqInfo.name)) {
45953
+ if (pm && !await pm.isToolEnabled(canonicalName)) {
45919
45954
  const matchingRule = pm.findMatchingDenyRule({
45920
- toolName: reqInfo.name
45955
+ toolName: canonicalName
45921
45956
  });
45922
45957
  const ruleInfo = matchingRule ? ` Matching deny rule: "${matchingRule}".` : "";
45923
45958
  const permissionErrorMessage = `Qwen Code requires permission to use "${reqInfo.name}", but that permission was declined.${ruleInfo}`;
@@ -45936,7 +45971,7 @@ var CoreToolScheduler = class {
45936
45971
  if (!pm) {
45937
45972
  const excludeTools = this.config.getPermissionsDeny?.() ?? void 0;
45938
45973
  if (excludeTools && excludeTools.length > 0) {
45939
- const normalizedToolName = reqInfo.name.toLowerCase().trim();
45974
+ const normalizedToolName = canonicalName.toLowerCase().trim();
45940
45975
  const excludedMatch = excludeTools.find(
45941
45976
  (excludedTool) => excludedTool.toLowerCase().trim() === normalizedToolName
45942
45977
  );
@@ -45956,7 +45991,7 @@ var CoreToolScheduler = class {
45956
45991
  }
45957
45992
  }
45958
45993
  }
45959
- const toolInstance = await this.toolRegistry.ensureTool(reqInfo.name);
45994
+ const toolInstance = await this.toolRegistry.ensureTool(canonicalName);
45960
45995
  if (!toolInstance) {
45961
45996
  const errorMessage = await this.getToolNotFoundMessage(reqInfo.name);
45962
45997
  newToolCalls.push({
@@ -46033,6 +46068,7 @@ var CoreToolScheduler = class {
46033
46068
  continue;
46034
46069
  }
46035
46070
  const { request: reqInfo, invocation } = toolCall;
46071
+ const canonicalName = canonicalToolName(reqInfo.name);
46036
46072
  try {
46037
46073
  if (signal.aborted) {
46038
46074
  this.setStatusInternal(
@@ -46046,13 +46082,13 @@ var CoreToolScheduler = class {
46046
46082
  const flowResult = await evaluatePermissionFlow(
46047
46083
  this.config,
46048
46084
  invocation,
46049
- reqInfo.name,
46085
+ canonicalName,
46050
46086
  toolParams
46051
46087
  );
46052
46088
  const { finalPermission, pmForcedAsk, pmCtx, denyMessage } = flowResult;
46053
46089
  const approvalMode = this.config.getApprovalMode();
46054
46090
  const isPlanMode = approvalMode === "plan" /* PLAN */;
46055
- const isExitPlanModeTool = reqInfo.name === "exit_plan_mode";
46091
+ const isExitPlanModeTool = canonicalName === ToolNames.EXIT_PLAN_MODE;
46056
46092
  if (finalPermission === "allow") {
46057
46093
  this.setToolCallOutcome(
46058
46094
  reqInfo.callId,
@@ -46073,9 +46109,9 @@ var CoreToolScheduler = class {
46073
46109
  );
46074
46110
  continue;
46075
46111
  }
46076
- const isAskUserQuestionTool = reqInfo.name === ToolNames.ASK_USER_QUESTION;
46112
+ const isAskUserQuestionTool = canonicalName === ToolNames.ASK_USER_QUESTION;
46077
46113
  let confirmationDetails;
46078
- if (!needsConfirmation(finalPermission, approvalMode, reqInfo.name)) {
46114
+ if (!needsConfirmation(finalPermission, approvalMode, canonicalName)) {
46079
46115
  this.setToolCallOutcome(
46080
46116
  reqInfo.callId,
46081
46117
  "proceed_always" /* ProceedAlways */
@@ -46131,7 +46167,7 @@ var CoreToolScheduler = class {
46131
46167
  const permissionMode = String(this.config.getApprovalMode());
46132
46168
  const hookResult = await firePermissionRequestHook(
46133
46169
  messageBus,
46134
- reqInfo.name,
46170
+ canonicalName,
46135
46171
  reqInfo.args || {},
46136
46172
  permissionMode
46137
46173
  );
@@ -46464,6 +46500,7 @@ var CoreToolScheduler = class {
46464
46500
  }
46465
46501
  async _executeToolCallBody(scheduledCall, signal, span) {
46466
46502
  const { callId, name: toolName } = scheduledCall.request;
46503
+ const canonicalName = canonicalToolName(toolName);
46467
46504
  const invocation = scheduledCall.invocation;
46468
46505
  const toolInput = scheduledCall.request.args;
46469
46506
  for (const key of PATH_ARG_KEYS) {
@@ -46486,7 +46523,7 @@ var CoreToolScheduler = class {
46486
46523
  const permissionMode = this.config.getApprovalMode();
46487
46524
  const preHookResult = await firePreToolUseHook(
46488
46525
  messageBus,
46489
- toolName,
46526
+ canonicalName,
46490
46527
  toolInput,
46491
46528
  toolUseId,
46492
46529
  permissionMode
@@ -46564,7 +46601,7 @@ var CoreToolScheduler = class {
46564
46601
  const failureHookResult = await safelyFirePostToolUseFailureHook(
46565
46602
  messageBus,
46566
46603
  toolUseId,
46567
- toolName,
46604
+ canonicalName,
46568
46605
  toolInput,
46569
46606
  cancelMessage,
46570
46607
  true,
@@ -46597,7 +46634,7 @@ ${failureHookResult.additionalContext}`;
46597
46634
  const permissionMode = this.config.getApprovalMode();
46598
46635
  const postHookResult = await firePostToolUseHook(
46599
46636
  messageBus,
46600
- toolName,
46637
+ canonicalName,
46601
46638
  toolInput,
46602
46639
  toolResponse,
46603
46640
  toolUseId,
@@ -46696,7 +46733,7 @@ ${body2}
46696
46733
  const failureHookResult = await safelyFirePostToolUseFailureHook(
46697
46734
  messageBus,
46698
46735
  toolUseId,
46699
- toolName,
46736
+ canonicalName,
46700
46737
  toolInput,
46701
46738
  toolResult.error.message,
46702
46739
  false,
@@ -46739,7 +46776,7 @@ ${failureHookResult.additionalContext}`;
46739
46776
  const failureHookResult = await safelyFirePostToolUseFailureHook(
46740
46777
  messageBus,
46741
46778
  toolUseId,
46742
- toolName,
46779
+ canonicalName,
46743
46780
  toolInput,
46744
46781
  cancelMessage,
46745
46782
  true,
@@ -46766,7 +46803,7 @@ ${failureHookResult.additionalContext}`;
46766
46803
  const failureHookResult = await safelyFirePostToolUseFailureHook(
46767
46804
  messageBus,
46768
46805
  toolUseId,
46769
- toolName,
46806
+ canonicalName,
46770
46807
  toolInput,
46771
46808
  errorMessage,
46772
46809
  false,
@@ -72327,7 +72364,7 @@ var PathScurryBase = class {
72327
72364
  const dirs = /* @__PURE__ */ new Set();
72328
72365
  const queue = [entry];
72329
72366
  let processing = 0;
72330
- const process7 = /* @__PURE__ */ __name(() => {
72367
+ const process8 = /* @__PURE__ */ __name(() => {
72331
72368
  let paused = false;
72332
72369
  while (!paused) {
72333
72370
  const dir = queue.shift();
@@ -72368,9 +72405,9 @@ var PathScurryBase = class {
72368
72405
  }
72369
72406
  }
72370
72407
  if (paused && !results.flowing) {
72371
- results.once("drain", process7);
72408
+ results.once("drain", process8);
72372
72409
  } else if (!sync2) {
72373
- process7();
72410
+ process8();
72374
72411
  }
72375
72412
  }, "onReaddir");
72376
72413
  let sync2 = true;
@@ -72378,7 +72415,7 @@ var PathScurryBase = class {
72378
72415
  sync2 = false;
72379
72416
  }
72380
72417
  }, "process");
72381
- process7();
72418
+ process8();
72382
72419
  return results;
72383
72420
  }
72384
72421
  streamSync(entry = this.cwd, opts = {}) {
@@ -72396,7 +72433,7 @@ var PathScurryBase = class {
72396
72433
  }
72397
72434
  const queue = [entry];
72398
72435
  let processing = 0;
72399
- const process7 = /* @__PURE__ */ __name(() => {
72436
+ const process8 = /* @__PURE__ */ __name(() => {
72400
72437
  let paused = false;
72401
72438
  while (!paused) {
72402
72439
  const dir = queue.shift();
@@ -72430,9 +72467,9 @@ var PathScurryBase = class {
72430
72467
  }
72431
72468
  }
72432
72469
  if (paused && !results.flowing)
72433
- results.once("drain", process7);
72470
+ results.once("drain", process8);
72434
72471
  }, "process");
72435
- process7();
72472
+ process8();
72436
72473
  return results;
72437
72474
  }
72438
72475
  chdir(path81 = this.cwd) {
@@ -75228,7 +75265,7 @@ var HybridTokenStorage = class extends BaseTokenStorage {
75228
75265
  const forceFileStorage = process.env[FORCE_FILE_STORAGE_ENV_VAR] === "true";
75229
75266
  if (!forceFileStorage) {
75230
75267
  try {
75231
- const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-DMFP5IJM.js");
75268
+ const { KeychainTokenStorage: KeychainTokenStorage2 } = await import("./keychain-token-storage-335UOLJ6.js");
75232
75269
  const keychainStorage = new KeychainTokenStorage2(this.serviceName);
75233
75270
  const isAvailable = await keychainStorage.isAvailable();
75234
75271
  if (isAvailable) {
@@ -85639,6 +85676,7 @@ var FileReadCache = class _FileReadCache {
85639
85676
  __name(this, "FileReadCache");
85640
85677
  }
85641
85678
  byInode = /* @__PURE__ */ new Map();
85679
+ static MAX_ENTRIES = 4096;
85642
85680
  /** Build the canonical key for a file from its Stats. */
85643
85681
  static inodeKey(stats) {
85644
85682
  return `${stats.dev}:${stats.ino}`;
@@ -85766,11 +85804,19 @@ var FileReadCache = class _FileReadCache {
85766
85804
  const key = _FileReadCache.inodeKey(stats);
85767
85805
  const existing = this.byInode.get(key);
85768
85806
  if (existing) {
85807
+ this.byInode.delete(key);
85769
85808
  existing.realPath = absPath;
85770
85809
  existing.mtimeMs = stats.mtimeMs;
85771
85810
  existing.sizeBytes = stats.size;
85811
+ this.byInode.set(key, existing);
85772
85812
  return existing;
85773
85813
  }
85814
+ if (this.byInode.size >= _FileReadCache.MAX_ENTRIES) {
85815
+ const oldestKey = this.byInode.keys().next().value;
85816
+ if (oldestKey) {
85817
+ this.byInode.delete(oldestKey);
85818
+ }
85819
+ }
85774
85820
  const entry = {
85775
85821
  inodeKey: key,
85776
85822
  realPath: absPath,
@@ -101138,6 +101184,8 @@ var Config = class {
101138
101184
  jsonFile;
101139
101185
  jsonSchema;
101140
101186
  inputFile;
101187
+ plansDir;
101188
+ plansDirectoryConfigured;
101141
101189
  defaultFileEncoding;
101142
101190
  enableManagedAutoMemory;
101143
101191
  enableManagedAutoDream;
@@ -101164,6 +101212,8 @@ var Config = class {
101164
101212
  this.fileSystemService = new StandardFileSystemService();
101165
101213
  this.sandbox = params.sandbox;
101166
101214
  this.targetDir = path63.resolve(params.targetDir);
101215
+ this.plansDirectoryConfigured = Boolean(params.plansDirectory?.trim());
101216
+ this.plansDir = Storage.getPlansDir(this.targetDir, params.plansDirectory);
101167
101217
  this.explicitIncludeDirectories = Array.from(
101168
101218
  new Set(params.includeDirectories ?? [])
101169
101219
  );
@@ -101264,6 +101314,7 @@ var Config = class {
101264
101314
  this.skipStartupContext = params.skipStartupContext ?? false;
101265
101315
  this.bareMode = params.bareMode ?? false;
101266
101316
  this.warnings = params.warnings ?? [];
101317
+ this.addLegacyPlanLocationWarning();
101267
101318
  this.allowedHttpHookUrls = params.allowedHttpHookUrls ?? [];
101268
101319
  this.onPersistPermissionRuleCallback = params.onPersistPermissionRule;
101269
101320
  this.useRipgrep = params.useRipgrep ?? true;
@@ -102392,26 +102443,120 @@ var Config = class {
102392
102443
  }
102393
102444
  this.approvalMode = mode;
102394
102445
  }
102446
+ /**
102447
+ * Returns the directory where this session's plan file is stored.
102448
+ */
102449
+ getPlansDir() {
102450
+ return this.plansDir;
102451
+ }
102452
+ assertPlansDirWithinTargetDir() {
102453
+ if (!this.plansDirectoryConfigured) {
102454
+ return;
102455
+ }
102456
+ Storage.assertPathWithinDirectory(
102457
+ this.plansDir,
102458
+ this.targetDir,
102459
+ `plansDirectory must resolve within the project root.`
102460
+ );
102461
+ }
102462
+ assertPlanFilePathWithinTargetDir(filePath) {
102463
+ if (!this.plansDirectoryConfigured) {
102464
+ return;
102465
+ }
102466
+ Storage.assertPathWithinDirectory(
102467
+ filePath,
102468
+ this.targetDir,
102469
+ `plansDirectory must resolve within the project root.`
102470
+ );
102471
+ }
102472
+ addLegacyPlanLocationWarning() {
102473
+ try {
102474
+ if (!this.plansDirectoryConfigured) {
102475
+ return;
102476
+ }
102477
+ const legacyPlansDir = Storage.getPlansDir();
102478
+ const legacyPlanFiles = this.getPlanFileNames(legacyPlansDir);
102479
+ if (legacyPlanFiles.length === 0) {
102480
+ return;
102481
+ }
102482
+ const configuredPlanFiles = new Set(this.getPlanFileNames(this.plansDir));
102483
+ const hiddenLegacyPlanFiles = legacyPlanFiles.filter(
102484
+ (fileName) => !configuredPlanFiles.has(fileName)
102485
+ );
102486
+ if (hiddenLegacyPlanFiles.length === 0) {
102487
+ return;
102488
+ }
102489
+ this.warnings.push(
102490
+ `Warning: Saved plan files exist at ${legacyPlansDir}, but plansDirectory is configured to use ${this.plansDir}. Move existing plan files to ${this.plansDir} if you want to keep using them.`
102491
+ );
102492
+ } catch (err2) {
102493
+ const message = `Failed to check legacy plan directory migration warning: ${err2 instanceof Error ? err2.message : String(err2)}`;
102494
+ this.warnings.push(message);
102495
+ this.debugLogger.warn(message, err2);
102496
+ }
102497
+ }
102498
+ getPlanFileNames(plansDir) {
102499
+ try {
102500
+ return fs63.readdirSync(plansDir).filter((entry) => entry.endsWith(".md"));
102501
+ } catch (err2) {
102502
+ const code2 = err2.code;
102503
+ if (code2 === "ENOENT") {
102504
+ return [];
102505
+ }
102506
+ if (code2 === "EACCES" || code2 === "EPERM") {
102507
+ const message = `Failed to read plan directory ${plansDir}: ${err2 instanceof Error ? err2.message : String(err2)}`;
102508
+ this.warnings.push(message);
102509
+ this.debugLogger.warn(message, err2);
102510
+ return [];
102511
+ }
102512
+ throw err2;
102513
+ }
102514
+ }
102395
102515
  /**
102396
102516
  * Returns the file path for this session's plan file.
102397
102517
  */
102398
102518
  getPlanFilePath() {
102399
- return Storage.getPlanFilePath(this.sessionId);
102519
+ return path63.join(
102520
+ this.plansDir,
102521
+ `${Storage.sanitizePlanSessionId(this.sessionId)}.md`
102522
+ );
102400
102523
  }
102401
102524
  /**
102402
102525
  * Saves a plan to disk for the current session.
102403
102526
  */
102404
102527
  savePlan(plan) {
102528
+ this.assertPlansDirWithinTargetDir();
102405
102529
  const filePath = this.getPlanFilePath();
102406
102530
  const dir = path63.dirname(filePath);
102407
102531
  fs63.mkdirSync(dir, { recursive: true });
102408
- fs63.writeFileSync(filePath, plan, "utf-8");
102532
+ const tmpPath = filePath + ".tmp";
102533
+ fs63.writeFileSync(tmpPath, plan, "utf-8");
102534
+ try {
102535
+ fs63.renameSync(tmpPath, filePath);
102536
+ } catch (err2) {
102537
+ if (err2.code !== "EXDEV") {
102538
+ throw err2;
102539
+ }
102540
+ fs63.copyFileSync(tmpPath, filePath);
102541
+ fs63.unlinkSync(tmpPath);
102542
+ }
102543
+ try {
102544
+ this.assertPlanFilePathWithinTargetDir(filePath);
102545
+ } catch (err2) {
102546
+ try {
102547
+ fs63.unlinkSync(filePath);
102548
+ } catch {
102549
+ }
102550
+ throw err2;
102551
+ }
102409
102552
  }
102410
102553
  /**
102411
102554
  * Loads the plan for the current session, or returns undefined if none exists.
102412
102555
  */
102413
102556
  loadPlan() {
102557
+ this.assertPlansDirWithinTargetDir();
102414
102558
  const filePath = this.getPlanFilePath();
102559
+ this.assertPlanFilePathWithinTargetDir(filePath);
102415
102560
  try {
102416
102561
  return fs63.readFileSync(filePath, "utf-8");
102417
102562
  } catch (error) {
@@ -103047,21 +103192,21 @@ var Config = class {
103047
103192
  if (options2?.forSubAgent) return;
103048
103193
  const schema = this.jsonSchema;
103049
103194
  await registerLazy(ToolNames.STRUCTURED_OUTPUT, async () => {
103050
- const { SyntheticOutputTool } = await import("./syntheticOutput-S4DRGMQM.js");
103195
+ const { SyntheticOutputTool } = await import("./syntheticOutput-HFL3DE7R.js");
103051
103196
  return new SyntheticOutputTool(schema);
103052
103197
  });
103053
103198
  }, "registerStructuredOutputIfRequested");
103054
103199
  if (this.getBareMode()) {
103055
103200
  await registerLazy(ToolNames.READ_FILE, async () => {
103056
- const { ReadFileTool } = await import("./read-file-WWUQVNCZ.js");
103201
+ const { ReadFileTool } = await import("./read-file-CQOF7BQ2.js");
103057
103202
  return new ReadFileTool(this);
103058
103203
  });
103059
103204
  await registerLazy(ToolNames.EDIT, async () => {
103060
- const { EditTool } = await import("./edit-VNAZBIZR.js");
103205
+ const { EditTool } = await import("./edit-74Q4AFHQ.js");
103061
103206
  return new EditTool(this);
103062
103207
  });
103063
103208
  await registerLazy(ToolNames.SHELL, async () => {
103064
- const { ShellTool: ShellTool2 } = await import("./shell-IAOKGIJ6.js");
103209
+ const { ShellTool: ShellTool2 } = await import("./shell-E2HMCBGR.js");
103065
103210
  return new ShellTool2(this);
103066
103211
  });
103067
103212
  await registerStructuredOutputIfRequested();
@@ -103071,31 +103216,31 @@ var Config = class {
103071
103216
  return registry;
103072
103217
  }
103073
103218
  await registerLazy(ToolNames.TOOL_SEARCH, async () => {
103074
- const { ToolSearchTool } = await import("./tool-search-MSJ6SXLI.js");
103219
+ const { ToolSearchTool } = await import("./tool-search-U4XQVLFU.js");
103075
103220
  return new ToolSearchTool(this);
103076
103221
  });
103077
103222
  await registerLazy(ToolNames.AGENT, async () => {
103078
- const { AgentTool: AgentTool2 } = await import("./agent-LIAWUWAO.js");
103223
+ const { AgentTool: AgentTool2 } = await import("./agent-ZNQPH67I.js");
103079
103224
  return new AgentTool2(this);
103080
103225
  });
103081
103226
  await registerLazy(ToolNames.TASK_STOP, async () => {
103082
- const { TaskStopTool } = await import("./task-stop-7THHVAQS.js");
103227
+ const { TaskStopTool } = await import("./task-stop-ZQF26RXS.js");
103083
103228
  return new TaskStopTool(this);
103084
103229
  });
103085
103230
  await registerLazy(ToolNames.SEND_MESSAGE, async () => {
103086
- const { SendMessageTool } = await import("./send-message-Q2JRAC3J.js");
103231
+ const { SendMessageTool } = await import("./send-message-GB4AQZNC.js");
103087
103232
  return new SendMessageTool(this);
103088
103233
  });
103089
103234
  await registerLazy(ToolNames.SKILL, async () => {
103090
- const { SkillTool } = await import("./skill-NHW6222K.js");
103235
+ const { SkillTool } = await import("./skill-KDZH6UZ6.js");
103091
103236
  return new SkillTool(this);
103092
103237
  });
103093
103238
  await registerLazy(ToolNames.LS, async () => {
103094
- const { LSTool } = await import("./ls-SUILOZZB.js");
103239
+ const { LSTool } = await import("./ls-6F3VSP6S.js");
103095
103240
  return new LSTool(this);
103096
103241
  });
103097
103242
  await registerLazy(ToolNames.READ_FILE, async () => {
103098
- const { ReadFileTool } = await import("./read-file-WWUQVNCZ.js");
103243
+ const { ReadFileTool } = await import("./read-file-CQOF7BQ2.js");
103099
103244
  return new ReadFileTool(this);
103100
103245
  });
103101
103246
  if (this.getUseRipgrep()) {
@@ -103108,7 +103253,7 @@ var Config = class {
103108
103253
  }
103109
103254
  if (useRipgrep) {
103110
103255
  await registerLazy(ToolNames.GREP, async () => {
103111
- const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-WCOAIWL6.js");
103256
+ const { RipGrepTool: RipGrepTool2 } = await import("./ripGrep-KR5LKGTI.js");
103112
103257
  return new RipGrepTool2(this);
103113
103258
  });
103114
103259
  } else {
@@ -103121,81 +103266,81 @@ var Config = class {
103121
103266
  )
103122
103267
  );
103123
103268
  await registerLazy(ToolNames.GREP, async () => {
103124
- const { GrepTool } = await import("./grep-4SETMY47.js");
103269
+ const { GrepTool } = await import("./grep-DZKSBFZK.js");
103125
103270
  return new GrepTool(this);
103126
103271
  });
103127
103272
  }
103128
103273
  } else {
103129
103274
  await registerLazy(ToolNames.GREP, async () => {
103130
- const { GrepTool } = await import("./grep-4SETMY47.js");
103275
+ const { GrepTool } = await import("./grep-DZKSBFZK.js");
103131
103276
  return new GrepTool(this);
103132
103277
  });
103133
103278
  }
103134
103279
  await registerLazy(ToolNames.GLOB, async () => {
103135
- const { GlobTool } = await import("./glob-G7XATELV.js");
103280
+ const { GlobTool } = await import("./glob-WEE3CJL6.js");
103136
103281
  return new GlobTool(this);
103137
103282
  });
103138
103283
  await registerLazy(ToolNames.EDIT, async () => {
103139
- const { EditTool } = await import("./edit-VNAZBIZR.js");
103284
+ const { EditTool } = await import("./edit-74Q4AFHQ.js");
103140
103285
  return new EditTool(this);
103141
103286
  });
103142
103287
  await registerLazy(ToolNames.WRITE_FILE, async () => {
103143
- const { WriteFileTool } = await import("./write-file-RKCENFZ5.js");
103288
+ const { WriteFileTool } = await import("./write-file-NBLRMNGB.js");
103144
103289
  return new WriteFileTool(this);
103145
103290
  });
103146
103291
  await registerLazy(ToolNames.SHELL, async () => {
103147
- const { ShellTool: ShellTool2 } = await import("./shell-IAOKGIJ6.js");
103292
+ const { ShellTool: ShellTool2 } = await import("./shell-E2HMCBGR.js");
103148
103293
  return new ShellTool2(this);
103149
103294
  });
103150
103295
  await registerLazy(ToolNames.TODO_WRITE, async () => {
103151
- const { TodoWriteTool } = await import("./todoWrite-WKUGUTPX.js");
103296
+ const { TodoWriteTool } = await import("./todoWrite-U4SC643O.js");
103152
103297
  return new TodoWriteTool(this);
103153
103298
  });
103154
103299
  await registerLazy(ToolNames.ASK_USER_QUESTION, async () => {
103155
- const { AskUserQuestionTool } = await import("./askUserQuestion-QFSCBTUO.js");
103300
+ const { AskUserQuestionTool } = await import("./askUserQuestion-WQILGUSQ.js");
103156
103301
  return new AskUserQuestionTool(this);
103157
103302
  });
103158
103303
  if (!this.sdkMode) {
103159
103304
  await registerLazy(ToolNames.EXIT_PLAN_MODE, async () => {
103160
- const { ExitPlanModeTool } = await import("./exitPlanMode-QZKO7GH7.js");
103305
+ const { ExitPlanModeTool } = await import("./exitPlanMode-NBR2PK2D.js");
103161
103306
  return new ExitPlanModeTool(this);
103162
103307
  });
103163
103308
  }
103164
103309
  await registerLazy(ToolNames.ENTER_WORKTREE, async () => {
103165
- const { EnterWorktreeTool } = await import("./enter-worktree-FOF5YZIV.js");
103310
+ const { EnterWorktreeTool } = await import("./enter-worktree-H72HXC7D.js");
103166
103311
  return new EnterWorktreeTool(this);
103167
103312
  });
103168
103313
  await registerLazy(ToolNames.EXIT_WORKTREE, async () => {
103169
- const { ExitWorktreeTool } = await import("./exit-worktree-Y6QVAO3C.js");
103314
+ const { ExitWorktreeTool } = await import("./exit-worktree-FGIQO3S3.js");
103170
103315
  return new ExitWorktreeTool(this);
103171
103316
  });
103172
103317
  await registerLazy(ToolNames.WEB_FETCH, async () => {
103173
- const { WebFetchTool } = await import("./web-fetch-OZE6ZQUF.js");
103318
+ const { WebFetchTool } = await import("./web-fetch-BRWZ4WSE.js");
103174
103319
  return new WebFetchTool(this);
103175
103320
  });
103176
103321
  if (this.isLspEnabled() && this.getLspClient()) {
103177
103322
  await registerLazy(ToolNames.LSP, async () => {
103178
- const { LspTool } = await import("./lsp-6TQBWVMZ.js");
103323
+ const { LspTool } = await import("./lsp-67Y7DJN5.js");
103179
103324
  return new LspTool(this);
103180
103325
  });
103181
103326
  }
103182
103327
  await registerStructuredOutputIfRequested();
103183
103328
  if (this.isCronEnabled()) {
103184
103329
  await registerLazy(ToolNames.CRON_CREATE, async () => {
103185
- const { CronCreateTool } = await import("./cron-create-WUTD5ZTH.js");
103330
+ const { CronCreateTool } = await import("./cron-create-AVI3Q267.js");
103186
103331
  return new CronCreateTool(this);
103187
103332
  });
103188
103333
  await registerLazy(ToolNames.CRON_LIST, async () => {
103189
- const { CronListTool } = await import("./cron-list-Z6RJJ4YH.js");
103334
+ const { CronListTool } = await import("./cron-list-VN653OK5.js");
103190
103335
  return new CronListTool(this);
103191
103336
  });
103192
103337
  await registerLazy(ToolNames.CRON_DELETE, async () => {
103193
- const { CronDeleteTool } = await import("./cron-delete-N3UQYCRA.js");
103338
+ const { CronDeleteTool } = await import("./cron-delete-ZCEGDXXV.js");
103194
103339
  return new CronDeleteTool(this);
103195
103340
  });
103196
103341
  }
103197
103342
  await registerLazy(ToolNames.MONITOR, async () => {
103198
- const { MonitorTool } = await import("./monitor-JTLJBJ7H.js");
103343
+ const { MonitorTool } = await import("./monitor-EDZWEZVS.js");
103199
103344
  return new MonitorTool(this);
103200
103345
  });
103201
103346
  if (!options2?.skipDiscovery) {
@@ -106321,16 +106466,16 @@ var LspServerManager = class {
106321
106466
  if (!config.socket) {
106322
106467
  throw new Error("LSP socket transport requires host/port or path");
106323
106468
  }
106324
- let process7;
106469
+ let process8;
106325
106470
  if (config.command) {
106326
- process7 = spawn7(config.command, config.args ?? [], {
106471
+ process8 = spawn7(config.command, config.args ?? [], {
106327
106472
  cwd: workspaceFolder,
106328
106473
  env: env2,
106329
106474
  stdio: "ignore"
106330
106475
  });
106331
106476
  await new Promise((resolve29, reject) => {
106332
- process7?.once("spawn", () => resolve29());
106333
- process7?.once("error", (error) => {
106477
+ process8?.once("spawn", () => resolve29());
106478
+ process8?.once("error", (error) => {
106334
106479
  reject(new Error(`Failed to spawn LSP server: ${error.message}`));
106335
106480
  });
106336
106481
  });
@@ -106342,7 +106487,7 @@ var LspServerManager = class {
106342
106487
  );
106343
106488
  return {
106344
106489
  connection: lspConnection.connection,
106345
- process: process7,
106490
+ process: process8,
106346
106491
  shutdown: /* @__PURE__ */ __name(async () => {
106347
106492
  await lspConnection.connection.shutdown();
106348
106493
  }, "shutdown"),
@@ -106352,8 +106497,8 @@ var LspServerManager = class {
106352
106497
  initialize: /* @__PURE__ */ __name(async (params) => lspConnection.connection.initialize(params), "initialize")
106353
106498
  };
106354
106499
  } catch (error) {
106355
- if (process7 && process7.exitCode === null) {
106356
- process7.kill();
106500
+ if (process8 && process8.exitCode === null) {
106501
+ process8.kill();
106357
106502
  }
106358
106503
  throw error;
106359
106504
  }
@@ -109003,6 +109148,8 @@ init_esbuild_shims();
109003
109148
  import crypto5 from "node:crypto";
109004
109149
  var crawlCache = /* @__PURE__ */ new Map();
109005
109150
  var cacheTimers = /* @__PURE__ */ new Map();
109151
+ var MAX_CACHE_ENTRIES = 256;
109152
+ var MAX_TOTAL_PATHS = 5e4;
109006
109153
  var getCacheKey = /* @__PURE__ */ __name((directory, ignoreContent, maxDepth, maxFiles, useGitignore = true) => {
109007
109154
  const hash = crypto5.createHash("sha256");
109008
109155
  hash.update(directory);
@@ -109016,11 +109163,58 @@ var getCacheKey = /* @__PURE__ */ __name((directory, ignoreContent, maxDepth, ma
109016
109163
  }
109017
109164
  return hash.digest("hex");
109018
109165
  }, "getCacheKey");
109019
- var read2 = /* @__PURE__ */ __name((key) => crawlCache.get(key), "read");
109166
+ var read2 = /* @__PURE__ */ __name((key) => {
109167
+ const result = crawlCache.get(key);
109168
+ if (result !== void 0) {
109169
+ crawlCache.delete(key);
109170
+ crawlCache.set(key, result);
109171
+ }
109172
+ return result;
109173
+ }, "read");
109020
109174
  var write2 = /* @__PURE__ */ __name((key, results, ttlMs) => {
109021
109175
  if (cacheTimers.has(key)) {
109022
109176
  clearTimeout(cacheTimers.get(key));
109023
109177
  }
109178
+ while (crawlCache.size >= MAX_CACHE_ENTRIES && !crawlCache.has(key)) {
109179
+ const oldestKey = crawlCache.keys().next().value;
109180
+ if (oldestKey) {
109181
+ crawlCache.delete(oldestKey);
109182
+ if (cacheTimers.has(oldestKey)) {
109183
+ clearTimeout(cacheTimers.get(oldestKey));
109184
+ cacheTimers.delete(oldestKey);
109185
+ }
109186
+ }
109187
+ }
109188
+ let totalPaths = 0;
109189
+ for (const [k, entry] of crawlCache) {
109190
+ if (k !== key) {
109191
+ totalPaths += entry.length;
109192
+ }
109193
+ }
109194
+ while (totalPaths + results.length > MAX_TOTAL_PATHS && crawlCache.size > 0) {
109195
+ let largestKey;
109196
+ let largestSize = 0;
109197
+ for (const [k, v] of crawlCache) {
109198
+ if (k === key) continue;
109199
+ if (v.length > largestSize) {
109200
+ largestSize = v.length;
109201
+ largestKey = k;
109202
+ }
109203
+ }
109204
+ if (largestKey) {
109205
+ totalPaths -= crawlCache.get(largestKey).length;
109206
+ crawlCache.delete(largestKey);
109207
+ if (cacheTimers.has(largestKey)) {
109208
+ clearTimeout(cacheTimers.get(largestKey));
109209
+ cacheTimers.delete(largestKey);
109210
+ }
109211
+ } else {
109212
+ break;
109213
+ }
109214
+ }
109215
+ if (crawlCache.has(key)) {
109216
+ crawlCache.delete(key);
109217
+ }
109024
109218
  crawlCache.set(key, results);
109025
109219
  const timerId = setTimeout(() => {
109026
109220
  crawlCache.delete(key);
@@ -111834,6 +112028,205 @@ async function runGit(args2, cwd2) {
111834
112028
  }
111835
112029
  __name(runGit, "runGit");
111836
112030
 
112031
+ // packages/core/src/utils/memoryDiagnostics.ts
112032
+ init_esbuild_shims();
112033
+ import { readdir as readdir14, readFile as readFile25 } from "node:fs/promises";
112034
+ import process7 from "node:process";
112035
+ import v8 from "node:v8";
112036
+ var RSS_HEAP_GAP_RATIO = 10;
112037
+ var RSS_HEAP_GAP_MIN_BYTES = 256 * 1024 * 1024;
112038
+ var NATIVE_MEMORY_PRESSURE_MIN_BYTES = 64 * 1024 * 1024;
112039
+ var ACTIVE_HANDLES_THRESHOLD = 256;
112040
+ var ACTIVE_REQUESTS_THRESHOLD = 100;
112041
+ var OPEN_FD_THRESHOLD = 500;
112042
+ var debugLogger89 = createDebugLogger("MEMORY_DIAGNOSTICS");
112043
+ async function collectMemoryDiagnostics(options2 = {}) {
112044
+ const now = options2.now ?? (() => /* @__PURE__ */ new Date());
112045
+ const platform8 = options2.platform ?? process7.platform;
112046
+ const memoryUsage = options2.memoryUsage?.() ?? process7.memoryUsage();
112047
+ const heapStatistics = options2.heapStatistics?.() ?? v8.getHeapStatistics();
112048
+ const resourceUsage = options2.resourceUsage?.() ?? process7.resourceUsage();
112049
+ const uptimeSeconds = options2.uptimeSeconds?.() ?? process7.uptime();
112050
+ const [openFileDescriptors, smapsRollup, heapSpaceStatistics] = await Promise.all([
112051
+ optionalProbe(
112052
+ "openFileDescriptors",
112053
+ options2.openFileDescriptors ?? countOpenFileDescriptors
112054
+ ),
112055
+ optionalProbe("smapsRollup", options2.smapsRollup ?? readProcSmapsRollup),
112056
+ optionalSyncProbe(
112057
+ "heapSpaceStatistics",
112058
+ options2.heapSpaceStatistics ?? (() => v8.getHeapSpaceStatistics())
112059
+ )
112060
+ ]);
112061
+ const v8HeapSpaces = mapHeapSpaces(heapSpaceStatistics);
112062
+ const maxRSSBytes = resourceUsage.maxRSS;
112063
+ const diagnostics = {
112064
+ timestamp: now().toISOString(),
112065
+ sessionId: options2.sessionId,
112066
+ qwenVersion: options2.qwenVersion,
112067
+ uptimeSeconds,
112068
+ memoryUsage,
112069
+ v8HeapStats: mapHeapStats(heapStatistics),
112070
+ v8HeapSpaces,
112071
+ resourceUsage: {
112072
+ maxRSS: maxRSSBytes,
112073
+ userCPUTime: resourceUsage.userCPUTime,
112074
+ systemCPUTime: resourceUsage.systemCPUTime
112075
+ },
112076
+ activeHandles: getProcessInternalCount(
112077
+ "activeHandles",
112078
+ "_getActiveHandles",
112079
+ options2.activeHandles
112080
+ ),
112081
+ activeRequests: getProcessInternalCount(
112082
+ "activeRequests",
112083
+ "_getActiveRequests",
112084
+ options2.activeRequests
112085
+ ),
112086
+ openFileDescriptors,
112087
+ smapsRollup,
112088
+ platform: platform8,
112089
+ nodeVersion: options2.nodeVersion ?? process7.version
112090
+ };
112091
+ return {
112092
+ ...diagnostics,
112093
+ analysis: analyzeMemoryDiagnostics(diagnostics)
112094
+ };
112095
+ }
112096
+ __name(collectMemoryDiagnostics, "collectMemoryDiagnostics");
112097
+ function mapHeapStats(heapInfo) {
112098
+ return {
112099
+ heapSizeLimit: heapInfo.heap_size_limit,
112100
+ totalHeapSize: heapInfo.total_heap_size,
112101
+ usedHeapSize: heapInfo.used_heap_size,
112102
+ mallocedMemory: heapInfo.malloced_memory,
112103
+ peakMallocedMemory: heapInfo.peak_malloced_memory,
112104
+ detachedContexts: heapInfo.number_of_detached_contexts,
112105
+ nativeContexts: heapInfo.number_of_native_contexts
112106
+ };
112107
+ }
112108
+ __name(mapHeapStats, "mapHeapStats");
112109
+ function mapHeapSpaces(heapSpaces) {
112110
+ if (!heapSpaces) {
112111
+ return null;
112112
+ }
112113
+ return heapSpaces.map((space) => ({
112114
+ name: space.space_name,
112115
+ size: space.space_size,
112116
+ used: space.space_used_size,
112117
+ available: space.space_available_size
112118
+ }));
112119
+ }
112120
+ __name(mapHeapSpaces, "mapHeapSpaces");
112121
+ function getProcessInternalCount(name3, internalMethod, probe) {
112122
+ try {
112123
+ if (probe) {
112124
+ return probe();
112125
+ }
112126
+ const internals = process7;
112127
+ const internalProbe = internals[internalMethod];
112128
+ if (typeof internalProbe !== "function") {
112129
+ logProbeFailure(name3, new Error(`${internalMethod} is unavailable`));
112130
+ return 0;
112131
+ }
112132
+ const result = internalProbe();
112133
+ if (!Array.isArray(result)) {
112134
+ logProbeFailure(
112135
+ name3,
112136
+ new Error(`${internalMethod} returned a non-array result`)
112137
+ );
112138
+ return 0;
112139
+ }
112140
+ return result.length;
112141
+ } catch (error) {
112142
+ logProbeFailure(name3, error);
112143
+ return 0;
112144
+ }
112145
+ }
112146
+ __name(getProcessInternalCount, "getProcessInternalCount");
112147
+ async function countOpenFileDescriptors() {
112148
+ return (await readdir14("/proc/self/fd")).length;
112149
+ }
112150
+ __name(countOpenFileDescriptors, "countOpenFileDescriptors");
112151
+ async function readProcSmapsRollup() {
112152
+ return readFile25("/proc/self/smaps_rollup", "utf8");
112153
+ }
112154
+ __name(readProcSmapsRollup, "readProcSmapsRollup");
112155
+ async function optionalProbe(name3, probe) {
112156
+ try {
112157
+ return await probe();
112158
+ } catch (error) {
112159
+ logProbeFailure(name3, error);
112160
+ return null;
112161
+ }
112162
+ }
112163
+ __name(optionalProbe, "optionalProbe");
112164
+ async function optionalSyncProbe(name3, probe) {
112165
+ try {
112166
+ return probe();
112167
+ } catch (error) {
112168
+ logProbeFailure(name3, error);
112169
+ return null;
112170
+ }
112171
+ }
112172
+ __name(optionalSyncProbe, "optionalSyncProbe");
112173
+ function logProbeFailure(name3, error) {
112174
+ debugLogger89.debug(`memory diagnostics probe failed: ${name3}`, error);
112175
+ }
112176
+ __name(logProbeFailure, "logProbeFailure");
112177
+ function analyzeMemoryDiagnostics(diagnostics) {
112178
+ const risks = [];
112179
+ const heapRatio = diagnostics.v8HeapStats.heapSizeLimit > 0 ? diagnostics.v8HeapStats.usedHeapSize / diagnostics.v8HeapStats.heapSizeLimit : 0;
112180
+ if (heapRatio >= 0.75) {
112181
+ risks.push({
112182
+ type: "heap-pressure",
112183
+ message: `Heap usage is ${(heapRatio * 100).toFixed(1)}% of the V8 limit.`
112184
+ });
112185
+ }
112186
+ if (diagnostics.v8HeapStats.detachedContexts > 0) {
112187
+ risks.push({
112188
+ type: "detached-contexts",
112189
+ message: `${diagnostics.v8HeapStats.detachedContexts} detached V8 context(s) detected.`
112190
+ });
112191
+ }
112192
+ if (diagnostics.activeHandles > ACTIVE_HANDLES_THRESHOLD) {
112193
+ risks.push({
112194
+ type: "active-handles",
112195
+ message: `${diagnostics.activeHandles} active handle(s) detected.`
112196
+ });
112197
+ }
112198
+ if (diagnostics.activeRequests > ACTIVE_REQUESTS_THRESHOLD) {
112199
+ risks.push({
112200
+ type: "active-requests",
112201
+ message: `${diagnostics.activeRequests} active request(s) detected.`
112202
+ });
112203
+ }
112204
+ if (diagnostics.openFileDescriptors !== null && diagnostics.openFileDescriptors > OPEN_FD_THRESHOLD) {
112205
+ risks.push({
112206
+ type: "fd-leak",
112207
+ message: `${diagnostics.openFileDescriptors} open file descriptor(s) detected.`
112208
+ });
112209
+ }
112210
+ const nativeMemory = diagnostics.v8HeapStats.mallocedMemory;
112211
+ if (nativeMemory >= NATIVE_MEMORY_PRESSURE_MIN_BYTES && nativeMemory > diagnostics.memoryUsage.heapUsed * 2) {
112212
+ risks.push({
112213
+ type: "native-memory-pressure",
112214
+ message: `V8 native malloced memory (${formatMemoryUsage(nativeMemory)}) is more than 2\xD7 heap used (${formatMemoryUsage(diagnostics.memoryUsage.heapUsed)}).`
112215
+ });
112216
+ }
112217
+ if (diagnostics.memoryUsage.heapUsed > 0 && diagnostics.memoryUsage.rss >= RSS_HEAP_GAP_MIN_BYTES && diagnostics.memoryUsage.rss > diagnostics.memoryUsage.heapUsed * RSS_HEAP_GAP_RATIO) {
112218
+ risks.push({
112219
+ type: "rss-heap-gap",
112220
+ message: `RSS (${formatMemoryUsage(diagnostics.memoryUsage.rss)}) is more than ${RSS_HEAP_GAP_RATIO}\xD7 heap used (${formatMemoryUsage(diagnostics.memoryUsage.heapUsed)}). Check native addons, libuv buffers, mapped files, or retained tool output.`
112221
+ });
112222
+ }
112223
+ return {
112224
+ risks,
112225
+ recommendation: risks.length > 0 ? `${risks.length} potential leak indicator(s) found.` : "No obvious leak indicators detected."
112226
+ };
112227
+ }
112228
+ __name(analyzeMemoryDiagnostics, "analyzeMemoryDiagnostics");
112229
+
111837
112230
  // packages/core/src/utils/pathReader.ts
111838
112231
  init_esbuild_shims();
111839
112232
  import { promises as fs73 } from "node:fs";
@@ -114140,7 +114533,7 @@ __name(shouldDefaultToNodePty, "shouldDefaultToNodePty");
114140
114533
  // packages/core/src/services/shellExecutionService.ts
114141
114534
  var import_headless = __toESM(require_xterm_headless(), 1);
114142
114535
  var { Terminal } = import_headless.default;
114143
- var debugLogger89 = createDebugLogger("SHELL_EXECUTION");
114536
+ var debugLogger90 = createDebugLogger("SHELL_EXECUTION");
114144
114537
  var SIGKILL_TIMEOUT_MS = 200;
114145
114538
  var PROMOTE_DRAIN_TIMEOUT_MS = 200;
114146
114539
  function getShellAbortReasonKind(reason) {
@@ -114459,13 +114852,13 @@ var ShellExecutionService = class _ShellExecutionService {
114459
114852
  const performBackgroundPromote = /* @__PURE__ */ __name(() => {
114460
114853
  if (!child.pid || exited) return;
114461
114854
  if (child.exitCode !== null || child.signalCode !== null) {
114462
- debugLogger89.debug(
114855
+ debugLogger90.debug(
114463
114856
  `Background-promote requested for pid ${child.pid} but child is already terminal (exitCode=${child.exitCode}, signalCode=${child.signalCode}); falling through to the normal exit-handled resolution.`
114464
114857
  );
114465
114858
  return;
114466
114859
  }
114467
114860
  if (streamStdout) {
114468
- debugLogger89.warn(
114861
+ debugLogger90.warn(
114469
114862
  "Background-promote on a streamStdout=true child_process: snapshot accumulators were never populated (output went through onOutputEvent), so result.output will be empty. Caller should fall back to rawOutput, or assemble its own snapshot from the data events it received."
114470
114863
  );
114471
114864
  }
@@ -114499,7 +114892,7 @@ var ShellExecutionService = class _ShellExecutionService {
114499
114892
  chunk: decoder.decode(chunk, { stream: true })
114500
114893
  });
114501
114894
  } catch (cbErr) {
114502
- debugLogger89.warn(
114895
+ debugLogger90.warn(
114503
114896
  `postPromote.onData threw: ${cbErr instanceof Error ? cbErr.message : String(cbErr)}`
114504
114897
  );
114505
114898
  }
@@ -114514,7 +114907,7 @@ var ShellExecutionService = class _ShellExecutionService {
114514
114907
  child.stderr?.on("data", postPromoteStderrHandler);
114515
114908
  }
114516
114909
  } catch (e) {
114517
- debugLogger89.warn(
114910
+ debugLogger90.warn(
114518
114911
  `re-attaching post-promote data listeners threw: ${e instanceof Error ? e.message : String(e)}`
114519
114912
  );
114520
114913
  }
@@ -114523,7 +114916,7 @@ var ShellExecutionService = class _ShellExecutionService {
114523
114916
  child.stdout?.resume();
114524
114917
  child.stderr?.resume();
114525
114918
  } catch (e) {
114526
- debugLogger89.warn(
114919
+ debugLogger90.warn(
114527
114920
  `post-promote stdout/stderr resume() threw: ${e instanceof Error ? e.message : String(e)}`
114528
114921
  );
114529
114922
  }
@@ -114551,7 +114944,7 @@ var ShellExecutionService = class _ShellExecutionService {
114551
114944
  }
114552
114945
  }
114553
114946
  } catch (flushErr) {
114554
- debugLogger89.warn(
114947
+ debugLogger90.warn(
114555
114948
  `post-promote decoder flush threw: ${flushErr instanceof Error ? flushErr.message : String(flushErr)}`
114556
114949
  );
114557
114950
  }
@@ -114572,7 +114965,7 @@ var ShellExecutionService = class _ShellExecutionService {
114572
114965
  try {
114573
114966
  postPromote.onSettle(info2);
114574
114967
  } catch (cbErr) {
114575
- debugLogger89.warn(
114968
+ debugLogger90.warn(
114576
114969
  `postPromote.onSettle threw: ${cbErr instanceof Error ? cbErr.message : String(cbErr)}`
114577
114970
  );
114578
114971
  }
@@ -114598,7 +114991,7 @@ var ShellExecutionService = class _ShellExecutionService {
114598
114991
  });
114599
114992
  });
114600
114993
  } catch (e) {
114601
- debugLogger89.warn(
114994
+ debugLogger90.warn(
114602
114995
  `re-attaching post-promote exit/error listeners threw: ${e instanceof Error ? e.message : String(e)}`
114603
114996
  );
114604
114997
  }
@@ -114934,7 +115327,7 @@ var ShellExecutionService = class _ShellExecutionService {
114934
115327
  const performBackgroundPromote = /* @__PURE__ */ __name(async () => {
114935
115328
  if (!ptyProcess.pid || exited) return;
114936
115329
  if (!_ShellExecutionService.isPtyActive(ptyProcess.pid)) {
114937
- debugLogger89.debug(
115330
+ debugLogger90.debug(
114938
115331
  `Background-promote requested for PTY pid ${ptyProcess.pid} but the process is no longer alive (process.kill(pid, 0) failed); falling through to normal exit-handled resolution.`
114939
115332
  );
114940
115333
  return;
@@ -114945,21 +115338,21 @@ var ShellExecutionService = class _ShellExecutionService {
114945
115338
  try {
114946
115339
  dataDisposable.dispose();
114947
115340
  } catch (e) {
114948
- debugLogger89.warn(
115341
+ debugLogger90.warn(
114949
115342
  `dataDisposable.dispose() threw during background-promote: ${e instanceof Error ? e.message : String(e)}`
114950
115343
  );
114951
115344
  }
114952
115345
  try {
114953
115346
  exitDisposable.dispose();
114954
115347
  } catch (e) {
114955
- debugLogger89.warn(
115348
+ debugLogger90.warn(
114956
115349
  `exitDisposable.dispose() threw during background-promote: ${e instanceof Error ? e.message : String(e)}`
114957
115350
  );
114958
115351
  }
114959
115352
  try {
114960
115353
  ptyProcess.removeListener("error", ptyErrorHandler);
114961
115354
  } catch (e) {
114962
- debugLogger89.warn(
115355
+ debugLogger90.warn(
114963
115356
  `ptyProcess.removeListener('error') threw during background-promote: ${e instanceof Error ? e.message : String(e)}`
114964
115357
  );
114965
115358
  }
@@ -114977,7 +115370,7 @@ var ShellExecutionService = class _ShellExecutionService {
114977
115370
  try {
114978
115371
  postPromoteDataDisposable.dispose();
114979
115372
  } catch (e) {
114980
- debugLogger89.warn(
115373
+ debugLogger90.warn(
114981
115374
  `disposing post-promote data listener threw: ${e instanceof Error ? e.message : String(e)}`
114982
115375
  );
114983
115376
  }
@@ -114987,7 +115380,7 @@ var ShellExecutionService = class _ShellExecutionService {
114987
115380
  try {
114988
115381
  postPromoteExitDisposable.dispose();
114989
115382
  } catch (e) {
114990
- debugLogger89.warn(
115383
+ debugLogger90.warn(
114991
115384
  `disposing post-promote exit listener threw: ${e instanceof Error ? e.message : String(e)}`
114992
115385
  );
114993
115386
  }
@@ -114997,7 +115390,7 @@ var ShellExecutionService = class _ShellExecutionService {
114997
115390
  try {
114998
115391
  ptyProcess.removeListener("error", postPromoteErrorListener);
114999
115392
  } catch (e) {
115000
- debugLogger89.warn(
115393
+ debugLogger90.warn(
115001
115394
  `removing post-promote error listener threw: ${e instanceof Error ? e.message : String(e)}`
115002
115395
  );
115003
115396
  }
@@ -115012,7 +115405,7 @@ var ShellExecutionService = class _ShellExecutionService {
115012
115405
  try {
115013
115406
  postPromote.onSettle(info2);
115014
115407
  } catch (cbErr) {
115015
- debugLogger89.warn(
115408
+ debugLogger90.warn(
115016
115409
  `postPromote.onSettle threw: ${cbErr instanceof Error ? cbErr.message : String(cbErr)}`
115017
115410
  );
115018
115411
  }
@@ -115024,13 +115417,13 @@ var ShellExecutionService = class _ShellExecutionService {
115024
115417
  try {
115025
115418
  onPostData({ type: "data", chunk: data });
115026
115419
  } catch (cbErr) {
115027
- debugLogger89.warn(
115420
+ debugLogger90.warn(
115028
115421
  `postPromote.onData threw: ${cbErr instanceof Error ? cbErr.message : String(cbErr)}`
115029
115422
  );
115030
115423
  }
115031
115424
  });
115032
115425
  } catch (e) {
115033
- debugLogger89.warn(
115426
+ debugLogger90.warn(
115034
115427
  `re-attaching post-promote data listener threw: ${e instanceof Error ? e.message : String(e)}`
115035
115428
  );
115036
115429
  }
@@ -115050,7 +115443,7 @@ var ShellExecutionService = class _ShellExecutionService {
115050
115443
  }
115051
115444
  );
115052
115445
  } catch (e) {
115053
- debugLogger89.warn(
115446
+ debugLogger90.warn(
115054
115447
  `re-attaching post-promote exit listener threw: ${e instanceof Error ? e.message : String(e)}`
115055
115448
  );
115056
115449
  }
@@ -115068,7 +115461,7 @@ var ShellExecutionService = class _ShellExecutionService {
115068
115461
  }, "postPromoteErrorListener");
115069
115462
  ptyProcess.on("error", postPromoteErrorListener);
115070
115463
  } catch (e) {
115071
- debugLogger89.warn(
115464
+ debugLogger90.warn(
115072
115465
  `re-attaching post-promote error listener threw: ${e instanceof Error ? e.message : String(e)}`
115073
115466
  );
115074
115467
  }
@@ -115084,7 +115477,7 @@ var ShellExecutionService = class _ShellExecutionService {
115084
115477
  )
115085
115478
  ]);
115086
115479
  if (winner === TIMEOUT_SENTINEL) {
115087
- debugLogger89.warn(
115480
+ debugLogger90.warn(
115088
115481
  `Background-promote drain hit the ${PROMOTE_DRAIN_TIMEOUT_MS}ms timeout before processingChain settled. The output snapshot may be missing the very last batch of bytes the PTY emitted before promote (rawOutput in the result still has the full buffer the caller can re-render).`
115089
115482
  );
115090
115483
  }
@@ -115101,7 +115494,7 @@ var ShellExecutionService = class _ShellExecutionService {
115101
115494
  snapshot = serializeTerminalToText(headlessTerminal) ?? "";
115102
115495
  }
115103
115496
  } catch (serErr) {
115104
- debugLogger89.warn(
115497
+ debugLogger90.warn(
115105
115498
  `Background-promote snapshot replay failed: ${serErr instanceof Error ? serErr.message : String(serErr)}. Falling back to direct headlessTerminal serialize; if that also fails, output stays empty.`
115106
115499
  );
115107
115500
  try {
@@ -115261,7 +115654,7 @@ var ShellExecutionService = class _ShellExecutionService {
115261
115654
 
115262
115655
  // packages/core/src/tools/shell.ts
115263
115656
  var import_shell_quote6 = __toESM(require_shell_quote(), 1);
115264
- var debugLogger90 = createDebugLogger("SHELL");
115657
+ var debugLogger91 = createDebugLogger("SHELL");
115265
115658
  function stripTrailingBackgroundAmp2(command) {
115266
115659
  const trimmed2 = command.trimEnd();
115267
115660
  if (!trimmed2.endsWith("&")) return command;
@@ -115344,7 +115737,7 @@ function tokeniseSegment(segment) {
115344
115737
  (t) => typeof t === "string"
115345
115738
  );
115346
115739
  } catch (e) {
115347
- debugLogger90.warn(
115740
+ debugLogger91.warn(
115348
115741
  `tokeniseSegment: parse failed for "${segment.slice(0, 80)}": ${e instanceof Error ? e.message : String(e)}`
115349
115742
  );
115350
115743
  return null;
@@ -115571,7 +115964,7 @@ function findAttributableCommitSegment(command) {
115571
115964
  for (const sub of splitCommands(command)) {
115572
115965
  const start2 = command.indexOf(sub, cursor);
115573
115966
  if (start2 < 0) {
115574
- debugLogger90.warn(
115967
+ debugLogger91.warn(
115575
115968
  `findAttributableCommitSegment: cannot map segment "${sub.slice(0, 60)}" back to the original command (likely line-continuation / whitespace mismatch).`
115576
115969
  );
115577
115970
  continue;
@@ -115605,7 +115998,7 @@ function findGhPrCreateSegment(command) {
115605
115998
  for (const sub of splitCommands(command)) {
115606
115999
  const start2 = command.indexOf(sub, cursor);
115607
116000
  if (start2 < 0) {
115608
- debugLogger90.warn(
116001
+ debugLogger91.warn(
115609
116002
  `findGhPrCreateSegment: cannot map segment "${sub.slice(0, 60)}" back to the original command (likely line-continuation / whitespace mismatch).`
115610
116003
  );
115611
116004
  continue;
@@ -115970,7 +116363,7 @@ var ShellToolInvocation = class extends BaseToolInvocation {
115970
116363
  return "allow";
115971
116364
  }
115972
116365
  } catch (e) {
115973
- debugLogger90.warn("AST read-only check failed, falling back to ask:", e);
116366
+ debugLogger91.warn("AST read-only check failed, falling back to ask:", e);
115974
116367
  }
115975
116368
  return "ask";
115976
116369
  }
@@ -116001,7 +116394,7 @@ var ShellToolInvocation = class extends BaseToolInvocation {
116001
116394
  continue;
116002
116395
  }
116003
116396
  } catch (e) {
116004
- debugLogger90.warn("PermissionManager command check failed:", e);
116397
+ debugLogger91.warn("PermissionManager command check failed:", e);
116005
116398
  }
116006
116399
  }
116007
116400
  confirmableSubCommands.push(sub);
@@ -116021,7 +116414,7 @@ var ShellToolInvocation = class extends BaseToolInvocation {
116021
116414
  }
116022
116415
  permissionRules = [...new Set(allRules)].map((rule) => `Bash(${rule})`);
116023
116416
  } catch (e) {
116024
- debugLogger90.warn("Failed to extract command rules:", e);
116417
+ debugLogger91.warn("Failed to extract command rules:", e);
116025
116418
  }
116026
116419
  const confirmationDetails = {
116027
116420
  type: "exec",
@@ -116165,12 +116558,12 @@ var ShellToolInvocation = class extends BaseToolInvocation {
116165
116558
  try {
116166
116559
  promoteArtifacts.stream.write(chunk);
116167
116560
  } catch (err2) {
116168
- debugLogger90.warn(
116561
+ debugLogger91.warn(
116169
116562
  `promote: postPromote stream.write failed: ${getErrorMessage(err2)}`
116170
116563
  );
116171
116564
  }
116172
116565
  } else if (promoteArtifacts.streamClosed) {
116173
- debugLogger90.debug(
116566
+ debugLogger91.debug(
116174
116567
  "promote: dropping post-promote chunk because output stream open failed"
116175
116568
  );
116176
116569
  } else {
@@ -116276,7 +116669,7 @@ ${result.output}`;
116276
116669
  const elapsedMs = performance.now() - executionStartTime;
116277
116670
  const longRunThreshold = longRunThresholdFor(effectiveTimeout);
116278
116671
  const shouldAppendLongRunHint = !result.aborted && result.signal === null && elapsedMs >= longRunThreshold;
116279
- debugLogger90.debug(
116672
+ debugLogger91.debug(
116280
116673
  `long-run hint: elapsed=${Math.round(elapsedMs)}ms threshold=${longRunThreshold}ms aborted=${result.aborted} signal=${result.signal} \u2192 ${shouldAppendLongRunHint ? "fire" : "suppress"}`
116281
116674
  );
116282
116675
  let returnDisplayMessage = "";
@@ -116374,7 +116767,7 @@ ${longRunHint}` : ""),
116374
116767
  mkdirError = err2 instanceof Error ? err2 : new Error(String(err2));
116375
116768
  }
116376
116769
  if (mkdirError) {
116377
- debugLogger90.warn(
116770
+ debugLogger91.warn(
116378
116771
  `promote: mkdirSync(${outputDir}) failed before registry register \u2014 killing orphan child: ${mkdirError.message}`
116379
116772
  );
116380
116773
  const pid = result.pid;
@@ -116406,7 +116799,7 @@ ${longRunHint}` : ""),
116406
116799
  try {
116407
116800
  outputStream = fs77.createWriteStream(outputPath, { flags: "w" });
116408
116801
  outputStream.on("error", (err2) => {
116409
- debugLogger90.warn(
116802
+ debugLogger91.warn(
116410
116803
  `promote: output write stream error for ${outputPath}: ${getErrorMessage(err2)}`
116411
116804
  );
116412
116805
  const droppedChunks = promoteArtifacts.buffer.length;
@@ -116429,13 +116822,13 @@ ${longRunHint}` : ""),
116429
116822
  outputStream.write(chunk);
116430
116823
  }
116431
116824
  } catch (err2) {
116432
- debugLogger90.warn(
116825
+ debugLogger91.warn(
116433
116826
  `promote: failed to open output stream for ${outputPath}: ${getErrorMessage(err2)}`
116434
116827
  );
116435
116828
  promoteArtifacts.stream = null;
116436
116829
  promoteArtifacts.streamClosed = true;
116437
116830
  if (promoteArtifacts.buffer.length > 0) {
116438
- debugLogger90.warn(
116831
+ debugLogger91.warn(
116439
116832
  `promote: dropping ${promoteArtifacts.buffer.length} buffered post-promote chunks for ${outputPath} (stream open failed before drain)`
116440
116833
  );
116441
116834
  promoteArtifacts.buffer.length = 0;
@@ -116443,7 +116836,7 @@ ${longRunHint}` : ""),
116443
116836
  try {
116444
116837
  fs77.writeFileSync(outputPath, result.output);
116445
116838
  } catch (err22) {
116446
- debugLogger90.warn(
116839
+ debugLogger91.warn(
116447
116840
  `promote: snapshot fallback writeFileSync also failed for ${outputPath}: ${getErrorMessage(err22)}`
116448
116841
  );
116449
116842
  }
@@ -116463,12 +116856,12 @@ ${longRunHint}` : ""),
116463
116856
  "/t"
116464
116857
  ]);
116465
116858
  taskkillChild.on("error", (err2) => {
116466
- debugLogger90.warn(
116859
+ debugLogger91.warn(
116467
116860
  `promote: taskkill spawn failed for pid=${pid}: ${err2.message}`
116468
116861
  );
116469
116862
  });
116470
116863
  } catch (e) {
116471
- debugLogger90.warn(
116864
+ debugLogger91.warn(
116472
116865
  `promote: childProcess.spawn('taskkill') threw for pid=${pid}: ${getErrorMessage(e)}`
116473
116866
  );
116474
116867
  }
@@ -116483,7 +116876,7 @@ ${longRunHint}` : ""),
116483
116876
  } catch {
116484
116877
  }
116485
116878
  } catch (e) {
116486
- debugLogger90.warn(
116879
+ debugLogger91.warn(
116487
116880
  `promote: process.kill on -${pid} threw: ${getErrorMessage(e)}`
116488
116881
  );
116489
116882
  }
@@ -116512,7 +116905,7 @@ ${longRunHint}` : ""),
116512
116905
  try {
116513
116906
  registry.register(entry);
116514
116907
  } catch (e) {
116515
- debugLogger90.warn(
116908
+ debugLogger91.warn(
116516
116909
  `promote: registry.register threw for ${shellId} (pid=${result.pid}) \u2014 killing orphan child: ${e instanceof Error ? e.message : String(e)}`
116517
116910
  );
116518
116911
  try {
@@ -116541,7 +116934,7 @@ ${longRunHint}` : ""),
116541
116934
  status: "failed",
116542
116935
  failMsg: `Terminated by signal ${info2.signal}`
116543
116936
  };
116544
- debugLogger90.warn(
116937
+ debugLogger91.warn(
116545
116938
  `promote: classifySettle all-null fallback hit for ${shellId} \u2014 exitCode=${info2.exitCode}, signal=${info2.signal}, error=undefined`
116546
116939
  );
116547
116940
  return {
@@ -116567,7 +116960,7 @@ ${longRunHint}` : ""),
116567
116960
  try {
116568
116961
  stream2.write(promoteArtifacts.buffer.shift());
116569
116962
  } catch (writeErr) {
116570
- debugLogger90.warn(
116963
+ debugLogger91.warn(
116571
116964
  `promote: pre-end buffer drain write failed: ${getErrorMessage(writeErr)}`
116572
116965
  );
116573
116966
  }
@@ -116587,7 +116980,7 @@ ${longRunHint}` : ""),
116587
116980
  transitionRegistry(info2);
116588
116981
  }, "finalize");
116589
116982
  const flushTimer = setTimeout(() => {
116590
- debugLogger90.warn(
116983
+ debugLogger91.warn(
116591
116984
  `promote: output stream flush timed out for ${shellId} after ${PROMOTE_FLUSH_TIMEOUT_MS}ms \u2014 transitioning registry without flush confirmation`
116592
116985
  );
116593
116986
  finalize();
@@ -116603,7 +116996,7 @@ ${longRunHint}` : ""),
116603
116996
  });
116604
116997
  stream2.end();
116605
116998
  } catch (closeErr) {
116606
- debugLogger90.warn(
116999
+ debugLogger91.warn(
116607
117000
  `promote: closing output stream on settle threw: ${getErrorMessage(closeErr)}`
116608
117001
  );
116609
117002
  transitionRegistry(info2);
@@ -116624,7 +117017,7 @@ ${longRunHint}` : ""),
116624
117017
  inspectLine,
116625
117018
  stopLine
116626
117019
  ].join("\n");
116627
- debugLogger90.debug(
117020
+ debugLogger91.debug(
116628
117021
  `promote: registered ${shellId} (pid=${result.pid}) \u2014 outputPath=${outputPath}`
116629
117022
  );
116630
117023
  return {
@@ -116650,7 +117043,7 @@ ${longRunHint}` : ""),
116650
117043
  const trimmedOriginal = this.params.command.trim();
116651
117044
  const noTrailingAmp = stripTrailingBackgroundAmp2(trimmedOriginal);
116652
117045
  if (noTrailingAmp !== trimmedOriginal) {
116653
- debugLogger90.warn(
117046
+ debugLogger91.warn(
116654
117047
  "Stripped trailing & from background shell command \u2014 managed path handles backgrounding"
116655
117048
  );
116656
117049
  }
@@ -116669,7 +117062,7 @@ ${longRunHint}` : ""),
116669
117062
  const entryAc = new AbortController();
116670
117063
  const outputStream = fs77.createWriteStream(outputPath, { flags: "w" });
116671
117064
  outputStream.on("error", (err2) => {
116672
- debugLogger90.warn(
117065
+ debugLogger91.warn(
116673
117066
  `background shell ${shellId} output write error: ${err2.message}`
116674
117067
  );
116675
117068
  });
@@ -116707,7 +117100,7 @@ ${longRunHint}` : ""),
116707
117100
  try {
116708
117101
  registry.register(registration);
116709
117102
  } catch (e) {
116710
- debugLogger90.warn(
117103
+ debugLogger91.warn(
116711
117104
  `background shell ${shellId} register threw (pid=${pid}) \u2014 aborting orphan child: ${e instanceof Error ? e.message : String(e)}`
116712
117105
  );
116713
117106
  try {
@@ -116878,7 +117271,7 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
116878
117271
  const commitCount = preHead !== null ? await this.countCommitsAfter(cwd2, preHead, postHead) : await this.countCommitsFromRoot(cwd2, postHead);
116879
117272
  if (commitCount !== 1) {
116880
117273
  const reason = commitCount === 0 ? "commit count unavailable (rev-list failed) after HEAD moved \u2014 refusing to assume single commit" : `multi-commit shell command (${commitCount} commits since ${preHead ? preHead.slice(0, 12) : "repo root"})`;
116881
- debugLogger90.warn(`Refusing AI attribution: ${reason}.`);
117274
+ debugLogger91.warn(`Refusing AI attribution: ${reason}.`);
116882
117275
  attributionService.noteCommitWithoutClearing();
116883
117276
  return null;
116884
117277
  }
@@ -116949,7 +117342,7 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
116949
117342
  );
116950
117343
  const notesCommand = buildGitNotesCommand(note, postHead);
116951
117344
  if (!notesCommand) {
116952
- debugLogger90.warn(
117345
+ debugLogger91.warn(
116953
117346
  "AI attribution note too large, skipping git notes attachment"
116954
117347
  );
116955
117348
  warning = "AI attribution note skipped: payload exceeded the 30 KB size cap (large generated-file exclusion list?). Co-authored-by trailer is unaffected.";
@@ -116981,20 +117374,20 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
116981
117374
  });
116982
117375
  if (exitCode !== 0) {
116983
117376
  if (timedOut) {
116984
- debugLogger90.warn(`git notes timed out after 5s: ${output}`);
117377
+ debugLogger91.warn(`git notes timed out after 5s: ${output}`);
116985
117378
  warning = "AI attribution note skipped: `git notes add` timed out after 5s" + (output ? ` (${output.trim().slice(0, 120)})` : "") + ". Co-authored-by trailer is unaffected.";
116986
117379
  } else {
116987
- debugLogger90.warn(`git notes exited with code ${exitCode}: ${output}`);
117380
+ debugLogger91.warn(`git notes exited with code ${exitCode}: ${output}`);
116988
117381
  warning = `AI attribution note skipped: \`git notes add\` exited ${exitCode}` + (output ? ` (${output.trim().slice(0, 120)})` : "") + ". Co-authored-by trailer is unaffected.";
116989
117382
  }
116990
117383
  } else {
116991
- debugLogger90.debug(
117384
+ debugLogger91.debug(
116992
117385
  `Attached AI attribution note: ${note.summary.aiPercent}% AI, ${note.summary.totalFilesTouched} file(s)`
116993
117386
  );
116994
117387
  shouldClear = committedAbsolutePaths;
116995
117388
  }
116996
117389
  } catch (err2) {
116997
- debugLogger90.warn(
117390
+ debugLogger91.warn(
116998
117391
  `Failed to attach AI attribution note: ${getErrorMessage(err2)}`
116999
117392
  );
117000
117393
  warning = `AI attribution note skipped: ${getErrorMessage(err2)}. Co-authored-by trailer is unaffected.`;
@@ -117059,14 +117452,14 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
117059
117452
  ]);
117060
117453
  const hasParent = hasParentOutput !== null && hasParentOutput.length > 0;
117061
117454
  if (parentShaOutput === null) {
117062
- debugLogger90.warn(
117455
+ debugLogger91.warn(
117063
117456
  "getCommittedFileInfo: log -1 --pretty=%P <postHead> failed; cannot distinguish shallow clone from true root commit."
117064
117457
  );
117065
117458
  return null;
117066
117459
  }
117067
117460
  const isTrueRootCommit = parentShaOutput.trim().length === 0;
117068
117461
  if (!hasParent && !isTrueRootCommit) {
117069
- debugLogger90.warn(
117462
+ debugLogger91.warn(
117070
117463
  "getCommittedFileInfo: <postHead>~1 unreadable but commit is not the true root (shallow clone?); skipping attribution to avoid attributing the entire commit contents."
117071
117464
  );
117072
117465
  return null;
@@ -117075,14 +117468,14 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
117075
117468
  let diffArgs;
117076
117469
  if (isAmend) {
117077
117470
  if (preHead === null) {
117078
- debugLogger90.warn(
117471
+ debugLogger91.warn(
117079
117472
  "getCommittedFileInfo: --amend with no preHead; skipping attribution note (cannot determine amend delta)."
117080
117473
  );
117081
117474
  return null;
117082
117475
  }
117083
117476
  const preHeadProbe = await runGit2(`rev-parse --verify ${preHead}`);
117084
117477
  if (preHeadProbe === null || preHeadProbe.length === 0) {
117085
- debugLogger90.warn(
117478
+ debugLogger91.warn(
117086
117479
  "getCommittedFileInfo: --amend preHead unresolvable; skipping attribution note (cannot determine amend delta)."
117087
117480
  );
117088
117481
  return null;
@@ -117111,7 +117504,7 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
117111
117504
  runGit2(diffArgs.numstat)
117112
117505
  ]);
117113
117506
  if (nameOutput === null || statusOutput === null || numstatOutput === null) {
117114
- debugLogger90.warn(
117507
+ debugLogger91.warn(
117115
117508
  "getCommittedFileInfo: one or more diff calls failed; cannot distinguish empty commit from analysis failure."
117116
117509
  );
117117
117510
  return null;
@@ -117133,7 +117526,7 @@ To inspect: /tasks (text) or the interactive Background tasks dialog (focus the
117133
117526
  }
117134
117527
  const diffSizes = parseNumstat(numstatOutput);
117135
117528
  if (diffSizes.size === 0) {
117136
- debugLogger90.warn(
117529
+ debugLogger91.warn(
117137
117530
  "getCommittedFileInfo: --numstat returned empty while --name-only listed files; skipping attribution note to avoid emitting all-zero AI percentages."
117138
117531
  );
117139
117532
  return null;
@@ -117266,7 +117659,7 @@ Co-authored-by: ${escapedName} <${escapedEmail}>`;
117266
117659
  return command.slice(0, idx) + replacement + command.slice(idx + fullMatch.length);
117267
117660
  }
117268
117661
  }
117269
- debugLogger90.warn(
117662
+ debugLogger91.warn(
117270
117663
  'addAttributionToPR: gh pr create detected but no inline `--body`/`-b` argument found to append attribution to (--body-file / --fill / editor flows are unsupported); PR will be created without the AI attribution line. Pass `--body "..."` inline to enable automatic attribution.'
117271
117664
  );
117272
117665
  return command;
@@ -118068,6 +118461,7 @@ export {
118068
118461
  parseShortstat,
118069
118462
  parseDeletedFromNameStatus,
118070
118463
  resolveGitDir2 as resolveGitDir,
118464
+ collectMemoryDiagnostics,
118071
118465
  readPathFromWorkspace,
118072
118466
  getWelcomeBackState,
118073
118467
  saveWelcomeBackRestartChoice,