@symerian/symi 2.8.17 → 2.9.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 (163) hide show
  1. package/dist/{agents-9cAyC5ED.js → agents-CvNeiuSB.js} +4 -4
  2. package/dist/{agents.config-Cu9zTq04.js → agents.config-BCgY5FjE.js} +1 -1
  3. package/dist/{agents.config-DuwhYjpi.js → agents.config-Ct64cGQ8.js} +1 -1
  4. package/dist/{audio-preflight-rjCWpcfE.js → audio-preflight-Cb-T0r6e.js} +4 -4
  5. package/dist/{auth-choice-CPqyqc93.js → auth-choice-ChFU9OCF.js} +1 -1
  6. package/dist/{auth-choice-DeNzlUAR.js → auth-choice-DmMyKZX4.js} +1 -1
  7. package/dist/{banner-S1NGA6-s.js → banner-Bf46tqiY.js} +1 -1
  8. package/dist/build-info.json +3 -3
  9. package/dist/bundled/boot-md/handler.js +7 -7
  10. package/dist/bundled/session-memory/handler.js +7 -7
  11. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  12. package/dist/{channel-options-C0v4BJgp.js → channel-options-Bqc2VCgt.js} +1 -1
  13. package/dist/{channel-options-C6y7Khvq.js → channel-options-D4a0ZJ72.js} +1 -1
  14. package/dist/{channel-web-DirOFV_n.js → channel-web-YNC2xS5K.js} +1 -1
  15. package/dist/{channels-cli-BhNHckMo.js → channels-cli-BFJcNLbB.js} +6 -6
  16. package/dist/{channels-cli-By_SbriI.js → channels-cli-h3GnmmM9.js} +6 -6
  17. package/dist/{chrome-C08Z0XAa.js → chrome-ROtrXlNs.js} +7 -7
  18. package/dist/{cli-B1QQv1cb.js → cli-BX54CAM7.js} +3 -3
  19. package/dist/{cli-Bx4RQCuK.js → cli-BpQlSGVs.js} +3 -3
  20. package/dist/{command-registry-uMOPbrbY.js → command-registry-BiRjJ2Sy.js} +10 -10
  21. package/dist/{completion-cli-B6s_3rEE.js → completion-cli-BYXofVqv.js} +2 -2
  22. package/dist/{completion-cli-DVD79pVj.js → completion-cli-C8K5J1ld.js} +1 -1
  23. package/dist/{config-cli-DzudcNAD.js → config-cli-BPPD3xqE.js} +1 -1
  24. package/dist/{config-cli-DCGgd-ZL.js → config-cli-Deoo6r2K.js} +1 -1
  25. package/dist/{configure-BybpK_1N.js → configure-BKHxUAAh.js} +3 -3
  26. package/dist/{configure-CItWwZwI.js → configure-D4f0P3bH.js} +3 -3
  27. package/dist/{deliver-qUx-eLKt.js → deliver-B0OUq6RP.js} +1 -1
  28. package/dist/{doctor-completion-BkwgaO4G.js → doctor-completion-gMWymNcA.js} +1 -1
  29. package/dist/{doctor-completion-Bf6dN4D-.js → doctor-completion-woDYSVtY.js} +1 -1
  30. package/dist/entry.js +1 -1
  31. package/dist/extensionAPI.js +2 -2
  32. package/dist/{gateway-cli-eNV6kb1V.js → gateway-cli-Bnh42-56.js} +85 -41
  33. package/dist/{gateway-cli-7CVmb3cX.js → gateway-cli-DsnkTUOp.js} +85 -41
  34. package/dist/{glass-ui-ws-i91Ms6ts.js → glass-ui-ws-0Y0KsBvU.js} +9 -9
  35. package/dist/{glass-ui-ws-B4fsBuHx.js → glass-ui-ws-uj3DRmL8.js} +9 -9
  36. package/dist/{health-C4tWTDu_.js → health-CcV5nKIK.js} +1 -1
  37. package/dist/{health-dA8r4WJ4.js → health-Dl2WRoTa.js} +1 -1
  38. package/dist/{hooks-cli-DYn9nXX0.js → hooks-cli-CTcHtm_0.js} +4 -4
  39. package/dist/{hooks-cli-uGLWBIcW.js → hooks-cli-DEJe3dUH.js} +4 -4
  40. package/dist/{image-C6rCON9L.js → image-BuVL0jHI.js} +1 -1
  41. package/dist/index.js +8 -8
  42. package/dist/llm-slug-generator.js +7 -7
  43. package/dist/{manager-DhGfNqfc.js → manager-9Mni2AA9.js} +1 -1
  44. package/dist/{manager-D6E6EGWa.js → manager-C-H0XXJq.js} +1 -1
  45. package/dist/{manager-BaSutzfz.js → manager-CjW8kPVc.js} +1 -1
  46. package/dist/{manager-CgQo1mIM.js → manager-QPF0UtOC.js} +1 -1
  47. package/dist/{memory-cli-BMb31chU.js → memory-cli-BTByRgM0.js} +3 -3
  48. package/dist/{memory-cli-lJe72a5i.js → memory-cli-OW9XfyYu.js} +3 -3
  49. package/dist/{models-BITN17gY.js → models-Q1jV8ArL.js} +2 -2
  50. package/dist/{models-cli-CHjxevMe.js → models-cli-Cy6H1sFq.js} +5 -5
  51. package/dist/{models-cli-C6JJWWoI.js → models-cli-pfVmmgpv.js} +4 -4
  52. package/dist/{onboard-C8Si08MS.js → onboard-CvpyaUQd.js} +2 -2
  53. package/dist/{onboard-DdJV-Doq.js → onboard-EL8foMiP.js} +2 -2
  54. package/dist/{onboard-channels-Cb-bemSg.js → onboard-channels-BRoSUijQ.js} +1 -1
  55. package/dist/{onboard-channels-PQP9wlk8.js → onboard-channels-Bupbm6zh.js} +1 -1
  56. package/dist/{onboarding-QAtuyHtA.js → onboarding-Ch8WSJ3j.js} +3 -3
  57. package/dist/{onboarding-CAaoPaVQ.js → onboarding-Dg5ydWSh.js} +3 -3
  58. package/dist/{onboarding.finalize-MuO2mvHv.js → onboarding.finalize-Bo8-8TtH.js} +7 -7
  59. package/dist/{onboarding.finalize-BhlQmJlX.js → onboarding.finalize-CCTaCp2s.js} +8 -8
  60. package/dist/{pi-embedded-BUYKq7Wv.js → pi-embedded-Bl3YkBkI.js} +149 -35
  61. package/dist/{pi-embedded-helpers-P13adotN.js → pi-embedded-helpers-D1_Sab0M.js} +4 -4
  62. package/dist/{plugin-registry-tXiHw0vr.js → plugin-registry-BVYZLxmo.js} +1 -1
  63. package/dist/{plugin-registry-DEhkDNDx.js → plugin-registry-Bn9Mj8mP.js} +1 -1
  64. package/dist/plugin-sdk/agents/pi-tools.read-edit-guard.d.ts +5 -0
  65. package/dist/plugin-sdk/agents/pi-tools.read-edit-tracker.d.ts +26 -0
  66. package/dist/plugin-sdk/{channel-web-C7aP_KKZ.js → channel-web-BhqGIC7q.js} +1 -1
  67. package/dist/plugin-sdk/index.js +3 -3
  68. package/dist/plugin-sdk/{manager-CvrDwB1Q.js → manager-DdOb0Em2.js} +1 -1
  69. package/dist/plugin-sdk/{reply-BI7Rf3_S.js → reply-Cjjf4VYT.js} +149 -35
  70. package/dist/plugin-sdk/{synthesis-B3z0Jqt1.js → synthesis-CZ8BYNXP.js} +2 -2
  71. package/dist/plugin-sdk/{web-D2WrY-DI.js → web-B8upqMUo.js} +3 -3
  72. package/dist/{plugins-cli-ByG6o7D2.js → plugins-cli-3h1N5N8n.js} +4 -4
  73. package/dist/{plugins-cli-D1vPxTOQ.js → plugins-cli-CYOQh2DM.js} +4 -4
  74. package/dist/{program-Q44fKoq6.js → program-D3_xE9BL.js} +9 -9
  75. package/dist/{program-context-C3QEc34t.js → program-context-COwsYCbf.js} +18 -18
  76. package/dist/{prompt-select-styled-DBVeLysq.js → prompt-select-styled-D88AWCeM.js} +6 -6
  77. package/dist/{prompt-select-styled-BSZrZcW2.js → prompt-select-styled-rKPBDv7n.js} +6 -6
  78. package/dist/{provider-auth-helpers-Bm4cf-Ms.js → provider-auth-helpers-CyZyVx-V.js} +1 -1
  79. package/dist/{provider-auth-helpers-rH91VXG-.js → provider-auth-helpers-rff7s_gC.js} +1 -1
  80. package/dist/{push-apns-CRD9IH1s.js → push-apns-BNzgqUl3.js} +1 -1
  81. package/dist/{push-apns-Cj10sUbK.js → push-apns-d9qKGKPe.js} +1 -1
  82. package/dist/{pw-ai-CeWN4iD9.js → pw-ai-DWkC5eGA.js} +1 -1
  83. package/dist/{register.agent-DGDnsvVd.js → register.agent-BjaqQA02.js} +7 -7
  84. package/dist/{register.agent-Dfu85lRL.js → register.agent-D_MON8p-.js} +8 -8
  85. package/dist/{register.configure-FCTbPCwe.js → register.configure-BWkkQhpH.js} +8 -8
  86. package/dist/{register.configure-BcdyiQui.js → register.configure-UJi9sfNv.js} +8 -8
  87. package/dist/{register.maintenance-Y8P9AnLe.js → register.maintenance-ChskcWGz.js} +10 -10
  88. package/dist/{register.maintenance-DvDwpW6B.js → register.maintenance-DJptz3DR.js} +9 -9
  89. package/dist/{register.message-mTqwOntI.js → register.message-BDTsiyrW.js} +4 -4
  90. package/dist/{register.message-C57ubt4f.js → register.message-CiadI_oS.js} +4 -4
  91. package/dist/{register.onboard-MIChlygg.js → register.onboard-BflOE1jy.js} +6 -6
  92. package/dist/{register.onboard-YCmMzAW-.js → register.onboard-KR_-4TLY.js} +6 -6
  93. package/dist/{register.setup-sQeN5xag.js → register.setup-Cl0sD25T.js} +6 -6
  94. package/dist/{register.setup-DzUZ2x6y.js → register.setup-W-oNfOp0.js} +6 -6
  95. package/dist/{register.status-health-sessions-DaPK2tow.js → register.status-health-sessions-CCQs235z.js} +5 -5
  96. package/dist/{register.status-health-sessions-DsptpS7K.js → register.status-health-sessions-CT_SmmOH.js} +5 -5
  97. package/dist/{register.subclis-17z5d7uO.js → register.subclis-ByZAz4st.js} +9 -9
  98. package/dist/{reply-2awhibgG.js → reply-CgyjcoxC.js} +148 -34
  99. package/dist/{run-main-CfVO6DFS.js → run-main-xmWpjZL9.js} +17 -17
  100. package/dist/{runner-D633VT13.js → runner-ecX1WzDt.js} +1 -1
  101. package/dist/{server-methods-Bdgs89ve.js → server-methods-CBn954AO.js} +8 -8
  102. package/dist/{server-methods-D_g3GJhv.js → server-methods-DDpCXuOU.js} +8 -8
  103. package/dist/{server-node-events-BZN3RZ8H.js → server-node-events-BBEMSKVE.js} +4 -4
  104. package/dist/{server-node-events-Cvgmf8fS.js → server-node-events-BUEZ3py9.js} +4 -4
  105. package/dist/{status-CwqBkxi2.js → status-BjMiGq0n.js} +1 -1
  106. package/dist/{status-Dkr4Celv.js → status-CG5iHUJ6.js} +3 -3
  107. package/dist/{status-DcxWlds6.js → status-CpvzoCOC.js} +1 -1
  108. package/dist/{status-Ca_VZkZV.js → status-PfvX-BjO.js} +3 -3
  109. package/dist/{subagent-registry-CncIZPCd.js → subagent-registry-D0IYimMO.js} +148 -34
  110. package/dist/{synthesis-CxvpkXBW.js → synthesis-BVZ5RJLg.js} +3 -3
  111. package/dist/{synthesis-lD0Vb_9q.js → synthesis-CBwKBuLy.js} +7 -7
  112. package/dist/{synthesis-CTC73eY9.js → synthesis-D55QrjAJ.js} +3 -3
  113. package/dist/{synthesis-DOmJ2Gay.js → synthesis-itgrzpuj.js} +2 -2
  114. package/dist/{unified-runner-JQaSdhSg.js → unified-runner-BhnvjB1J.js} +163 -49
  115. package/dist/{update-cli-BO1uw-SU.js → update-cli-CL1_LPBS.js} +10 -10
  116. package/dist/{update-cli-CplnPSZ5.js → update-cli-D3K4mhrr.js} +9 -9
  117. package/dist/{update-runner-Df4mjndq.js → update-runner-Bmq67eos.js} +1 -1
  118. package/dist/{update-runner-DFp9PDMN.js → update-runner-DMucmRlv.js} +1 -1
  119. package/dist/{web-CCEVjDcU.js → web-B0lZdBBl.js} +3 -3
  120. package/dist/{web-CZoQ03ZE.js → web-C1HPdY_D.js} +2 -2
  121. package/dist/{web-BEDc6iEz.js → web-DCO_YCRw.js} +7 -7
  122. package/dist/{web-Dn33Cd3-.js → web-DmgQtLx3.js} +4 -4
  123. package/extensions/bluebubbles/package.json +1 -1
  124. package/extensions/copilot-proxy/package.json +1 -1
  125. package/extensions/diagnostics-otel/package.json +1 -1
  126. package/extensions/discord/package.json +1 -1
  127. package/extensions/feishu/package.json +1 -1
  128. package/extensions/google-antigravity-auth/package.json +1 -1
  129. package/extensions/google-gemini-cli-auth/package.json +1 -1
  130. package/extensions/googlechat/package.json +1 -1
  131. package/extensions/imessage/package.json +1 -1
  132. package/extensions/irc/package.json +1 -1
  133. package/extensions/learning-loop/package.json +1 -1
  134. package/extensions/line/package.json +1 -1
  135. package/extensions/llm-task/package.json +1 -1
  136. package/extensions/matrix/CHANGELOG.md +6 -0
  137. package/extensions/matrix/package.json +1 -1
  138. package/extensions/mattermost/package.json +1 -1
  139. package/extensions/memory-core/package.json +1 -1
  140. package/extensions/memory-lancedb/package.json +1 -1
  141. package/extensions/minimax-portal-auth/package.json +1 -1
  142. package/extensions/msteams/CHANGELOG.md +6 -0
  143. package/extensions/msteams/package.json +1 -1
  144. package/extensions/nextcloud-talk/package.json +1 -1
  145. package/extensions/nostr/CHANGELOG.md +6 -0
  146. package/extensions/nostr/package.json +1 -1
  147. package/extensions/open-prose/package.json +1 -1
  148. package/extensions/outlook/package.json +1 -1
  149. package/extensions/pipeline/package.json +1 -1
  150. package/extensions/signal/package.json +1 -1
  151. package/extensions/slack/package.json +1 -1
  152. package/extensions/telegram/package.json +1 -1
  153. package/extensions/tlon/package.json +1 -1
  154. package/extensions/twitch/CHANGELOG.md +6 -0
  155. package/extensions/twitch/package.json +1 -1
  156. package/extensions/voice-call/CHANGELOG.md +6 -0
  157. package/extensions/voice-call/package.json +1 -1
  158. package/extensions/whatsapp/package.json +1 -1
  159. package/extensions/zalo/CHANGELOG.md +6 -0
  160. package/extensions/zalo/package.json +1 -1
  161. package/extensions/zalouser/CHANGELOG.md +6 -0
  162. package/extensions/zalouser/package.json +1 -1
  163. package/package.json +1 -1
@@ -37,7 +37,7 @@ import { i as resolveSessionTranscriptPath, n as resolveSessionFilePath, o as re
37
37
  import { t as emitSessionTranscriptUpdate } from "./transcript-events-C8Tqw4td.js";
38
38
  import { i as resolveImageSanitizationLimits, n as sanitizeImageBlocks, r as sanitizeToolResultImages } from "./tool-images-ChC2CXaN.js";
39
39
  import { S as ensureSymiModelsJson, _ as stripMinimaxToolCallXml, a as decodeDataUrl, b as stripReasoningTagsFromText, c as extractAssistantText$1, d as extractThinkingFromTaggedText, f as formatReasoningMessage, g as stripDowngradedToolCallText, h as promoteThinkingTagsToBlocks, i as coerceImageModelConfig, l as extractAssistantThinking, m as isAssistantMessage, o as resolveProviderVisionModelFromConfig, p as inferToolMetaFromArgs, r as coerceImageAssistantText, s as minimaxUnderstandImage, u as extractThinkingFromTaggedStream, v as stripThinkingTagsFromText, x as extractTextFromChatContent, y as resolveToolDisplay } from "./image-MNvheU8U.js";
40
- import { a as resolveMemorySearchConfig, i as resolveOllamaBaseUrl, r as probeOllamaEmbeddingModels, t as MemoryIndexManager } from "./manager-D6E6EGWa.js";
40
+ import { a as resolveMemorySearchConfig, i as resolveOllamaBaseUrl, r as probeOllamaEmbeddingModels, t as MemoryIndexManager } from "./manager-C-H0XXJq.js";
41
41
  import { c as normalizeExtraMemoryPaths, f as runTasksWithConcurrency, s as listMemoryFiles } from "./internal-479FB0St.js";
42
42
  import { n as retryAsync } from "./retry-QGp0jvVi.js";
43
43
  import { a as createActionGate, c as jsonResult, d as readReactionParams, f as readStringArrayParam, l as parseAvailableTags, m as readStringParam, n as missingTargetError, o as imageResult, p as readStringOrNumberParam, r as unknownTargetError, s as imageResultFromFile, t as ambiguousTargetError, u as readNumberParam } from "./target-errors-Dm716SF3.js";
@@ -3473,7 +3473,7 @@ async function getMemorySearchManager(params) {
3473
3473
  const wrapper = new FallbackMemoryManager({
3474
3474
  primary,
3475
3475
  fallbackFactory: async () => {
3476
- const { MemoryIndexManager } = await import("./manager-D6E6EGWa.js").then((n) => n.n);
3476
+ const { MemoryIndexManager } = await import("./manager-C-H0XXJq.js").then((n) => n.n);
3477
3477
  return await MemoryIndexManager.get(params);
3478
3478
  }
3479
3479
  }, () => QMD_MANAGER_CACHE.delete(cacheKey));
@@ -3486,7 +3486,7 @@ async function getMemorySearchManager(params) {
3486
3486
  }
3487
3487
  }
3488
3488
  try {
3489
- const { MemoryIndexManager } = await import("./manager-D6E6EGWa.js").then((n) => n.n);
3489
+ const { MemoryIndexManager } = await import("./manager-C-H0XXJq.js").then((n) => n.n);
3490
3490
  return { manager: await MemoryIndexManager.get(params) };
3491
3491
  } catch (err) {
3492
3492
  return {
@@ -10252,16 +10252,16 @@ function shouldComputeCommandAuthorized(text, cfg, options) {
10252
10252
 
10253
10253
  //#endregion
10254
10254
  //#region src/channels/sender-label.ts
10255
- function normalize(value) {
10255
+ function normalize$1(value) {
10256
10256
  const trimmed = value?.trim();
10257
10257
  return trimmed ? trimmed : void 0;
10258
10258
  }
10259
10259
  function resolveSenderLabel(params) {
10260
- const name = normalize(params.name);
10261
- const username = normalize(params.username);
10262
- const tag = normalize(params.tag);
10263
- const e164 = normalize(params.e164);
10264
- const id = normalize(params.id);
10260
+ const name = normalize$1(params.name);
10261
+ const username = normalize$1(params.username);
10262
+ const tag = normalize$1(params.tag);
10263
+ const e164 = normalize$1(params.e164);
10264
+ const id = normalize$1(params.id);
10265
10265
  const display = name ?? username ?? tag ?? "";
10266
10266
  const idPart = e164 ?? id ?? "";
10267
10267
  if (display && idPart && display !== idPart) return `${display} (${idPart})`;
@@ -30509,8 +30509,39 @@ const GatewayToolSchema = Type.Object({
30509
30509
  baseHash: Type.Optional(Type.String()),
30510
30510
  sessionKey: Type.Optional(Type.String()),
30511
30511
  note: Type.Optional(Type.String()),
30512
- restartDelayMs: Type.Optional(Type.Number())
30512
+ restartDelayMs: Type.Optional(Type.Number()),
30513
+ userRequestAcknowledgment: Type.Optional(Type.String())
30513
30514
  });
30515
+ /** Actions that mutate gateway state and require explicit user authorization. */
30516
+ const DESTRUCTIVE_ACTIONS = new Set([
30517
+ "config.apply",
30518
+ "config.patch",
30519
+ "update.run"
30520
+ ]);
30521
+ /** Minimum length for a meaningful authorization message. */
30522
+ const MIN_AUTHORIZATION_LENGTH = 10;
30523
+ /**
30524
+ * Asserts the user's request was explicitly acknowledged for destructive
30525
+ * actions. Throws a descriptive error if the acknowledgment is missing,
30526
+ * empty, or trivially short.
30527
+ *
30528
+ * NOTE: This is defense-in-depth, not a hard barrier. A determined model
30529
+ * could still populate the field with fabricated text. The barrier exists
30530
+ * to:
30531
+ * 1. Force the agent to deliberately compose a justification (vs. blind
30532
+ * tool invocation).
30533
+ * 2. Provide an audit trail (the acknowledgment is logged with the tool
30534
+ * call args).
30535
+ * 3. Surface for future tightening (e.g., matching against real session
30536
+ * history).
30537
+ */
30538
+ function assertUserAuthorization(action, params) {
30539
+ if (!DESTRUCTIVE_ACTIONS.has(action)) return;
30540
+ const ack = params.userRequestAcknowledgment;
30541
+ const trimmed = typeof ack === "string" ? ack.trim() : "";
30542
+ if (!trimmed) throw new Error(`Action '${action}' requires an explicit user authorization. Pass userRequestAcknowledgment with a paraphrase of the user's request (e.g., "user said: please update Symi"). If the user did not explicitly request this action, ask them first instead of invoking it.`);
30543
+ if (trimmed.length < MIN_AUTHORIZATION_LENGTH) throw new Error(`Action '${action}' requires a substantive userRequestAcknowledgment (minimum ${MIN_AUTHORIZATION_LENGTH} characters describing the user's request). Received: ${JSON.stringify(trimmed)}.`);
30544
+ }
30514
30545
  function createGatewayTool(opts) {
30515
30546
  return {
30516
30547
  label: "Gateway",
@@ -30521,6 +30552,7 @@ function createGatewayTool(opts) {
30521
30552
  execute: async (_toolCallId, args) => {
30522
30553
  const params = args;
30523
30554
  const action = readStringParam(params, "action", { required: true });
30555
+ assertUserAuthorization(action, params);
30524
30556
  if (action === "restart") {
30525
30557
  if (!isRestartEnabled(opts?.config)) throw new Error("Gateway restart is disabled (commands.restart=false).");
30526
30558
  const sessionKey = typeof params.sessionKey === "string" && params.sessionKey.trim() ? params.sessionKey.trim() : opts?.agentSessionKey?.trim() || void 0;
@@ -61626,7 +61658,7 @@ function isVoiceChannelType(type) {
61626
61658
  function createDefaultDeps() {
61627
61659
  return {
61628
61660
  sendMessageWhatsApp: async (...args) => {
61629
- const { sendMessageWhatsApp } = await import("./web-CZoQ03ZE.js");
61661
+ const { sendMessageWhatsApp } = await import("./web-C1HPdY_D.js");
61630
61662
  return await sendMessageWhatsApp(...args);
61631
61663
  },
61632
61664
  sendMessageTelegram: async (...args) => {
@@ -76906,7 +76938,7 @@ function loadWebLoginQr() {
76906
76938
  return webLoginQrPromise;
76907
76939
  }
76908
76940
  function loadWebChannel() {
76909
- webChannelPromise ??= import("./web-CZoQ03ZE.js");
76941
+ webChannelPromise ??= import("./web-C1HPdY_D.js");
76910
76942
  return webChannelPromise;
76911
76943
  }
76912
76944
  function loadWhatsAppActions() {
@@ -78375,6 +78407,91 @@ function isToolAllowedByPolicies(name, policies) {
78375
78407
  return policies.every((policy) => isToolAllowedByPolicyName(name, policy));
78376
78408
  }
78377
78409
 
78410
+ //#endregion
78411
+ //#region src/agents/pi-tools.read-edit-guard.ts
78412
+ const RETRY_GUIDANCE_SUFFIX$1 = " Read the file first, then retry the edit.";
78413
+ function readGuardError(filePath) {
78414
+ return /* @__PURE__ */ new Error(`Edit refused: '${filePath}' has not been read in this session. The edit tool requires the agent to read the file first so oldText can match real content rather than hallucinated content.${RETRY_GUIDANCE_SUFFIX$1}`);
78415
+ }
78416
+ function extractPath(args) {
78417
+ if (!args || typeof args !== "object") return;
78418
+ const record = args;
78419
+ const candidate = record.path ?? record.file_path;
78420
+ if (typeof candidate !== "string") return;
78421
+ const trimmed = candidate.trim();
78422
+ return trimmed.length > 0 ? trimmed : void 0;
78423
+ }
78424
+ function wrapReadToolWithTracker(tool, tracker) {
78425
+ return {
78426
+ ...tool,
78427
+ execute: async (toolCallId, args, signal, onUpdate) => {
78428
+ const result = await tool.execute(toolCallId, args, signal, onUpdate);
78429
+ if (!(!!result && typeof result === "object" && result.isError === true)) {
78430
+ const filePath = extractPath(args);
78431
+ if (filePath) tracker.recordRead(filePath);
78432
+ }
78433
+ return result;
78434
+ }
78435
+ };
78436
+ }
78437
+ function wrapWriteToolWithTracker(tool, tracker) {
78438
+ return {
78439
+ ...tool,
78440
+ execute: async (toolCallId, args, signal, onUpdate) => {
78441
+ const result = await tool.execute(toolCallId, args, signal, onUpdate);
78442
+ if (!(!!result && typeof result === "object" && result.isError === true)) {
78443
+ const filePath = extractPath(args);
78444
+ if (filePath) tracker.recordWrite(filePath);
78445
+ }
78446
+ return result;
78447
+ }
78448
+ };
78449
+ }
78450
+ function wrapEditToolWithGuard(tool, tracker) {
78451
+ return {
78452
+ ...tool,
78453
+ execute: async (toolCallId, args, signal, onUpdate) => {
78454
+ const filePath = extractPath(args);
78455
+ if (filePath && !tracker.hasObserved(filePath)) throw readGuardError(filePath);
78456
+ return tool.execute(toolCallId, args, signal, onUpdate);
78457
+ }
78458
+ };
78459
+ }
78460
+
78461
+ //#endregion
78462
+ //#region src/agents/pi-tools.read-edit-tracker.ts
78463
+ function normalize(filePath, workspaceRoot) {
78464
+ if (!workspaceRoot) return filePath;
78465
+ if (path.isAbsolute(filePath)) return path.normalize(filePath);
78466
+ return path.resolve(workspaceRoot, filePath);
78467
+ }
78468
+ function createReadEditTracker(opts = {}) {
78469
+ const observed = /* @__PURE__ */ new Map();
78470
+ const record = (filePath, kind) => {
78471
+ if (typeof filePath !== "string" || !filePath.trim()) return;
78472
+ const key = normalize(filePath.trim(), opts.workspaceRoot);
78473
+ const prior = observed.get(key);
78474
+ if (kind === "written" || prior !== "written") observed.set(key, kind);
78475
+ };
78476
+ return {
78477
+ recordRead: (filePath) => record(filePath, "read"),
78478
+ recordWrite: (filePath) => record(filePath, "written"),
78479
+ observation: (filePath) => {
78480
+ if (typeof filePath !== "string" || !filePath.trim()) return null;
78481
+ const key = normalize(filePath.trim(), opts.workspaceRoot);
78482
+ return observed.get(key) ?? null;
78483
+ },
78484
+ hasObserved: (filePath) => {
78485
+ if (typeof filePath !== "string" || !filePath.trim()) return false;
78486
+ const key = normalize(filePath.trim(), opts.workspaceRoot);
78487
+ return observed.has(key);
78488
+ },
78489
+ reset: () => {
78490
+ observed.clear();
78491
+ }
78492
+ };
78493
+ }
78494
+
78378
78495
  //#endregion
78379
78496
  //#region src/media/sniff-mime-from-base64.ts
78380
78497
  async function sniffMimeFromBase64(base64) {
@@ -79002,33 +79119,34 @@ function createSymiCodingTools(options) {
79002
79119
  });
79003
79120
  if (sandboxRoot && !sandboxFsBridge) throw new Error("Sandbox filesystem bridge is unavailable.");
79004
79121
  const imageSanitization = resolveImageSanitizationLimits(options?.config);
79122
+ const readEditTracker = createReadEditTracker({ workspaceRoot: sandboxRoot ?? workspaceRoot });
79005
79123
  const base = codingTools.flatMap((tool) => {
79006
79124
  if (tool.name === readTool.name) {
79007
79125
  if (sandboxRoot) {
79008
- const sandboxed = createSandboxedReadTool({
79126
+ const tracked = wrapReadToolWithTracker(createSandboxedReadTool({
79009
79127
  root: sandboxRoot,
79010
79128
  bridge: sandboxFsBridge,
79011
79129
  modelContextWindowTokens: options?.modelContextWindowTokens,
79012
79130
  imageSanitization
79013
- });
79014
- return [workspaceOnly ? wrapToolWorkspaceRootGuard(sandboxed, sandboxRoot) : sandboxed];
79131
+ }), readEditTracker);
79132
+ return [workspaceOnly ? wrapToolWorkspaceRootGuard(tracked, sandboxRoot) : tracked];
79015
79133
  }
79016
- const wrapped = createSymiReadTool(createReadTool(workspaceRoot), {
79134
+ const tracked = wrapReadToolWithTracker(createSymiReadTool(createReadTool(workspaceRoot), {
79017
79135
  modelContextWindowTokens: options?.modelContextWindowTokens,
79018
79136
  imageSanitization
79019
- });
79020
- return [workspaceOnly ? wrapToolWorkspaceRootGuard(wrapped, workspaceRoot) : wrapped];
79137
+ }), readEditTracker);
79138
+ return [workspaceOnly ? wrapToolWorkspaceRootGuard(tracked, workspaceRoot) : tracked];
79021
79139
  }
79022
79140
  if (tool.name === "bash" || tool.name === execToolName) return [];
79023
79141
  if (tool.name === "write") {
79024
79142
  if (sandboxRoot) return [];
79025
- const wrapped = wrapToolParamNormalization(createWriteTool(workspaceRoot), CLAUDE_PARAM_GROUPS.write);
79026
- return [workspaceOnly ? wrapToolWorkspaceRootGuard(wrapped, workspaceRoot) : wrapped];
79143
+ const tracked = wrapWriteToolWithTracker(wrapToolParamNormalization(createWriteTool(workspaceRoot), CLAUDE_PARAM_GROUPS.write), readEditTracker);
79144
+ return [workspaceOnly ? wrapToolWorkspaceRootGuard(tracked, workspaceRoot) : tracked];
79027
79145
  }
79028
79146
  if (tool.name === "edit") {
79029
79147
  if (sandboxRoot) return [];
79030
- const wrapped = wrapToolParamNormalization(createEditTool(workspaceRoot), CLAUDE_PARAM_GROUPS.edit);
79031
- return [workspaceOnly ? wrapToolWorkspaceRootGuard(wrapped, workspaceRoot) : wrapped];
79148
+ const guarded = wrapEditToolWithGuard(wrapToolParamNormalization(createEditTool(workspaceRoot), CLAUDE_PARAM_GROUPS.edit), readEditTracker);
79149
+ return [workspaceOnly ? wrapToolWorkspaceRootGuard(guarded, workspaceRoot) : guarded];
79032
79150
  }
79033
79151
  return [tool];
79034
79152
  });
@@ -79071,22 +79189,18 @@ function createSymiCodingTools(options) {
79071
79189
  } : void 0,
79072
79190
  workspaceOnly: applyPatchWorkspaceOnly
79073
79191
  });
79192
+ const sandboxedEditTool = sandboxRoot ? wrapEditToolWithGuard(createSandboxedEditTool({
79193
+ root: sandboxRoot,
79194
+ bridge: sandboxFsBridge
79195
+ }), readEditTracker) : null;
79196
+ const sandboxedWriteTool = sandboxRoot ? wrapWriteToolWithTracker(createSandboxedWriteTool({
79197
+ root: sandboxRoot,
79198
+ bridge: sandboxFsBridge
79199
+ }), readEditTracker) : null;
79074
79200
  const withHooks = applyToolPolicyPipeline({
79075
79201
  tools: applyOwnerOnlyToolPolicy([
79076
79202
  ...base,
79077
- ...sandboxRoot ? allowWorkspaceWrites ? [workspaceOnly ? wrapToolWorkspaceRootGuard(createSandboxedEditTool({
79078
- root: sandboxRoot,
79079
- bridge: sandboxFsBridge
79080
- }), sandboxRoot) : createSandboxedEditTool({
79081
- root: sandboxRoot,
79082
- bridge: sandboxFsBridge
79083
- }), workspaceOnly ? wrapToolWorkspaceRootGuard(createSandboxedWriteTool({
79084
- root: sandboxRoot,
79085
- bridge: sandboxFsBridge
79086
- }), sandboxRoot) : createSandboxedWriteTool({
79087
- root: sandboxRoot,
79088
- bridge: sandboxFsBridge
79089
- })] : [] : [],
79203
+ ...sandboxRoot ? allowWorkspaceWrites && sandboxedEditTool && sandboxedWriteTool ? [workspaceOnly ? wrapToolWorkspaceRootGuard(sandboxedEditTool, sandboxRoot) : sandboxedEditTool, workspaceOnly ? wrapToolWorkspaceRootGuard(sandboxedWriteTool, sandboxRoot) : sandboxedWriteTool] : [] : [],
79090
79204
  ...applyPatchTool ? [applyPatchTool] : [],
79091
79205
  execTool,
79092
79206
  processTool,
@@ -9,7 +9,7 @@ import { h as isPidAlive, m as resolveProcessScopedMap } from "./auth-profiles-C
9
9
  import { n as formatCliCommand } from "./env-BDXYbTKj.js";
10
10
  import { t as parseBooleanValue } from "./boolean-CE7i9tBR.js";
11
11
  import { _ as parseDurationMs, a as writeConfigFile, n as loadConfig, s as parseByteSize, t as createConfigIO } from "./config-BkZ9HOKT.js";
12
- import { A as DEFAULT_BROWSER_EVALUATE_ENABLED, D as DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS, E as DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH, M as DEFAULT_SYMI_BROWSER_ENABLED, N as DEFAULT_SYMI_BROWSER_PROFILE_NAME, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, S as stopChromeExtensionRelayServer, _ as fetchJson, a as resolveSymiUserDataDir, c as captureScreenshot, d as normalizeCdpWsUrl, f as snapshotAria, g as appendCdpPath, h as withBrowserNavigationPolicy, i as launchSymiChrome, j as DEFAULT_SYMI_BROWSER_COLOR, k as DEFAULT_BROWSER_DEFAULT_PROFILE_NAME, l as createTargetViaCdp, m as assertBrowserNavigationAllowed, n as isChromeCdpReady, o as stopSymiChrome, p as InvalidBrowserNavigationUrlError, r as isChromeReachable, s as resolveBrowserExecutableForPlatform, v as fetchOk, w as isLoopbackHost, x as ensureChromeExtensionRelayServer } from "./chrome-C08Z0XAa.js";
12
+ import { A as DEFAULT_BROWSER_EVALUATE_ENABLED, D as DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS, E as DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH, M as DEFAULT_SYMI_BROWSER_ENABLED, N as DEFAULT_SYMI_BROWSER_PROFILE_NAME, O as DEFAULT_AI_SNAPSHOT_MAX_CHARS, S as stopChromeExtensionRelayServer, _ as fetchJson, a as resolveSymiUserDataDir, c as captureScreenshot, d as normalizeCdpWsUrl, f as snapshotAria, g as appendCdpPath, h as withBrowserNavigationPolicy, i as launchSymiChrome, j as DEFAULT_SYMI_BROWSER_COLOR, k as DEFAULT_BROWSER_DEFAULT_PROFILE_NAME, l as createTargetViaCdp, m as assertBrowserNavigationAllowed, n as isChromeCdpReady, o as stopSymiChrome, p as InvalidBrowserNavigationUrlError, r as isChromeReachable, s as resolveBrowserExecutableForPlatform, v as fetchOk, w as isLoopbackHost, x as ensureChromeExtensionRelayServer } from "./chrome-ROtrXlNs.js";
13
13
  import { a as syncSkillsToWorkspace, l as resolveSandboxInputPath, m as sanitizeEnvVars, u as resolveSandboxPath } from "./skills-CXxrn_e2.js";
14
14
  import { n as formatErrorMessage, t as extractErrorCode } from "./errors-XIsvXeC-.js";
15
15
  import { b as openFileWithinRoot, i as getImageMetadata, n as buildImageResizeSideGrid, s as resizeToJpeg, t as IMAGE_REDUCE_QUALITY_STEPS, y as SafeOpenError } from "./image-ops-C7CauEK8.js";
@@ -940,7 +940,7 @@ function isModuleNotFoundError(err) {
940
940
  }
941
941
  async function loadPwAiModule(mode) {
942
942
  try {
943
- return await import("./pw-ai-CeWN4iD9.js");
943
+ return await import("./pw-ai-DWkC5eGA.js");
944
944
  } catch (err) {
945
945
  if (mode === "soft") return null;
946
946
  if (isModuleNotFoundError(err)) return null;
@@ -3480,11 +3480,11 @@ function createProfileContext(opts, profile) {
3480
3480
  const userDataDir = resolveSymiUserDataDir(profile.name);
3481
3481
  const profileState = getProfileState();
3482
3482
  if (await isHttpReachable(300) && !profileState.running) try {
3483
- await (await import("./pw-ai-CeWN4iD9.js")).closePlaywrightBrowserConnection();
3483
+ await (await import("./pw-ai-DWkC5eGA.js")).closePlaywrightBrowserConnection();
3484
3484
  } catch {}
3485
3485
  if (profileState.running) await stopRunningBrowser();
3486
3486
  try {
3487
- await (await import("./pw-ai-CeWN4iD9.js")).closePlaywrightBrowserConnection();
3487
+ await (await import("./pw-ai-DWkC5eGA.js")).closePlaywrightBrowserConnection();
3488
3488
  } catch {}
3489
3489
  if (!fs.existsSync(userDataDir)) return {
3490
3490
  moved: false,
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
- import { pt as loadSymiPlugins } from "./reply-2awhibgG.js";
2
+ import { pt as loadSymiPlugins } from "./reply-CgyjcoxC.js";
3
3
  import { d as getActivePluginRegistry } from "./registry-Cja8eT7G.js";
4
4
  import { t as createSubsystemLogger } from "./subsystem-D9vIQve0.js";
5
5
  import { c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-CgUHAtCo.js";
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
2
  import { M as getActivePluginRegistry, o as createSubsystemLogger } from "./entry.js";
3
3
  import { c as resolveAgentWorkspaceDir, l as resolveDefaultAgentId } from "./agent-scope-D-jRCY0d.js";
4
4
  import { i as loadConfig } from "./config-DXt3pc08.js";
5
- import { m as loadSymiPlugins } from "./subagent-registry-CncIZPCd.js";
5
+ import { m as loadSymiPlugins } from "./subagent-registry-D0IYimMO.js";
6
6
 
7
7
  //#region src/cli/plugin-registry.ts
8
8
  var plugin_registry_exports = /* @__PURE__ */ __exportAll({ ensurePluginRegistryLoaded: () => ensurePluginRegistryLoaded });
@@ -0,0 +1,5 @@
1
+ import type { ReadEditTracker } from "./pi-tools.read-edit-tracker.js";
2
+ import type { AnyAgentTool } from "./pi-tools.types.js";
3
+ export declare function wrapReadToolWithTracker(tool: AnyAgentTool, tracker: ReadEditTracker): AnyAgentTool;
4
+ export declare function wrapWriteToolWithTracker(tool: AnyAgentTool, tracker: ReadEditTracker): AnyAgentTool;
5
+ export declare function wrapEditToolWithGuard(tool: AnyAgentTool, tracker: ReadEditTracker): AnyAgentTool;
@@ -0,0 +1,26 @@
1
+ export type ReadEditTrackerObservation = "read" | "written";
2
+ export interface ReadEditTracker {
3
+ /** Mark a path as read by the agent. */
4
+ recordRead(filePath: string | undefined | null): void;
5
+ /** Mark a path as written by the agent (write counts as observed). */
6
+ recordWrite(filePath: string | undefined | null): void;
7
+ /**
8
+ * Returns the observation kind for a file, or null if never observed.
9
+ * Path normalization matches recordRead/recordWrite.
10
+ */
11
+ observation(filePath: string | undefined | null): ReadEditTrackerObservation | null;
12
+ /** Convenience: was this file ever observed (read or written)? */
13
+ hasObserved(filePath: string | undefined | null): boolean;
14
+ /** Reset the tracker (used in tests). */
15
+ reset(): void;
16
+ }
17
+ export interface CreateReadEditTrackerOptions {
18
+ /**
19
+ * Workspace root used to normalize relative paths to absolute. Without it
20
+ * the tracker only matches on exact strings, which means `read("foo.ts")`
21
+ * followed by `edit("/abs/foo.ts")` would fail. With it, both normalize to
22
+ * the same absolute path and match correctly.
23
+ */
24
+ workspaceRoot?: string;
25
+ }
26
+ export declare function createReadEditTracker(opts?: CreateReadEditTrackerOptions): ReadEditTracker;
@@ -1,6 +1,6 @@
1
1
  import { a as buildGroupHistoryKey, n as DEFAULT_MAIN_KEY, r as buildAgentMainSessionKey, s as normalizeAgentId } from "./session-key-C_0eELjb.js";
2
2
  import { f as readWebSelfId, o as getWebAuthAgeMs, r as resolveWhatsAppAccount } from "./accounts-D9zGZU5t.js";
3
- import { D as enqueueSystemEvent, G as shouldAckReactionForWhatsApp, K as resolveMentionGating, X as DEFAULT_GROUP_HISTORY_LIMIT, Z as buildHistoryContextFromEntries, _ as formatInboundEnvelope, b as shouldComputeCommandAuthorized, c as computeBackoff, d as buildPairingReply, f as formatDurationPrecise, g as resolveInboundDebounceMs, gt as createDedupeCache, h as createInboundDebouncer, it as normalizeMentionText, l as sleepWithAbort, n as normalizeGroupActivation, nt as recordPendingHistoryEntryIfEnabled, p as dispatchReplyWithBufferedBlockDispatcher, r as parseActivationCommand, rt as buildMentionRegexes, t as getReplyFromConfig, v as resolveEnvelopeFormatOptions, y as hasControlCommand } from "./reply-BI7Rf3_S.js";
3
+ import { D as enqueueSystemEvent, G as shouldAckReactionForWhatsApp, K as resolveMentionGating, X as DEFAULT_GROUP_HISTORY_LIMIT, Z as buildHistoryContextFromEntries, _ as formatInboundEnvelope, b as shouldComputeCommandAuthorized, c as computeBackoff, d as buildPairingReply, f as formatDurationPrecise, g as resolveInboundDebounceMs, gt as createDedupeCache, h as createInboundDebouncer, it as normalizeMentionText, l as sleepWithAbort, n as normalizeGroupActivation, nt as recordPendingHistoryEntryIfEnabled, p as dispatchReplyWithBufferedBlockDispatcher, r as parseActivationCommand, rt as buildMentionRegexes, t as getReplyFromConfig, v as resolveEnvelopeFormatOptions, y as hasControlCommand } from "./reply-Cjjf4VYT.js";
4
4
  import { A as normalizeE164, B as toWhatsappJid, K as logVerbose, N as resolveJidToE164, O as isSelfChatMode, R as sleep, Y as shouldLogVerbose, k as jidToE164, s as normalizeChatChannelId, tt as getChildLogger, x as clamp } from "./registry--_pGht6S.js";
5
5
  import { n as loadConfig } from "./config-BzupW6LN.js";
6
6
  import { i as defaultRuntime, t as createSubsystemLogger } from "./subsystem-Coz2AgU8.js";
@@ -1,6 +1,6 @@
1
1
  import { f as DEFAULT_ACCOUNT_ID, p as normalizeAccountId } from "./session-key-C_0eELjb.js";
2
2
  import { _ as createAccountListHelpers, i as resolveWhatsAppAuthDir, n as resolveDefaultWhatsAppAccountId, r as resolveWhatsAppAccount, t as listWhatsAppAccountIds } from "./accounts-D9zGZU5t.js";
3
- import { $ as clearHistoryEntries, A as detectBinary, At as CHANNEL_MESSAGE_ACTION_NAMES, B as logInboundDrop, C as processLineMessage, Ct as listThreadBindingsBySessionKey, Dt as BLUEBUBBLES_ACTIONS, E as attachFooterText, Et as resolveAllowlistMatchSimple, F as optionalStringEnum, G as shouldAckReactionForWhatsApp, H as createTypingCallbacks, I as stringEnum, J as mergeAllowlist, K as resolveMentionGating, L as recordInboundSession, M as resolveDiscordChannelAllowlist, N as collectDiscordAuditChannelIds, O as resolveSlackUserAllowlist, Ot as BLUEBUBBLES_ACTION_NAMES, P as formatDocsLink, Q as buildPendingHistoryContextFromMap, R as resolveControlCommandGate, S as hasMarkdownToConvert, St as autoBindSpawnedDiscordSubagent, T as createReceiptCard, Tt as formatAllowlistMatchMeta, U as removeAckReactionAfterReply, V as logTypingFailure, W as shouldAckReaction, X as DEFAULT_GROUP_HISTORY_LIMIT, Y as summarizeMapping, _t as approveDevicePairing, a as normalizeAccountId$1, at as isWSL2Sync, bt as extractToolSend, ct as DEFAULT_WEBHOOK_BODY_TIMEOUT_MS, dt as installRequestBodyLimitGuard, et as clearHistoryEntriesIfEnabled, ft as isRequestBodyLimitError, gt as createDedupeCache, ht as requestBodyErrorToText, i as listLineAccountIds, j as resolveDiscordUserAllowlist, k as resolveSlackChannelAllowlist, kt as BLUEBUBBLES_GROUP_ACTIONS, lt as DEFAULT_WEBHOOK_MAX_BODY_BYTES, mt as readRequestBodyWithLimit, nt as recordPendingHistoryEntryIfEnabled, o as resolveDefaultLineAccountId, ot as isWSLEnv, pt as readJsonBodyWithLimit, q as resolveMentionGatingWithBypass, s as resolveLineAccount, st as isWSLSync, tt as recordPendingHistoryEntry, ut as RequestBodyLimitError, vt as listDevicePairing, w as stripMarkdown, wt as unbindThreadBindingsBySessionKey, xt as registerPluginHttpRoute, yt as rejectDevicePairing, z as logAckFailure } from "./reply-BI7Rf3_S.js";
3
+ import { $ as clearHistoryEntries, A as detectBinary, At as CHANNEL_MESSAGE_ACTION_NAMES, B as logInboundDrop, C as processLineMessage, Ct as listThreadBindingsBySessionKey, Dt as BLUEBUBBLES_ACTIONS, E as attachFooterText, Et as resolveAllowlistMatchSimple, F as optionalStringEnum, G as shouldAckReactionForWhatsApp, H as createTypingCallbacks, I as stringEnum, J as mergeAllowlist, K as resolveMentionGating, L as recordInboundSession, M as resolveDiscordChannelAllowlist, N as collectDiscordAuditChannelIds, O as resolveSlackUserAllowlist, Ot as BLUEBUBBLES_ACTION_NAMES, P as formatDocsLink, Q as buildPendingHistoryContextFromMap, R as resolveControlCommandGate, S as hasMarkdownToConvert, St as autoBindSpawnedDiscordSubagent, T as createReceiptCard, Tt as formatAllowlistMatchMeta, U as removeAckReactionAfterReply, V as logTypingFailure, W as shouldAckReaction, X as DEFAULT_GROUP_HISTORY_LIMIT, Y as summarizeMapping, _t as approveDevicePairing, a as normalizeAccountId$1, at as isWSL2Sync, bt as extractToolSend, ct as DEFAULT_WEBHOOK_BODY_TIMEOUT_MS, dt as installRequestBodyLimitGuard, et as clearHistoryEntriesIfEnabled, ft as isRequestBodyLimitError, gt as createDedupeCache, ht as requestBodyErrorToText, i as listLineAccountIds, j as resolveDiscordUserAllowlist, k as resolveSlackChannelAllowlist, kt as BLUEBUBBLES_GROUP_ACTIONS, lt as DEFAULT_WEBHOOK_MAX_BODY_BYTES, mt as readRequestBodyWithLimit, nt as recordPendingHistoryEntryIfEnabled, o as resolveDefaultLineAccountId, ot as isWSLEnv, pt as readJsonBodyWithLimit, q as resolveMentionGatingWithBypass, s as resolveLineAccount, st as isWSLSync, tt as recordPendingHistoryEntry, ut as RequestBodyLimitError, vt as listDevicePairing, w as stripMarkdown, wt as unbindThreadBindingsBySessionKey, xt as registerPluginHttpRoute, yt as rejectDevicePairing, z as logAckFailure } from "./reply-Cjjf4VYT.js";
4
4
  import "./paths-DR2yt_mP.js";
5
5
  import "./github-copilot-token-D9X2phUj.js";
6
6
  import { D as resolveSlackAccount, E as resolveDefaultSlackAccountId, F as resolveDiscordAccount, M as listDiscordAccountIds, O as resolveSlackReplyToMode, P as resolveDefaultDiscordAccountId, S as resolveTelegramAccount, T as listSlackAccountIds, _ as normalizeWhatsAppTarget, a as listDiscordDirectoryPeersFromConfig, b as listTelegramAccountIds, c as listTelegramDirectoryGroupsFromConfig, d as listWhatsAppDirectoryPeersFromConfig, f as looksLikeSlackTargetId, g as isWhatsAppGroupJid, i as listDiscordDirectoryGroupsFromConfig, l as listTelegramDirectoryPeersFromConfig, o as listSlackDirectoryGroupsFromConfig, p as normalizeSlackMessagingTarget, s as listSlackDirectoryPeersFromConfig, u as listWhatsAppDirectoryGroupsFromConfig, w as listEnabledSlackAccounts, x as resolveDefaultTelegramAccountId } from "./plugins-BbAvhC25.js";
@@ -47,12 +47,12 @@ import "./paths-A0xdf3yk.js";
47
47
  import { h as onDiagnosticEvent, m as isDiagnosticsEnabled, p as emitDiagnosticEvent } from "./diagnostic-_oc91gNi.js";
48
48
  import { n as extractOriginalFilename } from "./store-Do3t33-c.js";
49
49
  import { t as resolveWhatsAppOutboundTarget } from "./resolve-outbound-target-BkCUbYGV.js";
50
- import { r as resolveWhatsAppHeartbeatRecipients } from "./channel-web-C7aP_KKZ.js";
50
+ import { r as resolveWhatsAppHeartbeatRecipients } from "./channel-web-BhqGIC7q.js";
51
51
  import "./image-DFyINnvE.js";
52
52
  import "./pi-model-discovery-LbcEa65a.js";
53
53
  import "./api-key-rotation-CBsLb_4V.js";
54
54
  import "./diagnostic-session-state-Wd5tNeQG.js";
55
- import "./manager-CvrDwB1Q.js";
55
+ import "./manager-DdOb0Em2.js";
56
56
  import "./sqlite-CmVrFEYD.js";
57
57
  import "./commands-registry-BuYpmEx-.js";
58
58
  import "./send-CGhw9mO3.js";
@@ -3970,7 +3970,7 @@ var MemoryIndexManager = class MemoryIndexManager extends MemoryManagerEmbedding
3970
3970
  * to bypass the min-interval guard (CLI use).
3971
3971
  */
3972
3972
  async runL3CycleIfDue(params) {
3973
- const [{ runL3Cycle, runL3CycleIfDue }, { createSynthesizer }] = await Promise.all([import("./consolidate-CafShdsH.js"), import("./synthesis-B3z0Jqt1.js")]);
3973
+ const [{ runL3Cycle, runL3CycleIfDue }, { createSynthesizer }] = await Promise.all([import("./consolidate-CafShdsH.js"), import("./synthesis-CZ8BYNXP.js")]);
3974
3974
  const synthesize = createSynthesizer({
3975
3975
  cfg: this.cfg,
3976
3976
  agentId: this.agentId,