@royalcat/opencode-dcp-rc 0.0.0-stage → 4.0.1

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 (215) hide show
  1. package/LICENSE +619 -0
  2. package/README.md +348 -2
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +8129 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/commands/compression-targets.d.ts +13 -0
  8. package/dist/lib/commands/compression-targets.d.ts.map +1 -0
  9. package/dist/lib/commands/context.d.ts +67 -0
  10. package/dist/lib/commands/context.d.ts.map +1 -0
  11. package/dist/lib/commands/decompress.d.ts +12 -0
  12. package/dist/lib/commands/decompress.d.ts.map +1 -0
  13. package/dist/lib/commands/help.d.ts +18 -0
  14. package/dist/lib/commands/help.d.ts.map +1 -0
  15. package/dist/lib/commands/index.d.ts +8 -0
  16. package/dist/lib/commands/index.d.ts.map +1 -0
  17. package/dist/lib/commands/manual.d.ts +23 -0
  18. package/dist/lib/commands/manual.d.ts.map +1 -0
  19. package/dist/lib/commands/recompress.d.ts +12 -0
  20. package/dist/lib/commands/recompress.d.ts.map +1 -0
  21. package/dist/lib/commands/stats.d.ts +27 -0
  22. package/dist/lib/commands/stats.d.ts.map +1 -0
  23. package/dist/lib/commands/sweep.d.ts +23 -0
  24. package/dist/lib/commands/sweep.d.ts.map +1 -0
  25. package/dist/lib/compress/index.d.ts +3 -0
  26. package/dist/lib/compress/index.d.ts.map +1 -0
  27. package/dist/lib/compress/pipeline.d.ts +29 -0
  28. package/dist/lib/compress/pipeline.d.ts.map +1 -0
  29. package/dist/lib/compress/protected-content.d.ts +6 -0
  30. package/dist/lib/compress/protected-content.d.ts.map +1 -0
  31. package/dist/lib/compress/rc.d.ts +15 -0
  32. package/dist/lib/compress/rc.d.ts.map +1 -0
  33. package/dist/lib/compress/search.d.ts +12 -0
  34. package/dist/lib/compress/search.d.ts.map +1 -0
  35. package/dist/lib/compress/state.d.ts +10 -0
  36. package/dist/lib/compress/state.d.ts.map +1 -0
  37. package/dist/lib/compress/summary.d.ts +68 -0
  38. package/dist/lib/compress/summary.d.ts.map +1 -0
  39. package/dist/lib/compress/timing.d.ts +18 -0
  40. package/dist/lib/compress/timing.d.ts.map +1 -0
  41. package/dist/lib/compress/types.d.ts +64 -0
  42. package/dist/lib/compress/types.d.ts.map +1 -0
  43. package/dist/lib/compress/usage.d.ts +45 -0
  44. package/dist/lib/compress/usage.d.ts.map +1 -0
  45. package/dist/lib/compress-permission.d.ts +4 -0
  46. package/dist/lib/compress-permission.d.ts.map +1 -0
  47. package/dist/lib/config.d.ts +83 -0
  48. package/dist/lib/config.d.ts.map +1 -0
  49. package/dist/lib/hooks.d.ts +22 -0
  50. package/dist/lib/hooks.d.ts.map +1 -0
  51. package/dist/lib/logger.d.ts +31 -0
  52. package/dist/lib/logger.d.ts.map +1 -0
  53. package/dist/lib/message-ids.d.ts +20 -0
  54. package/dist/lib/message-ids.d.ts.map +1 -0
  55. package/dist/lib/messages/index.d.ts +8 -0
  56. package/dist/lib/messages/index.d.ts.map +1 -0
  57. package/dist/lib/messages/inject/inject.d.ts +7 -0
  58. package/dist/lib/messages/inject/inject.d.ts.map +1 -0
  59. package/dist/lib/messages/inject/subagent-results.d.ts +4 -0
  60. package/dist/lib/messages/inject/subagent-results.d.ts.map +1 -0
  61. package/dist/lib/messages/inject/utils.d.ts +23 -0
  62. package/dist/lib/messages/inject/utils.d.ts.map +1 -0
  63. package/dist/lib/messages/prune.d.ts +4 -0
  64. package/dist/lib/messages/prune.d.ts.map +1 -0
  65. package/dist/lib/messages/query.d.ts +7 -0
  66. package/dist/lib/messages/query.d.ts.map +1 -0
  67. package/dist/lib/messages/reasoning-strip.d.ts +8 -0
  68. package/dist/lib/messages/reasoning-strip.d.ts.map +1 -0
  69. package/dist/lib/messages/shape.d.ts +5 -0
  70. package/dist/lib/messages/shape.d.ts.map +1 -0
  71. package/dist/lib/messages/sync.d.ts +4 -0
  72. package/dist/lib/messages/sync.d.ts.map +1 -0
  73. package/dist/lib/messages/utils.d.ts +27 -0
  74. package/dist/lib/messages/utils.d.ts.map +1 -0
  75. package/dist/lib/prompts/compress-rc.d.ts +4 -0
  76. package/dist/lib/prompts/compress-rc.d.ts.map +1 -0
  77. package/dist/lib/prompts/context-limit-nudge.d.ts +2 -0
  78. package/dist/lib/prompts/context-limit-nudge.d.ts.map +1 -0
  79. package/dist/lib/prompts/extensions/nudge.d.ts +4 -0
  80. package/dist/lib/prompts/extensions/nudge.d.ts.map +1 -0
  81. package/dist/lib/prompts/extensions/system.d.ts +4 -0
  82. package/dist/lib/prompts/extensions/system.d.ts.map +1 -0
  83. package/dist/lib/prompts/extensions/tool.d.ts +3 -0
  84. package/dist/lib/prompts/extensions/tool.d.ts.map +1 -0
  85. package/dist/lib/prompts/index.d.ts +4 -0
  86. package/dist/lib/prompts/index.d.ts.map +1 -0
  87. package/dist/lib/prompts/iteration-nudge.d.ts +2 -0
  88. package/dist/lib/prompts/iteration-nudge.d.ts.map +1 -0
  89. package/dist/lib/prompts/store.d.ts +26 -0
  90. package/dist/lib/prompts/store.d.ts.map +1 -0
  91. package/dist/lib/prompts/system.d.ts +4 -0
  92. package/dist/lib/prompts/system.d.ts.map +1 -0
  93. package/dist/lib/prompts/turn-nudge.d.ts +2 -0
  94. package/dist/lib/prompts/turn-nudge.d.ts.map +1 -0
  95. package/dist/lib/protected-patterns.d.ts +6 -0
  96. package/dist/lib/protected-patterns.d.ts.map +1 -0
  97. package/dist/lib/state/index.d.ts +5 -0
  98. package/dist/lib/state/index.d.ts.map +1 -0
  99. package/dist/lib/state/persistence.d.ts +47 -0
  100. package/dist/lib/state/persistence.d.ts.map +1 -0
  101. package/dist/lib/state/state.d.ts +9 -0
  102. package/dist/lib/state/state.d.ts.map +1 -0
  103. package/dist/lib/state/tool-cache.d.ts +13 -0
  104. package/dist/lib/state/tool-cache.d.ts.map +1 -0
  105. package/dist/lib/state/types.d.ts +105 -0
  106. package/dist/lib/state/types.d.ts.map +1 -0
  107. package/dist/lib/state/utils.d.ts +22 -0
  108. package/dist/lib/state/utils.d.ts.map +1 -0
  109. package/dist/lib/strategies/deduplication.d.ts +10 -0
  110. package/dist/lib/strategies/deduplication.d.ts.map +1 -0
  111. package/dist/lib/strategies/index.d.ts +3 -0
  112. package/dist/lib/strategies/index.d.ts.map +1 -0
  113. package/dist/lib/strategies/purge-errors.d.ts +13 -0
  114. package/dist/lib/strategies/purge-errors.d.ts.map +1 -0
  115. package/dist/lib/subagents/subagent-results.d.ts +5 -0
  116. package/dist/lib/subagents/subagent-results.d.ts.map +1 -0
  117. package/dist/lib/token-utils.d.ts +19 -0
  118. package/dist/lib/token-utils.d.ts.map +1 -0
  119. package/dist/lib/tui/dialogs.d.ts +29 -0
  120. package/dist/lib/tui/dialogs.d.ts.map +1 -0
  121. package/dist/lib/tui/format.d.ts +4 -0
  122. package/dist/lib/tui/format.d.ts.map +1 -0
  123. package/dist/lib/tui/types.d.ts +18 -0
  124. package/dist/lib/tui/types.d.ts.map +1 -0
  125. package/dist/lib/tui/ui.d.ts +48 -0
  126. package/dist/lib/tui/ui.d.ts.map +1 -0
  127. package/dist/lib/ui/notification.d.ts +17 -0
  128. package/dist/lib/ui/notification.d.ts.map +1 -0
  129. package/dist/lib/ui/utils.d.ts +10 -0
  130. package/dist/lib/ui/utils.d.ts.map +1 -0
  131. package/dist/lib/v2/index.d.ts +5 -0
  132. package/dist/lib/v2/index.d.ts.map +1 -0
  133. package/dist/lib/v2/messages.d.ts +13 -0
  134. package/dist/lib/v2/messages.d.ts.map +1 -0
  135. package/dist/lib/v2/rpc.d.ts +75 -0
  136. package/dist/lib/v2/rpc.d.ts.map +1 -0
  137. package/dist/lib/v2/theme.d.ts +55 -0
  138. package/dist/lib/v2/theme.d.ts.map +1 -0
  139. package/dist/lib/v2/tui.d.ts +4 -0
  140. package/dist/lib/v2/tui.d.ts.map +1 -0
  141. package/dist/lib/v2/usage.d.ts +44 -0
  142. package/dist/lib/v2/usage.d.ts.map +1 -0
  143. package/dist/tui.d.ts +7 -0
  144. package/dist/tui.d.ts.map +1 -0
  145. package/lib/commands/compression-targets.ts +54 -0
  146. package/lib/commands/context.ts +305 -0
  147. package/lib/commands/decompress.ts +273 -0
  148. package/lib/commands/help.ts +76 -0
  149. package/lib/commands/index.ts +11 -0
  150. package/lib/commands/manual.ts +126 -0
  151. package/lib/commands/recompress.ts +222 -0
  152. package/lib/commands/stats.ts +180 -0
  153. package/lib/commands/sweep.ts +266 -0
  154. package/lib/compress/index.ts +2 -0
  155. package/lib/compress/pipeline.ts +116 -0
  156. package/lib/compress/protected-content.ts +163 -0
  157. package/lib/compress/rc.ts +494 -0
  158. package/lib/compress/search.ts +277 -0
  159. package/lib/compress/state.ts +272 -0
  160. package/lib/compress/summary.ts +320 -0
  161. package/lib/compress/timing.ts +77 -0
  162. package/lib/compress/types.ts +70 -0
  163. package/lib/compress/usage.ts +168 -0
  164. package/lib/compress-permission.ts +9 -0
  165. package/lib/config.ts +995 -0
  166. package/lib/hooks.ts +205 -0
  167. package/lib/logger.ts +226 -0
  168. package/lib/message-ids.ts +181 -0
  169. package/lib/messages/index.ts +7 -0
  170. package/lib/messages/inject/inject.ts +215 -0
  171. package/lib/messages/inject/subagent-results.ts +84 -0
  172. package/lib/messages/inject/utils.ts +304 -0
  173. package/lib/messages/prune.ts +238 -0
  174. package/lib/messages/query.ts +71 -0
  175. package/lib/messages/reasoning-strip.ts +40 -0
  176. package/lib/messages/shape.ts +50 -0
  177. package/lib/messages/sync.ts +124 -0
  178. package/lib/messages/utils.ts +190 -0
  179. package/lib/prompts/compress-rc.ts +25 -0
  180. package/lib/prompts/context-limit-nudge.ts +18 -0
  181. package/lib/prompts/extensions/nudge.ts +34 -0
  182. package/lib/prompts/extensions/system.ts +32 -0
  183. package/lib/prompts/extensions/tool.ts +21 -0
  184. package/lib/prompts/index.ts +29 -0
  185. package/lib/prompts/iteration-nudge.ts +6 -0
  186. package/lib/prompts/store.ts +452 -0
  187. package/lib/prompts/system.ts +41 -0
  188. package/lib/prompts/turn-nudge.ts +10 -0
  189. package/lib/protected-patterns.ts +159 -0
  190. package/lib/state/index.ts +4 -0
  191. package/lib/state/persistence.ts +321 -0
  192. package/lib/state/state.ts +214 -0
  193. package/lib/state/tool-cache.ts +99 -0
  194. package/lib/state/types.ts +117 -0
  195. package/lib/state/utils.ts +345 -0
  196. package/lib/strategies/deduplication.ts +125 -0
  197. package/lib/strategies/index.ts +2 -0
  198. package/lib/strategies/purge-errors.ts +86 -0
  199. package/lib/subagents/subagent-results.ts +75 -0
  200. package/lib/token-utils.ts +164 -0
  201. package/lib/tui/dialogs.tsx +261 -0
  202. package/lib/tui/format.ts +25 -0
  203. package/lib/tui/types.ts +25 -0
  204. package/lib/tui/ui.tsx +245 -0
  205. package/lib/ui/notification.ts +347 -0
  206. package/lib/ui/utils.ts +304 -0
  207. package/lib/v2/index.ts +448 -0
  208. package/lib/v2/messages.ts +252 -0
  209. package/lib/v2/rpc.ts +60 -0
  210. package/lib/v2/theme.ts +67 -0
  211. package/lib/v2/tui.tsx +115 -0
  212. package/lib/v2/usage.ts +423 -0
  213. package/package.json +91 -5
  214. package/server.js +1 -0
  215. package/tui.tsx +7 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../lib/v2/index.ts","../lib/config.ts","../node_modules/jsonc-parser/lib/esm/impl/scanner.js","../node_modules/jsonc-parser/lib/esm/impl/string-intern.js","../node_modules/jsonc-parser/lib/esm/impl/parser.js","../node_modules/jsonc-parser/lib/esm/main.js","../lib/logger.ts","../lib/prompts/store.ts","../lib/prompts/system.ts","../lib/prompts/compress-rc.ts","../lib/prompts/context-limit-nudge.ts","../lib/prompts/turn-nudge.ts","../lib/prompts/iteration-nudge.ts","../lib/prompts/extensions/system.ts","../lib/compress/rc.ts","../lib/state/persistence.ts","../lib/compress/usage.ts","../lib/messages/shape.ts","../lib/messages/query.ts","../lib/token-utils.ts","../lib/state/utils.ts","../lib/message-ids.ts","../lib/compress/state.ts","../lib/compress/timing.ts","../lib/state/state.ts","../lib/state/tool-cache.ts","../lib/compress/search.ts","../lib/protected-patterns.ts","../lib/strategies/deduplication.ts","../lib/strategies/purge-errors.ts","../lib/ui/utils.ts","../lib/ui/notification.ts","../lib/compress/pipeline.ts","../lib/prompts/extensions/tool.ts","../lib/subagents/subagent-results.ts","../lib/compress/protected-content.ts","../lib/compress/summary.ts","../lib/v2/usage.ts","../lib/prompts/index.ts","../lib/commands/context.ts","../lib/messages/utils.ts","../lib/messages/prune.ts","../lib/messages/sync.ts","../lib/compress-permission.ts","../lib/prompts/extensions/nudge.ts","../lib/messages/inject/utils.ts","../lib/messages/inject/inject.ts","../lib/messages/inject/subagent-results.ts","../lib/commands/compression-targets.ts","../lib/commands/decompress.ts","../lib/commands/help.ts","../lib/commands/manual.ts","../lib/commands/recompress.ts","../lib/commands/stats.ts","../lib/commands/sweep.ts","../lib/hooks.ts","../lib/v2/messages.ts","../lib/v2/rpc.ts","../index.ts"],"sourcesContent":["import type { Plugin } from \"@opencode/plugin\"\nimport { tool, type ToolDefinition } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport { PromptStore } from \"../prompts/store\"\nimport { createRcCompressTool } from \"../compress\"\nimport { extractSummaryCallId, hasSummaryMarker } from \"../compress/summary\"\nimport { attachCompressionDuration } from \"../compress/state\"\nimport {\n createCompressionUsageTracker,\n installCompressionUsageHook,\n installHttpUsageHook,\n} from \"./usage\"\nimport { createCommandExecuteHandler, createSystemPromptHandler } from \"../hooks\"\nimport {\n createSessionState,\n ensureSessionInitialized,\n checkSession,\n saveSessionState,\n syncToolCache,\n type SessionState,\n} from \"../state\"\nimport { assignMessageRefs } from \"../message-ids\"\nimport { applyPendingManualTrigger } from \"../commands/manual\"\nimport {\n buildToolIdList,\n injectCompressNudges,\n injectMessageIds,\n injectExtendedSubAgentResults,\n prune,\n stripHallucinations,\n syncCompressionBlocks,\n} from \"../messages\"\nimport { countTokens } from \"../token-utils\"\nimport { matchesGlob } from \"../protected-patterns\"\nimport { history, project } from \"./messages\"\nimport { analyzeContextTokens } from \"../commands/context\"\nimport { buildStatsReport } from \"../commands/stats\"\nimport { rpc } from \"./rpc\"\n\n// Extension point for future model-invisible V2 reports. Never use synthetic()\n// here: its text would enter the model's context, unlike V1 ignored messages.\nexport async function report(logger: Logger, text: string, sessionID?: string) {\n logger.debug(\"V2 report (display pending)\", { sessionID, text })\n}\n\nexport async function setup(ctx: Plugin.Context) {\n const warnings = {\n tui: {\n showToast: async (input: { body: { message: string } }) => {\n console.warn(`DCP: ${input.body.message}`)\n },\n },\n }\n const config = getConfig({ directory: ctx.location.directory, client: warnings })\n if (!config.enabled) {\n await ctx.rpc.register(\n { ...rpc, methods: { status: rpc.methods.status } },\n { status: async () => ({ enabled: false }) },\n )\n return\n }\n const logger = new Logger(config.debug)\n const usageTracker = createCompressionUsageTracker()\n await installCompressionUsageHook(ctx, usageTracker, logger)\n await installHttpUsageHook(ctx, usageTracker, logger)\n const prompts = new PromptStore(\n logger,\n ctx.location.directory,\n config.experimental.customPrompts,\n \"compact\",\n )\n const sessions = new Map<string, SessionState>()\n const queues = new Map<string, Promise<unknown>>()\n const limits = new Map<string, number>()\n const aliases: Record<string, string> = {\n task: \"subagent\",\n bash: \"shell\",\n apply_patch: \"patch\",\n }\n for (const list of [\n config.compress.protectedTools,\n config.commands.protectedTools,\n config.strategies.deduplication.protectedTools,\n config.strategies.purgeErrors.protectedTools,\n ]) {\n for (const name of [...list])\n if (aliases[name] && !list.includes(aliases[name]!)) list.push(aliases[name]!)\n }\n\n function serial<T>(sessionID: string, operation: () => Promise<T>): Promise<T> {\n const pending = (queues.get(sessionID) ?? Promise.resolve()).catch(() => {}).then(operation)\n queues.set(sessionID, pending)\n void pending\n .finally(() => {\n if (queues.get(sessionID) === pending) queues.delete(sessionID)\n })\n .catch(() => {})\n return pending\n }\n\n const client = {\n session: {\n get: async ({ path }: { path: { id: string } }) => ({\n data: await ctx.session.get({ sessionID: path.id }),\n }),\n messages: async ({ path }: { path: { id: string } }) => {\n const [entries, session] = await Promise.all([\n ctx.session.context({ sessionID: path.id }),\n ctx.session.get({ sessionID: path.id }),\n ])\n return { data: history(entries, session) }\n },\n prompt: async (input: {\n path: { id: string }\n body: { parts: Array<{ text: string }> }\n }) =>\n report(logger, input.body.parts.map((part) => part.text).join(\"\\n\"), input.path.id),\n },\n tui: {\n showToast: async (input: { body: { message: string } }) =>\n report(logger, input.body.message),\n },\n }\n\n async function load(sessionID: string, agentID?: string) {\n const [session, entries] = await Promise.all([\n ctx.session.get({ sessionID }),\n ctx.session.context({ sessionID }),\n ])\n const selected =\n agentID ??\n session.agent ??\n entries.findLast((entry) => entry.type === \"assistant\")?.agent\n if (!selected) throw new Error(\"DCP commands require a session with a selected agent\")\n const { data: agent } = await ctx.agent.get({ agentID: selected })\n let state = sessions.get(sessionID)\n if (!state) {\n state = createSessionState(\"compact\")\n sessions.set(sessionID, state)\n }\n const messages = history(entries, session)\n await ensureSessionInitialized(\n client,\n state,\n sessionID,\n logger,\n messages,\n config.manualMode.enabled,\n )\n await checkSession(client, state, logger, messages, config.manualMode.enabled)\n const rule = [...agent.permissions, ...(session.permissions ?? [])].findLast(\n (rule) => matchesGlob(\"compress\", rule.action) && matchesGlob(\"*\", rule.resource),\n )\n state.compressPermission =\n config.compress.permission === \"deny\"\n ? \"deny\"\n : rule?.effect === \"deny\"\n ? \"deny\"\n : config.compress.permission === \"ask\" || rule?.effect === \"ask\"\n ? \"ask\"\n : \"allow\"\n return { state, entries, session, messages }\n }\n\n function allowed(state: SessionState) {\n if (state.isSubAgent && !config.experimental.allowSubAgents)\n throw new Error(\"DCP compression is disabled in subagents\")\n if (state.compressPermission === \"deny\") throw new Error(\"DCP compression is denied\")\n if (state.compressPermission === \"ask\")\n throw new Error(\n \"DCP: compress permission 'ask' is not supported by OpenCode V2's public plugin API yet. Compression was not performed.\",\n )\n }\n\n await ctx.model.transform((editor) => {\n limits.clear()\n for (const model of editor.list())\n limits.set(`${model.providerID}/${model.id}`, model.limit.context)\n })\n for (const kind of [\"context\", \"compaction\"] as const)\n await ctx.session.hook(kind, (event) =>\n serial(event.sessionID, async () => {\n const { state, entries, session, messages } = await load(\n event.sessionID,\n event.agent,\n )\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n delete event.tools.compress\n return\n }\n if (state.compressPermission === \"deny\") delete event.tools.compress\n state.modelContextLimit = limits.get(`${event.model.providerID}/${event.model.id}`)\n state.systemPromptTokens = countTokens(\n event.system.map((part) => part.text).join(\"\\n\"),\n )\n const view = project(event.messages, entries, {\n ...session,\n agent: event.agent,\n model: event.model,\n })\n stripHallucinations(view.messages, state.idFormat)\n assignMessageRefs(state, view.messages)\n // Compaction may select only a prefix; block origins can be in the retained tail.\n syncCompressionBlocks(state, logger, messages)\n syncToolCache(state, config, logger, view.messages)\n buildToolIdList(state, view.messages)\n prune(state, logger, view.messages, view.summaryBase)\n await injectExtendedSubAgentResults(\n client,\n state,\n logger,\n view.messages,\n config.experimental.allowSubAgents,\n )\n prompts.reload()\n injectCompressNudges(\n state,\n config,\n logger,\n view.messages,\n prompts.getRuntimePrompts(),\n kind === \"context\",\n )\n injectMessageIds(state, config, view.messages)\n applyPendingManualTrigger(state, view.messages, logger)\n event.messages = view.restore()\n const system = { system: event.system.map((part) => part.text) }\n await createSystemPromptHandler(\n state,\n logger,\n config,\n prompts,\n )(\n {\n sessionID: event.sessionID,\n model: { limit: { context: state.modelContextLimit ?? 0 } },\n },\n system,\n )\n event.system = system.system.map((text, index) => ({\n ...event.system[index],\n type: \"text\",\n text,\n }))\n await logger.saveContext(event.sessionID, view.messages)\n }),\n )\n\n // Hidden summary generation for rc mode: when our marker is present, drop\n // the session context and every tool so the transient request contains\n // only the prompt we built. This keeps the summarization request invisible\n // and independent of any injected metadata.\n await ctx.session.hook(\"generate\", (event) => {\n const own = event.messages.filter(\n (message) =>\n Array.isArray(message.content) &&\n message.content.some(\n (part: any) =>\n part?.type === \"text\" &&\n typeof part.text === \"string\" &&\n hasSummaryMarker(part.text),\n ),\n )\n if (own.length === 0) {\n return\n }\n event.messages = own as typeof event.messages\n for (const name of Object.keys(event.tools ?? {})) {\n delete (event.tools as Record<string, unknown>)[name]\n }\n\n // Local fallback estimate of the request input, used only when the\n // provider usage cannot be captured from the language model wrapper.\n const callId = own\n .flatMap((message) =>\n Array.isArray(message.content) ? (message.content as any[]) : [],\n )\n .filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n .map((part) => extractSummaryCallId(part.text))\n .find((id): id is string => !!id)\n if (callId) {\n const texts: string[] = []\n for (const part of event.system ?? []) {\n if (typeof (part as any)?.text === \"string\") {\n texts.push((part as any).text)\n }\n }\n for (const message of own) {\n for (const part of (message.content as any[]) ?? []) {\n if (part?.type === \"text\" && typeof part.text === \"string\") {\n texts.push(part.text)\n }\n }\n }\n usageTracker.recordEstimatedInput(callId, countTokens(texts.join(\"\\n\")))\n }\n })\n\n if (config.compress.permission !== \"deny\") {\n const define = (state: SessionState): ToolDefinition => {\n const context = {\n client,\n state,\n logger,\n config,\n prompts,\n generate: async (input: { sessionID: string; prompt: string; callId?: string }) => {\n try {\n const result = await ctx.session.generate({\n sessionID: input.sessionID,\n prompt: input.prompt,\n })\n const text = result?.text ?? \"\"\n const usage = input.callId\n ? usageTracker.resolve(input.callId, text)\n : undefined\n return { text, usage }\n } finally {\n if (input.callId) {\n usageTracker.discard(input.callId)\n }\n }\n },\n }\n return createRcCompressTool(context)\n }\n const definition = define(createSessionState(\"compact\"))\n await ctx.tool.transform((editor) =>\n editor.add({\n name: \"compress\",\n description: definition.description,\n input: tool.schema.object(definition.args),\n options: { codemode: false, permission: \"compress\" },\n execute: (input, context) =>\n serial(context.sessionID, async () => {\n const { state } = await load(context.sessionID, context.agent)\n allowed(state)\n const started = Date.now()\n const legacy = define(state)\n const content = await legacy.execute(input, {\n sessionID: context.sessionID,\n messageID: context.messageID,\n callID: context.id,\n agent: context.agent,\n directory: ctx.location.directory,\n worktree: ctx.location.directory,\n abort: new AbortController().signal,\n ask: async () => allowed(state),\n metadata: ({ title }: { title?: string }) => {\n void context.progress({ title })\n },\n } as Parameters<typeof legacy.execute>[1])\n attachCompressionDuration(\n state.prune.messages,\n context.messageID,\n context.id,\n Date.now() - started,\n )\n await saveSessionState(state, logger)\n // The rc executor returns the tool result text.\n return { content: content as string }\n }),\n }),\n )\n }\n if (config.commands.enabled)\n await ctx.command.transform((editor) => {\n for (const name of [\"dcp\", \"dcp-compress\"])\n editor.add({\n name,\n description: name === \"dcp\" ? \"DCP commands\" : \"Trigger DCP manual compression\",\n execute: async (invocation) => {\n const prompt = await serial(invocation.sessionID, async () => {\n const { state } = await load(invocation.sessionID)\n const permission =\n state.compressPermission ?? config.compress.permission\n if (\n name === \"dcp-compress\" ||\n invocation.prompt.text.trim().split(/\\s+/)[0] === \"compress\"\n )\n allowed(state)\n const output = { parts: [] }\n await createCommandExecuteHandler(\n client,\n state,\n logger,\n config,\n ctx.location.directory,\n )(\n {\n command: name,\n sessionID: invocation.sessionID,\n arguments: invocation.prompt.text,\n },\n output,\n )\n state.compressPermission = permission\n const pending = state.pendingManualTrigger\n if (!pending) return\n allowed(state)\n state.pendingManualTrigger = null\n return pending.prompt\n })\n if (prompt)\n await ctx.session.prompt({\n sessionID: invocation.sessionID,\n text: prompt,\n delivery: invocation.delivery,\n })\n },\n })\n })\n await ctx.rpc.register(rpc, {\n status: async () => ({ enabled: config.commands.enabled }),\n snapshot: ({ sessionID }) =>\n serial(sessionID, async () => {\n const { state, messages } = await load(sessionID)\n syncCompressionBlocks(state, logger, messages)\n return {\n manualMode: !!state.manualMode,\n canCompress:\n state.compressPermission === \"allow\" &&\n (!state.isSubAgent || config.experimental.allowSubAgents),\n ...(state.compressPermission === \"ask\"\n ? {\n blockedReason:\n \"Permission 'ask' is not supported by the V2 plugin API yet.\",\n }\n : {}),\n context: analyzeContextTokens(state, messages),\n stats: await buildStatsReport(state, logger),\n }\n }),\n manual: ({ sessionID, enabled }) =>\n serial(sessionID, async () => {\n const { state } = await load(sessionID)\n state.manualMode = enabled ? \"active\" : false\n await saveSessionState(state, logger)\n return {}\n }),\n })\n logger.info(\"DCP V2 initialized\")\n return () => {\n sessions.clear()\n limits.clear()\n }\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport { parse } from \"jsonc-parser/lib/esm/main.js\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype ConfigContext = Pick<PluginInput, \"directory\"> & {\n client: {\n tui: {\n showToast(input: {\n body: { title: string; message: string; variant: \"warning\"; duration: number }\n }): unknown\n }\n }\n}\n\ntype Permission = \"ask\" | \"allow\" | \"deny\"\n\nexport interface Deduplication {\n enabled: boolean\n protectedTools: string[]\n}\n\nexport interface CompressConfig {\n permission: Permission\n showCompression: boolean\n summaryBuffer: boolean\n maxContextLimit: number | `${number}%`\n minContextLimit: number | `${number}%`\n modelMaxLimits?: Record<string, number | `${number}%`>\n modelMinLimits?: Record<string, number | `${number}%`>\n nudgeFrequency: number\n iterationNudgeThreshold: number\n nudgeForce: \"strong\" | \"soft\"\n protectedTools: string[]\n protectTags: boolean\n protectUserMessages: boolean\n}\n\nexport interface Commands {\n enabled: boolean\n protectedTools: string[]\n}\n\nexport interface ManualModeConfig {\n enabled: boolean\n automaticStrategies: boolean\n}\n\nexport interface PurgeErrors {\n enabled: boolean\n turns: number\n protectedTools: string[]\n}\n\nexport interface TurnProtection {\n enabled: boolean\n turns: number\n}\n\nexport interface ExperimentalConfig {\n allowSubAgents: boolean\n customPrompts: boolean\n}\n\nexport interface PluginConfig {\n enabled: boolean\n debug: boolean\n pruneNotification: \"off\" | \"minimal\" | \"detailed\"\n pruneNotificationType: \"chat\" | \"toast\"\n commands: Commands\n manualMode: ManualModeConfig\n turnProtection: TurnProtection\n experimental: ExperimentalConfig\n protectedFilePatterns: string[]\n compress: CompressConfig\n strategies: {\n deduplication: Deduplication\n purgeErrors: PurgeErrors\n }\n}\n\ntype CompressOverride = Partial<CompressConfig>\n\nconst DEFAULT_PROTECTED_TOOLS = [\n \"task\",\n \"skill\",\n \"todowrite\",\n \"todoread\",\n \"compress\",\n \"batch\",\n \"plan_enter\",\n \"plan_exit\",\n \"write\",\n \"edit\",\n]\n\nconst COMPRESS_DEFAULT_PROTECTED_TOOLS = [\"task\", \"skill\", \"todowrite\", \"todoread\"]\n\nexport const VALID_CONFIG_KEYS = new Set([\n \"$schema\",\n \"enabled\",\n \"debug\",\n \"showUpdateToasts\",\n \"pruneNotification\",\n \"pruneNotificationType\",\n \"turnProtection\",\n \"turnProtection.enabled\",\n \"turnProtection.turns\",\n \"experimental\",\n \"experimental.allowSubAgents\",\n \"experimental.customPrompts\",\n \"protectedFilePatterns\",\n \"commands\",\n \"commands.enabled\",\n \"commands.protectedTools\",\n \"manualMode\",\n \"manualMode.enabled\",\n \"manualMode.automaticStrategies\",\n \"compress\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.modelMaxLimits\",\n \"compress.modelMinLimits\",\n \"compress.nudgeFrequency\",\n \"compress.iterationNudgeThreshold\",\n \"compress.nudgeForce\",\n \"compress.protectedTools\",\n \"compress.protectTags\",\n \"compress.protectUserMessages\",\n \"strategies\",\n \"strategies.deduplication\",\n \"strategies.deduplication.enabled\",\n \"strategies.deduplication.protectedTools\",\n \"strategies.purgeErrors\",\n \"strategies.purgeErrors.enabled\",\n \"strategies.purgeErrors.turns\",\n \"strategies.purgeErrors.protectedTools\",\n])\n\nfunction getConfigKeyPaths(obj: Record<string, any>, prefix = \"\"): string[] {\n const keys: string[] = []\n for (const key of Object.keys(obj)) {\n const fullKey = prefix ? `${prefix}.${key}` : key\n keys.push(fullKey)\n\n // model*Limits are dynamic maps keyed by providerID/modelID; do not recurse into arbitrary IDs.\n if (fullKey === \"compress.modelMaxLimits\" || fullKey === \"compress.modelMinLimits\") {\n continue\n }\n\n if (obj[key] && typeof obj[key] === \"object\" && !Array.isArray(obj[key])) {\n keys.push(...getConfigKeyPaths(obj[key], fullKey))\n }\n }\n return keys\n}\n\nexport function getInvalidConfigKeys(userConfig: Record<string, any>): string[] {\n const userKeys = getConfigKeyPaths(userConfig)\n return userKeys.filter((key) => !VALID_CONFIG_KEYS.has(key))\n}\n\ninterface ValidationError {\n key: string\n expected: string\n actual: string\n}\n\nexport function validateConfigTypes(config: Record<string, any>): ValidationError[] {\n const errors: ValidationError[] = []\n\n if (config.enabled !== undefined && typeof config.enabled !== \"boolean\") {\n errors.push({ key: \"enabled\", expected: \"boolean\", actual: typeof config.enabled })\n }\n\n if (config.debug !== undefined && typeof config.debug !== \"boolean\") {\n errors.push({ key: \"debug\", expected: \"boolean\", actual: typeof config.debug })\n }\n\n if (config.pruneNotification !== undefined) {\n const validValues = [\"off\", \"minimal\", \"detailed\"]\n if (!validValues.includes(config.pruneNotification)) {\n errors.push({\n key: \"pruneNotification\",\n expected: '\"off\" | \"minimal\" | \"detailed\"',\n actual: JSON.stringify(config.pruneNotification),\n })\n }\n }\n\n if (config.pruneNotificationType !== undefined) {\n const validValues = [\"chat\", \"toast\"]\n if (!validValues.includes(config.pruneNotificationType)) {\n errors.push({\n key: \"pruneNotificationType\",\n expected: '\"chat\" | \"toast\"',\n actual: JSON.stringify(config.pruneNotificationType),\n })\n }\n }\n\n if (config.protectedFilePatterns !== undefined) {\n if (!Array.isArray(config.protectedFilePatterns)) {\n errors.push({\n key: \"protectedFilePatterns\",\n expected: \"string[]\",\n actual: typeof config.protectedFilePatterns,\n })\n } else if (!config.protectedFilePatterns.every((v: unknown) => typeof v === \"string\")) {\n errors.push({\n key: \"protectedFilePatterns\",\n expected: \"string[]\",\n actual: \"non-string entries\",\n })\n }\n }\n\n if (config.turnProtection) {\n if (\n config.turnProtection.enabled !== undefined &&\n typeof config.turnProtection.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"turnProtection.enabled\",\n expected: \"boolean\",\n actual: typeof config.turnProtection.enabled,\n })\n }\n\n if (\n config.turnProtection.turns !== undefined &&\n typeof config.turnProtection.turns !== \"number\"\n ) {\n errors.push({\n key: \"turnProtection.turns\",\n expected: \"number\",\n actual: typeof config.turnProtection.turns,\n })\n }\n if (typeof config.turnProtection.turns === \"number\" && config.turnProtection.turns < 1) {\n errors.push({\n key: \"turnProtection.turns\",\n expected: \"positive number (>= 1)\",\n actual: `${config.turnProtection.turns}`,\n })\n }\n }\n\n const experimental = config.experimental\n if (experimental !== undefined) {\n if (\n typeof experimental !== \"object\" ||\n experimental === null ||\n Array.isArray(experimental)\n ) {\n errors.push({\n key: \"experimental\",\n expected: \"object\",\n actual: typeof experimental,\n })\n } else {\n if (\n experimental.allowSubAgents !== undefined &&\n typeof experimental.allowSubAgents !== \"boolean\"\n ) {\n errors.push({\n key: \"experimental.allowSubAgents\",\n expected: \"boolean\",\n actual: typeof experimental.allowSubAgents,\n })\n }\n\n if (\n experimental.customPrompts !== undefined &&\n typeof experimental.customPrompts !== \"boolean\"\n ) {\n errors.push({\n key: \"experimental.customPrompts\",\n expected: \"boolean\",\n actual: typeof experimental.customPrompts,\n })\n }\n }\n }\n\n const commands = config.commands\n if (commands !== undefined) {\n if (typeof commands !== \"object\" || commands === null || Array.isArray(commands)) {\n errors.push({\n key: \"commands\",\n expected: \"object\",\n actual: typeof commands,\n })\n } else {\n if (commands.enabled !== undefined && typeof commands.enabled !== \"boolean\") {\n errors.push({\n key: \"commands.enabled\",\n expected: \"boolean\",\n actual: typeof commands.enabled,\n })\n }\n if (commands.protectedTools !== undefined && !Array.isArray(commands.protectedTools)) {\n errors.push({\n key: \"commands.protectedTools\",\n expected: \"string[]\",\n actual: typeof commands.protectedTools,\n })\n }\n }\n }\n\n const manualMode = config.manualMode\n if (manualMode !== undefined) {\n if (typeof manualMode !== \"object\" || manualMode === null || Array.isArray(manualMode)) {\n errors.push({\n key: \"manualMode\",\n expected: \"object\",\n actual: typeof manualMode,\n })\n } else {\n if (manualMode.enabled !== undefined && typeof manualMode.enabled !== \"boolean\") {\n errors.push({\n key: \"manualMode.enabled\",\n expected: \"boolean\",\n actual: typeof manualMode.enabled,\n })\n }\n\n if (\n manualMode.automaticStrategies !== undefined &&\n typeof manualMode.automaticStrategies !== \"boolean\"\n ) {\n errors.push({\n key: \"manualMode.automaticStrategies\",\n expected: \"boolean\",\n actual: typeof manualMode.automaticStrategies,\n })\n }\n }\n }\n\n const compress = config.compress\n if (compress !== undefined) {\n if (typeof compress !== \"object\" || compress === null || Array.isArray(compress)) {\n errors.push({\n key: \"compress\",\n expected: \"object\",\n actual: typeof compress,\n })\n } else {\n if (\n compress.summaryBuffer !== undefined &&\n typeof compress.summaryBuffer !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.summaryBuffer\",\n expected: \"boolean\",\n actual: typeof compress.summaryBuffer,\n })\n }\n\n if (\n compress.nudgeFrequency !== undefined &&\n typeof compress.nudgeFrequency !== \"number\"\n ) {\n errors.push({\n key: \"compress.nudgeFrequency\",\n expected: \"number\",\n actual: typeof compress.nudgeFrequency,\n })\n }\n\n if (typeof compress.nudgeFrequency === \"number\" && compress.nudgeFrequency < 1) {\n errors.push({\n key: \"compress.nudgeFrequency\",\n expected: \"positive number (>= 1)\",\n actual: `${compress.nudgeFrequency} (will be clamped to 1)`,\n })\n }\n\n if (\n compress.iterationNudgeThreshold !== undefined &&\n typeof compress.iterationNudgeThreshold !== \"number\"\n ) {\n errors.push({\n key: \"compress.iterationNudgeThreshold\",\n expected: \"number\",\n actual: typeof compress.iterationNudgeThreshold,\n })\n }\n\n if (\n compress.nudgeForce !== undefined &&\n compress.nudgeForce !== \"strong\" &&\n compress.nudgeForce !== \"soft\"\n ) {\n errors.push({\n key: \"compress.nudgeForce\",\n expected: '\"strong\" | \"soft\"',\n actual: JSON.stringify(compress.nudgeForce),\n })\n }\n\n if (compress.protectedTools !== undefined && !Array.isArray(compress.protectedTools)) {\n errors.push({\n key: \"compress.protectedTools\",\n expected: \"string[]\",\n actual: typeof compress.protectedTools,\n })\n }\n\n if (compress.protectTags !== undefined && typeof compress.protectTags !== \"boolean\") {\n errors.push({\n key: \"compress.protectTags\",\n expected: \"boolean\",\n actual: typeof compress.protectTags,\n })\n }\n\n if (\n compress.protectUserMessages !== undefined &&\n typeof compress.protectUserMessages !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.protectUserMessages\",\n expected: \"boolean\",\n actual: typeof compress.protectUserMessages,\n })\n }\n\n if (\n typeof compress.iterationNudgeThreshold === \"number\" &&\n compress.iterationNudgeThreshold < 1\n ) {\n errors.push({\n key: \"compress.iterationNudgeThreshold\",\n expected: \"positive number (>= 1)\",\n actual: `${compress.iterationNudgeThreshold} (will be clamped to 1)`,\n })\n }\n\n const validateLimitValue = (\n key: string,\n value: unknown,\n actualValue: unknown = value,\n ): void => {\n const isValidNumber = typeof value === \"number\"\n const isPercentString = typeof value === \"string\" && value.endsWith(\"%\")\n\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key,\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(actualValue),\n })\n }\n }\n\n const validateModelLimits = (\n key: \"compress.modelMaxLimits\" | \"compress.modelMinLimits\",\n limits: unknown,\n ): void => {\n if (limits === undefined) {\n return\n }\n\n if (typeof limits !== \"object\" || limits === null || Array.isArray(limits)) {\n errors.push({\n key,\n expected: \"Record<string, number | ${number}%>\",\n actual: typeof limits,\n })\n return\n }\n\n for (const [providerModelKey, limit] of Object.entries(limits)) {\n const isValidNumber = typeof limit === \"number\"\n const isPercentString =\n typeof limit === \"string\" && /^\\d+(?:\\.\\d+)?%$/.test(limit)\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key: `${key}.${providerModelKey}`,\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(limit),\n })\n }\n }\n }\n\n if (compress.maxContextLimit !== undefined) {\n validateLimitValue(\"compress.maxContextLimit\", compress.maxContextLimit)\n }\n\n if (compress.minContextLimit !== undefined) {\n validateLimitValue(\"compress.minContextLimit\", compress.minContextLimit)\n }\n\n validateModelLimits(\"compress.modelMaxLimits\", compress.modelMaxLimits)\n validateModelLimits(\"compress.modelMinLimits\", compress.modelMinLimits)\n\n const validValues = [\"ask\", \"allow\", \"deny\"]\n if (compress.permission !== undefined && !validValues.includes(compress.permission)) {\n errors.push({\n key: \"compress.permission\",\n expected: '\"ask\" | \"allow\" | \"deny\"',\n actual: JSON.stringify(compress.permission),\n })\n }\n\n if (\n compress.showCompression !== undefined &&\n typeof compress.showCompression !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.showCompression\",\n expected: \"boolean\",\n actual: typeof compress.showCompression,\n })\n }\n }\n }\n\n const strategies = config.strategies\n if (strategies) {\n if (\n strategies.deduplication?.enabled !== undefined &&\n typeof strategies.deduplication.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.deduplication.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.deduplication.enabled,\n })\n }\n\n if (\n strategies.deduplication?.protectedTools !== undefined &&\n !Array.isArray(strategies.deduplication.protectedTools)\n ) {\n errors.push({\n key: \"strategies.deduplication.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.deduplication.protectedTools,\n })\n }\n\n if (strategies.purgeErrors) {\n if (\n strategies.purgeErrors.enabled !== undefined &&\n typeof strategies.purgeErrors.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.purgeErrors.enabled,\n })\n }\n\n if (\n strategies.purgeErrors.turns !== undefined &&\n typeof strategies.purgeErrors.turns !== \"number\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"number\",\n actual: typeof strategies.purgeErrors.turns,\n })\n }\n // Warn if turns is 0 or negative - will be clamped to 1\n if (\n typeof strategies.purgeErrors.turns === \"number\" &&\n strategies.purgeErrors.turns < 1\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"positive number (>= 1)\",\n actual: `${strategies.purgeErrors.turns} (will be clamped to 1)`,\n })\n }\n if (\n strategies.purgeErrors.protectedTools !== undefined &&\n !Array.isArray(strategies.purgeErrors.protectedTools)\n ) {\n errors.push({\n key: \"strategies.purgeErrors.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.purgeErrors.protectedTools,\n })\n }\n }\n }\n\n return errors\n}\n\nfunction showConfigWarnings(\n ctx: ConfigContext,\n configPath: string,\n configData: Record<string, any>,\n isProject: boolean,\n): void {\n const invalidKeys = getInvalidConfigKeys(configData)\n const typeErrors = validateConfigTypes(configData)\n\n if (invalidKeys.length === 0 && typeErrors.length === 0) {\n return\n }\n\n const configType = isProject ? \"project config\" : \"config\"\n const messages: string[] = []\n\n if (invalidKeys.length > 0) {\n const keyList = invalidKeys.slice(0, 3).join(\", \")\n const suffix = invalidKeys.length > 3 ? ` (+${invalidKeys.length - 3} more)` : \"\"\n messages.push(`Unknown keys: ${keyList}${suffix}`)\n }\n\n if (typeErrors.length > 0) {\n for (const err of typeErrors.slice(0, 2)) {\n messages.push(`${err.key}: expected ${err.expected}, got ${err.actual}`)\n }\n if (typeErrors.length > 2) {\n messages.push(`(+${typeErrors.length - 2} more type errors)`)\n }\n }\n\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title: `DCP: ${configType} warning`,\n message: `${configPath}\\n${messages.join(\"\\n\")}`,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nconst defaultConfig: PluginConfig = {\n enabled: true,\n debug: false,\n pruneNotification: \"off\",\n pruneNotificationType: \"chat\",\n commands: {\n enabled: true,\n protectedTools: [...DEFAULT_PROTECTED_TOOLS],\n },\n manualMode: {\n enabled: false,\n automaticStrategies: true,\n },\n turnProtection: {\n enabled: false,\n turns: 4,\n },\n experimental: {\n allowSubAgents: false,\n customPrompts: false,\n },\n protectedFilePatterns: [],\n compress: {\n permission: \"allow\",\n showCompression: false,\n summaryBuffer: true,\n maxContextLimit: 100000,\n minContextLimit: 50000,\n nudgeFrequency: 5,\n iterationNudgeThreshold: 15,\n nudgeForce: \"soft\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n },\n strategies: {\n deduplication: {\n enabled: true,\n protectedTools: [],\n },\n purgeErrors: {\n enabled: true,\n turns: 4,\n protectedTools: [],\n },\n },\n}\n\nconst GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, \"opencode\")\n : join(homedir(), \".config\", \"opencode\")\nconst GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp-rc.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp-rc.json\")\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate) && statSync(candidate).isDirectory()) {\n return candidate\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction getConfigPaths(ctx?: ConfigContext): {\n global: string | null\n configDir: string | null\n project: string | null\n} {\n const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)\n ? GLOBAL_CONFIG_PATH_JSONC\n : existsSync(GLOBAL_CONFIG_PATH_JSON)\n ? GLOBAL_CONFIG_PATH_JSON\n : null\n\n let configDir: string | null = null\n const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR\n if (opencodeConfigDir) {\n const configJsonc = join(opencodeConfigDir, \"dcp-rc.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp-rc.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : null\n }\n\n let project: string | null = null\n if (ctx?.directory) {\n const opencodeDir = findOpencodeDir(ctx.directory)\n if (opencodeDir) {\n const projectJsonc = join(opencodeDir, \"dcp-rc.jsonc\")\n const projectJson = join(opencodeDir, \"dcp-rc.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : null\n }\n }\n\n return { global, configDir, project }\n}\n\nfunction createDefaultConfig(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n\n const configContent = `{\n // DCP-RC fork configuration.\n // Summaries are generated automatically after the model selects IDs\n // (compress tool), and pruneNotification = \"off\" keeps the plugin's\n // internals hidden; only the compress tool call is visible.\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n}\n\ninterface ConfigLoadResult {\n data: Record<string, any> | null\n parseError?: string\n}\n\nfunction loadConfigFile(configPath: string): ConfigLoadResult {\n let fileContent = \"\"\n try {\n fileContent = readFileSync(configPath, \"utf-8\")\n } catch {\n return { data: null }\n }\n\n try {\n const parsed = parse(fileContent, undefined, { allowTrailingComma: true })\n if (parsed === undefined || parsed === null) {\n return { data: null, parseError: \"Config file is empty or invalid\" }\n }\n return { data: parsed }\n } catch (error: any) {\n return { data: null, parseError: error.message || \"Failed to parse config\" }\n }\n}\n\nfunction mergeStrategies(\n base: PluginConfig[\"strategies\"],\n override?: Partial<PluginConfig[\"strategies\"]>,\n): PluginConfig[\"strategies\"] {\n if (!override) {\n return base\n }\n\n return {\n deduplication: {\n enabled: override.deduplication?.enabled ?? base.deduplication.enabled,\n protectedTools: [\n ...new Set([\n ...base.deduplication.protectedTools,\n ...(override.deduplication?.protectedTools ?? []),\n ]),\n ],\n },\n purgeErrors: {\n enabled: override.purgeErrors?.enabled ?? base.purgeErrors.enabled,\n turns: override.purgeErrors?.turns ?? base.purgeErrors.turns,\n protectedTools: [\n ...new Set([\n ...base.purgeErrors.protectedTools,\n ...(override.purgeErrors?.protectedTools ?? []),\n ]),\n ],\n },\n }\n}\n\nfunction mergeCompress(\n base: PluginConfig[\"compress\"],\n override?: CompressOverride,\n): PluginConfig[\"compress\"] {\n if (!override) {\n return base\n }\n\n return {\n permission: override.permission ?? base.permission,\n showCompression: override.showCompression ?? base.showCompression,\n summaryBuffer: override.summaryBuffer ?? base.summaryBuffer,\n maxContextLimit: override.maxContextLimit ?? base.maxContextLimit,\n minContextLimit: override.minContextLimit ?? base.minContextLimit,\n modelMaxLimits: override.modelMaxLimits ?? base.modelMaxLimits,\n modelMinLimits: override.modelMinLimits ?? base.modelMinLimits,\n nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,\n iterationNudgeThreshold: override.iterationNudgeThreshold ?? base.iterationNudgeThreshold,\n nudgeForce: override.nudgeForce ?? base.nudgeForce,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n protectTags: override.protectTags ?? base.protectTags,\n protectUserMessages: override.protectUserMessages ?? base.protectUserMessages,\n }\n}\n\nfunction mergeCommands(\n base: PluginConfig[\"commands\"],\n override?: Partial<PluginConfig[\"commands\"]>,\n): PluginConfig[\"commands\"] {\n if (!override) {\n return base\n }\n\n return {\n enabled: override.enabled ?? base.enabled,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n }\n}\n\nfunction mergeManualMode(\n base: PluginConfig[\"manualMode\"],\n override?: Partial<PluginConfig[\"manualMode\"]>,\n): PluginConfig[\"manualMode\"] {\n if (override === undefined) return base\n\n return {\n enabled: override.enabled ?? base.enabled,\n automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (override === undefined) return base\n\n return {\n allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,\n customPrompts: override.customPrompts ?? base.customPrompts,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: {\n enabled: config.commands.enabled,\n protectedTools: [...config.commands.protectedTools],\n },\n manualMode: {\n enabled: config.manualMode.enabled,\n automaticStrategies: config.manualMode.automaticStrategies,\n },\n turnProtection: { ...config.turnProtection },\n experimental: { ...config.experimental },\n protectedFilePatterns: [...config.protectedFilePatterns],\n compress: {\n ...config.compress,\n modelMaxLimits: { ...config.compress.modelMaxLimits },\n modelMinLimits: { ...config.compress.modelMinLimits },\n protectedTools: [...config.compress.protectedTools],\n },\n strategies: {\n deduplication: {\n ...config.strategies.deduplication,\n protectedTools: [...config.strategies.deduplication.protectedTools],\n },\n purgeErrors: {\n ...config.strategies.purgeErrors,\n protectedTools: [...config.strategies.purgeErrors.protectedTools],\n },\n },\n }\n}\n\nfunction mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConfig {\n return {\n enabled: data.enabled ?? config.enabled,\n debug: data.debug ?? config.debug,\n pruneNotification: data.pruneNotification ?? config.pruneNotification,\n pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,\n commands: mergeCommands(config.commands, data.commands as any),\n manualMode: mergeManualMode(config.manualMode, data.manualMode as any),\n turnProtection: {\n enabled: data.turnProtection?.enabled ?? config.turnProtection.enabled,\n turns: data.turnProtection?.turns ?? config.turnProtection.turns,\n },\n experimental: mergeExperimental(config.experimental, data.experimental as any),\n protectedFilePatterns: [\n ...new Set([...config.protectedFilePatterns, ...(data.protectedFilePatterns ?? [])]),\n ],\n compress: mergeCompress(config.compress, data.compress as CompressOverride),\n strategies: mergeStrategies(config.strategies, data.strategies as any),\n }\n}\n\nfunction scheduleParseWarning(ctx: ConfigContext, title: string, message: string): void {\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title,\n message,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nexport function getConfig(ctx: ConfigContext): PluginConfig {\n let config = deepCloneConfig(defaultConfig)\n const configPaths = getConfigPaths(ctx)\n\n if (!configPaths.global) {\n createDefaultConfig()\n }\n\n const layers: Array<{ path: string | null; name: string; isProject: boolean }> = [\n { path: configPaths.global, name: \"config\", isProject: false },\n { path: configPaths.configDir, name: \"configDir config\", isProject: true },\n { path: configPaths.project, name: \"project config\", isProject: true },\n ]\n\n for (const layer of layers) {\n if (!layer.path) {\n continue\n }\n\n const result = loadConfigFile(layer.path)\n if (result.parseError) {\n scheduleParseWarning(\n ctx,\n `DCP: Invalid ${layer.name}`,\n `${layer.path}\\n${result.parseError}\\nUsing previous/default values`,\n )\n continue\n }\n\n if (!result.data) {\n continue\n }\n\n showConfigWarnings(ctx, layer.path, result.data, layer.isProject)\n config = mergeLayer(config, result.data)\n }\n\n return config\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport function createScanner(text, ignoreTrivia = false) {\n const len = text.length;\n let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;\n function scanHexDigits(count, exact) {\n let digits = 0;\n let value = 0;\n while (digits < count || !exact) {\n let ch = text.charCodeAt(pos);\n if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {\n value = value * 16 + ch - 48 /* CharacterCodes._0 */;\n }\n else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {\n value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;\n }\n else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {\n value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;\n }\n else {\n break;\n }\n pos++;\n digits++;\n }\n if (digits < count) {\n value = -1;\n }\n return value;\n }\n function setPosition(newPosition) {\n pos = newPosition;\n value = '';\n tokenOffset = 0;\n token = 16 /* SyntaxKind.Unknown */;\n scanError = 0 /* ScanError.None */;\n }\n function scanNumber() {\n let start = pos;\n if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {\n pos++;\n }\n else {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {\n pos++;\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n return text.substring(start, pos);\n }\n }\n let end = pos;\n if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {\n pos++;\n if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) {\n pos++;\n }\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n end = pos;\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n }\n }\n return text.substring(start, end);\n }\n function scanString() {\n let result = '', start = pos;\n while (true) {\n if (pos >= len) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch = text.charCodeAt(pos);\n if (ch === 34 /* CharacterCodes.doubleQuote */) {\n result += text.substring(start, pos);\n pos++;\n break;\n }\n if (ch === 92 /* CharacterCodes.backslash */) {\n result += text.substring(start, pos);\n pos++;\n if (pos >= len) {\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch2 = text.charCodeAt(pos++);\n switch (ch2) {\n case 34 /* CharacterCodes.doubleQuote */:\n result += '\\\"';\n break;\n case 92 /* CharacterCodes.backslash */:\n result += '\\\\';\n break;\n case 47 /* CharacterCodes.slash */:\n result += '/';\n break;\n case 98 /* CharacterCodes.b */:\n result += '\\b';\n break;\n case 102 /* CharacterCodes.f */:\n result += '\\f';\n break;\n case 110 /* CharacterCodes.n */:\n result += '\\n';\n break;\n case 114 /* CharacterCodes.r */:\n result += '\\r';\n break;\n case 116 /* CharacterCodes.t */:\n result += '\\t';\n break;\n case 117 /* CharacterCodes.u */:\n const ch3 = scanHexDigits(4, true);\n if (ch3 >= 0) {\n result += String.fromCharCode(ch3);\n }\n else {\n scanError = 4 /* ScanError.InvalidUnicode */;\n }\n break;\n default:\n scanError = 5 /* ScanError.InvalidEscapeCharacter */;\n }\n start = pos;\n continue;\n }\n if (ch >= 0 && ch <= 0x1f) {\n if (isLineBreak(ch)) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n else {\n scanError = 6 /* ScanError.InvalidCharacter */;\n // mark as error but continue with string\n }\n }\n pos++;\n }\n return result;\n }\n function scanNext() {\n value = '';\n scanError = 0 /* ScanError.None */;\n tokenOffset = pos;\n lineStartOffset = lineNumber;\n prevTokenLineStartOffset = tokenLineStartOffset;\n if (pos >= len) {\n // at the end\n tokenOffset = len;\n return token = 17 /* SyntaxKind.EOF */;\n }\n let code = text.charCodeAt(pos);\n // trivia: whitespace\n if (isWhiteSpace(code)) {\n do {\n pos++;\n value += String.fromCharCode(code);\n code = text.charCodeAt(pos);\n } while (isWhiteSpace(code));\n return token = 15 /* SyntaxKind.Trivia */;\n }\n // trivia: newlines\n if (isLineBreak(code)) {\n pos++;\n value += String.fromCharCode(code);\n if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n value += '\\n';\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n return token = 14 /* SyntaxKind.LineBreakTrivia */;\n }\n switch (code) {\n // tokens: []{}:,\n case 123 /* CharacterCodes.openBrace */:\n pos++;\n return token = 1 /* SyntaxKind.OpenBraceToken */;\n case 125 /* CharacterCodes.closeBrace */:\n pos++;\n return token = 2 /* SyntaxKind.CloseBraceToken */;\n case 91 /* CharacterCodes.openBracket */:\n pos++;\n return token = 3 /* SyntaxKind.OpenBracketToken */;\n case 93 /* CharacterCodes.closeBracket */:\n pos++;\n return token = 4 /* SyntaxKind.CloseBracketToken */;\n case 58 /* CharacterCodes.colon */:\n pos++;\n return token = 6 /* SyntaxKind.ColonToken */;\n case 44 /* CharacterCodes.comma */:\n pos++;\n return token = 5 /* SyntaxKind.CommaToken */;\n // strings\n case 34 /* CharacterCodes.doubleQuote */:\n pos++;\n value = scanString();\n return token = 10 /* SyntaxKind.StringLiteral */;\n // comments\n case 47 /* CharacterCodes.slash */:\n const start = pos - 1;\n // Single-line comment\n if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n while (pos < len) {\n if (isLineBreak(text.charCodeAt(pos))) {\n break;\n }\n pos++;\n }\n value = text.substring(start, pos);\n return token = 12 /* SyntaxKind.LineCommentTrivia */;\n }\n // Multi-line comment\n if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {\n pos += 2;\n const safeLength = len - 1; // For lookahead.\n let commentClosed = false;\n while (pos < safeLength) {\n const ch = text.charCodeAt(pos);\n if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n commentClosed = true;\n break;\n }\n pos++;\n if (isLineBreak(ch)) {\n if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n }\n }\n if (!commentClosed) {\n pos++;\n scanError = 1 /* ScanError.UnexpectedEndOfComment */;\n }\n value = text.substring(start, pos);\n return token = 13 /* SyntaxKind.BlockCommentTrivia */;\n }\n // just a single slash\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n // numbers\n case 45 /* CharacterCodes.minus */:\n value += String.fromCharCode(code);\n pos++;\n if (pos === len || !isDigit(text.charCodeAt(pos))) {\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // found a minus, followed by a number so\n // we fall through to proceed with scanning\n // numbers\n case 48 /* CharacterCodes._0 */:\n case 49 /* CharacterCodes._1 */:\n case 50 /* CharacterCodes._2 */:\n case 51 /* CharacterCodes._3 */:\n case 52 /* CharacterCodes._4 */:\n case 53 /* CharacterCodes._5 */:\n case 54 /* CharacterCodes._6 */:\n case 55 /* CharacterCodes._7 */:\n case 56 /* CharacterCodes._8 */:\n case 57 /* CharacterCodes._9 */:\n value += scanNumber();\n return token = 11 /* SyntaxKind.NumericLiteral */;\n // literals and unknown symbols\n default:\n // is a literal? Read the full word.\n while (pos < len && isUnknownContentCharacter(code)) {\n pos++;\n code = text.charCodeAt(pos);\n }\n if (tokenOffset !== pos) {\n value = text.substring(tokenOffset, pos);\n // keywords: true, false, null\n switch (value) {\n case 'true': return token = 8 /* SyntaxKind.TrueKeyword */;\n case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;\n case 'null': return token = 7 /* SyntaxKind.NullKeyword */;\n }\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // some\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n }\n }\n function isUnknownContentCharacter(code) {\n if (isWhiteSpace(code) || isLineBreak(code)) {\n return false;\n }\n switch (code) {\n case 125 /* CharacterCodes.closeBrace */:\n case 93 /* CharacterCodes.closeBracket */:\n case 123 /* CharacterCodes.openBrace */:\n case 91 /* CharacterCodes.openBracket */:\n case 34 /* CharacterCodes.doubleQuote */:\n case 58 /* CharacterCodes.colon */:\n case 44 /* CharacterCodes.comma */:\n case 47 /* CharacterCodes.slash */:\n return false;\n }\n return true;\n }\n function scanNextNonTrivia() {\n let result;\n do {\n result = scanNext();\n } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);\n return result;\n }\n return {\n setPosition: setPosition,\n getPosition: () => pos,\n scan: ignoreTrivia ? scanNextNonTrivia : scanNext,\n getToken: () => token,\n getTokenValue: () => value,\n getTokenOffset: () => tokenOffset,\n getTokenLength: () => pos - tokenOffset,\n getTokenStartLine: () => lineStartOffset,\n getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,\n getTokenError: () => scanError,\n };\n}\nfunction isWhiteSpace(ch) {\n return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;\n}\nfunction isLineBreak(ch) {\n return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;\n}\nfunction isDigit(ch) {\n return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;\n}\nvar CharacterCodes;\n(function (CharacterCodes) {\n CharacterCodes[CharacterCodes[\"lineFeed\"] = 10] = \"lineFeed\";\n CharacterCodes[CharacterCodes[\"carriageReturn\"] = 13] = \"carriageReturn\";\n CharacterCodes[CharacterCodes[\"space\"] = 32] = \"space\";\n CharacterCodes[CharacterCodes[\"_0\"] = 48] = \"_0\";\n CharacterCodes[CharacterCodes[\"_1\"] = 49] = \"_1\";\n CharacterCodes[CharacterCodes[\"_2\"] = 50] = \"_2\";\n CharacterCodes[CharacterCodes[\"_3\"] = 51] = \"_3\";\n CharacterCodes[CharacterCodes[\"_4\"] = 52] = \"_4\";\n CharacterCodes[CharacterCodes[\"_5\"] = 53] = \"_5\";\n CharacterCodes[CharacterCodes[\"_6\"] = 54] = \"_6\";\n CharacterCodes[CharacterCodes[\"_7\"] = 55] = \"_7\";\n CharacterCodes[CharacterCodes[\"_8\"] = 56] = \"_8\";\n CharacterCodes[CharacterCodes[\"_9\"] = 57] = \"_9\";\n CharacterCodes[CharacterCodes[\"a\"] = 97] = \"a\";\n CharacterCodes[CharacterCodes[\"b\"] = 98] = \"b\";\n CharacterCodes[CharacterCodes[\"c\"] = 99] = \"c\";\n CharacterCodes[CharacterCodes[\"d\"] = 100] = \"d\";\n CharacterCodes[CharacterCodes[\"e\"] = 101] = \"e\";\n CharacterCodes[CharacterCodes[\"f\"] = 102] = \"f\";\n CharacterCodes[CharacterCodes[\"g\"] = 103] = \"g\";\n CharacterCodes[CharacterCodes[\"h\"] = 104] = \"h\";\n CharacterCodes[CharacterCodes[\"i\"] = 105] = \"i\";\n CharacterCodes[CharacterCodes[\"j\"] = 106] = \"j\";\n CharacterCodes[CharacterCodes[\"k\"] = 107] = \"k\";\n CharacterCodes[CharacterCodes[\"l\"] = 108] = \"l\";\n CharacterCodes[CharacterCodes[\"m\"] = 109] = \"m\";\n CharacterCodes[CharacterCodes[\"n\"] = 110] = \"n\";\n CharacterCodes[CharacterCodes[\"o\"] = 111] = \"o\";\n CharacterCodes[CharacterCodes[\"p\"] = 112] = \"p\";\n CharacterCodes[CharacterCodes[\"q\"] = 113] = \"q\";\n CharacterCodes[CharacterCodes[\"r\"] = 114] = \"r\";\n CharacterCodes[CharacterCodes[\"s\"] = 115] = \"s\";\n CharacterCodes[CharacterCodes[\"t\"] = 116] = \"t\";\n CharacterCodes[CharacterCodes[\"u\"] = 117] = \"u\";\n CharacterCodes[CharacterCodes[\"v\"] = 118] = \"v\";\n CharacterCodes[CharacterCodes[\"w\"] = 119] = \"w\";\n CharacterCodes[CharacterCodes[\"x\"] = 120] = \"x\";\n CharacterCodes[CharacterCodes[\"y\"] = 121] = \"y\";\n CharacterCodes[CharacterCodes[\"z\"] = 122] = \"z\";\n CharacterCodes[CharacterCodes[\"A\"] = 65] = \"A\";\n CharacterCodes[CharacterCodes[\"B\"] = 66] = \"B\";\n CharacterCodes[CharacterCodes[\"C\"] = 67] = \"C\";\n CharacterCodes[CharacterCodes[\"D\"] = 68] = \"D\";\n CharacterCodes[CharacterCodes[\"E\"] = 69] = \"E\";\n CharacterCodes[CharacterCodes[\"F\"] = 70] = \"F\";\n CharacterCodes[CharacterCodes[\"G\"] = 71] = \"G\";\n CharacterCodes[CharacterCodes[\"H\"] = 72] = \"H\";\n CharacterCodes[CharacterCodes[\"I\"] = 73] = \"I\";\n CharacterCodes[CharacterCodes[\"J\"] = 74] = \"J\";\n CharacterCodes[CharacterCodes[\"K\"] = 75] = \"K\";\n CharacterCodes[CharacterCodes[\"L\"] = 76] = \"L\";\n CharacterCodes[CharacterCodes[\"M\"] = 77] = \"M\";\n CharacterCodes[CharacterCodes[\"N\"] = 78] = \"N\";\n CharacterCodes[CharacterCodes[\"O\"] = 79] = \"O\";\n CharacterCodes[CharacterCodes[\"P\"] = 80] = \"P\";\n CharacterCodes[CharacterCodes[\"Q\"] = 81] = \"Q\";\n CharacterCodes[CharacterCodes[\"R\"] = 82] = \"R\";\n CharacterCodes[CharacterCodes[\"S\"] = 83] = \"S\";\n CharacterCodes[CharacterCodes[\"T\"] = 84] = \"T\";\n CharacterCodes[CharacterCodes[\"U\"] = 85] = \"U\";\n CharacterCodes[CharacterCodes[\"V\"] = 86] = \"V\";\n CharacterCodes[CharacterCodes[\"W\"] = 87] = \"W\";\n CharacterCodes[CharacterCodes[\"X\"] = 88] = \"X\";\n CharacterCodes[CharacterCodes[\"Y\"] = 89] = \"Y\";\n CharacterCodes[CharacterCodes[\"Z\"] = 90] = \"Z\";\n CharacterCodes[CharacterCodes[\"asterisk\"] = 42] = \"asterisk\";\n CharacterCodes[CharacterCodes[\"backslash\"] = 92] = \"backslash\";\n CharacterCodes[CharacterCodes[\"closeBrace\"] = 125] = \"closeBrace\";\n CharacterCodes[CharacterCodes[\"closeBracket\"] = 93] = \"closeBracket\";\n CharacterCodes[CharacterCodes[\"colon\"] = 58] = \"colon\";\n CharacterCodes[CharacterCodes[\"comma\"] = 44] = \"comma\";\n CharacterCodes[CharacterCodes[\"dot\"] = 46] = \"dot\";\n CharacterCodes[CharacterCodes[\"doubleQuote\"] = 34] = \"doubleQuote\";\n CharacterCodes[CharacterCodes[\"minus\"] = 45] = \"minus\";\n CharacterCodes[CharacterCodes[\"openBrace\"] = 123] = \"openBrace\";\n CharacterCodes[CharacterCodes[\"openBracket\"] = 91] = \"openBracket\";\n CharacterCodes[CharacterCodes[\"plus\"] = 43] = \"plus\";\n CharacterCodes[CharacterCodes[\"slash\"] = 47] = \"slash\";\n CharacterCodes[CharacterCodes[\"formFeed\"] = 12] = \"formFeed\";\n CharacterCodes[CharacterCodes[\"tab\"] = 9] = \"tab\";\n})(CharacterCodes || (CharacterCodes = {}));\n","export const cachedSpaces = new Array(20).fill(0).map((_, index) => {\n return ' '.repeat(index);\n});\nconst maxCachedValues = 200;\nexport const cachedBreakLinesWithSpaces = {\n ' ': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + ' '.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + ' '.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + ' '.repeat(index);\n }),\n },\n '\\t': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + '\\t'.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + '\\t'.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + '\\t'.repeat(index);\n }),\n }\n};\nexport const supportedEols = ['\\n', '\\r', '\\r\\n'];\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nvar ParseOptions;\n(function (ParseOptions) {\n ParseOptions.DEFAULT = {\n allowTrailingComma: false\n };\n})(ParseOptions || (ParseOptions = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport function getLocation(text, position) {\n const segments = []; // strings or numbers\n const earlyReturnException = new Object();\n let previousNode = undefined;\n const previousNodeInst = {\n value: {},\n offset: 0,\n length: 0,\n type: 'object',\n parent: undefined\n };\n let isAtPropertyKey = false;\n function setPreviousNode(value, offset, length, type) {\n previousNodeInst.value = value;\n previousNodeInst.offset = offset;\n previousNodeInst.length = length;\n previousNodeInst.type = type;\n previousNodeInst.colonOffset = undefined;\n previousNode = previousNodeInst;\n }\n try {\n visit(text, {\n onObjectBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n isAtPropertyKey = position > offset;\n segments.push(''); // push a placeholder (will be replaced)\n },\n onObjectProperty: (name, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(name, offset, length, 'property');\n segments[segments.length - 1] = name;\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onObjectEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onArrayBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.push(0);\n },\n onArrayEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onLiteralValue: (value, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(value, offset, length, getNodeType(value));\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onSeparator: (sep, offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n if (sep === ':' && previousNode && previousNode.type === 'property') {\n previousNode.colonOffset = offset;\n isAtPropertyKey = false;\n previousNode = undefined;\n }\n else if (sep === ',') {\n const last = segments[segments.length - 1];\n if (typeof last === 'number') {\n segments[segments.length - 1] = last + 1;\n }\n else {\n isAtPropertyKey = true;\n segments[segments.length - 1] = '';\n }\n previousNode = undefined;\n }\n }\n });\n }\n catch (e) {\n if (e !== earlyReturnException) {\n throw e;\n }\n }\n return {\n path: segments,\n previousNode,\n isAtPropertyKey,\n matches: (pattern) => {\n let k = 0;\n for (let i = 0; k < pattern.length && i < segments.length; i++) {\n if (pattern[k] === segments[i] || pattern[k] === '*') {\n k++;\n }\n else if (pattern[k] !== '**') {\n return false;\n }\n }\n return k === pattern.length;\n }\n };\n}\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore always check the errors list to find out if the input was valid.\n */\nexport function parse(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentProperty = null;\n let currentParent = [];\n const previousParents = [];\n function onValue(value) {\n if (Array.isArray(currentParent)) {\n currentParent.push(value);\n }\n else if (currentProperty !== null) {\n currentParent[currentProperty] = value;\n }\n }\n const visitor = {\n onObjectBegin: () => {\n const object = {};\n onValue(object);\n previousParents.push(currentParent);\n currentParent = object;\n currentProperty = null;\n },\n onObjectProperty: (name) => {\n currentProperty = name;\n },\n onObjectEnd: () => {\n currentParent = previousParents.pop();\n },\n onArrayBegin: () => {\n const array = [];\n onValue(array);\n previousParents.push(currentParent);\n currentParent = array;\n currentProperty = null;\n },\n onArrayEnd: () => {\n currentParent = previousParents.pop();\n },\n onLiteralValue: onValue,\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n return currentParent[0];\n}\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root\n function ensurePropertyComplete(endOffset) {\n if (currentParent.type === 'property') {\n currentParent.length = endOffset - currentParent.offset;\n currentParent = currentParent.parent;\n }\n }\n function onValue(valueNode) {\n currentParent.children.push(valueNode);\n return valueNode;\n }\n const visitor = {\n onObjectBegin: (offset) => {\n currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });\n },\n onObjectProperty: (name, offset, length) => {\n currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });\n currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent });\n },\n onObjectEnd: (offset, length) => {\n ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onArrayBegin: (offset, length) => {\n currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });\n },\n onArrayEnd: (offset, length) => {\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onLiteralValue: (value, offset, length) => {\n onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });\n ensurePropertyComplete(offset + length);\n },\n onSeparator: (sep, offset, length) => {\n if (currentParent.type === 'property') {\n if (sep === ':') {\n currentParent.colonOffset = offset;\n }\n else if (sep === ',') {\n ensurePropertyComplete(offset);\n }\n }\n },\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n const result = currentParent.children[0];\n if (result) {\n delete result.parent;\n }\n return result;\n}\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport function findNodeAtLocation(root, path) {\n if (!root) {\n return undefined;\n }\n let node = root;\n for (let segment of path) {\n if (typeof segment === 'string') {\n if (node.type !== 'object' || !Array.isArray(node.children)) {\n return undefined;\n }\n let found = false;\n for (const propertyNode of node.children) {\n if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {\n node = propertyNode.children[1];\n found = true;\n break;\n }\n }\n if (!found) {\n return undefined;\n }\n }\n else {\n const index = segment;\n if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {\n return undefined;\n }\n node = node.children[index];\n }\n }\n return node;\n}\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport function getNodePath(node) {\n if (!node.parent || !node.parent.children) {\n return [];\n }\n const path = getNodePath(node.parent);\n if (node.parent.type === 'property') {\n const key = node.parent.children[0].value;\n path.push(key);\n }\n else if (node.parent.type === 'array') {\n const index = node.parent.children.indexOf(node);\n if (index !== -1) {\n path.push(index);\n }\n }\n return path;\n}\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport function getNodeValue(node) {\n switch (node.type) {\n case 'array':\n return node.children.map(getNodeValue);\n case 'object':\n const obj = Object.create(null);\n for (let prop of node.children) {\n const valueNode = prop.children[1];\n if (valueNode) {\n obj[prop.children[0].value] = getNodeValue(valueNode);\n }\n }\n return obj;\n case 'null':\n case 'string':\n case 'number':\n case 'boolean':\n return node.value;\n default:\n return undefined;\n }\n}\nexport function contains(node, offset, includeRightBound = false) {\n return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));\n}\n/**\n * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport function findNodeAtOffset(node, offset, includeRightBound = false) {\n if (contains(node, offset, includeRightBound)) {\n const children = node.children;\n if (Array.isArray(children)) {\n for (let i = 0; i < children.length && children[i].offset <= offset; i++) {\n const item = findNodeAtOffset(children[i], offset, includeRightBound);\n if (item) {\n return item;\n }\n }\n }\n return node;\n }\n return undefined;\n}\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport function visit(text, visitor, options = ParseOptions.DEFAULT) {\n const _scanner = createScanner(text, false);\n // Important: Only pass copies of this to visitor functions to prevent accidental modification, and\n // to not affect visitor functions which stored a reference to a previous JSONPath\n const _jsonPath = [];\n // Depth of onXXXBegin() callbacks suppressed. onXXXEnd() decrements this if it isn't 0 already.\n // Callbacks are only called when this value is 0.\n let suppressedCallbacks = 0;\n function toNoArgVisit(visitFunction) {\n return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisit(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisitWithPath(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;\n }\n function toBeginVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks++;\n }\n else {\n let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());\n if (cbReturn === false) {\n suppressedCallbacks = 1;\n }\n }\n }\n : () => true;\n }\n function toEndVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks--;\n }\n if (suppressedCallbacks === 0) {\n visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());\n }\n }\n : () => true;\n }\n const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);\n const disallowComments = options && options.disallowComments;\n const allowTrailingComma = options && options.allowTrailingComma;\n function scanNext() {\n while (true) {\n const token = _scanner.scan();\n switch (_scanner.getTokenError()) {\n case 4 /* ScanError.InvalidUnicode */:\n handleError(14 /* ParseErrorCode.InvalidUnicode */);\n break;\n case 5 /* ScanError.InvalidEscapeCharacter */:\n handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */);\n break;\n case 3 /* ScanError.UnexpectedEndOfNumber */:\n handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */);\n break;\n case 1 /* ScanError.UnexpectedEndOfComment */:\n if (!disallowComments) {\n handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */);\n }\n break;\n case 2 /* ScanError.UnexpectedEndOfString */:\n handleError(12 /* ParseErrorCode.UnexpectedEndOfString */);\n break;\n case 6 /* ScanError.InvalidCharacter */:\n handleError(16 /* ParseErrorCode.InvalidCharacter */);\n break;\n }\n switch (token) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (disallowComments) {\n handleError(10 /* ParseErrorCode.InvalidCommentToken */);\n }\n else {\n onComment();\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n handleError(1 /* ParseErrorCode.InvalidSymbol */);\n break;\n case 15 /* SyntaxKind.Trivia */:\n case 14 /* SyntaxKind.LineBreakTrivia */:\n break;\n default:\n return token;\n }\n }\n }\n function handleError(error, skipUntilAfter = [], skipUntil = []) {\n onError(error);\n if (skipUntilAfter.length + skipUntil.length > 0) {\n let token = _scanner.getToken();\n while (token !== 17 /* SyntaxKind.EOF */) {\n if (skipUntilAfter.indexOf(token) !== -1) {\n scanNext();\n break;\n }\n else if (skipUntil.indexOf(token) !== -1) {\n break;\n }\n token = scanNext();\n }\n }\n }\n function parseString(isValue) {\n const value = _scanner.getTokenValue();\n if (isValue) {\n onLiteralValue(value);\n }\n else {\n onObjectProperty(value);\n // add property name afterwards\n _jsonPath.push(value);\n }\n scanNext();\n return true;\n }\n function parseLiteral() {\n switch (_scanner.getToken()) {\n case 11 /* SyntaxKind.NumericLiteral */:\n const tokenValue = _scanner.getTokenValue();\n let value = Number(tokenValue);\n if (isNaN(value)) {\n handleError(2 /* ParseErrorCode.InvalidNumberFormat */);\n value = 0;\n }\n onLiteralValue(value);\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n onLiteralValue(null);\n break;\n case 8 /* SyntaxKind.TrueKeyword */:\n onLiteralValue(true);\n break;\n case 9 /* SyntaxKind.FalseKeyword */:\n onLiteralValue(false);\n break;\n default:\n return false;\n }\n scanNext();\n return true;\n }\n function parseProperty() {\n if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) {\n handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n return false;\n }\n parseString(false);\n if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) {\n onSeparator(':');\n scanNext(); // consume colon\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n }\n else {\n handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n _jsonPath.pop(); // remove processed property name\n return true;\n }\n function parseObject() {\n onObjectBegin();\n scanNext(); // consume open brace\n let needsComma = false;\n while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (!parseProperty()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onObjectEnd();\n if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) {\n handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []);\n }\n else {\n scanNext(); // consume close brace\n }\n return true;\n }\n function parseArray() {\n onArrayBegin();\n scanNext(); // consume open bracket\n let isFirstElement = true;\n let needsComma = false;\n while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (isFirstElement) {\n _jsonPath.push(0);\n isFirstElement = false;\n }\n else {\n _jsonPath[_jsonPath.length - 1]++;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onArrayEnd();\n if (!isFirstElement) {\n _jsonPath.pop(); // remove array index\n }\n if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) {\n handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []);\n }\n else {\n scanNext(); // consume close bracket\n }\n return true;\n }\n function parseValue() {\n switch (_scanner.getToken()) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n return parseArray();\n case 1 /* SyntaxKind.OpenBraceToken */:\n return parseObject();\n case 10 /* SyntaxKind.StringLiteral */:\n return parseString(true);\n default:\n return parseLiteral();\n }\n }\n scanNext();\n if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) {\n if (options.allowEmptyContent) {\n return true;\n }\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []);\n }\n return true;\n}\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport function stripComments(text, replaceCh) {\n let _scanner = createScanner(text), parts = [], kind, offset = 0, pos;\n do {\n pos = _scanner.getPosition();\n kind = _scanner.scan();\n switch (kind) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n case 17 /* SyntaxKind.EOF */:\n if (offset !== pos) {\n parts.push(text.substring(offset, pos));\n }\n if (replaceCh !== undefined) {\n parts.push(_scanner.getTokenValue().replace(/[^\\r\\n]/g, replaceCh));\n }\n offset = _scanner.getPosition();\n break;\n }\n } while (kind !== 17 /* SyntaxKind.EOF */);\n return parts.join('');\n}\nexport function getNodeType(value) {\n switch (typeof value) {\n case 'boolean': return 'boolean';\n case 'number': return 'number';\n case 'string': return 'string';\n case 'object': {\n if (!value) {\n return 'null';\n }\n else if (Array.isArray(value)) {\n return 'array';\n }\n return 'object';\n }\n default: return 'null';\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport * as formatter from './impl/format';\nimport * as edit from './impl/edit';\nimport * as scanner from './impl/scanner';\nimport * as parser from './impl/parser';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport const createScanner = scanner.createScanner;\nexport var ScanError;\n(function (ScanError) {\n ScanError[ScanError[\"None\"] = 0] = \"None\";\n ScanError[ScanError[\"UnexpectedEndOfComment\"] = 1] = \"UnexpectedEndOfComment\";\n ScanError[ScanError[\"UnexpectedEndOfString\"] = 2] = \"UnexpectedEndOfString\";\n ScanError[ScanError[\"UnexpectedEndOfNumber\"] = 3] = \"UnexpectedEndOfNumber\";\n ScanError[ScanError[\"InvalidUnicode\"] = 4] = \"InvalidUnicode\";\n ScanError[ScanError[\"InvalidEscapeCharacter\"] = 5] = \"InvalidEscapeCharacter\";\n ScanError[ScanError[\"InvalidCharacter\"] = 6] = \"InvalidCharacter\";\n})(ScanError || (ScanError = {}));\nexport var SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"OpenBraceToken\"] = 1] = \"OpenBraceToken\";\n SyntaxKind[SyntaxKind[\"CloseBraceToken\"] = 2] = \"CloseBraceToken\";\n SyntaxKind[SyntaxKind[\"OpenBracketToken\"] = 3] = \"OpenBracketToken\";\n SyntaxKind[SyntaxKind[\"CloseBracketToken\"] = 4] = \"CloseBracketToken\";\n SyntaxKind[SyntaxKind[\"CommaToken\"] = 5] = \"CommaToken\";\n SyntaxKind[SyntaxKind[\"ColonToken\"] = 6] = \"ColonToken\";\n SyntaxKind[SyntaxKind[\"NullKeyword\"] = 7] = \"NullKeyword\";\n SyntaxKind[SyntaxKind[\"TrueKeyword\"] = 8] = \"TrueKeyword\";\n SyntaxKind[SyntaxKind[\"FalseKeyword\"] = 9] = \"FalseKeyword\";\n SyntaxKind[SyntaxKind[\"StringLiteral\"] = 10] = \"StringLiteral\";\n SyntaxKind[SyntaxKind[\"NumericLiteral\"] = 11] = \"NumericLiteral\";\n SyntaxKind[SyntaxKind[\"LineCommentTrivia\"] = 12] = \"LineCommentTrivia\";\n SyntaxKind[SyntaxKind[\"BlockCommentTrivia\"] = 13] = \"BlockCommentTrivia\";\n SyntaxKind[SyntaxKind[\"LineBreakTrivia\"] = 14] = \"LineBreakTrivia\";\n SyntaxKind[SyntaxKind[\"Trivia\"] = 15] = \"Trivia\";\n SyntaxKind[SyntaxKind[\"Unknown\"] = 16] = \"Unknown\";\n SyntaxKind[SyntaxKind[\"EOF\"] = 17] = \"EOF\";\n})(SyntaxKind || (SyntaxKind = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport const getLocation = parser.getLocation;\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore, always check the errors list to find out if the input was valid.\n */\nexport const parse = parser.parse;\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport const parseTree = parser.parseTree;\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport const findNodeAtLocation = parser.findNodeAtLocation;\n/**\n * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport const findNodeAtOffset = parser.findNodeAtOffset;\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport const getNodePath = parser.getNodePath;\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport const getNodeValue = parser.getNodeValue;\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport const visit = parser.visit;\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport const stripComments = parser.stripComments;\nexport var ParseErrorCode;\n(function (ParseErrorCode) {\n ParseErrorCode[ParseErrorCode[\"InvalidSymbol\"] = 1] = \"InvalidSymbol\";\n ParseErrorCode[ParseErrorCode[\"InvalidNumberFormat\"] = 2] = \"InvalidNumberFormat\";\n ParseErrorCode[ParseErrorCode[\"PropertyNameExpected\"] = 3] = \"PropertyNameExpected\";\n ParseErrorCode[ParseErrorCode[\"ValueExpected\"] = 4] = \"ValueExpected\";\n ParseErrorCode[ParseErrorCode[\"ColonExpected\"] = 5] = \"ColonExpected\";\n ParseErrorCode[ParseErrorCode[\"CommaExpected\"] = 6] = \"CommaExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBraceExpected\"] = 7] = \"CloseBraceExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBracketExpected\"] = 8] = \"CloseBracketExpected\";\n ParseErrorCode[ParseErrorCode[\"EndOfFileExpected\"] = 9] = \"EndOfFileExpected\";\n ParseErrorCode[ParseErrorCode[\"InvalidCommentToken\"] = 10] = \"InvalidCommentToken\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfComment\"] = 11] = \"UnexpectedEndOfComment\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfString\"] = 12] = \"UnexpectedEndOfString\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfNumber\"] = 13] = \"UnexpectedEndOfNumber\";\n ParseErrorCode[ParseErrorCode[\"InvalidUnicode\"] = 14] = \"InvalidUnicode\";\n ParseErrorCode[ParseErrorCode[\"InvalidEscapeCharacter\"] = 15] = \"InvalidEscapeCharacter\";\n ParseErrorCode[ParseErrorCode[\"InvalidCharacter\"] = 16] = \"InvalidCharacter\";\n})(ParseErrorCode || (ParseErrorCode = {}));\nexport function printParseErrorCode(code) {\n switch (code) {\n case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol';\n case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat';\n case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected';\n case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected';\n case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected';\n case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected';\n case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected';\n case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected';\n case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected';\n case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken';\n case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment';\n case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString';\n case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber';\n case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode';\n case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter';\n case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter';\n }\n return '<unknown ParseErrorCode>';\n}\n/**\n * Computes the edit operations needed to format a JSON document.\n *\n * @param documentText The input text\n * @param range The range to format or `undefined` to format the full content\n * @param options The formatting options\n * @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function format(documentText, range, options) {\n return formatter.format(documentText, range, options);\n}\n/**\n * Computes the edit operations needed to modify a value in the JSON document.\n *\n * @param documentText The input text\n * @param path The path of the value to change. The path represents either to the document root, a property or an array item.\n * If the path points to an non-existing property or item, it will be created.\n * @param value The new value for the specified property or item. If the value is undefined,\n * the property or item will be removed.\n * @param options Options\n * @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function modify(text, path, value, options) {\n return edit.setProperty(text, path, value, options);\n}\n/**\n * Applies edits to an input string.\n * @param text The input text\n * @param edits Edit operations following the format described in {@linkcode EditResult}.\n * @returns The text with the applied edits.\n * @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.\n */\nexport function applyEdits(text, edits) {\n let sortedEdits = edits.slice(0).sort((a, b) => {\n const diff = a.offset - b.offset;\n if (diff === 0) {\n return a.length - b.length;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n if (e.offset + e.length <= lastModifiedOffset) {\n text = edit.applyEdit(text, e);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = e.offset;\n }\n return text;\n}\n","import { writeFile, mkdir } from \"fs/promises\"\nimport { join } from \"path\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\n\nexport class Logger {\n private logDir: string\n public enabled: boolean\n\n constructor(enabled: boolean) {\n this.enabled = enabled\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n this.logDir = join(configHome, \"opencode\", \"logs\", \"dcp\")\n }\n\n private async ensureLogDir() {\n if (!existsSync(this.logDir)) {\n await mkdir(this.logDir, { recursive: true })\n }\n }\n\n private formatData(data?: any): string {\n if (!data) return \"\"\n\n const parts: string[] = []\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue\n\n // Format arrays compactly\n if (Array.isArray(value)) {\n if (value.length === 0) continue\n parts.push(\n `${key}=[${value.slice(0, 3).join(\",\")}${value.length > 3 ? `...+${value.length - 3}` : \"\"}]`,\n )\n } else if (typeof value === \"object\") {\n const str = JSON.stringify(value)\n if (str.length < 50) {\n parts.push(`${key}=${str}`)\n }\n } else {\n parts.push(`${key}=${value}`)\n }\n }\n return parts.join(\" \")\n }\n\n private getCallerFile(skipFrames: number = 3): string {\n const originalPrepareStackTrace = Error.prepareStackTrace\n try {\n const err = new Error()\n Error.prepareStackTrace = (_, stack) => stack\n const stack = err.stack as unknown as NodeJS.CallSite[]\n Error.prepareStackTrace = originalPrepareStackTrace\n\n // Skip specified number of frames to get to actual caller\n for (let i = skipFrames; i < stack.length; i++) {\n const filename = stack[i]?.getFileName()\n if (filename && !filename.includes(\"/logger.\")) {\n // Extract just the filename without path and extension\n const match = filename.match(/([^/\\\\]+)\\.[tj]s$/)\n return match ? match[1] : filename\n }\n }\n return \"unknown\"\n } catch {\n return \"unknown\"\n }\n }\n\n private async write(level: string, component: string, message: string, data?: any) {\n if (!this.enabled) return\n\n try {\n await this.ensureLogDir()\n\n const timestamp = new Date().toISOString()\n const dataStr = this.formatData(data)\n\n const logLine = `${timestamp} ${level.padEnd(5)} ${component}: ${message}${dataStr ? \" | \" + dataStr : \"\"}\\n`\n\n const dailyLogDir = join(this.logDir, \"daily\")\n if (!existsSync(dailyLogDir)) {\n await mkdir(dailyLogDir, { recursive: true })\n }\n\n const logFile = join(dailyLogDir, `${new Date().toISOString().split(\"T\")[0]}.log`)\n await writeFile(logFile, logLine, { flag: \"a\" })\n } catch (error) {}\n }\n\n info(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"INFO\", component, message, data)\n }\n\n debug(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"DEBUG\", component, message, data)\n }\n\n warn(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"WARN\", component, message, data)\n }\n\n error(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"ERROR\", component, message, data)\n }\n\n /**\n * Strips unnecessary metadata from messages for cleaner debug logs.\n *\n * Removed:\n * - All IDs (id, sessionID, messageID, parentID)\n * - summary, path, cost, model, agent, mode, finish, providerID, modelID\n * - step-start and step-finish parts entirely\n * - snapshot fields\n * - ignored text parts\n *\n * Kept:\n * - role, time (created only), tokens (input, output, reasoning, cache)\n * - text, reasoning, tool parts with content\n * - tool calls with: tool, callID, input, output, metadata\n */\n private minimizeForDebug(messages: any[]): any[] {\n return messages.map((msg) => {\n const minimized: any = {\n role: msg.info?.role,\n }\n\n if (msg.info?.time?.created) {\n minimized.time = msg.info.time.created\n }\n\n if (msg.info?.tokens) {\n minimized.tokens = {\n input: msg.info.tokens.input,\n output: msg.info.tokens.output,\n reasoning: msg.info.tokens.reasoning,\n cache: msg.info.tokens.cache,\n }\n }\n\n if (msg.parts) {\n minimized.parts = msg.parts\n .map((part: any) => {\n if (part.type === \"step-start\" || part.type === \"step-finish\") {\n return null\n }\n\n if (part.type === \"text\") {\n if (part.ignored) return null\n const textPart: any = { type: \"text\", text: part.text }\n if (part.metadata) textPart.metadata = part.metadata\n return textPart\n }\n\n if (part.type === \"reasoning\") {\n const reasoningPart: any = { type: \"reasoning\", text: part.text }\n if (part.metadata) reasoningPart.metadata = part.metadata\n return reasoningPart\n }\n\n if (part.type === \"tool\") {\n const toolPart: any = {\n type: \"tool\",\n tool: part.tool,\n callID: part.callID,\n }\n\n if (part.state?.status) {\n toolPart.status = part.state.status\n }\n if (part.state?.input) {\n toolPart.input = part.state.input\n }\n if (part.state?.output) {\n toolPart.output = part.state.output\n }\n if (part.state?.error) {\n toolPart.error = part.state.error\n }\n if (part.metadata) {\n toolPart.metadata = part.metadata\n }\n if (part.state?.metadata) {\n toolPart.metadata = {\n ...(toolPart.metadata || {}),\n ...part.state.metadata,\n }\n }\n if (part.state?.title) {\n toolPart.title = part.state.title\n }\n\n return toolPart\n }\n\n return null\n })\n .filter(Boolean)\n }\n\n return minimized\n })\n }\n\n async saveContext(sessionId: string, messages: any[]) {\n if (!this.enabled) return\n\n try {\n const contextDir = join(this.logDir, \"context\", sessionId)\n if (!existsSync(contextDir)) {\n await mkdir(contextDir, { recursive: true })\n }\n\n const minimized = this.minimizeForDebug(messages).filter(\n (msg) => msg.parts && msg.parts.length > 0,\n )\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\")\n const contextFile = join(contextDir, `${timestamp}.json`)\n await writeFile(contextFile, JSON.stringify(minimized, null, 2))\n } catch (error) {}\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport type { Logger } from \"../logger\"\nimport { systemPrompt } from \"./system\"\nimport { rcPrompt } from \"./compress-rc\"\nimport type { IdFormat } from \"../message-ids\"\nimport { CONTEXT_LIMIT_NUDGE } from \"./context-limit-nudge\"\nimport { TURN_NUDGE } from \"./turn-nudge\"\nimport { ITERATION_NUDGE } from \"./iteration-nudge\"\nimport { MANUAL_MODE_SYSTEM_EXTENSION, SUBAGENT_SYSTEM_EXTENSION } from \"./extensions/system\"\n\nexport type PromptKey =\n | \"system\"\n | \"compress-rc\"\n | \"context-limit-nudge\"\n | \"turn-nudge\"\n | \"iteration-nudge\"\n\ntype EditablePromptField =\n | \"system\"\n | \"compressRc\"\n | \"contextLimitNudge\"\n | \"turnNudge\"\n | \"iterationNudge\"\n\ninterface PromptDefinition {\n key: PromptKey\n fileName: string\n label: string\n description: string\n usage: string\n runtimeField: EditablePromptField\n}\n\ninterface PromptOverrideCandidate {\n path: string\n}\n\ninterface PromptPaths {\n defaultsDir: string\n globalOverridesDir: string\n configDirOverridesDir: string | null\n projectOverridesDir: string | null\n}\n\nexport interface RuntimePrompts {\n system: string\n compressRc: string\n contextLimitNudge: string\n turnNudge: string\n iterationNudge: string\n manualExtension: string\n subagentExtension: string\n}\n\nconst PROMPT_DEFINITIONS: PromptDefinition[] = [\n {\n key: \"system\",\n fileName: \"system.md\",\n label: \"System\",\n description: \"Core system-level DCP instruction block\",\n usage: \"Injected into the model system prompt on every request\",\n runtimeField: \"system\",\n },\n {\n key: \"compress-rc\",\n fileName: \"compress-rc.md\",\n label: \"Compress RC\",\n description: \"rc-mode compress tool instructions (model selects IDs only)\",\n usage: \"Registered as the rc-mode compress tool description\",\n runtimeField: \"compressRc\",\n },\n {\n key: \"context-limit-nudge\",\n fileName: \"context-limit-nudge.md\",\n label: \"Context Limit Nudge\",\n description: \"High-priority nudge when context is over max threshold\",\n usage: \"Injected when context usage is beyond configured max limits\",\n runtimeField: \"contextLimitNudge\",\n },\n {\n key: \"turn-nudge\",\n fileName: \"turn-nudge.md\",\n label: \"Turn Nudge\",\n description: \"Nudge to compress closed ranges at turn boundaries\",\n usage: \"Injected when context is between min and max limits at a new user turn\",\n runtimeField: \"turnNudge\",\n },\n {\n key: \"iteration-nudge\",\n fileName: \"iteration-nudge.md\",\n label: \"Iteration Nudge\",\n description: \"Nudge after many iterations without user input\",\n usage: \"Injected when iteration threshold is crossed\",\n runtimeField: \"iterationNudge\",\n },\n]\n\nexport const PROMPT_KEYS: PromptKey[] = [\n \"system\",\n \"compress-rc\",\n \"context-limit-nudge\",\n \"turn-nudge\",\n \"iteration-nudge\",\n]\n\nconst HTML_COMMENT_REGEX = /<!--[\\s\\S]*?-->/g\nconst LEGACY_INLINE_COMMENT_LINE_REGEX = /^[ \\t]*\\/\\/.*?\\/\\/[ \\t]*$/gm\nconst DCP_SYSTEM_REMINDER_TAG_REGEX =\n /^\\s*<dcp-system-reminder\\b[^>]*>[\\s\\S]*<\\/dcp-system-reminder>\\s*$/i\nconst DEFAULTS_README_FILE = \"README.md\"\n\nfunction bundledPrompts(format: IdFormat): Record<EditablePromptField, string> {\n return {\n system: systemPrompt(format),\n compressRc: rcPrompt(format),\n contextLimitNudge: CONTEXT_LIMIT_NUDGE,\n turnNudge: TURN_NUDGE,\n iterationNudge: ITERATION_NUDGE,\n }\n}\n\nconst INTERNAL_PROMPT_EXTENSIONS = {\n manualExtension: MANUAL_MODE_SYSTEM_EXTENSION,\n subagentExtension: SUBAGENT_SYSTEM_EXTENSION,\n}\n\nfunction createBundledRuntimePrompts(bundled: Record<EditablePromptField, string>): RuntimePrompts {\n return {\n ...bundled,\n manualExtension: INTERNAL_PROMPT_EXTENSIONS.manualExtension,\n subagentExtension: INTERNAL_PROMPT_EXTENSIONS.subagentExtension,\n }\n}\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate)) {\n try {\n if (statSync(candidate).isDirectory()) {\n return candidate\n }\n } catch {\n // ignore inaccessible entries while walking upward\n }\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction resolvePromptPaths(workingDirectory: string): PromptPaths {\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n const globalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n const defaultsDir = join(globalRoot, \"defaults\")\n const globalOverridesDir = join(globalRoot, \"overrides\")\n\n const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR\n ? join(process.env.OPENCODE_CONFIG_DIR, \"dcp-prompts\", \"overrides\")\n : null\n\n const opencodeDir = findOpencodeDir(workingDirectory)\n const projectOverridesDir = opencodeDir ? join(opencodeDir, \"dcp-prompts\", \"overrides\") : null\n\n return {\n defaultsDir,\n globalOverridesDir,\n configDirOverridesDir,\n projectOverridesDir,\n }\n}\n\nfunction stripConditionalTag(content: string, tagName: string): string {\n const regex = new RegExp(`<${tagName}>[\\\\s\\\\S]*?<\\/${tagName}>`, \"gi\")\n return content.replace(regex, \"\")\n}\n\nfunction unwrapDcpTagIfWrapped(content: string): string {\n const trimmed = content.trim()\n\n if (DCP_SYSTEM_REMINDER_TAG_REGEX.test(trimmed)) {\n return trimmed\n .replace(/^\\s*<dcp-system-reminder\\b[^>]*>\\s*/i, \"\")\n .replace(/\\s*<\\/dcp-system-reminder>\\s*$/i, \"\")\n .trim()\n }\n\n return trimmed\n}\n\nfunction normalizeReminderPromptContent(content: string): string {\n const normalized = content.trim()\n\n if (!normalized) {\n return \"\"\n }\n\n const startsWrapped = /^\\s*<dcp-system-reminder\\b[^>]*>/i.test(normalized)\n const endsWrapped = /<\\/dcp-system-reminder>\\s*$/i.test(normalized)\n\n if (startsWrapped !== endsWrapped) {\n return \"\"\n }\n\n return unwrapDcpTagIfWrapped(normalized)\n}\n\nfunction stripPromptComments(content: string): string {\n return content\n .replace(/^\\uFEFF/, \"\")\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(HTML_COMMENT_REGEX, \"\")\n .replace(LEGACY_INLINE_COMMENT_LINE_REGEX, \"\")\n}\n\nfunction toEditablePromptText(definition: PromptDefinition, rawContent: string): string {\n let normalized = stripPromptComments(rawContent).trim()\n if (!normalized) {\n return \"\"\n }\n\n if (definition.key === \"system\") {\n normalized = stripConditionalTag(normalized, \"manual\")\n normalized = stripConditionalTag(normalized, \"subagent\")\n }\n\n normalized = normalizeReminderPromptContent(normalized)\n\n return normalized.trim()\n}\n\nfunction wrapRuntimePromptContent(definition: PromptDefinition, editableText: string): string {\n const trimmed = editableText.trim()\n if (!trimmed) {\n return \"\"\n }\n\n return `<dcp-system-reminder>\\n${trimmed}\\n</dcp-system-reminder>`\n}\n\nfunction buildDefaultPromptFileContent(bundledEditableText: string): string {\n return `${bundledEditableText.trim()}\\n`\n}\n\nfunction buildDefaultsReadmeContent(): string {\n const lines: string[] = []\n lines.push(\"# DCP Prompt Defaults\")\n lines.push(\"\")\n lines.push(\"This directory stores the DCP prompts.\")\n lines.push(\"Each prompt file here should contain plain text only (no XML wrappers).\")\n lines.push(\"\")\n lines.push(\"## Creating Overrides\")\n lines.push(\"\")\n lines.push(\n \"1. Copy a prompt file from this directory into an overrides directory using the same filename.\",\n )\n lines.push(\"2. Edit the copied file using plain text.\")\n lines.push(\"3. Restart OpenCode.\")\n lines.push(\"\")\n lines.push(\"To reset an override, delete the matching file from your overrides directory.\")\n lines.push(\"\")\n lines.push(\n \"Do not edit the default prompt files directly, they are just for reference, only files in the overrides directory are used.\",\n )\n lines.push(\"\")\n lines.push(\"Override precedence (highest first):\")\n lines.push(\"1. `.opencode/dcp-prompts/overrides/` (project)\")\n lines.push(\"2. `$OPENCODE_CONFIG_DIR/dcp-prompts/overrides/` (config dir)\")\n lines.push(\"3. `~/.config/opencode/dcp-prompts/overrides/` (global)\")\n lines.push(\"\")\n lines.push(\"## Prompt Files\")\n lines.push(\"\")\n\n for (const definition of PROMPT_DEFINITIONS) {\n lines.push(`- \\`${definition.fileName}\\``)\n lines.push(` - Purpose: ${definition.description}.`)\n lines.push(` - Runtime use: ${definition.usage}.`)\n }\n\n return `${lines.join(\"\\n\")}\\n`\n}\n\nfunction readFileIfExists(filePath: string): string | null {\n if (!existsSync(filePath)) {\n return null\n }\n\n try {\n return readFileSync(filePath, \"utf-8\")\n } catch {\n return null\n }\n}\n\nexport class PromptStore {\n private readonly logger: Logger\n private readonly paths: PromptPaths\n private readonly customPromptsEnabled: boolean\n private runtimePrompts: RuntimePrompts\n private readonly bundled: Record<EditablePromptField, string>\n\n constructor(\n logger: Logger,\n workingDirectory: string,\n customPromptsEnabled = false,\n idFormat: IdFormat = \"xml\",\n ) {\n this.logger = logger\n this.paths = resolvePromptPaths(workingDirectory)\n this.customPromptsEnabled = customPromptsEnabled\n this.bundled = bundledPrompts(idFormat)\n this.runtimePrompts = createBundledRuntimePrompts(this.bundled)\n\n if (this.customPromptsEnabled) {\n this.ensureDefaultFiles()\n }\n this.reload()\n }\n\n getRuntimePrompts(): RuntimePrompts {\n return { ...this.runtimePrompts }\n }\n\n reload(): void {\n const nextPrompts = createBundledRuntimePrompts(this.bundled)\n\n if (!this.customPromptsEnabled) {\n this.runtimePrompts = nextPrompts\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledSource = this.bundled[definition.runtimeField]\n const bundledEditable = toEditablePromptText(definition, bundledSource)\n const bundledRuntime = wrapRuntimePromptContent(definition, bundledEditable)\n const fallbackValue = bundledRuntime || bundledSource.trim()\n let effectiveValue = fallbackValue\n\n for (const candidate of this.getOverrideCandidates(definition.fileName)) {\n const rawOverride = readFileIfExists(candidate.path)\n if (rawOverride === null) {\n continue\n }\n\n const editableOverride = toEditablePromptText(definition, rawOverride)\n if (!editableOverride) {\n this.logger.warn(\"Prompt override is empty or invalid after normalization\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n const wrappedOverride = wrapRuntimePromptContent(definition, editableOverride)\n if (!wrappedOverride) {\n this.logger.warn(\"Prompt override could not be wrapped for runtime\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n effectiveValue = wrappedOverride\n break\n }\n\n nextPrompts[definition.runtimeField] = effectiveValue\n }\n\n this.runtimePrompts = nextPrompts\n }\n\n private getOverrideCandidates(fileName: string): PromptOverrideCandidate[] {\n const candidates: PromptOverrideCandidate[] = []\n\n if (this.paths.projectOverridesDir) {\n candidates.push({\n path: join(this.paths.projectOverridesDir, fileName),\n })\n }\n\n if (this.paths.configDirOverridesDir) {\n candidates.push({\n path: join(this.paths.configDirOverridesDir, fileName),\n })\n }\n\n candidates.push({\n path: join(this.paths.globalOverridesDir, fileName),\n })\n\n return candidates\n }\n\n private ensureDefaultFiles(): void {\n try {\n mkdirSync(this.paths.defaultsDir, { recursive: true })\n mkdirSync(this.paths.globalOverridesDir, { recursive: true })\n } catch {\n this.logger.warn(\"Failed to initialize prompt directories\", {\n defaultsDir: this.paths.defaultsDir,\n globalOverridesDir: this.paths.globalOverridesDir,\n })\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledEditable = toEditablePromptText(\n definition,\n this.bundled[definition.runtimeField],\n )\n const managedContent = buildDefaultPromptFileContent(\n bundledEditable || this.bundled[definition.runtimeField],\n )\n const filePath = join(this.paths.defaultsDir, definition.fileName)\n\n try {\n const existing = readFileIfExists(filePath)\n if (existing === managedContent) {\n continue\n }\n writeFileSync(filePath, managedContent, \"utf-8\")\n } catch {\n this.logger.warn(\"Failed to write default prompt file\", {\n key: definition.key,\n path: filePath,\n })\n }\n }\n\n const readmePath = join(this.paths.defaultsDir, DEFAULTS_README_FILE)\n const readmeContent = buildDefaultsReadmeContent()\n\n try {\n const existing = readFileIfExists(readmePath)\n if (existing !== readmeContent) {\n writeFileSync(readmePath, readmeContent, \"utf-8\")\n }\n } catch {\n this.logger.warn(\"Failed to write defaults README\", {\n path: readmePath,\n })\n }\n }\n}\n","import type { IdFormat } from \"../message-ids\"\n\nexport function systemPrompt(format: IdFormat = \"xml\"): string {\n const markers =\n format === \"compact\" ? \"`@4@`, `@b1@`, `@blocked@`, priority labels\" : \"`<dcp-message-id>`\"\n return `\nYou operate in a context-constrained environment. Manage context continuously to avoid buildup and preserve retrieval quality. Efficient context management is paramount for your agentic performance.\n\nThe ONLY tool you have for context management is \\`compress\\`. It replaces older conversation content with compact technical summaries.\n\n${markers} and \\`<dcp-system-reminder>\\` tags are environment-injected metadata. Do not output them.\n\nTHE PHILOSOPHY OF COMPRESS\n\\`compress\\` transforms conversation content into dense, high-fidelity summaries. This is not cleanup - it is crystallization. Your summary becomes the authoritative record of what transpired.\n\nThink of compression as phase transitions: raw exploration becomes refined understanding. The original context served its purpose; your summary now carries that understanding forward.\n\nCOMPRESS WHEN\n\nA section is genuinely closed and the raw conversation has served its purpose:\n\n- Research concluded and findings are clear\n- Implementation finished and verified\n- Exploration exhausted and patterns understood\n- Dead-end noise can be discarded without waiting for a whole chapter to close\n\nDO NOT COMPRESS IF\n\n- Raw context is still relevant and needed for edits or precise references\n- The target content is still actively in progress\n- You may need exact code, error messages, or file contents in the immediate next steps\n\nBefore compressing, ask: _\"Is this section closed enough to become summary-only right now?\"_\n\nEvaluate conversation signal-to-noise REGULARLY. Use \\`compress\\` deliberately with quality-first summaries. Prioritize stale content intelligently to maintain a high-signal context window that supports your agency.\n\nIt is of your responsibility to keep a sharp, high-quality context window for optimal performance.\n`\n}\n\nexport const SYSTEM = systemPrompt()\n","import type { IdFormat } from \"../message-ids\"\n\nexport function rcPrompt(format: IdFormat = \"xml\"): string {\n const single = format === \"compact\" ? \"`@4@`\" : \"`m0004`\"\n const block = format === \"compact\" ? \"`@b2@`\" : \"`b2`\"\n const range = format === \"compact\" ? \"`@4@-@8@`\" : \"`m0004-m0008`\"\n return `Compress stale conversation messages into technical summaries.\n\nPass \\`ids\\`: an ordered list of injected message IDs, block IDs, or inclusive\nranges. Each list item becomes one summary, so preserve the summary boundaries\nyou want. For example, {\"ids\": [${range}, ${single}]} creates one summary for\nthe range and one for the single message.\n\nUse only IDs visible in the conversation. A compressed block (${block}) can be\nused as a boundary: including it merges its summary into the new one and retires\nthe old block. Prefer one broad, comprehensive selection of stale or resolved\nmessages over several small calls. Do not compress messages whose exact code,\nerrors, or file contents may still be needed in the immediate next steps; do not\ncompress work that is still active.\n\nThe summaries are generated automatically during this tool call and replace the\nselected messages in your next request.`\n}\n\nexport const COMPRESS_RC = rcPrompt()\n","export const CONTEXT_LIMIT_NUDGE = `<dcp-system-reminder>\nCRITICAL WARNING: MAX CONTEXT LIMIT REACHED\n\nYou are at or beyond the configured max context threshold. This is an emergency context-recovery moment.\n\nYou MUST use the \\`compress\\` tool now. Do not continue normal exploration until compression is handled.\n\nIf you are in the middle of a critical atomic operation, finish that atomic step first, then compress immediately.\n\nSELECTION PROCESS\nStart from older, resolved history and capture as much stale context as safely possible in one pass.\nAvoid the newest active working messages unless it is clearly closed.\n\nSUMMARY REQUIREMENTS\nYour summary MUST cover all essential details from the selected messages so work can continue.\nIf the compressed range includes user messages, preserve user intent exactly. Prefer direct quotes for short user messages to avoid semantic drift.\n</dcp-system-reminder>\n`\n","export const TURN_NUDGE = `<dcp-system-reminder>\nEvaluate the conversation for compressible ranges.\n\nIf any messages are cleanly closed and unlikely to be needed again, use the compress tool on them.\nIf direction has shifted, compress earlier ranges that are now less relevant.\n\nThe goal is to filter noise and distill key information so context accumulation stays under control.\nKeep active context uncompressed.\n</dcp-system-reminder>\n`\n","export const ITERATION_NUDGE = `<dcp-system-reminder>\nYou've been iterating for a while after the last user message.\n\nIf there is a closed portion that is unlikely to be referenced immediately (for example, finished research before implementation), use the compress tool on it now.\n</dcp-system-reminder>\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `<dcp-system-reminder>\nManual mode is enabled. Do NOT use compress unless the user has explicitly triggered it through a manual marker.\n\nOnly use the compress tool after seeing \\`<compress triggered manually>\\` in the current user instruction context.\n\nIssue exactly ONE compress tool per manual trigger. Do NOT launch multiple compress tools in parallel. Each trigger grants a single compression; after it completes, wait for the next trigger.\n\nAfter completing a manually triggered context-management action, STOP IMMEDIATELY. Do NOT continue with any task execution. End your response right after the tool use completes and wait for the next user input.\n</dcp-system-reminder>\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `<dcp-system-reminder>\nYou are operating in a subagent environment.\n\nThe initial subagent instruction is imperative and must be followed exactly.\nIt is the only user message intentionally not assigned a message ID, and therefore is not eligible for compression.\nAll subsequent messages in the session will have IDs.\n</dcp-system-reminder>\n`\n\nexport function buildProtectedToolsExtension(protectedTools: string[]): string {\n if (protectedTools.length === 0) {\n return \"\"\n }\n\n const toolList = protectedTools.map((t) => `\\`${t}\\``).join(\", \")\n return `<dcp-system-reminder>\nThe following tools are environment-managed: ${toolList}.\nTheir outputs are automatically preserved during compression.\nDo not include their content in compress tool summaries — the environment retains it independently.\n</dcp-system-reminder>`\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext, SelectionResolution } from \"./types\"\nimport type { WithParts } from \"../state\"\nimport { refreshManualMode } from \"../state\"\nimport { formatBlockRef, formatMessageRef, parseBoundaryId, type IdFormat } from \"../message-ids\"\nimport {\n buildSearchContext,\n fetchSessionMessages,\n resolveAnchorMessageId,\n resolveBoundaryIds,\n resolveSelection,\n} from \"./search\"\nimport {\n allocateBlockId,\n allocateRunId,\n applyCompressionState,\n wrapCompressedSummary,\n} from \"./state\"\nimport { finalizeSession, prepareSession, type NotificationEntry } from \"./pipeline\"\nimport { countTokens } from \"../token-utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { rcFormat } from \"../prompts/extensions/tool\"\nimport { appendProtectedPromptInfo, appendProtectedTools } from \"./protected-content\"\nimport {\n addCompressionUsage,\n addCompressionUsageTotals,\n emptyCompressionUsage,\n estimatedCompressionUsage,\n type CompressionUsageTotals,\n} from \"./usage\"\nimport {\n buildSummaryPrompt,\n parseSummarySections,\n restoreSummary,\n type PriorSummary,\n type SummarySection,\n type SummarySegment,\n} from \"./summary\"\n\nexport interface RcCompressToolArgs {\n ids: string[]\n}\n\nlet summaryCallCounter = 0\n\n/** Unique per hidden summary request so provider usage can be attributed. */\nfunction nextSummaryCallId(): string {\n summaryCallCounter += 1\n return `c${summaryCallCounter.toString(36)}-${Date.now().toString(36)}-${Math.random()\n .toString(36)\n .slice(2, 8)}`\n}\n\n/**\n * Compress selections with a hidden, synchronous summary request.\n *\n * The model only selects message IDs (`ids`); summaries are generated by the\n * plugin in a transient `session.generate` call during this tool call and are\n * applied before the model's next step. Nothing except the `compress` tool\n * call itself is user-visible.\n */\n\nfunction validateArgs(args: RcCompressToolArgs): void {\n if (!args || typeof args !== \"object\") {\n throw new Error(\"compress requires an object argument with an `ids` array\")\n }\n if (!Array.isArray(args.ids)) {\n throw new Error(\"`ids` must be an array of message IDs or inclusive ranges\")\n }\n if (args.ids.length === 0) {\n throw new Error(\"`ids` must not be empty\")\n }\n}\n\ninterface ParsedSelector {\n selector: string\n startRef: string\n endRef: string\n}\n\nexport function parseSelector(selector: string, format: IdFormat): ParsedSelector {\n const raw = selector.trim().toLowerCase()\n const parts = raw.split(\"-\").map((part) => part.trim())\n if (parts.length === 1 || parts.length === 2) {\n const parseAny = (part: string) =>\n parseBoundaryId(part, format) ??\n parseBoundaryId(part, format === \"compact\" ? \"xml\" : \"compact\")\n const toRef = (parsed: NonNullable<ReturnType<typeof parseAny>>): string =>\n parsed.kind === \"message\"\n ? formatMessageRef(parsed.index, format)\n : formatBlockRef(parsed.blockId, format)\n\n const start = parseAny(parts[0]!)\n const end = parts.length === 2 ? parseAny(parts[1]!) : start\n if (start && end) {\n if (start.kind === \"message\" && end.kind === \"message\" && start.index > end.index) {\n throw new Error(`Invalid selector ${selector}: start comes after end`)\n }\n const startRef = toRef(start)\n const endRef = toRef(end)\n return {\n selector: startRef === endRef ? startRef : `${startRef}-${endRef}`,\n startRef,\n endRef,\n }\n }\n }\n throw new Error(\n `Invalid selector ${JSON.stringify(selector)}. Use an injected message ID (e.g. ${\n format === \"compact\" ? \"\" : \"m0004\"\n }), a block ID (e.g. ${\n format === \"compact\" ? \"\" : \"b2\"\n }), or an inclusive range of either.`,\n )\n}\n\ninterface RcPlan {\n selector: ParsedSelector\n messageIds: string[]\n messages: WithParts[]\n selection: SelectionResolution\n anchorMessageId: string\n priorSummaries: PriorSummary[]\n}\n\nfunction planSelections(\n ctx: ToolContext,\n rawMessages: WithParts[],\n selectors: ParsedSelector[],\n): RcPlan[] {\n const context = buildSearchContext(ctx.state, rawMessages)\n\n return selectors.map((selector) => {\n const { startReference, endReference } = resolveBoundaryIds(\n context,\n ctx.state,\n ctx.config,\n selector.startRef,\n selector.endRef,\n )\n const selection = resolveSelection(context, ctx.config, startReference, endReference)\n const messages = selection.messageIds\n .map((messageId) => context.rawMessagesById.get(messageId))\n .filter((message): message is WithParts => Boolean(message))\n const anchorMessageId = resolveAnchorMessageId(startReference)\n\n const priorSummaries: PriorSummary[] = []\n for (const blockId of selection.requiredBlockIds) {\n const block = ctx.state.prune.messages.blocksById.get(blockId)\n if (!block) {\n continue\n }\n const body = restoreSummary(block.summary)\n if (body.length > 0) {\n priorSummaries.push({\n ref: formatBlockRef(blockId, ctx.state.idFormat),\n body,\n })\n }\n }\n\n return {\n selector,\n messageIds: selection.messageIds,\n messages,\n selection,\n anchorMessageId,\n priorSummaries,\n }\n })\n}\n\nfunction validateNonOverlapping(plans: RcPlan[]): void {\n const sorted = [...plans].sort(\n (left, right) =>\n left.selection.startReference.rawIndex - right.selection.startReference.rawIndex ||\n left.selection.endReference.rawIndex - right.selection.endReference.rawIndex,\n )\n\n for (let index = 1; index < sorted.length; index++) {\n const previous = sorted[index - 1]\n const current = sorted[index]\n if (!previous || !current) {\n continue\n }\n if (current.selection.startReference.rawIndex <= previous.selection.endReference.rawIndex) {\n throw new Error(\n `Selectors ${previous.selector.selector} and ${current.selector.selector} overlap. Overlapping selections cannot be compressed in one call.`,\n )\n }\n }\n}\n\nfunction assertBlockCoverage(\n ctx: ToolContext,\n selector: string,\n selection: SelectionResolution,\n): void {\n const required = new Set(selection.requiredBlockIds)\n for (const messageId of selection.messageIds) {\n const entry = ctx.state.prune.messages.byMessageId.get(messageId)\n if (!entry || entry.activeBlockIds.length === 0) {\n continue\n }\n for (const blockId of entry.activeBlockIds) {\n if (required.has(blockId)) {\n continue\n }\n const ref = formatBlockRef(blockId, ctx.state.idFormat)\n throw new Error(\n `Selector ${selector} only partially covers compressed block ${ref}. Include ${ref} as a boundary so its summary can be merged, or exclude its messages.`,\n )\n }\n }\n}\n\nexport function createRcCompressTool(ctx: ToolContext): ReturnType<typeof tool> {\n ctx.prompts.reload()\n const runtimePrompts = ctx.prompts.getRuntimePrompts()\n return tool({\n description: runtimePrompts.compressRc + rcFormat(ctx.state.idFormat),\n args: {\n ids: tool.schema\n .array(tool.schema.string())\n .describe(\n \"The injected message or block IDs, or inclusive ranges, to compress. Each item becomes one summary.\",\n ),\n },\n async execute(args, toolCtx) {\n const input = (args ?? {}) as RcCompressToolArgs\n validateArgs(input)\n\n const sessionID =\n typeof (toolCtx as any)?.sessionID === \"string\" ? (toolCtx as any).sessionID : \"\"\n if (!sessionID) {\n throw new Error(\"compress could not determine the session\")\n }\n const callId =\n typeof (toolCtx as any)?.callID === \"string\" ? (toolCtx as any).callID : undefined\n const toolMessageID = String((toolCtx as any)?.messageID ?? \"\")\n\n try {\n const { rawMessages } = await prepareSession(\n ctx,\n toolCtx as any,\n `Compress: ${input.ids.join(\", \")}`,\n )\n\n const selectors = input.ids.map((selector) =>\n parseSelector(selector, ctx.state.idFormat),\n )\n const plans = planSelections(ctx, rawMessages, selectors)\n validateNonOverlapping(plans)\n for (const plan of plans) {\n assertBlockCoverage(ctx, plan.selector.selector, plan.selection)\n }\n\n const segments: SummarySegment[] = plans.map((plan) => ({\n selector: plan.selector.selector,\n messages: plan.messages,\n priorSummaries: plan.priorSummaries,\n }))\n\n const { text, usage } = await generateSummaries(ctx, sessionID, segments)\n ctx.state.stats.compressionUsage = addCompressionUsageTotals(\n ctx.state.stats.compressionUsage,\n usage,\n )\n await saveSessionState(ctx.state, ctx.logger)\n const accepted = await resolveAcceptedSections(\n ctx,\n plans.map((plan) => plan.selector.selector),\n text,\n )\n if (accepted.length === 0) {\n throw new Error(\"summary reply contained no usable sections\")\n }\n\n const { entries, applied, missing } = await applySummaries(\n ctx,\n sessionID,\n toolMessageID,\n callId,\n plans,\n accepted,\n )\n if (entries.length === 0) {\n throw new Error(\"summary reply could not be applied to the session\")\n }\n\n await finalizeSession(\n ctx,\n toolCtx as any,\n rawMessages,\n entries,\n plans.map((plan) => plan.selector.selector).join(\", \"),\n )\n\n if (missing.length === 0) {\n return `Compressed: ${applied.join(\", \")}.`\n }\n return `Compressed: ${applied.join(\", \")}. Not compressed: ${missing.join(\", \")}.`\n } catch (error) {\n await resetManualMode(ctx, sessionID)\n throw error\n }\n },\n })\n}\n\nasync function generateSummaries(\n ctx: ToolContext,\n sessionID: string,\n segments: SummarySegment[],\n): Promise<{ text: string; usage: CompressionUsageTotals }> {\n let usage = emptyCompressionUsage()\n\n const summarize = async (promptSegments: SummarySegment[]): Promise<string> => {\n const callId = nextSummaryCallId()\n const prompt = buildSummaryPrompt(promptSegments, ctx.state.idFormat, callId)\n const result = await ctx.generate({ sessionID, prompt, callId })\n const text = result.text ?? \"\"\n // Provider usage is authoritative; fall back to a local estimate when\n // the plugin could not observe the underlying model call.\n usage = addCompressionUsage(\n usage,\n result.usage ?? estimatedCompressionUsage(countTokens(prompt), countTokens(text)),\n )\n return text\n }\n\n let text = await summarize(segments)\n\n // One retry for sections the model failed to emit.\n for (let retry = 0; retry < 2; retry++) {\n const parsed = parseSummarySections(\n text,\n segments.map((segment) => segment.selector),\n ctx.state.idFormat,\n )\n const retrySelectors = [...parsed.missing, ...parsed.empty]\n if (retrySelectors.length === 0) {\n break\n }\n const retrySegments = segments.filter((segment) =>\n retrySelectors.includes(segment.selector.toLowerCase()),\n )\n if (retrySegments.length === 0) {\n break\n }\n try {\n text += \"\\n\\n\" + (await summarize(retrySegments))\n } catch {\n break\n }\n }\n return { text, usage }\n}\n\nasync function resolveAcceptedSections(\n ctx: ToolContext,\n selectors: string[],\n text: string,\n): Promise<SummarySection[]> {\n const parsed = parseSummarySections(text, selectors, ctx.state.idFormat)\n ctx.logger.info(\"rc summary reply parsed\", {\n replyChars: text.length,\n accepted: parsed.sections.map((section) => section.selector).join(\",\"),\n missing: parsed.missing.join(\",\"),\n empty: parsed.empty.join(\",\"),\n })\n if (parsed.missing.length > 0 || parsed.empty.length > 0) {\n ctx.logger.warn(\"rc compression reply was incomplete\", {\n missing: parsed.missing.join(\",\"),\n empty: parsed.empty.join(\",\"),\n })\n }\n return parsed.sections\n}\n\nasync function applySummaries(\n ctx: ToolContext,\n sessionID: string,\n toolMessageID: string,\n callId: string | undefined,\n plans: RcPlan[],\n sections: SummarySection[],\n): Promise<{ entries: NotificationEntry[]; applied: string[]; missing: string[] }> {\n // Re-read the session so we only apply summaries whose source messages are\n // still present (a compaction or revert may have happened meanwhile).\n const rawMessages = await fetchSessionMessages(ctx.client, sessionID)\n const context = buildSearchContext(ctx.state, rawMessages)\n const planBySelector = new Map(plans.map((plan) => [plan.selector.selector, plan]))\n\n const runId = allocateRunId(ctx.state)\n const batchTopic = plans.map((plan) => plan.selector.selector).join(\", \")\n const entries: NotificationEntry[] = []\n const applied: string[] = []\n const appliedSet = new Set<string>()\n\n for (const section of sections) {\n const plan = planBySelector.get(section.selector)\n if (!plan) {\n continue\n }\n\n try {\n const { startReference, endReference } = resolveBoundaryIds(\n context,\n ctx.state,\n ctx.config,\n plan.selector.startRef,\n plan.selector.endRef,\n )\n const selection = resolveSelection(context, ctx.config, startReference, endReference)\n if (selection.messageIds.length === 0) {\n continue\n }\n assertBlockCoverage(ctx, section.selector, selection)\n\n const anchorMessageId = resolveAnchorMessageId(startReference)\n const blockId = allocateBlockId(ctx.state)\n\n const withPromptInfo = appendProtectedPromptInfo(\n section.summary,\n selection,\n context,\n ctx.state,\n ctx.config.compress.protectTags,\n )\n const finalSummary = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n withPromptInfo,\n selection,\n context,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n const storedSummary = wrapCompressedSummary(blockId, finalSummary, ctx.state.idFormat)\n const summaryTokens = countTokens(storedSummary)\n\n applyCompressionState(\n ctx.state,\n {\n topic: section.selector,\n batchTopic,\n startId: plan.selector.startRef,\n endId: plan.selector.endRef,\n mode: \"rc\",\n runId,\n compressMessageId: toolMessageID,\n compressCallId: callId,\n summaryTokens,\n },\n selection,\n anchorMessageId,\n blockId,\n storedSummary,\n selection.requiredBlockIds,\n )\n\n entries.push({\n blockId,\n runId,\n summary: finalSummary,\n summaryTokens,\n })\n applied.push(section.selector)\n appliedSet.add(section.selector)\n } catch (error) {\n ctx.logger.warn(\"rc compression could not apply a summary\", {\n selector: section.selector,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n\n const missing = plans\n .map((plan) => plan.selector.selector)\n .filter((selector) => !appliedSet.has(selector))\n return { entries, applied, missing }\n}\n\nasync function resetManualMode(ctx: ToolContext, sessionID: string): Promise<void> {\n if (ctx.state.manualMode !== \"compress-pending\") {\n return\n }\n ctx.state.manualMode = false\n await refreshManualMode(ctx.state, sessionID, ctx.logger, ctx.config.manualMode.enabled)\n await saveSessionState(ctx.state, ctx.logger)\n}\n","/**\n * State persistence module for DCP plugin.\n * Persists pruned tool IDs across sessions so they survive OpenCode restarts.\n * Storage location: ~/.local/share/opencode/storage/plugin/dcp/{sessionId}.json\n */\n\nimport * as fs from \"fs/promises\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport {\n addCompressionUsageTotals,\n emptyCompressionUsage,\n normalizeCompressionUsageTotals,\n type CompressionUsageTotals,\n} from \"../compress/usage\"\nimport { serializePruneMessagesState } from \"./utils\"\n\n/** Prune state as stored on disk */\nexport interface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport interface PersistedPrune {\n tools?: Record<string, number>\n messages?: PersistedPruneMessagesState\n}\n\nexport interface PersistedNudges {\n contextLimitAnchors: string[]\n turnNudgeAnchors?: string[]\n iterationNudgeAnchors?: string[]\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n manualMode?: boolean\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n}\n\nconst STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n)\n\nasync function ensureStorageDir(): Promise<void> {\n if (!existsSync(STORAGE_DIR)) {\n await fs.mkdir(STORAGE_DIR, { recursive: true })\n }\n}\n\nfunction getSessionFilePath(sessionId: string): string {\n return join(STORAGE_DIR, `${sessionId}.json`)\n}\n\nasync function writePersistedSessionState(\n sessionId: string,\n state: PersistedSessionState,\n logger: Logger,\n): Promise<void> {\n await ensureStorageDir()\n\n const filePath = getSessionFilePath(sessionId)\n const content = JSON.stringify(state, null, 2)\n await fs.writeFile(filePath, content, \"utf-8\")\n\n logger.info(\"Saved session state to disk\", {\n sessionId,\n totalTokensSaved: state.stats.totalPruneTokens,\n })\n}\n\nexport async function saveSessionState(\n sessionState: SessionState,\n logger: Logger,\n sessionName?: string,\n): Promise<void> {\n try {\n if (!sessionState.sessionId) {\n return\n }\n\n const state: PersistedSessionState = {\n sessionName: sessionName,\n manualMode: !!sessionState.manualMode,\n prune: {\n tools: Object.fromEntries(sessionState.prune.tools),\n messages: serializePruneMessagesState(sessionState.prune.messages),\n },\n nudges: {\n contextLimitAnchors: Array.from(sessionState.nudges.contextLimitAnchors),\n turnNudgeAnchors: Array.from(sessionState.nudges.turnNudgeAnchors),\n iterationNudgeAnchors: Array.from(sessionState.nudges.iterationNudgeAnchors),\n },\n stats: sessionState.stats,\n lastUpdated: new Date().toISOString(),\n }\n\n await writePersistedSessionState(sessionState.sessionId, state, logger)\n } catch (error: any) {\n logger.error(\"Failed to save session state\", {\n sessionId: sessionState.sessionId,\n error: error?.message,\n })\n }\n}\n\nexport async function loadSessionState(\n sessionId: string,\n logger: Logger,\n): Promise<PersistedSessionState | null> {\n try {\n const filePath = getSessionFilePath(sessionId)\n\n if (!existsSync(filePath)) {\n return null\n }\n\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n const hasPruneTools = state?.prune?.tools && typeof state.prune.tools === \"object\"\n const hasPruneMessages = state?.prune?.messages && typeof state.prune.messages === \"object\"\n const hasNudgeFormat = state?.nudges && typeof state.nudges === \"object\"\n if (\n !state ||\n !state.prune ||\n !hasPruneTools ||\n !hasPruneMessages ||\n !state.stats ||\n !hasNudgeFormat\n ) {\n logger.warn(\"Invalid session state file, ignoring\", {\n sessionId: sessionId,\n })\n return null\n }\n\n const rawContextLimitAnchors = Array.isArray(state.nudges.contextLimitAnchors)\n ? state.nudges.contextLimitAnchors\n : []\n const validAnchors = rawContextLimitAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedAnchors = [...new Set(validAnchors)]\n if (validAnchors.length !== rawContextLimitAnchors.length) {\n logger.warn(\"Filtered out malformed contextLimitAnchors entries\", {\n sessionId: sessionId,\n original: rawContextLimitAnchors.length,\n valid: validAnchors.length,\n })\n }\n state.nudges.contextLimitAnchors = dedupedAnchors\n\n const rawTurnNudgeAnchors = Array.isArray(state.nudges.turnNudgeAnchors)\n ? state.nudges.turnNudgeAnchors\n : []\n const validSoftAnchors = rawTurnNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedSoftAnchors = [...new Set(validSoftAnchors)]\n if (validSoftAnchors.length !== rawTurnNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed turnNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawTurnNudgeAnchors.length,\n valid: validSoftAnchors.length,\n })\n }\n state.nudges.turnNudgeAnchors = dedupedSoftAnchors\n\n const rawIterationNudgeAnchors = Array.isArray(state.nudges.iterationNudgeAnchors)\n ? state.nudges.iterationNudgeAnchors\n : []\n const validIterationAnchors = rawIterationNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedIterationAnchors = [...new Set(validIterationAnchors)]\n if (validIterationAnchors.length !== rawIterationNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed iterationNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawIterationNudgeAnchors.length,\n valid: validIterationAnchors.length,\n })\n }\n state.nudges.iterationNudgeAnchors = dedupedIterationAnchors\n\n logger.info(\"Loaded session state from disk\", {\n sessionId: sessionId,\n })\n\n return state\n } catch (error: any) {\n logger.warn(\"Failed to load session state\", {\n sessionId: sessionId,\n error: error?.message,\n })\n return null\n }\n}\n\nfunction emptyPersistedState(manualMode: boolean): PersistedSessionState {\n return {\n manualMode,\n prune: {\n tools: {},\n messages: {\n byMessageId: {},\n blocksById: {},\n activeBlockIds: [],\n activeByAnchorMessageId: {},\n nextBlockId: 1,\n nextRunId: 1,\n },\n },\n nudges: {\n contextLimitAnchors: [],\n turnNudgeAnchors: [],\n iterationNudgeAnchors: [],\n },\n stats: {\n pruneTokenCounter: 0,\n totalPruneTokens: 0,\n compressionUsage: emptyCompressionUsage(),\n },\n lastUpdated: new Date().toISOString(),\n }\n}\n\nexport async function loadManualModeSetting(\n sessionId: string,\n logger: Logger,\n): Promise<boolean | undefined> {\n const state = await loadSessionState(sessionId, logger)\n return typeof state?.manualMode === \"boolean\" ? state.manualMode : undefined\n}\n\nexport async function saveManualModeSetting(\n sessionId: string,\n manualMode: boolean,\n logger: Logger,\n): Promise<void> {\n const existing = await loadSessionState(sessionId, logger)\n const state = existing ?? emptyPersistedState(manualMode)\n state.manualMode = manualMode\n state.lastUpdated = new Date().toISOString()\n await writePersistedSessionState(sessionId, state, logger)\n}\n\nexport interface AggregatedStats {\n totalTokens: number\n totalTools: number\n totalMessages: number\n sessionCount: number\n compressionUsage: CompressionUsageTotals\n}\n\nexport async function loadAllSessionStats(logger: Logger): Promise<AggregatedStats> {\n const result: AggregatedStats = {\n totalTokens: 0,\n totalTools: 0,\n totalMessages: 0,\n sessionCount: 0,\n compressionUsage: emptyCompressionUsage(),\n }\n\n try {\n if (!existsSync(STORAGE_DIR)) {\n return result\n }\n\n const files = await fs.readdir(STORAGE_DIR)\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"))\n\n for (const file of jsonFiles) {\n try {\n const filePath = join(STORAGE_DIR, file)\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n const usage = normalizeCompressionUsageTotals(state?.stats?.compressionUsage)\n const hasUsage = usage.calls > 0\n\n if (state?.prune && (state?.stats?.totalPruneTokens || hasUsage)) {\n result.totalTokens += state.stats?.totalPruneTokens || 0\n result.totalTools += state.prune.tools\n ? Object.keys(state.prune.tools).length\n : 0\n result.totalMessages += state.prune.messages?.byMessageId\n ? Object.keys(state.prune.messages.byMessageId).length\n : 0\n result.compressionUsage = addCompressionUsageTotals(\n result.compressionUsage,\n usage,\n )\n result.sessionCount++\n }\n } catch {\n // Skip invalid files\n }\n }\n\n logger.debug(\"Loaded all-time stats\", result)\n } catch (error: any) {\n logger.warn(\"Failed to load all-time stats\", { error: error?.message })\n }\n\n return result\n}\n","/**\n * Usage accounting for the hidden compression (summary) request.\n *\n * Provider-reported usage is preferred: OpenCode V2 generates the summary\n * through `session.generate`, which does not surface token usage to the\n * caller, so the numbers are captured by wrapping the resolved language\n * model (`ctx.aisdk.hook(\"language\")`) and reading the `finish` usage.\n * When that path is unavailable, local tokenizer estimates are recorded\n * instead so the plugin can still report an approximate cost.\n */\n\nexport type CompressionUsageSource = \"provider\" | \"estimated\"\n\n/** Usage of a single hidden compression request. */\nexport interface CompressionUsage {\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n reasoningTokens: number\n source: CompressionUsageSource\n}\n\n/** Aggregated usage of all hidden compression requests in a session. */\nexport interface CompressionUsageTotals {\n calls: number\n providerCalls: number\n estimatedCalls: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n reasoningTokens: number\n}\n\nexport function emptyCompressionUsage(): CompressionUsageTotals {\n return {\n calls: 0,\n providerCalls: 0,\n estimatedCalls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n reasoningTokens: 0,\n }\n}\n\nfunction toCount(value: unknown, fallback = 0): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return fallback\n }\n return Math.round(value)\n}\n\n/**\n * Normalize AI SDK v3 usage (`{ inputTokens: { total, noCache, cacheRead,\n * cacheWrite }, outputTokens: { total, text, reasoning } }`) into the plugin\n * shape. Returns undefined when there is nothing usable to record.\n */\nexport function normalizeProviderUsage(raw: unknown): CompressionUsage | undefined {\n if (!raw || typeof raw !== \"object\") {\n return undefined\n }\n\n const value = raw as { inputTokens?: unknown; outputTokens?: unknown }\n const input =\n value.inputTokens && typeof value.inputTokens === \"object\"\n ? (value.inputTokens as Record<string, unknown>)\n : {}\n const output =\n value.outputTokens && typeof value.outputTokens === \"object\"\n ? (value.outputTokens as Record<string, unknown>)\n : {}\n\n const cacheRead = toCount(input.cacheRead)\n const cacheWrite = toCount(input.cacheWrite)\n const uncached = toCount(input.noCache)\n const inputFromParts = uncached + cacheRead + cacheWrite\n const inputTotal = Math.max(toCount(input.total, inputFromParts), inputFromParts)\n\n const reasoning = toCount(output.reasoning)\n const outputTotal = Math.max(toCount(output.total, toCount(output.text) + reasoning), reasoning)\n\n if (\n inputTotal === 0 &&\n outputTotal === 0 &&\n cacheRead === 0 &&\n cacheWrite === 0 &&\n reasoning === 0\n ) {\n return undefined\n }\n\n return {\n inputTokens: inputTotal,\n outputTokens: outputTotal,\n cacheReadTokens: cacheRead,\n cacheWriteTokens: cacheWrite,\n reasoningTokens: reasoning,\n source: \"provider\",\n }\n}\n\n/** Local fallback when the provider did not report usage. */\nexport function estimatedCompressionUsage(\n inputTokens: number,\n outputTokens: number,\n): CompressionUsage {\n return {\n inputTokens: toCount(inputTokens),\n outputTokens: toCount(outputTokens),\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n reasoningTokens: 0,\n source: \"estimated\",\n }\n}\n\nexport function addCompressionUsage(\n totals: CompressionUsageTotals,\n usage: CompressionUsage,\n): CompressionUsageTotals {\n return {\n calls: totals.calls + 1,\n providerCalls: totals.providerCalls + (usage.source === \"provider\" ? 1 : 0),\n estimatedCalls: totals.estimatedCalls + (usage.source === \"estimated\" ? 1 : 0),\n inputTokens: totals.inputTokens + usage.inputTokens,\n outputTokens: totals.outputTokens + usage.outputTokens,\n cacheReadTokens: totals.cacheReadTokens + usage.cacheReadTokens,\n cacheWriteTokens: totals.cacheWriteTokens + usage.cacheWriteTokens,\n reasoningTokens: totals.reasoningTokens + usage.reasoningTokens,\n }\n}\n\nexport function addCompressionUsageTotals(\n totals: CompressionUsageTotals,\n other: CompressionUsageTotals,\n): CompressionUsageTotals {\n return {\n calls: totals.calls + other.calls,\n providerCalls: totals.providerCalls + other.providerCalls,\n estimatedCalls: totals.estimatedCalls + other.estimatedCalls,\n inputTokens: totals.inputTokens + other.inputTokens,\n outputTokens: totals.outputTokens + other.outputTokens,\n cacheReadTokens: totals.cacheReadTokens + other.cacheReadTokens,\n cacheWriteTokens: totals.cacheWriteTokens + other.cacheWriteTokens,\n reasoningTokens: totals.reasoningTokens + other.reasoningTokens,\n }\n}\n\n/** Backward-compatible load of persisted totals. */\nexport function normalizeCompressionUsageTotals(value: unknown): CompressionUsageTotals {\n if (!value || typeof value !== \"object\") {\n return emptyCompressionUsage()\n }\n const raw = value as Record<string, unknown>\n return {\n calls: toCount(raw.calls),\n providerCalls: toCount(raw.providerCalls),\n estimatedCalls: toCount(raw.estimatedCalls),\n inputTokens: toCount(raw.inputTokens),\n outputTokens: toCount(raw.outputTokens),\n cacheReadTokens: toCount(raw.cacheReadTokens),\n cacheWriteTokens: toCount(raw.cacheWriteTokens),\n reasoningTokens: toCount(raw.reasoningTokens),\n }\n}\n","import type { WithParts } from \"../state\"\n\nexport function isMessageWithInfo(message: unknown): message is WithParts {\n if (!message || typeof message !== \"object\") {\n return false\n }\n\n const info = (message as any).info\n const parts = (message as any).parts\n if (!info || typeof info !== \"object\") {\n return false\n }\n\n return (\n typeof info.id === \"string\" &&\n info.id.length > 0 &&\n typeof info.sessionID === \"string\" &&\n info.sessionID.length > 0 &&\n (info.role === \"user\" || info.role === \"assistant\") &&\n info.time &&\n typeof info.time === \"object\" &&\n typeof info.time.created === \"number\" &&\n Array.isArray(parts)\n )\n}\n\nexport function filterMessages(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n return messages.filter(isMessageWithInfo)\n}\n\nexport function filterMessagesInPlace(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n let writeIndex = 0\n\n for (const message of messages) {\n if (isMessageWithInfo(message)) {\n messages[writeIndex++] = message\n }\n }\n\n messages.length = writeIndex\n return messages as WithParts[]\n}\n","import type { PluginConfig } from \"../config\"\nimport type { WithParts } from \"../state\"\nimport { isMessageWithInfo } from \"./shape\"\n\nexport const getLastUserMessage = (\n messages: WithParts[],\n startIndex?: number,\n): WithParts | null => {\n const start = startIndex ?? messages.length - 1\n for (let i = start; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return msg\n }\n }\n return null\n}\n\nexport const messageHasCompress = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"assistant\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n\nexport const isIgnoredUserMessage = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"user\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n if (parts.length === 0) {\n return true\n }\n\n for (const part of parts) {\n if (!(part as any).ignored) {\n return false\n }\n }\n\n return true\n}\n\nexport function isProtectedUserMessage(config: PluginConfig, message: WithParts): boolean {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n return (\n config.compress.protectUserMessages &&\n message.info.role === \"user\" &&\n !isIgnoredUserMessage(message)\n )\n}\n","import { SessionState, WithParts } from \"./state\"\nimport { AssistantMessage, UserMessage } from \"@opencode-ai/sdk/v2\"\nimport { Logger } from \"./logger\"\nimport * as _anthropicTokenizer from \"@anthropic-ai/tokenizer\"\nconst anthropicCountTokens = (_anthropicTokenizer.countTokens ??\n (_anthropicTokenizer as any).default?.countTokens) as typeof _anthropicTokenizer.countTokens\nimport { getLastUserMessage } from \"./messages/query\"\n\nexport function getCurrentTokenUsage(state: SessionState, messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"assistant\") {\n continue\n }\n\n const assistantInfo = msg.info as AssistantMessage\n if ((assistantInfo.tokens?.output || 0) <= 0) {\n continue\n }\n\n if (\n state.lastCompaction > 0 &&\n (msg.info.time.created < state.lastCompaction ||\n (msg.info.summary === true && msg.info.time.created === state.lastCompaction))\n ) {\n return 0\n }\n\n const input = assistantInfo.tokens?.input || 0\n const output = assistantInfo.tokens?.output || 0\n const reasoning = assistantInfo.tokens?.reasoning || 0\n const cacheRead = assistantInfo.tokens?.cache?.read || 0\n const cacheWrite = assistantInfo.tokens?.cache?.write || 0\n return input + output + reasoning + cacheRead + cacheWrite\n }\n\n return 0\n}\n\nexport function getCurrentParams(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): {\n providerId: string | undefined\n modelId: string | undefined\n agent: string | undefined\n variant: string | undefined\n} {\n const userMsg = getLastUserMessage(messages)\n if (!userMsg) {\n logger.debug(\"No user message found when determining current params\")\n return {\n providerId: undefined,\n modelId: undefined,\n agent: undefined,\n variant: undefined,\n }\n }\n const userInfo = userMsg.info as UserMessage\n const agent: string = userInfo.agent\n const providerId: string | undefined = userInfo.model.providerID\n const modelId: string | undefined = userInfo.model.modelID\n const variant: string | undefined = userInfo.model.variant\n\n return { providerId, modelId, agent, variant }\n}\n\nexport function countTokens(text: string): number {\n if (!text) return 0\n try {\n return anthropicCountTokens(text)\n } catch {\n return Math.round(text.length / 4)\n }\n}\n\nexport function estimateTokensBatch(texts: string[]): number {\n if (texts.length === 0) return 0\n return countTokens(texts.join(\" \"))\n}\n\nexport const COMPACTED_TOOL_OUTPUT_PLACEHOLDER = \"[Old tool result content cleared]\"\n\nfunction stringifyToolContent(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value)\n}\n\nexport function extractCompletedToolOutput(part: any): string | undefined {\n if (\n part?.type !== \"tool\" ||\n part.state?.status !== \"completed\" ||\n part.state?.output === undefined\n ) {\n return undefined\n }\n\n if (part.state?.time?.compacted) {\n return COMPACTED_TOOL_OUTPUT_PLACEHOLDER\n }\n\n return stringifyToolContent(part.state.output)\n}\n\nexport function extractToolContent(part: any): string[] {\n const contents: string[] = []\n\n if (part?.type !== \"tool\") {\n return contents\n }\n\n if (part.state?.input !== undefined) {\n contents.push(stringifyToolContent(part.state.input))\n }\n\n const completedOutput = extractCompletedToolOutput(part)\n if (completedOutput !== undefined) {\n contents.push(completedOutput)\n } else if (part.state?.status === \"error\" && part.state?.error) {\n contents.push(stringifyToolContent(part.state.error))\n }\n\n return contents\n}\n\nexport function countToolTokens(part: any): number {\n const contents = extractToolContent(part)\n return estimateTokensBatch(contents)\n}\n\nexport function getTotalToolTokens(state: SessionState, toolIds: string[]): number {\n let total = 0\n for (const id of toolIds) {\n const entry = state.toolParameters.get(id)\n total += entry?.tokenCount ?? 0\n }\n return total\n}\n\nexport function countMessageTextTokens(msg: WithParts): number {\n const texts: string[] = []\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n\nexport function countAllMessageTokens(msg: WithParts): number {\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const texts: string[] = []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n } else {\n texts.push(...extractToolContent(part))\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n","import type {\n CompressionBlock,\n PruneMessagesState,\n PrunedMessageEntry,\n SessionState,\n WithParts,\n} from \"./types\"\nimport { isIgnoredUserMessage, messageHasCompress } from \"../messages/query\"\nimport { isMessageWithInfo } from \"../messages/shape\"\nimport { countTokens } from \"../token-utils\"\n\nexport const isMessageCompacted = (state: SessionState, msg: WithParts): boolean => {\n if (!isMessageWithInfo(msg)) {\n return false\n }\n\n if (msg.info.time.created < state.lastCompaction) {\n return true\n }\n const pruneEntry = state.prune.messages.byMessageId.get(msg.info.id)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n return true\n }\n return false\n}\n\ninterface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport function serializePruneMessagesState(\n messagesState: PruneMessagesState,\n): PersistedPruneMessagesState {\n return {\n byMessageId: Object.fromEntries(messagesState.byMessageId),\n blocksById: Object.fromEntries(\n Array.from(messagesState.blocksById.entries()).map(([blockId, block]) => [\n String(blockId),\n block,\n ]),\n ),\n activeBlockIds: Array.from(messagesState.activeBlockIds),\n activeByAnchorMessageId: Object.fromEntries(messagesState.activeByAnchorMessageId),\n nextBlockId: messagesState.nextBlockId,\n nextRunId: messagesState.nextRunId,\n }\n}\n\nexport async function isSubAgentSession(client: any, sessionID: string): Promise<boolean> {\n try {\n const result = await client.session.get({ path: { id: sessionID } })\n return !!result.data?.parentID\n } catch (error: any) {\n return false\n }\n}\n\nexport function findLastCompactionTimestamp(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"assistant\" && msg.info.summary === true) {\n return msg.info.time.created\n }\n }\n return 0\n}\n\nexport function countTurns(state: SessionState, messages: WithParts[]): number {\n let turnCount = 0\n for (const msg of messages) {\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCount++\n }\n }\n }\n return turnCount\n}\n\nexport function loadPruneMap(obj?: Record<string, number>): Map<string, number> {\n if (!obj || typeof obj !== \"object\") {\n return new Map()\n }\n\n const entries = Object.entries(obj).filter(\n (entry): entry is [string, number] =>\n typeof entry[0] === \"string\" && typeof entry[1] === \"number\",\n )\n return new Map(entries)\n}\n\nexport function createPruneMessagesState(): PruneMessagesState {\n return {\n byMessageId: new Map<string, PrunedMessageEntry>(),\n blocksById: new Map<number, CompressionBlock>(),\n activeBlockIds: new Set<number>(),\n activeByAnchorMessageId: new Map<string, number>(),\n nextBlockId: 1,\n nextRunId: 1,\n }\n}\n\nexport function loadPruneMessagesState(\n persisted?: PersistedPruneMessagesState,\n): PruneMessagesState {\n const state = createPruneMessagesState()\n if (!persisted || typeof persisted !== \"object\") {\n return state\n }\n\n if (typeof persisted.nextBlockId === \"number\" && Number.isInteger(persisted.nextBlockId)) {\n state.nextBlockId = Math.max(1, persisted.nextBlockId)\n }\n if (typeof persisted.nextRunId === \"number\" && Number.isInteger(persisted.nextRunId)) {\n state.nextRunId = Math.max(1, persisted.nextRunId)\n }\n\n if (persisted.byMessageId && typeof persisted.byMessageId === \"object\") {\n for (const [messageId, entry] of Object.entries(persisted.byMessageId)) {\n if (!entry || typeof entry !== \"object\") {\n continue\n }\n\n const tokenCount = typeof entry.tokenCount === \"number\" ? entry.tokenCount : 0\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [\n ...new Set(\n entry.allBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n const activeBlockIds = Array.isArray(entry.activeBlockIds)\n ? [\n ...new Set(\n entry.activeBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n\n state.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds,\n activeBlockIds,\n })\n }\n }\n\n if (persisted.blocksById && typeof persisted.blocksById === \"object\") {\n for (const [blockIdStr, block] of Object.entries(persisted.blocksById)) {\n const blockId = Number.parseInt(blockIdStr, 10)\n if (!Number.isInteger(blockId) || blockId < 1 || !block || typeof block !== \"object\") {\n continue\n }\n\n const toNumberArray = (value: unknown): number[] =>\n Array.isArray(value)\n ? [\n ...new Set(\n value.filter(\n (item): item is number => Number.isInteger(item) && item > 0,\n ),\n ),\n ]\n : []\n const toStringArray = (value: unknown): string[] =>\n Array.isArray(value)\n ? [...new Set(value.filter((item): item is string => typeof item === \"string\"))]\n : []\n\n state.blocksById.set(blockId, {\n blockId,\n runId:\n typeof block.runId === \"number\" &&\n Number.isInteger(block.runId) &&\n block.runId > 0\n ? block.runId\n : blockId,\n active: block.active === true,\n deactivatedByUser: block.deactivatedByUser === true,\n compressedTokens:\n typeof block.compressedTokens === \"number\" &&\n Number.isFinite(block.compressedTokens)\n ? Math.max(0, block.compressedTokens)\n : 0,\n summaryTokens:\n typeof block.summaryTokens === \"number\" && Number.isFinite(block.summaryTokens)\n ? Math.max(0, block.summaryTokens)\n : typeof block.summary === \"string\"\n ? countTokens(block.summary)\n : 0,\n durationMs:\n typeof block.durationMs === \"number\" && Number.isFinite(block.durationMs)\n ? Math.max(0, block.durationMs)\n : 0,\n mode: block.mode === \"rc\" ? \"rc\" : undefined,\n topic: typeof block.topic === \"string\" ? block.topic : \"\",\n batchTopic:\n typeof block.batchTopic === \"string\"\n ? block.batchTopic\n : typeof block.topic === \"string\"\n ? block.topic\n : \"\",\n startId: typeof block.startId === \"string\" ? block.startId : \"\",\n endId: typeof block.endId === \"string\" ? block.endId : \"\",\n anchorMessageId:\n typeof block.anchorMessageId === \"string\" ? block.anchorMessageId : \"\",\n compressMessageId:\n typeof block.compressMessageId === \"string\" ? block.compressMessageId : \"\",\n compressCallId:\n typeof block.compressCallId === \"string\" ? block.compressCallId : undefined,\n includedBlockIds: toNumberArray(block.includedBlockIds),\n consumedBlockIds: toNumberArray(block.consumedBlockIds),\n parentBlockIds: toNumberArray(block.parentBlockIds),\n directMessageIds: toStringArray(block.directMessageIds),\n directToolIds: toStringArray(block.directToolIds),\n effectiveMessageIds: toStringArray(block.effectiveMessageIds),\n effectiveToolIds: toStringArray(block.effectiveToolIds),\n createdAt: typeof block.createdAt === \"number\" ? block.createdAt : 0,\n deactivatedAt:\n typeof block.deactivatedAt === \"number\" ? block.deactivatedAt : undefined,\n deactivatedByBlockId:\n typeof block.deactivatedByBlockId === \"number\" &&\n Number.isInteger(block.deactivatedByBlockId)\n ? block.deactivatedByBlockId\n : undefined,\n summary: typeof block.summary === \"string\" ? block.summary : \"\",\n })\n }\n }\n\n if (Array.isArray(persisted.activeBlockIds)) {\n for (const blockId of persisted.activeBlockIds) {\n if (!Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeBlockIds.add(blockId)\n }\n }\n\n if (\n persisted.activeByAnchorMessageId &&\n typeof persisted.activeByAnchorMessageId === \"object\"\n ) {\n for (const [anchorMessageId, blockId] of Object.entries(\n persisted.activeByAnchorMessageId,\n )) {\n if (typeof blockId !== \"number\" || !Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeByAnchorMessageId.set(anchorMessageId, blockId)\n }\n }\n\n for (const [blockId, block] of state.blocksById) {\n if (block.active) {\n state.activeBlockIds.add(blockId)\n if (block.anchorMessageId) {\n state.activeByAnchorMessageId.set(block.anchorMessageId, blockId)\n }\n }\n if (blockId >= state.nextBlockId) {\n state.nextBlockId = blockId + 1\n }\n if (block.runId >= state.nextRunId) {\n state.nextRunId = block.runId + 1\n }\n }\n\n return state\n}\n\nexport function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {\n const anchors = new Set<string>()\n let pendingUserMessageId: string | null = null\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n\n if (messageHasCompress(message)) {\n break\n }\n\n if (message.info.role === \"user\") {\n if (!isIgnoredUserMessage(message)) {\n pendingUserMessageId = message.info.id\n }\n continue\n }\n\n if (message.info.role === \"assistant\" && pendingUserMessageId) {\n anchors.add(message.info.id)\n anchors.add(pendingUserMessageId)\n pendingUserMessageId = null\n }\n }\n\n return anchors\n}\n\nexport function getActiveSummaryTokenUsage(state: SessionState): number {\n let total = 0\n for (const blockId of state.prune.messages.activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block || !block.active) {\n continue\n }\n total += block.summaryTokens\n }\n return total\n}\n\nexport function resetOnCompaction(state: SessionState): void {\n state.toolParameters.clear()\n state.prune.tools = new Map<string, number>()\n state.prune.messages = createPruneMessagesState()\n state.messageIds = {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\n }\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n }\n}\n","import type { SessionState, WithParts } from \"./state\"\nimport { isIgnoredUserMessage } from \"./messages/query\"\n\nconst MESSAGE_REF_REGEX = /^m(\\d{4})$/\nconst BLOCK_REF_REGEX = /^b([1-9]\\d*)$/\nconst COMPACT_MESSAGE_REGEX = /^@([1-9]\\d*)@$/\nconst COMPACT_BLOCK_REGEX = /^@b([1-9]\\d*)@$/\nconst MESSAGE_ID_TAG_NAME = \"dcp-message-id\"\n\nexport type IdFormat = \"xml\" | \"compact\"\n\nconst MESSAGE_REF_WIDTH = 4\nconst MESSAGE_REF_MIN_INDEX = 1\nexport const MESSAGE_REF_MAX_INDEX = 9999\n\nexport type ParsedBoundaryId =\n | {\n kind: \"message\"\n ref: string\n index: number\n }\n | {\n kind: \"compressed-block\"\n ref: string\n blockId: number\n }\n\nexport function formatMessageRef(index: number, format: IdFormat = \"xml\"): string {\n const max = format === \"compact\" ? Number.MAX_SAFE_INTEGER : MESSAGE_REF_MAX_INDEX\n if (!Number.isSafeInteger(index) || index < MESSAGE_REF_MIN_INDEX || index > max) {\n throw new Error(`Message ID index out of bounds: ${index}. Supported range is 1-${max}.`)\n }\n return format === \"compact\"\n ? `@${index}@`\n : `m${index.toString().padStart(MESSAGE_REF_WIDTH, \"0\")}`\n}\n\nexport function formatBlockRef(blockId: number, format: IdFormat = \"xml\"): string {\n if (!Number.isInteger(blockId) || blockId < 1) {\n throw new Error(`Invalid block ID: ${blockId}`)\n }\n return format === \"compact\" ? `@b${blockId}@` : `b${blockId}`\n}\n\nexport function parseMessageRef(ref: string, format: IdFormat = \"xml\"): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(format === \"compact\" ? COMPACT_MESSAGE_REGEX : MESSAGE_REF_REGEX)\n if (!match) {\n return null\n }\n const index = Number.parseInt(match[1], 10)\n if (!Number.isSafeInteger(index)) {\n return null\n }\n const max = format === \"compact\" ? Number.MAX_SAFE_INTEGER : MESSAGE_REF_MAX_INDEX\n if (index < MESSAGE_REF_MIN_INDEX || index > max) {\n return null\n }\n return index\n}\n\nexport function parseBlockRef(ref: string, format: IdFormat = \"xml\"): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(format === \"compact\" ? COMPACT_BLOCK_REGEX : BLOCK_REF_REGEX)\n if (!match) {\n return null\n }\n const id = Number.parseInt(match[1], 10)\n return Number.isSafeInteger(id) ? id : null\n}\n\nexport function parseBoundaryId(id: string, format: IdFormat = \"xml\"): ParsedBoundaryId | null {\n const normalized = id.trim().toLowerCase()\n const messageIndex = parseMessageRef(normalized, format)\n if (messageIndex !== null) {\n return {\n kind: \"message\",\n ref: formatMessageRef(messageIndex, format),\n index: messageIndex,\n }\n }\n\n const blockId = parseBlockRef(normalized, format)\n if (blockId !== null) {\n return {\n kind: \"compressed-block\",\n ref: formatBlockRef(blockId, format),\n blockId,\n }\n }\n\n return null\n}\n\nfunction escapeXmlAttribute(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n format: IdFormat = \"xml\",\n): string {\n if (format === \"compact\") {\n if (ref === \"BLOCKED\") return \"\\n@blocked@\"\n const priority = attributes?.priority\n return `\\n${ref}${priority ? ` [${priority}]` : \"\"}`\n }\n const serializedAttributes = Object.entries(attributes || {})\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([name, value]) => {\n if (name.trim().length === 0 || typeof value !== \"string\" || value.length === 0) {\n return \"\"\n }\n\n return ` ${name}=\"${escapeXmlAttribute(value)}\"`\n })\n .join(\"\")\n\n return `\\n<${MESSAGE_ID_TAG_NAME}${serializedAttributes}>${ref}</${MESSAGE_ID_TAG_NAME}>`\n}\n\nexport function assignMessageRefs(state: SessionState, messages: WithParts[]): number {\n let assigned = 0\n let skippedSubAgentPrompt = false\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n if (state.isSubAgent && !skippedSubAgentPrompt && message.info.role === \"user\") {\n skippedSubAgentPrompt = true\n continue\n }\n\n const rawMessageId = message.info.id\n if (typeof rawMessageId !== \"string\" || rawMessageId.length === 0) {\n continue\n }\n\n const existingRef = state.messageIds.byRawId.get(rawMessageId)\n if (existingRef) {\n if (state.messageIds.byRef.get(existingRef) !== rawMessageId) {\n state.messageIds.byRef.set(existingRef, rawMessageId)\n }\n continue\n }\n\n const ref = allocateNextMessageRef(state)\n state.messageIds.byRawId.set(rawMessageId, ref)\n state.messageIds.byRef.set(ref, rawMessageId)\n assigned++\n }\n\n return assigned\n}\n\nfunction allocateNextMessageRef(state: SessionState): string {\n let candidate = Number.isInteger(state.messageIds.nextRef)\n ? Math.max(MESSAGE_REF_MIN_INDEX, state.messageIds.nextRef)\n : MESSAGE_REF_MIN_INDEX\n\n const max = state.idFormat === \"compact\" ? Number.MAX_SAFE_INTEGER : MESSAGE_REF_MAX_INDEX\n while (candidate <= max) {\n const ref = formatMessageRef(candidate, state.idFormat)\n if (!state.messageIds.byRef.has(ref)) {\n state.messageIds.nextRef = candidate + 1\n return ref\n }\n candidate++\n }\n\n throw new Error(\n `Message ID alias capacity exceeded. Cannot allocate more than ${formatMessageRef(max, state.idFormat)} aliases in this session.`,\n )\n}\n","import type { CompressionBlock, PruneMessagesState, SessionState } from \"../state\"\nimport { formatBlockRef, formatMessageIdTag, type IdFormat } from \"../message-ids\"\nimport type { AppliedCompressionResult, CompressionStateInput, SelectionResolution } from \"./types\"\n\nexport const COMPRESSED_BLOCK_HEADER = \"[Compressed conversation section]\"\n\nexport function allocateBlockId(state: SessionState): number {\n const next = state.prune.messages.nextBlockId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextBlockId = 2\n return 1\n }\n\n state.prune.messages.nextBlockId = next + 1\n return next\n}\n\nexport function allocateRunId(state: SessionState): number {\n const next = state.prune.messages.nextRunId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextRunId = 2\n return 1\n }\n\n state.prune.messages.nextRunId = next + 1\n return next\n}\n\nexport function attachCompressionDuration(\n messagesState: PruneMessagesState,\n messageId: string,\n callId: string,\n durationMs: number,\n): number {\n if (typeof durationMs !== \"number\" || !Number.isFinite(durationMs)) {\n return 0\n }\n\n let updates = 0\n for (const block of messagesState.blocksById.values()) {\n if (block.compressMessageId !== messageId || block.compressCallId !== callId) {\n continue\n }\n\n block.durationMs = durationMs\n updates++\n }\n\n return updates\n}\n\nexport function wrapCompressedSummary(\n blockId: number,\n summary: string,\n format: IdFormat = \"xml\",\n): string {\n const header = COMPRESSED_BLOCK_HEADER\n const footer = formatMessageIdTag(formatBlockRef(blockId, format), undefined, format)\n const body = summary.trim()\n if (body.length === 0) {\n return `${header}\\n${footer}`\n }\n return `${header}\\n${body}\\n\\n${footer}`\n}\n\nexport function applyCompressionState(\n state: SessionState,\n input: CompressionStateInput,\n selection: SelectionResolution,\n anchorMessageId: string,\n blockId: number,\n summary: string,\n consumedBlockIds: number[],\n): AppliedCompressionResult {\n const messagesState = state.prune.messages\n const consumed = [...new Set(consumedBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n const included = [...consumed]\n\n const effectiveMessageIds = new Set<string>(selection.messageIds)\n const effectiveToolIds = new Set<string>(selection.toolIds)\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n effectiveMessageIds.add(messageId)\n }\n for (const toolId of consumedBlock.effectiveToolIds) {\n effectiveToolIds.add(toolId)\n }\n }\n\n const initiallyActiveMessages = new Set<string>()\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (entry && entry.activeBlockIds.length > 0) {\n initiallyActiveMessages.add(messageId)\n }\n }\n\n const initiallyActiveToolIds = new Set<string>()\n for (const activeBlockId of messagesState.activeBlockIds) {\n const activeBlock = messagesState.blocksById.get(activeBlockId)\n if (!activeBlock || !activeBlock.active) {\n continue\n }\n\n for (const toolId of activeBlock.effectiveToolIds) {\n initiallyActiveToolIds.add(toolId)\n }\n }\n\n const createdAt = Date.now()\n const block: CompressionBlock = {\n blockId,\n runId: input.runId,\n active: true,\n deactivatedByUser: false,\n compressedTokens: 0,\n summaryTokens: input.summaryTokens,\n durationMs: 0,\n mode: input.mode,\n topic: input.topic,\n batchTopic: input.batchTopic,\n startId: input.startId,\n endId: input.endId,\n anchorMessageId,\n compressMessageId: input.compressMessageId,\n compressCallId: input.compressCallId,\n includedBlockIds: included,\n consumedBlockIds: consumed,\n parentBlockIds: [],\n directMessageIds: [],\n directToolIds: [],\n effectiveMessageIds: [...effectiveMessageIds],\n effectiveToolIds: [...effectiveToolIds],\n createdAt,\n summary,\n }\n\n messagesState.blocksById.set(blockId, block)\n messagesState.activeBlockIds.add(blockId)\n messagesState.activeByAnchorMessageId.set(anchorMessageId, blockId)\n\n const deactivatedAt = Date.now()\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock || !consumedBlock.active) {\n continue\n }\n\n consumedBlock.active = false\n consumedBlock.deactivatedAt = deactivatedAt\n consumedBlock.deactivatedByBlockId = blockId\n if (!consumedBlock.parentBlockIds.includes(blockId)) {\n consumedBlock.parentBlockIds.push(blockId)\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n const removeActiveBlockId = (\n entry: { activeBlockIds: number[] },\n blockIdToRemove: number,\n ): void => {\n if (entry.activeBlockIds.length === 0) {\n return\n }\n entry.activeBlockIds = entry.activeBlockIds.filter((id) => id !== blockIdToRemove)\n }\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n removeActiveBlockId(entry, consumedBlockId)\n }\n }\n\n for (const messageId of selection.messageIds) {\n const tokenCount = selection.messageTokenById.get(messageId) || 0\n const existing = messagesState.byMessageId.get(messageId)\n\n if (!existing) {\n messagesState.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds: [blockId],\n activeBlockIds: [blockId],\n })\n continue\n }\n\n existing.tokenCount = Math.max(existing.tokenCount, tokenCount)\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n for (const messageId of block.effectiveMessageIds) {\n if (selection.messageTokenById.has(messageId)) {\n continue\n }\n\n const existing = messagesState.byMessageId.get(messageId)\n if (!existing) {\n continue\n }\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n let compressedTokens = 0\n const newlyCompressedMessageIds: string[] = []\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n\n const isNowActive = entry.activeBlockIds.length > 0\n const wasActive = initiallyActiveMessages.has(messageId)\n\n if (isNowActive && !wasActive) {\n compressedTokens += entry.tokenCount\n newlyCompressedMessageIds.push(messageId)\n }\n }\n\n const newlyCompressedToolIds: string[] = []\n for (const toolId of effectiveToolIds) {\n if (!initiallyActiveToolIds.has(toolId)) {\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n block.directMessageIds = [...newlyCompressedMessageIds]\n block.directToolIds = [...newlyCompressedToolIds]\n\n block.compressedTokens = compressedTokens\n\n state.stats.pruneTokenCounter += compressedTokens\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n return {\n compressedTokens,\n messageIds: selection.messageIds,\n newlyCompressedMessageIds,\n newlyCompressedToolIds,\n }\n}\n","import type { SessionState } from \"../state/types\"\nimport { attachCompressionDuration } from \"./state\"\n\nexport interface PendingCompressionDuration {\n messageId: string\n callId: string\n durationMs: number\n}\n\nexport interface CompressionTimingState {\n startsByCallId: Map<string, number>\n pendingByCallId: Map<string, PendingCompressionDuration>\n}\n\nexport function buildCompressionTimingKey(messageId: string, callId: string): string {\n return `${messageId}:${callId}`\n}\n\nexport function consumeCompressionStart(\n state: SessionState,\n messageId: string,\n callId: string,\n): number | undefined {\n const key = buildCompressionTimingKey(messageId, callId)\n const start = state.compressionTiming.startsByCallId.get(key)\n state.compressionTiming.startsByCallId.delete(key)\n return start\n}\n\nexport function resolveCompressionDuration(\n startedAt: number | undefined,\n eventTime: number | undefined,\n partTime: { start?: unknown; end?: unknown } | undefined,\n): number | undefined {\n const runningAt =\n typeof partTime?.start === \"number\" && Number.isFinite(partTime.start)\n ? partTime.start\n : eventTime\n const pendingToRunningMs =\n typeof startedAt === \"number\" && typeof runningAt === \"number\"\n ? Math.max(0, runningAt - startedAt)\n : undefined\n\n const toolStart = partTime?.start\n const toolEnd = partTime?.end\n const runtimeMs =\n typeof toolStart === \"number\" &&\n Number.isFinite(toolStart) &&\n typeof toolEnd === \"number\" &&\n Number.isFinite(toolEnd)\n ? Math.max(0, toolEnd - toolStart)\n : undefined\n\n return typeof pendingToRunningMs === \"number\" ? pendingToRunningMs : runtimeMs\n}\n\nexport function applyPendingCompressionDurations(state: SessionState): number {\n if (state.compressionTiming.pendingByCallId.size === 0) {\n return 0\n }\n\n let updates = 0\n for (const [key, entry] of state.compressionTiming.pendingByCallId) {\n const applied = attachCompressionDuration(\n state.prune.messages,\n entry.messageId,\n entry.callId,\n entry.durationMs,\n )\n if (applied > 0) {\n updates += applied\n state.compressionTiming.pendingByCallId.delete(key)\n }\n }\n\n return updates\n}\n","import type { SessionState, ToolParameterEntry, WithParts } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { emptyCompressionUsage, normalizeCompressionUsageTotals } from \"../compress/usage\"\nimport { applyPendingCompressionDurations } from \"../compress/timing\"\nimport { loadManualModeSetting, loadSessionState, saveSessionState } from \"./persistence\"\nimport {\n isSubAgentSession,\n findLastCompactionTimestamp,\n countTurns,\n resetOnCompaction,\n createPruneMessagesState,\n loadPruneMessagesState,\n loadPruneMap,\n collectTurnNudgeAnchors,\n} from \"./utils\"\nimport { getLastUserMessage } from \"../messages/query\"\nimport type { IdFormat } from \"../message-ids\"\n\nexport const checkSession = async (\n client: any,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n manualModeDefault: boolean,\n): Promise<void> => {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return\n }\n\n const lastSessionId = lastUserMessage.info.sessionID\n\n if (state.sessionId === null || state.sessionId !== lastSessionId) {\n logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`)\n try {\n await ensureSessionInitialized(\n client,\n state,\n lastSessionId,\n logger,\n messages,\n manualModeDefault,\n )\n } catch (err: any) {\n logger.error(\"Failed to initialize session state\", { error: err.message })\n }\n }\n\n const lastCompactionTimestamp = findLastCompactionTimestamp(messages)\n if (lastCompactionTimestamp > state.lastCompaction) {\n state.lastCompaction = lastCompactionTimestamp\n resetOnCompaction(state)\n logger.info(\"Detected compaction - reset stale state\", {\n timestamp: lastCompactionTimestamp,\n })\n\n saveSessionState(state, logger).catch((error) => {\n logger.warn(\"Failed to persist state reset after compaction\", {\n error: error instanceof Error ? error.message : String(error),\n })\n })\n }\n\n state.currentTurn = countTurns(state, messages)\n await refreshManualMode(state, lastSessionId, logger, manualModeDefault)\n}\n\nexport function createSessionState(idFormat: IdFormat = \"xml\"): SessionState {\n return {\n idFormat,\n sessionId: null,\n isSubAgent: false,\n manualMode: false,\n compressPermission: undefined,\n pendingManualTrigger: null,\n prune: {\n tools: new Map<string, number>(),\n messages: createPruneMessagesState(),\n },\n nudges: {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n },\n stats: {\n pruneTokenCounter: 0,\n totalPruneTokens: 0,\n compressionUsage: emptyCompressionUsage(),\n },\n compressionTiming: {\n startsByCallId: new Map<string, number>(),\n pendingByCallId: new Map(),\n },\n toolParameters: new Map<string, ToolParameterEntry>(),\n subAgentResultCache: new Map<string, string>(),\n toolIdList: [],\n messageIds: {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\n },\n lastCompaction: 0,\n currentTurn: 0,\n modelContextLimit: undefined,\n systemPromptTokens: undefined,\n }\n}\n\nexport function resetSessionState(state: SessionState): void {\n state.sessionId = null\n state.isSubAgent = false\n state.manualMode = false\n state.compressPermission = undefined\n state.pendingManualTrigger = null\n state.prune = {\n tools: new Map<string, number>(),\n messages: createPruneMessagesState(),\n }\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n }\n state.stats = {\n pruneTokenCounter: 0,\n totalPruneTokens: 0,\n compressionUsage: emptyCompressionUsage(),\n }\n state.toolParameters.clear()\n state.subAgentResultCache.clear()\n state.toolIdList = []\n state.messageIds = {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\n }\n state.lastCompaction = 0\n state.currentTurn = 0\n state.modelContextLimit = undefined\n state.systemPromptTokens = undefined\n}\n\nexport async function ensureSessionInitialized(\n client: any,\n state: SessionState,\n sessionId: string,\n logger: Logger,\n messages: WithParts[],\n manualModeEnabled: boolean,\n): Promise<void> {\n if (state.sessionId === sessionId) {\n return\n }\n\n // logger.info(\"session ID = \" + sessionId)\n // logger.info(\"Initializing session state\", { sessionId: sessionId })\n\n resetSessionState(state)\n state.manualMode = manualModeEnabled ? \"active\" : false\n state.sessionId = sessionId\n\n const isSubAgent = await isSubAgentSession(client, sessionId)\n state.isSubAgent = isSubAgent\n // logger.info(\"isSubAgent = \" + isSubAgent)\n\n state.lastCompaction = findLastCompactionTimestamp(messages)\n state.currentTurn = countTurns(state, messages)\n state.nudges.turnNudgeAnchors = collectTurnNudgeAnchors(messages)\n\n const persisted = await loadSessionState(sessionId, logger)\n if (persisted === null) {\n return\n }\n\n if (typeof persisted.manualMode === \"boolean\") {\n state.manualMode = persisted.manualMode ? \"active\" : false\n }\n\n state.prune.tools = loadPruneMap(persisted.prune.tools)\n state.prune.messages = loadPruneMessagesState(persisted.prune.messages)\n state.nudges.contextLimitAnchors = new Set<string>(persisted.nudges.contextLimitAnchors || [])\n state.nudges.turnNudgeAnchors = new Set<string>([\n ...state.nudges.turnNudgeAnchors,\n ...(persisted.nudges.turnNudgeAnchors || []),\n ])\n state.nudges.iterationNudgeAnchors = new Set<string>(\n persisted.nudges.iterationNudgeAnchors || [],\n )\n state.stats = {\n pruneTokenCounter: persisted.stats?.pruneTokenCounter || 0,\n totalPruneTokens: persisted.stats?.totalPruneTokens || 0,\n compressionUsage: normalizeCompressionUsageTotals(persisted.stats?.compressionUsage),\n }\n\n const applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\n}\n\nexport async function refreshManualMode(\n state: SessionState,\n sessionId: string,\n logger: Logger,\n manualModeDefault: boolean,\n): Promise<void> {\n if (state.manualMode === \"compress-pending\") {\n return\n }\n\n const persisted = await loadManualModeSetting(sessionId, logger)\n const enabled = persisted ?? manualModeDefault\n state.manualMode = enabled ? \"active\" : false\n}\n","import type { SessionState, ToolStatus, WithParts } from \"./index\"\nimport type { Logger } from \"../logger\"\nimport { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"./utils\"\nimport { countToolTokens } from \"../token-utils\"\n\nconst MAX_TOOL_CACHE_SIZE = 1000\n\n/**\n * Sync tool parameters from session messages.\n */\nexport function syncToolCache(\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n): void {\n try {\n logger.info(\"Syncing tool parameters from OpenCode messages\")\n\n let turnCounter = 0\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCounter++\n continue\n }\n\n if (part.type !== \"tool\" || !part.callID) {\n continue\n }\n\n const turnProtectionEnabled = config.turnProtection.enabled\n const turnProtectionTurns = config.turnProtection.turns\n const isProtectedByTurn =\n turnProtectionEnabled &&\n turnProtectionTurns > 0 &&\n state.currentTurn - turnCounter < turnProtectionTurns\n\n if (state.toolParameters.has(part.callID)) {\n continue\n }\n\n if (isProtectedByTurn) {\n continue\n }\n\n const tokenCount = countToolTokens(part)\n\n state.toolParameters.set(part.callID, {\n tool: part.tool,\n parameters: part.state?.input ?? {},\n metadata: \"metadata\" in part.state ? part.state.metadata : undefined,\n status: part.state.status as ToolStatus | undefined,\n error: part.state.status === \"error\" ? part.state.error : undefined,\n turn: turnCounter,\n tokenCount,\n })\n logger.info(\n `Cached tool id: ${part.callID} (turn ${turnCounter}${tokenCount !== undefined ? `, ${tokenCount} tokens` : \"\"})`,\n )\n }\n }\n\n logger.info(\n `Synced cache - size: ${state.toolParameters.size}, currentTurn: ${state.currentTurn}`,\n )\n trimToolParametersCache(state)\n } catch (error) {\n logger.warn(\"Failed to sync tool parameters from OpenCode\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/**\n * Trim the tool parameters cache to prevent unbounded memory growth.\n * Uses FIFO eviction - removes oldest entries first.\n */\nexport function trimToolParametersCache(state: SessionState): void {\n if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {\n return\n }\n\n const keysToRemove = Array.from(state.toolParameters.keys()).slice(\n 0,\n state.toolParameters.size - MAX_TOOL_CACHE_SIZE,\n )\n\n for (const key of keysToRemove) {\n state.toolParameters.delete(key)\n }\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { formatBlockRef, parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../messages/query\"\nimport { filterMessages } from \"../messages/shape\"\nimport { countAllMessageTokens } from \"../token-utils\"\nimport type { BoundaryReference, SearchContext, SelectionResolution } from \"./types\"\n\nexport async function fetchSessionMessages(client: any, sessionId: string): Promise<WithParts[]> {\n const response = await client.session.messages({\n path: { id: sessionId },\n })\n\n return filterMessages(response?.data || response)\n}\n\nexport function buildSearchContext(state: SessionState, rawMessages: WithParts[]): SearchContext {\n const rawMessagesById = new Map<string, WithParts>()\n const rawIndexById = new Map<string, number>()\n for (const msg of rawMessages) {\n rawMessagesById.set(msg.info.id, msg)\n }\n for (let index = 0; index < rawMessages.length; index++) {\n const message = rawMessages[index]\n if (!message) {\n continue\n }\n rawIndexById.set(message.info.id, index)\n }\n\n const summaryByBlockId = new Map()\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (!block.active) {\n continue\n }\n summaryByBlockId.set(blockId, block)\n }\n\n return {\n rawMessages,\n rawMessagesById,\n rawIndexById,\n summaryByBlockId,\n }\n}\n\nexport function resolveBoundaryIds(\n context: SearchContext,\n state: SessionState,\n config: PluginConfig,\n startId: string,\n endId: string,\n): { startReference: BoundaryReference; endReference: BoundaryReference } {\n const lookup = buildBoundaryLookup(context, state, config)\n const issues: string[] = []\n const parsedStartId = parseBoundaryId(startId, state.idFormat)\n const parsedEndId = parseBoundaryId(endId, state.idFormat)\n const messageExample = state.idFormat === \"compact\" ? \"@4@\" : \"mNNNN\"\n const blockExample = state.idFormat === \"compact\" ? \"@b1@\" : \"bN\"\n\n if (parsedStartId === null) {\n issues.push(\n `startId is invalid. Use an injected message ID (${messageExample}) or block ID (${blockExample}).`,\n )\n }\n\n if (parsedEndId === null) {\n issues.push(\n `endId is invalid. Use an injected message ID (${messageExample}) or block ID (${blockExample}).`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!parsedStartId || !parsedEndId) {\n throw new Error(\"Invalid boundary ID(s)\")\n }\n\n const startReference = lookup.get(parsedStartId.ref)\n const endReference = lookup.get(parsedEndId.ref)\n\n if (!startReference) {\n issues.push(\n `startId ${parsedStartId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (!endReference) {\n issues.push(\n `endId ${parsedEndId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!startReference || !endReference) {\n throw new Error(\"Failed to resolve boundary IDs\")\n }\n\n if (startReference.rawIndex > endReference.rawIndex) {\n throw new Error(\n `startId ${parsedStartId.ref} appears after endId ${parsedEndId.ref} in the conversation. Start must come before end.`,\n )\n }\n\n return { startReference, endReference }\n}\n\nexport function resolveSelection(\n context: SearchContext,\n config: PluginConfig,\n startReference: BoundaryReference,\n endReference: BoundaryReference,\n): SelectionResolution {\n const startRawIndex = startReference.rawIndex\n const endRawIndex = endReference.rawIndex\n const messageIds: string[] = []\n const messageSeen = new Set<string>()\n const toolIds: string[] = []\n const toolSeen = new Set<string>()\n const requiredBlockIds: number[] = []\n const requiredBlockSeen = new Set<number>()\n const messageTokenById = new Map<string, number>()\n\n for (let index = startRawIndex; index <= endRawIndex; index++) {\n const rawMessage = context.rawMessages[index]\n if (!rawMessage) {\n continue\n }\n if (isIgnoredUserMessage(rawMessage) || isProtectedUserMessage(config, rawMessage)) {\n continue\n }\n\n const messageId = rawMessage.info.id\n if (!messageSeen.has(messageId)) {\n messageSeen.add(messageId)\n messageIds.push(messageId)\n }\n\n if (!messageTokenById.has(messageId)) {\n messageTokenById.set(messageId, countAllMessageTokens(rawMessage))\n }\n\n const parts = Array.isArray(rawMessage.parts) ? rawMessage.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\" || !part.callID) {\n continue\n }\n if (toolSeen.has(part.callID)) {\n continue\n }\n toolSeen.add(part.callID)\n toolIds.push(part.callID)\n }\n }\n\n const selectedMessageIds = new Set(messageIds)\n const summariesInSelection: Array<{ blockId: number; rawIndex: number }> = []\n for (const summary of context.summaryByBlockId.values()) {\n if (!selectedMessageIds.has(summary.anchorMessageId)) {\n continue\n }\n\n const anchorIndex = context.rawIndexById.get(summary.anchorMessageId)\n if (anchorIndex === undefined) {\n continue\n }\n\n summariesInSelection.push({\n blockId: summary.blockId,\n rawIndex: anchorIndex,\n })\n }\n\n summariesInSelection.sort((a, b) => a.rawIndex - b.rawIndex || a.blockId - b.blockId)\n for (const summary of summariesInSelection) {\n if (requiredBlockSeen.has(summary.blockId)) {\n continue\n }\n requiredBlockSeen.add(summary.blockId)\n requiredBlockIds.push(summary.blockId)\n }\n\n if (messageIds.length === 0) {\n throw new Error(\n \"Failed to map boundary matches back to raw messages. Choose boundaries that include original conversation messages.\",\n )\n }\n\n return {\n startReference,\n endReference,\n messageIds,\n messageTokenById,\n toolIds,\n requiredBlockIds,\n }\n}\n\nexport function resolveAnchorMessageId(startReference: BoundaryReference): string {\n if (startReference.kind === \"compressed-block\") {\n if (!startReference.anchorMessageId) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n return startReference.anchorMessageId\n }\n\n if (!startReference.messageId) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n return startReference.messageId\n}\n\nfunction buildBoundaryLookup(\n context: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): Map<string, BoundaryReference> {\n const lookup = new Map<string, BoundaryReference>()\n\n for (const [messageRef, messageId] of state.messageIds.byRef) {\n const rawMessage = context.rawMessagesById.get(messageId)\n if (!rawMessage) {\n continue\n }\n if (isIgnoredUserMessage(rawMessage) || isProtectedUserMessage(config, rawMessage)) {\n continue\n }\n\n const rawIndex = context.rawIndexById.get(messageId)\n if (rawIndex === undefined) {\n continue\n }\n lookup.set(messageRef, {\n kind: \"message\",\n rawIndex,\n messageId,\n })\n }\n\n const summaries = Array.from(context.summaryByBlockId.values()).sort(\n (a, b) => a.blockId - b.blockId,\n )\n for (const summary of summaries) {\n const anchorMessage = context.rawMessagesById.get(summary.anchorMessageId)\n if (!anchorMessage) {\n continue\n }\n if (isIgnoredUserMessage(anchorMessage)) {\n continue\n }\n\n const rawIndex = context.rawIndexById.get(summary.anchorMessageId)\n if (rawIndex === undefined) {\n continue\n }\n const blockRef = formatBlockRef(summary.blockId, state.idFormat)\n if (!lookup.has(blockRef)) {\n lookup.set(blockRef, {\n kind: \"compressed-block\",\n rawIndex,\n blockId: summary.blockId,\n anchorMessageId: summary.anchorMessageId,\n })\n }\n }\n\n return lookup\n}\n","function normalizePath(input: string): string {\n // A single backslash. In source, \"\\\\\" is the one-character string; the\n // previous \"\\\\\\\\\" was a *two*-character string, so it only ever matched a\n // doubled separator -- which a real Windows path does not contain. The\n // normalisation was therefore a no-op on the only platform that needs it.\n return input.replaceAll(\"\\\\\", \"/\")\n}\n\nfunction escapeRegExpChar(ch: string): string {\n return /[\\\\.^$+{}()|\\[\\]]/.test(ch) ? `\\\\${ch}` : ch\n}\n\nexport function matchesGlob(inputPath: string, pattern: string): boolean {\n if (!pattern) return false\n\n const input = normalizePath(inputPath)\n const pat = normalizePath(pattern)\n\n let regex = \"^\"\n\n for (let i = 0; i < pat.length; i++) {\n const ch = pat[i]\n\n if (ch === \"*\") {\n const next = pat[i + 1]\n if (next === \"*\") {\n const after = pat[i + 2]\n if (after === \"/\") {\n // **/ (zero or more directories)\n regex += \"(?:.*/)?\"\n i += 2\n continue\n }\n\n // **\n regex += \".*\"\n i++\n continue\n }\n\n // *\n regex += \"[^/]*\"\n continue\n }\n\n if (ch === \"?\") {\n regex += \"[^/]\"\n continue\n }\n\n if (ch === \"/\") {\n regex += \"/\"\n continue\n }\n\n regex += escapeRegExpChar(ch)\n }\n\n regex += \"$\"\n\n return new RegExp(regex).test(input)\n}\n\nexport function getFilePathsFromParameters(tool: string, parameters: unknown): string[] {\n if (typeof parameters !== \"object\" || parameters === null) {\n return []\n }\n\n const paths: string[] = []\n const params = parameters as Record<string, any>\n\n // 1. apply_patch uses patchText with embedded paths\n if ((tool === \"apply_patch\" || tool === \"patch\") && typeof params.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n let match\n while ((match = pathRegex.exec(params.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n }\n\n // 2. multiedit uses top-level filePath and nested edits array\n if (tool === \"multiedit\") {\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n if (Array.isArray(params.edits)) {\n for (const edit of params.edits) {\n if (edit && typeof edit.filePath === \"string\") {\n paths.push(edit.filePath)\n }\n }\n }\n }\n\n // 3. Default check for common filePath parameter (read, write, edit, etc)\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n\n // V2 file tools use path rather than filePath.\n if ([\"read\", \"write\", \"edit\"].includes(tool) && typeof params.path === \"string\") {\n paths.push(params.path)\n }\n\n // Return unique non-empty paths\n return [...new Set(paths)].filter((p) => p.length > 0)\n}\n\nexport function isFilePathProtected(filePaths: string[], patterns: string[]): boolean {\n if (!filePaths || filePaths.length === 0) return false\n if (!patterns || patterns.length === 0) return false\n\n return filePaths.some((path) => patterns.some((pattern) => matchesGlob(path, pattern)))\n}\n\nconst GLOB_CHARS = /[*?]/\n\nexport function isToolNameProtected(toolName: string, patterns: string[]): boolean {\n if (!toolName || !patterns || patterns.length === 0) return false\n\n const exactPatterns: Set<string> = new Set()\n const globPatterns: string[] = []\n\n for (const pattern of patterns) {\n if (GLOB_CHARS.test(pattern)) {\n globPatterns.push(pattern)\n } else {\n exactPatterns.add(pattern)\n }\n }\n\n if (exactPatterns.has(toolName)) {\n return true\n }\n\n return globPatterns.some((pattern) => matchesGlob(toolName, pattern))\n}\n\nexport function isToolProtected(\n tool: string,\n input: unknown,\n tools: string[],\n files: string[],\n metadata?: Record<string, unknown>,\n): boolean {\n const calls = [{ tool, input }]\n // V2 Code Mode keeps nested inputs, but only one combined output. Protect\n // that output as a whole when any nested call matches the user's rules.\n if (tool === \"execute\" && Array.isArray(metadata?.toolCalls)) {\n for (const call of metadata.toolCalls) {\n if (call && typeof call.tool === \"string\") calls.push(call)\n }\n }\n return calls.some(\n (call) =>\n isToolNameProtected(call.tool, tools) ||\n isFilePathProtected(getFilePathsFromParameters(call.tool, call.input), files),\n )\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isToolProtected } from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Deduplication strategy - prunes older tool calls that have identical\n * tool name and parameters, keeping only the most recent occurrence.\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const deduplicate = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.deduplication.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.deduplication.protectedTools\n\n // Group by signature (tool name + normalized parameters)\n const signatureMap = new Map<string, string[]>()\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n // logger.warn(`Missing metadata for tool call ID: ${id}`)\n continue\n }\n\n if (\n isToolProtected(\n metadata.tool,\n metadata.parameters,\n protectedTools,\n config.protectedFilePatterns,\n metadata.metadata,\n )\n ) {\n continue\n }\n\n const signature = createToolSignature(metadata.tool, metadata.parameters)\n if (!signatureMap.has(signature)) {\n signatureMap.set(signature, [])\n }\n const ids = signatureMap.get(signature)\n if (ids) {\n ids.push(id)\n }\n }\n\n // Find duplicates - keep only the most recent (last) in each group\n const newPruneIds: string[] = []\n\n for (const [, ids] of signatureMap.entries()) {\n if (ids.length > 1) {\n // All except last (most recent) should be pruned\n const idsToRemove = ids.slice(0, -1)\n newPruneIds.push(...idsToRemove)\n }\n }\n\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n\n if (newPruneIds.length > 0) {\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(`Marked ${newPruneIds.length} duplicate tool calls for pruning`)\n }\n}\n\nfunction createToolSignature(tool: string, parameters?: any): string {\n if (!parameters) {\n return tool\n }\n const normalized = normalizeParameters(parameters)\n const sorted = sortObjectKeys(normalized)\n return `${tool}::${JSON.stringify(sorted)}`\n}\n\nfunction normalizeParameters(params: any): any {\n if (typeof params !== \"object\" || params === null) return params\n if (Array.isArray(params)) return params\n\n const normalized: any = {}\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n normalized[key] = value\n }\n }\n return normalized\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj !== \"object\" || obj === null) return obj\n if (Array.isArray(obj)) return obj.map(sortObjectKeys)\n\n const sorted: any = {}\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortObjectKeys(obj[key])\n }\n return sorted\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isToolProtected } from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Purge Errors strategy - prunes tool inputs for tools that errored\n * after they are older than a configurable number of turns.\n * The error message is preserved, but the (potentially large) inputs\n * are removed to save context.\n *\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const purgeErrors = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.purgeErrors.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.purgeErrors.protectedTools\n const turnThreshold = Math.max(1, config.strategies.purgeErrors.turns)\n\n const newPruneIds: string[] = []\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n continue\n }\n\n if (\n isToolProtected(\n metadata.tool,\n metadata.parameters,\n protectedTools,\n config.protectedFilePatterns,\n metadata.metadata,\n )\n ) {\n continue\n }\n\n // Only process error tools\n if (metadata.status !== \"error\") {\n continue\n }\n\n // Check if the tool is old enough to prune\n const turnAge = state.currentTurn - metadata.turn\n if (turnAge >= turnThreshold) {\n newPruneIds.push(id)\n }\n }\n\n if (newPruneIds.length > 0) {\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(\n `Marked ${newPruneIds.length} error tool calls for pruning (older than ${turnThreshold} turns)`,\n )\n }\n}\n","import { SessionState, ToolParameterEntry, WithParts } from \"../state\"\nimport { countTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nfunction extractParameterKey(tool: string, parameters: any): string {\n if (!parameters) return \"\"\n\n if (tool === \"read\" && parameters.filePath) {\n const offset = parameters.offset\n const limit = parameters.limit\n if (offset !== undefined && limit !== undefined) {\n return `${parameters.filePath} (lines ${offset}-${offset + limit})`\n }\n if (offset !== undefined) {\n return `${parameters.filePath} (lines ${offset}+)`\n }\n if (limit !== undefined) {\n return `${parameters.filePath} (lines 0-${limit})`\n }\n return parameters.filePath\n }\n\n if ((tool === \"write\" || tool === \"edit\" || tool === \"multiedit\") && parameters.filePath) {\n return parameters.filePath\n }\n\n if (tool === \"apply_patch\" && typeof parameters.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n const paths: string[] = []\n let match\n while ((match = pathRegex.exec(parameters.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n if (paths.length > 0) {\n const uniquePaths = [...new Set(paths)]\n const count = uniquePaths.length\n const plural = count > 1 ? \"s\" : \"\"\n if (count === 1) return uniquePaths[0]\n if (count === 2) return uniquePaths.join(\", \")\n return `${count} file${plural}: ${uniquePaths[0]}, ${uniquePaths[1]}...`\n }\n return \"patch\"\n }\n\n if (tool === \"list\") {\n return parameters.path || \"(current directory)\"\n }\n\n if (tool === \"glob\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"grep\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"bash\") {\n if (parameters.description) return parameters.description\n if (parameters.command) {\n return parameters.command.length > 50\n ? parameters.command.substring(0, 50) + \"...\"\n : parameters.command\n }\n }\n\n if (tool === \"webfetch\" && parameters.url) {\n return parameters.url\n }\n if (tool === \"websearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n if (tool === \"codesearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n\n if (tool === \"todowrite\") {\n return `${parameters.todos?.length || 0} todos`\n }\n if (tool === \"todoread\") {\n return \"read todo list\"\n }\n\n if (tool === \"task\" && parameters.description) {\n return parameters.description\n }\n if (tool === \"skill\" && parameters.name) {\n return parameters.name\n }\n\n if (tool === \"lsp\") {\n const op = parameters.operation || \"lsp\"\n const path = parameters.filePath || \"\"\n const line = parameters.line\n const char = parameters.character\n if (path && line !== undefined && char !== undefined) {\n return `${op} ${path}:${line}:${char}`\n }\n if (path) {\n return `${op} ${path}`\n }\n return op\n }\n\n if (tool === \"question\") {\n const questions = parameters.questions\n if (Array.isArray(questions) && questions.length > 0) {\n const headers = questions\n .map((q: any) => q.header || \"\")\n .filter(Boolean)\n .slice(0, 3)\n\n const count = questions.length\n const plural = count > 1 ? \"s\" : \"\"\n\n if (headers.length > 0) {\n const suffix = count > 3 ? ` (+${count - 3} more)` : \"\"\n return `${count} question${plural}: ${headers.join(\", \")}${suffix}`\n }\n return `${count} question${plural}`\n }\n return \"question\"\n }\n\n const paramStr = JSON.stringify(parameters)\n if (paramStr === \"{}\" || paramStr === \"[]\" || paramStr === \"null\") {\n return \"\"\n }\n\n return paramStr.substring(0, 50)\n}\n\nexport function formatStatsHeader(totalTokensSaved: number, pruneTokenCounter: number): string {\n const totalTokensSavedStr = `~${formatTokenCount(totalTokensSaved + pruneTokenCounter)}`\n return [`▣ DCP | ${totalTokensSavedStr} saved total`].join(\"\\n\")\n}\n\nexport function formatTokenCount(tokens: number, compact?: boolean): string {\n const suffix = compact ? \"\" : \" tokens\"\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}K`.replace(\".0K\", \"K\") + suffix\n }\n return tokens.toString() + suffix\n}\n\nexport function truncate(str: string, maxLen: number = 60): string {\n if (str.length <= maxLen) return str\n return str.slice(0, maxLen - 3) + \"...\"\n}\n\nexport function formatProgressBar(\n messageIds: string[],\n prunedMessages: Map<string, number>,\n recentMessageIds: string[],\n width: number = 50,\n): string {\n const ACTIVE = \"█\"\n const PRUNED = \"░\"\n const RECENT = \"⣿\"\n const recentSet = new Set(recentMessageIds)\n\n const total = messageIds.length\n if (total === 0) return `│${PRUNED.repeat(width)}│`\n\n const bar = new Array(width).fill(ACTIVE)\n\n for (let m = 0; m < total; m++) {\n const msgId = messageIds[m]\n const start = Math.floor((m / total) * width)\n const end = Math.floor(((m + 1) / total) * width)\n\n if (recentSet.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = RECENT\n }\n } else if (prunedMessages.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = PRUNED\n }\n }\n }\n\n return `│${bar.join(\"\")}│`\n}\n\nexport function cacheSystemPromptTokens(state: SessionState, messages: WithParts[]): void {\n let firstInputTokens = 0\n for (const msg of messages) {\n if (msg.info.role !== \"assistant\") {\n continue\n }\n const info = msg.info as any\n const input = info?.tokens?.input || 0\n const cacheRead = info?.tokens?.cache?.read || 0\n const cacheWrite = info?.tokens?.cache?.write || 0\n if (input > 0 || cacheRead > 0 || cacheWrite > 0) {\n firstInputTokens = input + cacheRead + cacheWrite\n break\n }\n }\n\n if (firstInputTokens <= 0) {\n state.systemPromptTokens = undefined\n return\n }\n\n let firstUserText = \"\"\n for (const msg of messages) {\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && !(part as any).ignored) {\n firstUserText += part.text\n }\n }\n break\n }\n\n const estimatedSystemTokens = Math.max(0, firstInputTokens - countTokens(firstUserText))\n state.systemPromptTokens = estimatedSystemTokens > 0 ? estimatedSystemTokens : undefined\n}\n\nexport function shortenPath(input: string, workingDirectory?: string): string {\n const inPathMatch = input.match(/^(.+) in (.+)$/)\n if (inPathMatch) {\n const prefix = inPathMatch[1]\n const pathPart = inPathMatch[2]\n const shortenedPath = shortenSinglePath(pathPart, workingDirectory)\n return `${prefix} in ${shortenedPath}`\n }\n\n return shortenSinglePath(input, workingDirectory)\n}\n\nfunction shortenSinglePath(path: string, workingDirectory?: string): string {\n if (workingDirectory) {\n if (path.startsWith(workingDirectory + \"/\")) {\n return path.slice(workingDirectory.length + 1)\n }\n if (path === workingDirectory) {\n return \".\"\n }\n }\n\n return path\n}\n\nexport function formatPrunedItemsList(\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string[] {\n const lines: string[] = []\n\n for (const id of pruneToolIds) {\n const metadata = toolMetadata.get(id)\n\n if (metadata) {\n const paramKey = extractParameterKey(metadata.tool, metadata.parameters)\n if (paramKey) {\n // Use 60 char limit to match notification style\n const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60)\n lines.push(`→ ${metadata.tool}: ${displayKey}`)\n } else {\n lines.push(`→ ${metadata.tool}`)\n }\n }\n }\n\n const knownCount = pruneToolIds.filter((id) => toolMetadata.has(id)).length\n const unknownCount = pruneToolIds.length - knownCount\n\n if (unknownCount > 0) {\n lines.push(`→ (${unknownCount} tool${unknownCount > 1 ? \"s\" : \"\"} with unknown metadata)`)\n }\n\n return lines\n}\n\nexport function formatPruningResultForTool(\n prunedIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string {\n const lines: string[] = []\n lines.push(`Context pruning complete. Pruned ${prunedIds.length} tool outputs.`)\n lines.push(\"\")\n\n if (prunedIds.length > 0) {\n lines.push(`Semantically pruned (${prunedIds.length}):`)\n lines.push(...formatPrunedItemsList(prunedIds, toolMetadata, workingDirectory))\n }\n\n return lines.join(\"\\n\").trim()\n}\n","import type { Logger } from \"../logger\"\nimport type { SessionState } from \"../state\"\nimport {\n formatPrunedItemsList,\n formatProgressBar,\n formatStatsHeader,\n formatTokenCount,\n} from \"./utils\"\nimport { ToolParameterEntry } from \"../state\"\nimport { PluginConfig } from \"../config\"\nimport { getActiveSummaryTokenUsage } from \"../state/utils\"\n\nexport type PruneReason = \"completion\" | \"noise\" | \"extraction\"\nexport const PRUNE_REASON_LABELS: Record<PruneReason, string> = {\n completion: \"Task Complete\",\n noise: \"Noise Removal\",\n extraction: \"Extraction\",\n}\n\ninterface CompressionNotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nfunction buildMinimalMessage(state: SessionState, reason: PruneReason | undefined): string {\n const reasonSuffix = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n return (\n formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter) +\n reasonSuffix\n )\n}\n\nfunction buildDetailedMessage(\n state: SessionState,\n reason: PruneReason | undefined,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory: string,\n): string {\n let message = formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter)\n\n if (pruneToolIds.length > 0) {\n const pruneTokenCounterStr = `~${formatTokenCount(state.stats.pruneTokenCounter)}`\n const reasonLabel = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n message += `\\n\\n▣ Pruning (${pruneTokenCounterStr})${reasonLabel}`\n\n const itemLines = formatPrunedItemsList(pruneToolIds, toolMetadata, workingDirectory)\n message += \"\\n\" + itemLines.join(\"\\n\")\n }\n\n return message.trim()\n}\n\nconst TOAST_BODY_MAX_LINES = 12\nconst TOAST_SUMMARY_MAX_CHARS = 600\n\nfunction truncateToastBody(body: string, maxLines: number = TOAST_BODY_MAX_LINES): string {\n const lines = body.split(\"\\n\")\n if (lines.length <= maxLines) {\n return body\n }\n const kept = lines.slice(0, maxLines - 1)\n const remaining = lines.length - maxLines + 1\n return kept.join(\"\\n\") + `\\n... and ${remaining} more`\n}\n\nfunction truncateToastSummary(summary: string, maxChars: number = TOAST_SUMMARY_MAX_CHARS): string {\n if (summary.length <= maxChars) {\n return summary\n }\n return summary.slice(0, maxChars - 3) + \"...\"\n}\n\nfunction truncateExtractedSection(\n message: string,\n maxChars: number = TOAST_SUMMARY_MAX_CHARS,\n): string {\n const marker = \"\\n\\n▣ Extracted\"\n const index = message.indexOf(marker)\n if (index === -1) {\n return message\n }\n const extracted = message.slice(index)\n if (extracted.length <= maxChars) {\n return message\n }\n return message.slice(0, index) + truncateToastSummary(extracted, maxChars)\n}\n\nexport async function sendUnifiedNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n reason: PruneReason | undefined,\n params: any,\n workingDirectory: string,\n): Promise<boolean> {\n const hasPruned = pruneToolIds.length > 0\n if (!hasPruned) {\n return false\n }\n\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n const message =\n config.pruneNotification === \"minimal\"\n ? buildMinimalMessage(state, reason)\n : buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory)\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = truncateExtractedSection(message)\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nfunction buildCompressionSummary(\n entries: CompressionNotificationEntry[],\n state: SessionState,\n): string {\n if (entries.length === 1) {\n return entries[0]?.summary ?? \"\"\n }\n\n return entries\n .map((entry) => {\n const topic =\n state.prune.messages.blocksById.get(entry.blockId)?.topic ?? \"(unknown topic)\"\n return `### ${topic}\\n${entry.summary}`\n })\n .join(\"\\n\\n\")\n}\n\nfunction getCompressionLabel(entries: CompressionNotificationEntry[]): string {\n const runId = entries[0]?.runId\n if (runId === undefined) {\n return \"Compression\"\n }\n\n return `Compression #${runId}`\n}\n\nfunction formatCompressionMetrics(removedTokens: number, summaryTokens: number): string {\n const metrics = [`-${formatTokenCount(removedTokens, true)} removed`]\n if (summaryTokens > 0) {\n metrics.push(`+${formatTokenCount(summaryTokens, true)} summary`)\n }\n return metrics.join(\", \")\n}\n\nexport async function sendCompressNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n entries: CompressionNotificationEntry[],\n batchTopic: string | undefined,\n sessionMessageIds: string[],\n params: any,\n): Promise<boolean> {\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n if (entries.length === 0) {\n return false\n }\n\n let message: string\n const compressionLabel = getCompressionLabel(entries)\n const summary = buildCompressionSummary(entries, state)\n const summaryTokens = entries.reduce((total, entry) => total + entry.summaryTokens, 0)\n const summaryTokensStr = formatTokenCount(summaryTokens)\n const compressedTokens = entries.reduce((total, entry) => {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n logger.error(\"Compression block missing for notification\", {\n compressionId: entry.blockId,\n sessionId,\n })\n return total\n }\n\n return total + compressionBlock.compressedTokens\n }, 0)\n\n const newlyCompressedMessageIds: string[] = []\n const newlyCompressedToolIds: string[] = []\n const seenMessageIds = new Set<string>()\n const seenToolIds = new Set<string>()\n\n for (const entry of entries) {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n continue\n }\n\n for (const messageId of compressionBlock.directMessageIds) {\n if (seenMessageIds.has(messageId)) {\n continue\n }\n seenMessageIds.add(messageId)\n newlyCompressedMessageIds.push(messageId)\n }\n\n for (const toolId of compressionBlock.directToolIds) {\n if (seenToolIds.has(toolId)) {\n continue\n }\n seenToolIds.add(toolId)\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n const topic =\n batchTopic ??\n (entries.length === 1\n ? (state.prune.messages.blocksById.get(entries[0]?.blockId ?? -1)?.topic ??\n \"(unknown topic)\")\n : \"(unknown topic)\")\n\n const totalActiveSummaryTkns = getActiveSummaryTokenUsage(state)\n const totalGross = state.stats.totalPruneTokens + state.stats.pruneTokenCounter\n const notificationHeader = `▣ DCP | ${formatCompressionMetrics(totalGross, totalActiveSummaryTkns)}`\n\n if (config.pruneNotification === \"minimal\") {\n message = `${notificationHeader} — ${compressionLabel}`\n } else {\n message = notificationHeader\n\n const activePrunedMessages = new Map<string, number>()\n for (const [messageId, entry] of state.prune.messages.byMessageId) {\n if (entry.activeBlockIds.length > 0) {\n activePrunedMessages.set(messageId, entry.tokenCount)\n }\n }\n const progressBar = formatProgressBar(\n sessionMessageIds,\n activePrunedMessages,\n newlyCompressedMessageIds,\n 50,\n )\n message += `\\n\\n${progressBar}`\n message += `\\n▣ ${compressionLabel} ${formatCompressionMetrics(compressedTokens, summaryTokens)}`\n message += `\\n→ Topic: ${topic}`\n message += `\\n→ Items: ${newlyCompressedMessageIds.length} messages`\n if (newlyCompressedToolIds.length > 0) {\n message += ` and ${newlyCompressedToolIds.length} tools compressed`\n } else {\n message += ` compressed`\n }\n if (config.compress.showCompression) {\n message += `\\n→ Compression (~${summaryTokensStr}): ${summary}`\n }\n }\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = message\n if (config.compress.showCompression) {\n const truncatedSummary = truncateToastSummary(summary)\n if (truncatedSummary !== summary) {\n toastMessage = toastMessage.replace(\n `\\n→ Compression (~${summaryTokensStr}): ${summary}`,\n `\\n→ Compression (~${summaryTokensStr}): ${truncatedSummary}`,\n )\n }\n }\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nexport async function sendIgnoredMessage(\n client: any,\n sessionID: string,\n text: string,\n params: any,\n logger: Logger,\n): Promise<void> {\n const agent = params.agent || undefined\n const variant = params.variant || undefined\n const model =\n params.providerId && params.modelId\n ? {\n providerID: params.providerId,\n modelID: params.modelId,\n }\n : undefined\n\n try {\n await client.session.prompt({\n path: {\n id: sessionID,\n },\n body: {\n noReply: true,\n agent: agent,\n model: model,\n variant: variant,\n parts: [\n {\n type: \"text\",\n text: text,\n ignored: true,\n },\n ],\n },\n })\n } catch (error: any) {\n logger.error(\"Failed to send notification\", { error: error.message })\n }\n}\n","import type { WithParts } from \"../state\"\nimport { ensureSessionInitialized, refreshManualMode } from \"../state\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { assignMessageRefs } from \"../message-ids\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { deduplicate, purgeErrors } from \"../strategies\"\nimport { getCurrentParams, getCurrentTokenUsage } from \"../token-utils\"\nimport { sendCompressNotification } from \"../ui/notification\"\nimport type { ToolContext } from \"./types\"\nimport { buildSearchContext, fetchSessionMessages } from \"./search\"\nimport type { SearchContext } from \"./types\"\nimport { applyPendingCompressionDurations } from \"./timing\"\n\ninterface RunContext {\n ask(input: {\n permission: string\n patterns: string[]\n always: string[]\n metadata: Record<string, unknown>\n }): Promise<void>\n metadata(input: { title: string }): void\n sessionID: string\n}\n\nexport interface NotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nexport interface PreparedSession {\n rawMessages: WithParts[]\n searchContext: SearchContext\n}\n\nexport async function prepareSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n title: string,\n): Promise<PreparedSession> {\n await refreshManualMode(ctx.state, toolCtx.sessionID, ctx.logger, ctx.config.manualMode.enabled)\n\n if (ctx.state.manualMode && ctx.state.manualMode !== \"compress-pending\") {\n throw new Error(\n \"Manual mode: compress blocked. Do not retry until `<compress triggered manually>` appears in user context.\",\n )\n }\n\n await toolCtx.ask({\n permission: \"compress\",\n patterns: [\"*\"],\n always: [\"*\"],\n metadata: {},\n })\n\n toolCtx.metadata({ title })\n\n const rawMessages = await fetchSessionMessages(ctx.client, toolCtx.sessionID)\n\n await ensureSessionInitialized(\n ctx.client,\n ctx.state,\n toolCtx.sessionID,\n ctx.logger,\n rawMessages,\n ctx.config.manualMode.enabled,\n )\n\n assignMessageRefs(ctx.state, rawMessages)\n\n deduplicate(ctx.state, ctx.logger, ctx.config, rawMessages)\n purgeErrors(ctx.state, ctx.logger, ctx.config, rawMessages)\n\n return {\n rawMessages,\n searchContext: buildSearchContext(ctx.state, rawMessages),\n }\n}\n\nexport async function finalizeSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n rawMessages: WithParts[],\n entries: NotificationEntry[],\n batchTopic: string | undefined,\n): Promise<void> {\n if (ctx.state.manualMode === \"compress-pending\") {\n ctx.state.manualMode = false\n await refreshManualMode(\n ctx.state,\n toolCtx.sessionID,\n ctx.logger,\n ctx.config.manualMode.enabled,\n )\n }\n applyPendingCompressionDurations(ctx.state)\n await saveSessionState(ctx.state, ctx.logger)\n\n const params = getCurrentParams(ctx.state, rawMessages, ctx.logger)\n const sessionMessageIds = rawMessages\n .filter((msg) => !isIgnoredUserMessage(msg))\n .map((msg) => msg.info.id)\n\n await sendCompressNotification(\n ctx.client,\n ctx.logger,\n ctx.config,\n ctx.state,\n toolCtx.sessionID,\n entries,\n batchTopic,\n sessionMessageIds,\n params,\n )\n}\n","// These format schemas are kept separate from the editable compress prompts\n// so they cannot be modified via custom prompt overrides. The schemas must\n// match the tool's input validation and are not safe to change independently.\n\nimport type { IdFormat } from \"../../message-ids\"\n\nexport function rcFormat(format: IdFormat = \"xml\"): string {\n const single = format === \"compact\" ? \"@4@\" : \"m0004\"\n const block = format === \"compact\" ? \"@b2@\" : \"b2\"\n const range = format === \"compact\" ? \"@4@-@8@\" : \"m0004-m0008\"\n return `\nTHE FORMAT OF COMPRESS\n\n\\`\\`\\`\n{\n ids: string[] // Injected message IDs, block IDs, or inclusive ranges; each item becomes one summary\n}\n\\`\\`\\`\n\nExamples: \\`{\"ids\": [\"${range}\", \"${single}\"]}\\` creates one summary for the range and a separate summary for the single message. \\`{\"ids\": [\"${block}\"]}\\` merges an existing compressed block into a new summary.`\n}\n","import type { WithParts } from \"../state\"\n\nconst SUB_AGENT_RESULT_BLOCK_REGEX =\n /(<(?:task_result|subagent\\b[^>]*)>\\s*)([\\s\\S]*?)(\\s*<\\/(?:task_result|subagent)>)/i\n\nexport function getSubAgentId(part: any): string | null {\n const sessionId = part?.state?.metadata?.sessionId ?? part?.state?.metadata?.sessionID\n if (typeof sessionId !== \"string\") {\n return null\n }\n\n const value = sessionId.trim()\n return value.length > 0 ? value : null\n}\n\nexport function buildSubagentResultText(messages: WithParts[]): string {\n const assistantMessages = messages.filter((message) => message.info.role === \"assistant\")\n if (assistantMessages.length === 0) {\n return \"\"\n }\n\n const lastAssistant = assistantMessages[assistantMessages.length - 1]\n const lastText = getLastTextPart(lastAssistant)\n\n if (assistantMessages.length < 2) {\n return lastText\n }\n\n const secondToLastAssistant = assistantMessages[assistantMessages.length - 2]\n if (!assistantMessageHasCompressTool(secondToLastAssistant)) {\n return lastText\n }\n\n const secondToLastText = getLastTextPart(secondToLastAssistant)\n return [secondToLastText, lastText].filter((text) => text.length > 0).join(\"\\n\\n\")\n}\n\nexport function mergeSubagentResult(output: string, subAgentResultText: string): string {\n if (!subAgentResultText || typeof output !== \"string\") {\n return output\n }\n\n return output.replace(\n SUB_AGENT_RESULT_BLOCK_REGEX,\n (_match, openTag: string, _body: string, closeTag: string) =>\n `${openTag}${subAgentResultText}${closeTag}`,\n )\n}\n\nfunction getLastTextPart(message: WithParts): string {\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (let index = parts.length - 1; index >= 0; index--) {\n const part = parts[index]\n if (part.type !== \"text\" || typeof part.text !== \"string\") {\n continue\n }\n\n const text = part.text.trim()\n if (!text) {\n continue\n }\n\n return text\n }\n\n return \"\"\n}\n\nfunction assistantMessageHasCompressTool(message: WithParts): boolean {\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n","import type { SessionState } from \"../state\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { isToolProtected } from \"../protected-patterns\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../subagents/subagent-results\"\nimport { fetchSessionMessages } from \"./search\"\nimport type { SearchContext, SelectionResolution } from \"./types\"\n\nexport function appendProtectedPromptInfo(\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n state: SessionState,\n enabled: boolean,\n): string {\n if (!enabled) return summary\n\n const protectedTexts: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n if (message.info.role !== \"user\") continue\n if (isIgnoredUserMessage(message)) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type !== \"text\" || typeof part.text !== \"string\") continue\n\n protectedTexts.push(...extractProtectedPromptInfo(part.text))\n }\n }\n\n if (protectedTexts.length === 0) {\n return summary\n }\n\n const heading =\n \"\\n\\nThe following protected prompt information was included in this conversation verbatim:\"\n const body = protectedTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\n\nexport function extractProtectedPromptInfo(text: string): string[] {\n const protectedTexts: string[] = []\n const protectTagRegex = /<protect>([\\s\\S]*?)<\\/protect>/gi\n\n for (const match of text.matchAll(protectTagRegex)) {\n const protectedText = match[1]?.trim()\n if (protectedText) {\n protectedTexts.push(protectedText)\n }\n }\n\n return protectedTexts\n}\n\nexport async function appendProtectedTools(\n client: any,\n state: SessionState,\n allowSubAgents: boolean,\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n protectedTools: string[],\n protectedFilePatterns: string[] = [],\n): Promise<string> {\n const protectedOutputs: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID) {\n if (\n isToolProtected(\n part.tool,\n part.state.input,\n protectedTools,\n protectedFilePatterns,\n \"metadata\" in part.state ? part.state.metadata : undefined,\n )\n ) {\n const title = `Tool: ${part.tool}`\n let output = \"\"\n\n if (part.state?.status === \"completed\" && part.state?.output) {\n output =\n typeof part.state.output === \"string\"\n ? part.state.output\n : JSON.stringify(part.state.output)\n }\n\n if (\n allowSubAgents &&\n (part.tool === \"task\" || part.tool === \"subagent\") &&\n part.state?.status === \"completed\" &&\n typeof part.state?.output === \"string\"\n ) {\n const cachedSubAgentResult = state.subAgentResultCache.get(part.callID)\n\n if (cachedSubAgentResult !== undefined) {\n if (cachedSubAgentResult) {\n output = mergeSubagentResult(\n part.state.output,\n cachedSubAgentResult,\n )\n }\n } else {\n const subAgentSessionId = getSubAgentId(part)\n if (subAgentSessionId) {\n let subAgentResultText = \"\"\n try {\n const subAgentMessages = await fetchSessionMessages(\n client,\n subAgentSessionId,\n )\n subAgentResultText = buildSubagentResultText(subAgentMessages)\n } catch {\n subAgentResultText = \"\"\n }\n\n if (subAgentResultText) {\n state.subAgentResultCache.set(part.callID, subAgentResultText)\n output = mergeSubagentResult(\n part.state.output,\n subAgentResultText,\n )\n }\n }\n }\n }\n\n if (output) {\n protectedOutputs.push(`\\n### ${title}\\n${output}`)\n }\n }\n }\n }\n }\n\n if (protectedOutputs.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following protected tools were used in this conversation as well:\"\n return summary + heading + protectedOutputs.join(\"\")\n}\n","import type { WithParts } from \"../state\"\nimport { formatBlockRef, formatMessageRef, parseBoundaryId, type IdFormat } from \"../message-ids\"\n\n/**\n * Marker embedded in the hidden summary prompt so the plugin can recognize its\n * own transient (`session.generate`) request and strip everything else from it.\n * Requests carry a per-call suffix (`[[DCP-RC-SUMMARY:<callId>]]`) so captured\n * provider usage can be attributed to a specific request.\n */\nexport const RC_SUMMARY_MARKER = \"[[DCP-RC-SUMMARY]]\"\n/** Prefix shared by the static marker and its per-call variant. */\nexport const RC_SUMMARY_MARKER_PREFIX = \"[[DCP-RC-SUMMARY\"\n\nfunction sanitizeCallId(callId: string): string {\n return callId.replace(/[^A-Za-z0-9_-]/g, \"-\")\n}\n\n/** Marker line for a hidden summary request, optionally tagged with a call id. */\nexport function buildSummaryMarker(callId?: string): string {\n if (!callId) {\n return RC_SUMMARY_MARKER\n }\n return `${RC_SUMMARY_MARKER_PREFIX}:${sanitizeCallId(callId)}]]`\n}\n\n/** True when the text contains a hidden summary marker, with or without a call id. */\nexport function hasSummaryMarker(text: string): boolean {\n return text.includes(RC_SUMMARY_MARKER_PREFIX)\n}\n\n/** Extract the call id from a hidden summary marker, when present. */\nexport function extractSummaryCallId(text: string): string | undefined {\n return text.match(/\\[\\[DCP-RC-SUMMARY:([A-Za-z0-9_-]+)\\]\\]/)?.[1]\n}\n\nexport interface PriorSummary {\n /** Canonical block reference, e.g. `b2` or `@b2@`. */\n ref: string\n /** Summary body with the block header/footer stripped. */\n body: string\n}\n\nexport interface SummarySegment {\n /** Canonical selector, e.g. `m0004`, `m0004-m0008`, or `b2-m0011`. */\n selector: string\n messages: WithParts[]\n /** Summaries of active blocks consumed by this selection. */\n priorSummaries?: PriorSummary[]\n}\n\nexport interface SummarySection {\n selector: string\n summary: string\n}\n\nexport interface ParsedSummarySections {\n sections: SummarySection[]\n missing: string[]\n duplicates: string[]\n empty: string[]\n}\n\nfunction stringify(value: unknown): string {\n if (typeof value === \"string\") {\n return value\n }\n try {\n return JSON.stringify(value, null, 2)\n } catch {\n return String(value)\n }\n}\n\nfunction readToolState(part: any): {\n status?: string\n input?: unknown\n output?: unknown\n error?: unknown\n} {\n const state = part?.state\n if (!state || typeof state !== \"object\") {\n return {}\n }\n return {\n status: typeof state.status === \"string\" ? state.status : undefined,\n input: state.input,\n output: state.output,\n error: state.error,\n }\n}\n\n/**\n * Serialize one conversation message into plain text for the hidden summary\n * request. Binary/file payloads are intentionally omitted.\n */\nexport function serializeMessageForSummary(message: WithParts, selector: string): string {\n const role = message.info?.role ?? \"unknown\"\n const lines: string[] = []\n const parts = Array.isArray(message.parts) ? message.parts : []\n\n for (const part of parts as any[]) {\n if (!part || typeof part !== \"object\") {\n continue\n }\n switch (part.type) {\n case \"text\":\n if (typeof part.text === \"string\" && part.text.length > 0) {\n lines.push(part.text)\n }\n break\n case \"reasoning\":\n if (typeof part.text === \"string\" && part.text.length > 0) {\n lines.push(`[reasoning] ${part.text}`)\n }\n break\n case \"tool\": {\n const state = readToolState(part)\n const name = part.tool ?? \"tool\"\n lines.push(`[tool_call ${name}] ${stringify(state.input)}`)\n if (state.status === \"completed\") {\n lines.push(`[tool_result ${name}] ${stringify(state.output)}`)\n } else if (state.status === \"error\") {\n lines.push(`[tool_error ${name}] ${stringify(state.error)}`)\n } else if (state.status) {\n lines.push(`[tool_${state.status} ${name}]`)\n }\n break\n }\n case \"file\":\n lines.push(`[file ${part.mime ?? \"\"} ${part.filename ?? part.url ?? \"\"}]`.trim())\n break\n case \"patch\":\n lines.push(`[patch] ${stringify(part.hash ?? part.files ?? part)}`)\n break\n case \"agent\":\n lines.push(`[agent ${part.name ?? \"\"}]`.trim())\n break\n default:\n break\n }\n }\n\n const body = lines.join(\"\\n\").trim()\n return `### ${selector} (${role})\\n${body.length > 0 ? body : \"(empty message)\"}`\n}\n\nconst SUMMARY_RULES = `RULES\n- Reply with one section per selector, in the same order as listed. Nothing else: no introduction, no code fences, no tool calls, no trailing prose.\n- Each section starts with a header line exactly \\`SLEEV-SUMMARY <selector>\\` using the selector as listed.\n- The summary body continues until the next header or the end of the reply.\n- When a segment lists previous compressed summaries, merge their information into your summary: those blocks are replaced by the section you produce.\n- Preserve every high-signal detail: user intent (quote short user messages exactly), decisions, constraints, file paths, function and symbol names, commands run, key findings, errors, verification results, and any subagent task IDs with their scope and completion state.\n- Drop noise: failed attempts that led nowhere, repeated tool output, exploration that produced no durable result.\n- Be dense and precise. Prefer terse technical wording over narrative.`\n\n/**\n * Build the hidden summarization prompt. The selected segments are embedded\n * verbatim so the transient request does not depend on any injected metadata.\n */\nexport function buildSummaryPrompt(\n selectors: SummarySegment[],\n idFormat: IdFormat = \"xml\",\n callId?: string,\n): string {\n const selectorList = selectors.map((segment) => segment.selector)\n const example = selectorList[0] ?? (idFormat === \"compact\" ? \"\" : \"m0004\")\n const body = selectors\n .map((segment) => {\n const messageBody = segment.messages\n .map((message) => serializeMessageForSummary(message, segment.selector))\n .join(\"\\n\\n\")\n const priorBody = (segment.priorSummaries ?? [])\n .map(\n (prior) =>\n `### ${prior.ref} (previous compressed summary)\\n${prior.body.trim()}`,\n )\n .join(\"\\n\\n\")\n return [messageBody, priorBody].filter((part) => part.length > 0).join(\"\\n\\n\")\n })\n .join(\"\\n\\n\")\n\n return `${buildSummaryMarker(callId)}\n\nYou generate compressed-context entries for a coding session. Summarize ONLY the conversation segments listed below. Do not summarize anything else and do not ask questions.\n\nSUMMARY FORMAT\nSLEEV-SUMMARY ${example}\n<summary body>\n\n${SUMMARY_RULES.replace(\"one section per selector\", `${selectorList.length} section(s), one per selector`)}\n- The selectors for this request are exactly: ${selectorList.map((selector) => `\\`${selector}\\``).join(\", \")}\nRC-SELECTORS: ${selectorList.join(\", \")}\n\nSEGMENTS\n${body}\n`\n}\n\nfunction selectorPattern(): string {\n const boundary = \"(?:m[0-9]{4}|@[0-9]+@|b[1-9][0-9]*|@b[1-9][0-9]*@)\"\n return `(?:${boundary})(?:-${boundary})?`\n}\n\n/**\n * Normalize a selector written in either ID format (`m0004` or ``) into the\n * session's canonical format. Returns null when the selector is malformed.\n */\nexport function canonicalizeSelector(selector: string, format: IdFormat = \"xml\"): string | null {\n const parts = selector.trim().toLowerCase().split(\"-\")\n if (parts.length < 1 || parts.length > 2) {\n return null\n }\n const parse = (part: string) => parseBoundaryId(part, \"xml\") ?? parseBoundaryId(part, \"compact\")\n const toRef = (parsed: NonNullable<ReturnType<typeof parse>>): string =>\n parsed.kind === \"message\"\n ? formatMessageRef(parsed.index, format)\n : formatBlockRef(parsed.blockId, format)\n\n const start = parse(parts[0]!)\n const end = parts.length === 2 ? parse(parts[1]!) : start\n if (!start || !end) {\n return null\n }\n if (start.kind === \"message\" && end.kind === \"message\" && start.index > end.index) {\n return null\n }\n const startRef = toRef(start)\n const endRef = toRef(end)\n return startRef === endRef ? startRef : `${startRef}-${endRef}`\n}\n\n/**\n * Strip the `[Compressed conversation section]` header and trailing block tag\n * from a stored summary so it can be embedded in a new summary prompt.\n */\nexport function restoreSummary(summary: string): string {\n const headerMatch = summary.match(\n /^[ \\t]*\\[Compressed conversation(?: section)?(?: b[0-9]+)?\\]/i,\n )\n if (!headerMatch) {\n return summary\n }\n\n const body = summary.slice(headerMatch[0].length).trimStart()\n const lines = body.split(\"\\n\")\n while (lines.length > 0 && (lines[lines.length - 1] ?? \"\").trim() === \"\") {\n lines.pop()\n }\n const last = (lines[lines.length - 1] ?? \"\").trim()\n const isXmlTag = new RegExp(\"^<dcp-message-id>b[0-9]+</dcp-message-id>$\").test(last)\n const isCompactTag = /^@b[1-9][0-9]*@$/.test(last)\n if (isXmlTag || isCompactTag) {\n lines.pop()\n }\n return lines.join(\"\\n\").trimEnd()\n}\n\n/**\n * Parse `SLEEV-SUMMARY <selector>` sections from a model reply. Returns the\n * accepted sections plus the selectors that are missing, duplicated, or have\n * an empty body so the caller can retry only what is needed. Selectors are\n * accepted in either ID format and normalized to the session format.\n */\nexport function parseSummarySections(\n text: string,\n expected: string[],\n idFormat: IdFormat = \"xml\",\n): ParsedSummarySections {\n const header = new RegExp(`^SLEEV-SUMMARY (${selectorPattern()})[ \\t]*$`, \"gmi\")\n const matches: Array<{ selector: string; start: number; end: number }> = []\n let match: RegExpExecArray | null\n\n while ((match = header.exec(text)) !== null) {\n const selector = canonicalizeSelector((match[1] ?? \"\").trim(), idFormat)\n if (!selector) {\n continue\n }\n matches.push({\n selector,\n start: match.index,\n end: match.index + match[0].length,\n })\n }\n\n const normalizedExpected = expected\n .map((selector) => canonicalizeSelector(selector, idFormat))\n .filter((selector): selector is string => Boolean(selector))\n const expectedSet = new Set(normalizedExpected)\n const sections: SummarySection[] = []\n const seen = new Set<string>()\n const duplicates: string[] = []\n const empty: string[] = []\n\n for (let index = 0; index < matches.length; index++) {\n const current = matches[index]!\n if (!expectedSet.has(current.selector)) {\n continue\n }\n if (seen.has(current.selector)) {\n if (!duplicates.includes(current.selector)) {\n duplicates.push(current.selector)\n }\n continue\n }\n seen.add(current.selector)\n\n const next = matches[index + 1]\n const body = text.slice(current.end, next ? next.start : text.length).trim()\n if (body.length === 0) {\n empty.push(current.selector)\n continue\n }\n sections.push({ selector: current.selector, summary: body })\n }\n\n const missing = normalizedExpected.filter(\n (selector) => !seen.has(selector) && !empty.includes(selector),\n )\n return { sections, missing, duplicates, empty }\n}\n","/**\n * Captures token usage of the hidden compression (summary) requests.\n *\n * OpenCode V2 `session.generate` returns only the reply text, so provider\n * usage is observed in two complementary ways: wrapping the resolved language\n * model through the `aisdk.language` hook (AI SDK packages) and reading the\n * raw response body through the session `http.response` hook (native\n * `@opencode/ai` packages, whose model never passes through the core AISDK\n * service). The session `generate` hook records a local input estimate as a\n * fallback for runtimes where neither capture path is available. All state is\n * kept in memory and keyed by the per-request call id embedded in the hidden\n * prompt marker.\n */\n\nimport type { Plugin } from \"@opencode/plugin\"\nimport type { Logger } from \"../logger\"\nimport { countTokens } from \"../token-utils\"\nimport { extractSummaryCallId } from \"../compress/summary\"\nimport {\n estimatedCompressionUsage,\n normalizeProviderUsage,\n type CompressionUsage,\n} from \"../compress/usage\"\n\ninterface PendingUsage {\n provider?: CompressionUsage\n estimatedInput?: number\n}\n\nexport interface CompressionUsageTracker {\n recordProvider(callId: string, usage: CompressionUsage): void\n recordEstimatedInput(callId: string, inputTokens: number): void\n /** Provider usage when captured, otherwise a tokenizer estimate, otherwise undefined. */\n resolve(callId: string, outputText: string): CompressionUsage | undefined\n discard(callId: string): void\n}\n\nexport function createCompressionUsageTracker(): CompressionUsageTracker {\n const pending = new Map<string, PendingUsage>()\n\n const entry = (callId: string): PendingUsage => {\n let current = pending.get(callId)\n if (!current) {\n current = {}\n pending.set(callId, current)\n }\n return current\n }\n\n return {\n recordProvider(callId, usage) {\n entry(callId).provider = usage\n },\n recordEstimatedInput(callId, inputTokens) {\n if (Number.isFinite(inputTokens) && inputTokens > 0) {\n entry(callId).estimatedInput = Math.round(inputTokens)\n }\n },\n resolve(callId, outputText) {\n const current = pending.get(callId)\n if (!current) {\n return undefined\n }\n if (current.provider) {\n return current.provider\n }\n if (current.estimatedInput === undefined) {\n return undefined\n }\n return estimatedCompressionUsage(current.estimatedInput, countTokens(outputText))\n },\n discard(callId) {\n pending.delete(callId)\n },\n }\n}\n\n/** Depth-first search of the AI SDK call options for a summary marker. */\nfunction findSummaryCallId(options: unknown): string | undefined {\n const texts: string[] = []\n collectTexts((options as { prompt?: unknown } | undefined)?.prompt, texts)\n for (const text of texts) {\n const callId = extractSummaryCallId(text)\n if (callId) {\n return callId\n }\n }\n return undefined\n}\n\nfunction collectTexts(value: unknown, out: string[], depth = 0): void {\n if (depth > 8 || out.length > 200) {\n return\n }\n if (typeof value === \"string\") {\n out.push(value)\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectTexts(item, out, depth + 1)\n }\n return\n }\n if (value && typeof value === \"object\") {\n const record = value as Record<string, unknown>\n if (typeof record.text === \"string\") {\n out.push(record.text)\n }\n if (typeof record.content === \"string\") {\n out.push(record.content)\n } else if (Array.isArray(record.content)) {\n collectTexts(record.content, out, depth + 1)\n }\n }\n}\n\nfunction wrapLanguageModel(model: any, tracker: CompressionUsageTracker, logger: Logger): any {\n return new Proxy(model, {\n get(target, property, receiver) {\n if (property === \"doStream\") {\n return (options: unknown) => trackedStream(target, options, tracker, logger)\n }\n if (property === \"doGenerate\") {\n return (options: unknown) => trackedGenerate(target, options, tracker, logger)\n }\n return Reflect.get(target, property, receiver)\n },\n })\n}\n\nasync function trackedStream(\n target: any,\n options: unknown,\n tracker: CompressionUsageTracker,\n logger: Logger,\n): Promise<any> {\n const result = await target.doStream(options)\n const callId = findSummaryCallId(options)\n logger.debug(\"Compression usage stream call\", { callId: callId ?? null })\n const TransformStreamImpl = (globalThis as any).TransformStream\n if (!callId || typeof result?.stream?.pipeThrough !== \"function\") {\n return result\n }\n if (typeof TransformStreamImpl !== \"function\") {\n return result\n }\n\n let recorded = false\n const transform = new TransformStreamImpl({\n transform(part: any, controller: any) {\n try {\n if (!recorded && part?.type === \"finish\" && part.usage) {\n const usage = normalizeProviderUsage(part.usage)\n if (usage) {\n recorded = true\n tracker.recordProvider(callId, usage)\n }\n }\n } catch {\n // Never disturb the model stream because of usage accounting.\n }\n controller.enqueue(part)\n },\n })\n return { ...result, stream: result.stream.pipeThrough(transform) }\n}\n\nasync function trackedGenerate(\n target: any,\n options: unknown,\n tracker: CompressionUsageTracker,\n logger: Logger,\n): Promise<any> {\n const result = await target.doGenerate(options)\n const callId = findSummaryCallId(options)\n logger.debug(\"Compression usage generate call\", { callId: callId ?? null })\n if (!callId) {\n return result\n }\n const usage = normalizeProviderUsage(result?.usage)\n if (usage) {\n tracker.recordProvider(callId, usage)\n }\n return result\n}\n\n/**\n * Best-effort registration of the language-model wrapper. Runtimes without the\n * `aisdk` hook simply rely on the local estimate fallback.\n */\nexport async function installCompressionUsageHook(\n ctx: Plugin.Context,\n tracker: CompressionUsageTracker,\n logger: Logger,\n): Promise<void> {\n const aisdk = (ctx as any)?.aisdk\n if (!aisdk || typeof aisdk.hook !== \"function\") {\n logger.debug(\"aisdk hook unavailable; compression usage will be estimated\")\n return\n }\n\n try {\n await aisdk.hook(\"language\", (event: any) => {\n try {\n const isModel = (candidate: unknown) =>\n !!candidate && typeof (candidate as any).doStream === \"function\"\n logger.debug(\"Compression usage hook event\", {\n modelID: event?.model?.modelID ?? event?.model?.id ?? null,\n hasLanguage: isModel(event?.language),\n hasFactory: typeof event?.sdk?.languageModel === \"function\",\n })\n // Another hook may already have resolved a model; otherwise fall\n // back to the provider SDK factory the core would use itself.\n let model: unknown = isModel(event?.language) ? event.language : undefined\n if (!model && typeof event?.sdk?.languageModel === \"function\") {\n model = event.sdk.languageModel(\n event?.model?.modelID ?? event?.model?.id,\n ) as unknown\n }\n if (!isModel(model)) {\n return\n }\n event.language = wrapLanguageModel(model, tracker, logger)\n } catch (error: any) {\n logger.debug(\"Compression usage hook could not wrap language model\", {\n error: error?.message,\n })\n }\n })\n logger.debug(\"Compression usage hook installed\")\n } catch (error: any) {\n logger.warn(\"Compression usage hook registration failed\", {\n error: error?.message,\n })\n }\n}\n\ninterface UsageAccumulator {\n input: number\n output: number\n cacheRead: number\n cacheWrite: number\n reasoning: number\n /** Anthropic reports cache tokens in addition to `input_tokens`. */\n exclusiveInput: boolean\n}\n\nfunction emptyUsageAccumulator(): UsageAccumulator {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n reasoning: 0,\n exclusiveInput: false,\n }\n}\n\ntype UsageField = \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"reasoning\"\n\nfunction usageField(key: string): UsageField | undefined {\n switch (key) {\n case \"input_tokens\":\n case \"prompt_tokens\":\n case \"promptTokenCount\":\n return \"input\"\n case \"output_tokens\":\n case \"completion_tokens\":\n case \"candidatesTokenCount\":\n return \"output\"\n case \"cache_read_input_tokens\":\n case \"cache_creation_input_tokens\":\n case \"cached_tokens\":\n case \"cachedContentTokenCount\":\n return key === \"cache_creation_input_tokens\" ? \"cacheWrite\" : \"cacheRead\"\n case \"reasoning_tokens\":\n case \"thoughtsTokenCount\":\n return \"reasoning\"\n default:\n return undefined\n }\n}\n\n/** Merge every usage-like object found in a provider payload. */\nfunction scanUsage(value: unknown, acc: UsageAccumulator, depth: number): void {\n if (depth > 8 || !value || typeof value !== \"object\") {\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n scanUsage(item, acc, depth + 1)\n }\n return\n }\n for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n const field = usageField(key)\n if (field && typeof raw === \"number\" && Number.isFinite(raw)) {\n acc[field] = Math.max(acc[field], raw)\n if (key === \"cache_read_input_tokens\" || key === \"cache_creation_input_tokens\") {\n acc.exclusiveInput = true\n }\n continue\n }\n if (raw && typeof raw === \"object\") {\n scanUsage(raw, acc, depth + 1)\n }\n }\n}\n\nfunction usageFromAccumulator(acc: UsageAccumulator): CompressionUsage | undefined {\n const input = acc.exclusiveInput ? acc.input + acc.cacheRead + acc.cacheWrite : acc.input\n const usage: CompressionUsage = {\n inputTokens: Math.max(0, Math.round(input)),\n outputTokens: Math.max(0, Math.round(acc.output)),\n cacheReadTokens: Math.max(0, Math.round(acc.cacheRead)),\n cacheWriteTokens: Math.max(0, Math.round(acc.cacheWrite)),\n reasoningTokens: Math.max(0, Math.round(acc.reasoning)),\n source: \"provider\",\n }\n const total =\n usage.inputTokens +\n usage.outputTokens +\n usage.cacheReadTokens +\n usage.cacheWriteTokens +\n usage.reasoningTokens\n return total > 0 ? usage : undefined\n}\n\n/**\n * Parse provider usage from a raw model response body. Handles plain JSON\n * bodies and SSE streams from the common provider protocols (OpenAI\n * responses/chat, Anthropic, Google) by merging every usage-like object.\n */\nexport function parseProviderUsageFromBody(body: string): CompressionUsage | undefined {\n const acc = emptyUsageAccumulator()\n const trimmed = body.trim()\n let parsedJson = false\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n try {\n scanUsage(JSON.parse(trimmed), acc, 0)\n parsedJson = true\n } catch {\n // Not a single JSON document; treat the body as an SSE stream.\n }\n }\n if (!parsedJson) {\n for (const line of body.split(/\\r?\\n/)) {\n const match = /^\\s*data:\\s*(.*)$/.exec(line)\n if (!match) {\n continue\n }\n const payload = match[1].trim()\n if (!payload || payload === \"[DONE]\") {\n continue\n }\n try {\n scanUsage(JSON.parse(payload), acc, 0)\n } catch {\n // Ignore malformed events.\n }\n }\n }\n return usageFromAccumulator(acc)\n}\n\n/**\n * Best-effort capture of provider usage from the raw HTTP response of the\n * hidden summary request. Needed for native `@opencode/ai` provider packages,\n * which bypass the core AISDK service entirely. The hook reads clones of the\n * request/response, so the real traffic is never disturbed, and any failure\n * falls back to the local estimate recorded by the `generate` hook.\n */\nexport async function installHttpUsageHook(\n ctx: Plugin.Context,\n tracker: CompressionUsageTracker,\n logger: Logger,\n): Promise<void> {\n const session = (ctx as any)?.session\n if (!session || typeof session.hook !== \"function\") {\n return\n }\n\n try {\n await session.hook(\"http.response\", async (event: any) => {\n if (event?.kind !== \"generate\") {\n return\n }\n try {\n const request = event.request\n const response = event.response\n if (!request || typeof request.clone !== \"function\") {\n return\n }\n const callId = extractSummaryCallId(await request.clone().text())\n if (!callId) {\n return\n }\n if (!response || typeof response.clone !== \"function\") {\n return\n }\n const usage = parseProviderUsageFromBody(await response.clone().text())\n if (usage) {\n tracker.recordProvider(callId, usage)\n logger.debug(\"Compression usage captured from http response\", {\n callId,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n })\n }\n } catch (error: any) {\n logger.debug(\"Compression usage http capture failed\", {\n error: error?.message,\n })\n }\n })\n logger.debug(\"Compression usage http hook installed\")\n } catch (error: any) {\n logger.warn(\"Compression usage http hook registration failed\", {\n error: error?.message,\n })\n }\n}\n","import type { RuntimePrompts } from \"./store\"\nexport type { PromptStore, RuntimePrompts } from \"./store\"\n\nexport function renderSystemPrompt(\n prompts: RuntimePrompts,\n protectedToolsExtension?: string,\n manual?: boolean,\n subagent?: boolean,\n): string {\n const extensions: string[] = []\n\n if (protectedToolsExtension) {\n extensions.push(protectedToolsExtension.trim())\n }\n\n if (manual) {\n extensions.push(prompts.manualExtension.trim())\n }\n\n if (subagent) {\n extensions.push(prompts.subagentExtension.trim())\n }\n\n return [prompts.system.trim(), ...extensions]\n .filter(Boolean)\n .join(\"\\n\\n\")\n .replace(/\\n([ \\t]*\\n)+/g, \"\\n\\n\")\n .trim()\n}\n","/**\n * DCP Context Command\n * Shows a visual breakdown of token usage in the current session.\n *\n * TOKEN CALCULATION STRATEGY\n * ==========================\n * We minimize tokenizer estimation by leveraging API-reported values wherever possible.\n *\n * WHAT WE GET FROM THE API (exact):\n * - tokens.input : Input tokens for each assistant response\n * - tokens.output : Output tokens generated (includes text + tool calls)\n * - tokens.reasoning: Reasoning tokens used\n * - tokens.cache : Cache read/write tokens\n *\n * HOW WE CALCULATE EACH CATEGORY:\n *\n * SYSTEM = firstAssistant.input + cache.read + cache.write - tokenizer(firstUserMessage)\n * The first response's total input (input + cache.read + cache.write)\n * contains system + first user message. On the first request of a\n * session, the system prompt appears in cache.write (cache creation),\n * not cache.read.\n *\n * TOOLS = tokenizer(toolInputs + toolOutputs) - prunedTokens\n * We must tokenize tools anyway for pruning decisions.\n *\n * USER = tokenizer(all user messages)\n * User messages are typically small, so estimation is acceptable.\n *\n * ASSISTANT = total - system - user - tools\n * Calculated as residual. This absorbs:\n * - Assistant text output tokens\n * - Reasoning tokens (if persisted by the model)\n * - Any estimation errors\n *\n * TOTAL = input + output + reasoning + cache.read + cache.write\n * Matches opencode's UI display.\n *\n * WHY ASSISTANT IS THE RESIDUAL:\n * If reasoning tokens persist in context (model-dependent), they semantically\n * belong with \"Assistant\" since reasoning IS assistant-generated content.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport { countTokens, extractCompletedToolOutput, getCurrentParams } from \"../token-utils\"\nimport type { AssistantMessage, TextPart, ToolPart } from \"@opencode-ai/sdk/v2\"\n\nexport interface ContextCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\ninterface TokenBreakdown {\n system: number\n user: number\n assistant: number\n tools: number\n toolCount: number\n toolsInContextCount: number\n prunedTokens: number\n prunedToolCount: number\n prunedMessageCount: number\n total: number\n}\n\nexport function analyzeContextTokens(state: SessionState, messages: WithParts[]): TokenBreakdown {\n const breakdown: TokenBreakdown = {\n system: 0,\n user: 0,\n assistant: 0,\n tools: 0,\n toolCount: 0,\n toolsInContextCount: 0,\n prunedTokens: state.stats.totalPruneTokens,\n prunedToolCount: 0,\n prunedMessageCount: 0,\n total: 0,\n }\n\n let firstAssistant: AssistantMessage | undefined\n for (const msg of messages) {\n if (msg.info.role === \"assistant\") {\n const assistantInfo = msg.info as AssistantMessage\n if (\n assistantInfo.tokens?.input > 0 ||\n assistantInfo.tokens?.cache?.read > 0 ||\n assistantInfo.tokens?.cache?.write > 0\n ) {\n firstAssistant = assistantInfo\n break\n }\n }\n }\n\n let lastAssistant: AssistantMessage | undefined\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role === \"assistant\") {\n const assistantInfo = msg.info as AssistantMessage\n if (assistantInfo.tokens?.output > 0) {\n lastAssistant = assistantInfo\n break\n }\n }\n }\n\n const apiInput = lastAssistant?.tokens?.input || 0\n const apiOutput = lastAssistant?.tokens?.output || 0\n const apiReasoning = lastAssistant?.tokens?.reasoning || 0\n const apiCacheRead = lastAssistant?.tokens?.cache?.read || 0\n const apiCacheWrite = lastAssistant?.tokens?.cache?.write || 0\n breakdown.total = apiInput + apiOutput + apiReasoning + apiCacheRead + apiCacheWrite\n\n const userTextParts: string[] = []\n const toolInputParts: string[] = []\n const toolOutputParts: string[] = []\n let firstUserText = \"\"\n let foundFirstUser = false\n const allToolIds = new Set<string>()\n const activeToolIds = new Set<string>()\n const prunedByMessageToolIds = new Set<string>()\n const allMessageIds = new Set<string>()\n\n for (const msg of messages) {\n allMessageIds.add(msg.info.id)\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const isCompacted = isMessageCompacted(state, msg)\n const pruneEntry = state.prune.messages.byMessageId.get(msg.info.id)\n const isMessagePruned = !!pruneEntry && pruneEntry.activeBlockIds.length > 0\n const isIgnoredUser = isIgnoredUserMessage(msg)\n\n for (const part of parts) {\n if (part.type === \"tool\") {\n const toolPart = part as ToolPart\n if (toolPart.callID) {\n allToolIds.add(toolPart.callID)\n if (!isCompacted) {\n activeToolIds.add(toolPart.callID)\n }\n if (isMessagePruned) {\n prunedByMessageToolIds.add(toolPart.callID)\n }\n }\n\n const isPruned = toolPart.callID && state.prune.tools.has(toolPart.callID)\n if (!isCompacted && !isPruned) {\n if (toolPart.state?.input) {\n const inputStr =\n typeof toolPart.state.input === \"string\"\n ? toolPart.state.input\n : JSON.stringify(toolPart.state.input)\n toolInputParts.push(inputStr)\n }\n\n const outputStr = extractCompletedToolOutput(toolPart)\n if (outputStr !== undefined) {\n toolOutputParts.push(outputStr)\n }\n }\n } else if (\n part.type === \"text\" &&\n msg.info.role === \"user\" &&\n !isCompacted &&\n !isIgnoredUser\n ) {\n const textPart = part as TextPart\n const text = textPart.text || \"\"\n userTextParts.push(text)\n if (!foundFirstUser) {\n firstUserText += text\n }\n }\n }\n\n if (msg.info.role === \"user\" && !isIgnoredUser && !foundFirstUser) {\n foundFirstUser = true\n }\n }\n\n const prunedByToolIds = new Set<string>()\n for (const id of allToolIds) {\n if (state.prune.tools.has(id)) {\n prunedByToolIds.add(id)\n }\n }\n\n const prunedToolIds = new Set<string>([...prunedByToolIds, ...prunedByMessageToolIds])\n const toolsInContextCount = [...activeToolIds].filter((id) => !prunedByToolIds.has(id)).length\n\n let prunedMessageCount = 0\n for (const [id, entry] of state.prune.messages.byMessageId) {\n if (allMessageIds.has(id) && entry.activeBlockIds.length > 0) {\n prunedMessageCount++\n }\n }\n\n breakdown.toolCount = allToolIds.size\n breakdown.toolsInContextCount = toolsInContextCount\n breakdown.prunedToolCount = prunedToolIds.size\n breakdown.prunedMessageCount = prunedMessageCount\n\n const firstUserTokens = countTokens(firstUserText)\n breakdown.user = countTokens(userTextParts.join(\"\\n\"))\n const toolInputTokens = countTokens(toolInputParts.join(\"\\n\"))\n const toolOutputTokens = countTokens(toolOutputParts.join(\"\\n\"))\n\n if (firstAssistant) {\n const firstInput =\n (firstAssistant.tokens?.input || 0) +\n (firstAssistant.tokens?.cache?.read || 0) +\n (firstAssistant.tokens?.cache?.write || 0)\n breakdown.system = Math.max(0, firstInput - firstUserTokens)\n }\n\n breakdown.tools = toolInputTokens + toolOutputTokens\n breakdown.assistant = Math.max(\n 0,\n breakdown.total - breakdown.system - breakdown.user - breakdown.tools,\n )\n\n return breakdown\n}\n\nfunction createBar(value: number, maxValue: number, width: number, char: string = \"█\"): string {\n if (maxValue === 0) return \"\"\n const filled = Math.round((value / maxValue) * width)\n const bar = char.repeat(Math.max(0, filled))\n return bar\n}\n\nexport function formatContextMessage(breakdown: TokenBreakdown): string {\n const lines: string[] = []\n const barWidth = 30\n\n const toolsLabel = `Tools (${breakdown.toolsInContextCount})`\n\n const categories = [\n { label: \"System\", value: breakdown.system, char: \"█\" },\n { label: \"User\", value: breakdown.user, char: \"▓\" },\n { label: \"Assistant\", value: breakdown.assistant, char: \"▒\" },\n { label: toolsLabel, value: breakdown.tools, char: \"░\" },\n ] as const\n\n const maxLabelLen = Math.max(...categories.map((c) => c.label.length))\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Context Analysis │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Session Context Breakdown:\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n for (const cat of categories) {\n const bar = createBar(cat.value, breakdown.total, barWidth, cat.char)\n const percentage =\n breakdown.total > 0 ? ((cat.value / breakdown.total) * 100).toFixed(1) : \"0.0\"\n const labelWithPct = `${cat.label.padEnd(maxLabelLen)} ${percentage.padStart(5)}% `\n const valueStr = formatTokenCount(cat.value).padStart(13)\n lines.push(`${labelWithPct}│${bar.padEnd(barWidth)}│${valueStr}`)\n }\n\n lines.push(\"\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n lines.push(\"Summary:\")\n\n if (breakdown.prunedTokens > 0) {\n const withoutPruning = breakdown.total + breakdown.prunedTokens\n const pruned = []\n if (breakdown.prunedToolCount > 0) pruned.push(`${breakdown.prunedToolCount} tools`)\n if (breakdown.prunedMessageCount > 0)\n pruned.push(`${breakdown.prunedMessageCount} messages`)\n lines.push(\n ` Pruned: ${pruned.join(\", \")} (~${formatTokenCount(breakdown.prunedTokens)})`,\n )\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n lines.push(` Without DCP: ~${formatTokenCount(withoutPruning)}`)\n } else {\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n }\n\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleContextCommand(ctx: ContextCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const breakdown = analyzeContextTokens(state, messages)\n\n const message = formatContextMessage(breakdown)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n}\n","import { createHash } from \"node:crypto\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\nimport type { IdFormat } from \"../message-ids\"\n\nconst SUMMARY_ID_HASH_LENGTH = 16\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\nconst INJECTED_MESSAGE_ID_SUFFIX_REGEX = /(?<=\\n)<dcp-message-id[^>]*>m\\d+<\\/dcp-message-id>\\s*$/\nconst HALLUCINATED_PARAMETER_SUFFIX_REGEX = /(?<=\\n)m\\d+<\\/parameter>\\s*$/\nconst COMPACT_TAG_REGEX = /@(?:[1-9]\\d*|b[1-9]\\d*|blocked)@(?:[ \\t]+\\[(?:low|medium|high)\\])?/gi\n\nconst generateStableId = (prefix: string, seed: string): string => {\n const hash = createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, SUMMARY_ID_HASH_LENGTH)\n return `${prefix}_${hash}`\n}\n\nexport const createSyntheticUserMessage = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n): WithParts => {\n const userInfo = baseMessage.info as UserMessage\n const now = Date.now()\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const messageId = generateStableId(\"msg_dcp_summary\", deterministicSeed)\n const partId = generateStableId(\"prt_dcp_summary\", deterministicSeed)\n\n return {\n info: {\n id: messageId,\n sessionID: userInfo.sessionID,\n role: \"user\" as const,\n agent: userInfo.agent,\n model: userInfo.model,\n time: { created: now },\n },\n parts: [\n {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: messageId,\n type: \"text\" as const,\n text: content,\n },\n ],\n }\n}\n\nexport const createSyntheticTextPart = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n) => {\n const userInfo = baseMessage.info as UserMessage\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const partId = generateStableId(\"prt_dcp_text\", deterministicSeed)\n\n return {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: userInfo.id,\n type: \"text\" as const,\n text: content,\n }\n}\n\ntype MessagePart = WithParts[\"parts\"][number]\ntype ToolPart = Extract<MessagePart, { type: \"tool\" }>\ntype TextPart = Extract<MessagePart, { type: \"text\" }>\n\nexport const appendToLastTextPart = (message: WithParts, injection: string): boolean => {\n const textPart = findLastTextPart(message)\n if (!textPart) {\n return false\n }\n\n return appendToTextPart(textPart, injection)\n}\n\nconst findLastTextPart = (message: WithParts): TextPart | null => {\n for (let i = message.parts.length - 1; i >= 0; i--) {\n const part = message.parts[i]\n if (part.type === \"text\") {\n return part\n }\n }\n\n return null\n}\n\nexport const appendToTextPart = (part: TextPart, injection: string): boolean => {\n if (typeof part.text !== \"string\") {\n return false\n }\n\n const normalizedInjection = injection.replace(/^\\n+/, \"\")\n if (!normalizedInjection.trim()) {\n return false\n }\n if (part.text.includes(normalizedInjection)) {\n return true\n }\n\n const baseText = part.text.replace(/\\n*$/, \"\")\n part.text = baseText.length > 0 ? `${baseText}\\n\\n${normalizedInjection}` : normalizedInjection\n return true\n}\n\nexport const appendToAllToolParts = (message: WithParts, tag: string): boolean => {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"tool\") {\n injected = appendToToolPart(part, tag) || injected\n }\n }\n return injected\n}\n\nexport const appendToToolPart = (part: ToolPart, tag: string): boolean => {\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n return false\n }\n if (part.state.output.includes(tag)) {\n return true\n }\n\n part.state.output = `${part.state.output}${tag}`\n return true\n}\n\nexport const hasContent = (message: WithParts): boolean => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0) ||\n (part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"),\n )\n}\n\nexport function buildToolIdList(state: SessionState, messages: WithParts[]): string[] {\n const toolIds: string[] = []\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n state.toolIdList = toolIds\n return toolIds\n}\n\nexport const stripHallucinationsFromString = (text: string, format: IdFormat = \"xml\"): string => {\n if (format === \"compact\") text = text.replace(COMPACT_TAG_REGEX, \"\")\n const withoutKnownSuffixes = text\n .replace(INJECTED_MESSAGE_ID_SUFFIX_REGEX, \"\")\n .replace(HALLUCINATED_PARAMETER_SUFFIX_REGEX, \"\")\n return withoutKnownSuffixes\n .replace(DCP_PAIRED_TAG_REGEX, \"\")\n .replace(DCP_UNPAIRED_TAG_REGEX, \"\")\n}\n\nexport const stripHallucinations = (messages: WithParts[], format: IdFormat = \"xml\"): void => {\n for (const message of messages) {\n for (const part of message.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n part.text = stripHallucinationsFromString(part.text, format)\n }\n\n if (\n part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"\n ) {\n part.state.output = stripHallucinationsFromString(part.state.output, format)\n }\n }\n }\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport { createSyntheticUserMessage } from \"./utils\"\nimport { getLastUserMessage } from \"./query\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\nimport { formatBlockRef } from \"../message-ids\"\n\nconst PRUNED_TOOL_OUTPUT_REPLACEMENT =\n \"[Output removed to save context - information superseded or no longer needed]\"\nconst PRUNED_TOOL_ERROR_INPUT_REPLACEMENT = \"[input removed due to failed tool call]\"\nconst PRUNED_QUESTION_INPUT_REPLACEMENT = \"[questions removed - see output for user's answers]\"\n\nexport const prune = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n summaryBase?: WithParts,\n): void => {\n filterCompressedRanges(state, logger, messages, summaryBase)\n // pruneFullTool(state, logger, messages)\n pruneToolOutputs(state, logger, messages)\n pruneToolInputs(state, logger, messages)\n pruneToolErrors(state, logger, messages)\n}\n\nconst pruneFullTool = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n const messagesToRemove: string[] = []\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const partsToRemove: string[] = []\n\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.tool !== \"edit\" && part.tool !== \"write\") {\n continue\n }\n\n partsToRemove.push(part.callID)\n }\n\n if (partsToRemove.length === 0) {\n continue\n }\n\n msg.parts = parts.filter(\n (part) => part.type !== \"tool\" || !partsToRemove.includes(part.callID),\n )\n\n if (msg.parts.length === 0) {\n messagesToRemove.push(msg.info.id)\n }\n }\n\n if (messagesToRemove.length > 0) {\n const result = messages.filter((msg) => !messagesToRemove.includes(msg.info.id))\n messages.length = 0\n messages.push(...result)\n }\n}\n\nconst pruneToolOutputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool === \"question\" || part.tool === \"edit\" || part.tool === \"write\") {\n continue\n }\n\n part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT\n }\n }\n}\n\nconst pruneToolInputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool !== \"question\") {\n continue\n }\n\n if (part.state.input?.questions !== undefined) {\n part.state.input.questions = PRUNED_QUESTION_INPUT_REPLACEMENT\n }\n }\n }\n}\n\nconst pruneToolErrors = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"error\") {\n continue\n }\n\n // Prune all string inputs for errored tools\n const input = part.state.input\n if (input && typeof input === \"object\") {\n for (const key of Object.keys(input)) {\n if (typeof input[key] === \"string\") {\n input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT\n }\n }\n }\n }\n }\n}\n\nconst filterCompressedRanges = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n summaryBase?: WithParts,\n): void => {\n if (\n state.prune.messages.byMessageId.size === 0 &&\n state.prune.messages.activeByAnchorMessageId.size === 0\n ) {\n return\n }\n\n const result: WithParts[] = []\n\n for (const msg of messages) {\n const msgId = msg.info.id\n\n // Check if there's a summary to inject at this anchor point\n const blockId = state.prune.messages.activeByAnchorMessageId.get(msgId)\n const summary =\n blockId !== undefined ? state.prune.messages.blocksById.get(blockId) : undefined\n if (summary) {\n const rawSummaryContent = (summary as { summary?: unknown }).summary\n if (\n summary.active !== true ||\n typeof rawSummaryContent !== \"string\" ||\n rawSummaryContent.length === 0\n ) {\n logger.warn(\"Skipping malformed compress summary\", {\n anchorMessageId: msgId,\n blockId: (summary as { blockId?: unknown }).blockId,\n })\n } else {\n // Find user message for variant and as base for synthetic message\n const msgIndex = messages.indexOf(msg)\n const userMessage = getLastUserMessage(messages, msgIndex) ?? summaryBase\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n // Persisted summaries can outlive the host's tag format.\n let renderedSummary = rawSummaryContent\n if (state.idFormat === \"compact\") {\n renderedSummary = renderedSummary.replace(\n /<dcp-message-id>b(\\d+)<\\/dcp-message-id>\\s*$/i,\n (_, id) => formatBlockRef(Number(id), \"compact\"),\n )\n }\n const summaryContent = renderedSummary\n const summarySeed = `${summary.blockId}:${summary.anchorMessageId}`\n result.push(\n createSyntheticUserMessage(userMessage, summaryContent, summarySeed),\n )\n\n logger.info(\"Injected compress summary\", {\n anchorMessageId: msgId,\n summaryLength: summaryContent.length,\n })\n } else {\n logger.warn(\"No user message found for compress summary\", {\n anchorMessageId: msgId,\n })\n }\n }\n }\n\n // Skip messages that are in the prune list\n const pruneEntry = state.prune.messages.byMessageId.get(msgId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n continue\n }\n\n // Normal message, include it\n result.push(msg)\n }\n\n // Replace messages array contents\n messages.length = 0\n messages.push(...result)\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\n\nfunction sortBlocksByCreation(\n a: { createdAt: number; blockId: number },\n b: { createdAt: number; blockId: number },\n): number {\n const createdAtDiff = a.createdAt - b.createdAt\n if (createdAtDiff !== 0) {\n return createdAtDiff\n }\n return a.blockId - b.blockId\n}\n\nexport const syncCompressionBlocks = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n): void => {\n const messagesState = state.prune.messages\n if (!messagesState?.blocksById?.size) {\n return\n }\n\n const messageIds = new Set(messages.map((msg) => msg.info.id))\n const previousActiveBlockIds = new Set<number>(\n Array.from(messagesState.blocksById.values())\n .filter((block) => block.active)\n .map((block) => block.blockId),\n )\n\n messagesState.activeBlockIds.clear()\n messagesState.activeByAnchorMessageId.clear()\n\n const now = Date.now()\n const missingOriginBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n for (const block of orderedBlocks) {\n const hasOriginMessage =\n typeof block.compressMessageId === \"string\" &&\n block.compressMessageId.length > 0 &&\n messageIds.has(block.compressMessageId)\n\n if (!hasOriginMessage) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n missingOriginBlockIds.push(block.blockId)\n continue\n }\n\n if (block.deactivatedByUser) {\n block.active = false\n if (block.deactivatedAt === undefined) {\n block.deactivatedAt = now\n }\n block.deactivatedByBlockId = undefined\n continue\n }\n\n for (const consumedBlockId of block.consumedBlockIds) {\n if (!messagesState.activeBlockIds.has(consumedBlockId)) {\n continue\n }\n\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (consumedBlock) {\n consumedBlock.active = false\n consumedBlock.deactivatedAt = now\n consumedBlock.deactivatedByBlockId = block.blockId\n\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlock.blockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n }\n\n block.active = true\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n messagesState.activeBlockIds.add(block.blockId)\n if (messageIds.has(block.anchorMessageId)) {\n messagesState.activeByAnchorMessageId.set(block.anchorMessageId, block.blockId)\n }\n }\n\n for (const entry of messagesState.byMessageId.values()) {\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [...new Set(entry.allBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n : []\n\n entry.allBlockIds = allBlockIds\n entry.activeBlockIds = allBlockIds.filter((id) => messagesState.activeBlockIds.has(id))\n }\n\n const nextActiveBlockIds = messagesState.activeBlockIds\n let deactivatedCount = 0\n let reactivatedCount = 0\n\n for (const blockId of previousActiveBlockIds) {\n if (!nextActiveBlockIds.has(blockId)) {\n deactivatedCount++\n }\n }\n for (const blockId of nextActiveBlockIds) {\n if (!previousActiveBlockIds.has(blockId)) {\n reactivatedCount++\n }\n }\n\n if (missingOriginBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingOriginCount: missingOriginBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport type { SessionState } from \"./state\"\n\nexport const compressPermission = (\n state: SessionState,\n config: PluginConfig,\n): \"ask\" | \"allow\" | \"deny\" => {\n return state.compressPermission ?? config.compress.permission\n}\n","import type { SessionState } from \"../../state\"\nimport { formatBlockRef } from \"../../message-ids\"\n\nexport function buildCompressedBlockGuidance(state: SessionState): string {\n const refs = Array.from(state.prune.messages.activeBlockIds)\n .filter((id) => Number.isInteger(id) && id > 0)\n .sort((a, b) => a - b)\n .map((id) => formatBlockRef(id, state.idFormat))\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"none\"\n\n return [\n \"Compressed block context:\",\n `- Active compressed blocks in this session: ${blockCount} (${blockList})`,\n \"- Compressed blocks can be used as selection boundaries: include a block ID (or a range spanning it) to merge its summary into a new summary and retire the old block.\",\n ].join(\"\\n\")\n}\n\nexport function appendGuidanceToDcpTag(nudgeText: string, guidance: string): string {\n if (!guidance.trim()) {\n return nudgeText\n }\n\n const closeTag = \"</dcp-system-reminder>\"\n const closeTagIndex = nudgeText.lastIndexOf(closeTag)\n\n if (closeTagIndex === -1) {\n return nudgeText\n }\n\n const beforeClose = nudgeText.slice(0, closeTagIndex).trimEnd()\n const afterClose = nudgeText.slice(closeTagIndex)\n return `${beforeClose}\\n\\n${guidance}\\n${afterClose}`\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { PluginConfig } from \"../../config\"\nimport {\n appendGuidanceToDcpTag,\n buildCompressedBlockGuidance,\n} from \"../../prompts/extensions/nudge\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\nimport {\n appendToTextPart,\n appendToLastTextPart,\n createSyntheticTextPart,\n hasContent,\n} from \"../utils\"\nimport { getLastUserMessage, isIgnoredUserMessage } from \"../query\"\nimport { getCurrentTokenUsage } from \"../../token-utils\"\nimport { getActiveSummaryTokenUsage } from \"../../state/utils\"\n\nexport interface LastUserModelContext {\n providerId: string | undefined\n modelId: string | undefined\n}\n\nexport interface LastNonIgnoredMessage {\n message: WithParts\n index: number\n}\n\nexport function getNudgeFrequency(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.nudgeFrequency || 1))\n}\n\nexport function getIterationNudgeThreshold(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.iterationNudgeThreshold || 1))\n}\n\nexport function findLastNonIgnoredMessage(messages: WithParts[]): LastNonIgnoredMessage | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n return { message, index: i }\n }\n\n return null\n}\n\nexport function countMessagesAfterIndex(messages: WithParts[], index: number): number {\n let count = 0\n\n for (let i = index + 1; i < messages.length; i++) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n count++\n }\n\n return count\n}\n\nexport function getModelInfo(messages: WithParts[]): LastUserModelContext {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return {\n providerId: undefined,\n modelId: undefined,\n }\n }\n\n const userInfo = lastUserMessage.info as UserMessage\n return {\n providerId: userInfo.model.providerID,\n modelId: userInfo.model.modelID,\n }\n}\n\nfunction resolveContextTokenLimit(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n threshold: \"max\" | \"min\",\n): number | undefined {\n const parseLimitValue = (limit: number | `${number}%` | undefined): number | undefined => {\n if (limit === undefined) {\n return undefined\n }\n\n if (typeof limit === \"number\") {\n return limit\n }\n\n if (!limit.endsWith(\"%\") || state.modelContextLimit === undefined) {\n return undefined\n }\n\n const parsedPercent = parseFloat(limit.slice(0, -1))\n if (isNaN(parsedPercent)) {\n return undefined\n }\n\n const roundedPercent = Math.round(parsedPercent)\n const clampedPercent = Math.max(0, Math.min(100, roundedPercent))\n return Math.round((clampedPercent / 100) * state.modelContextLimit)\n }\n\n const modelLimits =\n threshold === \"max\" ? config.compress.modelMaxLimits : config.compress.modelMinLimits\n if (modelLimits && providerId !== undefined && modelId !== undefined) {\n const providerModelId = `${providerId}/${modelId}`\n const modelLimit = modelLimits[providerModelId]\n if (modelLimit !== undefined) {\n return parseLimitValue(modelLimit)\n }\n }\n\n const globalLimit =\n threshold === \"max\" ? config.compress.maxContextLimit : config.compress.minContextLimit\n return parseLimitValue(globalLimit)\n}\n\nexport function isContextOverLimits(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n messages: WithParts[],\n) {\n const summaryTokenExtension = config.compress.summaryBuffer\n ? getActiveSummaryTokenUsage(state)\n : 0\n const resolvedMaxContextLimit = resolveContextTokenLimit(\n config,\n state,\n providerId,\n modelId,\n \"max\",\n )\n const maxContextLimit =\n resolvedMaxContextLimit === undefined\n ? undefined\n : resolvedMaxContextLimit + summaryTokenExtension\n const minContextLimit = resolveContextTokenLimit(config, state, providerId, modelId, \"min\")\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n const overMaxLimit = maxContextLimit === undefined ? false : currentTokens > maxContextLimit\n const overMinLimit = minContextLimit === undefined ? true : currentTokens >= minContextLimit\n\n return {\n overMaxLimit,\n overMinLimit,\n }\n}\n\nexport function addAnchor(\n anchorMessageIds: Set<string>,\n anchorMessageId: string,\n anchorMessageIndex: number,\n messages: WithParts[],\n interval: number,\n): boolean {\n if (anchorMessageIndex < 0) {\n return false\n }\n\n let latestAnchorMessageIndex = -1\n for (let i = messages.length - 1; i >= 0; i--) {\n if (anchorMessageIds.has(messages[i].info.id)) {\n latestAnchorMessageIndex = i\n break\n }\n }\n\n const shouldAdd =\n latestAnchorMessageIndex < 0 || anchorMessageIndex - latestAnchorMessageIndex >= interval\n if (!shouldAdd) {\n return false\n }\n\n const previousSize = anchorMessageIds.size\n anchorMessageIds.add(anchorMessageId)\n return anchorMessageIds.size !== previousSize\n}\n\nfunction injectAnchoredNudge(message: WithParts, nudgeText: string): void {\n if (!nudgeText.trim()) {\n return\n }\n\n if (message.info.role === \"user\") {\n if (appendToLastTextPart(message, nudgeText)) {\n return\n }\n\n message.parts.push(createSyntheticTextPart(message, nudgeText))\n return\n }\n\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (!hasContent(message)) {\n return\n }\n\n for (const part of message.parts) {\n if (part.type === \"text\") {\n if (appendToTextPart(part, nudgeText)) {\n return\n }\n }\n }\n\n const syntheticPart = createSyntheticTextPart(message, nudgeText)\n const firstToolIndex = message.parts.findIndex((p) => p.type === \"tool\")\n if (firstToolIndex === -1) {\n message.parts.push(syntheticPart)\n } else {\n message.parts.splice(firstToolIndex, 0, syntheticPart)\n }\n}\n\nfunction collectAnchoredMessages(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n): Array<{ message: WithParts; index: number }> {\n const anchoredMessages: Array<{ message: WithParts; index: number }> = []\n\n for (const anchorMessageId of anchorMessageIds) {\n const index = messages.findIndex((message) => message.info.id === anchorMessageId)\n if (index === -1) {\n continue\n }\n\n anchoredMessages.push({\n message: messages[index],\n index,\n })\n }\n\n return anchoredMessages\n}\n\nfunction collectTurnNudgeAnchors(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n): Set<string> {\n const turnNudgeAnchors = new Set<string>()\n const targetRole = config.compress.nudgeForce === \"strong\" ? \"user\" : \"assistant\"\n\n for (const message of messages) {\n if (!state.nudges.turnNudgeAnchors.has(message.info.id)) continue\n\n if (message.info.role === targetRole) {\n turnNudgeAnchors.add(message.info.id)\n }\n }\n\n return turnNudgeAnchors\n}\n\nfunction applyGuidedAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n compressedBlockGuidance: string,\n): void {\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, compressedBlockGuidance)\n if (!nudgeText.trim()) {\n return\n }\n\n for (const { message } of collectAnchoredMessages(anchorMessageIds, messages)) {\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n): void {\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n\n applyGuidedAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n compressedBlockGuidance,\n )\n applyGuidedAnchoredNudge(turnNudgeAnchors, messages, prompts.turnNudge, compressedBlockGuidance)\n applyGuidedAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressedBlockGuidance,\n )\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { Logger } from \"../../logger\"\nimport type { PluginConfig } from \"../../config\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport { formatMessageIdTag } from \"../../message-ids\"\nimport { compressPermission } from \"../../compress-permission\"\nimport {\n getLastUserMessage,\n isIgnoredUserMessage,\n isProtectedUserMessage,\n messageHasCompress,\n} from \"../query\"\nimport { saveSessionState } from \"../../state/persistence\"\nimport {\n appendToTextPart,\n appendToLastTextPart,\n appendToAllToolParts,\n createSyntheticTextPart,\n hasContent,\n} from \"../utils\"\nimport {\n addAnchor,\n applyAnchoredNudges,\n countMessagesAfterIndex,\n findLastNonIgnoredMessage,\n getIterationNudgeThreshold,\n getNudgeFrequency,\n getModelInfo,\n isContextOverLimits,\n} from \"./utils\"\n\nexport const injectCompressNudges = (\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n prompts: RuntimePrompts,\n createAnchors = true,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n if (state.manualMode) {\n return\n }\n\n if (!createAnchors) {\n applyAnchoredNudges(state, config, messages, prompts)\n return\n }\n\n const lastMessage = findLastNonIgnoredMessage(messages)\n const lastAssistantMessage = messages.findLast((message) => message.info.role === \"assistant\")\n\n if (lastAssistantMessage && messageHasCompress(lastAssistantMessage)) {\n state.nudges.contextLimitAnchors.clear()\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n void saveSessionState(state, logger)\n return\n }\n\n const { providerId, modelId } = getModelInfo(messages)\n let anchorsChanged = false\n\n const { overMaxLimit, overMinLimit } = isContextOverLimits(\n config,\n state,\n providerId,\n modelId,\n messages,\n )\n\n if (!overMinLimit) {\n const hadTurnAnchors = state.nudges.turnNudgeAnchors.size > 0\n const hadIterationAnchors = state.nudges.iterationNudgeAnchors.size > 0\n\n if (hadTurnAnchors || hadIterationAnchors) {\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n anchorsChanged = true\n }\n }\n\n if (overMaxLimit) {\n if (lastMessage) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.contextLimitAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n if (added) {\n anchorsChanged = true\n }\n }\n } else if (overMinLimit) {\n const isLastMessageUser = lastMessage?.message.info.role === \"user\"\n\n if (isLastMessageUser && lastAssistantMessage) {\n const previousSize = state.nudges.turnNudgeAnchors.size\n state.nudges.turnNudgeAnchors.add(lastMessage.message.info.id)\n state.nudges.turnNudgeAnchors.add(lastAssistantMessage.info.id)\n if (state.nudges.turnNudgeAnchors.size !== previousSize) {\n anchorsChanged = true\n }\n }\n\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage && lastMessage) {\n const lastUserMessageIndex = messages.findIndex(\n (message) => message.info.id === lastUserMessage.info.id,\n )\n if (lastUserMessageIndex >= 0) {\n const messagesSinceUser = countMessagesAfterIndex(messages, lastUserMessageIndex)\n const iterationThreshold = getIterationNudgeThreshold(config)\n\n if (\n lastMessage.index > lastUserMessageIndex &&\n messagesSinceUser >= iterationThreshold\n ) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.iterationNudgeAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n\n if (added) {\n anchorsChanged = true\n }\n }\n }\n }\n }\n\n applyAnchoredNudges(state, config, messages, prompts)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger)\n }\n}\n\nexport const injectMessageIds = (\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n const messageRef = state.messageIds.byRawId.get(message.info.id)\n if (!messageRef) {\n continue\n }\n\n const isBlockedMessage = isProtectedUserMessage(config, message)\n const tag = formatMessageIdTag(\n isBlockedMessage ? \"BLOCKED\" : messageRef,\n undefined,\n state.idFormat,\n )\n\n if (message.info.role === \"user\") {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"text\") {\n injected = appendToTextPart(part, tag) || injected\n }\n }\n\n if (injected) {\n continue\n }\n\n message.parts.push(createSyntheticTextPart(message, tag))\n continue\n }\n\n if (message.info.role !== \"assistant\") {\n continue\n }\n\n if (!hasContent(message)) {\n continue\n }\n\n if (appendToAllToolParts(message, tag)) {\n continue\n }\n\n if (appendToLastTextPart(message, tag)) {\n continue\n }\n\n const syntheticPart = createSyntheticTextPart(message, tag)\n const firstToolIndex = message.parts.findIndex((p) => p.type === \"tool\")\n if (firstToolIndex === -1) {\n message.parts.push(syntheticPart)\n } else {\n message.parts.splice(firstToolIndex, 0, syntheticPart)\n }\n }\n}\n","import type { Logger } from \"../../logger\"\nimport type { SessionState, WithParts } from \"../../state\"\nimport { filterMessages } from \"../shape\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../../subagents/subagent-results\"\nimport { stripHallucinationsFromString } from \"../utils\"\n\nasync function fetchSubAgentMessages(client: any, sessionId: string): Promise<WithParts[]> {\n const response = await client.session.messages({\n path: { id: sessionId },\n })\n\n return filterMessages(response?.data || response)\n}\n\nexport const injectExtendedSubAgentResults = async (\n client: any,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n allowSubAgents: boolean,\n): Promise<void> => {\n if (!allowSubAgents) {\n return\n }\n\n for (const message of messages) {\n const parts = Array.isArray(message.parts) ? message.parts : []\n\n for (const part of parts) {\n if (part.type !== \"tool\" || ![\"task\", \"subagent\"].includes(part.tool) || !part.callID) {\n continue\n }\n if (state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n continue\n }\n\n const cachedResult = state.subAgentResultCache.get(part.callID)\n if (cachedResult !== undefined) {\n if (cachedResult) {\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, cachedResult),\n state.idFormat,\n )\n }\n continue\n }\n\n const subAgentSessionId = getSubAgentId(part)\n if (!subAgentSessionId) {\n continue\n }\n\n let subAgentMessages: WithParts[] = []\n try {\n subAgentMessages = await fetchSubAgentMessages(client, subAgentSessionId)\n } catch (error) {\n logger.warn(\"Failed to fetch subagent session for output expansion\", {\n subAgentSessionId,\n callID: part.callID,\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n\n const subAgentResultText = buildSubagentResultText(subAgentMessages)\n if (!subAgentResultText) {\n continue\n }\n\n state.subAgentResultCache.set(part.callID, subAgentResultText)\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, subAgentResultText),\n state.idFormat,\n )\n }\n }\n}\n","import type { CompressionBlock, PruneMessagesState } from \"../state\"\n\nexport interface CompressionTarget {\n displayId: number\n runId: number\n topic: string\n compressedTokens: number\n durationMs: number\n blocks: CompressionBlock[]\n}\n\nfunction byBlockId(a: CompressionBlock, b: CompressionBlock): number {\n return a.blockId - b.blockId\n}\n\nfunction buildTarget(block: CompressionBlock): CompressionTarget {\n return {\n displayId: block.blockId,\n runId: block.runId,\n topic: block.topic,\n compressedTokens: block.compressedTokens,\n durationMs: block.durationMs,\n blocks: [block],\n }\n}\n\nexport function getActiveCompressionTargets(\n messagesState: PruneMessagesState,\n): CompressionTarget[] {\n return Array.from(messagesState.activeBlockIds)\n .map((blockId) => messagesState.blocksById.get(blockId))\n .filter((block): block is CompressionBlock => !!block && block.active)\n .sort(byBlockId)\n .map(buildTarget)\n}\n\nexport function getRecompressibleCompressionTargets(\n messagesState: PruneMessagesState,\n availableMessageIds: Set<string>,\n): CompressionTarget[] {\n return Array.from(messagesState.blocksById.values())\n .filter((block) => availableMessageIds.has(block.compressMessageId))\n .filter((block) => block.deactivatedByUser && !block.active)\n .sort(byBlockId)\n .map(buildTarget)\n}\n\nexport function resolveCompressionTarget(\n messagesState: PruneMessagesState,\n blockId: number,\n): CompressionTarget | null {\n const block = messagesState.blocksById.get(blockId)\n return block ? buildTarget(block) : null\n}\n","import type { Logger } from \"../logger\"\nimport type { CompressionBlock, PruneMessagesState, SessionState, WithParts } from \"../state\"\nimport { syncCompressionBlocks } from \"../messages\"\nimport { parseBlockRef } from \"../message-ids\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport {\n getActiveCompressionTargets,\n resolveCompressionTarget,\n type CompressionTarget,\n} from \"./compression-targets\"\n\nexport interface DecompressCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n}\n\nfunction parseBlockIdArg(arg: string): number | null {\n const normalized = arg.trim().toLowerCase()\n const blockRef = parseBlockRef(normalized) ?? parseBlockRef(normalized, \"compact\")\n if (blockRef !== null) {\n return blockRef\n }\n\n if (!/^[1-9]\\d*$/.test(normalized)) {\n return null\n }\n\n const parsed = Number.parseInt(normalized, 10)\n return Number.isInteger(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction findActiveParentBlockId(\n messagesState: PruneMessagesState,\n block: CompressionBlock,\n): number | null {\n const queue = [...block.parentBlockIds]\n const visited = new Set<number>()\n\n while (queue.length > 0) {\n const parentBlockId = queue.shift()\n if (parentBlockId === undefined || visited.has(parentBlockId)) {\n continue\n }\n visited.add(parentBlockId)\n\n const parent = messagesState.blocksById.get(parentBlockId)\n if (!parent) {\n continue\n }\n\n if (parent.active) {\n return parent.blockId\n }\n\n for (const ancestorId of parent.parentBlockIds) {\n if (!visited.has(ancestorId)) {\n queue.push(ancestorId)\n }\n }\n }\n\n return null\n}\n\nfunction findActiveAncestorBlockId(\n messagesState: PruneMessagesState,\n target: CompressionTarget,\n): number | null {\n for (const block of target.blocks) {\n const activeAncestorBlockId = findActiveParentBlockId(messagesState, block)\n if (activeAncestorBlockId !== null) {\n return activeAncestorBlockId\n }\n }\n\n return null\n}\n\nfunction snapshotActiveMessages(messagesState: PruneMessagesState): Map<string, number> {\n const activeMessages = new Map<string, number>()\n for (const [messageId, entry] of messagesState.byMessageId) {\n if (entry.activeBlockIds.length > 0) {\n activeMessages.set(messageId, entry.tokenCount)\n }\n }\n return activeMessages\n}\n\nfunction formatDecompressMessage(\n target: CompressionTarget,\n restoredMessageCount: number,\n restoredTokens: number,\n reactivatedBlockIds: number[],\n): string {\n const lines: string[] = []\n\n lines.push(`Restored compression ${target.displayId}.`)\n if (target.runId !== target.displayId) {\n lines.push(`Tool call label: Compression #${target.runId}.`)\n }\n if (reactivatedBlockIds.length > 0) {\n const refs = reactivatedBlockIds.map((id) => String(id)).join(\", \")\n lines.push(`Also restored nested compression(s): ${refs}.`)\n }\n\n if (restoredMessageCount > 0) {\n lines.push(\n `Restored ${restoredMessageCount} message(s) (~${formatTokenCount(restoredTokens)}).`,\n )\n } else {\n lines.push(\"No messages were restored.\")\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction formatAvailableBlocksMessage(availableTargets: CompressionTarget[]): string {\n const lines: string[] = []\n\n lines.push(\"Usage: /dcp decompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No compressions are available to restore.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleDecompressCommand(ctx: DecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp decompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n\n if (!targetArg) {\n const availableTargets = getActiveCompressionTargets(messagesState)\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp decompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n const activeBlocks = target.blocks.filter((block) => block.active)\n if (activeBlocks.length === 0) {\n const activeAncestorBlockId = findActiveAncestorBlockId(messagesState, target)\n if (activeAncestorBlockId !== null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is inside compression ${activeAncestorBlockId}. Restore compression ${activeAncestorBlockId} first.`,\n params,\n logger,\n )\n return\n }\n\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is not active.`,\n params,\n logger,\n )\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n const deactivatedAt = Date.now()\n\n for (const block of target.blocks) {\n block.active = false\n block.deactivatedByUser = true\n block.deactivatedAt = deactivatedAt\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let restoredMessageCount = 0\n let restoredTokens = 0\n for (const [messageId, tokenCount] of activeMessagesBefore) {\n const entry = messagesState.byMessageId.get(messageId)\n const isActiveNow = entry ? entry.activeBlockIds.length > 0 : false\n if (!isActiveNow) {\n restoredMessageCount++\n restoredTokens += tokenCount\n }\n }\n\n state.stats.totalPruneTokens = Math.max(0, state.stats.totalPruneTokens - restoredTokens)\n\n const reactivatedBlockIds = Array.from(messagesState.activeBlockIds)\n .filter((blockId) => !activeBlockIdsBefore.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatDecompressMessage(\n target,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Decompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n })\n}\n","/**\n * DCP Help command handler.\n * Shows available DCP commands and their descriptions.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { PluginConfig } from \"../config\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { compressPermission } from \"../compress-permission\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { getCurrentParams } from \"../token-utils\"\n\nexport interface HelpCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nconst TUI_COMMANDS: [string, string][] = [\n [\"DCP Context\", \"Show token usage breakdown for current session\"],\n [\"DCP Stats\", \"Show DCP pruning statistics\"],\n [\"DCP Help\", \"Show this help in a modal\"],\n]\n\nconst TOOL_COMMANDS: Record<string, [string, string]> = {\n compress: [\"/dcp-compress [focus]\", \"Trigger manual compress tool execution\"],\n decompress: [\"/dcp decompress <n>\", \"Restore selected compression\"],\n recompress: [\"/dcp recompress <n>\", \"Re-apply a user-decompressed compression\"],\n}\n\nfunction getVisibleCommands(state: SessionState, config: PluginConfig): [string, string][] {\n const commands = [...TUI_COMMANDS]\n\n if (compressPermission(state, config) !== \"deny\") {\n commands.push(TOOL_COMMANDS.compress)\n }\n\n return commands\n}\n\nexport function formatHelpMessage(state: SessionState, config: PluginConfig): string {\n const commands = getVisibleCommands(state, config)\n const colWidth = Math.max(...commands.map(([cmd]) => cmd.length)) + 4\n const lines: string[] = []\n\n lines.push(\"╭─────────────────────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Commands │\")\n lines.push(\"╰─────────────────────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(` ${\"Manual mode:\".padEnd(colWidth)}${state.manualMode ? \"ON\" : \"OFF\"}`)\n lines.push(\"\")\n lines.push(\" Open the command palette for DCP modal commands.\")\n lines.push(\" Use /dcp-compress [focus] when you want DCP to ask the model to run compression.\")\n lines.push(\"\")\n for (const [cmd, desc] of commands) {\n lines.push(` ${cmd.padEnd(colWidth)}${desc}`)\n }\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleHelpCommand(ctx: HelpCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const { config } = ctx\n const message = formatHelpMessage(state, config)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Help command executed\")\n}\n","/**\n * DCP Manual mode command handler.\n * Handles toggling manual mode and triggering individual tool executions.\n *\n * Usage:\n * /dcp manual [on|off] - Toggle manual mode or set explicit state\n * /dcp-compress [focus] - Trigger manual compress execution\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { saveManualModeSetting } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { buildCompressedBlockGuidance } from \"../prompts/extensions/nudge\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nconst MANUAL_MODE_ON = \"Manual mode is now ON. Use /dcp-compress to trigger context tools manually.\"\n\nconst MANUAL_MODE_OFF = \"Manual mode is now OFF.\"\n\nconst COMPRESS_TRIGGER_PROMPT = [\n \"<compress triggered manually>\",\n \"Manual mode trigger received. You must now use the compress tool.\",\n \"Find the most significant completed conversation content that can be compressed into a high-fidelity technical summary.\",\n \"Follow the active compress mode, preserve all critical implementation details, and choose safe targets.\",\n \"Return after compress with a brief explanation of what content was compressed.\",\n].join(\"\\n\\n\")\n\nfunction getTriggerPrompt(\n tool: \"compress\",\n state: SessionState,\n config: PluginConfig,\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n\n const sections = [base, compressedBlockGuidance]\n if (userFocus && userFocus.trim().length > 0) {\n sections.push(`Additional user focus:\\n${userFocus.trim()}`)\n }\n\n return sections.join(\"\\n\\n\")\n}\n\nexport interface ManualCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport async function handleManualToggleCommand(\n ctx: ManualCommandContext,\n modeArg?: string,\n): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n if (modeArg === \"on\") {\n state.manualMode = \"active\"\n } else if (modeArg === \"off\") {\n state.manualMode = false\n } else {\n state.manualMode = state.manualMode ? false : \"active\"\n }\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(\n client,\n sessionId,\n state.manualMode ? MANUAL_MODE_ON : MANUAL_MODE_OFF,\n params,\n logger,\n )\n await saveManualModeSetting(sessionId, !!state.manualMode, logger)\n\n logger.info(\"Manual mode toggled\", { manualMode: state.manualMode })\n}\n\nexport async function handleManualTriggerCommand(\n ctx: ManualCommandContext,\n tool: \"compress\",\n userFocus?: string,\n): Promise<string | null> {\n return getTriggerPrompt(tool, ctx.state, ctx.config, userFocus)\n}\n\nexport function applyPendingManualTrigger(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): void {\n const pending = state.pendingManualTrigger\n if (!pending) {\n return\n }\n\n if (!state.sessionId || pending.sessionId !== state.sessionId) {\n state.pendingManualTrigger = null\n return\n }\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n\n for (const part of msg.parts) {\n if (part.type !== \"text\" || part.ignored || part.synthetic) {\n continue\n }\n\n part.text = pending.prompt\n state.pendingManualTrigger = null\n logger.debug(\"Applied manual prompt\", { sessionId: pending.sessionId })\n return\n }\n }\n\n state.pendingManualTrigger = null\n}\n","import type { Logger } from \"../logger\"\nimport type { PruneMessagesState, SessionState, WithParts } from \"../state\"\nimport { syncCompressionBlocks } from \"../messages\"\nimport { parseBlockRef } from \"../message-ids\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport {\n getRecompressibleCompressionTargets,\n resolveCompressionTarget,\n type CompressionTarget,\n} from \"./compression-targets\"\n\nexport interface RecompressCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n}\n\nfunction parseBlockIdArg(arg: string): number | null {\n const normalized = arg.trim().toLowerCase()\n const blockRef = parseBlockRef(normalized) ?? parseBlockRef(normalized, \"compact\")\n if (blockRef !== null) {\n return blockRef\n }\n\n if (!/^[1-9]\\d*$/.test(normalized)) {\n return null\n }\n\n const parsed = Number.parseInt(normalized, 10)\n return Number.isInteger(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction snapshotActiveMessages(messagesState: PruneMessagesState): Set<string> {\n const activeMessages = new Set<string>()\n for (const [messageId, entry] of messagesState.byMessageId) {\n if (entry.activeBlockIds.length > 0) {\n activeMessages.add(messageId)\n }\n }\n return activeMessages\n}\n\nfunction formatRecompressMessage(\n target: CompressionTarget,\n recompressedMessageCount: number,\n recompressedTokens: number,\n deactivatedBlockIds: number[],\n): string {\n const lines: string[] = []\n\n lines.push(`Re-applied compression ${target.displayId}.`)\n if (target.runId !== target.displayId) {\n lines.push(`Tool call label: Compression #${target.runId}.`)\n }\n if (deactivatedBlockIds.length > 0) {\n const refs = deactivatedBlockIds.map((id) => String(id)).join(\", \")\n lines.push(`Also re-compressed nested compression(s): ${refs}.`)\n }\n\n if (recompressedMessageCount > 0) {\n lines.push(\n `Re-compressed ${recompressedMessageCount} message(s) (~${formatTokenCount(recompressedTokens)}).`,\n )\n } else {\n lines.push(\"No messages were re-compressed.\")\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction formatAvailableBlocksMessage(availableTargets: CompressionTarget[]): string {\n const lines: string[] = []\n\n lines.push(\"Usage: /dcp recompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No user-decompressed blocks are available to re-compress.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available user-decompressed compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleRecompressCommand(ctx: RecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp recompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n const availableMessageIds = new Set(messages.map((msg) => msg.info.id))\n\n if (!targetArg) {\n const availableTargets = getRecompressibleCompressionTargets(\n messagesState,\n availableMessageIds,\n )\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp recompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n if (target.blocks.some((block) => !availableMessageIds.has(block.compressMessageId))) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} can no longer be re-applied because its origin message is no longer in this session.`,\n params,\n logger,\n )\n return\n }\n\n if (!target.blocks.some((block) => block.deactivatedByUser)) {\n const message = target.blocks.some((block) => block.active)\n ? `Compression ${target.displayId} is already active.`\n : `Compression ${target.displayId} is not user-decompressed.`\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n\n for (const block of target.blocks) {\n block.deactivatedByUser = false\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let recompressedMessageCount = 0\n let recompressedTokens = 0\n for (const [messageId, entry] of messagesState.byMessageId) {\n const isActiveNow = entry.activeBlockIds.length > 0\n if (isActiveNow && !activeMessagesBefore.has(messageId)) {\n recompressedMessageCount++\n recompressedTokens += entry.tokenCount\n }\n }\n\n state.stats.totalPruneTokens += recompressedTokens\n\n const deactivatedBlockIds = Array.from(activeBlockIdsBefore)\n .filter((blockId) => !messagesState.activeBlockIds.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatRecompressMessage(\n target,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Recompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n })\n}\n","/**\n * DCP Stats command handler.\n * Shows pruning statistics for the current session and all-time totals.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport { loadAllSessionStats, type AggregatedStats } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { normalizeCompressionUsageTotals, type CompressionUsageTotals } from \"../compress/usage\"\nimport { getActiveCompressionTargets } from \"./compression-targets\"\n\nexport interface StatsCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport function formatStatsMessage(\n sessionTokens: number,\n sessionSummaryTokens: number,\n sessionTools: number,\n sessionMessages: number,\n sessionDurationMs: number,\n sessionUsage: CompressionUsageTotals,\n allTime: AggregatedStats,\n): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Statistics │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Compression:\")\n lines.push(\"─\".repeat(60))\n lines.push(\n ` Tokens in|out: ~${formatTokenCount(sessionTokens)} | ~${formatTokenCount(sessionSummaryTokens)}`,\n )\n lines.push(` Ratio: ${formatCompressionRatio(sessionTokens, sessionSummaryTokens)}`)\n lines.push(` Time: ${formatCompressionTime(sessionDurationMs)}`)\n lines.push(` Messages: ${sessionMessages}`)\n lines.push(` Tools: ${sessionTools}`)\n lines.push(\n ` Summary requests: ${sessionUsage.calls} (${sessionUsage.providerCalls} provider, ${sessionUsage.estimatedCalls} estimated)`,\n )\n lines.push(\n ` Request in|out: ~${formatTokenCount(sessionUsage.inputTokens)} | ~${formatTokenCount(sessionUsage.outputTokens)}`,\n )\n lines.push(\n ` Request cache: ~${formatTokenCount(sessionUsage.cacheReadTokens)} read | ~${formatTokenCount(sessionUsage.cacheWriteTokens)} write`,\n )\n lines.push(` Request reason: ~${formatTokenCount(sessionUsage.reasoningTokens)}`)\n lines.push(\"\")\n lines.push(\"All-time:\")\n lines.push(\"─\".repeat(60))\n lines.push(` Tokens saved: ~${formatTokenCount(allTime.totalTokens)}`)\n lines.push(` Tools pruned: ${allTime.totalTools}`)\n lines.push(` Messages pruned: ${allTime.totalMessages}`)\n lines.push(` Sessions: ${allTime.sessionCount}`)\n lines.push(\n ` Summary requests: ${allTime.compressionUsage.calls} (~${formatTokenCount(allTime.compressionUsage.inputTokens)} in | ~${formatTokenCount(allTime.compressionUsage.outputTokens)} out)`,\n )\n\n return lines.join(\"\\n\")\n}\n\nfunction formatCompressionRatio(inputTokens: number, outputTokens: number): string {\n if (inputTokens <= 0) {\n return \"0:1\"\n }\n\n if (outputTokens <= 0) {\n return \"∞:1\"\n }\n\n const ratio = Math.max(1, Math.round(inputTokens / outputTokens))\n return `${ratio}:1`\n}\n\nfunction formatCompressionTime(ms: number): string {\n const safeMs = Math.max(0, Math.round(ms))\n if (safeMs < 1000) {\n return `${safeMs} ms`\n }\n\n const totalSeconds = safeMs / 1000\n if (totalSeconds < 60) {\n return `${totalSeconds.toFixed(1)} s`\n }\n\n const wholeSeconds = Math.floor(totalSeconds)\n const hours = Math.floor(wholeSeconds / 3600)\n const minutes = Math.floor((wholeSeconds % 3600) / 60)\n const seconds = wholeSeconds % 60\n\n if (hours > 0) {\n return `${hours}h ${minutes}m ${seconds}s`\n }\n\n return `${minutes}m ${seconds}s`\n}\n\nexport async function handleStatsCommand(ctx: StatsCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const report = await buildStatsReport(state, logger)\n const message = formatStatsMessage(\n report.sessionTokens,\n report.sessionSummaryTokens,\n report.sessionTools,\n report.sessionMessages,\n report.sessionDurationMs,\n report.sessionCompressionUsage,\n report.allTime,\n )\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Stats command executed\", {\n sessionTokens: report.sessionTokens,\n sessionSummaryTokens: report.sessionSummaryTokens,\n sessionTools: report.sessionTools,\n sessionMessages: report.sessionMessages,\n sessionDurationMs: report.sessionDurationMs,\n sessionCompressionUsage: report.sessionCompressionUsage,\n allTimeTokens: report.allTime.totalTokens,\n allTimeTools: report.allTime.totalTools,\n allTimeMessages: report.allTime.totalMessages,\n allTimeCompressionUsage: report.allTime.compressionUsage,\n })\n}\n\nexport async function buildStatsReport(state: SessionState, logger: Logger) {\n const sessionTokens = state.stats.totalPruneTokens\n const sessionSummaryTokens = Array.from(state.prune.messages.blocksById.values()).reduce(\n (total, block) => (block.active ? total + block.summaryTokens : total),\n 0,\n )\n const sessionDurationMs = getActiveCompressionTargets(state.prune.messages).reduce(\n (total, target) => total + target.durationMs,\n 0,\n )\n\n const prunedToolIds = new Set<string>(state.prune.tools.keys())\n for (const block of state.prune.messages.blocksById.values()) {\n if (block.active) {\n for (const toolId of block.effectiveToolIds) {\n prunedToolIds.add(toolId)\n }\n }\n }\n const sessionTools = prunedToolIds.size\n\n const sessionCompressionUsage = normalizeCompressionUsageTotals(state.stats.compressionUsage)\n\n let sessionMessages = 0\n for (const entry of state.prune.messages.byMessageId.values()) {\n if (entry.activeBlockIds.length > 0) {\n sessionMessages++\n }\n }\n\n // All-time stats from storage files\n const allTime = await loadAllSessionStats(logger)\n\n return {\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n sessionCompressionUsage,\n allTime,\n }\n}\n","/**\n * DCP Sweep command handler.\n * Prunes tool outputs since the last user message, or the last N tools.\n *\n * Usage:\n * /dcp sweep - Prune all tools since the previous user message\n * /dcp sweep 10 - Prune the last 10 tools\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts, ToolParameterEntry } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatPrunedItemsList } from \"../ui/utils\"\nimport { getCurrentParams, getTotalToolTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { buildToolIdList } from \"../messages/utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport { isToolProtected } from \"../protected-patterns\"\nimport { syncToolCache } from \"../state/tool-cache\"\n\nexport interface SweepCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n workingDirectory: string\n}\n\nfunction findLastUserMessageIndex(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return i\n }\n }\n\n return -1\n}\n\nfunction collectToolIdsAfterIndex(\n state: SessionState,\n messages: WithParts[],\n afterIndex: number,\n): string[] {\n const toolIds: string[] = []\n\n for (let i = afterIndex + 1; i < messages.length; i++) {\n const msg = messages[i]\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n\n return toolIds\n}\n\nfunction formatNoUserMessage(): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Nothing swept: no user message found.\")\n\n return lines.join(\"\\n\")\n}\n\nfunction formatSweepMessage(\n toolCount: number,\n tokensSaved: number,\n mode: \"since-user\" | \"last-n\",\n toolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n skippedProtected?: number,\n): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n\n if (toolCount === 0) {\n if (mode === \"since-user\") {\n lines.push(\"No tools found since the previous user message.\")\n } else {\n lines.push(`No tools found to sweep.`)\n }\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n } else {\n if (mode === \"since-user\") {\n lines.push(`Swept ${toolCount} tool(s) since the previous user message.`)\n } else {\n lines.push(`Swept the last ${toolCount} tool(s).`)\n }\n lines.push(`Tokens saved: ~${tokensSaved.toLocaleString()}`)\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n lines.push(\"\")\n const itemLines = formatPrunedItemsList(toolIds, toolMetadata, workingDirectory)\n lines.push(...itemLines)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleSweepCommand(ctx: SweepCommandContext): Promise<void> {\n const { client, state, config, logger, sessionId, messages, args, workingDirectory } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const protectedTools = config.commands.protectedTools\n\n syncToolCache(state, config, logger, messages)\n buildToolIdList(state, messages)\n\n // Parse optional numeric argument\n const numArg = args[0] ? parseInt(args[0], 10) : null\n const isLastNMode = numArg !== null && !isNaN(numArg) && numArg > 0\n\n let toolIdsToSweep: string[]\n let mode: \"since-user\" | \"last-n\"\n\n if (isLastNMode) {\n // Mode: Sweep last N tools\n mode = \"last-n\"\n const startIndex = Math.max(0, state.toolIdList.length - numArg!)\n toolIdsToSweep = state.toolIdList.slice(startIndex)\n logger.info(`Sweep command: last ${numArg} mode, found ${toolIdsToSweep.length} tools`)\n } else {\n // Mode: Sweep since last user message\n mode = \"since-user\"\n const lastUserMsgIndex = findLastUserMessageIndex(messages)\n\n if (lastUserMsgIndex === -1) {\n // No user message found - show message and return\n const message = formatNoUserMessage()\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no user message found\")\n return\n } else {\n toolIdsToSweep = collectToolIdsAfterIndex(state, messages, lastUserMsgIndex)\n logger.info(\n `Sweep command: found last user at index ${lastUserMsgIndex}, sweeping ${toolIdsToSweep.length} tools`,\n )\n }\n }\n\n // Filter out already-pruned tools, protected tools, and protected file paths\n const newToolIds = toolIdsToSweep.filter((id) => {\n if (state.prune.tools.has(id)) {\n return false\n }\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return true\n }\n if (\n isToolProtected(\n entry.tool,\n entry.parameters,\n protectedTools,\n config.protectedFilePatterns,\n entry.metadata,\n )\n ) {\n logger.debug(`Sweep: skipping protected tool ${entry.tool} (${id})`)\n return false\n }\n return true\n })\n\n // Count how many were skipped due to protection\n const skippedProtected = toolIdsToSweep.filter((id) => {\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return false\n }\n return isToolProtected(\n entry.tool,\n entry.parameters,\n protectedTools,\n config.protectedFilePatterns,\n entry.metadata,\n )\n }).length\n\n if (newToolIds.length === 0) {\n const message = formatSweepMessage(\n 0,\n 0,\n mode,\n [],\n new Map(),\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no new tools to sweep\", { skippedProtected })\n return\n }\n\n const tokensSaved = getTotalToolTokens(state, newToolIds)\n\n // Add to prune list\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n state.stats.pruneTokenCounter += tokensSaved\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n // Collect metadata for logging\n const toolMetadata: Map<string, ToolParameterEntry> = new Map()\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n if (entry) {\n toolMetadata.set(id, entry)\n }\n }\n\n // Persist state\n saveSessionState(state, logger).catch((err) =>\n logger.error(\"Failed to persist state after sweep\", { error: err.message }),\n )\n\n const message = formatSweepMessage(\n newToolIds.length,\n tokensSaved,\n mode,\n newToolIds,\n toolMetadata,\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Sweep command completed\", {\n toolsSwept: newToolIds.length,\n tokensSaved,\n skippedProtected,\n mode,\n tools: Array.from(toolMetadata.entries()).map(([id, entry]) => ({\n id,\n tool: entry.tool,\n })),\n })\n}\n","import type { SessionState, WithParts } from \"./state\"\nimport type { Logger } from \"./logger\"\nimport type { PluginConfig } from \"./config\"\nimport { renderSystemPrompt, type PromptStore } from \"./prompts\"\nimport { buildProtectedToolsExtension } from \"./prompts/extensions/system\"\nimport { filterMessages } from \"./messages/shape\"\nimport {\n handleContextCommand,\n handleDecompressCommand,\n handleHelpCommand,\n handleManualToggleCommand,\n handleManualTriggerCommand,\n handleRecompressCommand,\n handleStatsCommand,\n handleSweepCommand,\n} from \"./commands\"\nimport { compressPermission } from \"./compress-permission\"\nimport { ensureSessionInitialized } from \"./state\"\n\nconst INTERNAL_AGENT_SIGNATURES = [\n \"You are a title generator\",\n \"You are a helpful AI assistant tasked with summarizing conversations\",\n \"You are an anchored context summarization assistant for coding sessions\",\n \"Summarize what was done in this conversation\",\n]\n\nfunction isInternalAgentCall(systemPrompts: string[]): boolean {\n const primaryPrompt = systemPrompts[0]\n if (typeof primaryPrompt !== \"string\" || primaryPrompt.length === 0) {\n return false\n }\n\n return INTERNAL_AGENT_SIGNATURES.some((signature) => primaryPrompt.includes(signature))\n}\n\nexport function createSystemPromptHandler(\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n) {\n return async (\n input: { sessionID?: string; model: { limit: { context: number } } },\n output: { system: string[] },\n ) => {\n if (input.model?.limit?.context) {\n state.modelContextLimit = input.model.limit.context\n logger.debug(\"Cached model context limit\", { limit: state.modelContextLimit })\n }\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n if (isInternalAgentCall(output.system)) {\n logger.info(\"Skipping DCP system prompt injection for internal agent\")\n return\n }\n\n const effectivePermission =\n input.sessionID && state.sessionId === input.sessionID\n ? compressPermission(state, config)\n : config.compress.permission\n\n if (effectivePermission === \"deny\") {\n return\n }\n\n prompts.reload()\n const runtimePrompts = prompts.getRuntimePrompts()\n const newPrompt = renderSystemPrompt(\n runtimePrompts,\n buildProtectedToolsExtension(config.compress.protectedTools),\n !!state.manualMode,\n state.isSubAgent && config.experimental.allowSubAgents,\n )\n if (output.system.length > 0) {\n output.system[output.system.length - 1] += \"\\n\\n\" + newPrompt\n } else {\n output.system.push(newPrompt)\n }\n }\n}\n\nexport function createCommandExecuteHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n workingDirectory: string,\n) {\n return async (\n input: { command: string; sessionID: string; arguments: string },\n output: { parts: any[] },\n ) => {\n if (!config.commands.enabled) {\n return\n }\n\n if (input.command === \"dcp\" || input.command === \"dcp-compress\") {\n const messagesResponse = await client.session.messages({\n path: { id: input.sessionID },\n })\n const messages: WithParts[] = filterMessages(messagesResponse.data || messagesResponse)\n\n await ensureSessionInitialized(\n client,\n state,\n input.sessionID,\n logger,\n messages,\n config.manualMode.enabled,\n )\n\n const effectivePermission = compressPermission(state, config)\n if (effectivePermission === \"deny\") {\n return\n }\n\n const args = (input.arguments || \"\").trim().split(/\\s+/).filter(Boolean)\n const isCompressCommand = input.command === \"dcp-compress\"\n const subcommand = isCompressCommand ? \"compress\" : args[0]?.toLowerCase() || \"\"\n const subArgs = isCompressCommand ? args : args.slice(1)\n\n const commandCtx = {\n client,\n state,\n config,\n logger,\n sessionId: input.sessionID,\n messages,\n }\n\n if (subcommand === \"context\") {\n await handleContextCommand(commandCtx)\n return\n }\n\n if (subcommand === \"stats\") {\n await handleStatsCommand(commandCtx)\n return\n }\n\n if (subcommand === \"sweep\") {\n await handleSweepCommand({\n ...commandCtx,\n args: subArgs,\n workingDirectory,\n })\n return\n }\n\n if (subcommand === \"manual\") {\n await handleManualToggleCommand(commandCtx, subArgs[0]?.toLowerCase())\n return\n }\n\n if (subcommand === \"compress\") {\n const userFocus = subArgs.join(\" \").trim()\n const prompt = await handleManualTriggerCommand(commandCtx, \"compress\", userFocus)\n if (!prompt) {\n throw new Error(\"__DCP_MANUAL_TRIGGER_BLOCKED__\")\n }\n\n state.manualMode = \"compress-pending\"\n state.pendingManualTrigger = {\n sessionId: input.sessionID,\n prompt,\n }\n const rawArgs = (input.arguments || \"\").trim()\n output.parts.length = 0\n output.parts.push({\n type: \"text\",\n text: isCompressCommand\n ? rawArgs\n ? `/dcp-compress ${rawArgs}`\n : \"/dcp-compress\"\n : rawArgs\n ? `/dcp ${rawArgs}`\n : `/dcp ${subcommand}`,\n })\n return\n }\n\n if (subcommand === \"decompress\") {\n await handleDecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n return\n }\n\n if (subcommand === \"recompress\") {\n await handleRecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n return\n }\n\n await handleHelpCommand(commandCtx)\n return\n }\n }\n}\n","import type { Message, ContentPart, ToolResultPart } from \"@opencode/ai/schema/messages\"\nimport type { Plugin } from \"@opencode/plugin\"\nimport type { WithParts } from \"../state\"\n\ntype History = Awaited<ReturnType<Plugin.Context[\"session\"][\"context\"]>>\ntype Session = Awaited<ReturnType<Plugin.Context[\"session\"][\"get\"]>>\ntype Part = WithParts[\"parts\"][number]\n\nconst emptyUsage = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }\n\nfunction info(id: string, role: string, session: Session, entry?: History[number]) {\n const model = entry?.type === \"assistant\" ? entry.model : session.model\n return {\n id,\n role,\n sessionID: session.id,\n time: { created: entry?.time.created ?? 0 },\n agent: entry?.type === \"assistant\" ? entry.agent : session.agent,\n model: { providerID: model?.providerID, modelID: model?.id, variant: model?.variant },\n providerID: model?.providerID,\n modelID: model?.id,\n tokens: entry?.type === \"assistant\" ? (entry.tokens ?? emptyUsage) : emptyUsage,\n summary: entry?.type === \"compaction\" && entry.status === \"completed\",\n } as unknown as WithParts[\"info\"]\n}\n\n// Bookkeeping projections are never sent to a provider. Native messages remain\n// authoritative for reasoning, media, checkpoints, and provider metadata.\nexport function history(entries: History, session: Session): WithParts[] {\n return entries.flatMap((entry): WithParts[] => {\n const base = { sessionID: session.id, messageID: entry.id }\n if (entry.type === \"assistant\") {\n const parts = entry.content.map((part, index) => {\n if (part.type !== \"tool\")\n return { ...base, id: `${entry.id}:${index}`, type: part.type, text: part.text }\n const state = part.state\n return {\n ...base,\n id: part.id,\n type: \"tool\",\n callID: part.id,\n tool: part.name,\n state: {\n ...state,\n input: structuredClone(state.input),\n ...(state.status === \"completed\" ? { output: output(state.content) } : {}),\n },\n }\n })\n return [\n {\n info: info(entry.id, \"assistant\", session, entry),\n parts: [{ ...base, id: `${entry.id}:step`, type: \"step-start\" }, ...parts],\n } as WithParts,\n ]\n }\n let text: string | undefined\n if (entry.type === \"user\")\n text = [\n ...(entry.skills ?? []).flatMap((skill) =>\n skill.text === undefined ? [] : [skill.text],\n ),\n entry.text,\n ].join(\"\\n\\n\")\n if (entry.type === \"synthetic\" || entry.type === \"skill\") text = entry.text\n if (entry.type === \"location-switched\")\n text = `The working directory has been changed to ${entry.location.directory}.`\n if (entry.type === \"shell\" && entry.metadata?.background !== true)\n text = `The following shell command was executed by the user:\\n\\nCommand:\\n${entry.command}\\n\\nOutput:\\n${entry.output?.output ?? \"\"}`\n if (text !== undefined) {\n return [\n {\n info: info(entry.id, \"user\", session, entry),\n parts: [{ ...base, id: `${entry.id}:text`, type: \"text\", text }],\n } as WithParts,\n ]\n }\n if (entry.type === \"compaction\" && entry.status === \"completed\") {\n return [{ info: info(entry.id, \"assistant\", session, entry), parts: [] } as WithParts]\n }\n return []\n })\n}\n\nfunction output(content: ReadonlyArray<{ type: string; text?: string }>): unknown {\n return content.length === 1 && content[0]?.type === \"text\"\n ? content[0].text\n : structuredClone(content)\n}\n\nexport function project(native: Message[], entries: History, session: Session) {\n const byID = new Map(entries.map((entry) => [entry.id, entry]))\n const results = new Map<string, ToolResultPart>()\n const owners = new Map<string, string>()\n const links = new Map<ContentPart, Part>()\n const originals = new Map<string, WithParts>()\n const messages: WithParts[] = []\n for (const message of native)\n for (const part of message.content) {\n if (part.type === \"tool-result\") results.set(part.id, part)\n if (part.type === \"tool-call\" && message.id) owners.set(part.id, message.id)\n }\n for (const message of native) {\n if (!message.id || ![\"user\", \"assistant\"].includes(message.role)) continue\n const entry = byID.get(message.id)\n if (!entry || entry.type === \"compaction\") continue\n const base = { sessionID: session.id, messageID: message.id }\n const parts: Part[] = []\n if (message.role === \"assistant\")\n parts.push({ ...base, id: `${message.id}:step`, type: \"step-start\" })\n for (const [index, part] of message.content.entries()) {\n let projected: Part | undefined\n if (part.type === \"text\")\n projected = { ...base, id: `${message.id}:${index}`, type: \"text\", text: part.text }\n if (part.type === \"media\") {\n // Tolerate both media shapes: older hosts expose mediaType/data\n // directly, newer ones nest them under `media`.\n const media: any = (part as any).media\n const legacy: any = part as any\n const mime = media?.mediaType ?? legacy.mediaType ?? \"\"\n const source = media?.source\n const url =\n typeof legacy.data === \"string\"\n ? legacy.data\n : typeof source?.data === \"string\"\n ? source.data\n : typeof source?.url === \"string\"\n ? source.url\n : \"\"\n projected = {\n ...base,\n id: `${message.id}:${index}`,\n type: \"file\",\n mime,\n url,\n }\n }\n if (part.type === \"tool-call\") {\n const result = results.get(part.id)\n const entry = byID.get(message.id)\n const durable =\n entry?.type === \"assistant\"\n ? entry.content.find((item) => item.type === \"tool\" && item.id === part.id)\n : undefined\n projected = {\n ...base,\n id: part.id,\n type: \"tool\",\n callID: part.id,\n tool: part.name,\n state: {\n status: !result\n ? \"running\"\n : result.result.type === \"error\"\n ? \"error\"\n : \"completed\",\n input: structuredClone(part.input),\n ...(result?.result.type === \"error\"\n ? { error: result.result.value }\n : {\n output: structuredClone(\n result?.result.type === \"text\"\n ? result.result.value\n : result?.result,\n ),\n }),\n metadata:\n durable?.type === \"tool\" && \"metadata\" in durable.state\n ? durable.state.metadata\n : {},\n },\n } as Part\n if (result) links.set(result, projected)\n }\n if (projected) {\n parts.push(projected)\n links.set(part, projected)\n }\n }\n const projected = {\n info: info(message.id, message.role, session, byID.get(message.id)),\n parts,\n } as WithParts\n messages.push(projected)\n originals.set(message.id, projected)\n }\n\n function restore(): Message[] {\n const retained = new Set(messages.map((message) => message.info.id))\n const linked = new Set(links.values())\n const output: Message[] = []\n let next = 0\n const synthetic = () => {\n while (next < messages.length && !originals.has(messages[next]!.info.id)) {\n const message = messages[next++]!\n output.push({\n id: message.info.id,\n role: \"user\",\n content: message.parts\n .filter((part) => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text })),\n })\n }\n }\n for (const message of native) {\n const projected = message.id ? originals.get(message.id) : undefined\n if (projected) {\n synthetic()\n if (!retained.has(message.id!)) continue\n next++\n }\n const content: ContentPart[] = []\n const added =\n projected?.parts.flatMap((part) =>\n part.type === \"text\" && !linked.has(part)\n ? [{ type: \"text\" as const, text: part.text }]\n : [],\n ) ?? []\n for (const part of message.content) {\n if (part.type === \"tool-call\") content.push(...added.splice(0))\n if (\n part.type === \"tool-result\" &&\n originals.has(owners.get(part.id)!) &&\n !retained.has(owners.get(part.id)!)\n )\n continue\n const edit = links.get(part)\n if (part.type === \"text\" && edit?.type === \"text\")\n content.push({ ...part, text: edit.text })\n else if (part.type === \"tool-call\" && edit?.type === \"tool\")\n content.push({ ...part, input: edit.state.input })\n else if (\n part.type === \"tool-result\" &&\n edit?.type === \"tool\" &&\n edit.state.status === \"completed\" &&\n typeof edit.state.output === \"string\" &&\n edit.state.output !== part.result.value\n ) {\n content.push({ ...part, result: { type: \"text\", value: edit.state.output } })\n } else content.push(part)\n }\n content.push(...added)\n if (content.length || message.content.length === 0) output.push({ ...message, content })\n }\n synthetic()\n return output\n }\n // A native checkpoint can replace every user message. Summary construction\n // still needs session/agent/model fields, without projecting that checkpoint.\n const summaryBase: WithParts = { info: info(\"msg_dcp_base\", \"user\", session), parts: [] }\n return { messages, restore, summaryBase }\n}\n","import { tool } from \"@opencode-ai/plugin\"\n\nconst z = tool.schema\nconst session = z.object({ sessionID: z.string() })\nconst compressionUsage = z.object({\n calls: z.number(),\n providerCalls: z.number(),\n estimatedCalls: z.number(),\n inputTokens: z.number(),\n outputTokens: z.number(),\n cacheReadTokens: z.number(),\n cacheWriteTokens: z.number(),\n reasoningTokens: z.number(),\n})\nconst stats = z.object({\n sessionTokens: z.number(),\n sessionSummaryTokens: z.number(),\n sessionDurationMs: z.number(),\n sessionTools: z.number(),\n sessionMessages: z.number(),\n sessionCompressionUsage: compressionUsage,\n allTime: z.object({\n totalTokens: z.number(),\n totalTools: z.number(),\n totalMessages: z.number(),\n sessionCount: z.number(),\n compressionUsage,\n }),\n})\nconst context = z.object({\n system: z.number(),\n user: z.number(),\n assistant: z.number(),\n tools: z.number(),\n toolCount: z.number(),\n toolsInContextCount: z.number(),\n prunedTokens: z.number(),\n prunedToolCount: z.number(),\n prunedMessageCount: z.number(),\n total: z.number(),\n})\n\nexport const rpc = {\n id: \"dcp-rc\",\n methods: {\n status: { input: z.object({}), output: z.object({ enabled: z.boolean() }) },\n snapshot: {\n input: session,\n output: z.object({\n manualMode: z.boolean(),\n canCompress: z.boolean(),\n blockedReason: z.string().optional(),\n context,\n stats,\n }),\n },\n manual: { input: session.extend({ enabled: z.boolean() }), output: z.object({}) },\n },\n events: {},\n} as const\n","import type { Plugin } from \"@opencode/plugin\"\nimport { setup } from \"./lib/v2\"\n\nexport default {\n id: \"@royalcat/opencode-dcp-rc\",\n setup,\n} satisfies Plugin.Plugin\n"],"mappings":"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I,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC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","names":["tool","value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","project","parse","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","join","dirname","homedir","format","format","format","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","existsSync","homedir","join","output","info","output","countTokens","countTokens","join","homedir","existsSync","format","format","context","tool","tool","tool","format","output","output","format","parse","format","context","text","countTokens","countTokens","session","countTokens","format","collectTurnNudgeAnchors","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","report","message","output","session","projected","entry","output","tool","session","rule","countTokens","context","tool","output"]}