@lexwdex-org/opencode-dcp 3.4.8 → 3.4.10
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.
- package/README.en.md +2 -2
- package/README.md +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +870 -357
- package/dist/index.js.map +1 -1
- package/dist/lib/commands/context.d.ts +2 -1
- package/dist/lib/commands/context.d.ts.map +1 -1
- package/dist/lib/commands/decompress.d.ts +2 -1
- package/dist/lib/commands/decompress.d.ts.map +1 -1
- package/dist/lib/commands/help.d.ts +2 -1
- package/dist/lib/commands/help.d.ts.map +1 -1
- package/dist/lib/commands/manual.d.ts +2 -1
- package/dist/lib/commands/manual.d.ts.map +1 -1
- package/dist/lib/commands/recompress.d.ts +2 -1
- package/dist/lib/commands/recompress.d.ts.map +1 -1
- package/dist/lib/commands/stats.d.ts +2 -1
- package/dist/lib/commands/stats.d.ts.map +1 -1
- package/dist/lib/commands/sweep.d.ts +2 -1
- package/dist/lib/commands/sweep.d.ts.map +1 -1
- package/dist/lib/compress/external-content.d.ts +4 -0
- package/dist/lib/compress/external-content.d.ts.map +1 -0
- package/dist/lib/compress/external-inference.d.ts.map +1 -1
- package/dist/lib/compress/message.d.ts.map +1 -1
- package/dist/lib/compress/pipeline.d.ts +3 -2
- package/dist/lib/compress/pipeline.d.ts.map +1 -1
- package/dist/lib/compress/protected-content.d.ts +2 -1
- package/dist/lib/compress/protected-content.d.ts.map +1 -1
- package/dist/lib/compress/range.d.ts.map +1 -1
- package/dist/lib/compress/search.d.ts +2 -1
- package/dist/lib/compress/search.d.ts.map +1 -1
- package/dist/lib/compress/timing.d.ts +2 -0
- package/dist/lib/compress/timing.d.ts.map +1 -1
- package/dist/lib/compress/types.d.ts +4 -3
- package/dist/lib/compress/types.d.ts.map +1 -1
- package/dist/lib/compress-permission.d.ts.map +1 -1
- package/dist/lib/concurrency.d.ts +2 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts +6 -5
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/messages/inject/inject.d.ts.map +1 -1
- package/dist/lib/messages/inject/subagent-results.d.ts +2 -1
- package/dist/lib/messages/inject/subagent-results.d.ts.map +1 -1
- package/dist/lib/messages/inject/utils.d.ts +2 -2
- package/dist/lib/messages/inject/utils.d.ts.map +1 -1
- package/dist/lib/messages/utils.d.ts.map +1 -1
- package/dist/lib/opencode-client.d.ts +3 -0
- package/dist/lib/opencode-client.d.ts.map +1 -0
- package/dist/lib/prompts/context-limit-nudge.d.ts +1 -1
- package/dist/lib/prompts/context-limit-nudge.d.ts.map +1 -1
- package/dist/lib/prompts/iteration-nudge.d.ts +1 -1
- package/dist/lib/prompts/iteration-nudge.d.ts.map +1 -1
- package/dist/lib/prompts/store.d.ts +1 -0
- package/dist/lib/prompts/store.d.ts.map +1 -1
- package/dist/lib/prompts/system.d.ts +1 -1
- package/dist/lib/prompts/system.d.ts.map +1 -1
- package/dist/lib/prompts/turn-nudge.d.ts +1 -1
- package/dist/lib/prompts/turn-nudge.d.ts.map +1 -1
- package/dist/lib/state/index.d.ts +1 -0
- package/dist/lib/state/index.d.ts.map +1 -1
- package/dist/lib/state/persistence.d.ts +1 -0
- package/dist/lib/state/persistence.d.ts.map +1 -1
- package/dist/lib/state/state.d.ts +5 -2
- package/dist/lib/state/state.d.ts.map +1 -1
- package/dist/lib/state/store.d.ts +38 -0
- package/dist/lib/state/store.d.ts.map +1 -0
- package/dist/lib/state/tool-cache.d.ts.map +1 -1
- package/dist/lib/state/types.d.ts +2 -1
- package/dist/lib/state/types.d.ts.map +1 -1
- package/dist/lib/state/utils.d.ts +4 -1
- package/dist/lib/state/utils.d.ts.map +1 -1
- package/dist/lib/strategies/deduplication.d.ts.map +1 -1
- package/dist/lib/token-utils.d.ts +0 -1
- package/dist/lib/token-utils.d.ts.map +1 -1
- package/dist/lib/ui/notification.d.ts +4 -3
- package/dist/lib/ui/notification.d.ts.map +1 -1
- package/dist/lib/update.d.ts +3 -9
- package/dist/lib/update.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/lib/auth.d.ts +0 -4
- package/dist/lib/auth.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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/config-env-override.ts","../lib/compress/message.ts","../lib/token-utils.ts","../lib/messages/shape.ts","../lib/messages/query.ts","../lib/prompts/extensions/tool.ts","../lib/message-ids.ts","../lib/compress/search.ts","../lib/compress/state.ts","../lib/compress/message-utils.ts","../lib/state/persistence.ts","../lib/state/utils.ts","../lib/compress/timing.ts","../lib/state/state.ts","../lib/state/tool-cache.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/subagents/subagent-results.ts","../lib/compress/protected-content.ts","../lib/compress/external-inference.ts","../lib/compress/range.ts","../lib/compress/range-utils.ts","../lib/host-permissions.ts","../lib/logger.ts","../lib/prompts/store.ts","../lib/prompts/system.ts","../lib/prompts/compress-range.ts","../lib/prompts/compress-message.ts","../lib/prompts/context-limit-nudge.ts","../lib/prompts/turn-nudge.ts","../lib/prompts/iteration-nudge.ts","../lib/prompts/extensions/system.ts","../lib/messages/utils.ts","../lib/messages/prune.ts","../lib/messages/sync.ts","../lib/compress-permission.ts","../lib/prompts/extensions/nudge.ts","../lib/messages/priority.ts","../lib/messages/inject/utils.ts","../lib/messages/inject/inject.ts","../lib/messages/inject/subagent-results.ts","../lib/messages/reasoning-strip.ts","../lib/prompts/index.ts","../lib/commands/context.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/auth.ts","../lib/update.ts","../index.ts"],"sourcesContent":["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\"\nimport { applyExternalModelEnvOverride } from \"./config-env-override\"\n\ntype Permission = \"ask\" | \"allow\" | \"deny\"\ntype CompressMode = \"range\" | \"message\"\n\nexport interface Deduplication {\n enabled: boolean\n protectedTools: string[]\n}\n\nexport interface ExternalModelConfig {\n url: string\n apiKey?: string\n model: string\n timeout?: number\n retries?: number\n}\n\nexport interface CompressConfig {\n mode: CompressMode\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 externalModel?: ExternalModelConfig\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 autoUpdate: 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 \"autoUpdate\",\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.mode\",\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 \"compress.externalModel\",\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.autoUpdate !== undefined && typeof config.autoUpdate !== \"boolean\") {\n errors.push({ key: \"autoUpdate\", expected: \"boolean\", actual: typeof config.autoUpdate })\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.mode !== undefined &&\n compress.mode !== \"range\" &&\n compress.mode !== \"message\"\n ) {\n errors.push({\n key: \"compress.mode\",\n expected: '\"range\" | \"message\"',\n actual: JSON.stringify(compress.mode),\n })\n }\n\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 (compress.externalModel !== undefined) {\n if (\n typeof compress.externalModel !== \"object\" ||\n compress.externalModel === null ||\n Array.isArray(compress.externalModel)\n ) {\n errors.push({\n key: \"compress.externalModel\",\n expected: \"object with url and model\",\n actual: typeof compress.externalModel,\n })\n } else {\n if (typeof compress.externalModel.url !== \"string\") {\n errors.push({\n key: \"compress.externalModel.url\",\n expected: \"string\",\n actual: typeof compress.externalModel.url,\n })\n }\n if (typeof compress.externalModel.model !== \"string\") {\n errors.push({\n key: \"compress.externalModel.model\",\n expected: \"string\",\n actual: typeof compress.externalModel.model,\n })\n }\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: PluginInput,\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 autoUpdate: true,\n debug: false,\n pruneNotification: \"detailed\",\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 mode: \"range\",\n permission: \"allow\",\n showCompression: false,\n summaryBuffer: true,\n maxContextLimit: \"85%\",\n minContextLimit: \"50%\",\n nudgeFrequency: 2,\n iterationNudgeThreshold: 15,\n nudgeForce: \"strong\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n externalModel: undefined,\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.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.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?: PluginInput): {\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.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.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.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.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 \"$schema\": \"https://raw.githubusercontent.com/LeXwDeX/opencode-dynamic-context-pruning/master/dcp.schema.json\"\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 mode: override.mode ?? base.mode,\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 externalModel: override.externalModel ?? base.externalModel,\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 externalModel: config.compress.externalModel\n ? { ...config.compress.externalModel }\n : undefined,\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 autoUpdate: data.autoUpdate ?? config.autoUpdate,\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: PluginInput, 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: PluginInput): 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 applyExternalModelEnvOverride(config)\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 type { ExternalModelConfig, PluginConfig } from \"./config\"\n\nexport function applyExternalModelEnvOverride(config: PluginConfig): void {\n const envUrl = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_URL\n const envApiKey = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_KEY\n const envModel = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_MODEL\n const envTimeout = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_TIMEOUT\n const envRetries = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_RETRIES\n\n if (envUrl && envModel) {\n const externalModel: ExternalModelConfig = {\n url: envUrl,\n model: envModel,\n }\n if (envApiKey) {\n externalModel.apiKey = envApiKey\n }\n if (envTimeout) {\n const parsed = parseInt(envTimeout, 10)\n if (parsed > 0) {\n externalModel.timeout = parsed\n }\n }\n if (envRetries) {\n const parsed = parseInt(envRetries, 10)\n if (parsed >= 0) {\n externalModel.retries = parsed\n }\n }\n config.compress.externalModel = externalModel\n }\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { buildMessageFormatExtension } from \"../prompts/extensions/tool\"\nimport { formatIssues, formatResult, resolveMessages, validateArgs } from \"./message-utils\"\nimport { finalizeSession, prepareSession, type NotificationEntry } from \"./pipeline\"\nimport { appendProtectedPromptInfo, appendProtectedTools } from \"./protected-content\"\nimport {\n allocateBlockId,\n allocateRunId,\n applyCompressionState,\n wrapCompressedSummary,\n} from \"./state\"\nimport type { CompressMessageToolArgs, SearchContext } from \"./types\"\nimport { generateSummaryViaExternal } from \"./external-inference\"\n\nfunction extractMessageText(messageId: string, searchContext: SearchContext): string {\n const msg = searchContext.rawMessagesById.get(messageId)\n if (!msg) return \"\"\n const parts: string[] = []\n for (const part of msg.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n parts.push(part.text)\n }\n }\n return parts.join(\"\\n\\n\")\n}\n\nfunction buildSchema(externalModelEnabled: boolean) {\n const summaryField = externalModelEnabled\n ? tool.schema\n .string()\n .optional()\n .describe(\n \"Complete technical summary replacing that one message (optional when external model is configured)\",\n )\n : tool.schema.string().describe(\"Complete technical summary replacing that one message\")\n\n return {\n topic: tool.schema\n .string()\n .describe(\n \"Short label (3-5 words) for the overall batch - e.g., 'Closed Research Notes'\",\n ),\n content: tool.schema\n .array(\n tool.schema.object({\n messageId: tool.schema\n .string()\n .describe(\"Raw message ID to compress (e.g. m0001)\"),\n topic: tool.schema\n .string()\n .describe(\"Short label (3-5 words) for this one message summary\"),\n summary: summaryField,\n }),\n )\n .describe(\"Batch of individual message summaries to create in one tool call\"),\n }\n}\n\nexport function createCompressMessageTool(ctx: ToolContext): ReturnType<typeof tool> {\n ctx.prompts.reload()\n const runtimePrompts = ctx.prompts.getRuntimePrompts()\n const externalModelEnabled = ctx.config.compress.externalModel !== undefined\n\n return tool({\n description:\n runtimePrompts.compressMessage + buildMessageFormatExtension(externalModelEnabled),\n args: buildSchema(externalModelEnabled),\n async execute(args, toolCtx) {\n const input = args as CompressMessageToolArgs\n validateArgs(input)\n const callId =\n typeof (toolCtx as unknown as { callID?: unknown }).callID === \"string\"\n ? (toolCtx as unknown as { callID: string }).callID\n : undefined\n\n const { rawMessages, searchContext } = await prepareSession(\n ctx,\n toolCtx,\n `Compress Message: ${input.topic}`,\n )\n const { plans, skippedIssues, skippedCount } = resolveMessages(\n input,\n searchContext,\n ctx.state,\n ctx.config,\n )\n\n if (plans.length === 0 && skippedCount > 0) {\n throw new Error(formatIssues(skippedIssues, skippedCount))\n }\n\n if (ctx.config.compress.externalModel) {\n for (const plan of plans) {\n if (plan.entry.summary === undefined) {\n const userContent = extractMessageText(plan.entry.messageId, searchContext)\n const generated = await generateSummaryViaExternal(\n ctx.config.compress.externalModel,\n {\n systemPrompt: runtimePrompts.compressMessage,\n userContent,\n },\n )\n plan.entry.summary = generated\n }\n }\n }\n\n const notifications: NotificationEntry[] = []\n\n const preparedPlans: Array<{\n plan: (typeof plans)[number]\n summaryWithTools: string\n }> = []\n\n for (const plan of plans) {\n if (plan.entry.summary === undefined) {\n throw new Error(\n \"缺少 summary:未配置外部模型,请提供 summary 或配置 OPENCODE_DCP_EXTERNAL_COMPRESS_URL/MODEL\",\n )\n }\n const summaryWithPromptInfo = appendProtectedPromptInfo(\n plan.entry.summary,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectTags,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n summaryWithPromptInfo,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n preparedPlans.push({\n plan,\n summaryWithTools,\n })\n }\n\n const runId = allocateRunId(ctx.state)\n\n for (const { plan, summaryWithTools } of preparedPlans) {\n const blockId = allocateBlockId(ctx.state)\n const storedSummary = wrapCompressedSummary(blockId, summaryWithTools)\n const summaryTokens = countTokens(storedSummary)\n\n applyCompressionState(\n ctx.state,\n {\n topic: plan.entry.topic,\n batchTopic: input.topic,\n startId: plan.entry.messageId,\n endId: plan.entry.messageId,\n mode: \"message\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n plan.selection,\n plan.anchorMessageId,\n blockId,\n storedSummary,\n [],\n )\n\n notifications.push({\n blockId,\n runId,\n summary: summaryWithTools,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return formatResult(plans.length, skippedIssues, skippedCount)\n },\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 { 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.mode === \"message\" &&\n config.compress.protectUserMessages &&\n message.info.role === \"user\" &&\n !isIgnoredUserMessage(message)\n )\n}\n","// 这些格式模式与可编辑的压缩提示分开保存\n// 因此不能通过自定义提示覆盖来修改。这些模式必须\n// 与工具的输入验证匹配,且不能独立更改。\n\nexport function buildRangeFormatExtension(externalModelEnabled: boolean): string {\n const summaryField = externalModelEnabled\n ? `summary?: string // 替换范围内所有内容的完整技术摘要(可省略;外部模型生成)`\n : `summary: string // 替换范围内所有内容的完整技术摘要`\n\n const externalHint = externalModelEnabled\n ? `\\n\\n当启用外部模型压缩时,summary 字段可省略;插件将自动调用外部模型生成。`\n : \"\"\n\n return `\n压缩格式\n\n\\`\\`\\`\n{\n topic: string, // 短标签(3-5 个词)- 例如,\"认证系统探索\"\n content: [ // 一个或多个要压缩的范围\n {\n startId: string, // 范围开始的边界 ID:mNNNN 或 bN\n endId: string, // 范围结束的边界 ID:mNNNN 或 bN\n ${summaryField}\n }\n ]\n}\n\\`\\`\\`\n\n边界 ID 必须从当前可见上下文中已有的注入 ID 精确选取;不要发明 ID,也不要根据顺序外推不存在的 ID。${externalHint}`\n}\n\nexport function buildMessageFormatExtension(externalModelEnabled: boolean): string {\n const summaryField = externalModelEnabled\n ? `summary?: string // 替换该条消息的完整技术摘要(可省略;外部模型生成)`\n : `summary: string // 替换该条消息的完整技术摘要`\n\n const externalHint = externalModelEnabled\n ? `\\n\\n当启用外部模型压缩时,summary 字段可省略;插件将自动调用外部模型生成。`\n : \"\"\n\n return `\n压缩格式\n\n\\`\\`\\`\n{\n topic: string, // 整个批次的短标签(3-5 个词)\n content: [ // 一个或多个要独立压缩的消息\n {\n messageId: string, // 仅原始消息 ID:mNNNN(忽略 priority 等元数据属性)\n topic: string, // 此单条消息摘要的短标签(3-5 个词)\n ${summaryField}\n }\n ]\n}\n\\`\\`\\`${externalHint}`\n}\n\nexport const RANGE_FORMAT_EXTENSION = buildRangeFormatExtension(false)\nexport const MESSAGE_FORMAT_EXTENSION = buildMessageFormatExtension(false)\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 MESSAGE_ID_TAG_NAME = \"dcp-message-id\"\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): string {\n if (\n !Number.isInteger(index) ||\n index < MESSAGE_REF_MIN_INDEX ||\n index > MESSAGE_REF_MAX_INDEX\n ) {\n throw new Error(\n `Message ID index out of bounds: ${index}. Supported range is 0-${MESSAGE_REF_MAX_INDEX}.`,\n )\n }\n return `m${index.toString().padStart(MESSAGE_REF_WIDTH, \"0\")}`\n}\n\nexport function formatBlockRef(blockId: number): string {\n if (!Number.isInteger(blockId) || blockId < 1) {\n throw new Error(`Invalid block ID: ${blockId}`)\n }\n return `b${blockId}`\n}\n\nexport function parseMessageRef(ref: string): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(MESSAGE_REF_REGEX)\n if (!match) {\n return null\n }\n const index = Number.parseInt(match[1], 10)\n if (!Number.isInteger(index)) {\n return null\n }\n if (index < MESSAGE_REF_MIN_INDEX || index > MESSAGE_REF_MAX_INDEX) {\n return null\n }\n return index\n}\n\nexport function parseBlockRef(ref: string): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(BLOCK_REF_REGEX)\n if (!match) {\n return null\n }\n const id = Number.parseInt(match[1], 10)\n return Number.isInteger(id) ? id : null\n}\n\nexport function parseBoundaryId(id: string): ParsedBoundaryId | null {\n const normalized = id.trim().toLowerCase()\n const messageIndex = parseMessageRef(normalized)\n if (messageIndex !== null) {\n return {\n kind: \"message\",\n ref: formatMessageRef(messageIndex),\n index: messageIndex,\n }\n }\n\n const blockId = parseBlockRef(normalized)\n if (blockId !== null) {\n return {\n kind: \"compressed-block\",\n ref: formatBlockRef(blockId),\n blockId,\n }\n }\n\n return null\n}\n\nfunction escapeXmlAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): string {\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 if (\n state.lastCompaction > 0 &&\n message.info.time.created < state.lastCompaction &&\n !state.messageIds.byRawId.has(rawMessageId)\n ) {\n // Pre-compaction messages may still appear in full session history\n // (e.g. fetched by the compress tool) even though the chat hook's\n // trimmed view no longer shows them. Skip assigning them a fresh\n // ref so they don't get sorted out of order against recent refs.\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 while (candidate <= MESSAGE_REF_MAX_INDEX) {\n const ref = formatMessageRef(candidate)\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(MESSAGE_REF_MAX_INDEX)} aliases in this session.`,\n )\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport { formatBlockRef, parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage } 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 startId: string,\n endId: string,\n): { startReference: BoundaryReference; endReference: BoundaryReference } {\n const lookup = buildBoundaryLookup(context, state)\n const issues: string[] = []\n const parsedStartId = parseBoundaryId(startId)\n const parsedEndId = parseBoundaryId(endId)\n const hint = formatAvailableBoundaryHint(lookup)\n const guidance = formatBoundaryUsageGuidance()\n\n if (parsedStartId === null) {\n issues.push(\n `startId is invalid (received ${JSON.stringify(startId)}). Use an injected message ID (mNNNN) or block ID (bN).${hint}${guidance}`,\n )\n }\n\n if (parsedEndId === null) {\n issues.push(\n `endId is invalid (received ${JSON.stringify(endId)}). Use an injected message ID (mNNNN) or block ID (bN).${hint}${guidance}`,\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 || !endReference) {\n if (!startReference) {\n const wasKnown = state.messageIds.byRef.has(parsedStartId.ref)\n const reason = wasKnown\n ? \" (message was likely compacted out of the conversation)\"\n : \" (invalid ID)\"\n issues.push(\n `startId ${parsedStartId.ref} is not available${reason}. Choose an injected ID visible in context.${hint}${guidance}`,\n )\n }\n\n if (!endReference) {\n const wasKnown = state.messageIds.byRef.has(parsedEndId.ref)\n const reason = wasKnown\n ? \" (message was likely compacted out of the conversation)\"\n : \" (invalid ID)\"\n issues.push(\n `endId ${parsedEndId.ref} is not available${reason}. Choose an injected ID visible in context.${hint}${guidance}`,\n )\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 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)) {\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 formatAvailableBoundaryHint(lookup: Map<string, BoundaryReference>): string {\n const allKeys = Array.from(lookup.keys())\n\n const availableBlockRefs = allKeys\n .filter((key) => key.startsWith(\"b\"))\n .sort((a, b) => Number.parseInt(a.slice(1), 10) - Number.parseInt(b.slice(1), 10))\n\n const availableMsgRefs = allKeys\n .filter((key) => key.startsWith(\"m\"))\n .sort((a, b) => Number.parseInt(a.slice(1), 10) - Number.parseInt(b.slice(1), 10))\n\n const blockHint = availableBlockRefs.length\n ? ` Available block IDs: ${availableBlockRefs.join(\", \")}.`\n : \" No block IDs available.\"\n\n const msgHint =\n availableMsgRefs.length === 0\n ? \" No message IDs available.\"\n : availableMsgRefs.length <= 10\n ? ` Available message IDs: ${availableMsgRefs.join(\", \")}.`\n : ` Available message IDs: ${availableMsgRefs[0]} to ${availableMsgRefs[availableMsgRefs.length - 1]} (${availableMsgRefs.length} total).`\n\n return `${msgHint}${blockHint}`\n}\n\nfunction formatBoundaryUsageGuidance(): string {\n return \" Use exactly one of the listed injected IDs. For already compressed content, use its bN block ID.\"\n}\n\nfunction buildBoundaryLookup(\n context: SearchContext,\n state: SessionState,\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)) {\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)\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 // Fallback: include inactive blocks whose anchor still exists in the conversation\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (block.active) {\n continue // already handled above\n }\n const blockRef = formatBlockRef(blockId)\n if (lookup.has(blockRef)) {\n continue // already in lookup (shouldn't happen for inactive, but safer)\n }\n const anchorMessage = context.rawMessagesById.get(block.anchorMessageId)\n if (!anchorMessage) {\n continue // anchor gone — block is truly orphaned\n }\n if (isIgnoredUserMessage(anchorMessage)) {\n continue\n }\n const rawIndex = context.rawIndexById.get(block.anchorMessageId)\n if (rawIndex === undefined) {\n continue\n }\n lookup.set(blockRef, {\n kind: \"compressed-block\",\n rawIndex,\n blockId: block.blockId,\n anchorMessageId: block.anchorMessageId,\n })\n }\n\n return lookup\n}\n","import type { CompressionBlock, PruneMessagesState, SessionState } from \"../state\"\nimport { formatBlockRef, formatMessageIdTag } 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(blockId: number, summary: string): string {\n const header = COMPRESSED_BLOCK_HEADER\n const footer = formatMessageIdTag(formatBlockRef(blockId))\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 { PluginConfig } from \"../config\"\nimport type { SessionState } from \"../state\"\nimport { parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../messages/query\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport { COMPRESSED_BLOCK_HEADER } from \"./state\"\nimport type {\n CompressMessageEntry,\n CompressMessageToolArgs,\n ResolvedMessageCompression,\n ResolvedMessageCompressionsResult,\n SearchContext,\n} from \"./types\"\n\ninterface SkippedIssue {\n kind: string\n messageId: string\n}\n\nclass SoftIssue extends Error {\n constructor(\n public readonly kind: string,\n public readonly messageId: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport function validateArgs(args: CompressMessageToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.messageId !== \"string\" || entry.messageId.trim().length === 0) {\n throw new Error(`${prefix}.messageId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.topic !== \"string\" || entry.topic.trim().length === 0) {\n throw new Error(`${prefix}.topic is required and must be a non-empty string`)\n }\n\n if (entry?.summary !== undefined) {\n if (typeof entry.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary must be a non-empty string when provided`)\n }\n }\n }\n}\n\nexport function formatResult(\n processedCount: number,\n skippedIssues: string[],\n skippedCount: number,\n): string {\n const messageNoun = processedCount === 1 ? \"message\" : \"messages\"\n const processedText =\n processedCount > 0\n ? `Compressed ${processedCount} ${messageNoun} into ${COMPRESSED_BLOCK_HEADER}.`\n : \"Compressed 0 messages.\"\n\n if (skippedCount === 0) {\n return processedText\n }\n\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `${processedText}\\nSkipped ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nexport function formatIssues(skippedIssues: string[], skippedCount: number): string {\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `Unable to compress any messages. Found ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nconst ISSUE_TEMPLATES: Record<string, [singular: string, plural: string]> = {\n blocked: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"invalid-format\": [\n \"is invalid. Use an injected raw message ID of the form mNNNN.\",\n \"are invalid. Use injected raw message IDs of the form mNNNN.\",\n ],\n \"block-id\": [\n \"is invalid here. Block IDs like bN are not allowed; use an mNNNN message ID instead.\",\n \"are invalid here. Block IDs like bN are not allowed; use mNNNN message IDs instead.\",\n ],\n \"not-in-context\": [\n \"is not available in the current conversation context. Choose an injected mNNNN ID visible in context.\",\n \"are not available in the current conversation context. Choose injected mNNNN IDs visible in context.\",\n ],\n protected: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"already-compressed\": [\n \"is already part of an active compression.\",\n \"are already part of active compressions.\",\n ],\n duplicate: [\n \"was selected more than once in this batch.\",\n \"were each selected more than once in this batch.\",\n ],\n}\n\nfunction formatSkippedGroup(kind: string, messageIds: string[]): string {\n const templates = ISSUE_TEMPLATES[kind]\n const ids = messageIds.join(\", \")\n const single = messageIds.length === 1\n const prefix = single ? \"messageId\" : \"messageIds\"\n\n if (!templates) {\n return `${prefix} ${ids}: unknown issue.`\n }\n\n return `${prefix} ${ids} ${single ? templates[0] : templates[1]}`\n}\n\nfunction groupSkippedIssues(issues: SkippedIssue[]): string[] {\n const groups = new Map<string, string[]>()\n const order: string[] = []\n\n for (const issue of issues) {\n let ids = groups.get(issue.kind)\n if (!ids) {\n ids = []\n groups.set(issue.kind, ids)\n order.push(issue.kind)\n }\n ids.push(issue.messageId)\n }\n\n return order.map((kind) => {\n const ids = groups.get(kind)!\n return formatSkippedGroup(kind, ids)\n })\n}\n\nexport function resolveMessages(\n args: CompressMessageToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompressionsResult {\n const issues: SkippedIssue[] = []\n const plans: ResolvedMessageCompression[] = []\n const seenMessageIds = new Set<string>()\n\n for (const entry of args.content) {\n const normalizedMessageId = entry.messageId.trim()\n if (seenMessageIds.has(normalizedMessageId)) {\n issues.push({ kind: \"duplicate\", messageId: normalizedMessageId })\n continue\n }\n\n try {\n const plan = resolveMessage(\n {\n ...entry,\n messageId: normalizedMessageId,\n },\n searchContext,\n state,\n config,\n )\n seenMessageIds.add(plan.entry.messageId)\n plans.push(plan)\n } catch (error: any) {\n if (error instanceof SoftIssue) {\n issues.push({ kind: error.kind, messageId: error.messageId })\n continue\n }\n\n throw error\n }\n }\n\n return {\n plans,\n skippedIssues: groupSkippedIssues(issues),\n skippedCount: issues.length,\n }\n}\n\nfunction resolveMessage(\n entry: CompressMessageEntry,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompression {\n if (entry.messageId.toUpperCase() === \"BLOCKED\") {\n throw new SoftIssue(\"blocked\", \"BLOCKED\", \"protected message\")\n }\n\n const parsed = parseBoundaryId(entry.messageId)\n\n if (!parsed) {\n throw new SoftIssue(\"invalid-format\", entry.messageId, \"invalid format\")\n }\n\n if (parsed.kind === \"compressed-block\") {\n throw new SoftIssue(\"block-id\", entry.messageId, \"block ID used\")\n }\n\n const messageId = state.messageIds.byRef.get(parsed.ref)\n const rawMessage = messageId ? searchContext.rawMessagesById.get(messageId) : undefined\n if (\n !messageId ||\n !rawMessage ||\n !searchContext.rawIndexById.has(messageId) ||\n isIgnoredUserMessage(rawMessage)\n ) {\n throw new SoftIssue(\"not-in-context\", parsed.ref, \"not in context\")\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n parsed.ref,\n parsed.ref,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n if (isProtectedUserMessage(config, rawMessage)) {\n throw new SoftIssue(\"protected\", parsed.ref, \"protected message\")\n }\n\n const pruneEntry = state.prune.messages.byMessageId.get(messageId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n throw new SoftIssue(\"already-compressed\", parsed.ref, \"already compressed\")\n }\n\n return {\n entry: {\n messageId: parsed.ref,\n topic: entry.topic,\n summary: entry.summary,\n },\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\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 { 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 PersistedMessageIdState {\n byRawId: Record<string, string>\n byRef: Record<string, string>\n nextRef: number\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n manualMode?: boolean\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n lastCompaction?: number\n messageIds?: PersistedMessageIdState\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 lastCompaction: sessionState.lastCompaction,\n messageIds: {\n byRawId: Object.fromEntries(sessionState.messageIds.byRawId),\n byRef: Object.fromEntries(sessionState.messageIds.byRef),\n nextRef: sessionState.messageIds.nextRef,\n },\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\nexport interface AggregatedStats {\n totalTokens: number\n totalTools: number\n totalMessages: number\n sessionCount: number\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 }\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 if (state?.stats?.totalPruneTokens && state?.prune) {\n result.totalTokens += state.stats.totalPruneTokens\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.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","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 === \"range\" || block.mode === \"message\" ? block.mode : 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, messages: WithParts[] = []): void {\n state.toolParameters.clear()\n\n if (messages.length === 0) {\n return\n }\n\n const liveMessageIds = new Set(messages.map((msg) => msg.info.id))\n\n for (const [ref, rawId] of state.messageIds.byRef) {\n if (!liveMessageIds.has(rawId)) {\n state.messageIds.byRef.delete(ref)\n state.messageIds.byRawId.delete(rawId)\n }\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 { applyPendingCompressionDurations } from \"../compress/timing\"\nimport { 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\"\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, messages)\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}\n\nexport function createSessionState(): SessionState {\n return {\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 },\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 }\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 }\n\n if (typeof persisted.lastCompaction === \"number\") {\n state.lastCompaction = Math.max(state.lastCompaction, persisted.lastCompaction)\n }\n if (persisted.messageIds && typeof persisted.messageIds === \"object\") {\n state.messageIds = {\n byRawId: new Map<string, string>(\n Object.entries(persisted.messageIds.byRawId || {}).filter(\n (e): e is [string, string] => typeof e[1] === \"string\",\n ),\n ),\n byRef: new Map<string, string>(\n Object.entries(persisted.messageIds.byRef || {}).filter(\n (e): e is [string, string] => typeof e[1] === \"string\",\n ),\n ),\n nextRef:\n typeof persisted.messageIds.nextRef === \"number\" &&\n persisted.messageIds.nextRef >= 1\n ? persisted.messageIds.nextRef\n : 1,\n }\n }\n\n const applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\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 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","function normalizePath(input: string): string {\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\" && 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 // 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","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\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 } 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 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 ctx.state.manualMode = ctx.state.manualMode ? \"active\" : false\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","import type { WithParts } from \"../state\"\n\nconst SUB_AGENT_RESULT_BLOCK_REGEX = /(<task_result>\\s*)([\\s\\S]*?)(\\s*<\\/task_result>)/i\n\nexport function getSubAgentId(part: any): string | null {\n const 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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 appendProtectedUserMessages(\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 userTexts: 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\" && part.text.trim()) {\n userTexts.push(part.text)\n break\n }\n }\n }\n\n if (userTexts.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following user messages were sent in this conversation verbatim:\"\n const body = userTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\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 let isToolProtected = isToolNameProtected(part.tool, protectedTools)\n\n if (!isToolProtected && protectedFilePatterns.length > 0) {\n const filePaths = getFilePathsFromParameters(part.tool, part.state?.input)\n if (isFilePathProtected(filePaths, protectedFilePatterns)) {\n isToolProtected = true\n }\n }\n\n if (isToolProtected) {\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\" &&\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 { ExternalModelConfig } from \"../config\"\n\nexport type { ExternalModelConfig }\n\nexport interface ExternalSummaryRequest {\n systemPrompt: string\n userContent: string\n}\n\nexport type ExternalModelErrorKind = \"network\" | \"http\" | \"parse\" | \"empty\" | \"timeout\"\n\nexport class ExternalModelError extends Error {\n constructor(\n message: string,\n public readonly kind: ExternalModelErrorKind,\n public readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"ExternalModelError\"\n }\n}\n\nexport function resolveCompressBaseUrl(url: string): string {\n const normalized = url.replace(/\\/$/, \"\")\n if (normalized.endsWith(\"/chat/completions\")) {\n return normalized\n }\n return `${normalized}/chat/completions`\n}\n\nasync function callExternalModel(\n endpoint: string,\n cfg: ExternalModelConfig,\n req: ExternalSummaryRequest,\n): Promise<string> {\n const controller = new AbortController()\n const timeoutMs = cfg.timeout ?? 120000\n const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(cfg.apiKey ? { Authorization: `Bearer ${cfg.apiKey}` } : {}),\n },\n body: JSON.stringify({\n model: cfg.model,\n messages: [\n { role: \"system\", content: req.systemPrompt },\n { role: \"user\", content: req.userContent },\n ],\n temperature: 0,\n }),\n signal: controller.signal,\n })\n } catch (error: unknown) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new ExternalModelError(\n `External model request timed out after ${timeoutMs}ms`,\n \"timeout\",\n error,\n )\n }\n throw new ExternalModelError(\n `External model request failed: ${error instanceof Error ? error.message : String(error)}`,\n \"network\",\n error,\n )\n } finally {\n clearTimeout(timeoutHandle)\n }\n\n if (!response.ok) {\n let errorBody = \"\"\n try {\n errorBody = await response.text()\n } catch {}\n throw new ExternalModelError(\n `External model returned HTTP ${response.status}: ${errorBody.slice(0, 200)}`,\n \"http\",\n { status: response.status, body: errorBody },\n )\n }\n\n let parsed: any\n try {\n parsed = await response.json()\n } catch (error) {\n throw new ExternalModelError(\"External model returned invalid JSON\", \"parse\", error)\n }\n\n const content = parsed?.choices?.[0]?.message?.content\n if (typeof content !== \"string\" || content.trim().length === 0) {\n throw new ExternalModelError(\n \"External model returned empty or missing summary content\",\n \"empty\",\n parsed,\n )\n }\n\n return content\n}\n\nexport async function generateSummaryViaExternal(\n cfg: ExternalModelConfig,\n req: ExternalSummaryRequest,\n): Promise<string> {\n const endpoint = resolveCompressBaseUrl(cfg.url)\n const maxRetries = cfg.retries ?? 1\n\n let lastError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await callExternalModel(endpoint, cfg, req)\n } catch (error) {\n lastError = error\n }\n }\n\n throw lastError\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { buildRangeFormatExtension } from \"../prompts/extensions/tool\"\nimport { finalizeSession, prepareSession, type NotificationEntry } from \"./pipeline\"\nimport {\n appendProtectedPromptInfo,\n appendProtectedTools,\n appendProtectedUserMessages,\n} from \"./protected-content\"\nimport {\n appendMissingBlockSummaries,\n injectBlockPlaceholders,\n parseBlockPlaceholders,\n resolveRanges,\n validateArgs,\n validateNonOverlapping,\n validateSummaryPlaceholders,\n} from \"./range-utils\"\nimport {\n COMPRESSED_BLOCK_HEADER,\n allocateBlockId,\n allocateRunId,\n applyCompressionState,\n wrapCompressedSummary,\n} from \"./state\"\nimport type { CompressRangeToolArgs, SearchContext } from \"./types\"\nimport { generateSummaryViaExternal } from \"./external-inference\"\n\nfunction extractRangeText(\n selection: { messageIds: string[] },\n searchContext: SearchContext,\n): string {\n const parts: string[] = []\n for (const messageId of selection.messageIds) {\n const msg = searchContext.rawMessagesById.get(messageId)\n if (!msg) continue\n for (const part of msg.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n parts.push(part.text)\n }\n }\n }\n return parts.join(\"\\n\\n\")\n}\n\nfunction buildSchema(externalModelEnabled: boolean) {\n const summaryField = externalModelEnabled\n ? tool.schema\n .string()\n .optional()\n .describe(\n \"Complete technical summary replacing all content in range (optional when external model is configured)\",\n )\n : tool.schema.string().describe(\"Complete technical summary replacing all content in range\")\n\n return {\n topic: tool.schema\n .string()\n .describe(\"Short label (3-5 words) for display - e.g., 'Auth System Exploration'\"),\n content: tool.schema\n .array(\n tool.schema.object({\n startId: tool.schema\n .string()\n .describe(\n \"Injected message or block ID visible in the current context marking the beginning of the range. Do not invent IDs; use an exact visible mNNNN or bN boundary.\",\n ),\n endId: tool.schema\n .string()\n .describe(\n \"Injected message or block ID visible in the current context marking the end of the range. Do not invent IDs; use an exact visible mNNNN or bN boundary.\",\n ),\n summary: summaryField,\n }),\n )\n .describe(\n \"One or more ranges to compress, each with start/end boundaries and a summary\",\n ),\n }\n}\n\nexport function createCompressRangeTool(ctx: ToolContext): ReturnType<typeof tool> {\n ctx.prompts.reload()\n const runtimePrompts = ctx.prompts.getRuntimePrompts()\n const externalModelEnabled = ctx.config.compress.externalModel !== undefined\n\n return tool({\n description: runtimePrompts.compressRange + buildRangeFormatExtension(externalModelEnabled),\n args: buildSchema(externalModelEnabled),\n async execute(args, toolCtx) {\n const input = args as CompressRangeToolArgs\n validateArgs(input)\n const callId =\n typeof (toolCtx as unknown as { callID?: unknown }).callID === \"string\"\n ? (toolCtx as unknown as { callID: string }).callID\n : undefined\n\n const { rawMessages, searchContext } = await prepareSession(\n ctx,\n toolCtx,\n `Compress Range: ${input.topic}`,\n )\n const resolvedPlans = resolveRanges(input, searchContext, ctx.state)\n validateNonOverlapping(resolvedPlans)\n\n if (ctx.config.compress.externalModel) {\n for (const plan of resolvedPlans) {\n if (plan.entry.summary === undefined) {\n const userContent = extractRangeText(plan.selection, searchContext)\n const generated = await generateSummaryViaExternal(\n ctx.config.compress.externalModel,\n {\n systemPrompt: runtimePrompts.compressRange,\n userContent,\n },\n )\n plan.entry.summary = generated\n }\n }\n }\n\n const notifications: NotificationEntry[] = []\n const preparedPlans: Array<{\n entry: (typeof resolvedPlans)[number][\"entry\"]\n selection: (typeof resolvedPlans)[number][\"selection\"]\n anchorMessageId: string\n finalSummary: string\n consumedBlockIds: number[]\n }> = []\n let totalCompressedMessages = 0\n\n for (const plan of resolvedPlans) {\n if (plan.entry.summary === undefined) {\n throw new Error(\n \"缺少 summary:未配置外部模型,请提供 summary 或配置 OPENCODE_DCP_EXTERNAL_COMPRESS_URL/MODEL\",\n )\n }\n const parsedPlaceholders = parseBlockPlaceholders(plan.entry.summary)\n const missingBlockIds = validateSummaryPlaceholders(\n parsedPlaceholders,\n plan.selection.requiredBlockIds,\n plan.selection.startReference,\n plan.selection.endReference,\n searchContext.summaryByBlockId,\n )\n\n const injected = injectBlockPlaceholders(\n plan.entry.summary,\n parsedPlaceholders,\n searchContext.summaryByBlockId,\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n const summaryWithUsers = appendProtectedUserMessages(\n injected.expandedSummary,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectUserMessages,\n )\n\n const summaryWithPromptInfo = appendProtectedPromptInfo(\n summaryWithUsers,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectTags,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n summaryWithPromptInfo,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n const completedSummary = appendMissingBlockSummaries(\n summaryWithTools,\n missingBlockIds,\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: completedSummary.consumedBlockIds,\n })\n }\n\n const runId = allocateRunId(ctx.state)\n\n for (const preparedPlan of preparedPlans) {\n const blockId = allocateBlockId(ctx.state)\n const storedSummary = wrapCompressedSummary(blockId, preparedPlan.finalSummary)\n const summaryTokens = countTokens(storedSummary)\n\n const applied = applyCompressionState(\n ctx.state,\n {\n topic: input.topic,\n batchTopic: input.topic,\n startId: preparedPlan.entry.startId,\n endId: preparedPlan.entry.endId,\n mode: \"range\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n preparedPlan.selection,\n preparedPlan.anchorMessageId,\n blockId,\n storedSummary,\n preparedPlan.consumedBlockIds,\n )\n\n totalCompressedMessages += applied.messageIds.length\n\n notifications.push({\n blockId,\n runId,\n summary: preparedPlan.finalSummary,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return `Compressed ${totalCompressedMessages} messages into ${COMPRESSED_BLOCK_HEADER}.`\n },\n })\n}\n","import type { CompressionBlock, SessionState } from \"../state\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport type {\n BoundaryReference,\n CompressRangeToolArgs,\n InjectedSummaryResult,\n ParsedBlockPlaceholder,\n ResolvedRangeCompression,\n SearchContext,\n} from \"./types\"\n\nconst BLOCK_PLACEHOLDER_REGEX = /\\(b(\\d+)\\)|\\{block_(\\d+)\\}/gi\n\nexport function validateArgs(args: CompressRangeToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.startId !== \"string\" || entry.startId.trim().length === 0) {\n throw new Error(`${prefix}.startId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.endId !== \"string\" || entry.endId.trim().length === 0) {\n throw new Error(`${prefix}.endId is required and must be a non-empty string`)\n }\n\n if (entry?.summary !== undefined) {\n if (typeof entry.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary must be a non-empty string when provided`)\n }\n }\n }\n}\n\nexport function resolveRanges(\n args: CompressRangeToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n): ResolvedRangeCompression[] {\n return args.content.map((entry, index) => {\n const normalizedEntry = {\n startId: entry.startId.trim(),\n endId: entry.endId.trim(),\n summary: entry.summary,\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n normalizedEntry.startId,\n normalizedEntry.endId,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n return {\n index,\n entry: normalizedEntry,\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\n })\n}\n\nexport function validateNonOverlapping(plans: ResolvedRangeCompression[]): void {\n const sortedPlans = [...plans].sort(\n (left, right) =>\n left.selection.startReference.rawIndex - right.selection.startReference.rawIndex ||\n left.selection.endReference.rawIndex - right.selection.endReference.rawIndex ||\n left.index - right.index,\n )\n\n const issues: string[] = []\n\n for (let index = 1; index < sortedPlans.length; index++) {\n const previous = sortedPlans[index - 1]\n const current = sortedPlans[index]\n if (!previous || !current) {\n continue\n }\n\n if (current.selection.startReference.rawIndex > previous.selection.endReference.rawIndex) {\n continue\n }\n\n issues.push(\n `content[${previous.index}] (${previous.entry.startId}..${previous.entry.endId}) overlaps content[${current.index}] (${current.entry.startId}..${current.entry.endId}). Overlapping ranges cannot be compressed in the same batch.`,\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\nexport function parseBlockPlaceholders(summary: string): ParsedBlockPlaceholder[] {\n const placeholders: ParsedBlockPlaceholder[] = []\n const regex = new RegExp(BLOCK_PLACEHOLDER_REGEX)\n\n let match: RegExpExecArray | null\n while ((match = regex.exec(summary)) !== null) {\n const full = match[0]\n const blockIdPart = match[1] || match[2]\n const parsed = Number.parseInt(blockIdPart, 10)\n if (!Number.isInteger(parsed)) {\n continue\n }\n\n placeholders.push({\n raw: full,\n blockId: parsed,\n startIndex: match.index,\n endIndex: match.index + full.length,\n })\n }\n\n return placeholders\n}\n\nexport function validateSummaryPlaceholders(\n placeholders: ParsedBlockPlaceholder[],\n requiredBlockIds: number[],\n startReference: BoundaryReference,\n endReference: BoundaryReference,\n summaryByBlockId: Map<number, CompressionBlock>,\n): number[] {\n const boundaryOptionalIds = new Set<number>()\n if (startReference.kind === \"compressed-block\") {\n if (startReference.blockId === undefined) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n boundaryOptionalIds.add(startReference.blockId)\n }\n if (endReference.kind === \"compressed-block\") {\n if (endReference.blockId === undefined) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n boundaryOptionalIds.add(endReference.blockId)\n }\n\n const strictRequiredIds = requiredBlockIds.filter((id) => !boundaryOptionalIds.has(id))\n const requiredSet = new Set(requiredBlockIds)\n const keptPlaceholderIds = new Set<number>()\n const validPlaceholders: ParsedBlockPlaceholder[] = []\n\n for (const placeholder of placeholders) {\n const isKnown = summaryByBlockId.has(placeholder.blockId)\n const isRequired = requiredSet.has(placeholder.blockId)\n const isDuplicate = keptPlaceholderIds.has(placeholder.blockId)\n\n if (isKnown && isRequired && !isDuplicate) {\n validPlaceholders.push(placeholder)\n keptPlaceholderIds.add(placeholder.blockId)\n }\n }\n\n placeholders.length = 0\n placeholders.push(...validPlaceholders)\n\n return strictRequiredIds.filter((id) => !keptPlaceholderIds.has(id))\n}\n\nexport function injectBlockPlaceholders(\n summary: string,\n placeholders: ParsedBlockPlaceholder[],\n summaryByBlockId: Map<number, CompressionBlock>,\n startReference: BoundaryReference,\n endReference: BoundaryReference,\n): InjectedSummaryResult {\n let cursor = 0\n let expanded = summary\n const consumed: number[] = []\n const consumedSeen = new Set<number>()\n\n if (placeholders.length > 0) {\n expanded = \"\"\n for (const placeholder of placeholders) {\n const target = summaryByBlockId.get(placeholder.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${placeholder.blockId})`)\n }\n\n expanded += summary.slice(cursor, placeholder.startIndex)\n expanded += restoreSummary(target.summary)\n cursor = placeholder.endIndex\n\n if (!consumedSeen.has(placeholder.blockId)) {\n consumedSeen.add(placeholder.blockId)\n consumed.push(placeholder.blockId)\n }\n }\n\n expanded += summary.slice(cursor)\n }\n\n expanded = injectBoundarySummary(\n expanded,\n startReference,\n \"start\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n expanded = injectBoundarySummary(\n expanded,\n endReference,\n \"end\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n\n return {\n expandedSummary: expanded,\n consumedBlockIds: consumed,\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n missingBlockIds: number[],\n summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n const consumedSeen = new Set<number>(consumedBlockIds)\n const consumed = [...consumedBlockIds]\n\n const missingSummaries: string[] = []\n for (const blockId of missingBlockIds) {\n if (consumedSeen.has(blockId)) {\n continue\n }\n\n const target = summaryByBlockId.get(blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${blockId})`)\n }\n\n missingSummaries.push(`\\n### (b${blockId})\\n${restoreSummary(target.summary)}`)\n consumedSeen.add(blockId)\n consumed.push(blockId)\n }\n\n if (missingSummaries.length === 0) {\n return {\n expandedSummary: summary,\n consumedBlockIds: consumed,\n }\n }\n\n const heading =\n \"\\n\\nThe following previously compressed summaries were also part of this conversation section:\"\n\n return {\n expandedSummary: summary + heading + missingSummaries.join(\"\"),\n consumedBlockIds: consumed,\n }\n}\n\nfunction restoreSummary(summary: string): string {\n const headerMatch = summary.match(/^\\s*\\[Compressed conversation(?: section)?(?: b\\d+)?\\]/i)\n if (!headerMatch) {\n return summary\n }\n\n const afterHeader = summary.slice(headerMatch[0].length)\n const withoutLeadingBreaks = afterHeader.replace(/^(?:\\r?\\n)+/, \"\")\n return withoutLeadingBreaks\n .replace(/(?:\\r?\\n)*<dcp-message-id>b\\d+<\\/dcp-message-id>\\s*$/i, \"\")\n .replace(/(?:\\r?\\n)+$/, \"\")\n}\n\nfunction injectBoundarySummary(\n summary: string,\n reference: BoundaryReference,\n position: \"start\" | \"end\",\n summaryByBlockId: Map<number, CompressionBlock>,\n consumed: number[],\n consumedSeen: Set<number>,\n): string {\n if (reference.kind !== \"compressed-block\" || reference.blockId === undefined) {\n return summary\n }\n if (consumedSeen.has(reference.blockId)) {\n return summary\n }\n\n const target = summaryByBlockId.get(reference.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${reference.blockId})`)\n }\n\n const injectedBody = restoreSummary(target.summary)\n const left = position === \"start\" ? injectedBody.trim() : summary.trim()\n const right = position === \"start\" ? summary.trim() : injectedBody.trim()\n const next = !left ? right : !right ? left : `${left}\\n\\n${right}`\n\n consumedSeen.add(reference.blockId)\n consumed.push(reference.blockId)\n return next\n}\n","export type PermissionAction = \"ask\" | \"allow\" | \"deny\"\n\nexport type PermissionValue = PermissionAction | Record<string, PermissionAction>\n\nexport type PermissionConfig = Record<string, PermissionValue> | undefined\n\nexport interface HostPermissionSnapshot {\n global: PermissionConfig\n agents: Record<string, PermissionConfig>\n}\n\ntype PermissionRule = {\n permission: string\n pattern: string\n action: PermissionAction\n}\n\nconst findLastMatchingRule = (\n rules: PermissionRule[],\n predicate: (rule: PermissionRule) => boolean,\n): PermissionRule | undefined => {\n for (let index = rules.length - 1; index >= 0; index -= 1) {\n const rule = rules[index]\n if (rule && predicate(rule)) {\n return rule\n }\n }\n\n return undefined\n}\n\nconst wildcardMatch = (value: string, pattern: string): boolean => {\n const normalizedValue = value.replaceAll(\"\\\\\", \"/\")\n let escaped = pattern\n .replaceAll(\"\\\\\", \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")\n\n if (escaped.endsWith(\" .*\")) {\n escaped = escaped.slice(0, -3) + \"( .*)?\"\n }\n\n const flags = process.platform === \"win32\" ? \"si\" : \"s\"\n return new RegExp(`^${escaped}$`, flags).test(normalizedValue)\n}\n\nconst getPermissionRules = (permissionConfigs: PermissionConfig[]): PermissionRule[] => {\n const rules: PermissionRule[] = []\n for (const permissionConfig of permissionConfigs) {\n if (!permissionConfig) {\n continue\n }\n\n for (const [permission, value] of Object.entries(permissionConfig)) {\n if (value === \"ask\" || value === \"allow\" || value === \"deny\") {\n rules.push({ permission, pattern: \"*\", action: value })\n continue\n }\n\n for (const [pattern, action] of Object.entries(value)) {\n if (action === \"ask\" || action === \"allow\" || action === \"deny\") {\n rules.push({ permission, pattern, action })\n }\n }\n }\n }\n return rules\n}\n\nexport const compressDisabledByOpencode = (...permissionConfigs: PermissionConfig[]): boolean => {\n const match = findLastMatchingRule(getPermissionRules(permissionConfigs), (rule) =>\n wildcardMatch(\"compress\", rule.permission),\n )\n\n return match?.pattern === \"*\" && match.action === \"deny\"\n}\n\nexport const resolveEffectiveCompressPermission = (\n basePermission: PermissionAction,\n hostPermissions: HostPermissionSnapshot,\n agentName?: string,\n): PermissionAction => {\n if (basePermission === \"deny\") {\n return \"deny\"\n }\n\n return compressDisabledByOpencode(\n hostPermissions.global,\n agentName ? hostPermissions.agents[agentName] : undefined,\n )\n ? \"deny\"\n : basePermission\n}\n\nexport const hasExplicitToolPermission = (\n permissionConfig: PermissionConfig,\n tool: string,\n): boolean => {\n return permissionConfig ? Object.prototype.hasOwnProperty.call(permissionConfig, tool) : false\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 { SYSTEM as SYSTEM_PROMPT } from \"./system\"\nimport { COMPRESS_RANGE as COMPRESS_RANGE_PROMPT } from \"./compress-range\"\nimport { COMPRESS_MESSAGE as COMPRESS_MESSAGE_PROMPT } from \"./compress-message\"\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-range\"\n | \"compress-message\"\n | \"context-limit-nudge\"\n | \"turn-nudge\"\n | \"iteration-nudge\"\n\ntype EditablePromptField =\n | \"system\"\n | \"compressRange\"\n | \"compressMessage\"\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 compressRange: string\n compressMessage: 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-range\",\n fileName: \"compress-range.md\",\n label: \"Compress Range\",\n description: \"range-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the range-mode compress tool description\",\n runtimeField: \"compressRange\",\n },\n {\n key: \"compress-message\",\n fileName: \"compress-message.md\",\n label: \"Compress Message\",\n description: \"message-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the message-mode compress tool description\",\n runtimeField: \"compressMessage\",\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-range\",\n \"compress-message\",\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\nconst BUNDLED_EDITABLE_PROMPTS: Record<EditablePromptField, string> = {\n system: SYSTEM_PROMPT,\n compressRange: COMPRESS_RANGE_PROMPT,\n compressMessage: COMPRESS_MESSAGE_PROMPT,\n contextLimitNudge: CONTEXT_LIMIT_NUDGE,\n turnNudge: TURN_NUDGE,\n iterationNudge: ITERATION_NUDGE,\n}\n\nconst INTERNAL_PROMPT_EXTENSIONS = {\n manualExtension: MANUAL_MODE_SYSTEM_EXTENSION,\n subagentExtension: SUBAGENT_SYSTEM_EXTENSION,\n}\n\nfunction createBundledRuntimePrompts(): RuntimePrompts {\n return {\n system: BUNDLED_EDITABLE_PROMPTS.system,\n compressRange: BUNDLED_EDITABLE_PROMPTS.compressRange,\n compressMessage: BUNDLED_EDITABLE_PROMPTS.compressMessage,\n contextLimitNudge: BUNDLED_EDITABLE_PROMPTS.contextLimitNudge,\n turnNudge: BUNDLED_EDITABLE_PROMPTS.turnNudge,\n iterationNudge: BUNDLED_EDITABLE_PROMPTS.iterationNudge,\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 if (definition.key !== \"compress-range\" && definition.key !== \"compress-message\") {\n normalized = normalizeReminderPromptContent(normalized)\n }\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 if (definition.key === \"compress-range\" || definition.key === \"compress-message\") {\n return trimmed\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\n constructor(logger: Logger, workingDirectory: string, customPromptsEnabled = false) {\n this.logger = logger\n this.paths = resolvePromptPaths(workingDirectory)\n this.customPromptsEnabled = customPromptsEnabled\n this.runtimePrompts = createBundledRuntimePrompts()\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()\n\n if (!this.customPromptsEnabled) {\n this.runtimePrompts = nextPrompts\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledSource = BUNDLED_EDITABLE_PROMPTS[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 BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const managedContent = buildDefaultPromptFileContent(\n bundledEditable || BUNDLED_EDITABLE_PROMPTS[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","export const SYSTEM = `\nYou run in a context-limited environment. Manage context actively to avoid accumulation and keep retrieval quality high.\n\nYour only context-management tool is \\`compress\\`. It replaces older conversation content with a technical summary you generate.\n\nHard constraints\n- Context management is done ONLY by calling \\`compress\\`. Never produce summaries in plain text.\n- NEVER output \\`<summary>\\` or \\`<analysis>\\` XML tags in text responses — they cause system errors.\n- If context needs compression, call \\`compress\\`. Do not write summaries inline.\n- Use Markdown headings (e.g. \\`## Analysis\\`, \\`## Summary\\`) to organize information. Never use XML tags.\n\n\\`<dcp-message-id>\\` and \\`<dcp-system-reminder>\\` are environment-injected metadata. Do not output them.\n\nWhen to compress\n\nHIGHEST-PRIORITY HARD TRIGGER — call \\`compress\\` immediately whenever the conversation TOPIC changes. Compress the previous topic's finished context into a summary.\n\nA topic change is an objective, low-judgment signal, not a subjective call. Any of these counts:\n\n- The user raises a task or question unrelated to the previous one\n- The focus shifts from one module/file/feature to another\n- The goal shifts from explore/research → implement, or implement → debug/verify\n- A distinct problem is resolved and you move to the next\n\nWhen any occurs, compress the finished range of the previous topic at once. Do not wait. This is the single most effective way to keep context clear.\n\nAlso compress (when a section genuinely closes even without a topic change):\n\n- Research is done and findings are settled\n- Implementation is complete and verified\n- Exploration is exhausted and patterns understood\n- Dead-end noise can be dropped without waiting for the whole section to close\n\nDo NOT compress when:\n\n- Raw context is still needed for editing or exact reference\n- The target work is actively in progress\n- You may need the exact code, error message, or file content in the next steps\n\nAsk yourself before compressing: _\"Is this section closed enough to be summary-only?\"_\n\nIf the answer is \"the topic switched, the old content is no longer needed\" — the answer is always yes.\n\nPeriodically assess the conversation's signal-to-noise ratio. Use \\`compress\\` deliberately and provide high-quality summaries. Prioritize stale content to maintain a high-signal context window.\n\nKeeping a sharp, high-quality context window for best performance is your responsibility.\n`\n","export const COMPRESS_RANGE = `将对话中的一个范围折叠为详细摘要。\n\n输出格式\n每个摘要必须使用 Markdown 标题结构:\n\n\\`\\`\\`\n## 分析\n[分析:探索了什么、遇到了什么问题、尝试了哪些方法]\n\n## 总结\n[总结:最终结论、关键决策、重要文件路径、函数签名、代码变更]\n\\`\\`\\`\n\n禁止使用 \\`<analysis>\\` 或 \\`<summary>\\` 等 XML 标签。只使用 Markdown \\`## 分析\\` 和 \\`## 总结\\` 标题。\n\n摘要要求\n摘要必须详尽。捕获文件路径、函数签名、所做决策、发现的约束、关键发现……所有维持上下文完整性的内容。这不是简短笔记——而是一份权威记录,忠实到原始对话不再有任何价值。\n\n用户意图保真\n当压缩范围包含用户消息时,格外小心地保留用户意图。不要改变范围、约束、优先级、验收标准或请求的结果。\n当用户消息足够短时直接引用。直接引用在最能保留精确含义时优先使用。\n\n历史审批处理\n当压缩范围包含用户的审批/批准短语(如\"就执行吧\"、\"按照这个执行\"、\"好的,继续\"等)时,必须将其标记为历史事件而非当前有效指令。\n- 错误:保留\"用户说:就执行吧\"(可能被误解为当前指令)\n- 正确:标记为\"用户曾批准了先前的方案(该批准仅适用于当时的上下文,不构成对后续操作的授权)\"\n这确保压缩后的上下文不会被误解为新的执行授权。\n\n同时保持精简。去除噪音:无果的失败尝试、冗长的工具输出、反复探索。留下的应该是纯信号——保留完整理解、零歧义的精华细节。\n\n压缩块占位符\n当选定范围包含之前压缩的块时,引用时使用以下精确占位符格式:\n\n- \\`(bN)\\`\n\n上下文中的压缩块部分用标题明确标记:\n\n- \\`[已压缩的对话部分]\\`\n\n压缩块 ID 始终使用 \\`bN\\` 形式(不是 \\`mNNNN\\`),并以相同的 XML 元数据标签格式表示。\n\n规则:\n\n- 每个必需的块占位符恰好包含一次。\n- 不要为选定范围之外的块发明占位符。\n- 将 \\`(bN)\\` 占位符视为保留标记。除了有意占位符外,不要在任何地方输出 \\`(bN)\\` 文本。\n- 如果需要在正文中提及一个块,使用纯文本如 \\`压缩块 bN\\`(不作为占位符)。\n- 最终确定前的预检:摘要中的 \\`(bN)\\` 占位符集合必须与必需集合完全匹配,无重复。\n\n这些占位符是语义引用。当工具处理你的输出时,它们将被替换为完整的存储压缩块内容。\n\n占位符的流畅性\n使用压缩块占位符时,编写周围的摘要文本,使其在占位符展开后仍然正确可读。\n\n- 将每个占位符视为完整对话段的替代,而不是短标签。\n- 确保每个占位符前后的过渡保留时间顺序和因果关系。\n- 不要编写依赖于占位符保持字面意义的文本(例如\"如 \\`(b2)\\` 中所述\")。\n- 当每个占位符被替换为其完整压缩块内容后,最终含义必须连贯。\n\n边界 ID\n使用对话中可见的注入 ID 按 ID 指定边界:\n\n- \\`mNNNN\\` ID 标识原始消息\n- \\`bN\\` ID 标识之前压缩的块\n\n每条消息在 XML 元数据标签内有 ID,如 \\`<dcp-message-id>m0007</dcp-message-id>\\`。\n相同的 ID 标签出现在该消息所属的每个工具输出中——每个唯一 ID 标识一条完整消息。\n将这些标签仅视为边界元数据,而非工具结果内容。\n\n规则:\n\n- 直接从上下文中的注入 ID 选取 \\`startId\\` 和 \\`endId\\`。\n- ID 必须存在于当前可见上下文中。\n- \\`startId\\` 必须出现在 \\`endId\\` 之前。\n- 不要发明 ID。只使用上下文中存在的 ID。\n\n批量处理\n当多个独立范围已准备好且边界不重叠时,将它们全部作为单独条目包含在单次工具调用的 \\`content\\` 数组中。每个条目应有自己的 \\`startId\\`、\\`endId\\` 和 \\`summary\\`。\n`\n","export const COMPRESS_MESSAGE = `将对话中选定的单条消息折叠为详细摘要。\n\n摘要要求\n摘要必须详尽。捕获文件路径、函数签名、所做决策、发现的约束、关键发现、工具结果,以及重要的用户意图细节……所有在原始消息被移除后保留其价值的内容。\n\n用户意图保真\n当选定消息包含用户意图时,格外小心地保留该意图。不要改变范围、约束、优先级、验收标准或请求的结果。\n当直接引用简短用户指令最能保留精确含义时,直接引用。\n\n历史审批处理\n当压缩包含用户的审批/批准短语(如\"就执行吧\"、\"按照这个执行\"、\"好的,继续\"等)时,必须将其标记为历史事件而非当前有效指令。\n- 错误:保留\"用户说:就执行吧\"(可能被误解为当前指令)\n- 正确:标记为\"用户曾批准了先前的方案(该批准仅适用于当时的上下文,不构成对后续操作的授权)\"\n这确保压缩后的上下文不会被误解为新的执行授权。\n\n同时保持精简。去除噪音:无果的失败尝试、冗长的工具输出和重复。留下的应该是纯信号——保留完整理解、零歧义的精华细节。\n如果消息不包含重要的技术决策、代码变更或用户需求,生成最小化的一行摘要而非详细摘要。\n\n消息 ID\n使用对话中可见的注入 ID 按 ID 指定单条原始消息:\n\n- \\`mNNNN\\` ID 标识原始消息\n\n每条消息在 XML 元数据标签内有 ID,如 \\`<dcp-message-id priority=\"high\">m0007</dcp-message-id>\\`。\n相同的 ID 标签出现在该消息所属的每个工具输出中——每个唯一 ID 标识一条完整消息。\n将这些标签仅视为消息元数据,而非要摘要的内容。只使用内部的 \\`mNNNN\\` 值作为 \\`messageId\\`。\n\\`priority\\` 属性表示相对上下文成本。当高优先级消息的完整文本对当前任务不再必要时,你必须压缩它们。\n如果存在之前的压缩工具结果,始终在更广泛的压缩过程中将它们最小化地压缩和摘要。不要仅为了重新压缩之前的压缩结果而调用压缩工具。\n标记为 \\`<dcp-message-id>BLOCKED</dcp-message-id>\\` 的消息不能被压缩。\n\n规则:\n\n- 直接从上下文中可见的注入 ID 选取每个 \\`messageId\\`。\n- 只使用 \\`mNNNN\\` 形式的原始消息 ID。\n- 复制 ID 时忽略 \\`priority\\` 等 XML 属性;只使用内部的 \\`mNNNN\\` 值。\n- 不要发明 ID。只使用上下文中存在的 ID。\n\n批量处理\n当多条消息可以安全压缩时,在单次工具调用中选择多条消息。\n每个条目应恰好摘要一条消息,工具可以在一次批量中接收任意数量的条目。\n\n通用清理\n使用主题\"通用清理\"进行广泛的清理。\n在通用清理期间,压缩所有与当前任务无关的中高优先级消息。\n优化减少上下文占用,而非按主题分组消息。\n不要压缩掉仍然活跃的指令、未解决的问题或可能很快重要的约束。\n优先处理上下文中最早的消息,因为它们与当前任务的相关性最低。\n通用清理应定期在其他正常压缩工具调用之间进行,而非作为压缩的主要形式。\n`\n","export const CONTEXT_LIMIT_NUDGE = `<dcp-system-reminder>\nCRITICAL: 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 call \\`compress\\` now. Do not continue normal exploration until compression is done.\n\nIf mid-atomic-step, finish that one step, then compress immediately.\n\nSelection\nStart from older, already-finished history and capture as much stale context as possible in one pass.\nDo not select the latest working messages unless they are clearly concluded.\n\nSummary requirements\nYour summary must cover all key details in the selected messages so work can continue.\nIf the range contains user messages, preserve their intent fully. For short user messages, prefer direct quotes to avoid semantic drift.\n</dcp-system-reminder>\n`\n","export const TURN_NUDGE = `\nNew user turn. This is the moment topic changes are most likely.\n\nIs this turn's request a different topic/task from the previous one?\n- New or independent topic: call \\`compress\\` now to fold the previous topic's finished context into a summary. Its details no longer need verbatim retention.\n- Continuation of the same topic: you may keep it, but still watch for stale accumulation.\n\nTopic change is the clearest, most objective compression trigger — do not miss it.\n`\n","export const ITERATION_NUDGE = `\nMany iterations elapsed without new user input.\n\nHas the current iteration's task effectively finished, or has its topic drifted away from earlier steps?\n- If earlier steps belong to a resolved problem or a superseded exploration, call \\`compress\\` now to fold them into a summary.\n- If the iteration still continues the same unfinished goal and early context is still needed, keep it.\n\nDo not let finished exploration directions keep occupying context. Topic drift is the best moment to compress.\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `\n手动模式已启用。压缩操作需要用户明确触发。\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `\n子代理模式:压缩功能已禁用。\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 `以下工具的输出受保护,压缩时不要包含其完整内容:${toolList}`\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\"\n\nconst SUMMARY_ID_HASH_LENGTH = 16\nconst DCP_BLOCK_ID_TAG_REGEX = /(<dcp-message-id(?=[\\s>])[^>]*>)b\\d+(<\\/dcp-message-id>)/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\nconst INJECTED_TAG_SUFFIX_REGEX = /\\n<dcp-message-id(?:\\s[^>]*)?>m\\d+<\\/dcp-message-id>\\s*$/\nconst TRAILING_MESSAGE_REF_REGEX = /\\nm\\d{4}\\s*$/\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 replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n // Issue #556: Remove legitimately injected message ID suffix before running\n // paired regex so it can't act as a false closing match\n const safe = text.replace(INJECTED_TAG_SUFFIX_REGEX, \"\")\n // Issue #555: Strip trailing mXXXX hallucinated message refs\n return safe\n .replace(DCP_PAIRED_TAG_REGEX, \"\")\n .replace(DCP_UNPAIRED_TAG_REGEX, \"\")\n .replace(TRAILING_MESSAGE_REF_REGEX, \"\")\n}\n\nexport const stripHallucinations = (messages: WithParts[]): 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)\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)\n }\n }\n }\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\nimport type { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport { createSyntheticUserMessage, replaceBlockIdsWithBlocked } from \"./utils\"\nimport { getLastUserMessage } from \"./query\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\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 config: PluginConfig,\n messages: WithParts[],\n): void => {\n filterCompressedRanges(state, logger, config, messages)\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 config: PluginConfig,\n messages: 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)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(rawSummaryContent)\n : rawSummaryContent\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 missingAnchorBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n for (const block of orderedBlocks) {\n const hasAnchorMessage =\n typeof block.anchorMessageId === \"string\" &&\n block.anchorMessageId.length > 0 &&\n messageIds.has(block.anchorMessageId)\n\n if (!hasAnchorMessage) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n missingAnchorBlockIds.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 (missingAnchorBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingAnchorCount: missingAnchorBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type HostPermissionSnapshot, resolveEffectiveCompressPermission } from \"./host-permissions\"\nimport type { SessionState, WithParts } from \"./state\"\nimport { getLastUserMessage } from \"./messages/query\"\n\nexport const compressPermission = (\n state: SessionState,\n config: PluginConfig,\n): \"ask\" | \"allow\" | \"deny\" => {\n return state.compressPermission ?? config.compress.permission\n}\n\nexport const syncCompressPermissionState = (\n state: SessionState,\n config: PluginConfig,\n hostPermissions: HostPermissionSnapshot,\n messages: WithParts[],\n): void => {\n const activeAgent = getLastUserMessage(messages)?.info.agent\n state.compressPermission = resolveEffectiveCompressPermission(\n config.compress.permission,\n hostPermissions,\n activeAgent,\n )\n}\n","import type { PluginConfig } from \"../../config\"\nimport type { SessionState, WithParts } from \"../../state\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../../messages/query\"\nimport { isMessageCompacted } from \"../../state/utils\"\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) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"无\"\n\n return [\n \"压缩块上下文:\",\n `- 此会话中的活跃压缩块:${blockCount} 个(${blockList})`,\n \"- 如果你选择的压缩范围包含任何列出的块,在摘要中使用 `(bN)` 恰好包含每个必需的占位符一次。\",\n ].join(\"\\n\")\n}\n\nexport function buildAvailableMessageIdGuidance(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n): string {\n const visibleIds = new Set(\n messages\n .filter(\n (msg) =>\n !isIgnoredUserMessage(msg) &&\n !isMessageCompacted(state, msg) &&\n !isProtectedUserMessage(config, msg),\n )\n .map((msg) => msg.info.id),\n )\n\n const refs = []\n for (const [ref, rawId] of state.messageIds.byRef) {\n if (visibleIds.has(rawId)) {\n refs.push(ref)\n }\n }\n\n refs.sort((a, b) => {\n const numA = Number.parseInt(a.slice(1), 10)\n const numB = Number.parseInt(b.slice(1), 10)\n return numA - numB\n })\n\n if (refs.length === 0) {\n return \"\"\n }\n\n const refList =\n refs.length <= 15\n ? refs.join(\", \")\n : `${refs[0]} 到 ${refs[refs.length - 1]}(共 ${refs.length} 个)`\n\n return [\n \"可用消息边界 ID:\",\n `- 当前上下文中可作为 compress 边界的合法消息 ID:${refList}`,\n config.compress.mode === \"message\"\n ? \"- 只从以上列表中选取 content[].messageId。不要发明、外推或使用不在列表中的 ID。\"\n : \"- 只从以上列表中选取 startId 和 endId。不要发明、外推或使用不在列表中的 ID。\",\n ].join(\"\\n\")\n}\n\nexport function renderMessagePriorityGuidance(priorityLabel: string, refs: string[]): string {\n const refList = refs.length > 0 ? refs.join(\", \") : \"无\"\n\n const normalized = priorityLabel.toLowerCase()\n const priorityLabelZh = normalized === \"high\" ? \"高\" : normalized === \"medium\" ? \"中\" : \"低\"\n\n return [\n \"消息优先级上下文:\",\n \"- 高优先级的旧消息消耗更多上下文,如果安全的话应立即压缩。\",\n `- 此点之前的${priorityLabelZh}优先级消息 ID:${refList}`,\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 = \"\"\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 { PluginConfig } from \"../config\"\nimport { countAllMessageTokens } from \"../token-utils\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isIgnoredUserMessage, isProtectedUserMessage, messageHasCompress } from \"./query\"\n\nconst MEDIUM_PRIORITY_MIN_TOKENS = 500\nconst HIGH_PRIORITY_MIN_TOKENS = 5000\n\nexport type MessagePriority = \"low\" | \"medium\" | \"high\"\n\nexport interface CompressionPriorityEntry {\n ref: string\n tokenCount: number\n priority: MessagePriority\n}\n\nexport type CompressionPriorityMap = Map<string, CompressionPriorityEntry>\n\nexport function buildPriorityMap(\n config: PluginConfig,\n state: SessionState,\n messages: WithParts[],\n): CompressionPriorityMap {\n if (config.compress.mode !== \"message\") {\n return new Map()\n }\n const priorities: CompressionPriorityMap = new Map()\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n if (isProtectedUserMessage(config, message)) {\n continue\n }\n\n if (isMessageCompacted(state, message)) {\n continue\n }\n\n const rawMessageId = message.info.id\n if (typeof rawMessageId !== \"string\" || rawMessageId.length === 0) {\n continue\n }\n\n const ref = state.messageIds.byRawId.get(rawMessageId)\n if (!ref) {\n continue\n }\n\n const tokenCount = countAllMessageTokens(message)\n priorities.set(rawMessageId, {\n ref,\n tokenCount,\n priority: messageHasCompress(message) ? \"high\" : classifyMessagePriority(tokenCount),\n })\n }\n\n return priorities\n}\n\nexport function classifyMessagePriority(tokenCount: number): MessagePriority {\n if (tokenCount >= HIGH_PRIORITY_MIN_TOKENS) {\n return \"high\"\n }\n\n if (tokenCount >= MEDIUM_PRIORITY_MIN_TOKENS) {\n return \"medium\"\n }\n\n return \"low\"\n}\n\nexport function listPriorityRefsBeforeIndex(\n messages: WithParts[],\n priorities: CompressionPriorityMap,\n anchorIndex: number,\n priority: MessagePriority,\n): string[] {\n const refs: string[] = []\n const seen = new Set<string>()\n const upperBound = Math.max(0, Math.min(anchorIndex, messages.length))\n\n for (let index = 0; index < upperBound; index++) {\n const rawMessageId = messages[index]?.info.id\n if (typeof rawMessageId !== \"string\") {\n continue\n }\n\n const entry = priorities.get(rawMessageId)\n if (!entry || entry.priority !== priority || seen.has(entry.ref)) {\n continue\n }\n\n seen.add(entry.ref)\n refs.push(entry.ref)\n }\n\n return refs\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { PluginConfig } from \"../../config\"\nimport {\n appendGuidanceToDcpTag,\n buildAvailableMessageIdGuidance,\n buildCompressedBlockGuidance,\n renderMessagePriorityGuidance,\n} from \"../../prompts/extensions/nudge\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\nimport {\n type CompressionPriorityMap,\n type MessagePriority,\n listPriorityRefsBeforeIndex,\n} from \"../priority\"\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\nconst MESSAGE_MODE_NUDGE_PRIORITY: MessagePriority = \"high\"\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 1\n}\n\nexport function getIterationNudgeThreshold(_config: PluginConfig): number {\n return 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 buildMessagePriorityGuidance(\n messages: WithParts[],\n compressionPriorities: CompressionPriorityMap | undefined,\n anchorIndex: number,\n priority: MessagePriority,\n): string {\n if (!compressionPriorities || compressionPriorities.size === 0) {\n return \"\"\n }\n\n const refs = listPriorityRefsBeforeIndex(messages, compressionPriorities, anchorIndex, priority)\n const priorityLabel = `${priority[0].toUpperCase()}${priority.slice(1)}`\n\n return renderMessagePriorityGuidance(priorityLabel, refs)\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 applyRangeModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n compressedBlockGuidance: string,\n availableMessageIdGuidance: string,\n): void {\n const combinedGuidance = [availableMessageIdGuidance, compressedBlockGuidance]\n .filter((g) => g.trim().length > 0)\n .join(\"\\n\\n\")\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, combinedGuidance)\n if (!nudgeText.trim()) {\n return\n }\n\n for (const { message } of collectAnchoredMessages(anchorMessageIds, messages)) {\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nfunction applyMessageModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n availableMessageIdGuidance: string,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n for (const { message, index } of collectAnchoredMessages(anchorMessageIds, messages)) {\n const priorityGuidance = buildMessagePriorityGuidance(\n messages,\n compressionPriorities,\n index,\n MESSAGE_MODE_NUDGE_PRIORITY,\n )\n const combinedGuidance = [availableMessageIdGuidance, priorityGuidance]\n .filter((g) => g.trim().length > 0)\n .join(\"\\n\\n\")\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, combinedGuidance)\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(state, config, messages)\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n return\n }\n\n const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(state, config, messages)\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\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 type { CompressionPriorityMap } from \"../priority\"\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 compressionPriorities?: CompressionPriorityMap,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n if (state.manualMode) {\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 const continuationReminder =\n \"\\n<dcp-system-reminder>\\nCompression complete. Resume your previous task.\\n</dcp-system-reminder>\\n\"\n\n if (lastMessage) {\n const targetMessage = lastMessage.message\n let injected = false\n for (const part of targetMessage.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n part.text += continuationReminder\n injected = true\n break\n }\n }\n if (!injected) {\n targetMessage.parts.push(\n createSyntheticTextPart(targetMessage, continuationReminder),\n )\n }\n }\n\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, compressionPriorities)\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 compressionPriorities?: CompressionPriorityMap,\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 priority =\n config.compress.mode === \"message\" && !isBlockedMessage\n ? compressionPriorities?.get(message.info.id)?.priority\n : undefined\n const tag = formatMessageIdTag(\n isBlockedMessage ? \"BLOCKED\" : messageRef,\n priority ? { priority } : undefined,\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\" || part.tool !== \"task\" || !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 )\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 )\n }\n }\n}\n","import type { WithParts } from \"../state\"\nimport { getLastUserMessage } from \"./query\"\n\n/**\n * Mirrors opencode's differentModel handling by preserving part content while\n * dropping provider metadata on assistant parts that came from a different\n * model/provider than the current turn's user message.\n */\nexport function stripStaleMetadata(messages: WithParts[]): void {\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage?.info.role !== \"user\") {\n return\n }\n\n const modelID = lastUserMessage.info.model.modelID\n const providerID = lastUserMessage.info.model.providerID\n\n messages.forEach((message) => {\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (message.info.modelID === modelID && message.info.providerID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\") {\n return part\n }\n\n if (!(\"metadata\" in part)) {\n return part\n }\n\n const { metadata: _metadata, ...rest } = part\n return rest\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\nfunction analyzeTokens(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\nfunction 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 = analyzeTokens(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 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 grouped: boolean\n blocks: CompressionBlock[]\n}\n\nfunction byBlockId(a: CompressionBlock, b: CompressionBlock): number {\n return a.blockId - b.blockId\n}\n\nfunction buildTarget(blocks: CompressionBlock[]): CompressionTarget {\n const ordered = [...blocks].sort(byBlockId)\n const first = ordered[0]\n if (!first) {\n throw new Error(\"Cannot build compression target from empty block list.\")\n }\n\n const grouped = first.mode === \"message\"\n return {\n displayId: first.blockId,\n runId: first.runId,\n topic: grouped ? first.batchTopic || first.topic : first.topic,\n compressedTokens: ordered.reduce((total, block) => total + block.compressedTokens, 0),\n durationMs: ordered.reduce((total, block) => Math.max(total, block.durationMs), 0),\n grouped,\n blocks: ordered,\n }\n}\n\nfunction groupMessageBlocks(blocks: CompressionBlock[]): CompressionTarget[] {\n const grouped = new Map<number, CompressionBlock[]>()\n\n for (const block of blocks) {\n const existing = grouped.get(block.runId)\n if (existing) {\n existing.push(block)\n continue\n }\n grouped.set(block.runId, [block])\n }\n\n return Array.from(grouped.values()).map(buildTarget)\n}\n\nfunction splitTargets(blocks: CompressionBlock[]): CompressionTarget[] {\n const messageBlocks: CompressionBlock[] = []\n const singleBlocks: CompressionBlock[] = []\n\n for (const block of blocks) {\n if (block.mode === \"message\") {\n messageBlocks.push(block)\n } else {\n singleBlocks.push(block)\n }\n }\n\n const targets = [\n ...singleBlocks.map((block) => buildTarget([block])),\n ...groupMessageBlocks(messageBlocks),\n ]\n return targets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function getActiveCompressionTargets(\n messagesState: PruneMessagesState,\n): CompressionTarget[] {\n const activeBlocks = Array.from(messagesState.activeBlockIds)\n .map((blockId) => messagesState.blocksById.get(blockId))\n .filter((block): block is CompressionBlock => !!block && block.active)\n\n return splitTargets(activeBlocks)\n}\n\nexport function getRecompressibleCompressionTargets(\n messagesState: PruneMessagesState,\n availableMessageIds: Set<string>,\n): CompressionTarget[] {\n const allBlocks = Array.from(messagesState.blocksById.values()).filter((block) => {\n return availableMessageIds.has(block.anchorMessageId)\n })\n\n const messageGroups = new Map<number, CompressionBlock[]>()\n const singleTargets: CompressionTarget[] = []\n\n for (const block of allBlocks) {\n if (block.mode === \"message\") {\n const existing = messageGroups.get(block.runId)\n if (existing) {\n existing.push(block)\n } else {\n messageGroups.set(block.runId, [block])\n }\n continue\n }\n\n if (block.deactivatedByUser && !block.active) {\n singleTargets.push(buildTarget([block]))\n }\n }\n\n for (const blocks of messageGroups.values()) {\n if (blocks.some((block) => block.deactivatedByUser && !block.active)) {\n singleTargets.push(buildTarget(blocks))\n }\n }\n\n return singleTargets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function resolveCompressionTarget(\n messagesState: PruneMessagesState,\n blockId: number,\n): CompressionTarget | null {\n const block = messagesState.blocksById.get(blockId)\n if (!block) {\n return null\n }\n\n if (block.mode !== \"message\") {\n return buildTarget([block])\n }\n\n const blocks = Array.from(messagesState.blocksById.values()).filter(\n (candidate) => candidate.mode === \"message\" && candidate.runId === block.runId,\n )\n if (blocks.length === 0) {\n return null\n }\n\n return buildTarget(blocks)\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)\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 || target.grouped) {\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 = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `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 BASE_COMMANDS: [string, string][] = [\n [\"/dcp context\", \"Show token usage breakdown for current session\"],\n [\"/dcp stats\", \"Show DCP pruning statistics\"],\n [\"/dcp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/dcp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\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 = [...BASE_COMMANDS]\n\n if (compressPermission(state, config) !== \"deny\") {\n commands.push(TOOL_COMMANDS.compress)\n commands.push(TOOL_COMMANDS.decompress)\n commands.push(TOOL_COMMANDS.recompress)\n }\n\n return commands\n}\n\nfunction 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 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 { saveSessionState } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport {\n buildAvailableMessageIdGuidance,\n buildCompressedBlockGuidance,\n} 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 messages: WithParts[],\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state)\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(\n state,\n config,\n messages,\n )\n\n const sections = [base, availableMessageIdGuidance, 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 await saveSessionState(state, logger)\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\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, ctx.messages, 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)\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 || target.grouped) {\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 = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `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.anchorMessageId))) {\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 { 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\nfunction formatStatsMessage(\n sessionTokens: number,\n sessionSummaryTokens: number,\n sessionTools: number,\n sessionMessages: number,\n sessionDurationMs: number,\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 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\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 // Session stats from in-memory state\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 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 const message = formatStatsMessage(\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n 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,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTimeTokens: allTime.totalTokens,\n allTimeTools: allTime.totalTools,\n allTimeMessages: allTime.totalMessages,\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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 (isToolNameProtected(entry.tool, protectedTools)) {\n logger.debug(`Sweep: skipping protected tool ${entry.tool} (${id})`)\n return false\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n logger.debug(`Sweep: skipping protected file path(s) ${filePaths.join(\", \")} (${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 if (isToolNameProtected(entry.tool, protectedTools)) {\n return true\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n return true\n }\n return false\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 { assignMessageRefs } from \"./message-ids\"\nimport {\n buildPriorityMap,\n buildToolIdList,\n injectCompressNudges,\n injectExtendedSubAgentResults,\n injectMessageIds,\n prune,\n stripHallucinations,\n stripHallucinationsFromString,\n stripStaleMetadata,\n syncCompressionBlocks,\n} from \"./messages\"\nimport { renderSystemPrompt, type PromptStore } from \"./prompts\"\nimport { buildProtectedToolsExtension } from \"./prompts/extensions/system\"\nimport {\n applyPendingCompressionDurations,\n buildCompressionTimingKey,\n consumeCompressionStart,\n resolveCompressionDuration,\n} from \"./compress/timing\"\nimport { filterMessages, filterMessagesInPlace } from \"./messages/shape\"\nimport {\n applyPendingManualTrigger,\n handleContextCommand,\n handleDecompressCommand,\n handleHelpCommand,\n handleManualToggleCommand,\n handleManualTriggerCommand,\n handleRecompressCommand,\n handleStatsCommand,\n handleSweepCommand,\n} from \"./commands\"\nimport { type HostPermissionSnapshot } from \"./host-permissions\"\nimport { compressPermission, syncCompressPermissionState } from \"./compress-permission\"\nimport { checkSession, ensureSessionInitialized, saveSessionState, syncToolCache } from \"./state\"\nimport { cacheSystemPromptTokens } from \"./ui/utils\"\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\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 const systemText = output.system.join(\"\\n\")\n if (INTERNAL_AGENT_SIGNATURES.some((sig) => systemText.includes(sig))) {\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 createChatMessageTransformHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (input: {}, output: { messages: WithParts[] }) => {\n const receivedMessages = Array.isArray(output.messages) ? output.messages.length : 0\n const messages = filterMessagesInPlace(output.messages)\n if (messages.length !== receivedMessages) {\n logger.warn(\"Skipping messages with unexpected shape during chat transform\", {\n received: receivedMessages,\n usable: messages.length,\n })\n }\n\n await checkSession(client, state, logger, output.messages, config.manualMode.enabled)\n\n syncCompressPermissionState(state, config, hostPermissions, output.messages)\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n const originalMessages = output.messages\n output.messages = structuredClone(output.messages)\n\n try {\n stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n syncCompressionBlocks(state, logger, output.messages)\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n prune(state, logger, config, output.messages)\n await injectExtendedSubAgentResults(\n client,\n state,\n logger,\n output.messages,\n config.experimental.allowSubAgents,\n )\n const compressionPriorities = buildPriorityMap(config, state, output.messages)\n prompts.reload()\n injectCompressNudges(\n state,\n config,\n logger,\n output.messages,\n prompts.getRuntimePrompts(),\n compressionPriorities,\n )\n injectMessageIds(state, config, output.messages, compressionPriorities)\n applyPendingManualTrigger(state, output.messages, logger)\n stripStaleMetadata(output.messages)\n\n if (state.sessionId) {\n await logger.saveContext(state.sessionId, output.messages)\n }\n } catch (error) {\n logger.error(\"Chat message transform failed, returning original messages\", {\n error: error instanceof Error ? error.message : String(error),\n })\n output.messages = originalMessages\n }\n }\n}\n\nexport function createCommandExecuteHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n workingDirectory: string,\n hostPermissions: HostPermissionSnapshot,\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\") {\n const messagesResponse = await client.session.messages({\n path: { id: input.sessionID },\n })\n const messages = 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 syncCompressPermissionState(state, config, hostPermissions, messages)\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 subcommand = args[0]?.toLowerCase() || \"\"\n const subArgs = 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 throw new Error(\"__DCP_CONTEXT_HANDLED__\")\n }\n\n if (subcommand === \"stats\") {\n await handleStatsCommand(commandCtx)\n throw new Error(\"__DCP_STATS_HANDLED__\")\n }\n\n if (subcommand === \"sweep\") {\n await handleSweepCommand({\n ...commandCtx,\n args: subArgs,\n workingDirectory,\n })\n throw new Error(\"__DCP_SWEEP_HANDLED__\")\n }\n\n if (subcommand === \"manual\") {\n await handleManualToggleCommand(commandCtx, subArgs[0]?.toLowerCase())\n throw new Error(\"__DCP_MANUAL_HANDLED__\")\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: rawArgs ? `/dcp ${rawArgs}` : `/dcp ${subcommand}`,\n })\n return\n }\n\n if (subcommand === \"decompress\") {\n await handleDecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_DECOMPRESS_HANDLED__\")\n }\n\n if (subcommand === \"recompress\") {\n await handleRecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_RECOMPRESS_HANDLED__\")\n }\n\n await handleHelpCommand(commandCtx)\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n }\n}\n\nexport function createTextCompleteHandler() {\n return async (\n _input: { sessionID: string; messageID: string; partID: string },\n output: { text: string },\n ) => {\n output.text = stripHallucinationsFromString(output.text)\n }\n}\n\nexport function createEventHandler(state: SessionState, logger: Logger) {\n return async (input: { event: any }) => {\n const eventTime =\n typeof input.event?.time === \"number\" && Number.isFinite(input.event.time)\n ? input.event.time\n : typeof input.event?.properties?.time === \"number\" &&\n Number.isFinite(input.event.properties.time)\n ? input.event.properties.time\n : undefined\n\n if (input.event.type !== \"message.part.updated\") {\n return\n }\n\n const part = input.event.properties?.part\n if (part?.type !== \"tool\" || part.tool !== \"compress\") {\n return\n }\n\n if (part.state.status === \"pending\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const startedAt = eventTime ?? Date.now()\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n if (state.compressionTiming.startsByCallId.has(key)) {\n return\n }\n state.compressionTiming.startsByCallId.set(key, startedAt)\n logger.debug(\"Recorded compression start\", {\n messageID: part.messageID,\n callID: part.callID,\n startedAt,\n })\n return\n }\n\n if (part.state.status === \"completed\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n const start = consumeCompressionStart(state, part.messageID, part.callID)\n const durationMs = resolveCompressionDuration(start, eventTime, part.state.time)\n if (typeof durationMs !== \"number\") {\n return\n }\n\n state.compressionTiming.pendingByCallId.set(key, {\n messageId: part.messageID,\n callId: part.callID,\n durationMs,\n })\n\n const updates = applyPendingCompressionDurations(state)\n if (updates === 0) {\n return\n }\n\n await saveSessionState(state, logger)\n\n logger.info(\"Attached compression time to blocks\", {\n messageID: part.messageID,\n callID: part.callID,\n blocks: updates,\n durationMs,\n })\n return\n }\n\n if (part.state.status === \"running\") {\n return\n }\n\n if (typeof part.callID === \"string\" && typeof part.messageID === \"string\") {\n state.compressionTiming.startsByCallId.delete(\n buildCompressionTimingKey(part.messageID, part.callID),\n )\n }\n }\n}\n","export function isSecureMode(): boolean {\n return !!process.env.OPENCODE_SERVER_PASSWORD\n}\n\nexport function getAuthorizationHeader(): string | undefined {\n const password = process.env.OPENCODE_SERVER_PASSWORD\n if (!password) return undefined\n\n const username = process.env.OPENCODE_SERVER_USERNAME ?? \"opencode\"\n // Use Buffer for Node.js base64 encoding (btoa may not be available in all Node versions)\n const credentials = Buffer.from(`${username}:${password}`).toString(\"base64\")\n return `Basic ${credentials}`\n}\n\nexport function configureClientAuth(client: any): any {\n const authHeader = getAuthorizationHeader()\n\n if (!authHeader) {\n return client\n }\n\n // The SDK client has an internal client with request interceptors\n // Access the underlying client to add the interceptor\n const innerClient = client._client || client.client\n\n if (innerClient?.interceptors?.request) {\n innerClient.interceptors.request.use((request: Request) => {\n // Only add auth header if not already present\n if (!request.headers.has(\"Authorization\")) {\n request.headers.set(\"Authorization\", authHeader)\n }\n return request\n })\n }\n\n return client\n}\n","import { readFile, rm } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { updated: true; name: string; current: string; latest: string }\n | { updated: false; error: \"remove_failed\"; name: string; current: string; latest: string }\n | { updated: false }\n\nconst PACKAGE_NAME = \"@lexwdex-org/opencode-dcp\"\n\nexport function startAutoUpdate(ctx: PluginInput, enabled: boolean): void {\n if (!enabled) return\n\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 10_000)\n void checkAutoUpdate(controller.signal)\n .then((result) => {\n if (!result.updated) return\n setTimeout(() => {\n ctx.client.tui.showToast({\n body: {\n title: \"DCP update ready\",\n message: `Updated ${result.name} from ${result.current} to ${result.latest}. Restart OpenCode to finish.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { updated: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { updated: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { updated: false }\n\n const removeDir = await updateRemoveDir(packageDir, pkg.name)\n if (!removeDir) return { updated: false }\n\n try {\n await rm(removeDir, { recursive: true, force: true })\n } catch {\n return {\n updated: false,\n error: \"remove_failed\",\n name: pkg.name,\n current: pkg.version,\n latest,\n }\n }\n\n return { updated: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function updateRemoveDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nfunction wrapperSpec(wrapperDir: string, name: string) {\n if (name.startsWith(\"@\")) {\n const [scope, pkg] = name.split(\"/\")\n if (!scope || !pkg || basename(dirname(wrapperDir)) !== scope) return undefined\n const prefix = `${pkg}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n }\n\n const prefix = `${name}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"./lib/config\"\nimport { createCompressMessageTool, createCompressRangeTool } from \"./lib/compress\"\nimport {\n compressDisabledByOpencode,\n hasExplicitToolPermission,\n type HostPermissionSnapshot,\n} from \"./lib/host-permissions\"\nimport { Logger } from \"./lib/logger\"\nimport { createSessionState } from \"./lib/state\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport {\n createChatMessageTransformHandler,\n createCommandExecuteHandler,\n createEventHandler,\n createSystemPromptHandler,\n createTextCompleteHandler,\n} from \"./lib/hooks\"\nimport { configureClientAuth, isSecureMode } from \"./lib/auth\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n\n if (!config.enabled) {\n return {}\n }\n\n const logger = new Logger(config.debug)\n const state = createSessionState()\n const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts)\n const hostPermissions: HostPermissionSnapshot = {\n global: undefined,\n agents: {},\n }\n\n if (isSecureMode()) {\n configureClientAuth(ctx.client)\n // logger.info(\"Secure mode detected, configured client authentication\")\n }\n\n logger.info(\"DCP initialized\", {\n strategies: config.strategies,\n })\n\n startAutoUpdate(ctx, config.autoUpdate)\n\n const compressToolContext = {\n client: ctx.client,\n state,\n logger,\n config,\n prompts,\n }\n\n return {\n \"experimental.chat.system.transform\": createSystemPromptHandler(\n state,\n logger,\n config,\n prompts,\n ),\n \"experimental.chat.messages.transform\": createChatMessageTransformHandler(\n ctx.client,\n state,\n logger,\n config,\n prompts,\n hostPermissions,\n ) as any,\n \"experimental.text.complete\": createTextCompleteHandler(),\n \"command.execute.before\": createCommandExecuteHandler(\n ctx.client,\n state,\n logger,\n config,\n ctx.directory,\n hostPermissions,\n ),\n event: createEventHandler(state, logger),\n tool: {\n ...(config.compress.permission !== \"deny\" && {\n compress:\n config.compress.mode === \"message\"\n ? createCompressMessageTool(compressToolContext)\n : createCompressRangeTool(compressToolContext),\n }),\n },\n config: async (opencodeConfig) => {\n if (\n config.compress.permission !== \"deny\" &&\n compressDisabledByOpencode(opencodeConfig.permission)\n ) {\n config.compress.permission = \"deny\"\n }\n\n if (config.commands.enabled && config.compress.permission !== \"deny\") {\n opencodeConfig.command ??= {}\n opencodeConfig.command[\"dcp\"] = {\n template: \"\",\n description: \"Show available DCP commands\",\n }\n }\n\n const toolsToAdd: string[] = []\n if (config.compress.permission !== \"deny\" && !config.experimental.allowSubAgents) {\n toolsToAdd.push(\"compress\")\n }\n\n if (toolsToAdd.length > 0) {\n const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? []\n opencodeConfig.experimental = {\n ...opencodeConfig.experimental,\n primary_tools: [...existingPrimaryTools, ...toolsToAdd],\n }\n }\n\n if (!hasExplicitToolPermission(opencodeConfig.permission, \"compress\")) {\n const permission = opencodeConfig.permission ?? {}\n opencodeConfig.permission = {\n ...permission,\n compress: config.compress.permission,\n } as typeof permission\n }\n\n hostPermissions.global = opencodeConfig.permission\n hostPermissions.agents = Object.fromEntries(\n Object.entries(opencodeConfig.agent ?? {}).map(([name, agent]) => [\n name,\n agent?.permission,\n ]),\n )\n },\n }\n}) satisfies Plugin\n\nexport default server\n"],"mappings":"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BAAeA,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;AAC3C,EAAAA,gBAAeA,gBAAe,GAA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","names":["value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","parse","countTokens","existsSync","homedir","join","countTokens","join","homedir","existsSync","tool","tool","tool","countTokens","countTokens","tool","validateArgs","buildSchema","tool","validateArgs","countTokens","tool","writeFile","mkdir","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","availableMessageIdGuidance","countTokens","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","message","readFile","dirname","join","prefix","base"]}
|
|
1
|
+
{"version":3,"sources":["../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/config-env-override.ts","../lib/compress/message.ts","../lib/token-utils.ts","../lib/messages/shape.ts","../lib/messages/query.ts","../lib/prompts/extensions/tool.ts","../lib/message-ids.ts","../lib/compress/search.ts","../lib/compress/state.ts","../lib/compress/message-utils.ts","../lib/state/persistence.ts","../lib/state/utils.ts","../lib/concurrency.ts","../lib/compress/timing.ts","../lib/state/store.ts","../lib/state/state.ts","../lib/state/tool-cache.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/subagents/subagent-results.ts","../lib/compress/protected-content.ts","../lib/compress/external-inference.ts","../lib/compress/external-content.ts","../lib/compress/range.ts","../lib/compress/range-utils.ts","../lib/host-permissions.ts","../lib/logger.ts","../lib/prompts/store.ts","../lib/prompts/system.ts","../lib/prompts/compress-range.ts","../lib/prompts/compress-message.ts","../lib/prompts/context-limit-nudge.ts","../lib/prompts/turn-nudge.ts","../lib/prompts/iteration-nudge.ts","../lib/prompts/extensions/system.ts","../lib/messages/utils.ts","../lib/messages/prune.ts","../lib/messages/sync.ts","../lib/compress-permission.ts","../lib/prompts/extensions/nudge.ts","../lib/messages/priority.ts","../lib/messages/inject/utils.ts","../lib/messages/inject/inject.ts","../lib/messages/inject/subagent-results.ts","../lib/messages/reasoning-strip.ts","../lib/prompts/index.ts","../lib/commands/context.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/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport * as jsoncParser from \"jsonc-parser\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\nimport { applyExternalModelEnvOverride } from \"./config-env-override\"\n\ntype Permission = \"ask\" | \"allow\" | \"deny\"\ntype CompressMode = \"range\" | \"message\"\n\nexport interface Deduplication {\n enabled: boolean\n protectedTools: string[]\n}\n\nexport interface ExternalModelConfig {\n url: string\n apiKey?: string\n model: string\n timeout?: number\n retries?: number\n}\n\nexport interface CompressConfig {\n mode: CompressMode\n permission: Permission\n showCompression: boolean\n summaryBuffer: boolean\n maxContextLimit: number | `${number}%`\n minContextLimit: number | `${number}%`\n boundaryNudge?: boolean\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 externalModel?: ExternalModelConfig\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 autoUpdate: 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 \"autoUpdate\",\n \"debug\",\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.mode\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.boundaryNudge\",\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 \"compress.externalModel\",\n \"compress.externalModel.url\",\n \"compress.externalModel.model\",\n \"compress.externalModel.apiKey\",\n \"compress.externalModel.timeout\",\n \"compress.externalModel.retries\",\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.autoUpdate !== undefined && typeof config.autoUpdate !== \"boolean\") {\n errors.push({ key: \"autoUpdate\", expected: \"boolean\", actual: typeof config.autoUpdate })\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.mode !== undefined &&\n compress.mode !== \"range\" &&\n compress.mode !== \"message\"\n ) {\n errors.push({\n key: \"compress.mode\",\n expected: '\"range\" | \"message\"',\n actual: JSON.stringify(compress.mode),\n })\n }\n\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.boundaryNudge !== undefined &&\n typeof compress.boundaryNudge !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.boundaryNudge\",\n expected: \"boolean\",\n actual: typeof compress.boundaryNudge,\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 (compress.externalModel !== undefined) {\n if (\n typeof compress.externalModel !== \"object\" ||\n compress.externalModel === null ||\n Array.isArray(compress.externalModel)\n ) {\n errors.push({\n key: \"compress.externalModel\",\n expected: \"object with url and model\",\n actual: typeof compress.externalModel,\n })\n } else {\n if (typeof compress.externalModel.url !== \"string\") {\n errors.push({\n key: \"compress.externalModel.url\",\n expected: \"string\",\n actual: typeof compress.externalModel.url,\n })\n } else if (compress.externalModel.url.trim().length === 0) {\n errors.push({\n key: \"compress.externalModel.url\",\n expected: \"non-empty string\",\n actual: \"empty string\",\n })\n }\n if (typeof compress.externalModel.model !== \"string\") {\n errors.push({\n key: \"compress.externalModel.model\",\n expected: \"string\",\n actual: typeof compress.externalModel.model,\n })\n } else if (compress.externalModel.model.trim().length === 0) {\n errors.push({\n key: \"compress.externalModel.model\",\n expected: \"non-empty string\",\n actual: \"empty string\",\n })\n }\n if (\n compress.externalModel.apiKey !== undefined &&\n typeof compress.externalModel.apiKey !== \"string\"\n ) {\n errors.push({\n key: \"compress.externalModel.apiKey\",\n expected: \"string\",\n actual: typeof compress.externalModel.apiKey,\n })\n }\n if (\n compress.externalModel.timeout !== undefined &&\n (typeof compress.externalModel.timeout !== \"number\" ||\n !Number.isFinite(compress.externalModel.timeout) ||\n compress.externalModel.timeout <= 0)\n ) {\n errors.push({\n key: \"compress.externalModel.timeout\",\n expected: \"positive finite number\",\n actual: JSON.stringify(compress.externalModel.timeout),\n })\n }\n if (\n compress.externalModel.retries !== undefined &&\n (!Number.isInteger(compress.externalModel.retries) ||\n compress.externalModel.retries < 0)\n ) {\n errors.push({\n key: \"compress.externalModel.retries\",\n expected: \"non-negative integer\",\n actual: JSON.stringify(compress.externalModel.retries),\n })\n }\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: PluginInput,\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 autoUpdate: true,\n debug: false,\n pruneNotification: \"detailed\",\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 mode: \"range\",\n permission: \"allow\",\n showCompression: false,\n summaryBuffer: true,\n maxContextLimit: \"85%\",\n minContextLimit: \"50%\",\n boundaryNudge: true,\n nudgeFrequency: 2,\n iterationNudgeThreshold: 15,\n nudgeForce: \"strong\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n externalModel: undefined,\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.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.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?: PluginInput): {\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.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.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.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.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 \"$schema\": \"https://raw.githubusercontent.com/LeXwDeX/opencode-dynamic-context-pruning/master/dcp.schema.json\"\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 = jsoncParser.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 mode: override.mode ?? base.mode,\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 boundaryNudge: override.boundaryNudge ?? base.boundaryNudge,\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 externalModel: override.externalModel ?? base.externalModel,\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 externalModel: config.compress.externalModel\n ? { ...config.compress.externalModel }\n : undefined,\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 autoUpdate: data.autoUpdate ?? config.autoUpdate,\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: PluginInput, 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: PluginInput): 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 applyExternalModelEnvOverride(config)\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 type { ExternalModelConfig, PluginConfig } from \"./config\"\n\nexport function applyExternalModelEnvOverride(config: PluginConfig): void {\n const envUrl = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_URL\n const envApiKey = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_KEY\n const envModel = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_MODEL\n const envTimeout = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_TIMEOUT\n const envRetries = process.env.OPENCODE_DCP_EXTERNAL_COMPRESS_RETRIES\n\n if (envUrl && envModel) {\n const externalModel: ExternalModelConfig = {\n url: envUrl,\n model: envModel,\n }\n if (envApiKey) {\n externalModel.apiKey = envApiKey\n }\n if (envTimeout) {\n const parsed = parseInt(envTimeout, 10)\n if (parsed > 0) {\n externalModel.timeout = parsed\n }\n }\n if (envRetries) {\n const parsed = parseInt(envRetries, 10)\n if (parsed >= 0) {\n externalModel.retries = parsed\n }\n }\n config.compress.externalModel = externalModel\n }\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { buildMessageFormatExtension } from \"../prompts/extensions/tool\"\nimport { formatIssues, formatResult, resolveMessages, validateArgs } from \"./message-utils\"\nimport { finalizeSession, prepareSession, type NotificationEntry } from \"./pipeline\"\nimport { appendProtectedPromptInfo, appendProtectedTools } from \"./protected-content\"\nimport {\n allocateBlockId,\n allocateRunId,\n applyCompressionState,\n wrapCompressedSummary,\n} from \"./state\"\nimport type { CompressMessageToolArgs, SearchContext } from \"./types\"\nimport { generateSummaryViaExternal } from \"./external-inference\"\nimport { runWithConcurrency, serializeMessagesForExternalSummary } from \"./external-content\"\n\nfunction buildSchema(externalModelEnabled: boolean) {\n const summaryField = externalModelEnabled\n ? tool.schema\n .string()\n .optional()\n .describe(\n \"Complete technical summary replacing that one message (optional when external model is configured)\",\n )\n : tool.schema.string().describe(\"Complete technical summary replacing that one message\")\n\n return {\n topic: tool.schema\n .string()\n .describe(\n \"Short label (3-5 words) for the overall batch - e.g., 'Closed Research Notes'\",\n ),\n content: tool.schema\n .array(\n tool.schema.object({\n messageId: tool.schema\n .string()\n .describe(\"Raw message ID to compress (e.g. m0001)\"),\n topic: tool.schema\n .string()\n .describe(\"Short label (3-5 words) for this one message summary\"),\n summary: summaryField,\n }),\n )\n .describe(\"Batch of individual message summaries to create in one tool call\"),\n }\n}\n\nexport function createCompressMessageTool(ctx: ToolContext): ReturnType<typeof tool> {\n ctx.prompts.reload()\n const runtimePrompts = ctx.prompts.getRuntimePrompts()\n const externalModelEnabled = ctx.config.compress.externalModel !== undefined\n\n return tool({\n description:\n runtimePrompts.compressMessage + buildMessageFormatExtension(externalModelEnabled),\n args: buildSchema(externalModelEnabled),\n async execute(args, toolCtx) {\n const input = args as CompressMessageToolArgs\n validateArgs(input)\n const callId =\n typeof (toolCtx as unknown as { callID?: unknown }).callID === \"string\"\n ? (toolCtx as unknown as { callID: string }).callID\n : undefined\n\n const { state, rawMessages, searchContext } = await prepareSession(\n ctx,\n toolCtx,\n `Compress Message: ${input.topic}`,\n )\n const { plans, skippedIssues, skippedCount } = resolveMessages(\n input,\n searchContext,\n state,\n ctx.config,\n )\n\n if (plans.length === 0 && skippedCount > 0) {\n throw new Error(formatIssues(skippedIssues, skippedCount))\n }\n\n const externalModel = ctx.config.compress.externalModel\n if (externalModel) {\n await runWithConcurrency(plans, 3, async (plan) => {\n if (plan.entry.summary === undefined) {\n const message = searchContext.rawMessagesById.get(plan.entry.messageId)\n const userContent = serializeMessagesForExternalSummary(\n message ? [message] : [],\n )\n const generated = await generateSummaryViaExternal(externalModel, {\n systemPrompt: runtimePrompts.compressMessage,\n userContent,\n })\n plan.entry.summary = generated\n }\n })\n }\n\n const notifications: NotificationEntry[] = []\n\n const preparedPlans: Array<{\n plan: (typeof plans)[number]\n summaryWithTools: string\n }> = []\n\n for (const plan of plans) {\n if (plan.entry.summary === undefined) {\n throw new Error(\n \"缺少 summary:未配置外部模型,请提供 summary 或配置 OPENCODE_DCP_EXTERNAL_COMPRESS_URL/MODEL\",\n )\n }\n const summaryWithPromptInfo = appendProtectedPromptInfo(\n plan.entry.summary,\n plan.selection,\n searchContext,\n state,\n ctx.config.compress.protectTags,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n state,\n ctx.config.experimental.allowSubAgents,\n summaryWithPromptInfo,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n preparedPlans.push({\n plan,\n summaryWithTools,\n })\n }\n\n const runId = allocateRunId(state)\n\n for (const { plan, summaryWithTools } of preparedPlans) {\n const blockId = allocateBlockId(state)\n const storedSummary = wrapCompressedSummary(blockId, summaryWithTools)\n const summaryTokens = countTokens(storedSummary)\n\n applyCompressionState(\n state,\n {\n topic: plan.entry.topic,\n batchTopic: input.topic,\n startId: plan.entry.messageId,\n endId: plan.entry.messageId,\n mode: \"message\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n plan.selection,\n plan.anchorMessageId,\n blockId,\n storedSummary,\n [],\n )\n\n notifications.push({\n blockId,\n runId,\n summary: summaryWithTools,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, state, toolCtx, rawMessages, notifications, input.topic)\n\n return formatResult(plans.length, skippedIssues, skippedCount)\n },\n })\n}\n","import { SessionState, WithParts } from \"./state\"\nimport { AssistantMessage, UserMessage } from \"@opencode-ai/sdk\"\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 let reportedTokens = 0\n let lastReportedIndex = -1\n\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 lastReportedIndex = i\n break\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 reportedTokens = input + output + reasoning + cacheRead + cacheWrite\n lastReportedIndex = i\n break\n }\n\n let unreportedTokens = 0\n for (let i = lastReportedIndex + 1; i < messages.length; i++) {\n unreportedTokens += countAllMessageTokens(messages[i])\n }\n\n return reportedTokens + unreportedTokens\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} {\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 }\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\n return { providerId, modelId, agent }\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 if (contents.length === 0) return 0\n // Tool-cache synchronization is a hot path and can process hundreds of old\n // results. A byte-based estimate avoids invoking the tokenizer once per tool.\n return Math.ceil(Buffer.byteLength(contents.join(\" \"), \"utf-8\") / 4)\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 { 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.mode === \"message\" &&\n config.compress.protectUserMessages &&\n message.info.role === \"user\" &&\n !isIgnoredUserMessage(message)\n )\n}\n","// 这些格式模式与可编辑的压缩提示分开保存\n// 因此不能通过自定义提示覆盖来修改。这些模式必须\n// 与工具的输入验证匹配,且不能独立更改。\n\nexport function buildRangeFormatExtension(externalModelEnabled: boolean): string {\n const summaryField = externalModelEnabled\n ? `summary?: string // 替换范围内所有内容的完整技术摘要(可省略;外部模型生成)`\n : `summary: string // 替换范围内所有内容的完整技术摘要`\n\n const externalHint = externalModelEnabled\n ? `\\n\\n当启用外部模型压缩时,summary 字段可省略;插件将自动调用外部模型生成。`\n : \"\"\n\n return `\n压缩格式\n\n\\`\\`\\`\n{\n topic: string, // 短标签(3-5 个词)- 例如,\"认证系统探索\"\n content: [ // 一个或多个要压缩的范围\n {\n startId: string, // 范围开始的边界 ID:mNNNN 或 bN\n endId: string, // 范围结束的边界 ID:mNNNN 或 bN\n ${summaryField}\n }\n ]\n}\n\\`\\`\\`\n\n边界 ID 必须从当前可见上下文中已有的注入 ID 精确选取;不要发明 ID,也不要根据顺序外推不存在的 ID。${externalHint}`\n}\n\nexport function buildMessageFormatExtension(externalModelEnabled: boolean): string {\n const summaryField = externalModelEnabled\n ? `summary?: string // 替换该条消息的完整技术摘要(可省略;外部模型生成)`\n : `summary: string // 替换该条消息的完整技术摘要`\n\n const externalHint = externalModelEnabled\n ? `\\n\\n当启用外部模型压缩时,summary 字段可省略;插件将自动调用外部模型生成。`\n : \"\"\n\n return `\n压缩格式\n\n\\`\\`\\`\n{\n topic: string, // 整个批次的短标签(3-5 个词)\n content: [ // 一个或多个要独立压缩的消息\n {\n messageId: string, // 仅原始消息 ID:mNNNN(忽略 priority 等元数据属性)\n topic: string, // 此单条消息摘要的短标签(3-5 个词)\n ${summaryField}\n }\n ]\n}\n\\`\\`\\`${externalHint}`\n}\n\nexport const RANGE_FORMAT_EXTENSION = buildRangeFormatExtension(false)\nexport const MESSAGE_FORMAT_EXTENSION = buildMessageFormatExtension(false)\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 MESSAGE_ID_TAG_NAME = \"dcp-message-id\"\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): string {\n if (\n !Number.isInteger(index) ||\n index < MESSAGE_REF_MIN_INDEX ||\n index > MESSAGE_REF_MAX_INDEX\n ) {\n throw new Error(\n `Message ID index out of bounds: ${index}. Supported range is ${MESSAGE_REF_MIN_INDEX}-${MESSAGE_REF_MAX_INDEX}.`,\n )\n }\n return `m${index.toString().padStart(MESSAGE_REF_WIDTH, \"0\")}`\n}\n\nexport function formatBlockRef(blockId: number): string {\n if (!Number.isInteger(blockId) || blockId < 1) {\n throw new Error(`Invalid block ID: ${blockId}`)\n }\n return `b${blockId}`\n}\n\nexport function parseMessageRef(ref: string): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(MESSAGE_REF_REGEX)\n if (!match) {\n return null\n }\n const index = Number.parseInt(match[1], 10)\n if (!Number.isInteger(index)) {\n return null\n }\n if (index < MESSAGE_REF_MIN_INDEX || index > MESSAGE_REF_MAX_INDEX) {\n return null\n }\n return index\n}\n\nexport function parseBlockRef(ref: string): number | null {\n const normalized = ref.trim().toLowerCase()\n const match = normalized.match(BLOCK_REF_REGEX)\n if (!match) {\n return null\n }\n const id = Number.parseInt(match[1], 10)\n return Number.isInteger(id) ? id : null\n}\n\nexport function parseBoundaryId(id: string): ParsedBoundaryId | null {\n const normalized = id.trim().toLowerCase()\n const messageIndex = parseMessageRef(normalized)\n if (messageIndex !== null) {\n return {\n kind: \"message\",\n ref: formatMessageRef(messageIndex),\n index: messageIndex,\n }\n }\n\n const blockId = parseBlockRef(normalized)\n if (blockId !== null) {\n return {\n kind: \"compressed-block\",\n ref: formatBlockRef(blockId),\n blockId,\n }\n }\n\n return null\n}\n\nfunction escapeXmlAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): string {\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 if (\n state.lastCompaction > 0 &&\n message.info.time.created < state.lastCompaction &&\n !state.messageIds.byRawId.has(rawMessageId)\n ) {\n // Pre-compaction messages may still appear in full session history\n // (e.g. fetched by the compress tool) even though the chat hook's\n // trimmed view no longer shows them. Skip assigning them a fresh\n // ref so they don't get sorted out of order against recent refs.\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 const capacity = MESSAGE_REF_MAX_INDEX - MESSAGE_REF_MIN_INDEX + 1\n const requested = Number.isInteger(state.messageIds.nextRef)\n ? state.messageIds.nextRef\n : MESSAGE_REF_MIN_INDEX\n const start =\n requested >= MESSAGE_REF_MIN_INDEX && requested <= MESSAGE_REF_MAX_INDEX\n ? requested\n : MESSAGE_REF_MIN_INDEX\n\n for (let offset = 0; offset < capacity; offset++) {\n const candidate =\n MESSAGE_REF_MIN_INDEX + ((start - MESSAGE_REF_MIN_INDEX + offset) % capacity)\n const ref = formatMessageRef(candidate)\n if (!state.messageIds.byRef.has(ref)) {\n state.messageIds.nextRef =\n candidate === MESSAGE_REF_MAX_INDEX ? MESSAGE_REF_MIN_INDEX : candidate + 1\n return ref\n }\n }\n\n throw new Error(\n `Message ID alias capacity exceeded. Cannot allocate more than ${formatMessageRef(MESSAGE_REF_MAX_INDEX)} aliases in this session.`,\n )\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport { formatBlockRef, parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { filterMessages } from \"../messages/shape\"\nimport { countAllMessageTokens } from \"../token-utils\"\nimport type { BoundaryReference, SearchContext, SelectionResolution } from \"./types\"\nimport type { OpenCodeClient } from \"../opencode-client\"\n\nexport async function fetchSessionMessages(\n client: OpenCodeClient,\n sessionId: string,\n): 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 startId: string,\n endId: string,\n): { startReference: BoundaryReference; endReference: BoundaryReference } {\n const lookup = buildBoundaryLookup(context, state)\n const issues: string[] = []\n const parsedStartId = parseBoundaryId(startId)\n const parsedEndId = parseBoundaryId(endId)\n const hint = formatAvailableBoundaryHint(lookup)\n const guidance = formatBoundaryUsageGuidance()\n\n if (parsedStartId === null) {\n issues.push(\n `startId is invalid (received ${JSON.stringify(startId)}). Use an injected message ID (mNNNN) or block ID (bN).${hint}${guidance}`,\n )\n }\n\n if (parsedEndId === null) {\n issues.push(\n `endId is invalid (received ${JSON.stringify(endId)}). Use an injected message ID (mNNNN) or block ID (bN).${hint}${guidance}`,\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 || !endReference) {\n if (!startReference) {\n const wasKnown = state.messageIds.byRef.has(parsedStartId.ref)\n const reason = wasKnown\n ? \" (message was likely compacted out of the conversation)\"\n : \" (invalid ID)\"\n issues.push(\n `startId ${parsedStartId.ref} is not available${reason}. Choose an injected ID visible in context.${hint}${guidance}`,\n )\n }\n\n if (!endReference) {\n const wasKnown = state.messageIds.byRef.has(parsedEndId.ref)\n const reason = wasKnown\n ? \" (message was likely compacted out of the conversation)\"\n : \" (invalid ID)\"\n issues.push(\n `endId ${parsedEndId.ref} is not available${reason}. Choose an injected ID visible in context.${hint}${guidance}`,\n )\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 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)) {\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 formatAvailableBoundaryHint(lookup: Map<string, BoundaryReference>): string {\n const allKeys = Array.from(lookup.keys())\n\n const availableBlockRefs = allKeys\n .filter((key) => key.startsWith(\"b\"))\n .sort((a, b) => Number.parseInt(a.slice(1), 10) - Number.parseInt(b.slice(1), 10))\n\n const availableMsgRefs = allKeys\n .filter((key) => key.startsWith(\"m\"))\n .sort((a, b) => Number.parseInt(a.slice(1), 10) - Number.parseInt(b.slice(1), 10))\n\n const blockHint = availableBlockRefs.length\n ? ` Available block IDs: ${availableBlockRefs.join(\", \")}.`\n : \" No block IDs available.\"\n\n const msgHint =\n availableMsgRefs.length === 0\n ? \" No message IDs available.\"\n : availableMsgRefs.length <= 10\n ? ` Available message IDs: ${availableMsgRefs.join(\", \")}.`\n : ` Available message IDs: ${availableMsgRefs[0]} to ${availableMsgRefs[availableMsgRefs.length - 1]} (${availableMsgRefs.length} total).`\n\n return `${msgHint}${blockHint}`\n}\n\nfunction formatBoundaryUsageGuidance(): string {\n return \" Use exactly one of the listed injected IDs. For already compressed content, use its bN block ID.\"\n}\n\nfunction buildBoundaryLookup(\n context: SearchContext,\n state: SessionState,\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)) {\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)\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 // Fallback: include inactive blocks whose anchor still exists in the conversation\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (block.active) {\n continue // already handled above\n }\n const blockRef = formatBlockRef(blockId)\n if (lookup.has(blockRef)) {\n continue // already in lookup (shouldn't happen for inactive, but safer)\n }\n const anchorMessage = context.rawMessagesById.get(block.anchorMessageId)\n if (!anchorMessage) {\n continue // anchor gone — block is truly orphaned\n }\n if (isIgnoredUserMessage(anchorMessage)) {\n continue\n }\n const rawIndex = context.rawIndexById.get(block.anchorMessageId)\n if (rawIndex === undefined) {\n continue\n }\n lookup.set(blockRef, {\n kind: \"compressed-block\",\n rawIndex,\n blockId: block.blockId,\n anchorMessageId: block.anchorMessageId,\n })\n }\n\n return lookup\n}\n","import type { CompressionBlock, PruneMessagesState, SessionState } from \"../state\"\nimport { formatBlockRef, formatMessageIdTag } 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(blockId: number, summary: string): string {\n const header = COMPRESSED_BLOCK_HEADER\n const footer = formatMessageIdTag(formatBlockRef(blockId))\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 { PluginConfig } from \"../config\"\nimport type { SessionState } from \"../state\"\nimport { parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../messages/query\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport { COMPRESSED_BLOCK_HEADER } from \"./state\"\nimport type {\n CompressMessageEntry,\n CompressMessageToolArgs,\n ResolvedMessageCompression,\n ResolvedMessageCompressionsResult,\n SearchContext,\n} from \"./types\"\n\ninterface SkippedIssue {\n kind: string\n messageId: string\n}\n\nclass SoftIssue extends Error {\n constructor(\n public readonly kind: string,\n public readonly messageId: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport function validateArgs(args: CompressMessageToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.messageId !== \"string\" || entry.messageId.trim().length === 0) {\n throw new Error(`${prefix}.messageId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.topic !== \"string\" || entry.topic.trim().length === 0) {\n throw new Error(`${prefix}.topic is required and must be a non-empty string`)\n }\n\n if (entry?.summary !== undefined) {\n if (typeof entry.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary must be a non-empty string when provided`)\n }\n }\n }\n}\n\nexport function formatResult(\n processedCount: number,\n skippedIssues: string[],\n skippedCount: number,\n): string {\n const messageNoun = processedCount === 1 ? \"message\" : \"messages\"\n const processedText =\n processedCount > 0\n ? `Compressed ${processedCount} ${messageNoun} into ${COMPRESSED_BLOCK_HEADER}.`\n : \"Compressed 0 messages.\"\n\n if (skippedCount === 0) {\n return processedText\n }\n\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `${processedText}\\nSkipped ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nexport function formatIssues(skippedIssues: string[], skippedCount: number): string {\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `Unable to compress any messages. Found ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nconst ISSUE_TEMPLATES: Record<string, [singular: string, plural: string]> = {\n blocked: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"invalid-format\": [\n \"is invalid. Use an injected raw message ID of the form mNNNN.\",\n \"are invalid. Use injected raw message IDs of the form mNNNN.\",\n ],\n \"block-id\": [\n \"is invalid here. Block IDs like bN are not allowed; use an mNNNN message ID instead.\",\n \"are invalid here. Block IDs like bN are not allowed; use mNNNN message IDs instead.\",\n ],\n \"not-in-context\": [\n \"is not available in the current conversation context. Choose an injected mNNNN ID visible in context.\",\n \"are not available in the current conversation context. Choose injected mNNNN IDs visible in context.\",\n ],\n protected: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"already-compressed\": [\n \"is already part of an active compression.\",\n \"are already part of active compressions.\",\n ],\n duplicate: [\n \"was selected more than once in this batch.\",\n \"were each selected more than once in this batch.\",\n ],\n}\n\nfunction formatSkippedGroup(kind: string, messageIds: string[]): string {\n const templates = ISSUE_TEMPLATES[kind]\n const ids = messageIds.join(\", \")\n const single = messageIds.length === 1\n const prefix = single ? \"messageId\" : \"messageIds\"\n\n if (!templates) {\n return `${prefix} ${ids}: unknown issue.`\n }\n\n return `${prefix} ${ids} ${single ? templates[0] : templates[1]}`\n}\n\nfunction groupSkippedIssues(issues: SkippedIssue[]): string[] {\n const groups = new Map<string, string[]>()\n const order: string[] = []\n\n for (const issue of issues) {\n let ids = groups.get(issue.kind)\n if (!ids) {\n ids = []\n groups.set(issue.kind, ids)\n order.push(issue.kind)\n }\n ids.push(issue.messageId)\n }\n\n return order.map((kind) => {\n const ids = groups.get(kind)!\n return formatSkippedGroup(kind, ids)\n })\n}\n\nexport function resolveMessages(\n args: CompressMessageToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompressionsResult {\n const issues: SkippedIssue[] = []\n const plans: ResolvedMessageCompression[] = []\n const seenMessageIds = new Set<string>()\n\n for (const entry of args.content) {\n const normalizedMessageId = entry.messageId.trim()\n if (seenMessageIds.has(normalizedMessageId)) {\n issues.push({ kind: \"duplicate\", messageId: normalizedMessageId })\n continue\n }\n\n try {\n const plan = resolveMessage(\n {\n ...entry,\n messageId: normalizedMessageId,\n },\n searchContext,\n state,\n config,\n )\n seenMessageIds.add(plan.entry.messageId)\n plans.push(plan)\n } catch (error: any) {\n if (error instanceof SoftIssue) {\n issues.push({ kind: error.kind, messageId: error.messageId })\n continue\n }\n\n throw error\n }\n }\n\n return {\n plans,\n skippedIssues: groupSkippedIssues(issues),\n skippedCount: issues.length,\n }\n}\n\nfunction resolveMessage(\n entry: CompressMessageEntry,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompression {\n if (entry.messageId.toUpperCase() === \"BLOCKED\") {\n throw new SoftIssue(\"blocked\", \"BLOCKED\", \"protected message\")\n }\n\n const parsed = parseBoundaryId(entry.messageId)\n\n if (!parsed) {\n throw new SoftIssue(\"invalid-format\", entry.messageId, \"invalid format\")\n }\n\n if (parsed.kind === \"compressed-block\") {\n throw new SoftIssue(\"block-id\", entry.messageId, \"block ID used\")\n }\n\n const messageId = state.messageIds.byRef.get(parsed.ref)\n const rawMessage = messageId ? searchContext.rawMessagesById.get(messageId) : undefined\n if (\n !messageId ||\n !rawMessage ||\n !searchContext.rawIndexById.has(messageId) ||\n isIgnoredUserMessage(rawMessage)\n ) {\n throw new SoftIssue(\"not-in-context\", parsed.ref, \"not in context\")\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n parsed.ref,\n parsed.ref,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n if (isProtectedUserMessage(config, rawMessage)) {\n throw new SoftIssue(\"protected\", parsed.ref, \"protected message\")\n }\n\n const pruneEntry = state.prune.messages.byMessageId.get(messageId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n throw new SoftIssue(\"already-compressed\", parsed.ref, \"already compressed\")\n }\n\n return {\n entry: {\n messageId: parsed.ref,\n topic: entry.topic,\n summary: entry.summary,\n },\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\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 { randomUUID } from \"crypto\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { serializePruneMessagesState } from \"./utils\"\nimport { runWithConcurrency } from \"../concurrency\"\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 boundaryPending?: boolean\n}\n\nexport interface PersistedMessageIdState {\n byRawId: Record<string, string>\n byRef: Record<string, string>\n nextRef: number\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n manualMode?: boolean\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n lastCompaction?: number\n messageIds?: PersistedMessageIdState\n}\n\nconst saveQueues = new Map<string, Promise<void>>()\n\nfunction getStorageDir(): string {\n return join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n )\n}\n\nasync function ensureStorageDir(): Promise<void> {\n const storageDir = getStorageDir()\n if (!existsSync(storageDir)) {\n await fs.mkdir(storageDir, { recursive: true })\n }\n}\n\nfunction getSessionFilePath(sessionId: string): string {\n return join(getStorageDir(), `${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 temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`\n const content = JSON.stringify(state, null, 2)\n try {\n await fs.writeFile(temporaryPath, content, \"utf-8\")\n await fs.rename(temporaryPath, filePath)\n } catch (error) {\n await fs.unlink(temporaryPath).catch(() => undefined)\n throw error\n }\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 if (!sessionState.sessionId) {\n return\n }\n\n const sessionId = sessionState.sessionId\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 boundaryPending: sessionState.nudges.boundaryPending === true,\n },\n stats: { ...sessionState.stats },\n lastUpdated: new Date().toISOString(),\n lastCompaction: sessionState.lastCompaction,\n messageIds: {\n byRawId: Object.fromEntries(sessionState.messageIds.byRawId),\n byRef: Object.fromEntries(sessionState.messageIds.byRef),\n nextRef: sessionState.messageIds.nextRef,\n },\n }\n const previous = saveQueues.get(sessionId) ?? Promise.resolve()\n const current = previous\n .catch(() => undefined)\n .then(() => writePersistedSessionState(sessionId, state, logger))\n saveQueues.set(sessionId, current)\n\n try {\n await current\n } catch (error: any) {\n logger.error(\"Failed to save session state\", {\n sessionId,\n error: error?.message,\n })\n throw error\n } finally {\n if (saveQueues.get(sessionId) === current) {\n saveQueues.delete(sessionId)\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 state.nudges.boundaryPending = state.nudges.boundaryPending === true\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\nexport interface AggregatedStats {\n totalTokens: number\n totalTools: number\n totalMessages: number\n sessionCount: number\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 }\n\n try {\n const storageDir = getStorageDir()\n if (!existsSync(storageDir)) {\n return result\n }\n\n const files = await fs.readdir(storageDir)\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"))\n\n await runWithConcurrency(jsonFiles, 16, async (file) => {\n try {\n const filePath = join(storageDir, file)\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n if (state?.stats?.totalPruneTokens && state?.prune) {\n result.totalTokens += state.stats.totalPruneTokens\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.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","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\"\nimport type { OpenCodeClient } from \"../opencode-client\"\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(\n client: OpenCodeClient,\n sessionID: string,\n): 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 === \"range\" || block.mode === \"message\" ? block.mode : 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\nconst MAX_SUBAGENT_CACHE_ENTRIES = 64\nconst MAX_SUBAGENT_CACHE_CHARS = 500_000\nconst MAX_SUBAGENT_CACHE_TOTAL_CHARS = 2_000_000\n\nexport function getCachedSubAgentResult(state: SessionState, callId: string): string | undefined {\n const cached = state.subAgentResultCache.get(callId)\n if (cached === undefined) return undefined\n state.subAgentResultCache.delete(callId)\n state.subAgentResultCache.set(callId, cached)\n return cached\n}\n\nexport function cacheSubAgentResult(state: SessionState, callId: string, result: string): string {\n const cached =\n result.length <= MAX_SUBAGENT_CACHE_CHARS\n ? result\n : result.slice(0, MAX_SUBAGENT_CACHE_CHARS) + \"\\n[子代理结果因长度限制被截断]\"\n state.subAgentResultCache.delete(callId)\n state.subAgentResultCache.set(callId, cached)\n\n let totalChars = Array.from(state.subAgentResultCache.values()).reduce(\n (total, value) => total + value.length,\n 0,\n )\n while (\n state.subAgentResultCache.size > MAX_SUBAGENT_CACHE_ENTRIES ||\n totalChars > MAX_SUBAGENT_CACHE_TOTAL_CHARS\n ) {\n const oldest = state.subAgentResultCache.keys().next().value\n if (typeof oldest !== \"string\") break\n totalChars -= state.subAgentResultCache.get(oldest)?.length ?? 0\n state.subAgentResultCache.delete(oldest)\n }\n return cached\n}\n\nexport function resetOnCompaction(state: SessionState, messages: WithParts[] = []): void {\n state.toolParameters.clear()\n\n if (messages.length === 0) {\n return\n }\n\n const liveMessageIds = new Set(messages.map((msg) => msg.info.id))\n const liveToolIds = new Set(\n messages.flatMap((message) =>\n message.parts.flatMap((part) =>\n part.type === \"tool\" && part.callID ? [part.callID] : [],\n ),\n ),\n )\n\n for (const [ref, rawId] of state.messageIds.byRef) {\n if (!liveMessageIds.has(rawId)) {\n state.messageIds.byRef.delete(ref)\n state.messageIds.byRawId.delete(rawId)\n }\n }\n for (const callId of state.subAgentResultCache.keys()) {\n if (!liveToolIds.has(callId)) state.subAgentResultCache.delete(callId)\n }\n\n const anchorSets = [\n state.nudges.contextLimitAnchors,\n state.nudges.turnNudgeAnchors,\n state.nudges.iterationNudgeAnchors,\n ]\n for (const anchorSet of anchorSets) {\n for (const anchorId of anchorSet) {\n if (!liveMessageIds.has(anchorId)) {\n anchorSet.delete(anchorId)\n }\n }\n }\n}\n","export async function runWithConcurrency<T>(\n items: T[],\n concurrency: number,\n task: (item: T) => Promise<void>,\n): Promise<void> {\n let nextIndex = 0\n const workerCount = Math.min(items.length, Math.max(1, Math.floor(concurrency)))\n const workers = Array.from({ length: workerCount }, async () => {\n for (;;) {\n const index = nextIndex++\n if (index >= items.length) return\n await task(items[index])\n }\n })\n await Promise.all(workers)\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 recordedAtByCallId: Map<string, number>\n}\n\nconst MAX_TIMING_ENTRIES = 2048\nconst TIMING_TTL_MS = 30 * 60 * 1000\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 state.compressionTiming.recordedAtByCallId.delete(key)\n return start\n}\n\nexport function pruneCompressionTiming(state: SessionState, now = Date.now()): void {\n const timing = state.compressionTiming\n const cutoff = now - TIMING_TTL_MS\n for (const [key, recordedAt] of timing.recordedAtByCallId) {\n if (recordedAt >= cutoff) continue\n timing.recordedAtByCallId.delete(key)\n timing.startsByCallId.delete(key)\n timing.pendingByCallId.delete(key)\n }\n\n while (timing.recordedAtByCallId.size > MAX_TIMING_ENTRIES) {\n const oldest = timing.recordedAtByCallId.keys().next().value\n if (typeof oldest !== \"string\") break\n timing.recordedAtByCallId.delete(oldest)\n timing.startsByCallId.delete(oldest)\n timing.pendingByCallId.delete(oldest)\n }\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 state.compressionTiming.recordedAtByCallId.delete(key)\n }\n }\n\n return updates\n}\n","import type { CompressionTimingState } from \"../compress/timing\"\nimport type { SessionState, WithParts } from \"./types\"\n\nconst MAX_RESIDENT_SESSIONS = 64\nconst MAX_MESSAGE_OWNERS = 20_000\nconst MAX_TIMING_ENTRIES = 2048\nconst TIMING_TTL_MS = 30 * 60 * 1000\n\ninterface TimedStart {\n startedAt: number\n recordedAt: number\n}\n\ninterface TimedPending {\n messageId: string\n callId: string\n durationMs: number\n recordedAt: number\n}\n\n/**\n * Keeps mutable plugin state isolated per OpenCode session.\n *\n * OpenCode creates one plugin instance per workspace, not per chat session. Every\n * hook must therefore resolve its own SessionState through this store.\n */\nexport class SessionStateStore {\n private readonly states = new Map<string, SessionState>()\n private readonly initializationQueues = new Map<string, Promise<void>>()\n private readonly messageOwners = new Map<string, string>()\n private readonly orphanStarts = new Map<string, TimedStart>()\n private readonly orphanPending = new Map<string, TimedPending>()\n\n constructor(private readonly createState: () => SessionState) {}\n\n get(sessionId: string): SessionState {\n const existing = this.states.get(sessionId)\n if (existing) {\n this.touch(sessionId, existing)\n return existing\n }\n\n const state = this.createState()\n this.states.set(sessionId, state)\n this.trimSessions()\n return state\n }\n\n peek(sessionId: string): SessionState | undefined {\n return this.states.get(sessionId)\n }\n\n forEach(callback: (state: SessionState, sessionId: string) => void): void {\n for (const [sessionId, state] of this.states) {\n callback(state, sessionId)\n }\n }\n\n async initialize(\n sessionId: string,\n initializer: (state: SessionState) => Promise<void>,\n ): Promise<SessionState> {\n const state = this.get(sessionId)\n const previous = this.initializationQueues.get(sessionId) ?? Promise.resolve()\n const current = previous.catch(() => undefined).then(() => initializer(state))\n this.initializationQueues.set(sessionId, current)\n\n try {\n await current\n } finally {\n if (this.initializationQueues.get(sessionId) === current) {\n this.initializationQueues.delete(sessionId)\n }\n }\n\n return state\n }\n\n registerMessages(sessionId: string, messages: WithParts[]): SessionState {\n const state = this.get(sessionId)\n for (const message of messages) {\n const messageId = message.info?.id\n if (typeof messageId !== \"string\") continue\n this.messageOwners.delete(messageId)\n this.messageOwners.set(messageId, sessionId)\n this.moveOrphanTiming(messageId, state.compressionTiming)\n }\n while (this.messageOwners.size > MAX_MESSAGE_OWNERS) {\n const oldest = this.messageOwners.keys().next().value\n if (typeof oldest !== \"string\") break\n this.messageOwners.delete(oldest)\n }\n return state\n }\n\n resolveEventState(sessionId: string | undefined, messageId: string): SessionState | undefined {\n const resolvedSessionId = sessionId ?? this.messageOwners.get(messageId)\n if (!resolvedSessionId) return undefined\n this.messageOwners.set(messageId, resolvedSessionId)\n return this.get(resolvedSessionId)\n }\n\n recordOrphanStart(key: string, startedAt: number): void {\n this.pruneOrphanTiming()\n if (this.orphanStarts.has(key)) return\n this.orphanStarts.set(key, { startedAt, recordedAt: Date.now() })\n this.trimMap(this.orphanStarts)\n }\n\n consumeOrphanStart(key: string): number | undefined {\n const entry = this.orphanStarts.get(key)\n this.orphanStarts.delete(key)\n return entry?.startedAt\n }\n\n recordOrphanPending(\n key: string,\n entry: { messageId: string; callId: string; durationMs: number },\n ): void {\n this.pruneOrphanTiming()\n this.orphanPending.set(key, { ...entry, recordedAt: Date.now() })\n this.trimMap(this.orphanPending)\n }\n\n deleteOrphanStart(key: string): void {\n this.orphanStarts.delete(key)\n }\n\n private moveOrphanTiming(messageId: string, timing: CompressionTimingState): void {\n const prefix = `${messageId}:`\n for (const [key, entry] of this.orphanStarts) {\n if (!key.startsWith(prefix)) continue\n if (!timing.startsByCallId.has(key)) {\n timing.startsByCallId.set(key, entry.startedAt)\n }\n timing.recordedAtByCallId.set(key, entry.recordedAt)\n this.orphanStarts.delete(key)\n }\n for (const [key, entry] of this.orphanPending) {\n if (!key.startsWith(prefix)) continue\n timing.pendingByCallId.set(key, {\n messageId: entry.messageId,\n callId: entry.callId,\n durationMs: entry.durationMs,\n })\n timing.recordedAtByCallId.set(key, entry.recordedAt)\n this.orphanPending.delete(key)\n }\n }\n\n private touch(sessionId: string, state: SessionState): void {\n this.states.delete(sessionId)\n this.states.set(sessionId, state)\n }\n\n private trimSessions(): void {\n while (this.states.size > MAX_RESIDENT_SESSIONS) {\n const oldest = Array.from(this.states.keys()).find(\n (sessionId) => !this.initializationQueues.has(sessionId),\n )\n if (!oldest) return\n this.states.delete(oldest)\n for (const [messageId, owner] of this.messageOwners) {\n if (owner === oldest) this.messageOwners.delete(messageId)\n }\n }\n }\n\n private pruneOrphanTiming(): void {\n const cutoff = Date.now() - TIMING_TTL_MS\n for (const [key, entry] of this.orphanStarts) {\n if (entry.recordedAt < cutoff) this.orphanStarts.delete(key)\n }\n for (const [key, entry] of this.orphanPending) {\n if (entry.recordedAt < cutoff) this.orphanPending.delete(key)\n }\n }\n\n private trimMap<T>(map: Map<string, T>): void {\n while (map.size > MAX_TIMING_ENTRIES) {\n const oldest = map.keys().next().value\n if (typeof oldest !== \"string\") return\n map.delete(oldest)\n }\n }\n}\n\nexport type SessionStateTarget = SessionState | SessionStateStore\n\nexport function resolveSessionState(target: SessionStateTarget, sessionId: string): SessionState {\n return target instanceof SessionStateStore ? target.get(sessionId) : target\n}\n","import type { SessionState, ToolParameterEntry, WithParts } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { applyPendingCompressionDurations } from \"../compress/timing\"\nimport { 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 { SessionStateStore, type SessionStateTarget, resolveSessionState } from \"./store\"\nimport type { OpenCodeClient } from \"../opencode-client\"\n\nexport const checkSession = async (\n client: OpenCodeClient,\n target: SessionStateTarget,\n logger: Logger,\n messages: WithParts[],\n manualModeDefault: boolean,\n): Promise<SessionState | undefined> => {\n const lastUserMessage = getLastUserMessage(messages)\n const lastSessionId =\n lastUserMessage?.info.sessionID ??\n messages.findLast((message) => typeof message.info?.sessionID === \"string\")?.info.sessionID\n if (!lastSessionId) return target instanceof SessionStateStore ? undefined : target\n const state =\n target instanceof SessionStateStore\n ? target.registerMessages(lastSessionId, messages)\n : resolveSessionState(target, lastSessionId)\n\n if (state.sessionId === null || state.sessionId !== lastSessionId) {\n logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`)\n try {\n await initializeSessionState(\n client,\n target,\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, messages)\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 return state\n}\n\nexport function createSessionState(): SessionState {\n return {\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 boundaryPending: false,\n },\n stats: {\n pruneTokenCounter: 0,\n totalPruneTokens: 0,\n },\n compressionTiming: {\n startsByCallId: new Map<string, number>(),\n pendingByCallId: new Map(),\n recordedAtByCallId: new Map<string, number>(),\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 const modelContextLimit = state.modelContextLimit\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 boundaryPending: false,\n }\n state.stats = {\n pruneTokenCounter: 0,\n totalPruneTokens: 0,\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 = modelContextLimit\n state.systemPromptTokens = undefined\n}\n\nexport async function initializeSessionState(\n client: OpenCodeClient,\n target: SessionStateTarget,\n sessionId: string,\n logger: Logger,\n messages: WithParts[],\n manualModeEnabled: boolean,\n): Promise<SessionState> {\n if (target instanceof SessionStateStore) {\n target.registerMessages(sessionId, messages)\n return target.initialize(sessionId, (state) =>\n ensureSessionInitialized(client, state, sessionId, logger, messages, manualModeEnabled),\n )\n }\n\n await ensureSessionInitialized(client, target, sessionId, logger, messages, manualModeEnabled)\n return target\n}\n\nexport async function ensureSessionInitialized(\n client: OpenCodeClient,\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.nudges.boundaryPending = persisted.nudges.boundaryPending === true\n state.stats = {\n pruneTokenCounter: persisted.stats?.pruneTokenCounter || 0,\n totalPruneTokens: persisted.stats?.totalPruneTokens || 0,\n }\n\n if (typeof persisted.lastCompaction === \"number\") {\n state.lastCompaction = Math.max(state.lastCompaction, persisted.lastCompaction)\n }\n if (persisted.messageIds && typeof persisted.messageIds === \"object\") {\n state.messageIds = {\n byRawId: new Map<string, string>(\n Object.entries(persisted.messageIds.byRawId || {}).filter(\n (e): e is [string, string] => typeof e[1] === \"string\",\n ),\n ),\n byRef: new Map<string, string>(\n Object.entries(persisted.messageIds.byRef || {}).filter(\n (e): e is [string, string] => typeof e[1] === \"string\",\n ),\n ),\n nextRef:\n typeof persisted.messageIds.nextRef === \"number\" &&\n persisted.messageIds.nextRef >= 1\n ? persisted.messageIds.nextRef\n : 1,\n }\n }\n\n const applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\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 const candidates = new Map<\n string,\n { part: Extract<WithParts[\"parts\"][number], { type: \"tool\" }>; turn: number }\n >()\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 candidates.delete(part.callID)\n candidates.set(part.callID, { part, turn: turnCounter })\n }\n }\n\n const recentCandidates = Array.from(candidates.entries())\n .filter(([, candidate]) => {\n const turnProtectionEnabled = config.turnProtection.enabled\n const turnProtectionTurns = config.turnProtection.turns\n return !(\n turnProtectionEnabled &&\n turnProtectionTurns > 0 &&\n state.currentTurn - candidate.turn < turnProtectionTurns\n )\n })\n .slice(-MAX_TOOL_CACHE_SIZE)\n const retainedIds = new Set(recentCandidates.map(([callId]) => callId))\n\n for (const callId of state.toolParameters.keys()) {\n if (!retainedIds.has(callId)) state.toolParameters.delete(callId)\n }\n\n for (const [callId, { part, turn }] of recentCandidates) {\n const status = part.state.status as ToolStatus | undefined\n const cached = state.toolParameters.get(callId)\n if (cached?.status === status) continue\n\n const tokenCount = countToolTokens(part)\n state.toolParameters.set(callId, {\n tool: part.tool,\n parameters: part.state?.input ?? {},\n status,\n error: part.state.status === \"error\" ? part.state.error : undefined,\n turn,\n tokenCount,\n })\n if (!cached) {\n logger.info(\n `Cached tool id: ${callId} (turn ${turn}${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","function normalizePath(input: string): string {\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\" && 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 // 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","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 // Errors and in-flight calls are not interchangeable with successful results.\n // Let purgeErrors handle failures according to its own turn policy.\n if (\n metadata.status !== undefined &&\n metadata.status !== \"completed\" &&\n (metadata.status as string) !== \"success\"\n ) {\n continue\n }\n\n // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\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 successful 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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} 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 // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\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 { OpenCodeClient } from \"../opencode-client\"\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: OpenCodeClient,\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: OpenCodeClient,\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: OpenCodeClient,\n sessionID: string,\n text: string,\n params: any,\n logger: Logger,\n): Promise<void> {\n const agent = params.agent || 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 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 { SessionState, WithParts } from \"../state\"\nimport { initializeSessionState, resolveSessionState } 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 state: SessionState\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 const state = resolveSessionState(ctx.state, toolCtx.sessionID)\n toolCtx.metadata({ title })\n\n const rawMessages = await fetchSessionMessages(ctx.client, toolCtx.sessionID)\n\n await initializeSessionState(\n ctx.client,\n ctx.state,\n toolCtx.sessionID,\n ctx.logger,\n rawMessages,\n ctx.config.manualMode.enabled,\n )\n\n if (state.manualMode && 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 assignMessageRefs(state, rawMessages)\n\n deduplicate(state, ctx.logger, ctx.config, rawMessages)\n purgeErrors(state, ctx.logger, ctx.config, rawMessages)\n\n return {\n state,\n rawMessages,\n searchContext: buildSearchContext(state, rawMessages),\n }\n}\n\nexport async function finalizeSession(\n ctx: ToolContext,\n state: SessionState,\n toolCtx: RunContext,\n rawMessages: WithParts[],\n entries: NotificationEntry[],\n batchTopic: string | undefined,\n): Promise<void> {\n state.manualMode = state.manualMode ? \"active\" : false\n applyPendingCompressionDurations(state)\n await saveSessionState(state, ctx.logger)\n\n const params = getCurrentParams(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 state,\n toolCtx.sessionID,\n entries,\n batchTopic,\n sessionMessageIds,\n params,\n )\n}\n","import type { WithParts } from \"../state\"\n\nconst SUB_AGENT_RESULT_BLOCK_REGEX = /(<task_result>\\s*)([\\s\\S]*?)(\\s*<\\/task_result>)/i\n\nexport function getSubAgentId(part: any): string | null {\n const 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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../subagents/subagent-results\"\nimport { cacheSubAgentResult, getCachedSubAgentResult } from \"../state/utils\"\nimport { fetchSessionMessages } from \"./search\"\nimport type { SearchContext, SelectionResolution } from \"./types\"\nimport type { OpenCodeClient } from \"../opencode-client\"\n\nexport function appendProtectedUserMessages(\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 userTexts: 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\" && part.text.trim()) {\n userTexts.push(part.text)\n break\n }\n }\n }\n\n if (userTexts.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following user messages were sent in this conversation verbatim:\"\n const body = userTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\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: OpenCodeClient,\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 let isToolProtected = isToolNameProtected(part.tool, protectedTools)\n\n if (!isToolProtected && protectedFilePatterns.length > 0) {\n const filePaths = getFilePathsFromParameters(part.tool, part.state?.input)\n if (isFilePathProtected(filePaths, protectedFilePatterns)) {\n isToolProtected = true\n }\n }\n\n if (isToolProtected) {\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\" &&\n part.state?.status === \"completed\" &&\n typeof part.state?.output === \"string\"\n ) {\n const cachedSubAgentResult = getCachedSubAgentResult(state, 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 subAgentResultText = cacheSubAgentResult(\n state,\n part.callID,\n subAgentResultText,\n )\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 { ExternalModelConfig } from \"../config\"\n\nexport type { ExternalModelConfig }\n\nexport interface ExternalSummaryRequest {\n systemPrompt: string\n userContent: string\n}\n\nexport type ExternalModelErrorKind = \"network\" | \"http\" | \"parse\" | \"empty\" | \"timeout\"\n\nexport class ExternalModelError extends Error {\n constructor(\n message: string,\n public readonly kind: ExternalModelErrorKind,\n public readonly cause?: unknown,\n ) {\n super(message)\n this.name = \"ExternalModelError\"\n }\n}\n\nexport function resolveCompressBaseUrl(url: string): string {\n const normalized = url.replace(/\\/$/, \"\")\n if (normalized.endsWith(\"/chat/completions\")) {\n return normalized\n }\n return `${normalized}/chat/completions`\n}\n\nasync function callExternalModel(\n endpoint: string,\n cfg: ExternalModelConfig,\n req: ExternalSummaryRequest,\n): Promise<string> {\n const controller = new AbortController()\n const timeoutMs = cfg.timeout ?? 120000\n const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs)\n\n let response: Response\n try {\n response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(cfg.apiKey ? { Authorization: `Bearer ${cfg.apiKey}` } : {}),\n },\n body: JSON.stringify({\n model: cfg.model,\n messages: [\n { role: \"system\", content: req.systemPrompt },\n { role: \"user\", content: req.userContent },\n ],\n temperature: 0,\n }),\n signal: controller.signal,\n })\n } catch (error: unknown) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new ExternalModelError(\n `External model request timed out after ${timeoutMs}ms`,\n \"timeout\",\n error,\n )\n }\n throw new ExternalModelError(\n `External model request failed: ${error instanceof Error ? error.message : String(error)}`,\n \"network\",\n error,\n )\n } finally {\n clearTimeout(timeoutHandle)\n }\n\n if (!response.ok) {\n let errorBody = \"\"\n try {\n errorBody = await response.text()\n } catch {}\n throw new ExternalModelError(\n `External model returned HTTP ${response.status}: ${errorBody.slice(0, 200)}`,\n \"http\",\n { status: response.status, body: errorBody },\n )\n }\n\n let parsed: any\n try {\n parsed = await response.json()\n } catch (error) {\n throw new ExternalModelError(\"External model returned invalid JSON\", \"parse\", error)\n }\n\n const content = parsed?.choices?.[0]?.message?.content\n if (typeof content !== \"string\" || content.trim().length === 0) {\n throw new ExternalModelError(\n \"External model returned empty or missing summary content\",\n \"empty\",\n parsed,\n )\n }\n\n return content\n}\n\nexport async function generateSummaryViaExternal(\n cfg: ExternalModelConfig,\n req: ExternalSummaryRequest,\n): Promise<string> {\n if (typeof cfg.url !== \"string\" || cfg.url.trim().length === 0) {\n throw new Error(\"外部压缩模型 url 必须是非空字符串\")\n }\n if (typeof cfg.model !== \"string\" || cfg.model.trim().length === 0) {\n throw new Error(\"外部压缩模型 model 必须是非空字符串\")\n }\n if (cfg.apiKey !== undefined && typeof cfg.apiKey !== \"string\") {\n throw new Error(\"外部压缩模型 apiKey 必须是字符串\")\n }\n if (cfg.timeout !== undefined && (!Number.isFinite(cfg.timeout) || cfg.timeout <= 0)) {\n throw new Error(\"外部压缩模型 timeout 必须是正数\")\n }\n if (cfg.retries !== undefined && (!Number.isInteger(cfg.retries) || cfg.retries < 0)) {\n throw new Error(\"外部压缩模型 retries 必须是非负整数\")\n }\n const endpoint = resolveCompressBaseUrl(cfg.url)\n const maxRetries = cfg.retries ?? 1\n\n let lastError: unknown\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await callExternalModel(endpoint, cfg, req)\n } catch (error) {\n lastError = error\n }\n }\n\n throw lastError\n}\n","import type { WithParts } from \"../state\"\nexport { runWithConcurrency } from \"../concurrency\"\n\nconst MAX_PART_CHARS = 100_000\nconst MAX_TOTAL_CHARS = 1_000_000\nconst TRUNCATED_MARKER = \"\\n[内容因长度限制被截断]\"\n\nfunction stringify(value: unknown): string {\n if (typeof value === \"string\") return value\n try {\n return JSON.stringify(value, null, 2) ?? String(value)\n } catch {\n return String(value)\n }\n}\n\nfunction truncate(value: string, limit = MAX_PART_CHARS): string {\n if (value.length <= limit) return value\n return value.slice(0, limit) + TRUNCATED_MARKER\n}\n\nfunction serializePart(part: WithParts[\"parts\"][number]): string[] {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n return [truncate(part.text)]\n }\n if (part.type !== \"tool\") return []\n\n const chunks = [`[工具:${part.tool};状态:${part.state.status}]`]\n if (part.state.input !== undefined) {\n chunks.push(\"输入:\\n\" + truncate(stringify(part.state.input)))\n }\n if (part.state.status === \"completed\" && part.state.output !== undefined) {\n chunks.push(\"输出:\\n\" + truncate(stringify(part.state.output)))\n } else if (part.state.status === \"error\" && part.state.error !== undefined) {\n chunks.push(\"错误:\\n\" + truncate(stringify(part.state.error)))\n }\n return chunks\n}\n\nexport function serializeMessagesForExternalSummary(messages: WithParts[]): string {\n const chunks: string[] = []\n let length = 0\n\n for (const message of messages) {\n const header = `[消息:${message.info.id};角色:${message.info.role}]`\n const content = [header, ...message.parts.flatMap(serializePart)].join(\"\\n\")\n if (length + content.length > MAX_TOTAL_CHARS) {\n const remaining = Math.max(0, MAX_TOTAL_CHARS - length)\n if (remaining > 0) chunks.push(content.slice(0, remaining))\n chunks.push(TRUNCATED_MARKER.trim())\n break\n }\n chunks.push(content)\n length += content.length\n }\n\n return chunks.join(\"\\n\\n\")\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { buildRangeFormatExtension } from \"../prompts/extensions/tool\"\nimport { finalizeSession, prepareSession, type NotificationEntry } from \"./pipeline\"\nimport {\n appendProtectedPromptInfo,\n appendProtectedTools,\n appendProtectedUserMessages,\n} from \"./protected-content\"\nimport {\n appendMissingBlockSummaries,\n injectBlockPlaceholders,\n parseBlockPlaceholders,\n resolveRanges,\n validateArgs,\n validateNonOverlapping,\n validateSummaryPlaceholders,\n} from \"./range-utils\"\nimport {\n COMPRESSED_BLOCK_HEADER,\n allocateBlockId,\n allocateRunId,\n applyCompressionState,\n wrapCompressedSummary,\n} from \"./state\"\nimport type { CompressRangeToolArgs, SearchContext } from \"./types\"\nimport { generateSummaryViaExternal } from \"./external-inference\"\nimport { runWithConcurrency, serializeMessagesForExternalSummary } from \"./external-content\"\n\nfunction buildSchema(externalModelEnabled: boolean) {\n const summaryField = externalModelEnabled\n ? tool.schema\n .string()\n .optional()\n .describe(\n \"Complete technical summary replacing all content in range (optional when external model is configured)\",\n )\n : tool.schema.string().describe(\"Complete technical summary replacing all content in range\")\n\n return {\n topic: tool.schema\n .string()\n .describe(\"Short label (3-5 words) for display - e.g., 'Auth System Exploration'\"),\n content: tool.schema\n .array(\n tool.schema.object({\n startId: tool.schema\n .string()\n .describe(\n \"Injected message or block ID visible in the current context marking the beginning of the range. Do not invent IDs; use an exact visible mNNNN or bN boundary.\",\n ),\n endId: tool.schema\n .string()\n .describe(\n \"Injected message or block ID visible in the current context marking the end of the range. Do not invent IDs; use an exact visible mNNNN or bN boundary.\",\n ),\n summary: summaryField,\n }),\n )\n .describe(\n \"One or more ranges to compress, each with start/end boundaries and a summary\",\n ),\n }\n}\n\nexport function createCompressRangeTool(ctx: ToolContext): ReturnType<typeof tool> {\n ctx.prompts.reload()\n const runtimePrompts = ctx.prompts.getRuntimePrompts()\n const externalModelEnabled = ctx.config.compress.externalModel !== undefined\n\n return tool({\n description: runtimePrompts.compressRange + buildRangeFormatExtension(externalModelEnabled),\n args: buildSchema(externalModelEnabled),\n async execute(args, toolCtx) {\n const input = args as CompressRangeToolArgs\n validateArgs(input)\n const callId =\n typeof (toolCtx as unknown as { callID?: unknown }).callID === \"string\"\n ? (toolCtx as unknown as { callID: string }).callID\n : undefined\n\n const { state, rawMessages, searchContext } = await prepareSession(\n ctx,\n toolCtx,\n `Compress Range: ${input.topic}`,\n )\n const resolvedPlans = resolveRanges(input, searchContext, state)\n validateNonOverlapping(resolvedPlans)\n\n const externalModel = ctx.config.compress.externalModel\n if (externalModel) {\n await runWithConcurrency(resolvedPlans, 3, async (plan) => {\n if (plan.entry.summary === undefined) {\n const selectedMessages = plan.selection.messageIds.flatMap((messageId) => {\n const message = searchContext.rawMessagesById.get(messageId)\n return message ? [message] : []\n })\n const userContent = serializeMessagesForExternalSummary(selectedMessages)\n const generated = await generateSummaryViaExternal(externalModel, {\n systemPrompt: runtimePrompts.compressRange,\n userContent,\n })\n plan.entry.summary = generated\n }\n })\n }\n\n const notifications: NotificationEntry[] = []\n const preparedPlans: Array<{\n entry: (typeof resolvedPlans)[number][\"entry\"]\n selection: (typeof resolvedPlans)[number][\"selection\"]\n anchorMessageId: string\n finalSummary: string\n consumedBlockIds: number[]\n }> = []\n let totalCompressedMessages = 0\n\n for (const plan of resolvedPlans) {\n if (plan.entry.summary === undefined) {\n throw new Error(\n \"缺少 summary:未配置外部模型,请提供 summary 或配置 OPENCODE_DCP_EXTERNAL_COMPRESS_URL/MODEL\",\n )\n }\n const parsedPlaceholders = parseBlockPlaceholders(plan.entry.summary)\n const missingBlockIds = validateSummaryPlaceholders(\n parsedPlaceholders,\n plan.selection.requiredBlockIds,\n plan.selection.startReference,\n plan.selection.endReference,\n searchContext.summaryByBlockId,\n )\n\n const injected = injectBlockPlaceholders(\n plan.entry.summary,\n parsedPlaceholders,\n searchContext.summaryByBlockId,\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n const summaryWithUsers = appendProtectedUserMessages(\n injected.expandedSummary,\n plan.selection,\n searchContext,\n state,\n ctx.config.compress.protectUserMessages,\n )\n\n const summaryWithPromptInfo = appendProtectedPromptInfo(\n summaryWithUsers,\n plan.selection,\n searchContext,\n state,\n ctx.config.compress.protectTags,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n state,\n ctx.config.experimental.allowSubAgents,\n summaryWithPromptInfo,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n const completedSummary = appendMissingBlockSummaries(\n summaryWithTools,\n missingBlockIds,\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: completedSummary.consumedBlockIds,\n })\n }\n\n const runId = allocateRunId(state)\n\n for (const preparedPlan of preparedPlans) {\n const blockId = allocateBlockId(state)\n const storedSummary = wrapCompressedSummary(blockId, preparedPlan.finalSummary)\n const summaryTokens = countTokens(storedSummary)\n\n const applied = applyCompressionState(\n state,\n {\n topic: input.topic,\n batchTopic: input.topic,\n startId: preparedPlan.entry.startId,\n endId: preparedPlan.entry.endId,\n mode: \"range\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n preparedPlan.selection,\n preparedPlan.anchorMessageId,\n blockId,\n storedSummary,\n preparedPlan.consumedBlockIds,\n )\n\n totalCompressedMessages += applied.messageIds.length\n\n notifications.push({\n blockId,\n runId,\n summary: preparedPlan.finalSummary,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, state, toolCtx, rawMessages, notifications, input.topic)\n\n return `Compressed ${totalCompressedMessages} messages into ${COMPRESSED_BLOCK_HEADER}.`\n },\n })\n}\n","import type { CompressionBlock, SessionState } from \"../state\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport type {\n BoundaryReference,\n CompressRangeToolArgs,\n InjectedSummaryResult,\n ParsedBlockPlaceholder,\n ResolvedRangeCompression,\n SearchContext,\n} from \"./types\"\n\nconst BLOCK_PLACEHOLDER_REGEX = /\\(b(\\d+)\\)|\\{block_(\\d+)\\}/gi\n\nexport function validateArgs(args: CompressRangeToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.startId !== \"string\" || entry.startId.trim().length === 0) {\n throw new Error(`${prefix}.startId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.endId !== \"string\" || entry.endId.trim().length === 0) {\n throw new Error(`${prefix}.endId is required and must be a non-empty string`)\n }\n\n if (entry?.summary !== undefined) {\n if (typeof entry.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary must be a non-empty string when provided`)\n }\n }\n }\n}\n\nexport function resolveRanges(\n args: CompressRangeToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n): ResolvedRangeCompression[] {\n return args.content.map((entry, index) => {\n const normalizedEntry = {\n startId: entry.startId.trim(),\n endId: entry.endId.trim(),\n summary: entry.summary,\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n normalizedEntry.startId,\n normalizedEntry.endId,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n return {\n index,\n entry: normalizedEntry,\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\n })\n}\n\nexport function validateNonOverlapping(plans: ResolvedRangeCompression[]): void {\n const sortedPlans = [...plans].sort(\n (left, right) =>\n left.selection.startReference.rawIndex - right.selection.startReference.rawIndex ||\n left.selection.endReference.rawIndex - right.selection.endReference.rawIndex ||\n left.index - right.index,\n )\n\n const issues: string[] = []\n\n for (let index = 1; index < sortedPlans.length; index++) {\n const previous = sortedPlans[index - 1]\n const current = sortedPlans[index]\n if (!previous || !current) {\n continue\n }\n\n if (current.selection.startReference.rawIndex > previous.selection.endReference.rawIndex) {\n continue\n }\n\n issues.push(\n `content[${previous.index}] (${previous.entry.startId}..${previous.entry.endId}) overlaps content[${current.index}] (${current.entry.startId}..${current.entry.endId}). Overlapping ranges cannot be compressed in the same batch.`,\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\nexport function parseBlockPlaceholders(summary: string): ParsedBlockPlaceholder[] {\n const placeholders: ParsedBlockPlaceholder[] = []\n const regex = new RegExp(BLOCK_PLACEHOLDER_REGEX)\n\n let match: RegExpExecArray | null\n while ((match = regex.exec(summary)) !== null) {\n const full = match[0]\n const blockIdPart = match[1] || match[2]\n const parsed = Number.parseInt(blockIdPart, 10)\n if (!Number.isInteger(parsed)) {\n continue\n }\n\n placeholders.push({\n raw: full,\n blockId: parsed,\n startIndex: match.index,\n endIndex: match.index + full.length,\n })\n }\n\n return placeholders\n}\n\nexport function validateSummaryPlaceholders(\n placeholders: ParsedBlockPlaceholder[],\n requiredBlockIds: number[],\n startReference: BoundaryReference,\n endReference: BoundaryReference,\n summaryByBlockId: Map<number, CompressionBlock>,\n): number[] {\n const boundaryOptionalIds = new Set<number>()\n if (startReference.kind === \"compressed-block\") {\n if (startReference.blockId === undefined) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n boundaryOptionalIds.add(startReference.blockId)\n }\n if (endReference.kind === \"compressed-block\") {\n if (endReference.blockId === undefined) {\n throw new Error(\"Failed to map boundary matches back to raw messages\")\n }\n boundaryOptionalIds.add(endReference.blockId)\n }\n\n const strictRequiredIds = requiredBlockIds.filter((id) => !boundaryOptionalIds.has(id))\n const requiredSet = new Set(requiredBlockIds)\n const keptPlaceholderIds = new Set<number>()\n const validPlaceholders: ParsedBlockPlaceholder[] = []\n\n for (const placeholder of placeholders) {\n const isKnown = summaryByBlockId.has(placeholder.blockId)\n const isRequired = requiredSet.has(placeholder.blockId)\n const isDuplicate = keptPlaceholderIds.has(placeholder.blockId)\n\n if (isKnown && isRequired && !isDuplicate) {\n validPlaceholders.push(placeholder)\n keptPlaceholderIds.add(placeholder.blockId)\n }\n }\n\n placeholders.length = 0\n placeholders.push(...validPlaceholders)\n\n return strictRequiredIds.filter((id) => !keptPlaceholderIds.has(id))\n}\n\nexport function injectBlockPlaceholders(\n summary: string,\n placeholders: ParsedBlockPlaceholder[],\n summaryByBlockId: Map<number, CompressionBlock>,\n startReference: BoundaryReference,\n endReference: BoundaryReference,\n): InjectedSummaryResult {\n let cursor = 0\n let expanded = summary\n const consumed: number[] = []\n const consumedSeen = new Set<number>()\n\n if (placeholders.length > 0) {\n expanded = \"\"\n for (const placeholder of placeholders) {\n const target = summaryByBlockId.get(placeholder.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${placeholder.blockId})`)\n }\n\n expanded += summary.slice(cursor, placeholder.startIndex)\n expanded += restoreSummary(target.summary)\n cursor = placeholder.endIndex\n\n if (!consumedSeen.has(placeholder.blockId)) {\n consumedSeen.add(placeholder.blockId)\n consumed.push(placeholder.blockId)\n }\n }\n\n expanded += summary.slice(cursor)\n }\n\n expanded = injectBoundarySummary(\n expanded,\n startReference,\n \"start\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n expanded = injectBoundarySummary(\n expanded,\n endReference,\n \"end\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n\n return {\n expandedSummary: expanded,\n consumedBlockIds: consumed,\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n missingBlockIds: number[],\n summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n const consumedSeen = new Set<number>(consumedBlockIds)\n const consumed = [...consumedBlockIds]\n\n const missingSummaries: string[] = []\n for (const blockId of missingBlockIds) {\n if (consumedSeen.has(blockId)) {\n continue\n }\n\n const target = summaryByBlockId.get(blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${blockId})`)\n }\n\n missingSummaries.push(`\\n### (b${blockId})\\n${restoreSummary(target.summary)}`)\n consumedSeen.add(blockId)\n consumed.push(blockId)\n }\n\n if (missingSummaries.length === 0) {\n return {\n expandedSummary: summary,\n consumedBlockIds: consumed,\n }\n }\n\n const heading =\n \"\\n\\nThe following previously compressed summaries were also part of this conversation section:\"\n\n return {\n expandedSummary: summary + heading + missingSummaries.join(\"\"),\n consumedBlockIds: consumed,\n }\n}\n\nfunction restoreSummary(summary: string): string {\n const headerMatch = summary.match(/^\\s*\\[Compressed conversation(?: section)?(?: b\\d+)?\\]/i)\n if (!headerMatch) {\n return summary\n }\n\n const afterHeader = summary.slice(headerMatch[0].length)\n const withoutLeadingBreaks = afterHeader.replace(/^(?:\\r?\\n)+/, \"\")\n return withoutLeadingBreaks\n .replace(/(?:\\r?\\n)*<dcp-message-id>b\\d+<\\/dcp-message-id>\\s*$/i, \"\")\n .replace(/(?:\\r?\\n)+$/, \"\")\n}\n\nfunction injectBoundarySummary(\n summary: string,\n reference: BoundaryReference,\n position: \"start\" | \"end\",\n summaryByBlockId: Map<number, CompressionBlock>,\n consumed: number[],\n consumedSeen: Set<number>,\n): string {\n if (reference.kind !== \"compressed-block\" || reference.blockId === undefined) {\n return summary\n }\n if (consumedSeen.has(reference.blockId)) {\n return summary\n }\n\n const target = summaryByBlockId.get(reference.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${reference.blockId})`)\n }\n\n const injectedBody = restoreSummary(target.summary)\n const left = position === \"start\" ? injectedBody.trim() : summary.trim()\n const right = position === \"start\" ? summary.trim() : injectedBody.trim()\n const next = !left ? right : !right ? left : `${left}\\n\\n${right}`\n\n consumedSeen.add(reference.blockId)\n consumed.push(reference.blockId)\n return next\n}\n","export type PermissionAction = \"ask\" | \"allow\" | \"deny\"\n\nexport type PermissionValue = PermissionAction | Record<string, PermissionAction>\n\nexport type PermissionConfig = Record<string, PermissionValue> | undefined\n\nexport interface HostPermissionSnapshot {\n global: PermissionConfig\n agents: Record<string, PermissionConfig>\n}\n\ntype PermissionRule = {\n permission: string\n pattern: string\n action: PermissionAction\n}\n\nconst findLastMatchingRule = (\n rules: PermissionRule[],\n predicate: (rule: PermissionRule) => boolean,\n): PermissionRule | undefined => {\n for (let index = rules.length - 1; index >= 0; index -= 1) {\n const rule = rules[index]\n if (rule && predicate(rule)) {\n return rule\n }\n }\n\n return undefined\n}\n\nconst wildcardMatch = (value: string, pattern: string): boolean => {\n const normalizedValue = value.replaceAll(\"\\\\\", \"/\")\n let escaped = pattern\n .replaceAll(\"\\\\\", \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")\n\n if (escaped.endsWith(\" .*\")) {\n escaped = escaped.slice(0, -3) + \"( .*)?\"\n }\n\n const flags = process.platform === \"win32\" ? \"si\" : \"s\"\n return new RegExp(`^${escaped}$`, flags).test(normalizedValue)\n}\n\nconst getPermissionRules = (permissionConfigs: PermissionConfig[]): PermissionRule[] => {\n const rules: PermissionRule[] = []\n for (const permissionConfig of permissionConfigs) {\n if (!permissionConfig) {\n continue\n }\n\n for (const [permission, value] of Object.entries(permissionConfig)) {\n if (value === \"ask\" || value === \"allow\" || value === \"deny\") {\n rules.push({ permission, pattern: \"*\", action: value })\n continue\n }\n\n for (const [pattern, action] of Object.entries(value)) {\n if (action === \"ask\" || action === \"allow\" || action === \"deny\") {\n rules.push({ permission, pattern, action })\n }\n }\n }\n }\n return rules\n}\n\nexport const compressDisabledByOpencode = (...permissionConfigs: PermissionConfig[]): boolean => {\n const match = findLastMatchingRule(getPermissionRules(permissionConfigs), (rule) =>\n wildcardMatch(\"compress\", rule.permission),\n )\n\n return match?.pattern === \"*\" && match.action === \"deny\"\n}\n\nexport const resolveEffectiveCompressPermission = (\n basePermission: PermissionAction,\n hostPermissions: HostPermissionSnapshot,\n agentName?: string,\n): PermissionAction => {\n if (basePermission === \"deny\") {\n return \"deny\"\n }\n\n return compressDisabledByOpencode(\n hostPermissions.global,\n agentName ? hostPermissions.agents[agentName] : undefined,\n )\n ? \"deny\"\n : basePermission\n}\n\nexport const hasExplicitToolPermission = (\n permissionConfig: PermissionConfig,\n tool: string,\n): boolean => {\n return permissionConfig ? Object.prototype.hasOwnProperty.call(permissionConfig, tool) : false\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 { SYSTEM as SYSTEM_PROMPT } from \"./system\"\nimport { COMPRESS_RANGE as COMPRESS_RANGE_PROMPT } from \"./compress-range\"\nimport { COMPRESS_MESSAGE as COMPRESS_MESSAGE_PROMPT } from \"./compress-message\"\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-range\"\n | \"compress-message\"\n | \"context-limit-nudge\"\n | \"turn-nudge\"\n | \"iteration-nudge\"\n\ntype EditablePromptField =\n | \"system\"\n | \"compressRange\"\n | \"compressMessage\"\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 compressRange: string\n compressMessage: 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-range\",\n fileName: \"compress-range.md\",\n label: \"Compress Range\",\n description: \"range-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the range-mode compress tool description\",\n runtimeField: \"compressRange\",\n },\n {\n key: \"compress-message\",\n fileName: \"compress-message.md\",\n label: \"Compress Message\",\n description: \"message-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the message-mode compress tool description\",\n runtimeField: \"compressMessage\",\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-range\",\n \"compress-message\",\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\nconst BUNDLED_EDITABLE_PROMPTS: Record<EditablePromptField, string> = {\n system: SYSTEM_PROMPT,\n compressRange: COMPRESS_RANGE_PROMPT,\n compressMessage: COMPRESS_MESSAGE_PROMPT,\n contextLimitNudge: CONTEXT_LIMIT_NUDGE,\n turnNudge: TURN_NUDGE,\n iterationNudge: ITERATION_NUDGE,\n}\n\nconst INTERNAL_PROMPT_EXTENSIONS = {\n manualExtension: MANUAL_MODE_SYSTEM_EXTENSION,\n subagentExtension: SUBAGENT_SYSTEM_EXTENSION,\n}\n\nfunction createBundledRuntimePrompts(): RuntimePrompts {\n return {\n system: BUNDLED_EDITABLE_PROMPTS.system,\n compressRange: BUNDLED_EDITABLE_PROMPTS.compressRange,\n compressMessage: BUNDLED_EDITABLE_PROMPTS.compressMessage,\n contextLimitNudge: BUNDLED_EDITABLE_PROMPTS.contextLimitNudge,\n turnNudge: BUNDLED_EDITABLE_PROMPTS.turnNudge,\n iterationNudge: BUNDLED_EDITABLE_PROMPTS.iterationNudge,\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 if (definition.key !== \"compress-range\" && definition.key !== \"compress-message\") {\n normalized = normalizeReminderPromptContent(normalized)\n }\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 if (definition.key === \"compress-range\" || definition.key === \"compress-message\") {\n return trimmed\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 lastReloadAt = 0\n\n constructor(logger: Logger, workingDirectory: string, customPromptsEnabled = false) {\n this.logger = logger\n this.paths = resolvePromptPaths(workingDirectory)\n this.customPromptsEnabled = customPromptsEnabled\n this.runtimePrompts = createBundledRuntimePrompts()\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 now = Date.now()\n if (now - this.lastReloadAt < 1000) return\n this.lastReloadAt = now\n\n const nextPrompts = createBundledRuntimePrompts()\n\n if (!this.customPromptsEnabled) {\n this.runtimePrompts = nextPrompts\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledSource = BUNDLED_EDITABLE_PROMPTS[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 BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const managedContent = buildDefaultPromptFileContent(\n bundledEditable || BUNDLED_EDITABLE_PROMPTS[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","export const SYSTEM = `\n你在上下文长度受限的环境中运行。主动管理上下文,避免无效累积并保持较高的检索质量。\n\n唯一的上下文管理工具是 \\`compress\\`。它会用你生成的技术摘要替换较早的对话内容。\n\n硬性约束\n- 只能通过调用 \\`compress\\` 管理上下文,绝不能在普通文本中直接生成压缩摘要。\n- 文本回复中绝不能输出 \\`<summary>\\` 或 \\`<analysis>\\` XML 标签,它们会导致系统错误。\n- 需要压缩时调用 \\`compress\\`,不要在回复中内联编写摘要。\n- 使用 Markdown 标题(例如 \\`## 分析\\`、\\`## 摘要\\`)组织信息,绝不能使用 XML 标签。\n\n\\`<dcp-message-id>\\` 和 \\`<dcp-system-reminder>\\` 是环境注入的元数据,不要输出它们。\n\n何时压缩\n\n最高优先级的强制触发条件:只要对话主题发生变化,立即调用 \\`compress\\`,把上一主题已经完成的上下文压缩为摘要。\n\n主题变化是客观且不需要复杂判断的信号。以下任一情况都算主题变化:\n\n- 用户提出与上一任务无关的问题\n- 工作重点从一个模块、文件或功能转移到另一个\n- 目标从探索/研究转为实现,或从实现转为调试/验证\n- 一个独立问题已经解决,开始处理下一个问题\n\n出现任一情况时,立即压缩上一主题已经完成的范围,不要等待。这是保持上下文清晰最有效的方法。\n\n即使主题没有变化,在以下阶段确实结束时也应压缩:\n\n- 研究完成,结论已经确定\n- 实现完成并通过验证\n- 探索已经充分,相关规律已经明确\n- 已确认无效的方向可以丢弃,无需等待整个阶段结束\n\n以下情况不要压缩:\n\n- 编辑或精确引用仍需要原始上下文\n- 目标工作仍在进行\n- 后续步骤可能需要精确的代码、错误信息或文件内容\n\n压缩前先问自己:_“这一部分是否已经结束,可以只保留摘要?”_\n\n如果情况是“主题已经切换,不再需要旧内容”,答案始终是“可以”。\n\n定期评估对话的有效信息比例。谨慎使用 \\`compress\\` 并生成高质量摘要,优先处理过期内容,保持高质量上下文。\n\n你有责任维护精确、高质量的上下文,以获得最佳表现。\n`\n","export const COMPRESS_RANGE = `将对话中的一个范围折叠为详细摘要。\n\n输出格式\n每个摘要必须使用 Markdown 标题结构:\n\n\\`\\`\\`\n## 分析\n[分析:探索了什么、遇到了什么问题、尝试了哪些方法]\n\n## 总结\n[总结:最终结论、关键决策、重要文件路径、函数签名、代码变更]\n\\`\\`\\`\n\n禁止使用 \\`<analysis>\\` 或 \\`<summary>\\` 等 XML 标签。只使用 Markdown \\`## 分析\\` 和 \\`## 总结\\` 标题。\n\n摘要要求\n摘要必须详尽。捕获文件路径、函数签名、所做决策、发现的约束、关键发现……所有维持上下文完整性的内容。这不是简短笔记——而是一份权威记录,忠实到原始对话不再有任何价值。\n\n用户意图保真\n当压缩范围包含用户消息时,格外小心地保留用户意图。不要改变范围、约束、优先级、验收标准或请求的结果。\n当用户消息足够短时直接引用。直接引用在最能保留精确含义时优先使用。\n\n历史审批处理\n当压缩范围包含用户的审批/批准短语(如\"就执行吧\"、\"按照这个执行\"、\"好的,继续\"等)时,必须将其标记为历史事件而非当前有效指令。\n- 错误:保留\"用户说:就执行吧\"(可能被误解为当前指令)\n- 正确:标记为\"用户曾批准了先前的方案(该批准仅适用于当时的上下文,不构成对后续操作的授权)\"\n这确保压缩后的上下文不会被误解为新的执行授权。\n\n同时保持精简。去除噪音:无果的失败尝试、冗长的工具输出、反复探索。留下的应该是纯信号——保留完整理解、零歧义的精华细节。\n\n压缩块占位符\n当选定范围包含之前压缩的块时,引用时使用以下精确占位符格式:\n\n- \\`(bN)\\`\n\n上下文中的压缩块部分用标题明确标记:\n\n- \\`[已压缩的对话部分]\\`\n\n压缩块 ID 始终使用 \\`bN\\` 形式(不是 \\`mNNNN\\`),并以相同的 XML 元数据标签格式表示。\n\n规则:\n\n- 每个必需的块占位符恰好包含一次。\n- 不要为选定范围之外的块发明占位符。\n- 将 \\`(bN)\\` 占位符视为保留标记。除了有意占位符外,不要在任何地方输出 \\`(bN)\\` 文本。\n- 如果需要在正文中提及一个块,使用纯文本如 \\`压缩块 bN\\`(不作为占位符)。\n- 最终确定前的预检:摘要中的 \\`(bN)\\` 占位符集合必须与必需集合完全匹配,无重复。\n\n这些占位符是语义引用。当工具处理你的输出时,它们将被替换为完整的存储压缩块内容。\n\n占位符的流畅性\n使用压缩块占位符时,编写周围的摘要文本,使其在占位符展开后仍然正确可读。\n\n- 将每个占位符视为完整对话段的替代,而不是短标签。\n- 确保每个占位符前后的过渡保留时间顺序和因果关系。\n- 不要编写依赖于占位符保持字面意义的文本(例如\"如 \\`(b2)\\` 中所述\")。\n- 当每个占位符被替换为其完整压缩块内容后,最终含义必须连贯。\n\n边界 ID\n使用对话中可见的注入 ID 按 ID 指定边界:\n\n- \\`mNNNN\\` ID 标识原始消息\n- \\`bN\\` ID 标识之前压缩的块\n\n每条消息在 XML 元数据标签内有 ID,如 \\`<dcp-message-id>m0007</dcp-message-id>\\`。\n相同的 ID 标签出现在该消息所属的每个工具输出中——每个唯一 ID 标识一条完整消息。\n将这些标签仅视为边界元数据,而非工具结果内容。\n\n规则:\n\n- 直接从上下文中的注入 ID 选取 \\`startId\\` 和 \\`endId\\`。\n- ID 必须存在于当前可见上下文中。\n- \\`startId\\` 必须出现在 \\`endId\\` 之前。\n- 不要发明 ID。只使用上下文中存在的 ID。\n\n批量处理\n当多个独立范围已准备好且边界不重叠时,将它们全部作为单独条目包含在单次工具调用的 \\`content\\` 数组中。每个条目应有自己的 \\`startId\\`、\\`endId\\` 和 \\`summary\\`。\n`\n","export const COMPRESS_MESSAGE = `将对话中选定的单条消息折叠为详细摘要。\n\n摘要要求\n摘要必须详尽。捕获文件路径、函数签名、所做决策、发现的约束、关键发现、工具结果,以及重要的用户意图细节……所有在原始消息被移除后保留其价值的内容。\n\n用户意图保真\n当选定消息包含用户意图时,格外小心地保留该意图。不要改变范围、约束、优先级、验收标准或请求的结果。\n当直接引用简短用户指令最能保留精确含义时,直接引用。\n\n历史审批处理\n当压缩包含用户的审批/批准短语(如\"就执行吧\"、\"按照这个执行\"、\"好的,继续\"等)时,必须将其标记为历史事件而非当前有效指令。\n- 错误:保留\"用户说:就执行吧\"(可能被误解为当前指令)\n- 正确:标记为\"用户曾批准了先前的方案(该批准仅适用于当时的上下文,不构成对后续操作的授权)\"\n这确保压缩后的上下文不会被误解为新的执行授权。\n\n同时保持精简。去除噪音:无果的失败尝试、冗长的工具输出和重复。留下的应该是纯信号——保留完整理解、零歧义的精华细节。\n如果消息不包含重要的技术决策、代码变更或用户需求,生成最小化的一行摘要而非详细摘要。\n\n消息 ID\n使用对话中可见的注入 ID 按 ID 指定单条原始消息:\n\n- \\`mNNNN\\` ID 标识原始消息\n\n每条消息在 XML 元数据标签内有 ID,如 \\`<dcp-message-id priority=\"high\">m0007</dcp-message-id>\\`。\n相同的 ID 标签出现在该消息所属的每个工具输出中——每个唯一 ID 标识一条完整消息。\n将这些标签仅视为消息元数据,而非要摘要的内容。只使用内部的 \\`mNNNN\\` 值作为 \\`messageId\\`。\n\\`priority\\` 属性表示相对上下文成本。当高优先级消息的完整文本对当前任务不再必要时,你必须压缩它们。\n如果存在之前的压缩工具结果,始终在更广泛的压缩过程中将它们最小化地压缩和摘要。不要仅为了重新压缩之前的压缩结果而调用压缩工具。\n标记为 \\`<dcp-message-id>BLOCKED</dcp-message-id>\\` 的消息不能被压缩。\n\n规则:\n\n- 直接从上下文中可见的注入 ID 选取每个 \\`messageId\\`。\n- 只使用 \\`mNNNN\\` 形式的原始消息 ID。\n- 复制 ID 时忽略 \\`priority\\` 等 XML 属性;只使用内部的 \\`mNNNN\\` 值。\n- 不要发明 ID。只使用上下文中存在的 ID。\n\n批量处理\n当多条消息可以安全压缩时,在单次工具调用中选择多条消息。\n每个条目应恰好摘要一条消息,工具可以在一次批量中接收任意数量的条目。\n\n通用清理\n使用主题\"通用清理\"进行广泛的清理。\n在通用清理期间,压缩所有与当前任务无关的中高优先级消息。\n优化减少上下文占用,而非按主题分组消息。\n不要压缩掉仍然活跃的指令、未解决的问题或可能很快重要的约束。\n优先处理上下文中最早的消息,因为它们与当前任务的相关性最低。\n通用清理应定期在其他正常压缩工具调用之间进行,而非作为压缩的主要形式。\n`\n","export const CONTEXT_LIMIT_NUDGE = `<dcp-system-reminder>\n紧急:已达到上下文上限。\n\n当前上下文已达到或超过配置的最大阈值,必须立即回收上下文。\n\n你必须现在调用 \\`compress\\`。压缩完成前不要继续常规探索。\n\n如果正在执行一个不可中断的步骤,只完成该步骤,随后立刻压缩。\n\n选择范围\n从较早且已经完成的历史开始,一次覆盖尽可能多的过期上下文。\n除非最新工作已经明确结束,否则不要选择最近的工作消息。\n\n摘要要求\n摘要必须覆盖所选消息中的所有关键信息,确保后续工作可以继续。\n如果范围包含用户消息,必须完整保留用户意图。对于较短的用户消息,优先直接引用,避免语义偏移。\n</dcp-system-reminder>\n`\n","export const TURN_NUDGE = `\n用户开始了新一轮对话,此时最容易发生主题变化。\n\n本轮请求是否与上一轮属于不同主题或任务?\n- 新主题或独立任务:现在调用 \\`compress\\`,把上一主题已经完成的上下文压缩为摘要,不再逐字保留细节。\n- 同一主题的延续:可以保留,但仍需注意过期内容的累积。\n\n主题变化是最明确、最客观的压缩触发条件,不要遗漏。\n`\n","export const ITERATION_NUDGE = `\n在没有新用户输入的情况下已经执行了多轮。\n\n当前任务是否已经完成,或者当前主题是否已经偏离早期步骤?\n- 如果早期步骤属于已经解决的问题或已被替代的探索,现在调用 \\`compress\\` 将它们压缩为摘要。\n- 如果仍在继续同一个未完成目标,而且还需要早期上下文,则保留这些内容。\n\n不要让已经结束的探索方向继续占用上下文。主题发生偏移时最适合压缩。\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `\n手动模式已启用。压缩操作需要用户明确触发。\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `\n子代理模式:压缩功能已禁用。\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 `以下工具的输出受保护,压缩时不要包含其完整内容:${toolList}`\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\"\n\nconst SUMMARY_ID_HASH_LENGTH = 16\nconst DCP_BLOCK_ID_TAG_REGEX = /(<dcp-message-id(?=[\\s>])[^>]*>)b\\d+(<\\/dcp-message-id>)/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\nconst INJECTED_TAG_SUFFIX_REGEX = /\\n<dcp-message-id(?:\\s[^>]*)?>m\\d+<\\/dcp-message-id>\\s*$/\nconst TRAILING_MESSAGE_REF_REGEX = /\\nm\\d{4}\\s*$/\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 replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n // Issue #556: Remove legitimately injected message ID suffix before running\n // paired regex so it can't act as a false closing match\n const safe = text.replace(INJECTED_TAG_SUFFIX_REGEX, \"\")\n // Issue #555: Strip trailing mXXXX hallucinated message refs\n return safe\n .replace(DCP_PAIRED_TAG_REGEX, \"\")\n .replace(DCP_UNPAIRED_TAG_REGEX, \"\")\n .replace(TRAILING_MESSAGE_REF_REGEX, \"\")\n}\n\nexport const stripHallucinations = (messages: WithParts[]): void => {\n for (const message of messages) {\n if (message.info.role !== \"assistant\") {\n continue\n }\n for (const part of message.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n part.text = stripHallucinationsFromString(part.text)\n }\n }\n }\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\nimport type { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport { createSyntheticUserMessage, replaceBlockIdsWithBlocked } from \"./utils\"\nimport { getLastUserMessage } from \"./query\"\nimport type { UserMessage } from \"@opencode-ai/sdk\"\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 config: PluginConfig,\n messages: WithParts[],\n): void => {\n filterCompressedRanges(state, logger, config, messages)\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 config: PluginConfig,\n messages: 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 (let msgIndex = 0; msgIndex < messages.length; msgIndex++) {\n const msg = messages[msgIndex]\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 userMessage = getLastUserMessage(messages, msgIndex)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(rawSummaryContent)\n : rawSummaryContent\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 missingAnchorBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n for (const block of orderedBlocks) {\n const hasAnchorMessage =\n typeof block.anchorMessageId === \"string\" &&\n block.anchorMessageId.length > 0 &&\n messageIds.has(block.anchorMessageId)\n\n if (!hasAnchorMessage) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n missingAnchorBlockIds.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 (missingAnchorBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingAnchorCount: missingAnchorBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type HostPermissionSnapshot, resolveEffectiveCompressPermission } from \"./host-permissions\"\nimport type { SessionState, WithParts } from \"./state\"\nimport { getLastUserMessage } from \"./messages/query\"\nimport type { UserMessage } from \"@opencode-ai/sdk\"\n\nexport const compressPermission = (\n state: SessionState,\n config: PluginConfig,\n): \"ask\" | \"allow\" | \"deny\" => {\n return state.compressPermission ?? config.compress.permission\n}\n\nexport const syncCompressPermissionState = (\n state: SessionState,\n config: PluginConfig,\n hostPermissions: HostPermissionSnapshot,\n messages: WithParts[],\n): void => {\n const activeAgent = (getLastUserMessage(messages)?.info as UserMessage | undefined)?.agent\n state.compressPermission = resolveEffectiveCompressPermission(\n config.compress.permission,\n hostPermissions,\n activeAgent,\n )\n}\n","import type { PluginConfig } from \"../../config\"\nimport type { SessionState, WithParts } from \"../../state\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../../messages/query\"\nimport { isMessageCompacted } from \"../../state/utils\"\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) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"无\"\n\n return [\n \"压缩块上下文:\",\n `- 此会话中的活跃压缩块:${blockCount} 个(${blockList})`,\n \"- 如果你选择的压缩范围包含任何列出的块,在摘要中使用 `(bN)` 恰好包含每个必需的占位符一次。\",\n ].join(\"\\n\")\n}\n\nexport function buildAvailableMessageIdGuidance(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n): string {\n const visibleIds = new Set(\n messages\n .filter(\n (msg) =>\n !isIgnoredUserMessage(msg) &&\n !isMessageCompacted(state, msg) &&\n !isProtectedUserMessage(config, msg),\n )\n .map((msg) => msg.info.id),\n )\n\n const refs = []\n for (const [ref, rawId] of state.messageIds.byRef) {\n if (visibleIds.has(rawId)) {\n refs.push(ref)\n }\n }\n\n refs.sort((a, b) => {\n const numA = Number.parseInt(a.slice(1), 10)\n const numB = Number.parseInt(b.slice(1), 10)\n return numA - numB\n })\n\n if (refs.length === 0) {\n return \"\"\n }\n\n const refList =\n refs.length <= 15\n ? refs.join(\", \")\n : `${refs[0]} 到 ${refs[refs.length - 1]}(共 ${refs.length} 个)`\n\n return [\n \"可用消息边界 ID:\",\n `- 当前上下文中可作为 compress 边界的合法消息 ID:${refList}`,\n config.compress.mode === \"message\"\n ? \"- 只从以上列表中选取 content[].messageId。不要发明、外推或使用不在列表中的 ID。\"\n : \"- 只从以上列表中选取 startId 和 endId。不要发明、外推或使用不在列表中的 ID。\",\n ].join(\"\\n\")\n}\n\nexport function renderMessagePriorityGuidance(priorityLabel: string, refs: string[]): string {\n const refList = refs.length > 0 ? refs.join(\", \") : \"无\"\n\n const normalized = priorityLabel.toLowerCase()\n const priorityLabelZh = normalized === \"high\" ? \"高\" : normalized === \"medium\" ? \"中\" : \"低\"\n\n return [\n \"消息优先级上下文:\",\n \"- 高优先级的旧消息消耗更多上下文,如果安全的话应立即压缩。\",\n `- 此点之前的${priorityLabelZh}优先级消息 ID:${refList}`,\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 = \"\"\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 { PluginConfig } from \"../config\"\nimport { countAllMessageTokens } from \"../token-utils\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isIgnoredUserMessage, isProtectedUserMessage, messageHasCompress } from \"./query\"\n\nconst MEDIUM_PRIORITY_MIN_TOKENS = 500\nconst HIGH_PRIORITY_MIN_TOKENS = 5000\n\nexport type MessagePriority = \"low\" | \"medium\" | \"high\"\n\nexport interface CompressionPriorityEntry {\n ref: string\n tokenCount: number\n priority: MessagePriority\n}\n\nexport type CompressionPriorityMap = Map<string, CompressionPriorityEntry>\n\nexport function buildPriorityMap(\n config: PluginConfig,\n state: SessionState,\n messages: WithParts[],\n): CompressionPriorityMap {\n if (config.compress.mode !== \"message\") {\n return new Map()\n }\n const priorities: CompressionPriorityMap = new Map()\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n if (isProtectedUserMessage(config, message)) {\n continue\n }\n\n if (isMessageCompacted(state, message)) {\n continue\n }\n\n const rawMessageId = message.info.id\n if (typeof rawMessageId !== \"string\" || rawMessageId.length === 0) {\n continue\n }\n\n const ref = state.messageIds.byRawId.get(rawMessageId)\n if (!ref) {\n continue\n }\n\n const tokenCount = countAllMessageTokens(message)\n priorities.set(rawMessageId, {\n ref,\n tokenCount,\n priority: messageHasCompress(message) ? \"high\" : classifyMessagePriority(tokenCount),\n })\n }\n\n return priorities\n}\n\nexport function classifyMessagePriority(tokenCount: number): MessagePriority {\n if (tokenCount >= HIGH_PRIORITY_MIN_TOKENS) {\n return \"high\"\n }\n\n if (tokenCount >= MEDIUM_PRIORITY_MIN_TOKENS) {\n return \"medium\"\n }\n\n return \"low\"\n}\n\nexport function listPriorityRefsBeforeIndex(\n messages: WithParts[],\n priorities: CompressionPriorityMap,\n anchorIndex: number,\n priority: MessagePriority,\n): string[] {\n const refs: string[] = []\n const seen = new Set<string>()\n const upperBound = Math.max(0, Math.min(anchorIndex, messages.length))\n\n for (let index = 0; index < upperBound; index++) {\n const rawMessageId = messages[index]?.info.id\n if (typeof rawMessageId !== \"string\") {\n continue\n }\n\n const entry = priorities.get(rawMessageId)\n if (!entry || entry.priority !== priority || seen.has(entry.ref)) {\n continue\n }\n\n seen.add(entry.ref)\n refs.push(entry.ref)\n }\n\n return refs\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { PluginConfig } from \"../../config\"\nimport {\n appendGuidanceToDcpTag,\n buildAvailableMessageIdGuidance,\n buildCompressedBlockGuidance,\n renderMessagePriorityGuidance,\n} from \"../../prompts/extensions/nudge\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport type { UserMessage } from \"@opencode-ai/sdk\"\nimport {\n type CompressionPriorityMap,\n type MessagePriority,\n listPriorityRefsBeforeIndex,\n} from \"../priority\"\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\nconst MESSAGE_MODE_NUDGE_PRIORITY: MessagePriority = \"high\"\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 const value = config.compress.nudgeFrequency\n return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : 1\n}\n\nexport function getIterationNudgeThreshold(config: PluginConfig): number {\n const value = config.compress.iterationNudgeThreshold\n return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : 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 buildMessagePriorityGuidance(\n messages: WithParts[],\n compressionPriorities: CompressionPriorityMap | undefined,\n anchorIndex: number,\n priority: MessagePriority,\n): string {\n if (!compressionPriorities || compressionPriorities.size === 0) {\n return \"\"\n }\n\n const refs = listPriorityRefsBeforeIndex(messages, compressionPriorities, anchorIndex, priority)\n const priorityLabel = `${priority[0].toUpperCase()}${priority.slice(1)}`\n\n return renderMessagePriorityGuidance(priorityLabel, refs)\n}\n\nfunction normalizeNudgeSignature(baseNudgeText: string): string {\n return baseNudgeText\n .replace(/<\\/dcp-system-reminder>\\s*$/, \"\")\n .replace(/^\\n+/, \"\")\n .trim()\n}\n\nfunction messageContainsNudgeSignature(message: WithParts, baseNudgeText: string): boolean {\n const signature = normalizeNudgeSignature(baseNudgeText)\n if (!signature) {\n return false\n }\n\n for (const part of message.parts) {\n if (\n part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.includes(signature)\n ) {\n return true\n }\n }\n\n return false\n}\n\nfunction injectAnchoredNudge(message: WithParts, nudgeText: string, baseNudgeText: string): void {\n if (!nudgeText.trim()) {\n return\n }\n\n if (messageContainsNudgeSignature(message, baseNudgeText)) {\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 applyRangeModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n compressedBlockGuidance: string,\n availableMessageIdGuidance: string,\n): void {\n const combinedGuidance = [availableMessageIdGuidance, compressedBlockGuidance]\n .filter((g) => g.trim().length > 0)\n .join(\"\\n\\n\")\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, combinedGuidance)\n if (!nudgeText.trim()) {\n return\n }\n\n for (const { message } of collectAnchoredMessages(anchorMessageIds, messages)) {\n injectAnchoredNudge(message, nudgeText, baseNudgeText)\n }\n}\n\nfunction applyMessageModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n availableMessageIdGuidance: string,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n for (const { message, index } of collectAnchoredMessages(anchorMessageIds, messages)) {\n const priorityGuidance = buildMessagePriorityGuidance(\n messages,\n compressionPriorities,\n index,\n MESSAGE_MODE_NUDGE_PRIORITY,\n )\n const combinedGuidance = [availableMessageIdGuidance, priorityGuidance]\n .filter((g) => g.trim().length > 0)\n .join(\"\\n\\n\")\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, combinedGuidance)\n injectAnchoredNudge(message, nudgeText, baseNudgeText)\n }\n}\n\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(state, config, messages)\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n availableMessageIdGuidance,\n compressionPriorities,\n )\n return\n }\n\n const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(state, config, messages)\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressedBlockGuidance,\n availableMessageIdGuidance,\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 type { CompressionPriorityMap } from \"../priority\"\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\nfunction userMessagesAfterLastAnchor(state: SessionState, messages: WithParts[]): number {\n let latestAnchorIndex = -1\n for (let index = messages.length - 1; index >= 0; index--) {\n if (state.nudges.turnNudgeAnchors.has(messages[index].info.id)) {\n latestAnchorIndex = index\n break\n }\n }\n\n let userCount = 0\n for (let index = latestAnchorIndex + 1; index < messages.length; index++) {\n const message = messages[index]\n if (message.info.role === \"user\" && !isIgnoredUserMessage(message)) {\n userCount++\n }\n }\n\n return userCount\n}\n\nexport const injectCompressNudges = (\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void => {\n const clearPendingBoundary = (): void => {\n if (!state.nudges.boundaryPending) {\n return\n }\n state.nudges.boundaryPending = false\n if (!state.sessionId) {\n return\n }\n void saveSessionState(state, logger).catch((error) =>\n logger.warn(\"Failed to persist boundary nudge cleanup\", {\n error: error instanceof Error ? error.message : String(error),\n }),\n )\n }\n\n if (compressPermission(state, config) === \"deny\") {\n clearPendingBoundary()\n return\n }\n\n if (state.manualMode) {\n clearPendingBoundary()\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 const continuationReminder =\n \"\\n<dcp-system-reminder>\\nCompression complete. Resume your previous task.\\n</dcp-system-reminder>\\n\"\n\n if (lastMessage) {\n const targetMessage = lastMessage.message\n let injected = false\n for (const part of targetMessage.parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n part.text += continuationReminder\n injected = true\n break\n }\n }\n if (!injected) {\n targetMessage.parts.push(\n createSyntheticTextPart(targetMessage, continuationReminder),\n )\n }\n }\n\n state.nudges.contextLimitAnchors.clear()\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n state.nudges.boundaryPending = false\n void saveSessionState(state, logger).catch((error) =>\n logger.warn(\"Failed to persist context-limit nudge\", {\n error: error instanceof Error ? error.message : String(error),\n }),\n )\n return\n }\n\n const { providerId, modelId } = getModelInfo(messages)\n const boundaryNudgeEnabled = config.compress.boundaryNudge !== false\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 hadIterationAnchors = state.nudges.iterationNudgeAnchors.size > 0\n\n if (hadIterationAnchors) {\n state.nudges.iterationNudgeAnchors.clear()\n anchorsChanged = true\n }\n\n if (!boundaryNudgeEnabled) {\n const hadTurnAnchors = state.nudges.turnNudgeAnchors.size > 0\n if (hadTurnAnchors) {\n state.nudges.turnNudgeAnchors.clear()\n anchorsChanged = true\n }\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 (!boundaryNudgeEnabled && 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 if (boundaryNudgeEnabled && !overMaxLimit) {\n const lastUserMessage = getLastUserMessage(messages)\n const isLastMessageUser = lastMessage?.message.info.role === \"user\"\n const hasPendingBoundary = state.nudges.boundaryPending\n\n if (lastUserMessage && lastAssistantMessage) {\n const lastUserMessageIndex = messages.findIndex(\n (message) => message.info.id === lastUserMessage.info.id,\n )\n const lastAssistantMessageIndex = messages.findIndex(\n (message) => message.info.id === lastAssistantMessage.info.id,\n )\n const alreadyAnchored =\n state.nudges.turnNudgeAnchors.has(lastUserMessage.info.id) &&\n state.nudges.turnNudgeAnchors.has(lastAssistantMessage.info.id)\n\n if (!alreadyAnchored && lastUserMessageIndex >= 0 && lastAssistantMessageIndex >= 0) {\n const interval = getNudgeFrequency(config)\n const shouldAnchor =\n hasPendingBoundary ||\n (isLastMessageUser && userMessagesAfterLastAnchor(state, messages) >= interval)\n\n if (shouldAnchor) {\n state.nudges.turnNudgeAnchors.add(lastAssistantMessage.info.id)\n state.nudges.turnNudgeAnchors.add(lastUserMessage.info.id)\n anchorsChanged = true\n }\n }\n\n if (hasPendingBoundary) {\n state.nudges.boundaryPending = false\n anchorsChanged = true\n }\n }\n }\n\n applyAnchoredNudges(state, config, messages, prompts, compressionPriorities)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger).catch((error) =>\n logger.warn(\"Failed to persist compression nudge\", {\n error: error instanceof Error ? error.message : String(error),\n }),\n )\n }\n}\n\nexport const injectMessageIds = (\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n compressionPriorities?: CompressionPriorityMap,\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 priority =\n config.compress.mode === \"message\" && !isBlockedMessage\n ? compressionPriorities?.get(message.info.id)?.priority\n : undefined\n const tag = formatMessageIdTag(\n isBlockedMessage ? \"BLOCKED\" : messageRef,\n priority ? { priority } : undefined,\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\"\nimport { runWithConcurrency } from \"../../concurrency\"\nimport { cacheSubAgentResult, getCachedSubAgentResult } from \"../../state/utils\"\nimport type { OpenCodeClient } from \"../../opencode-client\"\n\nasync function fetchSubAgentMessages(\n client: OpenCodeClient,\n sessionId: string,\n): 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: OpenCodeClient,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n allowSubAgents: boolean,\n): Promise<void> => {\n if (!allowSubAgents) {\n return\n }\n\n type CompletedToolPart = Extract<WithParts[\"parts\"][number], { type: \"tool\" }> & {\n state: { status: \"completed\"; output: string }\n }\n const tasks: Array<{ part: CompletedToolPart }> = []\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\" || part.tool !== \"task\" || !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 tasks.push({ part: part as CompletedToolPart })\n }\n }\n\n await runWithConcurrency(tasks, 4, async ({ part }) => {\n const cachedResult = getCachedSubAgentResult(state, part.callID)\n if (cachedResult !== undefined) {\n if (cachedResult) {\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, cachedResult),\n )\n }\n return\n }\n\n const subAgentSessionId = getSubAgentId(part)\n if (!subAgentSessionId) {\n return\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 return\n }\n\n const subAgentResultText = buildSubagentResultText(subAgentMessages)\n if (!subAgentResultText) {\n return\n }\n\n const cached = cacheSubAgentResult(state, part.callID, subAgentResultText)\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, cached),\n )\n })\n}\n","import type { WithParts } from \"../state\"\nimport { getLastUserMessage } from \"./query\"\n\n/**\n * Mirrors opencode's differentModel handling by preserving part content while\n * dropping provider metadata on assistant parts that came from a different\n * model/provider than the current turn's user message.\n */\nexport function stripStaleMetadata(messages: WithParts[]): void {\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage?.info.role !== \"user\") {\n return\n }\n\n const modelID = lastUserMessage.info.model.modelID\n const providerID = lastUserMessage.info.model.providerID\n\n messages.forEach((message) => {\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (message.info.modelID === modelID && message.info.providerID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\") {\n return part\n }\n\n if (!(\"metadata\" in part)) {\n return part\n }\n\n const { metadata: _metadata, ...rest } = part\n return rest\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 { OpenCodeClient } from \"../opencode-client\"\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\"\n\nexport interface ContextCommandContext {\n client: OpenCodeClient\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\nfunction analyzeTokens(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\nfunction 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 = analyzeTokens(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 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 grouped: boolean\n blocks: CompressionBlock[]\n}\n\nfunction byBlockId(a: CompressionBlock, b: CompressionBlock): number {\n return a.blockId - b.blockId\n}\n\nfunction buildTarget(blocks: CompressionBlock[]): CompressionTarget {\n const ordered = [...blocks].sort(byBlockId)\n const first = ordered[0]\n if (!first) {\n throw new Error(\"Cannot build compression target from empty block list.\")\n }\n\n const grouped = first.mode === \"message\"\n return {\n displayId: first.blockId,\n runId: first.runId,\n topic: grouped ? first.batchTopic || first.topic : first.topic,\n compressedTokens: ordered.reduce((total, block) => total + block.compressedTokens, 0),\n durationMs: ordered.reduce((total, block) => Math.max(total, block.durationMs), 0),\n grouped,\n blocks: ordered,\n }\n}\n\nfunction groupMessageBlocks(blocks: CompressionBlock[]): CompressionTarget[] {\n const grouped = new Map<number, CompressionBlock[]>()\n\n for (const block of blocks) {\n const existing = grouped.get(block.runId)\n if (existing) {\n existing.push(block)\n continue\n }\n grouped.set(block.runId, [block])\n }\n\n return Array.from(grouped.values()).map(buildTarget)\n}\n\nfunction splitTargets(blocks: CompressionBlock[]): CompressionTarget[] {\n const messageBlocks: CompressionBlock[] = []\n const singleBlocks: CompressionBlock[] = []\n\n for (const block of blocks) {\n if (block.mode === \"message\") {\n messageBlocks.push(block)\n } else {\n singleBlocks.push(block)\n }\n }\n\n const targets = [\n ...singleBlocks.map((block) => buildTarget([block])),\n ...groupMessageBlocks(messageBlocks),\n ]\n return targets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function getActiveCompressionTargets(\n messagesState: PruneMessagesState,\n): CompressionTarget[] {\n const activeBlocks = Array.from(messagesState.activeBlockIds)\n .map((blockId) => messagesState.blocksById.get(blockId))\n .filter((block): block is CompressionBlock => !!block && block.active)\n\n return splitTargets(activeBlocks)\n}\n\nexport function getRecompressibleCompressionTargets(\n messagesState: PruneMessagesState,\n availableMessageIds: Set<string>,\n): CompressionTarget[] {\n const allBlocks = Array.from(messagesState.blocksById.values()).filter((block) => {\n return availableMessageIds.has(block.anchorMessageId)\n })\n\n const messageGroups = new Map<number, CompressionBlock[]>()\n const singleTargets: CompressionTarget[] = []\n\n for (const block of allBlocks) {\n if (block.mode === \"message\") {\n const existing = messageGroups.get(block.runId)\n if (existing) {\n existing.push(block)\n } else {\n messageGroups.set(block.runId, [block])\n }\n continue\n }\n\n if (block.deactivatedByUser && !block.active) {\n singleTargets.push(buildTarget([block]))\n }\n }\n\n for (const blocks of messageGroups.values()) {\n if (blocks.some((block) => block.deactivatedByUser && !block.active)) {\n singleTargets.push(buildTarget(blocks))\n }\n }\n\n return singleTargets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function resolveCompressionTarget(\n messagesState: PruneMessagesState,\n blockId: number,\n): CompressionTarget | null {\n const block = messagesState.blocksById.get(blockId)\n if (!block) {\n return null\n }\n\n if (block.mode !== \"message\") {\n return buildTarget([block])\n }\n\n const blocks = Array.from(messagesState.blocksById.values()).filter(\n (candidate) => candidate.mode === \"message\" && candidate.runId === block.runId,\n )\n if (blocks.length === 0) {\n return null\n }\n\n return buildTarget(blocks)\n}\n","import type { Logger } from \"../logger\"\nimport type { OpenCodeClient } from \"../opencode-client\"\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: OpenCodeClient\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)\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 || target.grouped) {\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 = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `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 { OpenCodeClient } from \"../opencode-client\"\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: OpenCodeClient\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nconst BASE_COMMANDS: [string, string][] = [\n [\"/dcp context\", \"Show token usage breakdown for current session\"],\n [\"/dcp stats\", \"Show DCP pruning statistics\"],\n [\"/dcp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/dcp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\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 = [...BASE_COMMANDS]\n\n if (compressPermission(state, config) !== \"deny\") {\n commands.push(TOOL_COMMANDS.compress)\n commands.push(TOOL_COMMANDS.decompress)\n commands.push(TOOL_COMMANDS.recompress)\n }\n\n return commands\n}\n\nfunction 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 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 { OpenCodeClient } from \"../opencode-client\"\nimport type { SessionState, WithParts } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport {\n buildAvailableMessageIdGuidance,\n buildCompressedBlockGuidance,\n} 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 messages: WithParts[],\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state)\n const availableMessageIdGuidance = buildAvailableMessageIdGuidance(state, config, messages)\n\n const sections = [base, availableMessageIdGuidance, 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: OpenCodeClient\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 await saveSessionState(state, logger)\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\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, ctx.messages, 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 { OpenCodeClient } from \"../opencode-client\"\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: OpenCodeClient\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)\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 || target.grouped) {\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 = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `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.anchorMessageId))) {\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 { OpenCodeClient } from \"../opencode-client\"\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 { getActiveCompressionTargets } from \"./compression-targets\"\n\nexport interface StatsCommandContext {\n client: OpenCodeClient\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nfunction formatStatsMessage(\n sessionTokens: number,\n sessionSummaryTokens: number,\n sessionTools: number,\n sessionMessages: number,\n sessionDurationMs: number,\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 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\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 // Session stats from in-memory state\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 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 const message = formatStatsMessage(\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n 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,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTimeTokens: allTime.totalTokens,\n allTimeTools: allTime.totalTools,\n allTimeMessages: allTime.totalMessages,\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 { OpenCodeClient } from \"../opencode-client\"\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 {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { syncToolCache } from \"../state/tool-cache\"\n\nexport interface SweepCommandContext {\n client: OpenCodeClient\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 (isToolNameProtected(entry.tool, protectedTools)) {\n logger.debug(`Sweep: skipping protected tool ${entry.tool} (${id})`)\n return false\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n logger.debug(`Sweep: skipping protected file path(s) ${filePaths.join(\", \")} (${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 if (isToolNameProtected(entry.tool, protectedTools)) {\n return true\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n return true\n }\n return false\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 {\n initializeSessionState,\n resolveSessionState,\n SessionStateStore,\n type SessionState,\n type SessionStateTarget,\n type WithParts,\n} from \"./state\"\nimport type { Logger } from \"./logger\"\nimport type { PluginConfig } from \"./config\"\nimport { assignMessageRefs } from \"./message-ids\"\nimport {\n buildPriorityMap,\n buildToolIdList,\n injectCompressNudges,\n injectExtendedSubAgentResults,\n injectMessageIds,\n prune,\n stripHallucinations,\n stripHallucinationsFromString,\n stripStaleMetadata,\n syncCompressionBlocks,\n} from \"./messages\"\nimport { renderSystemPrompt, type PromptStore } from \"./prompts\"\nimport { buildProtectedToolsExtension } from \"./prompts/extensions/system\"\nimport {\n applyPendingCompressionDurations,\n buildCompressionTimingKey,\n consumeCompressionStart,\n pruneCompressionTiming,\n resolveCompressionDuration,\n} from \"./compress/timing\"\nimport { filterMessages, filterMessagesInPlace } from \"./messages/shape\"\nimport {\n applyPendingManualTrigger,\n handleContextCommand,\n handleDecompressCommand,\n handleHelpCommand,\n handleManualToggleCommand,\n handleManualTriggerCommand,\n handleRecompressCommand,\n handleStatsCommand,\n handleSweepCommand,\n} from \"./commands\"\nimport { type HostPermissionSnapshot } from \"./host-permissions\"\nimport { compressPermission, syncCompressPermissionState } from \"./compress-permission\"\nimport { checkSession, saveSessionState, syncToolCache } from \"./state\"\nimport { cacheSystemPromptTokens } from \"./ui/utils\"\nimport type { OpenCodeClient } from \"./opencode-client\"\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\nexport function createSystemPromptHandler(\n target: SessionStateTarget,\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 const state = input.sessionID\n ? resolveSessionState(target, input.sessionID)\n : target instanceof SessionStateStore\n ? undefined\n : target\n\n if (state && 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 const systemText = output.system.join(\"\\n\")\n if (INTERNAL_AGENT_SIGNATURES.some((sig) => systemText.includes(sig))) {\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 createChatMessageTransformHandler(\n client: OpenCodeClient,\n target: SessionStateTarget,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (input: {}, output: { messages: WithParts[] }) => {\n const receivedMessages = Array.isArray(output.messages) ? output.messages.length : 0\n const messages = filterMessagesInPlace(output.messages)\n if (messages.length !== receivedMessages) {\n logger.warn(\"Skipping messages with unexpected shape during chat transform\", {\n received: receivedMessages,\n usable: messages.length,\n })\n }\n\n const state = await checkSession(\n client,\n target,\n logger,\n output.messages,\n config.manualMode.enabled,\n )\n if (!state) return\n\n syncCompressPermissionState(state, config, hostPermissions, output.messages)\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n const originalMessages = output.messages\n output.messages = structuredClone(output.messages)\n\n try {\n stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n syncCompressionBlocks(state, logger, output.messages)\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n prune(state, logger, config, output.messages)\n await injectExtendedSubAgentResults(\n client,\n state,\n logger,\n output.messages,\n config.experimental.allowSubAgents,\n )\n const compressionPriorities = buildPriorityMap(config, state, output.messages)\n prompts.reload()\n injectCompressNudges(\n state,\n config,\n logger,\n output.messages,\n prompts.getRuntimePrompts(),\n compressionPriorities,\n )\n injectMessageIds(state, config, output.messages, compressionPriorities)\n applyPendingManualTrigger(state, output.messages, logger)\n stripStaleMetadata(output.messages)\n\n if (state.sessionId) {\n await logger.saveContext(state.sessionId, output.messages)\n }\n } catch (error) {\n logger.error(\"Chat message transform failed, returning original messages\", {\n error: error instanceof Error ? error.message : String(error),\n })\n output.messages = originalMessages\n }\n }\n}\n\nexport function createCommandExecuteHandler(\n client: OpenCodeClient,\n target: SessionStateTarget,\n logger: Logger,\n config: PluginConfig,\n workingDirectory: string,\n hostPermissions: HostPermissionSnapshot,\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\") {\n const messagesResponse = await client.session.messages({\n path: { id: input.sessionID },\n })\n const messages = filterMessages(messagesResponse.data || messagesResponse)\n\n const state = await initializeSessionState(\n client,\n target,\n input.sessionID,\n logger,\n messages,\n config.manualMode.enabled,\n )\n\n syncCompressPermissionState(state, config, hostPermissions, messages)\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 subcommand = args[0]?.toLowerCase() || \"\"\n const subArgs = 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 throw new Error(\"__DCP_CONTEXT_HANDLED__\")\n }\n\n if (subcommand === \"stats\") {\n await handleStatsCommand(commandCtx)\n throw new Error(\"__DCP_STATS_HANDLED__\")\n }\n\n if (subcommand === \"sweep\") {\n await handleSweepCommand({\n ...commandCtx,\n args: subArgs,\n workingDirectory,\n })\n throw new Error(\"__DCP_SWEEP_HANDLED__\")\n }\n\n if (subcommand === \"manual\") {\n await handleManualToggleCommand(commandCtx, subArgs[0]?.toLowerCase())\n throw new Error(\"__DCP_MANUAL_HANDLED__\")\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: rawArgs ? `/dcp ${rawArgs}` : `/dcp ${subcommand}`,\n })\n return\n }\n\n if (subcommand === \"decompress\") {\n await handleDecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_DECOMPRESS_HANDLED__\")\n }\n\n if (subcommand === \"recompress\") {\n await handleRecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_RECOMPRESS_HANDLED__\")\n }\n\n await handleHelpCommand(commandCtx)\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n }\n}\n\nexport function createTextCompleteHandler() {\n return async (\n _input: { sessionID: string; messageID: string; partID: string },\n output: { text: string },\n ) => {\n output.text = stripHallucinationsFromString(output.text)\n }\n}\n\nexport function createEventHandler(\n target: SessionStateTarget,\n logger: Logger,\n config: PluginConfig,\n) {\n const markBoundaryPending = async (state: SessionState | undefined): Promise<void> => {\n if (!state) return\n if (config.compress.boundaryNudge === false) return\n if (state.manualMode) return\n if (state.isSubAgent && !config.experimental.allowSubAgents) return\n if (compressPermission(state, config) === \"deny\") return\n if (!state.sessionId) return\n if (state.nudges.boundaryPending) return\n\n state.nudges.boundaryPending = true\n await saveSessionState(state, logger)\n logger.debug(\"Marked boundary nudge pending\", { sessionId: state.sessionId })\n }\n\n return async (input: { event: any }) => {\n if (input.event.type === \"session.idle\") {\n const sessionId = input.event.properties?.sessionID\n if (typeof sessionId === \"string\") {\n const state =\n target instanceof SessionStateStore\n ? target.peek(sessionId)\n : target.sessionId === sessionId\n ? target\n : undefined\n await markBoundaryPending(state).catch((error) =>\n logger.warn(\"Failed to persist boundary nudge\", {\n error: error instanceof Error ? error.message : String(error),\n }),\n )\n }\n return\n }\n\n if (input.event.type === \"vcs.branch.updated\") {\n if (target instanceof SessionStateStore) {\n const sessions: SessionState[] = []\n target.forEach((state) => sessions.push(state))\n await Promise.all(\n sessions.map((state) =>\n markBoundaryPending(state).catch((error) =>\n logger.warn(\"Failed to persist boundary nudge\", {\n error: error instanceof Error ? error.message : String(error),\n }),\n ),\n ),\n )\n } else {\n await markBoundaryPending(target)\n }\n return\n }\n\n const eventTime =\n typeof input.event?.time === \"number\" && Number.isFinite(input.event.time)\n ? input.event.time\n : typeof input.event?.properties?.time === \"number\" &&\n Number.isFinite(input.event.properties.time)\n ? input.event.properties.time\n : undefined\n\n if (input.event.type !== \"message.part.updated\") {\n return\n }\n\n const part = input.event.properties?.part\n if (part?.type !== \"tool\" || part.tool !== \"compress\") {\n return\n }\n\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const eventSessionId =\n typeof input.event.properties?.sessionID === \"string\"\n ? input.event.properties.sessionID\n : typeof part.sessionID === \"string\"\n ? part.sessionID\n : undefined\n const state =\n target instanceof SessionStateStore\n ? target.resolveEventState(eventSessionId, part.messageID)\n : target\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n if (state) pruneCompressionTiming(state)\n\n if (part.state.status === \"pending\") {\n const startedAt = eventTime ?? Date.now()\n if (!state && target instanceof SessionStateStore) {\n target.recordOrphanStart(key, startedAt)\n return\n }\n if (!state) return\n if (state.compressionTiming.startsByCallId.has(key)) {\n return\n }\n state.compressionTiming.startsByCallId.set(key, startedAt)\n state.compressionTiming.recordedAtByCallId.set(key, Date.now())\n logger.debug(\"Recorded compression start\", {\n messageID: part.messageID,\n callID: part.callID,\n startedAt,\n })\n return\n }\n\n if (part.state.status === \"completed\") {\n const start = state\n ? consumeCompressionStart(state, part.messageID, part.callID)\n : target instanceof SessionStateStore\n ? target.consumeOrphanStart(key)\n : undefined\n const durationMs = resolveCompressionDuration(start, eventTime, part.state.time)\n if (typeof durationMs !== \"number\") {\n return\n }\n\n if (!state && target instanceof SessionStateStore) {\n target.recordOrphanPending(key, {\n messageId: part.messageID,\n callId: part.callID,\n durationMs,\n })\n return\n }\n if (!state) return\n state.compressionTiming.pendingByCallId.set(key, {\n messageId: part.messageID,\n callId: part.callID,\n durationMs,\n })\n state.compressionTiming.recordedAtByCallId.set(key, Date.now())\n\n const updates = applyPendingCompressionDurations(state)\n if (updates === 0) {\n return\n }\n\n await saveSessionState(state, logger)\n\n logger.info(\"Attached compression time to blocks\", {\n messageID: part.messageID,\n callID: part.callID,\n blocks: updates,\n durationMs,\n })\n return\n }\n\n if (part.state.status === \"running\") {\n return\n }\n\n if (state) {\n state.compressionTiming.startsByCallId.delete(\n buildCompressionTimingKey(part.messageID, part.callID),\n )\n state.compressionTiming.recordedAtByCallId.delete(key)\n } else if (target instanceof SessionStateStore) {\n target.deleteOrphanStart(key)\n }\n }\n}\n","import { readFile } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { available: true; name: string; current: string; latest: string }\n | { available: false }\n\nconst PACKAGE_NAME = \"@lexwdex-org/opencode-dcp\"\n\nexport function startAutoUpdate(ctx: PluginInput, enabled: boolean): void {\n if (!enabled) return\n\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 10_000)\n void checkAutoUpdate(controller.signal)\n .then((result) => {\n if (!result.available) return\n setTimeout(() => {\n void ctx.client.tui\n .showToast({\n body: {\n title: \"DCP update available\",\n message: `${result.name} ${result.latest} is available (current ${result.current}). Reinstall the plugin to update.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n .catch(() => {})\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { available: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { available: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { available: false }\n\n const wrapperDir = await findAutoUpdateWrapperDir(packageDir, pkg.name)\n if (!wrapperDir) return { available: false }\n\n return { available: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function findAutoUpdateWrapperDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nfunction wrapperSpec(wrapperDir: string, name: string) {\n if (name.startsWith(\"@\")) {\n const [scope, pkg] = name.split(\"/\")\n if (!scope || !pkg || basename(dirname(wrapperDir)) !== scope) return undefined\n const prefix = `${pkg}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n }\n\n const prefix = `${name}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"./lib/config\"\nimport { createCompressMessageTool, createCompressRangeTool } from \"./lib/compress\"\nimport {\n compressDisabledByOpencode,\n hasExplicitToolPermission,\n type HostPermissionSnapshot,\n} from \"./lib/host-permissions\"\nimport { Logger } from \"./lib/logger\"\nimport { createSessionState, SessionStateStore } from \"./lib/state\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport {\n createChatMessageTransformHandler,\n createCommandExecuteHandler,\n createEventHandler,\n createSystemPromptHandler,\n createTextCompleteHandler,\n} from \"./lib/hooks\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n\n if (!config.enabled) {\n return {}\n }\n\n const logger = new Logger(config.debug)\n const states = new SessionStateStore(createSessionState)\n const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts)\n const hostPermissions: HostPermissionSnapshot = {\n global: undefined,\n agents: {},\n }\n\n logger.info(\"DCP initialized\", {\n strategies: config.strategies,\n })\n\n startAutoUpdate(ctx, config.autoUpdate)\n\n const compressToolContext = {\n client: ctx.client,\n state: states,\n logger,\n config,\n prompts,\n }\n\n return {\n \"experimental.chat.system.transform\": createSystemPromptHandler(\n states,\n logger,\n config,\n prompts,\n ),\n \"experimental.chat.messages.transform\": createChatMessageTransformHandler(\n ctx.client,\n states,\n logger,\n config,\n prompts,\n hostPermissions,\n ),\n \"experimental.text.complete\": createTextCompleteHandler(),\n \"command.execute.before\": createCommandExecuteHandler(\n ctx.client,\n states,\n logger,\n config,\n ctx.directory,\n hostPermissions,\n ),\n event: createEventHandler(states, logger, config),\n tool: {\n ...(config.compress.permission !== \"deny\" && {\n compress:\n config.compress.mode === \"message\"\n ? createCompressMessageTool(compressToolContext)\n : createCompressRangeTool(compressToolContext),\n }),\n },\n config: async (opencodeConfig) => {\n if (\n config.compress.permission !== \"deny\" &&\n compressDisabledByOpencode(opencodeConfig.permission)\n ) {\n config.compress.permission = \"deny\"\n }\n\n if (config.commands.enabled && config.compress.permission !== \"deny\") {\n opencodeConfig.command ??= {}\n opencodeConfig.command[\"dcp\"] = {\n template: \"\",\n description: \"Show available DCP commands\",\n }\n }\n\n const toolsToAdd: string[] = []\n if (config.compress.permission !== \"deny\" && !config.experimental.allowSubAgents) {\n toolsToAdd.push(\"compress\")\n }\n\n if (toolsToAdd.length > 0) {\n const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? []\n opencodeConfig.experimental = {\n ...opencodeConfig.experimental,\n primary_tools: [...existingPrimaryTools, ...toolsToAdd],\n }\n }\n\n if (!hasExplicitToolPermission(opencodeConfig.permission, \"compress\")) {\n const permission = opencodeConfig.permission ?? {}\n opencodeConfig.permission = {\n ...permission,\n compress: config.compress.permission,\n } as typeof permission\n }\n\n hostPermissions.global = opencodeConfig.permission\n hostPermissions.agents = Object.fromEntries(\n Object.entries(opencodeConfig.agent ?? {}).map(([name, agent]) => [\n name,\n agent?.permission,\n ]),\n )\n },\n }\n}) satisfies Plugin\n\nexport default server\n"],"mappings":"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BAAeA,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;AAC3C,EAAAA,gBAAeA,gBAAe,GAA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","names":["value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","parse","countTokens","existsSync","homedir","join","countTokens","join","homedir","existsSync","MAX_TIMING_ENTRIES","TIMING_TTL_MS","tool","tool","tool","countTokens","truncate","countTokens","tool","validateArgs","buildSchema","tool","validateArgs","countTokens","tool","writeFile","mkdir","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","availableMessageIdGuidance","countTokens","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","message","state","readFile","dirname","join","prefix","base"]}
|