@lexwdex-org/opencode-dcp 3.5.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/auto-prune.ts","../lib/config.ts","../node_modules/jsonc-parser/lib/esm/impl/scanner.js","../node_modules/jsonc-parser/lib/esm/impl/string-intern.js","../node_modules/jsonc-parser/lib/esm/impl/parser.js","../node_modules/jsonc-parser/lib/esm/main.js","../lib/session-boundary.ts","../lib/hooks.ts","../lib/logger.ts","../lib/prompts/store.ts","../lib/prompts/compaction.ts","../lib/prune-tool.ts","../lib/session-model.ts","../lib/prune-service.ts","../lib/summarize.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import type { AutoPruneConfig } from \"./config\"\n\nexport type PruneSignal = \"topic-drift\" | \"volume\" | \"idle-gap\"\n\nexport interface ObserveResult {\n signals: PruneSignal[]\n}\n\ninterface SessionState {\n window: string[]\n count: number\n lastAt: number\n pendingSignals: PruneSignal[]\n lastTriggerAt: number\n}\n\nexport function tokenize(text: string): Set<string> {\n const tokens = new Set<string>()\n for (const match of text.toLowerCase().matchAll(/[\\p{L}\\p{N}]+/gu)) {\n const word = match[0]\n if (/[\\u4e00-\\u9fff]/.test(word)) {\n if (word.length === 1) {\n tokens.add(word)\n continue\n }\n for (let index = 0; index < word.length - 1; index++) {\n tokens.add(word.slice(index, index + 2))\n }\n } else {\n tokens.add(word)\n }\n }\n return tokens\n}\n\nexport function jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 1\n let intersection = 0\n for (const token of a) {\n if (b.has(token)) intersection++\n }\n return intersection / (a.size + b.size - intersection)\n}\n\nconst WINDOW_SIZE = 4\nconst DRIFT_BASELINE = 3\n// Short messages (\"继续\", \"ok\") share almost no tokens with any previous turn,\n// so comparing them against the window would fake a topic change. Drift is\n// only evaluated for messages substantial enough to describe a topic.\nconst MIN_DRIFT_TOKENS = 6\n\nfunction extractText(parts: unknown[]): string {\n const texts: string[] = []\n for (const part of parts) {\n if (\n part &&\n typeof part === \"object\" &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n texts.push((part as { text: string }).text)\n }\n }\n return texts.join(\" \").trim()\n}\n\nexport class AutoPruner {\n private readonly sessions = new Map<string, SessionState>()\n private readonly now: () => number\n\n constructor(\n private readonly config: AutoPruneConfig,\n now?: () => number,\n ) {\n this.now = now ?? Date.now\n }\n\n observeUserMessage(sessionID: string, parts: unknown[], at = this.now()): ObserveResult {\n const state = this.state(sessionID)\n const text = extractText(parts)\n\n const signals = this.evaluate(state, text, at)\n\n if (text) {\n state.window.push(text)\n if (state.window.length > WINDOW_SIZE) state.window.shift()\n }\n state.count += 1\n state.lastAt = at\n\n for (const signal of signals) {\n if (!state.pendingSignals.includes(signal)) state.pendingSignals.push(signal)\n }\n\n return { signals }\n }\n\n consumePending(sessionID: string, at = this.now()): PruneSignal[] | null {\n const state = this.sessions.get(sessionID)\n if (!state || state.pendingSignals.length === 0) return null\n const signals = [...state.pendingSignals]\n state.pendingSignals = []\n if (at - state.lastTriggerAt < this.config.cooldownMs) return null\n state.lastTriggerAt = at\n return signals\n }\n\n markPruned(sessionID: string, at = this.now()): void {\n const state = this.sessions.get(sessionID)\n if (!state) return\n state.count = 0\n state.window = []\n state.pendingSignals = []\n state.lastTriggerAt = at\n }\n\n dropSession(sessionID: string): void {\n this.sessions.delete(sessionID)\n }\n\n private evaluate(state: SessionState, text: string, at: number): PruneSignal[] {\n if (state.count + 1 < this.config.minMessages) return []\n\n const signals: PruneSignal[] = []\n const enabled = this.config.signals\n\n if (enabled.idleGap && state.count > 0 && at - state.lastAt >= this.config.idleGapMs) {\n signals.push(\"idle-gap\")\n }\n\n if (enabled.topicDrift && state.count >= DRIFT_BASELINE && text) {\n const current = tokenize(text)\n if (current.size >= MIN_DRIFT_TOKENS) {\n let max = 0\n for (\n let index = Math.max(0, state.window.length - DRIFT_BASELINE);\n index < state.window.length;\n index++\n ) {\n max = Math.max(max, jaccard(current, tokenize(state.window[index])))\n }\n if (max < this.config.driftThreshold) signals.push(\"topic-drift\")\n }\n }\n\n if (enabled.volume && state.count + 1 >= this.config.volumeThreshold) signals.push(\"volume\")\n\n return signals\n }\n\n private state(sessionID: string): SessionState {\n let state = this.sessions.get(sessionID)\n if (!state) {\n state = { window: [], count: 0, lastAt: 0, pendingSignals: [], lastTriggerAt: 0 }\n this.sessions.set(sessionID, state)\n if (this.sessions.size > 200) {\n const oldest = this.sessions.keys().next().value\n if (oldest !== undefined && oldest !== sessionID) this.sessions.delete(oldest)\n }\n }\n return state\n }\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport * as jsoncParser from \"jsonc-parser\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\nexport interface Commands {\n enabled: boolean\n}\n\nexport interface ExperimentalConfig {\n customPrompts: boolean\n}\n\nexport interface SummarizeConfig {\n failureCooldownMs: number\n}\n\nexport interface AutoPruneSignals {\n topicDrift: boolean\n volume: boolean\n idleGap: boolean\n}\n\nexport interface AutoPruneConfig {\n enabled: boolean\n /** Per-signal switches; only topic changes are enabled by default (LD1). */\n signals: AutoPruneSignals\n minMessages: number\n volumeThreshold: number\n driftThreshold: number\n idleGapMs: number\n cooldownMs: number\n}\n\nexport interface ToolConfig {\n enabled: boolean\n}\n\nexport type DcpLanguage = \"zh\" | \"en\"\n\nexport interface PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n language: DcpLanguage\n commands: Commands\n experimental: ExperimentalConfig\n summarize: SummarizeConfig\n autoPrune: AutoPruneConfig\n tool: ToolConfig\n}\n\nconst DEFAULT_FAILURE_COOLDOWN_MS = 30_000\n\nexport const DEFAULT_AUTO_PRUNE: AutoPruneConfig = {\n enabled: true,\n signals: { topicDrift: true, volume: false, idleGap: false },\n minMessages: 8,\n volumeThreshold: 30,\n driftThreshold: 0.18,\n idleGapMs: 30 * 60_000,\n cooldownMs: 5 * 60_000,\n}\n\nexport const VALID_CONFIG_KEYS = new Set([\n \"$schema\",\n \"enabled\",\n \"autoUpdate\",\n \"debug\",\n \"language\",\n \"commands\",\n \"commands.enabled\",\n \"experimental\",\n \"experimental.customPrompts\",\n \"summarize\",\n \"summarize.failureCooldownMs\",\n \"autoPrune\",\n \"autoPrune.enabled\",\n \"autoPrune.signals\",\n \"autoPrune.signals.topicDrift\",\n \"autoPrune.signals.volume\",\n \"autoPrune.signals.idleGap\",\n \"autoPrune.minMessages\",\n \"autoPrune.volumeThreshold\",\n \"autoPrune.driftThreshold\",\n \"autoPrune.idleGapMs\",\n \"autoPrune.cooldownMs\",\n \"tool\",\n \"tool.enabled\",\n])\n\n// Keys that only existed in the legacy plugin-owned compression state machine.\n// They are recognized so users get a migration hint instead of an \"unknown key\"\n// warning; their values are dropped and pruning is handled by native compaction.\nexport const DEPRECATED_CONFIG_KEYS = new Set([\n \"compress\",\n \"compress.mode\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.boundaryNudge\",\n \"compress.modelMaxLimits\",\n \"compress.modelMinLimits\",\n \"compress.nudgeFrequency\",\n \"compress.iterationNudgeThreshold\",\n \"compress.nudgeForce\",\n \"compress.protectedTools\",\n \"compress.protectTags\",\n \"compress.protectUserMessages\",\n \"compress.externalModel\",\n \"compress.externalModel.url\",\n \"compress.externalModel.model\",\n \"compress.externalModel.apiKey\",\n \"compress.externalModel.timeout\",\n \"compress.externalModel.retries\",\n \"manualMode\",\n \"manualMode.enabled\",\n \"manualMode.automaticStrategies\",\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 \"turnProtection\",\n \"turnProtection.enabled\",\n \"turnProtection.turns\",\n \"pruneNotification\",\n \"pruneNotificationType\",\n \"protectedFilePatterns\",\n \"commands.protectedTools\",\n \"experimental.allowSubAgents\",\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 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 getDeprecatedConfigKeys(userConfig: Record<string, any>): string[] {\n return getConfigKeyPaths(userConfig).filter((key) => DEPRECATED_CONFIG_KEYS.has(key))\n}\n\nexport function getInvalidConfigKeys(userConfig: Record<string, any>): string[] {\n return getConfigKeyPaths(userConfig).filter(\n (key) => !VALID_CONFIG_KEYS.has(key) && !DEPRECATED_CONFIG_KEYS.has(key),\n )\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.language !== undefined && config.language !== \"zh\" && config.language !== \"en\") {\n errors.push({\n key: \"language\",\n expected: '\"zh\" or \"en\"',\n actual: JSON.stringify(config.language),\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 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 }\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 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 const summarize = config.summarize\n if (summarize !== undefined) {\n if (typeof summarize !== \"object\" || summarize === null || Array.isArray(summarize)) {\n errors.push({\n key: \"summarize\",\n expected: \"object\",\n actual: typeof summarize,\n })\n } else {\n if (\n summarize.failureCooldownMs !== undefined &&\n (typeof summarize.failureCooldownMs !== \"number\" ||\n !Number.isFinite(summarize.failureCooldownMs) ||\n summarize.failureCooldownMs < 0)\n ) {\n errors.push({\n key: \"summarize.failureCooldownMs\",\n expected: \"non-negative finite number\",\n actual: JSON.stringify(summarize.failureCooldownMs),\n })\n }\n }\n }\n\n const autoPrune = config.autoPrune\n if (autoPrune !== undefined) {\n if (typeof autoPrune !== \"object\" || autoPrune === null || Array.isArray(autoPrune)) {\n errors.push({\n key: \"autoPrune\",\n expected: \"object\",\n actual: typeof autoPrune,\n })\n } else {\n const numericKeys: Array<[string, number, number]> = [\n [\"minMessages\", 1, Number.POSITIVE_INFINITY],\n [\"volumeThreshold\", 2, Number.POSITIVE_INFINITY],\n [\"driftThreshold\", 0, 1],\n [\"idleGapMs\", 0, Number.POSITIVE_INFINITY],\n [\"cooldownMs\", 0, Number.POSITIVE_INFINITY],\n ]\n for (const [key, min, max] of numericKeys) {\n const value = (autoPrune as Record<string, any>)[key]\n if (\n value !== undefined &&\n (typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < min ||\n value > max)\n ) {\n errors.push({\n key: `autoPrune.${key}`,\n expected: `number in [${min}, ${max === Number.POSITIVE_INFINITY ? \"∞\" : max}]`,\n actual: JSON.stringify(value),\n })\n }\n }\n for (const key of [\"enabled\"] as const) {\n const value = (autoPrune as Record<string, any>)[key]\n if (value !== undefined && typeof value !== \"boolean\") {\n errors.push({\n key: `autoPrune.${key}`,\n expected: \"boolean\",\n actual: typeof value,\n })\n }\n }\n const signals = (autoPrune as Record<string, any>).signals\n if (signals !== undefined) {\n if (typeof signals !== \"object\" || signals === null || Array.isArray(signals)) {\n errors.push({\n key: \"autoPrune.signals\",\n expected: \"object\",\n actual: typeof signals,\n })\n } else {\n for (const key of [\"topicDrift\", \"volume\", \"idleGap\"] as const) {\n const value = (signals as Record<string, any>)[key]\n if (value !== undefined && typeof value !== \"boolean\") {\n errors.push({\n key: `autoPrune.signals.${key}`,\n expected: \"boolean\",\n actual: typeof value,\n })\n }\n }\n }\n }\n }\n }\n\n const tool = config.tool\n if (tool !== undefined) {\n if (typeof tool !== \"object\" || tool === null || Array.isArray(tool)) {\n errors.push({\n key: \"tool\",\n expected: \"object\",\n actual: typeof tool,\n })\n } else if (tool.enabled !== undefined && typeof tool.enabled !== \"boolean\") {\n errors.push({\n key: \"tool.enabled\",\n expected: \"boolean\",\n actual: typeof tool.enabled,\n })\n }\n }\n\n return errors\n}\n\n/**\n * SR1 migration hint condition: auto prune is on but the user config predates\n * the per-signal switches. The hint fires on every config load where this\n * holds (same always-fires, stateless mechanism as the compress.* hints — no\n * persistent \"one-time\" flag).\n */\nexport function needsSignalsMigrationHint(configData: Record<string, any>): boolean {\n const autoPrune = configData.autoPrune\n return (\n autoPrune !== null &&\n typeof autoPrune === \"object\" &&\n !Array.isArray(autoPrune) &&\n autoPrune.enabled === true &&\n autoPrune.signals === undefined\n )\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 deprecatedKeys = getDeprecatedConfigKeys(configData)\n const typeErrors = validateConfigTypes(configData)\n const signalsHint = needsSignalsMigrationHint(configData)\n\n if (\n !signalsHint &&\n invalidKeys.length === 0 &&\n deprecatedKeys.length === 0 &&\n typeErrors.length === 0\n ) {\n return\n }\n\n const configType = isProject ? \"project config\" : \"config\"\n const messages: string[] = []\n\n if (signalsHint) {\n messages.push(\n \"auto-prune signals `volume` and `idleGap` are now disabled by default; re-enable via autoPrune.signals.*\",\n )\n }\n\n if (deprecatedKeys.length > 0) {\n const keyList = deprecatedKeys.slice(0, 3).join(\", \")\n const suffix = deprecatedKeys.length > 3 ? ` (+${deprecatedKeys.length - 3} more)` : \"\"\n messages.push(\n `Removed legacy compression keys are ignored: ${keyList}${suffix}. Pruning now runs through OpenCode's native compaction.`,\n )\n }\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 language: \"zh\",\n commands: {\n enabled: true,\n },\n experimental: {\n customPrompts: false,\n },\n summarize: {\n failureCooldownMs: DEFAULT_FAILURE_COOLDOWN_MS,\n },\n autoPrune: { ...DEFAULT_AUTO_PRUNE },\n tool: {\n enabled: true,\n },\n}\n\nconst GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, \"opencode\")\n : join(homedir(), \".config\", \"opencode\")\nconst GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.json\")\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate) && statSync(candidate).isDirectory()) {\n return candidate\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction getConfigPaths(ctx?: PluginInput): {\n global: string | null\n configDir: string | null\n project: string | null\n} {\n const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)\n ? GLOBAL_CONFIG_PATH_JSONC\n : existsSync(GLOBAL_CONFIG_PATH_JSON)\n ? GLOBAL_CONFIG_PATH_JSON\n : null\n\n let configDir: string | null = null\n const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR\n if (opencodeConfigDir) {\n const configJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : null\n }\n\n let project: string | null = null\n if (ctx?.directory) {\n const opencodeDir = findOpencodeDir(ctx.directory)\n if (opencodeDir) {\n const projectJsonc = join(opencodeDir, \"dcp.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : null\n }\n }\n\n return { global, configDir, project }\n}\n\nfunction createDefaultConfig(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/LeXwDeX/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n}\n\ninterface ConfigLoadResult {\n data: Record<string, any> | null\n parseError?: string\n}\n\nfunction loadConfigFile(configPath: string): ConfigLoadResult {\n let fileContent = \"\"\n try {\n fileContent = readFileSync(configPath, \"utf-8\")\n } catch {\n return { data: null }\n }\n\n try {\n const parsed = jsoncParser.parse(fileContent, undefined, { allowTrailingComma: true })\n if (parsed === undefined || parsed === null) {\n return { data: null, parseError: \"Config file is empty or invalid\" }\n }\n return { data: parsed }\n } catch (error: any) {\n return { data: null, parseError: error.message || \"Failed to parse config\" }\n }\n}\n\nfunction 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: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (!override) {\n return base\n }\n\n return {\n customPrompts:\n typeof override.customPrompts === \"boolean\"\n ? override.customPrompts\n : base.customPrompts,\n }\n}\n\nfunction mergeSummarize(\n base: PluginConfig[\"summarize\"],\n override?: Partial<PluginConfig[\"summarize\"]>,\n): PluginConfig[\"summarize\"] {\n if (!override) {\n return base\n }\n\n return {\n failureCooldownMs:\n typeof override.failureCooldownMs === \"number\" &&\n Number.isFinite(override.failureCooldownMs) &&\n override.failureCooldownMs >= 0\n ? override.failureCooldownMs\n : base.failureCooldownMs,\n }\n}\n\nfunction mergeAutoPrune(base: AutoPruneConfig, override?: Record<string, any>): AutoPruneConfig {\n if (!override || typeof override !== \"object\" || Array.isArray(override)) {\n return base\n }\n\n const number = (\n key: \"minMessages\" | \"volumeThreshold\" | \"driftThreshold\" | \"idleGapMs\" | \"cooldownMs\",\n min: number,\n max = Number.POSITIVE_INFINITY,\n ): number =>\n typeof override[key] === \"number\" &&\n Number.isFinite(override[key]) &&\n override[key] >= min &&\n override[key] <= max\n ? override[key]\n : base[key]\n\n const signalsOverride = override.signals\n const signals: AutoPruneSignals =\n signalsOverride && typeof signalsOverride === \"object\" && !Array.isArray(signalsOverride)\n ? {\n topicDrift:\n typeof signalsOverride.topicDrift === \"boolean\"\n ? signalsOverride.topicDrift\n : base.signals.topicDrift,\n volume:\n typeof signalsOverride.volume === \"boolean\"\n ? signalsOverride.volume\n : base.signals.volume,\n idleGap:\n typeof signalsOverride.idleGap === \"boolean\"\n ? signalsOverride.idleGap\n : base.signals.idleGap,\n }\n : base.signals\n\n return {\n enabled: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n signals,\n minMessages: number(\"minMessages\", 1),\n volumeThreshold: number(\"volumeThreshold\", 2),\n driftThreshold: number(\"driftThreshold\", 0, 1),\n idleGapMs: number(\"idleGapMs\", 0),\n cooldownMs: number(\"cooldownMs\", 0),\n }\n}\n\nfunction mergeTool(base: ToolConfig, override?: Partial<ToolConfig>): ToolConfig {\n if (!override) {\n return base\n }\n\n return {\n enabled: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: { ...config.commands },\n experimental: { ...config.experimental },\n summarize: { ...config.summarize },\n autoPrune: { ...config.autoPrune, signals: { ...config.autoPrune.signals } },\n tool: { ...config.tool },\n }\n}\n\nfunction mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConfig {\n return {\n enabled: typeof data.enabled === \"boolean\" ? data.enabled : config.enabled,\n autoUpdate: typeof data.autoUpdate === \"boolean\" ? data.autoUpdate : config.autoUpdate,\n debug: typeof data.debug === \"boolean\" ? data.debug : config.debug,\n language:\n data.language === \"zh\" || data.language === \"en\" ? data.language : config.language,\n commands: mergeCommands(config.commands, data.commands),\n experimental: mergeExperimental(config.experimental, data.experimental),\n summarize: mergeSummarize(config.summarize, data.summarize),\n autoPrune: mergeAutoPrune(config.autoPrune, data.autoPrune),\n tool: mergeTool(config.tool, data.tool),\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 type { Logger } from \"./logger\"\n\n/**\n * Per-session boundary phase. The compression boundary is NOT the raw\n * `session.idle` instant: an idle observation opens a quiet window, and only\n * a window that survives its full duration plus a live status probe is\n * classified as AT-REST. Busy/retry evidence at any point cancels the window.\n */\nexport type BoundaryPhase = \"unknown\" | \"busy\" | \"pending-rest\" | \"at-rest\"\n\n/** Why an at-rest classification fired. `probe-failopen` covers a missing\n * endpoint, an HTTP error, and a timed-out probe — all fail open. */\nexport type RestFireReason = \"window-expired\" | \"probe-failopen\"\n\nexport type AtRestListener = (sessionID: string, reason: RestFireReason) => void | Promise<void>\n\n/** Internal constants — deliberately NOT config: safety semantics, not user\n * preference (design ADR-0004). Clock and timers are injectable for tests. */\nexport const BOUNDARY_QUIET_MS = 2_000\nexport const PROBE_TIMEOUT_MS = 2_000\n// Busy evidence that never got its matching idle must not wedge the session\n// forever; after this long it decays back to \"unknown\" (fail-open).\nconst BUSY_EVIDENCE_TTL_MS = 10 * 60_000\nconst MAX_TRACKED_SESSIONS = 500\n\nexport interface SessionBoundaryDeps {\n /** THE single busy probe (PruneService.probeBusy), injected — never\n * imported, so this module never depends on prune-service. */\n probeBusy: (sessionID: string) => Promise<boolean | null>\n logger: Logger\n now?: () => number\n setTimer?: (fn: () => void, ms: number) => unknown\n clearTimer?: (t: unknown) => void\n}\n\ninterface SessionEntry {\n phase: BoundaryPhase\n /** Bumped on every cancel/re-arm so an in-flight expiry probe result that\n * predates a canceling event is discarded (probe-in-flight guard). */\n generation: number\n timer?: unknown\n busyAt?: number\n /** Whether any `session.status` observation ever arrived for this session.\n * Hosts that never send status events run in T3 degrade mode where every\n * turn-end legacy idle re-arms the boundary from at-rest. */\n sawStatus: boolean\n}\n\n/**\n * Classifies turn boundaries as AT-REST or relay-idle. Owns the ONLY\n * per-session busy/idle event state machine (it absorbed the former\n * SessionActivityTracker): exactly one entry per session, LRU-bounded.\n *\n * State model per session:\n * - unknown no evidence (fresh, TTL-decayed, or post-lifecycle); fail-open\n * - busy busy/retry evidence cached; TTL-decays to unknown\n * - pending-rest quiet window armed (BOUNDARY_QUIET_MS); busy/retry cancels\n * - at-rest rest confirmed; onAtRest fired once\n *\n * Idle handling: `pending-rest` + idle -> ignore (dual-publish second leg).\n * `at-rest` + idle -> ignore on status-capable hosts (T1/T2: a real next turn\n * is preceded by a busy/retry status that exits at-rest first). In degrade\n * mode (T3: no status observation ever received) a legacy idle from at-rest\n * RE-ARMS the window — every turn-end idle is a new boundary candidate.\n */\nexport class SessionBoundaryTracker {\n private readonly sessions = new Map<string, SessionEntry>()\n private readonly listeners: AtRestListener[] = []\n private readonly probeBusy: (sessionID: string) => Promise<boolean | null>\n private readonly logger: Logger\n private readonly now: () => number\n private readonly setTimer: (fn: () => void, ms: number) => unknown\n private readonly clearTimer: (t: unknown) => void\n\n constructor(deps: SessionBoundaryDeps) {\n this.probeBusy = deps.probeBusy\n this.logger = deps.logger\n this.now = deps.now ?? Date.now\n this.setTimer = deps.setTimer ?? ((fn, ms) => setTimeout(fn, ms))\n this.clearTimer =\n deps.clearTimer ?? ((t) => clearTimeout(t as ReturnType<typeof setTimeout>))\n }\n\n /** Register an at-rest listener; listeners fire in registration order\n * (1. deferred drain, 2. heuristic auto prune) and are individually\n * error-isolated: a throw or rejection is warn-logged and never blocks\n * later listeners nor escapes into the timer callback. */\n onAtRest(listener: AtRestListener): void {\n this.listeners.push(listener)\n }\n\n /** Primary input: `session.status` event payload status type. */\n observeStatus(sessionID: string | undefined, statusType: unknown): void {\n if (!sessionID) return\n const entry = this.entry(sessionID)\n entry.sawStatus = true\n if (statusType === \"busy\" || statusType === \"retry\") {\n this.transition(\n sessionID,\n entry,\n \"busy\",\n statusType === \"retry\" ? \"retry-observed\" : \"busy-observed\",\n )\n return\n }\n if (statusType === \"idle\") {\n this.observeIdle(sessionID, entry, \"status\")\n }\n }\n\n /** First-class input: legacy `session.idle`. Absorbed by dedup on hosts\n * that dual-publish; the only boundary signal on status-less hosts (T3). */\n observeLegacyIdle(sessionID: string | undefined): void {\n if (!sessionID) return\n this.observeIdle(sessionID, this.entry(sessionID), \"legacy-idle\")\n }\n\n /** Lifecycle: cancel any pending window and forget the session. */\n observeDeleted(sessionID: string | undefined): void {\n if (!sessionID) return\n const entry = this.sessions.get(sessionID)\n if (!entry) return\n this.cancelWindow(entry)\n this.sessions.delete(sessionID)\n this.logger.debug(\"Boundary session dropped\", { sessionId: sessionID, reason: \"deleted\" })\n }\n\n /** Lifecycle: compaction ended; reset to unknown so the next idle opens a\n * fresh window. */\n observeCompacted(sessionID: string | undefined): void {\n if (!sessionID) return\n const entry = this.sessions.get(sessionID)\n if (!entry) return\n const from = entry.phase\n this.cancelWindow(entry)\n entry.phase = \"unknown\"\n delete entry.busyAt\n this.logger.debug(\"Boundary transition\", {\n sessionId: sessionID,\n from,\n to: \"unknown\",\n reason: \"compacted\",\n })\n }\n\n /** Absorbed busy-evidence cache: `busy` decays to `unknown` after the TTL;\n * the table is LRU-bounded (pending-rest/at-rest entries have no TTL exit\n * and rely on the cap). */\n state(sessionID: string): BoundaryPhase {\n const entry = this.sessions.get(sessionID)\n if (!entry) return \"unknown\"\n if (\n entry.phase === \"busy\" &&\n entry.busyAt !== undefined &&\n this.now() - entry.busyAt > BUSY_EVIDENCE_TTL_MS\n ) {\n return \"unknown\"\n }\n return entry.phase\n }\n\n dispose(sessionID: string): void {\n this.observeDeleted(sessionID)\n }\n\n private observeIdle(\n sessionID: string,\n entry: SessionEntry,\n source: \"status\" | \"legacy-idle\",\n ): void {\n if (entry.phase === \"pending-rest\") {\n this.logger.debug(\"Boundary duplicate idle ignored\", { sessionId: sessionID, source })\n return\n }\n if (entry.phase === \"at-rest\") {\n if (source === \"legacy-idle\" && !entry.sawStatus) {\n // T3 degrade re-arm: without status events this idle is the\n // next turn's boundary, not a duplicate second leg.\n this.armWindow(sessionID, entry, \"degrade-rearm\")\n } else {\n this.logger.debug(\"Boundary duplicate idle ignored\", {\n sessionId: sessionID,\n source,\n })\n }\n return\n }\n this.armWindow(sessionID, entry, \"idle-observed\")\n }\n\n private armWindow(sessionID: string, entry: SessionEntry, reason: string): void {\n this.cancelWindow(entry)\n entry.phase = \"pending-rest\"\n entry.timer = this.setTimer(() => {\n entry.timer = undefined\n void this.onWindowExpiry(sessionID, entry)\n }, BOUNDARY_QUIET_MS)\n this.refresh(sessionID, entry)\n this.logger.debug(\"Boundary quiet window armed\", {\n sessionId: sessionID,\n reason,\n generation: entry.generation,\n })\n }\n\n private async onWindowExpiry(sessionID: string, entry: SessionEntry): Promise<void> {\n if (entry.phase !== \"pending-rest\") return\n const generation = entry.generation\n let busy: boolean | null\n try {\n busy = await this.probeBusy(sessionID)\n } catch {\n busy = null\n }\n // Probe-in-flight guard: a busy/retry/deleted event that arrived while\n // the probe was awaited bumped the generation or moved the phase — a\n // stale result must never fire. An entry that was LRU-evicted mid-flight\n // is equally stale (identity check).\n if (\n entry.phase !== \"pending-rest\" ||\n entry.generation !== generation ||\n this.sessions.get(sessionID) !== entry\n ) {\n this.logger.debug(\"Boundary probe result discarded\", {\n sessionId: sessionID,\n generation,\n })\n return\n }\n if (busy === true) {\n this.transition(sessionID, entry, \"busy\", \"probe-busy\")\n return\n }\n const reason: RestFireReason = busy === false ? \"window-expired\" : \"probe-failopen\"\n const from = entry.phase\n entry.phase = \"at-rest\"\n this.refresh(sessionID, entry)\n this.logger.debug(\"Boundary transition\", {\n sessionId: sessionID,\n from,\n to: \"at-rest\",\n reason,\n })\n this.fireAtRest(sessionID, reason)\n }\n\n private transition(\n sessionID: string,\n entry: SessionEntry,\n phase: \"busy\" | \"unknown\",\n reason: string,\n ): void {\n const from = entry.phase\n this.cancelWindow(entry)\n entry.phase = phase\n if (phase === \"busy\") entry.busyAt = this.now()\n else delete entry.busyAt\n this.refresh(sessionID, entry)\n this.logger.debug(\"Boundary transition\", { sessionId: sessionID, from, to: phase, reason })\n }\n\n private cancelWindow(entry: SessionEntry): void {\n if (entry.timer !== undefined) {\n this.clearTimer(entry.timer)\n entry.timer = undefined\n }\n // Bump the generation so an in-flight expiry probe result is voided.\n entry.generation += 1\n }\n\n private fireAtRest(sessionID: string, reason: RestFireReason): void {\n for (const listener of this.listeners) {\n try {\n const result = listener(sessionID, reason)\n if (result instanceof Promise) {\n result.catch((error) => {\n this.logger.warn(\"At-rest listener rejected\", {\n sessionId: sessionID,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n }\n } catch (error) {\n this.logger.warn(\"At-rest listener failed\", {\n sessionId: sessionID,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n }\n\n private entry(sessionID: string): SessionEntry {\n let entry = this.sessions.get(sessionID)\n if (!entry) {\n entry = { phase: \"unknown\", generation: 0, sawStatus: false }\n this.sessions.set(sessionID, entry)\n this.evictIfNeeded(sessionID)\n return entry\n }\n this.refresh(sessionID, entry)\n return entry\n }\n\n private refresh(sessionID: string, entry: SessionEntry): void {\n this.sessions.delete(sessionID)\n this.sessions.set(sessionID, entry)\n this.evictIfNeeded(sessionID)\n }\n\n private evictIfNeeded(kept: string): void {\n if (this.sessions.size <= MAX_TRACKED_SESSIONS) return\n const oldest = this.sessions.keys().next().value\n if (oldest === undefined || oldest === kept) return\n const victim = this.sessions.get(oldest)\n if (victim?.timer !== undefined) this.clearTimer(victim.timer)\n this.sessions.delete(oldest)\n }\n}\n\n/** Ceil a cooldown to whole seconds for user-facing copy. */\nexport function retrySeconds(retryAfterMs: number): number {\n return Math.ceil(retryAfterMs / 1000)\n}\n\n/**\n * Resolves the session ID from a host event's properties. Most events carry\n * `sessionID` directly, but some (e.g. `session.deleted`) only carry\n * `info: Session`. Returns `undefined` when neither is a non-empty string.\n */\nexport function eventSessionID(properties?: Record<string, any>): string | undefined {\n const direct = properties?.sessionID\n if (typeof direct === \"string\" && direct) return direct\n const info = properties?.info?.id\n if (typeof info === \"string\" && info) return info\n return undefined\n}\n","import type { AutoPruneConfig } from \"./config\"\nimport type { Logger } from \"./logger\"\nimport type { OpenCodeClient } from \"./opencode-client\"\nimport type { PromptStore } from \"./prompts/store\"\nimport type { PruneSignal, AutoPruner } from \"./auto-prune\"\nimport type { PruneService } from \"./prune-service\"\nimport type { RestFireReason } from \"./session-boundary\"\nimport { eventSessionID, retrySeconds } from \"./session-boundary\"\n\ninterface CompactionOutput {\n context: string[]\n prompt?: string\n}\n\nexport function createSessionCompactingHandler(prompts: PromptStore, logger: Logger) {\n return async (input: { sessionID: string }, output: CompactionOutput): Promise<void> => {\n try {\n prompts.reload()\n const prompt = prompts.getRuntimePrompts().compaction\n if (!output.prompt) {\n output.prompt = prompt\n } else if (!output.context.includes(prompt)) {\n output.context.push(prompt)\n }\n logger.debug(\"Applied semantic pruning prompt\", { sessionId: input.sessionID })\n } catch (error) {\n logger.warn(\"Failed to apply semantic pruning prompt; native compaction continues\", {\n sessionId: input.sessionID,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\nasync function showToast(\n client: OpenCodeClient,\n title: string,\n message: string,\n variant: \"info\" | \"warning\" | \"error\" = \"info\",\n): Promise<void> {\n await client.tui\n .showToast({\n body: { title, message, variant, duration: 5000 },\n })\n .catch(() => undefined)\n}\n\nexport function createChatMessageHandler(autoPruner: AutoPruner) {\n return async (input: { sessionID: string }, _output?: unknown): Promise<void> => {\n const parts = (_output as { parts?: unknown[] } | undefined)?.parts ?? []\n autoPruner.observeUserMessage(input.sessionID, parts)\n }\n}\n\nconst SIGNAL_LABELS: Record<PruneSignal, string> = {\n \"topic-drift\": \"话题变更\",\n volume: \"消息量达到阈值\",\n \"idle-gap\": \"长时间中断后恢复\",\n}\n\nexport interface EventHandlerDeps {\n prune: PruneService\n autoPruner: AutoPruner\n logger: Logger\n}\n\n/**\n * Every host event feeds the PruneService first: `session.status` / legacy\n * `session.idle` observations go to the boundary tracker, which classifies\n * at-rest boundaries (quiet window + live probe) and drives both the\n * deferred-prune drain and the at-rest auto-prune listener. This handler only\n * keeps the heuristic pruner's own lifecycle state in sync.\n */\nexport function createEventHandler(deps: EventHandlerDeps) {\n return async (input: { event: { type: string; properties?: Record<string, any> } }) => {\n const event = input.event\n try {\n deps.prune.observeEvent(event.type, event.properties)\n const sessionID = eventSessionID(event.properties)\n if (!sessionID) return\n if (event.type === \"session.compacted\") {\n deps.autoPruner.markPruned(sessionID)\n return\n }\n if (event.type === \"session.deleted\") {\n deps.autoPruner.dropSession(sessionID)\n }\n } catch (error) {\n deps.logger.warn(\"Event handler failed\", {\n type: event.type,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\nasync function triggerAutoPrune(\n deps: AtRestAutoPruneDeps,\n sessionID: string,\n signals: PruneSignal[],\n): Promise<void> {\n const reason = signals.map((signal) => SIGNAL_LABELS[signal]).join(\"、\")\n const result = await deps.prune.request({ sessionID, onBusy: \"proceed\" })\n\n // busy and no-model mean nothing was attempted this time. consumePending\n // has already cleared the signals, so this trigger is spent: there is no\n // retry at the next boundary. New signals only arrive from later messages.\n const attempted =\n result.status === \"succeeded\" || result.status === \"failed\" || result.status === \"cooldown\"\n if (!attempted) {\n if (result.status === \"busy\") {\n await showToast(\n deps.client,\n \"DCP 自动压缩\",\n `检测到${reason},但会话正忙,本次已跳过;原始上下文保持不变。`,\n \"warning\",\n )\n }\n deps.logger.debug(\"Auto prune skipped\", {\n sessionId: sessionID,\n status: result.status,\n })\n return\n }\n deps.autoPruner.markPruned(sessionID)\n\n if (result.status === \"succeeded\") {\n await showToast(deps.client, \"DCP 自动压缩\", `检测到${reason},已生成新的语义检查点。`)\n } else if (result.status === \"cooldown\") {\n await showToast(\n deps.client,\n \"DCP 自动压缩\",\n `检测到${reason},但上一次压缩失败;${retrySeconds(result.retryAfterMs)} 秒后可重试。`,\n \"warning\",\n )\n } else {\n await showToast(\n deps.client,\n \"DCP 自动压缩\",\n `检测到${reason},但压缩失败;原始上下文保持不变。`,\n \"warning\",\n )\n }\n deps.logger.debug(\"Auto prune finished\", { sessionId: sessionID, status: result.status })\n}\n\nexport interface AtRestAutoPruneDeps {\n client: OpenCodeClient\n prune: PruneService\n autoPruner: AutoPruner\n config: AutoPruneConfig\n logger: Logger\n}\n\n/**\n * At-rest listener #2: the heuristic auto prune. The `enabled` gate stays at\n * this mount point — a tool-only configuration (auto prune disabled) never\n * registers the listener, so it gains no auto-prune behavior.\n */\nexport function createAtRestAutoPruneListener(deps: AtRestAutoPruneDeps) {\n return async (sessionID: string, _reason: RestFireReason): Promise<void> => {\n if (!deps.config.enabled) return\n const signals = deps.autoPruner.consumePending(sessionID)\n if (signals) await triggerAutoPrune(deps, sessionID, signals)\n }\n}\n\nexport function createCommandExecuteHandler(\n client: OpenCodeClient,\n prune: PruneService,\n logger: Logger,\n) {\n return async (\n input: {\n command: string\n sessionID: string\n arguments: string\n },\n _output?: { parts: unknown[] },\n ): Promise<void> => {\n if (input.command !== \"dcp\") return\n\n const subcommand = (input.arguments ?? \"\").trim().split(/\\s+/, 1)[0]?.toLowerCase()\n if (subcommand !== \"summarize\") {\n await showToast(\n client,\n \"DCP\",\n \"Use /dcp summarize for semantic pruning, or OpenCode's native /compact command.\",\n )\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n\n const result = await prune.request({ sessionID: input.sessionID, onBusy: \"proceed\" })\n if (result.status === \"busy\") {\n await showToast(\n client,\n \"DCP summarize\",\n \"Session is busy; the prune will not interrupt the current turn. Try again once it finishes.\",\n \"warning\",\n )\n throw new Error(\"__DCP_SUMMARIZE_HANDLED__\")\n }\n if (result.status === \"no-model\") {\n await showToast(\n client,\n \"DCP summarize\",\n \"No session model is available yet.\",\n \"warning\",\n )\n throw new Error(\"__DCP_SUMMARIZE_NO_MODEL__\")\n }\n if (result.status === \"succeeded\") {\n await showToast(client, \"DCP summarize\", \"Semantic pruning checkpoint created.\")\n } else if (result.status === \"cooldown\") {\n await showToast(\n client,\n \"DCP summarize\",\n `Previous attempt failed; retry in ${retrySeconds(result.retryAfterMs)}s.`,\n \"warning\",\n )\n } else {\n await showToast(\n client,\n \"DCP summarize\",\n \"Native compaction failed; the original context was kept.\",\n \"error\",\n )\n }\n logger.debug(\"Handled DCP summarize command\", {\n sessionId: input.sessionID,\n status: result.status,\n })\n throw new Error(\"__DCP_SUMMARIZE_HANDLED__\")\n }\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, statSync, writeFileSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport { dirname, join } from \"node:path\"\nimport type { Logger } from \"../logger\"\nimport { getCompactionPrompt } from \"./compaction\"\n\nexport interface RuntimePrompts {\n compaction: string\n}\n\ninterface PromptPaths {\n defaultsDir: string\n overrides: string[]\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) && statSync(candidate).isDirectory()) return candidate\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return null\n}\n\nfunction resolvePaths(workingDirectory: string): PromptPaths {\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n const globalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n const opencodeDir = findOpencodeDir(workingDirectory)\n return {\n defaultsDir: join(globalRoot, \"defaults\"),\n overrides: [\n opencodeDir ? join(opencodeDir, \"dcp-prompts\", \"overrides\", \"compaction.md\") : \"\",\n process.env.OPENCODE_CONFIG_DIR\n ? join(process.env.OPENCODE_CONFIG_DIR, \"dcp-prompts\", \"overrides\", \"compaction.md\")\n : \"\",\n join(globalRoot, \"overrides\", \"compaction.md\"),\n ].filter(Boolean),\n }\n}\n\nfunction normalize(content: string): string {\n return content\n .replace(/^\\uFEFF/, \"\")\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(/<!--[\\s\\S]*?-->/g, \"\")\n .trim()\n}\n\nexport class PromptStore {\n private readonly paths: PromptPaths\n private readonly defaultPrompt: string\n private runtime: RuntimePrompts\n private lastReloadAt = 0\n\n constructor(\n private readonly logger: Logger,\n workingDirectory: string,\n private readonly customPromptsEnabled = false,\n language?: string,\n ) {\n this.paths = resolvePaths(workingDirectory)\n this.defaultPrompt = getCompactionPrompt(language)\n this.runtime = { compaction: this.defaultPrompt }\n if (customPromptsEnabled) this.ensureDefaults()\n this.reload()\n }\n\n getRuntimePrompts(): RuntimePrompts {\n return { ...this.runtime }\n }\n\n reload(): void {\n const now = Date.now()\n if (now - this.lastReloadAt < 1000) return\n this.lastReloadAt = now\n this.runtime = { compaction: this.defaultPrompt }\n if (!this.customPromptsEnabled) return\n\n for (const path of this.paths.overrides) {\n if (!existsSync(path)) continue\n try {\n const prompt = normalize(readFileSync(path, \"utf-8\"))\n if (prompt) this.runtime = { compaction: prompt }\n return\n } catch (error) {\n this.logger.warn(\"Failed to load compaction prompt override\", {\n path,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n }\n\n private ensureDefaults(): void {\n try {\n mkdirSync(this.paths.defaultsDir, { recursive: true })\n writeFileSync(\n join(this.paths.defaultsDir, \"compaction.md\"),\n `${this.defaultPrompt.trim()}\\n`,\n )\n writeFileSync(\n join(this.paths.defaultsDir, \"README.md\"),\n \"# DCP compaction prompt\\n\\nCopy `compaction.md` to an `overrides` directory and restart OpenCode.\\n\",\n )\n } catch (error) {\n this.logger.warn(\"Failed to write bundled compaction prompt\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n","export const COMPACTION = `你正在生成当前会话唯一的滚动检查点。输出将替代旧对话前缀,成为后续模型看到的第一段上下文;OpenCode 会在它后面保留尚未压缩的近期尾部。系统级内容(AGENTS.md、项目规则等)由 OpenCode 在每次请求时独立注入,不属于压缩范围,不要复述它们。\n\n这不是聊天记录摘要,而是可直接继续工作的语义剪枝结果。按以下规则压缩:\n\n1. 如果输入含有上一份检查点,把仍有效的信息合并进新检查点;不要嵌套、引用或重复旧检查点。\n2. 删除无关闲聊、其他项目或其他仓库的对话、重复解释、已经推翻且不再有诊断价值的方案。\n3. 多次工具调用试错或失败后成功时,只保留最终成功结果;仅当根因会影响后续工作时保留一次简短失败原因。\n4. 同一内容或文件被重复编辑时,只保留最终状态、仍有效的关键决策和必要理由,不复述每轮修改。\n5. 按时间分层决定压缩深度:早期历史和中部历史高度压缩——每个主题只留一句话结论,不留过程;最近历史轻度压缩——尤其是与当前任务相关的内容,保留继续工作所需的关键细节(文件路径、接口、命令、测试结果、错误事实、仍有效的决策及理由),只折叠重复与已失效的内容。最近历史指自上一份检查点以来的新内容。\n\n使用以下固定结构,省略确实为空的条目:\n\n## 历史概要\n早期与中部历史的主题和背景,每项一句话结论;远期已完成任务归入此处,不含执行过程。\n\n## 已完成任务的概括\n最近的已完成任务,每个任务一句话概括其结果与关键产出。\n\n## 进行中任务详情\n当前正在进行的任务逐项写清:目标、已完成步骤、涉及文件路径与接口、关键决策、遇到的阻塞、下一步具体动作。本节属于轻度压缩区,宁可多保留细节,不做二次推断。\n\n## 未解决问题\n跨任务的遗留风险和待确认事项。只写未在「进行中任务详情」中出现的内容,避免与该节重复。\n\n保持具体、可验证和项目内聚。进行中的任务必须能凭检查点直接继续,不要依赖已被压缩掉的中间过程。保留文件路径、接口、命令、测试结果和错误事实等硬事实,但不要保留消息 ID、块 ID、锚点、占位符、控制标签或过程性聊天。`\n\nexport const COMPACTION_EN = `You are generating the single rolling checkpoint for this session. Your output will replace the old conversation prefix as the first context the model sees afterwards; OpenCode keeps an uncompacted recent tail right after it. System-level content (AGENTS.md, project rules, etc.) is injected independently by OpenCode on every request and is not part of compaction; do not restate it.\n\nThis is not a chat-log summary but a semantic pruning result one can resume working from directly. Compress by these rules:\n\n1. If the input contains a previous checkpoint, merge the still-valid information into the new checkpoint; do not nest, quote, or duplicate the old one.\n2. Remove irrelevant chitchat, conversations about other projects or repositories, repeated explanations, and approaches that were overturned and no longer carry diagnostic value.\n3. When repeated tool trial-and-error ends in success, keep only the final successful outcome; retain one brief failure reason only if the root cause affects future work.\n4. When the same content or file was edited repeatedly, keep only the final state, the still-valid key decisions, and the necessary rationale; do not restate each round of edits.\n5. Choose compression depth by recency tiers: early and middle history are compressed heavily—one concluding sentence per topic, no process detail; recent history is compressed lightly—especially content related to the current task, keeping the key details needed to continue (file paths, interfaces, commands, test results, error facts, still-valid decisions and their rationale), folding only duplicates and invalidated content. Recent history means everything generated since the previous checkpoint.\n\nUse the following fixed structure, omitting sections that are truly empty:\n\n## History Overview\nTopics and background from early and middle history, one concluding sentence each; long-completed tasks belong here, without execution process.\n\n## Completed Task Summaries\nRecently completed tasks, one sentence per task covering its outcome and key outputs.\n\n## In-Progress Task Details\nFor the current task, itemize: goal, completed steps, file paths and interfaces involved, key decisions, blockers encountered, concrete next actions. This is the lightly-compressed zone; prefer keeping more detail and avoid second-order inference.\n\n## Unresolved Issues\nCross-task lingering risks and items awaiting confirmation. Only list items not already covered under In-Progress Task Details, to avoid duplication.\n\nStay specific, verifiable, and project-cohesive. An in-progress task must be resumable straight from this checkpoint, without relying on intermediate process that was pruned away. Keep hard facts such as file paths, interfaces, commands, test results, and error facts, but never message IDs, block IDs, anchors, placeholders, control tags, or procedural chatter.`\n\nexport function getCompactionPrompt(language?: string): string {\n return language === \"en\" ? COMPACTION_EN : COMPACTION\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { Logger } from \"./logger\"\nimport type { PruneService } from \"./prune-service\"\nimport { retrySeconds } from \"./prune-service\"\n\nexport const PRUNE_TOOL_NAME = \"dcp_prune\"\n\nconst PRUNE_TOOL_DESCRIPTION = `把当前会话的旧对话前缀折叠为一个滚动检查点(保留系统级规则、压缩中部历史、详述进行中的任务),近期尾部不受影响。\n\n仅在这些情况下调用:\n- 对话话题发生明显变更:开始处理新的问题域、切换到另一个模块/仓库/任务;\n- 用户明确要求压缩上下文。\n\n同一任务内的多轮追问、参数微调、延续当前工作,都不要调用。调用不会打断当前工作:压缩会排队,并在下一个确认的静息边界(短暂静默窗口加实时状态检查)尝试执行;并发请求自动合并,失败不会破坏现有上下文。不要为同一话题反复调用。`\n\nexport interface PruneToolDeps {\n prune: PruneService\n logger: Logger\n}\n\nexport function createPruneTool(deps: PruneToolDeps) {\n return tool({\n description: PRUNE_TOOL_DESCRIPTION,\n args: {},\n execute: async (_args, context) => {\n const sessionID = context.sessionID\n const result = await deps.prune.request({ sessionID, onBusy: \"defer\" })\n\n if (result.status === \"succeeded\") {\n deps.logger.debug(\"Prune tool triggered native compaction\", {\n sessionId: sessionID,\n })\n return \"DCP:语义压缩完成,旧上下文已折叠为新检查点。\"\n }\n if (result.status === \"deferred\") {\n return \"DCP:会话仍在工作中,压缩已排队,将在下一个确认的静息边界尝试自动执行;当前上下文不受影响。\"\n }\n if (result.status === \"busy\") {\n return \"DCP:会话正忙,为避免打断当前工作,本次未执行压缩。\"\n }\n if (result.status === \"cooldown\") {\n return `DCP:上一次压缩失败,${retrySeconds(result.retryAfterMs)} 秒后才能重试。`\n }\n if (result.status === \"no-model\") {\n return \"DCP:会话中还没有可用的模型信息,无法执行压缩。\"\n }\n return `DCP:压缩失败(${result.error}),原始上下文保持不变。`\n },\n })\n}\n","import type { OpenCodeClient } from \"./opencode-client\"\n\nexport interface SessionModel {\n providerID: string\n modelID: string\n}\n\nexport function latestUserModel(messages: unknown): SessionModel | null {\n if (!Array.isArray(messages)) return null\n\n for (let index = messages.length - 1; index >= 0; index--) {\n const info = messages[index]?.info\n if (info?.role !== \"user\") continue\n const providerID = info.model?.providerID\n const modelID = info.model?.modelID\n if (typeof providerID === \"string\" && typeof modelID === \"string\") {\n return { providerID, modelID }\n }\n }\n return null\n}\n\nexport async function resolveSessionModel(\n client: OpenCodeClient,\n sessionID: string,\n): Promise<SessionModel | null> {\n try {\n const response = await client.session.messages({ path: { id: sessionID } })\n return latestUserModel(response.data ?? response)\n } catch {\n return null\n }\n}\n","import type { Logger } from \"./logger\"\nimport type { OpenCodeClient } from \"./opencode-client\"\nimport { resolveSessionModel } from \"./session-model\"\nimport {\n PROBE_TIMEOUT_MS,\n SessionBoundaryTracker,\n eventSessionID,\n retrySeconds,\n} from \"./session-boundary\"\nimport type { SummarizeCoordinator } from \"./summarize\"\n\nexport { eventSessionID, retrySeconds } from \"./session-boundary\"\n\n/**\n * How a trigger surface wants the service to react when the session is (or may\n * be) mid-turn:\n * - `\"defer\"`: compaction must never interrupt a running turn. Queue the prune\n * and execute it at the next confirmed at-rest boundary. Used by the\n * model-invokable tool, which by definition executes mid-turn.\n * - `\"proceed\"`: fire at turn boundaries anyway; only stand down on positive\n * busy evidence. Used by at-rest-driven auto prune and the manual command.\n */\nexport type PruneBusyPolicy = \"defer\" | \"proceed\"\n\nexport type PruneOutcome =\n | { status: \"succeeded\" }\n | { status: \"deferred\" }\n | { status: \"busy\" }\n | { status: \"no-model\" }\n | { status: \"cooldown\"; retryAfterMs: number }\n | { status: \"failed\"; error: string }\n\nexport interface PruneRequest {\n sessionID: string\n onBusy: PruneBusyPolicy\n}\n\nexport interface PruneServiceDeps {\n client: OpenCodeClient\n summarize: SummarizeCoordinator\n logger: Logger\n /** Injectable clock/timers (tests). BOUNDARY_QUIET_MS stays a code constant. */\n now?: () => number\n setTimer?: (fn: () => void, ms: number) => unknown\n clearTimer?: (t: unknown) => void\n /** Injectable probe deadline (tests only; defaults to PROBE_TIMEOUT_MS). */\n probeTimeoutMs?: number\n}\n\ntype Admission = { action: \"go\" } | { action: \"defer\" } | { action: \"stand-down\" }\n\n/** Host event names this service derives safety decisions from. */\nexport type PruneEventName =\n | \"session.idle\"\n | \"session.status\"\n | \"session.compacted\"\n | \"session.deleted\"\n | (string & {})\n\n/**\n * The single compression entry point. Every trigger surface (model tool,\n * heuristic auto prune, manual command) goes through `request`; the service\n * owns everything a caller must not have to know: session busy state, the\n * never-interrupt-a-running-turn invariant, deferral to the next confirmed\n * at-rest boundary, session model resolution, and delegation to the native\n * summarize coordinator (single-flight + failure cooldown).\n *\n * `request` never rejects: every failure mode is a `PruneOutcome`.\n */\nexport class PruneService {\n private readonly deferred = new Set<string>()\n private readonly client: OpenCodeClient\n private readonly summarize: SummarizeCoordinator\n private readonly logger: Logger\n private readonly probeTimeoutMs: number\n /** THE single busy/idle event state machine (absorbed the former\n * SessionActivityTracker — no second busy cache may exist). */\n readonly boundary: SessionBoundaryTracker\n\n constructor(deps: PruneServiceDeps) {\n this.client = deps.client\n this.summarize = deps.summarize\n this.logger = deps.logger\n this.probeTimeoutMs = deps.probeTimeoutMs ?? PROBE_TIMEOUT_MS\n this.boundary = new SessionBoundaryTracker({\n probeBusy: (sessionID) => this.probeBusy(sessionID),\n logger: deps.logger,\n now: deps.now,\n setTimer: deps.setTimer,\n clearTimer: deps.clearTimer,\n })\n // At-rest listener #1: drain deferred (tool) prunes at the confirmed\n // boundary. Registration order matters — the drain runs before the\n // heuristic auto-prune listener the plugin entry registers.\n this.boundary.onAtRest((sessionID) => {\n if (!this.deferred.delete(sessionID)) return\n void this.drainQueued(sessionID)\n })\n }\n\n /**\n * Feed every host event through here. `session.status` and legacy\n * `session.idle` feed the boundary tracker (quiet window + expiry probe);\n * the deferral queue drains at the confirmed at-rest classification, and\n * queued prunes are forgotten once a compaction (or the session itself)\n * is gone.\n */\n observeEvent(type: PruneEventName, properties?: Record<string, any>): void {\n const sessionID = eventSessionID(properties)\n if (type === \"session.status\") {\n this.boundary.observeStatus(sessionID, properties?.status?.type)\n return\n }\n if (type === \"session.idle\") {\n // Legacy first-class input: dual-published legs are absorbed by\n // the dedup; on status-less hosts it is the only boundary signal.\n this.boundary.observeLegacyIdle(sessionID)\n return\n }\n if (!sessionID) return\n if (type === \"session.compacted\") {\n this.deferred.delete(sessionID)\n this.boundary.observeCompacted(sessionID)\n return\n }\n if (type === \"session.deleted\") {\n this.deferred.delete(sessionID)\n this.boundary.observeDeleted(sessionID)\n }\n }\n\n async request(request: PruneRequest): Promise<PruneOutcome> {\n const beforeModel = await this.gate(request)\n if (beforeModel) return beforeModel\n\n const model = await resolveSessionModel(this.client, request.sessionID)\n if (!model) return { status: \"no-model\" }\n\n // Session activity may have flipped while the model was being\n // resolved; re-evaluate so a turn that just started is never\n // interrupted.\n const afterModel = await this.gate(request)\n if (afterModel) return afterModel\n\n // Last line of defense: ask the host for its live session status right\n // before the native call. Event-derived state can lag; this shrinks the\n // race window between \"we saw rest\" and \"the host mutates the session\"\n // to a single back-to-back HTTP hop. Fail open when the host does not\n // expose the status endpoint.\n const serverBusy = await this.probeBusy(request.sessionID)\n if (serverBusy === true) {\n const fallback = await this.outcomeFor(request, { action: \"stand-down\" })\n if (fallback) return fallback\n }\n\n const result = await this.summarize.summarize({ sessionID: request.sessionID, model })\n // A host that guards its summarize endpoint rejects the collision\n // instead of silently corrupting the run; the coordinator surfaces\n // that without arming the failure cooldown, and it is a `busy` prune\n // outcome, not a failure.\n if (result.status === \"rejected\") {\n return { status: \"busy\" }\n }\n return result\n }\n\n /** One admission check; `null` means the request may proceed. */\n private gate(request: PruneRequest): Promise<PruneOutcome | null> {\n return this.outcomeFor(request, this.admit(request))\n }\n\n /**\n * Executes a queued prune at the confirmed at-rest boundary. The tool\n * already promised its caller this prune would run; losing the busy race\n * must not silently break that promise, so a busy outcome re-queues for\n * the next at-rest boundary. Every other outcome is terminal: it is\n * logged and never retried — new prune demand arrives through new\n * triggers only. Execution is re-guarded on every attempt, so re-queueing\n * never violates the never-interrupt invariant.\n */\n private async drainQueued(sessionID: string): Promise<void> {\n let outcome: PruneOutcome\n try {\n outcome = await this.request({ sessionID, onBusy: \"proceed\" })\n } catch (error) {\n this.logger.warn(\"Queued prune drain failed; the prune was not retried\", {\n sessionId: sessionID,\n error: error instanceof Error ? error.message : String(error),\n })\n return\n }\n if (outcome.status === \"busy\") {\n this.deferred.add(sessionID)\n return\n }\n this.logger.debug(\"Queued prune drain finished\", {\n sessionId: sessionID,\n status: outcome.status,\n })\n }\n\n /**\n * Turns an admission decision into a terminal outcome, or `null` when the\n * request may proceed. Deferral additionally enqueues the session.\n */\n private async outcomeFor(\n request: PruneRequest,\n admission: Admission,\n ): Promise<PruneOutcome | null> {\n if (admission.action === \"go\") return null\n if (admission.action === \"stand-down\") return { status: \"busy\" }\n this.deferred.add(request.sessionID)\n this.logger.debug(\"Prune deferred to the next session at-rest boundary\", {\n sessionId: request.sessionID,\n })\n return { status: \"deferred\" }\n }\n\n private admit(request: PruneRequest): Admission {\n // `defer` is unconditional: the tool executes inside a running turn by\n // construction, so event-derived \"idle\" is stale by definition and the\n // call must queue for the next turn boundary. Only the event feed can\n // drain it, which is why the event hook stays on whenever the tool is.\n if (request.onBusy === \"defer\") return { action: \"defer\" }\n if (this.boundary.state(request.sessionID) === \"busy\") return { action: \"stand-down\" }\n return { action: \"go\" }\n }\n\n /**\n * THE single live busy probe, reused verbatim by the boundary tracker's\n * expiry check. Bounded by a finite deadline: a never-returning probe\n * resolves `null` within the timeout (fail-open). Returns `null` when the\n * answer is unknown (endpoint or SDK method missing, request failed,\n * timeout) — callers must fail open in that case.\n */\n async probeBusy(sessionID: string): Promise<boolean | null> {\n const statusFn = (this.client.session as unknown as Record<string, unknown>).status\n if (typeof statusFn !== \"function\") return null\n const query = (async () => {\n try {\n return await (statusFn as (input?: unknown) => Promise<unknown>).call(\n this.client.session,\n )\n } catch {\n return null\n }\n })()\n const response = await Promise.race([\n query,\n new Promise<null>((resolve) => setTimeout(() => resolve(null), this.probeTimeoutMs)),\n ])\n const map = (response as { data?: unknown })?.data ?? response\n const info = (map as Record<string, { type?: unknown }>)?.[sessionID]\n // `retry` is an active turn between attempts — never compact it.\n return info?.type === \"busy\" || info?.type === \"retry\"\n }\n}\n","import type { Logger } from \"./logger\"\nimport type { OpenCodeClient } from \"./opencode-client\"\n\nexport interface SummarizeRequest {\n sessionID: string\n model: {\n providerID: string\n modelID: string\n }\n}\n\nexport type SummarizeResult =\n | { status: \"succeeded\" }\n | { status: \"rejected\"; reason: \"busy\" }\n | { status: \"failed\"; error: string }\n | { status: \"cooldown\"; retryAfterMs: number }\n\ninterface SummarizeCoordinatorOptions {\n failureCooldownMs: number\n now?: () => number\n}\n\ninterface NativeResponse {\n data?: unknown\n error?: unknown\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n if (typeof error === \"string\") return error\n try {\n return JSON.stringify(error)\n } catch {\n return \"Unknown native compaction error\"\n }\n}\n\n/**\n * Recognizes the host's \"session is busy\" rejection. Such a rejection is not\n * a compaction failure: nothing went wrong, so it must not arm the failure\n * cooldown. Detection is deliberately defensive — a word-bounded \"busy\" in\n * the message, a structured 409 status/code, or a Busy* error name — because\n * hosts differ in how they surface it.\n */\nfunction isBusyRejection(error: unknown): boolean {\n if (error instanceof Error && /\\bbusy\\b/i.test(error.message)) return true\n if (typeof error === \"string\" && /\\bbusy\\b/i.test(error)) return true\n const structured = error as {\n status?: unknown\n statusCode?: unknown\n code?: unknown\n name?: unknown\n } | null\n if (!structured || typeof structured !== \"object\") return false\n if (structured.status === 409 || structured.statusCode === 409 || structured.code === 409) {\n return true\n }\n return typeof structured.name === \"string\" && /busy/i.test(structured.name)\n}\n\nexport class SummarizeCoordinator {\n private readonly inFlight = new Map<string, Promise<SummarizeResult>>()\n private readonly failedAt = new Map<string, number>()\n private readonly now: () => number\n\n constructor(\n private readonly client: OpenCodeClient,\n private readonly logger: Logger,\n private readonly options: SummarizeCoordinatorOptions,\n ) {\n this.now = options.now ?? Date.now\n }\n\n summarize(request: SummarizeRequest): Promise<SummarizeResult> {\n const active = this.inFlight.get(request.sessionID)\n if (active) return active\n\n const failedAt = this.failedAt.get(request.sessionID)\n if (failedAt !== undefined) {\n const retryAfterMs = this.options.failureCooldownMs - (this.now() - failedAt)\n if (retryAfterMs > 0) {\n return Promise.resolve({ status: \"cooldown\", retryAfterMs })\n }\n this.failedAt.delete(request.sessionID)\n }\n\n const promise = this.invokeNative(request).finally(() => {\n if (this.inFlight.get(request.sessionID) === promise) {\n this.inFlight.delete(request.sessionID)\n }\n })\n this.inFlight.set(request.sessionID, promise)\n return promise\n }\n\n private async invokeNative(request: SummarizeRequest): Promise<SummarizeResult> {\n try {\n const response = (await this.client.session.summarize({\n path: { id: request.sessionID },\n body: request.model,\n })) as NativeResponse\n // Judge the raw structured error before wrapping it: a busy\n // rejection must surface as `rejected`, not as an arming failure.\n const nativeError = response?.error\n if (nativeError && isBusyRejection(nativeError)) {\n return { status: \"rejected\", reason: \"busy\" }\n }\n if (nativeError || response?.data !== true) {\n throw new Error(errorMessage(nativeError ?? \"Native summarize returned false\"))\n }\n this.failedAt.delete(request.sessionID)\n return { status: \"succeeded\" }\n } catch (error) {\n if (isBusyRejection(error)) {\n return { status: \"rejected\", reason: \"busy\" }\n }\n this.failedAt.set(request.sessionID, this.now())\n const message = errorMessage(error)\n await this.logger.warn(\"Native summarize failed; context remains unchanged\", {\n sessionId: request.sessionID,\n error: message,\n })\n return { status: \"failed\", error: message }\n }\n }\n}\n","import { readFile } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { available: true; name: string; current: string; latest: string }\n | { available: false }\n\nconst PACKAGE_NAME = \"@lexwdex-org/opencode-dcp\"\n\nexport function startAutoUpdate(ctx: PluginInput, enabled: boolean): void {\n if (!enabled) return\n\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 10_000)\n void checkAutoUpdate(controller.signal)\n .then((result) => {\n if (!result.available) return\n setTimeout(() => {\n void ctx.client.tui\n .showToast({\n body: {\n title: \"DCP update available\",\n message: `${result.name} ${result.latest} is available (current ${result.current}). Reinstall the plugin to update.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n .catch(() => {})\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { available: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { available: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { available: false }\n\n const wrapperDir = await findAutoUpdateWrapperDir(packageDir, pkg.name)\n if (!wrapperDir) return { available: false }\n\n return { available: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function findAutoUpdateWrapperDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nfunction wrapperSpec(wrapperDir: string, name: string) {\n if (name.startsWith(\"@\")) {\n const [scope, pkg] = name.split(\"/\")\n if (!scope || !pkg || basename(dirname(wrapperDir)) !== scope) return undefined\n const prefix = `${pkg}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n }\n\n const prefix = `${name}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { AutoPruner } from \"./lib/auto-prune\"\nimport { getConfig } from \"./lib/config\"\nimport {\n createAtRestAutoPruneListener,\n createChatMessageHandler,\n createCommandExecuteHandler,\n createEventHandler,\n createSessionCompactingHandler,\n} from \"./lib/hooks\"\nimport { Logger } from \"./lib/logger\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport { PRUNE_TOOL_NAME, createPruneTool } from \"./lib/prune-tool\"\nimport { PruneService } from \"./lib/prune-service\"\nimport { SummarizeCoordinator } from \"./lib/summarize\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n if (!config.enabled) return {}\n\n const logger = new Logger(config.debug)\n const prompts = new PromptStore(\n logger,\n ctx.directory,\n config.experimental.customPrompts,\n config.language,\n )\n const summarize = new SummarizeCoordinator(ctx.client, logger, {\n failureCooldownMs: config.summarize.failureCooldownMs,\n })\n const prune = new PruneService({ client: ctx.client, summarize, logger })\n const autoPruner = new AutoPruner(config.autoPrune)\n // At-rest listener #2 (heuristic auto prune) is mounted only when auto\n // prune is enabled; the service's deferred drain is always listener #1.\n if (config.autoPrune.enabled) {\n prune.boundary.onAtRest(\n createAtRestAutoPruneListener({\n client: ctx.client,\n prune,\n autoPruner,\n config: config.autoPrune,\n logger,\n }),\n )\n }\n\n logger.info(\"DCP initialized\", {\n commands: config.commands.enabled,\n autoPrune: config.autoPrune.enabled,\n tool: config.tool.enabled,\n customPrompts: config.experimental.customPrompts,\n })\n startAutoUpdate(ctx, config.autoUpdate)\n\n return {\n \"experimental.session.compacting\": createSessionCompactingHandler(prompts, logger),\n ...(config.autoPrune.enabled && {\n \"chat.message\": createChatMessageHandler(autoPruner),\n }),\n // The event feed drives both the boundary classification (status/idle\n // observations) and the tool's deferred prunes, so it stays registered\n // whenever either surface is on.\n ...((config.autoPrune.enabled || config.tool.enabled) && {\n event: createEventHandler({\n prune,\n autoPruner,\n logger,\n }),\n }),\n ...(config.tool.enabled && {\n tool: { [PRUNE_TOOL_NAME]: createPruneTool({ prune, logger }) },\n }),\n ...(config.commands.enabled && {\n \"command.execute.before\": createCommandExecuteHandler(ctx.client, prune, logger),\n config: async (opencodeConfig) => {\n opencodeConfig.command ??= {}\n opencodeConfig.command.dcp = {\n template: \"\",\n description: \"Run semantic context pruning with native compaction\",\n }\n },\n }),\n }\n}) satisfies Plugin\n\nexport default server\n"],"mappings":"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A,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,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","names":["value","CharacterCodes","ParseOptions","ScanError","SyntaxKind","parse","ParseErrorCode","tool","parse","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","statSync","writeFileSync","homedir","dirname","join","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","dirname","join","prefix","base"]}
1
+ {"version":3,"sources":["../lib/config.ts","../node_modules/jsonc-parser/lib/esm/impl/scanner.js","../node_modules/jsonc-parser/lib/esm/impl/string-intern.js","../node_modules/jsonc-parser/lib/esm/impl/parser.js","../node_modules/jsonc-parser/lib/esm/main.js","../lib/text.ts","../lib/dtc/digest.ts","../lib/dtc/engine.ts","../lib/dtc/state.ts","../lib/session-events.ts","../lib/hooks.ts","../lib/logger.ts","../lib/prompts/store.ts","../lib/prompts/compaction.ts","../lib/prune-tool.ts","../lib/update.ts","../index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from \"fs\"\nimport { join, dirname } from \"path\"\nimport { homedir } from \"os\"\nimport * as jsoncParser from \"jsonc-parser\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\nimport { DTC_DEFAULTS, type DtcConfig } from \"./dtc/engine\"\n\nexport interface Commands {\n enabled: boolean\n}\n\nexport interface ExperimentalConfig {\n customPrompts: boolean\n}\n\n/** DTC engine knobs plus the master switch for request-time compression. */\nexport interface DtcPluginConfig extends DtcConfig {\n enabled: boolean\n}\n\nexport interface ToolConfig {\n enabled: boolean\n}\n\nexport type DcpLanguage = \"zh\" | \"en\"\n\nexport interface PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n language: DcpLanguage\n commands: Commands\n experimental: ExperimentalConfig\n dtc: DtcPluginConfig\n tool: ToolConfig\n}\n\nexport const DEFAULT_DTC: DtcPluginConfig = {\n enabled: true,\n ...DTC_DEFAULTS,\n}\n\nexport const VALID_CONFIG_KEYS = new Set([\n \"$schema\",\n \"enabled\",\n \"autoUpdate\",\n \"debug\",\n \"language\",\n \"commands\",\n \"commands.enabled\",\n \"experimental\",\n \"experimental.customPrompts\",\n \"dtc\",\n \"dtc.enabled\",\n \"dtc.tailTurns\",\n \"dtc.lowWatermarkRatio\",\n \"dtc.targetRatio\",\n \"dtc.driftThreshold\",\n \"dtc.toolOutputKeepChars\",\n \"tool\",\n \"tool.enabled\",\n])\n\n// Keys that only existed in earlier plugin-owned compression architectures.\n// They are recognized so users get a migration hint instead of an \"unknown\n// key\" warning; their values are dropped. autoPrune.* is superseded by the\n// always-on request-time DTC engine; driftThreshold migrates to dtc.*.\nexport const DEPRECATED_CONFIG_KEYS = new Set([\n \"compress\",\n \"compress.mode\",\n \"compress.permission\",\n \"compress.showCompression\",\n \"compress.summaryBuffer\",\n \"compress.maxContextLimit\",\n \"compress.minContextLimit\",\n \"compress.boundaryNudge\",\n \"compress.modelMaxLimits\",\n \"compress.modelMinLimits\",\n \"compress.nudgeFrequency\",\n \"compress.iterationNudgeThreshold\",\n \"compress.nudgeForce\",\n \"compress.protectedTools\",\n \"compress.protectTags\",\n \"compress.protectUserMessages\",\n \"compress.externalModel\",\n \"compress.externalModel.url\",\n \"compress.externalModel.model\",\n \"compress.externalModel.apiKey\",\n \"compress.externalModel.timeout\",\n \"compress.externalModel.retries\",\n \"manualMode\",\n \"manualMode.enabled\",\n \"manualMode.automaticStrategies\",\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 \"turnProtection\",\n \"turnProtection.enabled\",\n \"turnProtection.turns\",\n \"pruneNotification\",\n \"pruneNotificationType\",\n \"protectedFilePatterns\",\n \"commands.protectedTools\",\n \"experimental.allowSubAgents\",\n \"summarize\",\n \"summarize.failureCooldownMs\",\n \"autoPrune\",\n \"autoPrune.enabled\",\n \"autoPrune.signals\",\n \"autoPrune.signals.topicDrift\",\n \"autoPrune.signals.volume\",\n \"autoPrune.signals.idleGap\",\n \"autoPrune.autoContinue\",\n \"autoPrune.minMessages\",\n \"autoPrune.volumeThreshold\",\n \"autoPrune.driftThreshold\",\n \"autoPrune.idleGapMs\",\n \"autoPrune.cooldownMs\",\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 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 getDeprecatedConfigKeys(userConfig: Record<string, any>): string[] {\n return getConfigKeyPaths(userConfig).filter((key) => DEPRECATED_CONFIG_KEYS.has(key))\n}\n\nexport function getInvalidConfigKeys(userConfig: Record<string, any>): string[] {\n return getConfigKeyPaths(userConfig).filter(\n (key) => !VALID_CONFIG_KEYS.has(key) && !DEPRECATED_CONFIG_KEYS.has(key),\n )\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.language !== undefined && config.language !== \"zh\" && config.language !== \"en\") {\n errors.push({\n key: \"language\",\n expected: '\"zh\" or \"en\"',\n actual: JSON.stringify(config.language),\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({ key: \"commands\", expected: \"object\", actual: typeof commands })\n } else 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 }\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({ key: \"experimental\", expected: \"object\", actual: typeof experimental })\n } else 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 const dtc = config.dtc\n if (dtc !== undefined) {\n if (typeof dtc !== \"object\" || dtc === null || Array.isArray(dtc)) {\n errors.push({ key: \"dtc\", expected: \"object\", actual: typeof dtc })\n } else {\n if (dtc.enabled !== undefined && typeof dtc.enabled !== \"boolean\") {\n errors.push({ key: \"dtc.enabled\", expected: \"boolean\", actual: typeof dtc.enabled })\n }\n const numericKeys: Array<[string, number, number]> = [\n [\"tailTurns\", 0, Number.POSITIVE_INFINITY],\n [\"lowWatermarkRatio\", 0, 1],\n [\"targetRatio\", 0, 1],\n [\"driftThreshold\", 0, 1],\n [\"toolOutputKeepChars\", 200, Number.POSITIVE_INFINITY],\n ]\n for (const [key, min, max] of numericKeys) {\n const value = (dtc as Record<string, any>)[key]\n if (\n value !== undefined &&\n (typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n value < min ||\n value > max)\n ) {\n errors.push({\n key: `dtc.${key}`,\n expected: `number in [${min}, ${max === Number.POSITIVE_INFINITY ? \"∞\" : max}]`,\n actual: JSON.stringify(value),\n })\n }\n }\n }\n }\n\n const tool = config.tool\n if (tool !== undefined) {\n if (typeof tool !== \"object\" || tool === null || Array.isArray(tool)) {\n errors.push({ key: \"tool\", expected: \"object\", actual: typeof tool })\n } else if (tool.enabled !== undefined && typeof tool.enabled !== \"boolean\") {\n errors.push({ key: \"tool.enabled\", expected: \"boolean\", actual: typeof tool.enabled })\n }\n }\n\n return errors\n}\n\n/** Legacy autoPrune.driftThreshold migrates to dtc.driftThreshold. */\nexport function legacyDriftThreshold(configData: Record<string, any>): number | undefined {\n const autoPrune = configData.autoPrune\n if (autoPrune === null || typeof autoPrune !== \"object\" || Array.isArray(autoPrune)) {\n return undefined\n }\n const value = (autoPrune as Record<string, any>).driftThreshold\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 1\n ? value\n : undefined\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 deprecatedKeys = getDeprecatedConfigKeys(configData)\n const typeErrors = validateConfigTypes(configData)\n\n if (invalidKeys.length === 0 && deprecatedKeys.length === 0 && typeErrors.length === 0) {\n return\n }\n\n const configType = isProject ? \"project config\" : \"config\"\n const messages: string[] = []\n\n if (deprecatedKeys.length > 0) {\n const keyList = deprecatedKeys.slice(0, 3).join(\", \")\n const suffix = deprecatedKeys.length > 3 ? ` (+${deprecatedKeys.length - 3} more)` : \"\"\n messages.push(\n `Removed legacy keys are ignored: ${keyList}${suffix}. Compression now runs as dynamic request-time folding (dtc.*).`,\n )\n }\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 language: \"zh\",\n commands: {\n enabled: true,\n },\n experimental: {\n customPrompts: false,\n },\n dtc: { ...DEFAULT_DTC },\n tool: {\n enabled: true,\n },\n}\n\nconst GLOBAL_CONFIG_DIR = process.env.XDG_CONFIG_HOME\n ? join(process.env.XDG_CONFIG_HOME, \"opencode\")\n : join(homedir(), \".config\", \"opencode\")\nconst GLOBAL_CONFIG_PATH_JSONC = join(GLOBAL_CONFIG_DIR, \"dcp.jsonc\")\nconst GLOBAL_CONFIG_PATH_JSON = join(GLOBAL_CONFIG_DIR, \"dcp.json\")\n\nfunction findOpencodeDir(startDir: string): string | null {\n let current = startDir\n while (current !== \"/\") {\n const candidate = join(current, \".opencode\")\n if (existsSync(candidate) && statSync(candidate).isDirectory()) {\n return candidate\n }\n const parent = dirname(current)\n if (parent === current) {\n break\n }\n current = parent\n }\n return null\n}\n\nfunction getConfigPaths(ctx?: PluginInput): {\n global: string | null\n configDir: string | null\n project: string | null\n} {\n const global = existsSync(GLOBAL_CONFIG_PATH_JSONC)\n ? GLOBAL_CONFIG_PATH_JSONC\n : existsSync(GLOBAL_CONFIG_PATH_JSON)\n ? GLOBAL_CONFIG_PATH_JSON\n : null\n\n let configDir: string | null = null\n const opencodeConfigDir = process.env.OPENCODE_CONFIG_DIR\n if (opencodeConfigDir) {\n const configJsonc = join(opencodeConfigDir, \"dcp.jsonc\")\n const configJson = join(opencodeConfigDir, \"dcp.json\")\n configDir = existsSync(configJsonc)\n ? configJsonc\n : existsSync(configJson)\n ? configJson\n : null\n }\n\n let project: string | null = null\n if (ctx?.directory) {\n const opencodeDir = findOpencodeDir(ctx.directory)\n if (opencodeDir) {\n const projectJsonc = join(opencodeDir, \"dcp.jsonc\")\n const projectJson = join(opencodeDir, \"dcp.json\")\n project = existsSync(projectJsonc)\n ? projectJsonc\n : existsSync(projectJson)\n ? projectJson\n : null\n }\n }\n\n return { global, configDir, project }\n}\n\nfunction createDefaultConfig(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true })\n }\n\n const configContent = `{\n \"$schema\": \"https://raw.githubusercontent.com/LeXwDeX/opencode-dynamic-context-pruning/master/dcp.schema.json\"\n}\n`\n writeFileSync(GLOBAL_CONFIG_PATH_JSONC, configContent, \"utf-8\")\n}\n\ninterface ConfigLoadResult {\n data: Record<string, any> | null\n parseError?: string\n}\n\nfunction loadConfigFile(configPath: string): ConfigLoadResult {\n let fileContent = \"\"\n try {\n fileContent = readFileSync(configPath, \"utf-8\")\n } catch {\n return { data: null }\n }\n\n try {\n const parsed = jsoncParser.parse(fileContent, undefined, { allowTrailingComma: true })\n if (parsed === undefined || parsed === null) {\n return { data: null, parseError: \"Config file is empty or invalid\" }\n }\n return { data: parsed }\n } catch (error: any) {\n return { data: null, parseError: error.message || \"Failed to parse config\" }\n }\n}\n\nfunction 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: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n }\n}\n\nfunction mergeExperimental(\n base: PluginConfig[\"experimental\"],\n override?: Partial<PluginConfig[\"experimental\"]>,\n): PluginConfig[\"experimental\"] {\n if (!override) {\n return base\n }\n\n return {\n customPrompts:\n typeof override.customPrompts === \"boolean\"\n ? override.customPrompts\n : base.customPrompts,\n }\n}\n\nfunction mergeDtc(\n base: DtcPluginConfig,\n override?: Record<string, any>,\n legacyDrift?: number,\n): DtcPluginConfig {\n const driftFallback = legacyDrift ?? base.driftThreshold\n if (!override || typeof override !== \"object\" || Array.isArray(override)) {\n return { ...base, driftThreshold: driftFallback }\n }\n\n const number = (key: keyof DtcConfig, min: number, max: number): number =>\n typeof override[key] === \"number\" &&\n Number.isFinite(override[key]) &&\n override[key] >= min &&\n override[key] <= max\n ? override[key]\n : (base[key] as number)\n\n return {\n enabled: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n tailTurns: number(\"tailTurns\", 0, Number.POSITIVE_INFINITY),\n lowWatermarkRatio: number(\"lowWatermarkRatio\", 0, 1),\n targetRatio: number(\"targetRatio\", 0, 1),\n driftThreshold:\n typeof override.driftThreshold === \"number\" &&\n Number.isFinite(override.driftThreshold) &&\n override.driftThreshold >= 0 &&\n override.driftThreshold <= 1\n ? override.driftThreshold\n : driftFallback,\n toolOutputKeepChars: number(\"toolOutputKeepChars\", 200, Number.POSITIVE_INFINITY),\n }\n}\n\nfunction mergeTool(base: ToolConfig, override?: Partial<ToolConfig>): ToolConfig {\n if (!override) {\n return base\n }\n\n return {\n enabled: typeof override.enabled === \"boolean\" ? override.enabled : base.enabled,\n }\n}\n\nfunction deepCloneConfig(config: PluginConfig): PluginConfig {\n return {\n ...config,\n commands: { ...config.commands },\n experimental: { ...config.experimental },\n dtc: { ...config.dtc },\n tool: { ...config.tool },\n }\n}\n\nfunction mergeLayer(config: PluginConfig, data: Record<string, any>): PluginConfig {\n return {\n enabled: typeof data.enabled === \"boolean\" ? data.enabled : config.enabled,\n autoUpdate: typeof data.autoUpdate === \"boolean\" ? data.autoUpdate : config.autoUpdate,\n debug: typeof data.debug === \"boolean\" ? data.debug : config.debug,\n language:\n data.language === \"zh\" || data.language === \"en\" ? data.language : config.language,\n commands: mergeCommands(config.commands, data.commands),\n experimental: mergeExperimental(config.experimental, data.experimental),\n dtc: mergeDtc(config.dtc, data.dtc, legacyDriftThreshold(data)),\n tool: mergeTool(config.tool, data.tool),\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","/**\n * Shared text utilities for the dynamic tiered compression engine and the\n * topic-boundary scanner. Pure functions only — everything here must stay\n * deterministic so folded output and digests are stable across requests.\n */\n\nexport function tokenize(text: string): Set<string> {\n const tokens = new Set<string>()\n for (const match of text.toLowerCase().matchAll(/[\\p{L}\\p{N}]+/gu)) {\n const word = match[0]\n if (/[\\u4e00-\\u9fff]/.test(word)) {\n if (word.length === 1) {\n tokens.add(word)\n continue\n }\n for (let index = 0; index < word.length - 1; index++) {\n tokens.add(word.slice(index, index + 2))\n }\n } else {\n tokens.add(word)\n }\n }\n return tokens\n}\n\nexport function jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 1\n let intersection = 0\n for (const token of a) {\n if (b.has(token)) intersection++\n }\n return intersection / (a.size + b.size - intersection)\n}\n\n/**\n * Cheap deterministic token estimate: CJK characters count ~0.7 tokens each,\n * everything else ~0.25 (the standard chars/4 approximation). Precise enough\n * for budget decisions — the escalation loop re-measures after every level.\n */\nexport function estimateTokens(text: string): number {\n let cjk = 0\n let other = 0\n for (let index = 0; index < text.length; index++) {\n const code = text.charCodeAt(index)\n if (code >= 0x4e00 && code <= 0x9fff) cjk++\n else other++\n }\n return Math.ceil(cjk * 0.7 + other / 4)\n}\n\n/** djb2 string hash — stable digest cache keys without storing content. */\nexport function hashString(text: string): string {\n let hash = 5381\n for (let index = 0; index < text.length; index++) {\n hash = ((hash << 5) + hash + text.charCodeAt(index)) | 0\n }\n return (hash >>> 0).toString(36)\n}\n\nexport function firstLine(text: string, maxChars: number): string {\n const line = text.split(\"\\n\", 1)[0]?.trim() ?? \"\"\n return line.length > maxChars ? `${line.slice(0, maxChars)}…` : line\n}\n\nexport function truncateMiddle(text: string, keepChars: number, note: string): string {\n if (text.length <= keepChars) return text\n const head = Math.ceil(keepChars / 2)\n const tail = Math.floor(keepChars / 2)\n return `${text.slice(0, head)}\\n${note}\\n${text.slice(text.length - tail)}`\n}\n\nexport function extractTextParts(parts: unknown[]): string {\n const texts: string[] = []\n for (const part of parts) {\n if (\n part &&\n typeof part === \"object\" &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n texts.push((part as { text: string }).text)\n }\n }\n return texts.join(\" \").trim()\n}\n","import { estimateTokens, firstLine, hashString, tokenize, jaccard } from \"../text\"\nimport type { MessageLike, PartLike, Turn } from \"./types\"\n\n/**\n * Mechanical turn digests for the distant zone. Deterministic string\n * extraction — no model calls, no persisted state — so the same turn always\n * folds to the same line and the result is safe to cache in memory.\n */\n\nconst INTENT_MAX = 120\nconst RESULT_MAX = 160\nconst MAX_TOOLS = 8\nconst MAX_FILES = 6\nconst DIGEST_MAX_CHARS = 600\n\nconst PATH_KEYS = [\"filePath\", \"path\", \"file\", \"filename\", \"pattern\", \"directory\"]\n\nfunction toolSummary(parts: PartLike[]): { actions: string; files: string; errors: number } {\n const counts = new Map<string, number>()\n const files: string[] = []\n let errors = 0\n for (const part of parts) {\n if (!part || typeof part !== \"object\" || part.type !== \"tool\") continue\n const name = part.tool ?? \"tool\"\n counts.set(name, (counts.get(name) ?? 0) + 1)\n if (part.state?.status === \"error\") errors++\n const input = part.state?.input\n if (input && typeof input === \"object\") {\n for (const key of PATH_KEYS) {\n const value = (input as Record<string, unknown>)[key]\n if (typeof value === \"string\" && value && !files.includes(value)) {\n files.push(value)\n }\n }\n const command = (input as Record<string, unknown>).command\n if (typeof command === \"string\" && command && !files.includes(firstLine(command, 60))) {\n files.push(firstLine(command, 60))\n }\n }\n }\n const actions = [...counts.entries()]\n .map(([name, count]) => (count > 1 ? `${name}×${count}` : name))\n .slice(0, MAX_TOOLS)\n .join(\", \")\n return { actions, files: files.slice(0, MAX_FILES).join(\" \"), errors }\n}\n\n/** Builds the one-block digest that replaces a distant turn's content. */\nexport function digestTurn(messages: MessageLike[], turn: Turn, index: number): string {\n const slice = messages.slice(turn.start, turn.end)\n const user = slice[0]\n const intent = firstLine(userText(user), INTENT_MAX) || \"(无文本)\"\n const { actions, files, errors } = toolSummary(\n slice.flatMap((m) => (m && typeof m === \"object\" ? (m.parts ?? []) : [])),\n )\n let result = \"\"\n for (let i = slice.length - 1; i >= 0; i--) {\n if (slice[i]?.info?.role !== \"assistant\") continue\n const text = assistantText(slice[i])\n if (text) {\n result = firstLine(text, RESULT_MAX)\n break\n }\n }\n const parts = [`[DCP·轮${index}]`, `意图: ${intent}`]\n if (actions) parts.push(`动作: ${actions}`)\n if (files) parts.push(`涉及: ${files}`)\n if (result) parts.push(`结果: ${result}`)\n if (errors > 0) parts.push(`错误×${errors}`)\n const digest = parts.join(\" | \")\n return digest.length > DIGEST_MAX_CHARS ? `${digest.slice(0, DIGEST_MAX_CHARS)}…` : digest\n}\n\nfunction userText(message: MessageLike | undefined): string {\n const parts = message?.parts ?? []\n const texts = parts\n .filter((p) => p?.type === \"text\" && typeof p.text === \"string\")\n .map((p) => p.text as string)\n return texts.join(\" \").trim()\n}\n\nfunction assistantText(message: MessageLike | undefined): string {\n return userText(message)\n}\n\n/** Stable cache key: identity of the opening message + shape of the content. */\nexport function digestKey(messages: MessageLike[], turn: Turn): string {\n const first = messages[turn.start]\n const id = first?.info?.id ?? \"noid\"\n let shape = \"\"\n for (let i = turn.start; i < turn.end && i < messages.length; i++) {\n const message = messages[i]\n shape += `${message?.info?.role ?? \"?\"}:${(message?.parts ?? []).length};`\n for (const part of message?.parts ?? []) {\n if (!part || typeof part !== \"object\") continue\n if (part.type === \"text\" && typeof part.text === \"string\") {\n shape += part.text.slice(0, 64)\n } else if (part.type === \"tool\") {\n shape += `${part.tool ?? \"tool\"}:${part.state?.status ?? \"?\"}:${(part.state?.output ?? \"\").length}`\n }\n }\n }\n return `${id}:${hashString(shape)}`\n}\n\n/**\n * Stateless topic-boundary scanner over the head region: a boundary is a\n * substantial user message whose similarity to its predecessor drops below\n * the drift threshold. Returns turn positions (indices into `turns`).\n */\nexport function findTopicBoundaries(\n messages: MessageLike[],\n turns: Turn[],\n driftThreshold: number,\n): number[] {\n const boundaries: number[] = []\n let previous: Set<string> | undefined\n for (let t = 0; t < turns.length; t++) {\n const text = userText(messages[turns[t]!.start])\n const tokens = tokenize(text)\n // Short messages (\"继续\", \"ok\") share almost no tokens with anything\n // and would fake a topic change; only substantial texts count.\n if (tokens.size < 6) continue\n if (previous && jaccard(tokens, previous) < driftThreshold) boundaries.push(t)\n previous = tokens\n }\n return boundaries\n}\n\n/** Token estimate of a message slice, summing every string payload. Parts\n * folded with the host's compacted marker count as the short placeholder the\n * host serializer will actually emit, not the stored output. */\nexport function estimateSlice(messages: MessageLike[], start: number, end: number): number {\n let tokens = 0\n for (let i = start; i < end && i < messages.length; i++) {\n for (const part of messages[i]?.parts ?? []) {\n if (!part || typeof part !== \"object\") continue\n if (typeof part.text === \"string\") tokens += estimateTokens(part.text)\n const state = part.state\n if (!state) continue\n if (state.time?.compacted) {\n tokens += 8\n continue\n }\n if (typeof state.output === \"string\") tokens += estimateTokens(state.output)\n if (state.input) tokens += estimateTokens(JSON.stringify(state.input))\n }\n }\n return tokens\n}\n","import type { Logger } from \"../logger\"\nimport { firstLine, truncateMiddle } from \"../text\"\nimport { digestKey, digestTurn, estimateSlice, findTopicBoundaries } from \"./digest\"\nimport type { DtcState } from \"./state\"\nimport type { MessageLike, PartLike, Turn } from \"./types\"\n\n/**\n * The dynamic tiered compression engine. Runs inside the host's\n * `experimental.chat.messages.transform` hook on every model request and\n * rewrites ONLY string payloads of the request-scoped message copies:\n *\n * - messages and parts are never added, removed, or reordered\n * - part IDs, tool-call pairing, and roles are never touched\n * - distant tool outputs are folded with the host's own `time.compacted`\n * marker, so the wire rendering is the host's native one\n *\n * Nothing here writes to the session; the host rebuilds this array from\n * storage on every request, so all mutations are inherently request-scoped.\n */\n\nexport interface DtcConfig {\n /** Turns kept completely verbatim at the end (never folded). */\n tailTurns: number\n /** Below this fraction of the context window, no folding happens at all. */\n lowWatermarkRatio: number\n /** Folding escalates until the estimate fits this fraction. */\n targetRatio: number\n /** Jaccard similarity below which consecutive turns count as a topic change. */\n driftThreshold: number\n /** C-zone tool outputs are head+tail truncated to this many characters. */\n toolOutputKeepChars: number\n}\n\nexport const DTC_DEFAULTS: DtcConfig = {\n tailTurns: 4,\n lowWatermarkRatio: 0.5,\n targetRatio: 0.7,\n driftThreshold: 0.18,\n toolOutputKeepChars: 4000,\n}\n\n/** Zone width caps in turns: the current-task zone never spans more than\n * C_ZONE_MAX_TURNS even without a topic boundary; the medium zone between\n * C and D never spans more than M_ZONE_MAX_TURNS. Code constants by design —\n * they shape the tier geometry, not user policy. */\nconst C_ZONE_MAX_TURNS = 8\nconst M_ZONE_MAX_TURNS = 12\n/** M-zone text parts keep their first line, capped at this many characters. */\nconst M_TEXT_KEEP_CHARS = 200\n/** Reasoning payloads degrade to a single space (never an empty string —\n * providers differ on empty content blocks). */\nconst FOLDED_TEXT = \" \"\n\nexport type FoldLevel = 0 | 1 | 2 | 3\n\nexport interface TransformStats {\n messages: number\n userTurns: number\n level: FoldLevel\n estimatedBefore: number\n estimatedAfter: number\n contextTokens: number\n foldedTools: number\n foldedTexts: number\n digestedTurns: number\n skipped: \"short\" | \"unknown-context\" | \"compaction\" | undefined\n}\n\nconst NO_STATS: TransformStats = {\n messages: 0,\n userTurns: 0,\n level: 0,\n estimatedBefore: 0,\n estimatedAfter: 0,\n contextTokens: 0,\n foldedTools: 0,\n foldedTexts: 0,\n digestedTurns: 0,\n skipped: undefined,\n}\n\nexport interface TransformDeps {\n state: DtcState\n config: DtcConfig\n logger?: Logger\n now?: () => number\n}\n\n/** Splits the array into turns at user messages (compaction-part users are\n * host machinery, not conversational turns — same rule as the fork's own\n * `turns()` in session/compaction.ts). */\nexport function segmentTurns(messages: MessageLike[]): Turn[] {\n const turns: Turn[] = []\n for (let i = 0; i < messages.length; i++) {\n const info = messages[i]?.info\n if (info?.role !== \"user\") continue\n if ((messages[i]?.parts ?? []).some((p) => p?.type === \"compaction\")) continue\n turns.push({ start: i, end: messages.length })\n }\n for (let i = 0; i < turns.length - 1; i++) {\n turns[i]!.end = turns[i + 1]!.start\n }\n return turns\n}\n\nexport function transformMessages(messages: MessageLike[], deps: TransformDeps): TransformStats {\n const stats: TransformStats = { ...NO_STATS }\n if (!Array.isArray(messages) || messages.length === 0) return stats\n stats.messages = messages.length\n\n const sessionID = findSessionID(messages)\n if (sessionID && deps.state.consumeCompactionSkip(sessionID)) {\n stats.skipped = \"compaction\"\n return stats\n }\n\n const turns = segmentTurns(messages)\n stats.userTurns = turns.length\n const { config, state } = deps\n if (turns.length <= config.tailTurns) {\n stats.skipped = \"short\"\n return stats\n }\n\n const contextTokens = sessionID ? state.contextTokens(sessionID) : undefined\n if (!contextTokens) {\n // Fail open until `chat.params` has taught us the window size.\n stats.skipped = \"unknown-context\"\n return stats\n }\n stats.contextTokens = contextTokens\n\n const headTurns = turns.slice(0, turns.length - config.tailTurns)\n const estimatedBefore = estimateSlice(messages, 0, messages.length)\n stats.estimatedBefore = estimatedBefore\n\n const lowWatermark = Math.floor(contextTokens * config.lowWatermarkRatio)\n const target = Math.floor(contextTokens * config.targetRatio)\n const minLevel = sessionID ? state.minLevel(sessionID) : 0\n if (estimatedBefore <= lowWatermark && minLevel === 0) {\n stats.estimatedAfter = estimatedBefore\n return stats\n }\n\n const zones = computeZones(messages, headTurns, sessionID, state, config)\n const now = (deps.now ?? Date.now)()\n\n let level = Math.max(1, minLevel) as FoldLevel\n applyLevel(messages, headTurns, zones, level, deps, stats, now)\n let estimatedAfter = estimateSlice(messages, 0, messages.length)\n while (estimatedAfter > target && level < 3) {\n level = (level + 1) as FoldLevel\n applyLevel(messages, headTurns, zones, level, deps, stats, now)\n estimatedAfter = estimateSlice(messages, 0, messages.length)\n }\n\n stats.level = level\n stats.estimatedAfter = estimatedAfter\n deps.logger?.debug(\"DTC transform\", {\n sessionId: sessionID,\n messages: stats.messages,\n userTurns: stats.userTurns,\n level,\n estimatedBefore,\n estimatedAfter,\n contextTokens,\n foldedTools: stats.foldedTools,\n digestedTurns: stats.digestedTurns,\n })\n return stats\n}\n\ninterface Zones {\n /** Head-turn ordinals: D = [0, mStart), M = [mStart, cStart), C = [cStart, head.length). */\n mStart: number\n cStart: number\n}\n\nfunction computeZones(\n messages: MessageLike[],\n headTurns: Turn[],\n sessionID: string | undefined,\n state: DtcState,\n config: DtcConfig,\n): Zones {\n const boundaries = findTopicBoundaries(messages, headTurns, config.driftThreshold)\n const lastBoundary = boundaries.length > 0 ? boundaries[boundaries.length - 1]! : 0\n const secondLast = boundaries.length > 1 ? boundaries[boundaries.length - 2]! : 0\n\n let markStart = 0\n const markAt = sessionID ? state.boundaryMark(sessionID) : undefined\n if (markAt !== undefined) {\n // The tool fired inside a turn: that turn is the LAST of the old\n // topic, so the new topic starts at the following head turn. When the\n // marked turn already sits inside the protected tail, the whole head\n // becomes foldable (C empty) — exactly the \"topic changed, fold the\n // old task away\" semantics.\n for (let t = 0; t < headTurns.length; t++) {\n const created = messages[headTurns[t]!.start]?.info?.time?.created\n if (typeof created === \"number\" && created <= markAt) markStart = t + 1\n }\n }\n\n const cStart = Math.min(\n headTurns.length,\n Math.max(lastBoundary, markStart, headTurns.length - C_ZONE_MAX_TURNS),\n )\n const mStart = Math.min(cStart, Math.max(secondLast, cStart - M_ZONE_MAX_TURNS))\n return { mStart, cStart }\n}\n\nfunction applyLevel(\n messages: MessageLike[],\n headTurns: Turn[],\n zones: Zones,\n level: FoldLevel,\n deps: TransformDeps,\n stats: TransformStats,\n now: number,\n): void {\n // Zones fold exactly once: escalation only touches the newly added band,\n // so cumulative levels never re-fold (and never double-digest) a turn.\n const prev = level === 1 ? -1 : level - 1\n if (level >= 1 && prev < 1) {\n for (let t = 0; t < zones.mStart; t++) {\n foldDistant(messages, headTurns[t]!, t + 1, deps, stats, now)\n }\n }\n if (level >= 2 && prev < 2) {\n for (let t = zones.mStart; t < zones.cStart; t++) {\n foldMiddle(messages, headTurns[t]!, stats, now)\n }\n }\n if (level >= 3 && prev < 3) {\n for (let t = zones.cStart; t < headTurns.length; t++) {\n foldCurrent(messages, headTurns[t]!, deps.config.toolOutputKeepChars, stats)\n }\n }\n}\n\nfunction foldDistant(\n messages: MessageLike[],\n turn: Turn,\n ordinal: number,\n deps: TransformDeps,\n stats: TransformStats,\n now: number,\n): void {\n const key = digestKey(messages, turn)\n let digest = deps.state.cachedDigest(key)\n if (digest === undefined) {\n digest = digestTurn(messages, turn, ordinal)\n deps.state.storeDigest(key, digest)\n }\n stats.digestedTurns++\n\n let digestPlaced = false\n for (let i = turn.start; i < turn.end; i++) {\n const message = messages[i]\n for (const part of message?.parts ?? []) {\n if (!part || typeof part !== \"object\") continue\n if (foldToolPart(part, now, true)) {\n stats.foldedTools++\n continue\n }\n if (\n part.type === \"reasoning\" &&\n typeof part.text === \"string\" &&\n part.text.length > 0\n ) {\n part.text = FOLDED_TEXT\n continue\n }\n if (part.type === \"text\" && typeof part.text === \"string\") {\n if (!digestPlaced && message?.info?.role === \"user\") {\n part.text = digest\n digestPlaced = true\n } else {\n part.text = FOLDED_TEXT\n }\n stats.foldedTexts++\n }\n }\n }\n}\n\nfunction foldMiddle(messages: MessageLike[], turn: Turn, stats: TransformStats, now: number): void {\n for (let i = turn.start; i < turn.end; i++) {\n for (const part of messages[i]?.parts ?? []) {\n if (!part || typeof part !== \"object\") continue\n if (foldToolPart(part, now, false)) {\n stats.foldedTools++\n continue\n }\n if (\n part.type === \"reasoning\" &&\n typeof part.text === \"string\" &&\n part.text.length > 0\n ) {\n part.text = FOLDED_TEXT\n continue\n }\n if (\n part.type === \"text\" &&\n typeof part.text === \"string\" &&\n part.text.length > M_TEXT_KEEP_CHARS\n ) {\n part.text = firstLine(part.text, M_TEXT_KEEP_CHARS) || FOLDED_TEXT\n stats.foldedTexts++\n }\n }\n }\n}\n\nfunction foldCurrent(\n messages: MessageLike[],\n turn: Turn,\n keepChars: number,\n stats: TransformStats,\n): void {\n for (let i = turn.start; i < turn.end; i++) {\n for (const part of messages[i]?.parts ?? []) {\n if (!part || typeof part !== \"object\" || part.type !== \"tool\") continue\n const state = part.state\n if (!state || state.status !== \"completed\") continue\n const output = state.output\n if (typeof output !== \"string\" || output.length <= keepChars) continue\n state.output = truncateMiddle(\n output,\n keepChars,\n `[DCP 已折叠 ${output.length - keepChars} 字符]`,\n )\n stats.foldedTools++\n }\n }\n}\n\n/**\n * Folds a completed tool part using the host's native degradation marker\n * (rendered as \"[Old tool result content cleared]\" by the host serializer).\n * In the distant zone the call arguments are cleared as well — the digest\n * carries the paths and commands that still matter. Returns true when folded.\n */\nfunction foldToolPart(part: PartLike, now: number, clearInput: boolean): boolean {\n if (part.type !== \"tool\") return false\n const state = part.state\n if (!state || state.status !== \"completed\") return false\n if (state.time && typeof state.time === \"object\") {\n state.time.compacted = now\n } else {\n state.time = { compacted: now }\n }\n if (clearInput && state.input && typeof state.input === \"object\") {\n state.input = {}\n }\n return true\n}\n\nfunction findSessionID(messages: MessageLike[]): string | undefined {\n for (const message of messages) {\n const id = message?.info?.sessionID\n if (typeof id === \"string\" && id) return id\n }\n return undefined\n}\n","/**\n * Per-session runtime state for the DTC engine. Everything here is\n * request-scoped or in-memory only — nothing is ever persisted, matching the\n * \"no plugin checkpoint persistence\" constraint. All maps are LRU-bounded.\n */\n\nconst SESSION_LIMIT = 500\nconst DIGEST_LIMIT = 2000\n\nfunction lruSet<K, V>(map: Map<K, V>, key: K, value: V, limit: number): void {\n if (map.has(key)) map.delete(key)\n map.set(key, value)\n while (map.size > limit) {\n const oldest = map.keys().next().value\n if (oldest === undefined) break\n map.delete(oldest)\n }\n}\n\ninterface SessionDtcState {\n /** Context window size learned from `chat.params` (tokens). */\n contextTokens?: number\n /**\n * One-shot skip flag: set by the compacting hook so the transform that\n * the host runs over the compaction input (fork compaction.ts fires\n * compacting at :373 and the transform at :380 in the same flow) never\n * folds content the summarizer needs at full fidelity.\n */\n skipNextTransform?: boolean\n /**\n * `dcp_prune` marks a topic boundary: folds deepen (minimum level) and\n * the current-task zone restarts at the first turn created after this\n * timestamp.\n */\n boundaryMarkAt?: number\n /** Manual severity bump from `dcp_prune` / `/dcp fold`. */\n minLevel?: number\n}\n\nexport class DtcState {\n private readonly sessions = new Map<string, SessionDtcState>()\n private readonly digests = new Map<string, string>()\n\n observeContextLimit(sessionID: string, contextTokens: number | undefined): void {\n if (!sessionID || !contextTokens || !Number.isFinite(contextTokens) || contextTokens <= 0) {\n return\n }\n const state = this.session(sessionID)\n state.contextTokens = contextTokens\n lruSet(this.sessions, sessionID, state, SESSION_LIMIT)\n }\n\n contextTokens(sessionID: string): number | undefined {\n return this.sessions.get(sessionID)?.contextTokens\n }\n\n /** Called by the compacting hook; consumed by the very next transform. */\n armCompactionSkip(sessionID: string): void {\n const state = this.session(sessionID)\n state.skipNextTransform = true\n lruSet(this.sessions, sessionID, state, SESSION_LIMIT)\n }\n\n consumeCompactionSkip(sessionID: string): boolean {\n const state = this.sessions.get(sessionID)\n if (!state?.skipNextTransform) return false\n state.skipNextTransform = false\n return true\n }\n\n /** `dcp_prune` / `/dcp fold`: mark a boundary now and deepen folding. */\n markBoundary(sessionID: string, at: number, minLevel = 2): void {\n const state = this.session(sessionID)\n state.boundaryMarkAt = at\n state.minLevel = Math.max(state.minLevel ?? 0, minLevel)\n lruSet(this.sessions, sessionID, state, SESSION_LIMIT)\n }\n\n boundaryMark(sessionID: string): number | undefined {\n return this.sessions.get(sessionID)?.boundaryMarkAt\n }\n\n minLevel(sessionID: string): number {\n return this.sessions.get(sessionID)?.minLevel ?? 0\n }\n\n cachedDigest(key: string): string | undefined {\n return this.digests.get(key)\n }\n\n storeDigest(key: string, digest: string): void {\n lruSet(this.digests, key, digest, DIGEST_LIMIT)\n }\n\n dropSession(sessionID: string): void {\n this.sessions.delete(sessionID)\n }\n\n /** Test/inspection surface. */\n stats(): { sessions: number; digests: number } {\n return { sessions: this.sessions.size, digests: this.digests.size }\n }\n\n private session(sessionID: string): SessionDtcState {\n return this.sessions.get(sessionID) ?? {}\n }\n}\n","/**\n * Resolves the session ID from a host event's properties. Most events carry\n * `sessionID` directly, but some (e.g. `session.deleted`) only carry\n * `info: Session`. Returns `undefined` when neither is a non-empty string.\n */\nexport function eventSessionID(properties?: Record<string, any>): string | undefined {\n const direct = properties?.sessionID\n if (typeof direct === \"string\" && direct) return direct\n const info = properties?.info?.id\n if (typeof info === \"string\" && info) return info\n return undefined\n}\n","import type { PluginConfig } from \"./config\"\nimport type { Logger } from \"./logger\"\nimport type { OpenCodeClient } from \"./opencode-client\"\nimport type { PromptStore } from \"./prompts/store\"\nimport { segmentTurns, transformMessages } from \"./dtc/engine\"\nimport type { DtcState } from \"./dtc/state\"\nimport type { MessageLike } from \"./dtc/types\"\nimport { estimateSlice } from \"./dtc/digest\"\nimport { eventSessionID } from \"./session-events\"\n\ninterface CompactionOutput {\n context: string[]\n prompt?: string\n}\n\n/** Host-side tail protection DCP applies unless the user configured it. */\nexport const DEFAULT_TAIL_TURNS = 4\nexport const DEFAULT_PRESERVE_RECENT_TOKENS = 32_000\n\n/**\n * Extracts the text of the most recent completed checkpoint (assistant\n * message flagged `summary`) from a session messages response. The host\n * hides prior checkpoint pairs from the summarizer input and only re-exposes\n * them through its own default prompt — which DCP replaces. Fetching the\n * previous checkpoint here is what keeps the checkpoint rolling instead of\n * restarting from the retained tail each compaction.\n */\nexport function extractPreviousCheckpoint(messages: unknown): string | undefined {\n if (!Array.isArray(messages)) return undefined\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index] as { info?: any; parts?: any[] } | undefined\n const info = message?.info\n if (info?.role !== \"assistant\" || info.summary !== true) continue\n const parts = Array.isArray(message?.parts) ? message.parts : []\n const text = parts\n .filter((part) => part?.type === \"text\" && typeof part.text === \"string\")\n .map((part) => part.text.trim())\n .filter(Boolean)\n .join(\"\\n\\n\")\n .trim()\n if (text) return text\n }\n return undefined\n}\n\nasync function fetchPreviousCheckpoint(\n client: OpenCodeClient,\n sessionID: string,\n): Promise<string | undefined> {\n if (!sessionID) return undefined\n try {\n const response = await client.session.messages({ path: { id: sessionID } })\n return extractPreviousCheckpoint(response.data ?? response)\n } catch {\n // Fail-open: without the previous checkpoint the compaction still\n // runs, it just restarts from the raw history.\n return undefined\n }\n}\n\nexport interface SessionCompactingDeps {\n prompts: PromptStore\n logger: Logger\n client: OpenCodeClient\n state: DtcState\n}\n\nexport function createSessionCompactingHandler(deps: SessionCompactingDeps) {\n return async (input: { sessionID: string }, output: CompactionOutput): Promise<void> => {\n try {\n // The host fires this hook and then runs the messages transform\n // over the compaction input in the same flow (fork\n // session/compaction.ts :373 → :380). Folding that input would\n // strip detail the summarizer needs, so arm a one-shot skip.\n deps.state.armCompactionSkip(input.sessionID)\n deps.prompts.reload()\n const prompt = deps.prompts.getRuntimePrompts().compaction\n const previous = await fetchPreviousCheckpoint(deps.client, input.sessionID)\n const withCheckpoint = previous\n ? `${prompt}\\n\\n<previous-checkpoint>\\n${previous}\\n</previous-checkpoint>`\n : prompt\n if (!output.prompt) {\n output.prompt = withCheckpoint\n } else if (!output.context.includes(prompt)) {\n output.context.push(withCheckpoint)\n }\n deps.logger.debug(\"Applied semantic pruning prompt\", {\n sessionId: input.sessionID,\n carriedCheckpoint: Boolean(previous),\n })\n } catch (error) {\n deps.logger.warn(\n \"Failed to apply semantic pruning prompt; native compaction continues\",\n {\n sessionId: input.sessionID,\n error: error instanceof Error ? error.message : String(error),\n },\n )\n }\n }\n}\n\n/**\n * `chat.params` fires on every LLM request with the resolved model. DTC only\n * reads the context-window size from it — the budget tiers are fractions of\n * that window, and until it is known the engine fails open (no folding).\n */\nexport function createChatParamsHandler(deps: { state: DtcState; logger: Logger }) {\n return async (\n input: { sessionID: string; model?: { limit?: { context?: number } } },\n _output?: unknown,\n ): Promise<void> => {\n try {\n const context = input.model?.limit?.context\n if (typeof context === \"number\" && Number.isFinite(context) && context > 0) {\n deps.state.observeContextLimit(input.sessionID, context)\n }\n } catch (error) {\n deps.logger.debug(\"chat.params observation failed\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\nexport interface TransformHandlerDeps {\n state: DtcState\n config: PluginConfig[\"dtc\"]\n logger: Logger\n}\n\n/**\n * THE compression surface: runs inside the host's per-request messages\n * transform. Fail-open by contract — any engine error must leave the array\n * untouched rather than break the model call.\n */\nexport function createTransformHandler(deps: TransformHandlerDeps) {\n return async (_input: unknown, output: { messages: unknown[] }): Promise<void> => {\n try {\n if (!Array.isArray(output?.messages) || output.messages.length === 0) return\n transformMessages(output.messages as MessageLike[], {\n state: deps.state,\n config: deps.config,\n logger: deps.logger,\n })\n } catch (error) {\n deps.logger.warn(\"DTC transform failed; the request proceeds unfolded\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\nexport interface EventHandlerDeps {\n state: DtcState\n logger: Logger\n}\n\n/** Slim lifecycle feed: only session deletion needs explicit cleanup; every\n * other DTC structure is LRU-bounded or request-scoped. */\nexport function createEventHandler(deps: EventHandlerDeps) {\n return async (input: { event: { type: string; properties?: Record<string, any> } }) => {\n try {\n if (input.event.type !== \"session.deleted\") return\n const sessionID = eventSessionID(input.event.properties)\n if (sessionID) deps.state.dropSession(sessionID)\n } catch (error) {\n deps.logger.warn(\"Event handler failed\", {\n type: input.event.type,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n\nasync function showToast(\n client: OpenCodeClient,\n title: string,\n message: string,\n variant: \"info\" | \"warning\" | \"error\" = \"info\",\n): Promise<void> {\n await client.tui\n .showToast({\n body: { title, message, variant, duration: 5000 },\n })\n .catch(() => undefined)\n}\n\nexport interface CommandExecuteDeps {\n client: OpenCodeClient\n state: DtcState\n config: PluginConfig[\"dtc\"]\n logger: Logger\n}\n\nexport function createCommandExecuteHandler(deps: CommandExecuteDeps) {\n return async (\n input: {\n command: string\n sessionID: string\n arguments: string\n },\n _output?: { parts: unknown[] },\n ): Promise<void> => {\n if (input.command !== \"dcp\") return\n\n const subcommand = (input.arguments ?? \"\").trim().split(/\\s+/, 1)[0]?.toLowerCase()\n\n if (subcommand === \"fold\") {\n deps.state.markBoundary(input.sessionID, Date.now(), 3)\n await showToast(\n deps.client,\n \"DCP fold\",\n \"已标记话题边界并加深折叠;下一次模型请求起生效,会话不中断。\",\n )\n deps.logger.debug(\"Handled DCP fold command\", { sessionId: input.sessionID })\n throw new Error(\"__DCP_FOLD_HANDLED__\")\n }\n\n if (subcommand === \"status\") {\n const message = await buildStatusMessage(deps, input.sessionID)\n await showToast(deps.client, \"DCP status\", message)\n throw new Error(\"__DCP_STATUS_HANDLED__\")\n }\n\n await showToast(\n deps.client,\n \"DCP\",\n \"用法:/dcp fold(立即深折叠)或 /dcp status(查看分区状态)。压缩由动态分级引擎在每次请求时自动完成。\",\n )\n throw new Error(\"__DCP_HELP_HANDLED__\")\n }\n}\n\nasync function buildStatusMessage(deps: CommandExecuteDeps, sessionID: string): Promise<string> {\n try {\n const response = await deps.client.session.messages({ path: { id: sessionID } })\n const data = (response as { data?: unknown }).data ?? response\n const messages = (Array.isArray(data) ? data : []) as MessageLike[]\n const turns = segmentTurns(messages)\n const estimated = estimateSlice(messages, 0, messages.length)\n const context = deps.state.contextTokens(sessionID)\n const tail = Math.min(deps.config.tailTurns, turns.length)\n const lines = [\n `消息 ${messages.length} 条 / 对话轮 ${turns.length}(尾部保护 ${tail} 轮)`,\n `估算 ${estimated.toLocaleString()} tokens` +\n (context ? ` / 上下文窗口 ${context.toLocaleString()}` : \"(窗口未知,暂未折叠)\"),\n `手动降级档位:${deps.state.minLevel(sessionID)}`,\n ]\n return lines.join(\"\\n\")\n } catch {\n return \"无法读取会话状态。\"\n }\n}\n\n/**\n * Mutates the host config at load time: register the `/dcp` command when\n * enabled, and raise the host's compaction tail protection to DCP's tiered\n * defaults (last turns kept verbatim) unless the user already configured\n * them — this shapes the host's own overflow-compaction fallback, which is\n * the only compaction that still writes checkpoints.\n */\nexport function createConfigHandler(config: PluginConfig, logger: Logger) {\n return async (opencodeConfig: Record<string, any>): Promise<void> => {\n const compaction = (opencodeConfig.compaction ??= {})\n if (compaction.tail_turns === undefined) {\n compaction.tail_turns = DEFAULT_TAIL_TURNS\n }\n if (compaction.preserve_recent_tokens === undefined) {\n compaction.preserve_recent_tokens = DEFAULT_PRESERVE_RECENT_TOKENS\n }\n if (config.commands.enabled) {\n opencodeConfig.command ??= {}\n opencodeConfig.command.dcp = {\n template: \"\",\n description: \"Dynamic context pruning: /dcp fold | /dcp status\",\n }\n }\n logger.debug(\"Applied host config defaults\", {\n tailTurns: compaction.tail_turns,\n preserveRecentTokens: compaction.preserve_recent_tokens,\n })\n }\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, statSync, writeFileSync } from \"node:fs\"\nimport { homedir } from \"node:os\"\nimport { dirname, join } from \"node:path\"\nimport type { Logger } from \"../logger\"\nimport { getCompactionPrompt } from \"./compaction\"\n\nexport interface RuntimePrompts {\n compaction: string\n}\n\ninterface PromptPaths {\n defaultsDir: string\n overrides: string[]\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) && statSync(candidate).isDirectory()) return candidate\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n return null\n}\n\nfunction resolvePaths(workingDirectory: string): PromptPaths {\n const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), \".config\")\n const globalRoot = join(configHome, \"opencode\", \"dcp-prompts\")\n const opencodeDir = findOpencodeDir(workingDirectory)\n return {\n defaultsDir: join(globalRoot, \"defaults\"),\n overrides: [\n opencodeDir ? join(opencodeDir, \"dcp-prompts\", \"overrides\", \"compaction.md\") : \"\",\n process.env.OPENCODE_CONFIG_DIR\n ? join(process.env.OPENCODE_CONFIG_DIR, \"dcp-prompts\", \"overrides\", \"compaction.md\")\n : \"\",\n join(globalRoot, \"overrides\", \"compaction.md\"),\n ].filter(Boolean),\n }\n}\n\nfunction normalize(content: string): string {\n return content\n .replace(/^\\uFEFF/, \"\")\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(/<!--[\\s\\S]*?-->/g, \"\")\n .trim()\n}\n\nexport class PromptStore {\n private readonly paths: PromptPaths\n private readonly defaultPrompt: string\n private runtime: RuntimePrompts\n private lastReloadAt = 0\n\n constructor(\n private readonly logger: Logger,\n workingDirectory: string,\n private readonly customPromptsEnabled = false,\n language?: string,\n ) {\n this.paths = resolvePaths(workingDirectory)\n this.defaultPrompt = getCompactionPrompt(language)\n this.runtime = { compaction: this.defaultPrompt }\n if (customPromptsEnabled) this.ensureDefaults()\n this.reload()\n }\n\n getRuntimePrompts(): RuntimePrompts {\n return { ...this.runtime }\n }\n\n reload(): void {\n const now = Date.now()\n if (now - this.lastReloadAt < 1000) return\n this.lastReloadAt = now\n this.runtime = { compaction: this.defaultPrompt }\n if (!this.customPromptsEnabled) return\n\n for (const path of this.paths.overrides) {\n if (!existsSync(path)) continue\n try {\n const prompt = normalize(readFileSync(path, \"utf-8\"))\n if (prompt) this.runtime = { compaction: prompt }\n return\n } catch (error) {\n this.logger.warn(\"Failed to load compaction prompt override\", {\n path,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n }\n\n private ensureDefaults(): void {\n try {\n mkdirSync(this.paths.defaultsDir, { recursive: true })\n writeFileSync(\n join(this.paths.defaultsDir, \"compaction.md\"),\n `${this.defaultPrompt.trim()}\\n`,\n )\n writeFileSync(\n join(this.paths.defaultsDir, \"README.md\"),\n \"# DCP compaction prompt\\n\\nCopy `compaction.md` to an `overrides` directory and restart OpenCode.\\n\",\n )\n } catch (error) {\n this.logger.warn(\"Failed to write bundled compaction prompt\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n}\n","export const COMPACTION = `你正在生成当前会话唯一的滚动检查点。输出将替代旧对话前缀,成为后续模型看到的第一段上下文;OpenCode 会在检查点之后直接保留最近若干轮完整对话(不经压缩,范围由宿主配置决定),这部分尾部不属于压缩对象,不要复述、总结或改写它们。系统级内容(AGENTS.md、项目规则等)由 OpenCode 在每次请求时独立注入,不属于压缩范围,不要复述它们。\n\n这不是聊天记录摘要,而是可直接继续工作的语义剪枝结果。按以下分层规则压缩:\n\n1. 滚动合并:如果输入末尾含有 <previous-checkpoint> 标签包裹的上一份检查点,把仍有效的信息合并进新检查点;不要嵌套、引用或逐字重复旧检查点,失效内容直接丢弃。没有该标签时忽略本条。\n2. 远距离内容(早期与中部历史)重度压缩:每个主题只留一句话结论,不留过程、不复述对话往来。\n3. 删除无关闲聊、其他项目或其他仓库的对话、重复解释、已经推翻且不再有诊断价值的方案。\n4. 多次工具调用试错或失败后成功时,只保留最终成功结果;仅当根因会影响后续工作时保留一次简短失败原因。\n5. 同一内容或文件被重复编辑时,只保留最终状态、仍有效的关键决策和必要理由,不复述每轮修改。\n6. 近距离内容(自上一份检查点以来的新内容,且不属于宿主保留的尾部)轻度压缩:当前任务、目标、状态与进行中的情况做汇总但不丢细节——保留继续工作所需的文件路径、接口、命令、测试结果、错误事实、仍有效的决策及理由,只折叠重复与已失效的内容。\n\n使用以下固定结构,省略确实为空的条目:\n\n## 历史概要\n早期与中部历史的主题和背景,每项一句话结论;远期已完成任务归入此处,不含执行过程。\n\n## 已完成任务的概括\n最近的已完成任务,每个任务一句话概括其结果与关键产出。\n\n## 进行中任务详情\n当前正在进行的任务逐项写清:目标、已完成步骤、涉及文件路径与接口、关键决策、遇到的阻塞、下一步具体动作。本节属于轻度压缩区,宁可多保留细节,不做二次推断。\n\n## 未解决问题\n跨任务的遗留风险和待确认事项。只写未在「进行中任务详情」中出现的内容,避免与该节重复。\n\n保持具体、可验证和项目内聚。进行中的任务必须能凭检查点直接继续,不要依赖已被压缩掉的中间过程。保留文件路径、接口、命令、测试结果和错误事实等硬事实,但不要保留消息 ID、块 ID、锚点、占位符、控制标签或过程性聊天。`\n\nexport const COMPACTION_EN = `You are generating the single rolling checkpoint for this session. Your output will replace the old conversation prefix as the first context the model sees afterwards; OpenCode keeps the most recent conversation turns directly after the checkpoint, uncompacted (their range is a host setting). That tail is outside the compaction scope: do not restate, summarize, or rewrite it. System-level content (AGENTS.md, project rules, etc.) is injected independently by OpenCode on every request and is not part of compaction; do not restate it.\n\nThis is not a chat-log summary but a semantic pruning result one can resume working from directly. Compress by these tiered rules:\n\n1. Rolling merge: if the input ends with a <previous-checkpoint> block containing the previous checkpoint, merge its still-valid information into the new checkpoint; do not nest, quote, or repeat it verbatim, and drop stale content outright. Ignore this rule when the tag is absent.\n2. Distant content (early and middle history) is compressed heavily: one concluding sentence per topic, no process detail, no dialogue restatement.\n3. Remove irrelevant chitchat, conversations about other projects or repositories, repeated explanations, and approaches that were overturned and no longer carry diagnostic value.\n4. When repeated tool trial-and-error ends in success, keep only the final successful outcome; retain one brief failure reason only if the root cause affects future work.\n5. When the same content or file was edited repeatedly, keep only the final state, the still-valid key decisions, and the necessary rationale; do not restate each round of edits.\n6. Recent content (everything generated since the previous checkpoint, excluding the host-retained tail) is compressed lightly: summarize the current task, goals, status, and in-progress work without losing detail—keep the file paths, interfaces, commands, test results, error facts, and still-valid decisions with rationale needed to continue, folding only duplicates and invalidated content.\n\nUse the following fixed structure, omitting sections that are truly empty:\n\n## History Overview\nTopics and background from early and middle history, one concluding sentence each; long-completed tasks belong here, without execution process.\n\n## Completed Task Summaries\nRecently completed tasks, one sentence per task covering its outcome and key outputs.\n\n## In-Progress Task Details\nFor the current task, itemize: goal, completed steps, file paths and interfaces involved, key decisions, blockers encountered, concrete next actions. This is the lightly-compressed zone; prefer keeping more detail and avoid second-order inference.\n\n## Unresolved Issues\nCross-task lingering risks and items awaiting confirmation. Only list items not already covered under In-Progress Task Details, to avoid duplication.\n\nStay specific, verifiable, and project-cohesive. An in-progress task must be resumable straight from this checkpoint, without relying on intermediate process that was pruned away. Keep hard facts such as file paths, interfaces, commands, test results, and error facts, but never message IDs, block IDs, anchors, placeholders, control tags, or procedural chatter.`\n\nexport function getCompactionPrompt(language?: string): string {\n return language === \"en\" ? COMPACTION_EN : COMPACTION\n}\n","import { tool } from \"@opencode-ai/plugin\"\nimport type { Logger } from \"./logger\"\nimport type { DtcState } from \"./dtc/state\"\n\nexport const PRUNE_TOOL_NAME = \"dcp_prune\"\n\nconst PRUNE_TOOL_DESCRIPTION = `标记话题边界并加深本会话的动态上下文折叠。压缩本身由 DCP 在每次模型请求时自动分级完成(远距离重度折叠、当前任务轻度折叠、最近数轮原样保留),本工具只调整折叠策略,不执行任何会话操作。\n\n仅在这些情况下调用:\n- 对话话题发生明显变更:开始处理新的问题域、切换到另一个模块/仓库/任务;\n- 用户明确要求压缩上下文。\n\n同一任务内的多轮追问、参数微调、延续当前工作,都不要调用。调用瞬时完成,绝不打断当前工作:旧任务内容从下一次模型请求起被折叠为结构化摘要,最近对话与当前任务细节不受影响。不要为同一话题反复调用。`\n\nexport interface PruneToolDeps {\n state: DtcState\n logger: Logger\n now?: () => number\n}\n\nexport function createPruneTool(deps: PruneToolDeps) {\n return tool({\n description: PRUNE_TOOL_DESCRIPTION,\n args: {},\n execute: async (_args, context) => {\n const sessionID = context.sessionID\n const now = (deps.now ?? Date.now)()\n deps.state.markBoundary(sessionID, now, 2)\n deps.logger.debug(\"Prune tool marked a topic boundary\", {\n sessionId: sessionID,\n })\n return \"DCP:已标记话题边界并加深本会话折叠——旧任务内容将从下一次模型请求起分级折叠为结构化摘要;最近对话与当前任务细节不受影响,会话未中断。\"\n },\n })\n}\n","import { readFile } from \"node:fs/promises\"\nimport { basename, dirname, join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\ntype PackageJson = {\n name?: string\n version?: string\n dependencies?: Record<string, string>\n}\n\ntype UpdateResult =\n | { available: true; name: string; current: string; latest: string }\n | { available: false }\n\nconst PACKAGE_NAME = \"@lexwdex-org/opencode-dcp\"\n\nexport function startAutoUpdate(ctx: PluginInput, enabled: boolean): void {\n if (!enabled) return\n\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 10_000)\n void checkAutoUpdate(controller.signal)\n .then((result) => {\n if (!result.available) return\n setTimeout(() => {\n void ctx.client.tui\n .showToast({\n body: {\n title: \"DCP update available\",\n message: `${result.name} ${result.latest} is available (current ${result.current}). Reinstall the plugin to update.`,\n variant: \"info\",\n duration: 7000,\n },\n })\n .catch(() => {})\n }, 5000)\n })\n .catch(() => {})\n .finally(() => clearTimeout(timeout))\n}\n\nexport async function checkAutoUpdate(signal: AbortSignal): Promise<UpdateResult> {\n const packageDir = await findPackageDir(PACKAGE_NAME)\n if (!packageDir) return { available: false }\n\n const pkg = await readPackageJson(join(packageDir, \"package.json\"))\n if (!pkg?.name || !pkg.version) return { available: false }\n\n const latest = await fetchLatestVersion(pkg.name, signal)\n if (!latest || !isVersionNewer(latest, pkg.version)) return { available: false }\n\n const wrapperDir = await findAutoUpdateWrapperDir(packageDir, pkg.name)\n if (!wrapperDir) return { available: false }\n\n return { available: true, name: pkg.name, current: pkg.version, latest }\n}\n\nasync function findPackageDir(name: string) {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (;;) {\n const pkg = await readPackageJson(join(dir, \"package.json\"))\n if (pkg?.name === name) return dir\n\n const parent = dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n }\n}\n\nexport async function findAutoUpdateWrapperDir(packageDir: string, name: string) {\n const packageParent = dirname(packageDir)\n const nodeModulesDir = basename(packageParent).startsWith(\"@\")\n ? dirname(packageParent)\n : packageParent\n if (basename(nodeModulesDir) !== \"node_modules\") return undefined\n\n const wrapperDir = dirname(nodeModulesDir)\n const wrapperPkg = await readPackageJson(join(wrapperDir, \"package.json\"))\n const spec = wrapperSpec(wrapperDir, name) ?? wrapperPkg?.dependencies?.[name]\n if (!spec || !isAutoUpdatableSpec(spec)) return undefined\n\n return wrapperDir\n}\n\nfunction wrapperSpec(wrapperDir: string, name: string) {\n if (name.startsWith(\"@\")) {\n const [scope, pkg] = name.split(\"/\")\n if (!scope || !pkg || basename(dirname(wrapperDir)) !== scope) return undefined\n const prefix = `${pkg}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n }\n\n const prefix = `${name}@`\n const base = basename(wrapperDir)\n return base.startsWith(prefix) ? base.slice(prefix.length) : undefined\n}\n\nexport function isAutoUpdatableSpec(spec: string) {\n const value = spec.trim()\n if (!value) return false\n if (value === \"latest\" || value === \"*\") return true\n if (/^[~^]/.test(value)) return true\n if (/^(?:>=|>|<=|<)/.test(value)) return true\n if (/\\s+(?:\\|\\||-|[<>=])\\s+/.test(value)) return true\n return false\n}\n\nasync function readPackageJson(path: string): Promise<PackageJson | undefined> {\n try {\n const data = JSON.parse(await readFile(path, \"utf-8\"))\n return data && typeof data === \"object\" ? (data as PackageJson) : undefined\n } catch {\n return undefined\n }\n}\n\nasync function fetchLatestVersion(name: string, signal: AbortSignal) {\n try {\n const response = await fetch(\n `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`,\n {\n signal,\n },\n )\n if (!response.ok) return undefined\n const data: unknown = await response.json()\n if (!data || typeof data !== \"object\") return undefined\n const version = (data as { version?: unknown }).version\n return typeof version === \"string\" ? version : undefined\n } catch {\n return undefined\n }\n}\n\nexport function isVersionNewer(latest: string, current: string) {\n const next = parseVersion(latest)\n const prev = parseVersion(current)\n if (!next || !prev) return false\n\n for (let i = 0; i < 3; i++) {\n if (next.parts[i] !== prev.parts[i]) return next.parts[i] > prev.parts[i]\n }\n\n if (!next.pre.length && prev.pre.length) return true\n if (next.pre.length && !prev.pre.length) return false\n\n for (let i = 0; i < Math.max(next.pre.length, prev.pre.length); i++) {\n const a = next.pre[i]\n const b = prev.pre[i]\n if (a === undefined) return false\n if (b === undefined) return true\n if (a === b) continue\n\n const aNumber = /^\\d+$/.test(a) ? Number(a) : undefined\n const bNumber = /^\\d+$/.test(b) ? Number(b) : undefined\n if (aNumber !== undefined && bNumber !== undefined) return aNumber > bNumber\n if (aNumber !== undefined) return false\n if (bNumber !== undefined) return true\n return a > b\n }\n\n return false\n}\n\nfunction parseVersion(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+.+)?$/)\n if (!match) return undefined\n return {\n parts: [Number(match[1]), Number(match[2]), Number(match[3])],\n pre: match[4]?.split(\".\") ?? [],\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { getConfig } from \"./lib/config\"\nimport { DtcState } from \"./lib/dtc/state\"\nimport {\n createChatParamsHandler,\n createCommandExecuteHandler,\n createConfigHandler,\n createEventHandler,\n createSessionCompactingHandler,\n createTransformHandler,\n} from \"./lib/hooks\"\nimport { Logger } from \"./lib/logger\"\nimport { PromptStore } from \"./lib/prompts/store\"\nimport { PRUNE_TOOL_NAME, createPruneTool } from \"./lib/prune-tool\"\nimport { startAutoUpdate } from \"./lib/update\"\n\nconst server: Plugin = (async (ctx) => {\n const config = getConfig(ctx)\n if (!config.enabled) return {}\n\n const logger = new Logger(config.debug)\n const prompts = new PromptStore(\n logger,\n ctx.directory,\n config.experimental.customPrompts,\n config.language,\n )\n // All DTC runtime state is in-memory and request-scoped by design: the\n // engine never writes to the session, so there is nothing to persist.\n const state = new DtcState()\n\n logger.info(\"DCP initialized\", {\n commands: config.commands.enabled,\n dtc: config.dtc.enabled,\n tool: config.tool.enabled,\n customPrompts: config.experimental.customPrompts,\n })\n startAutoUpdate(ctx, config.autoUpdate)\n\n return {\n \"experimental.session.compacting\": createSessionCompactingHandler({\n prompts,\n logger,\n client: ctx.client,\n state,\n }),\n // THE compression surface: dynamic tiered folding on every model\n // request, plus the chat.params feed that teaches the engine each\n // session's context-window size.\n ...(config.dtc.enabled && {\n \"experimental.chat.messages.transform\": createTransformHandler({\n state,\n config: config.dtc,\n logger,\n }),\n \"chat.params\": createChatParamsHandler({ state, logger }),\n }),\n // Lifecycle cleanup for DTC session state (LRU-bounded regardless).\n event: createEventHandler({ state, logger }),\n ...(config.tool.enabled && {\n tool: { [PRUNE_TOOL_NAME]: createPruneTool({ state, logger }) },\n }),\n ...(config.commands.enabled && {\n \"command.execute.before\": createCommandExecuteHandler({\n client: ctx.client,\n state,\n config: config.dtc,\n logger,\n }),\n }),\n // Always registered: besides the optional /dcp command it raises the\n // host's compaction tail protection to DCP's tiered defaults.\n config: createConfigHandler(config, logger),\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","tool","parse","join","existsSync","homedir","stack","existsSync","mkdirSync","readFileSync","statSync","writeFileSync","homedir","dirname","join","findOpencodeDir","join","existsSync","statSync","dirname","homedir","readFileSync","mkdirSync","writeFileSync","dirname","join","prefix","base"]}