@tarquinen/opencode-dcp 3.1.10 → 3.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.js +77 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/compress/message.d.ts.map +1 -1
- package/dist/lib/compress/protected-content.d.ts +2 -0
- package/dist/lib/compress/protected-content.d.ts.map +1 -1
- package/dist/lib/compress/range.d.ts.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts +0 -2
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/messages/index.d.ts +0 -1
- package/dist/lib/messages/index.d.ts.map +1 -1
- package/dist/lib/messages/inject/utils.d.ts +0 -7
- package/dist/lib/messages/inject/utils.d.ts.map +1 -1
- package/dist/lib/update.d.ts.map +1 -1
- package/package.json +2 -3
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/hooks.ts","../lib/auth.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport { parse } from \"jsonc-parser/lib/esm/main.js\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\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 protectUserMessages: boolean\n}\n\nexport interface Commands {\n enabled: boolean\n protectedTools: string[]\n}\n\nexport interface ManualModeConfig {\n enabled: boolean\n automaticStrategies: boolean\n}\n\nexport interface PurgeErrors {\n enabled: boolean\n turns: number\n protectedTools: string[]\n}\n\nexport interface TurnProtection {\n enabled: boolean\n turns: number\n}\n\nexport interface ExperimentalConfig {\n allowSubAgents: boolean\n customPrompts: boolean\n}\n\nexport interface PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n pruneNotification: \"off\" | \"minimal\" | \"detailed\"\n pruneNotificationType: \"chat\" | \"toast\"\n commands: Commands\n manualMode: ManualModeConfig\n turnProtection: TurnProtection\n experimental: ExperimentalConfig\n protectedFilePatterns: string[]\n compress: CompressConfig\n strategies: {\n deduplication: Deduplication\n purgeErrors: PurgeErrors\n }\n}\n\ntype CompressOverride = Partial<CompressConfig>\n\nconst DEFAULT_PROTECTED_TOOLS = [\n \"task\",\n \"skill\",\n \"todowrite\",\n \"todoread\",\n \"compress\",\n \"batch\",\n \"plan_enter\",\n \"plan_exit\",\n \"write\",\n \"edit\",\n]\n\nconst COMPRESS_DEFAULT_PROTECTED_TOOLS = [\"task\", \"skill\", \"todowrite\", \"todoread\"]\n\nexport const VALID_CONFIG_KEYS = new Set([\n \"$schema\",\n \"enabled\",\n \"autoUpdate\",\n \"debug\",\n \"showUpdateToasts\",\n \"pruneNotification\",\n \"pruneNotificationType\",\n \"turnProtection\",\n \"turnProtection.enabled\",\n \"turnProtection.turns\",\n \"experimental\",\n \"experimental.allowSubAgents\",\n \"experimental.customPrompts\",\n \"protectedFilePatterns\",\n \"commands\",\n \"commands.enabled\",\n \"commands.protectedTools\",\n \"manualMode\",\n \"manualMode.enabled\",\n \"manualMode.automaticStrategies\",\n \"compress\",\n \"compress.mode\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.modelMaxLimits\",\n \"compress.modelMinLimits\",\n \"compress.nudgeFrequency\",\n \"compress.iterationNudgeThreshold\",\n \"compress.nudgeForce\",\n \"compress.protectedTools\",\n \"compress.protectUserMessages\",\n \"strategies\",\n \"strategies.deduplication\",\n \"strategies.deduplication.enabled\",\n \"strategies.deduplication.protectedTools\",\n \"strategies.purgeErrors\",\n \"strategies.purgeErrors.enabled\",\n \"strategies.purgeErrors.turns\",\n \"strategies.purgeErrors.protectedTools\",\n])\n\nfunction getConfigKeyPaths(obj: Record<string, any>, prefix = \"\"): string[] {\n const keys: string[] = []\n for (const key of Object.keys(obj)) {\n const fullKey = prefix ? `${prefix}.${key}` : key\n keys.push(fullKey)\n\n // model*Limits are dynamic maps keyed by providerID/modelID; do not recurse into arbitrary IDs.\n if (fullKey === \"compress.modelMaxLimits\" || fullKey === \"compress.modelMinLimits\") {\n continue\n }\n\n if (obj[key] && typeof obj[key] === \"object\" && !Array.isArray(obj[key])) {\n keys.push(...getConfigKeyPaths(obj[key], fullKey))\n }\n }\n return keys\n}\n\nexport function getInvalidConfigKeys(userConfig: Record<string, any>): string[] {\n const userKeys = getConfigKeyPaths(userConfig)\n return userKeys.filter((key) => !VALID_CONFIG_KEYS.has(key))\n}\n\ninterface ValidationError {\n key: string\n expected: string\n actual: string\n}\n\nexport function validateConfigTypes(config: Record<string, any>): ValidationError[] {\n const errors: ValidationError[] = []\n\n if (config.enabled !== undefined && typeof config.enabled !== \"boolean\") {\n errors.push({ key: \"enabled\", expected: \"boolean\", actual: typeof config.enabled })\n }\n\n if (config.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 (\n compress.protectUserMessages !== undefined &&\n typeof compress.protectUserMessages !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.protectUserMessages\",\n expected: \"boolean\",\n actual: typeof compress.protectUserMessages,\n })\n }\n\n if (\n typeof compress.iterationNudgeThreshold === \"number\" &&\n compress.iterationNudgeThreshold < 1\n ) {\n errors.push({\n key: \"compress.iterationNudgeThreshold\",\n expected: \"positive number (>= 1)\",\n actual: `${compress.iterationNudgeThreshold} (will be clamped to 1)`,\n })\n }\n\n const validateLimitValue = (\n key: string,\n value: unknown,\n actualValue: unknown = value,\n ): void => {\n const isValidNumber = typeof value === \"number\"\n const isPercentString = typeof value === \"string\" && value.endsWith(\"%\")\n\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key,\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(actualValue),\n })\n }\n }\n\n const validateModelLimits = (\n key: \"compress.modelMaxLimits\" | \"compress.modelMinLimits\",\n limits: unknown,\n ): void => {\n if (limits === undefined) {\n return\n }\n\n if (typeof limits !== \"object\" || limits === null || Array.isArray(limits)) {\n errors.push({\n key,\n expected: \"Record<string, number | ${number}%>\",\n actual: typeof limits,\n })\n return\n }\n\n for (const [providerModelKey, limit] of Object.entries(limits)) {\n const isValidNumber = typeof limit === \"number\"\n const isPercentString =\n typeof limit === \"string\" && /^\\d+(?:\\.\\d+)?%$/.test(limit)\n if (!isValidNumber && !isPercentString) {\n errors.push({\n key: `${key}.${providerModelKey}`,\n expected: 'number | \"${number}%\"',\n actual: JSON.stringify(limit),\n })\n }\n }\n }\n\n if (compress.maxContextLimit !== undefined) {\n validateLimitValue(\"compress.maxContextLimit\", compress.maxContextLimit)\n }\n\n if (compress.minContextLimit !== undefined) {\n validateLimitValue(\"compress.minContextLimit\", compress.minContextLimit)\n }\n\n validateModelLimits(\"compress.modelMaxLimits\", compress.modelMaxLimits)\n validateModelLimits(\"compress.modelMinLimits\", compress.modelMinLimits)\n\n const validValues = [\"ask\", \"allow\", \"deny\"]\n if (compress.permission !== undefined && !validValues.includes(compress.permission)) {\n errors.push({\n key: \"compress.permission\",\n expected: '\"ask\" | \"allow\" | \"deny\"',\n actual: JSON.stringify(compress.permission),\n })\n }\n\n if (\n compress.showCompression !== undefined &&\n typeof compress.showCompression !== \"boolean\"\n ) {\n errors.push({\n key: \"compress.showCompression\",\n expected: \"boolean\",\n actual: typeof compress.showCompression,\n })\n }\n }\n }\n\n const strategies = config.strategies\n if (strategies) {\n if (\n strategies.deduplication?.enabled !== undefined &&\n typeof strategies.deduplication.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.deduplication.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.deduplication.enabled,\n })\n }\n\n if (\n strategies.deduplication?.protectedTools !== undefined &&\n !Array.isArray(strategies.deduplication.protectedTools)\n ) {\n errors.push({\n key: \"strategies.deduplication.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.deduplication.protectedTools,\n })\n }\n\n if (strategies.purgeErrors) {\n if (\n strategies.purgeErrors.enabled !== undefined &&\n typeof strategies.purgeErrors.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.purgeErrors.enabled,\n })\n }\n\n if (\n strategies.purgeErrors.turns !== undefined &&\n typeof strategies.purgeErrors.turns !== \"number\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"number\",\n actual: typeof strategies.purgeErrors.turns,\n })\n }\n // Warn if turns is 0 or negative - will be clamped to 1\n if (\n typeof strategies.purgeErrors.turns === \"number\" &&\n strategies.purgeErrors.turns < 1\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"positive number (>= 1)\",\n actual: `${strategies.purgeErrors.turns} (will be clamped to 1)`,\n })\n }\n if (\n strategies.purgeErrors.protectedTools !== undefined &&\n !Array.isArray(strategies.purgeErrors.protectedTools)\n ) {\n errors.push({\n key: \"strategies.purgeErrors.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.purgeErrors.protectedTools,\n })\n }\n }\n }\n\n return errors\n}\n\nfunction showConfigWarnings(\n ctx: PluginInput,\n configPath: string,\n configData: Record<string, any>,\n isProject: boolean,\n): void {\n const invalidKeys = getInvalidConfigKeys(configData)\n const typeErrors = validateConfigTypes(configData)\n\n if (invalidKeys.length === 0 && typeErrors.length === 0) {\n return\n }\n\n const configType = isProject ? \"project config\" : \"config\"\n const messages: string[] = []\n\n if (invalidKeys.length > 0) {\n const keyList = invalidKeys.slice(0, 3).join(\", \")\n const suffix = invalidKeys.length > 3 ? ` (+${invalidKeys.length - 3} more)` : \"\"\n messages.push(`Unknown keys: ${keyList}${suffix}`)\n }\n\n if (typeErrors.length > 0) {\n for (const err of typeErrors.slice(0, 2)) {\n messages.push(`${err.key}: expected ${err.expected}, got ${err.actual}`)\n }\n if (typeErrors.length > 2) {\n messages.push(`(+${typeErrors.length - 2} more type errors)`)\n }\n }\n\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title: `DCP: ${configType} warning`,\n message: `${configPath}\\n${messages.join(\"\\n\")}`,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nconst defaultConfig: PluginConfig = {\n enabled: true,\n autoUpdate: true,\n debug: false,\n pruneNotification: \"detailed\",\n pruneNotificationType: \"chat\",\n commands: {\n enabled: true,\n protectedTools: [...DEFAULT_PROTECTED_TOOLS],\n },\n manualMode: {\n enabled: false,\n automaticStrategies: true,\n },\n turnProtection: {\n enabled: false,\n turns: 4,\n },\n experimental: {\n allowSubAgents: false,\n customPrompts: false,\n },\n protectedFilePatterns: [],\n compress: {\n mode: \"range\",\n permission: \"allow\",\n showCompression: false,\n summaryBuffer: true,\n maxContextLimit: 100000,\n minContextLimit: 50000,\n nudgeFrequency: 5,\n iterationNudgeThreshold: 15,\n nudgeForce: \"soft\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectUserMessages: false,\n },\n strategies: {\n deduplication: {\n enabled: true,\n protectedTools: [],\n },\n purgeErrors: {\n enabled: true,\n turns: 4,\n protectedTools: [],\n },\n },\n}\n\nconst GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, \"opencode\")\n : join(homedir(), \".config\", \"opencode\")\nconst GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.json\")\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate) && statSync(candidate).isDirectory()) {\n return candidate\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction getConfigPaths(ctx?: PluginInput): {\n global: string | null\n configDir: string | null\n project: string | null\n} {\n const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)\n ? GLOBAL_CONFIG_PATH_JSONC\n : existsSync(GLOBAL_CONFIG_PATH_JSON)\n ? GLOBAL_CONFIG_PATH_JSON\n : null\n\n let configDir: string | null = null\n const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR\n if (opencodeConfigDir) {\n const configJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : null\n }\n\n let project: string | null = null\n if (ctx?.directory) {\n const opencodeDir = findOpencodeDir(ctx.directory)\n if (opencodeDir) {\n const projectJsonc = join(opencodeDir, \"dcp.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : null\n }\n }\n\n return { global, configDir, project }\n}\n\nfunction createDefaultConfig(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n}\n\ninterface ConfigLoadResult {\n data: Record<string, any> | null\n parseError?: string\n}\n\nfunction loadConfigFile(configPath: string): ConfigLoadResult {\n let fileContent = \"\"\n try {\n fileContent = readFileSync(configPath, \"utf-8\")\n } catch {\n return { data: null }\n }\n\n try {\n const parsed = parse(fileContent, undefined, { allowTrailingComma: true })\n if (parsed === undefined || parsed === null) {\n return { data: null, parseError: \"Config file is empty or invalid\" }\n }\n return { data: parsed }\n } catch (error: any) {\n return { data: null, parseError: error.message || \"Failed to parse config\" }\n }\n}\n\nfunction mergeStrategies(\n base: PluginConfig[\"strategies\"],\n override?: Partial<PluginConfig[\"strategies\"]>,\n): PluginConfig[\"strategies\"] {\n if (!override) {\n return base\n }\n\n return {\n deduplication: {\n enabled: override.deduplication?.enabled ?? base.deduplication.enabled,\n protectedTools: [\n ...new Set([\n ...base.deduplication.protectedTools,\n ...(override.deduplication?.protectedTools ?? []),\n ]),\n ],\n },\n purgeErrors: {\n enabled: override.purgeErrors?.enabled ?? base.purgeErrors.enabled,\n turns: override.purgeErrors?.turns ?? base.purgeErrors.turns,\n protectedTools: [\n ...new Set([\n ...base.purgeErrors.protectedTools,\n ...(override.purgeErrors?.protectedTools ?? []),\n ]),\n ],\n },\n }\n}\n\nfunction mergeCompress(\n base: PluginConfig[\"compress\"],\n override?: CompressOverride,\n): PluginConfig[\"compress\"] {\n if (!override) {\n return base\n }\n\n return {\n mode: override.mode ?? base.mode,\n permission: override.permission ?? base.permission,\n showCompression: override.showCompression ?? base.showCompression,\n summaryBuffer: override.summaryBuffer ?? base.summaryBuffer,\n maxContextLimit: override.maxContextLimit ?? base.maxContextLimit,\n minContextLimit: override.minContextLimit ?? base.minContextLimit,\n modelMaxLimits: override.modelMaxLimits ?? base.modelMaxLimits,\n modelMinLimits: override.modelMinLimits ?? base.modelMinLimits,\n nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,\n iterationNudgeThreshold: override.iterationNudgeThreshold ?? base.iterationNudgeThreshold,\n nudgeForce: override.nudgeForce ?? base.nudgeForce,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n protectUserMessages: override.protectUserMessages ?? base.protectUserMessages,\n }\n}\n\nfunction mergeCommands(\n base: PluginConfig[\"commands\"],\n override?: Partial<PluginConfig[\"commands\"]>,\n): PluginConfig[\"commands\"] {\n if (!override) {\n return base\n }\n\n return {\n enabled: override.enabled ?? base.enabled,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n }\n}\n\nfunction mergeManualMode(\n base: PluginConfig[\"manualMode\"],\n override?: Partial<PluginConfig[\"manualMode\"]>,\n): PluginConfig[\"manualMode\"] {\n if (override === undefined) return base\n\n return {\n enabled: override.enabled ?? base.enabled,\n automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (override === undefined) return base\n\n return {\n allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,\n customPrompts: override.customPrompts ?? base.customPrompts,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: {\n enabled: config.commands.enabled,\n protectedTools: [...config.commands.protectedTools],\n },\n manualMode: {\n enabled: config.manualMode.enabled,\n automaticStrategies: config.manualMode.automaticStrategies,\n },\n turnProtection: { ...config.turnProtection },\n experimental: { ...config.experimental },\n protectedFilePatterns: [...config.protectedFilePatterns],\n compress: {\n ...config.compress,\n modelMaxLimits: { ...config.compress.modelMaxLimits },\n modelMinLimits: { ...config.compress.modelMinLimits },\n protectedTools: [...config.compress.protectedTools],\n },\n strategies: {\n deduplication: {\n ...config.strategies.deduplication,\n protectedTools: [...config.strategies.deduplication.protectedTools],\n },\n purgeErrors: {\n ...config.strategies.purgeErrors,\n protectedTools: [...config.strategies.purgeErrors.protectedTools],\n },\n },\n }\n}\n\nfunction mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConfig {\n return {\n enabled: data.enabled ?? config.enabled,\n autoUpdate: data.autoUpdate ?? config.autoUpdate,\n debug: data.debug ?? config.debug,\n pruneNotification: data.pruneNotification ?? config.pruneNotification,\n pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,\n commands: mergeCommands(config.commands, data.commands as any),\n manualMode: mergeManualMode(config.manualMode, data.manualMode as any),\n turnProtection: {\n enabled: data.turnProtection?.enabled ?? config.turnProtection.enabled,\n turns: data.turnProtection?.turns ?? config.turnProtection.turns,\n },\n experimental: mergeExperimental(config.experimental, data.experimental as any),\n protectedFilePatterns: [\n ...new Set([...config.protectedFilePatterns, ...(data.protectedFilePatterns ?? [])]),\n ],\n compress: mergeCompress(config.compress, data.compress as CompressOverride),\n strategies: mergeStrategies(config.strategies, data.strategies as any),\n }\n}\n\nfunction scheduleParseWarning(ctx: PluginInput, title: string, message: string): void {\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title,\n message,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nexport function getConfig(ctx: PluginInput): PluginConfig {\n let config = deepCloneConfig(defaultConfig)\n const configPaths = getConfigPaths(ctx)\n\n if (!configPaths.global) {\n createDefaultConfig()\n }\n\n const layers: Array<{ path: string | null; name: string; isProject: boolean }> = [\n { path: configPaths.global, name: \"config\", isProject: false },\n { path: configPaths.configDir, name: \"configDir config\", isProject: true },\n { path: configPaths.project, name: \"project config\", isProject: true },\n ]\n\n for (const layer of layers) {\n if (!layer.path) {\n continue\n }\n\n const result = loadConfigFile(layer.path)\n if (result.parseError) {\n scheduleParseWarning(\n ctx,\n `DCP: Invalid ${layer.name}`,\n `${layer.path}\\n${result.parseError}\\nUsing previous/default values`,\n )\n continue\n }\n\n if (!result.data) {\n continue\n }\n\n showConfigWarnings(ctx, layer.path, result.data, layer.isProject)\n config = mergeLayer(config, result.data)\n }\n\n 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 { 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 summaryWithTools = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n plan.entry.summary,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n preparedPlans.push({\n plan,\n summaryWithTools,\n })\n }\n\n const runId = allocateRunId(ctx.state)\n\n for (const { plan, summaryWithTools } of preparedPlans) {\n const blockId = allocateBlockId(ctx.state)\n const storedSummary = wrapCompressedSummary(blockId, summaryWithTools)\n const summaryTokens = countTokens(storedSummary)\n\n applyCompressionState(\n ctx.state,\n {\n topic: plan.entry.topic,\n batchTopic: input.topic,\n startId: plan.entry.messageId,\n endId: plan.entry.messageId,\n mode: \"message\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n plan.selection,\n plan.anchorMessageId,\n blockId,\n storedSummary,\n [],\n )\n\n notifications.push({\n blockId,\n runId,\n summary: summaryWithTools,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return formatResult(plans.length, skippedIssues, skippedCount)\n },\n })\n}\n","import { SessionState, WithParts } from \"./state\"\nimport { AssistantMessage, UserMessage } from \"@opencode-ai/sdk/v2\"\nimport { Logger } from \"./logger\"\nimport * as _anthropicTokenizer from \"@anthropic-ai/tokenizer\"\nconst anthropicCountTokens = (_anthropicTokenizer.countTokens ??\n (_anthropicTokenizer as any).default?.countTokens) as typeof _anthropicTokenizer.countTokens\nimport { getLastUserMessage } from \"./messages/query\"\n\nexport function getCurrentTokenUsage(state: SessionState, messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"assistant\") {\n continue\n }\n\n const assistantInfo = msg.info as AssistantMessage\n if ((assistantInfo.tokens?.output || 0) <= 0) {\n continue\n }\n\n if (\n state.lastCompaction > 0 &&\n (msg.info.time.created < state.lastCompaction ||\n (msg.info.summary === true && msg.info.time.created === state.lastCompaction))\n ) {\n return 0\n }\n\n const input = assistantInfo.tokens?.input || 0\n const output = assistantInfo.tokens?.output || 0\n const reasoning = assistantInfo.tokens?.reasoning || 0\n const cacheRead = assistantInfo.tokens?.cache?.read || 0\n const cacheWrite = assistantInfo.tokens?.cache?.write || 0\n return input + output + reasoning + cacheRead + cacheWrite\n }\n\n return 0\n}\n\nexport function getCurrentParams(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): {\n providerId: string | undefined\n modelId: string | undefined\n agent: string | undefined\n variant: string | undefined\n} {\n const userMsg = getLastUserMessage(messages)\n if (!userMsg) {\n logger.debug(\"No user message found when determining current params\")\n return {\n providerId: undefined,\n modelId: undefined,\n agent: undefined,\n variant: undefined,\n }\n }\n const userInfo = userMsg.info as UserMessage\n const agent: string = userInfo.agent\n const providerId: string | undefined = userInfo.model.providerID\n const modelId: string | undefined = userInfo.model.modelID\n const variant: string | undefined = userInfo.model.variant\n\n return { providerId, modelId, agent, variant }\n}\n\nexport function countTokens(text: string): number {\n if (!text) return 0\n try {\n return anthropicCountTokens(text)\n } catch {\n return Math.round(text.length / 4)\n }\n}\n\nexport function estimateTokensBatch(texts: string[]): number {\n if (texts.length === 0) return 0\n return countTokens(texts.join(\" \"))\n}\n\nexport const COMPACTED_TOOL_OUTPUT_PLACEHOLDER = \"[Old tool result content cleared]\"\n\nfunction stringifyToolContent(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value)\n}\n\nexport function extractCompletedToolOutput(part: any): string | undefined {\n if (\n part?.type !== \"tool\" ||\n part.state?.status !== \"completed\" ||\n part.state?.output === undefined\n ) {\n return undefined\n }\n\n if (part.state?.time?.compacted) {\n return COMPACTED_TOOL_OUTPUT_PLACEHOLDER\n }\n\n return stringifyToolContent(part.state.output)\n}\n\nexport function extractToolContent(part: any): string[] {\n const contents: string[] = []\n\n if (part?.type !== \"tool\") {\n return contents\n }\n\n if (part.state?.input !== undefined) {\n contents.push(stringifyToolContent(part.state.input))\n }\n\n const completedOutput = extractCompletedToolOutput(part)\n if (completedOutput !== undefined) {\n contents.push(completedOutput)\n } else if (part.state?.status === \"error\" && part.state?.error) {\n contents.push(stringifyToolContent(part.state.error))\n }\n\n return contents\n}\n\nexport function countToolTokens(part: any): number {\n const contents = extractToolContent(part)\n return estimateTokensBatch(contents)\n}\n\nexport function getTotalToolTokens(state: SessionState, toolIds: string[]): number {\n let total = 0\n for (const id of toolIds) {\n const entry = state.toolParameters.get(id)\n total += entry?.tokenCount ?? 0\n }\n return total\n}\n\nexport function countMessageTextTokens(msg: WithParts): number {\n const texts: string[] = []\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n\nexport function countAllMessageTokens(msg: WithParts): number {\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const texts: string[] = []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n } else {\n texts.push(...extractToolContent(part))\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n","import type { WithParts } from \"../state\"\n\nexport function isMessageWithInfo(message: unknown): message is WithParts {\n if (!message || typeof message !== \"object\") {\n return false\n }\n\n const info = (message as any).info\n const parts = (message as any).parts\n if (!info || typeof info !== \"object\") {\n return false\n }\n\n return (\n typeof info.id === \"string\" &&\n info.id.length > 0 &&\n typeof info.sessionID === \"string\" &&\n info.sessionID.length > 0 &&\n (info.role === \"user\" || info.role === \"assistant\") &&\n info.time &&\n typeof info.time === \"object\" &&\n typeof info.time.created === \"number\" &&\n Array.isArray(parts)\n )\n}\n\nexport function filterMessages(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n return messages.filter(isMessageWithInfo)\n}\n\nexport function filterMessagesInPlace(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n let writeIndex = 0\n\n for (const message of messages) {\n if (isMessageWithInfo(message)) {\n messages[writeIndex++] = message\n }\n }\n\n messages.length = writeIndex\n return messages as WithParts[]\n}\n","import type { PluginConfig } from \"../config\"\nimport type { WithParts } from \"../state\"\nimport { isMessageWithInfo } from \"./shape\"\n\nexport const getLastUserMessage = (\n messages: WithParts[],\n startIndex?: number,\n): WithParts | null => {\n const start = startIndex ?? messages.length - 1\n for (let i = start; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return msg\n }\n }\n return null\n}\n\nexport const messageHasCompress = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"assistant\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n\nexport const isIgnoredUserMessage = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"user\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n if (parts.length === 0) {\n return true\n }\n\n for (const part of parts) {\n if (!(part as any).ignored) {\n return false\n }\n }\n\n return true\n}\n\nexport function isProtectedUserMessage(config: PluginConfig, message: WithParts): boolean {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n return (\n config.compress.mode === \"message\" &&\n config.compress.protectUserMessages &&\n message.info.role === \"user\" &&\n !isIgnoredUserMessage(message)\n )\n}\n","// 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, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): string {\n const serializedAttributes = Object.entries(attributes || {})\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([name, value]) => {\n if (name.trim().length === 0 || typeof value !== \"string\" || value.length === 0) {\n return \"\"\n }\n\n return ` ${name}=\"${escapeXmlAttribute(value)}\"`\n })\n .join(\"\")\n\n return `\\n<${MESSAGE_ID_TAG_NAME}${serializedAttributes}>${ref}</${MESSAGE_ID_TAG_NAME}>`\n}\n\nexport function assignMessageRefs(state: SessionState, messages: WithParts[]): number {\n let assigned = 0\n let skippedSubAgentPrompt = false\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n if (state.isSubAgent && !skippedSubAgentPrompt && message.info.role === \"user\") {\n skippedSubAgentPrompt = true\n continue\n }\n\n const rawMessageId = message.info.id\n if (typeof rawMessageId !== \"string\" || rawMessageId.length === 0) {\n continue\n }\n\n 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 const startReference = lookup.get(parsedStartId.ref)\n const endReference = lookup.get(parsedEndId.ref)\n\n if (!startReference) {\n issues.push(\n `startId ${parsedStartId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (!endReference) {\n issues.push(\n `endId ${parsedEndId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!startReference || !endReference) {\n throw new Error(\"Failed to resolve boundary IDs\")\n }\n\n if (startReference.rawIndex > endReference.rawIndex) {\n throw new Error(\n `startId ${parsedStartId.ref} appears after endId ${parsedEndId.ref} in the conversation. Start must come before end.`,\n )\n }\n\n return { startReference, endReference }\n}\n\nexport function resolveSelection(\n context: SearchContext,\n 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\"\n\nexport const COMPRESSED_BLOCK_HEADER = \"[Compressed conversation section]\"\n\nexport function allocateBlockId(state: SessionState): number {\n const next = state.prune.messages.nextBlockId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextBlockId = 2\n return 1\n }\n\n state.prune.messages.nextBlockId = next + 1\n return next\n}\n\nexport function allocateRunId(state: SessionState): number {\n const next = state.prune.messages.nextRunId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextRunId = 2\n return 1\n }\n\n state.prune.messages.nextRunId = next + 1\n return next\n}\n\nexport function attachCompressionDuration(\n messagesState: PruneMessagesState,\n messageId: string,\n callId: string,\n durationMs: number,\n): number {\n if (typeof durationMs !== \"number\" || !Number.isFinite(durationMs)) {\n return 0\n }\n\n let updates = 0\n for (const block of messagesState.blocksById.values()) {\n if (block.compressMessageId !== messageId || block.compressCallId !== callId) {\n continue\n }\n\n block.durationMs = durationMs\n updates++\n }\n\n return updates\n}\n\nexport function wrapCompressedSummary(blockId: number, summary: string): string {\n const header = COMPRESSED_BLOCK_HEADER\n const footer = formatMessageIdTag(formatBlockRef(blockId))\n const body = summary.trim()\n if (body.length === 0) {\n return `${header}\\n${footer}`\n }\n return `${header}\\n${body}\\n\\n${footer}`\n}\n\nexport function applyCompressionState(\n state: SessionState,\n input: CompressionStateInput,\n selection: SelectionResolution,\n anchorMessageId: string,\n blockId: number,\n summary: string,\n consumedBlockIds: number[],\n): AppliedCompressionResult {\n const messagesState = state.prune.messages\n const consumed = [...new Set(consumedBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n const included = [...consumed]\n\n const effectiveMessageIds = new Set<string>(selection.messageIds)\n const effectiveToolIds = new Set<string>(selection.toolIds)\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n effectiveMessageIds.add(messageId)\n }\n for (const toolId of consumedBlock.effectiveToolIds) {\n effectiveToolIds.add(toolId)\n }\n }\n\n const initiallyActiveMessages = new Set<string>()\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (entry && entry.activeBlockIds.length > 0) {\n initiallyActiveMessages.add(messageId)\n }\n }\n\n const initiallyActiveToolIds = new Set<string>()\n for (const activeBlockId of messagesState.activeBlockIds) {\n const activeBlock = messagesState.blocksById.get(activeBlockId)\n if (!activeBlock || !activeBlock.active) {\n continue\n }\n\n for (const toolId of activeBlock.effectiveToolIds) {\n initiallyActiveToolIds.add(toolId)\n }\n }\n\n const createdAt = Date.now()\n const block: CompressionBlock = {\n blockId,\n runId: input.runId,\n active: true,\n deactivatedByUser: false,\n compressedTokens: 0,\n summaryTokens: input.summaryTokens,\n durationMs: 0,\n mode: input.mode,\n topic: input.topic,\n batchTopic: input.batchTopic,\n startId: input.startId,\n endId: input.endId,\n anchorMessageId,\n compressMessageId: input.compressMessageId,\n compressCallId: input.compressCallId,\n includedBlockIds: included,\n consumedBlockIds: consumed,\n parentBlockIds: [],\n directMessageIds: [],\n directToolIds: [],\n effectiveMessageIds: [...effectiveMessageIds],\n effectiveToolIds: [...effectiveToolIds],\n createdAt,\n summary,\n }\n\n messagesState.blocksById.set(blockId, block)\n messagesState.activeBlockIds.add(blockId)\n messagesState.activeByAnchorMessageId.set(anchorMessageId, blockId)\n\n const deactivatedAt = Date.now()\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock || !consumedBlock.active) {\n continue\n }\n\n consumedBlock.active = false\n consumedBlock.deactivatedAt = deactivatedAt\n consumedBlock.deactivatedByBlockId = blockId\n if (!consumedBlock.parentBlockIds.includes(blockId)) {\n consumedBlock.parentBlockIds.push(blockId)\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n const removeActiveBlockId = (\n entry: { activeBlockIds: number[] },\n blockIdToRemove: number,\n ): void => {\n if (entry.activeBlockIds.length === 0) {\n return\n }\n entry.activeBlockIds = entry.activeBlockIds.filter((id) => id !== blockIdToRemove)\n }\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n removeActiveBlockId(entry, consumedBlockId)\n }\n }\n\n for (const messageId of selection.messageIds) {\n const tokenCount = selection.messageTokenById.get(messageId) || 0\n const existing = messagesState.byMessageId.get(messageId)\n\n if (!existing) {\n messagesState.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds: [blockId],\n activeBlockIds: [blockId],\n })\n continue\n }\n\n existing.tokenCount = Math.max(existing.tokenCount, tokenCount)\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n for (const messageId of block.effectiveMessageIds) {\n if (selection.messageTokenById.has(messageId)) {\n continue\n }\n\n const existing = messagesState.byMessageId.get(messageId)\n if (!existing) {\n continue\n }\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n let compressedTokens = 0\n const newlyCompressedMessageIds: string[] = []\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n\n const isNowActive = entry.activeBlockIds.length > 0\n const wasActive = initiallyActiveMessages.has(messageId)\n\n if (isNowActive && !wasActive) {\n compressedTokens += entry.tokenCount\n newlyCompressedMessageIds.push(messageId)\n }\n }\n\n const newlyCompressedToolIds: string[] = []\n for (const toolId of effectiveToolIds) {\n if (!initiallyActiveToolIds.has(toolId)) {\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n block.directMessageIds = [...newlyCompressedMessageIds]\n block.directToolIds = [...newlyCompressedToolIds]\n\n block.compressedTokens = compressedTokens\n\n state.stats.pruneTokenCounter += compressedTokens\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n return {\n compressedTokens,\n messageIds: selection.messageIds,\n newlyCompressedMessageIds,\n newlyCompressedToolIds,\n }\n}\n","import type { PluginConfig } from \"../config\"\nimport type { SessionState } from \"../state\"\nimport { parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../messages/query\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport { COMPRESSED_BLOCK_HEADER } from \"./state\"\nimport type {\n CompressMessageEntry,\n CompressMessageToolArgs,\n ResolvedMessageCompression,\n ResolvedMessageCompressionsResult,\n SearchContext,\n} from \"./types\"\n\ninterface SkippedIssue {\n kind: string\n messageId: string\n}\n\nclass SoftIssue extends Error {\n constructor(\n public readonly kind: string,\n public readonly messageId: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport function validateArgs(args: CompressMessageToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.messageId !== \"string\" || entry.messageId.trim().length === 0) {\n throw new Error(`${prefix}.messageId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.topic !== \"string\" || entry.topic.trim().length === 0) {\n throw new Error(`${prefix}.topic is required and must be a non-empty string`)\n }\n\n if (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\n if (skippedCount === 0) {\n return processedText\n }\n\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `${processedText}\\nSkipped ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nexport function formatIssues(skippedIssues: string[], skippedCount: number): string {\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `Unable to compress any messages. Found ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nconst ISSUE_TEMPLATES: Record<string, [singular: string, plural: string]> = {\n blocked: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"invalid-format\": [\n \"is invalid. Use an injected raw message ID of the form mNNNN.\",\n \"are invalid. Use injected raw message IDs of the form mNNNN.\",\n ],\n \"block-id\": [\n \"is invalid here. Block IDs like bN are not allowed; use an mNNNN message ID instead.\",\n \"are invalid here. Block IDs like bN are not allowed; use mNNNN message IDs instead.\",\n ],\n \"not-in-context\": [\n \"is not available in the current conversation context. Choose an injected mNNNN ID visible in context.\",\n \"are not available in the current conversation context. Choose injected mNNNN IDs visible in context.\",\n ],\n protected: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"already-compressed\": [\n \"is already part of an active compression.\",\n \"are already part of active compressions.\",\n ],\n duplicate: [\n \"was selected more than once in this batch.\",\n \"were each selected more than once in this batch.\",\n ],\n}\n\nfunction formatSkippedGroup(kind: string, messageIds: string[]): string {\n const templates = ISSUE_TEMPLATES[kind]\n const ids = messageIds.join(\", \")\n const single = messageIds.length === 1\n const prefix = single ? \"messageId\" : \"messageIds\"\n\n if (!templates) {\n return `${prefix} ${ids}: unknown issue.`\n }\n\n return `${prefix} ${ids} ${single ? templates[0] : templates[1]}`\n}\n\nfunction groupSkippedIssues(issues: SkippedIssue[]): string[] {\n const groups = new Map<string, string[]>()\n const order: string[] = []\n\n for (const issue of issues) {\n let ids = groups.get(issue.kind)\n if (!ids) {\n ids = []\n groups.set(issue.kind, ids)\n order.push(issue.kind)\n }\n ids.push(issue.messageId)\n }\n\n return order.map((kind) => {\n const ids = groups.get(kind)!\n return formatSkippedGroup(kind, ids)\n })\n}\n\nexport function resolveMessages(\n args: CompressMessageToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompressionsResult {\n const issues: SkippedIssue[] = []\n const plans: ResolvedMessageCompression[] = []\n const seenMessageIds = new Set<string>()\n\n for (const entry of args.content) {\n const normalizedMessageId = entry.messageId.trim()\n if (seenMessageIds.has(normalizedMessageId)) {\n issues.push({ kind: \"duplicate\", messageId: normalizedMessageId })\n continue\n }\n\n try {\n const plan = resolveMessage(\n {\n ...entry,\n messageId: normalizedMessageId,\n },\n searchContext,\n state,\n config,\n )\n seenMessageIds.add(plan.entry.messageId)\n plans.push(plan)\n } catch (error: any) {\n if (error instanceof SoftIssue) {\n issues.push({ kind: error.kind, messageId: error.messageId })\n continue\n }\n\n throw error\n }\n }\n\n return {\n plans,\n skippedIssues: groupSkippedIssues(issues),\n skippedCount: issues.length,\n }\n}\n\nfunction resolveMessage(\n entry: CompressMessageEntry,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompression {\n if (entry.messageId.toUpperCase() === \"BLOCKED\") {\n throw new SoftIssue(\"blocked\", \"BLOCKED\", \"protected message\")\n }\n\n const parsed = parseBoundaryId(entry.messageId)\n\n if (!parsed) {\n throw new SoftIssue(\"invalid-format\", entry.messageId, \"invalid format\")\n }\n\n if (parsed.kind === \"compressed-block\") {\n throw new SoftIssue(\"block-id\", entry.messageId, \"block ID used\")\n }\n\n const messageId = state.messageIds.byRef.get(parsed.ref)\n const rawMessage = messageId ? searchContext.rawMessagesById.get(messageId) : undefined\n if (\n !messageId ||\n !rawMessage ||\n !searchContext.rawIndexById.has(messageId) ||\n isIgnoredUserMessage(rawMessage)\n ) {\n throw new SoftIssue(\"not-in-context\", parsed.ref, \"not in context\")\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n parsed.ref,\n parsed.ref,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n if (isProtectedUserMessage(config, rawMessage)) {\n throw new SoftIssue(\"protected\", parsed.ref, \"protected message\")\n }\n\n const pruneEntry = state.prune.messages.byMessageId.get(messageId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n throw new SoftIssue(\"already-compressed\", parsed.ref, \"already compressed\")\n }\n\n return {\n entry: {\n messageId: parsed.ref,\n topic: entry.topic,\n summary: entry.summary,\n },\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\n}\n","/**\n * State persistence module for DCP plugin.\n * Persists pruned tool IDs across sessions so they survive OpenCode restarts.\n * Storage location: ~/.local/share/opencode/storage/plugin/dcp/{sessionId}.json\n */\n\nimport * as fs from \"fs/promises\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { serializePruneMessagesState } from \"./utils\"\n\n/** Prune state as stored on disk */\nexport interface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport interface PersistedPrune {\n tools?: Record<string, number>\n messages?: PersistedPruneMessagesState\n}\n\nexport interface PersistedNudges {\n contextLimitAnchors: string[]\n turnNudgeAnchors?: string[]\n iterationNudgeAnchors?: string[]\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n}\n\nconst STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n)\n\nasync function ensureStorageDir(): Promise<void> {\n if (!existsSync(STORAGE_DIR)) {\n await fs.mkdir(STORAGE_DIR, { recursive: true })\n }\n}\n\nfunction getSessionFilePath(sessionId: string): string {\n return join(STORAGE_DIR, `${sessionId}.json`)\n}\n\nasync function writePersistedSessionState(\n sessionId: string,\n state: PersistedSessionState,\n logger: Logger,\n): Promise<void> {\n await ensureStorageDir()\n\n const filePath = getSessionFilePath(sessionId)\n const content = JSON.stringify(state, null, 2)\n await fs.writeFile(filePath, content, \"utf-8\")\n\n logger.info(\"Saved session state to disk\", {\n sessionId,\n totalTokensSaved: state.stats.totalPruneTokens,\n })\n}\n\nexport async function saveSessionState(\n sessionState: SessionState,\n logger: Logger,\n sessionName?: string,\n): Promise<void> {\n try {\n if (!sessionState.sessionId) {\n return\n }\n\n const state: PersistedSessionState = {\n sessionName: sessionName,\n prune: {\n tools: Object.fromEntries(sessionState.prune.tools),\n messages: serializePruneMessagesState(sessionState.prune.messages),\n },\n nudges: {\n contextLimitAnchors: Array.from(sessionState.nudges.contextLimitAnchors),\n turnNudgeAnchors: Array.from(sessionState.nudges.turnNudgeAnchors),\n iterationNudgeAnchors: Array.from(sessionState.nudges.iterationNudgeAnchors),\n },\n stats: sessionState.stats,\n lastUpdated: new Date().toISOString(),\n }\n\n await writePersistedSessionState(sessionState.sessionId, state, logger)\n } catch (error: any) {\n logger.error(\"Failed to save session state\", {\n sessionId: sessionState.sessionId,\n error: error?.message,\n })\n }\n}\n\nexport async function loadSessionState(\n sessionId: string,\n logger: Logger,\n): Promise<PersistedSessionState | null> {\n try {\n const filePath = getSessionFilePath(sessionId)\n\n if (!existsSync(filePath)) {\n return null\n }\n\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n const hasPruneTools = state?.prune?.tools && typeof state.prune.tools === \"object\"\n const hasPruneMessages = state?.prune?.messages && typeof state.prune.messages === \"object\"\n const hasNudgeFormat = state?.nudges && typeof state.nudges === \"object\"\n if (\n !state ||\n !state.prune ||\n !hasPruneTools ||\n !hasPruneMessages ||\n !state.stats ||\n !hasNudgeFormat\n ) {\n logger.warn(\"Invalid session state file, ignoring\", {\n sessionId: sessionId,\n })\n return null\n }\n\n const rawContextLimitAnchors = Array.isArray(state.nudges.contextLimitAnchors)\n ? state.nudges.contextLimitAnchors\n : []\n const validAnchors = rawContextLimitAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedAnchors = [...new Set(validAnchors)]\n if (validAnchors.length !== rawContextLimitAnchors.length) {\n logger.warn(\"Filtered out malformed contextLimitAnchors entries\", {\n sessionId: sessionId,\n original: rawContextLimitAnchors.length,\n valid: validAnchors.length,\n })\n }\n state.nudges.contextLimitAnchors = dedupedAnchors\n\n const rawTurnNudgeAnchors = Array.isArray(state.nudges.turnNudgeAnchors)\n ? state.nudges.turnNudgeAnchors\n : []\n const validSoftAnchors = rawTurnNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedSoftAnchors = [...new Set(validSoftAnchors)]\n if (validSoftAnchors.length !== rawTurnNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed turnNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawTurnNudgeAnchors.length,\n valid: validSoftAnchors.length,\n })\n }\n state.nudges.turnNudgeAnchors = dedupedSoftAnchors\n\n const rawIterationNudgeAnchors = Array.isArray(state.nudges.iterationNudgeAnchors)\n ? state.nudges.iterationNudgeAnchors\n : []\n const validIterationAnchors = rawIterationNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedIterationAnchors = [...new Set(validIterationAnchors)]\n if (validIterationAnchors.length !== rawIterationNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed iterationNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawIterationNudgeAnchors.length,\n valid: validIterationAnchors.length,\n })\n }\n state.nudges.iterationNudgeAnchors = dedupedIterationAnchors\n\n logger.info(\"Loaded session state from disk\", {\n sessionId: sessionId,\n })\n\n return state\n } catch (error: any) {\n logger.warn(\"Failed to load session state\", {\n sessionId: sessionId,\n error: error?.message,\n })\n return null\n }\n}\n\nexport interface AggregatedStats {\n totalTokens: number\n totalTools: number\n totalMessages: number\n sessionCount: number\n}\n\nexport async function loadAllSessionStats(logger: Logger): Promise<AggregatedStats> {\n const result: AggregatedStats = {\n totalTokens: 0,\n totalTools: 0,\n totalMessages: 0,\n sessionCount: 0,\n }\n\n try {\n if (!existsSync(STORAGE_DIR)) {\n return result\n }\n\n const files = await fs.readdir(STORAGE_DIR)\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"))\n\n for (const file of jsonFiles) {\n try {\n const filePath = join(STORAGE_DIR, file)\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n if (state?.stats?.totalPruneTokens && state?.prune) {\n result.totalTokens += state.stats.totalPruneTokens\n result.totalTools += state.prune.tools\n ? Object.keys(state.prune.tools).length\n : 0\n result.totalMessages += state.prune.messages?.byMessageId\n ? Object.keys(state.prune.messages.byMessageId).length\n : 0\n result.sessionCount++\n }\n } catch {\n // Skip invalid files\n }\n }\n\n logger.debug(\"Loaded all-time stats\", result)\n } catch (error: any) {\n logger.warn(\"Failed to load all-time stats\", { error: error?.message })\n }\n\n return result\n}\n","import type {\n CompressionBlock,\n PruneMessagesState,\n PrunedMessageEntry,\n SessionState,\n WithParts,\n} from \"./types\"\nimport { isIgnoredUserMessage, messageHasCompress } from \"../messages/query\"\nimport { isMessageWithInfo } from \"../messages/shape\"\nimport { countTokens } from \"../token-utils\"\n\nexport const isMessageCompacted = (state: SessionState, msg: WithParts): boolean => {\n if (!isMessageWithInfo(msg)) {\n return false\n }\n\n if (msg.info.time.created < state.lastCompaction) {\n return true\n }\n const pruneEntry = state.prune.messages.byMessageId.get(msg.info.id)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n return true\n }\n return false\n}\n\ninterface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport function serializePruneMessagesState(\n messagesState: PruneMessagesState,\n): PersistedPruneMessagesState {\n return {\n byMessageId: Object.fromEntries(messagesState.byMessageId),\n blocksById: Object.fromEntries(\n Array.from(messagesState.blocksById.entries()).map(([blockId, block]) => [\n String(blockId),\n block,\n ]),\n ),\n activeBlockIds: Array.from(messagesState.activeBlockIds),\n activeByAnchorMessageId: Object.fromEntries(messagesState.activeByAnchorMessageId),\n nextBlockId: messagesState.nextBlockId,\n nextRunId: messagesState.nextRunId,\n }\n}\n\nexport async function isSubAgentSession(client: any, sessionID: string): Promise<boolean> {\n try {\n const result = await client.session.get({ path: { id: sessionID } })\n return !!result.data?.parentID\n } catch (error: any) {\n return false\n }\n}\n\nexport function findLastCompactionTimestamp(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"assistant\" && msg.info.summary === true) {\n return msg.info.time.created\n }\n }\n return 0\n}\n\nexport function countTurns(state: SessionState, messages: WithParts[]): number {\n let turnCount = 0\n for (const msg of messages) {\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCount++\n }\n }\n }\n return turnCount\n}\n\nexport function loadPruneMap(obj?: Record<string, number>): Map<string, number> {\n if (!obj || typeof obj !== \"object\") {\n return new Map()\n }\n\n const entries = Object.entries(obj).filter(\n (entry): entry is [string, number] =>\n typeof entry[0] === \"string\" && typeof entry[1] === \"number\",\n )\n return new Map(entries)\n}\n\nexport function createPruneMessagesState(): PruneMessagesState {\n return {\n byMessageId: new Map<string, PrunedMessageEntry>(),\n blocksById: new Map<number, CompressionBlock>(),\n activeBlockIds: new Set<number>(),\n activeByAnchorMessageId: new Map<string, number>(),\n nextBlockId: 1,\n nextRunId: 1,\n }\n}\n\nexport function loadPruneMessagesState(\n persisted?: PersistedPruneMessagesState,\n): PruneMessagesState {\n const state = createPruneMessagesState()\n if (!persisted || typeof persisted !== \"object\") {\n return state\n }\n\n if (typeof persisted.nextBlockId === \"number\" && Number.isInteger(persisted.nextBlockId)) {\n state.nextBlockId = Math.max(1, persisted.nextBlockId)\n }\n if (typeof persisted.nextRunId === \"number\" && Number.isInteger(persisted.nextRunId)) {\n state.nextRunId = Math.max(1, persisted.nextRunId)\n }\n\n if (persisted.byMessageId && typeof persisted.byMessageId === \"object\") {\n for (const [messageId, entry] of Object.entries(persisted.byMessageId)) {\n if (!entry || typeof entry !== \"object\") {\n continue\n }\n\n const tokenCount = typeof entry.tokenCount === \"number\" ? entry.tokenCount : 0\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [\n ...new Set(\n entry.allBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n const activeBlockIds = Array.isArray(entry.activeBlockIds)\n ? [\n ...new Set(\n entry.activeBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n\n state.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds,\n activeBlockIds,\n })\n }\n }\n\n if (persisted.blocksById && typeof persisted.blocksById === \"object\") {\n for (const [blockIdStr, block] of Object.entries(persisted.blocksById)) {\n const blockId = Number.parseInt(blockIdStr, 10)\n if (!Number.isInteger(blockId) || blockId < 1 || !block || typeof block !== \"object\") {\n continue\n }\n\n const toNumberArray = (value: unknown): number[] =>\n Array.isArray(value)\n ? [\n ...new Set(\n value.filter(\n (item): item is number => Number.isInteger(item) && item > 0,\n ),\n ),\n ]\n : []\n const toStringArray = (value: unknown): string[] =>\n Array.isArray(value)\n ? [...new Set(value.filter((item): item is string => typeof item === \"string\"))]\n : []\n\n state.blocksById.set(blockId, {\n blockId,\n runId:\n typeof block.runId === \"number\" &&\n Number.isInteger(block.runId) &&\n block.runId > 0\n ? block.runId\n : blockId,\n active: block.active === true,\n deactivatedByUser: block.deactivatedByUser === true,\n compressedTokens:\n typeof block.compressedTokens === \"number\" &&\n Number.isFinite(block.compressedTokens)\n ? Math.max(0, block.compressedTokens)\n : 0,\n summaryTokens:\n typeof block.summaryTokens === \"number\" && Number.isFinite(block.summaryTokens)\n ? Math.max(0, block.summaryTokens)\n : typeof block.summary === \"string\"\n ? countTokens(block.summary)\n : 0,\n durationMs:\n typeof block.durationMs === \"number\" && Number.isFinite(block.durationMs)\n ? Math.max(0, block.durationMs)\n : 0,\n mode: block.mode === \"range\" || block.mode === \"message\" ? block.mode : undefined,\n topic: typeof block.topic === \"string\" ? block.topic : \"\",\n batchTopic:\n typeof block.batchTopic === \"string\"\n ? block.batchTopic\n : typeof block.topic === \"string\"\n ? block.topic\n : \"\",\n startId: typeof block.startId === \"string\" ? block.startId : \"\",\n endId: typeof block.endId === \"string\" ? block.endId : \"\",\n anchorMessageId:\n typeof block.anchorMessageId === \"string\" ? block.anchorMessageId : \"\",\n compressMessageId:\n typeof block.compressMessageId === \"string\" ? block.compressMessageId : \"\",\n compressCallId:\n typeof block.compressCallId === \"string\" ? block.compressCallId : undefined,\n includedBlockIds: toNumberArray(block.includedBlockIds),\n consumedBlockIds: toNumberArray(block.consumedBlockIds),\n parentBlockIds: toNumberArray(block.parentBlockIds),\n directMessageIds: toStringArray(block.directMessageIds),\n directToolIds: toStringArray(block.directToolIds),\n effectiveMessageIds: toStringArray(block.effectiveMessageIds),\n effectiveToolIds: toStringArray(block.effectiveToolIds),\n createdAt: typeof block.createdAt === \"number\" ? block.createdAt : 0,\n deactivatedAt:\n typeof block.deactivatedAt === \"number\" ? block.deactivatedAt : undefined,\n deactivatedByBlockId:\n typeof block.deactivatedByBlockId === \"number\" &&\n Number.isInteger(block.deactivatedByBlockId)\n ? block.deactivatedByBlockId\n : undefined,\n summary: typeof block.summary === \"string\" ? block.summary : \"\",\n })\n }\n }\n\n if (Array.isArray(persisted.activeBlockIds)) {\n for (const blockId of persisted.activeBlockIds) {\n if (!Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeBlockIds.add(blockId)\n }\n }\n\n if (\n persisted.activeByAnchorMessageId &&\n typeof persisted.activeByAnchorMessageId === \"object\"\n ) {\n for (const [anchorMessageId, blockId] of Object.entries(\n persisted.activeByAnchorMessageId,\n )) {\n if (typeof blockId !== \"number\" || !Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeByAnchorMessageId.set(anchorMessageId, blockId)\n }\n }\n\n for (const [blockId, block] of state.blocksById) {\n if (block.active) {\n state.activeBlockIds.add(blockId)\n if (block.anchorMessageId) {\n state.activeByAnchorMessageId.set(block.anchorMessageId, blockId)\n }\n }\n if (blockId >= state.nextBlockId) {\n state.nextBlockId = blockId + 1\n }\n if (block.runId >= state.nextRunId) {\n state.nextRunId = block.runId + 1\n }\n }\n\n return state\n}\n\nexport function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {\n const anchors = new Set<string>()\n let pendingUserMessageId: string | null = null\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n\n if (messageHasCompress(message)) {\n break\n }\n\n if (message.info.role === \"user\") {\n if (!isIgnoredUserMessage(message)) {\n pendingUserMessageId = message.info.id\n }\n continue\n }\n\n if (message.info.role === \"assistant\" && pendingUserMessageId) {\n anchors.add(message.info.id)\n anchors.add(pendingUserMessageId)\n pendingUserMessageId = null\n }\n }\n\n return anchors\n}\n\nexport function getActiveSummaryTokenUsage(state: SessionState): number {\n let total = 0\n for (const blockId of state.prune.messages.activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block || !block.active) {\n continue\n }\n total += block.summaryTokens\n }\n return total\n}\n\nexport function resetOnCompaction(state: SessionState): void {\n state.toolParameters.clear()\n state.prune.tools = new Map<string, number>()\n state.prune.messages = createPruneMessagesState()\n state.messageIds = {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\n }\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n }\n}\n","import type { SessionState } 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 applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\n}\n","import type { SessionState, ToolStatus, WithParts } from \"./index\"\nimport type { Logger } from \"../logger\"\nimport { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"./utils\"\nimport { countToolTokens } from \"../token-utils\"\n\nconst MAX_TOOL_CACHE_SIZE = 1000\n\n/**\n * Sync tool parameters from session messages.\n */\nexport function syncToolCache(\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n): void {\n try {\n logger.info(\"Syncing tool parameters from OpenCode messages\")\n\n let turnCounter = 0\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCounter++\n continue\n }\n\n if (part.type !== \"tool\" || !part.callID) {\n continue\n }\n\n const turnProtectionEnabled = config.turnProtection.enabled\n const turnProtectionTurns = config.turnProtection.turns\n const isProtectedByTurn =\n turnProtectionEnabled &&\n turnProtectionTurns > 0 &&\n state.currentTurn - turnCounter < turnProtectionTurns\n\n if (state.toolParameters.has(part.callID)) {\n continue\n }\n\n if (isProtectedByTurn) {\n continue\n }\n\n const tokenCount = countToolTokens(part)\n\n state.toolParameters.set(part.callID, {\n tool: part.tool,\n parameters: part.state?.input ?? {},\n status: part.state.status as ToolStatus | undefined,\n error: part.state.status === \"error\" ? part.state.error : undefined,\n turn: turnCounter,\n tokenCount,\n })\n logger.info(\n `Cached tool id: ${part.callID} (turn ${turnCounter}${tokenCount !== undefined ? `, ${tokenCount} tokens` : \"\"})`,\n )\n }\n }\n\n logger.info(\n `Synced cache - size: ${state.toolParameters.size}, currentTurn: ${state.currentTurn}`,\n )\n trimToolParametersCache(state)\n } catch (error) {\n logger.warn(\"Failed to sync tool parameters from OpenCode\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/**\n * Trim the tool parameters cache to prevent unbounded memory growth.\n * Uses FIFO eviction - removes oldest entries first.\n */\nexport function trimToolParametersCache(state: SessionState): void {\n if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {\n return\n }\n\n const keysToRemove = Array.from(state.toolParameters.keys()).slice(\n 0,\n state.toolParameters.size - MAX_TOOL_CACHE_SIZE,\n )\n\n for (const key of keysToRemove) {\n state.toolParameters.delete(key)\n }\n}\n","function normalizePath(input: string): string {\n return input.replaceAll(\"\\\\\\\\\", \"/\")\n}\n\nfunction escapeRegExpChar(ch: string): string {\n return /[\\\\.^$+{}()|\\[\\]]/.test(ch) ? `\\\\${ch}` : ch\n}\n\nexport function matchesGlob(inputPath: string, pattern: string): boolean {\n if (!pattern) return false\n\n const input = normalizePath(inputPath)\n const pat = normalizePath(pattern)\n\n let regex = \"^\"\n\n for (let i = 0; i < pat.length; i++) {\n const ch = pat[i]\n\n if (ch === \"*\") {\n const next = pat[i + 1]\n if (next === \"*\") {\n const after = pat[i + 2]\n if (after === \"/\") {\n // **/ (zero or more directories)\n regex += \"(?:.*/)?\"\n i += 2\n continue\n }\n\n // **\n regex += \".*\"\n i++\n continue\n }\n\n // *\n regex += \"[^/]*\"\n continue\n }\n\n if (ch === \"?\") {\n regex += \"[^/]\"\n continue\n }\n\n if (ch === \"/\") {\n regex += \"/\"\n continue\n }\n\n regex += escapeRegExpChar(ch)\n }\n\n regex += \"$\"\n\n return new RegExp(regex).test(input)\n}\n\nexport function getFilePathsFromParameters(tool: string, parameters: unknown): string[] {\n if (typeof parameters !== \"object\" || parameters === null) {\n return []\n }\n\n const paths: string[] = []\n const params = parameters as Record<string, any>\n\n // 1. apply_patch uses patchText with embedded paths\n if (tool === \"apply_patch\" && typeof params.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n let match\n while ((match = pathRegex.exec(params.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n }\n\n // 2. multiedit uses top-level filePath and nested edits array\n if (tool === \"multiedit\") {\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n if (Array.isArray(params.edits)) {\n for (const edit of params.edits) {\n if (edit && typeof edit.filePath === \"string\") {\n paths.push(edit.filePath)\n }\n }\n }\n }\n\n // 3. Default check for common filePath parameter (read, write, edit, etc)\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n\n // Return unique non-empty paths\n return [...new Set(paths)].filter((p) => p.length > 0)\n}\n\nexport function isFilePathProtected(filePaths: string[], patterns: string[]): boolean {\n if (!filePaths || filePaths.length === 0) return false\n if (!patterns || patterns.length === 0) return false\n\n return filePaths.some((path) => patterns.some((pattern) => matchesGlob(path, pattern)))\n}\n\nconst GLOB_CHARS = /[*?]/\n\nexport function isToolNameProtected(toolName: string, patterns: string[]): boolean {\n if (!toolName || !patterns || patterns.length === 0) return false\n\n const exactPatterns: Set<string> = new Set()\n const globPatterns: string[] = []\n\n for (const pattern of patterns) {\n if (GLOB_CHARS.test(pattern)) {\n globPatterns.push(pattern)\n } else {\n exactPatterns.add(pattern)\n }\n }\n\n if (exactPatterns.has(toolName)) {\n return true\n }\n\n return globPatterns.some((pattern) => matchesGlob(toolName, pattern))\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Deduplication strategy - prunes older tool calls that have identical\n * tool name and parameters, keeping only the most recent occurrence.\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const deduplicate = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.deduplication.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.deduplication.protectedTools\n\n // Group by signature (tool name + normalized parameters)\n const signatureMap = new Map<string, string[]>()\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n // logger.warn(`Missing metadata for tool call ID: ${id}`)\n continue\n }\n\n // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n continue\n }\n\n const signature = createToolSignature(metadata.tool, metadata.parameters)\n if (!signatureMap.has(signature)) {\n signatureMap.set(signature, [])\n }\n const ids = signatureMap.get(signature)\n if (ids) {\n ids.push(id)\n }\n }\n\n // Find duplicates - keep only the most recent (last) in each group\n const newPruneIds: string[] = []\n\n for (const [, ids] of signatureMap.entries()) {\n if (ids.length > 1) {\n // All except last (most recent) should be pruned\n const idsToRemove = ids.slice(0, -1)\n newPruneIds.push(...idsToRemove)\n }\n }\n\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n\n if (newPruneIds.length > 0) {\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(`Marked ${newPruneIds.length} duplicate tool calls for pruning`)\n }\n}\n\nfunction createToolSignature(tool: string, parameters?: any): string {\n if (!parameters) {\n return tool\n }\n const normalized = normalizeParameters(parameters)\n const sorted = sortObjectKeys(normalized)\n return `${tool}::${JSON.stringify(sorted)}`\n}\n\nfunction normalizeParameters(params: any): any {\n if (typeof params !== \"object\" || params === null) return params\n if (Array.isArray(params)) return params\n\n const normalized: any = {}\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n normalized[key] = value\n }\n }\n return normalized\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj !== \"object\" || obj === null) return obj\n if (Array.isArray(obj)) return obj.map(sortObjectKeys)\n\n const sorted: any = {}\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortObjectKeys(obj[key])\n }\n return sorted\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Purge Errors strategy - prunes tool inputs for tools that errored\n * after they are older than a configurable number of turns.\n * The error message is preserved, but the (potentially large) inputs\n * are removed to save context.\n *\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const purgeErrors = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.purgeErrors.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.purgeErrors.protectedTools\n const turnThreshold = Math.max(1, config.strategies.purgeErrors.turns)\n\n const newPruneIds: string[] = []\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n continue\n }\n\n // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n continue\n }\n\n // Only process error tools\n if (metadata.status !== \"error\") {\n continue\n }\n\n // Check if the tool is old enough to prune\n const turnAge = state.currentTurn - metadata.turn\n if (turnAge >= turnThreshold) {\n newPruneIds.push(id)\n }\n }\n\n if (newPruneIds.length > 0) {\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(\n `Marked ${newPruneIds.length} error tool calls for pruning (older than ${turnThreshold} turns)`,\n )\n }\n}\n","import { SessionState, ToolParameterEntry, WithParts } from \"../state\"\nimport { countTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nfunction extractParameterKey(tool: string, parameters: any): string {\n if (!parameters) return \"\"\n\n if (tool === \"read\" && parameters.filePath) {\n const offset = parameters.offset\n const limit = parameters.limit\n if (offset !== undefined && limit !== undefined) {\n return `${parameters.filePath} (lines ${offset}-${offset + limit})`\n }\n if (offset !== undefined) {\n return `${parameters.filePath} (lines ${offset}+)`\n }\n if (limit !== undefined) {\n return `${parameters.filePath} (lines 0-${limit})`\n }\n return parameters.filePath\n }\n\n if ((tool === \"write\" || tool === \"edit\" || tool === \"multiedit\") && parameters.filePath) {\n return parameters.filePath\n }\n\n if (tool === \"apply_patch\" && typeof parameters.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n const paths: string[] = []\n let match\n while ((match = pathRegex.exec(parameters.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n if (paths.length > 0) {\n const uniquePaths = [...new Set(paths)]\n const count = uniquePaths.length\n const plural = count > 1 ? \"s\" : \"\"\n if (count === 1) return uniquePaths[0]\n if (count === 2) return uniquePaths.join(\", \")\n return `${count} file${plural}: ${uniquePaths[0]}, ${uniquePaths[1]}...`\n }\n return \"patch\"\n }\n\n if (tool === \"list\") {\n return parameters.path || \"(current directory)\"\n }\n\n if (tool === \"glob\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"grep\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"bash\") {\n if (parameters.description) return parameters.description\n if (parameters.command) {\n return parameters.command.length > 50\n ? parameters.command.substring(0, 50) + \"...\"\n : parameters.command\n }\n }\n\n if (tool === \"webfetch\" && parameters.url) {\n return parameters.url\n }\n if (tool === \"websearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n if (tool === \"codesearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n\n if (tool === \"todowrite\") {\n return `${parameters.todos?.length || 0} todos`\n }\n if (tool === \"todoread\") {\n return \"read todo list\"\n }\n\n if (tool === \"task\" && parameters.description) {\n return parameters.description\n }\n if (tool === \"skill\" && parameters.name) {\n return parameters.name\n }\n\n if (tool === \"lsp\") {\n const op = parameters.operation || \"lsp\"\n const path = parameters.filePath || \"\"\n const line = parameters.line\n const char = parameters.character\n if (path && line !== undefined && char !== undefined) {\n return `${op} ${path}:${line}:${char}`\n }\n if (path) {\n return `${op} ${path}`\n }\n return op\n }\n\n if (tool === \"question\") {\n const questions = parameters.questions\n if (Array.isArray(questions) && questions.length > 0) {\n const headers = questions\n .map((q: any) => q.header || \"\")\n .filter(Boolean)\n .slice(0, 3)\n\n const count = questions.length\n const plural = count > 1 ? \"s\" : \"\"\n\n if (headers.length > 0) {\n const suffix = count > 3 ? ` (+${count - 3} more)` : \"\"\n return `${count} question${plural}: ${headers.join(\", \")}${suffix}`\n }\n return `${count} question${plural}`\n }\n return \"question\"\n }\n\n const paramStr = JSON.stringify(parameters)\n if (paramStr === \"{}\" || paramStr === \"[]\" || paramStr === \"null\") {\n return \"\"\n }\n\n return paramStr.substring(0, 50)\n}\n\nexport function formatStatsHeader(totalTokensSaved: number, pruneTokenCounter: number): string {\n const totalTokensSavedStr = `~${formatTokenCount(totalTokensSaved + pruneTokenCounter)}`\n return [`▣ DCP | ${totalTokensSavedStr} saved total`].join(\"\\n\")\n}\n\nexport function formatTokenCount(tokens: number, compact?: boolean): string {\n const suffix = compact ? \"\" : \" tokens\"\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}K`.replace(\".0K\", \"K\") + suffix\n }\n return tokens.toString() + suffix\n}\n\nexport function truncate(str: string, maxLen: number = 60): string {\n if (str.length <= maxLen) return str\n return str.slice(0, maxLen - 3) + \"...\"\n}\n\nexport function formatProgressBar(\n messageIds: string[],\n prunedMessages: Map<string, number>,\n recentMessageIds: string[],\n width: number = 50,\n): string {\n const ACTIVE = \"█\"\n const PRUNED = \"░\"\n const RECENT = \"⣿\"\n const recentSet = new Set(recentMessageIds)\n\n const total = messageIds.length\n if (total === 0) return `│${PRUNED.repeat(width)}│`\n\n const bar = new Array(width).fill(ACTIVE)\n\n for (let m = 0; m < total; m++) {\n const msgId = messageIds[m]\n const start = Math.floor((m / total) * width)\n const end = Math.floor(((m + 1) / total) * width)\n\n if (recentSet.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = RECENT\n }\n } else if (prunedMessages.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = PRUNED\n }\n }\n }\n\n return `│${bar.join(\"\")}│`\n}\n\nexport function cacheSystemPromptTokens(state: SessionState, messages: WithParts[]): void {\n let firstInputTokens = 0\n for (const msg of messages) {\n if (msg.info.role !== \"assistant\") {\n continue\n }\n const info = msg.info as any\n const input = info?.tokens?.input || 0\n const cacheRead = info?.tokens?.cache?.read || 0\n const cacheWrite = info?.tokens?.cache?.write || 0\n if (input > 0 || cacheRead > 0 || cacheWrite > 0) {\n firstInputTokens = input + cacheRead + cacheWrite\n break\n }\n }\n\n if (firstInputTokens <= 0) {\n state.systemPromptTokens = undefined\n return\n }\n\n let firstUserText = \"\"\n for (const msg of messages) {\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && !(part as any).ignored) {\n firstUserText += part.text\n }\n }\n break\n }\n\n const estimatedSystemTokens = Math.max(0, firstInputTokens - countTokens(firstUserText))\n state.systemPromptTokens = estimatedSystemTokens > 0 ? estimatedSystemTokens : undefined\n}\n\nexport function shortenPath(input: string, workingDirectory?: string): string {\n const inPathMatch = input.match(/^(.+) in (.+)$/)\n if (inPathMatch) {\n const prefix = inPathMatch[1]\n const pathPart = inPathMatch[2]\n const shortenedPath = shortenSinglePath(pathPart, workingDirectory)\n return `${prefix} in ${shortenedPath}`\n }\n\n return shortenSinglePath(input, workingDirectory)\n}\n\nfunction shortenSinglePath(path: string, workingDirectory?: string): string {\n if (workingDirectory) {\n if (path.startsWith(workingDirectory + \"/\")) {\n return path.slice(workingDirectory.length + 1)\n }\n if (path === workingDirectory) {\n return \".\"\n }\n }\n\n return path\n}\n\nexport function formatPrunedItemsList(\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string[] {\n const lines: string[] = []\n\n for (const id of pruneToolIds) {\n const metadata = toolMetadata.get(id)\n\n if (metadata) {\n const paramKey = extractParameterKey(metadata.tool, metadata.parameters)\n if (paramKey) {\n // Use 60 char limit to match notification style\n const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60)\n lines.push(`→ ${metadata.tool}: ${displayKey}`)\n } else {\n lines.push(`→ ${metadata.tool}`)\n }\n }\n }\n\n const knownCount = pruneToolIds.filter((id) => toolMetadata.has(id)).length\n const unknownCount = pruneToolIds.length - knownCount\n\n if (unknownCount > 0) {\n lines.push(`→ (${unknownCount} tool${unknownCount > 1 ? \"s\" : \"\"} with unknown metadata)`)\n }\n\n return lines\n}\n\nexport function formatPruningResultForTool(\n prunedIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string {\n const lines: string[] = []\n lines.push(`Context pruning complete. Pruned ${prunedIds.length} tool outputs.`)\n lines.push(\"\")\n\n if (prunedIds.length > 0) {\n lines.push(`Semantically pruned (${prunedIds.length}):`)\n lines.push(...formatPrunedItemsList(prunedIds, toolMetadata, workingDirectory))\n }\n\n return lines.join(\"\\n\").trim()\n}\n","import type { Logger } from \"../logger\"\nimport type { SessionState } from \"../state\"\nimport {\n formatPrunedItemsList,\n formatProgressBar,\n formatStatsHeader,\n formatTokenCount,\n} from \"./utils\"\nimport { ToolParameterEntry } from \"../state\"\nimport { PluginConfig } from \"../config\"\nimport { getActiveSummaryTokenUsage } from \"../state/utils\"\n\nexport type PruneReason = \"completion\" | \"noise\" | \"extraction\"\nexport const PRUNE_REASON_LABELS: Record<PruneReason, string> = {\n completion: \"Task Complete\",\n noise: \"Noise Removal\",\n extraction: \"Extraction\",\n}\n\ninterface CompressionNotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nfunction buildMinimalMessage(state: SessionState, reason: PruneReason | undefined): string {\n const reasonSuffix = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n return (\n formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter) +\n reasonSuffix\n )\n}\n\nfunction buildDetailedMessage(\n state: SessionState,\n reason: PruneReason | undefined,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory: string,\n): string {\n let message = formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter)\n\n if (pruneToolIds.length > 0) {\n const pruneTokenCounterStr = `~${formatTokenCount(state.stats.pruneTokenCounter)}`\n const reasonLabel = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n message += `\\n\\n▣ Pruning (${pruneTokenCounterStr})${reasonLabel}`\n\n const itemLines = formatPrunedItemsList(pruneToolIds, toolMetadata, workingDirectory)\n message += \"\\n\" + itemLines.join(\"\\n\")\n }\n\n return message.trim()\n}\n\nconst TOAST_BODY_MAX_LINES = 12\nconst TOAST_SUMMARY_MAX_CHARS = 600\n\nfunction truncateToastBody(body: string, maxLines: number = TOAST_BODY_MAX_LINES): string {\n const lines = body.split(\"\\n\")\n if (lines.length <= maxLines) {\n return body\n }\n const kept = lines.slice(0, maxLines - 1)\n const remaining = lines.length - maxLines + 1\n return kept.join(\"\\n\") + `\\n... and ${remaining} more`\n}\n\nfunction truncateToastSummary(summary: string, maxChars: number = TOAST_SUMMARY_MAX_CHARS): string {\n if (summary.length <= maxChars) {\n return summary\n }\n return summary.slice(0, maxChars - 3) + \"...\"\n}\n\nfunction truncateExtractedSection(\n message: string,\n maxChars: number = TOAST_SUMMARY_MAX_CHARS,\n): string {\n const marker = \"\\n\\n▣ Extracted\"\n const index = message.indexOf(marker)\n if (index === -1) {\n return message\n }\n const extracted = message.slice(index)\n if (extracted.length <= maxChars) {\n return message\n }\n return message.slice(0, index) + truncateToastSummary(extracted, maxChars)\n}\n\nexport async function sendUnifiedNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n reason: PruneReason | undefined,\n params: any,\n workingDirectory: string,\n): Promise<boolean> {\n const hasPruned = pruneToolIds.length > 0\n if (!hasPruned) {\n return false\n }\n\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n const message =\n config.pruneNotification === \"minimal\"\n ? buildMinimalMessage(state, reason)\n : buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory)\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = truncateExtractedSection(message)\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nfunction buildCompressionSummary(\n entries: CompressionNotificationEntry[],\n state: SessionState,\n): string {\n if (entries.length === 1) {\n return entries[0]?.summary ?? \"\"\n }\n\n return entries\n .map((entry) => {\n const topic =\n state.prune.messages.blocksById.get(entry.blockId)?.topic ?? \"(unknown topic)\"\n return `### ${topic}\\n${entry.summary}`\n })\n .join(\"\\n\\n\")\n}\n\nfunction getCompressionLabel(entries: CompressionNotificationEntry[]): string {\n const runId = entries[0]?.runId\n if (runId === undefined) {\n return \"Compression\"\n }\n\n return `Compression #${runId}`\n}\n\nfunction formatCompressionMetrics(removedTokens: number, summaryTokens: number): string {\n const metrics = [`-${formatTokenCount(removedTokens, true)} removed`]\n if (summaryTokens > 0) {\n metrics.push(`+${formatTokenCount(summaryTokens, true)} summary`)\n }\n return metrics.join(\", \")\n}\n\nexport async function sendCompressNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n entries: CompressionNotificationEntry[],\n batchTopic: string | undefined,\n sessionMessageIds: string[],\n params: any,\n): Promise<boolean> {\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n if (entries.length === 0) {\n return false\n }\n\n let message: string\n const compressionLabel = getCompressionLabel(entries)\n const summary = buildCompressionSummary(entries, state)\n const summaryTokens = entries.reduce((total, entry) => total + entry.summaryTokens, 0)\n const summaryTokensStr = formatTokenCount(summaryTokens)\n const compressedTokens = entries.reduce((total, entry) => {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n logger.error(\"Compression block missing for notification\", {\n compressionId: entry.blockId,\n sessionId,\n })\n return total\n }\n\n return total + compressionBlock.compressedTokens\n }, 0)\n\n const newlyCompressedMessageIds: string[] = []\n const newlyCompressedToolIds: string[] = []\n const seenMessageIds = new Set<string>()\n const seenToolIds = new Set<string>()\n\n for (const entry of entries) {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n continue\n }\n\n for (const messageId of compressionBlock.directMessageIds) {\n if (seenMessageIds.has(messageId)) {\n continue\n }\n seenMessageIds.add(messageId)\n newlyCompressedMessageIds.push(messageId)\n }\n\n for (const toolId of compressionBlock.directToolIds) {\n if (seenToolIds.has(toolId)) {\n continue\n }\n seenToolIds.add(toolId)\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n const topic =\n batchTopic ??\n (entries.length === 1\n ? (state.prune.messages.blocksById.get(entries[0]?.blockId ?? -1)?.topic ??\n \"(unknown topic)\")\n : \"(unknown topic)\")\n\n const totalActiveSummaryTkns = getActiveSummaryTokenUsage(state)\n const totalGross = state.stats.totalPruneTokens + state.stats.pruneTokenCounter\n const notificationHeader = `▣ DCP | ${formatCompressionMetrics(totalGross, totalActiveSummaryTkns)}`\n\n if (config.pruneNotification === \"minimal\") {\n message = `${notificationHeader} — ${compressionLabel}`\n } else {\n message = notificationHeader\n\n const activePrunedMessages = new Map<string, number>()\n for (const [messageId, entry] of state.prune.messages.byMessageId) {\n if (entry.activeBlockIds.length > 0) {\n activePrunedMessages.set(messageId, entry.tokenCount)\n }\n }\n const progressBar = formatProgressBar(\n sessionMessageIds,\n activePrunedMessages,\n newlyCompressedMessageIds,\n 50,\n )\n message += `\\n\\n${progressBar}`\n message += `\\n▣ ${compressionLabel} ${formatCompressionMetrics(compressedTokens, summaryTokens)}`\n message += `\\n→ Topic: ${topic}`\n message += `\\n→ Items: ${newlyCompressedMessageIds.length} messages`\n if (newlyCompressedToolIds.length > 0) {\n message += ` and ${newlyCompressedToolIds.length} tools compressed`\n } else {\n message += ` compressed`\n }\n if (config.compress.showCompression) {\n message += `\\n→ Compression (~${summaryTokensStr}): ${summary}`\n }\n }\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = message\n if (config.compress.showCompression) {\n const truncatedSummary = truncateToastSummary(summary)\n if (truncatedSummary !== summary) {\n toastMessage = toastMessage.replace(\n `\\n→ Compression (~${summaryTokensStr}): ${summary}`,\n `\\n→ Compression (~${summaryTokensStr}): ${truncatedSummary}`,\n )\n }\n }\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nexport async function sendIgnoredMessage(\n client: any,\n sessionID: string,\n text: string,\n params: any,\n logger: Logger,\n): Promise<void> {\n const agent = params.agent || undefined\n const variant = params.variant || undefined\n const model =\n params.providerId && params.modelId\n ? {\n providerID: params.providerId,\n modelID: params.modelId,\n }\n : undefined\n\n try {\n await client.session.prompt({\n path: {\n id: sessionID,\n },\n body: {\n noReply: true,\n agent: agent,\n model: model,\n variant: variant,\n parts: [\n {\n type: \"text\",\n text: text,\n ignored: true,\n },\n ],\n },\n })\n } catch (error: any) {\n logger.error(\"Failed to send notification\", { error: error.message })\n }\n}\n","import type { WithParts } from \"../state\"\nimport { ensureSessionInitialized } from \"../state\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { assignMessageRefs } from \"../message-ids\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { deduplicate, purgeErrors } from \"../strategies\"\nimport { getCurrentParams, getCurrentTokenUsage } from \"../token-utils\"\nimport { sendCompressNotification } from \"../ui/notification\"\nimport type { ToolContext } from \"./types\"\nimport { buildSearchContext, fetchSessionMessages } from \"./search\"\nimport type { SearchContext } from \"./types\"\nimport { applyPendingCompressionDurations } from \"./timing\"\n\ninterface RunContext {\n ask(input: {\n permission: string\n patterns: string[]\n always: string[]\n metadata: Record<string, unknown>\n }): Promise<void>\n metadata(input: { title: string }): void\n sessionID: string\n}\n\nexport interface NotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nexport interface PreparedSession {\n rawMessages: WithParts[]\n searchContext: SearchContext\n}\n\nexport async function prepareSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n title: string,\n): Promise<PreparedSession> {\n if (ctx.state.manualMode && ctx.state.manualMode !== \"compress-pending\") {\n throw new Error(\n \"Manual mode: compress blocked. Do not retry until `<compress triggered manually>` appears in user context.\",\n )\n }\n\n await toolCtx.ask({\n permission: \"compress\",\n patterns: [\"*\"],\n always: [\"*\"],\n metadata: {},\n })\n\n toolCtx.metadata({ title })\n\n const rawMessages = await fetchSessionMessages(ctx.client, toolCtx.sessionID)\n\n await ensureSessionInitialized(\n ctx.client,\n ctx.state,\n toolCtx.sessionID,\n ctx.logger,\n rawMessages,\n ctx.config.manualMode.enabled,\n )\n\n assignMessageRefs(ctx.state, rawMessages)\n\n deduplicate(ctx.state, ctx.logger, ctx.config, rawMessages)\n purgeErrors(ctx.state, ctx.logger, ctx.config, rawMessages)\n\n return {\n rawMessages,\n searchContext: buildSearchContext(ctx.state, rawMessages),\n }\n}\n\nexport async function finalizeSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n rawMessages: WithParts[],\n entries: NotificationEntry[],\n batchTopic: string | undefined,\n): Promise<void> {\n ctx.state.manualMode = ctx.state.manualMode ? \"active\" : false\n applyPendingCompressionDurations(ctx.state)\n await saveSessionState(ctx.state, ctx.logger)\n\n const params = getCurrentParams(ctx.state, rawMessages, ctx.logger)\n const sessionMessageIds = rawMessages\n .filter((msg) => !isIgnoredUserMessage(msg))\n .map((msg) => msg.info.id)\n\n await sendCompressNotification(\n ctx.client,\n ctx.logger,\n ctx.config,\n ctx.state,\n toolCtx.sessionID,\n entries,\n batchTopic,\n sessionMessageIds,\n params,\n )\n}\n","import type { WithParts } from \"../state\"\n\nconst SUB_AGENT_RESULT_BLOCK_REGEX = /(<task_result>\\s*)([\\s\\S]*?)(\\s*<\\/task_result>)/i\n\nexport function getSubAgentId(part: any): string | null {\n const sessionId = part?.state?.metadata?.sessionId\n if (typeof sessionId !== \"string\") {\n return null\n }\n\n const value = sessionId.trim()\n return value.length > 0 ? value : null\n}\n\nexport function buildSubagentResultText(messages: WithParts[]): string {\n const assistantMessages = messages.filter((message) => message.info.role === \"assistant\")\n if (assistantMessages.length === 0) {\n return \"\"\n }\n\n const lastAssistant = assistantMessages[assistantMessages.length - 1]\n const lastText = getLastTextPart(lastAssistant)\n\n if (assistantMessages.length < 2) {\n return lastText\n }\n\n const secondToLastAssistant = assistantMessages[assistantMessages.length - 2]\n if (!assistantMessageHasCompressTool(secondToLastAssistant)) {\n return lastText\n }\n\n const secondToLastText = getLastTextPart(secondToLastAssistant)\n return [secondToLastText, lastText].filter((text) => text.length > 0).join(\"\\n\\n\")\n}\n\nexport function mergeSubagentResult(output: string, subAgentResultText: string): string {\n if (!subAgentResultText || typeof output !== \"string\") {\n return output\n }\n\n return output.replace(\n SUB_AGENT_RESULT_BLOCK_REGEX,\n (_match, openTag: string, _body: string, closeTag: string) =>\n `${openTag}${subAgentResultText}${closeTag}`,\n )\n}\n\nfunction getLastTextPart(message: WithParts): string {\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (let index = parts.length - 1; index >= 0; index--) {\n const part = parts[index]\n if (part.type !== \"text\" || typeof part.text !== \"string\") {\n continue\n }\n\n const text = part.text.trim()\n if (!text) {\n continue\n }\n\n return text\n }\n\n return \"\"\n}\n\nfunction assistantMessageHasCompressTool(message: WithParts): boolean {\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n","import type { SessionState } from \"../state\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../subagents/subagent-results\"\nimport { fetchSessionMessages } from \"./search\"\nimport type { SearchContext, SelectionResolution } from \"./types\"\n\nexport function appendProtectedUserMessages(\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n state: SessionState,\n enabled: boolean,\n): string {\n if (!enabled) return summary\n\n const userTexts: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n if (message.info.role !== \"user\") continue\n if (isIgnoredUserMessage(message)) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && typeof part.text === \"string\" && part.text.trim()) {\n userTexts.push(part.text)\n break\n }\n }\n }\n\n if (userTexts.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following user messages were sent in this conversation verbatim:\"\n const body = userTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\n\nexport 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 { appendProtectedTools, appendProtectedUserMessages } 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 const missingBlockIds = validateSummaryPlaceholders(\n parsedPlaceholders,\n plan.selection.requiredBlockIds,\n plan.selection.startReference,\n plan.selection.endReference,\n searchContext.summaryByBlockId,\n )\n\n const injected = injectBlockPlaceholders(\n plan.entry.summary,\n parsedPlaceholders,\n searchContext.summaryByBlockId,\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n const summaryWithUsers = appendProtectedUserMessages(\n injected.expandedSummary,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectUserMessages,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n summaryWithUsers,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n const completedSummary = appendMissingBlockSummaries(\n summaryWithTools,\n missingBlockIds,\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: completedSummary.consumedBlockIds,\n })\n }\n\n const runId = allocateRunId(ctx.state)\n\n for (const preparedPlan of preparedPlans) {\n const blockId = allocateBlockId(ctx.state)\n const storedSummary = wrapCompressedSummary(blockId, preparedPlan.finalSummary)\n const summaryTokens = countTokens(storedSummary)\n\n const applied = applyCompressionState(\n ctx.state,\n {\n topic: input.topic,\n batchTopic: input.topic,\n startId: preparedPlan.entry.startId,\n endId: preparedPlan.entry.endId,\n mode: \"range\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n preparedPlan.selection,\n preparedPlan.anchorMessageId,\n blockId,\n storedSummary,\n preparedPlan.consumedBlockIds,\n )\n\n totalCompressedMessages += applied.messageIds.length\n\n notifications.push({\n blockId,\n runId,\n summary: preparedPlan.finalSummary,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return `Compressed ${totalCompressedMessages} messages into ${COMPRESSED_BLOCK_HEADER}.`\n },\n })\n}\n","import type { CompressionBlock, SessionState } from \"../state\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport type {\n BoundaryReference,\n CompressRangeToolArgs,\n InjectedSummaryResult,\n ParsedBlockPlaceholder,\n ResolvedRangeCompression,\n SearchContext,\n} from \"./types\"\n\nconst BLOCK_PLACEHOLDER_REGEX = /\\(b(\\d+)\\)|\\{block_(\\d+)\\}/gi\n\nexport function validateArgs(args: CompressRangeToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.startId !== \"string\" || entry.startId.trim().length === 0) {\n throw new Error(`${prefix}.startId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.endId !== \"string\" || entry.endId.trim().length === 0) {\n throw new Error(`${prefix}.endId is required and must be a non-empty string`)\n }\n\n if (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 let cursor = 0\n let expanded = summary\n const consumed: number[] = []\n const consumedSeen = new Set<number>()\n\n if (placeholders.length > 0) {\n expanded = \"\"\n for (const placeholder of placeholders) {\n const target = summaryByBlockId.get(placeholder.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${placeholder.blockId})`)\n }\n\n expanded += summary.slice(cursor, placeholder.startIndex)\n expanded += restoreSummary(target.summary)\n cursor = placeholder.endIndex\n\n if (!consumedSeen.has(placeholder.blockId)) {\n consumedSeen.add(placeholder.blockId)\n consumed.push(placeholder.blockId)\n }\n }\n\n expanded += summary.slice(cursor)\n }\n\n expanded = injectBoundarySummary(\n expanded,\n startReference,\n \"start\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n expanded = injectBoundarySummary(\n expanded,\n endReference,\n \"end\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n\n return {\n expandedSummary: expanded,\n consumedBlockIds: consumed,\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n missingBlockIds: number[],\n summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n const consumedSeen = new Set<number>(consumedBlockIds)\n const consumed = [...consumedBlockIds]\n\n const missingSummaries: string[] = []\n for (const blockId of missingBlockIds) {\n if (consumedSeen.has(blockId)) {\n continue\n }\n\n const target = summaryByBlockId.get(blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${blockId})`)\n }\n\n missingSummaries.push(`\\n### (b${blockId})\\n${restoreSummary(target.summary)}`)\n consumedSeen.add(blockId)\n consumed.push(blockId)\n }\n\n if (missingSummaries.length === 0) {\n return {\n expandedSummary: summary,\n consumedBlockIds: consumed,\n }\n }\n\n const heading =\n \"\\n\\nThe following previously compressed summaries were also part of this conversation section:\"\n\n return {\n expandedSummary: summary + heading + missingSummaries.join(\"\"),\n consumedBlockIds: consumed,\n }\n}\n\nfunction restoreSummary(summary: string): string {\n const headerMatch = summary.match(/^\\s*\\[Compressed conversation(?: section)?(?: b\\d+)?\\]/i)\n if (!headerMatch) {\n return summary\n }\n\n const afterHeader = summary.slice(headerMatch[0].length)\n const withoutLeadingBreaks = afterHeader.replace(/^(?:\\r?\\n)+/, \"\")\n return withoutLeadingBreaks\n .replace(/(?:\\r?\\n)*<dcp-message-id>b\\d+<\\/dcp-message-id>\\s*$/i, \"\")\n .replace(/(?:\\r?\\n)+$/, \"\")\n}\n\nfunction injectBoundarySummary(\n summary: string,\n reference: BoundaryReference,\n position: \"start\" | \"end\",\n summaryByBlockId: Map<number, CompressionBlock>,\n consumed: number[],\n consumedSeen: Set<number>,\n): string {\n if (reference.kind !== \"compressed-block\" || reference.blockId === undefined) {\n return summary\n }\n if (consumedSeen.has(reference.blockId)) {\n return summary\n }\n\n const target = summaryByBlockId.get(reference.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${reference.blockId})`)\n }\n\n const injectedBody = restoreSummary(target.summary)\n const left = position === \"start\" ? injectedBody.trim() : summary.trim()\n const right = position === \"start\" ? summary.trim() : injectedBody.trim()\n const next = !left ? right : !right ? left : `${left}\\n\\n${right}`\n\n consumedSeen.add(reference.blockId)\n consumed.push(reference.blockId)\n return next\n}\n","export type PermissionAction = \"ask\" | \"allow\" | \"deny\"\n\nexport type PermissionValue = PermissionAction | Record<string, PermissionAction>\n\nexport type PermissionConfig = Record<string, PermissionValue> | undefined\n\nexport interface HostPermissionSnapshot {\n global: PermissionConfig\n agents: Record<string, PermissionConfig>\n}\n\ntype PermissionRule = {\n permission: string\n pattern: string\n action: PermissionAction\n}\n\nconst findLastMatchingRule = (\n rules: PermissionRule[],\n predicate: (rule: PermissionRule) => boolean,\n): PermissionRule | undefined => {\n for (let index = rules.length - 1; index >= 0; index -= 1) {\n const rule = rules[index]\n if (rule && predicate(rule)) {\n return rule\n }\n }\n\n return undefined\n}\n\nconst wildcardMatch = (value: string, pattern: string): boolean => {\n const normalizedValue = value.replaceAll(\"\\\\\", \"/\")\n let escaped = pattern\n .replaceAll(\"\\\\\", \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")\n\n if (escaped.endsWith(\" .*\")) {\n escaped = escaped.slice(0, -3) + \"( .*)?\"\n }\n\n const flags = process.platform === \"win32\" ? \"si\" : \"s\"\n return new RegExp(`^${escaped}$`, flags).test(normalizedValue)\n}\n\nconst getPermissionRules = (permissionConfigs: PermissionConfig[]): PermissionRule[] => {\n const rules: PermissionRule[] = []\n for (const permissionConfig of permissionConfigs) {\n if (!permissionConfig) {\n continue\n }\n\n for (const [permission, value] of Object.entries(permissionConfig)) {\n if (value === \"ask\" || value === \"allow\" || value === \"deny\") {\n rules.push({ permission, pattern: \"*\", action: value })\n continue\n }\n\n for (const [pattern, action] of Object.entries(value)) {\n if (action === \"ask\" || action === \"allow\" || action === \"deny\") {\n rules.push({ permission, pattern, action })\n }\n }\n }\n }\n return rules\n}\n\nexport const compressDisabledByOpencode = (...permissionConfigs: PermissionConfig[]): boolean => {\n const match = findLastMatchingRule(getPermissionRules(permissionConfigs), (rule) =>\n wildcardMatch(\"compress\", rule.permission),\n )\n\n return match?.pattern === \"*\" && match.action === \"deny\"\n}\n\nexport const resolveEffectiveCompressPermission = (\n basePermission: PermissionAction,\n hostPermissions: HostPermissionSnapshot,\n agentName?: string,\n): PermissionAction => {\n if (basePermission === \"deny\") {\n return \"deny\"\n }\n\n return compressDisabledByOpencode(\n hostPermissions.global,\n agentName ? hostPermissions.agents[agentName] : undefined,\n )\n ? \"deny\"\n : basePermission\n}\n\nexport const hasExplicitToolPermission = (\n permissionConfig: PermissionConfig,\n tool: string,\n): boolean => {\n return permissionConfig ? Object.prototype.hasOwnProperty.call(permissionConfig, tool) : false\n}\n","import { writeFile, mkdir } from \"fs/promises\"\nimport { join } from \"path\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\n\nexport class Logger {\n private logDir: string\n public enabled: boolean\n\n constructor(enabled: boolean) {\n this.enabled = enabled\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n this.logDir = join(configHome, \"opencode\", \"logs\", \"dcp\")\n }\n\n private async ensureLogDir() {\n if (!existsSync(this.logDir)) {\n await mkdir(this.logDir, { recursive: true })\n }\n }\n\n private formatData(data?: any): string {\n if (!data) return \"\"\n\n const parts: string[] = []\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue\n\n // Format arrays compactly\n if (Array.isArray(value)) {\n if (value.length === 0) continue\n parts.push(\n `${key}=[${value.slice(0, 3).join(\",\")}${value.length > 3 ? `...+${value.length - 3}` : \"\"}]`,\n )\n } else if (typeof value === \"object\") {\n const str = JSON.stringify(value)\n if (str.length < 50) {\n parts.push(`${key}=${str}`)\n }\n } else {\n parts.push(`${key}=${value}`)\n }\n }\n return parts.join(\" \")\n }\n\n private getCallerFile(skipFrames: number = 3): string {\n const originalPrepareStackTrace = Error.prepareStackTrace\n try {\n const err = new Error()\n Error.prepareStackTrace = (_, stack) => stack\n const stack = err.stack as unknown as NodeJS.CallSite[]\n Error.prepareStackTrace = originalPrepareStackTrace\n\n // Skip specified number of frames to get to actual caller\n for (let i = skipFrames; i < stack.length; i++) {\n const filename = stack[i]?.getFileName()\n if (filename && !filename.includes(\"/logger.\")) {\n // Extract just the filename without path and extension\n const match = filename.match(/([^/\\\\]+)\\.[tj]s$/)\n return match ? match[1] : filename\n }\n }\n return \"unknown\"\n } catch {\n return \"unknown\"\n }\n }\n\n private async write(level: string, component: string, message: string, data?: any) {\n if (!this.enabled) return\n\n try {\n await this.ensureLogDir()\n\n const timestamp = new Date().toISOString()\n const dataStr = this.formatData(data)\n\n const logLine = `${timestamp} ${level.padEnd(5)} ${component}: ${message}${dataStr ? \" | \" + dataStr : \"\"}\\n`\n\n const dailyLogDir = join(this.logDir, \"daily\")\n if (!existsSync(dailyLogDir)) {\n await mkdir(dailyLogDir, { recursive: true })\n }\n\n const logFile = join(dailyLogDir, `${new Date().toISOString().split(\"T\")[0]}.log`)\n await writeFile(logFile, logLine, { flag: \"a\" })\n } catch (error) {}\n }\n\n info(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"INFO\", component, message, data)\n }\n\n debug(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"DEBUG\", component, message, data)\n }\n\n warn(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"WARN\", component, message, data)\n }\n\n error(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"ERROR\", component, message, data)\n }\n\n /**\n * Strips unnecessary metadata from messages for cleaner debug logs.\n *\n * Removed:\n * - All IDs (id, sessionID, messageID, parentID)\n * - summary, path, cost, model, agent, mode, finish, providerID, modelID\n * - step-start and step-finish parts entirely\n * - snapshot fields\n * - ignored text parts\n *\n * Kept:\n * - role, time (created only), tokens (input, output, reasoning, cache)\n * - text, reasoning, tool parts with content\n * - tool calls with: tool, callID, input, output, metadata\n */\n private minimizeForDebug(messages: any[]): any[] {\n return messages.map((msg) => {\n const minimized: any = {\n role: msg.info?.role,\n }\n\n if (msg.info?.time?.created) {\n minimized.time = msg.info.time.created\n }\n\n if (msg.info?.tokens) {\n minimized.tokens = {\n input: msg.info.tokens.input,\n output: msg.info.tokens.output,\n reasoning: msg.info.tokens.reasoning,\n cache: msg.info.tokens.cache,\n }\n }\n\n if (msg.parts) {\n minimized.parts = msg.parts\n .map((part: any) => {\n if (part.type === \"step-start\" || part.type === \"step-finish\") {\n return null\n }\n\n if (part.type === \"text\") {\n if (part.ignored) return null\n const textPart: any = { type: \"text\", text: part.text }\n if (part.metadata) textPart.metadata = part.metadata\n return textPart\n }\n\n if (part.type === \"reasoning\") {\n const reasoningPart: any = { type: \"reasoning\", text: part.text }\n if (part.metadata) reasoningPart.metadata = part.metadata\n return reasoningPart\n }\n\n if (part.type === \"tool\") {\n const toolPart: any = {\n type: \"tool\",\n tool: part.tool,\n callID: part.callID,\n }\n\n if (part.state?.status) {\n toolPart.status = part.state.status\n }\n if (part.state?.input) {\n toolPart.input = part.state.input\n }\n if (part.state?.output) {\n toolPart.output = part.state.output\n }\n if (part.state?.error) {\n toolPart.error = part.state.error\n }\n if (part.metadata) {\n toolPart.metadata = part.metadata\n }\n if (part.state?.metadata) {\n toolPart.metadata = {\n ...(toolPart.metadata || {}),\n ...part.state.metadata,\n }\n }\n if (part.state?.title) {\n toolPart.title = part.state.title\n }\n\n return toolPart\n }\n\n return null\n })\n .filter(Boolean)\n }\n\n return minimized\n })\n }\n\n async saveContext(sessionId: string, messages: any[]) {\n if (!this.enabled) return\n\n try {\n const contextDir = join(this.logDir, \"context\", sessionId)\n if (!existsSync(contextDir)) {\n await mkdir(contextDir, { recursive: true })\n }\n\n const minimized = this.minimizeForDebug(messages).filter(\n (msg) => msg.parts && msg.parts.length > 0,\n )\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\")\n const contextFile = join(contextDir, `${timestamp}.json`)\n await writeFile(contextFile, JSON.stringify(minimized, null, 2))\n } catch (error) {}\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport type { Logger } from \"../logger\"\nimport { SYSTEM as SYSTEM_PROMPT } from \"./system\"\nimport { COMPRESS_RANGE as COMPRESS_RANGE_PROMPT } from \"./compress-range\"\nimport { COMPRESS_MESSAGE as COMPRESS_MESSAGE_PROMPT } from \"./compress-message\"\nimport { CONTEXT_LIMIT_NUDGE } from \"./context-limit-nudge\"\nimport { TURN_NUDGE } from \"./turn-nudge\"\nimport { ITERATION_NUDGE } from \"./iteration-nudge\"\nimport { MANUAL_MODE_SYSTEM_EXTENSION, SUBAGENT_SYSTEM_EXTENSION } from \"./extensions/system\"\n\nexport type PromptKey =\n | \"system\"\n | \"compress-range\"\n | \"compress-message\"\n | \"context-limit-nudge\"\n | \"turn-nudge\"\n | \"iteration-nudge\"\n\ntype EditablePromptField =\n | \"system\"\n | \"compressRange\"\n | \"compressMessage\"\n | \"contextLimitNudge\"\n | \"turnNudge\"\n | \"iterationNudge\"\n\ninterface PromptDefinition {\n key: PromptKey\n fileName: string\n label: string\n description: string\n usage: string\n runtimeField: EditablePromptField\n}\n\ninterface PromptOverrideCandidate {\n path: string\n}\n\ninterface PromptPaths {\n defaultsDir: string\n globalOverridesDir: string\n configDirOverridesDir: string | null\n projectOverridesDir: string | null\n}\n\nexport interface RuntimePrompts {\n system: string\n compressRange: string\n compressMessage: string\n contextLimitNudge: string\n turnNudge: string\n iterationNudge: string\n manualExtension: string\n subagentExtension: string\n}\n\nconst PROMPT_DEFINITIONS: PromptDefinition[] = [\n {\n key: \"system\",\n fileName: \"system.md\",\n label: \"System\",\n description: \"Core system-level DCP instruction block\",\n usage: \"Injected into the model system prompt on every request\",\n runtimeField: \"system\",\n },\n {\n key: \"compress-range\",\n fileName: \"compress-range.md\",\n label: \"Compress Range\",\n description: \"range-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the range-mode compress tool description\",\n runtimeField: \"compressRange\",\n },\n {\n key: \"compress-message\",\n fileName: \"compress-message.md\",\n label: \"Compress Message\",\n description: \"message-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the message-mode compress tool description\",\n runtimeField: \"compressMessage\",\n },\n {\n key: \"context-limit-nudge\",\n fileName: \"context-limit-nudge.md\",\n label: \"Context Limit Nudge\",\n description: \"High-priority nudge when context is over max threshold\",\n usage: \"Injected when context usage is beyond configured max limits\",\n runtimeField: \"contextLimitNudge\",\n },\n {\n key: \"turn-nudge\",\n fileName: \"turn-nudge.md\",\n label: \"Turn Nudge\",\n description: \"Nudge to compress closed ranges at turn boundaries\",\n usage: \"Injected when context is between min and max limits at a new user turn\",\n runtimeField: \"turnNudge\",\n },\n {\n key: \"iteration-nudge\",\n fileName: \"iteration-nudge.md\",\n label: \"Iteration Nudge\",\n description: \"Nudge after many iterations without user input\",\n usage: \"Injected when iteration threshold is crossed\",\n runtimeField: \"iterationNudge\",\n },\n]\n\nexport const PROMPT_KEYS: PromptKey[] = [\n \"system\",\n \"compress-range\",\n \"compress-message\",\n \"context-limit-nudge\",\n \"turn-nudge\",\n \"iteration-nudge\",\n]\n\nconst HTML_COMMENT_REGEX = /<!--[\\s\\S]*?-->/g\nconst LEGACY_INLINE_COMMENT_LINE_REGEX = /^[ \\t]*\\/\\/.*?\\/\\/[ \\t]*$/gm\nconst DCP_SYSTEM_REMINDER_TAG_REGEX =\n /^\\s*<dcp-system-reminder\\b[^>]*>[\\s\\S]*<\\/dcp-system-reminder>\\s*$/i\nconst DEFAULTS_README_FILE = \"README.md\"\n\nconst BUNDLED_EDITABLE_PROMPTS: Record<EditablePromptField, string> = {\n system: SYSTEM_PROMPT,\n compressRange: COMPRESS_RANGE_PROMPT,\n compressMessage: COMPRESS_MESSAGE_PROMPT,\n contextLimitNudge: CONTEXT_LIMIT_NUDGE,\n turnNudge: TURN_NUDGE,\n iterationNudge: ITERATION_NUDGE,\n}\n\nconst INTERNAL_PROMPT_EXTENSIONS = {\n manualExtension: MANUAL_MODE_SYSTEM_EXTENSION,\n subagentExtension: SUBAGENT_SYSTEM_EXTENSION,\n}\n\nfunction createBundledRuntimePrompts(): RuntimePrompts {\n return {\n system: BUNDLED_EDITABLE_PROMPTS.system,\n compressRange: BUNDLED_EDITABLE_PROMPTS.compressRange,\n compressMessage: BUNDLED_EDITABLE_PROMPTS.compressMessage,\n contextLimitNudge: BUNDLED_EDITABLE_PROMPTS.contextLimitNudge,\n turnNudge: BUNDLED_EDITABLE_PROMPTS.turnNudge,\n iterationNudge: BUNDLED_EDITABLE_PROMPTS.iterationNudge,\n manualExtension: INTERNAL_PROMPT_EXTENSIONS.manualExtension,\n subagentExtension: INTERNAL_PROMPT_EXTENSIONS.subagentExtension,\n }\n}\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate)) {\n try {\n if (statSync(candidate).isDirectory()) {\n return candidate\n }\n } catch {\n // ignore inaccessible entries while walking upward\n }\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction resolvePromptPaths(workingDirectory: string): PromptPaths {\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n const globalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n const defaultsDir = join(globalRoot, \"defaults\")\n const globalOverridesDir = join(globalRoot, \"overrides\")\n\n const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR\n ? join(process.env.OPENCODE_CONFIG_DIR, \"dcp-prompts\", \"overrides\")\n : null\n\n const opencodeDir = findOpencodeDir(workingDirectory)\n const projectOverridesDir = opencodeDir ? join(opencodeDir, \"dcp-prompts\", \"overrides\") : null\n\n return {\n defaultsDir,\n globalOverridesDir,\n configDirOverridesDir,\n projectOverridesDir,\n }\n}\n\nfunction stripConditionalTag(content: string, tagName: string): string {\n const regex = new RegExp(`<${tagName}>[\\\\s\\\\S]*?<\\/${tagName}>`, \"gi\")\n return content.replace(regex, \"\")\n}\n\nfunction unwrapDcpTagIfWrapped(content: string): string {\n const trimmed = content.trim()\n\n if (DCP_SYSTEM_REMINDER_TAG_REGEX.test(trimmed)) {\n return trimmed\n .replace(/^\\s*<dcp-system-reminder\\b[^>]*>\\s*/i, \"\")\n .replace(/\\s*<\\/dcp-system-reminder>\\s*$/i, \"\")\n .trim()\n }\n\n return trimmed\n}\n\nfunction normalizeReminderPromptContent(content: string): string {\n const normalized = content.trim()\n\n if (!normalized) {\n return \"\"\n }\n\n const startsWrapped = /^\\s*<dcp-system-reminder\\b[^>]*>/i.test(normalized)\n const endsWrapped = /<\\/dcp-system-reminder>\\s*$/i.test(normalized)\n\n if (startsWrapped !== endsWrapped) {\n return \"\"\n }\n\n return unwrapDcpTagIfWrapped(normalized)\n}\n\nfunction stripPromptComments(content: string): string {\n return content\n .replace(/^\\uFEFF/, \"\")\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(HTML_COMMENT_REGEX, \"\")\n .replace(LEGACY_INLINE_COMMENT_LINE_REGEX, \"\")\n}\n\nfunction toEditablePromptText(definition: PromptDefinition, rawContent: string): string {\n let normalized = stripPromptComments(rawContent).trim()\n if (!normalized) {\n return \"\"\n }\n\n if (definition.key === \"system\") {\n normalized = stripConditionalTag(normalized, \"manual\")\n normalized = stripConditionalTag(normalized, \"subagent\")\n }\n\n if (definition.key !== \"compress-range\" && definition.key !== \"compress-message\") {\n normalized = normalizeReminderPromptContent(normalized)\n }\n\n return normalized.trim()\n}\n\nfunction wrapRuntimePromptContent(definition: PromptDefinition, editableText: string): string {\n const trimmed = editableText.trim()\n if (!trimmed) {\n return \"\"\n }\n\n if (definition.key === \"compress-range\" || definition.key === \"compress-message\") {\n return trimmed\n }\n\n return `<dcp-system-reminder>\\n${trimmed}\\n</dcp-system-reminder>`\n}\n\nfunction buildDefaultPromptFileContent(bundledEditableText: string): string {\n return `${bundledEditableText.trim()}\\n`\n}\n\nfunction buildDefaultsReadmeContent(): string {\n const lines: string[] = []\n lines.push(\"# DCP Prompt Defaults\")\n lines.push(\"\")\n lines.push(\"This directory stores the DCP prompts.\")\n lines.push(\"Each prompt file here should contain plain text only (no XML wrappers).\")\n lines.push(\"\")\n lines.push(\"## Creating Overrides\")\n lines.push(\"\")\n lines.push(\n \"1. Copy a prompt file from this directory into an overrides directory using the same filename.\",\n )\n lines.push(\"2. Edit the copied file using plain text.\")\n lines.push(\"3. Restart OpenCode.\")\n lines.push(\"\")\n lines.push(\"To reset an override, delete the matching file from your overrides directory.\")\n lines.push(\"\")\n lines.push(\n \"Do not edit the default prompt files directly, they are just for reference, only files in the overrides directory are used.\",\n )\n lines.push(\"\")\n lines.push(\"Override precedence (highest first):\")\n lines.push(\"1. `.opencode/dcp-prompts/overrides/` (project)\")\n lines.push(\"2. `$OPENCODE_CONFIG_DIR/dcp-prompts/overrides/` (config dir)\")\n lines.push(\"3. `~/.config/opencode/dcp-prompts/overrides/` (global)\")\n lines.push(\"\")\n lines.push(\"## Prompt Files\")\n lines.push(\"\")\n\n for (const definition of PROMPT_DEFINITIONS) {\n lines.push(`- \\`${definition.fileName}\\``)\n lines.push(` - Purpose: ${definition.description}.`)\n lines.push(` - Runtime use: ${definition.usage}.`)\n }\n\n return `${lines.join(\"\\n\")}\\n`\n}\n\nfunction readFileIfExists(filePath: string): string | null {\n if (!existsSync(filePath)) {\n return null\n }\n\n try {\n return readFileSync(filePath, \"utf-8\")\n } catch {\n return null\n }\n}\n\nexport class PromptStore {\n private readonly logger: Logger\n private readonly paths: PromptPaths\n private readonly customPromptsEnabled: boolean\n private runtimePrompts: RuntimePrompts\n\n constructor(logger: Logger, workingDirectory: string, customPromptsEnabled = false) {\n this.logger = logger\n this.paths = resolvePromptPaths(workingDirectory)\n this.customPromptsEnabled = customPromptsEnabled\n this.runtimePrompts = createBundledRuntimePrompts()\n\n if (this.customPromptsEnabled) {\n this.ensureDefaultFiles()\n }\n this.reload()\n }\n\n getRuntimePrompts(): RuntimePrompts {\n return { ...this.runtimePrompts }\n }\n\n reload(): void {\n const nextPrompts = createBundledRuntimePrompts()\n\n if (!this.customPromptsEnabled) {\n this.runtimePrompts = nextPrompts\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledSource = BUNDLED_EDITABLE_PROMPTS[definition.runtimeField]\n const bundledEditable = toEditablePromptText(definition, bundledSource)\n const bundledRuntime = wrapRuntimePromptContent(definition, bundledEditable)\n const fallbackValue = bundledRuntime || bundledSource.trim()\n let effectiveValue = fallbackValue\n\n for (const candidate of this.getOverrideCandidates(definition.fileName)) {\n const rawOverride = readFileIfExists(candidate.path)\n if (rawOverride === null) {\n continue\n }\n\n const editableOverride = toEditablePromptText(definition, rawOverride)\n if (!editableOverride) {\n this.logger.warn(\"Prompt override is empty or invalid after normalization\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n const wrappedOverride = wrapRuntimePromptContent(definition, editableOverride)\n if (!wrappedOverride) {\n this.logger.warn(\"Prompt override could not be wrapped for runtime\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n effectiveValue = wrappedOverride\n break\n }\n\n nextPrompts[definition.runtimeField] = effectiveValue\n }\n\n this.runtimePrompts = nextPrompts\n }\n\n private getOverrideCandidates(fileName: string): PromptOverrideCandidate[] {\n const candidates: PromptOverrideCandidate[] = []\n\n if (this.paths.projectOverridesDir) {\n candidates.push({\n path: join(this.paths.projectOverridesDir, fileName),\n })\n }\n\n if (this.paths.configDirOverridesDir) {\n candidates.push({\n path: join(this.paths.configDirOverridesDir, fileName),\n })\n }\n\n candidates.push({\n path: join(this.paths.globalOverridesDir, fileName),\n })\n\n return candidates\n }\n\n private ensureDefaultFiles(): void {\n try {\n mkdirSync(this.paths.defaultsDir, { recursive: true })\n mkdirSync(this.paths.globalOverridesDir, { recursive: true })\n } catch {\n this.logger.warn(\"Failed to initialize prompt directories\", {\n defaultsDir: this.paths.defaultsDir,\n globalOverridesDir: this.paths.globalOverridesDir,\n })\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledEditable = toEditablePromptText(\n definition,\n BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const managedContent = buildDefaultPromptFileContent(\n bundledEditable || BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const filePath = join(this.paths.defaultsDir, definition.fileName)\n\n try {\n const existing = readFileIfExists(filePath)\n if (existing === managedContent) {\n continue\n }\n writeFileSync(filePath, managedContent, \"utf-8\")\n } catch {\n this.logger.warn(\"Failed to write default prompt file\", {\n key: definition.key,\n path: filePath,\n })\n }\n }\n\n const readmePath = join(this.paths.defaultsDir, DEFAULTS_README_FILE)\n const readmeContent = buildDefaultsReadmeContent()\n\n try {\n const existing = readFileIfExists(readmePath)\n if (existing !== readmeContent) {\n writeFileSync(readmePath, readmeContent, \"utf-8\")\n }\n } catch {\n this.logger.warn(\"Failed to write defaults README\", {\n path: readmePath,\n })\n }\n }\n}\n","export const SYSTEM = `\nYou 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.\n- \\`startId\\` must appear before \\`endId\\`.\n- Do not invent IDs. Use only IDs that are present in context.\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 = `<dcp-system-reminder>\nCRITICAL WARNING: MAX CONTEXT LIMIT REACHED\n\nYou are at or beyond the configured max context threshold. This is an emergency context-recovery moment.\n\nYou MUST use the \\`compress\\` tool now. Do not continue normal exploration until compression is handled.\n\nIf you are in the middle of a critical atomic operation, finish that atomic step first, then compress immediately.\n\nSELECTION PROCESS\nStart from older, resolved history and capture as much stale context as safely possible in one pass.\nAvoid the newest active working messages unless it is clearly closed.\n\nSUMMARY REQUIREMENTS\nYour summary MUST cover all essential details from the selected messages so work can continue.\nIf the compressed range includes user messages, preserve user intent exactly. Prefer direct quotes for short user messages to avoid semantic drift.\n</dcp-system-reminder>\n`\n","export const TURN_NUDGE = `<dcp-system-reminder>\nEvaluate the conversation for compressible ranges.\n\nIf any messages are cleanly closed and unlikely to be needed again, use the compress tool on them.\nIf direction has shifted, compress earlier ranges that are now less relevant.\n\nThe goal is to filter noise and distill key information so context accumulation stays under control.\nKeep active context uncompressed.\n</dcp-system-reminder>\n`\n","export const ITERATION_NUDGE = `<dcp-system-reminder>\nYou've been iterating for a while after the last user message.\n\nIf there is a closed portion that is unlikely to be referenced immediately (for example, finished research before implementation), use the compress tool on it now.\n</dcp-system-reminder>\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `<dcp-system-reminder>\nManual mode is enabled. Do NOT use compress unless the user has explicitly triggered it through a manual marker.\n\nOnly use the compress tool after seeing \\`<compress triggered manually>\\` in the current user instruction context.\n\nIssue exactly ONE compress tool per manual trigger. Do NOT launch multiple compress tools in parallel. Each trigger grants a single compression; after it completes, wait for the next trigger.\n\nAfter completing a manually triggered context-management action, STOP IMMEDIATELY. Do NOT continue with any task execution. End your response right after the tool use completes and wait for the next user input.\n</dcp-system-reminder>\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `<dcp-system-reminder>\nYou are operating in a subagent environment.\n\nThe initial subagent instruction is imperative and must be followed exactly.\nIt is the only user message intentionally not assigned a message ID, and therefore is not eligible for compression.\nAll subsequent messages in the session will have IDs.\n</dcp-system-reminder>\n`\n\nexport function buildProtectedToolsExtension(protectedTools: string[]): string {\n if (protectedTools.length === 0) {\n return \"\"\n }\n\n const toolList = protectedTools.map((t) => `\\`${t}\\``).join(\", \")\n return `<dcp-system-reminder>\nThe following tools are environment-managed: ${toolList}.\nTheir outputs are automatically preserved during compression.\nDo not include their content in compress tool summaries — the environment retains it independently.\n</dcp-system-reminder>`\n}\n","import { createHash } from \"node:crypto\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\n\nconst SUMMARY_ID_HASH_LENGTH = 16\nconst DCP_BLOCK_ID_TAG_REGEX = /(<dcp-message-id(?=[\\s>])[^>]*>)b\\d+(<\\/dcp-message-id>)/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\n\nconst generateStableId = (prefix: string, seed: string): string => {\n const hash = createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, SUMMARY_ID_HASH_LENGTH)\n return `${prefix}_${hash}`\n}\n\nexport const createSyntheticUserMessage = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n): WithParts => {\n const userInfo = baseMessage.info as UserMessage\n const now = Date.now()\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const messageId = generateStableId(\"msg_dcp_summary\", deterministicSeed)\n const partId = generateStableId(\"prt_dcp_summary\", deterministicSeed)\n\n return {\n info: {\n id: messageId,\n sessionID: userInfo.sessionID,\n role: \"user\" as const,\n agent: userInfo.agent,\n model: userInfo.model,\n time: { created: now },\n },\n parts: [\n {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: messageId,\n type: \"text\" as const,\n text: content,\n },\n ],\n }\n}\n\nexport const createSyntheticTextPart = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n) => {\n const userInfo = baseMessage.info as UserMessage\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const partId = generateStableId(\"prt_dcp_text\", deterministicSeed)\n\n return {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: userInfo.id,\n type: \"text\" as const,\n text: content,\n }\n}\n\ntype MessagePart = WithParts[\"parts\"][number]\ntype ToolPart = Extract<MessagePart, { type: \"tool\" }>\ntype TextPart = Extract<MessagePart, { type: \"text\" }>\n\nexport const appendToLastTextPart = (message: WithParts, injection: string): boolean => {\n const textPart = findLastTextPart(message)\n if (!textPart) {\n return false\n }\n\n return appendToTextPart(textPart, injection)\n}\n\nconst findLastTextPart = (message: WithParts): TextPart | null => {\n for (let i = message.parts.length - 1; i >= 0; i--) {\n const part = message.parts[i]\n if (part.type === \"text\") {\n return part\n }\n }\n\n return null\n}\n\nexport const appendToTextPart = (part: TextPart, injection: string): boolean => {\n if (typeof part.text !== \"string\") {\n return false\n }\n\n const normalizedInjection = injection.replace(/^\\n+/, \"\")\n if (!normalizedInjection.trim()) {\n return false\n }\n if (part.text.includes(normalizedInjection)) {\n return true\n }\n\n const baseText = part.text.replace(/\\n*$/, \"\")\n part.text = baseText.length > 0 ? `${baseText}\\n\\n${normalizedInjection}` : normalizedInjection\n return true\n}\n\nexport const appendToAllToolParts = (message: WithParts, tag: string): boolean => {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"tool\") {\n injected = appendToToolPart(part, tag) || injected\n }\n }\n return injected\n}\n\nexport const appendToToolPart = (part: ToolPart, tag: string): boolean => {\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n return false\n }\n if (part.state.output.includes(tag)) {\n return true\n }\n\n part.state.output = `${part.state.output}${tag}`\n return true\n}\n\nexport const hasContent = (message: WithParts): boolean => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0) ||\n (part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"),\n )\n}\n\nexport function buildToolIdList(state: SessionState, messages: WithParts[]): string[] {\n const toolIds: string[] = []\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n state.toolIdList = toolIds\n return toolIds\n}\n\nexport const replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n 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 } from \"./utils\"\nimport { getLastUserMessage } from \"./query\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\n\nconst PRUNED_TOOL_OUTPUT_REPLACEMENT =\n \"[Output removed to save context - information superseded or no longer needed]\"\nconst PRUNED_TOOL_ERROR_INPUT_REPLACEMENT = \"[input removed due to failed tool call]\"\nconst PRUNED_QUESTION_INPUT_REPLACEMENT = \"[questions removed - see output for user's answers]\"\n\nexport const prune = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n filterCompressedRanges(state, logger, config, messages)\n // pruneFullTool(state, logger, messages)\n pruneToolOutputs(state, logger, messages)\n pruneToolInputs(state, logger, messages)\n pruneToolErrors(state, logger, messages)\n}\n\nconst pruneFullTool = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n const messagesToRemove: string[] = []\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const partsToRemove: string[] = []\n\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.tool !== \"edit\" && part.tool !== \"write\") {\n continue\n }\n\n partsToRemove.push(part.callID)\n }\n\n if (partsToRemove.length === 0) {\n continue\n }\n\n msg.parts = parts.filter(\n (part) => part.type !== \"tool\" || !partsToRemove.includes(part.callID),\n )\n\n if (msg.parts.length === 0) {\n messagesToRemove.push(msg.info.id)\n }\n }\n\n if (messagesToRemove.length > 0) {\n const result = messages.filter((msg) => !messagesToRemove.includes(msg.info.id))\n messages.length = 0\n messages.push(...result)\n }\n}\n\nconst pruneToolOutputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool === \"question\" || part.tool === \"edit\" || part.tool === \"write\") {\n continue\n }\n\n part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT\n }\n }\n}\n\nconst pruneToolInputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool !== \"question\") {\n continue\n }\n\n if (part.state.input?.questions !== undefined) {\n part.state.input.questions = PRUNED_QUESTION_INPUT_REPLACEMENT\n }\n }\n }\n}\n\nconst pruneToolErrors = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"error\") {\n continue\n }\n\n // Prune all string inputs for errored tools\n const input = part.state.input\n if (input && typeof input === \"object\") {\n for (const key of Object.keys(input)) {\n if (typeof input[key] === \"string\") {\n input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT\n }\n }\n }\n }\n }\n}\n\nconst filterCompressedRanges = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (\n state.prune.messages.byMessageId.size === 0 &&\n state.prune.messages.activeByAnchorMessageId.size === 0\n ) {\n return\n }\n\n const result: WithParts[] = []\n\n for (const msg of messages) {\n const msgId = msg.info.id\n\n // Check if there's a summary to inject at this anchor point\n const blockId = state.prune.messages.activeByAnchorMessageId.get(msgId)\n const summary =\n blockId !== undefined ? state.prune.messages.blocksById.get(blockId) : undefined\n if (summary) {\n const rawSummaryContent = (summary as { summary?: unknown }).summary\n if (\n summary.active !== true ||\n typeof rawSummaryContent !== \"string\" ||\n rawSummaryContent.length === 0\n ) {\n logger.warn(\"Skipping malformed compress summary\", {\n anchorMessageId: msgId,\n blockId: (summary as { blockId?: unknown }).blockId,\n })\n } else {\n // Find user message for variant and as base for synthetic message\n const msgIndex = messages.indexOf(msg)\n const userMessage = getLastUserMessage(messages, msgIndex)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(rawSummaryContent)\n : rawSummaryContent\n const summarySeed = `${summary.blockId}:${summary.anchorMessageId}`\n result.push(\n createSyntheticUserMessage(userMessage, summaryContent, summarySeed),\n )\n\n logger.info(\"Injected compress summary\", {\n anchorMessageId: msgId,\n summaryLength: summaryContent.length,\n })\n } else {\n logger.warn(\"No user message found for compress summary\", {\n anchorMessageId: msgId,\n })\n }\n }\n }\n\n // Skip messages that are in the prune list\n const pruneEntry = state.prune.messages.byMessageId.get(msgId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n continue\n }\n\n // Normal message, include it\n result.push(msg)\n }\n\n // Replace messages array contents\n messages.length = 0\n messages.push(...result)\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\n\nfunction sortBlocksByCreation(\n a: { createdAt: number; blockId: number },\n b: { createdAt: number; blockId: number },\n): number {\n const createdAtDiff = a.createdAt - b.createdAt\n if (createdAtDiff !== 0) {\n return createdAtDiff\n }\n return a.blockId - b.blockId\n}\n\nexport const syncCompressionBlocks = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n): void => {\n const messagesState = state.prune.messages\n if (!messagesState?.blocksById?.size) {\n return\n }\n\n const messageIds = new Set(messages.map((msg) => msg.info.id))\n const previousActiveBlockIds = new Set<number>(\n Array.from(messagesState.blocksById.values())\n .filter((block) => block.active)\n .map((block) => block.blockId),\n )\n\n messagesState.activeBlockIds.clear()\n messagesState.activeByAnchorMessageId.clear()\n\n const now = Date.now()\n const missingOriginBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n for (const block of orderedBlocks) {\n const hasOriginMessage =\n typeof block.compressMessageId === \"string\" &&\n block.compressMessageId.length > 0 &&\n messageIds.has(block.compressMessageId)\n\n if (!hasOriginMessage) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n missingOriginBlockIds.push(block.blockId)\n continue\n }\n\n if (block.deactivatedByUser) {\n block.active = false\n if (block.deactivatedAt === undefined) {\n block.deactivatedAt = now\n }\n block.deactivatedByBlockId = undefined\n continue\n }\n\n for (const consumedBlockId of block.consumedBlockIds) {\n if (!messagesState.activeBlockIds.has(consumedBlockId)) {\n continue\n }\n\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (consumedBlock) {\n consumedBlock.active = false\n consumedBlock.deactivatedAt = now\n consumedBlock.deactivatedByBlockId = block.blockId\n\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlock.blockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n }\n\n block.active = true\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n messagesState.activeBlockIds.add(block.blockId)\n if (messageIds.has(block.anchorMessageId)) {\n messagesState.activeByAnchorMessageId.set(block.anchorMessageId, block.blockId)\n }\n }\n\n for (const entry of messagesState.byMessageId.values()) {\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [...new Set(entry.allBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n : []\n\n entry.allBlockIds = allBlockIds\n entry.activeBlockIds = allBlockIds.filter((id) => messagesState.activeBlockIds.has(id))\n }\n\n const nextActiveBlockIds = messagesState.activeBlockIds\n let deactivatedCount = 0\n let reactivatedCount = 0\n\n for (const blockId of previousActiveBlockIds) {\n if (!nextActiveBlockIds.has(blockId)) {\n deactivatedCount++\n }\n }\n for (const blockId of nextActiveBlockIds) {\n if (!previousActiveBlockIds.has(blockId)) {\n reactivatedCount++\n }\n }\n\n if (missingOriginBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingOriginCount: missingOriginBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type 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 } from \"../../state\"\n\nexport function buildCompressedBlockGuidance(state: SessionState): string {\n const refs = Array.from(state.prune.messages.activeBlockIds)\n .filter((id) => Number.isInteger(id) && id > 0)\n .sort((a, b) => a - b)\n .map((id) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"none\"\n\n return [\n \"Compressed block context:\",\n `- Active compressed blocks in this session: ${blockCount} (${blockList})`,\n \"- If your selected compression range includes any listed block, include each required placeholder exactly once in the summary using `(bN)`.\",\n ].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 const overMaxLimit = maxContextLimit === undefined ? false : currentTokens > maxContextLimit\n const overMinLimit = minContextLimit === undefined ? true : currentTokens >= minContextLimit\n\n return {\n overMaxLimit,\n overMinLimit,\n }\n}\n\nexport function addAnchor(\n anchorMessageIds: Set<string>,\n anchorMessageId: string,\n anchorMessageIndex: number,\n messages: WithParts[],\n interval: number,\n): boolean {\n if (anchorMessageIndex < 0) {\n return false\n }\n\n let latestAnchorMessageIndex = -1\n for (let i = messages.length - 1; i >= 0; i--) {\n if (anchorMessageIds.has(messages[i].info.id)) {\n latestAnchorMessageIndex = i\n break\n }\n }\n\n const shouldAdd =\n latestAnchorMessageIndex < 0 || anchorMessageIndex - latestAnchorMessageIndex >= interval\n if (!shouldAdd) {\n return false\n }\n\n const previousSize = anchorMessageIds.size\n anchorMessageIds.add(anchorMessageId)\n return anchorMessageIds.size !== previousSize\n}\n\nfunction buildMessagePriorityGuidance(\n messages: WithParts[],\n compressionPriorities: CompressionPriorityMap | undefined,\n anchorIndex: number,\n priority: MessagePriority,\n): string {\n if (!compressionPriorities || compressionPriorities.size === 0) {\n return \"\"\n }\n\n const refs = listPriorityRefsBeforeIndex(messages, compressionPriorities, anchorIndex, priority)\n const priorityLabel = `${priority[0].toUpperCase()}${priority.slice(1)}`\n\n return renderMessagePriorityGuidance(priorityLabel, refs)\n}\n\nfunction injectAnchoredNudge(message: WithParts, nudgeText: string): void {\n if (!nudgeText.trim()) {\n return\n }\n\n if (message.info.role === \"user\") {\n if (appendToLastTextPart(message, nudgeText)) {\n return\n }\n\n message.parts.push(createSyntheticTextPart(message, nudgeText))\n return\n }\n\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (!hasContent(message)) {\n return\n }\n\n for (const part of message.parts) {\n if (part.type === \"text\") {\n if (appendToTextPart(part, nudgeText)) {\n return\n }\n }\n }\n\n const syntheticPart = createSyntheticTextPart(message, nudgeText)\n const firstToolIndex = message.parts.findIndex((p) => p.type === \"tool\")\n if (firstToolIndex === -1) {\n message.parts.push(syntheticPart)\n } else {\n message.parts.splice(firstToolIndex, 0, syntheticPart)\n }\n}\n\nfunction collectAnchoredMessages(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n): Array<{ message: WithParts; index: number }> {\n const anchoredMessages: Array<{ message: WithParts; index: number }> = []\n\n for (const anchorMessageId of anchorMessageIds) {\n const index = messages.findIndex((message) => message.info.id === anchorMessageId)\n if (index === -1) {\n continue\n }\n\n anchoredMessages.push({\n message: messages[index],\n index,\n })\n }\n\n return anchoredMessages\n}\n\nfunction collectTurnNudgeAnchors(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n): Set<string> {\n const turnNudgeAnchors = new Set<string>()\n const targetRole = config.compress.nudgeForce === \"strong\" ? \"user\" : \"assistant\"\n\n for (const message of messages) {\n if (!state.nudges.turnNudgeAnchors.has(message.info.id)) continue\n\n if (message.info.role === targetRole) {\n turnNudgeAnchors.add(message.info.id)\n }\n }\n\n return turnNudgeAnchors\n}\n\nfunction applyRangeModeAnchoredNudge(\n anchorMessageIds: Set<string>,\n messages: WithParts[],\n baseNudgeText: string,\n compressedBlockGuidance: string,\n): 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\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\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 const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n compressedBlockGuidance,\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressedBlockGuidance,\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressedBlockGuidance,\n )\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { Logger } from \"../../logger\"\nimport type { PluginConfig } from \"../../config\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport { formatMessageIdTag } from \"../../message-ids\"\nimport type { CompressionPriorityMap } from \"../priority\"\nimport { compressPermission } from \"../../compress-permission\"\nimport {\n getLastUserMessage,\n isIgnoredUserMessage,\n isProtectedUserMessage,\n messageHasCompress,\n} from \"../query\"\nimport { saveSessionState } from \"../../state/persistence\"\nimport {\n appendToTextPart,\n appendToLastTextPart,\n appendToAllToolParts,\n createSyntheticTextPart,\n hasContent,\n} from \"../utils\"\nimport {\n addAnchor,\n applyAnchoredNudges,\n countMessagesAfterIndex,\n findLastNonIgnoredMessage,\n getIterationNudgeThreshold,\n getNudgeFrequency,\n getModelInfo,\n isContextOverLimits,\n} from \"./utils\"\n\nexport const injectCompressNudges = (\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n if (state.manualMode) {\n return\n }\n\n const lastMessage = findLastNonIgnoredMessage(messages)\n const lastAssistantMessage = messages.findLast((message) => message.info.role === \"assistant\")\n\n if (lastAssistantMessage && messageHasCompress(lastAssistantMessage)) {\n state.nudges.contextLimitAnchors.clear()\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n void saveSessionState(state, logger)\n return\n }\n\n const { providerId, modelId } = getModelInfo(messages)\n let anchorsChanged = false\n\n const { overMaxLimit, overMinLimit } = isContextOverLimits(\n config,\n state,\n providerId,\n modelId,\n messages,\n )\n\n if (!overMinLimit) {\n const hadTurnAnchors = state.nudges.turnNudgeAnchors.size > 0\n const hadIterationAnchors = state.nudges.iterationNudgeAnchors.size > 0\n\n if (hadTurnAnchors || hadIterationAnchors) {\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n anchorsChanged = true\n }\n }\n\n if (overMaxLimit) {\n if (lastMessage) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.contextLimitAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n if (added) {\n anchorsChanged = true\n }\n }\n } else if (overMinLimit) {\n const isLastMessageUser = lastMessage?.message.info.role === \"user\"\n\n if (isLastMessageUser && lastAssistantMessage) {\n const previousSize = state.nudges.turnNudgeAnchors.size\n state.nudges.turnNudgeAnchors.add(lastMessage.message.info.id)\n state.nudges.turnNudgeAnchors.add(lastAssistantMessage.info.id)\n if (state.nudges.turnNudgeAnchors.size !== previousSize) {\n anchorsChanged = true\n }\n }\n\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage && lastMessage) {\n const lastUserMessageIndex = messages.findIndex(\n (message) => message.info.id === lastUserMessage.info.id,\n )\n if (lastUserMessageIndex >= 0) {\n const messagesSinceUser = countMessagesAfterIndex(messages, lastUserMessageIndex)\n const iterationThreshold = getIterationNudgeThreshold(config)\n\n if (\n lastMessage.index > lastUserMessageIndex &&\n messagesSinceUser >= iterationThreshold\n ) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.iterationNudgeAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n\n if (added) {\n anchorsChanged = true\n }\n }\n }\n }\n }\n\n applyAnchoredNudges(state, config, messages, prompts, compressionPriorities)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger)\n }\n}\n\nexport const injectMessageIds = (\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n compressionPriorities?: CompressionPriorityMap,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n const messageRef = state.messageIds.byRawId.get(message.info.id)\n if (!messageRef) {\n continue\n }\n\n const isBlockedMessage = isProtectedUserMessage(config, message)\n const priority =\n config.compress.mode === \"message\" && !isBlockedMessage\n ? compressionPriorities?.get(message.info.id)?.priority\n : undefined\n const tag = formatMessageIdTag(\n isBlockedMessage ? \"BLOCKED\" : messageRef,\n priority ? { priority } : undefined,\n )\n\n if (message.info.role === \"user\") {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"text\") {\n injected = appendToTextPart(part, tag) || injected\n }\n }\n\n if (injected) {\n continue\n }\n\n message.parts.push(createSyntheticTextPart(message, tag))\n continue\n }\n\n if (message.info.role !== \"assistant\") {\n continue\n }\n\n if (!hasContent(message)) {\n continue\n }\n\n if (appendToAllToolParts(message, tag)) {\n continue\n }\n\n if (appendToLastTextPart(message, tag)) {\n continue\n }\n\n const syntheticPart = createSyntheticTextPart(message, tag)\n const firstToolIndex = message.parts.findIndex((p) => p.type === \"tool\")\n if (firstToolIndex === -1) {\n message.parts.push(syntheticPart)\n } else {\n message.parts.splice(firstToolIndex, 0, syntheticPart)\n }\n }\n}\n","import type { Logger } from \"../../logger\"\nimport type { SessionState, WithParts } from \"../../state\"\nimport { filterMessages } from \"../shape\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../../subagents/subagent-results\"\nimport { stripHallucinationsFromString } from \"../utils\"\n\nasync function fetchSubAgentMessages(client: any, sessionId: string): Promise<WithParts[]> {\n const response = await client.session.messages({\n path: { id: sessionId },\n })\n\n return filterMessages(response?.data || response)\n}\n\nexport const injectExtendedSubAgentResults = async (\n client: any,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n allowSubAgents: boolean,\n): Promise<void> => {\n if (!allowSubAgents) {\n return\n }\n\n for (const message of messages) {\n const parts = Array.isArray(message.parts) ? message.parts : []\n\n for (const part of parts) {\n if (part.type !== \"tool\" || part.tool !== \"task\" || !part.callID) {\n continue\n }\n if (state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n continue\n }\n\n const cachedResult = state.subAgentResultCache.get(part.callID)\n if (cachedResult !== undefined) {\n if (cachedResult) {\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, cachedResult),\n )\n }\n continue\n }\n\n const subAgentSessionId = getSubAgentId(part)\n if (!subAgentSessionId) {\n continue\n }\n\n let subAgentMessages: WithParts[] = []\n try {\n subAgentMessages = await fetchSubAgentMessages(client, subAgentSessionId)\n } catch (error) {\n logger.warn(\"Failed to fetch subagent session for output expansion\", {\n subAgentSessionId,\n callID: part.callID,\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n\n const subAgentResultText = buildSubagentResultText(subAgentMessages)\n if (!subAgentResultText) {\n continue\n }\n\n state.subAgentResultCache.set(part.callID, subAgentResultText)\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, subAgentResultText),\n )\n }\n }\n}\n","import type { WithParts } from \"../state\"\nimport { getLastUserMessage } from \"./query\"\n\n/**\n * Mirrors opencode's differentModel handling by preserving part content while\n * dropping provider metadata on assistant parts that came from a different\n * model/provider than the current turn's user message.\n */\nexport function stripStaleMetadata(messages: WithParts[]): void {\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage?.info.role !== \"user\") {\n return\n }\n\n const modelID = lastUserMessage.info.model.modelID\n const providerID = lastUserMessage.info.model.providerID\n\n messages.forEach((message) => {\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (message.info.modelID === modelID && message.info.providerID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\" && 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(\"│ DCP Context Analysis │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Session Context Breakdown:\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n for (const cat of categories) {\n const bar = createBar(cat.value, breakdown.total, barWidth, cat.char)\n const percentage =\n breakdown.total > 0 ? ((cat.value / breakdown.total) * 100).toFixed(1) : \"0.0\"\n const labelWithPct = `${cat.label.padEnd(maxLabelLen)} ${percentage.padStart(5)}% `\n const valueStr = formatTokenCount(cat.value).padStart(13)\n lines.push(`${labelWithPct}│${bar.padEnd(barWidth)}│${valueStr}`)\n }\n\n lines.push(\"\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n lines.push(\"Summary:\")\n\n if (breakdown.prunedTokens > 0) {\n const withoutPruning = breakdown.total + breakdown.prunedTokens\n const pruned = []\n if (breakdown.prunedToolCount > 0) pruned.push(`${breakdown.prunedToolCount} tools`)\n if (breakdown.prunedMessageCount > 0)\n pruned.push(`${breakdown.prunedMessageCount} messages`)\n lines.push(\n ` Pruned: ${pruned.join(\", \")} (~${formatTokenCount(breakdown.prunedTokens)})`,\n )\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n lines.push(` Without DCP: ~${formatTokenCount(withoutPruning)}`)\n } else {\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n }\n\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleContextCommand(ctx: ContextCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const breakdown = analyzeTokens(state, messages)\n\n const message = formatContextMessage(breakdown)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n}\n","import type { CompressionBlock, PruneMessagesState } from \"../state\"\n\nexport interface CompressionTarget {\n displayId: number\n runId: number\n topic: string\n compressedTokens: number\n durationMs: number\n grouped: boolean\n blocks: CompressionBlock[]\n}\n\nfunction byBlockId(a: CompressionBlock, b: CompressionBlock): number {\n return a.blockId - b.blockId\n}\n\nfunction buildTarget(blocks: CompressionBlock[]): CompressionTarget {\n const ordered = [...blocks].sort(byBlockId)\n const first = ordered[0]\n if (!first) {\n throw new Error(\"Cannot build compression target from empty block list.\")\n }\n\n const grouped = first.mode === \"message\"\n return {\n displayId: first.blockId,\n runId: first.runId,\n topic: grouped ? first.batchTopic || first.topic : first.topic,\n compressedTokens: ordered.reduce((total, block) => total + block.compressedTokens, 0),\n durationMs: ordered.reduce((total, block) => Math.max(total, block.durationMs), 0),\n grouped,\n blocks: ordered,\n }\n}\n\nfunction groupMessageBlocks(blocks: CompressionBlock[]): CompressionTarget[] {\n const grouped = new Map<number, CompressionBlock[]>()\n\n for (const block of blocks) {\n const existing = grouped.get(block.runId)\n if (existing) {\n existing.push(block)\n continue\n }\n grouped.set(block.runId, [block])\n }\n\n return Array.from(grouped.values()).map(buildTarget)\n}\n\nfunction splitTargets(blocks: CompressionBlock[]): CompressionTarget[] {\n const messageBlocks: CompressionBlock[] = []\n const singleBlocks: CompressionBlock[] = []\n\n for (const block of blocks) {\n if (block.mode === \"message\") {\n messageBlocks.push(block)\n } else {\n singleBlocks.push(block)\n }\n }\n\n const targets = [\n ...singleBlocks.map((block) => buildTarget([block])),\n ...groupMessageBlocks(messageBlocks),\n ]\n return targets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function getActiveCompressionTargets(\n messagesState: PruneMessagesState,\n): CompressionTarget[] {\n const activeBlocks = Array.from(messagesState.activeBlockIds)\n .map((blockId) => messagesState.blocksById.get(blockId))\n .filter((block): block is CompressionBlock => !!block && block.active)\n\n return splitTargets(activeBlocks)\n}\n\nexport function getRecompressibleCompressionTargets(\n messagesState: PruneMessagesState,\n availableMessageIds: Set<string>,\n): CompressionTarget[] {\n const allBlocks = Array.from(messagesState.blocksById.values()).filter((block) => {\n return availableMessageIds.has(block.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: /dcp decompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No compressions are available to restore.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleDecompressCommand(ctx: DecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp decompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n\n if (!targetArg) {\n const availableTargets = getActiveCompressionTargets(messagesState)\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp decompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n const activeBlocks = target.blocks.filter((block) => block.active)\n if (activeBlocks.length === 0) {\n const activeAncestorBlockId = findActiveAncestorBlockId(messagesState, target)\n if (activeAncestorBlockId !== null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is inside compression ${activeAncestorBlockId}. Restore compression ${activeAncestorBlockId} first.`,\n params,\n logger,\n )\n return\n }\n\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is not active.`,\n params,\n logger,\n )\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n const deactivatedAt = Date.now()\n\n for (const block of target.blocks) {\n block.active = false\n block.deactivatedByUser = true\n block.deactivatedAt = deactivatedAt\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let restoredMessageCount = 0\n let restoredTokens = 0\n for (const [messageId, tokenCount] of activeMessagesBefore) {\n const entry = messagesState.byMessageId.get(messageId)\n const isActiveNow = entry ? entry.activeBlockIds.length > 0 : false\n if (!isActiveNow) {\n restoredMessageCount++\n restoredTokens += tokenCount\n }\n }\n\n state.stats.totalPruneTokens = Math.max(0, state.stats.totalPruneTokens - restoredTokens)\n\n const reactivatedBlockIds = Array.from(messagesState.activeBlockIds)\n .filter((blockId) => !activeBlockIdsBefore.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatDecompressMessage(\n target,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Decompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n })\n}\n","/**\n * DCP Help command handler.\n * Shows available DCP commands and their descriptions.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { PluginConfig } from \"../config\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { compressPermission } from \"../compress-permission\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { getCurrentParams } from \"../token-utils\"\n\nexport interface HelpCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nconst BASE_COMMANDS: [string, string][] = [\n [\"/dcp context\", \"Show token usage breakdown for current session\"],\n [\"/dcp stats\", \"Show DCP pruning statistics\"],\n [\"/dcp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/dcp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\n]\n\nconst TOOL_COMMANDS: Record<string, [string, string]> = {\n compress: [\"/dcp compress [focus]\", \"Trigger manual compress tool execution\"],\n decompress: [\"/dcp decompress <n>\", \"Restore selected compression\"],\n recompress: [\"/dcp recompress <n>\", \"Re-apply a user-decompressed compression\"],\n}\n\nfunction getVisibleCommands(state: SessionState, config: PluginConfig): [string, string][] {\n const commands = [...BASE_COMMANDS]\n\n if (compressPermission(state, config) !== \"deny\") {\n commands.push(TOOL_COMMANDS.compress)\n commands.push(TOOL_COMMANDS.decompress)\n commands.push(TOOL_COMMANDS.recompress)\n }\n\n return commands\n}\n\nfunction formatHelpMessage(state: SessionState, config: PluginConfig): string {\n const commands = getVisibleCommands(state, config)\n const colWidth = Math.max(...commands.map(([cmd]) => cmd.length)) + 4\n const lines: string[] = []\n\n lines.push(\"╭─────────────────────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Commands │\")\n lines.push(\"╰─────────────────────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(` ${\"Manual mode:\".padEnd(colWidth)}${state.manualMode ? \"ON\" : \"OFF\"}`)\n lines.push(\"\")\n for (const [cmd, desc] of commands) {\n lines.push(` ${cmd.padEnd(colWidth)}${desc}`)\n }\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleHelpCommand(ctx: HelpCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const { config } = ctx\n const message = formatHelpMessage(state, config)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Help command executed\")\n}\n","/**\n * DCP Manual mode command handler.\n * Handles toggling manual mode and triggering individual tool executions.\n *\n * Usage:\n * /dcp manual [on|off] - Toggle manual mode or set explicit state\n * /dcp compress [focus] - Trigger manual compress execution\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { buildCompressedBlockGuidance } from \"../prompts/extensions/nudge\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nconst MANUAL_MODE_ON = \"Manual mode is now ON. Use /dcp compress to trigger context tools manually.\"\n\nconst MANUAL_MODE_OFF = \"Manual mode is now OFF.\"\n\nconst COMPRESS_TRIGGER_PROMPT = [\n \"<compress triggered manually>\",\n \"Manual mode trigger received. You must now use the compress tool.\",\n \"Find the most significant completed conversation content that can be compressed into a high-fidelity technical summary.\",\n \"Follow the active compress mode, preserve all critical implementation details, and choose safe targets.\",\n \"Return after compress with a brief explanation of what content was compressed.\",\n].join(\"\\n\\n\")\n\nfunction getTriggerPrompt(\n tool: \"compress\",\n state: SessionState,\n config: PluginConfig,\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state)\n\n const sections = [base, compressedBlockGuidance]\n if (userFocus && userFocus.trim().length > 0) {\n sections.push(`Additional user focus:\\n${userFocus.trim()}`)\n }\n\n return sections.join(\"\\n\\n\")\n}\n\nexport interface ManualCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport async function handleManualToggleCommand(\n ctx: ManualCommandContext,\n modeArg?: string,\n): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n if (modeArg === \"on\") {\n state.manualMode = \"active\"\n } else if (modeArg === \"off\") {\n state.manualMode = false\n } else {\n state.manualMode = state.manualMode ? false : \"active\"\n }\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(\n client,\n sessionId,\n state.manualMode ? MANUAL_MODE_ON : MANUAL_MODE_OFF,\n params,\n logger,\n )\n\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: /dcp recompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No user-decompressed blocks are available to re-compress.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available user-decompressed compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleRecompressCommand(ctx: RecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp recompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n const availableMessageIds = new Set(messages.map((msg) => msg.info.id))\n\n if (!targetArg) {\n const availableTargets = getRecompressibleCompressionTargets(\n messagesState,\n availableMessageIds,\n )\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp recompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n if (target.blocks.some((block) => !availableMessageIds.has(block.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(\"│ DCP Statistics │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Compression:\")\n lines.push(\"─\".repeat(60))\n lines.push(\n ` Tokens in|out: ~${formatTokenCount(sessionTokens)} | ~${formatTokenCount(sessionSummaryTokens)}`,\n )\n lines.push(` Ratio: ${formatCompressionRatio(sessionTokens, sessionSummaryTokens)}`)\n lines.push(` Time: ${formatCompressionTime(sessionDurationMs)}`)\n lines.push(` Messages: ${sessionMessages}`)\n lines.push(` Tools: ${sessionTools}`)\n lines.push(\"\")\n lines.push(\"All-time:\")\n lines.push(\"─\".repeat(60))\n lines.push(` Tokens saved: ~${formatTokenCount(allTime.totalTokens)}`)\n lines.push(` Tools pruned: ${allTime.totalTools}`)\n lines.push(` Messages pruned: ${allTime.totalMessages}`)\n lines.push(` Sessions: ${allTime.sessionCount}`)\n\n return lines.join(\"\\n\")\n}\n\nfunction formatCompressionRatio(inputTokens: number, outputTokens: number): string {\n if (inputTokens <= 0) {\n return \"0:1\"\n }\n\n if (outputTokens <= 0) {\n return \"∞:1\"\n }\n\n const ratio = Math.max(1, Math.round(inputTokens / outputTokens))\n return `${ratio}:1`\n}\n\nfunction formatCompressionTime(ms: number): string {\n const safeMs = Math.max(0, Math.round(ms))\n if (safeMs < 1000) {\n return `${safeMs} ms`\n }\n\n const totalSeconds = safeMs / 1000\n if (totalSeconds < 60) {\n return `${totalSeconds.toFixed(1)} s`\n }\n\n const wholeSeconds = Math.floor(totalSeconds)\n const hours = Math.floor(wholeSeconds / 3600)\n const minutes = Math.floor((wholeSeconds % 3600) / 60)\n const seconds = wholeSeconds % 60\n\n if (hours > 0) {\n return `${hours}h ${minutes}m ${seconds}s`\n }\n\n return `${minutes}m ${seconds}s`\n}\n\nexport async function handleStatsCommand(ctx: StatsCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n // Session stats from in-memory state\n const sessionTokens = state.stats.totalPruneTokens\n const sessionSummaryTokens = Array.from(state.prune.messages.blocksById.values()).reduce(\n (total, block) => (block.active ? total + block.summaryTokens : total),\n 0,\n )\n const sessionDurationMs = getActiveCompressionTargets(state.prune.messages).reduce(\n (total, target) => total + target.durationMs,\n 0,\n )\n\n const prunedToolIds = new Set<string>(state.prune.tools.keys())\n for (const block of state.prune.messages.blocksById.values()) {\n if (block.active) {\n for (const toolId of block.effectiveToolIds) {\n prunedToolIds.add(toolId)\n }\n }\n }\n const sessionTools = prunedToolIds.size\n\n let sessionMessages = 0\n for (const entry of state.prune.messages.byMessageId.values()) {\n if (entry.activeBlockIds.length > 0) {\n sessionMessages++\n }\n }\n\n // All-time stats from storage files\n const allTime = await loadAllSessionStats(logger)\n\n const message = formatStatsMessage(\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTime,\n )\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Stats command executed\", {\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTimeTokens: allTime.totalTokens,\n allTimeTools: allTime.totalTools,\n allTimeMessages: allTime.totalMessages,\n })\n}\n","/**\n * DCP Sweep command handler.\n * Prunes tool outputs since the last user message, or the last N tools.\n *\n * Usage:\n * /dcp sweep - Prune all tools since the previous user message\n * /dcp sweep 10 - Prune the last 10 tools\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts, ToolParameterEntry } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatPrunedItemsList } from \"../ui/utils\"\nimport { getCurrentParams, getTotalToolTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { buildToolIdList } from \"../messages/utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { syncToolCache } from \"../state/tool-cache\"\n\nexport interface SweepCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n workingDirectory: string\n}\n\nfunction findLastUserMessageIndex(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return i\n }\n }\n\n return -1\n}\n\nfunction collectToolIdsAfterIndex(\n state: SessionState,\n messages: WithParts[],\n afterIndex: number,\n): string[] {\n const toolIds: string[] = []\n\n for (let i = afterIndex + 1; i < messages.length; i++) {\n const msg = messages[i]\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n\n return toolIds\n}\n\nfunction formatNoUserMessage(): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Nothing swept: no user message found.\")\n\n return lines.join(\"\\n\")\n}\n\nfunction formatSweepMessage(\n toolCount: number,\n tokensSaved: number,\n mode: \"since-user\" | \"last-n\",\n toolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n skippedProtected?: number,\n): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n\n if (toolCount === 0) {\n if (mode === \"since-user\") {\n lines.push(\"No tools found since the previous user message.\")\n } else {\n lines.push(`No tools found to sweep.`)\n }\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n } else {\n if (mode === \"since-user\") {\n lines.push(`Swept ${toolCount} tool(s) since the previous user message.`)\n } else {\n lines.push(`Swept the last ${toolCount} tool(s).`)\n }\n lines.push(`Tokens saved: ~${tokensSaved.toLocaleString()}`)\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n lines.push(\"\")\n const itemLines = formatPrunedItemsList(toolIds, toolMetadata, workingDirectory)\n lines.push(...itemLines)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleSweepCommand(ctx: SweepCommandContext): Promise<void> {\n const { client, state, config, logger, sessionId, messages, args, workingDirectory } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const protectedTools = config.commands.protectedTools\n\n syncToolCache(state, config, logger, messages)\n buildToolIdList(state, messages)\n\n // Parse optional numeric argument\n const numArg = args[0] ? parseInt(args[0], 10) : null\n const isLastNMode = numArg !== null && !isNaN(numArg) && numArg > 0\n\n let toolIdsToSweep: string[]\n let mode: \"since-user\" | \"last-n\"\n\n if (isLastNMode) {\n // Mode: Sweep last N tools\n mode = \"last-n\"\n const startIndex = Math.max(0, state.toolIdList.length - numArg!)\n toolIdsToSweep = state.toolIdList.slice(startIndex)\n logger.info(`Sweep command: last ${numArg} mode, found ${toolIdsToSweep.length} tools`)\n } else {\n // Mode: Sweep since last user message\n mode = \"since-user\"\n const lastUserMsgIndex = findLastUserMessageIndex(messages)\n\n if (lastUserMsgIndex === -1) {\n // No user message found - show message and return\n const message = formatNoUserMessage()\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no user message found\")\n return\n } else {\n toolIdsToSweep = collectToolIdsAfterIndex(state, messages, lastUserMsgIndex)\n logger.info(\n `Sweep command: found last user at index ${lastUserMsgIndex}, sweeping ${toolIdsToSweep.length} tools`,\n )\n }\n }\n\n // Filter out already-pruned tools, protected tools, and protected file paths\n const newToolIds = toolIdsToSweep.filter((id) => {\n if (state.prune.tools.has(id)) {\n return false\n }\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return true\n }\n if (isToolNameProtected(entry.tool, protectedTools)) {\n logger.debug(`Sweep: skipping protected tool ${entry.tool} (${id})`)\n return false\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n logger.debug(`Sweep: skipping protected file path(s) ${filePaths.join(\", \")} (${id})`)\n return false\n }\n return true\n })\n\n // Count how many were skipped due to protection\n const skippedProtected = toolIdsToSweep.filter((id) => {\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return false\n }\n if (isToolNameProtected(entry.tool, protectedTools)) {\n return true\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n return true\n }\n return false\n }).length\n\n if (newToolIds.length === 0) {\n const message = formatSweepMessage(\n 0,\n 0,\n mode,\n [],\n new Map(),\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no new tools to sweep\", { skippedProtected })\n return\n }\n\n const tokensSaved = getTotalToolTokens(state, newToolIds)\n\n // Add to prune list\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n state.stats.pruneTokenCounter += tokensSaved\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n // Collect metadata for logging\n const toolMetadata: Map<string, ToolParameterEntry> = new Map()\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n if (entry) {\n toolMetadata.set(id, entry)\n }\n }\n\n // Persist state\n saveSessionState(state, logger).catch((err) =>\n logger.error(\"Failed to persist state after sweep\", { error: err.message }),\n )\n\n const message = formatSweepMessage(\n newToolIds.length,\n tokensSaved,\n mode,\n newToolIds,\n toolMetadata,\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Sweep command completed\", {\n toolsSwept: newToolIds.length,\n tokensSaved,\n skippedProtected,\n mode,\n tools: Array.from(toolMetadata.entries()).map(([id, entry]) => ({\n id,\n tool: entry.tool,\n })),\n })\n}\n","import type { SessionState, WithParts } from \"./state\"\nimport type { Logger } from \"./logger\"\nimport type { PluginConfig } from \"./config\"\nimport { assignMessageRefs } from \"./message-ids\"\nimport {\n buildPriorityMap,\n buildToolIdList,\n injectCompressNudges,\n injectExtendedSubAgentResults,\n injectMessageIds,\n prune,\n stripHallucinations,\n stripHallucinationsFromString,\n stripStaleMetadata,\n syncCompressionBlocks,\n 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\"\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 const inputBudget = computeInputBudget(input.model.limit)\n if (inputBudget !== undefined) {\n state.modelContextLimit = inputBudget\n }\n logger.debug(\"Cached model context limit\", { limit: state.modelContextLimit })\n }\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n const systemText = output.system.join(\"\\n\")\n if (INTERNAL_AGENT_SIGNATURES.some((sig) => systemText.includes(sig))) {\n logger.info(\"Skipping DCP system prompt injection for internal agent\")\n return\n }\n\n const effectivePermission =\n input.sessionID && state.sessionId === input.sessionID\n ? compressPermission(state, config)\n : config.compress.permission\n\n if (effectivePermission === \"deny\") {\n return\n }\n\n prompts.reload()\n const runtimePrompts = prompts.getRuntimePrompts()\n const newPrompt = renderSystemPrompt(\n runtimePrompts,\n buildProtectedToolsExtension(config.compress.protectedTools),\n !!state.manualMode,\n state.isSubAgent && config.experimental.allowSubAgents,\n )\n if (output.system.length > 0) {\n output.system[output.system.length - 1] += \"\\n\\n\" + newPrompt\n } else {\n output.system.push(newPrompt)\n }\n }\n}\n\nexport function createChatMessageTransformHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (input: {}, output: { messages: WithParts[] }) => {\n const receivedMessages = Array.isArray(output.messages) ? output.messages.length : 0\n const messages = filterMessagesInPlace(output.messages)\n if (messages.length !== receivedMessages) {\n logger.warn(\"Skipping messages with unexpected shape during chat transform\", {\n received: receivedMessages,\n usable: messages.length,\n })\n }\n\n await checkSession(client, state, logger, output.messages, config.manualMode.enabled)\n\n syncCompressPermissionState(state, config, hostPermissions, output.messages)\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n syncCompressionBlocks(state, logger, output.messages)\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n prune(state, logger, config, output.messages)\n await injectExtendedSubAgentResults(\n client,\n state,\n logger,\n output.messages,\n config.experimental.allowSubAgents,\n )\n const compressionPriorities = buildPriorityMap(config, state, output.messages)\n prompts.reload()\n injectCompressNudges(\n state,\n config,\n logger,\n output.messages,\n prompts.getRuntimePrompts(),\n compressionPriorities,\n )\n injectMessageIds(state, config, output.messages, compressionPriorities)\n applyPendingManualTrigger(state, output.messages, logger)\n stripStaleMetadata(output.messages)\n\n if (state.sessionId) {\n await logger.saveContext(state.sessionId, output.messages)\n }\n }\n}\n\nexport function createCommandExecuteHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n workingDirectory: string,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (\n input: { command: string; sessionID: string; arguments: string },\n output: { parts: any[] },\n ) => {\n if (!config.commands.enabled) {\n return\n }\n\n if (input.command === \"dcp\") {\n const messagesResponse = await client.session.messages({\n path: { id: input.sessionID },\n })\n const messages = filterMessages(messagesResponse.data || messagesResponse)\n\n await ensureSessionInitialized(\n client,\n state,\n input.sessionID,\n logger,\n messages,\n config.manualMode.enabled,\n )\n\n syncCompressPermissionState(state, config, hostPermissions, messages)\n\n const effectivePermission = compressPermission(state, config)\n if (effectivePermission === \"deny\") {\n return\n }\n\n const args = (input.arguments || \"\").trim().split(/\\s+/).filter(Boolean)\n const subcommand = args[0]?.toLowerCase() || \"\"\n const subArgs = args.slice(1)\n\n const commandCtx = {\n client,\n state,\n config,\n logger,\n sessionId: input.sessionID,\n messages,\n }\n\n if (subcommand === \"context\") {\n await handleContextCommand(commandCtx)\n throw new Error(\"__DCP_CONTEXT_HANDLED__\")\n }\n\n if (subcommand === \"stats\") {\n await handleStatsCommand(commandCtx)\n throw new Error(\"__DCP_STATS_HANDLED__\")\n }\n\n if (subcommand === \"sweep\") {\n await handleSweepCommand({\n ...commandCtx,\n args: subArgs,\n workingDirectory,\n })\n throw new Error(\"__DCP_SWEEP_HANDLED__\")\n }\n\n if (subcommand === \"manual\") {\n await handleManualToggleCommand(commandCtx, subArgs[0]?.toLowerCase())\n throw new Error(\"__DCP_MANUAL_HANDLED__\")\n }\n\n if (subcommand === \"compress\") {\n const userFocus = subArgs.join(\" \").trim()\n const prompt = await handleManualTriggerCommand(commandCtx, \"compress\", userFocus)\n if (!prompt) {\n throw new Error(\"__DCP_MANUAL_TRIGGER_BLOCKED__\")\n }\n\n state.manualMode = \"compress-pending\"\n state.pendingManualTrigger = {\n sessionId: input.sessionID,\n prompt,\n }\n const rawArgs = (input.arguments || \"\").trim()\n output.parts.length = 0\n output.parts.push({\n type: \"text\",\n text: rawArgs ? `/dcp ${rawArgs}` : `/dcp ${subcommand}`,\n })\n return\n }\n\n if (subcommand === \"decompress\") {\n await handleDecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_DECOMPRESS_HANDLED__\")\n }\n\n if (subcommand === \"recompress\") {\n await handleRecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_RECOMPRESS_HANDLED__\")\n }\n\n await handleHelpCommand(commandCtx)\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n }\n}\n\nexport function createTextCompleteHandler() {\n return async (\n _input: { sessionID: string; messageID: string; partID: string },\n output: { text: string },\n ) => {\n output.text = stripHallucinationsFromString(output.text)\n }\n}\n\nexport function createEventHandler(state: SessionState, logger: Logger) {\n return async (input: { event: any }) => {\n const eventTime =\n typeof input.event?.time === \"number\" && Number.isFinite(input.event.time)\n ? input.event.time\n : typeof input.event?.properties?.time === \"number\" &&\n Number.isFinite(input.event.properties.time)\n ? input.event.properties.time\n : undefined\n\n if (input.event.type !== \"message.part.updated\") {\n return\n }\n\n const part = input.event.properties?.part\n if (part?.type !== \"tool\" || part.tool !== \"compress\") {\n return\n }\n\n if (part.state.status === \"pending\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const startedAt = eventTime ?? Date.now()\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n if (state.compressionTiming.startsByCallId.has(key)) {\n return\n }\n state.compressionTiming.startsByCallId.set(key, startedAt)\n logger.debug(\"Recorded compression start\", {\n messageID: part.messageID,\n callID: part.callID,\n startedAt,\n })\n return\n }\n\n if (part.state.status === \"completed\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n const start = consumeCompressionStart(state, part.messageID, part.callID)\n const durationMs = resolveCompressionDuration(start, eventTime, part.state.time)\n if (typeof durationMs !== \"number\") {\n return\n }\n\n state.compressionTiming.pendingByCallId.set(key, {\n messageId: part.messageID,\n callId: part.callID,\n durationMs,\n })\n\n const updates = applyPendingCompressionDurations(state)\n if (updates === 0) {\n return\n }\n\n await saveSessionState(state, logger)\n\n logger.info(\"Attached compression time to blocks\", {\n messageID: part.messageID,\n callID: part.callID,\n blocks: updates,\n durationMs,\n })\n return\n }\n\n if (part.state.status === \"running\") {\n return\n }\n\n if (typeof part.callID === \"string\" && typeof part.messageID === \"string\") {\n state.compressionTiming.startsByCallId.delete(\n buildCompressionTimingKey(part.messageID, part.callID),\n )\n }\n }\n}\n","export function isSecureMode(): boolean {\n return !!process.env.OPENCODE_SERVER_PASSWORD\n}\n\nexport function getAuthorizationHeader(): string | undefined {\n const password = process.env.OPENCODE_SERVER_PASSWORD\n if (!password) return undefined\n\n const username = process.env.OPENCODE_SERVER_USERNAME ?? \"opencode\"\n // Use Buffer for Node.js base64 encoding (btoa may not be available in all Node versions)\n const credentials = Buffer.from(`${username}:${password}`).toString(\"base64\")\n return `Basic ${credentials}`\n}\n\nexport function configureClientAuth(client: any): any {\n const authHeader = getAuthorizationHeader()\n\n if (!authHeader) {\n return client\n }\n\n // The SDK client has an internal client with request interceptors\n // Access the underlying client to add the interceptor\n const innerClient = client._client || client.client\n\n if (innerClient?.interceptors?.request) {\n innerClient.interceptors.request.use((request: Request) => {\n // Only add auth header if not already present\n if (!request.headers.has(\"Authorization\")) {\n request.headers.set(\"Authorization\", authHeader)\n }\n return request\n })\n }\n\n return client\n}\n","import { readFile, rm } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { updated: true; name: string; current: string; latest: string }\n | { updated: false; error: \"remove_failed\"; name: string; current: string; latest: string }\n | { updated: false }\n\nconst PACKAGE_NAME = \"@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: \"DCP update ready\",\n message: `Updated ${result.name} from ${result.current} to ${result.latest}. Restart OpenCode to finish.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { updated: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { updated: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { updated: false }\n\n const removeDir = await updateRemoveDir(packageDir, pkg.name)\n if (!removeDir) return { updated: false }\n\n try {\n await rm(removeDir, { recursive: true, force: true })\n } catch {\n return {\n updated: false,\n error: \"remove_failed\",\n name: pkg.name,\n current: pkg.version,\n latest,\n }\n }\n\n return { updated: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function updateRemoveDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"./lib/config\"\nimport { createCompressMessageTool, createCompressRangeTool } from \"./lib/compress\"\nimport {\n compressDisabledByOpencode,\n hasExplicitToolPermission,\n type HostPermissionSnapshot,\n} from \"./lib/host-permissions\"\nimport { Logger } from \"./lib/logger\"\nimport { createSessionState } from \"./lib/state\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport {\n createChatMessageTransformHandler,\n createCommandExecuteHandler,\n createEventHandler,\n createSystemPromptHandler,\n createTextCompleteHandler,\n} from \"./lib/hooks\"\nimport { configureClientAuth, isSecureMode } from \"./lib/auth\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n\n if (!config.enabled) {\n return {}\n }\n\n const logger = new Logger(config.debug)\n const state = createSessionState()\n const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts)\n const hostPermissions: HostPermissionSnapshot = {\n global: undefined,\n agents: {},\n }\n\n if (isSecureMode()) {\n configureClientAuth(ctx.client)\n // logger.info(\"Secure mode detected, configured client authentication\")\n }\n\n logger.info(\"DCP initialized\", {\n strategies: config.strategies,\n })\n\n startAutoUpdate(ctx, config.autoUpdate)\n\n const compressToolContext = {\n client: ctx.client,\n state,\n logger,\n config,\n prompts,\n }\n\n return {\n \"experimental.chat.system.transform\": createSystemPromptHandler(\n state,\n logger,\n config,\n prompts,\n ),\n \"experimental.chat.messages.transform\": createChatMessageTransformHandler(\n ctx.client,\n state,\n logger,\n config,\n prompts,\n hostPermissions,\n ) as any,\n \"experimental.text.complete\": createTextCompleteHandler(),\n \"command.execute.before\": createCommandExecuteHandler(\n ctx.client,\n state,\n logger,\n config,\n ctx.directory,\n hostPermissions,\n ),\n event: createEventHandler(state, logger),\n tool: {\n ...(config.compress.permission !== \"deny\" && {\n compress:\n config.compress.mode === \"message\"\n ? createCompressMessageTool(compressToolContext)\n : createCompressRangeTool(compressToolContext),\n }),\n },\n config: async (opencodeConfig) => {\n if (\n config.compress.permission !== \"deny\" &&\n compressDisabledByOpencode(opencodeConfig.permission)\n ) {\n config.compress.permission = \"deny\"\n }\n\n if (config.commands.enabled && config.compress.permission !== \"deny\") {\n opencodeConfig.command ??= {}\n opencodeConfig.command[\"dcp\"] = {\n template: \"\",\n description: \"Show available DCP commands\",\n }\n }\n\n const toolsToAdd: string[] = []\n if (config.compress.permission !== \"deny\" && !config.experimental.allowSubAgents) {\n toolsToAdd.push(\"compress\")\n }\n\n if (toolsToAdd.length > 0) {\n const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? []\n opencodeConfig.experimental = {\n ...opencodeConfig.experimental,\n primary_tools: [...existingPrimaryTools, ...toolsToAdd],\n }\n }\n\n if (!hasExplicitToolPermission(opencodeConfig.permission, \"compress\")) {\n const permission = opencodeConfig.permission ?? {}\n opencodeConfig.permission = {\n ...permission,\n compress: config.compress.permission,\n } as typeof permission\n }\n\n hostPermissions.global = opencodeConfig.permission\n hostPermissions.agents = Object.fromEntries(\n Object.entries(opencodeConfig.agent ?? {}).map(([name, agent]) => [\n name,\n agent?.permission,\n ]),\n )\n },\n }\n}) satisfies Plugin\n\nexport default server\n"],"mappings":";AAAA,SAAS,cAAc,eAAe,YAAY,WAAW,gBAAgB;AAC7E,SAAS,MAAM,eAAe;AAC9B,SAAS,eAAe;;;ACOjB,SAAS,cAAc,MAAM,eAAe,OAAO;AACtD,QAAM,MAAM,KAAK;AACjB,MAAI,MAAM,GAAG,QAAQ,IAAI,cAAc,GAAG,QAAQ,IAA6B,aAAa,GAAG,kBAAkB,GAAG,uBAAuB,GAAG,2BAA2B,GAAG,YAAY;AACxL,WAAS,cAAc,OAAO,OAAO;AACjC,QAAI,SAAS;AACb,QAAIA,SAAQ;AACZ,WAAO,SAAS,SAAS,CAAC,OAAO;AAC7B,UAAI,KAAK,KAAK,WAAW,GAAG;AAC5B,UAAI,MAAM,MAA8B,MAAM,IAA4B;AACtE,QAAAA,SAAQA,SAAQ,KAAK,KAAK;AAAA,MAC9B,WACS,MAAM,MAA6B,MAAM,IAA2B;AACzE,QAAAA,SAAQA,SAAQ,KAAK,KAAK,KAA4B;AAAA,MAC1D,WACS,MAAM,MAA6B,MAAM,KAA4B;AAC1E,QAAAA,SAAQA,SAAQ,KAAK,KAAK,KAA4B;AAAA,MAC1D,OACK;AACD;AAAA,MACJ;AACA;AACA;AAAA,IACJ;AACA,QAAI,SAAS,OAAO;AAChB,MAAAA,SAAQ;AAAA,IACZ;AACA,WAAOA;AAAA,EACX;AACA,WAAS,YAAY,aAAa;AAC9B,UAAM;AACN,YAAQ;AACR,kBAAc;AACd,YAAQ;AACR,gBAAY;AAAA,EAChB;AACA,WAAS,aAAa;AAClB,QAAI,QAAQ;AACZ,QAAI,KAAK,WAAW,GAAG,MAAM,IAA4B;AACrD;AAAA,IACJ,OACK;AACD;AACA,aAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AACvD;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,MAAM,KAAK,UAAU,KAAK,WAAW,GAAG,MAAM,IAA6B;AAC3E;AACA,UAAI,MAAM,KAAK,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AACpD;AACA,eAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AACvD;AAAA,QACJ;AAAA,MACJ,OACK;AACD,oBAAY;AACZ,eAAO,KAAK,UAAU,OAAO,GAAG;AAAA,MACpC;AAAA,IACJ;AACA,QAAI,MAAM;AACV,QAAI,MAAM,KAAK,WAAW,KAAK,WAAW,GAAG,MAAM,MAA6B,KAAK,WAAW,GAAG,MAAM,MAA6B;AAClI;AACA,UAAI,MAAM,KAAK,UAAU,KAAK,WAAW,GAAG,MAAM,MAAgC,KAAK,WAAW,GAAG,MAAM,IAA+B;AACtI;AAAA,MACJ;AACA,UAAI,MAAM,KAAK,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AACpD;AACA,eAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AACvD;AAAA,QACJ;AACA,cAAM;AAAA,MACV,OACK;AACD,oBAAY;AAAA,MAChB;AAAA,IACJ;AACA,WAAO,KAAK,UAAU,OAAO,GAAG;AAAA,EACpC;AACA,WAAS,aAAa;AAClB,QAAI,SAAS,IAAI,QAAQ;AACzB,WAAO,MAAM;AACT,UAAI,OAAO,KAAK;AACZ,kBAAU,KAAK,UAAU,OAAO,GAAG;AACnC,oBAAY;AACZ;AAAA,MACJ;AACA,YAAM,KAAK,KAAK,WAAW,GAAG;AAC9B,UAAI,OAAO,IAAqC;AAC5C,kBAAU,KAAK,UAAU,OAAO,GAAG;AACnC;AACA;AAAA,MACJ;AACA,UAAI,OAAO,IAAmC;AAC1C,kBAAU,KAAK,UAAU,OAAO,GAAG;AACnC;AACA,YAAI,OAAO,KAAK;AACZ,sBAAY;AACZ;AAAA,QACJ;AACA,cAAM,MAAM,KAAK,WAAW,KAAK;AACjC,gBAAQ,KAAK;AAAA,UACT,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,sBAAU;AACV;AAAA,UACJ,KAAK;AACD,kBAAM,MAAM,cAAc,GAAG,IAAI;AACjC,gBAAI,OAAO,GAAG;AACV,wBAAU,OAAO,aAAa,GAAG;AAAA,YACrC,OACK;AACD,0BAAY;AAAA,YAChB;AACA;AAAA,UACJ;AACI,wBAAY;AAAA,QACpB;AACA,gBAAQ;AACR;AAAA,MACJ;AACA,UAAI,MAAM,KAAK,MAAM,IAAM;AACvB,YAAI,YAAY,EAAE,GAAG;AACjB,oBAAU,KAAK,UAAU,OAAO,GAAG;AACnC,sBAAY;AACZ;AAAA,QACJ,OACK;AACD,sBAAY;AAAA,QAEhB;AAAA,MACJ;AACA;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AACA,WAAS,WAAW;AAChB,YAAQ;AACR,gBAAY;AACZ,kBAAc;AACd,sBAAkB;AAClB,+BAA2B;AAC3B,QAAI,OAAO,KAAK;AAEZ,oBAAc;AACd,aAAO,QAAQ;AAAA,IACnB;AACA,QAAI,OAAO,KAAK,WAAW,GAAG;AAE9B,QAAI,aAAa,IAAI,GAAG;AACpB,SAAG;AACC;AACA,iBAAS,OAAO,aAAa,IAAI;AACjC,eAAO,KAAK,WAAW,GAAG;AAAA,MAC9B,SAAS,aAAa,IAAI;AAC1B,aAAO,QAAQ;AAAA,IACnB;AAEA,QAAI,YAAY,IAAI,GAAG;AACnB;AACA,eAAS,OAAO,aAAa,IAAI;AACjC,UAAI,SAAS,MAA0C,KAAK,WAAW,GAAG,MAAM,IAAkC;AAC9G;AACA,iBAAS;AAAA,MACb;AACA;AACA,6BAAuB;AACvB,aAAO,QAAQ;AAAA,IACnB;AACA,YAAQ,MAAM;AAAA;AAAA,MAEV,KAAK;AACD;AACA,eAAO,QAAQ;AAAA,MACnB,KAAK;AACD;AACA,eAAO,QAAQ;AAAA,MACnB,KAAK;AACD;AACA,eAAO,QAAQ;AAAA,MACnB,KAAK;AACD;AACA,eAAO,QAAQ;AAAA,MACnB,KAAK;AACD;AACA,eAAO,QAAQ;AAAA,MACnB,KAAK;AACD;AACA,eAAO,QAAQ;AAAA;AAAA,MAEnB,KAAK;AACD;AACA,gBAAQ,WAAW;AACnB,eAAO,QAAQ;AAAA;AAAA,MAEnB,KAAK;AACD,cAAM,QAAQ,MAAM;AAEpB,YAAI,KAAK,WAAW,MAAM,CAAC,MAAM,IAA+B;AAC5D,iBAAO;AACP,iBAAO,MAAM,KAAK;AACd,gBAAI,YAAY,KAAK,WAAW,GAAG,CAAC,GAAG;AACnC;AAAA,YACJ;AACA;AAAA,UACJ;AACA,kBAAQ,KAAK,UAAU,OAAO,GAAG;AACjC,iBAAO,QAAQ;AAAA,QACnB;AAEA,YAAI,KAAK,WAAW,MAAM,CAAC,MAAM,IAAkC;AAC/D,iBAAO;AACP,gBAAM,aAAa,MAAM;AACzB,cAAI,gBAAgB;AACpB,iBAAO,MAAM,YAAY;AACrB,kBAAM,KAAK,KAAK,WAAW,GAAG;AAC9B,gBAAI,OAAO,MAAoC,KAAK,WAAW,MAAM,CAAC,MAAM,IAA+B;AACvG,qBAAO;AACP,8BAAgB;AAChB;AAAA,YACJ;AACA;AACA,gBAAI,YAAY,EAAE,GAAG;AACjB,kBAAI,OAAO,MAA0C,KAAK,WAAW,GAAG,MAAM,IAAkC;AAC5G;AAAA,cACJ;AACA;AACA,qCAAuB;AAAA,YAC3B;AAAA,UACJ;AACA,cAAI,CAAC,eAAe;AAChB;AACA,wBAAY;AAAA,UAChB;AACA,kBAAQ,KAAK,UAAU,OAAO,GAAG;AACjC,iBAAO,QAAQ;AAAA,QACnB;AAEA,iBAAS,OAAO,aAAa,IAAI;AACjC;AACA,eAAO,QAAQ;AAAA;AAAA,MAEnB,KAAK;AACD,iBAAS,OAAO,aAAa,IAAI;AACjC;AACA,YAAI,QAAQ,OAAO,CAAC,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;AAC/C,iBAAO,QAAQ;AAAA,QACnB;AAAA;AAAA;AAAA;AAAA,MAIJ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACD,iBAAS,WAAW;AACpB,eAAO,QAAQ;AAAA;AAAA,MAEnB;AAEI,eAAO,MAAM,OAAO,0BAA0B,IAAI,GAAG;AACjD;AACA,iBAAO,KAAK,WAAW,GAAG;AAAA,QAC9B;AACA,YAAI,gBAAgB,KAAK;AACrB,kBAAQ,KAAK,UAAU,aAAa,GAAG;AAEvC,kBAAQ,OAAO;AAAA,YACX,KAAK;AAAQ,qBAAO,QAAQ;AAAA,YAC5B,KAAK;AAAS,qBAAO,QAAQ;AAAA,YAC7B,KAAK;AAAQ,qBAAO,QAAQ;AAAA,UAChC;AACA,iBAAO,QAAQ;AAAA,QACnB;AAEA,iBAAS,OAAO,aAAa,IAAI;AACjC;AACA,eAAO,QAAQ;AAAA,IACvB;AAAA,EACJ;AACA,WAAS,0BAA0B,MAAM;AACrC,QAAI,aAAa,IAAI,KAAK,YAAY,IAAI,GAAG;AACzC,aAAO;AAAA,IACX;AACA,YAAQ,MAAM;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACD,eAAO;AAAA,IACf;AACA,WAAO;AAAA,EACX;AACA,WAAS,oBAAoB;AACzB,QAAI;AACJ,OAAG;AACC,eAAS,SAAS;AAAA,IACtB,SAAS,UAAU,MAAyC,UAAU;AACtE,WAAO;AAAA,EACX;AACA,SAAO;AAAA,IACH;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,MAAM,eAAe,oBAAoB;AAAA,IACzC,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,IACrB,gBAAgB,MAAM;AAAA,IACtB,gBAAgB,MAAM,MAAM;AAAA,IAC5B,mBAAmB,MAAM;AAAA,IACzB,wBAAwB,MAAM,cAAc;AAAA,IAC5C,eAAe,MAAM;AAAA,EACzB;AACJ;AACA,SAAS,aAAa,IAAI;AACtB,SAAO,OAAO,MAAiC,OAAO;AAC1D;AACA,SAAS,YAAY,IAAI;AACrB,SAAO,OAAO,MAAoC,OAAO;AAC7D;AACA,SAAS,QAAQ,IAAI;AACjB,SAAO,MAAM,MAA8B,MAAM;AACrD;AACA,IAAI;AAAA,CACH,SAAUC,iBAAgB;AACvB,EAAAA,gBAAeA,gBAAe,UAAU,IAAI,EAAE,IAAI;AAClD,EAAAA,gBAAeA,gBAAe,gBAAgB,IAAI,EAAE,IAAI;AACxD,EAAAA,gBAAeA,gBAAe,OAAO,IAAI,EAAE,IAAI;AAC/C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAA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","names":["value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","parse","countTokens","existsSync","homedir","join","countTokens","join","homedir","existsSync","tool","tool","tool","countTokens","countTokens","tool","validateArgs","buildSchema","tool","validateArgs","countTokens","tool","writeFile","mkdir","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","countTokens","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","message","readFile","dirname","join"]}
|
|
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/hooks.ts","../lib/auth.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport { parse } from \"jsonc-parser/lib/esm/main.js\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\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 PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n pruneNotification: \"off\" | \"minimal\" | \"detailed\"\n pruneNotificationType: \"chat\" | \"toast\"\n commands: Commands\n manualMode: ManualModeConfig\n turnProtection: TurnProtection\n experimental: ExperimentalConfig\n protectedFilePatterns: string[]\n compress: CompressConfig\n strategies: {\n deduplication: Deduplication\n purgeErrors: PurgeErrors\n }\n}\n\ntype CompressOverride = Partial<CompressConfig>\n\nconst DEFAULT_PROTECTED_TOOLS = [\n \"task\",\n \"skill\",\n \"todowrite\",\n \"todoread\",\n \"compress\",\n \"batch\",\n \"plan_enter\",\n \"plan_exit\",\n \"write\",\n \"edit\",\n]\n\nconst COMPRESS_DEFAULT_PROTECTED_TOOLS = [\"task\", \"skill\", \"todowrite\", \"todoread\"]\n\nexport const VALID_CONFIG_KEYS = new Set([\n \"$schema\",\n \"enabled\",\n \"autoUpdate\",\n \"debug\",\n \"showUpdateToasts\",\n \"pruneNotification\",\n \"pruneNotificationType\",\n \"turnProtection\",\n \"turnProtection.enabled\",\n \"turnProtection.turns\",\n \"experimental\",\n \"experimental.allowSubAgents\",\n \"experimental.customPrompts\",\n \"protectedFilePatterns\",\n \"commands\",\n \"commands.enabled\",\n \"commands.protectedTools\",\n \"manualMode\",\n \"manualMode.enabled\",\n \"manualMode.automaticStrategies\",\n \"compress\",\n \"compress.mode\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.modelMaxLimits\",\n \"compress.modelMinLimits\",\n \"compress.nudgeFrequency\",\n \"compress.iterationNudgeThreshold\",\n \"compress.nudgeForce\",\n \"compress.protectedTools\",\n \"compress.protectTags\",\n \"compress.protectUserMessages\",\n \"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 strategies = config.strategies\n if (strategies) {\n if (\n strategies.deduplication?.enabled !== undefined &&\n typeof strategies.deduplication.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.deduplication.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.deduplication.enabled,\n })\n }\n\n if (\n strategies.deduplication?.protectedTools !== undefined &&\n !Array.isArray(strategies.deduplication.protectedTools)\n ) {\n errors.push({\n key: \"strategies.deduplication.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.deduplication.protectedTools,\n })\n }\n\n if (strategies.purgeErrors) {\n if (\n strategies.purgeErrors.enabled !== undefined &&\n typeof strategies.purgeErrors.enabled !== \"boolean\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.enabled\",\n expected: \"boolean\",\n actual: typeof strategies.purgeErrors.enabled,\n })\n }\n\n if (\n strategies.purgeErrors.turns !== undefined &&\n typeof strategies.purgeErrors.turns !== \"number\"\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"number\",\n actual: typeof strategies.purgeErrors.turns,\n })\n }\n // Warn if turns is 0 or negative - will be clamped to 1\n if (\n typeof strategies.purgeErrors.turns === \"number\" &&\n strategies.purgeErrors.turns < 1\n ) {\n errors.push({\n key: \"strategies.purgeErrors.turns\",\n expected: \"positive number (>= 1)\",\n actual: `${strategies.purgeErrors.turns} (will be clamped to 1)`,\n })\n }\n if (\n strategies.purgeErrors.protectedTools !== undefined &&\n !Array.isArray(strategies.purgeErrors.protectedTools)\n ) {\n errors.push({\n key: \"strategies.purgeErrors.protectedTools\",\n expected: \"string[]\",\n actual: typeof strategies.purgeErrors.protectedTools,\n })\n }\n }\n }\n\n return errors\n}\n\nfunction showConfigWarnings(\n ctx: PluginInput,\n configPath: string,\n configData: Record<string, any>,\n isProject: boolean,\n): void {\n const invalidKeys = getInvalidConfigKeys(configData)\n const typeErrors = validateConfigTypes(configData)\n\n if (invalidKeys.length === 0 && typeErrors.length === 0) {\n return\n }\n\n const configType = isProject ? \"project config\" : \"config\"\n const messages: string[] = []\n\n if (invalidKeys.length > 0) {\n const keyList = invalidKeys.slice(0, 3).join(\", \")\n const suffix = invalidKeys.length > 3 ? ` (+${invalidKeys.length - 3} more)` : \"\"\n messages.push(`Unknown keys: ${keyList}${suffix}`)\n }\n\n if (typeErrors.length > 0) {\n for (const err of typeErrors.slice(0, 2)) {\n messages.push(`${err.key}: expected ${err.expected}, got ${err.actual}`)\n }\n if (typeErrors.length > 2) {\n messages.push(`(+${typeErrors.length - 2} more type errors)`)\n }\n }\n\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title: `DCP: ${configType} warning`,\n message: `${configPath}\\n${messages.join(\"\\n\")}`,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nconst defaultConfig: PluginConfig = {\n enabled: true,\n autoUpdate: true,\n debug: false,\n pruneNotification: \"detailed\",\n pruneNotificationType: \"chat\",\n commands: {\n enabled: true,\n protectedTools: [...DEFAULT_PROTECTED_TOOLS],\n },\n manualMode: {\n enabled: false,\n automaticStrategies: true,\n },\n turnProtection: {\n enabled: false,\n turns: 4,\n },\n experimental: {\n allowSubAgents: false,\n customPrompts: false,\n },\n protectedFilePatterns: [],\n compress: {\n mode: \"range\",\n permission: \"allow\",\n showCompression: false,\n summaryBuffer: true,\n maxContextLimit: 100000,\n minContextLimit: 50000,\n nudgeFrequency: 5,\n iterationNudgeThreshold: 15,\n nudgeForce: \"soft\",\n protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],\n protectTags: false,\n protectUserMessages: false,\n },\n strategies: {\n deduplication: {\n enabled: true,\n protectedTools: [],\n },\n purgeErrors: {\n enabled: true,\n turns: 4,\n protectedTools: [],\n },\n },\n}\n\nconst GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, \"opencode\")\n : join(homedir(), \".config\", \"opencode\")\nconst GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.json\")\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate) && statSync(candidate).isDirectory()) {\n return candidate\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction getConfigPaths(ctx?: PluginInput): {\n global: string | null\n configDir: string | null\n project: string | null\n} {\n const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)\n ? GLOBAL_CONFIG_PATH_JSONC\n : existsSync(GLOBAL_CONFIG_PATH_JSON)\n ? GLOBAL_CONFIG_PATH_JSON\n : null\n\n let configDir: string | null = null\n const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR\n if (opencodeConfigDir) {\n const configJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : null\n }\n\n let project: string | null = null\n if (ctx?.directory) {\n const opencodeDir = findOpencodeDir(ctx.directory)\n if (opencodeDir) {\n const projectJsonc = join(opencodeDir, \"dcp.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : null\n }\n }\n\n return { global, configDir, project }\n}\n\nfunction createDefaultConfig(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/Opencode-DCP/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n}\n\ninterface ConfigLoadResult {\n data: Record<string, any> | null\n parseError?: string\n}\n\nfunction loadConfigFile(configPath: string): ConfigLoadResult {\n let fileContent = \"\"\n try {\n fileContent = readFileSync(configPath, \"utf-8\")\n } catch {\n return { data: null }\n }\n\n try {\n const parsed = parse(fileContent, undefined, { allowTrailingComma: true })\n if (parsed === undefined || parsed === null) {\n return { data: null, parseError: \"Config file is empty or invalid\" }\n }\n return { data: parsed }\n } catch (error: any) {\n return { data: null, parseError: error.message || \"Failed to parse config\" }\n }\n}\n\nfunction mergeStrategies(\n base: PluginConfig[\"strategies\"],\n override?: Partial<PluginConfig[\"strategies\"]>,\n): PluginConfig[\"strategies\"] {\n if (!override) {\n return base\n }\n\n return {\n deduplication: {\n enabled: override.deduplication?.enabled ?? base.deduplication.enabled,\n protectedTools: [\n ...new Set([\n ...base.deduplication.protectedTools,\n ...(override.deduplication?.protectedTools ?? []),\n ]),\n ],\n },\n purgeErrors: {\n enabled: override.purgeErrors?.enabled ?? base.purgeErrors.enabled,\n turns: override.purgeErrors?.turns ?? base.purgeErrors.turns,\n protectedTools: [\n ...new Set([\n ...base.purgeErrors.protectedTools,\n ...(override.purgeErrors?.protectedTools ?? []),\n ]),\n ],\n },\n }\n}\n\nfunction mergeCompress(\n base: PluginConfig[\"compress\"],\n override?: CompressOverride,\n): PluginConfig[\"compress\"] {\n if (!override) {\n return base\n }\n\n return {\n mode: override.mode ?? base.mode,\n permission: override.permission ?? base.permission,\n showCompression: override.showCompression ?? base.showCompression,\n summaryBuffer: override.summaryBuffer ?? base.summaryBuffer,\n maxContextLimit: override.maxContextLimit ?? base.maxContextLimit,\n minContextLimit: override.minContextLimit ?? base.minContextLimit,\n modelMaxLimits: override.modelMaxLimits ?? base.modelMaxLimits,\n modelMinLimits: override.modelMinLimits ?? base.modelMinLimits,\n nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,\n iterationNudgeThreshold: override.iterationNudgeThreshold ?? base.iterationNudgeThreshold,\n nudgeForce: override.nudgeForce ?? base.nudgeForce,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n protectTags: override.protectTags ?? base.protectTags,\n protectUserMessages: override.protectUserMessages ?? base.protectUserMessages,\n }\n}\n\nfunction mergeCommands(\n base: PluginConfig[\"commands\"],\n override?: Partial<PluginConfig[\"commands\"]>,\n): PluginConfig[\"commands\"] {\n if (!override) {\n return base\n }\n\n return {\n enabled: override.enabled ?? base.enabled,\n protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],\n }\n}\n\nfunction mergeManualMode(\n base: PluginConfig[\"manualMode\"],\n override?: Partial<PluginConfig[\"manualMode\"]>,\n): PluginConfig[\"manualMode\"] {\n if (override === undefined) return base\n\n return {\n enabled: override.enabled ?? base.enabled,\n automaticStrategies: override.automaticStrategies ?? base.automaticStrategies,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (override === undefined) return base\n\n return {\n allowSubAgents: override.allowSubAgents ?? base.allowSubAgents,\n customPrompts: override.customPrompts ?? base.customPrompts,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: {\n enabled: config.commands.enabled,\n protectedTools: [...config.commands.protectedTools],\n },\n manualMode: {\n enabled: config.manualMode.enabled,\n automaticStrategies: config.manualMode.automaticStrategies,\n },\n turnProtection: { ...config.turnProtection },\n experimental: { ...config.experimental },\n protectedFilePatterns: [...config.protectedFilePatterns],\n compress: {\n ...config.compress,\n modelMaxLimits: { ...config.compress.modelMaxLimits },\n modelMinLimits: { ...config.compress.modelMinLimits },\n protectedTools: [...config.compress.protectedTools],\n },\n strategies: {\n deduplication: {\n ...config.strategies.deduplication,\n protectedTools: [...config.strategies.deduplication.protectedTools],\n },\n purgeErrors: {\n ...config.strategies.purgeErrors,\n protectedTools: [...config.strategies.purgeErrors.protectedTools],\n },\n },\n }\n}\n\nfunction mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConfig {\n return {\n enabled: data.enabled ?? config.enabled,\n autoUpdate: data.autoUpdate ?? config.autoUpdate,\n debug: data.debug ?? config.debug,\n pruneNotification: data.pruneNotification ?? config.pruneNotification,\n pruneNotificationType: data.pruneNotificationType ?? config.pruneNotificationType,\n commands: mergeCommands(config.commands, data.commands as any),\n manualMode: mergeManualMode(config.manualMode, data.manualMode as any),\n turnProtection: {\n enabled: data.turnProtection?.enabled ?? config.turnProtection.enabled,\n turns: data.turnProtection?.turns ?? config.turnProtection.turns,\n },\n experimental: mergeExperimental(config.experimental, data.experimental as any),\n protectedFilePatterns: [\n ...new Set([...config.protectedFilePatterns, ...(data.protectedFilePatterns ?? [])]),\n ],\n compress: mergeCompress(config.compress, data.compress as CompressOverride),\n strategies: mergeStrategies(config.strategies, data.strategies as any),\n }\n}\n\nfunction scheduleParseWarning(ctx: PluginInput, title: string, message: string): void {\n setTimeout(() => {\n try {\n ctx.client.tui.showToast({\n body: {\n title,\n message,\n variant: \"warning\",\n duration: 7000,\n },\n })\n } catch {}\n }, 7000)\n}\n\nexport function getConfig(ctx: PluginInput): PluginConfig {\n let config = deepCloneConfig(defaultConfig)\n const configPaths = getConfigPaths(ctx)\n\n if (!configPaths.global) {\n createDefaultConfig()\n }\n\n const layers: Array<{ path: string | null; name: string; isProject: boolean }> = [\n { path: configPaths.global, name: \"config\", isProject: false },\n { path: configPaths.configDir, name: \"configDir config\", isProject: true },\n { path: configPaths.project, name: \"project config\", isProject: true },\n ]\n\n for (const layer of layers) {\n if (!layer.path) {\n continue\n }\n\n const result = loadConfigFile(layer.path)\n if (result.parseError) {\n scheduleParseWarning(\n ctx,\n `DCP: Invalid ${layer.name}`,\n `${layer.path}\\n${result.parseError}\\nUsing previous/default values`,\n )\n continue\n }\n\n if (!result.data) {\n continue\n }\n\n showConfigWarnings(ctx, layer.path, result.data, layer.isProject)\n config = mergeLayer(config, result.data)\n }\n\n 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 )\n\n notifications.push({\n blockId,\n runId,\n summary: summaryWithTools,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return formatResult(plans.length, skippedIssues, skippedCount)\n },\n })\n}\n","import { SessionState, WithParts } from \"./state\"\nimport { AssistantMessage, UserMessage } from \"@opencode-ai/sdk/v2\"\nimport { Logger } from \"./logger\"\nimport * as _anthropicTokenizer from \"@anthropic-ai/tokenizer\"\nconst anthropicCountTokens = (_anthropicTokenizer.countTokens ??\n (_anthropicTokenizer as any).default?.countTokens) as typeof _anthropicTokenizer.countTokens\nimport { getLastUserMessage } from \"./messages/query\"\n\nexport function getCurrentTokenUsage(state: SessionState, messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role !== \"assistant\") {\n continue\n }\n\n const assistantInfo = msg.info as AssistantMessage\n if ((assistantInfo.tokens?.output || 0) <= 0) {\n continue\n }\n\n if (\n state.lastCompaction > 0 &&\n (msg.info.time.created < state.lastCompaction ||\n (msg.info.summary === true && msg.info.time.created === state.lastCompaction))\n ) {\n return 0\n }\n\n const input = assistantInfo.tokens?.input || 0\n const output = assistantInfo.tokens?.output || 0\n const reasoning = assistantInfo.tokens?.reasoning || 0\n const cacheRead = assistantInfo.tokens?.cache?.read || 0\n const cacheWrite = assistantInfo.tokens?.cache?.write || 0\n return input + output + reasoning + cacheRead + cacheWrite\n }\n\n return 0\n}\n\nexport function getCurrentParams(\n state: SessionState,\n messages: WithParts[],\n logger: Logger,\n): {\n providerId: string | undefined\n modelId: string | undefined\n agent: string | undefined\n variant: string | undefined\n} {\n const userMsg = getLastUserMessage(messages)\n if (!userMsg) {\n logger.debug(\"No user message found when determining current params\")\n return {\n providerId: undefined,\n modelId: undefined,\n agent: undefined,\n variant: undefined,\n }\n }\n const userInfo = userMsg.info as UserMessage\n const agent: string = userInfo.agent\n const providerId: string | undefined = userInfo.model.providerID\n const modelId: string | undefined = userInfo.model.modelID\n const variant: string | undefined = userInfo.model.variant\n\n return { providerId, modelId, agent, variant }\n}\n\nexport function countTokens(text: string): number {\n if (!text) return 0\n try {\n return anthropicCountTokens(text)\n } catch {\n return Math.round(text.length / 4)\n }\n}\n\nexport function estimateTokensBatch(texts: string[]): number {\n if (texts.length === 0) return 0\n return countTokens(texts.join(\" \"))\n}\n\nexport const COMPACTED_TOOL_OUTPUT_PLACEHOLDER = \"[Old tool result content cleared]\"\n\nfunction stringifyToolContent(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value)\n}\n\nexport function extractCompletedToolOutput(part: any): string | undefined {\n if (\n part?.type !== \"tool\" ||\n part.state?.status !== \"completed\" ||\n part.state?.output === undefined\n ) {\n return undefined\n }\n\n if (part.state?.time?.compacted) {\n return COMPACTED_TOOL_OUTPUT_PLACEHOLDER\n }\n\n return stringifyToolContent(part.state.output)\n}\n\nexport function extractToolContent(part: any): string[] {\n const contents: string[] = []\n\n if (part?.type !== \"tool\") {\n return contents\n }\n\n if (part.state?.input !== undefined) {\n contents.push(stringifyToolContent(part.state.input))\n }\n\n const completedOutput = extractCompletedToolOutput(part)\n if (completedOutput !== undefined) {\n contents.push(completedOutput)\n } else if (part.state?.status === \"error\" && part.state?.error) {\n contents.push(stringifyToolContent(part.state.error))\n }\n\n return contents\n}\n\nexport function countToolTokens(part: any): number {\n const contents = extractToolContent(part)\n return estimateTokensBatch(contents)\n}\n\nexport function getTotalToolTokens(state: SessionState, toolIds: string[]): number {\n let total = 0\n for (const id of toolIds) {\n const entry = state.toolParameters.get(id)\n total += entry?.tokenCount ?? 0\n }\n return total\n}\n\nexport function countMessageTextTokens(msg: WithParts): number {\n const texts: string[] = []\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n\nexport function countAllMessageTokens(msg: WithParts): number {\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const texts: string[] = []\n for (const part of parts) {\n if (part.type === \"text\") {\n texts.push(part.text)\n } else {\n texts.push(...extractToolContent(part))\n }\n }\n if (texts.length === 0) return 0\n return estimateTokensBatch(texts)\n}\n","import type { WithParts } from \"../state\"\n\nexport function isMessageWithInfo(message: unknown): message is WithParts {\n if (!message || typeof message !== \"object\") {\n return false\n }\n\n const info = (message as any).info\n const parts = (message as any).parts\n if (!info || typeof info !== \"object\") {\n return false\n }\n\n return (\n typeof info.id === \"string\" &&\n info.id.length > 0 &&\n typeof info.sessionID === \"string\" &&\n info.sessionID.length > 0 &&\n (info.role === \"user\" || info.role === \"assistant\") &&\n info.time &&\n typeof info.time === \"object\" &&\n typeof info.time.created === \"number\" &&\n Array.isArray(parts)\n )\n}\n\nexport function filterMessages(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n return messages.filter(isMessageWithInfo)\n}\n\nexport function filterMessagesInPlace(messages: unknown): WithParts[] {\n if (!Array.isArray(messages)) {\n return []\n }\n\n let writeIndex = 0\n\n for (const message of messages) {\n if (isMessageWithInfo(message)) {\n messages[writeIndex++] = message\n }\n }\n\n messages.length = writeIndex\n return messages as WithParts[]\n}\n","import type { PluginConfig } from \"../config\"\nimport type { WithParts } from \"../state\"\nimport { isMessageWithInfo } from \"./shape\"\n\nexport const getLastUserMessage = (\n messages: WithParts[],\n startIndex?: number,\n): WithParts | null => {\n const start = startIndex ?? messages.length - 1\n for (let i = start; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return msg\n }\n }\n return null\n}\n\nexport const messageHasCompress = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"assistant\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n\nexport const isIgnoredUserMessage = (message: WithParts): boolean => {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n if (message.info.role !== \"user\") {\n return false\n }\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n if (parts.length === 0) {\n return true\n }\n\n for (const part of parts) {\n if (!(part as any).ignored) {\n return false\n }\n }\n\n return true\n}\n\nexport function isProtectedUserMessage(config: PluginConfig, message: WithParts): boolean {\n if (!isMessageWithInfo(message)) {\n return false\n }\n\n return (\n config.compress.mode === \"message\" &&\n config.compress.protectUserMessages &&\n message.info.role === \"user\" &&\n !isIgnoredUserMessage(message)\n )\n}\n","// 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, \"&\")\n .replace(/\"/g, \""\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n}\n\nexport function formatMessageIdTag(\n ref: string,\n attributes?: Record<string, string | undefined>,\n): string {\n const serializedAttributes = Object.entries(attributes || {})\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([name, value]) => {\n if (name.trim().length === 0 || typeof value !== \"string\" || value.length === 0) {\n return \"\"\n }\n\n return ` ${name}=\"${escapeXmlAttribute(value)}\"`\n })\n .join(\"\")\n\n return `\\n<${MESSAGE_ID_TAG_NAME}${serializedAttributes}>${ref}</${MESSAGE_ID_TAG_NAME}>`\n}\n\nexport function assignMessageRefs(state: SessionState, messages: WithParts[]): number {\n let assigned = 0\n let skippedSubAgentPrompt = false\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n if (state.isSubAgent && !skippedSubAgentPrompt && message.info.role === \"user\") {\n skippedSubAgentPrompt = true\n continue\n }\n\n const rawMessageId = message.info.id\n if (typeof rawMessageId !== \"string\" || rawMessageId.length === 0) {\n continue\n }\n\n 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 const startReference = lookup.get(parsedStartId.ref)\n const endReference = lookup.get(parsedEndId.ref)\n\n if (!startReference) {\n issues.push(\n `startId ${parsedStartId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (!endReference) {\n issues.push(\n `endId ${parsedEndId.ref} is not available in the current conversation context. Choose an injected ID visible in context.`,\n )\n }\n\n if (issues.length > 0) {\n throw new Error(\n issues.length === 1 ? issues[0] : issues.map((issue) => `- ${issue}`).join(\"\\n\"),\n )\n }\n\n if (!startReference || !endReference) {\n throw new Error(\"Failed to resolve boundary IDs\")\n }\n\n if (startReference.rawIndex > endReference.rawIndex) {\n throw new Error(\n `startId ${parsedStartId.ref} appears after endId ${parsedEndId.ref} in the conversation. Start must come before end.`,\n )\n }\n\n return { startReference, endReference }\n}\n\nexport function resolveSelection(\n context: SearchContext,\n 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\"\n\nexport const COMPRESSED_BLOCK_HEADER = \"[Compressed conversation section]\"\n\nexport function allocateBlockId(state: SessionState): number {\n const next = state.prune.messages.nextBlockId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextBlockId = 2\n return 1\n }\n\n state.prune.messages.nextBlockId = next + 1\n return next\n}\n\nexport function allocateRunId(state: SessionState): number {\n const next = state.prune.messages.nextRunId\n if (!Number.isInteger(next) || next < 1) {\n state.prune.messages.nextRunId = 2\n return 1\n }\n\n state.prune.messages.nextRunId = next + 1\n return next\n}\n\nexport function attachCompressionDuration(\n messagesState: PruneMessagesState,\n messageId: string,\n callId: string,\n durationMs: number,\n): number {\n if (typeof durationMs !== \"number\" || !Number.isFinite(durationMs)) {\n return 0\n }\n\n let updates = 0\n for (const block of messagesState.blocksById.values()) {\n if (block.compressMessageId !== messageId || block.compressCallId !== callId) {\n continue\n }\n\n block.durationMs = durationMs\n updates++\n }\n\n return updates\n}\n\nexport function wrapCompressedSummary(blockId: number, summary: string): string {\n const header = COMPRESSED_BLOCK_HEADER\n const footer = formatMessageIdTag(formatBlockRef(blockId))\n const body = summary.trim()\n if (body.length === 0) {\n return `${header}\\n${footer}`\n }\n return `${header}\\n${body}\\n\\n${footer}`\n}\n\nexport function applyCompressionState(\n state: SessionState,\n input: CompressionStateInput,\n selection: SelectionResolution,\n anchorMessageId: string,\n blockId: number,\n summary: string,\n consumedBlockIds: number[],\n): AppliedCompressionResult {\n const messagesState = state.prune.messages\n const consumed = [...new Set(consumedBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n const included = [...consumed]\n\n const effectiveMessageIds = new Set<string>(selection.messageIds)\n const effectiveToolIds = new Set<string>(selection.toolIds)\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n effectiveMessageIds.add(messageId)\n }\n for (const toolId of consumedBlock.effectiveToolIds) {\n effectiveToolIds.add(toolId)\n }\n }\n\n const initiallyActiveMessages = new Set<string>()\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (entry && entry.activeBlockIds.length > 0) {\n initiallyActiveMessages.add(messageId)\n }\n }\n\n const initiallyActiveToolIds = new Set<string>()\n for (const activeBlockId of messagesState.activeBlockIds) {\n const activeBlock = messagesState.blocksById.get(activeBlockId)\n if (!activeBlock || !activeBlock.active) {\n continue\n }\n\n for (const toolId of activeBlock.effectiveToolIds) {\n initiallyActiveToolIds.add(toolId)\n }\n }\n\n const createdAt = Date.now()\n const block: CompressionBlock = {\n blockId,\n runId: input.runId,\n active: true,\n deactivatedByUser: false,\n compressedTokens: 0,\n summaryTokens: input.summaryTokens,\n durationMs: 0,\n mode: input.mode,\n topic: input.topic,\n batchTopic: input.batchTopic,\n startId: input.startId,\n endId: input.endId,\n anchorMessageId,\n compressMessageId: input.compressMessageId,\n compressCallId: input.compressCallId,\n includedBlockIds: included,\n consumedBlockIds: consumed,\n parentBlockIds: [],\n directMessageIds: [],\n directToolIds: [],\n effectiveMessageIds: [...effectiveMessageIds],\n effectiveToolIds: [...effectiveToolIds],\n createdAt,\n summary,\n }\n\n messagesState.blocksById.set(blockId, block)\n messagesState.activeBlockIds.add(blockId)\n messagesState.activeByAnchorMessageId.set(anchorMessageId, blockId)\n\n const deactivatedAt = Date.now()\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock || !consumedBlock.active) {\n continue\n }\n\n consumedBlock.active = false\n consumedBlock.deactivatedAt = deactivatedAt\n consumedBlock.deactivatedByBlockId = blockId\n if (!consumedBlock.parentBlockIds.includes(blockId)) {\n consumedBlock.parentBlockIds.push(blockId)\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n const removeActiveBlockId = (\n entry: { activeBlockIds: number[] },\n blockIdToRemove: number,\n ): void => {\n if (entry.activeBlockIds.length === 0) {\n return\n }\n entry.activeBlockIds = entry.activeBlockIds.filter((id) => id !== blockIdToRemove)\n }\n\n for (const consumedBlockId of consumed) {\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (!consumedBlock) {\n continue\n }\n for (const messageId of consumedBlock.effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n removeActiveBlockId(entry, consumedBlockId)\n }\n }\n\n for (const messageId of selection.messageIds) {\n const tokenCount = selection.messageTokenById.get(messageId) || 0\n const existing = messagesState.byMessageId.get(messageId)\n\n if (!existing) {\n messagesState.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds: [blockId],\n activeBlockIds: [blockId],\n })\n continue\n }\n\n existing.tokenCount = Math.max(existing.tokenCount, tokenCount)\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n for (const messageId of block.effectiveMessageIds) {\n if (selection.messageTokenById.has(messageId)) {\n continue\n }\n\n const existing = messagesState.byMessageId.get(messageId)\n if (!existing) {\n continue\n }\n if (!existing.allBlockIds.includes(blockId)) {\n existing.allBlockIds.push(blockId)\n }\n if (!existing.activeBlockIds.includes(blockId)) {\n existing.activeBlockIds.push(blockId)\n }\n }\n\n let compressedTokens = 0\n const newlyCompressedMessageIds: string[] = []\n for (const messageId of effectiveMessageIds) {\n const entry = messagesState.byMessageId.get(messageId)\n if (!entry) {\n continue\n }\n\n const isNowActive = entry.activeBlockIds.length > 0\n const wasActive = initiallyActiveMessages.has(messageId)\n\n if (isNowActive && !wasActive) {\n compressedTokens += entry.tokenCount\n newlyCompressedMessageIds.push(messageId)\n }\n }\n\n const newlyCompressedToolIds: string[] = []\n for (const toolId of effectiveToolIds) {\n if (!initiallyActiveToolIds.has(toolId)) {\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n block.directMessageIds = [...newlyCompressedMessageIds]\n block.directToolIds = [...newlyCompressedToolIds]\n\n block.compressedTokens = compressedTokens\n\n state.stats.pruneTokenCounter += compressedTokens\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n return {\n compressedTokens,\n messageIds: selection.messageIds,\n newlyCompressedMessageIds,\n newlyCompressedToolIds,\n }\n}\n","import type { PluginConfig } from \"../config\"\nimport type { SessionState } from \"../state\"\nimport { parseBoundaryId } from \"../message-ids\"\nimport { isIgnoredUserMessage, isProtectedUserMessage } from \"../messages/query\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport { COMPRESSED_BLOCK_HEADER } from \"./state\"\nimport type {\n CompressMessageEntry,\n CompressMessageToolArgs,\n ResolvedMessageCompression,\n ResolvedMessageCompressionsResult,\n SearchContext,\n} from \"./types\"\n\ninterface SkippedIssue {\n kind: string\n messageId: string\n}\n\nclass SoftIssue extends Error {\n constructor(\n public readonly kind: string,\n public readonly messageId: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport function validateArgs(args: CompressMessageToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.messageId !== \"string\" || entry.messageId.trim().length === 0) {\n throw new Error(`${prefix}.messageId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.topic !== \"string\" || entry.topic.trim().length === 0) {\n throw new Error(`${prefix}.topic is required and must be a non-empty string`)\n }\n\n if (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\n if (skippedCount === 0) {\n return processedText\n }\n\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `${processedText}\\nSkipped ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nexport function formatIssues(skippedIssues: string[], skippedCount: number): string {\n const issueNoun = skippedCount === 1 ? \"issue\" : \"issues\"\n const issueLines = skippedIssues.map((issue) => `- ${issue}`).join(\"\\n\")\n return `Unable to compress any messages. Found ${skippedCount} ${issueNoun}:\\n${issueLines}`\n}\n\nconst ISSUE_TEMPLATES: Record<string, [singular: string, plural: string]> = {\n blocked: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"invalid-format\": [\n \"is invalid. Use an injected raw message ID of the form mNNNN.\",\n \"are invalid. Use injected raw message IDs of the form mNNNN.\",\n ],\n \"block-id\": [\n \"is invalid here. Block IDs like bN are not allowed; use an mNNNN message ID instead.\",\n \"are invalid here. Block IDs like bN are not allowed; use mNNNN message IDs instead.\",\n ],\n \"not-in-context\": [\n \"is not available in the current conversation context. Choose an injected mNNNN ID visible in context.\",\n \"are not available in the current conversation context. Choose injected mNNNN IDs visible in context.\",\n ],\n protected: [\n \"refers to a protected message and cannot be compressed.\",\n \"refer to protected messages and cannot be compressed.\",\n ],\n \"already-compressed\": [\n \"is already part of an active compression.\",\n \"are already part of active compressions.\",\n ],\n duplicate: [\n \"was selected more than once in this batch.\",\n \"were each selected more than once in this batch.\",\n ],\n}\n\nfunction formatSkippedGroup(kind: string, messageIds: string[]): string {\n const templates = ISSUE_TEMPLATES[kind]\n const ids = messageIds.join(\", \")\n const single = messageIds.length === 1\n const prefix = single ? \"messageId\" : \"messageIds\"\n\n if (!templates) {\n return `${prefix} ${ids}: unknown issue.`\n }\n\n return `${prefix} ${ids} ${single ? templates[0] : templates[1]}`\n}\n\nfunction groupSkippedIssues(issues: SkippedIssue[]): string[] {\n const groups = new Map<string, string[]>()\n const order: string[] = []\n\n for (const issue of issues) {\n let ids = groups.get(issue.kind)\n if (!ids) {\n ids = []\n groups.set(issue.kind, ids)\n order.push(issue.kind)\n }\n ids.push(issue.messageId)\n }\n\n return order.map((kind) => {\n const ids = groups.get(kind)!\n return formatSkippedGroup(kind, ids)\n })\n}\n\nexport function resolveMessages(\n args: CompressMessageToolArgs,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompressionsResult {\n const issues: SkippedIssue[] = []\n const plans: ResolvedMessageCompression[] = []\n const seenMessageIds = new Set<string>()\n\n for (const entry of args.content) {\n const normalizedMessageId = entry.messageId.trim()\n if (seenMessageIds.has(normalizedMessageId)) {\n issues.push({ kind: \"duplicate\", messageId: normalizedMessageId })\n continue\n }\n\n try {\n const plan = resolveMessage(\n {\n ...entry,\n messageId: normalizedMessageId,\n },\n searchContext,\n state,\n config,\n )\n seenMessageIds.add(plan.entry.messageId)\n plans.push(plan)\n } catch (error: any) {\n if (error instanceof SoftIssue) {\n issues.push({ kind: error.kind, messageId: error.messageId })\n continue\n }\n\n throw error\n }\n }\n\n return {\n plans,\n skippedIssues: groupSkippedIssues(issues),\n skippedCount: issues.length,\n }\n}\n\nfunction resolveMessage(\n entry: CompressMessageEntry,\n searchContext: SearchContext,\n state: SessionState,\n config: PluginConfig,\n): ResolvedMessageCompression {\n if (entry.messageId.toUpperCase() === \"BLOCKED\") {\n throw new SoftIssue(\"blocked\", \"BLOCKED\", \"protected message\")\n }\n\n const parsed = parseBoundaryId(entry.messageId)\n\n if (!parsed) {\n throw new SoftIssue(\"invalid-format\", entry.messageId, \"invalid format\")\n }\n\n if (parsed.kind === \"compressed-block\") {\n throw new SoftIssue(\"block-id\", entry.messageId, \"block ID used\")\n }\n\n const messageId = state.messageIds.byRef.get(parsed.ref)\n const rawMessage = messageId ? searchContext.rawMessagesById.get(messageId) : undefined\n if (\n !messageId ||\n !rawMessage ||\n !searchContext.rawIndexById.has(messageId) ||\n isIgnoredUserMessage(rawMessage)\n ) {\n throw new SoftIssue(\"not-in-context\", parsed.ref, \"not in context\")\n }\n\n const { startReference, endReference } = resolveBoundaryIds(\n searchContext,\n state,\n parsed.ref,\n parsed.ref,\n )\n const selection = resolveSelection(searchContext, startReference, endReference)\n\n if (isProtectedUserMessage(config, rawMessage)) {\n throw new SoftIssue(\"protected\", parsed.ref, \"protected message\")\n }\n\n const pruneEntry = state.prune.messages.byMessageId.get(messageId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n throw new SoftIssue(\"already-compressed\", parsed.ref, \"already compressed\")\n }\n\n return {\n entry: {\n messageId: parsed.ref,\n topic: entry.topic,\n summary: entry.summary,\n },\n selection,\n anchorMessageId: resolveAnchorMessageId(startReference),\n }\n}\n","/**\n * State persistence module for DCP plugin.\n * Persists pruned tool IDs across sessions so they survive OpenCode restarts.\n * Storage location: ~/.local/share/opencode/storage/plugin/dcp/{sessionId}.json\n */\n\nimport * as fs from \"fs/promises\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join } from \"path\"\nimport type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from \"./types\"\nimport type { Logger } from \"../logger\"\nimport { serializePruneMessagesState } from \"./utils\"\n\n/** Prune state as stored on disk */\nexport interface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport interface PersistedPrune {\n tools?: Record<string, number>\n messages?: PersistedPruneMessagesState\n}\n\nexport interface PersistedNudges {\n contextLimitAnchors: string[]\n turnNudgeAnchors?: string[]\n iterationNudgeAnchors?: string[]\n}\n\nexport interface PersistedSessionState {\n sessionName?: string\n prune: PersistedPrune\n nudges: PersistedNudges\n stats: SessionStats\n lastUpdated: string\n}\n\nconst STORAGE_DIR = join(\n process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\"),\n \"opencode\",\n \"storage\",\n \"plugin\",\n \"dcp\",\n)\n\nasync function ensureStorageDir(): Promise<void> {\n if (!existsSync(STORAGE_DIR)) {\n await fs.mkdir(STORAGE_DIR, { recursive: true })\n }\n}\n\nfunction getSessionFilePath(sessionId: string): string {\n return join(STORAGE_DIR, `${sessionId}.json`)\n}\n\nasync function writePersistedSessionState(\n sessionId: string,\n state: PersistedSessionState,\n logger: Logger,\n): Promise<void> {\n await ensureStorageDir()\n\n const filePath = getSessionFilePath(sessionId)\n const content = JSON.stringify(state, null, 2)\n await fs.writeFile(filePath, content, \"utf-8\")\n\n logger.info(\"Saved session state to disk\", {\n sessionId,\n totalTokensSaved: state.stats.totalPruneTokens,\n })\n}\n\nexport async function saveSessionState(\n sessionState: SessionState,\n logger: Logger,\n sessionName?: string,\n): Promise<void> {\n try {\n if (!sessionState.sessionId) {\n return\n }\n\n const state: PersistedSessionState = {\n sessionName: sessionName,\n prune: {\n tools: Object.fromEntries(sessionState.prune.tools),\n messages: serializePruneMessagesState(sessionState.prune.messages),\n },\n nudges: {\n contextLimitAnchors: Array.from(sessionState.nudges.contextLimitAnchors),\n turnNudgeAnchors: Array.from(sessionState.nudges.turnNudgeAnchors),\n iterationNudgeAnchors: Array.from(sessionState.nudges.iterationNudgeAnchors),\n },\n stats: sessionState.stats,\n lastUpdated: new Date().toISOString(),\n }\n\n await writePersistedSessionState(sessionState.sessionId, state, logger)\n } catch (error: any) {\n logger.error(\"Failed to save session state\", {\n sessionId: sessionState.sessionId,\n error: error?.message,\n })\n }\n}\n\nexport async function loadSessionState(\n sessionId: string,\n logger: Logger,\n): Promise<PersistedSessionState | null> {\n try {\n const filePath = getSessionFilePath(sessionId)\n\n if (!existsSync(filePath)) {\n return null\n }\n\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n const hasPruneTools = state?.prune?.tools && typeof state.prune.tools === \"object\"\n const hasPruneMessages = state?.prune?.messages && typeof state.prune.messages === \"object\"\n const hasNudgeFormat = state?.nudges && typeof state.nudges === \"object\"\n if (\n !state ||\n !state.prune ||\n !hasPruneTools ||\n !hasPruneMessages ||\n !state.stats ||\n !hasNudgeFormat\n ) {\n logger.warn(\"Invalid session state file, ignoring\", {\n sessionId: sessionId,\n })\n return null\n }\n\n const rawContextLimitAnchors = Array.isArray(state.nudges.contextLimitAnchors)\n ? state.nudges.contextLimitAnchors\n : []\n const validAnchors = rawContextLimitAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedAnchors = [...new Set(validAnchors)]\n if (validAnchors.length !== rawContextLimitAnchors.length) {\n logger.warn(\"Filtered out malformed contextLimitAnchors entries\", {\n sessionId: sessionId,\n original: rawContextLimitAnchors.length,\n valid: validAnchors.length,\n })\n }\n state.nudges.contextLimitAnchors = dedupedAnchors\n\n const rawTurnNudgeAnchors = Array.isArray(state.nudges.turnNudgeAnchors)\n ? state.nudges.turnNudgeAnchors\n : []\n const validSoftAnchors = rawTurnNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedSoftAnchors = [...new Set(validSoftAnchors)]\n if (validSoftAnchors.length !== rawTurnNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed turnNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawTurnNudgeAnchors.length,\n valid: validSoftAnchors.length,\n })\n }\n state.nudges.turnNudgeAnchors = dedupedSoftAnchors\n\n const rawIterationNudgeAnchors = Array.isArray(state.nudges.iterationNudgeAnchors)\n ? state.nudges.iterationNudgeAnchors\n : []\n const validIterationAnchors = rawIterationNudgeAnchors.filter(\n (entry): entry is string => typeof entry === \"string\",\n )\n const dedupedIterationAnchors = [...new Set(validIterationAnchors)]\n if (validIterationAnchors.length !== rawIterationNudgeAnchors.length) {\n logger.warn(\"Filtered out malformed iterationNudgeAnchors entries\", {\n sessionId: sessionId,\n original: rawIterationNudgeAnchors.length,\n valid: validIterationAnchors.length,\n })\n }\n state.nudges.iterationNudgeAnchors = dedupedIterationAnchors\n\n logger.info(\"Loaded session state from disk\", {\n sessionId: sessionId,\n })\n\n return state\n } catch (error: any) {\n logger.warn(\"Failed to load session state\", {\n sessionId: sessionId,\n error: error?.message,\n })\n return null\n }\n}\n\nexport interface AggregatedStats {\n totalTokens: number\n totalTools: number\n totalMessages: number\n sessionCount: number\n}\n\nexport async function loadAllSessionStats(logger: Logger): Promise<AggregatedStats> {\n const result: AggregatedStats = {\n totalTokens: 0,\n totalTools: 0,\n totalMessages: 0,\n sessionCount: 0,\n }\n\n try {\n if (!existsSync(STORAGE_DIR)) {\n return result\n }\n\n const files = await fs.readdir(STORAGE_DIR)\n const jsonFiles = files.filter((f) => f.endsWith(\".json\"))\n\n for (const file of jsonFiles) {\n try {\n const filePath = join(STORAGE_DIR, file)\n const content = await fs.readFile(filePath, \"utf-8\")\n const state = JSON.parse(content) as PersistedSessionState\n\n if (state?.stats?.totalPruneTokens && state?.prune) {\n result.totalTokens += state.stats.totalPruneTokens\n result.totalTools += state.prune.tools\n ? Object.keys(state.prune.tools).length\n : 0\n result.totalMessages += state.prune.messages?.byMessageId\n ? Object.keys(state.prune.messages.byMessageId).length\n : 0\n result.sessionCount++\n }\n } catch {\n // Skip invalid files\n }\n }\n\n logger.debug(\"Loaded all-time stats\", result)\n } catch (error: any) {\n logger.warn(\"Failed to load all-time stats\", { error: error?.message })\n }\n\n return result\n}\n","import type {\n CompressionBlock,\n PruneMessagesState,\n PrunedMessageEntry,\n SessionState,\n WithParts,\n} from \"./types\"\nimport { isIgnoredUserMessage, messageHasCompress } from \"../messages/query\"\nimport { isMessageWithInfo } from \"../messages/shape\"\nimport { countTokens } from \"../token-utils\"\n\nexport const isMessageCompacted = (state: SessionState, msg: WithParts): boolean => {\n if (!isMessageWithInfo(msg)) {\n return false\n }\n\n if (msg.info.time.created < state.lastCompaction) {\n return true\n }\n const pruneEntry = state.prune.messages.byMessageId.get(msg.info.id)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n return true\n }\n return false\n}\n\ninterface PersistedPruneMessagesState {\n byMessageId: Record<string, PrunedMessageEntry>\n blocksById: Record<string, CompressionBlock>\n activeBlockIds: number[]\n activeByAnchorMessageId: Record<string, number>\n nextBlockId: number\n nextRunId: number\n}\n\nexport function serializePruneMessagesState(\n messagesState: PruneMessagesState,\n): PersistedPruneMessagesState {\n return {\n byMessageId: Object.fromEntries(messagesState.byMessageId),\n blocksById: Object.fromEntries(\n Array.from(messagesState.blocksById.entries()).map(([blockId, block]) => [\n String(blockId),\n block,\n ]),\n ),\n activeBlockIds: Array.from(messagesState.activeBlockIds),\n activeByAnchorMessageId: Object.fromEntries(messagesState.activeByAnchorMessageId),\n nextBlockId: messagesState.nextBlockId,\n nextRunId: messagesState.nextRunId,\n }\n}\n\nexport async function isSubAgentSession(client: any, sessionID: string): Promise<boolean> {\n try {\n const result = await client.session.get({ path: { id: sessionID } })\n return !!result.data?.parentID\n } catch (error: any) {\n return false\n }\n}\n\nexport function findLastCompactionTimestamp(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (msg.info.role === \"assistant\" && msg.info.summary === true) {\n return msg.info.time.created\n }\n }\n return 0\n}\n\nexport function countTurns(state: SessionState, messages: WithParts[]): number {\n let turnCount = 0\n for (const msg of messages) {\n if (!isMessageWithInfo(msg)) {\n continue\n }\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCount++\n }\n }\n }\n return turnCount\n}\n\nexport function loadPruneMap(obj?: Record<string, number>): Map<string, number> {\n if (!obj || typeof obj !== \"object\") {\n return new Map()\n }\n\n const entries = Object.entries(obj).filter(\n (entry): entry is [string, number] =>\n typeof entry[0] === \"string\" && typeof entry[1] === \"number\",\n )\n return new Map(entries)\n}\n\nexport function createPruneMessagesState(): PruneMessagesState {\n return {\n byMessageId: new Map<string, PrunedMessageEntry>(),\n blocksById: new Map<number, CompressionBlock>(),\n activeBlockIds: new Set<number>(),\n activeByAnchorMessageId: new Map<string, number>(),\n nextBlockId: 1,\n nextRunId: 1,\n }\n}\n\nexport function loadPruneMessagesState(\n persisted?: PersistedPruneMessagesState,\n): PruneMessagesState {\n const state = createPruneMessagesState()\n if (!persisted || typeof persisted !== \"object\") {\n return state\n }\n\n if (typeof persisted.nextBlockId === \"number\" && Number.isInteger(persisted.nextBlockId)) {\n state.nextBlockId = Math.max(1, persisted.nextBlockId)\n }\n if (typeof persisted.nextRunId === \"number\" && Number.isInteger(persisted.nextRunId)) {\n state.nextRunId = Math.max(1, persisted.nextRunId)\n }\n\n if (persisted.byMessageId && typeof persisted.byMessageId === \"object\") {\n for (const [messageId, entry] of Object.entries(persisted.byMessageId)) {\n if (!entry || typeof entry !== \"object\") {\n continue\n }\n\n const tokenCount = typeof entry.tokenCount === \"number\" ? entry.tokenCount : 0\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [\n ...new Set(\n entry.allBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n const activeBlockIds = Array.isArray(entry.activeBlockIds)\n ? [\n ...new Set(\n entry.activeBlockIds.filter(\n (id): id is number => Number.isInteger(id) && id > 0,\n ),\n ),\n ]\n : []\n\n state.byMessageId.set(messageId, {\n tokenCount,\n allBlockIds,\n activeBlockIds,\n })\n }\n }\n\n if (persisted.blocksById && typeof persisted.blocksById === \"object\") {\n for (const [blockIdStr, block] of Object.entries(persisted.blocksById)) {\n const blockId = Number.parseInt(blockIdStr, 10)\n if (!Number.isInteger(blockId) || blockId < 1 || !block || typeof block !== \"object\") {\n continue\n }\n\n const toNumberArray = (value: unknown): number[] =>\n Array.isArray(value)\n ? [\n ...new Set(\n value.filter(\n (item): item is number => Number.isInteger(item) && item > 0,\n ),\n ),\n ]\n : []\n const toStringArray = (value: unknown): string[] =>\n Array.isArray(value)\n ? [...new Set(value.filter((item): item is string => typeof item === \"string\"))]\n : []\n\n state.blocksById.set(blockId, {\n blockId,\n runId:\n typeof block.runId === \"number\" &&\n Number.isInteger(block.runId) &&\n block.runId > 0\n ? block.runId\n : blockId,\n active: block.active === true,\n deactivatedByUser: block.deactivatedByUser === true,\n compressedTokens:\n typeof block.compressedTokens === \"number\" &&\n Number.isFinite(block.compressedTokens)\n ? Math.max(0, block.compressedTokens)\n : 0,\n summaryTokens:\n typeof block.summaryTokens === \"number\" && Number.isFinite(block.summaryTokens)\n ? Math.max(0, block.summaryTokens)\n : typeof block.summary === \"string\"\n ? countTokens(block.summary)\n : 0,\n durationMs:\n typeof block.durationMs === \"number\" && Number.isFinite(block.durationMs)\n ? Math.max(0, block.durationMs)\n : 0,\n mode: block.mode === \"range\" || block.mode === \"message\" ? block.mode : undefined,\n topic: typeof block.topic === \"string\" ? block.topic : \"\",\n batchTopic:\n typeof block.batchTopic === \"string\"\n ? block.batchTopic\n : typeof block.topic === \"string\"\n ? block.topic\n : \"\",\n startId: typeof block.startId === \"string\" ? block.startId : \"\",\n endId: typeof block.endId === \"string\" ? block.endId : \"\",\n anchorMessageId:\n typeof block.anchorMessageId === \"string\" ? block.anchorMessageId : \"\",\n compressMessageId:\n typeof block.compressMessageId === \"string\" ? block.compressMessageId : \"\",\n compressCallId:\n typeof block.compressCallId === \"string\" ? block.compressCallId : undefined,\n includedBlockIds: toNumberArray(block.includedBlockIds),\n consumedBlockIds: toNumberArray(block.consumedBlockIds),\n parentBlockIds: toNumberArray(block.parentBlockIds),\n directMessageIds: toStringArray(block.directMessageIds),\n directToolIds: toStringArray(block.directToolIds),\n effectiveMessageIds: toStringArray(block.effectiveMessageIds),\n effectiveToolIds: toStringArray(block.effectiveToolIds),\n createdAt: typeof block.createdAt === \"number\" ? block.createdAt : 0,\n deactivatedAt:\n typeof block.deactivatedAt === \"number\" ? block.deactivatedAt : undefined,\n deactivatedByBlockId:\n typeof block.deactivatedByBlockId === \"number\" &&\n Number.isInteger(block.deactivatedByBlockId)\n ? block.deactivatedByBlockId\n : undefined,\n summary: typeof block.summary === \"string\" ? block.summary : \"\",\n })\n }\n }\n\n if (Array.isArray(persisted.activeBlockIds)) {\n for (const blockId of persisted.activeBlockIds) {\n if (!Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeBlockIds.add(blockId)\n }\n }\n\n if (\n persisted.activeByAnchorMessageId &&\n typeof persisted.activeByAnchorMessageId === \"object\"\n ) {\n for (const [anchorMessageId, blockId] of Object.entries(\n persisted.activeByAnchorMessageId,\n )) {\n if (typeof blockId !== \"number\" || !Number.isInteger(blockId) || blockId < 1) {\n continue\n }\n state.activeByAnchorMessageId.set(anchorMessageId, blockId)\n }\n }\n\n for (const [blockId, block] of state.blocksById) {\n if (block.active) {\n state.activeBlockIds.add(blockId)\n if (block.anchorMessageId) {\n state.activeByAnchorMessageId.set(block.anchorMessageId, blockId)\n }\n }\n if (blockId >= state.nextBlockId) {\n state.nextBlockId = blockId + 1\n }\n if (block.runId >= state.nextRunId) {\n state.nextRunId = block.runId + 1\n }\n }\n\n return state\n}\n\nexport function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {\n const anchors = new Set<string>()\n let pendingUserMessageId: string | null = null\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n\n if (messageHasCompress(message)) {\n break\n }\n\n if (message.info.role === \"user\") {\n if (!isIgnoredUserMessage(message)) {\n pendingUserMessageId = message.info.id\n }\n continue\n }\n\n if (message.info.role === \"assistant\" && pendingUserMessageId) {\n anchors.add(message.info.id)\n anchors.add(pendingUserMessageId)\n pendingUserMessageId = null\n }\n }\n\n return anchors\n}\n\nexport function getActiveSummaryTokenUsage(state: SessionState): number {\n let total = 0\n for (const blockId of state.prune.messages.activeBlockIds) {\n const block = state.prune.messages.blocksById.get(blockId)\n if (!block || !block.active) {\n continue\n }\n total += block.summaryTokens\n }\n return total\n}\n\nexport function resetOnCompaction(state: SessionState): void {\n state.toolParameters.clear()\n state.prune.tools = new Map<string, number>()\n state.prune.messages = createPruneMessagesState()\n state.messageIds = {\n byRawId: new Map<string, string>(),\n byRef: new Map<string, string>(),\n nextRef: 1,\n }\n state.nudges = {\n contextLimitAnchors: new Set<string>(),\n turnNudgeAnchors: new Set<string>(),\n iterationNudgeAnchors: new Set<string>(),\n }\n}\n","import type { SessionState } 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 applied = applyPendingCompressionDurations(state)\n if (applied > 0) {\n await saveSessionState(state, logger)\n }\n}\n","import type { SessionState, ToolStatus, WithParts } from \"./index\"\nimport type { Logger } from \"../logger\"\nimport { PluginConfig } from \"../config\"\nimport { isMessageCompacted } from \"./utils\"\nimport { countToolTokens } from \"../token-utils\"\n\nconst MAX_TOOL_CACHE_SIZE = 1000\n\n/**\n * Sync tool parameters from session messages.\n */\nexport function syncToolCache(\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n): void {\n try {\n logger.info(\"Syncing tool parameters from OpenCode messages\")\n\n let turnCounter = 0\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"step-start\") {\n turnCounter++\n continue\n }\n\n if (part.type !== \"tool\" || !part.callID) {\n continue\n }\n\n const turnProtectionEnabled = config.turnProtection.enabled\n const turnProtectionTurns = config.turnProtection.turns\n const isProtectedByTurn =\n turnProtectionEnabled &&\n turnProtectionTurns > 0 &&\n state.currentTurn - turnCounter < turnProtectionTurns\n\n if (state.toolParameters.has(part.callID)) {\n continue\n }\n\n if (isProtectedByTurn) {\n continue\n }\n\n const tokenCount = countToolTokens(part)\n\n state.toolParameters.set(part.callID, {\n tool: part.tool,\n parameters: part.state?.input ?? {},\n status: part.state.status as ToolStatus | undefined,\n error: part.state.status === \"error\" ? part.state.error : undefined,\n turn: turnCounter,\n tokenCount,\n })\n logger.info(\n `Cached tool id: ${part.callID} (turn ${turnCounter}${tokenCount !== undefined ? `, ${tokenCount} tokens` : \"\"})`,\n )\n }\n }\n\n logger.info(\n `Synced cache - size: ${state.toolParameters.size}, currentTurn: ${state.currentTurn}`,\n )\n trimToolParametersCache(state)\n } catch (error) {\n logger.warn(\"Failed to sync tool parameters from OpenCode\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n}\n\n/**\n * Trim the tool parameters cache to prevent unbounded memory growth.\n * Uses FIFO eviction - removes oldest entries first.\n */\nexport function trimToolParametersCache(state: SessionState): void {\n if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {\n return\n }\n\n const keysToRemove = Array.from(state.toolParameters.keys()).slice(\n 0,\n state.toolParameters.size - MAX_TOOL_CACHE_SIZE,\n )\n\n for (const key of keysToRemove) {\n state.toolParameters.delete(key)\n }\n}\n","function normalizePath(input: string): string {\n return input.replaceAll(\"\\\\\\\\\", \"/\")\n}\n\nfunction escapeRegExpChar(ch: string): string {\n return /[\\\\.^$+{}()|\\[\\]]/.test(ch) ? `\\\\${ch}` : ch\n}\n\nexport function matchesGlob(inputPath: string, pattern: string): boolean {\n if (!pattern) return false\n\n const input = normalizePath(inputPath)\n const pat = normalizePath(pattern)\n\n let regex = \"^\"\n\n for (let i = 0; i < pat.length; i++) {\n const ch = pat[i]\n\n if (ch === \"*\") {\n const next = pat[i + 1]\n if (next === \"*\") {\n const after = pat[i + 2]\n if (after === \"/\") {\n // **/ (zero or more directories)\n regex += \"(?:.*/)?\"\n i += 2\n continue\n }\n\n // **\n regex += \".*\"\n i++\n continue\n }\n\n // *\n regex += \"[^/]*\"\n continue\n }\n\n if (ch === \"?\") {\n regex += \"[^/]\"\n continue\n }\n\n if (ch === \"/\") {\n regex += \"/\"\n continue\n }\n\n regex += escapeRegExpChar(ch)\n }\n\n regex += \"$\"\n\n return new RegExp(regex).test(input)\n}\n\nexport function getFilePathsFromParameters(tool: string, parameters: unknown): string[] {\n if (typeof parameters !== \"object\" || parameters === null) {\n return []\n }\n\n const paths: string[] = []\n const params = parameters as Record<string, any>\n\n // 1. apply_patch uses patchText with embedded paths\n if (tool === \"apply_patch\" && typeof params.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n let match\n while ((match = pathRegex.exec(params.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n }\n\n // 2. multiedit uses top-level filePath and nested edits array\n if (tool === \"multiedit\") {\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n if (Array.isArray(params.edits)) {\n for (const edit of params.edits) {\n if (edit && typeof edit.filePath === \"string\") {\n paths.push(edit.filePath)\n }\n }\n }\n }\n\n // 3. Default check for common filePath parameter (read, write, edit, etc)\n if (typeof params.filePath === \"string\") {\n paths.push(params.filePath)\n }\n\n // Return unique non-empty paths\n return [...new Set(paths)].filter((p) => p.length > 0)\n}\n\nexport function isFilePathProtected(filePaths: string[], patterns: string[]): boolean {\n if (!filePaths || filePaths.length === 0) return false\n if (!patterns || patterns.length === 0) return false\n\n return filePaths.some((path) => patterns.some((pattern) => matchesGlob(path, pattern)))\n}\n\nconst GLOB_CHARS = /[*?]/\n\nexport function isToolNameProtected(toolName: string, patterns: string[]): boolean {\n if (!toolName || !patterns || patterns.length === 0) return false\n\n const exactPatterns: Set<string> = new Set()\n const globPatterns: string[] = []\n\n for (const pattern of patterns) {\n if (GLOB_CHARS.test(pattern)) {\n globPatterns.push(pattern)\n } else {\n exactPatterns.add(pattern)\n }\n }\n\n if (exactPatterns.has(toolName)) {\n return true\n }\n\n return globPatterns.some((pattern) => matchesGlob(toolName, pattern))\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Deduplication strategy - prunes older tool calls that have identical\n * tool name and parameters, keeping only the most recent occurrence.\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const deduplicate = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.deduplication.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.deduplication.protectedTools\n\n // Group by signature (tool name + normalized parameters)\n const signatureMap = new Map<string, string[]>()\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n // logger.warn(`Missing metadata for tool call ID: ${id}`)\n continue\n }\n\n // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n continue\n }\n\n const signature = createToolSignature(metadata.tool, metadata.parameters)\n if (!signatureMap.has(signature)) {\n signatureMap.set(signature, [])\n }\n const ids = signatureMap.get(signature)\n if (ids) {\n ids.push(id)\n }\n }\n\n // Find duplicates - keep only the most recent (last) in each group\n const newPruneIds: string[] = []\n\n for (const [, ids] of signatureMap.entries()) {\n if (ids.length > 1) {\n // All except last (most recent) should be pruned\n const idsToRemove = ids.slice(0, -1)\n newPruneIds.push(...idsToRemove)\n }\n }\n\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n\n if (newPruneIds.length > 0) {\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(`Marked ${newPruneIds.length} duplicate tool calls for pruning`)\n }\n}\n\nfunction createToolSignature(tool: string, parameters?: any): string {\n if (!parameters) {\n return tool\n }\n const normalized = normalizeParameters(parameters)\n const sorted = sortObjectKeys(normalized)\n return `${tool}::${JSON.stringify(sorted)}`\n}\n\nfunction normalizeParameters(params: any): any {\n if (typeof params !== \"object\" || params === null) return params\n if (Array.isArray(params)) return params\n\n const normalized: any = {}\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n normalized[key] = value\n }\n }\n return normalized\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj !== \"object\" || obj === null) return obj\n if (Array.isArray(obj)) return obj.map(sortObjectKeys)\n\n const sorted: any = {}\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = sortObjectKeys(obj[key])\n }\n return sorted\n}\n","import { PluginConfig } from \"../config\"\nimport { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { getTotalToolTokens } from \"../token-utils\"\n\n/**\n * Purge Errors strategy - prunes tool inputs for tools that errored\n * after they are older than a configurable number of turns.\n * The error message is preserved, but the (potentially large) inputs\n * are removed to save context.\n *\n * Modifies the session state in place to add pruned tool call IDs.\n */\nexport const purgeErrors = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (state.manualMode && !config.manualMode.automaticStrategies) {\n return\n }\n\n if (!config.strategies.purgeErrors.enabled) {\n return\n }\n\n const allToolIds = state.toolIdList\n if (allToolIds.length === 0) {\n return\n }\n\n // Filter out IDs already pruned\n const unprunedIds = allToolIds.filter((id) => !state.prune.tools.has(id))\n\n if (unprunedIds.length === 0) {\n return\n }\n\n const protectedTools = config.strategies.purgeErrors.protectedTools\n const turnThreshold = Math.max(1, config.strategies.purgeErrors.turns)\n\n const newPruneIds: string[] = []\n\n for (const id of unprunedIds) {\n const metadata = state.toolParameters.get(id)\n if (!metadata) {\n continue\n }\n\n // Skip protected tools\n if (isToolNameProtected(metadata.tool, protectedTools)) {\n continue\n }\n\n const filePaths = getFilePathsFromParameters(metadata.tool, metadata.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n continue\n }\n\n // Only process error tools\n if (metadata.status !== \"error\") {\n continue\n }\n\n // Check if the tool is old enough to prune\n const turnAge = state.currentTurn - metadata.turn\n if (turnAge >= turnThreshold) {\n newPruneIds.push(id)\n }\n }\n\n if (newPruneIds.length > 0) {\n state.stats.totalPruneTokens += getTotalToolTokens(state, newPruneIds)\n for (const id of newPruneIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n logger.debug(\n `Marked ${newPruneIds.length} error tool calls for pruning (older than ${turnThreshold} turns)`,\n )\n }\n}\n","import { SessionState, ToolParameterEntry, WithParts } from \"../state\"\nimport { countTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nfunction extractParameterKey(tool: string, parameters: any): string {\n if (!parameters) return \"\"\n\n if (tool === \"read\" && parameters.filePath) {\n const offset = parameters.offset\n const limit = parameters.limit\n if (offset !== undefined && limit !== undefined) {\n return `${parameters.filePath} (lines ${offset}-${offset + limit})`\n }\n if (offset !== undefined) {\n return `${parameters.filePath} (lines ${offset}+)`\n }\n if (limit !== undefined) {\n return `${parameters.filePath} (lines 0-${limit})`\n }\n return parameters.filePath\n }\n\n if ((tool === \"write\" || tool === \"edit\" || tool === \"multiedit\") && parameters.filePath) {\n return parameters.filePath\n }\n\n if (tool === \"apply_patch\" && typeof parameters.patchText === \"string\") {\n const pathRegex = /\\*\\*\\* (?:Add|Delete|Update) File: ([^\\n\\r]+)/g\n const paths: string[] = []\n let match\n while ((match = pathRegex.exec(parameters.patchText)) !== null) {\n paths.push(match[1].trim())\n }\n if (paths.length > 0) {\n const uniquePaths = [...new Set(paths)]\n const count = uniquePaths.length\n const plural = count > 1 ? \"s\" : \"\"\n if (count === 1) return uniquePaths[0]\n if (count === 2) return uniquePaths.join(\", \")\n return `${count} file${plural}: ${uniquePaths[0]}, ${uniquePaths[1]}...`\n }\n return \"patch\"\n }\n\n if (tool === \"list\") {\n return parameters.path || \"(current directory)\"\n }\n\n if (tool === \"glob\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"grep\") {\n if (parameters.pattern) {\n const pathInfo = parameters.path ? ` in ${parameters.path}` : \"\"\n return `\"${parameters.pattern}\"${pathInfo}`\n }\n return \"(unknown pattern)\"\n }\n\n if (tool === \"bash\") {\n if (parameters.description) return parameters.description\n if (parameters.command) {\n return parameters.command.length > 50\n ? parameters.command.substring(0, 50) + \"...\"\n : parameters.command\n }\n }\n\n if (tool === \"webfetch\" && parameters.url) {\n return parameters.url\n }\n if (tool === \"websearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n if (tool === \"codesearch\" && parameters.query) {\n return `\"${parameters.query}\"`\n }\n\n if (tool === \"todowrite\") {\n return `${parameters.todos?.length || 0} todos`\n }\n if (tool === \"todoread\") {\n return \"read todo list\"\n }\n\n if (tool === \"task\" && parameters.description) {\n return parameters.description\n }\n if (tool === \"skill\" && parameters.name) {\n return parameters.name\n }\n\n if (tool === \"lsp\") {\n const op = parameters.operation || \"lsp\"\n const path = parameters.filePath || \"\"\n const line = parameters.line\n const char = parameters.character\n if (path && line !== undefined && char !== undefined) {\n return `${op} ${path}:${line}:${char}`\n }\n if (path) {\n return `${op} ${path}`\n }\n return op\n }\n\n if (tool === \"question\") {\n const questions = parameters.questions\n if (Array.isArray(questions) && questions.length > 0) {\n const headers = questions\n .map((q: any) => q.header || \"\")\n .filter(Boolean)\n .slice(0, 3)\n\n const count = questions.length\n const plural = count > 1 ? \"s\" : \"\"\n\n if (headers.length > 0) {\n const suffix = count > 3 ? ` (+${count - 3} more)` : \"\"\n return `${count} question${plural}: ${headers.join(\", \")}${suffix}`\n }\n return `${count} question${plural}`\n }\n return \"question\"\n }\n\n const paramStr = JSON.stringify(parameters)\n if (paramStr === \"{}\" || paramStr === \"[]\" || paramStr === \"null\") {\n return \"\"\n }\n\n return paramStr.substring(0, 50)\n}\n\nexport function formatStatsHeader(totalTokensSaved: number, pruneTokenCounter: number): string {\n const totalTokensSavedStr = `~${formatTokenCount(totalTokensSaved + pruneTokenCounter)}`\n return [`▣ DCP | ${totalTokensSavedStr} saved total`].join(\"\\n\")\n}\n\nexport function formatTokenCount(tokens: number, compact?: boolean): string {\n const suffix = compact ? \"\" : \" tokens\"\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}K`.replace(\".0K\", \"K\") + suffix\n }\n return tokens.toString() + suffix\n}\n\nexport function truncate(str: string, maxLen: number = 60): string {\n if (str.length <= maxLen) return str\n return str.slice(0, maxLen - 3) + \"...\"\n}\n\nexport function formatProgressBar(\n messageIds: string[],\n prunedMessages: Map<string, number>,\n recentMessageIds: string[],\n width: number = 50,\n): string {\n const ACTIVE = \"█\"\n const PRUNED = \"░\"\n const RECENT = \"⣿\"\n const recentSet = new Set(recentMessageIds)\n\n const total = messageIds.length\n if (total === 0) return `│${PRUNED.repeat(width)}│`\n\n const bar = new Array(width).fill(ACTIVE)\n\n for (let m = 0; m < total; m++) {\n const msgId = messageIds[m]\n const start = Math.floor((m / total) * width)\n const end = Math.floor(((m + 1) / total) * width)\n\n if (recentSet.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = RECENT\n }\n } else if (prunedMessages.has(msgId)) {\n for (let i = start; i < end; i++) {\n bar[i] = PRUNED\n }\n }\n }\n\n return `│${bar.join(\"\")}│`\n}\n\nexport function cacheSystemPromptTokens(state: SessionState, messages: WithParts[]): void {\n let firstInputTokens = 0\n for (const msg of messages) {\n if (msg.info.role !== \"assistant\") {\n continue\n }\n const info = msg.info as any\n const input = info?.tokens?.input || 0\n const cacheRead = info?.tokens?.cache?.read || 0\n const cacheWrite = info?.tokens?.cache?.write || 0\n if (input > 0 || cacheRead > 0 || cacheWrite > 0) {\n firstInputTokens = input + cacheRead + cacheWrite\n break\n }\n }\n\n if (firstInputTokens <= 0) {\n state.systemPromptTokens = undefined\n return\n }\n\n let firstUserText = \"\"\n for (const msg of messages) {\n if (msg.info.role !== \"user\" || isIgnoredUserMessage(msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && !(part as any).ignored) {\n firstUserText += part.text\n }\n }\n break\n }\n\n const estimatedSystemTokens = Math.max(0, firstInputTokens - countTokens(firstUserText))\n state.systemPromptTokens = estimatedSystemTokens > 0 ? estimatedSystemTokens : undefined\n}\n\nexport function shortenPath(input: string, workingDirectory?: string): string {\n const inPathMatch = input.match(/^(.+) in (.+)$/)\n if (inPathMatch) {\n const prefix = inPathMatch[1]\n const pathPart = inPathMatch[2]\n const shortenedPath = shortenSinglePath(pathPart, workingDirectory)\n return `${prefix} in ${shortenedPath}`\n }\n\n return shortenSinglePath(input, workingDirectory)\n}\n\nfunction shortenSinglePath(path: string, workingDirectory?: string): string {\n if (workingDirectory) {\n if (path.startsWith(workingDirectory + \"/\")) {\n return path.slice(workingDirectory.length + 1)\n }\n if (path === workingDirectory) {\n return \".\"\n }\n }\n\n return path\n}\n\nexport function formatPrunedItemsList(\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string[] {\n const lines: string[] = []\n\n for (const id of pruneToolIds) {\n const metadata = toolMetadata.get(id)\n\n if (metadata) {\n const paramKey = extractParameterKey(metadata.tool, metadata.parameters)\n if (paramKey) {\n // Use 60 char limit to match notification style\n const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60)\n lines.push(`→ ${metadata.tool}: ${displayKey}`)\n } else {\n lines.push(`→ ${metadata.tool}`)\n }\n }\n }\n\n const knownCount = pruneToolIds.filter((id) => toolMetadata.has(id)).length\n const unknownCount = pruneToolIds.length - knownCount\n\n if (unknownCount > 0) {\n lines.push(`→ (${unknownCount} tool${unknownCount > 1 ? \"s\" : \"\"} with unknown metadata)`)\n }\n\n return lines\n}\n\nexport function formatPruningResultForTool(\n prunedIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n): string {\n const lines: string[] = []\n lines.push(`Context pruning complete. Pruned ${prunedIds.length} tool outputs.`)\n lines.push(\"\")\n\n if (prunedIds.length > 0) {\n lines.push(`Semantically pruned (${prunedIds.length}):`)\n lines.push(...formatPrunedItemsList(prunedIds, toolMetadata, workingDirectory))\n }\n\n return lines.join(\"\\n\").trim()\n}\n","import type { Logger } from \"../logger\"\nimport type { SessionState } from \"../state\"\nimport {\n formatPrunedItemsList,\n formatProgressBar,\n formatStatsHeader,\n formatTokenCount,\n} from \"./utils\"\nimport { ToolParameterEntry } from \"../state\"\nimport { PluginConfig } from \"../config\"\nimport { getActiveSummaryTokenUsage } from \"../state/utils\"\n\nexport type PruneReason = \"completion\" | \"noise\" | \"extraction\"\nexport const PRUNE_REASON_LABELS: Record<PruneReason, string> = {\n completion: \"Task Complete\",\n noise: \"Noise Removal\",\n extraction: \"Extraction\",\n}\n\ninterface CompressionNotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nfunction buildMinimalMessage(state: SessionState, reason: PruneReason | undefined): string {\n const reasonSuffix = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n return (\n formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter) +\n reasonSuffix\n )\n}\n\nfunction buildDetailedMessage(\n state: SessionState,\n reason: PruneReason | undefined,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory: string,\n): string {\n let message = formatStatsHeader(state.stats.totalPruneTokens, state.stats.pruneTokenCounter)\n\n if (pruneToolIds.length > 0) {\n const pruneTokenCounterStr = `~${formatTokenCount(state.stats.pruneTokenCounter)}`\n const reasonLabel = reason ? ` — ${PRUNE_REASON_LABELS[reason]}` : \"\"\n message += `\\n\\n▣ Pruning (${pruneTokenCounterStr})${reasonLabel}`\n\n const itemLines = formatPrunedItemsList(pruneToolIds, toolMetadata, workingDirectory)\n message += \"\\n\" + itemLines.join(\"\\n\")\n }\n\n return message.trim()\n}\n\nconst TOAST_BODY_MAX_LINES = 12\nconst TOAST_SUMMARY_MAX_CHARS = 600\n\nfunction truncateToastBody(body: string, maxLines: number = TOAST_BODY_MAX_LINES): string {\n const lines = body.split(\"\\n\")\n if (lines.length <= maxLines) {\n return body\n }\n const kept = lines.slice(0, maxLines - 1)\n const remaining = lines.length - maxLines + 1\n return kept.join(\"\\n\") + `\\n... and ${remaining} more`\n}\n\nfunction truncateToastSummary(summary: string, maxChars: number = TOAST_SUMMARY_MAX_CHARS): string {\n if (summary.length <= maxChars) {\n return summary\n }\n return summary.slice(0, maxChars - 3) + \"...\"\n}\n\nfunction truncateExtractedSection(\n message: string,\n maxChars: number = TOAST_SUMMARY_MAX_CHARS,\n): string {\n const marker = \"\\n\\n▣ Extracted\"\n const index = message.indexOf(marker)\n if (index === -1) {\n return message\n }\n const extracted = message.slice(index)\n if (extracted.length <= maxChars) {\n return message\n }\n return message.slice(0, index) + truncateToastSummary(extracted, maxChars)\n}\n\nexport async function sendUnifiedNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n pruneToolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n reason: PruneReason | undefined,\n params: any,\n workingDirectory: string,\n): Promise<boolean> {\n const hasPruned = pruneToolIds.length > 0\n if (!hasPruned) {\n return false\n }\n\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n const message =\n config.pruneNotification === \"minimal\"\n ? buildMinimalMessage(state, reason)\n : buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory)\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = truncateExtractedSection(message)\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nfunction buildCompressionSummary(\n entries: CompressionNotificationEntry[],\n state: SessionState,\n): string {\n if (entries.length === 1) {\n return entries[0]?.summary ?? \"\"\n }\n\n return entries\n .map((entry) => {\n const topic =\n state.prune.messages.blocksById.get(entry.blockId)?.topic ?? \"(unknown topic)\"\n return `### ${topic}\\n${entry.summary}`\n })\n .join(\"\\n\\n\")\n}\n\nfunction getCompressionLabel(entries: CompressionNotificationEntry[]): string {\n const runId = entries[0]?.runId\n if (runId === undefined) {\n return \"Compression\"\n }\n\n return `Compression #${runId}`\n}\n\nfunction formatCompressionMetrics(removedTokens: number, summaryTokens: number): string {\n const metrics = [`-${formatTokenCount(removedTokens, true)} removed`]\n if (summaryTokens > 0) {\n metrics.push(`+${formatTokenCount(summaryTokens, true)} summary`)\n }\n return metrics.join(\", \")\n}\n\nexport async function sendCompressNotification(\n client: any,\n logger: Logger,\n config: PluginConfig,\n state: SessionState,\n sessionId: string,\n entries: CompressionNotificationEntry[],\n batchTopic: string | undefined,\n sessionMessageIds: string[],\n params: any,\n): Promise<boolean> {\n if (config.pruneNotification === \"off\") {\n return false\n }\n\n if (entries.length === 0) {\n return false\n }\n\n let message: string\n const compressionLabel = getCompressionLabel(entries)\n const summary = buildCompressionSummary(entries, state)\n const summaryTokens = entries.reduce((total, entry) => total + entry.summaryTokens, 0)\n const summaryTokensStr = formatTokenCount(summaryTokens)\n const compressedTokens = entries.reduce((total, entry) => {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n logger.error(\"Compression block missing for notification\", {\n compressionId: entry.blockId,\n sessionId,\n })\n return total\n }\n\n return total + compressionBlock.compressedTokens\n }, 0)\n\n const newlyCompressedMessageIds: string[] = []\n const newlyCompressedToolIds: string[] = []\n const seenMessageIds = new Set<string>()\n const seenToolIds = new Set<string>()\n\n for (const entry of entries) {\n const compressionBlock = state.prune.messages.blocksById.get(entry.blockId)\n if (!compressionBlock) {\n continue\n }\n\n for (const messageId of compressionBlock.directMessageIds) {\n if (seenMessageIds.has(messageId)) {\n continue\n }\n seenMessageIds.add(messageId)\n newlyCompressedMessageIds.push(messageId)\n }\n\n for (const toolId of compressionBlock.directToolIds) {\n if (seenToolIds.has(toolId)) {\n continue\n }\n seenToolIds.add(toolId)\n newlyCompressedToolIds.push(toolId)\n }\n }\n\n const topic =\n batchTopic ??\n (entries.length === 1\n ? (state.prune.messages.blocksById.get(entries[0]?.blockId ?? -1)?.topic ??\n \"(unknown topic)\")\n : \"(unknown topic)\")\n\n const totalActiveSummaryTkns = getActiveSummaryTokenUsage(state)\n const totalGross = state.stats.totalPruneTokens + state.stats.pruneTokenCounter\n const notificationHeader = `▣ DCP | ${formatCompressionMetrics(totalGross, totalActiveSummaryTkns)}`\n\n if (config.pruneNotification === \"minimal\") {\n message = `${notificationHeader} — ${compressionLabel}`\n } else {\n message = notificationHeader\n\n const activePrunedMessages = new Map<string, number>()\n for (const [messageId, entry] of state.prune.messages.byMessageId) {\n if (entry.activeBlockIds.length > 0) {\n activePrunedMessages.set(messageId, entry.tokenCount)\n }\n }\n const progressBar = formatProgressBar(\n sessionMessageIds,\n activePrunedMessages,\n newlyCompressedMessageIds,\n 50,\n )\n message += `\\n\\n${progressBar}`\n message += `\\n▣ ${compressionLabel} ${formatCompressionMetrics(compressedTokens, summaryTokens)}`\n message += `\\n→ Topic: ${topic}`\n message += `\\n→ Items: ${newlyCompressedMessageIds.length} messages`\n if (newlyCompressedToolIds.length > 0) {\n message += ` and ${newlyCompressedToolIds.length} tools compressed`\n } else {\n message += ` compressed`\n }\n if (config.compress.showCompression) {\n message += `\\n→ Compression (~${summaryTokensStr}): ${summary}`\n }\n }\n\n if (config.pruneNotificationType === \"toast\") {\n let toastMessage = message\n if (config.compress.showCompression) {\n const truncatedSummary = truncateToastSummary(summary)\n if (truncatedSummary !== summary) {\n toastMessage = toastMessage.replace(\n `\\n→ Compression (~${summaryTokensStr}): ${summary}`,\n `\\n→ Compression (~${summaryTokensStr}): ${truncatedSummary}`,\n )\n }\n }\n toastMessage =\n config.pruneNotification === \"minimal\" ? toastMessage : truncateToastBody(toastMessage)\n\n await client.tui.showToast({\n body: {\n title: \"DCP: Compress Notification\",\n message: toastMessage,\n variant: \"info\",\n duration: 5000,\n },\n })\n return true\n }\n\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return true\n}\n\nexport async function sendIgnoredMessage(\n client: any,\n sessionID: string,\n text: string,\n params: any,\n logger: Logger,\n): Promise<void> {\n const agent = params.agent || undefined\n const variant = params.variant || undefined\n const model =\n params.providerId && params.modelId\n ? {\n providerID: params.providerId,\n modelID: params.modelId,\n }\n : undefined\n\n try {\n await client.session.prompt({\n path: {\n id: sessionID,\n },\n body: {\n noReply: true,\n agent: agent,\n model: model,\n variant: variant,\n parts: [\n {\n type: \"text\",\n text: text,\n ignored: true,\n },\n ],\n },\n })\n } catch (error: any) {\n logger.error(\"Failed to send notification\", { error: error.message })\n }\n}\n","import type { WithParts } from \"../state\"\nimport { ensureSessionInitialized } from \"../state\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { assignMessageRefs } from \"../message-ids\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { deduplicate, purgeErrors } from \"../strategies\"\nimport { getCurrentParams, getCurrentTokenUsage } from \"../token-utils\"\nimport { sendCompressNotification } from \"../ui/notification\"\nimport type { ToolContext } from \"./types\"\nimport { buildSearchContext, fetchSessionMessages } from \"./search\"\nimport type { SearchContext } from \"./types\"\nimport { applyPendingCompressionDurations } from \"./timing\"\n\ninterface RunContext {\n ask(input: {\n permission: string\n patterns: string[]\n always: string[]\n metadata: Record<string, unknown>\n }): Promise<void>\n metadata(input: { title: string }): void\n sessionID: string\n}\n\nexport interface NotificationEntry {\n blockId: number\n runId: number\n summary: string\n summaryTokens: number\n}\n\nexport interface PreparedSession {\n rawMessages: WithParts[]\n searchContext: SearchContext\n}\n\nexport async function prepareSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n title: string,\n): Promise<PreparedSession> {\n if (ctx.state.manualMode && ctx.state.manualMode !== \"compress-pending\") {\n throw new Error(\n \"Manual mode: compress blocked. Do not retry until `<compress triggered manually>` appears in user context.\",\n )\n }\n\n await toolCtx.ask({\n permission: \"compress\",\n patterns: [\"*\"],\n always: [\"*\"],\n metadata: {},\n })\n\n toolCtx.metadata({ title })\n\n const rawMessages = await fetchSessionMessages(ctx.client, toolCtx.sessionID)\n\n await ensureSessionInitialized(\n ctx.client,\n ctx.state,\n toolCtx.sessionID,\n ctx.logger,\n rawMessages,\n ctx.config.manualMode.enabled,\n )\n\n assignMessageRefs(ctx.state, rawMessages)\n\n deduplicate(ctx.state, ctx.logger, ctx.config, rawMessages)\n purgeErrors(ctx.state, ctx.logger, ctx.config, rawMessages)\n\n return {\n rawMessages,\n searchContext: buildSearchContext(ctx.state, rawMessages),\n }\n}\n\nexport async function finalizeSession(\n ctx: ToolContext,\n toolCtx: RunContext,\n rawMessages: WithParts[],\n entries: NotificationEntry[],\n batchTopic: string | undefined,\n): Promise<void> {\n ctx.state.manualMode = ctx.state.manualMode ? \"active\" : false\n applyPendingCompressionDurations(ctx.state)\n await saveSessionState(ctx.state, ctx.logger)\n\n const params = getCurrentParams(ctx.state, rawMessages, ctx.logger)\n const sessionMessageIds = rawMessages\n .filter((msg) => !isIgnoredUserMessage(msg))\n .map((msg) => msg.info.id)\n\n await sendCompressNotification(\n ctx.client,\n ctx.logger,\n ctx.config,\n ctx.state,\n toolCtx.sessionID,\n entries,\n batchTopic,\n sessionMessageIds,\n params,\n )\n}\n","import type { WithParts } from \"../state\"\n\nconst SUB_AGENT_RESULT_BLOCK_REGEX = /(<task_result>\\s*)([\\s\\S]*?)(\\s*<\\/task_result>)/i\n\nexport function getSubAgentId(part: any): string | null {\n const sessionId = part?.state?.metadata?.sessionId\n if (typeof sessionId !== \"string\") {\n return null\n }\n\n const value = sessionId.trim()\n return value.length > 0 ? value : null\n}\n\nexport function buildSubagentResultText(messages: WithParts[]): string {\n const assistantMessages = messages.filter((message) => message.info.role === \"assistant\")\n if (assistantMessages.length === 0) {\n return \"\"\n }\n\n const lastAssistant = assistantMessages[assistantMessages.length - 1]\n const lastText = getLastTextPart(lastAssistant)\n\n if (assistantMessages.length < 2) {\n return lastText\n }\n\n const secondToLastAssistant = assistantMessages[assistantMessages.length - 2]\n if (!assistantMessageHasCompressTool(secondToLastAssistant)) {\n return lastText\n }\n\n const secondToLastText = getLastTextPart(secondToLastAssistant)\n return [secondToLastText, lastText].filter((text) => text.length > 0).join(\"\\n\\n\")\n}\n\nexport function mergeSubagentResult(output: string, subAgentResultText: string): string {\n if (!subAgentResultText || typeof output !== \"string\") {\n return output\n }\n\n return output.replace(\n SUB_AGENT_RESULT_BLOCK_REGEX,\n (_match, openTag: string, _body: string, closeTag: string) =>\n `${openTag}${subAgentResultText}${closeTag}`,\n )\n}\n\nfunction getLastTextPart(message: WithParts): string {\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (let index = parts.length - 1; index >= 0; index--) {\n const part = parts[index]\n if (part.type !== \"text\" || typeof part.text !== \"string\") {\n continue\n }\n\n const text = part.text.trim()\n if (!text) {\n continue\n }\n\n return text\n }\n\n return \"\"\n}\n\nfunction assistantMessageHasCompressTool(message: WithParts): boolean {\n const parts = Array.isArray(message.parts) ? message.parts : []\n return parts.some(\n (part) =>\n part.type === \"tool\" && part.tool === \"compress\" && part.state?.status === \"completed\",\n )\n}\n","import type { SessionState } from \"../state\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../subagents/subagent-results\"\nimport { fetchSessionMessages } from \"./search\"\nimport type { SearchContext, SelectionResolution } from \"./types\"\n\nexport function appendProtectedUserMessages(\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n state: SessionState,\n enabled: boolean,\n): string {\n if (!enabled) return summary\n\n const userTexts: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n if (message.info.role !== \"user\") continue\n if (isIgnoredUserMessage(message)) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type === \"text\" && typeof part.text === \"string\" && part.text.trim()) {\n userTexts.push(part.text)\n break\n }\n }\n }\n\n if (userTexts.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following user messages were sent in this conversation verbatim:\"\n const body = userTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\n\nexport function appendProtectedPromptInfo(\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n state: SessionState,\n enabled: boolean,\n): string {\n if (!enabled) return summary\n\n const protectedTexts: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n if (message.info.role !== \"user\") continue\n if (isIgnoredUserMessage(message)) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type !== \"text\" || typeof part.text !== \"string\") continue\n\n protectedTexts.push(...extractProtectedPromptInfo(part.text))\n }\n }\n\n if (protectedTexts.length === 0) {\n return summary\n }\n\n const heading =\n \"\\n\\nThe following protected prompt information was included in this conversation verbatim:\"\n const body = protectedTexts.map((text) => `\\n${text}`).join(\"\")\n return summary + heading + body\n}\n\nexport function extractProtectedPromptInfo(text: string): string[] {\n const protectedTexts: string[] = []\n const protectTagRegex = /<protect>([\\s\\S]*?)<\\/protect>/gi\n\n for (const match of text.matchAll(protectTagRegex)) {\n const protectedText = match[1]?.trim()\n if (protectedText) {\n protectedTexts.push(protectedText)\n }\n }\n\n return protectedTexts\n}\n\nexport async function appendProtectedTools(\n client: any,\n state: SessionState,\n allowSubAgents: boolean,\n summary: string,\n selection: SelectionResolution,\n searchContext: SearchContext,\n protectedTools: string[],\n protectedFilePatterns: string[] = [],\n): Promise<string> {\n const protectedOutputs: string[] = []\n\n for (const messageId of selection.messageIds) {\n const existingCompressionEntry = state.prune.messages.byMessageId.get(messageId)\n if (existingCompressionEntry && existingCompressionEntry.activeBlockIds.length > 0) {\n continue\n }\n\n const message = searchContext.rawMessagesById.get(messageId)\n if (!message) continue\n\n const parts = Array.isArray(message.parts) ? message.parts : []\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID) {\n let isToolProtected = isToolNameProtected(part.tool, protectedTools)\n\n if (!isToolProtected && protectedFilePatterns.length > 0) {\n const filePaths = getFilePathsFromParameters(part.tool, part.state?.input)\n if (isFilePathProtected(filePaths, protectedFilePatterns)) {\n isToolProtected = true\n }\n }\n\n if (isToolProtected) {\n const title = `Tool: ${part.tool}`\n let output = \"\"\n\n if (part.state?.status === \"completed\" && part.state?.output) {\n output =\n typeof part.state.output === \"string\"\n ? part.state.output\n : JSON.stringify(part.state.output)\n }\n\n if (\n allowSubAgents &&\n part.tool === \"task\" &&\n part.state?.status === \"completed\" &&\n typeof part.state?.output === \"string\"\n ) {\n const cachedSubAgentResult = state.subAgentResultCache.get(part.callID)\n\n if (cachedSubAgentResult !== undefined) {\n if (cachedSubAgentResult) {\n output = mergeSubagentResult(\n part.state.output,\n cachedSubAgentResult,\n )\n }\n } else {\n const subAgentSessionId = getSubAgentId(part)\n if (subAgentSessionId) {\n let subAgentResultText = \"\"\n try {\n const subAgentMessages = await fetchSessionMessages(\n client,\n subAgentSessionId,\n )\n subAgentResultText = buildSubagentResultText(subAgentMessages)\n } catch {\n subAgentResultText = \"\"\n }\n\n if (subAgentResultText) {\n state.subAgentResultCache.set(part.callID, subAgentResultText)\n output = mergeSubagentResult(\n part.state.output,\n subAgentResultText,\n )\n }\n }\n }\n }\n\n if (output) {\n protectedOutputs.push(`\\n### ${title}\\n${output}`)\n }\n }\n }\n }\n }\n\n if (protectedOutputs.length === 0) {\n return summary\n }\n\n const heading = \"\\n\\nThe following protected tools were used in this conversation as well:\"\n return summary + heading + protectedOutputs.join(\"\")\n}\n","import { 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 const missingBlockIds = validateSummaryPlaceholders(\n parsedPlaceholders,\n plan.selection.requiredBlockIds,\n plan.selection.startReference,\n plan.selection.endReference,\n searchContext.summaryByBlockId,\n )\n\n const injected = injectBlockPlaceholders(\n plan.entry.summary,\n parsedPlaceholders,\n searchContext.summaryByBlockId,\n plan.selection.startReference,\n plan.selection.endReference,\n )\n\n const summaryWithUsers = appendProtectedUserMessages(\n injected.expandedSummary,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectUserMessages,\n )\n\n const summaryWithPromptInfo = appendProtectedPromptInfo(\n summaryWithUsers,\n plan.selection,\n searchContext,\n ctx.state,\n ctx.config.compress.protectTags,\n )\n\n const summaryWithTools = await appendProtectedTools(\n ctx.client,\n ctx.state,\n ctx.config.experimental.allowSubAgents,\n summaryWithPromptInfo,\n plan.selection,\n searchContext,\n ctx.config.compress.protectedTools,\n ctx.config.protectedFilePatterns,\n )\n\n const completedSummary = appendMissingBlockSummaries(\n summaryWithTools,\n missingBlockIds,\n searchContext.summaryByBlockId,\n injected.consumedBlockIds,\n )\n\n preparedPlans.push({\n entry: plan.entry,\n selection: plan.selection,\n anchorMessageId: plan.anchorMessageId,\n finalSummary: completedSummary.expandedSummary,\n consumedBlockIds: completedSummary.consumedBlockIds,\n })\n }\n\n const runId = allocateRunId(ctx.state)\n\n for (const preparedPlan of preparedPlans) {\n const blockId = allocateBlockId(ctx.state)\n const storedSummary = wrapCompressedSummary(blockId, preparedPlan.finalSummary)\n const summaryTokens = countTokens(storedSummary)\n\n const applied = applyCompressionState(\n ctx.state,\n {\n topic: input.topic,\n batchTopic: input.topic,\n startId: preparedPlan.entry.startId,\n endId: preparedPlan.entry.endId,\n mode: \"range\",\n runId,\n compressMessageId: toolCtx.messageID,\n compressCallId: callId,\n summaryTokens,\n },\n preparedPlan.selection,\n preparedPlan.anchorMessageId,\n blockId,\n storedSummary,\n preparedPlan.consumedBlockIds,\n )\n\n totalCompressedMessages += applied.messageIds.length\n\n notifications.push({\n blockId,\n runId,\n summary: preparedPlan.finalSummary,\n summaryTokens,\n })\n }\n\n await finalizeSession(ctx, toolCtx, rawMessages, notifications, input.topic)\n\n return `Compressed ${totalCompressedMessages} messages into ${COMPRESSED_BLOCK_HEADER}.`\n },\n })\n}\n","import type { CompressionBlock, SessionState } from \"../state\"\nimport { resolveAnchorMessageId, resolveBoundaryIds, resolveSelection } from \"./search\"\nimport type {\n BoundaryReference,\n CompressRangeToolArgs,\n InjectedSummaryResult,\n ParsedBlockPlaceholder,\n ResolvedRangeCompression,\n SearchContext,\n} from \"./types\"\n\nconst BLOCK_PLACEHOLDER_REGEX = /\\(b(\\d+)\\)|\\{block_(\\d+)\\}/gi\n\nexport function validateArgs(args: CompressRangeToolArgs): void {\n if (typeof args.topic !== \"string\" || args.topic.trim().length === 0) {\n throw new Error(\"topic is required and must be a non-empty string\")\n }\n\n if (!Array.isArray(args.content) || args.content.length === 0) {\n throw new Error(\"content is required and must be a non-empty array\")\n }\n\n for (let index = 0; index < args.content.length; index++) {\n const entry = args.content[index]\n const prefix = `content[${index}]`\n\n if (typeof entry?.startId !== \"string\" || entry.startId.trim().length === 0) {\n throw new Error(`${prefix}.startId is required and must be a non-empty string`)\n }\n\n if (typeof entry?.endId !== \"string\" || entry.endId.trim().length === 0) {\n throw new Error(`${prefix}.endId is required and must be a non-empty string`)\n }\n\n if (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 let cursor = 0\n let expanded = summary\n const consumed: number[] = []\n const consumedSeen = new Set<number>()\n\n if (placeholders.length > 0) {\n expanded = \"\"\n for (const placeholder of placeholders) {\n const target = summaryByBlockId.get(placeholder.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${placeholder.blockId})`)\n }\n\n expanded += summary.slice(cursor, placeholder.startIndex)\n expanded += restoreSummary(target.summary)\n cursor = placeholder.endIndex\n\n if (!consumedSeen.has(placeholder.blockId)) {\n consumedSeen.add(placeholder.blockId)\n consumed.push(placeholder.blockId)\n }\n }\n\n expanded += summary.slice(cursor)\n }\n\n expanded = injectBoundarySummary(\n expanded,\n startReference,\n \"start\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n expanded = injectBoundarySummary(\n expanded,\n endReference,\n \"end\",\n summaryByBlockId,\n consumed,\n consumedSeen,\n )\n\n return {\n expandedSummary: expanded,\n consumedBlockIds: consumed,\n }\n}\n\nexport function appendMissingBlockSummaries(\n summary: string,\n missingBlockIds: number[],\n summaryByBlockId: Map<number, CompressionBlock>,\n consumedBlockIds: number[],\n): InjectedSummaryResult {\n const consumedSeen = new Set<number>(consumedBlockIds)\n const consumed = [...consumedBlockIds]\n\n const missingSummaries: string[] = []\n for (const blockId of missingBlockIds) {\n if (consumedSeen.has(blockId)) {\n continue\n }\n\n const target = summaryByBlockId.get(blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${blockId})`)\n }\n\n missingSummaries.push(`\\n### (b${blockId})\\n${restoreSummary(target.summary)}`)\n consumedSeen.add(blockId)\n consumed.push(blockId)\n }\n\n if (missingSummaries.length === 0) {\n return {\n expandedSummary: summary,\n consumedBlockIds: consumed,\n }\n }\n\n const heading =\n \"\\n\\nThe following previously compressed summaries were also part of this conversation section:\"\n\n return {\n expandedSummary: summary + heading + missingSummaries.join(\"\"),\n consumedBlockIds: consumed,\n }\n}\n\nfunction restoreSummary(summary: string): string {\n const headerMatch = summary.match(/^\\s*\\[Compressed conversation(?: section)?(?: b\\d+)?\\]/i)\n if (!headerMatch) {\n return summary\n }\n\n const afterHeader = summary.slice(headerMatch[0].length)\n const withoutLeadingBreaks = afterHeader.replace(/^(?:\\r?\\n)+/, \"\")\n return withoutLeadingBreaks\n .replace(/(?:\\r?\\n)*<dcp-message-id>b\\d+<\\/dcp-message-id>\\s*$/i, \"\")\n .replace(/(?:\\r?\\n)+$/, \"\")\n}\n\nfunction injectBoundarySummary(\n summary: string,\n reference: BoundaryReference,\n position: \"start\" | \"end\",\n summaryByBlockId: Map<number, CompressionBlock>,\n consumed: number[],\n consumedSeen: Set<number>,\n): string {\n if (reference.kind !== \"compressed-block\" || reference.blockId === undefined) {\n return summary\n }\n if (consumedSeen.has(reference.blockId)) {\n return summary\n }\n\n const target = summaryByBlockId.get(reference.blockId)\n if (!target) {\n throw new Error(`Compressed block not found: (b${reference.blockId})`)\n }\n\n const injectedBody = restoreSummary(target.summary)\n const left = position === \"start\" ? injectedBody.trim() : summary.trim()\n const right = position === \"start\" ? summary.trim() : injectedBody.trim()\n const next = !left ? right : !right ? left : `${left}\\n\\n${right}`\n\n consumedSeen.add(reference.blockId)\n consumed.push(reference.blockId)\n return next\n}\n","export type PermissionAction = \"ask\" | \"allow\" | \"deny\"\n\nexport type PermissionValue = PermissionAction | Record<string, PermissionAction>\n\nexport type PermissionConfig = Record<string, PermissionValue> | undefined\n\nexport interface HostPermissionSnapshot {\n global: PermissionConfig\n agents: Record<string, PermissionConfig>\n}\n\ntype PermissionRule = {\n permission: string\n pattern: string\n action: PermissionAction\n}\n\nconst findLastMatchingRule = (\n rules: PermissionRule[],\n predicate: (rule: PermissionRule) => boolean,\n): PermissionRule | undefined => {\n for (let index = rules.length - 1; index >= 0; index -= 1) {\n const rule = rules[index]\n if (rule && predicate(rule)) {\n return rule\n }\n }\n\n return undefined\n}\n\nconst wildcardMatch = (value: string, pattern: string): boolean => {\n const normalizedValue = value.replaceAll(\"\\\\\", \"/\")\n let escaped = pattern\n .replaceAll(\"\\\\\", \"/\")\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\")\n\n if (escaped.endsWith(\" .*\")) {\n escaped = escaped.slice(0, -3) + \"( .*)?\"\n }\n\n const flags = process.platform === \"win32\" ? \"si\" : \"s\"\n return new RegExp(`^${escaped}$`, flags).test(normalizedValue)\n}\n\nconst getPermissionRules = (permissionConfigs: PermissionConfig[]): PermissionRule[] => {\n const rules: PermissionRule[] = []\n for (const permissionConfig of permissionConfigs) {\n if (!permissionConfig) {\n continue\n }\n\n for (const [permission, value] of Object.entries(permissionConfig)) {\n if (value === \"ask\" || value === \"allow\" || value === \"deny\") {\n rules.push({ permission, pattern: \"*\", action: value })\n continue\n }\n\n for (const [pattern, action] of Object.entries(value)) {\n if (action === \"ask\" || action === \"allow\" || action === \"deny\") {\n rules.push({ permission, pattern, action })\n }\n }\n }\n }\n return rules\n}\n\nexport const compressDisabledByOpencode = (...permissionConfigs: PermissionConfig[]): boolean => {\n const match = findLastMatchingRule(getPermissionRules(permissionConfigs), (rule) =>\n wildcardMatch(\"compress\", rule.permission),\n )\n\n return match?.pattern === \"*\" && match.action === \"deny\"\n}\n\nexport const resolveEffectiveCompressPermission = (\n basePermission: PermissionAction,\n hostPermissions: HostPermissionSnapshot,\n agentName?: string,\n): PermissionAction => {\n if (basePermission === \"deny\") {\n return \"deny\"\n }\n\n return compressDisabledByOpencode(\n hostPermissions.global,\n agentName ? hostPermissions.agents[agentName] : undefined,\n )\n ? \"deny\"\n : basePermission\n}\n\nexport const hasExplicitToolPermission = (\n permissionConfig: PermissionConfig,\n tool: string,\n): boolean => {\n return permissionConfig ? Object.prototype.hasOwnProperty.call(permissionConfig, tool) : false\n}\n","import { writeFile, mkdir } from \"fs/promises\"\nimport { join } from \"path\"\nimport { existsSync } from \"fs\"\nimport { homedir } from \"os\"\n\nexport class Logger {\n private logDir: string\n public enabled: boolean\n\n constructor(enabled: boolean) {\n this.enabled = enabled\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n this.logDir = join(configHome, \"opencode\", \"logs\", \"dcp\")\n }\n\n private async ensureLogDir() {\n if (!existsSync(this.logDir)) {\n await mkdir(this.logDir, { recursive: true })\n }\n }\n\n private formatData(data?: any): string {\n if (!data) return \"\"\n\n const parts: string[] = []\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined || value === null) continue\n\n // Format arrays compactly\n if (Array.isArray(value)) {\n if (value.length === 0) continue\n parts.push(\n `${key}=[${value.slice(0, 3).join(\",\")}${value.length > 3 ? `...+${value.length - 3}` : \"\"}]`,\n )\n } else if (typeof value === \"object\") {\n const str = JSON.stringify(value)\n if (str.length < 50) {\n parts.push(`${key}=${str}`)\n }\n } else {\n parts.push(`${key}=${value}`)\n }\n }\n return parts.join(\" \")\n }\n\n private getCallerFile(skipFrames: number = 3): string {\n const originalPrepareStackTrace = Error.prepareStackTrace\n try {\n const err = new Error()\n Error.prepareStackTrace = (_, stack) => stack\n const stack = err.stack as unknown as NodeJS.CallSite[]\n Error.prepareStackTrace = originalPrepareStackTrace\n\n // Skip specified number of frames to get to actual caller\n for (let i = skipFrames; i < stack.length; i++) {\n const filename = stack[i]?.getFileName()\n if (filename && !filename.includes(\"/logger.\")) {\n // Extract just the filename without path and extension\n const match = filename.match(/([^/\\\\]+)\\.[tj]s$/)\n return match ? match[1] : filename\n }\n }\n return \"unknown\"\n } catch {\n return \"unknown\"\n }\n }\n\n private async write(level: string, component: string, message: string, data?: any) {\n if (!this.enabled) return\n\n try {\n await this.ensureLogDir()\n\n const timestamp = new Date().toISOString()\n const dataStr = this.formatData(data)\n\n const logLine = `${timestamp} ${level.padEnd(5)} ${component}: ${message}${dataStr ? \" | \" + dataStr : \"\"}\\n`\n\n const dailyLogDir = join(this.logDir, \"daily\")\n if (!existsSync(dailyLogDir)) {\n await mkdir(dailyLogDir, { recursive: true })\n }\n\n const logFile = join(dailyLogDir, `${new Date().toISOString().split(\"T\")[0]}.log`)\n await writeFile(logFile, logLine, { flag: \"a\" })\n } catch (error) {}\n }\n\n info(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"INFO\", component, message, data)\n }\n\n debug(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"DEBUG\", component, message, data)\n }\n\n warn(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"WARN\", component, message, data)\n }\n\n error(message: string, data?: any) {\n const component = this.getCallerFile(2)\n return this.write(\"ERROR\", component, message, data)\n }\n\n /**\n * Strips unnecessary metadata from messages for cleaner debug logs.\n *\n * Removed:\n * - All IDs (id, sessionID, messageID, parentID)\n * - summary, path, cost, model, agent, mode, finish, providerID, modelID\n * - step-start and step-finish parts entirely\n * - snapshot fields\n * - ignored text parts\n *\n * Kept:\n * - role, time (created only), tokens (input, output, reasoning, cache)\n * - text, reasoning, tool parts with content\n * - tool calls with: tool, callID, input, output, metadata\n */\n private minimizeForDebug(messages: any[]): any[] {\n return messages.map((msg) => {\n const minimized: any = {\n role: msg.info?.role,\n }\n\n if (msg.info?.time?.created) {\n minimized.time = msg.info.time.created\n }\n\n if (msg.info?.tokens) {\n minimized.tokens = {\n input: msg.info.tokens.input,\n output: msg.info.tokens.output,\n reasoning: msg.info.tokens.reasoning,\n cache: msg.info.tokens.cache,\n }\n }\n\n if (msg.parts) {\n minimized.parts = msg.parts\n .map((part: any) => {\n if (part.type === \"step-start\" || part.type === \"step-finish\") {\n return null\n }\n\n if (part.type === \"text\") {\n if (part.ignored) return null\n const textPart: any = { type: \"text\", text: part.text }\n if (part.metadata) textPart.metadata = part.metadata\n return textPart\n }\n\n if (part.type === \"reasoning\") {\n const reasoningPart: any = { type: \"reasoning\", text: part.text }\n if (part.metadata) reasoningPart.metadata = part.metadata\n return reasoningPart\n }\n\n if (part.type === \"tool\") {\n const toolPart: any = {\n type: \"tool\",\n tool: part.tool,\n callID: part.callID,\n }\n\n if (part.state?.status) {\n toolPart.status = part.state.status\n }\n if (part.state?.input) {\n toolPart.input = part.state.input\n }\n if (part.state?.output) {\n toolPart.output = part.state.output\n }\n if (part.state?.error) {\n toolPart.error = part.state.error\n }\n if (part.metadata) {\n toolPart.metadata = part.metadata\n }\n if (part.state?.metadata) {\n toolPart.metadata = {\n ...(toolPart.metadata || {}),\n ...part.state.metadata,\n }\n }\n if (part.state?.title) {\n toolPart.title = part.state.title\n }\n\n return toolPart\n }\n\n return null\n })\n .filter(Boolean)\n }\n\n return minimized\n })\n }\n\n async saveContext(sessionId: string, messages: any[]) {\n if (!this.enabled) return\n\n try {\n const contextDir = join(this.logDir, \"context\", sessionId)\n if (!existsSync(contextDir)) {\n await mkdir(contextDir, { recursive: true })\n }\n\n const minimized = this.minimizeForDebug(messages).filter(\n (msg) => msg.parts && msg.parts.length > 0,\n )\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\")\n const contextFile = join(contextDir, `${timestamp}.json`)\n await writeFile(contextFile, JSON.stringify(minimized, null, 2))\n } catch (error) {}\n }\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport type { Logger } from \"../logger\"\nimport { SYSTEM as SYSTEM_PROMPT } from \"./system\"\nimport { COMPRESS_RANGE as COMPRESS_RANGE_PROMPT } from \"./compress-range\"\nimport { COMPRESS_MESSAGE as COMPRESS_MESSAGE_PROMPT } from \"./compress-message\"\nimport { CONTEXT_LIMIT_NUDGE } from \"./context-limit-nudge\"\nimport { TURN_NUDGE } from \"./turn-nudge\"\nimport { ITERATION_NUDGE } from \"./iteration-nudge\"\nimport { MANUAL_MODE_SYSTEM_EXTENSION, SUBAGENT_SYSTEM_EXTENSION } from \"./extensions/system\"\n\nexport type PromptKey =\n | \"system\"\n | \"compress-range\"\n | \"compress-message\"\n | \"context-limit-nudge\"\n | \"turn-nudge\"\n | \"iteration-nudge\"\n\ntype EditablePromptField =\n | \"system\"\n | \"compressRange\"\n | \"compressMessage\"\n | \"contextLimitNudge\"\n | \"turnNudge\"\n | \"iterationNudge\"\n\ninterface PromptDefinition {\n key: PromptKey\n fileName: string\n label: string\n description: string\n usage: string\n runtimeField: EditablePromptField\n}\n\ninterface PromptOverrideCandidate {\n path: string\n}\n\ninterface PromptPaths {\n defaultsDir: string\n globalOverridesDir: string\n configDirOverridesDir: string | null\n projectOverridesDir: string | null\n}\n\nexport interface RuntimePrompts {\n system: string\n compressRange: string\n compressMessage: string\n contextLimitNudge: string\n turnNudge: string\n iterationNudge: string\n manualExtension: string\n subagentExtension: string\n}\n\nconst PROMPT_DEFINITIONS: PromptDefinition[] = [\n {\n key: \"system\",\n fileName: \"system.md\",\n label: \"System\",\n description: \"Core system-level DCP instruction block\",\n usage: \"Injected into the model system prompt on every request\",\n runtimeField: \"system\",\n },\n {\n key: \"compress-range\",\n fileName: \"compress-range.md\",\n label: \"Compress Range\",\n description: \"range-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the range-mode compress tool description\",\n runtimeField: \"compressRange\",\n },\n {\n key: \"compress-message\",\n fileName: \"compress-message.md\",\n label: \"Compress Message\",\n description: \"message-mode compress tool instructions and summary constraints\",\n usage: \"Registered as the message-mode compress tool description\",\n runtimeField: \"compressMessage\",\n },\n {\n key: \"context-limit-nudge\",\n fileName: \"context-limit-nudge.md\",\n label: \"Context Limit Nudge\",\n description: \"High-priority nudge when context is over max threshold\",\n usage: \"Injected when context usage is beyond configured max limits\",\n runtimeField: \"contextLimitNudge\",\n },\n {\n key: \"turn-nudge\",\n fileName: \"turn-nudge.md\",\n label: \"Turn Nudge\",\n description: \"Nudge to compress closed ranges at turn boundaries\",\n usage: \"Injected when context is between min and max limits at a new user turn\",\n runtimeField: \"turnNudge\",\n },\n {\n key: \"iteration-nudge\",\n fileName: \"iteration-nudge.md\",\n label: \"Iteration Nudge\",\n description: \"Nudge after many iterations without user input\",\n usage: \"Injected when iteration threshold is crossed\",\n runtimeField: \"iterationNudge\",\n },\n]\n\nexport const PROMPT_KEYS: PromptKey[] = [\n \"system\",\n \"compress-range\",\n \"compress-message\",\n \"context-limit-nudge\",\n \"turn-nudge\",\n \"iteration-nudge\",\n]\n\nconst HTML_COMMENT_REGEX = /<!--[\\s\\S]*?-->/g\nconst LEGACY_INLINE_COMMENT_LINE_REGEX = /^[ \\t]*\\/\\/.*?\\/\\/[ \\t]*$/gm\nconst DCP_SYSTEM_REMINDER_TAG_REGEX =\n /^\\s*<dcp-system-reminder\\b[^>]*>[\\s\\S]*<\\/dcp-system-reminder>\\s*$/i\nconst DEFAULTS_README_FILE = \"README.md\"\n\nconst BUNDLED_EDITABLE_PROMPTS: Record<EditablePromptField, string> = {\n system: SYSTEM_PROMPT,\n compressRange: COMPRESS_RANGE_PROMPT,\n compressMessage: COMPRESS_MESSAGE_PROMPT,\n contextLimitNudge: CONTEXT_LIMIT_NUDGE,\n turnNudge: TURN_NUDGE,\n iterationNudge: ITERATION_NUDGE,\n}\n\nconst INTERNAL_PROMPT_EXTENSIONS = {\n manualExtension: MANUAL_MODE_SYSTEM_EXTENSION,\n subagentExtension: SUBAGENT_SYSTEM_EXTENSION,\n}\n\nfunction createBundledRuntimePrompts(): RuntimePrompts {\n return {\n system: BUNDLED_EDITABLE_PROMPTS.system,\n compressRange: BUNDLED_EDITABLE_PROMPTS.compressRange,\n compressMessage: BUNDLED_EDITABLE_PROMPTS.compressMessage,\n contextLimitNudge: BUNDLED_EDITABLE_PROMPTS.contextLimitNudge,\n turnNudge: BUNDLED_EDITABLE_PROMPTS.turnNudge,\n iterationNudge: BUNDLED_EDITABLE_PROMPTS.iterationNudge,\n manualExtension: INTERNAL_PROMPT_EXTENSIONS.manualExtension,\n subagentExtension: INTERNAL_PROMPT_EXTENSIONS.subagentExtension,\n }\n}\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate)) {\n try {\n if (statSync(candidate).isDirectory()) {\n return candidate\n }\n } catch {\n // ignore inaccessible entries while walking upward\n }\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction resolvePromptPaths(workingDirectory: string): PromptPaths {\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n const globalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n const defaultsDir = join(globalRoot, \"defaults\")\n const globalOverridesDir = join(globalRoot, \"overrides\")\n\n const configDirOverridesDir = process.env.OPENCODE_CONFIG_DIR\n ? join(process.env.OPENCODE_CONFIG_DIR, \"dcp-prompts\", \"overrides\")\n : null\n\n const opencodeDir = findOpencodeDir(workingDirectory)\n const projectOverridesDir = opencodeDir ? join(opencodeDir, \"dcp-prompts\", \"overrides\") : null\n\n return {\n defaultsDir,\n globalOverridesDir,\n configDirOverridesDir,\n projectOverridesDir,\n }\n}\n\nfunction stripConditionalTag(content: string, tagName: string): string {\n const regex = new RegExp(`<${tagName}>[\\\\s\\\\S]*?<\\/${tagName}>`, \"gi\")\n return content.replace(regex, \"\")\n}\n\nfunction unwrapDcpTagIfWrapped(content: string): string {\n const trimmed = content.trim()\n\n if (DCP_SYSTEM_REMINDER_TAG_REGEX.test(trimmed)) {\n return trimmed\n .replace(/^\\s*<dcp-system-reminder\\b[^>]*>\\s*/i, \"\")\n .replace(/\\s*<\\/dcp-system-reminder>\\s*$/i, \"\")\n .trim()\n }\n\n return trimmed\n}\n\nfunction normalizeReminderPromptContent(content: string): string {\n const normalized = content.trim()\n\n if (!normalized) {\n return \"\"\n }\n\n const startsWrapped = /^\\s*<dcp-system-reminder\\b[^>]*>/i.test(normalized)\n const endsWrapped = /<\\/dcp-system-reminder>\\s*$/i.test(normalized)\n\n if (startsWrapped !== endsWrapped) {\n return \"\"\n }\n\n return unwrapDcpTagIfWrapped(normalized)\n}\n\nfunction stripPromptComments(content: string): string {\n return content\n .replace(/^\\uFEFF/, \"\")\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(HTML_COMMENT_REGEX, \"\")\n .replace(LEGACY_INLINE_COMMENT_LINE_REGEX, \"\")\n}\n\nfunction toEditablePromptText(definition: PromptDefinition, rawContent: string): string {\n let normalized = stripPromptComments(rawContent).trim()\n if (!normalized) {\n return \"\"\n }\n\n if (definition.key === \"system\") {\n normalized = stripConditionalTag(normalized, \"manual\")\n normalized = stripConditionalTag(normalized, \"subagent\")\n }\n\n if (definition.key !== \"compress-range\" && definition.key !== \"compress-message\") {\n normalized = normalizeReminderPromptContent(normalized)\n }\n\n return normalized.trim()\n}\n\nfunction wrapRuntimePromptContent(definition: PromptDefinition, editableText: string): string {\n const trimmed = editableText.trim()\n if (!trimmed) {\n return \"\"\n }\n\n if (definition.key === \"compress-range\" || definition.key === \"compress-message\") {\n return trimmed\n }\n\n return `<dcp-system-reminder>\\n${trimmed}\\n</dcp-system-reminder>`\n}\n\nfunction buildDefaultPromptFileContent(bundledEditableText: string): string {\n return `${bundledEditableText.trim()}\\n`\n}\n\nfunction buildDefaultsReadmeContent(): string {\n const lines: string[] = []\n lines.push(\"# DCP Prompt Defaults\")\n lines.push(\"\")\n lines.push(\"This directory stores the DCP prompts.\")\n lines.push(\"Each prompt file here should contain plain text only (no XML wrappers).\")\n lines.push(\"\")\n lines.push(\"## Creating Overrides\")\n lines.push(\"\")\n lines.push(\n \"1. Copy a prompt file from this directory into an overrides directory using the same filename.\",\n )\n lines.push(\"2. Edit the copied file using plain text.\")\n lines.push(\"3. Restart OpenCode.\")\n lines.push(\"\")\n lines.push(\"To reset an override, delete the matching file from your overrides directory.\")\n lines.push(\"\")\n lines.push(\n \"Do not edit the default prompt files directly, they are just for reference, only files in the overrides directory are used.\",\n )\n lines.push(\"\")\n lines.push(\"Override precedence (highest first):\")\n lines.push(\"1. `.opencode/dcp-prompts/overrides/` (project)\")\n lines.push(\"2. `$OPENCODE_CONFIG_DIR/dcp-prompts/overrides/` (config dir)\")\n lines.push(\"3. `~/.config/opencode/dcp-prompts/overrides/` (global)\")\n lines.push(\"\")\n lines.push(\"## Prompt Files\")\n lines.push(\"\")\n\n for (const definition of PROMPT_DEFINITIONS) {\n lines.push(`- \\`${definition.fileName}\\``)\n lines.push(` - Purpose: ${definition.description}.`)\n lines.push(` - Runtime use: ${definition.usage}.`)\n }\n\n return `${lines.join(\"\\n\")}\\n`\n}\n\nfunction readFileIfExists(filePath: string): string | null {\n if (!existsSync(filePath)) {\n return null\n }\n\n try {\n return readFileSync(filePath, \"utf-8\")\n } catch {\n return null\n }\n}\n\nexport class PromptStore {\n private readonly logger: Logger\n private readonly paths: PromptPaths\n private readonly customPromptsEnabled: boolean\n private runtimePrompts: RuntimePrompts\n\n constructor(logger: Logger, workingDirectory: string, customPromptsEnabled = false) {\n this.logger = logger\n this.paths = resolvePromptPaths(workingDirectory)\n this.customPromptsEnabled = customPromptsEnabled\n this.runtimePrompts = createBundledRuntimePrompts()\n\n if (this.customPromptsEnabled) {\n this.ensureDefaultFiles()\n }\n this.reload()\n }\n\n getRuntimePrompts(): RuntimePrompts {\n return { ...this.runtimePrompts }\n }\n\n reload(): void {\n const nextPrompts = createBundledRuntimePrompts()\n\n if (!this.customPromptsEnabled) {\n this.runtimePrompts = nextPrompts\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledSource = BUNDLED_EDITABLE_PROMPTS[definition.runtimeField]\n const bundledEditable = toEditablePromptText(definition, bundledSource)\n const bundledRuntime = wrapRuntimePromptContent(definition, bundledEditable)\n const fallbackValue = bundledRuntime || bundledSource.trim()\n let effectiveValue = fallbackValue\n\n for (const candidate of this.getOverrideCandidates(definition.fileName)) {\n const rawOverride = readFileIfExists(candidate.path)\n if (rawOverride === null) {\n continue\n }\n\n const editableOverride = toEditablePromptText(definition, rawOverride)\n if (!editableOverride) {\n this.logger.warn(\"Prompt override is empty or invalid after normalization\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n const wrappedOverride = wrapRuntimePromptContent(definition, editableOverride)\n if (!wrappedOverride) {\n this.logger.warn(\"Prompt override could not be wrapped for runtime\", {\n key: definition.key,\n path: candidate.path,\n })\n continue\n }\n\n effectiveValue = wrappedOverride\n break\n }\n\n nextPrompts[definition.runtimeField] = effectiveValue\n }\n\n this.runtimePrompts = nextPrompts\n }\n\n private getOverrideCandidates(fileName: string): PromptOverrideCandidate[] {\n const candidates: PromptOverrideCandidate[] = []\n\n if (this.paths.projectOverridesDir) {\n candidates.push({\n path: join(this.paths.projectOverridesDir, fileName),\n })\n }\n\n if (this.paths.configDirOverridesDir) {\n candidates.push({\n path: join(this.paths.configDirOverridesDir, fileName),\n })\n }\n\n candidates.push({\n path: join(this.paths.globalOverridesDir, fileName),\n })\n\n return candidates\n }\n\n private ensureDefaultFiles(): void {\n try {\n mkdirSync(this.paths.defaultsDir, { recursive: true })\n mkdirSync(this.paths.globalOverridesDir, { recursive: true })\n } catch {\n this.logger.warn(\"Failed to initialize prompt directories\", {\n defaultsDir: this.paths.defaultsDir,\n globalOverridesDir: this.paths.globalOverridesDir,\n })\n return\n }\n\n for (const definition of PROMPT_DEFINITIONS) {\n const bundledEditable = toEditablePromptText(\n definition,\n BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const managedContent = buildDefaultPromptFileContent(\n bundledEditable || BUNDLED_EDITABLE_PROMPTS[definition.runtimeField],\n )\n const filePath = join(this.paths.defaultsDir, definition.fileName)\n\n try {\n const existing = readFileIfExists(filePath)\n if (existing === managedContent) {\n continue\n }\n writeFileSync(filePath, managedContent, \"utf-8\")\n } catch {\n this.logger.warn(\"Failed to write default prompt file\", {\n key: definition.key,\n path: filePath,\n })\n }\n }\n\n const readmePath = join(this.paths.defaultsDir, DEFAULTS_README_FILE)\n const readmeContent = buildDefaultsReadmeContent()\n\n try {\n const existing = readFileIfExists(readmePath)\n if (existing !== readmeContent) {\n writeFileSync(readmePath, readmeContent, \"utf-8\")\n }\n } catch {\n this.logger.warn(\"Failed to write defaults README\", {\n path: readmePath,\n })\n }\n }\n}\n","export const SYSTEM = `\nYou 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.\n- \\`startId\\` must appear before \\`endId\\`.\n- Do not invent IDs. Use only IDs that are present in context.\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 = `<dcp-system-reminder>\nCRITICAL WARNING: MAX CONTEXT LIMIT REACHED\n\nYou are at or beyond the configured max context threshold. This is an emergency context-recovery moment.\n\nYou MUST use the \\`compress\\` tool now. Do not continue normal exploration until compression is handled.\n\nIf you are in the middle of a critical atomic operation, finish that atomic step first, then compress immediately.\n\nSELECTION PROCESS\nStart from older, resolved history and capture as much stale context as safely possible in one pass.\nAvoid the newest active working messages unless it is clearly closed.\n\nSUMMARY REQUIREMENTS\nYour summary MUST cover all essential details from the selected messages so work can continue.\nIf the compressed range includes user messages, preserve user intent exactly. Prefer direct quotes for short user messages to avoid semantic drift.\n</dcp-system-reminder>\n`\n","export const TURN_NUDGE = `<dcp-system-reminder>\nEvaluate the conversation for compressible ranges.\n\nIf any messages are cleanly closed and unlikely to be needed again, use the compress tool on them.\nIf direction has shifted, compress earlier ranges that are now less relevant.\n\nThe goal is to filter noise and distill key information so context accumulation stays under control.\nKeep active context uncompressed.\n</dcp-system-reminder>\n`\n","export const ITERATION_NUDGE = `<dcp-system-reminder>\nYou've been iterating for a while after the last user message.\n\nIf there is a closed portion that is unlikely to be referenced immediately (for example, finished research before implementation), use the compress tool on it now.\n</dcp-system-reminder>\n`\n","export const MANUAL_MODE_SYSTEM_EXTENSION = `<dcp-system-reminder>\nManual mode is enabled. Do NOT use compress unless the user has explicitly triggered it through a manual marker.\n\nOnly use the compress tool after seeing \\`<compress triggered manually>\\` in the current user instruction context.\n\nIssue exactly ONE compress tool per manual trigger. Do NOT launch multiple compress tools in parallel. Each trigger grants a single compression; after it completes, wait for the next trigger.\n\nAfter completing a manually triggered context-management action, STOP IMMEDIATELY. Do NOT continue with any task execution. End your response right after the tool use completes and wait for the next user input.\n</dcp-system-reminder>\n`\n\nexport const SUBAGENT_SYSTEM_EXTENSION = `<dcp-system-reminder>\nYou are operating in a subagent environment.\n\nThe initial subagent instruction is imperative and must be followed exactly.\nIt is the only user message intentionally not assigned a message ID, and therefore is not eligible for compression.\nAll subsequent messages in the session will have IDs.\n</dcp-system-reminder>\n`\n\nexport function buildProtectedToolsExtension(protectedTools: string[]): string {\n if (protectedTools.length === 0) {\n return \"\"\n }\n\n const toolList = protectedTools.map((t) => `\\`${t}\\``).join(\", \")\n return `<dcp-system-reminder>\nThe following tools are environment-managed: ${toolList}.\nTheir outputs are automatically preserved during compression.\nDo not include their content in compress tool summaries — the environment retains it independently.\n</dcp-system-reminder>`\n}\n","import { createHash } from \"node:crypto\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\n\nconst SUMMARY_ID_HASH_LENGTH = 16\nconst DCP_BLOCK_ID_TAG_REGEX = /(<dcp-message-id(?=[\\s>])[^>]*>)b\\d+(<\\/dcp-message-id>)/g\nconst DCP_PAIRED_TAG_REGEX = /<dcp[^>]*>[\\s\\S]*?<\\/dcp[^>]*>/gi\nconst DCP_UNPAIRED_TAG_REGEX = /<\\/?dcp[^>]*>/gi\n\nconst generateStableId = (prefix: string, seed: string): string => {\n const hash = createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, SUMMARY_ID_HASH_LENGTH)\n return `${prefix}_${hash}`\n}\n\nexport const createSyntheticUserMessage = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n): WithParts => {\n const userInfo = baseMessage.info as UserMessage\n const now = Date.now()\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const messageId = generateStableId(\"msg_dcp_summary\", deterministicSeed)\n const partId = generateStableId(\"prt_dcp_summary\", deterministicSeed)\n\n return {\n info: {\n id: messageId,\n sessionID: userInfo.sessionID,\n role: \"user\" as const,\n agent: userInfo.agent,\n model: userInfo.model,\n time: { created: now },\n },\n parts: [\n {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: messageId,\n type: \"text\" as const,\n text: content,\n },\n ],\n }\n}\n\nexport const createSyntheticTextPart = (\n baseMessage: WithParts,\n content: string,\n stableSeed?: string,\n) => {\n const userInfo = baseMessage.info as UserMessage\n const deterministicSeed = stableSeed?.trim() || userInfo.id\n const partId = generateStableId(\"prt_dcp_text\", deterministicSeed)\n\n return {\n id: partId,\n sessionID: userInfo.sessionID,\n messageID: userInfo.id,\n type: \"text\" as const,\n text: content,\n }\n}\n\ntype MessagePart = WithParts[\"parts\"][number]\ntype ToolPart = Extract<MessagePart, { type: \"tool\" }>\ntype TextPart = Extract<MessagePart, { type: \"text\" }>\n\nexport const appendToLastTextPart = (message: WithParts, injection: string): boolean => {\n const textPart = findLastTextPart(message)\n if (!textPart) {\n return false\n }\n\n return appendToTextPart(textPart, injection)\n}\n\nconst findLastTextPart = (message: WithParts): TextPart | null => {\n for (let i = message.parts.length - 1; i >= 0; i--) {\n const part = message.parts[i]\n if (part.type === \"text\") {\n return part\n }\n }\n\n return null\n}\n\nexport const appendToTextPart = (part: TextPart, injection: string): boolean => {\n if (typeof part.text !== \"string\") {\n return false\n }\n\n const normalizedInjection = injection.replace(/^\\n+/, \"\")\n if (!normalizedInjection.trim()) {\n return false\n }\n if (part.text.includes(normalizedInjection)) {\n return true\n }\n\n const baseText = part.text.replace(/\\n*$/, \"\")\n part.text = baseText.length > 0 ? `${baseText}\\n\\n${normalizedInjection}` : normalizedInjection\n return true\n}\n\nexport const appendToAllToolParts = (message: WithParts, tag: string): boolean => {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"tool\") {\n injected = appendToToolPart(part, tag) || injected\n }\n }\n return injected\n}\n\nexport const appendToToolPart = (part: ToolPart, tag: string): boolean => {\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n return false\n }\n if (part.state.output.includes(tag)) {\n return true\n }\n\n part.state.output = `${part.state.output}${tag}`\n return true\n}\n\nexport const hasContent = (message: WithParts): boolean => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0) ||\n (part.type === \"tool\" &&\n part.state?.status === \"completed\" &&\n typeof part.state.output === \"string\"),\n )\n}\n\nexport function buildToolIdList(state: SessionState, messages: WithParts[]): string[] {\n const toolIds: string[] = []\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n state.toolIdList = toolIds\n return toolIds\n}\n\nexport const replaceBlockIdsWithBlocked = (text: string): string => {\n return text.replace(DCP_BLOCK_ID_TAG_REGEX, \"$1BLOCKED$2\")\n}\n\nexport const stripHallucinationsFromString = (text: string): string => {\n 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 } from \"./utils\"\nimport { getLastUserMessage } from \"./query\"\nimport type { UserMessage } from \"@opencode-ai/sdk/v2\"\n\nconst PRUNED_TOOL_OUTPUT_REPLACEMENT =\n \"[Output removed to save context - information superseded or no longer needed]\"\nconst PRUNED_TOOL_ERROR_INPUT_REPLACEMENT = \"[input removed due to failed tool call]\"\nconst PRUNED_QUESTION_INPUT_REPLACEMENT = \"[questions removed - see output for user's answers]\"\n\nexport const prune = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n filterCompressedRanges(state, logger, config, messages)\n // pruneFullTool(state, logger, messages)\n pruneToolOutputs(state, logger, messages)\n pruneToolInputs(state, logger, messages)\n pruneToolErrors(state, logger, messages)\n}\n\nconst pruneFullTool = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n const messagesToRemove: string[] = []\n\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n const partsToRemove: string[] = []\n\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.tool !== \"edit\" && part.tool !== \"write\") {\n continue\n }\n\n partsToRemove.push(part.callID)\n }\n\n if (partsToRemove.length === 0) {\n continue\n }\n\n msg.parts = parts.filter(\n (part) => part.type !== \"tool\" || !partsToRemove.includes(part.callID),\n )\n\n if (msg.parts.length === 0) {\n messagesToRemove.push(msg.info.id)\n }\n }\n\n if (messagesToRemove.length > 0) {\n const result = messages.filter((msg) => !messagesToRemove.includes(msg.info.id))\n messages.length = 0\n messages.push(...result)\n }\n}\n\nconst pruneToolOutputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool === \"question\" || part.tool === \"edit\" || part.tool === \"write\") {\n continue\n }\n\n part.state.output = PRUNED_TOOL_OUTPUT_REPLACEMENT\n }\n }\n}\n\nconst pruneToolInputs = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"completed\") {\n continue\n }\n if (part.tool !== \"question\") {\n continue\n }\n\n if (part.state.input?.questions !== undefined) {\n part.state.input.questions = PRUNED_QUESTION_INPUT_REPLACEMENT\n }\n }\n }\n}\n\nconst pruneToolErrors = (state: SessionState, logger: Logger, messages: WithParts[]): void => {\n for (const msg of messages) {\n if (isMessageCompacted(state, msg)) {\n continue\n }\n\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n for (const part of parts) {\n if (part.type !== \"tool\") {\n continue\n }\n if (!state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state.status !== \"error\") {\n continue\n }\n\n // Prune all string inputs for errored tools\n const input = part.state.input\n if (input && typeof input === \"object\") {\n for (const key of Object.keys(input)) {\n if (typeof input[key] === \"string\") {\n input[key] = PRUNED_TOOL_ERROR_INPUT_REPLACEMENT\n }\n }\n }\n }\n }\n}\n\nconst filterCompressedRanges = (\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n messages: WithParts[],\n): void => {\n if (\n state.prune.messages.byMessageId.size === 0 &&\n state.prune.messages.activeByAnchorMessageId.size === 0\n ) {\n return\n }\n\n const result: WithParts[] = []\n\n for (const msg of messages) {\n const msgId = msg.info.id\n\n // Check if there's a summary to inject at this anchor point\n const blockId = state.prune.messages.activeByAnchorMessageId.get(msgId)\n const summary =\n blockId !== undefined ? state.prune.messages.blocksById.get(blockId) : undefined\n if (summary) {\n const rawSummaryContent = (summary as { summary?: unknown }).summary\n if (\n summary.active !== true ||\n typeof rawSummaryContent !== \"string\" ||\n rawSummaryContent.length === 0\n ) {\n logger.warn(\"Skipping malformed compress summary\", {\n anchorMessageId: msgId,\n blockId: (summary as { blockId?: unknown }).blockId,\n })\n } else {\n // Find user message for variant and as base for synthetic message\n const msgIndex = messages.indexOf(msg)\n const userMessage = getLastUserMessage(messages, msgIndex)\n\n if (userMessage) {\n const userInfo = userMessage.info as UserMessage\n const summaryContent =\n config.compress.mode === \"message\"\n ? replaceBlockIdsWithBlocked(rawSummaryContent)\n : rawSummaryContent\n const summarySeed = `${summary.blockId}:${summary.anchorMessageId}`\n result.push(\n createSyntheticUserMessage(userMessage, summaryContent, summarySeed),\n )\n\n logger.info(\"Injected compress summary\", {\n anchorMessageId: msgId,\n summaryLength: summaryContent.length,\n })\n } else {\n logger.warn(\"No user message found for compress summary\", {\n anchorMessageId: msgId,\n })\n }\n }\n }\n\n // Skip messages that are in the prune list\n const pruneEntry = state.prune.messages.byMessageId.get(msgId)\n if (pruneEntry && pruneEntry.activeBlockIds.length > 0) {\n continue\n }\n\n // Normal message, include it\n result.push(msg)\n }\n\n // Replace messages array contents\n messages.length = 0\n messages.push(...result)\n}\n","import type { SessionState, WithParts } from \"../state\"\nimport type { Logger } from \"../logger\"\n\nfunction sortBlocksByCreation(\n a: { createdAt: number; blockId: number },\n b: { createdAt: number; blockId: number },\n): number {\n const createdAtDiff = a.createdAt - b.createdAt\n if (createdAtDiff !== 0) {\n return createdAtDiff\n }\n return a.blockId - b.blockId\n}\n\nexport const syncCompressionBlocks = (\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n): void => {\n const messagesState = state.prune.messages\n if (!messagesState?.blocksById?.size) {\n return\n }\n\n const messageIds = new Set(messages.map((msg) => msg.info.id))\n const previousActiveBlockIds = new Set<number>(\n Array.from(messagesState.blocksById.values())\n .filter((block) => block.active)\n .map((block) => block.blockId),\n )\n\n messagesState.activeBlockIds.clear()\n messagesState.activeByAnchorMessageId.clear()\n\n const now = Date.now()\n const missingOriginBlockIds: number[] = []\n const orderedBlocks = Array.from(messagesState.blocksById.values()).sort(sortBlocksByCreation)\n\n for (const block of orderedBlocks) {\n const hasOriginMessage =\n typeof block.compressMessageId === \"string\" &&\n block.compressMessageId.length > 0 &&\n messageIds.has(block.compressMessageId)\n\n if (!hasOriginMessage) {\n block.active = false\n block.deactivatedAt = now\n block.deactivatedByBlockId = undefined\n missingOriginBlockIds.push(block.blockId)\n continue\n }\n\n if (block.deactivatedByUser) {\n block.active = false\n if (block.deactivatedAt === undefined) {\n block.deactivatedAt = now\n }\n block.deactivatedByBlockId = undefined\n continue\n }\n\n for (const consumedBlockId of block.consumedBlockIds) {\n if (!messagesState.activeBlockIds.has(consumedBlockId)) {\n continue\n }\n\n const consumedBlock = messagesState.blocksById.get(consumedBlockId)\n if (consumedBlock) {\n consumedBlock.active = false\n consumedBlock.deactivatedAt = now\n consumedBlock.deactivatedByBlockId = block.blockId\n\n const mappedBlockId = messagesState.activeByAnchorMessageId.get(\n consumedBlock.anchorMessageId,\n )\n if (mappedBlockId === consumedBlock.blockId) {\n messagesState.activeByAnchorMessageId.delete(consumedBlock.anchorMessageId)\n }\n }\n\n messagesState.activeBlockIds.delete(consumedBlockId)\n }\n\n block.active = true\n block.deactivatedAt = undefined\n block.deactivatedByBlockId = undefined\n messagesState.activeBlockIds.add(block.blockId)\n if (messageIds.has(block.anchorMessageId)) {\n messagesState.activeByAnchorMessageId.set(block.anchorMessageId, block.blockId)\n }\n }\n\n for (const entry of messagesState.byMessageId.values()) {\n const allBlockIds = Array.isArray(entry.allBlockIds)\n ? [...new Set(entry.allBlockIds.filter((id) => Number.isInteger(id) && id > 0))]\n : []\n\n entry.allBlockIds = allBlockIds\n entry.activeBlockIds = allBlockIds.filter((id) => messagesState.activeBlockIds.has(id))\n }\n\n const nextActiveBlockIds = messagesState.activeBlockIds\n let deactivatedCount = 0\n let reactivatedCount = 0\n\n for (const blockId of previousActiveBlockIds) {\n if (!nextActiveBlockIds.has(blockId)) {\n deactivatedCount++\n }\n }\n for (const blockId of nextActiveBlockIds) {\n if (!previousActiveBlockIds.has(blockId)) {\n reactivatedCount++\n }\n }\n\n if (missingOriginBlockIds.length > 0 || deactivatedCount > 0 || reactivatedCount > 0) {\n logger.info(\"Synced compress block state\", {\n missingOriginCount: missingOriginBlockIds.length,\n deactivatedCount,\n reactivatedCount,\n })\n }\n}\n","import type { PluginConfig } from \"./config\"\nimport { type 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 } from \"../../state\"\n\nexport function buildCompressedBlockGuidance(state: SessionState): string {\n const refs = Array.from(state.prune.messages.activeBlockIds)\n .filter((id) => Number.isInteger(id) && id > 0)\n .sort((a, b) => a - b)\n .map((id) => `b${id}`)\n const blockCount = refs.length\n const blockList = blockCount > 0 ? refs.join(\", \") : \"none\"\n\n return [\n \"Compressed block context:\",\n `- Active compressed blocks in this session: ${blockCount} (${blockList})`,\n \"- If your selected compression range includes any listed block, include each required placeholder exactly once in the summary using `(bN)`.\",\n ].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\nexport function getNudgeFrequency(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.nudgeFrequency || 1))\n}\n\nexport function getIterationNudgeThreshold(config: PluginConfig): number {\n return Math.max(1, Math.floor(config.compress.iterationNudgeThreshold || 1))\n}\n\nexport function findLastNonIgnoredMessage(messages: WithParts[]): LastNonIgnoredMessage | null {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n return { message, index: i }\n }\n\n return null\n}\n\nexport function countMessagesAfterIndex(messages: WithParts[], index: number): number {\n let count = 0\n\n for (let i = index + 1; i < messages.length; i++) {\n const message = messages[i]\n if (isIgnoredUserMessage(message)) {\n continue\n }\n count++\n }\n\n return count\n}\n\nexport function getModelInfo(messages: WithParts[]): LastUserModelContext {\n const lastUserMessage = getLastUserMessage(messages)\n if (!lastUserMessage) {\n return {\n providerId: undefined,\n modelId: undefined,\n }\n }\n\n const userInfo = lastUserMessage.info as UserMessage\n return {\n providerId: userInfo.model.providerID,\n modelId: userInfo.model.modelID,\n }\n}\n\nfunction resolveContextTokenLimit(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n threshold: \"max\" | \"min\",\n): number | undefined {\n const parseLimitValue = (limit: number | `${number}%` | undefined): number | undefined => {\n if (limit === undefined) {\n return undefined\n }\n\n if (typeof limit === \"number\") {\n return limit\n }\n\n if (!limit.endsWith(\"%\") || state.modelContextLimit === undefined) {\n return undefined\n }\n\n const parsedPercent = parseFloat(limit.slice(0, -1))\n if (isNaN(parsedPercent)) {\n return undefined\n }\n\n const roundedPercent = Math.round(parsedPercent)\n const clampedPercent = Math.max(0, Math.min(100, roundedPercent))\n return Math.round((clampedPercent / 100) * state.modelContextLimit)\n }\n\n const modelLimits =\n threshold === \"max\" ? config.compress.modelMaxLimits : config.compress.modelMinLimits\n if (modelLimits && providerId !== undefined && modelId !== undefined) {\n const providerModelId = `${providerId}/${modelId}`\n const modelLimit = modelLimits[providerModelId]\n if (modelLimit !== undefined) {\n return parseLimitValue(modelLimit)\n }\n }\n\n const globalLimit =\n threshold === \"max\" ? config.compress.maxContextLimit : config.compress.minContextLimit\n return parseLimitValue(globalLimit)\n}\n\nexport function isContextOverLimits(\n config: PluginConfig,\n state: SessionState,\n providerId: string | undefined,\n modelId: string | undefined,\n messages: WithParts[],\n) {\n const summaryTokenExtension = config.compress.summaryBuffer\n ? getActiveSummaryTokenUsage(state)\n : 0\n const resolvedMaxContextLimit = resolveContextTokenLimit(\n config,\n state,\n providerId,\n modelId,\n \"max\",\n )\n const maxContextLimit =\n resolvedMaxContextLimit === undefined\n ? undefined\n : resolvedMaxContextLimit + summaryTokenExtension\n const minContextLimit = resolveContextTokenLimit(config, state, providerId, modelId, \"min\")\n const currentTokens = getCurrentTokenUsage(state, messages)\n\n const overMaxLimit = maxContextLimit === undefined ? false : currentTokens > maxContextLimit\n const overMinLimit = minContextLimit === undefined ? true : currentTokens >= minContextLimit\n\n return {\n overMaxLimit,\n overMinLimit,\n }\n}\n\nexport function addAnchor(\n anchorMessageIds: Set<string>,\n anchorMessageId: string,\n anchorMessageIndex: number,\n messages: WithParts[],\n interval: number,\n): boolean {\n if (anchorMessageIndex < 0) {\n return false\n }\n\n let latestAnchorMessageIndex = -1\n for (let i = messages.length - 1; i >= 0; i--) {\n if (anchorMessageIds.has(messages[i].info.id)) {\n latestAnchorMessageIndex = i\n break\n }\n }\n\n const shouldAdd =\n latestAnchorMessageIndex < 0 || anchorMessageIndex - latestAnchorMessageIndex >= interval\n if (!shouldAdd) {\n return false\n }\n\n const previousSize = anchorMessageIds.size\n anchorMessageIds.add(anchorMessageId)\n return anchorMessageIds.size !== previousSize\n}\n\nfunction 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\nexport function applyAnchoredNudges(\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void {\n const turnNudgeAnchors = collectTurnNudgeAnchors(state, config, messages)\n\n if (config.compress.mode === \"message\") {\n applyMessageModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\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 const compressedBlockGuidance = buildCompressedBlockGuidance(state)\n applyRangeModeAnchoredNudge(\n state.nudges.contextLimitAnchors,\n messages,\n prompts.contextLimitNudge,\n compressedBlockGuidance,\n )\n applyRangeModeAnchoredNudge(\n turnNudgeAnchors,\n messages,\n prompts.turnNudge,\n compressedBlockGuidance,\n )\n applyRangeModeAnchoredNudge(\n state.nudges.iterationNudgeAnchors,\n messages,\n prompts.iterationNudge,\n compressedBlockGuidance,\n )\n}\n","import type { SessionState, WithParts } from \"../../state\"\nimport type { Logger } from \"../../logger\"\nimport type { PluginConfig } from \"../../config\"\nimport type { RuntimePrompts } from \"../../prompts/store\"\nimport { formatMessageIdTag } from \"../../message-ids\"\nimport type { CompressionPriorityMap } from \"../priority\"\nimport { compressPermission } from \"../../compress-permission\"\nimport {\n getLastUserMessage,\n isIgnoredUserMessage,\n isProtectedUserMessage,\n messageHasCompress,\n} from \"../query\"\nimport { saveSessionState } from \"../../state/persistence\"\nimport {\n appendToTextPart,\n appendToLastTextPart,\n appendToAllToolParts,\n createSyntheticTextPart,\n hasContent,\n} from \"../utils\"\nimport {\n addAnchor,\n applyAnchoredNudges,\n countMessagesAfterIndex,\n findLastNonIgnoredMessage,\n getIterationNudgeThreshold,\n getNudgeFrequency,\n getModelInfo,\n isContextOverLimits,\n} from \"./utils\"\n\nexport const injectCompressNudges = (\n state: SessionState,\n config: PluginConfig,\n logger: Logger,\n messages: WithParts[],\n prompts: RuntimePrompts,\n compressionPriorities?: CompressionPriorityMap,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n if (state.manualMode) {\n return\n }\n\n const lastMessage = findLastNonIgnoredMessage(messages)\n const lastAssistantMessage = messages.findLast((message) => message.info.role === \"assistant\")\n\n if (lastAssistantMessage && messageHasCompress(lastAssistantMessage)) {\n state.nudges.contextLimitAnchors.clear()\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n void saveSessionState(state, logger)\n return\n }\n\n const { providerId, modelId } = getModelInfo(messages)\n let anchorsChanged = false\n\n const { overMaxLimit, overMinLimit } = isContextOverLimits(\n config,\n state,\n providerId,\n modelId,\n messages,\n )\n\n if (!overMinLimit) {\n const hadTurnAnchors = state.nudges.turnNudgeAnchors.size > 0\n const hadIterationAnchors = state.nudges.iterationNudgeAnchors.size > 0\n\n if (hadTurnAnchors || hadIterationAnchors) {\n state.nudges.turnNudgeAnchors.clear()\n state.nudges.iterationNudgeAnchors.clear()\n anchorsChanged = true\n }\n }\n\n if (overMaxLimit) {\n if (lastMessage) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.contextLimitAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n if (added) {\n anchorsChanged = true\n }\n }\n } else if (overMinLimit) {\n const isLastMessageUser = lastMessage?.message.info.role === \"user\"\n\n if (isLastMessageUser && lastAssistantMessage) {\n const previousSize = state.nudges.turnNudgeAnchors.size\n state.nudges.turnNudgeAnchors.add(lastMessage.message.info.id)\n state.nudges.turnNudgeAnchors.add(lastAssistantMessage.info.id)\n if (state.nudges.turnNudgeAnchors.size !== previousSize) {\n anchorsChanged = true\n }\n }\n\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage && lastMessage) {\n const lastUserMessageIndex = messages.findIndex(\n (message) => message.info.id === lastUserMessage.info.id,\n )\n if (lastUserMessageIndex >= 0) {\n const messagesSinceUser = countMessagesAfterIndex(messages, lastUserMessageIndex)\n const iterationThreshold = getIterationNudgeThreshold(config)\n\n if (\n lastMessage.index > lastUserMessageIndex &&\n messagesSinceUser >= iterationThreshold\n ) {\n const interval = getNudgeFrequency(config)\n const added = addAnchor(\n state.nudges.iterationNudgeAnchors,\n lastMessage.message.info.id,\n lastMessage.index,\n messages,\n interval,\n )\n\n if (added) {\n anchorsChanged = true\n }\n }\n }\n }\n }\n\n applyAnchoredNudges(state, config, messages, prompts, compressionPriorities)\n\n if (anchorsChanged) {\n void saveSessionState(state, logger)\n }\n}\n\nexport const injectMessageIds = (\n state: SessionState,\n config: PluginConfig,\n messages: WithParts[],\n compressionPriorities?: CompressionPriorityMap,\n): void => {\n if (compressPermission(state, config) === \"deny\") {\n return\n }\n\n for (const message of messages) {\n if (isIgnoredUserMessage(message)) {\n continue\n }\n\n const messageRef = state.messageIds.byRawId.get(message.info.id)\n if (!messageRef) {\n continue\n }\n\n const isBlockedMessage = isProtectedUserMessage(config, message)\n const priority =\n config.compress.mode === \"message\" && !isBlockedMessage\n ? compressionPriorities?.get(message.info.id)?.priority\n : undefined\n const tag = formatMessageIdTag(\n isBlockedMessage ? \"BLOCKED\" : messageRef,\n priority ? { priority } : undefined,\n )\n\n if (message.info.role === \"user\") {\n let injected = false\n for (const part of message.parts) {\n if (part.type === \"text\") {\n injected = appendToTextPart(part, tag) || injected\n }\n }\n\n if (injected) {\n continue\n }\n\n message.parts.push(createSyntheticTextPart(message, tag))\n continue\n }\n\n if (message.info.role !== \"assistant\") {\n continue\n }\n\n if (!hasContent(message)) {\n continue\n }\n\n if (appendToAllToolParts(message, tag)) {\n continue\n }\n\n if (appendToLastTextPart(message, tag)) {\n continue\n }\n\n const syntheticPart = createSyntheticTextPart(message, tag)\n const firstToolIndex = message.parts.findIndex((p) => p.type === \"tool\")\n if (firstToolIndex === -1) {\n message.parts.push(syntheticPart)\n } else {\n message.parts.splice(firstToolIndex, 0, syntheticPart)\n }\n }\n}\n","import type { Logger } from \"../../logger\"\nimport type { SessionState, WithParts } from \"../../state\"\nimport { filterMessages } from \"../shape\"\nimport {\n buildSubagentResultText,\n getSubAgentId,\n mergeSubagentResult,\n} from \"../../subagents/subagent-results\"\nimport { stripHallucinationsFromString } from \"../utils\"\n\nasync function fetchSubAgentMessages(client: any, sessionId: string): Promise<WithParts[]> {\n const response = await client.session.messages({\n path: { id: sessionId },\n })\n\n return filterMessages(response?.data || response)\n}\n\nexport const injectExtendedSubAgentResults = async (\n client: any,\n state: SessionState,\n logger: Logger,\n messages: WithParts[],\n allowSubAgents: boolean,\n): Promise<void> => {\n if (!allowSubAgents) {\n return\n }\n\n for (const message of messages) {\n const parts = Array.isArray(message.parts) ? message.parts : []\n\n for (const part of parts) {\n if (part.type !== \"tool\" || part.tool !== \"task\" || !part.callID) {\n continue\n }\n if (state.prune.tools.has(part.callID)) {\n continue\n }\n if (part.state?.status !== \"completed\" || typeof part.state.output !== \"string\") {\n continue\n }\n\n const cachedResult = state.subAgentResultCache.get(part.callID)\n if (cachedResult !== undefined) {\n if (cachedResult) {\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, cachedResult),\n )\n }\n continue\n }\n\n const subAgentSessionId = getSubAgentId(part)\n if (!subAgentSessionId) {\n continue\n }\n\n let subAgentMessages: WithParts[] = []\n try {\n subAgentMessages = await fetchSubAgentMessages(client, subAgentSessionId)\n } catch (error) {\n logger.warn(\"Failed to fetch subagent session for output expansion\", {\n subAgentSessionId,\n callID: part.callID,\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n\n const subAgentResultText = buildSubagentResultText(subAgentMessages)\n if (!subAgentResultText) {\n continue\n }\n\n state.subAgentResultCache.set(part.callID, subAgentResultText)\n part.state.output = stripHallucinationsFromString(\n mergeSubagentResult(part.state.output, subAgentResultText),\n )\n }\n }\n}\n","import type { WithParts } from \"../state\"\nimport { getLastUserMessage } from \"./query\"\n\n/**\n * Mirrors opencode's differentModel handling by preserving part content while\n * dropping provider metadata on assistant parts that came from a different\n * model/provider than the current turn's user message.\n */\nexport function stripStaleMetadata(messages: WithParts[]): void {\n const lastUserMessage = getLastUserMessage(messages)\n if (lastUserMessage?.info.role !== \"user\") {\n return\n }\n\n const modelID = lastUserMessage.info.model.modelID\n const providerID = lastUserMessage.info.model.providerID\n\n messages.forEach((message) => {\n if (message.info.role !== \"assistant\") {\n return\n }\n\n if (message.info.modelID === modelID && message.info.providerID === providerID) {\n return\n }\n\n message.parts = message.parts.map((part) => {\n if (part.type !== \"text\" && part.type !== \"tool\" && 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(\"│ DCP Context Analysis │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Session Context Breakdown:\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n for (const cat of categories) {\n const bar = createBar(cat.value, breakdown.total, barWidth, cat.char)\n const percentage =\n breakdown.total > 0 ? ((cat.value / breakdown.total) * 100).toFixed(1) : \"0.0\"\n const labelWithPct = `${cat.label.padEnd(maxLabelLen)} ${percentage.padStart(5)}% `\n const valueStr = formatTokenCount(cat.value).padStart(13)\n lines.push(`${labelWithPct}│${bar.padEnd(barWidth)}│${valueStr}`)\n }\n\n lines.push(\"\")\n lines.push(\"─\".repeat(60))\n lines.push(\"\")\n\n lines.push(\"Summary:\")\n\n if (breakdown.prunedTokens > 0) {\n const withoutPruning = breakdown.total + breakdown.prunedTokens\n const pruned = []\n if (breakdown.prunedToolCount > 0) pruned.push(`${breakdown.prunedToolCount} tools`)\n if (breakdown.prunedMessageCount > 0)\n pruned.push(`${breakdown.prunedMessageCount} messages`)\n lines.push(\n ` Pruned: ${pruned.join(\", \")} (~${formatTokenCount(breakdown.prunedTokens)})`,\n )\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n lines.push(` Without DCP: ~${formatTokenCount(withoutPruning)}`)\n } else {\n lines.push(` Current context: ~${formatTokenCount(breakdown.total)}`)\n }\n\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleContextCommand(ctx: ContextCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const breakdown = analyzeTokens(state, messages)\n\n const message = formatContextMessage(breakdown)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n}\n","import type { CompressionBlock, PruneMessagesState } from \"../state\"\n\nexport interface CompressionTarget {\n displayId: number\n runId: number\n topic: string\n compressedTokens: number\n durationMs: number\n grouped: boolean\n blocks: CompressionBlock[]\n}\n\nfunction byBlockId(a: CompressionBlock, b: CompressionBlock): number {\n return a.blockId - b.blockId\n}\n\nfunction buildTarget(blocks: CompressionBlock[]): CompressionTarget {\n const ordered = [...blocks].sort(byBlockId)\n const first = ordered[0]\n if (!first) {\n throw new Error(\"Cannot build compression target from empty block list.\")\n }\n\n const grouped = first.mode === \"message\"\n return {\n displayId: first.blockId,\n runId: first.runId,\n topic: grouped ? first.batchTopic || first.topic : first.topic,\n compressedTokens: ordered.reduce((total, block) => total + block.compressedTokens, 0),\n durationMs: ordered.reduce((total, block) => Math.max(total, block.durationMs), 0),\n grouped,\n blocks: ordered,\n }\n}\n\nfunction groupMessageBlocks(blocks: CompressionBlock[]): CompressionTarget[] {\n const grouped = new Map<number, CompressionBlock[]>()\n\n for (const block of blocks) {\n const existing = grouped.get(block.runId)\n if (existing) {\n existing.push(block)\n continue\n }\n grouped.set(block.runId, [block])\n }\n\n return Array.from(grouped.values()).map(buildTarget)\n}\n\nfunction splitTargets(blocks: CompressionBlock[]): CompressionTarget[] {\n const messageBlocks: CompressionBlock[] = []\n const singleBlocks: CompressionBlock[] = []\n\n for (const block of blocks) {\n if (block.mode === \"message\") {\n messageBlocks.push(block)\n } else {\n singleBlocks.push(block)\n }\n }\n\n const targets = [\n ...singleBlocks.map((block) => buildTarget([block])),\n ...groupMessageBlocks(messageBlocks),\n ]\n return targets.sort((a, b) => a.displayId - b.displayId)\n}\n\nexport function getActiveCompressionTargets(\n messagesState: PruneMessagesState,\n): CompressionTarget[] {\n const activeBlocks = Array.from(messagesState.activeBlockIds)\n .map((blockId) => messagesState.blocksById.get(blockId))\n .filter((block): block is CompressionBlock => !!block && block.active)\n\n return splitTargets(activeBlocks)\n}\n\nexport function getRecompressibleCompressionTargets(\n messagesState: PruneMessagesState,\n availableMessageIds: Set<string>,\n): CompressionTarget[] {\n const allBlocks = Array.from(messagesState.blocksById.values()).filter((block) => {\n return availableMessageIds.has(block.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: /dcp decompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No compressions are available to restore.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleDecompressCommand(ctx: DecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp decompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n\n if (!targetArg) {\n const availableTargets = getActiveCompressionTargets(messagesState)\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp decompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n const activeBlocks = target.blocks.filter((block) => block.active)\n if (activeBlocks.length === 0) {\n const activeAncestorBlockId = findActiveAncestorBlockId(messagesState, target)\n if (activeAncestorBlockId !== null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is inside compression ${activeAncestorBlockId}. Restore compression ${activeAncestorBlockId} first.`,\n params,\n logger,\n )\n return\n }\n\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${target.displayId} is not active.`,\n params,\n logger,\n )\n return\n }\n\n const activeMessagesBefore = snapshotActiveMessages(messagesState)\n const activeBlockIdsBefore = new Set(messagesState.activeBlockIds)\n const deactivatedAt = Date.now()\n\n for (const block of target.blocks) {\n block.active = false\n block.deactivatedByUser = true\n block.deactivatedAt = deactivatedAt\n block.deactivatedByBlockId = undefined\n }\n\n syncCompressionBlocks(state, logger, messages)\n\n let restoredMessageCount = 0\n let restoredTokens = 0\n for (const [messageId, tokenCount] of activeMessagesBefore) {\n const entry = messagesState.byMessageId.get(messageId)\n const isActiveNow = entry ? entry.activeBlockIds.length > 0 : false\n if (!isActiveNow) {\n restoredMessageCount++\n restoredTokens += tokenCount\n }\n }\n\n state.stats.totalPruneTokens = Math.max(0, state.stats.totalPruneTokens - restoredTokens)\n\n const reactivatedBlockIds = Array.from(messagesState.activeBlockIds)\n .filter((blockId) => !activeBlockIdsBefore.has(blockId))\n .sort((a, b) => a - b)\n\n await saveSessionState(state, logger)\n\n const message = formatDecompressMessage(\n target,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Decompress command completed\", {\n targetBlockId: target.displayId,\n targetRunId: target.runId,\n restoredMessageCount,\n restoredTokens,\n reactivatedBlockIds,\n })\n}\n","/**\n * DCP Help command handler.\n * Shows available DCP commands and their descriptions.\n */\n\nimport type { Logger } from \"../logger\"\nimport type { PluginConfig } from \"../config\"\nimport type { SessionState, WithParts } from \"../state\"\nimport { compressPermission } from \"../compress-permission\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { getCurrentParams } from \"../token-utils\"\n\nexport interface HelpCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nconst BASE_COMMANDS: [string, string][] = [\n [\"/dcp context\", \"Show token usage breakdown for current session\"],\n [\"/dcp stats\", \"Show DCP pruning statistics\"],\n [\"/dcp sweep [n]\", \"Prune tools since last user message, or last n tools\"],\n [\"/dcp manual [on|off]\", \"Toggle manual mode or set explicit state\"],\n]\n\nconst TOOL_COMMANDS: Record<string, [string, string]> = {\n compress: [\"/dcp compress [focus]\", \"Trigger manual compress tool execution\"],\n decompress: [\"/dcp decompress <n>\", \"Restore selected compression\"],\n recompress: [\"/dcp recompress <n>\", \"Re-apply a user-decompressed compression\"],\n}\n\nfunction getVisibleCommands(state: SessionState, config: PluginConfig): [string, string][] {\n const commands = [...BASE_COMMANDS]\n\n if (compressPermission(state, config) !== \"deny\") {\n commands.push(TOOL_COMMANDS.compress)\n commands.push(TOOL_COMMANDS.decompress)\n commands.push(TOOL_COMMANDS.recompress)\n }\n\n return commands\n}\n\nfunction formatHelpMessage(state: SessionState, config: PluginConfig): string {\n const commands = getVisibleCommands(state, config)\n const colWidth = Math.max(...commands.map(([cmd]) => cmd.length)) + 4\n const lines: string[] = []\n\n lines.push(\"╭─────────────────────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Commands │\")\n lines.push(\"╰─────────────────────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(` ${\"Manual mode:\".padEnd(colWidth)}${state.manualMode ? \"ON\" : \"OFF\"}`)\n lines.push(\"\")\n for (const [cmd, desc] of commands) {\n lines.push(` ${cmd.padEnd(colWidth)}${desc}`)\n }\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleHelpCommand(ctx: HelpCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n const { config } = ctx\n const message = formatHelpMessage(state, config)\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Help command executed\")\n}\n","/**\n * DCP Manual mode command handler.\n * Handles toggling manual mode and triggering individual tool executions.\n *\n * Usage:\n * /dcp manual [on|off] - Toggle manual mode or set explicit state\n * /dcp compress [focus] - Trigger manual compress execution\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { getCurrentParams } from \"../token-utils\"\nimport { buildCompressedBlockGuidance } from \"../prompts/extensions/nudge\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\n\nconst MANUAL_MODE_ON = \"Manual mode is now ON. Use /dcp compress to trigger context tools manually.\"\n\nconst MANUAL_MODE_OFF = \"Manual mode is now OFF.\"\n\nconst COMPRESS_TRIGGER_PROMPT = [\n \"<compress triggered manually>\",\n \"Manual mode trigger received. You must now use the compress tool.\",\n \"Find the most significant completed conversation content that can be compressed into a high-fidelity technical summary.\",\n \"Follow the active compress mode, preserve all critical implementation details, and choose safe targets.\",\n \"Return after compress with a brief explanation of what content was compressed.\",\n].join(\"\\n\\n\")\n\nfunction getTriggerPrompt(\n tool: \"compress\",\n state: SessionState,\n config: PluginConfig,\n userFocus?: string,\n): string {\n const base = COMPRESS_TRIGGER_PROMPT\n const compressedBlockGuidance =\n config.compress.mode === \"message\" ? \"\" : buildCompressedBlockGuidance(state)\n\n const sections = [base, compressedBlockGuidance]\n if (userFocus && userFocus.trim().length > 0) {\n sections.push(`Additional user focus:\\n${userFocus.trim()}`)\n }\n\n return sections.join(\"\\n\\n\")\n}\n\nexport interface ManualCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n}\n\nexport async function handleManualToggleCommand(\n ctx: ManualCommandContext,\n modeArg?: string,\n): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n if (modeArg === \"on\") {\n state.manualMode = \"active\"\n } else if (modeArg === \"off\") {\n state.manualMode = false\n } else {\n state.manualMode = state.manualMode ? false : \"active\"\n }\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(\n client,\n sessionId,\n state.manualMode ? MANUAL_MODE_ON : MANUAL_MODE_OFF,\n params,\n logger,\n )\n\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: /dcp recompress <n>\")\n lines.push(\"\")\n\n if (availableTargets.length === 0) {\n lines.push(\"No user-decompressed blocks are available to re-compress.\")\n return lines.join(\"\\n\")\n }\n\n lines.push(\"Available user-decompressed compressions:\")\n const entries = availableTargets.map((target) => {\n const topic = target.topic.replace(/\\s+/g, \" \").trim() || \"(no topic)\"\n const label = `${target.displayId} (${formatTokenCount(target.compressedTokens)})`\n const details = target.grouped\n ? `Compression #${target.runId} - ${target.blocks.length} messages`\n : `Compression #${target.runId}`\n return { label, topic: `${details} - ${topic}` }\n })\n\n const labelWidth = Math.max(...entries.map((entry) => entry.label.length)) + 4\n for (const entry of entries) {\n lines.push(` ${entry.label.padEnd(labelWidth)}${entry.topic}`)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleRecompressCommand(ctx: RecompressCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages, args } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const targetArg = args[0]\n\n if (args.length > 1) {\n await sendIgnoredMessage(\n client,\n sessionId,\n \"Invalid arguments. Usage: /dcp recompress <n>\",\n params,\n logger,\n )\n return\n }\n\n syncCompressionBlocks(state, logger, messages)\n const messagesState = state.prune.messages\n const availableMessageIds = new Set(messages.map((msg) => msg.info.id))\n\n if (!targetArg) {\n const availableTargets = getRecompressibleCompressionTargets(\n messagesState,\n availableMessageIds,\n )\n const message = formatAvailableBlocksMessage(availableTargets)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n return\n }\n\n const targetBlockId = parseBlockIdArg(targetArg)\n if (targetBlockId === null) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Please enter a compression number. Example: /dcp recompress 2`,\n params,\n logger,\n )\n return\n }\n\n const target = resolveCompressionTarget(messagesState, targetBlockId)\n if (!target) {\n await sendIgnoredMessage(\n client,\n sessionId,\n `Compression ${targetBlockId} does not exist.`,\n params,\n logger,\n )\n return\n }\n\n if (target.blocks.some((block) => !availableMessageIds.has(block.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(\"│ DCP Statistics │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Compression:\")\n lines.push(\"─\".repeat(60))\n lines.push(\n ` Tokens in|out: ~${formatTokenCount(sessionTokens)} | ~${formatTokenCount(sessionSummaryTokens)}`,\n )\n lines.push(` Ratio: ${formatCompressionRatio(sessionTokens, sessionSummaryTokens)}`)\n lines.push(` Time: ${formatCompressionTime(sessionDurationMs)}`)\n lines.push(` Messages: ${sessionMessages}`)\n lines.push(` Tools: ${sessionTools}`)\n lines.push(\"\")\n lines.push(\"All-time:\")\n lines.push(\"─\".repeat(60))\n lines.push(` Tokens saved: ~${formatTokenCount(allTime.totalTokens)}`)\n lines.push(` Tools pruned: ${allTime.totalTools}`)\n lines.push(` Messages pruned: ${allTime.totalMessages}`)\n lines.push(` Sessions: ${allTime.sessionCount}`)\n\n return lines.join(\"\\n\")\n}\n\nfunction formatCompressionRatio(inputTokens: number, outputTokens: number): string {\n if (inputTokens <= 0) {\n return \"0:1\"\n }\n\n if (outputTokens <= 0) {\n return \"∞:1\"\n }\n\n const ratio = Math.max(1, Math.round(inputTokens / outputTokens))\n return `${ratio}:1`\n}\n\nfunction formatCompressionTime(ms: number): string {\n const safeMs = Math.max(0, Math.round(ms))\n if (safeMs < 1000) {\n return `${safeMs} ms`\n }\n\n const totalSeconds = safeMs / 1000\n if (totalSeconds < 60) {\n return `${totalSeconds.toFixed(1)} s`\n }\n\n const wholeSeconds = Math.floor(totalSeconds)\n const hours = Math.floor(wholeSeconds / 3600)\n const minutes = Math.floor((wholeSeconds % 3600) / 60)\n const seconds = wholeSeconds % 60\n\n if (hours > 0) {\n return `${hours}h ${minutes}m ${seconds}s`\n }\n\n return `${minutes}m ${seconds}s`\n}\n\nexport async function handleStatsCommand(ctx: StatsCommandContext): Promise<void> {\n const { client, state, logger, sessionId, messages } = ctx\n\n // Session stats from in-memory state\n const sessionTokens = state.stats.totalPruneTokens\n const sessionSummaryTokens = Array.from(state.prune.messages.blocksById.values()).reduce(\n (total, block) => (block.active ? total + block.summaryTokens : total),\n 0,\n )\n const sessionDurationMs = getActiveCompressionTargets(state.prune.messages).reduce(\n (total, target) => total + target.durationMs,\n 0,\n )\n\n const prunedToolIds = new Set<string>(state.prune.tools.keys())\n for (const block of state.prune.messages.blocksById.values()) {\n if (block.active) {\n for (const toolId of block.effectiveToolIds) {\n prunedToolIds.add(toolId)\n }\n }\n }\n const sessionTools = prunedToolIds.size\n\n let sessionMessages = 0\n for (const entry of state.prune.messages.byMessageId.values()) {\n if (entry.activeBlockIds.length > 0) {\n sessionMessages++\n }\n }\n\n // All-time stats from storage files\n const allTime = await loadAllSessionStats(logger)\n\n const message = formatStatsMessage(\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTime,\n )\n\n const params = getCurrentParams(state, messages, logger)\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Stats command executed\", {\n sessionTokens,\n sessionSummaryTokens,\n sessionTools,\n sessionMessages,\n sessionDurationMs,\n allTimeTokens: allTime.totalTokens,\n allTimeTools: allTime.totalTools,\n allTimeMessages: allTime.totalMessages,\n })\n}\n","/**\n * DCP Sweep command handler.\n * Prunes tool outputs since the last user message, or the last N tools.\n *\n * Usage:\n * /dcp sweep - Prune all tools since the previous user message\n * /dcp sweep 10 - Prune the last 10 tools\n */\n\nimport type { Logger } from \"../logger\"\nimport type { SessionState, WithParts, ToolParameterEntry } from \"../state\"\nimport type { PluginConfig } from \"../config\"\nimport { sendIgnoredMessage } from \"../ui/notification\"\nimport { formatPrunedItemsList } from \"../ui/utils\"\nimport { getCurrentParams, getTotalToolTokens } from \"../token-utils\"\nimport { isIgnoredUserMessage } from \"../messages/query\"\nimport { buildToolIdList } from \"../messages/utils\"\nimport { saveSessionState } from \"../state/persistence\"\nimport { isMessageCompacted } from \"../state/utils\"\nimport {\n getFilePathsFromParameters,\n isFilePathProtected,\n isToolNameProtected,\n} from \"../protected-patterns\"\nimport { syncToolCache } from \"../state/tool-cache\"\n\nexport interface SweepCommandContext {\n client: any\n state: SessionState\n config: PluginConfig\n logger: Logger\n sessionId: string\n messages: WithParts[]\n args: string[]\n workingDirectory: string\n}\n\nfunction findLastUserMessageIndex(messages: WithParts[]): number {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.info.role === \"user\" && !isIgnoredUserMessage(msg)) {\n return i\n }\n }\n\n return -1\n}\n\nfunction collectToolIdsAfterIndex(\n state: SessionState,\n messages: WithParts[],\n afterIndex: number,\n): string[] {\n const toolIds: string[] = []\n\n for (let i = afterIndex + 1; i < messages.length; i++) {\n const msg = messages[i]\n if (isMessageCompacted(state, msg)) {\n continue\n }\n const parts = Array.isArray(msg.parts) ? msg.parts : []\n if (parts.length > 0) {\n for (const part of parts) {\n if (part.type === \"tool\" && part.callID && part.tool) {\n toolIds.push(part.callID)\n }\n }\n }\n }\n\n return toolIds\n}\n\nfunction formatNoUserMessage(): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n lines.push(\"Nothing swept: no user message found.\")\n\n return lines.join(\"\\n\")\n}\n\nfunction formatSweepMessage(\n toolCount: number,\n tokensSaved: number,\n mode: \"since-user\" | \"last-n\",\n toolIds: string[],\n toolMetadata: Map<string, ToolParameterEntry>,\n workingDirectory?: string,\n skippedProtected?: number,\n): string {\n const lines: string[] = []\n\n lines.push(\"╭───────────────────────────────────────────────────────────╮\")\n lines.push(\"│ DCP Sweep │\")\n lines.push(\"╰───────────────────────────────────────────────────────────╯\")\n lines.push(\"\")\n\n if (toolCount === 0) {\n if (mode === \"since-user\") {\n lines.push(\"No tools found since the previous user message.\")\n } else {\n lines.push(`No tools found to sweep.`)\n }\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n } else {\n if (mode === \"since-user\") {\n lines.push(`Swept ${toolCount} tool(s) since the previous user message.`)\n } else {\n lines.push(`Swept the last ${toolCount} tool(s).`)\n }\n lines.push(`Tokens saved: ~${tokensSaved.toLocaleString()}`)\n if (skippedProtected && skippedProtected > 0) {\n lines.push(`(${skippedProtected} protected tool(s) skipped)`)\n }\n lines.push(\"\")\n const itemLines = formatPrunedItemsList(toolIds, toolMetadata, workingDirectory)\n lines.push(...itemLines)\n }\n\n return lines.join(\"\\n\")\n}\n\nexport async function handleSweepCommand(ctx: SweepCommandContext): Promise<void> {\n const { client, state, config, logger, sessionId, messages, args, workingDirectory } = ctx\n\n const params = getCurrentParams(state, messages, logger)\n const protectedTools = config.commands.protectedTools\n\n syncToolCache(state, config, logger, messages)\n buildToolIdList(state, messages)\n\n // Parse optional numeric argument\n const numArg = args[0] ? parseInt(args[0], 10) : null\n const isLastNMode = numArg !== null && !isNaN(numArg) && numArg > 0\n\n let toolIdsToSweep: string[]\n let mode: \"since-user\" | \"last-n\"\n\n if (isLastNMode) {\n // Mode: Sweep last N tools\n mode = \"last-n\"\n const startIndex = Math.max(0, state.toolIdList.length - numArg!)\n toolIdsToSweep = state.toolIdList.slice(startIndex)\n logger.info(`Sweep command: last ${numArg} mode, found ${toolIdsToSweep.length} tools`)\n } else {\n // Mode: Sweep since last user message\n mode = \"since-user\"\n const lastUserMsgIndex = findLastUserMessageIndex(messages)\n\n if (lastUserMsgIndex === -1) {\n // No user message found - show message and return\n const message = formatNoUserMessage()\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no user message found\")\n return\n } else {\n toolIdsToSweep = collectToolIdsAfterIndex(state, messages, lastUserMsgIndex)\n logger.info(\n `Sweep command: found last user at index ${lastUserMsgIndex}, sweeping ${toolIdsToSweep.length} tools`,\n )\n }\n }\n\n // Filter out already-pruned tools, protected tools, and protected file paths\n const newToolIds = toolIdsToSweep.filter((id) => {\n if (state.prune.tools.has(id)) {\n return false\n }\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return true\n }\n if (isToolNameProtected(entry.tool, protectedTools)) {\n logger.debug(`Sweep: skipping protected tool ${entry.tool} (${id})`)\n return false\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n logger.debug(`Sweep: skipping protected file path(s) ${filePaths.join(\", \")} (${id})`)\n return false\n }\n return true\n })\n\n // Count how many were skipped due to protection\n const skippedProtected = toolIdsToSweep.filter((id) => {\n const entry = state.toolParameters.get(id)\n if (!entry) {\n return false\n }\n if (isToolNameProtected(entry.tool, protectedTools)) {\n return true\n }\n const filePaths = getFilePathsFromParameters(entry.tool, entry.parameters)\n if (isFilePathProtected(filePaths, config.protectedFilePatterns)) {\n return true\n }\n return false\n }).length\n\n if (newToolIds.length === 0) {\n const message = formatSweepMessage(\n 0,\n 0,\n mode,\n [],\n new Map(),\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n logger.info(\"Sweep command: no new tools to sweep\", { skippedProtected })\n return\n }\n\n const tokensSaved = getTotalToolTokens(state, newToolIds)\n\n // Add to prune list\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n state.prune.tools.set(id, entry?.tokenCount ?? 0)\n }\n state.stats.pruneTokenCounter += tokensSaved\n state.stats.totalPruneTokens += state.stats.pruneTokenCounter\n state.stats.pruneTokenCounter = 0\n\n // Collect metadata for logging\n const toolMetadata: Map<string, ToolParameterEntry> = new Map()\n for (const id of newToolIds) {\n const entry = state.toolParameters.get(id)\n if (entry) {\n toolMetadata.set(id, entry)\n }\n }\n\n // Persist state\n saveSessionState(state, logger).catch((err) =>\n logger.error(\"Failed to persist state after sweep\", { error: err.message }),\n )\n\n const message = formatSweepMessage(\n newToolIds.length,\n tokensSaved,\n mode,\n newToolIds,\n toolMetadata,\n workingDirectory,\n skippedProtected,\n )\n await sendIgnoredMessage(client, sessionId, message, params, logger)\n\n logger.info(\"Sweep command completed\", {\n toolsSwept: newToolIds.length,\n tokensSaved,\n skippedProtected,\n mode,\n tools: Array.from(toolMetadata.entries()).map(([id, entry]) => ({\n id,\n tool: entry.tool,\n })),\n })\n}\n","import type { SessionState, WithParts } from \"./state\"\nimport type { Logger } from \"./logger\"\nimport type { PluginConfig } from \"./config\"\nimport { assignMessageRefs } from \"./message-ids\"\nimport {\n buildPriorityMap,\n buildToolIdList,\n injectCompressNudges,\n injectExtendedSubAgentResults,\n injectMessageIds,\n prune,\n stripHallucinations,\n stripHallucinationsFromString,\n stripStaleMetadata,\n syncCompressionBlocks,\n} from \"./messages\"\nimport { renderSystemPrompt, type PromptStore } from \"./prompts\"\nimport { buildProtectedToolsExtension } from \"./prompts/extensions/system\"\nimport {\n applyPendingCompressionDurations,\n buildCompressionTimingKey,\n consumeCompressionStart,\n resolveCompressionDuration,\n} from \"./compress/timing\"\nimport { filterMessages, filterMessagesInPlace } from \"./messages/shape\"\nimport {\n applyPendingManualTrigger,\n handleContextCommand,\n handleDecompressCommand,\n handleHelpCommand,\n handleManualToggleCommand,\n handleManualTriggerCommand,\n handleRecompressCommand,\n handleStatsCommand,\n handleSweepCommand,\n} from \"./commands\"\nimport { type HostPermissionSnapshot } from \"./host-permissions\"\nimport { compressPermission, syncCompressPermissionState } from \"./compress-permission\"\nimport { checkSession, ensureSessionInitialized, saveSessionState, syncToolCache } from \"./state\"\nimport { cacheSystemPromptTokens } from \"./ui/utils\"\n\nconst INTERNAL_AGENT_SIGNATURES = [\n \"You are a title generator\",\n \"You are a helpful AI assistant tasked with summarizing conversations\",\n \"You are an anchored context summarization assistant for coding sessions\",\n \"Summarize what was done in this conversation\",\n]\n\nexport function createSystemPromptHandler(\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n) {\n return async (\n input: { sessionID?: string; model: { limit: { context: number } } },\n output: { system: string[] },\n ) => {\n if (input.model?.limit?.context) {\n state.modelContextLimit = input.model.limit.context\n logger.debug(\"Cached model context limit\", { limit: state.modelContextLimit })\n }\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n const systemText = output.system.join(\"\\n\")\n if (INTERNAL_AGENT_SIGNATURES.some((sig) => systemText.includes(sig))) {\n logger.info(\"Skipping DCP system prompt injection for internal agent\")\n return\n }\n\n const effectivePermission =\n input.sessionID && state.sessionId === input.sessionID\n ? compressPermission(state, config)\n : config.compress.permission\n\n if (effectivePermission === \"deny\") {\n return\n }\n\n prompts.reload()\n const runtimePrompts = prompts.getRuntimePrompts()\n const newPrompt = renderSystemPrompt(\n runtimePrompts,\n buildProtectedToolsExtension(config.compress.protectedTools),\n !!state.manualMode,\n state.isSubAgent && config.experimental.allowSubAgents,\n )\n if (output.system.length > 0) {\n output.system[output.system.length - 1] += \"\\n\\n\" + newPrompt\n } else {\n output.system.push(newPrompt)\n }\n }\n}\n\nexport function createChatMessageTransformHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n prompts: PromptStore,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (input: {}, output: { messages: WithParts[] }) => {\n const receivedMessages = Array.isArray(output.messages) ? output.messages.length : 0\n const messages = filterMessagesInPlace(output.messages)\n if (messages.length !== receivedMessages) {\n logger.warn(\"Skipping messages with unexpected shape during chat transform\", {\n received: receivedMessages,\n usable: messages.length,\n })\n }\n\n await checkSession(client, state, logger, output.messages, config.manualMode.enabled)\n\n syncCompressPermissionState(state, config, hostPermissions, output.messages)\n\n if (state.isSubAgent && !config.experimental.allowSubAgents) {\n return\n }\n\n stripHallucinations(output.messages)\n cacheSystemPromptTokens(state, output.messages)\n assignMessageRefs(state, output.messages)\n syncCompressionBlocks(state, logger, output.messages)\n syncToolCache(state, config, logger, output.messages)\n buildToolIdList(state, output.messages)\n prune(state, logger, config, output.messages)\n await injectExtendedSubAgentResults(\n client,\n state,\n logger,\n output.messages,\n config.experimental.allowSubAgents,\n )\n const compressionPriorities = buildPriorityMap(config, state, output.messages)\n prompts.reload()\n injectCompressNudges(\n state,\n config,\n logger,\n output.messages,\n prompts.getRuntimePrompts(),\n compressionPriorities,\n )\n injectMessageIds(state, config, output.messages, compressionPriorities)\n applyPendingManualTrigger(state, output.messages, logger)\n stripStaleMetadata(output.messages)\n\n if (state.sessionId) {\n await logger.saveContext(state.sessionId, output.messages)\n }\n }\n}\n\nexport function createCommandExecuteHandler(\n client: any,\n state: SessionState,\n logger: Logger,\n config: PluginConfig,\n workingDirectory: string,\n hostPermissions: HostPermissionSnapshot,\n) {\n return async (\n input: { command: string; sessionID: string; arguments: string },\n output: { parts: any[] },\n ) => {\n if (!config.commands.enabled) {\n return\n }\n\n if (input.command === \"dcp\") {\n const messagesResponse = await client.session.messages({\n path: { id: input.sessionID },\n })\n const messages = filterMessages(messagesResponse.data || messagesResponse)\n\n await ensureSessionInitialized(\n client,\n state,\n input.sessionID,\n logger,\n messages,\n config.manualMode.enabled,\n )\n\n syncCompressPermissionState(state, config, hostPermissions, messages)\n\n const effectivePermission = compressPermission(state, config)\n if (effectivePermission === \"deny\") {\n return\n }\n\n const args = (input.arguments || \"\").trim().split(/\\s+/).filter(Boolean)\n const subcommand = args[0]?.toLowerCase() || \"\"\n const subArgs = args.slice(1)\n\n const commandCtx = {\n client,\n state,\n config,\n logger,\n sessionId: input.sessionID,\n messages,\n }\n\n if (subcommand === \"context\") {\n await handleContextCommand(commandCtx)\n throw new Error(\"__DCP_CONTEXT_HANDLED__\")\n }\n\n if (subcommand === \"stats\") {\n await handleStatsCommand(commandCtx)\n throw new Error(\"__DCP_STATS_HANDLED__\")\n }\n\n if (subcommand === \"sweep\") {\n await handleSweepCommand({\n ...commandCtx,\n args: subArgs,\n workingDirectory,\n })\n throw new Error(\"__DCP_SWEEP_HANDLED__\")\n }\n\n if (subcommand === \"manual\") {\n await handleManualToggleCommand(commandCtx, subArgs[0]?.toLowerCase())\n throw new Error(\"__DCP_MANUAL_HANDLED__\")\n }\n\n if (subcommand === \"compress\") {\n const userFocus = subArgs.join(\" \").trim()\n const prompt = await handleManualTriggerCommand(commandCtx, \"compress\", userFocus)\n if (!prompt) {\n throw new Error(\"__DCP_MANUAL_TRIGGER_BLOCKED__\")\n }\n\n state.manualMode = \"compress-pending\"\n state.pendingManualTrigger = {\n sessionId: input.sessionID,\n prompt,\n }\n const rawArgs = (input.arguments || \"\").trim()\n output.parts.length = 0\n output.parts.push({\n type: \"text\",\n text: rawArgs ? `/dcp ${rawArgs}` : `/dcp ${subcommand}`,\n })\n return\n }\n\n if (subcommand === \"decompress\") {\n await handleDecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_DECOMPRESS_HANDLED__\")\n }\n\n if (subcommand === \"recompress\") {\n await handleRecompressCommand({\n ...commandCtx,\n args: subArgs,\n })\n throw new Error(\"__DCP_RECOMPRESS_HANDLED__\")\n }\n\n await handleHelpCommand(commandCtx)\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n }\n}\n\nexport function createTextCompleteHandler() {\n return async (\n _input: { sessionID: string; messageID: string; partID: string },\n output: { text: string },\n ) => {\n output.text = stripHallucinationsFromString(output.text)\n }\n}\n\nexport function createEventHandler(state: SessionState, logger: Logger) {\n return async (input: { event: any }) => {\n const eventTime =\n typeof input.event?.time === \"number\" && Number.isFinite(input.event.time)\n ? input.event.time\n : typeof input.event?.properties?.time === \"number\" &&\n Number.isFinite(input.event.properties.time)\n ? input.event.properties.time\n : undefined\n\n if (input.event.type !== \"message.part.updated\") {\n return\n }\n\n const part = input.event.properties?.part\n if (part?.type !== \"tool\" || part.tool !== \"compress\") {\n return\n }\n\n if (part.state.status === \"pending\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const startedAt = eventTime ?? Date.now()\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n if (state.compressionTiming.startsByCallId.has(key)) {\n return\n }\n state.compressionTiming.startsByCallId.set(key, startedAt)\n logger.debug(\"Recorded compression start\", {\n messageID: part.messageID,\n callID: part.callID,\n startedAt,\n })\n return\n }\n\n if (part.state.status === \"completed\") {\n if (typeof part.callID !== \"string\" || typeof part.messageID !== \"string\") {\n return\n }\n\n const key = buildCompressionTimingKey(part.messageID, part.callID)\n const start = consumeCompressionStart(state, part.messageID, part.callID)\n const durationMs = resolveCompressionDuration(start, eventTime, part.state.time)\n if (typeof durationMs !== \"number\") {\n return\n }\n\n state.compressionTiming.pendingByCallId.set(key, {\n messageId: part.messageID,\n callId: part.callID,\n durationMs,\n })\n\n const updates = applyPendingCompressionDurations(state)\n if (updates === 0) {\n return\n }\n\n await saveSessionState(state, logger)\n\n logger.info(\"Attached compression time to blocks\", {\n messageID: part.messageID,\n callID: part.callID,\n blocks: updates,\n durationMs,\n })\n return\n }\n\n if (part.state.status === \"running\") {\n return\n }\n\n if (typeof part.callID === \"string\" && typeof part.messageID === \"string\") {\n state.compressionTiming.startsByCallId.delete(\n buildCompressionTimingKey(part.messageID, part.callID),\n )\n }\n }\n}\n","export function isSecureMode(): boolean {\n return !!process.env.OPENCODE_SERVER_PASSWORD\n}\n\nexport function getAuthorizationHeader(): string | undefined {\n const password = process.env.OPENCODE_SERVER_PASSWORD\n if (!password) return undefined\n\n const username = process.env.OPENCODE_SERVER_USERNAME ?? \"opencode\"\n // Use Buffer for Node.js base64 encoding (btoa may not be available in all Node versions)\n const credentials = Buffer.from(`${username}:${password}`).toString(\"base64\")\n return `Basic ${credentials}`\n}\n\nexport function configureClientAuth(client: any): any {\n const authHeader = getAuthorizationHeader()\n\n if (!authHeader) {\n return client\n }\n\n // The SDK client has an internal client with request interceptors\n // Access the underlying client to add the interceptor\n const innerClient = client._client || client.client\n\n if (innerClient?.interceptors?.request) {\n innerClient.interceptors.request.use((request: Request) => {\n // Only add auth header if not already present\n if (!request.headers.has(\"Authorization\")) {\n request.headers.set(\"Authorization\", authHeader)\n }\n return request\n })\n }\n\n return client\n}\n","import { readFile, rm } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { updated: true; name: string; current: string; latest: string }\n | { updated: false; error: \"remove_failed\"; name: string; current: string; latest: string }\n | { updated: false }\n\nconst PACKAGE_NAME = \"@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: \"DCP update ready\",\n message: `Updated ${result.name} from ${result.current} to ${result.latest}. Restart OpenCode to finish.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { updated: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { updated: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { updated: false }\n\n const removeDir = await updateRemoveDir(packageDir, pkg.name)\n if (!removeDir) return { updated: false }\n\n try {\n await rm(removeDir, { recursive: true, force: true })\n } catch {\n return {\n updated: false,\n error: \"remove_failed\",\n name: pkg.name,\n current: pkg.version,\n latest,\n }\n }\n\n return { updated: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function updateRemoveDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nfunction wrapperSpec(wrapperDir: string, name: string) {\n if (name.startsWith(\"@\")) {\n const [scope, pkg] = name.split(\"/\")\n if (!scope || !pkg || basename(dirname(wrapperDir)) !== scope) return undefined\n const prefix = `${pkg}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n }\n\n const prefix = `${name}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"./lib/config\"\nimport { createCompressMessageTool, createCompressRangeTool } from \"./lib/compress\"\nimport {\n compressDisabledByOpencode,\n hasExplicitToolPermission,\n type HostPermissionSnapshot,\n} from \"./lib/host-permissions\"\nimport { Logger } from \"./lib/logger\"\nimport { createSessionState } from \"./lib/state\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport {\n createChatMessageTransformHandler,\n createCommandExecuteHandler,\n createEventHandler,\n createSystemPromptHandler,\n createTextCompleteHandler,\n} from \"./lib/hooks\"\nimport { configureClientAuth, isSecureMode } from \"./lib/auth\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n\n if (!config.enabled) {\n return {}\n }\n\n const logger = new Logger(config.debug)\n const state = createSessionState()\n const prompts = new PromptStore(logger, ctx.directory, config.experimental.customPrompts)\n const hostPermissions: HostPermissionSnapshot = {\n global: undefined,\n agents: {},\n }\n\n if (isSecureMode()) {\n configureClientAuth(ctx.client)\n // logger.info(\"Secure mode detected, configured client authentication\")\n }\n\n logger.info(\"DCP initialized\", {\n strategies: config.strategies,\n })\n\n startAutoUpdate(ctx, config.autoUpdate)\n\n const compressToolContext = {\n client: ctx.client,\n state,\n logger,\n config,\n prompts,\n }\n\n return {\n \"experimental.chat.system.transform\": createSystemPromptHandler(\n state,\n logger,\n config,\n prompts,\n ),\n \"experimental.chat.messages.transform\": createChatMessageTransformHandler(\n ctx.client,\n state,\n logger,\n config,\n prompts,\n hostPermissions,\n ) as any,\n \"experimental.text.complete\": createTextCompleteHandler(),\n \"command.execute.before\": createCommandExecuteHandler(\n ctx.client,\n state,\n logger,\n config,\n ctx.directory,\n hostPermissions,\n ),\n event: createEventHandler(state, logger),\n tool: {\n ...(config.compress.permission !== \"deny\" && {\n compress:\n config.compress.mode === \"message\"\n ? createCompressMessageTool(compressToolContext)\n : createCompressRangeTool(compressToolContext),\n }),\n },\n config: async (opencodeConfig) => {\n if (\n config.compress.permission !== \"deny\" &&\n compressDisabledByOpencode(opencodeConfig.permission)\n ) {\n config.compress.permission = \"deny\"\n }\n\n if (config.commands.enabled && config.compress.permission !== \"deny\") {\n opencodeConfig.command ??= {}\n opencodeConfig.command[\"dcp\"] = {\n template: \"\",\n description: \"Show available DCP commands\",\n }\n }\n\n const toolsToAdd: string[] = []\n if (config.compress.permission !== \"deny\" && !config.experimental.allowSubAgents) {\n toolsToAdd.push(\"compress\")\n }\n\n if (toolsToAdd.length > 0) {\n const existingPrimaryTools = opencodeConfig.experimental?.primary_tools ?? []\n opencodeConfig.experimental = {\n ...opencodeConfig.experimental,\n primary_tools: [...existingPrimaryTools, ...toolsToAdd],\n }\n }\n\n if (!hasExplicitToolPermission(opencodeConfig.permission, \"compress\")) {\n const permission = opencodeConfig.permission ?? {}\n opencodeConfig.permission = {\n ...permission,\n compress: config.compress.permission,\n } as typeof permission\n }\n\n hostPermissions.global = opencodeConfig.permission\n hostPermissions.agents = Object.fromEntries(\n Object.entries(opencodeConfig.agent ?? {}).map(([name, agent]) => [\n name,\n agent?.permission,\n ]),\n )\n },\n }\n}) satisfies Plugin\n\nexport default server\n"],"mappings":"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BAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,IAAI,IAAI,EAAE,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,GAAG,IAAI;AAC5C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAAG,IAAI,EAAE,IAAI;AAC3C,EAAAA,gBAAeA,gBAAe,GAA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","names":["value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","parse","countTokens","existsSync","homedir","join","countTokens","join","homedir","existsSync","tool","tool","tool","countTokens","countTokens","tool","validateArgs","buildSchema","tool","validateArgs","countTokens","tool","writeFile","mkdir","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","join","dirname","homedir","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","collectTurnNudgeAnchors","countTokens","message","tool","parseBlockIdArg","snapshotActiveMessages","formatAvailableBlocksMessage","message","message","readFile","dirname","join","prefix","base"]}
|