@lexwdex-org/opencode-dcp 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -24,7 +24,7 @@ The host fires `experimental.chat.messages.transform` before every model request
24
24
  - **M middle zone**: long texts keep their first line; tool outputs get the host's native fold marker (rendered by the host as its own `[Old tool result content cleared]`); **tool arguments reduce to a target skeleton** (only filePath / command first line and friends — `oldString`/`newString`/`content` payloads are dropped); **failed attempts (error parts) fold to a short first line** — three edits on one file with two failures collapse to three recognizable call skeletons plus two single-line errors, with the final state owned by disk and the current-task zone; reasoning is emptied.
25
25
  - **D distant zone**: whole turns collapse into one mechanical digest line (intent / actions / files touched / outcome / error count) and tool inputs are cleared — hard facts live on in the digest.
26
26
 
27
- **Dynamic budget**: below `lowWatermarkRatio` of the context window (default 50%) **nothing is folded at all** — short sessions pay zero cost. Above it, folding escalates D→M→C from the far end until the estimate fits `targetRatio` (default 70%). The window size is learned per session from the `chat.params` hook; until it is known the engine fails open (no folding).
27
+ **Dynamic budget**: below `lowWatermarkRatio` of the context window (default 50%) **nothing is folded at all** — short sessions pay zero cost. Above it, folding escalates D→M→C from the far end until the estimate fits `targetRatio` (default 70%). The window size is learned per session from the `chat.params` hook; until it is known the engine fails open (no folding). Session attribution reads `sessionID` straight off the message payload on official hosts; on fork hosts that strip message IDs into database columns, DTC falls back to a `chat.params`-recorded "user-message timestamp → session" index (content-keyed, so concurrent sessions never cross-attribute; a session's very first request has no record yet and skips folding).
28
28
 
29
29
  **Three structural laws** (the constructive exclusion of the old versions' "lost markers" failure):
30
30
 
package/README.md CHANGED
@@ -24,7 +24,7 @@ DCP 以**动态分级请求期压缩(DTC)**管理 OpenCode 会话上下文
24
24
  - **M 中距离区**:长文本保留首行;tool 输出打宿主原生折叠标记(渲染为宿主自己的 `[Old tool result content cleared]`);**tool 参数规约为目标骨架**(仅留 filePath/command 首行等,`oldString`/`newString`/`content` 等载荷全部丢弃);**失败尝试(error part)折为短首行**——同一文件连改 3 次错 2 次,折叠后只剩 3 个可辨识调用骨架 + 2 条单行错误,最终状态以磁盘与当前任务区为准;推理内容清空。
25
25
  - **D 远距离区**:整轮塌缩为一行机械摘要(意图 / 动作 / 涉及文件 / 结果 / 错误数),tool 参数一并清空——硬事实保留在摘要里。
26
26
 
27
- **动态预算**:估算低于上下文窗口的 `lowWatermarkRatio`(默认 50%)时**完全不折叠**,短会话零开销;超出则按 D→M→C 从远到近逐级加深,直到估算落回 `targetRatio`(默认 70%)以内。窗口大小由 `chat.params` 钩子按会话自动学习,未知时 fail-open 不折叠。
27
+ **动态预算**:估算低于上下文窗口的 `lowWatermarkRatio`(默认 50%)时**完全不折叠**,短会话零开销;超出则按 D→M→C 从远到近逐级加深,直到估算落回 `targetRatio`(默认 70%)以内。窗口大小由 `chat.params` 钩子按会话自动学习,未知时 fail-open 不折叠。会话归属按官方宿主形状直读消息体 `sessionID`;fork 宿主把 id/sessionID 剥离进数据库列时,自动改用 `chat.params` 预记录的「用户消息时间戳 → 会话」索引反查归属(内容键关联,并发会话不串扰;会话首个请求尚无记录则跳过折叠)。
28
28
 
29
29
  **三条结构铁律**(老版本"丢失标记号"问题的构造性排除):
30
30
 
package/dist/index.js CHANGED
@@ -1081,7 +1081,7 @@ function transformMessages(messages, deps) {
1081
1081
  const stats = { ...NO_STATS };
1082
1082
  if (!Array.isArray(messages) || messages.length === 0) return stats;
1083
1083
  stats.messages = messages.length;
1084
- const sessionID = findSessionID(messages);
1084
+ const sessionID = findSessionID(messages, deps.state);
1085
1085
  if (sessionID && deps.state.consumeCompactionSkip(sessionID)) {
1086
1086
  stats.skipped = "compaction";
1087
1087
  return stats;
@@ -1294,11 +1294,20 @@ function foldErrorPart(part, keepChars, clearInput, stats) {
1294
1294
  stats.reducedInputs++;
1295
1295
  }
1296
1296
  }
1297
- function findSessionID(messages) {
1297
+ function findSessionID(messages, state) {
1298
1298
  for (const message of messages) {
1299
1299
  const id = message?.info?.sessionID;
1300
1300
  if (typeof id === "string" && id) return id;
1301
1301
  }
1302
+ for (let i = messages.length - 1; i >= 0; i--) {
1303
+ const message = messages[i];
1304
+ if (message?.info?.role !== "user") continue;
1305
+ if ((message.parts ?? []).some((p) => p?.type === "compaction")) continue;
1306
+ const created = message.info?.time?.created;
1307
+ if (typeof created !== "number") continue;
1308
+ const sessionID = state.sessionByUserTime(created);
1309
+ if (sessionID) return sessionID;
1310
+ }
1302
1311
  return void 0;
1303
1312
  }
1304
1313
 
@@ -1694,6 +1703,7 @@ Using previous/default values`
1694
1703
  // lib/dtc/state.ts
1695
1704
  var SESSION_LIMIT = 500;
1696
1705
  var DIGEST_LIMIT = 2e3;
1706
+ var PARAMS_INDEX_LIMIT = 200;
1697
1707
  function lruSet(map, key, value, limit) {
1698
1708
  if (map.has(key)) map.delete(key);
1699
1709
  map.set(key, value);
@@ -1706,6 +1716,8 @@ function lruSet(map, key, value, limit) {
1706
1716
  var DtcState = class {
1707
1717
  sessions = /* @__PURE__ */ new Map();
1708
1718
  digests = /* @__PURE__ */ new Map();
1719
+ /** User-message creation time → sessionID, fed by `chat.params`. */
1720
+ paramsIndex = /* @__PURE__ */ new Map();
1709
1721
  observeContextLimit(sessionID, contextTokens) {
1710
1722
  if (!sessionID || !contextTokens || !Number.isFinite(contextTokens) || contextTokens <= 0) {
1711
1723
  return;
@@ -1717,6 +1729,23 @@ var DtcState = class {
1717
1729
  contextTokens(sessionID) {
1718
1730
  return this.sessions.get(sessionID)?.contextTokens;
1719
1731
  }
1732
+ /**
1733
+ * Fork hosts strip id/sessionID out of message payloads (they live in
1734
+ * database columns), so the transform cannot read the session off the
1735
+ * messages like it does on the official host. `chat.params` fires on
1736
+ * every request carrying both the sessionID and the triggering user
1737
+ * message; recording that pair lets the NEXT request's transform resolve
1738
+ * its session by matching user-message creation times. The key is
1739
+ * content (a timestamp), not recency, so concurrent sessions never
1740
+ * cross-attribute.
1741
+ */
1742
+ recordParamsSession(sessionID, userTimeCreated) {
1743
+ if (!sessionID || !Number.isFinite(userTimeCreated)) return;
1744
+ lruSet(this.paramsIndex, userTimeCreated, sessionID, PARAMS_INDEX_LIMIT);
1745
+ }
1746
+ sessionByUserTime(userTimeCreated) {
1747
+ return this.paramsIndex.get(userTimeCreated);
1748
+ }
1720
1749
  /** Called by the compacting hook; consumed by the very next transform.
1721
1750
  * Accepted leak: if the host aborts between the hook and the summarizer
1722
1751
  * transform, the flag skips folding once for the next unrelated request —
@@ -1753,10 +1782,17 @@ var DtcState = class {
1753
1782
  }
1754
1783
  dropSession(sessionID) {
1755
1784
  this.sessions.delete(sessionID);
1785
+ for (const [time, sid] of this.paramsIndex) {
1786
+ if (sid === sessionID) this.paramsIndex.delete(time);
1787
+ }
1756
1788
  }
1757
1789
  /** Test/inspection surface. */
1758
1790
  stats() {
1759
- return { sessions: this.sessions.size, digests: this.digests.size };
1791
+ return {
1792
+ sessions: this.sessions.size,
1793
+ digests: this.digests.size,
1794
+ params: this.paramsIndex.size
1795
+ };
1760
1796
  }
1761
1797
  session(sessionID) {
1762
1798
  return this.sessions.get(sessionID) ?? {};
@@ -1797,6 +1833,10 @@ function createChatParamsHandler(deps) {
1797
1833
  if (typeof context === "number" && Number.isFinite(context) && context > 0) {
1798
1834
  deps.state.observeContextLimit(input.sessionID, context);
1799
1835
  }
1836
+ const created = input.message?.time?.created;
1837
+ if (input.sessionID && typeof created === "number" && Number.isFinite(created)) {
1838
+ deps.state.recordParamsSession(input.sessionID, created);
1839
+ }
1800
1840
  } catch (error) {
1801
1841
  deps.logger.debug("chat.params observation failed", {
1802
1842
  error: error instanceof Error ? error.message : String(error)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/config.ts","../node_modules/jsonc-parser/lib/esm/impl/scanner.js","../node_modules/jsonc-parser/lib/esm/impl/string-intern.js","../node_modules/jsonc-parser/lib/esm/impl/parser.js","../node_modules/jsonc-parser/lib/esm/main.js","../lib/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/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\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 interface PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n commands: Commands\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 \"commands\",\n \"commands.enabled\",\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 \"language\",\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.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 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 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 commands: {\n enabled: true,\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 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 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 commands: mergeCommands(config.commands, data.commands),\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 if (typeof state.error === \"string\") tokens += estimateTokens(state.error)\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/** Error text caps: middle zone keeps a short first line, distant zone less. */\nconst M_ERROR_KEEP_CHARS = 200\nconst D_ERROR_KEEP_CHARS = 100\n/** Tool inputs reduce to their target identity; commands keep a short head. */\nconst INPUT_TARGET_KEYS = [\"filePath\", \"path\", \"file\", \"filename\", \"pattern\", \"directory\"]\nconst COMMAND_KEEP_CHARS = 80\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 reducedInputs: number\n foldedErrors: 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 reducedInputs: 0,\n foldedErrors: 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 // Bands apply cumulatively: a manual minimum level can start at 2 or 3,\n // and every band below it must still fold — starting high never skips the\n // distant zone. Each band folds exactly once per request.\n let appliedBand = 0\n const applyUpTo = (lvl: FoldLevel): void => {\n while (appliedBand < lvl) {\n appliedBand++\n applyBand(messages, headTurns, zones, appliedBand, deps, stats, now)\n }\n }\n applyUpTo(level)\n let estimatedAfter = estimateSlice(messages, 0, messages.length)\n while (estimatedAfter > target && level < 3) {\n level = (level + 1) as FoldLevel\n applyUpTo(level)\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 reducedInputs: stats.reducedInputs,\n foldedErrors: stats.foldedErrors,\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 applyBand(\n messages: MessageLike[],\n headTurns: Turn[],\n zones: Zones,\n band: number,\n deps: TransformDeps,\n stats: TransformStats,\n now: number,\n): void {\n if (band === 1) {\n for (let t = 0; t < zones.mStart; t++) {\n foldDistant(messages, headTurns[t]!, t + 1, deps, stats, now)\n }\n } else if (band === 2) {\n for (let t = zones.mStart; t < zones.cStart; t++) {\n foldMiddle(messages, headTurns[t]!, stats, now)\n }\n } else if (band === 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 (part.type === \"tool\" && part.state?.status === \"error\") {\n foldErrorPart(part, D_ERROR_KEEP_CHARS, true, stats)\n continue\n }\n if (foldToolPart(part, now, \"distant\", stats)) {\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 (part.type === \"tool\" && part.state?.status === \"error\") {\n foldErrorPart(part, M_ERROR_KEEP_CHARS, false, stats)\n continue\n }\n if (foldToolPart(part, now, \"middle\", stats)) {\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 * Reduces a tool call's arguments to their target identity: path-like keys\n * stay, `command` keeps a short first line, and content payloads\n * (oldString/newString/content/…) are dropped. Repeated or failed operations\n * on the same target collapse to a recognizable skeleton — the final state\n * lives on disk and in the current-task zone, never in stale payloads.\n */\nexport function reduceInput(input: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!input || typeof input !== \"object\") return {}\n const reduced: Record<string, unknown> = {}\n for (const key of INPUT_TARGET_KEYS) {\n const value = input[key]\n if (typeof value === \"string\" && value) reduced[key] = value\n }\n const command = input.command\n if (typeof command === \"string\" && command) {\n reduced.command = firstLine(command, COMMAND_KEEP_CHARS)\n }\n return reduced\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 * and reduces the call arguments per zone: the distant zone clears them\n * entirely (the digest carries paths/commands), the middle zone keeps the\n * target skeleton. Returns true when folded.\n */\nfunction foldToolPart(\n part: PartLike,\n now: number,\n zone: \"distant\" | \"middle\",\n stats: TransformStats,\n): 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 (state.input && typeof state.input === \"object\") {\n state.input = zone === \"distant\" ? {} : reduceInput(state.input)\n stats.reducedInputs++\n }\n return true\n}\n\n/**\n * Folds a terminal error tool part: the failure text keeps a short first\n * line (diagnostic value without the stack-trace weight) and the arguments\n * reduce like a completed call's. The part itself stays — structure, IDs,\n * and tool-call pairing are never touched. Current/tail zones never call\n * this: in-flight task detail is the spec's red line.\n */\nfunction foldErrorPart(\n part: PartLike,\n keepChars: number,\n clearInput: boolean,\n stats: TransformStats,\n): void {\n const state = part.state\n if (!state) return\n if (typeof state.error === \"string\" && state.error.length > keepChars) {\n state.error = firstLine(state.error, keepChars) || FOLDED_TEXT\n stats.foldedErrors++\n }\n if (state.input && typeof state.input === \"object\") {\n state.input = clearInput ? {} : reduceInput(state.input)\n stats.reducedInputs++\n }\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 * Accepted leak: if the host aborts between the hook and the summarizer\n * transform, the flag skips folding once for the next unrelated request —\n * fail-open (extra tokens, never lost information) and self-healing. */\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 { 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\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\nexport interface SessionCompactingDeps {\n state: DtcState\n logger: Logger\n}\n\n/**\n * The host fires this hook right before it runs the messages transform over\n * the compaction input (fork session/compaction.ts :373 → :380). DCP does NOT\n * touch the compaction prompt: the host's native anchored-summary template\n * (with its own previous-summary rolling merge) stays fully in charge of\n * `/compact` and the overflow fallback. The hook's single job is arming the\n * one-shot DTC skip so the summarizer always sees full-fidelity input instead\n * of request-time folds.\n */\nexport function createSessionCompactingHandler(deps: SessionCompactingDeps) {\n return async (input: { sessionID: string }, _output?: unknown): Promise<void> => {\n try {\n deps.state.armCompactionSkip(input.sessionID)\n deps.logger.debug(\"Armed DTC skip for the native compaction input\", {\n sessionId: input.sessionID,\n })\n } catch (error) {\n deps.logger.warn(\"Failed to arm the compaction skip; native compaction continues\", {\n sessionId: input.sessionID,\n error: error instanceof Error ? error.message : String(error),\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 { 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 { 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 // 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 })\n startAutoUpdate(ctx, config.autoUpdate)\n\n return {\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. The compacting hook rides along\n // solely to keep the host's native compaction input unfolded — the\n // native prompt is never touched. With DTC off, DCP registers no\n // compaction-adjacent hook at all.\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 \"experimental.session.compacting\": createSessionCompactingHandler({ 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","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/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\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 interface PluginConfig {\n enabled: boolean\n autoUpdate: boolean\n debug: boolean\n commands: Commands\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 \"commands\",\n \"commands.enabled\",\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 \"language\",\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.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 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 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 commands: {\n enabled: true,\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 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 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 commands: mergeCommands(config.commands, data.commands),\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 if (typeof state.error === \"string\") tokens += estimateTokens(state.error)\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/** Error text caps: middle zone keeps a short first line, distant zone less. */\nconst M_ERROR_KEEP_CHARS = 200\nconst D_ERROR_KEEP_CHARS = 100\n/** Tool inputs reduce to their target identity; commands keep a short head. */\nconst INPUT_TARGET_KEYS = [\"filePath\", \"path\", \"file\", \"filename\", \"pattern\", \"directory\"]\nconst COMMAND_KEEP_CHARS = 80\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 reducedInputs: number\n foldedErrors: 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 reducedInputs: 0,\n foldedErrors: 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, deps.state)\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 // Bands apply cumulatively: a manual minimum level can start at 2 or 3,\n // and every band below it must still fold — starting high never skips the\n // distant zone. Each band folds exactly once per request.\n let appliedBand = 0\n const applyUpTo = (lvl: FoldLevel): void => {\n while (appliedBand < lvl) {\n appliedBand++\n applyBand(messages, headTurns, zones, appliedBand, deps, stats, now)\n }\n }\n applyUpTo(level)\n let estimatedAfter = estimateSlice(messages, 0, messages.length)\n while (estimatedAfter > target && level < 3) {\n level = (level + 1) as FoldLevel\n applyUpTo(level)\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 reducedInputs: stats.reducedInputs,\n foldedErrors: stats.foldedErrors,\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 applyBand(\n messages: MessageLike[],\n headTurns: Turn[],\n zones: Zones,\n band: number,\n deps: TransformDeps,\n stats: TransformStats,\n now: number,\n): void {\n if (band === 1) {\n for (let t = 0; t < zones.mStart; t++) {\n foldDistant(messages, headTurns[t]!, t + 1, deps, stats, now)\n }\n } else if (band === 2) {\n for (let t = zones.mStart; t < zones.cStart; t++) {\n foldMiddle(messages, headTurns[t]!, stats, now)\n }\n } else if (band === 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 (part.type === \"tool\" && part.state?.status === \"error\") {\n foldErrorPart(part, D_ERROR_KEEP_CHARS, true, stats)\n continue\n }\n if (foldToolPart(part, now, \"distant\", stats)) {\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 (part.type === \"tool\" && part.state?.status === \"error\") {\n foldErrorPart(part, M_ERROR_KEEP_CHARS, false, stats)\n continue\n }\n if (foldToolPart(part, now, \"middle\", stats)) {\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 * Reduces a tool call's arguments to their target identity: path-like keys\n * stay, `command` keeps a short first line, and content payloads\n * (oldString/newString/content/…) are dropped. Repeated or failed operations\n * on the same target collapse to a recognizable skeleton — the final state\n * lives on disk and in the current-task zone, never in stale payloads.\n */\nexport function reduceInput(input: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!input || typeof input !== \"object\") return {}\n const reduced: Record<string, unknown> = {}\n for (const key of INPUT_TARGET_KEYS) {\n const value = input[key]\n if (typeof value === \"string\" && value) reduced[key] = value\n }\n const command = input.command\n if (typeof command === \"string\" && command) {\n reduced.command = firstLine(command, COMMAND_KEEP_CHARS)\n }\n return reduced\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 * and reduces the call arguments per zone: the distant zone clears them\n * entirely (the digest carries paths/commands), the middle zone keeps the\n * target skeleton. Returns true when folded.\n */\nfunction foldToolPart(\n part: PartLike,\n now: number,\n zone: \"distant\" | \"middle\",\n stats: TransformStats,\n): 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 (state.input && typeof state.input === \"object\") {\n state.input = zone === \"distant\" ? {} : reduceInput(state.input)\n stats.reducedInputs++\n }\n return true\n}\n\n/**\n * Folds a terminal error tool part: the failure text keeps a short first\n * line (diagnostic value without the stack-trace weight) and the arguments\n * reduce like a completed call's. The part itself stays — structure, IDs,\n * and tool-call pairing are never touched. Current/tail zones never call\n * this: in-flight task detail is the spec's red line.\n */\nfunction foldErrorPart(\n part: PartLike,\n keepChars: number,\n clearInput: boolean,\n stats: TransformStats,\n): void {\n const state = part.state\n if (!state) return\n if (typeof state.error === \"string\" && state.error.length > keepChars) {\n state.error = firstLine(state.error, keepChars) || FOLDED_TEXT\n stats.foldedErrors++\n }\n if (state.input && typeof state.input === \"object\") {\n state.input = clearInput ? {} : reduceInput(state.input)\n stats.reducedInputs++\n }\n}\n\nfunction findSessionID(messages: MessageLike[], state: DtcState): string | undefined {\n for (const message of messages) {\n const id = message?.info?.sessionID\n if (typeof id === \"string\" && id) return id\n }\n // Fork-shape fallback: the host stripped id/sessionID from the payload,\n // so correlate through the chat.params index instead — scan user turns\n // newest-first and return the session recorded for that message's\n // creation time. Request N's chat.params records the user message that\n // triggered it, so from request N+1 on the session always resolves;\n // the very first request of a session finds nothing and fails open.\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (message?.info?.role !== \"user\") continue\n if ((message.parts ?? []).some((p) => p?.type === \"compaction\")) continue\n const created = message.info?.time?.created\n if (typeof created !== \"number\") continue\n const sessionID = state.sessionByUserTime(created)\n if (sessionID) return sessionID\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\nconst PARAMS_INDEX_LIMIT = 200\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 /** User-message creation time → sessionID, fed by `chat.params`. */\n private readonly paramsIndex = new Map<number, 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 /**\n * Fork hosts strip id/sessionID out of message payloads (they live in\n * database columns), so the transform cannot read the session off the\n * messages like it does on the official host. `chat.params` fires on\n * every request carrying both the sessionID and the triggering user\n * message; recording that pair lets the NEXT request's transform resolve\n * its session by matching user-message creation times. The key is\n * content (a timestamp), not recency, so concurrent sessions never\n * cross-attribute.\n */\n recordParamsSession(sessionID: string, userTimeCreated: number): void {\n if (!sessionID || !Number.isFinite(userTimeCreated)) return\n lruSet(this.paramsIndex, userTimeCreated, sessionID, PARAMS_INDEX_LIMIT)\n }\n\n sessionByUserTime(userTimeCreated: number): string | undefined {\n return this.paramsIndex.get(userTimeCreated)\n }\n\n /** Called by the compacting hook; consumed by the very next transform.\n * Accepted leak: if the host aborts between the hook and the summarizer\n * transform, the flag skips folding once for the next unrelated request —\n * fail-open (extra tokens, never lost information) and self-healing. */\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 for (const [time, sid] of this.paramsIndex) {\n if (sid === sessionID) this.paramsIndex.delete(time)\n }\n }\n\n /** Test/inspection surface. */\n stats(): { sessions: number; digests: number; params: number } {\n return {\n sessions: this.sessions.size,\n digests: this.digests.size,\n params: this.paramsIndex.size,\n }\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 { 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\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\nexport interface SessionCompactingDeps {\n state: DtcState\n logger: Logger\n}\n\n/**\n * The host fires this hook right before it runs the messages transform over\n * the compaction input (fork session/compaction.ts :373 → :380). DCP does NOT\n * touch the compaction prompt: the host's native anchored-summary template\n * (with its own previous-summary rolling merge) stays fully in charge of\n * `/compact` and the overflow fallback. The hook's single job is arming the\n * one-shot DTC skip so the summarizer always sees full-fidelity input instead\n * of request-time folds.\n */\nexport function createSessionCompactingHandler(deps: SessionCompactingDeps) {\n return async (input: { sessionID: string }, _output?: unknown): Promise<void> => {\n try {\n deps.state.armCompactionSkip(input.sessionID)\n deps.logger.debug(\"Armed DTC skip for the native compaction input\", {\n sessionId: input.sessionID,\n })\n } catch (error) {\n deps.logger.warn(\"Failed to arm the compaction skip; native compaction continues\", {\n sessionId: input.sessionID,\n error: error instanceof Error ? error.message : String(error),\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: {\n sessionID: string\n model?: { limit?: { context?: number } }\n message?: { time?: { created?: number } }\n },\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 const created = input.message?.time?.created\n if (input.sessionID && typeof created === \"number\" && Number.isFinite(created)) {\n deps.state.recordParamsSession(input.sessionID, created)\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 { 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 { 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 // 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 })\n startAutoUpdate(ctx, config.autoUpdate)\n\n return {\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. The compacting hook rides along\n // solely to keep the host's native compaction input unfolded — the\n // native prompt is never touched. With DTC off, DCP registers no\n // compaction-adjacent hook at all.\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 \"experimental.session.compacting\": createSessionCompactingHandler({ 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","dirname","join","prefix","base"]}
@@ -6,8 +6,22 @@
6
6
  export declare class DtcState {
7
7
  private readonly sessions;
8
8
  private readonly digests;
9
+ /** User-message creation time → sessionID, fed by `chat.params`. */
10
+ private readonly paramsIndex;
9
11
  observeContextLimit(sessionID: string, contextTokens: number | undefined): void;
10
12
  contextTokens(sessionID: string): number | undefined;
13
+ /**
14
+ * Fork hosts strip id/sessionID out of message payloads (they live in
15
+ * database columns), so the transform cannot read the session off the
16
+ * messages like it does on the official host. `chat.params` fires on
17
+ * every request carrying both the sessionID and the triggering user
18
+ * message; recording that pair lets the NEXT request's transform resolve
19
+ * its session by matching user-message creation times. The key is
20
+ * content (a timestamp), not recency, so concurrent sessions never
21
+ * cross-attribute.
22
+ */
23
+ recordParamsSession(sessionID: string, userTimeCreated: number): void;
24
+ sessionByUserTime(userTimeCreated: number): string | undefined;
11
25
  /** Called by the compacting hook; consumed by the very next transform.
12
26
  * Accepted leak: if the host aborts between the hook and the summarizer
13
27
  * transform, the flag skips folding once for the next unrelated request —
@@ -25,6 +39,7 @@ export declare class DtcState {
25
39
  stats(): {
26
40
  sessions: number;
27
41
  digests: number;
42
+ params: number;
28
43
  };
29
44
  private session;
30
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/dtc/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmCH,qBAAa,QAAQ;IACjB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAS/E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpD;;;4EAGwE;IACxE,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM1C,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAOjD,yEAAyE;IACzE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,IAAI;IAO/D,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAInC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI9C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIpC,+BAA+B;IAC/B,KAAK,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAI9C,OAAO,CAAC,OAAO;CAGlB"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/dtc/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoCH,qBAAa,QAAQ;IACjB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IAExD,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAS/E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpD;;;;;;;;;OASG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAKrE,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI9D;;;4EAGwE;IACxE,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM1C,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAOjD,yEAAyE;IACzE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,IAAI;IAO/D,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAInC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI9C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOpC,+BAA+B;IAC/B,KAAK,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAQ9D,OAAO,CAAC,OAAO;CAGlB"}
@@ -36,6 +36,11 @@ export declare function createChatParamsHandler(deps: {
36
36
  context?: number;
37
37
  };
38
38
  };
39
+ message?: {
40
+ time?: {
41
+ created?: number;
42
+ };
43
+ };
39
44
  }, _output?: unknown) => Promise<void>;
40
45
  export interface TransformHandlerDeps {
41
46
  state: DtcState;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAK3C,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,8BAA8B,QAAS,CAAA;AAEpD,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,qBAAqB,IACxD,OAAO;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAahF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,IAEzE,OAAO;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,EACtE,UAAU,OAAO,KAClB,OAAO,CAAC,IAAI,CAAC,CAYnB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,IAC/C,QAAQ,OAAO,EAAE,QAAQ;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAcjF;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;2DAC2D;AAC3D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IACvC,OAAO;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,mBAYrF;AAeD,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,kBAAkB,IAE5D,OAAO;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CACpB,EACD,UAAU;IAAE,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,KAC/B,OAAO,CAAC,IAAI,CAAC,CA6BnB;AAuBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IACtD,gBAAgB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAoBpE"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAK3C,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,8BAA8B,QAAS,CAAA;AAEpD,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,qBAAqB,IACxD,OAAO;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC,CAahF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,IAEzE,OAAO;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;IACxC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAC5C,EACD,UAAU,OAAO,KAClB,OAAO,CAAC,IAAI,CAAC,CAgBnB;AAED,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,IAC/C,QAAQ,OAAO,EAAE,QAAQ;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAcjF;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;2DAC2D;AAC3D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IACvC,OAAO;IAAE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,mBAYrF;AAeD,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,kBAAkB,IAE5D,OAAO;IACH,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CACpB,EACD,UAAU;IAAE,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,KAC/B,OAAO,CAAC,IAAI,CAAC,CA6BnB;AAuBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,IACtD,gBAAgB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAoBpE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@lexwdex-org/opencode-dcp",
4
- "version": "5.0.1",
4
+ "version": "5.0.2",
5
5
  "type": "module",
6
6
  "description": "Semantic pruning for OpenCode native context compaction",
7
7
  "main": "./dist/index.js",