opencode-acp 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/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/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/gc/truncate.ts","../lib/hooks.ts","../lib/auth.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, copyFileSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport { parse } from \"jsonc-parser/lib/esm/main.js\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype Permission = \"ask\" | \"allow\" | \"deny\"\ntype CompressMode = \"range\" | \"message\"\n\nexport interface Deduplication {\n enabled: boolean\n protectedTools: string[]\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}\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 GCConfig {\n algorithm: \"truncate\"\n promotionThreshold: number\n maxBlockAge: number\n maxOldGenSummaryLength: number\n majorGcThresholdPercent: number | `${number}%`\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 gc: GCConfig\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 \"gc\",\n \"gc.algorithm\",\n \"gc.promotionThreshold\",\n \"gc.maxBlockAge\",\n \"gc.maxOldGenSummaryLength\",\n \"gc.majorGcThresholdPercent\",\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 (\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 gc = config.gc\n if (gc !== undefined) {\n if (typeof gc !== \"object\" || gc === null || Array.isArray(gc)) {\n errors.push({\n key: \"gc\",\n expected: \"object\",\n actual: typeof gc,\n })\n } else {\n if (gc.algorithm !== undefined && gc.algorithm !== \"truncate\") {\n errors.push({\n key: \"gc.algorithm\",\n expected: '\"truncate\"',\n actual: JSON.stringify(gc.algorithm),\n })\n }\n if (gc.promotionThreshold !== undefined && typeof gc.promotionThreshold !== \"number\") {\n errors.push({\n key: \"gc.promotionThreshold\",\n expected: \"number\",\n actual: typeof gc.promotionThreshold,\n })\n }\n if (gc.maxBlockAge !== undefined && typeof gc.maxBlockAge !== \"number\") {\n errors.push({\n key: \"gc.maxBlockAge\",\n expected: \"number\",\n actual: typeof gc.maxBlockAge,\n })\n }\n if (gc.maxOldGenSummaryLength !== undefined && typeof gc.maxOldGenSummaryLength !== \"number\") {\n errors.push({\n key: \"gc.maxOldGenSummaryLength\",\n expected: \"number\",\n actual: typeof gc.maxOldGenSummaryLength,\n })\n }\n if (gc.majorGcThresholdPercent !== undefined) {\n const isValidNumber = typeof gc.majorGcThresholdPercent === \"number\"\n const isPercentString = typeof gc.majorGcThresholdPercent === \"string\" && gc.majorGcThresholdPercent.endsWith(\"%\")\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key: \"gc.majorGcThresholdPercent\",\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(gc.majorGcThresholdPercent),\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: `ACP: ${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: 100000,\n minContextLimit: 50000,\n nudgeFrequency: 5,\n iterationNudgeThreshold: 15,\n nudgeForce: \"soft\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n },\n strategies: {\n deduplication: {\n enabled: true,\n protectedTools: [],\n },\n purgeErrors: {\n enabled: true,\n turns: 4,\n protectedTools: [],\n },\n },\n gc: {\n algorithm: \"truncate\",\n promotionThreshold: 5,\n maxBlockAge: 15,\n maxOldGenSummaryLength: 3000,\n majorGcThresholdPercent: \"55%\",\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, \"acp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"acp.json\")\nconst LEGACY_GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst LEGACY_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 : existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)\n ? LEGACY_GLOBAL_CONFIG_PATH_JSONC\n : existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)\n ? LEGACY_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, \"acp.jsonc\")\n const configJson = join(opencodeConfigDir, \"acp.json\")\n const legacyJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const legacyJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : existsSync(legacyJsonc)\n ? legacyJsonc\n : existsSync(legacyJson)\n ? legacyJson\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, \"acp.jsonc\")\n const projectJson = join(opencodeDir, \"acp.json\")\n const legacyJsonc = join(opencodeDir, \"dcp.jsonc\")\n const legacyJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : existsSync(legacyJsonc)\n ? legacyJsonc\n : existsSync(legacyJson)\n ? legacyJson\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 if (!existsSync(GLOBAL_CONFIG_PATH_JSONC)) {\n if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.jsonc to acp.jsonc\")\n } else if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSON, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.json to acp.jsonc\")\n } else {\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n }\n }\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 }\n}\n\nfunction mergeCommands(\n base: PluginConfig[\"commands\"],\n override?: Partial<PluginConfig[\"commands\"]>,\n): PluginConfig[\"commands\"] {\n if (!override) {\n return base\n }\n\n return {\n enabled: override.enabled ?? base.enabled,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n }\n}\n\nfunction mergeManualMode(\n base: PluginConfig[\"manualMode\"],\n override?: Partial<PluginConfig[\"manualMode\"]>,\n): PluginConfig[\"manualMode\"] {\n if (override === undefined) return base\n\n return {\n enabled: override.enabled ?? base.enabled,\n automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (override === undefined) return base\n\n return {\n allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,\n customPrompts: override.customPrompts ?? base.customPrompts,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: {\n enabled: config.commands.enabled,\n protectedTools: [...config.commands.protectedTools],\n },\n manualMode: {\n enabled: config.manualMode.enabled,\n automaticStrategies: config.manualMode.automaticStrategies,\n },\n turnProtection: { ...config.turnProtection },\n experimental: { ...config.experimental },\n protectedFilePatterns: [...config.protectedFilePatterns],\n compress: {\n ...config.compress,\n modelMaxLimits: { ...config.compress.modelMaxLimits },\n modelMinLimits: { ...config.compress.modelMinLimits },\n protectedTools: [...config.compress.protectedTools],\n },\n strategies: {\n deduplication: {\n ...config.strategies.deduplication,\n protectedTools: [...config.strategies.deduplication.protectedTools],\n },\n purgeErrors: {\n ...config.strategies.purgeErrors,\n protectedTools: [...config.strategies.purgeErrors.protectedTools],\n },\n },\n gc: { ...config.gc },\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 gc: { ...config.gc, ...(data.gc as Partial<GCConfig>) },\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 // Migration: dcp.jsonc → acp.jsonc (must run before createDefaultConfig check)\n if (!existsSync(GLOBAL_CONFIG_PATH_JSONC) && !existsSync(GLOBAL_CONFIG_PATH_JSON)) {\n if (existsSync(GLOBAL_CONFIG_DIR) || existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC) || existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.jsonc to acp.jsonc\")\n } else if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSON, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.json to acp.jsonc\")\n }\n }\n }\n\n if (!configPaths.global && !existsSync(GLOBAL_CONFIG_PATH_JSONC)) {\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 `ACP: Invalid ${layer.name}`,\n `${layer.path}\\n${result.parseError}\\nUsing previous/default values`,\n )\n continue\n }\n\n if (!result.data) {\n continue\n }\n\n showConfigWarnings(ctx, layer.path, result.data, layer.isProject)\n config = mergeLayer(config, result.data)\n }\n\n return config\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport function createScanner(text, ignoreTrivia = false) {\n const len = text.length;\n let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;\n function scanHexDigits(count, exact) {\n let digits = 0;\n let value = 0;\n while (digits < count || !exact) {\n let ch = text.charCodeAt(pos);\n if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {\n value = value * 16 + ch - 48 /* CharacterCodes._0 */;\n }\n else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {\n value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;\n }\n else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {\n value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;\n }\n else {\n break;\n }\n pos++;\n digits++;\n }\n if (digits < count) {\n value = -1;\n }\n return value;\n }\n function setPosition(newPosition) {\n pos = newPosition;\n value = '';\n tokenOffset = 0;\n token = 16 /* SyntaxKind.Unknown */;\n scanError = 0 /* ScanError.None */;\n }\n function scanNumber() {\n let start = pos;\n if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {\n pos++;\n }\n else {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {\n pos++;\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n return text.substring(start, pos);\n }\n }\n let end = pos;\n if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {\n pos++;\n if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) {\n pos++;\n }\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n end = pos;\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n }\n }\n return text.substring(start, end);\n }\n function scanString() {\n let result = '', start = pos;\n while (true) {\n if (pos >= len) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch = text.charCodeAt(pos);\n if (ch === 34 /* CharacterCodes.doubleQuote */) {\n result += text.substring(start, pos);\n pos++;\n break;\n }\n if (ch === 92 /* CharacterCodes.backslash */) {\n result += text.substring(start, pos);\n pos++;\n if (pos >= len) {\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch2 = text.charCodeAt(pos++);\n switch (ch2) {\n case 34 /* CharacterCodes.doubleQuote */:\n result += '\\\"';\n break;\n case 92 /* CharacterCodes.backslash */:\n result += '\\\\';\n break;\n case 47 /* CharacterCodes.slash */:\n result += '/';\n break;\n case 98 /* CharacterCodes.b */:\n result += '\\b';\n break;\n case 102 /* CharacterCodes.f */:\n result += '\\f';\n break;\n case 110 /* CharacterCodes.n */:\n result += '\\n';\n break;\n case 114 /* CharacterCodes.r */:\n result += '\\r';\n break;\n case 116 /* CharacterCodes.t */:\n result += '\\t';\n break;\n case 117 /* CharacterCodes.u */:\n const ch3 = scanHexDigits(4, true);\n if (ch3 >= 0) {\n result += String.fromCharCode(ch3);\n }\n else {\n scanError = 4 /* ScanError.InvalidUnicode */;\n }\n break;\n default:\n scanError = 5 /* ScanError.InvalidEscapeCharacter */;\n }\n start = pos;\n continue;\n }\n if (ch >= 0 && ch <= 0x1f) {\n if (isLineBreak(ch)) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n else {\n scanError = 6 /* ScanError.InvalidCharacter */;\n // mark as error but continue with string\n }\n }\n pos++;\n }\n return result;\n }\n function scanNext() {\n value = '';\n scanError = 0 /* ScanError.None */;\n tokenOffset = pos;\n lineStartOffset = lineNumber;\n prevTokenLineStartOffset = tokenLineStartOffset;\n if (pos >= len) {\n // at the end\n tokenOffset = len;\n return token = 17 /* SyntaxKind.EOF */;\n }\n let code = text.charCodeAt(pos);\n // trivia: whitespace\n if (isWhiteSpace(code)) {\n do {\n pos++;\n value += String.fromCharCode(code);\n code = text.charCodeAt(pos);\n } while (isWhiteSpace(code));\n return token = 15 /* SyntaxKind.Trivia */;\n }\n // trivia: newlines\n if (isLineBreak(code)) {\n pos++;\n value += String.fromCharCode(code);\n if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n value += '\\n';\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n return token = 14 /* SyntaxKind.LineBreakTrivia */;\n }\n switch (code) {\n // tokens: []{}:,\n case 123 /* CharacterCodes.openBrace */:\n pos++;\n return token = 1 /* SyntaxKind.OpenBraceToken */;\n case 125 /* CharacterCodes.closeBrace */:\n pos++;\n return token = 2 /* SyntaxKind.CloseBraceToken */;\n case 91 /* CharacterCodes.openBracket */:\n pos++;\n return token = 3 /* SyntaxKind.OpenBracketToken */;\n case 93 /* CharacterCodes.closeBracket */:\n pos++;\n return token = 4 /* SyntaxKind.CloseBracketToken */;\n case 58 /* CharacterCodes.colon */:\n pos++;\n return token = 6 /* SyntaxKind.ColonToken */;\n case 44 /* CharacterCodes.comma */:\n pos++;\n return token = 5 /* SyntaxKind.CommaToken */;\n // strings\n case 34 /* CharacterCodes.doubleQuote */:\n pos++;\n value = scanString();\n return token = 10 /* SyntaxKind.StringLiteral */;\n // comments\n case 47 /* CharacterCodes.slash */:\n const start = pos - 1;\n // Single-line comment\n if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n while (pos < len) {\n if (isLineBreak(text.charCodeAt(pos))) {\n break;\n }\n pos++;\n }\n value = text.substring(start, pos);\n return token = 12 /* SyntaxKind.LineCommentTrivia */;\n }\n // Multi-line comment\n if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {\n pos += 2;\n const safeLength = len - 1; // For lookahead.\n let commentClosed = false;\n while (pos < safeLength) {\n const ch = text.charCodeAt(pos);\n if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n commentClosed = true;\n break;\n }\n pos++;\n if (isLineBreak(ch)) {\n if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n }\n }\n if (!commentClosed) {\n pos++;\n scanError = 1 /* ScanError.UnexpectedEndOfComment */;\n }\n value = text.substring(start, pos);\n return token = 13 /* SyntaxKind.BlockCommentTrivia */;\n }\n // just a single slash\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n // numbers\n case 45 /* CharacterCodes.minus */:\n value += String.fromCharCode(code);\n pos++;\n if (pos === len || !isDigit(text.charCodeAt(pos))) {\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // found a minus, followed by a number so\n // we fall through to proceed with scanning\n // numbers\n case 48 /* CharacterCodes._0 */:\n case 49 /* CharacterCodes._1 */:\n case 50 /* CharacterCodes._2 */:\n case 51 /* CharacterCodes._3 */:\n case 52 /* CharacterCodes._4 */:\n case 53 /* CharacterCodes._5 */:\n case 54 /* CharacterCodes._6 */:\n case 55 /* CharacterCodes._7 */:\n case 56 /* CharacterCodes._8 */:\n case 57 /* CharacterCodes._9 */:\n value += scanNumber();\n return token = 11 /* SyntaxKind.NumericLiteral */;\n // literals and unknown symbols\n default:\n // is a literal? Read the full word.\n while (pos < len && isUnknownContentCharacter(code)) {\n pos++;\n code = text.charCodeAt(pos);\n }\n if (tokenOffset !== pos) {\n value = text.substring(tokenOffset, pos);\n // keywords: true, false, null\n switch (value) {\n case 'true': return token = 8 /* SyntaxKind.TrueKeyword */;\n case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;\n case 'null': return token = 7 /* SyntaxKind.NullKeyword */;\n }\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // some\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n }\n }\n function isUnknownContentCharacter(code) {\n if (isWhiteSpace(code) || isLineBreak(code)) {\n return false;\n }\n switch (code) {\n case 125 /* CharacterCodes.closeBrace */:\n case 93 /* CharacterCodes.closeBracket */:\n case 123 /* CharacterCodes.openBrace */:\n case 91 /* CharacterCodes.openBracket */:\n case 34 /* CharacterCodes.doubleQuote */:\n case 58 /* CharacterCodes.colon */:\n case 44 /* CharacterCodes.comma */:\n case 47 /* CharacterCodes.slash */:\n return false;\n }\n return true;\n }\n function scanNextNonTrivia() {\n let result;\n do {\n result = scanNext();\n } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);\n return result;\n }\n return {\n setPosition: setPosition,\n getPosition: () => pos,\n scan: ignoreTrivia ? scanNextNonTrivia : scanNext,\n getToken: () => token,\n getTokenValue: () => value,\n getTokenOffset: () => tokenOffset,\n getTokenLength: () => pos - tokenOffset,\n getTokenStartLine: () => lineStartOffset,\n getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,\n getTokenError: () => scanError,\n };\n}\nfunction isWhiteSpace(ch) {\n return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;\n}\nfunction isLineBreak(ch) {\n return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;\n}\nfunction isDigit(ch) {\n return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;\n}\nvar CharacterCodes;\n(function (CharacterCodes) {\n CharacterCodes[CharacterCodes[\"lineFeed\"] = 10] = \"lineFeed\";\n CharacterCodes[CharacterCodes[\"carriageReturn\"] = 13] = \"carriageReturn\";\n CharacterCodes[CharacterCodes[\"space\"] = 32] = \"space\";\n CharacterCodes[CharacterCodes[\"_0\"] = 48] = \"_0\";\n CharacterCodes[CharacterCodes[\"_1\"] = 49] = \"_1\";\n CharacterCodes[CharacterCodes[\"_2\"] = 50] = \"_2\";\n CharacterCodes[CharacterCodes[\"_3\"] = 51] = \"_3\";\n CharacterCodes[CharacterCodes[\"_4\"] = 52] = \"_4\";\n CharacterCodes[CharacterCodes[\"_5\"] = 53] = \"_5\";\n CharacterCodes[CharacterCodes[\"_6\"] = 54] = \"_6\";\n CharacterCodes[CharacterCodes[\"_7\"] = 55] = \"_7\";\n CharacterCodes[CharacterCodes[\"_8\"] = 56] = \"_8\";\n CharacterCodes[CharacterCodes[\"_9\"] = 57] = \"_9\";\n CharacterCodes[CharacterCodes[\"a\"] = 97] = \"a\";\n CharacterCodes[CharacterCodes[\"b\"] = 98] = \"b\";\n CharacterCodes[CharacterCodes[\"c\"] = 99] = \"c\";\n CharacterCodes[CharacterCodes[\"d\"] = 100] = \"d\";\n CharacterCodes[CharacterCodes[\"e\"] = 101] = \"e\";\n CharacterCodes[CharacterCodes[\"f\"] = 102] = \"f\";\n CharacterCodes[CharacterCodes[\"g\"] = 103] = \"g\";\n CharacterCodes[CharacterCodes[\"h\"] = 104] = \"h\";\n CharacterCodes[CharacterCodes[\"i\"] = 105] = \"i\";\n CharacterCodes[CharacterCodes[\"j\"] = 106] = \"j\";\n CharacterCodes[CharacterCodes[\"k\"] = 107] = \"k\";\n CharacterCodes[CharacterCodes[\"l\"] = 108] = \"l\";\n CharacterCodes[CharacterCodes[\"m\"] = 109] = \"m\";\n CharacterCodes[CharacterCodes[\"n\"] = 110] = \"n\";\n CharacterCodes[CharacterCodes[\"o\"] = 111] = \"o\";\n CharacterCodes[CharacterCodes[\"p\"] = 112] = \"p\";\n CharacterCodes[CharacterCodes[\"q\"] = 113] = \"q\";\n CharacterCodes[CharacterCodes[\"r\"] = 114] = \"r\";\n CharacterCodes[CharacterCodes[\"s\"] = 115] = \"s\";\n CharacterCodes[CharacterCodes[\"t\"] = 116] = \"t\";\n CharacterCodes[CharacterCodes[\"u\"] = 117] = \"u\";\n CharacterCodes[CharacterCodes[\"v\"] = 118] = \"v\";\n CharacterCodes[CharacterCodes[\"w\"] = 119] = \"w\";\n CharacterCodes[CharacterCodes[\"x\"] = 120] = \"x\";\n CharacterCodes[CharacterCodes[\"y\"] = 121] = \"y\";\n CharacterCodes[CharacterCodes[\"z\"] = 122] = \"z\";\n CharacterCodes[CharacterCodes[\"A\"] = 65] = \"A\";\n CharacterCodes[CharacterCodes[\"B\"] = 66] = \"B\";\n CharacterCodes[CharacterCodes[\"C\"] = 67] = \"C\";\n CharacterCodes[CharacterCodes[\"D\"] = 68] = \"D\";\n CharacterCodes[CharacterCodes[\"E\"] = 69] = \"E\";\n CharacterCodes[CharacterCodes[\"F\"] = 70] = \"F\";\n CharacterCodes[CharacterCodes[\"G\"] = 71] = \"G\";\n CharacterCodes[CharacterCodes[\"H\"] = 72] = \"H\";\n CharacterCodes[CharacterCodes[\"I\"] = 73] = \"I\";\n CharacterCodes[CharacterCodes[\"J\"] = 74] = \"J\";\n CharacterCodes[CharacterCodes[\"K\"] = 75] = \"K\";\n CharacterCodes[CharacterCodes[\"L\"] = 76] = \"L\";\n CharacterCodes[CharacterCodes[\"M\"] = 77] = \"M\";\n CharacterCodes[CharacterCodes[\"N\"] = 78] = \"N\";\n CharacterCodes[CharacterCodes[\"O\"] = 79] = \"O\";\n CharacterCodes[CharacterCodes[\"P\"] = 80] = \"P\";\n CharacterCodes[CharacterCodes[\"Q\"] = 81] = \"Q\";\n CharacterCodes[CharacterCodes[\"R\"] = 82] = \"R\";\n CharacterCodes[CharacterCodes[\"S\"] = 83] = \"S\";\n CharacterCodes[CharacterCodes[\"T\"] = 84] = \"T\";\n CharacterCodes[CharacterCodes[\"U\"] = 85] = \"U\";\n CharacterCodes[CharacterCodes[\"V\"] = 86] = \"V\";\n CharacterCodes[CharacterCodes[\"W\"] = 87] = \"W\";\n CharacterCodes[CharacterCodes[\"X\"] = 88] = \"X\";\n CharacterCodes[CharacterCodes[\"Y\"] = 89] = \"Y\";\n CharacterCodes[CharacterCodes[\"Z\"] = 90] = \"Z\";\n CharacterCodes[CharacterCodes[\"asterisk\"] = 42] = \"asterisk\";\n CharacterCodes[CharacterCodes[\"backslash\"] = 92] = \"backslash\";\n CharacterCodes[CharacterCodes[\"closeBrace\"] = 125] = \"closeBrace\";\n CharacterCodes[CharacterCodes[\"closeBracket\"] = 93] = \"closeBracket\";\n CharacterCodes[CharacterCodes[\"colon\"] = 58] = \"colon\";\n CharacterCodes[CharacterCodes[\"comma\"] = 44] = \"comma\";\n CharacterCodes[CharacterCodes[\"dot\"] = 46] = \"dot\";\n CharacterCodes[CharacterCodes[\"doubleQuote\"] = 34] = \"doubleQuote\";\n CharacterCodes[CharacterCodes[\"minus\"] = 45] = \"minus\";\n CharacterCodes[CharacterCodes[\"openBrace\"] = 123] = \"openBrace\";\n CharacterCodes[CharacterCodes[\"openBracket\"] = 91] = \"openBracket\";\n CharacterCodes[CharacterCodes[\"plus\"] = 43] = \"plus\";\n CharacterCodes[CharacterCodes[\"slash\"] = 47] = \"slash\";\n CharacterCodes[CharacterCodes[\"formFeed\"] = 12] = \"formFeed\";\n CharacterCodes[CharacterCodes[\"tab\"] = 9] = \"tab\";\n})(CharacterCodes || (CharacterCodes = {}));\n","export const cachedSpaces = new Array(20).fill(0).map((_, index) => {\n return ' '.repeat(index);\n});\nconst maxCachedValues = 200;\nexport const cachedBreakLinesWithSpaces = {\n ' ': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + ' '.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + ' '.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + ' '.repeat(index);\n }),\n },\n '\\t': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + '\\t'.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + '\\t'.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + '\\t'.repeat(index);\n }),\n }\n};\nexport const supportedEols = ['\\n', '\\r', '\\r\\n'];\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nvar ParseOptions;\n(function (ParseOptions) {\n ParseOptions.DEFAULT = {\n allowTrailingComma: false\n };\n})(ParseOptions || (ParseOptions = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport function getLocation(text, position) {\n const segments = []; // strings or numbers\n const earlyReturnException = new Object();\n let previousNode = undefined;\n const previousNodeInst = {\n value: {},\n offset: 0,\n length: 0,\n type: 'object',\n parent: undefined\n };\n let isAtPropertyKey = false;\n function setPreviousNode(value, offset, length, type) {\n previousNodeInst.value = value;\n previousNodeInst.offset = offset;\n previousNodeInst.length = length;\n previousNodeInst.type = type;\n previousNodeInst.colonOffset = undefined;\n previousNode = previousNodeInst;\n }\n try {\n visit(text, {\n onObjectBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n isAtPropertyKey = position > offset;\n segments.push(''); // push a placeholder (will be replaced)\n },\n onObjectProperty: (name, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(name, offset, length, 'property');\n segments[segments.length - 1] = name;\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onObjectEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onArrayBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.push(0);\n },\n onArrayEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onLiteralValue: (value, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(value, offset, length, getNodeType(value));\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onSeparator: (sep, offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n if (sep === ':' && previousNode && previousNode.type === 'property') {\n previousNode.colonOffset = offset;\n isAtPropertyKey = false;\n previousNode = undefined;\n }\n else if (sep === ',') {\n const last = segments[segments.length - 1];\n if (typeof last === 'number') {\n segments[segments.length - 1] = last + 1;\n }\n else {\n isAtPropertyKey = true;\n segments[segments.length - 1] = '';\n }\n previousNode = undefined;\n }\n }\n });\n }\n catch (e) {\n if (e !== earlyReturnException) {\n throw e;\n }\n }\n return {\n path: segments,\n previousNode,\n isAtPropertyKey,\n matches: (pattern) => {\n let k = 0;\n for (let i = 0; k < pattern.length && i < segments.length; i++) {\n if (pattern[k] === segments[i] || pattern[k] === '*') {\n k++;\n }\n else if (pattern[k] !== '**') {\n return false;\n }\n }\n return k === pattern.length;\n }\n };\n}\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore always check the errors list to find out if the input was valid.\n */\nexport function parse(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentProperty = null;\n let currentParent = [];\n const previousParents = [];\n function onValue(value) {\n if (Array.isArray(currentParent)) {\n currentParent.push(value);\n }\n else if (currentProperty !== null) {\n currentParent[currentProperty] = value;\n }\n }\n const visitor = {\n onObjectBegin: () => {\n const object = {};\n onValue(object);\n previousParents.push(currentParent);\n currentParent = object;\n currentProperty = null;\n },\n onObjectProperty: (name) => {\n currentProperty = name;\n },\n onObjectEnd: () => {\n currentParent = previousParents.pop();\n },\n onArrayBegin: () => {\n const array = [];\n onValue(array);\n previousParents.push(currentParent);\n currentParent = array;\n currentProperty = null;\n },\n onArrayEnd: () => {\n currentParent = previousParents.pop();\n },\n onLiteralValue: onValue,\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n return currentParent[0];\n}\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root\n function ensurePropertyComplete(endOffset) {\n if (currentParent.type === 'property') {\n currentParent.length = endOffset - currentParent.offset;\n currentParent = currentParent.parent;\n }\n }\n function onValue(valueNode) {\n currentParent.children.push(valueNode);\n return valueNode;\n }\n const visitor = {\n onObjectBegin: (offset) => {\n currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });\n },\n onObjectProperty: (name, offset, length) => {\n currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });\n currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent });\n },\n onObjectEnd: (offset, length) => {\n ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onArrayBegin: (offset, length) => {\n currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });\n },\n onArrayEnd: (offset, length) => {\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onLiteralValue: (value, offset, length) => {\n onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });\n ensurePropertyComplete(offset + length);\n },\n onSeparator: (sep, offset, length) => {\n if (currentParent.type === 'property') {\n if (sep === ':') {\n currentParent.colonOffset = offset;\n }\n else if (sep === ',') {\n ensurePropertyComplete(offset);\n }\n }\n },\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n const result = currentParent.children[0];\n if (result) {\n delete result.parent;\n }\n return result;\n}\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport function findNodeAtLocation(root, path) {\n if (!root) {\n return undefined;\n }\n let node = root;\n for (let segment of path) {\n if (typeof segment === 'string') {\n if (node.type !== 'object' || !Array.isArray(node.children)) {\n return undefined;\n }\n let found = false;\n for (const propertyNode of node.children) {\n if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {\n node = propertyNode.children[1];\n found = true;\n break;\n }\n }\n if (!found) {\n return undefined;\n }\n }\n else {\n const index = segment;\n if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {\n return undefined;\n }\n node = node.children[index];\n }\n }\n return node;\n}\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport function getNodePath(node) {\n if (!node.parent || !node.parent.children) {\n return [];\n }\n const path = getNodePath(node.parent);\n if (node.parent.type === 'property') {\n const key = node.parent.children[0].value;\n path.push(key);\n }\n else if (node.parent.type === 'array') {\n const index = node.parent.children.indexOf(node);\n if (index !== -1) {\n path.push(index);\n }\n }\n return path;\n}\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport function getNodeValue(node) {\n switch (node.type) {\n case 'array':\n return node.children.map(getNodeValue);\n case 'object':\n const obj = Object.create(null);\n for (let prop of node.children) {\n const valueNode = prop.children[1];\n if (valueNode) {\n obj[prop.children[0].value] = getNodeValue(valueNode);\n }\n }\n return obj;\n case 'null':\n case 'string':\n case 'number':\n case 'boolean':\n return node.value;\n default:\n return undefined;\n }\n}\nexport function contains(node, offset, includeRightBound = false) {\n return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));\n}\n/**\n * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport function findNodeAtOffset(node, offset, includeRightBound = false) {\n if (contains(node, offset, includeRightBound)) {\n const children = node.children;\n if (Array.isArray(children)) {\n for (let i = 0; i < children.length && children[i].offset <= offset; i++) {\n const item = findNodeAtOffset(children[i], offset, includeRightBound);\n if (item) {\n return item;\n }\n }\n }\n return node;\n }\n return undefined;\n}\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport function visit(text, visitor, options = ParseOptions.DEFAULT) {\n const _scanner = createScanner(text, false);\n // Important: Only pass copies of this to visitor functions to prevent accidental modification, and\n // to not affect visitor functions which stored a reference to a previous JSONPath\n const _jsonPath = [];\n // Depth of onXXXBegin() callbacks suppressed. onXXXEnd() decrements this if it isn't 0 already.\n // Callbacks are only called when this value is 0.\n let suppressedCallbacks = 0;\n function toNoArgVisit(visitFunction) {\n return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisit(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisitWithPath(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;\n }\n function toBeginVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks++;\n }\n else {\n let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());\n if (cbReturn === false) {\n suppressedCallbacks = 1;\n }\n }\n }\n : () => true;\n }\n function toEndVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks--;\n }\n if (suppressedCallbacks === 0) {\n visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());\n }\n }\n : () => true;\n }\n const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);\n const disallowComments = options && options.disallowComments;\n const allowTrailingComma = options && options.allowTrailingComma;\n function scanNext() {\n while (true) {\n const token = _scanner.scan();\n switch (_scanner.getTokenError()) {\n case 4 /* ScanError.InvalidUnicode */:\n handleError(14 /* ParseErrorCode.InvalidUnicode */);\n break;\n case 5 /* ScanError.InvalidEscapeCharacter */:\n handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */);\n break;\n case 3 /* ScanError.UnexpectedEndOfNumber */:\n handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */);\n break;\n case 1 /* ScanError.UnexpectedEndOfComment */:\n if (!disallowComments) {\n handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */);\n }\n break;\n case 2 /* ScanError.UnexpectedEndOfString */:\n handleError(12 /* ParseErrorCode.UnexpectedEndOfString */);\n break;\n case 6 /* ScanError.InvalidCharacter */:\n handleError(16 /* ParseErrorCode.InvalidCharacter */);\n break;\n }\n switch (token) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (disallowComments) {\n handleError(10 /* ParseErrorCode.InvalidCommentToken */);\n }\n else {\n onComment();\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n handleError(1 /* ParseErrorCode.InvalidSymbol */);\n break;\n case 15 /* SyntaxKind.Trivia */:\n case 14 /* SyntaxKind.LineBreakTrivia */:\n break;\n default:\n return token;\n }\n }\n }\n function handleError(error, skipUntilAfter = [], skipUntil = []) {\n onError(error);\n if (skipUntilAfter.length + skipUntil.length > 0) {\n let token = _scanner.getToken();\n while (token !== 17 /* SyntaxKind.EOF */) {\n if (skipUntilAfter.indexOf(token) !== -1) {\n scanNext();\n break;\n }\n else if (skipUntil.indexOf(token) !== -1) {\n break;\n }\n token = scanNext();\n }\n }\n }\n function parseString(isValue) {\n const value = _scanner.getTokenValue();\n if (isValue) {\n onLiteralValue(value);\n }\n else {\n onObjectProperty(value);\n // add property name afterwards\n _jsonPath.push(value);\n }\n scanNext();\n return true;\n }\n function parseLiteral() {\n switch (_scanner.getToken()) {\n case 11 /* SyntaxKind.NumericLiteral */:\n const tokenValue = _scanner.getTokenValue();\n let value = Number(tokenValue);\n if (isNaN(value)) {\n handleError(2 /* ParseErrorCode.InvalidNumberFormat */);\n value = 0;\n }\n onLiteralValue(value);\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n onLiteralValue(null);\n break;\n case 8 /* SyntaxKind.TrueKeyword */:\n onLiteralValue(true);\n break;\n case 9 /* SyntaxKind.FalseKeyword */:\n onLiteralValue(false);\n break;\n default:\n return false;\n }\n scanNext();\n return true;\n }\n function parseProperty() {\n if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) {\n handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n return false;\n }\n parseString(false);\n if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) {\n onSeparator(':');\n scanNext(); // consume colon\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n }\n else {\n handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n _jsonPath.pop(); // remove processed property name\n return true;\n }\n function parseObject() {\n onObjectBegin();\n scanNext(); // consume open brace\n let needsComma = false;\n while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (!parseProperty()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onObjectEnd();\n if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) {\n handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []);\n }\n else {\n scanNext(); // consume close brace\n }\n return true;\n }\n function parseArray() {\n onArrayBegin();\n scanNext(); // consume open bracket\n let isFirstElement = true;\n let needsComma = false;\n while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (isFirstElement) {\n _jsonPath.push(0);\n isFirstElement = false;\n }\n else {\n _jsonPath[_jsonPath.length - 1]++;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onArrayEnd();\n if (!isFirstElement) {\n _jsonPath.pop(); // remove array index\n }\n if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) {\n handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []);\n }\n else {\n scanNext(); // consume close bracket\n }\n return true;\n }\n function parseValue() {\n switch (_scanner.getToken()) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n return parseArray();\n case 1 /* SyntaxKind.OpenBraceToken */:\n return parseObject();\n case 10 /* SyntaxKind.StringLiteral */:\n return parseString(true);\n default:\n return parseLiteral();\n }\n }\n scanNext();\n if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) {\n if (options.allowEmptyContent) {\n return true;\n }\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []);\n }\n return true;\n}\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport function stripComments(text, replaceCh) {\n let _scanner = createScanner(text), parts = [], kind, offset = 0, pos;\n do {\n pos = _scanner.getPosition();\n kind = _scanner.scan();\n switch (kind) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n case 17 /* SyntaxKind.EOF */:\n if (offset !== pos) {\n parts.push(text.substring(offset, pos));\n }\n if (replaceCh !== undefined) {\n parts.push(_scanner.getTokenValue().replace(/[^\\r\\n]/g, replaceCh));\n }\n offset = _scanner.getPosition();\n break;\n }\n } while (kind !== 17 /* SyntaxKind.EOF */);\n return parts.join('');\n}\nexport function getNodeType(value) {\n switch (typeof value) {\n case 'boolean': return 'boolean';\n case 'number': return 'number';\n case 'string': return 'string';\n case 'object': {\n if (!value) {\n return 'null';\n }\n else if (Array.isArray(value)) {\n return 'array';\n }\n return 'object';\n }\n default: return 'null';\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport * as formatter from './impl/format';\nimport * as edit from './impl/edit';\nimport * as scanner from './impl/scanner';\nimport * as parser from './impl/parser';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport const createScanner = scanner.createScanner;\nexport var ScanError;\n(function (ScanError) {\n ScanError[ScanError[\"None\"] = 0] = \"None\";\n ScanError[ScanError[\"UnexpectedEndOfComment\"] = 1] = \"UnexpectedEndOfComment\";\n ScanError[ScanError[\"UnexpectedEndOfString\"] = 2] = \"UnexpectedEndOfString\";\n ScanError[ScanError[\"UnexpectedEndOfNumber\"] = 3] = \"UnexpectedEndOfNumber\";\n ScanError[ScanError[\"InvalidUnicode\"] = 4] = \"InvalidUnicode\";\n ScanError[ScanError[\"InvalidEscapeCharacter\"] = 5] = \"InvalidEscapeCharacter\";\n ScanError[ScanError[\"InvalidCharacter\"] = 6] = \"InvalidCharacter\";\n})(ScanError || (ScanError = {}));\nexport var SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"OpenBraceToken\"] = 1] = \"OpenBraceToken\";\n SyntaxKind[SyntaxKind[\"CloseBraceToken\"] = 2] = \"CloseBraceToken\";\n SyntaxKind[SyntaxKind[\"OpenBracketToken\"] = 3] = \"OpenBracketToken\";\n SyntaxKind[SyntaxKind[\"CloseBracketToken\"] = 4] = \"CloseBracketToken\";\n SyntaxKind[SyntaxKind[\"CommaToken\"] = 5] = \"CommaToken\";\n SyntaxKind[SyntaxKind[\"ColonToken\"] = 6] = \"ColonToken\";\n SyntaxKind[SyntaxKind[\"NullKeyword\"] = 7] = \"NullKeyword\";\n SyntaxKind[SyntaxKind[\"TrueKeyword\"] = 8] = \"TrueKeyword\";\n SyntaxKind[SyntaxKind[\"FalseKeyword\"] = 9] = \"FalseKeyword\";\n SyntaxKind[SyntaxKind[\"StringLiteral\"] = 10] = \"StringLiteral\";\n SyntaxKind[SyntaxKind[\"NumericLiteral\"] = 11] = \"NumericLiteral\";\n SyntaxKind[SyntaxKind[\"LineCommentTrivia\"] = 12] = \"LineCommentTrivia\";\n SyntaxKind[SyntaxKind[\"BlockCommentTrivia\"] = 13] = \"BlockCommentTrivia\";\n SyntaxKind[SyntaxKind[\"LineBreakTrivia\"] = 14] = \"LineBreakTrivia\";\n SyntaxKind[SyntaxKind[\"Trivia\"] = 15] = \"Trivia\";\n SyntaxKind[SyntaxKind[\"Unknown\"] = 16] = \"Unknown\";\n SyntaxKind[SyntaxKind[\"EOF\"] = 17] = \"EOF\";\n})(SyntaxKind || (SyntaxKind = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport const getLocation = parser.getLocation;\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore, always check the errors list to find out if the input was valid.\n */\nexport const parse = parser.parse;\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport const parseTree = parser.parseTree;\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport const findNodeAtLocation = parser.findNodeAtLocation;\n/**\n * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport const findNodeAtOffset = parser.findNodeAtOffset;\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport const getNodePath = parser.getNodePath;\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport const getNodeValue = parser.getNodeValue;\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport const visit = parser.visit;\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport const stripComments = parser.stripComments;\nexport var ParseErrorCode;\n(function (ParseErrorCode) {\n ParseErrorCode[ParseErrorCode[\"InvalidSymbol\"] = 1] = \"InvalidSymbol\";\n ParseErrorCode[ParseErrorCode[\"InvalidNumberFormat\"] = 2] = \"InvalidNumberFormat\";\n ParseErrorCode[ParseErrorCode[\"PropertyNameExpected\"] = 3] = \"PropertyNameExpected\";\n ParseErrorCode[ParseErrorCode[\"ValueExpected\"] = 4] = \"ValueExpected\";\n ParseErrorCode[ParseErrorCode[\"ColonExpected\"] = 5] = \"ColonExpected\";\n ParseErrorCode[ParseErrorCode[\"CommaExpected\"] = 6] = \"CommaExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBraceExpected\"] = 7] = \"CloseBraceExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBracketExpected\"] = 8] = \"CloseBracketExpected\";\n ParseErrorCode[ParseErrorCode[\"EndOfFileExpected\"] = 9] = \"EndOfFileExpected\";\n ParseErrorCode[ParseErrorCode[\"InvalidCommentToken\"] = 10] = \"InvalidCommentToken\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfComment\"] = 11] = \"UnexpectedEndOfComment\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfString\"] = 12] = \"UnexpectedEndOfString\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfNumber\"] = 13] = \"UnexpectedEndOfNumber\";\n ParseErrorCode[ParseErrorCode[\"InvalidUnicode\"] = 14] = \"InvalidUnicode\";\n ParseErrorCode[ParseErrorCode[\"InvalidEscapeCharacter\"] = 15] = \"InvalidEscapeCharacter\";\n ParseErrorCode[ParseErrorCode[\"InvalidCharacter\"] = 16] = \"InvalidCharacter\";\n})(ParseErrorCode || (ParseErrorCode = {}));\nexport function printParseErrorCode(code) {\n switch (code) {\n case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol';\n case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat';\n case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected';\n case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected';\n case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected';\n case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected';\n case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected';\n case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected';\n case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected';\n case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken';\n case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment';\n case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString';\n case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber';\n case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode';\n case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter';\n case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter';\n }\n return '<unknown ParseErrorCode>';\n}\n/**\n * Computes the edit operations needed to format a JSON document.\n *\n * @param documentText The input text\n * @param range The range to format or `undefined` to format the full content\n * @param options The formatting options\n * @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function format(documentText, range, options) {\n return formatter.format(documentText, range, options);\n}\n/**\n * Computes the edit operations needed to modify a value in the JSON document.\n *\n * @param documentText The input text\n * @param path The path of the value to change. The path represents either to the document root, a property or an array item.\n * If the path points to an non-existing property or item, it will be created.\n * @param value The new value for the specified property or item. If the value is undefined,\n * the property or item will be removed.\n * @param options Options\n * @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function modify(text, path, value, options) {\n return edit.setProperty(text, path, value, options);\n}\n/**\n * Applies edits to an input string.\n * @param text The input text\n * @param edits Edit operations following the format described in {@linkcode EditResult}.\n * @returns The text with the applied edits.\n * @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.\n */\nexport function applyEdits(text, edits) {\n let sortedEdits = edits.slice(0).sort((a, b) => {\n const diff = a.offset - b.offset;\n if (diff === 0) {\n return a.length - b.length;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n if (e.offset + e.length <= lastModifiedOffset) {\n text = edit.applyEdit(text, e);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = e.offset;\n }\n return text;\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { MESSAGE_FORMAT_EXTENSION } 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 } from \"./types\"\n\nfunction buildSchema() {\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: tool.schema\n .string()\n .describe(\"Complete technical summary replacing that one message\"),\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\n return tool({\n description: runtimePrompts.compressMessage + MESSAGE_FORMAT_EXTENSION,\n args: buildSchema(),\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 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 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 ctx.config.gc,\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\n // [FIX Bug 17] Universal token estimation\n // opencode session.ts: adjustedInputTokens = inputTokens - cacheRead - cacheWrite\n // So: input + cacheRead + cacheWrite = prompt_tokens (total input)\n // Total context usage = prompt_tokens + output + reasoning\n return input + cacheRead + cacheWrite + output + reasoning\n }\n\n // [FIX Bug 5] fallback: estimate tokens from message content when no assistant\n // message has output tokens (first turn or after full compaction)\n let estimated = 0\n for (const m of messages) {\n const parts = Array.isArray(m.parts) ? m.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n estimated += countTokens(part.text)\n }\n }\n }\n return estimated\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","// These format schemas are kept separate from the editable compress prompts\n// so they cannot be modified via custom prompt overrides. The schemas must\n// match the tool's input validation and are not safe to change independently.\n\nexport const RANGE_FORMAT_EXTENSION = `\nTHE FORMAT OF COMPRESS\n\n\\`\\`\\`\n{\n topic: string, // Short label (3-5 words) - e.g., \"Auth System Exploration\"\n content: [ // One or more ranges to compress\n {\n startId: string, // Boundary ID at range start: mNNNN or bN\n endId: string, // Boundary ID at range end: mNNNN or bN\n summary: string // Complete technical summary replacing all content in range\n }\n ]\n}\n\\`\\`\\``\n\nexport const MESSAGE_FORMAT_EXTENSION = `\nTHE FORMAT OF COMPRESS\n\n\\`\\`\\`\n{\n topic: string, // Short label (3-5 words) for the overall batch\n content: [ // One or more messages to compress independently\n {\n messageId: string, // Raw message ID only: mNNNN (ignore metadata attributes like priority)\n topic: string, // Short label (3-5 words) for this one message summary\n summary: string // Complete technical summary replacing that one message\n }\n ]\n}\n\\`\\`\\``\n","import type { SessionState, WithParts } from \"./state\"\nimport { isIgnoredUserMessage } from \"./messages/query\"\n\nconst MESSAGE_REF_REGEX = /^m(\\d{4})$/\nconst BLOCK_REF_REGEX = /^b([1-9]\\d*)$/\nconst 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, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): 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 // [FIX Bug 29] Skip synthetic messages created by DCP\n if (rawMessageId.startsWith(\"msg_dcp_summary_\") || rawMessageId.startsWith(\"msg_dcp_text_\")) {\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\n if (parsedStartId === null) {\n issues.push(\"startId is invalid. Use an injected message ID (mNNNN) or block ID (bN).\")\n }\n\n if (parsedEndId === null) {\n issues.push(\"endId is invalid. Use an injected message ID (mNNNN) or block ID (bN).\")\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 let startReference = lookup.get(parsedStartId.ref)\n let endReference = lookup.get(parsedEndId.ref)\n\n if (!startReference) {\n issues.push(\n `startId ${parsedStartId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (!endReference) {\n issues.push(\n `endId ${parsedEndId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!startReference || !endReference) {\n throw new Error(\"Failed to resolve boundary IDs\")\n }\n\n // [FIX Bug 34] Auto-swap reversed boundaries instead of throwing.\n // Block IDs (bN) are assigned in creation order, which may not match\n // conversation order. Models naturally assume bN < bM means bN is earlier,\n // but anchor message ordering can differ. Auto-swap prevents compress failures\n // that cause models to give up without compressing.\n if (startReference.rawIndex > endReference.rawIndex) {\n [startReference, endReference] = [endReference, startReference]\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 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 return lookup\n}\n","import type { CompressionBlock, PruneMessagesState, SessionState } from \"../state\"\nimport { formatBlockRef, formatMessageIdTag } from \"../message-ids\"\nimport type { AppliedCompressionResult, CompressionStateInput, SelectionResolution } from \"./types\"\nimport type { GCConfig } from \"../config\"\n\nconst DEFAULT_PROMOTION_THRESHOLD = 5\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 gcConfig?: GCConfig,\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 survivedCount: 0,\n generation: \"young\",\n }\n\n const promotionThreshold = gcConfig?.promotionThreshold ?? DEFAULT_PROMOTION_THRESHOLD\n for (const [activeId, activeBlock] of messagesState.blocksById) {\n if (!activeBlock.active) continue\n if (consumed.includes(activeId)) continue\n activeBlock.survivedCount = (activeBlock.survivedCount || 0) + 1\n if (activeBlock.survivedCount >= promotionThreshold) {\n activeBlock.generation = \"old\"\n }\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 (typeof entry?.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary is required and must be a non-empty string`)\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 // [FIX Bug 30] Prevent model from treating compress result as conversation end\n const instruction = \"\\nIMPORTANT: This was an automatic context compression. You MUST continue your previous task exactly where you left off. Do NOT ask the user what to do next.\"\n\n if (skippedCount === 0) {\n return processedText + instruction\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}${instruction}`\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 ACP plugin.\n * Persists pruned tool IDs across sessions so they survive OpenCode restarts.\n * Storage location: ~/.local/share/opencode/storage/plugin/acp/{sessionId}.json\n */\n\nimport * as fs from \"fs/promises\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport { cpSync, existsSync as existsSyncSync } from \"fs\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { serializePruneMessagesState } from \"./utils\"\n\nconst LEGACY_STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n)\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 PersistedMessageIds {\n byRawId: Record<string, string>\n byRef: Record<string, string>\n nextRef: number\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n messageIds?: PersistedMessageIds\n lastCompaction?: number\n}\n\nconst STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"acp\",\n)\n\n/** One-time migration: copy plugin/dcp/ → plugin/acp/ if ACP dir doesn't exist yet */\nfunction migrateFromLegacyIfNeeded(logger: Logger): void {\n if (existsSyncSync(STORAGE_DIR)) return\n if (!existsSyncSync(LEGACY_STORAGE_DIR)) return\n try {\n cpSync(LEGACY_STORAGE_DIR, STORAGE_DIR, { recursive: true })\n logger.info(`[ACP] Migrated storage from ${LEGACY_STORAGE_DIR} → ${STORAGE_DIR}`)\n } catch (e: any) {\n logger.warn(`[ACP] Storage migration failed: ${e.message}`)\n }\n}\n\nasync function ensureStorageDir(logger: Logger): Promise<void> {\n if (!existsSync(STORAGE_DIR)) {\n migrateFromLegacyIfNeeded(logger)\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(logger)\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\n// [FIX Bug 6] Removed try/catch — errors now propagate to callers so they know save failed\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 state: PersistedSessionState = {\n sessionName: sessionName,\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 messageIds: {\n byRawId: Object.fromEntries(sessionState.messageIds.byRawId),\n byRef: Object.fromEntries(sessionState.messageIds.byRef),\n nextRef: sessionState.messageIds.nextRef,\n },\n lastCompaction: sessionState.lastCompaction,\n }\n\n await writePersistedSessionState(sessionState.sessionId, state, logger)\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 const persistedMessageIds = (state as any).messageIds as PersistedMessageIds | undefined\n if (persistedMessageIds) {\n ;(state as any)._persistedMessageIds = persistedMessageIds\n }\n const persistedLastCompaction = (state as any).lastCompaction as number | undefined\n if (persistedLastCompaction !== undefined) {\n ;(state as any)._persistedLastCompaction = persistedLastCompaction\n }\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\n// [FIX Bug 3] Added summary check to match getCurrentTokenUsage exclusion logic\nexport const isMessageCompacted = (state: SessionState, msg: WithParts): boolean => {\n if (!isMessageWithInfo(msg)) {\n return false\n }\n\n if (state.lastCompaction <= 0) return false\n if (msg.info.time.created < state.lastCompaction) {\n return true\n }\n if (msg.info.summary === true && 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 survivedCount:\n typeof block.survivedCount === \"number\" && Number.isFinite(block.survivedCount)\n ? Math.max(0, Math.floor(block.survivedCount))\n : 0,\n generation:\n block.generation === \"young\" || block.generation === \"old\"\n ? block.generation\n : undefined,\n })\n }\n }\n\n // [FIX Bug 11] Skip loading persisted activeBlockIds here.\n // They will be correctly rebuilt from blocksById below (lines 273-286).\n // Loading them here first caused stale IDs for blocks with active:false.\n\n if (\n persisted.activeByAnchorMessageId &&\n typeof persisted.activeByAnchorMessageId === \"object\"\n ) {\n for (const [anchorMessageId, blockId] of Object.entries(\n persisted.activeByAnchorMessageId,\n )) {\n if (typeof blockId !== \"number\" || !Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeByAnchorMessageId.set(anchorMessageId, blockId)\n }\n }\n\n for (const [blockId, block] of state.blocksById) {\n if (block.active) {\n state.activeBlockIds.add(blockId)\n if (block.anchorMessageId) {\n state.activeByAnchorMessageId.set(block.anchorMessageId, blockId)\n }\n }\n if (blockId >= state.nextBlockId) {\n state.nextBlockId = blockId + 1\n }\n if (block.runId >= state.nextRunId) {\n state.nextRunId = block.runId + 1\n }\n }\n\n return state\n}\n\nexport function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {\n const anchors = new Set<string>()\n let pendingUserMessageId: string | null = null\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n\n if (messageHasCompress(message)) {\n break\n }\n\n if (message.info.role === \"user\") {\n if (!isIgnoredUserMessage(message)) {\n pendingUserMessageId = message.info.id\n }\n continue\n }\n\n if (message.info.role === \"assistant\" && pendingUserMessageId) {\n anchors.add(message.info.id)\n anchors.add(pendingUserMessageId)\n pendingUserMessageId = null\n }\n }\n\n return anchors\n}\n\nexport function getActiveSummaryTokenUsage(state: SessionState): number {\n let total = 0\n for (const blockId of state.prune.messages.activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block || !block.active) {\n continue\n }\n total += block.summaryTokens\n }\n return total\n}\n\nexport function resetOnCompaction(state: SessionState): void {\n state.toolParameters.clear()\n state.prune.tools = new Map<string, number>()\n // [PATCH Bug 2] Preserve prune.messages (compression blocks) on compaction.\n // Only reset transient state. Compression blocks are still valid even after\n // opencode compacts — their summaries are still needed in context.\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\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)\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 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 const persistedAny = persisted as any\n if (persistedAny._persistedMessageIds) {\n state.messageIds = {\n byRawId: new Map(Object.entries(persistedAny._persistedMessageIds.byRawId || {})),\n byRef: new Map(Object.entries(persistedAny._persistedMessageIds.byRef || {})),\n nextRef: persistedAny._persistedMessageIds.nextRef || 1,\n }\n // [FIX Bug 29] Auto-cleanup stale synthetic message refs from persistence\n for (const [rawId, ref] of state.messageIds.byRawId) {\n if (rawId.startsWith(\"msg_dcp_summary_\") || rawId.startsWith(\"msg_dcp_text_\")) {\n state.messageIds.byRawId.delete(rawId)\n state.messageIds.byRef.delete(ref)\n }\n }\n }\n if (persistedAny._persistedLastCompaction !== undefined) {\n state.lastCompaction = Math.max(state.lastCompaction, persistedAny._persistedLastCompaction)\n }\n\n const applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\n // [FIX Bug 1] Always save after initialization to persist messageIds + lastCompaction\n await saveSessionState(state, logger)\n}\n","import type { SessionState, ToolStatus, WithParts } from \"./index\"\nimport type { Logger } from \"../logger\"\nimport { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"./utils\"\nimport { countToolTokens, extractToolContent } 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 // [FIX Bug 33] Use fast token estimate instead of expensive Anthropic tokenizer\n // The tokenizer takes ~50ms per call; with 500+ tools that's 25 seconds.\n // text.length / 4 is accurate enough for pruning decisions.\n const contents = extractToolContent(part)\n const rawLength = contents.reduce((sum: number, s: string) => sum + (s?.length ?? 0), 0)\n const tokenCount = Math.round(rawLength / 4)\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 [`▣ ACP | ${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\nconst NOTIFICATION_SUMMARY_MAX_CHARS = 1500\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: \"ACP: 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 let result = \"\"\n for (const entry of entries) {\n const topic =\n state.prune.messages.blocksById.get(entry.blockId)?.topic ?? \"(unknown topic)\"\n const section = `### ${topic}\\n${entry.summary}`\n if (result.length + section.length + 2 > NOTIFICATION_SUMMARY_MAX_CHARS) {\n result += `\\n\\n... and ${entries.length - entries.indexOf(entry)} more`\n break\n }\n result += (result ? \"\\n\\n\" : \"\") + section\n }\n return result\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 = `▣ ACP | ${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 const displaySummary =\n summary.length > NOTIFICATION_SUMMARY_MAX_CHARS\n ? truncateToastSummary(summary, NOTIFICATION_SUMMARY_MAX_CHARS)\n : summary\n message += `\\n→ Compression (~${summaryTokensStr}): ${displaySummary}`\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}): ${truncateToastSummary(summary, NOTIFICATION_SUMMARY_MAX_CHARS)}`,\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: \"ACP: 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 { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { RANGE_FORMAT_EXTENSION } 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 } from \"./types\"\n\nfunction buildSchema() {\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 \"Message or block ID marking the beginning of range (e.g. m0001, b2)\",\n ),\n endId: tool.schema\n .string()\n .describe(\"Message or block ID marking the end of range (e.g. m0012, b5)\"),\n summary: tool.schema\n .string()\n .describe(\"Complete technical summary replacing all content in range\"),\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\n return tool({\n description: runtimePrompts.compressRange + RANGE_FORMAT_EXTENSION,\n args: buildSchema(),\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 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 const parsedPlaceholders = parseBlockPlaceholders(plan.entry.summary)\n 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 [],\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n const mergeConsumedBlockIds = extractBoundaryConsumedBlocks(\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: mergeConsumedBlockIds,\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 ctx.config.gc,\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}.\\nIMPORTANT: This was an automatic context compression. You MUST continue your previous task exactly where you left off. Do NOT ask the user what to do next.`\n },\n })\n}\n\nfunction extractBoundaryConsumedBlocks(\n startReference: { kind: string; blockId?: number },\n endReference: { kind: string; blockId?: number },\n): number[] {\n const consumed: number[] = []\n const seen = new Set<number>()\n for (const ref of [startReference, endReference]) {\n if (ref.kind === \"compressed-block\" && ref.blockId !== undefined && !seen.has(ref.blockId)) {\n seen.add(ref.blockId)\n consumed.push(ref.blockId)\n }\n }\n return consumed\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 (typeof entry?.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary is required and must be a non-empty string`)\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 return {\n expandedSummary: summary,\n consumedBlockIds: [],\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n _missingBlockIds: number[],\n _summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n return {\n expandedSummary: summary,\n consumedBlockIds: [...consumedBlockIds],\n }\n}\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\", \"acp\")\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 if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"INFO\", component, message, data)\n }\n\n debug(message: string, data?: any) {\n if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"DEBUG\", component, message, data)\n }\n\n warn(message: string, data?: any) {\n if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"WARN\", component, message, data)\n }\n\n error(message: string, data?: any) {\n if (!this.enabled) return\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, cpSync } 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 ACP 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\", \"acp-prompts\")\n const legacyGlobalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n\n if (!existsSync(globalRoot) && existsSync(legacyGlobalRoot)) {\n try {\n cpSync(legacyGlobalRoot, globalRoot, { recursive: true })\n console.log(\"[ACP] Migrated prompts from dcp-prompts to acp-prompts\")\n } catch (e: any) {\n console.warn(`[ACP] Prompts migration failed: ${e.message}`)\n }\n }\n\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, \"acp-prompts\", \"overrides\")\n : null\n\n const opencodeDir = findOpencodeDir(workingDirectory)\n const projectOverridesDir = opencodeDir ? join(opencodeDir, \"acp-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(\"# ACP Prompt Defaults\")\n lines.push(\"\")\n lines.push(\"This directory stores the ACP 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/acp-prompts/overrides/` (project)\")\n lines.push(\"2. `$OPENCODE_CONFIG_DIR/acp-prompts/overrides/` (config dir)\")\n lines.push(\"3. `~/.config/opencode/acp-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 operate in a context-constrained environment. Manage context continuously to avoid buildup and preserve retrieval quality. Efficient context management is paramount for your agentic performance.\n\nThe ONLY tool you have for context management is \\`compress\\`. It replaces older conversation content with technical summaries you produce.\n\n\\`<dcp-message-id>\\` and \\`<dcp-system-reminder>\\` tags are environment-injected metadata. Do not output them.\n\nTHE PHILOSOPHY OF COMPRESS\n\\`compress\\` transforms conversation content into dense, high-fidelity summaries. This is not cleanup - it is crystallization. Your summary becomes the authoritative record of what transpired.\n\nThink of compression as phase transitions: raw exploration becomes refined understanding. The original context served its purpose; your summary now carries that understanding forward.\n\nCOMPRESS WHEN\n\nA section is genuinely closed and the raw conversation has served its purpose:\n\n- Research concluded and findings are clear\n- Implementation finished and verified\n- Exploration exhausted and patterns understood\n- Dead-end noise can be discarded without waiting for a whole chapter to close\n\nDO NOT COMPRESS IF\n\n- Raw context is still relevant and needed for edits or precise references\n- The target content is still actively in progress\n- You may need exact code, error messages, or file contents in the immediate next steps\n\nBefore compressing, ask: _\"Is this section closed enough to become summary-only right now?\"_\n\nEvaluate conversation signal-to-noise REGULARLY. Use \\`compress\\` deliberately with quality-first summaries. Prioritize stale content intelligently to maintain a high-signal context window that supports your agency.\n\nIt is of your responsibility to keep a sharp, high-quality context window for optimal performance.\n`\n","export const COMPRESS_RANGE = `Collapse a range in the conversation into a detailed summary.\n\nTHE SUMMARY\nYour summary must be EXHAUSTIVE. Capture file paths, function signatures, decisions made, constraints discovered, key findings... EVERYTHING that maintains context integrity. This is not a brief note - it is an authoritative record so faithful that the original conversation adds no value.\n\nUSER INTENT FIDELITY\nWhen the compressed range includes user messages, preserve the user's intent with extra care. Do not change scope, constraints, priorities, acceptance criteria, or requested outcomes.\nDirectly quote user messages when they are short enough to include safely. Direct quotes are preferred when they best preserve exact meaning.\n\nYet be LEAN. Strip away the noise: failed attempts that led nowhere, verbose tool outputs, back-and-forth exploration. What remains should be pure signal - golden nuggets of detail that preserve full understanding with zero ambiguity.\n\nCOMPRESSED BLOCK PLACEHOLDERS\nWhen the selected range includes previously compressed blocks, use this exact placeholder format when referencing one:\n\n- \\`(bN)\\`\n\nCompressed block sections in context are clearly marked with a header:\n\n- \\`[Compressed conversation section]\\`\n\nCompressed block IDs always use the \\`bN\\` form (never \\`mNNNN\\`) and are represented in the same XML metadata tag format.\n\nRules:\n\n- Include every required block placeholder exactly once.\n- Do not invent placeholders for blocks outside the selected range.\n- Treat \\`(bN)\\` placeholders as RESERVED TOKENS. Do not emit \\`(bN)\\` text anywhere except intentional placeholders.\n- If you need to mention a block in prose, use plain text like \\`compressed bN\\` (not as a placeholder).\n- Preflight check before finalizing: the set of \\`(bN)\\` placeholders in your summary must exactly match the required set, with no duplicates.\n\nThese placeholders are semantic references. They will be replaced with the full stored compressed block content when the tool processes your output.\n\nFLOW PRESERVATION WITH PLACEHOLDERS\nWhen you use compressed block placeholders, write the surrounding summary text so it still reads correctly AFTER placeholder expansion.\n\n- Treat each placeholder as a stand-in for a full conversation segment, not as a short label.\n- Ensure transitions before and after each placeholder preserve chronology and causality.\n- Do not write text that depends on the placeholder staying literal (for example, \"as noted in \\`(b2)\\`\").\n- Your final meaning must be coherent once each placeholder is replaced with its full compressed block content.\n\nBOUNDARY IDS\nYou specify boundaries by ID using the injected IDs visible in the conversation:\n\n- \\`mNNNN\\` IDs identify raw messages\n- \\`bN\\` IDs identify previously compressed blocks\n\nEach message has an ID inside XML metadata tags like \\`<dcp-message-id>...</dcp-message-id>\\`.\nThe same ID tag appears in every tool output of the message it belongs to — each unique ID identifies one complete message.\nTreat these tags as boundary metadata only, not as tool result content.\n\nRules:\n\n- Pick \\`startId\\` and \\`endId\\` directly from injected IDs in context.\n- IDs must exist in the current visible context. If you cannot see an ID in the messages above, it is stale and will fail.\n- \\`startId\\` must appear before \\`endId\\`.\n- Do not invent IDs. Use only IDs that are present in context.\n- NEVER use IDs from compressed block summaries, previous nudges, or your own memory — only IDs currently visible as XML metadata tags in the conversation.\n\nBATCHING\nWhen multiple independent ranges are ready and their boundaries do not overlap, include all of them as separate entries in the \\`content\\` array of a single tool call. Each entry should have its own \\`startId\\`, \\`endId\\`, and \\`summary\\`.\n`\n","export const COMPRESS_MESSAGE = `Collapse selected individual messages in the conversation into detailed summaries.\n\nTHE SUMMARY\nYour summary must be EXHAUSTIVE. Capture file paths, function signatures, decisions made, constraints discovered, key findings, tool outcomes, and user intent details that matter... EVERYTHING that preserves the value of the selected message after the raw message is removed.\n\nUSER INTENT FIDELITY\nWhen a selected message contains user intent, preserve that intent with extra care. Do not change scope, constraints, priorities, acceptance criteria, or requested outcomes.\nDirectly quote short user instructions when that best preserves exact meaning.\n\nYet be LEAN. Strip away the noise: failed attempts that led nowhere, verbose tool output, and repetition. What remains should be pure signal - golden nuggets of detail that preserve full understanding with zero ambiguity.\nIf a message contains no significant technical decisions, code changes, or user requirements, produce a minimal one-line summary rather than a detailed one.\n\nMESSAGE IDS\nYou specify individual raw messages by ID using the injected IDs visible in the conversation:\n\n- \\`mNNNN\\` IDs identify raw messages\n\nEach message has an ID inside XML metadata tags like \\`<dcp-message-id priority=\"high\">m0007</dcp-message-id>\\`.\nThe same ID tag appears in every tool output of the message it belongs to — each unique ID identifies one complete message.\nTreat these tags as message metadata only, not as content to summarize. Use only the inner \\`mNNNN\\` value as the \\`messageId\\`.\nThe \\`priority\\` attribute indicates relative context cost. You MUST compress high-priority messages when their full text is no longer necessary for the active task.\nIf prior compress-tool results are present, always compress and summarize them minimally only as part of a broader compression pass. Do not invoke the compress tool solely to re-compress an earlier compression result.\nMessages marked as \\`<dcp-message-id>BLOCKED</dcp-message-id>\\` cannot be compressed.\n\nRules:\n\n- Pick each \\`messageId\\` directly from injected IDs visible in context.\n- Only use raw message IDs of the form \\`mNNNN\\`.\n- Ignore XML attributes such as \\`priority\\` when copying the ID; use only the inner \\`mNNNN\\` value.\n- Do not invent IDs. Use only IDs that are present in context.\n\nBATCHING\nSelect MANY messages in a single tool call when they are safe to compress.\nEach entry should summarize exactly one message, and the tool can receive as many entries as needed in one batch.\n\nGENERAL CLEANUP\nUse the topic \"general cleanup\" for broad cleanup passes.\nDuring general cleanup, compress all medium and high-priority messages that are not relevant to the active task.\nOptimize for reducing context footprint, not for grouping messages by topic.\nDo not compress away still-active instructions, unresolved questions, or constraints that are likely to matter soon.\nPrioritize the earliest messages in the context as they will be the least relevant to the active task.\nGeneral cleanup should be done periodically between other normal compression tool passes, not as the primary form of compression.\n`\n","export const CONTEXT_LIMIT_NUDGE = `\n<system-reminder>\n⚠️ CRITICAL: Context limit reached. You MUST use the \\`compress\\` tool NOW.\n\nIf mid-atomic-operation, finish that step first, then compress immediately.\n\nHOW TO CALL COMPRESS:\n{\n \"topic\": \"Short Label\",\n \"content\": [\n {\n \"startId\": \"<ID from early in this conversation>\",\n \"endId\": \"<ID from later in this conversation>\",\n \"summary\": \"Complete technical summary of everything in the range\"\n }\n ]\n}\n\n⚠️ ID RULES — MOST COMMON CAUSE OF ERRORS:\n- ONLY use IDs you can see in <dcp-message-id> tags in the messages ABOVE.\n- Do NOT copy IDs from this example. Do NOT invent IDs.\n- Do NOT use IDs from compressed block summaries — they are stale.\n- startId must appear BEFORE endId in the conversation.\n\nSUMMARY RULES:\n- Capture ALL essential details: file paths, decisions, constraints, key findings.\n- Preserve user intent exactly. Direct-quote short user messages.\n- Prefer one large range over multiple small ones.\n- Compress OLDER resolved history first. Keep recent active work.\n</system-reminder>\n`\n","export const TURN_NUDGE = `\n<system-reminder>\nContext is getting full. Compress closed/older conversation ranges now.\n\n{\n \"topic\": \"Short Label\",\n \"content\": [{ \"startId\": \"<visible message ID>\", \"endId\": \"<visible message ID>\", \"summary\": \"...\" }]\n}\n\n⚠️ ONLY use IDs from <dcp-message-id> tags visible above. Do NOT invent or copy example IDs.\n</system-reminder>\n`\n","export const ITERATION_NUDGE = `\n<system-reminder>\nYou've been iterating for a while. If any earlier work is closed and unlikely to be referenced, compress it now.\n\n{\n \"topic\": \"Short Label\",\n \"content\": [{ \"startId\": \"<visible message ID>\", \"endId\": \"<visible message ID>\", \"summary\": \"...\" }]\n}\n\n⚠️ ONLY use IDs from <dcp-message-id> tags visible above. Do NOT invent or copy example IDs.\n</system-reminder>\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `<dcp-system-reminder>\nManual mode is enabled. Do NOT use compress unless the user has explicitly triggered it through a manual marker.\n\nOnly use the compress tool after seeing \\`<compress triggered manually>\\` in the current user instruction context.\n\nIssue exactly ONE compress tool per manual trigger. Do NOT launch multiple compress tools in parallel. Each trigger grants a single compression; after it completes, wait for the next trigger.\n\nAfter completing a manually triggered context-management action, STOP IMMEDIATELY. Do NOT continue with any task execution. End your response right after the tool use completes and wait for the next user input.\n</dcp-system-reminder>\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `<dcp-system-reminder>\nYou are operating in a subagent environment.\n\nThe initial subagent instruction is imperative and must be followed exactly.\nIt is the only user message intentionally not assigned a message ID, and therefore is not eligible for compression.\nAll subsequent messages in the session will have IDs.\n</dcp-system-reminder>\n`\n\nexport function buildProtectedToolsExtension(protectedTools: string[]): string {\n if (protectedTools.length === 0) {\n return \"\"\n }\n\n const toolList = protectedTools.map((t) => `\\`${t}\\``).join(\", \")\n return `<dcp-system-reminder>\nThe following tools are environment-managed: ${toolList}.\nTheir outputs are automatically preserved during compression.\nDo not include their content in compress tool summaries — the environment retains it independently.\n</dcp-system-reminder>`\n}\n","import { 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\n// [FIX Bug 28] Regex to strip stale mNNNN refs from compressed summaries\nconst DCP_MESSAGE_REF_TAG_REGEX = /<dcp-message-id>m\\d+<\\/dcp-message-id>/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\n\nconst generateStableId = (prefix: string, seed: string): string => {\n const hash = createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, SUMMARY_ID_HASH_LENGTH)\n return `${prefix}_${hash}`\n}\n\nexport const createSyntheticUserMessage = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n): WithParts => {\n const userInfo = baseMessage.info as UserMessage\n const now = Date.now()\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const messageId = generateStableId(\"msg_dcp_summary\", deterministicSeed)\n const partId = generateStableId(\"prt_dcp_summary\", deterministicSeed)\n\n return {\n info: {\n id: messageId,\n sessionID: userInfo.sessionID,\n role: \"user\" as const,\n agent: userInfo.agent,\n model: userInfo.model,\n time: { created: now },\n },\n parts: [\n {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: messageId,\n type: \"text\" as const,\n text: content,\n },\n ],\n }\n}\n\nexport const createSyntheticTextPart = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n) => {\n const userInfo = baseMessage.info as UserMessage\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const partId = generateStableId(\"prt_dcp_text\", deterministicSeed)\n\n return {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: userInfo.id,\n type: \"text\" as const,\n text: content,\n }\n}\n\ntype MessagePart = WithParts[\"parts\"][number]\ntype ToolPart = Extract<MessagePart, { type: \"tool\" }>\ntype TextPart = Extract<MessagePart, { type: \"text\" }>\n\nexport const appendToLastTextPart = (message: WithParts, injection: string): boolean => {\n const textPart = findLastTextPart(message)\n if (!textPart) {\n return false\n }\n\n return appendToTextPart(textPart, injection)\n}\n\nconst findLastTextPart = (message: WithParts): TextPart | null => {\n for (let i = message.parts.length - 1; i >= 0; i--) {\n const part = message.parts[i]\n if (part.type === \"text\") {\n return part\n }\n }\n\n return null\n}\n\nexport const appendToTextPart = (part: TextPart, injection: string): boolean => {\n if (typeof part.text !== \"string\") {\n return false\n }\n\n const normalizedInjection = injection.replace(/^\\n+/, \"\")\n if (!normalizedInjection.trim()) {\n return false\n }\n if (part.text.includes(normalizedInjection)) {\n return true\n }\n\n const baseText = part.text.replace(/\\n*$/, \"\")\n part.text = baseText.length > 0 ? `${baseText}\\n\\n${normalizedInjection}` : normalizedInjection\n return true\n}\n\nexport const appendToAllToolParts = (message: WithParts, tag: string): boolean => {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"tool\") {\n injected = appendToToolPart(part, tag) || injected\n }\n }\n return injected\n}\n\nexport const appendToToolPart = (part: ToolPart, tag: string): boolean => {\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n return false\n }\n if (part.state.output.includes(tag)) {\n return true\n }\n\n part.state.output = `${part.state.output}${tag}`\n return true\n}\n\nexport const hasContent = (message: WithParts): boolean => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0) ||\n (part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"),\n )\n}\n\nexport function buildToolIdList(state: SessionState, messages: WithParts[]): string[] {\n const toolIds: string[] = []\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n state.toolIdList = toolIds\n return toolIds\n}\n\nexport const replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\n// [FIX Bug 28] Strip stale mNNNN refs from compressed summaries before injection\nexport const stripStaleMessageRefs = (text: string): string => {\n return text.replace(DCP_MESSAGE_REF_TAG_REGEX, \"\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n return text.replace(DCP_PAIRED_TAG_REGEX, \"\").replace(DCP_UNPAIRED_TAG_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, stripStaleMessageRefs } 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 // [FIX Bug 28] Strip stale mNNNN refs before injection\n const _cleaned = stripStaleMessageRefs(rawSummaryContent)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(_cleaned)\n : _cleaned\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 // [FIX Bug 1] no preceding user message — build fallback base so summary is always injected\n const anchorInfo = msg.info as any\n const fallbackBase: WithParts = {\n info: {\n id: anchorInfo.id || msgId,\n sessionID: anchorInfo.sessionID || \"\",\n role: \"user\" as const,\n agent: anchorInfo.agent || \"code\",\n model:\n anchorInfo.model || {\n providerID: \"\",\n modelID: \"\",\n variant: undefined,\n },\n time: { created: anchorInfo.time?.created || Date.now() },\n },\n parts: [],\n }\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(_cleaned)\n : _cleaned\n const summarySeed = `${summary.blockId}:${summary.anchorMessageId}`\n result.push(\n createSyntheticUserMessage(fallbackBase, summaryContent, summarySeed),\n )\n\n logger.info(\"Injected compress summary (fallback, no preceding user message)\", {\n anchorMessageId: msgId,\n summaryLength: summaryContent.length,\n })\n }\n }\n }\n\n // Skip messages that are in the prune list\n const pruneEntry = state.prune.messages.byMessageId.get(msgId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n continue\n }\n\n // Normal message, include it\n result.push(msg)\n }\n\n // Replace messages array contents\n messages.length = 0\n messages.push(...result)\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\n\nfunction sortBlocksByCreation(\n a: { createdAt: number; blockId: number },\n b: { createdAt: number; blockId: number },\n): number {\n const createdAtDiff = a.createdAt - b.createdAt\n if (createdAtDiff !== 0) {\n return createdAtDiff\n }\n return a.blockId - b.blockId\n}\n\nexport const syncCompressionBlocks = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n): void => {\n const messagesState = state.prune.messages\n if (!messagesState?.blocksById?.size) {\n return\n }\n\n const messageIds = new Set(messages.map((msg) => msg.info.id))\n const previousActiveBlockIds = new Set<number>(\n Array.from(messagesState.blocksById.values())\n .filter((block) => block.active)\n .map((block) => block.blockId),\n )\n\n messagesState.activeBlockIds.clear()\n messagesState.activeByAnchorMessageId.clear()\n\n const now = Date.now()\n const missingOriginBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n // [PATCH Bug 3] Removed compressMessageId presence check.\n // Blocks should remain active even if the compress tool call message was\n // removed by opencode's internal compaction. The block's existence IS proof\n // that compression happened.\n for (const block of orderedBlocks) {\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 // Only deactivate if anchor message is completely gone from both current messages AND DCP tracked messages\n if (\n typeof block.anchorMessageId === \"string\" &&\n block.anchorMessageId.length > 0 &&\n !messageIds.has(block.anchorMessageId)\n ) {\n // If anchor exists in DCP's byMessageId (persisted), keep block active\n if (!messagesState.byMessageId.has(block.anchorMessageId)) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n continue\n }\n }\n\n for (const consumedBlockId of block.consumedBlockIds) {\n if (!messagesState.activeBlockIds.has(consumedBlockId)) {\n continue\n }\n\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (consumedBlock) {\n consumedBlock.active = false\n consumedBlock.deactivatedAt = now\n consumedBlock.deactivatedByBlockId = block.blockId\n\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlock.blockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n }\n\n block.active = true\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n messagesState.activeBlockIds.add(block.blockId)\n if (messageIds.has(block.anchorMessageId)) {\n messagesState.activeByAnchorMessageId.set(block.anchorMessageId, block.blockId)\n }\n }\n\n for (const entry of messagesState.byMessageId.values()) {\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [...new Set(entry.allBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n : []\n\n entry.allBlockIds = allBlockIds\n entry.activeBlockIds = allBlockIds.filter((id) => messagesState.activeBlockIds.has(id))\n }\n\n const nextActiveBlockIds = messagesState.activeBlockIds\n let deactivatedCount = 0\n let reactivatedCount = 0\n\n for (const blockId of previousActiveBlockIds) {\n if (!nextActiveBlockIds.has(blockId)) {\n deactivatedCount++\n }\n }\n for (const blockId of nextActiveBlockIds) {\n if (!previousActiveBlockIds.has(blockId)) {\n reactivatedCount++\n }\n }\n\n if (missingOriginBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingOriginCount: missingOriginBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type 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 { SessionState, CompressionBlock } from \"../../state\"\nimport type { GCConfig } from \"../../config\"\n\nexport interface BlockGuidanceContext {\n currentTokens?: number\n modelContextLimit?: number\n}\n\nexport function buildCompressedBlockGuidance(\n state: SessionState,\n gcConfig?: GCConfig,\n context?: BlockGuidanceContext,\n): string {\n const activeBlockIds = Array.from(state.prune.messages.activeBlockIds)\n .filter((id) => Number.isInteger(id) && id > 0)\n .sort((a, b) => a - b)\n\n const refs = activeBlockIds.map((id) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"none\"\n\n const lines = [\n \"Compressed block context:\",\n `- Active compressed blocks: ${blockCount} (${blockList})`,\n \"- If your selected compression range includes any listed block, include each required placeholder exactly once in the summary using `(bN)`.\",\n ]\n\n // [FIX Bug 35] Only show aging warnings when context usage is above 50%.\n // Showing warnings at low usage causes unnecessary compress operations that\n // waste tokens and attention — the model preemptively re-summarizes blocks\n // that aren't actually at risk of GC truncation.\n const usageRatio =\n context?.currentTokens && context?.modelContextLimit\n ? context.currentTokens / context.modelContextLimit\n : 0\n\n if (gcConfig && usageRatio > 0.5) {\n const promotionThreshold = gcConfig.promotionThreshold\n const agingBlocks: string[] = []\n\n for (const blockId of activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block) continue\n\n const survived = block.survivedCount ?? 0\n const gen = block.generation ?? \"young\"\n const sizeK = (block.summary.length / 1000).toFixed(1)\n const preview = block.summary.slice(0, 120).replace(/\\n/g, \" \")\n\n if (gen === \"old\" || survived >= promotionThreshold - 2) {\n agingBlocks.push(\n ` b${blockId}: age=${survived}/${promotionThreshold}, gen=${gen}, size=${sizeK}K chars — ${preview}...`,\n )\n }\n }\n\n if (agingBlocks.length > 0) {\n lines.push(\"\")\n lines.push(\"⚠️ Block aging warning — these blocks may be truncated by GC soon:\")\n lines.push(...agingBlocks)\n lines.push(\n \"To preserve important content: use the compress tool to re-summarize these blocks into new concise ones. Unhandled blocks will be auto-truncated.\",\n )\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nexport function renderMessagePriorityGuidance(priorityLabel: string, refs: string[]): string {\n const refList = refs.length > 0 ? refs.join(\", \") : \"none\"\n\n return [\n \"Message priority context:\",\n \"- Higher-priority older messages consume more context and should be compressed right away if it is safe to do so.\",\n `- ${priorityLabel}-priority message IDs before this point: ${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 = \"</dcp-system-reminder>\"\n const closeTagIndex = nudgeText.lastIndexOf(closeTag)\n\n if (closeTagIndex === -1) {\n return nudgeText\n }\n\n const beforeClose = nudgeText.slice(0, closeTagIndex).trimEnd()\n const afterClose = nudgeText.slice(closeTagIndex)\n return `${beforeClose}\\n\\n${guidance}\\n${afterClose}`\n}\n","import type { 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 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\ninterface ModelLimit {\n context: number\n input?: number\n output?: number\n}\n\nexport function computeInputBudget(limit: ModelLimit): number | undefined {\n if (!limit.context) {\n return undefined\n }\n\n return limit.input ?? Math.max(0, limit.context - (limit.output ?? 0))\n}\n\nexport function getNudgeFrequency(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.nudgeFrequency || 1))\n}\n\nexport function getIterationNudgeThreshold(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.iterationNudgeThreshold || 1))\n}\n\nexport function findLastNonIgnoredMessage(messages: WithParts[]): LastNonIgnoredMessage | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n return { message, index: i }\n }\n\n return null\n}\n\nexport function countMessagesAfterIndex(messages: WithParts[], index: number): number {\n let count = 0\n\n for (let i = index + 1; i < messages.length; i++) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n count++\n }\n\n return count\n}\n\nexport function getModelInfo(messages: WithParts[]): LastUserModelContext {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return {\n providerId: undefined,\n modelId: undefined,\n }\n }\n\n const userInfo = lastUserMessage.info as UserMessage\n return {\n providerId: userInfo.model.providerID,\n modelId: userInfo.model.modelID,\n }\n}\n\nfunction resolveContextTokenLimit(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n threshold: \"max\" | \"min\",\n): number | undefined {\n const parseLimitValue = (limit: number | `${number}%` | undefined): number | undefined => {\n if (limit === undefined) {\n return undefined\n }\n\n if (typeof limit === \"number\") {\n return limit\n }\n\n if (!limit.endsWith(\"%\") || state.modelContextLimit === undefined) {\n return undefined\n }\n\n const parsedPercent = parseFloat(limit.slice(0, -1))\n if (isNaN(parsedPercent)) {\n return undefined\n }\n\n const roundedPercent = Math.round(parsedPercent)\n const clampedPercent = Math.max(0, Math.min(100, roundedPercent))\n return Math.round((clampedPercent / 100) * state.modelContextLimit)\n }\n\n const modelLimits =\n threshold === \"max\" ? config.compress.modelMaxLimits : config.compress.modelMinLimits\n if (modelLimits && providerId !== undefined && modelId !== undefined) {\n const providerModelId = `${providerId}/${modelId}`\n const modelLimit = modelLimits[providerModelId]\n if (modelLimit !== undefined) {\n return parseLimitValue(modelLimit)\n }\n }\n\n const globalLimit =\n threshold === \"max\" ? config.compress.maxContextLimit : config.compress.minContextLimit\n return parseLimitValue(globalLimit)\n}\n\nexport function isContextOverLimits(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n messages: WithParts[],\n) {\n const summaryTokenExtension = config.compress.summaryBuffer\n ? getActiveSummaryTokenUsage(state)\n : 0\n const resolvedMaxContextLimit = resolveContextTokenLimit(\n config,\n state,\n providerId,\n modelId,\n \"max\",\n )\n const maxContextLimit =\n resolvedMaxContextLimit === undefined\n ? undefined\n : resolvedMaxContextLimit + summaryTokenExtension\n const minContextLimit = resolveContextTokenLimit(config, state, providerId, modelId, \"min\")\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n let overMaxLimit = maxContextLimit === undefined ? false : currentTokens > maxContextLimit\n const overMinLimit = minContextLimit === undefined ? false : currentTokens >= minContextLimit\n\n // [FIX Bug 20] Suppress overMax while cacheRead hasn't updated after compress\n if (overMaxLimit) {\n const recentCompressCount = 3\n const recentMessages = messages.slice(-recentCompressCount)\n for (const msg of recentMessages) {\n if (msg.info.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if ((part as any).type === \"tool-invocation\" && (part as any).toolInvocation?.toolName === \"compress\") {\n overMaxLimit = false\n break\n }\n }\n }\n if (!overMaxLimit) break\n }\n }\n\n return {\n overMaxLimit,\n overMinLimit,\n currentTokens,\n modelContextLimit: state.modelContextLimit,\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): void {\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, compressedBlockGuidance)\n if (!nudgeText.trim()) {\n return\n }\n\n for (const { message } of collectAnchoredMessages(anchorMessageIds, messages)) {\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nfunction applyMessageModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: 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 nudgeText = appendGuidanceToDcpTag(baseNudgeText, priorityGuidance)\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nfunction buildContextUsageInfo(currentTokens?: number, modelContextLimit?: number): string {\n if (currentTokens === undefined || modelContextLimit === undefined || modelContextLimit === 0) {\n return \"\"\n }\n const percentage = ((currentTokens / modelContextLimit) * 100).toFixed(1)\n const formatK = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n))\n return `\\n\\nContext usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent — use the compress tool proactively to manage context quality.`\n}\n\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n currentTokens?: number,\n modelContextLimit?: number,\n): void {\n const contextUsageInfo = buildContextUsageInfo(currentTokens, modelContextLimit)\n const contextLimitNudgeWithUsage = prompts.contextLimitNudge + contextUsageInfo\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n contextLimitNudgeWithUsage,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressionPriorities,\n )\n return\n }\n\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n contextLimitNudgeWithUsage,\n \"\",\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n \"\",\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n \"\",\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\"\nimport { buildCompressedBlockGuidance } from \"../../prompts/extensions/nudge\"\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 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, currentTokens, modelContextLimit } = 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, currentTokens, modelContextLimit)\n\n injectContextUsage(messages, currentTokens, modelContextLimit)\n\n if (config.compress.mode !== \"message\") {\n const blockGuidance = buildCompressedBlockGuidance(state, config.gc, { currentTokens, modelContextLimit })\n if (blockGuidance.trim()) {\n const lastUser = getLastUserMessage(messages)\n if (lastUser) appendToLastTextPart(lastUser, \"\\n\\n\" + blockGuidance)\n }\n }\n\n injectVisibleIdRange(state, messages)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger)\n }\n}\n\nfunction injectContextUsage(\n messages: WithParts[],\n currentTokens?: number,\n modelContextLimit?: number,\n): void {\n if (currentTokens === undefined || modelContextLimit === undefined || modelContextLimit === 0) {\n return\n }\n const lastUser = getLastUserMessage(messages)\n if (!lastUser) return\n\n const percentage = ((currentTokens / modelContextLimit) * 100).toFixed(1)\n const formatK = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n))\n const usageTag = `\\n\\nContext usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent — use the compress tool proactively to manage context quality.`\n\n for (const part of lastUser.parts) {\n if (part.type === \"text\") {\n appendToTextPart(part, usageTag)\n return\n }\n }\n lastUser.parts.push(createSyntheticTextPart(lastUser, usageTag))\n}\n\nfunction injectVisibleIdRange(state: SessionState, messages: WithParts[]): void {\n const visibleRefs: string[] = []\n for (const message of messages) {\n const ref = state.messageIds.byRawId.get(message.info.id)\n if (ref) {\n visibleRefs.push(ref)\n }\n }\n\n if (visibleRefs.length === 0) return\n\n visibleRefs.sort()\n const first = visibleRefs[0]\n const last = visibleRefs[visibleRefs.length - 1]\n const rangeTag = `\\n\\n[Visible message IDs: ${first} to ${last} (${visibleRefs.length} messages). Only use IDs in this range for compress.]`\n\n const lastUser = getLastUserMessage(messages)\n if (!lastUser) return\n\n for (const part of lastUser.parts) {\n if (part.type === \"text\") {\n appendToTextPart(part, rangeTag)\n return\n }\n }\n lastUser.parts.push(createSyntheticTextPart(lastUser, rangeTag))\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 // [FIX Bug 8] Guard against undefined modelID/providerID\n const msgModelID = (message.info as any).modelID\n const msgProviderID = (message.info as any).providerID\n if (msgModelID === modelID && msgProviderID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\" && part.type !== \"reasoning\") {\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(\"│ ACP 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 ACP: ~${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.compressMessageId)\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: /acp 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: /acp 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: /acp 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 // [FIX Bug 10] Mark consumed inner blocks so syncCompressionBlocks won't re-activate them\n for (const consumedId of block.consumedBlockIds) {\n const consumedBlock = messagesState.blocksById.get(consumedId)\n if (consumedBlock) {\n consumedBlock.deactivatedByUser = true\n }\n }\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 * ACP Help command handler.\n * Shows available ACP 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 [\"/acp context\", \"Show token usage breakdown for current session\"],\n [\"/acp stats\", \"Show ACP pruning statistics\"],\n [\"/acp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/acp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\n]\n\nconst TOOL_COMMANDS: Record<string, [string, string]> = {\n compress: [\"/acp compress [focus]\", \"Trigger manual compress tool execution\"],\n decompress: [\"/acp decompress <n>\", \"Restore selected compression\"],\n recompress: [\"/acp 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(\"│ ACP 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 * /acp manual [on|off] - Toggle manual mode or set explicit state\n * /acp 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 { getCurrentParams } from \"../token-utils\"\nimport { buildCompressedBlockGuidance } from \"../prompts/extensions/nudge\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nconst MANUAL_MODE_ON = \"Manual mode is now ON. Use /acp compress to trigger context tools manually.\"\n\nconst MANUAL_MODE_OFF = \"Manual mode is now OFF.\"\n\nconst COMPRESS_TRIGGER_PROMPT = [\n \"<compress triggered manually>\",\n \"Manual mode trigger received. You must now use the compress tool.\",\n \"Find the most significant completed conversation content that can be compressed into a high-fidelity technical summary.\",\n \"Follow the active compress mode, preserve all critical implementation details, and choose safe targets.\",\n \"Return after compress with a brief explanation of what content was compressed.\",\n].join(\"\\n\\n\")\n\nfunction getTriggerPrompt(\n tool: \"compress\",\n state: SessionState,\n config: PluginConfig,\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state, config.gc)\n\n const sections = [base, compressedBlockGuidance]\n if (userFocus && userFocus.trim().length > 0) {\n sections.push(`Additional user focus:\\n${userFocus.trim()}`)\n }\n\n return sections.join(\"\\n\\n\")\n}\n\nexport interface ManualCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport async function handleManualToggleCommand(\n ctx: ManualCommandContext,\n modeArg?: string,\n): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n if (modeArg === \"on\") {\n state.manualMode = \"active\"\n } else if (modeArg === \"off\") {\n state.manualMode = false\n } else {\n state.manualMode = state.manualMode ? false : \"active\"\n }\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(\n client,\n sessionId,\n state.manualMode ? MANUAL_MODE_ON : MANUAL_MODE_OFF,\n params,\n logger,\n )\n\n logger.info(\"Manual mode toggled\", { manualMode: state.manualMode })\n}\n\nexport async function handleManualTriggerCommand(\n ctx: ManualCommandContext,\n tool: \"compress\",\n userFocus?: string,\n): Promise<string | null> {\n return getTriggerPrompt(tool, ctx.state, ctx.config, userFocus)\n}\n\nexport function applyPendingManualTrigger(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): void {\n const pending = state.pendingManualTrigger\n if (!pending) {\n return\n }\n\n if (!state.sessionId || pending.sessionId !== state.sessionId) {\n state.pendingManualTrigger = null\n return\n }\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n\n for (const part of msg.parts) {\n if (part.type !== \"text\" || part.ignored || part.synthetic) {\n continue\n }\n\n part.text = pending.prompt\n state.pendingManualTrigger = null\n logger.debug(\"Applied manual prompt\", { sessionId: pending.sessionId })\n return\n }\n }\n\n state.pendingManualTrigger = null\n}\n","import type { Logger } from \"../logger\"\nimport type { PruneMessagesState, SessionState, WithParts } from \"../state\"\nimport { syncCompressionBlocks } from \"../messages\"\nimport { parseBlockRef } from \"../message-ids\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport {\n getRecompressibleCompressionTargets,\n resolveCompressionTarget,\n type CompressionTarget,\n} from \"./compression-targets\"\n\nexport interface RecompressCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n}\n\nfunction parseBlockIdArg(arg: string): number | null {\n const normalized = arg.trim().toLowerCase()\n const blockRef = parseBlockRef(normalized)\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: /acp 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: /acp 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: /acp recompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n if (target.blocks.some((block) => !availableMessageIds.has(block.compressMessageId))) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} can no longer be re-applied because its origin message is no longer in this session.`,\n params,\n logger,\n )\n return\n }\n\n if (!target.blocks.some((block) => block.deactivatedByUser)) {\n const message = target.blocks.some((block) => block.active)\n ? `Compression ${target.displayId} is already active.`\n : `Compression ${target.displayId} is not user-decompressed.`\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n\n for (const block of target.blocks) {\n block.deactivatedByUser = false\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let recompressedMessageCount = 0\n let recompressedTokens = 0\n for (const [messageId, entry] of messagesState.byMessageId) {\n const isActiveNow = entry.activeBlockIds.length > 0\n if (isActiveNow && !activeMessagesBefore.has(messageId)) {\n recompressedMessageCount++\n recompressedTokens += entry.tokenCount\n }\n }\n\n state.stats.totalPruneTokens += recompressedTokens\n\n const deactivatedBlockIds = Array.from(activeBlockIdsBefore)\n .filter((blockId) => !messagesState.activeBlockIds.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatRecompressMessage(\n target,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Recompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n })\n}\n","/**\n * DCP Stats command handler.\n * Shows pruning statistics for the current session and all-time totals.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport { loadAllSessionStats, type AggregatedStats } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { 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(\"│ ACP 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 * /acp sweep - Prune all tools since the previous user message\n * /acp 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(\"│ ACP 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(\"│ ACP 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 { CompressionBlock } from \"../state\"\nimport type { GCConfig } from \"../config\"\n\nexport interface CompactionResult {\n compactedBlocks: number\n savedTokens: number\n}\n\nexport interface GCParams {\n maxOldGenSummaryLength: number\n modelContextLimit: number\n currentTokens: number\n}\n\nexport function runTruncateGC(\n blocks: CompressionBlock[],\n params: GCParams,\n): CompactionResult {\n let compactedBlocks = 0\n let savedTokens = 0\n\n for (const block of blocks) {\n if (!block.active) continue\n if (block.summary.length <= params.maxOldGenSummaryLength) continue\n\n const originalLength = block.summary.length\n const truncated = truncateSummary(block.summary, params.maxOldGenSummaryLength, block.blockId)\n const savedChars = originalLength - truncated.length\n if (savedChars > 0) {\n block.summary = truncated\n block.summaryTokens = Math.round(truncated.length / 4)\n compactedBlocks++\n savedTokens += Math.round(savedChars / 4)\n }\n }\n\n return { compactedBlocks, savedTokens }\n}\n\nfunction truncateSummary(summary: string, maxLength: number, _blockId: number): string {\n if (summary.length <= maxLength) return summary\n\n const headerEnd = summary.indexOf(\"\\n\")\n if (headerEnd === -1) return summary.slice(0, maxLength) + \"\\n...\\n[GC truncated]\"\n\n const header = summary.slice(0, headerEnd + 1)\n const footerStart = summary.lastIndexOf(\"\\n\\n\")\n const footer = footerStart > headerEnd ? summary.slice(footerStart) : \"\"\n\n const availableForContent = maxLength - header.length - footer.length - 20\n if (availableForContent < 100) {\n return header + \"...\\n[GC truncated]\" + footer\n }\n\n const content = summary.slice(headerEnd + 1, headerEnd + 1 + availableForContent)\n return header + content + \"\\n...\\n[GC truncated]\" + footer\n}\n\nexport function shouldRunMajorGC(\n currentTokens: number,\n modelContextLimit: number | undefined,\n gcConfig: GCConfig,\n): boolean {\n if (!modelContextLimit || modelContextLimit === 0) return false\n\n const threshold = parseGcThreshold(gcConfig.majorGcThresholdPercent, modelContextLimit)\n return currentTokens >= threshold\n}\n\nexport function getGCParams(gcConfig: GCConfig, modelContextLimit: number, currentTokens: number): GCParams {\n return {\n maxOldGenSummaryLength: gcConfig.maxOldGenSummaryLength,\n modelContextLimit,\n currentTokens,\n }\n}\n\nfunction parseGcThreshold(limit: number | `${number}%`, modelContextLimit: number): number {\n if (typeof limit === \"number\") return limit\n const percent = parseFloat(limit.slice(0, -1))\n if (isNaN(percent)) return modelContextLimit\n return Math.round((Math.max(0, Math.min(100, Math.round(percent))) / 100) * modelContextLimit)\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 computeInputBudget,\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\"\nimport { runTruncateGC, shouldRunMajorGC, getGCParams } from \"./gc/truncate\"\nimport { getCurrentTokenUsage } from \"./token-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: {\n sessionID?: string\n model: { limit: { context: number; input?: number; output?: number } }\n },\n output: { system: string[] },\n ) => {\n if (input.model?.limit?.context) {\n state.modelContextLimit = input.model.limit.context\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\nfunction runMajorGC(\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n): void {\n // [FIX Bug 32] Age-based deactivation does NOT depend on modelContextLimit.\n // modelContextLimit is set in the system prompt hook, which runs AFTER the\n // messages transform hook. If we guard this with modelContextLimit, age-based\n // deactivation never runs after restart (modelContextLimit starts as undefined).\n const maxBlockAge = config.gc.maxBlockAge ?? 15\n let agedOutCount = 0\n let agedOutTokens = 0\n const now = Date.now()\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (!block.active) continue\n const age = block.survivedCount ?? 0\n if (age > maxBlockAge) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n state.prune.messages.activeBlockIds.delete(Number(blockId))\n const anchorMapped = state.prune.messages.activeByAnchorMessageId.get(block.anchorMessageId)\n if (anchorMapped === Number(blockId)) {\n state.prune.messages.activeByAnchorMessageId.delete(block.anchorMessageId)\n }\n agedOutCount++\n agedOutTokens += block.summaryTokens ?? Math.round(block.summary.length / 4)\n }\n }\n\n if (agedOutCount > 0) {\n logger.info(\"Major GC: deactivated aged-out blocks\", {\n agedOutCount,\n agedOutTokens,\n maxBlockAge,\n })\n void saveSessionState(state, logger)\n }\n\n if (!state.modelContextLimit) return\n\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n // Check if any active block is oversized (summary > 2x maxOldGenSummaryLength)\n // These should always be truncated regardless of token threshold\n const oversizedThreshold = config.gc.maxOldGenSummaryLength * 2\n let hasOversizedBlocks = false\n for (const [, block] of state.prune.messages.blocksById) {\n if (block.active && block.summary.length > oversizedThreshold) {\n hasOversizedBlocks = true\n break\n }\n }\n\n if (!shouldRunMajorGC(currentTokens, state.modelContextLimit, config.gc) && !hasOversizedBlocks) return\n\n const oldBlocks: import(\"./state\").CompressionBlock[] = []\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (!block.active) continue\n if (\n block.generation === \"old\" ||\n block.generation === undefined ||\n block.summary.length > config.gc.maxOldGenSummaryLength\n ) {\n oldBlocks.push(block)\n }\n }\n\n if (oldBlocks.length === 0) return\n\n const params = getGCParams(config.gc, state.modelContextLimit, currentTokens)\n const result = runTruncateGC(oldBlocks, params)\n\n if (result.compactedBlocks > 0) {\n logger.info(\"Major GC: truncated old-gen blocks\", {\n compactedBlocks: result.compactedBlocks,\n savedTokens: result.savedTokens,\n currentTokens,\n threshold: config.gc.majorGcThresholdPercent,\n })\n void saveSessionState(state, logger)\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 stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n const activeBlockCountBefore = state.prune.messages.activeBlockIds.size // [FIX Bug 4]\n syncCompressionBlocks(state, logger, output.messages)\n if (state.prune.messages.activeBlockIds.size !== activeBlockCountBefore) { // [FIX Bug 4]\n void saveSessionState(state, logger) // [FIX Bug 4] persist deactivations\n }\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n runMajorGC(state, config, logger, output.messages)\n prune(state, logger, config, output.messages)\n // [FIX Bug 2] assign refs to newly created synthetic messages from prune/filterCompressedRanges\n assignMessageRefs(state, 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 }\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 === \"acp\" || 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 = \"@tarquinen/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: \"ACP 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[\"acp\"] = {\n template: \"\",\n description: \"Show available ACP 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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AAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAA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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","cpSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","cpSync","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","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-validation.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/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/gc/truncate.ts","../lib/hooks.ts","../lib/auth.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, copyFileSync } 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 { VALID_CONFIG_KEYS, getInvalidConfigKeys, validateConfigTypes, type ValidationError } from \"./config-validation\"\n\n\ntype Permission = \"ask\" | \"allow\" | \"deny\"\ntype CompressMode = \"range\" | \"message\"\n\nexport interface Deduplication {\n enabled: boolean\n protectedTools: string[]\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}\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 GCConfig {\n algorithm: \"truncate\"\n promotionThreshold: number\n maxBlockAge: number\n maxOldGenSummaryLength: number\n majorGcThresholdPercent: number | `${number}%`\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 gc: GCConfig\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 { VALID_CONFIG_KEYS, getInvalidConfigKeys, validateConfigTypes, type ValidationError } from \"./config-validation\"\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: `ACP: ${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: true,\n summaryBuffer: true,\n maxContextLimit: \"55%\",\n minContextLimit: \"45%\",\n nudgeFrequency: 5,\n iterationNudgeThreshold: 15,\n nudgeForce: \"soft\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n },\n strategies: {\n deduplication: {\n enabled: true,\n protectedTools: [],\n },\n purgeErrors: {\n enabled: true,\n turns: 4,\n protectedTools: [],\n },\n },\n gc: {\n algorithm: \"truncate\",\n promotionThreshold: 5,\n maxBlockAge: 15,\n maxOldGenSummaryLength: 3000,\n majorGcThresholdPercent: \"100%\",\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, \"acp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"acp.json\")\nconst LEGACY_GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst LEGACY_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 : existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)\n ? LEGACY_GLOBAL_CONFIG_PATH_JSONC\n : existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)\n ? LEGACY_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, \"acp.jsonc\")\n const configJson = join(opencodeConfigDir, \"acp.json\")\n const legacyJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const legacyJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : existsSync(legacyJsonc)\n ? legacyJsonc\n : existsSync(legacyJson)\n ? legacyJson\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, \"acp.jsonc\")\n const projectJson = join(opencodeDir, \"acp.json\")\n const legacyJsonc = join(opencodeDir, \"dcp.jsonc\")\n const legacyJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : existsSync(legacyJsonc)\n ? legacyJsonc\n : existsSync(legacyJson)\n ? legacyJson\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 if (!existsSync(GLOBAL_CONFIG_PATH_JSONC)) {\n if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.jsonc to acp.jsonc\")\n } else if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSON, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.json to acp.jsonc\")\n } else {\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n }\n }\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 }\n}\n\nfunction mergeCommands(\n base: PluginConfig[\"commands\"],\n override?: Partial<PluginConfig[\"commands\"]>,\n): PluginConfig[\"commands\"] {\n if (!override) {\n return base\n }\n\n return {\n enabled: override.enabled ?? base.enabled,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n }\n}\n\nfunction mergeManualMode(\n base: PluginConfig[\"manualMode\"],\n override?: Partial<PluginConfig[\"manualMode\"]>,\n): PluginConfig[\"manualMode\"] {\n if (override === undefined) return base\n\n return {\n enabled: override.enabled ?? base.enabled,\n automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (override === undefined) return base\n\n return {\n allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,\n customPrompts: override.customPrompts ?? base.customPrompts,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: {\n enabled: config.commands.enabled,\n protectedTools: [...config.commands.protectedTools],\n },\n manualMode: {\n enabled: config.manualMode.enabled,\n automaticStrategies: config.manualMode.automaticStrategies,\n },\n turnProtection: { ...config.turnProtection },\n experimental: { ...config.experimental },\n protectedFilePatterns: [...config.protectedFilePatterns],\n compress: {\n ...config.compress,\n modelMaxLimits: { ...config.compress.modelMaxLimits },\n modelMinLimits: { ...config.compress.modelMinLimits },\n protectedTools: [...config.compress.protectedTools],\n },\n strategies: {\n deduplication: {\n ...config.strategies.deduplication,\n protectedTools: [...config.strategies.deduplication.protectedTools],\n },\n purgeErrors: {\n ...config.strategies.purgeErrors,\n protectedTools: [...config.strategies.purgeErrors.protectedTools],\n },\n },\n gc: { ...config.gc },\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 gc: { ...config.gc, ...(data.gc as Partial<GCConfig>) },\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 // Migration: dcp.jsonc → acp.jsonc (must run before createDefaultConfig check)\n if (!existsSync(GLOBAL_CONFIG_PATH_JSONC) && !existsSync(GLOBAL_CONFIG_PATH_JSON)) {\n if (existsSync(GLOBAL_CONFIG_DIR) || existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC) || existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSONC, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.jsonc to acp.jsonc\")\n } else if (existsSync(LEGACY_GLOBAL_CONFIG_PATH_JSON)) {\n copyFileSync(LEGACY_GLOBAL_CONFIG_PATH_JSON, GLOBAL_CONFIG_PATH_JSONC)\n console.log(\"[ACP] Migrated config from dcp.json to acp.jsonc\")\n }\n }\n }\n\n if (!configPaths.global && !existsSync(GLOBAL_CONFIG_PATH_JSONC)) {\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 `ACP: Invalid ${layer.name}`,\n `${layer.path}\\n${result.parseError}\\nUsing previous/default values`,\n )\n continue\n }\n\n if (!result.data) {\n continue\n }\n\n showConfigWarnings(ctx, layer.path, result.data, layer.isProject)\n config = mergeLayer(config, result.data)\n }\n\n return config\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport function createScanner(text, ignoreTrivia = false) {\n const len = text.length;\n let pos = 0, value = '', tokenOffset = 0, token = 16 /* SyntaxKind.Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* ScanError.None */;\n function scanHexDigits(count, exact) {\n let digits = 0;\n let value = 0;\n while (digits < count || !exact) {\n let ch = text.charCodeAt(pos);\n if (ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */) {\n value = value * 16 + ch - 48 /* CharacterCodes._0 */;\n }\n else if (ch >= 65 /* CharacterCodes.A */ && ch <= 70 /* CharacterCodes.F */) {\n value = value * 16 + ch - 65 /* CharacterCodes.A */ + 10;\n }\n else if (ch >= 97 /* CharacterCodes.a */ && ch <= 102 /* CharacterCodes.f */) {\n value = value * 16 + ch - 97 /* CharacterCodes.a */ + 10;\n }\n else {\n break;\n }\n pos++;\n digits++;\n }\n if (digits < count) {\n value = -1;\n }\n return value;\n }\n function setPosition(newPosition) {\n pos = newPosition;\n value = '';\n tokenOffset = 0;\n token = 16 /* SyntaxKind.Unknown */;\n scanError = 0 /* ScanError.None */;\n }\n function scanNumber() {\n let start = pos;\n if (text.charCodeAt(pos) === 48 /* CharacterCodes._0 */) {\n pos++;\n }\n else {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n if (pos < text.length && text.charCodeAt(pos) === 46 /* CharacterCodes.dot */) {\n pos++;\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n return text.substring(start, pos);\n }\n }\n let end = pos;\n if (pos < text.length && (text.charCodeAt(pos) === 69 /* CharacterCodes.E */ || text.charCodeAt(pos) === 101 /* CharacterCodes.e */)) {\n pos++;\n if (pos < text.length && text.charCodeAt(pos) === 43 /* CharacterCodes.plus */ || text.charCodeAt(pos) === 45 /* CharacterCodes.minus */) {\n pos++;\n }\n if (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n while (pos < text.length && isDigit(text.charCodeAt(pos))) {\n pos++;\n }\n end = pos;\n }\n else {\n scanError = 3 /* ScanError.UnexpectedEndOfNumber */;\n }\n }\n return text.substring(start, end);\n }\n function scanString() {\n let result = '', start = pos;\n while (true) {\n if (pos >= len) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch = text.charCodeAt(pos);\n if (ch === 34 /* CharacterCodes.doubleQuote */) {\n result += text.substring(start, pos);\n pos++;\n break;\n }\n if (ch === 92 /* CharacterCodes.backslash */) {\n result += text.substring(start, pos);\n pos++;\n if (pos >= len) {\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n const ch2 = text.charCodeAt(pos++);\n switch (ch2) {\n case 34 /* CharacterCodes.doubleQuote */:\n result += '\\\"';\n break;\n case 92 /* CharacterCodes.backslash */:\n result += '\\\\';\n break;\n case 47 /* CharacterCodes.slash */:\n result += '/';\n break;\n case 98 /* CharacterCodes.b */:\n result += '\\b';\n break;\n case 102 /* CharacterCodes.f */:\n result += '\\f';\n break;\n case 110 /* CharacterCodes.n */:\n result += '\\n';\n break;\n case 114 /* CharacterCodes.r */:\n result += '\\r';\n break;\n case 116 /* CharacterCodes.t */:\n result += '\\t';\n break;\n case 117 /* CharacterCodes.u */:\n const ch3 = scanHexDigits(4, true);\n if (ch3 >= 0) {\n result += String.fromCharCode(ch3);\n }\n else {\n scanError = 4 /* ScanError.InvalidUnicode */;\n }\n break;\n default:\n scanError = 5 /* ScanError.InvalidEscapeCharacter */;\n }\n start = pos;\n continue;\n }\n if (ch >= 0 && ch <= 0x1f) {\n if (isLineBreak(ch)) {\n result += text.substring(start, pos);\n scanError = 2 /* ScanError.UnexpectedEndOfString */;\n break;\n }\n else {\n scanError = 6 /* ScanError.InvalidCharacter */;\n // mark as error but continue with string\n }\n }\n pos++;\n }\n return result;\n }\n function scanNext() {\n value = '';\n scanError = 0 /* ScanError.None */;\n tokenOffset = pos;\n lineStartOffset = lineNumber;\n prevTokenLineStartOffset = tokenLineStartOffset;\n if (pos >= len) {\n // at the end\n tokenOffset = len;\n return token = 17 /* SyntaxKind.EOF */;\n }\n let code = text.charCodeAt(pos);\n // trivia: whitespace\n if (isWhiteSpace(code)) {\n do {\n pos++;\n value += String.fromCharCode(code);\n code = text.charCodeAt(pos);\n } while (isWhiteSpace(code));\n return token = 15 /* SyntaxKind.Trivia */;\n }\n // trivia: newlines\n if (isLineBreak(code)) {\n pos++;\n value += String.fromCharCode(code);\n if (code === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n value += '\\n';\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n return token = 14 /* SyntaxKind.LineBreakTrivia */;\n }\n switch (code) {\n // tokens: []{}:,\n case 123 /* CharacterCodes.openBrace */:\n pos++;\n return token = 1 /* SyntaxKind.OpenBraceToken */;\n case 125 /* CharacterCodes.closeBrace */:\n pos++;\n return token = 2 /* SyntaxKind.CloseBraceToken */;\n case 91 /* CharacterCodes.openBracket */:\n pos++;\n return token = 3 /* SyntaxKind.OpenBracketToken */;\n case 93 /* CharacterCodes.closeBracket */:\n pos++;\n return token = 4 /* SyntaxKind.CloseBracketToken */;\n case 58 /* CharacterCodes.colon */:\n pos++;\n return token = 6 /* SyntaxKind.ColonToken */;\n case 44 /* CharacterCodes.comma */:\n pos++;\n return token = 5 /* SyntaxKind.CommaToken */;\n // strings\n case 34 /* CharacterCodes.doubleQuote */:\n pos++;\n value = scanString();\n return token = 10 /* SyntaxKind.StringLiteral */;\n // comments\n case 47 /* CharacterCodes.slash */:\n const start = pos - 1;\n // Single-line comment\n if (text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n while (pos < len) {\n if (isLineBreak(text.charCodeAt(pos))) {\n break;\n }\n pos++;\n }\n value = text.substring(start, pos);\n return token = 12 /* SyntaxKind.LineCommentTrivia */;\n }\n // Multi-line comment\n if (text.charCodeAt(pos + 1) === 42 /* CharacterCodes.asterisk */) {\n pos += 2;\n const safeLength = len - 1; // For lookahead.\n let commentClosed = false;\n while (pos < safeLength) {\n const ch = text.charCodeAt(pos);\n if (ch === 42 /* CharacterCodes.asterisk */ && text.charCodeAt(pos + 1) === 47 /* CharacterCodes.slash */) {\n pos += 2;\n commentClosed = true;\n break;\n }\n pos++;\n if (isLineBreak(ch)) {\n if (ch === 13 /* CharacterCodes.carriageReturn */ && text.charCodeAt(pos) === 10 /* CharacterCodes.lineFeed */) {\n pos++;\n }\n lineNumber++;\n tokenLineStartOffset = pos;\n }\n }\n if (!commentClosed) {\n pos++;\n scanError = 1 /* ScanError.UnexpectedEndOfComment */;\n }\n value = text.substring(start, pos);\n return token = 13 /* SyntaxKind.BlockCommentTrivia */;\n }\n // just a single slash\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n // numbers\n case 45 /* CharacterCodes.minus */:\n value += String.fromCharCode(code);\n pos++;\n if (pos === len || !isDigit(text.charCodeAt(pos))) {\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // found a minus, followed by a number so\n // we fall through to proceed with scanning\n // numbers\n case 48 /* CharacterCodes._0 */:\n case 49 /* CharacterCodes._1 */:\n case 50 /* CharacterCodes._2 */:\n case 51 /* CharacterCodes._3 */:\n case 52 /* CharacterCodes._4 */:\n case 53 /* CharacterCodes._5 */:\n case 54 /* CharacterCodes._6 */:\n case 55 /* CharacterCodes._7 */:\n case 56 /* CharacterCodes._8 */:\n case 57 /* CharacterCodes._9 */:\n value += scanNumber();\n return token = 11 /* SyntaxKind.NumericLiteral */;\n // literals and unknown symbols\n default:\n // is a literal? Read the full word.\n while (pos < len && isUnknownContentCharacter(code)) {\n pos++;\n code = text.charCodeAt(pos);\n }\n if (tokenOffset !== pos) {\n value = text.substring(tokenOffset, pos);\n // keywords: true, false, null\n switch (value) {\n case 'true': return token = 8 /* SyntaxKind.TrueKeyword */;\n case 'false': return token = 9 /* SyntaxKind.FalseKeyword */;\n case 'null': return token = 7 /* SyntaxKind.NullKeyword */;\n }\n return token = 16 /* SyntaxKind.Unknown */;\n }\n // some\n value += String.fromCharCode(code);\n pos++;\n return token = 16 /* SyntaxKind.Unknown */;\n }\n }\n function isUnknownContentCharacter(code) {\n if (isWhiteSpace(code) || isLineBreak(code)) {\n return false;\n }\n switch (code) {\n case 125 /* CharacterCodes.closeBrace */:\n case 93 /* CharacterCodes.closeBracket */:\n case 123 /* CharacterCodes.openBrace */:\n case 91 /* CharacterCodes.openBracket */:\n case 34 /* CharacterCodes.doubleQuote */:\n case 58 /* CharacterCodes.colon */:\n case 44 /* CharacterCodes.comma */:\n case 47 /* CharacterCodes.slash */:\n return false;\n }\n return true;\n }\n function scanNextNonTrivia() {\n let result;\n do {\n result = scanNext();\n } while (result >= 12 /* SyntaxKind.LineCommentTrivia */ && result <= 15 /* SyntaxKind.Trivia */);\n return result;\n }\n return {\n setPosition: setPosition,\n getPosition: () => pos,\n scan: ignoreTrivia ? scanNextNonTrivia : scanNext,\n getToken: () => token,\n getTokenValue: () => value,\n getTokenOffset: () => tokenOffset,\n getTokenLength: () => pos - tokenOffset,\n getTokenStartLine: () => lineStartOffset,\n getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,\n getTokenError: () => scanError,\n };\n}\nfunction isWhiteSpace(ch) {\n return ch === 32 /* CharacterCodes.space */ || ch === 9 /* CharacterCodes.tab */;\n}\nfunction isLineBreak(ch) {\n return ch === 10 /* CharacterCodes.lineFeed */ || ch === 13 /* CharacterCodes.carriageReturn */;\n}\nfunction isDigit(ch) {\n return ch >= 48 /* CharacterCodes._0 */ && ch <= 57 /* CharacterCodes._9 */;\n}\nvar CharacterCodes;\n(function (CharacterCodes) {\n CharacterCodes[CharacterCodes[\"lineFeed\"] = 10] = \"lineFeed\";\n CharacterCodes[CharacterCodes[\"carriageReturn\"] = 13] = \"carriageReturn\";\n CharacterCodes[CharacterCodes[\"space\"] = 32] = \"space\";\n CharacterCodes[CharacterCodes[\"_0\"] = 48] = \"_0\";\n CharacterCodes[CharacterCodes[\"_1\"] = 49] = \"_1\";\n CharacterCodes[CharacterCodes[\"_2\"] = 50] = \"_2\";\n CharacterCodes[CharacterCodes[\"_3\"] = 51] = \"_3\";\n CharacterCodes[CharacterCodes[\"_4\"] = 52] = \"_4\";\n CharacterCodes[CharacterCodes[\"_5\"] = 53] = \"_5\";\n CharacterCodes[CharacterCodes[\"_6\"] = 54] = \"_6\";\n CharacterCodes[CharacterCodes[\"_7\"] = 55] = \"_7\";\n CharacterCodes[CharacterCodes[\"_8\"] = 56] = \"_8\";\n CharacterCodes[CharacterCodes[\"_9\"] = 57] = \"_9\";\n CharacterCodes[CharacterCodes[\"a\"] = 97] = \"a\";\n CharacterCodes[CharacterCodes[\"b\"] = 98] = \"b\";\n CharacterCodes[CharacterCodes[\"c\"] = 99] = \"c\";\n CharacterCodes[CharacterCodes[\"d\"] = 100] = \"d\";\n CharacterCodes[CharacterCodes[\"e\"] = 101] = \"e\";\n CharacterCodes[CharacterCodes[\"f\"] = 102] = \"f\";\n CharacterCodes[CharacterCodes[\"g\"] = 103] = \"g\";\n CharacterCodes[CharacterCodes[\"h\"] = 104] = \"h\";\n CharacterCodes[CharacterCodes[\"i\"] = 105] = \"i\";\n CharacterCodes[CharacterCodes[\"j\"] = 106] = \"j\";\n CharacterCodes[CharacterCodes[\"k\"] = 107] = \"k\";\n CharacterCodes[CharacterCodes[\"l\"] = 108] = \"l\";\n CharacterCodes[CharacterCodes[\"m\"] = 109] = \"m\";\n CharacterCodes[CharacterCodes[\"n\"] = 110] = \"n\";\n CharacterCodes[CharacterCodes[\"o\"] = 111] = \"o\";\n CharacterCodes[CharacterCodes[\"p\"] = 112] = \"p\";\n CharacterCodes[CharacterCodes[\"q\"] = 113] = \"q\";\n CharacterCodes[CharacterCodes[\"r\"] = 114] = \"r\";\n CharacterCodes[CharacterCodes[\"s\"] = 115] = \"s\";\n CharacterCodes[CharacterCodes[\"t\"] = 116] = \"t\";\n CharacterCodes[CharacterCodes[\"u\"] = 117] = \"u\";\n CharacterCodes[CharacterCodes[\"v\"] = 118] = \"v\";\n CharacterCodes[CharacterCodes[\"w\"] = 119] = \"w\";\n CharacterCodes[CharacterCodes[\"x\"] = 120] = \"x\";\n CharacterCodes[CharacterCodes[\"y\"] = 121] = \"y\";\n CharacterCodes[CharacterCodes[\"z\"] = 122] = \"z\";\n CharacterCodes[CharacterCodes[\"A\"] = 65] = \"A\";\n CharacterCodes[CharacterCodes[\"B\"] = 66] = \"B\";\n CharacterCodes[CharacterCodes[\"C\"] = 67] = \"C\";\n CharacterCodes[CharacterCodes[\"D\"] = 68] = \"D\";\n CharacterCodes[CharacterCodes[\"E\"] = 69] = \"E\";\n CharacterCodes[CharacterCodes[\"F\"] = 70] = \"F\";\n CharacterCodes[CharacterCodes[\"G\"] = 71] = \"G\";\n CharacterCodes[CharacterCodes[\"H\"] = 72] = \"H\";\n CharacterCodes[CharacterCodes[\"I\"] = 73] = \"I\";\n CharacterCodes[CharacterCodes[\"J\"] = 74] = \"J\";\n CharacterCodes[CharacterCodes[\"K\"] = 75] = \"K\";\n CharacterCodes[CharacterCodes[\"L\"] = 76] = \"L\";\n CharacterCodes[CharacterCodes[\"M\"] = 77] = \"M\";\n CharacterCodes[CharacterCodes[\"N\"] = 78] = \"N\";\n CharacterCodes[CharacterCodes[\"O\"] = 79] = \"O\";\n CharacterCodes[CharacterCodes[\"P\"] = 80] = \"P\";\n CharacterCodes[CharacterCodes[\"Q\"] = 81] = \"Q\";\n CharacterCodes[CharacterCodes[\"R\"] = 82] = \"R\";\n CharacterCodes[CharacterCodes[\"S\"] = 83] = \"S\";\n CharacterCodes[CharacterCodes[\"T\"] = 84] = \"T\";\n CharacterCodes[CharacterCodes[\"U\"] = 85] = \"U\";\n CharacterCodes[CharacterCodes[\"V\"] = 86] = \"V\";\n CharacterCodes[CharacterCodes[\"W\"] = 87] = \"W\";\n CharacterCodes[CharacterCodes[\"X\"] = 88] = \"X\";\n CharacterCodes[CharacterCodes[\"Y\"] = 89] = \"Y\";\n CharacterCodes[CharacterCodes[\"Z\"] = 90] = \"Z\";\n CharacterCodes[CharacterCodes[\"asterisk\"] = 42] = \"asterisk\";\n CharacterCodes[CharacterCodes[\"backslash\"] = 92] = \"backslash\";\n CharacterCodes[CharacterCodes[\"closeBrace\"] = 125] = \"closeBrace\";\n CharacterCodes[CharacterCodes[\"closeBracket\"] = 93] = \"closeBracket\";\n CharacterCodes[CharacterCodes[\"colon\"] = 58] = \"colon\";\n CharacterCodes[CharacterCodes[\"comma\"] = 44] = \"comma\";\n CharacterCodes[CharacterCodes[\"dot\"] = 46] = \"dot\";\n CharacterCodes[CharacterCodes[\"doubleQuote\"] = 34] = \"doubleQuote\";\n CharacterCodes[CharacterCodes[\"minus\"] = 45] = \"minus\";\n CharacterCodes[CharacterCodes[\"openBrace\"] = 123] = \"openBrace\";\n CharacterCodes[CharacterCodes[\"openBracket\"] = 91] = \"openBracket\";\n CharacterCodes[CharacterCodes[\"plus\"] = 43] = \"plus\";\n CharacterCodes[CharacterCodes[\"slash\"] = 47] = \"slash\";\n CharacterCodes[CharacterCodes[\"formFeed\"] = 12] = \"formFeed\";\n CharacterCodes[CharacterCodes[\"tab\"] = 9] = \"tab\";\n})(CharacterCodes || (CharacterCodes = {}));\n","export const cachedSpaces = new Array(20).fill(0).map((_, index) => {\n return ' '.repeat(index);\n});\nconst maxCachedValues = 200;\nexport const cachedBreakLinesWithSpaces = {\n ' ': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + ' '.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + ' '.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + ' '.repeat(index);\n }),\n },\n '\\t': {\n '\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\n' + '\\t'.repeat(index);\n }),\n '\\r': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r' + '\\t'.repeat(index);\n }),\n '\\r\\n': new Array(maxCachedValues).fill(0).map((_, index) => {\n return '\\r\\n' + '\\t'.repeat(index);\n }),\n }\n};\nexport const supportedEols = ['\\n', '\\r', '\\r\\n'];\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport { createScanner } from './scanner';\nvar ParseOptions;\n(function (ParseOptions) {\n ParseOptions.DEFAULT = {\n allowTrailingComma: false\n };\n})(ParseOptions || (ParseOptions = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport function getLocation(text, position) {\n const segments = []; // strings or numbers\n const earlyReturnException = new Object();\n let previousNode = undefined;\n const previousNodeInst = {\n value: {},\n offset: 0,\n length: 0,\n type: 'object',\n parent: undefined\n };\n let isAtPropertyKey = false;\n function setPreviousNode(value, offset, length, type) {\n previousNodeInst.value = value;\n previousNodeInst.offset = offset;\n previousNodeInst.length = length;\n previousNodeInst.type = type;\n previousNodeInst.colonOffset = undefined;\n previousNode = previousNodeInst;\n }\n try {\n visit(text, {\n onObjectBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n isAtPropertyKey = position > offset;\n segments.push(''); // push a placeholder (will be replaced)\n },\n onObjectProperty: (name, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(name, offset, length, 'property');\n segments[segments.length - 1] = name;\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onObjectEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onArrayBegin: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.push(0);\n },\n onArrayEnd: (offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n previousNode = undefined;\n segments.pop();\n },\n onLiteralValue: (value, offset, length) => {\n if (position < offset) {\n throw earlyReturnException;\n }\n setPreviousNode(value, offset, length, getNodeType(value));\n if (position <= offset + length) {\n throw earlyReturnException;\n }\n },\n onSeparator: (sep, offset, length) => {\n if (position <= offset) {\n throw earlyReturnException;\n }\n if (sep === ':' && previousNode && previousNode.type === 'property') {\n previousNode.colonOffset = offset;\n isAtPropertyKey = false;\n previousNode = undefined;\n }\n else if (sep === ',') {\n const last = segments[segments.length - 1];\n if (typeof last === 'number') {\n segments[segments.length - 1] = last + 1;\n }\n else {\n isAtPropertyKey = true;\n segments[segments.length - 1] = '';\n }\n previousNode = undefined;\n }\n }\n });\n }\n catch (e) {\n if (e !== earlyReturnException) {\n throw e;\n }\n }\n return {\n path: segments,\n previousNode,\n isAtPropertyKey,\n matches: (pattern) => {\n let k = 0;\n for (let i = 0; k < pattern.length && i < segments.length; i++) {\n if (pattern[k] === segments[i] || pattern[k] === '*') {\n k++;\n }\n else if (pattern[k] !== '**') {\n return false;\n }\n }\n return k === pattern.length;\n }\n };\n}\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore always check the errors list to find out if the input was valid.\n */\nexport function parse(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentProperty = null;\n let currentParent = [];\n const previousParents = [];\n function onValue(value) {\n if (Array.isArray(currentParent)) {\n currentParent.push(value);\n }\n else if (currentProperty !== null) {\n currentParent[currentProperty] = value;\n }\n }\n const visitor = {\n onObjectBegin: () => {\n const object = {};\n onValue(object);\n previousParents.push(currentParent);\n currentParent = object;\n currentProperty = null;\n },\n onObjectProperty: (name) => {\n currentProperty = name;\n },\n onObjectEnd: () => {\n currentParent = previousParents.pop();\n },\n onArrayBegin: () => {\n const array = [];\n onValue(array);\n previousParents.push(currentParent);\n currentParent = array;\n currentProperty = null;\n },\n onArrayEnd: () => {\n currentParent = previousParents.pop();\n },\n onLiteralValue: onValue,\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n return currentParent[0];\n}\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {\n let currentParent = { type: 'array', offset: -1, length: -1, children: [], parent: undefined }; // artificial root\n function ensurePropertyComplete(endOffset) {\n if (currentParent.type === 'property') {\n currentParent.length = endOffset - currentParent.offset;\n currentParent = currentParent.parent;\n }\n }\n function onValue(valueNode) {\n currentParent.children.push(valueNode);\n return valueNode;\n }\n const visitor = {\n onObjectBegin: (offset) => {\n currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] });\n },\n onObjectProperty: (name, offset, length) => {\n currentParent = onValue({ type: 'property', offset, length: -1, parent: currentParent, children: [] });\n currentParent.children.push({ type: 'string', value: name, offset, length, parent: currentParent });\n },\n onObjectEnd: (offset, length) => {\n ensurePropertyComplete(offset + length); // in case of a missing value for a property: make sure property is complete\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onArrayBegin: (offset, length) => {\n currentParent = onValue({ type: 'array', offset, length: -1, parent: currentParent, children: [] });\n },\n onArrayEnd: (offset, length) => {\n currentParent.length = offset + length - currentParent.offset;\n currentParent = currentParent.parent;\n ensurePropertyComplete(offset + length);\n },\n onLiteralValue: (value, offset, length) => {\n onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });\n ensurePropertyComplete(offset + length);\n },\n onSeparator: (sep, offset, length) => {\n if (currentParent.type === 'property') {\n if (sep === ':') {\n currentParent.colonOffset = offset;\n }\n else if (sep === ',') {\n ensurePropertyComplete(offset);\n }\n }\n },\n onError: (error, offset, length) => {\n errors.push({ error, offset, length });\n }\n };\n visit(text, visitor, options);\n const result = currentParent.children[0];\n if (result) {\n delete result.parent;\n }\n return result;\n}\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport function findNodeAtLocation(root, path) {\n if (!root) {\n return undefined;\n }\n let node = root;\n for (let segment of path) {\n if (typeof segment === 'string') {\n if (node.type !== 'object' || !Array.isArray(node.children)) {\n return undefined;\n }\n let found = false;\n for (const propertyNode of node.children) {\n if (Array.isArray(propertyNode.children) && propertyNode.children[0].value === segment && propertyNode.children.length === 2) {\n node = propertyNode.children[1];\n found = true;\n break;\n }\n }\n if (!found) {\n return undefined;\n }\n }\n else {\n const index = segment;\n if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) {\n return undefined;\n }\n node = node.children[index];\n }\n }\n return node;\n}\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport function getNodePath(node) {\n if (!node.parent || !node.parent.children) {\n return [];\n }\n const path = getNodePath(node.parent);\n if (node.parent.type === 'property') {\n const key = node.parent.children[0].value;\n path.push(key);\n }\n else if (node.parent.type === 'array') {\n const index = node.parent.children.indexOf(node);\n if (index !== -1) {\n path.push(index);\n }\n }\n return path;\n}\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport function getNodeValue(node) {\n switch (node.type) {\n case 'array':\n return node.children.map(getNodeValue);\n case 'object':\n const obj = Object.create(null);\n for (let prop of node.children) {\n const valueNode = prop.children[1];\n if (valueNode) {\n obj[prop.children[0].value] = getNodeValue(valueNode);\n }\n }\n return obj;\n case 'null':\n case 'string':\n case 'number':\n case 'boolean':\n return node.value;\n default:\n return undefined;\n }\n}\nexport function contains(node, offset, includeRightBound = false) {\n return (offset >= node.offset && offset < (node.offset + node.length)) || includeRightBound && (offset === (node.offset + node.length));\n}\n/**\n * Finds the most inner node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport function findNodeAtOffset(node, offset, includeRightBound = false) {\n if (contains(node, offset, includeRightBound)) {\n const children = node.children;\n if (Array.isArray(children)) {\n for (let i = 0; i < children.length && children[i].offset <= offset; i++) {\n const item = findNodeAtOffset(children[i], offset, includeRightBound);\n if (item) {\n return item;\n }\n }\n }\n return node;\n }\n return undefined;\n}\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport function visit(text, visitor, options = ParseOptions.DEFAULT) {\n const _scanner = createScanner(text, false);\n // Important: Only pass copies of this to visitor functions to prevent accidental modification, and\n // to not affect visitor functions which stored a reference to a previous JSONPath\n const _jsonPath = [];\n // Depth of onXXXBegin() callbacks suppressed. onXXXEnd() decrements this if it isn't 0 already.\n // Callbacks are only called when this value is 0.\n let suppressedCallbacks = 0;\n function toNoArgVisit(visitFunction) {\n return visitFunction ? () => suppressedCallbacks === 0 && visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisit(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter()) : () => true;\n }\n function toOneArgVisitWithPath(visitFunction) {\n return visitFunction ? (arg) => suppressedCallbacks === 0 && visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice()) : () => true;\n }\n function toBeginVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks++;\n }\n else {\n let cbReturn = visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter(), () => _jsonPath.slice());\n if (cbReturn === false) {\n suppressedCallbacks = 1;\n }\n }\n }\n : () => true;\n }\n function toEndVisit(visitFunction) {\n return visitFunction ?\n () => {\n if (suppressedCallbacks > 0) {\n suppressedCallbacks--;\n }\n if (suppressedCallbacks === 0) {\n visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength(), _scanner.getTokenStartLine(), _scanner.getTokenStartCharacter());\n }\n }\n : () => true;\n }\n const onObjectBegin = toBeginVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisitWithPath(visitor.onObjectProperty), onObjectEnd = toEndVisit(visitor.onObjectEnd), onArrayBegin = toBeginVisit(visitor.onArrayBegin), onArrayEnd = toEndVisit(visitor.onArrayEnd), onLiteralValue = toOneArgVisitWithPath(visitor.onLiteralValue), onSeparator = toOneArgVisit(visitor.onSeparator), onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError);\n const disallowComments = options && options.disallowComments;\n const allowTrailingComma = options && options.allowTrailingComma;\n function scanNext() {\n while (true) {\n const token = _scanner.scan();\n switch (_scanner.getTokenError()) {\n case 4 /* ScanError.InvalidUnicode */:\n handleError(14 /* ParseErrorCode.InvalidUnicode */);\n break;\n case 5 /* ScanError.InvalidEscapeCharacter */:\n handleError(15 /* ParseErrorCode.InvalidEscapeCharacter */);\n break;\n case 3 /* ScanError.UnexpectedEndOfNumber */:\n handleError(13 /* ParseErrorCode.UnexpectedEndOfNumber */);\n break;\n case 1 /* ScanError.UnexpectedEndOfComment */:\n if (!disallowComments) {\n handleError(11 /* ParseErrorCode.UnexpectedEndOfComment */);\n }\n break;\n case 2 /* ScanError.UnexpectedEndOfString */:\n handleError(12 /* ParseErrorCode.UnexpectedEndOfString */);\n break;\n case 6 /* ScanError.InvalidCharacter */:\n handleError(16 /* ParseErrorCode.InvalidCharacter */);\n break;\n }\n switch (token) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n if (disallowComments) {\n handleError(10 /* ParseErrorCode.InvalidCommentToken */);\n }\n else {\n onComment();\n }\n break;\n case 16 /* SyntaxKind.Unknown */:\n handleError(1 /* ParseErrorCode.InvalidSymbol */);\n break;\n case 15 /* SyntaxKind.Trivia */:\n case 14 /* SyntaxKind.LineBreakTrivia */:\n break;\n default:\n return token;\n }\n }\n }\n function handleError(error, skipUntilAfter = [], skipUntil = []) {\n onError(error);\n if (skipUntilAfter.length + skipUntil.length > 0) {\n let token = _scanner.getToken();\n while (token !== 17 /* SyntaxKind.EOF */) {\n if (skipUntilAfter.indexOf(token) !== -1) {\n scanNext();\n break;\n }\n else if (skipUntil.indexOf(token) !== -1) {\n break;\n }\n token = scanNext();\n }\n }\n }\n function parseString(isValue) {\n const value = _scanner.getTokenValue();\n if (isValue) {\n onLiteralValue(value);\n }\n else {\n onObjectProperty(value);\n // add property name afterwards\n _jsonPath.push(value);\n }\n scanNext();\n return true;\n }\n function parseLiteral() {\n switch (_scanner.getToken()) {\n case 11 /* SyntaxKind.NumericLiteral */:\n const tokenValue = _scanner.getTokenValue();\n let value = Number(tokenValue);\n if (isNaN(value)) {\n handleError(2 /* ParseErrorCode.InvalidNumberFormat */);\n value = 0;\n }\n onLiteralValue(value);\n break;\n case 7 /* SyntaxKind.NullKeyword */:\n onLiteralValue(null);\n break;\n case 8 /* SyntaxKind.TrueKeyword */:\n onLiteralValue(true);\n break;\n case 9 /* SyntaxKind.FalseKeyword */:\n onLiteralValue(false);\n break;\n default:\n return false;\n }\n scanNext();\n return true;\n }\n function parseProperty() {\n if (_scanner.getToken() !== 10 /* SyntaxKind.StringLiteral */) {\n handleError(3 /* ParseErrorCode.PropertyNameExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n return false;\n }\n parseString(false);\n if (_scanner.getToken() === 6 /* SyntaxKind.ColonToken */) {\n onSeparator(':');\n scanNext(); // consume colon\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n }\n else {\n handleError(5 /* ParseErrorCode.ColonExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n _jsonPath.pop(); // remove processed property name\n return true;\n }\n function parseObject() {\n onObjectBegin();\n scanNext(); // consume open brace\n let needsComma = false;\n while (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 2 /* SyntaxKind.CloseBraceToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (!parseProperty()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [2 /* SyntaxKind.CloseBraceToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onObjectEnd();\n if (_scanner.getToken() !== 2 /* SyntaxKind.CloseBraceToken */) {\n handleError(7 /* ParseErrorCode.CloseBraceExpected */, [2 /* SyntaxKind.CloseBraceToken */], []);\n }\n else {\n scanNext(); // consume close brace\n }\n return true;\n }\n function parseArray() {\n onArrayBegin();\n scanNext(); // consume open bracket\n let isFirstElement = true;\n let needsComma = false;\n while (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */ && _scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n if (_scanner.getToken() === 5 /* SyntaxKind.CommaToken */) {\n if (!needsComma) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n }\n onSeparator(',');\n scanNext(); // consume comma\n if (_scanner.getToken() === 4 /* SyntaxKind.CloseBracketToken */ && allowTrailingComma) {\n break;\n }\n }\n else if (needsComma) {\n handleError(6 /* ParseErrorCode.CommaExpected */, [], []);\n }\n if (isFirstElement) {\n _jsonPath.push(0);\n isFirstElement = false;\n }\n else {\n _jsonPath[_jsonPath.length - 1]++;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], [4 /* SyntaxKind.CloseBracketToken */, 5 /* SyntaxKind.CommaToken */]);\n }\n needsComma = true;\n }\n onArrayEnd();\n if (!isFirstElement) {\n _jsonPath.pop(); // remove array index\n }\n if (_scanner.getToken() !== 4 /* SyntaxKind.CloseBracketToken */) {\n handleError(8 /* ParseErrorCode.CloseBracketExpected */, [4 /* SyntaxKind.CloseBracketToken */], []);\n }\n else {\n scanNext(); // consume close bracket\n }\n return true;\n }\n function parseValue() {\n switch (_scanner.getToken()) {\n case 3 /* SyntaxKind.OpenBracketToken */:\n return parseArray();\n case 1 /* SyntaxKind.OpenBraceToken */:\n return parseObject();\n case 10 /* SyntaxKind.StringLiteral */:\n return parseString(true);\n default:\n return parseLiteral();\n }\n }\n scanNext();\n if (_scanner.getToken() === 17 /* SyntaxKind.EOF */) {\n if (options.allowEmptyContent) {\n return true;\n }\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (!parseValue()) {\n handleError(4 /* ParseErrorCode.ValueExpected */, [], []);\n return false;\n }\n if (_scanner.getToken() !== 17 /* SyntaxKind.EOF */) {\n handleError(9 /* ParseErrorCode.EndOfFileExpected */, [], []);\n }\n return true;\n}\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport function stripComments(text, replaceCh) {\n let _scanner = createScanner(text), parts = [], kind, offset = 0, pos;\n do {\n pos = _scanner.getPosition();\n kind = _scanner.scan();\n switch (kind) {\n case 12 /* SyntaxKind.LineCommentTrivia */:\n case 13 /* SyntaxKind.BlockCommentTrivia */:\n case 17 /* SyntaxKind.EOF */:\n if (offset !== pos) {\n parts.push(text.substring(offset, pos));\n }\n if (replaceCh !== undefined) {\n parts.push(_scanner.getTokenValue().replace(/[^\\r\\n]/g, replaceCh));\n }\n offset = _scanner.getPosition();\n break;\n }\n } while (kind !== 17 /* SyntaxKind.EOF */);\n return parts.join('');\n}\nexport function getNodeType(value) {\n switch (typeof value) {\n case 'boolean': return 'boolean';\n case 'number': return 'number';\n case 'string': return 'string';\n case 'object': {\n if (!value) {\n return 'null';\n }\n else if (Array.isArray(value)) {\n return 'array';\n }\n return 'object';\n }\n default: return 'null';\n }\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\nimport * as formatter from './impl/format';\nimport * as edit from './impl/edit';\nimport * as scanner from './impl/scanner';\nimport * as parser from './impl/parser';\n/**\n * Creates a JSON scanner on the given text.\n * If ignoreTrivia is set, whitespaces or comments are ignored.\n */\nexport const createScanner = scanner.createScanner;\nexport var ScanError;\n(function (ScanError) {\n ScanError[ScanError[\"None\"] = 0] = \"None\";\n ScanError[ScanError[\"UnexpectedEndOfComment\"] = 1] = \"UnexpectedEndOfComment\";\n ScanError[ScanError[\"UnexpectedEndOfString\"] = 2] = \"UnexpectedEndOfString\";\n ScanError[ScanError[\"UnexpectedEndOfNumber\"] = 3] = \"UnexpectedEndOfNumber\";\n ScanError[ScanError[\"InvalidUnicode\"] = 4] = \"InvalidUnicode\";\n ScanError[ScanError[\"InvalidEscapeCharacter\"] = 5] = \"InvalidEscapeCharacter\";\n ScanError[ScanError[\"InvalidCharacter\"] = 6] = \"InvalidCharacter\";\n})(ScanError || (ScanError = {}));\nexport var SyntaxKind;\n(function (SyntaxKind) {\n SyntaxKind[SyntaxKind[\"OpenBraceToken\"] = 1] = \"OpenBraceToken\";\n SyntaxKind[SyntaxKind[\"CloseBraceToken\"] = 2] = \"CloseBraceToken\";\n SyntaxKind[SyntaxKind[\"OpenBracketToken\"] = 3] = \"OpenBracketToken\";\n SyntaxKind[SyntaxKind[\"CloseBracketToken\"] = 4] = \"CloseBracketToken\";\n SyntaxKind[SyntaxKind[\"CommaToken\"] = 5] = \"CommaToken\";\n SyntaxKind[SyntaxKind[\"ColonToken\"] = 6] = \"ColonToken\";\n SyntaxKind[SyntaxKind[\"NullKeyword\"] = 7] = \"NullKeyword\";\n SyntaxKind[SyntaxKind[\"TrueKeyword\"] = 8] = \"TrueKeyword\";\n SyntaxKind[SyntaxKind[\"FalseKeyword\"] = 9] = \"FalseKeyword\";\n SyntaxKind[SyntaxKind[\"StringLiteral\"] = 10] = \"StringLiteral\";\n SyntaxKind[SyntaxKind[\"NumericLiteral\"] = 11] = \"NumericLiteral\";\n SyntaxKind[SyntaxKind[\"LineCommentTrivia\"] = 12] = \"LineCommentTrivia\";\n SyntaxKind[SyntaxKind[\"BlockCommentTrivia\"] = 13] = \"BlockCommentTrivia\";\n SyntaxKind[SyntaxKind[\"LineBreakTrivia\"] = 14] = \"LineBreakTrivia\";\n SyntaxKind[SyntaxKind[\"Trivia\"] = 15] = \"Trivia\";\n SyntaxKind[SyntaxKind[\"Unknown\"] = 16] = \"Unknown\";\n SyntaxKind[SyntaxKind[\"EOF\"] = 17] = \"EOF\";\n})(SyntaxKind || (SyntaxKind = {}));\n/**\n * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.\n */\nexport const getLocation = parser.getLocation;\n/**\n * Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n * Therefore, always check the errors list to find out if the input was valid.\n */\nexport const parse = parser.parse;\n/**\n * Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.\n */\nexport const parseTree = parser.parseTree;\n/**\n * Finds the node at the given path in a JSON DOM.\n */\nexport const findNodeAtLocation = parser.findNodeAtLocation;\n/**\n * Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.\n */\nexport const findNodeAtOffset = parser.findNodeAtOffset;\n/**\n * Gets the JSON path of the given JSON DOM node\n */\nexport const getNodePath = parser.getNodePath;\n/**\n * Evaluates the JavaScript object of the given JSON DOM node\n */\nexport const getNodeValue = parser.getNodeValue;\n/**\n * Parses the given text and invokes the visitor functions for each object, array and literal reached.\n */\nexport const visit = parser.visit;\n/**\n * Takes JSON with JavaScript-style comments and remove\n * them. Optionally replaces every none-newline character\n * of comments with a replaceCharacter\n */\nexport const stripComments = parser.stripComments;\nexport var ParseErrorCode;\n(function (ParseErrorCode) {\n ParseErrorCode[ParseErrorCode[\"InvalidSymbol\"] = 1] = \"InvalidSymbol\";\n ParseErrorCode[ParseErrorCode[\"InvalidNumberFormat\"] = 2] = \"InvalidNumberFormat\";\n ParseErrorCode[ParseErrorCode[\"PropertyNameExpected\"] = 3] = \"PropertyNameExpected\";\n ParseErrorCode[ParseErrorCode[\"ValueExpected\"] = 4] = \"ValueExpected\";\n ParseErrorCode[ParseErrorCode[\"ColonExpected\"] = 5] = \"ColonExpected\";\n ParseErrorCode[ParseErrorCode[\"CommaExpected\"] = 6] = \"CommaExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBraceExpected\"] = 7] = \"CloseBraceExpected\";\n ParseErrorCode[ParseErrorCode[\"CloseBracketExpected\"] = 8] = \"CloseBracketExpected\";\n ParseErrorCode[ParseErrorCode[\"EndOfFileExpected\"] = 9] = \"EndOfFileExpected\";\n ParseErrorCode[ParseErrorCode[\"InvalidCommentToken\"] = 10] = \"InvalidCommentToken\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfComment\"] = 11] = \"UnexpectedEndOfComment\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfString\"] = 12] = \"UnexpectedEndOfString\";\n ParseErrorCode[ParseErrorCode[\"UnexpectedEndOfNumber\"] = 13] = \"UnexpectedEndOfNumber\";\n ParseErrorCode[ParseErrorCode[\"InvalidUnicode\"] = 14] = \"InvalidUnicode\";\n ParseErrorCode[ParseErrorCode[\"InvalidEscapeCharacter\"] = 15] = \"InvalidEscapeCharacter\";\n ParseErrorCode[ParseErrorCode[\"InvalidCharacter\"] = 16] = \"InvalidCharacter\";\n})(ParseErrorCode || (ParseErrorCode = {}));\nexport function printParseErrorCode(code) {\n switch (code) {\n case 1 /* ParseErrorCode.InvalidSymbol */: return 'InvalidSymbol';\n case 2 /* ParseErrorCode.InvalidNumberFormat */: return 'InvalidNumberFormat';\n case 3 /* ParseErrorCode.PropertyNameExpected */: return 'PropertyNameExpected';\n case 4 /* ParseErrorCode.ValueExpected */: return 'ValueExpected';\n case 5 /* ParseErrorCode.ColonExpected */: return 'ColonExpected';\n case 6 /* ParseErrorCode.CommaExpected */: return 'CommaExpected';\n case 7 /* ParseErrorCode.CloseBraceExpected */: return 'CloseBraceExpected';\n case 8 /* ParseErrorCode.CloseBracketExpected */: return 'CloseBracketExpected';\n case 9 /* ParseErrorCode.EndOfFileExpected */: return 'EndOfFileExpected';\n case 10 /* ParseErrorCode.InvalidCommentToken */: return 'InvalidCommentToken';\n case 11 /* ParseErrorCode.UnexpectedEndOfComment */: return 'UnexpectedEndOfComment';\n case 12 /* ParseErrorCode.UnexpectedEndOfString */: return 'UnexpectedEndOfString';\n case 13 /* ParseErrorCode.UnexpectedEndOfNumber */: return 'UnexpectedEndOfNumber';\n case 14 /* ParseErrorCode.InvalidUnicode */: return 'InvalidUnicode';\n case 15 /* ParseErrorCode.InvalidEscapeCharacter */: return 'InvalidEscapeCharacter';\n case 16 /* ParseErrorCode.InvalidCharacter */: return 'InvalidCharacter';\n }\n return '<unknown ParseErrorCode>';\n}\n/**\n * Computes the edit operations needed to format a JSON document.\n *\n * @param documentText The input text\n * @param range The range to format or `undefined` to format the full content\n * @param options The formatting options\n * @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function format(documentText, range, options) {\n return formatter.format(documentText, range, options);\n}\n/**\n * Computes the edit operations needed to modify a value in the JSON document.\n *\n * @param documentText The input text\n * @param path The path of the value to change. The path represents either to the document root, a property or an array item.\n * If the path points to an non-existing property or item, it will be created.\n * @param value The new value for the specified property or item. If the value is undefined,\n * the property or item will be removed.\n * @param options Options\n * @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.\n * To apply the edit operations to the input, use {@linkcode applyEdits}.\n */\nexport function modify(text, path, value, options) {\n return edit.setProperty(text, path, value, options);\n}\n/**\n * Applies edits to an input string.\n * @param text The input text\n * @param edits Edit operations following the format described in {@linkcode EditResult}.\n * @returns The text with the applied edits.\n * @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.\n */\nexport function applyEdits(text, edits) {\n let sortedEdits = edits.slice(0).sort((a, b) => {\n const diff = a.offset - b.offset;\n if (diff === 0) {\n return a.length - b.length;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n if (e.offset + e.length <= lastModifiedOffset) {\n text = edit.applyEdit(text, e);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = e.offset;\n }\n return text;\n}\n","/**\n * Pure config validation logic — no runtime dependencies (fs, jsonc-parser, etc.)\n * This module is extracted from config.ts to enable direct unit testing.\n */\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 \"gc\",\n \"gc.algorithm\",\n \"gc.promotionThreshold\",\n \"gc.maxBlockAge\",\n \"gc.maxOldGenSummaryLength\",\n \"gc.majorGcThresholdPercent\",\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\nexport function 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\nexport interface 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 (\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 gc = config.gc\n if (gc !== undefined) {\n if (typeof gc !== \"object\" || gc === null || Array.isArray(gc)) {\n errors.push({\n key: \"gc\",\n expected: \"object\",\n actual: typeof gc,\n })\n } else {\n if (gc.algorithm !== undefined && gc.algorithm !== \"truncate\") {\n errors.push({\n key: \"gc.algorithm\",\n expected: '\"truncate\"',\n actual: JSON.stringify(gc.algorithm),\n })\n }\n if (gc.promotionThreshold !== undefined && typeof gc.promotionThreshold !== \"number\") {\n errors.push({\n key: \"gc.promotionThreshold\",\n expected: \"number\",\n actual: typeof gc.promotionThreshold,\n })\n }\n if (gc.maxBlockAge !== undefined && typeof gc.maxBlockAge !== \"number\") {\n errors.push({\n key: \"gc.maxBlockAge\",\n expected: \"number\",\n actual: typeof gc.maxBlockAge,\n })\n }\n if (\n gc.maxOldGenSummaryLength !== undefined &&\n typeof gc.maxOldGenSummaryLength !== \"number\"\n ) {\n errors.push({\n key: \"gc.maxOldGenSummaryLength\",\n expected: \"number\",\n actual: typeof gc.maxOldGenSummaryLength,\n })\n }\n if (\n gc.majorGcThresholdPercent !== undefined\n ) {\n const isValidNumber = typeof gc.majorGcThresholdPercent === \"number\"\n const isPercentString =\n typeof gc.majorGcThresholdPercent === \"string\" &&\n /^\\d+(?:\\.\\d+)?%$/.test(gc.majorGcThresholdPercent)\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key: \"gc.majorGcThresholdPercent\",\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(gc.majorGcThresholdPercent),\n })\n }\n }\n }\n }\n\n const strategies = config.strategies\n if (strategies !== undefined) {\n if (typeof strategies !== \"object\" || strategies === null || Array.isArray(strategies)) {\n errors.push({\n key: \"strategies\",\n expected: \"object\",\n actual: typeof strategies,\n })\n } else {\n const dedup = strategies.deduplication\n if (dedup !== undefined) {\n if (typeof dedup !== \"object\" || dedup === null || Array.isArray(dedup)) {\n errors.push({\n key: \"strategies.deduplication\",\n expected: \"object\",\n actual: typeof dedup,\n })\n } else {\n if (dedup.enabled !== undefined && typeof dedup.enabled !== \"boolean\") {\n errors.push({\n key: \"strategies.deduplication.enabled\",\n expected: \"boolean\",\n actual: typeof dedup.enabled,\n })\n }\n if (dedup.protectedTools !== undefined && !Array.isArray(dedup.protectedTools)) {\n errors.push({\n key: \"strategies.deduplication.protectedTools\",\n expected: \"string[]\",\n actual: typeof dedup.protectedTools,\n })\n }\n }\n }\n\n const purge = strategies.purgeErrors\n if (purge !== undefined) {\n if (typeof purge !== \"object\" || purge === null || Array.isArray(purge)) {\n errors.push({\n key: \"strategies.purgeErrors\",\n expected: \"object\",\n actual: typeof purge,\n })\n } else {\n if (purge.enabled !== undefined && typeof purge.enabled !== \"boolean\") {\n errors.push({\n key: \"strategies.purgeErrors.enabled\",\n expected: \"boolean\",\n actual: typeof purge.enabled,\n })\n }\n if (purge.turns !== undefined && typeof purge.turns !== \"number\") {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"number\",\n actual: typeof purge.turns,\n })\n }\n if (typeof purge.turns === \"number\" && purge.turns < 1) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"positive number (>= 1)\",\n actual: `${purge.turns} (will be clamped to 1)`,\n })\n }\n if (purge.protectedTools !== undefined && !Array.isArray(purge.protectedTools)) {\n errors.push({\n key: \"strategies.purgeErrors.protectedTools\",\n expected: \"string[]\",\n actual: typeof purge.protectedTools,\n })\n }\n }\n }\n }\n }\n\n return errors\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { MESSAGE_FORMAT_EXTENSION } 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 } from \"./types\"\n\nfunction buildSchema() {\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. m00001)\"),\n topic: tool.schema\n .string()\n .describe(\"Short label (3-5 words) for this one message summary\"),\n summary: tool.schema\n .string()\n .describe(\"Complete technical summary replacing that one message\"),\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\n return tool({\n description: runtimePrompts.compressMessage + MESSAGE_FORMAT_EXTENSION,\n args: buildSchema(),\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 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 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 ctx.config.gc,\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\n // [FIX Bug 17] Universal token estimation\n // opencode session.ts: adjustedInputTokens = inputTokens - cacheRead - cacheWrite\n // So: input + cacheRead + cacheWrite = prompt_tokens (total input)\n // Total context usage = prompt_tokens + output + reasoning\n return input + cacheRead + cacheWrite + output + reasoning\n }\n\n // [FIX Bug 5] fallback: estimate tokens from message content when no assistant\n // message has output tokens (first turn or after full compaction)\n let estimated = 0\n for (const m of messages) {\n const parts = Array.isArray(m.parts) ? m.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && typeof part.text === \"string\") {\n estimated += countTokens(part.text)\n }\n }\n }\n return estimated\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","// These format schemas are kept separate from the editable compress prompts\n// so they cannot be modified via custom prompt overrides. The schemas must\n// match the tool's input validation and are not safe to change independently.\n\nexport const RANGE_FORMAT_EXTENSION = `\nTHE FORMAT OF COMPRESS\n\n\\`\\`\\`\n{\n topic: string, // Short label (3-5 words) - e.g., \"Auth System Exploration\"\n content: [ // One or more ranges to compress\n {\n startId: string, // Boundary ID at range start: mNNNNN or bN\n endId: string, // Boundary ID at range end: mNNNNN or bN\n summary: string // Complete technical summary replacing all content in range\n }\n ]\n}\n\\`\\`\\``\n\nexport const MESSAGE_FORMAT_EXTENSION = `\nTHE FORMAT OF COMPRESS\n\n\\`\\`\\`\n{\n topic: string, // Short label (3-5 words) for the overall batch\n content: [ // One or more messages to compress independently\n {\n messageId: string, // Raw message ID only: mNNNNN (ignore metadata attributes like priority)\n topic: string, // Short label (3-5 words) for this one message summary\n summary: string // Complete technical summary replacing that one message\n }\n ]\n}\n\\`\\`\\``\n","import type { SessionState, WithParts } from \"./state\"\nimport { isIgnoredUserMessage } from \"./messages/query\"\n\nconst MESSAGE_REF_REGEX = /^m(\\d{4,5})$/\nconst BLOCK_REF_REGEX = /^b([1-9]\\d*)$/\nconst MESSAGE_ID_TAG_NAME = \"dcp-message-id\"\n\nconst MESSAGE_REF_WIDTH = 5\nconst MESSAGE_REF_MIN_INDEX = 1\nexport const MESSAGE_REF_MAX_INDEX = 99999\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, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): 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 // [FIX Bug 29] Skip synthetic messages created by DCP\n if (rawMessageId.startsWith(\"msg_dcp_summary_\") || rawMessageId.startsWith(\"msg_dcp_text_\")) {\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\n if (parsedStartId === null) {\n issues.push(\"startId is invalid. Use an injected message ID (mNNNNN) or block ID (bN).\")\n }\n\n if (parsedEndId === null) {\n issues.push(\"endId is invalid. Use an injected message ID (mNNNNN) or block ID (bN).\")\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 let startReference = lookup.get(parsedStartId.ref)\n let endReference = lookup.get(parsedEndId.ref)\n\n if (!startReference) {\n issues.push(\n `startId ${parsedStartId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (!endReference) {\n issues.push(\n `endId ${parsedEndId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!startReference || !endReference) {\n throw new Error(\"Failed to resolve boundary IDs\")\n }\n\n // [FIX Bug 34] Auto-swap reversed boundaries instead of throwing.\n // Block IDs (bN) are assigned in creation order, which may not match\n // conversation order. Models naturally assume bN < bM means bN is earlier,\n // but anchor message ordering can differ. Auto-swap prevents compress failures\n // that cause models to give up without compressing.\n if (startReference.rawIndex > endReference.rawIndex) {\n [startReference, endReference] = [endReference, startReference]\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 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 return lookup\n}\n","import type { CompressionBlock, PruneMessagesState, SessionState } from \"../state\"\nimport { formatBlockRef, formatMessageIdTag } from \"../message-ids\"\nimport type { AppliedCompressionResult, CompressionStateInput, SelectionResolution } from \"./types\"\nimport type { GCConfig } from \"../config\"\n\nconst DEFAULT_PROMOTION_THRESHOLD = 5\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 gcConfig?: GCConfig,\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 survivedCount: 0,\n generation: \"young\",\n }\n\n const promotionThreshold = gcConfig?.promotionThreshold ?? DEFAULT_PROMOTION_THRESHOLD\n for (const [activeId, activeBlock] of messagesState.blocksById) {\n if (!activeBlock.active) continue\n if (consumed.includes(activeId)) continue\n activeBlock.survivedCount = (activeBlock.survivedCount || 0) + 1\n if (activeBlock.survivedCount >= promotionThreshold) {\n activeBlock.generation = \"old\"\n }\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 (typeof entry?.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary is required and must be a non-empty string`)\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 // [FIX Bug 30] Prevent model from treating compress result as conversation end\n const instruction = \"\\nIMPORTANT: This was an automatic context compression. You MUST continue your previous task exactly where you left off. Do NOT ask the user what to do next.\"\n\n if (skippedCount === 0) {\n return processedText + instruction\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}${instruction}`\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 mNNNNN.\",\n \"are invalid. Use injected raw message IDs of the form mNNNNN.\",\n ],\n \"block-id\": [\n \"is invalid here. Block IDs like bN are not allowed; use an mNNNNN message ID instead.\",\n \"are invalid here. Block IDs like bN are not allowed; use mNNNNN message IDs instead.\",\n ],\n \"not-in-context\": [\n \"is not available in the current conversation context. Choose an injected mNNNNN ID visible in context.\",\n \"are not available in the current conversation context. Choose injected mNNNNN 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 ACP plugin.\n * Persists pruned tool IDs across sessions so they survive OpenCode restarts.\n * Storage location: ~/.local/share/opencode/storage/plugin/acp/{sessionId}.json\n */\n\nimport * as fs from \"fs/promises\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport { cpSync, existsSync as existsSyncSync } from \"fs\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { serializePruneMessagesState } from \"./utils\"\n\nconst LEGACY_STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n)\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 PersistedMessageIds {\n byRawId: Record<string, string>\n byRef: Record<string, string>\n nextRef: number\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n messageIds?: PersistedMessageIds\n lastCompaction?: number\n}\n\nconst STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"acp\",\n)\n\n/** One-time migration: copy plugin/dcp/ → plugin/acp/ if ACP dir doesn't exist yet */\nfunction migrateFromLegacyIfNeeded(logger: Logger): void {\n if (existsSyncSync(STORAGE_DIR)) return\n if (!existsSyncSync(LEGACY_STORAGE_DIR)) return\n try {\n cpSync(LEGACY_STORAGE_DIR, STORAGE_DIR, { recursive: true })\n logger.info(`[ACP] Migrated storage from ${LEGACY_STORAGE_DIR} → ${STORAGE_DIR}`)\n } catch (e: any) {\n logger.warn(`[ACP] Storage migration failed: ${e.message}`)\n }\n}\n\nasync function ensureStorageDir(logger: Logger): Promise<void> {\n if (!existsSync(STORAGE_DIR)) {\n migrateFromLegacyIfNeeded(logger)\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(logger)\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\n// [FIX Bug 6] Removed try/catch — errors now propagate to callers so they know save failed\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 state: PersistedSessionState = {\n sessionName: sessionName,\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 messageIds: {\n byRawId: Object.fromEntries(sessionState.messageIds.byRawId),\n byRef: Object.fromEntries(sessionState.messageIds.byRef),\n nextRef: sessionState.messageIds.nextRef,\n },\n lastCompaction: sessionState.lastCompaction,\n }\n\n await writePersistedSessionState(sessionState.sessionId, state, logger)\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 const persistedMessageIds = (state as any).messageIds as PersistedMessageIds | undefined\n if (persistedMessageIds) {\n ;(state as any)._persistedMessageIds = persistedMessageIds\n }\n const persistedLastCompaction = (state as any).lastCompaction as number | undefined\n if (persistedLastCompaction !== undefined) {\n ;(state as any)._persistedLastCompaction = persistedLastCompaction\n }\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\n// [FIX Bug 3] Added summary check to match getCurrentTokenUsage exclusion logic\nexport const isMessageCompacted = (state: SessionState, msg: WithParts): boolean => {\n if (!isMessageWithInfo(msg)) {\n return false\n }\n\n if (state.lastCompaction <= 0) return false\n if (msg.info.time.created < state.lastCompaction) {\n return true\n }\n if (msg.info.summary === true && 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 survivedCount:\n typeof block.survivedCount === \"number\" && Number.isFinite(block.survivedCount)\n ? Math.max(0, Math.floor(block.survivedCount))\n : 0,\n generation:\n block.generation === \"young\" || block.generation === \"old\"\n ? block.generation\n : undefined,\n })\n }\n }\n\n // [FIX Bug 11] Skip loading persisted activeBlockIds here.\n // They will be correctly rebuilt from blocksById below (lines 273-286).\n // Loading them here first caused stale IDs for blocks with active:false.\n\n if (\n persisted.activeByAnchorMessageId &&\n typeof persisted.activeByAnchorMessageId === \"object\"\n ) {\n for (const [anchorMessageId, blockId] of Object.entries(\n persisted.activeByAnchorMessageId,\n )) {\n if (typeof blockId !== \"number\" || !Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeByAnchorMessageId.set(anchorMessageId, blockId)\n }\n }\n\n for (const [blockId, block] of state.blocksById) {\n if (block.active) {\n state.activeBlockIds.add(blockId)\n if (block.anchorMessageId) {\n state.activeByAnchorMessageId.set(block.anchorMessageId, blockId)\n }\n }\n if (blockId >= state.nextBlockId) {\n state.nextBlockId = blockId + 1\n }\n if (block.runId >= state.nextRunId) {\n state.nextRunId = block.runId + 1\n }\n }\n\n return state\n}\n\nexport function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {\n const anchors = new Set<string>()\n let pendingUserMessageId: string | null = null\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n\n if (messageHasCompress(message)) {\n break\n }\n\n if (message.info.role === \"user\") {\n if (!isIgnoredUserMessage(message)) {\n pendingUserMessageId = message.info.id\n }\n continue\n }\n\n if (message.info.role === \"assistant\" && pendingUserMessageId) {\n anchors.add(message.info.id)\n anchors.add(pendingUserMessageId)\n pendingUserMessageId = null\n }\n }\n\n return anchors\n}\n\nexport function getActiveSummaryTokenUsage(state: SessionState): number {\n let total = 0\n for (const blockId of state.prune.messages.activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block || !block.active) {\n continue\n }\n total += block.summaryTokens\n }\n return total\n}\n\nexport function resetOnCompaction(state: SessionState): void {\n state.toolParameters.clear()\n state.prune.tools = new Map<string, number>()\n // [PATCH Bug 2] Preserve prune.messages (compression blocks) on compaction.\n // Only reset transient state. Compression blocks are still valid even after\n // opencode compacts — their summaries are still needed in context.\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n }\n // [FIX] Reset message IDs on compaction — old mappings are stale after\n // compaction replaces messages with a summary. Keeping them causes\n // assignMessageRefs to allocate from stale nextRef positions.\n state.messageIds = {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\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\"\nimport { parseMessageRef, formatMessageRef } from \"../message-ids\"\n\nexport const checkSession = async (\n client: any,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n manualModeDefault: boolean,\n): Promise<void> => {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return\n }\n\n const lastSessionId = lastUserMessage.info.sessionID\n\n if (state.sessionId === null || state.sessionId !== lastSessionId) {\n logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`)\n try {\n await ensureSessionInitialized(\n client,\n state,\n lastSessionId,\n logger,\n messages,\n manualModeDefault,\n )\n } catch (err: any) {\n logger.error(\"Failed to initialize session state\", { error: err.message })\n }\n }\n\n const lastCompactionTimestamp = findLastCompactionTimestamp(messages)\n if (lastCompactionTimestamp > state.lastCompaction) {\n state.lastCompaction = lastCompactionTimestamp\n resetOnCompaction(state)\n logger.info(\"Detected compaction - reset stale state\", {\n timestamp: lastCompactionTimestamp,\n })\n\n saveSessionState(state, logger).catch((error) => {\n logger.warn(\"Failed to persist state reset after compaction\", {\n error: error instanceof Error ? error.message : String(error),\n })\n })\n }\n\n state.currentTurn = countTurns(state, messages)\n}\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 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 const persistedAny = persisted as any\n if (persistedAny._persistedMessageIds) {\n state.messageIds = {\n byRawId: new Map(Object.entries(persistedAny._persistedMessageIds.byRawId || {})),\n byRef: new Map(Object.entries(persistedAny._persistedMessageIds.byRef || {})),\n nextRef: persistedAny._persistedMessageIds.nextRef || 1,\n }\n // [FIX Bug 29] Auto-cleanup stale synthetic message refs from persistence\n for (const [rawId, ref] of state.messageIds.byRawId) {\n if (rawId.startsWith(\"msg_dcp_summary_\") || rawId.startsWith(\"msg_dcp_text_\")) {\n state.messageIds.byRawId.delete(rawId)\n state.messageIds.byRef.delete(ref)\n }\n }\n // Migrate 4-digit refs (m0001) to 5-digit (m00001) for msgid expansion\n for (const [rawId, oldRef] of state.messageIds.byRawId) {\n const parsed = parseMessageRef(oldRef)\n if (parsed !== null) {\n const newRef = formatMessageRef(parsed)\n if (newRef !== oldRef) {\n state.messageIds.byRawId.set(rawId, newRef)\n state.messageIds.byRef.delete(oldRef)\n state.messageIds.byRef.set(newRef, rawId)\n }\n }\n }\n }\n if (persistedAny._persistedLastCompaction !== undefined) {\n state.lastCompaction = Math.max(state.lastCompaction, persistedAny._persistedLastCompaction)\n }\n\n const applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\n // [FIX Bug 1] Always save after initialization to persist messageIds + lastCompaction\n await saveSessionState(state, logger)\n}\n","import type { SessionState, ToolStatus, WithParts } from \"./index\"\nimport type { Logger } from \"../logger\"\nimport { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"./utils\"\nimport { countToolTokens, extractToolContent } 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 // [FIX Bug 33] Use fast token estimate instead of expensive Anthropic tokenizer\n // The tokenizer takes ~50ms per call; with 500+ tools that's 25 seconds.\n // text.length / 4 is accurate enough for pruning decisions.\n const contents = extractToolContent(part)\n const rawLength = contents.reduce((sum: number, s: string) => sum + (s?.length ?? 0), 0)\n const tokenCount = Math.round(rawLength / 4)\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 [`▣ ACP | ${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\nconst NOTIFICATION_SUMMARY_MAX_CHARS = 1500\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: \"ACP: 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 let result = \"\"\n for (const entry of entries) {\n const topic =\n state.prune.messages.blocksById.get(entry.blockId)?.topic ?? \"(unknown topic)\"\n const section = `### ${topic}\\n${entry.summary}`\n if (result.length + section.length + 2 > NOTIFICATION_SUMMARY_MAX_CHARS) {\n result += `\\n\\n... and ${entries.length - entries.indexOf(entry)} more`\n break\n }\n result += (result ? \"\\n\\n\" : \"\") + section\n }\n return result\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 = `▣ ACP | ${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 const displaySummary =\n summary.length > NOTIFICATION_SUMMARY_MAX_CHARS\n ? truncateToastSummary(summary, NOTIFICATION_SUMMARY_MAX_CHARS)\n : summary\n message += `\\n→ Compression (~${summaryTokensStr}): ${displaySummary}`\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}): ${truncateToastSummary(summary, NOTIFICATION_SUMMARY_MAX_CHARS)}`,\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: \"ACP: 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 { tool } from \"@opencode-ai/plugin\"\nimport type { ToolContext } from \"./types\"\nimport { countTokens } from \"../token-utils\"\nimport { RANGE_FORMAT_EXTENSION } 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 } from \"./types\"\n\nfunction buildSchema() {\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 \"Message or block ID marking the beginning of range (e.g. m00001, b2)\",\n ),\n endId: tool.schema\n .string()\n .describe(\"Message or block ID marking the end of range (e.g. m00012, b5)\"),\n summary: tool.schema\n .string()\n .describe(\"Complete technical summary replacing all content in range\"),\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\n return tool({\n description: runtimePrompts.compressRange + RANGE_FORMAT_EXTENSION,\n args: buildSchema(),\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 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 const parsedPlaceholders = parseBlockPlaceholders(plan.entry.summary)\n 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 [],\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n const mergeConsumedBlockIds = extractBoundaryConsumedBlocks(\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: mergeConsumedBlockIds,\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 ctx.config.gc,\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}.\\nIMPORTANT: This was an automatic context compression. You MUST continue your previous task exactly where you left off. Do NOT ask the user what to do next.`\n },\n })\n}\n\nfunction extractBoundaryConsumedBlocks(\n startReference: { kind: string; blockId?: number },\n endReference: { kind: string; blockId?: number },\n): number[] {\n const consumed: number[] = []\n const seen = new Set<number>()\n for (const ref of [startReference, endReference]) {\n if (ref.kind === \"compressed-block\" && ref.blockId !== undefined && !seen.has(ref.blockId)) {\n seen.add(ref.blockId)\n consumed.push(ref.blockId)\n }\n }\n return consumed\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 (typeof entry?.summary !== \"string\" || entry.summary.trim().length === 0) {\n throw new Error(`${prefix}.summary is required and must be a non-empty string`)\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 return {\n expandedSummary: summary,\n consumedBlockIds: [],\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n _missingBlockIds: number[],\n _summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n return {\n expandedSummary: summary,\n consumedBlockIds: [...consumedBlockIds],\n }\n}\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\", \"acp\")\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 if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"INFO\", component, message, data)\n }\n\n debug(message: string, data?: any) {\n if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"DEBUG\", component, message, data)\n }\n\n warn(message: string, data?: any) {\n if (!this.enabled) return\n const component = this.getCallerFile(2)\n return this.write(\"WARN\", component, message, data)\n }\n\n error(message: string, data?: any) {\n if (!this.enabled) return\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, cpSync } 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 ACP 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\", \"acp-prompts\")\n const legacyGlobalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n\n if (!existsSync(globalRoot) && existsSync(legacyGlobalRoot)) {\n try {\n cpSync(legacyGlobalRoot, globalRoot, { recursive: true })\n console.log(\"[ACP] Migrated prompts from dcp-prompts to acp-prompts\")\n } catch (e: any) {\n console.warn(`[ACP] Prompts migration failed: ${e.message}`)\n }\n }\n\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, \"acp-prompts\", \"overrides\")\n : null\n\n const opencodeDir = findOpencodeDir(workingDirectory)\n const projectOverridesDir = opencodeDir ? join(opencodeDir, \"acp-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(\"# ACP Prompt Defaults\")\n lines.push(\"\")\n lines.push(\"This directory stores the ACP 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/acp-prompts/overrides/` (project)\")\n lines.push(\"2. `$OPENCODE_CONFIG_DIR/acp-prompts/overrides/` (config dir)\")\n lines.push(\"3. `~/.config/opencode/acp-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 operate in a context-constrained environment. Manage context continuously to avoid buildup and preserve retrieval quality. Efficient context management is paramount for your agentic performance.\n\nThe ONLY tool you have for context management is \\`compress\\`. It replaces older conversation content with technical summaries you produce.\n\n\\`<dcp-message-id>\\` and \\`<dcp-system-reminder>\\` tags are environment-injected metadata. Do not output them.\n\nTHE PHILOSOPHY OF COMPRESS\n\\`compress\\` transforms conversation content into dense, high-fidelity summaries. This is not cleanup - it is crystallization. Your summary becomes the authoritative record of what transpired.\n\nThink of compression as phase transitions: raw exploration becomes refined understanding. The original context served its purpose; your summary now carries that understanding forward.\n\nCOMPRESS WHEN\n\nA section is genuinely closed and the raw conversation has served its purpose:\n\n- Research concluded and findings are clear\n- Implementation finished and verified\n- Exploration exhausted and patterns understood\n- Dead-end noise can be discarded without waiting for a whole chapter to close\n\nDO NOT COMPRESS IF\n\n- Raw context is still relevant and needed for edits or precise references\n- The target content is still actively in progress\n- You may need exact code, error messages, or file contents in the immediate next steps\n\nBefore compressing, ask: _\"Is this section closed enough to become summary-only right now?\"_\n\nEvaluate conversation signal-to-noise REGULARLY. Use \\`compress\\` deliberately with quality-first summaries. Prioritize stale content intelligently to maintain a high-signal context window that supports your agency.\n\nIt is of your responsibility to keep a sharp, high-quality context window for optimal performance.\n`\n","export const COMPRESS_RANGE = `Collapse a range in the conversation into a detailed summary.\n\nTHE SUMMARY\nYour summary must be EXHAUSTIVE. Capture file paths, function signatures, decisions made, constraints discovered, key findings... EVERYTHING that maintains context integrity. This is not a brief note - it is an authoritative record so faithful that the original conversation adds no value.\n\nUSER INTENT FIDELITY\nWhen the compressed range includes user messages, preserve the user's intent with extra care. Do not change scope, constraints, priorities, acceptance criteria, or requested outcomes.\nDirectly quote user messages when they are short enough to include safely. Direct quotes are preferred when they best preserve exact meaning.\n\nYet be LEAN. Strip away the noise: failed attempts that led nowhere, verbose tool outputs, back-and-forth exploration. What remains should be pure signal - golden nuggets of detail that preserve full understanding with zero ambiguity.\n\nCOMPRESSED BLOCK PLACEHOLDERS\nWhen the selected range includes previously compressed blocks, use this exact placeholder format when referencing one:\n\n- \\`(bN)\\`\n\nCompressed block sections in context are clearly marked with a header:\n\n- \\`[Compressed conversation section]\\`\n\nCompressed block IDs always use the \\`bN\\` form (never \\`mNNNNN\\`) and are represented in the same XML metadata tag format.\n\nRules:\n\n- Include every required block placeholder exactly once.\n- Do not invent placeholders for blocks outside the selected range.\n- Treat \\`(bN)\\` placeholders as RESERVED TOKENS. Do not emit \\`(bN)\\` text anywhere except intentional placeholders.\n- If you need to mention a block in prose, use plain text like \\`compressed bN\\` (not as a placeholder).\n- Preflight check before finalizing: the set of \\`(bN)\\` placeholders in your summary must exactly match the required set, with no duplicates.\n\nThese placeholders are semantic references. They will be replaced with the full stored compressed block content when the tool processes your output.\n\nFLOW PRESERVATION WITH PLACEHOLDERS\nWhen you use compressed block placeholders, write the surrounding summary text so it still reads correctly AFTER placeholder expansion.\n\n- Treat each placeholder as a stand-in for a full conversation segment, not as a short label.\n- Ensure transitions before and after each placeholder preserve chronology and causality.\n- Do not write text that depends on the placeholder staying literal (for example, \"as noted in \\`(b2)\\`\").\n- Your final meaning must be coherent once each placeholder is replaced with its full compressed block content.\n\nBOUNDARY IDS\nYou specify boundaries by ID using the injected IDs visible in the conversation:\n\n- \\`mNNNNN\\` IDs identify raw messages\n- \\`bN\\` IDs identify previously compressed blocks\n\nEach message has an ID inside XML metadata tags like \\`<dcp-message-id>...</dcp-message-id>\\`.\nThe same ID tag appears in every tool output of the message it belongs to — each unique ID identifies one complete message.\nTreat these tags as boundary metadata only, not as tool result content.\n\nRules:\n\n- Pick \\`startId\\` and \\`endId\\` directly from injected IDs in context.\n- IDs must exist in the current visible context. If you cannot see an ID in the messages above, it is stale and will fail.\n- \\`startId\\` must appear before \\`endId\\`.\n- Do not invent IDs. Use only IDs that are present in context.\n- NEVER use IDs from compressed block summaries, previous nudges, or your own memory — only IDs currently visible as XML metadata tags in the conversation.\n\nBATCHING\nWhen multiple independent ranges are ready and their boundaries do not overlap, include all of them as separate entries in the \\`content\\` array of a single tool call. Each entry should have its own \\`startId\\`, \\`endId\\`, and \\`summary\\`.\n`\n","export const COMPRESS_MESSAGE = `Collapse selected individual messages in the conversation into detailed summaries.\n\nTHE SUMMARY\nYour summary must be EXHAUSTIVE. Capture file paths, function signatures, decisions made, constraints discovered, key findings, tool outcomes, and user intent details that matter... EVERYTHING that preserves the value of the selected message after the raw message is removed.\n\nUSER INTENT FIDELITY\nWhen a selected message contains user intent, preserve that intent with extra care. Do not change scope, constraints, priorities, acceptance criteria, or requested outcomes.\nDirectly quote short user instructions when that best preserves exact meaning.\n\nYet be LEAN. Strip away the noise: failed attempts that led nowhere, verbose tool output, and repetition. What remains should be pure signal - golden nuggets of detail that preserve full understanding with zero ambiguity.\nIf a message contains no significant technical decisions, code changes, or user requirements, produce a minimal one-line summary rather than a detailed one.\n\nMESSAGE IDS\nYou specify individual raw messages by ID using the injected IDs visible in the conversation:\n\n- \\`mNNNNN\\` IDs identify raw messages\n\nEach message has an ID inside XML metadata tags like \\`<dcp-message-id priority=\"high\">m0007</dcp-message-id>\\`.\nThe same ID tag appears in every tool output of the message it belongs to — each unique ID identifies one complete message.\nTreat these tags as message metadata only, not as content to summarize. Use only the inner \\`mNNNNN\\` value as the \\`messageId\\`.\nThe \\`priority\\` attribute indicates relative context cost. You MUST compress high-priority messages when their full text is no longer necessary for the active task.\nIf prior compress-tool results are present, always compress and summarize them minimally only as part of a broader compression pass. Do not invoke the compress tool solely to re-compress an earlier compression result.\nMessages marked as \\`<dcp-message-id>BLOCKED</dcp-message-id>\\` cannot be compressed.\n\nRules:\n\n- Pick each \\`messageId\\` directly from injected IDs visible in context.\n- Only use raw message IDs of the form \\`mNNNNN\\`.\n- Ignore XML attributes such as \\`priority\\` when copying the ID; use only the inner \\`mNNNNN\\` value.\n- Do not invent IDs. Use only IDs that are present in context.\n\nBATCHING\nSelect MANY messages in a single tool call when they are safe to compress.\nEach entry should summarize exactly one message, and the tool can receive as many entries as needed in one batch.\n\nGENERAL CLEANUP\nUse the topic \"general cleanup\" for broad cleanup passes.\nDuring general cleanup, compress all medium and high-priority messages that are not relevant to the active task.\nOptimize for reducing context footprint, not for grouping messages by topic.\nDo not compress away still-active instructions, unresolved questions, or constraints that are likely to matter soon.\nPrioritize the earliest messages in the context as they will be the least relevant to the active task.\nGeneral cleanup should be done periodically between other normal compression tool passes, not as the primary form of compression.\n`\n","export const CONTEXT_LIMIT_NUDGE = `\n<system-reminder>\n⚠️ CRITICAL: Context limit reached. You MUST use the \\`compress\\` tool NOW.\n\nIf mid-atomic-operation, finish that step first, then compress immediately.\n\nHOW TO CALL COMPRESS:\n{\n \"topic\": \"Short Label\",\n \"content\": [\n {\n \"startId\": \"<ID from early in this conversation>\",\n \"endId\": \"<ID from later in this conversation>\",\n \"summary\": \"Complete technical summary of everything in the range\"\n }\n ]\n}\n\n⚠️ ID RULES — MOST COMMON CAUSE OF ERRORS:\n- ONLY use IDs you can see in <dcp-message-id> tags in the messages ABOVE.\n- Do NOT copy IDs from this example. Do NOT invent IDs.\n- Do NOT use IDs from compressed block summaries — they are stale.\n- startId must appear BEFORE endId in the conversation.\n\nSUMMARY RULES:\n- Capture ALL essential details: file paths, decisions, constraints, key findings.\n- Preserve user intent exactly. Direct-quote short user messages.\n- Prefer one large range over multiple small ones.\n- Compress OLDER resolved history first. Keep recent active work.\n</system-reminder>\n`\n","export const TURN_NUDGE = `\n<system-reminder>\nContext is getting full. Compress closed/older conversation ranges now.\n\n{\n \"topic\": \"Short Label\",\n \"content\": [{ \"startId\": \"<visible message ID>\", \"endId\": \"<visible message ID>\", \"summary\": \"...\" }]\n}\n\n⚠️ ONLY use IDs from <dcp-message-id> tags visible above. Do NOT invent or copy example IDs.\n</system-reminder>\n`\n","export const ITERATION_NUDGE = `\n<system-reminder>\nYou've been iterating for a while. If any earlier work is closed and unlikely to be referenced, compress it now.\n\n{\n \"topic\": \"Short Label\",\n \"content\": [{ \"startId\": \"<visible message ID>\", \"endId\": \"<visible message ID>\", \"summary\": \"...\" }]\n}\n\n⚠️ ONLY use IDs from <dcp-message-id> tags visible above. Do NOT invent or copy example IDs.\n</system-reminder>\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `<dcp-system-reminder>\nManual mode is enabled. Do NOT use compress unless the user has explicitly triggered it through a manual marker.\n\nOnly use the compress tool after seeing \\`<compress triggered manually>\\` in the current user instruction context.\n\nIssue exactly ONE compress tool per manual trigger. Do NOT launch multiple compress tools in parallel. Each trigger grants a single compression; after it completes, wait for the next trigger.\n\nAfter completing a manually triggered context-management action, STOP IMMEDIATELY. Do NOT continue with any task execution. End your response right after the tool use completes and wait for the next user input.\n</dcp-system-reminder>\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `<dcp-system-reminder>\nYou are operating in a subagent environment.\n\nThe initial subagent instruction is imperative and must be followed exactly.\nIt is the only user message intentionally not assigned a message ID, and therefore is not eligible for compression.\nAll subsequent messages in the session will have IDs.\n</dcp-system-reminder>\n`\n\nexport function buildProtectedToolsExtension(protectedTools: string[]): string {\n if (protectedTools.length === 0) {\n return \"\"\n }\n\n const toolList = protectedTools.map((t) => `\\`${t}\\``).join(\", \")\n return `<dcp-system-reminder>\nThe following tools are environment-managed: ${toolList}.\nTheir outputs are automatically preserved during compression.\nDo not include their content in compress tool summaries — the environment retains it independently.\n</dcp-system-reminder>`\n}\n","import { 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\n// [FIX Bug 28] Regex to strip stale mNNNN refs from compressed summaries\nconst DCP_MESSAGE_REF_TAG_REGEX = /<dcp-message-id>m\\d+<\\/dcp-message-id>/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\n\nconst generateStableId = (prefix: string, seed: string): string => {\n const hash = createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, SUMMARY_ID_HASH_LENGTH)\n return `${prefix}_${hash}`\n}\n\nexport const createSyntheticUserMessage = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n): WithParts => {\n const userInfo = baseMessage.info as UserMessage\n const now = Date.now()\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const messageId = generateStableId(\"msg_dcp_summary\", deterministicSeed)\n const partId = generateStableId(\"prt_dcp_summary\", deterministicSeed)\n\n return {\n info: {\n id: messageId,\n sessionID: userInfo.sessionID,\n role: \"user\" as const,\n agent: userInfo.agent,\n model: userInfo.model,\n time: { created: now },\n },\n parts: [\n {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: messageId,\n type: \"text\" as const,\n text: content,\n },\n ],\n }\n}\n\nexport const createSyntheticTextPart = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n) => {\n const userInfo = baseMessage.info as UserMessage\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const partId = generateStableId(\"prt_dcp_text\", deterministicSeed)\n\n return {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: userInfo.id,\n type: \"text\" as const,\n text: content,\n }\n}\n\ntype MessagePart = WithParts[\"parts\"][number]\ntype ToolPart = Extract<MessagePart, { type: \"tool\" }>\ntype TextPart = Extract<MessagePart, { type: \"text\" }>\n\nexport const appendToLastTextPart = (message: WithParts, injection: string): boolean => {\n const textPart = findLastTextPart(message)\n if (!textPart) {\n return false\n }\n\n return appendToTextPart(textPart, injection)\n}\n\nconst findLastTextPart = (message: WithParts): TextPart | null => {\n for (let i = message.parts.length - 1; i >= 0; i--) {\n const part = message.parts[i]\n if (part.type === \"text\") {\n return part\n }\n }\n\n return null\n}\n\nexport const appendToTextPart = (part: TextPart, injection: string): boolean => {\n if (typeof part.text !== \"string\") {\n return false\n }\n\n const normalizedInjection = injection.replace(/^\\n+/, \"\")\n if (!normalizedInjection.trim()) {\n return false\n }\n if (part.text.includes(normalizedInjection)) {\n return true\n }\n\n const baseText = part.text.replace(/\\n*$/, \"\")\n part.text = baseText.length > 0 ? `${baseText}\\n\\n${normalizedInjection}` : normalizedInjection\n return true\n}\n\nexport const appendToAllToolParts = (message: WithParts, tag: string): boolean => {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"tool\") {\n injected = appendToToolPart(part, tag) || injected\n }\n }\n return injected\n}\n\nexport const appendToToolPart = (part: ToolPart, tag: string): boolean => {\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n return false\n }\n if (part.state.output.includes(tag)) {\n return true\n }\n\n part.state.output = `${part.state.output}${tag}`\n return true\n}\n\nexport const hasContent = (message: WithParts): boolean => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0) ||\n (part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"),\n )\n}\n\nexport function buildToolIdList(state: SessionState, messages: WithParts[]): string[] {\n const toolIds: string[] = []\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n state.toolIdList = toolIds\n return toolIds\n}\n\nexport const replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\n// [FIX Bug 28] Strip stale mNNNN refs from compressed summaries before injection\nexport const stripStaleMessageRefs = (text: string): string => {\n return text.replace(DCP_MESSAGE_REF_TAG_REGEX, \"\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n return text.replace(DCP_PAIRED_TAG_REGEX, \"\").replace(DCP_UNPAIRED_TAG_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, stripStaleMessageRefs } 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 // [FIX Bug 28] Strip stale mNNNN refs before injection\n const _cleaned = stripStaleMessageRefs(rawSummaryContent)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(_cleaned)\n : _cleaned\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 // [FIX Bug 1] no preceding user message — build fallback base so summary is always injected\n const anchorInfo = msg.info as any\n const fallbackBase: WithParts = {\n info: {\n id: anchorInfo.id || msgId,\n sessionID: anchorInfo.sessionID || \"\",\n role: \"user\" as const,\n agent: anchorInfo.agent || \"code\",\n model:\n anchorInfo.model || {\n providerID: \"\",\n modelID: \"\",\n variant: undefined,\n },\n time: { created: anchorInfo.time?.created || Date.now() },\n },\n parts: [],\n }\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(_cleaned)\n : _cleaned\n const summarySeed = `${summary.blockId}:${summary.anchorMessageId}`\n result.push(\n createSyntheticUserMessage(fallbackBase, summaryContent, summarySeed),\n )\n\n logger.info(\"Injected compress summary (fallback, no preceding user message)\", {\n anchorMessageId: msgId,\n summaryLength: summaryContent.length,\n })\n }\n }\n }\n\n // Skip messages that are in the prune list\n const pruneEntry = state.prune.messages.byMessageId.get(msgId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n continue\n }\n\n // Normal message, include it\n result.push(msg)\n }\n\n // Replace messages array contents\n messages.length = 0\n messages.push(...result)\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\n\nfunction sortBlocksByCreation(\n a: { createdAt: number; blockId: number },\n b: { createdAt: number; blockId: number },\n): number {\n const createdAtDiff = a.createdAt - b.createdAt\n if (createdAtDiff !== 0) {\n return createdAtDiff\n }\n return a.blockId - b.blockId\n}\n\nexport const syncCompressionBlocks = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n): void => {\n const messagesState = state.prune.messages\n if (!messagesState?.blocksById?.size) {\n return\n }\n\n const messageIds = new Set(messages.map((msg) => msg.info.id))\n const previousActiveBlockIds = new Set<number>(\n Array.from(messagesState.blocksById.values())\n .filter((block) => block.active)\n .map((block) => block.blockId),\n )\n\n messagesState.activeBlockIds.clear()\n messagesState.activeByAnchorMessageId.clear()\n\n const now = Date.now()\n const missingOriginBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n // [PATCH Bug 3] Removed compressMessageId presence check.\n // Blocks should remain active even if the compress tool call message was\n // removed by opencode's internal compaction. The block's existence IS proof\n // that compression happened.\n for (const block of orderedBlocks) {\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 // Only deactivate if anchor message is completely gone from both current messages AND DCP tracked messages\n if (\n typeof block.anchorMessageId === \"string\" &&\n block.anchorMessageId.length > 0 &&\n !messageIds.has(block.anchorMessageId)\n ) {\n // If anchor exists in DCP's byMessageId (persisted), keep block active\n if (!messagesState.byMessageId.has(block.anchorMessageId)) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n continue\n }\n }\n\n for (const consumedBlockId of block.consumedBlockIds) {\n if (!messagesState.activeBlockIds.has(consumedBlockId)) {\n continue\n }\n\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (consumedBlock) {\n consumedBlock.active = false\n consumedBlock.deactivatedAt = now\n consumedBlock.deactivatedByBlockId = block.blockId\n\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlock.blockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n }\n\n block.active = true\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n messagesState.activeBlockIds.add(block.blockId)\n if (messageIds.has(block.anchorMessageId)) {\n messagesState.activeByAnchorMessageId.set(block.anchorMessageId, block.blockId)\n }\n }\n\n for (const entry of messagesState.byMessageId.values()) {\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [...new Set(entry.allBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n : []\n\n entry.allBlockIds = allBlockIds\n entry.activeBlockIds = allBlockIds.filter((id) => messagesState.activeBlockIds.has(id))\n }\n\n const nextActiveBlockIds = messagesState.activeBlockIds\n let deactivatedCount = 0\n let reactivatedCount = 0\n\n for (const blockId of previousActiveBlockIds) {\n if (!nextActiveBlockIds.has(blockId)) {\n deactivatedCount++\n }\n }\n for (const blockId of nextActiveBlockIds) {\n if (!previousActiveBlockIds.has(blockId)) {\n reactivatedCount++\n }\n }\n\n if (missingOriginBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingOriginCount: missingOriginBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type 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 { SessionState, CompressionBlock } from \"../../state\"\nimport type { GCConfig } from \"../../config\"\n\nexport interface BlockGuidanceContext {\n currentTokens?: number\n modelContextLimit?: number\n}\n\nexport function buildCompressedBlockGuidance(\n state: SessionState,\n gcConfig?: GCConfig,\n context?: BlockGuidanceContext,\n): string {\n const activeBlockIds = Array.from(state.prune.messages.activeBlockIds)\n .filter((id) => Number.isInteger(id) && id > 0)\n .sort((a, b) => a - b)\n\n const refs = activeBlockIds.map((id) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"none\"\n\n const lines = [\n \"Compressed block context:\",\n `- Active compressed blocks: ${blockCount} (${blockList})`,\n \"- If your selected compression range includes any listed block, include each required placeholder exactly once in the summary using `(bN)`.\",\n ]\n\n // [FIX Bug 35] Only show aging warnings when context usage is above 50%.\n // Showing warnings at low usage causes unnecessary compress operations that\n // waste tokens and attention — the model preemptively re-summarizes blocks\n // that aren't actually at risk of GC truncation.\n const usageRatio =\n context?.currentTokens && context?.modelContextLimit\n ? context.currentTokens / context.modelContextLimit\n : 0\n\n if (gcConfig && usageRatio > 0.5) {\n const promotionThreshold = gcConfig.promotionThreshold\n const agingBlocks: string[] = []\n\n for (const blockId of activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block) continue\n\n const survived = block.survivedCount ?? 0\n const gen = block.generation ?? \"young\"\n const sizeK = (block.summary.length / 1000).toFixed(1)\n const preview = block.summary.slice(0, 120).replace(/\\n/g, \" \")\n\n if (gen === \"old\" || survived >= promotionThreshold - 2) {\n agingBlocks.push(\n ` b${blockId}: age=${survived}/${promotionThreshold}, gen=${gen}, size=${sizeK}K chars — ${preview}...`,\n )\n }\n }\n\n if (agingBlocks.length > 0) {\n lines.push(\"\")\n lines.push(\"⚠️ Block aging warning — these blocks may be truncated by GC soon:\")\n lines.push(...agingBlocks)\n lines.push(\n \"To preserve important content: use the compress tool to re-summarize these blocks into new concise ones. Unhandled blocks will be auto-truncated.\",\n )\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nexport function renderMessagePriorityGuidance(priorityLabel: string, refs: string[]): string {\n const refList = refs.length > 0 ? refs.join(\", \") : \"none\"\n\n return [\n \"Message priority context:\",\n \"- Higher-priority older messages consume more context and should be compressed right away if it is safe to do so.\",\n `- ${priorityLabel}-priority message IDs before this point: ${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 = \"</dcp-system-reminder>\"\n const closeTagIndex = nudgeText.lastIndexOf(closeTag)\n\n if (closeTagIndex === -1) {\n return nudgeText\n }\n\n const beforeClose = nudgeText.slice(0, closeTagIndex).trimEnd()\n const afterClose = nudgeText.slice(closeTagIndex)\n return `${beforeClose}\\n\\n${guidance}\\n${afterClose}`\n}\n","import type { 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 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\ninterface ModelLimit {\n context: number\n input?: number\n output?: number\n}\n\nexport function computeInputBudget(limit: ModelLimit): number | undefined {\n if (!limit.context) {\n return undefined\n }\n\n return limit.input ?? Math.max(0, limit.context - (limit.output ?? 0))\n}\n\nexport function getNudgeFrequency(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.nudgeFrequency || 1))\n}\n\nexport function getIterationNudgeThreshold(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.iterationNudgeThreshold || 1))\n}\n\nexport function findLastNonIgnoredMessage(messages: WithParts[]): LastNonIgnoredMessage | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n return { message, index: i }\n }\n\n return null\n}\n\nexport function countMessagesAfterIndex(messages: WithParts[], index: number): number {\n let count = 0\n\n for (let i = index + 1; i < messages.length; i++) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n count++\n }\n\n return count\n}\n\nexport function getModelInfo(messages: WithParts[]): LastUserModelContext {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return {\n providerId: undefined,\n modelId: undefined,\n }\n }\n\n const userInfo = lastUserMessage.info as UserMessage\n return {\n providerId: userInfo.model.providerID,\n modelId: userInfo.model.modelID,\n }\n}\n\nfunction resolveContextTokenLimit(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n threshold: \"max\" | \"min\",\n): number | undefined {\n const parseLimitValue = (limit: number | `${number}%` | undefined): number | undefined => {\n if (limit === undefined) {\n return undefined\n }\n\n if (typeof limit === \"number\") {\n return limit\n }\n\n if (!limit.endsWith(\"%\") || state.modelContextLimit === undefined) {\n return undefined\n }\n\n const parsedPercent = parseFloat(limit.slice(0, -1))\n if (isNaN(parsedPercent)) {\n return undefined\n }\n\n const roundedPercent = Math.round(parsedPercent)\n const clampedPercent = Math.max(0, Math.min(100, roundedPercent))\n return Math.round((clampedPercent / 100) * state.modelContextLimit)\n }\n\n const modelLimits =\n threshold === \"max\" ? config.compress.modelMaxLimits : config.compress.modelMinLimits\n if (modelLimits && providerId !== undefined && modelId !== undefined) {\n const providerModelId = `${providerId}/${modelId}`\n const modelLimit = modelLimits[providerModelId]\n if (modelLimit !== undefined) {\n return parseLimitValue(modelLimit)\n }\n }\n\n const globalLimit =\n threshold === \"max\" ? config.compress.maxContextLimit : config.compress.minContextLimit\n return parseLimitValue(globalLimit)\n}\n\nexport function isContextOverLimits(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n messages: WithParts[],\n) {\n const summaryTokenExtension = config.compress.summaryBuffer\n ? getActiveSummaryTokenUsage(state)\n : 0\n const resolvedMaxContextLimit = resolveContextTokenLimit(\n config,\n state,\n providerId,\n modelId,\n \"max\",\n )\n const maxContextLimit =\n resolvedMaxContextLimit === undefined\n ? undefined\n : resolvedMaxContextLimit + summaryTokenExtension\n const minContextLimit = resolveContextTokenLimit(config, state, providerId, modelId, \"min\")\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n let overMaxLimit = maxContextLimit === undefined ? false : currentTokens > maxContextLimit\n const overMinLimit = minContextLimit === undefined ? false : currentTokens >= minContextLimit\n\n // [FIX Bug 20] Suppress overMax while cacheRead hasn't updated after compress\n if (overMaxLimit) {\n const recentCompressCount = 3\n const recentMessages = messages.slice(-recentCompressCount)\n for (const msg of recentMessages) {\n if (msg.info.role === \"assistant\" && msg.parts) {\n for (const part of msg.parts) {\n if ((part as any).type === \"tool-invocation\" && (part as any).toolInvocation?.toolName === \"compress\") {\n overMaxLimit = false\n break\n }\n }\n }\n if (!overMaxLimit) break\n }\n }\n\n return {\n overMaxLimit,\n overMinLimit,\n currentTokens,\n modelContextLimit: state.modelContextLimit,\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): void {\n const nudgeText = appendGuidanceToDcpTag(baseNudgeText, compressedBlockGuidance)\n if (!nudgeText.trim()) {\n return\n }\n\n for (const { message } of collectAnchoredMessages(anchorMessageIds, messages)) {\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nfunction applyMessageModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: 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 nudgeText = appendGuidanceToDcpTag(baseNudgeText, priorityGuidance)\n injectAnchoredNudge(message, nudgeText)\n }\n}\n\nfunction buildContextUsageInfo(currentTokens?: number, modelContextLimit?: number): string {\n if (currentTokens === undefined || modelContextLimit === undefined || modelContextLimit === 0) {\n return \"\"\n }\n const percentage = ((currentTokens / modelContextLimit) * 100).toFixed(1)\n const formatK = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n))\n return `\\n\\nContext usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent — use the compress tool proactively to manage context quality.`\n}\n\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n currentTokens?: number,\n modelContextLimit?: number,\n): void {\n const contextUsageInfo = buildContextUsageInfo(currentTokens, modelContextLimit)\n const contextLimitNudgeWithUsage = prompts.contextLimitNudge + contextUsageInfo\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n contextLimitNudgeWithUsage,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressionPriorities,\n )\n applyMessageModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressionPriorities,\n )\n return\n }\n\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n contextLimitNudgeWithUsage,\n \"\",\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n \"\",\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n \"\",\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\"\nimport { buildCompressedBlockGuidance } from \"../../prompts/extensions/nudge\"\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 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, currentTokens, modelContextLimit } = 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, currentTokens, modelContextLimit)\n\n injectContextUsage(messages, currentTokens, modelContextLimit)\n\n if (config.compress.mode !== \"message\") {\n const blockGuidance = buildCompressedBlockGuidance(state, config.gc, { currentTokens, modelContextLimit })\n if (blockGuidance.trim()) {\n const lastUser = getLastUserMessage(messages)\n if (lastUser) appendToLastTextPart(lastUser, \"\\n\\n\" + blockGuidance)\n }\n }\n\n injectVisibleIdRange(state, messages)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger)\n }\n}\n\nfunction injectContextUsage(\n messages: WithParts[],\n currentTokens?: number,\n modelContextLimit?: number,\n): void {\n if (currentTokens === undefined || modelContextLimit === undefined || modelContextLimit === 0) {\n return\n }\n const lastUser = getLastUserMessage(messages)\n if (!lastUser) return\n\n const percentage = ((currentTokens / modelContextLimit) * 100).toFixed(1)\n const formatK = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(1)}K` : String(n))\n const usageTag = `\\n\\nContext usage: ${formatK(currentTokens)} / ${formatK(modelContextLimit)} tokens (${percentage}%). ACP (Active Context Pruning) threshold: 55%. You ARE the ACP agent — use the compress tool proactively to manage context quality.`\n\n for (const part of lastUser.parts) {\n if (part.type === \"text\") {\n appendToTextPart(part, usageTag)\n return\n }\n }\n lastUser.parts.push(createSyntheticTextPart(lastUser, usageTag))\n}\n\nfunction injectVisibleIdRange(state: SessionState, messages: WithParts[]): void {\n const visibleRefs: string[] = []\n for (const message of messages) {\n const ref = state.messageIds.byRawId.get(message.info.id)\n if (ref) {\n visibleRefs.push(ref)\n }\n }\n\n if (visibleRefs.length === 0) return\n\n visibleRefs.sort()\n const first = visibleRefs[0]\n const last = visibleRefs[visibleRefs.length - 1]\n const rangeTag = `\\n\\n[Visible message IDs: ${first} to ${last} (${visibleRefs.length} messages). Only use IDs in this range for compress.]`\n\n const lastUser = getLastUserMessage(messages)\n if (!lastUser) return\n\n for (const part of lastUser.parts) {\n if (part.type === \"text\") {\n appendToTextPart(part, rangeTag)\n return\n }\n }\n lastUser.parts.push(createSyntheticTextPart(lastUser, rangeTag))\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 // [FIX Bug 8] Guard against undefined modelID/providerID\n const msgModelID = (message.info as any).modelID\n const msgProviderID = (message.info as any).providerID\n if (msgModelID === modelID && msgProviderID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\" && part.type !== \"reasoning\") {\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(\"│ ACP 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 ACP: ~${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.compressMessageId)\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: /acp 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: /acp 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: /acp 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 // [FIX Bug 10] Mark consumed inner blocks so syncCompressionBlocks won't re-activate them\n for (const consumedId of block.consumedBlockIds) {\n const consumedBlock = messagesState.blocksById.get(consumedId)\n if (consumedBlock) {\n consumedBlock.deactivatedByUser = true\n }\n }\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 * ACP Help command handler.\n * Shows available ACP 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 [\"/acp context\", \"Show token usage breakdown for current session\"],\n [\"/acp stats\", \"Show ACP pruning statistics\"],\n [\"/acp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/acp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\n]\n\nconst TOOL_COMMANDS: Record<string, [string, string]> = {\n compress: [\"/acp compress [focus]\", \"Trigger manual compress tool execution\"],\n decompress: [\"/acp decompress <n>\", \"Restore selected compression\"],\n recompress: [\"/acp 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(\"│ ACP 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 * /acp manual [on|off] - Toggle manual mode or set explicit state\n * /acp 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 { getCurrentParams } from \"../token-utils\"\nimport { buildCompressedBlockGuidance } from \"../prompts/extensions/nudge\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nconst MANUAL_MODE_ON = \"Manual mode is now ON. Use /acp compress to trigger context tools manually.\"\n\nconst MANUAL_MODE_OFF = \"Manual mode is now OFF.\"\n\nconst COMPRESS_TRIGGER_PROMPT = [\n \"<compress triggered manually>\",\n \"Manual mode trigger received. You must now use the compress tool.\",\n \"Find the most significant completed conversation content that can be compressed into a high-fidelity technical summary.\",\n \"Follow the active compress mode, preserve all critical implementation details, and choose safe targets.\",\n \"Return after compress with a brief explanation of what content was compressed.\",\n].join(\"\\n\\n\")\n\nfunction getTriggerPrompt(\n tool: \"compress\",\n state: SessionState,\n config: PluginConfig,\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state, config.gc)\n\n const sections = [base, compressedBlockGuidance]\n if (userFocus && userFocus.trim().length > 0) {\n sections.push(`Additional user focus:\\n${userFocus.trim()}`)\n }\n\n return sections.join(\"\\n\\n\")\n}\n\nexport interface ManualCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport async function handleManualToggleCommand(\n ctx: ManualCommandContext,\n modeArg?: string,\n): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n if (modeArg === \"on\") {\n state.manualMode = \"active\"\n } else if (modeArg === \"off\") {\n state.manualMode = false\n } else {\n state.manualMode = state.manualMode ? false : \"active\"\n }\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(\n client,\n sessionId,\n state.manualMode ? MANUAL_MODE_ON : MANUAL_MODE_OFF,\n params,\n logger,\n )\n\n logger.info(\"Manual mode toggled\", { manualMode: state.manualMode })\n}\n\nexport async function handleManualTriggerCommand(\n ctx: ManualCommandContext,\n tool: \"compress\",\n userFocus?: string,\n): Promise<string | null> {\n return getTriggerPrompt(tool, ctx.state, ctx.config, userFocus)\n}\n\nexport function applyPendingManualTrigger(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): void {\n const pending = state.pendingManualTrigger\n if (!pending) {\n return\n }\n\n if (!state.sessionId || pending.sessionId !== state.sessionId) {\n state.pendingManualTrigger = null\n return\n }\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n\n for (const part of msg.parts) {\n if (part.type !== \"text\" || part.ignored || part.synthetic) {\n continue\n }\n\n part.text = pending.prompt\n state.pendingManualTrigger = null\n logger.debug(\"Applied manual prompt\", { sessionId: pending.sessionId })\n return\n }\n }\n\n state.pendingManualTrigger = null\n}\n","import type { Logger } from \"../logger\"\nimport type { PruneMessagesState, SessionState, WithParts } from \"../state\"\nimport { syncCompressionBlocks } from \"../messages\"\nimport { parseBlockRef } from \"../message-ids\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport {\n getRecompressibleCompressionTargets,\n resolveCompressionTarget,\n type CompressionTarget,\n} from \"./compression-targets\"\n\nexport interface RecompressCommandContext {\n client: any\n state: SessionState\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n}\n\nfunction parseBlockIdArg(arg: string): number | null {\n const normalized = arg.trim().toLowerCase()\n const blockRef = parseBlockRef(normalized)\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: /acp 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: /acp 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: /acp recompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n if (target.blocks.some((block) => !availableMessageIds.has(block.compressMessageId))) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} can no longer be re-applied because its origin message is no longer in this session.`,\n params,\n logger,\n )\n return\n }\n\n if (!target.blocks.some((block) => block.deactivatedByUser)) {\n const message = target.blocks.some((block) => block.active)\n ? `Compression ${target.displayId} is already active.`\n : `Compression ${target.displayId} is not user-decompressed.`\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n\n for (const block of target.blocks) {\n block.deactivatedByUser = false\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let recompressedMessageCount = 0\n let recompressedTokens = 0\n for (const [messageId, entry] of messagesState.byMessageId) {\n const isActiveNow = entry.activeBlockIds.length > 0\n if (isActiveNow && !activeMessagesBefore.has(messageId)) {\n recompressedMessageCount++\n recompressedTokens += entry.tokenCount\n }\n }\n\n state.stats.totalPruneTokens += recompressedTokens\n\n const deactivatedBlockIds = Array.from(activeBlockIdsBefore)\n .filter((blockId) => !messagesState.activeBlockIds.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatRecompressMessage(\n target,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Recompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n recompressedMessageCount,\n recompressedTokens,\n deactivatedBlockIds,\n })\n}\n","/**\n * DCP Stats command handler.\n * Shows pruning statistics for the current session and all-time totals.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatTokenCount } from \"../ui/utils\"\nimport { loadAllSessionStats, type AggregatedStats } from \"../state/persistence\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { 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(\"│ ACP 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 * /acp sweep - Prune all tools since the previous user message\n * /acp 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(\"│ ACP 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(\"│ ACP 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 { CompressionBlock } from \"../state\"\nimport type { GCConfig } from \"../config\"\n\nexport interface CompactionResult {\n compactedBlocks: number\n savedTokens: number\n}\n\nexport interface GCParams {\n maxOldGenSummaryLength: number\n modelContextLimit: number\n currentTokens: number\n}\n\nexport function runTruncateGC(\n blocks: CompressionBlock[],\n params: GCParams,\n): CompactionResult {\n let compactedBlocks = 0\n let savedTokens = 0\n\n for (const block of blocks) {\n if (!block.active) continue\n if (block.summary.length <= params.maxOldGenSummaryLength) continue\n\n const originalLength = block.summary.length\n const truncated = truncateSummary(block.summary, params.maxOldGenSummaryLength, block.blockId)\n const savedChars = originalLength - truncated.length\n if (savedChars > 0) {\n block.summary = truncated\n block.summaryTokens = Math.round(truncated.length / 4)\n compactedBlocks++\n savedTokens += Math.round(savedChars / 4)\n }\n }\n\n return { compactedBlocks, savedTokens }\n}\n\nfunction truncateSummary(summary: string, maxLength: number, _blockId: number): string {\n if (summary.length <= maxLength) return summary\n\n const headerEnd = summary.indexOf(\"\\n\")\n if (headerEnd === -1) return summary.slice(0, maxLength) + \"\\n...\\n[GC truncated]\"\n\n const header = summary.slice(0, headerEnd + 1)\n const footerStart = summary.lastIndexOf(\"\\n\\n\")\n const footer = footerStart > headerEnd ? summary.slice(footerStart) : \"\"\n\n const availableForContent = maxLength - header.length - footer.length - 20\n if (availableForContent < 100) {\n return header + \"...\\n[GC truncated]\" + footer\n }\n\n const content = summary.slice(headerEnd + 1, headerEnd + 1 + availableForContent)\n return header + content + \"\\n...\\n[GC truncated]\" + footer\n}\n\nexport function shouldRunMajorGC(\n currentTokens: number,\n modelContextLimit: number | undefined,\n gcConfig: GCConfig,\n): boolean {\n if (!modelContextLimit || modelContextLimit === 0) return false\n\n const threshold = parseGcThreshold(gcConfig.majorGcThresholdPercent, modelContextLimit)\n return currentTokens >= threshold\n}\n\nexport function getGCParams(gcConfig: GCConfig, modelContextLimit: number, currentTokens: number): GCParams {\n return {\n maxOldGenSummaryLength: gcConfig.maxOldGenSummaryLength,\n modelContextLimit,\n currentTokens,\n }\n}\n\nfunction parseGcThreshold(limit: number | `${number}%`, modelContextLimit: number): number {\n if (typeof limit === \"number\") return limit\n const percent = parseFloat(limit.slice(0, -1))\n if (isNaN(percent)) return modelContextLimit\n return Math.round((Math.max(0, Math.min(100, Math.round(percent))) / 100) * modelContextLimit)\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 computeInputBudget,\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\"\nimport { runTruncateGC, shouldRunMajorGC, getGCParams } from \"./gc/truncate\"\nimport { getCurrentTokenUsage } from \"./token-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: {\n sessionID?: string\n model: { limit: { context: number; input?: number; output?: number } }\n },\n output: { system: string[] },\n ) => {\n if (input.model?.limit?.context) {\n state.modelContextLimit = input.model.limit.context\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\nfunction runMajorGC(\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n): void {\n // [FIX Bug 32] Age-based deactivation does NOT depend on modelContextLimit.\n // modelContextLimit is set in the system prompt hook, which runs AFTER the\n // messages transform hook. If we guard this with modelContextLimit, age-based\n // deactivation never runs after restart (modelContextLimit starts as undefined).\n const maxBlockAge = config.gc.maxBlockAge ?? 15\n let agedOutCount = 0\n let agedOutTokens = 0\n const now = Date.now()\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (!block.active) continue\n const age = block.survivedCount ?? 0\n if (age > maxBlockAge) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n state.prune.messages.activeBlockIds.delete(Number(blockId))\n const anchorMapped = state.prune.messages.activeByAnchorMessageId.get(block.anchorMessageId)\n if (anchorMapped === Number(blockId)) {\n state.prune.messages.activeByAnchorMessageId.delete(block.anchorMessageId)\n }\n agedOutCount++\n agedOutTokens += block.summaryTokens ?? Math.round(block.summary.length / 4)\n }\n }\n\n if (agedOutCount > 0) {\n logger.info(\"Major GC: deactivated aged-out blocks\", {\n agedOutCount,\n agedOutTokens,\n maxBlockAge,\n })\n void saveSessionState(state, logger)\n }\n\n if (!state.modelContextLimit) return\n\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n // Check if any active block is oversized (summary > 2x maxOldGenSummaryLength)\n // These should always be truncated regardless of token threshold\n const oversizedThreshold = config.gc.maxOldGenSummaryLength * 2\n let hasOversizedBlocks = false\n for (const [, block] of state.prune.messages.blocksById) {\n if (block.active && block.summary.length > oversizedThreshold) {\n hasOversizedBlocks = true\n break\n }\n }\n\n if (!shouldRunMajorGC(currentTokens, state.modelContextLimit, config.gc) && !hasOversizedBlocks) return\n\n const oldBlocks: import(\"./state\").CompressionBlock[] = []\n for (const [blockId, block] of state.prune.messages.blocksById) {\n if (!block.active) continue\n if (\n block.generation === \"old\" ||\n block.generation === undefined ||\n block.summary.length > config.gc.maxOldGenSummaryLength\n ) {\n oldBlocks.push(block)\n }\n }\n\n if (oldBlocks.length === 0) return\n\n const params = getGCParams(config.gc, state.modelContextLimit, currentTokens)\n const result = runTruncateGC(oldBlocks, params)\n\n if (result.compactedBlocks > 0) {\n logger.info(\"Major GC: truncated old-gen blocks\", {\n compactedBlocks: result.compactedBlocks,\n savedTokens: result.savedTokens,\n currentTokens,\n threshold: config.gc.majorGcThresholdPercent,\n })\n void saveSessionState(state, logger)\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 stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n const activeBlockCountBefore = state.prune.messages.activeBlockIds.size // [FIX Bug 4]\n syncCompressionBlocks(state, logger, output.messages)\n if (state.prune.messages.activeBlockIds.size !== activeBlockCountBefore) { // [FIX Bug 4]\n void saveSessionState(state, logger) // [FIX Bug 4] persist deactivations\n }\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n runMajorGC(state, config, logger, output.messages)\n prune(state, logger, config, output.messages)\n // [FIX Bug 2] assign refs to newly created synthetic messages from prune/filterCompressedRanges\n assignMessageRefs(state, 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 }\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 === \"acp\" || 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 = \"@tarquinen/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: \"ACP 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[\"acp\"] = {\n template: \"\",\n description: \"Show available ACP 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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AAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAA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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","cpSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","cpSync","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","countTokens","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","message","readFile","dirname","join","prefix","base"]}