reasonix 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +9 -0
  2. package/dashboard/dist/app.js +123 -16
  3. package/dashboard/dist/app.js.map +1 -1
  4. package/dist/cli/{acp-4ROCGYNH.js → acp-WFQIC6SO.js} +52 -135
  5. package/dist/cli/acp-WFQIC6SO.js.map +1 -0
  6. package/dist/cli/chat-D32JGNVH.js +51 -0
  7. package/dist/cli/{chunk-S2RMQULY.js → chunk-23ZPCIPR.js} +12 -9
  8. package/dist/cli/chunk-23ZPCIPR.js.map +1 -0
  9. package/dist/cli/{chunk-TKVXTQ3T.js → chunk-3ZZXQ3CZ.js} +27 -27
  10. package/dist/cli/chunk-3ZZXQ3CZ.js.map +1 -0
  11. package/dist/cli/{chunk-5OHHAQ4W.js → chunk-7AST3QQ3.js} +2 -2
  12. package/dist/cli/{chunk-MRZG4GBF.js → chunk-7JTKBJ2G.js} +3 -3
  13. package/dist/cli/{chunk-X53B3JIX.js → chunk-7X4JJOO7.js} +2 -61
  14. package/dist/cli/{chunk-X53B3JIX.js.map → chunk-7X4JJOO7.js.map} +1 -1
  15. package/dist/cli/{chunk-MOJYKO2A.js → chunk-ASOLXV67.js} +3 -3
  16. package/dist/cli/{chunk-7M4YYMKW.js → chunk-AWEULQG6.js} +49 -56
  17. package/dist/cli/{chunk-7M4YYMKW.js.map → chunk-AWEULQG6.js.map} +1 -1
  18. package/dist/cli/{chunk-HR5NBKEM.js → chunk-DFX5ZH5L.js} +2 -2
  19. package/dist/cli/{chunk-3WGTGXO4.js → chunk-GNS7BAT2.js} +4 -4
  20. package/dist/cli/chunk-GNS7BAT2.js.map +1 -0
  21. package/dist/cli/{chunk-TE5UIIFL.js → chunk-J2IHQGPQ.js} +12 -6
  22. package/dist/cli/chunk-J2IHQGPQ.js.map +1 -0
  23. package/dist/cli/{chunk-I4M5QJNL.js → chunk-JGTX4RRQ.js} +3 -3
  24. package/dist/cli/{chunk-FY4S7TJZ.js → chunk-JNTMOX7G.js} +10 -2
  25. package/dist/cli/chunk-JNTMOX7G.js.map +1 -0
  26. package/dist/cli/{chunk-OB4BUJBL.js → chunk-MGTBP7GG.js} +5 -2
  27. package/dist/cli/chunk-MGTBP7GG.js.map +1 -0
  28. package/dist/cli/{chunk-OPYALNTT.js → chunk-MQWO32ZD.js} +387 -184
  29. package/dist/cli/chunk-MQWO32ZD.js.map +1 -0
  30. package/dist/cli/{chunk-2QSTA2QV.js → chunk-O5LIHAMP.js} +8 -4
  31. package/dist/cli/chunk-O5LIHAMP.js.map +1 -0
  32. package/dist/cli/{chunk-NMQSUNLB.js → chunk-PB3MAFEI.js} +6 -3
  33. package/dist/cli/chunk-PB3MAFEI.js.map +1 -0
  34. package/dist/cli/{chunk-H4CCXMDD.js → chunk-PEMG6CUB.js} +2 -2
  35. package/dist/cli/{chunk-RUDBUHO4.js → chunk-PXBQ6IZ7.js} +3 -3
  36. package/dist/cli/{chunk-J2TQAWOM.js → chunk-Q46B3Z7H.js} +25 -10
  37. package/dist/cli/{chunk-J2TQAWOM.js.map → chunk-Q46B3Z7H.js.map} +1 -1
  38. package/dist/cli/{chunk-6MZTZO7A.js → chunk-QF32ROX2.js} +2152 -2613
  39. package/dist/cli/chunk-QF32ROX2.js.map +1 -0
  40. package/dist/cli/{chunk-OG5JANQ4.js → chunk-QX5TWXRZ.js} +2 -2
  41. package/dist/cli/{chunk-V4Y732RQ.js → chunk-TAIKVL35.js} +2 -2
  42. package/dist/cli/{chunk-B5CZL2SE.js → chunk-TEDWJKEI.js} +4 -9
  43. package/dist/cli/chunk-TEDWJKEI.js.map +1 -0
  44. package/dist/cli/{chunk-EMMENC4O.js → chunk-U5XQDCK7.js} +5 -5
  45. package/dist/cli/{chunk-DOWEOA6E.js → chunk-W46ZMNKO.js} +3 -3
  46. package/dist/cli/{chunk-CDVSFSAK.js → chunk-WMTMMSXU.js} +184 -8
  47. package/dist/cli/chunk-WMTMMSXU.js.map +1 -0
  48. package/dist/cli/{chunk-YW63N3ZR.js → chunk-YEF7C4XI.js} +270 -96
  49. package/dist/cli/chunk-YEF7C4XI.js.map +1 -0
  50. package/dist/cli/{chunk-JMDE6IO3.js → chunk-ZAEJWKXB.js} +2 -2
  51. package/dist/cli/chunk-ZWHSHFDP.js +6173 -0
  52. package/dist/cli/chunk-ZWHSHFDP.js.map +1 -0
  53. package/dist/cli/{code-PMPJWXEO.js → code-R4IHI7SR.js} +30 -30
  54. package/dist/cli/{commands-QS6TG4G3.js → commands-DRHFCYMO.js} +4 -4
  55. package/dist/cli/{commit-XPRSKUBF.js → commit-AG5KB4YP.js} +3 -3
  56. package/dist/cli/{desktop-562OPWIU.js → desktop-JGL6GORA.js} +60 -23
  57. package/dist/cli/desktop-JGL6GORA.js.map +1 -0
  58. package/dist/cli/{diff-I6W4AUWJ.js → diff-4Z7ETWZO.js} +9 -9
  59. package/dist/cli/{doctor-6XVZKT4U.js → doctor-VA3RHQLB.js} +9 -9
  60. package/dist/cli/index.js +37 -36
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli/{mcp-7W7ANO2Y.js → mcp-LZO4HXFA.js} +34 -23
  63. package/dist/cli/mcp-LZO4HXFA.js.map +1 -0
  64. package/dist/cli/{mcp-browse-LA4I4YIZ.js → mcp-browse-C3GXVMYZ.js} +3 -3
  65. package/dist/cli/{mcp-inspect-LWXXU7BY.js → mcp-inspect-ZMYUNFDS.js} +2 -2
  66. package/dist/cli/{prompt-RKZD4X6Y.js → prompt-MC3U5KRP.js} +5 -4
  67. package/dist/cli/{prune-sessions-SEWX7GP6.js → prune-sessions-OEPFH4N6.js} +11 -7
  68. package/dist/cli/prune-sessions-OEPFH4N6.js.map +1 -0
  69. package/dist/cli/{replay-2X7MVXOI.js → replay-4TP7ZUMZ.js} +10 -10
  70. package/dist/cli/{run-TPKXIJ27.js → run-6MXQYBOE.js} +16 -15
  71. package/dist/cli/run-6MXQYBOE.js.map +1 -0
  72. package/dist/cli/{server-NHQ3QXOZ.js → server-Z3IMJNNI.js} +65 -12
  73. package/dist/cli/server-Z3IMJNNI.js.map +1 -0
  74. package/dist/cli/{sessions-2A4DGSHA.js → sessions-NXQ5SAV7.js} +18 -18
  75. package/dist/cli/sessions-NXQ5SAV7.js.map +1 -0
  76. package/dist/cli/{setup-GOLP7J4C.js → setup-LHZELI6I.js} +6 -6
  77. package/dist/cli/{stats-CGDAFDKI.js → stats-SUIJ3QWY.js} +6 -6
  78. package/dist/cli/{version-FIL4ZFOS.js → version-BIFONEUB.js} +13 -13
  79. package/dist/index.d.ts +71 -17
  80. package/dist/index.js +1040 -391
  81. package/dist/index.js.map +1 -1
  82. package/package.json +6 -2
  83. package/dist/cli/acp-4ROCGYNH.js.map +0 -1
  84. package/dist/cli/chat-GZNB5625.js +0 -51
  85. package/dist/cli/chunk-2QSTA2QV.js.map +0 -1
  86. package/dist/cli/chunk-3WGTGXO4.js.map +0 -1
  87. package/dist/cli/chunk-6MZTZO7A.js.map +0 -1
  88. package/dist/cli/chunk-B5CZL2SE.js.map +0 -1
  89. package/dist/cli/chunk-CDVSFSAK.js.map +0 -1
  90. package/dist/cli/chunk-FY4S7TJZ.js.map +0 -1
  91. package/dist/cli/chunk-NMQSUNLB.js.map +0 -1
  92. package/dist/cli/chunk-OB4BUJBL.js.map +0 -1
  93. package/dist/cli/chunk-OPYALNTT.js.map +0 -1
  94. package/dist/cli/chunk-S2RMQULY.js.map +0 -1
  95. package/dist/cli/chunk-TE5UIIFL.js.map +0 -1
  96. package/dist/cli/chunk-TKVXTQ3T.js.map +0 -1
  97. package/dist/cli/chunk-WZGNXR6E.js +0 -2020
  98. package/dist/cli/chunk-WZGNXR6E.js.map +0 -1
  99. package/dist/cli/chunk-YW63N3ZR.js.map +0 -1
  100. package/dist/cli/desktop-562OPWIU.js.map +0 -1
  101. package/dist/cli/mcp-7W7ANO2Y.js.map +0 -1
  102. package/dist/cli/prune-sessions-SEWX7GP6.js.map +0 -1
  103. package/dist/cli/run-TPKXIJ27.js.map +0 -1
  104. package/dist/cli/server-NHQ3QXOZ.js.map +0 -1
  105. package/dist/cli/sessions-2A4DGSHA.js.map +0 -1
  106. /package/dist/cli/{chat-GZNB5625.js.map → chat-D32JGNVH.js.map} +0 -0
  107. /package/dist/cli/{chunk-5OHHAQ4W.js.map → chunk-7AST3QQ3.js.map} +0 -0
  108. /package/dist/cli/{chunk-MRZG4GBF.js.map → chunk-7JTKBJ2G.js.map} +0 -0
  109. /package/dist/cli/{chunk-MOJYKO2A.js.map → chunk-ASOLXV67.js.map} +0 -0
  110. /package/dist/cli/{chunk-HR5NBKEM.js.map → chunk-DFX5ZH5L.js.map} +0 -0
  111. /package/dist/cli/{chunk-I4M5QJNL.js.map → chunk-JGTX4RRQ.js.map} +0 -0
  112. /package/dist/cli/{chunk-H4CCXMDD.js.map → chunk-PEMG6CUB.js.map} +0 -0
  113. /package/dist/cli/{chunk-RUDBUHO4.js.map → chunk-PXBQ6IZ7.js.map} +0 -0
  114. /package/dist/cli/{chunk-OG5JANQ4.js.map → chunk-QX5TWXRZ.js.map} +0 -0
  115. /package/dist/cli/{chunk-V4Y732RQ.js.map → chunk-TAIKVL35.js.map} +0 -0
  116. /package/dist/cli/{chunk-EMMENC4O.js.map → chunk-U5XQDCK7.js.map} +0 -0
  117. /package/dist/cli/{chunk-DOWEOA6E.js.map → chunk-W46ZMNKO.js.map} +0 -0
  118. /package/dist/cli/{chunk-JMDE6IO3.js.map → chunk-ZAEJWKXB.js.map} +0 -0
  119. /package/dist/cli/{code-PMPJWXEO.js.map → code-R4IHI7SR.js.map} +0 -0
  120. /package/dist/cli/{commands-QS6TG4G3.js.map → commands-DRHFCYMO.js.map} +0 -0
  121. /package/dist/cli/{commit-XPRSKUBF.js.map → commit-AG5KB4YP.js.map} +0 -0
  122. /package/dist/cli/{diff-I6W4AUWJ.js.map → diff-4Z7ETWZO.js.map} +0 -0
  123. /package/dist/cli/{doctor-6XVZKT4U.js.map → doctor-VA3RHQLB.js.map} +0 -0
  124. /package/dist/cli/{mcp-browse-LA4I4YIZ.js.map → mcp-browse-C3GXVMYZ.js.map} +0 -0
  125. /package/dist/cli/{mcp-inspect-LWXXU7BY.js.map → mcp-inspect-ZMYUNFDS.js.map} +0 -0
  126. /package/dist/cli/{prompt-RKZD4X6Y.js.map → prompt-MC3U5KRP.js.map} +0 -0
  127. /package/dist/cli/{replay-2X7MVXOI.js.map → replay-4TP7ZUMZ.js.map} +0 -0
  128. /package/dist/cli/{setup-GOLP7J4C.js.map → setup-LHZELI6I.js.map} +0 -0
  129. /package/dist/cli/{stats-CGDAFDKI.js.map → stats-SUIJ3QWY.js.map} +0 -0
  130. /package/dist/cli/{version-FIL4ZFOS.js.map → version-BIFONEUB.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/cli/commands/doctor.ts"],"sourcesContent":["/** Plain-text (not Ink) — must work when everything else is broken. fail → exit 1; warn → exit 0. */\n\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { DeepSeekClient, pickPrimaryBalance } from \"../../client.js\";\nimport {\n defaultConfigPath,\n loadBaseUrl,\n loadProxyConfig,\n readConfig,\n resolveSemanticEmbeddingConfig,\n} from \"../../config.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { loadHooks } from \"../../hooks.js\";\nimport { t } from \"../../i18n/index.js\";\nimport { indexExists } from \"../../index/semantic/builder.js\";\nimport { checkOllamaStatus } from \"../../index/semantic/ollama-launcher.js\";\nimport { listSessions } from \"../../memory/session.js\";\nimport { detectProxyUrl, matchesNoProxy, resolveNoProxy } from \"../../net/proxy.js\";\nimport { resolveDataPath } from \"../../tokenizer.js\";\nimport { VERSION } from \"../../version.js\";\n\nexport type DoctorLevel = \"ok\" | \"warn\" | \"fail\";\n\nexport interface DoctorCheck {\n id: string;\n label: string;\n level: DoctorLevel;\n detail: string;\n}\n\nexport interface DoctorOptions {\n json?: boolean;\n}\n\ntype Level = DoctorLevel;\ntype Check = DoctorCheck;\n\nexport async function runDoctorChecks(projectRoot: string): Promise<DoctorCheck[]> {\n // No descriptive names for the destructured slots — CodeQL's clear-text-logging\n // heuristic taints any variable name matching `*key*`/`*auth*`/`*cred*`/etc and\n // would trip on `apiKeyCheck`. The slots map 1:1 to the Promise.all array below.\n const r = await Promise.all([\n checkApiKey(),\n checkConfig(),\n checkApiReach(),\n checkTokenizer(),\n checkSessions(),\n checkHooks(projectRoot),\n checkOllama(projectRoot),\n checkProject(projectRoot),\n ]);\n return [r[0], r[1], ...checkProxy(), r[2], r[3], r[4], r[5], r[6], r[7]];\n}\n\n/** Probe hosts used to show users what's going through the proxy vs. direct. Cheap (no I/O), purely a routing simulation against the same NO_PROXY patterns the dispatcher uses. */\nconst PROXY_PROBE_HOSTS = [\"api.deepseek.com\", \"github.com\", \"api.github.com\"] as const;\n\nfunction checkProxy(): Check[] {\n const url = detectProxyUrl();\n if (!url) {\n return [\n {\n id: \"proxy\",\n label: \"http proxy \",\n level: \"ok\",\n detail: \"no HTTPS_PROXY / HTTP_PROXY / ALL_PROXY set — direct connection\",\n },\n ];\n }\n let redacted = url;\n try {\n const u = new URL(url);\n if (u.username || u.password) {\n u.username = \"***\";\n u.password = \"\";\n redacted = u.toString();\n }\n } catch {\n /* not a URL — leave raw */\n }\n const cfg = loadProxyConfig();\n if (cfg.disabled) {\n return [\n {\n id: \"proxy\",\n label: \"http proxy \",\n level: \"ok\",\n detail: `HTTPS_PROXY=${redacted} is set but cfg.proxy.disabled — Reasonix routes direct`,\n },\n ];\n }\n const resolved = resolveNoProxy(process.env, { extraNoProxy: cfg.noProxy });\n const total = resolved.all.length;\n const sourceSummary = [\n `defaults ${resolved.defaults.length}`,\n resolved.envSystem.length > 0 ? `env ${resolved.envSystem.length}` : null,\n resolved.envReasonix.length > 0 ? `REASONIX ${resolved.envReasonix.length}` : null,\n resolved.extra.length > 0 ? `config ${resolved.extra.length}` : null,\n ]\n .filter(Boolean)\n .join(\" + \");\n const proxyCheck: Check = {\n id: \"proxy\",\n label: \"http proxy \",\n level: \"ok\",\n detail: `routing fetch through ${redacted} (NO_PROXY: ${total} pattern${total === 1 ? \"\" : \"s\"} — ${sourceSummary})`,\n };\n const probes = PROXY_PROBE_HOSTS.map(\n (h) => `${h} → ${matchesNoProxy(h, resolved.all) ? \"direct\" : \"via proxy\"}`,\n );\n const routingCheck: Check = {\n id: \"proxy-routing\",\n label: \"proxy routing\",\n level: \"ok\",\n detail: probes.join(\", \"),\n };\n return [proxyCheck, routingCheck];\n}\n\nconst TTY = process.stdout.isTTY && process.env.TERM !== \"dumb\";\n\nfunction color(text: string, code: string): string {\n if (!TTY) return text;\n return `\\x1b[${code}m${text}\\x1b[0m`;\n}\n\nfunction badge(level: Level): string {\n if (level === \"ok\") return color(\"✓\", \"32\");\n if (level === \"warn\") return color(\"⚠\", \"33\");\n return color(\"✗\", \"31\");\n}\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(1)} MB`;\n}\n\nasync function checkApiKey(): Promise<Check> {\n const fromEnv = process.env.DEEPSEEK_API_KEY;\n if (fromEnv) {\n return {\n id: \"api-key\",\n label: \"api key \",\n level: \"ok\",\n detail: \"set via env DEEPSEEK_API_KEY\",\n };\n }\n try {\n const cfg = readConfig();\n if (cfg.apiKey) {\n return {\n id: \"api-key\",\n label: \"api key \",\n level: \"ok\",\n detail: `from ${defaultConfigPath()}`,\n };\n }\n } catch {\n /* fall through */\n }\n return {\n id: \"api-key\",\n label: \"api key \",\n level: \"fail\",\n detail:\n \"not set — `reasonix setup` to save one, or export DEEPSEEK_API_KEY. Get a key at https://platform.deepseek.com/api_keys\",\n };\n}\n\nasync function checkConfig(): Promise<Check> {\n const path = defaultConfigPath();\n if (!existsSync(path)) {\n return {\n id: \"config\",\n label: \"config \",\n level: \"warn\",\n detail: \"missing — running with library defaults. `reasonix setup` writes one.\",\n };\n }\n try {\n const cfg = readConfig(path);\n const parts: string[] = [];\n if (cfg.preset) parts.push(`preset=${cfg.preset}`);\n if (cfg.editMode) parts.push(`editMode=${cfg.editMode}`);\n if (cfg.mcp && cfg.mcp.length > 0) parts.push(`mcp=${cfg.mcp.length}`);\n return {\n id: \"config\",\n label: \"config \",\n level: \"ok\",\n detail: `${path}${parts.length ? ` (${parts.join(\", \")})` : \"\"}`,\n };\n } catch (err) {\n return {\n id: \"config\",\n label: \"config \",\n level: \"fail\",\n detail: t(\"doctorErrors.unreadable\", { path, message: (err as Error).message }),\n };\n }\n}\n\nasync function checkApiReach(): Promise<Check> {\n const key = process.env.DEEPSEEK_API_KEY ?? readConfig().apiKey;\n if (!key) {\n return {\n id: \"api-reach\",\n label: \"api reach \",\n level: \"warn\",\n detail: \"skipped — no api key to test with\",\n };\n }\n try {\n const client = new DeepSeekClient({ apiKey: key, baseUrl: loadBaseUrl() });\n const ctl = new AbortController();\n const timer = setTimeout(() => ctl.abort(), 8_000);\n let balance: Awaited<ReturnType<DeepSeekClient[\"getBalance\"]>>;\n try {\n balance = await client.getBalance({ signal: ctl.signal });\n } finally {\n clearTimeout(timer);\n }\n if (!balance) {\n return {\n id: \"api-reach\",\n label: \"api reach \",\n level: \"fail\",\n detail: \"/user/balance returned null — auth failed or network blocked\",\n };\n }\n const summary = summarizeBalances(balance.balance_infos);\n if (!balance.is_available) {\n return {\n id: \"api-reach\",\n label: \"api reach \",\n level: \"warn\",\n detail: `account flagged not-available${summary ? ` (${summary})` : \"\"} — top up or check your dashboard`,\n };\n }\n return {\n id: \"api-reach\",\n label: \"api reach \",\n level: \"ok\",\n detail: summary ? `/user/balance ok — ${summary}` : \"/user/balance ok\",\n };\n } catch (err) {\n return {\n id: \"api-reach\",\n label: \"api reach \",\n level: \"fail\",\n detail: `${(err as Error).message}`,\n };\n }\n}\n\nfunction summarizeBalances(\n infos: ReadonlyArray<{ currency: string; total_balance: string }>,\n): string {\n if (infos.length === 0) return \"\";\n const primary = pickPrimaryBalance(infos);\n if (infos.length === 1 || !primary)\n return primary ? `${primary.total_balance} ${primary.currency}` : \"\";\n const rest = infos.filter((i) => i !== primary).map((i) => `${i.total_balance} ${i.currency}`);\n return `${primary.total_balance} ${primary.currency} + ${rest.join(\" + \")}`;\n}\n\nasync function checkTokenizer(): Promise<Check> {\n // Reuse the runtime's resolver so the doctor never disagrees with what\n // the tokenizer actually loads — three candidates including a global\n // npm install probe via createRequire.\n const path = resolveDataPath();\n if (existsSync(path)) {\n try {\n const stat = statSync(path);\n return {\n id: \"tokenizer\",\n label: \"tokenizer \",\n level: \"ok\",\n detail: `${path} (${fmtBytes(stat.size)})`,\n };\n } catch {\n /* fall through to warn */\n }\n }\n return {\n id: \"tokenizer\",\n label: \"tokenizer \",\n level: \"warn\",\n detail:\n \"data/deepseek-tokenizer.json.gz not found — token counts will fall back to char heuristics\",\n };\n}\n\nasync function checkSessions(): Promise<Check> {\n try {\n const list = listSessions();\n if (list.length === 0) {\n return {\n id: \"sessions\",\n label: \"sessions \",\n level: \"ok\",\n detail: \"0 saved\",\n };\n }\n const totalBytes = list.reduce((s, e) => s + e.size, 0);\n const oldest = list[list.length - 1]!;\n const ageDays = Math.floor((Date.now() - oldest.mtime.getTime()) / (24 * 60 * 60 * 1000));\n const stale = list.filter(\n (e) => Date.now() - e.mtime.getTime() >= 90 * 24 * 60 * 60 * 1000,\n ).length;\n const detail = `${list.length} saved · ${fmtBytes(totalBytes)} · oldest ${ageDays}d`;\n if (stale > 0) {\n return {\n id: \"sessions\",\n label: \"sessions \",\n level: \"warn\",\n detail: `${detail} · ${stale} idle ≥90d (run \\`reasonix prune-sessions\\`)`,\n };\n }\n return { id: \"sessions\", label: \"sessions \", level: \"ok\", detail };\n } catch (err) {\n return {\n id: \"sessions\",\n label: \"sessions \",\n level: \"warn\",\n detail: t(\"doctorErrors.cannotList\", { message: (err as Error).message }),\n };\n }\n}\n\nasync function checkHooks(projectRoot: string): Promise<Check> {\n try {\n const all = loadHooks({ projectRoot });\n const global = all.filter((h) => h.scope === \"global\").length;\n const project = all.filter((h) => h.scope === \"project\").length;\n return {\n id: \"hooks\",\n label: \"hooks \",\n level: \"ok\",\n detail: `${global} global, ${project} project`,\n };\n } catch (err) {\n return {\n id: \"hooks\",\n label: \"hooks \",\n level: \"warn\",\n detail: t(\"doctorErrors.parseFailed\", { message: (err as Error).message }),\n };\n }\n}\n\nasync function checkOllama(projectRoot: string): Promise<Check> {\n let exists = false;\n try {\n exists = await indexExists(projectRoot);\n } catch {\n /* treat as no index */\n }\n if (!exists) {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"ok\",\n detail: \"not in use (no semantic index built; `reasonix index` to enable)\",\n };\n }\n const meta = readSemanticMeta(projectRoot);\n if (meta?.provider === \"openai-compat\") {\n const resolved = resolveSemanticEmbeddingConfig();\n if (resolved.provider !== \"openai-compat\") {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"warn\",\n detail: `index uses openai-compat/${meta.model} but current config resolves to ${resolved.provider}/${resolved.model} — rebuild before searching`,\n };\n }\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"ok\",\n detail: `openai-compat · ${resolved.baseUrl} · model ${resolved.model} · api key configured`,\n };\n }\n try {\n const model = meta?.model || process.env.REASONIX_EMBED_MODEL || \"nomic-embed-text\";\n const status = await checkOllamaStatus(model);\n if (!status.binaryFound) {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"warn\",\n detail:\n \"ollama binary not on PATH — semantic_search will fail; install from https://ollama.com\",\n };\n }\n if (!status.daemonRunning) {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"warn\",\n detail:\n \"ollama daemon not running — `ollama serve` (or call /semantic in TUI to auto-start)\",\n };\n }\n if (!status.modelPulled) {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"warn\",\n detail: `model ${status.modelName} not pulled — \\`ollama pull ${status.modelName}\\``,\n };\n }\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"ok\",\n detail: `ollama daemon up · model ${status.modelName} ready`,\n };\n } catch (err) {\n return {\n id: \"semantic\",\n label: \"semantic \",\n level: \"warn\",\n detail: t(\"doctorErrors.probeFailed\", { message: (err as Error).message }),\n };\n }\n}\n\nfunction readSemanticMeta(\n projectRoot: string,\n): { provider: \"ollama\" | \"openai-compat\"; model: string } | null {\n try {\n const raw = readFileSync(join(projectRoot, \".reasonix\", \"semantic\", \"index.meta.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { provider?: string; model?: string };\n return {\n provider: parsed.provider === \"openai-compat\" ? \"openai-compat\" : \"ollama\",\n model: typeof parsed.model === \"string\" ? parsed.model : \"\",\n };\n } catch {\n return null;\n }\n}\n\nasync function checkProject(projectRoot: string): Promise<Check> {\n // Heuristic: a \"real\" project has either .git, REASONIX.md, or\n // package.json. Lacking all three, `reasonix code` still works but\n // @-mentions and the project-memory pin won't surface much.\n const markers = [\".git\", \"REASONIX.md\", \"package.json\", \"pyproject.toml\", \"Cargo.toml\", \"go.mod\"];\n const found = markers.filter((m) => existsSync(join(projectRoot, m)));\n if (found.length === 0) {\n return {\n id: \"project\",\n label: \"project \",\n level: \"warn\",\n detail: `${projectRoot} has none of: ${markers.slice(0, 3).join(\", \")} … — \\`reasonix code\\` will still run, but @-mentions and project memory have nothing to anchor`,\n };\n }\n return {\n id: \"project\",\n label: \"project \",\n level: \"ok\",\n detail: `${projectRoot} (${found.join(\", \")})`,\n };\n}\n\nexport function formatDoctorJson(checks: DoctorCheck[], version: string): string {\n const ok = checks.filter((c) => c.level === \"ok\").length;\n const warn = checks.filter((c) => c.level === \"warn\").length;\n const fail = checks.filter((c) => c.level === \"fail\").length;\n return JSON.stringify({\n version,\n summary: { ok, warn, fail },\n checks: checks.map((c) => ({ id: c.id, status: c.level, message: c.detail })),\n });\n}\n\nexport async function doctorCommand(opts: DoctorOptions = {}): Promise<void> {\n loadDotenv();\n\n const projectRoot = resolve(process.cwd());\n const json = !!opts.json;\n\n if (!json) {\n console.log(`${color(`reasonix ${VERSION} · doctor`, \"1\")} (cwd: ${projectRoot})`);\n console.log(` home: ${homedir()}`);\n console.log(\"\");\n }\n\n // Run independent checks in parallel — saves ~5s when api-reach has\n // to time out. Each handler swallows its own throws into a `fail`\n // result so a thrown promise can't kill the whole report.\n const checks = await runDoctorChecks(projectRoot);\n\n const ok = checks.filter((c) => c.level === \"ok\").length;\n const warn = checks.filter((c) => c.level === \"warn\").length;\n const fail = checks.filter((c) => c.level === \"fail\").length;\n\n if (json) {\n console.log(formatDoctorJson(checks, VERSION));\n if (fail > 0) process.exit(1);\n return;\n }\n\n for (const c of checks) {\n console.log(` ${badge(c.level)} ${c.label} ${c.detail}`);\n }\n\n console.log(\"\");\n const summary = `${ok} ok · ${warn} warn · ${fail} fail`;\n if (fail > 0) {\n console.log(color(summary, \"31\"));\n process.exit(1);\n } else if (warn > 0) {\n console.log(color(summary, \"33\"));\n } else {\n console.log(color(summary, \"32\"));\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/retry.ts","../../src/client.ts"],"sourcesContent":["/** No retry on aborts or mid-stream body errors — re-billing the user for desynced output is worse than failing. */\n\nexport interface RetryOptions {\n /** Maximum total attempts (including the first). Default 4. */\n maxAttempts?: number;\n /** Initial backoff in ms. Doubles each retry, with jitter. Default 500. */\n initialBackoffMs?: number;\n /** Upper bound on any single backoff delay. Default 10000 (10s). */\n maxBackoffMs?: number;\n /** HTTP statuses to treat as retryable. Default [408, 429, 500, 502, 503, 504]. */\n retryableStatuses?: readonly number[];\n /** Abort signal; we do NOT retry once aborted. */\n signal?: AbortSignal;\n /** Telemetry hook — called before each wait. */\n onRetry?: (info: RetryInfo) => void;\n}\n\nexport interface RetryInfo {\n attempt: number;\n reason: string;\n waitMs: number;\n}\n\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504] as const;\n\nexport async function fetchWithRetry(\n fetchFn: typeof fetch,\n url: string,\n init: RequestInit,\n opts: RetryOptions = {},\n): Promise<Response> {\n const maxAttempts = opts.maxAttempts ?? 4;\n const initial = opts.initialBackoffMs ?? 500;\n const cap = opts.maxBackoffMs ?? 10_000;\n const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (opts.signal?.aborted) throw new Error(\"aborted\");\n\n try {\n const resp = await fetchFn(url, init);\n\n // Success or non-retryable failure: return as-is.\n if (resp.ok || !retryable.has(resp.status)) return resp;\n\n // Retryable but out of attempts: return the last response so the caller\n // can surface the status to the user.\n if (attempt === maxAttempts - 1) return resp;\n\n // Drain the body so the connection can be reused on the next attempt.\n await resp.text().catch(() => undefined);\n\n const waitMs = computeWait(attempt, initial, cap, resp.headers.get(\"Retry-After\"));\n opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });\n await sleep(waitMs, opts.signal);\n } catch (err) {\n lastError = err;\n // Respect explicit aborts — do not retry.\n if (isAbortError(err) || opts.signal?.aborted) throw err;\n if (attempt === maxAttempts - 1) throw err;\n\n const waitMs = computeWait(attempt, initial, cap, null);\n opts.onRetry?.({\n attempt: attempt + 1,\n reason: `network: ${messageOf(err)}`,\n waitMs,\n });\n await sleep(waitMs, opts.signal);\n }\n }\n\n throw lastError ?? new Error(\"fetchWithRetry: loop exited unexpectedly\");\n}\n\nfunction computeWait(\n attempt: number,\n initial: number,\n cap: number,\n retryAfter: string | null,\n): number {\n if (retryAfter) {\n const seconds = Number.parseFloat(retryAfter);\n if (Number.isFinite(seconds) && seconds > 0) {\n return Math.min(seconds * 1000, cap);\n }\n }\n const exp = initial * 2 ** attempt;\n // Jitter range [75%, 125%] to spread retries out when many clients hit 429 together.\n const jitter = exp * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(jitter, 0), cap);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n if (signal) {\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const name = (err as { name?: unknown }).name;\n return name === \"AbortError\";\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof Error) return err.message;\n try {\n return String(err);\n } catch {\n return \"unknown error\";\n }\n}\n","import { type EventSourceMessage, createParser } from \"eventsource-parser\";\nimport { loadRateLimit } from \"./config.js\";\nimport { type RetryOptions, fetchWithRetry } from \"./retry.js\";\nimport type { ChatMessage, ChatRequestOptions, RawUsage, ToolCall, ToolSpec } from \"./types.js\";\n\nexport class Usage {\n constructor(\n public promptTokens = 0,\n public completionTokens = 0,\n public totalTokens = 0,\n public promptCacheHitTokens = 0,\n public promptCacheMissTokens = 0,\n ) {}\n\n get cacheHitRatio(): number {\n const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;\n return denom > 0 ? this.promptCacheHitTokens / denom : 0;\n }\n\n static fromApi(raw: RawUsage | undefined | null): Usage {\n const u = raw ?? {};\n const promptTokens = u.prompt_tokens ?? 0;\n const cacheHitTokens = u.prompt_cache_hit_tokens ?? 0;\n const cacheMissTokens =\n u.prompt_cache_miss_tokens ?? Math.max(0, promptTokens - cacheHitTokens);\n return new Usage(\n promptTokens,\n u.completion_tokens ?? 0,\n u.total_tokens ?? 0,\n cacheHitTokens,\n cacheMissTokens,\n );\n }\n}\n\nexport interface ChatResponse {\n content: string;\n reasoningContent: string | null;\n toolCalls: ToolCall[];\n usage: Usage;\n raw: unknown;\n}\n\nexport interface StreamChunk {\n contentDelta?: string;\n reasoningDelta?: string;\n toolCallDelta?: { index: number; id?: string; name?: string; argumentsDelta?: string };\n usage?: Usage;\n finishReason?: string;\n raw: any;\n}\n\nexport interface BalanceInfo {\n currency: string;\n total_balance: string;\n granted_balance?: string;\n topped_up_balance?: string;\n}\n\nexport interface UserBalance {\n is_available: boolean;\n balance_infos: BalanceInfo[];\n}\n\n/** Largest `total_balance` wins — the wallet the user actually paid for and expects to see ticking down. */\nexport function pickPrimaryBalance(infos: ReadonlyArray<BalanceInfo>): BalanceInfo | null {\n if (infos.length === 0) return null;\n let best = infos[0]!;\n for (let i = 1; i < infos.length; i++) {\n if (Number(infos[i]!.total_balance) > Number(best.total_balance)) best = infos[i]!;\n }\n return best;\n}\n\nexport interface ModelInfo {\n id: string;\n object: \"model\";\n owned_by: string;\n}\n\nexport interface ModelList {\n object: \"list\";\n data: ModelInfo[];\n}\n\nexport interface DeepSeekClientOptions {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n rateLimit?: { rpm?: number };\n /** Retry configuration. Pass `{ maxAttempts: 1 }` to disable retries. */\n retry?: RetryOptions;\n}\n\nexport class DeepSeekClient {\n readonly apiKey: string;\n readonly baseUrl: string;\n readonly timeoutMs: number;\n readonly retry: RetryOptions;\n private readonly _fetch: typeof fetch;\n private readonly minChatIntervalMs: number;\n private nextChatRequestAt = 0;\n\n constructor(opts: DeepSeekClientOptions = {}) {\n const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient.\",\n );\n }\n this.apiKey = apiKey;\n let url = opts.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? \"https://api.deepseek.com\";\n // Manual trim — `/\\/+$/` is O(n²) on slash-heavy non-matches per CodeQL js/polynomial-redos.\n while (url.endsWith(\"/\")) url = url.slice(0, -1);\n this.baseUrl = url;\n // 11 min. DeepSeek's load-balancer may keep a connection open for\n // up to 10 minutes while the request waits in queue (non-streaming\n // sends empty lines, streaming sends `:` SSE keep-alive comments —\n // both are invisible to our parsers, so neither surfaces until the\n // real response starts). Timing out at the legacy 2-min default\n // killed queued requests prematurely, burned the queue slot on\n // retry, and could loop through the whole queue repeatedly.\n // Setting 11 min lets the server's own 10-min cap close the\n // connection first (clean EOF → natural retry), and our timer\n // is a safety net for genuinely hung sockets.\n this.timeoutMs = opts.timeoutMs ?? 660_000;\n this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.retry = opts.retry ?? {};\n const rpm = opts.rateLimit?.rpm ?? loadRateLimit()?.rpm;\n this.minChatIntervalMs = rpm ? Math.ceil(60_000 / rpm) : 0;\n }\n\n private async waitForChatRateLimit(signal?: AbortSignal): Promise<void> {\n if (this.minChatIntervalMs <= 0) return;\n const now = Date.now();\n const waitMs = Math.max(0, this.nextChatRequestAt - now);\n this.nextChatRequestAt = Math.max(now, this.nextChatRequestAt) + this.minChatIntervalMs;\n if (waitMs <= 0) return;\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, waitMs);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true },\n );\n });\n }\n\n private buildPayload(opts: ChatRequestOptions, stream: boolean) {\n const payload: Record<string, unknown> = {\n model: opts.model,\n messages: opts.messages,\n stream,\n };\n if (opts.tools?.length) payload.tools = opts.tools;\n if (opts.temperature !== undefined) payload.temperature = opts.temperature;\n if (opts.maxTokens !== undefined) payload.max_tokens = opts.maxTokens;\n if (opts.responseFormat) payload.response_format = opts.responseFormat;\n // V4 thinking-mode toggle: lives under `extra_body.thinking.type` per\n // DeepSeek's docs. Docs also note that in thinking mode `temperature`,\n // `top_p`, `presence_penalty`, `frequency_penalty` are silently\n // ignored — we don't strip them here because the server's explicit\n // \"setting won't report an error\" contract means leaving them in is\n // safe and keeps the request payload diffable against OpenAI tooling.\n if (opts.thinking && !this._isAzureEndpoint()) {\n payload.extra_body = { thinking: { type: opts.thinking } };\n }\n if (opts.reasoningEffort) {\n payload.reasoning_effort = opts.reasoningEffort;\n }\n return payload;\n }\n\n /** Azure OpenAI-compatible endpoints do not accept DeepSeek's proprietary\n * `extra_body.thinking` field (they reject the request with 400). We still\n * send `reasoning_effort`, which Azure *does* support. */\n private _isAzureEndpoint(): boolean {\n try {\n const host = new URL(this.baseUrl).hostname;\n return host === \"azure.com\" || host.endsWith(\".azure.com\");\n } catch {\n return false;\n }\n }\n\n /** Returns null on failure so callers can degrade — session must keep working without balance UI. */\n async getBalance(opts: { signal?: AbortSignal } = {}): Promise<UserBalance | null> {\n try {\n const resp = await this._fetch(`${this.baseUrl}/user/balance`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n signal: opts.signal,\n });\n if (!resp.ok) return null;\n const data = (await resp.json()) as UserBalance;\n if (!data || !Array.isArray(data.balance_infos)) return null;\n return data;\n } catch {\n return null;\n }\n }\n\n /** Returns null on failure — callers fall back to a hardcoded model hint. */\n async listModels(opts: { signal?: AbortSignal } = {}): Promise<ModelList | null> {\n try {\n const resp = await this._fetch(`${this.baseUrl}/models`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n signal: opts.signal,\n });\n if (!resp.ok) return null;\n const data = (await resp.json()) as ModelList;\n if (!data || !Array.isArray(data.data)) return null;\n return data;\n } catch {\n return null;\n }\n }\n\n async chat(opts: ChatRequestOptions): Promise<ChatResponse> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n try {\n await this.waitForChatRateLimit(signal);\n const resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(this.buildPayload(opts, false)),\n signal,\n },\n { ...this.retry, signal },\n );\n if (!resp.ok) {\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);\n }\n const data: any = await resp.json();\n const choice = data.choices?.[0]?.message ?? {};\n return {\n content: choice.content ?? \"\",\n reasoningContent: choice.reasoning_content ?? null,\n toolCalls: choice.tool_calls ?? [],\n usage: Usage.fromApi(data.usage),\n raw: data,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n async *stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n let resp: Response;\n try {\n await this.waitForChatRateLimit(signal);\n // Only the initial fetch is retried. Once the server has started sending\n // the stream body we do NOT retry — a mid-stream retry would re-bill and\n // desync the session context.\n resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(this.buildPayload(opts, true)),\n signal,\n },\n { ...this.retry, signal },\n );\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n if (!resp.ok || !resp.body) {\n clearTimeout(timer);\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => \"\")}`);\n }\n\n const queue: StreamChunk[] = [];\n let done = false;\n const parser = createParser({\n onEvent: (ev: EventSourceMessage) => {\n if (!ev.data || ev.data === \"[DONE]\") {\n done = true;\n return;\n }\n try {\n const json = JSON.parse(ev.data);\n const delta = json.choices?.[0]?.delta ?? {};\n const finishReason = json.choices?.[0]?.finish_reason ?? undefined;\n const chunk: StreamChunk = { raw: json, finishReason };\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n chunk.contentDelta = delta.content;\n }\n if (typeof delta.reasoning_content === \"string\" && delta.reasoning_content.length > 0) {\n chunk.reasoningDelta = delta.reasoning_content;\n }\n if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {\n const tc = delta.tool_calls[0];\n chunk.toolCallDelta = {\n index: tc.index ?? 0,\n id: tc.id,\n name: tc.function?.name,\n argumentsDelta: tc.function?.arguments,\n };\n }\n if (json.usage) {\n chunk.usage = Usage.fromApi(json.usage);\n }\n queue.push(chunk);\n } catch {\n /* skip malformed sse frame */\n }\n },\n });\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n try {\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n if (done) break;\n const { value, done: streamDone } = await reader.read();\n if (streamDone) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n while (queue.length > 0) yield queue.shift()!;\n } finally {\n clearTimeout(timer);\n reader.releaseLock();\n }\n }\n}\n\nexport type { ChatMessage, ToolCall, ToolSpec };\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../node_modules/emoji-regex/index.mjs","../../node_modules/string-width/index.js","../../src/cli/ui/primitives.tsx"],"sourcesContent":["export default () => {\n\t// https://mths.be/emoji\n\treturn /[#*0-9]\\uFE0F?\\u20E3|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]\\uFE0F?|[\\u261D\\u270C\\u270D](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\u270A\\u270B](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u2693\\u26A1\\u26AB\\u26C5\\u26CE\\u26D4\\u26EA\\u26FD\\u2705\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2795-\\u2797\\u27B0\\u27BF\\u2B50]|\\u26D3\\uFE0F?(?:\\u200D\\uD83D\\uDCA5)?|\\u26F9(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\u2764\\uFE0F?(?:\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79))?|\\uD83C(?:[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]\\uFE0F?|[\\uDF85\\uDFC2\\uDFC7](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDFC4\\uDFCA](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDFCB\\uDFCC](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF43\\uDF45-\\uDF4A\\uDF4C-\\uDF7C\\uDF7E-\\uDF84\\uDF86-\\uDF93\\uDFA0-\\uDFC1\\uDFC5\\uDFC6\\uDFC8\\uDFC9\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF8-\\uDFFF]|\\uDDE6\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF]|\\uDDE7\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF]|\\uDDE8\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF7\\uDDFA-\\uDDFF]|\\uDDE9\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF]|\\uDDEA\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA]|\\uDDEB\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7]|\\uDDEC\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE]|\\uDDED\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA]|\\uDDEE\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9]|\\uDDEF\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5]|\\uDDF0\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF]|\\uDDF1\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE]|\\uDDF2\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF]|\\uDDF3\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF]|\\uDDF4\\uD83C\\uDDF2|\\uDDF5\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE]|\\uDDF6\\uD83C\\uDDE6|\\uDDF7\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC]|\\uDDF8\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF]|\\uDDF9\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF]|\\uDDFA\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF]|\\uDDFB\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA]|\\uDDFC\\uD83C[\\uDDEB\\uDDF8]|\\uDDFD\\uD83C\\uDDF0|\\uDDFE\\uD83C[\\uDDEA\\uDDF9]|\\uDDFF\\uD83C[\\uDDE6\\uDDF2\\uDDFC]|\\uDF44(?:\\u200D\\uD83D\\uDFEB)?|\\uDF4B(?:\\u200D\\uD83D\\uDFE9)?|\\uDFC3(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDFF3\\uFE0F?(?:\\u200D(?:\\u26A7\\uFE0F?|\\uD83C\\uDF08))?|\\uDFF4(?:\\u200D\\u2620\\uFE0F?|\\uDB40\\uDC67\\uDB40\\uDC62\\uDB40(?:\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67|\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73)\\uDB40\\uDC7F)?)|\\uD83D(?:[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3]\\uFE0F?|[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDC6E-\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4\\uDEB5](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD74\\uDD90](?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?|[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC25\\uDC27-\\uDC3A\\uDC3C-\\uDC3E\\uDC40\\uDC44\\uDC45\\uDC51-\\uDC65\\uDC6A\\uDC79-\\uDC7B\\uDC7D-\\uDC80\\uDC84\\uDC88-\\uDC8E\\uDC90\\uDC92-\\uDCA9\\uDCAB-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDDA4\\uDDFB-\\uDE2D\\uDE2F-\\uDE34\\uDE37-\\uDE41\\uDE43\\uDE44\\uDE48-\\uDE4A\\uDE80-\\uDEA2\\uDEA4-\\uDEB3\\uDEB7-\\uDEBF\\uDEC1-\\uDEC5\\uDED0-\\uDED2\\uDED5-\\uDED8\\uDEDC-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uDC08(?:\\u200D\\u2B1B)?|\\uDC15(?:\\u200D\\uD83E\\uDDBA)?|\\uDC26(?:\\u200D(?:\\u2B1B|\\uD83D\\uDD25))?|\\uDC3B(?:\\u200D\\u2744\\uFE0F?)?|\\uDC41\\uFE0F?(?:\\u200D\\uD83D\\uDDE8\\uFE0F?)?|\\uDC68(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDC68\\uDC69]\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?)|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFC-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?\\uDC68\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDD1D\\uDEEF]\\u200D\\uD83D\\uDC68\\uD83C[\\uDFFB-\\uDFFE]|[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3])))?))?|\\uDC69(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:\\uDC8B\\u200D\\uD83D)?[\\uDC68\\uDC69]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?|\\uDC69\\u200D\\uD83D(?:\\uDC66(?:\\u200D\\uD83D\\uDC66)?|\\uDC67(?:\\u200D\\uD83D[\\uDC66\\uDC67])?))|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFC-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D\\uD83D(?:[\\uDC68\\uDC69]|\\uDC8B\\u200D\\uD83D[\\uDC68\\uDC69])\\uD83C[\\uDFFB-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3]|\\uDD1D\\u200D\\uD83D[\\uDC68\\uDC69]\\uD83C[\\uDFFB-\\uDFFE]|\\uDEEF\\u200D\\uD83D\\uDC69\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDD75(?:\\uD83C[\\uDFFB-\\uDFFF]|\\uFE0F)?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|\\uDE2E(?:\\u200D\\uD83D\\uDCA8)?|\\uDE35(?:\\u200D\\uD83D\\uDCAB)?|\\uDE36(?:\\u200D\\uD83C\\uDF2B\\uFE0F?)?|\\uDE42(?:\\u200D[\\u2194\\u2195]\\uFE0F?)?|\\uDEB6(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?)|\\uD83E(?:[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF8](?:\\uD83C[\\uDFFB-\\uDFFF])?|[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD\\uDDCF\\uDDD4\\uDDD6-\\uDDDD](?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDDDE\\uDDDF](?:\\u200D[\\u2640\\u2642]\\uFE0F?)?|[\\uDD0D\\uDD0E\\uDD10-\\uDD17\\uDD20-\\uDD25\\uDD27-\\uDD2F\\uDD3A\\uDD3F-\\uDD45\\uDD47-\\uDD76\\uDD78-\\uDDB4\\uDDB7\\uDDBA\\uDDBC-\\uDDCC\\uDDD0\\uDDE0-\\uDDFF\\uDE70-\\uDE7C\\uDE80-\\uDE8A\\uDE8E-\\uDEC2\\uDEC6\\uDEC8\\uDECD-\\uDEDC\\uDEDF-\\uDEEA\\uDEEF]|\\uDDCE(?:\\uD83C[\\uDFFB-\\uDFFF])?(?:\\u200D(?:[\\u2640\\u2642]\\uFE0F?(?:\\u200D\\u27A1\\uFE0F?)?|\\u27A1\\uFE0F?))?|\\uDDD1(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1|\\uDDD1\\u200D\\uD83E\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?|\\uDDD2(?:\\u200D\\uD83E\\uDDD2)?))|\\uD83C(?:\\uDFFB(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFC-\\uDFFF])))?|\\uDFFC(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])))?|\\uDFFD(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])))?|\\uDFFE(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])))?|\\uDFFF(?:\\u200D(?:[\\u2695\\u2696\\u2708]\\uFE0F?|\\u2764\\uFE0F?\\u200D(?:\\uD83D\\uDC8B\\u200D)?\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D(?:[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uDC30\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])|\\uD83E(?:[\\uDDAF\\uDDBC\\uDDBD](?:\\u200D\\u27A1\\uFE0F?)?|[\\uDDB0-\\uDDB3\\uDE70]|\\uDD1D\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFF]|\\uDEEF\\u200D\\uD83E\\uDDD1\\uD83C[\\uDFFB-\\uDFFE])))?))?|\\uDEF1(?:\\uD83C(?:\\uDFFB(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFC-\\uDFFF])?|\\uDFFC(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])?|\\uDFFD(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])?|\\uDFFE(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])?|\\uDFFF(?:\\u200D\\uD83E\\uDEF2\\uD83C[\\uDFFB-\\uDFFE])?))?)/g;\n};\n","import stripAnsi from 'strip-ansi';\nimport {eastAsianWidth} from 'get-east-asian-width';\nimport emojiRegex from 'emoji-regex';\n\nconst segmenter = new Intl.Segmenter();\n\nconst defaultIgnorableCodePointRegex = /^\\p{Default_Ignorable_Code_Point}$/u;\n\nexport default function stringWidth(string, options = {}) {\n\tif (typeof string !== 'string' || string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tconst {\n\t\tambiguousIsNarrow = true,\n\t\tcountAnsiEscapeCodes = false,\n\t} = options;\n\n\tif (!countAnsiEscapeCodes) {\n\t\tstring = stripAnsi(string);\n\t}\n\n\tif (string.length === 0) {\n\t\treturn 0;\n\t}\n\n\tlet width = 0;\n\tconst eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};\n\n\tfor (const {segment: character} of segmenter.segment(string)) {\n\t\tconst codePoint = character.codePointAt(0);\n\n\t\t// Ignore control characters\n\t\tif (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore zero-width characters\n\t\tif (\n\t\t\t(codePoint >= 0x20_0B && codePoint <= 0x20_0F) // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark\n\t\t\t|| codePoint === 0xFE_FF // Zero-width no-break space\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore combining characters\n\t\tif (\n\t\t\t(codePoint >= 0x3_00 && codePoint <= 0x3_6F) // Combining diacritical marks\n\t\t\t|| (codePoint >= 0x1A_B0 && codePoint <= 0x1A_FF) // Combining diacritical marks extended\n\t\t\t|| (codePoint >= 0x1D_C0 && codePoint <= 0x1D_FF) // Combining diacritical marks supplement\n\t\t\t|| (codePoint >= 0x20_D0 && codePoint <= 0x20_FF) // Combining diacritical marks for symbols\n\t\t\t|| (codePoint >= 0xFE_20 && codePoint <= 0xFE_2F) // Combining half marks\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore surrogate pairs\n\t\tif (codePoint >= 0xD8_00 && codePoint <= 0xDF_FF) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Ignore variation selectors\n\t\tif (codePoint >= 0xFE_00 && codePoint <= 0xFE_0F) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// This covers some of the above cases, but we still keep them for performance reasons.\n\t\tif (defaultIgnorableCodePointRegex.test(character)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TODO: Use `/\\p{RGI_Emoji}/v` when targeting Node.js 20.\n\t\tif (emojiRegex().test(character)) {\n\t\t\twidth += 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\twidth += eastAsianWidth(codePoint, eastAsianWidthOptions);\n\t}\n\n\treturn width;\n}\n","import { Text, useStdout } from \"ink\";\n// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React from \"react\";\nimport { t } from \"../../i18n/index.js\";\nimport { COLOR } from \"./theme.js\";\n\n/**\n * Faint full-width horizontal rule. Width tracks the terminal columns\n * minus 2 cells so it lines up exactly under content rendered inside\n * a `paddingX={1}` parent — the standard chrome layout. Used by the\n * top chrome bar, the replay StatsPanel, and the bottom ctx footer.\n */\nexport function ChromeRule(): React.ReactElement {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const w = Math.max(20, cols - 2);\n return <Text dimColor>{\"─\".repeat(w)}</Text>;\n}\n\n/** Compact decimal-K token formatter — `1234 → \"1.2K\"`, `131000 → \"131K\"`. Base-1000 matches DeepSeek's \"1M context\" / \"128K\" wording and the web dashboard's display, so the CLI bottom bar and the web bar agree on ctx capacity. */\nexport function formatTokens(n: number): string {\n if (n < 1000) return String(n);\n const k = n / 1000;\n return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;\n}\n\n/**\n * Filled / empty progress bar. `▰▱` glyphs have distinct shapes so the\n * boundary stays visible even when the terminal collapses to 8-color slots.\n */\nexport function Bar({\n ratio,\n color,\n cells = 14,\n dim,\n}: {\n ratio: number;\n color: string;\n cells?: number;\n dim?: boolean;\n}): React.ReactElement {\n const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));\n return (\n <Text>\n <Text color={color} dimColor={dim}>\n {\"▰\".repeat(filled)}\n </Text>\n <Text dimColor>{\"▱\".repeat(cells - filled)}</Text>\n </Text>\n );\n}\n\n/**\n * `▣ ctx ▰▰▱▱… 14K/128K (11%)` — the canonical context-pressure cell.\n * Used by the persistent footer (chat) and StatsPanel (replay). Color\n * thresholds match the `/compact` warning policy in the loop:\n * green <60% · amber 60-80% · red ≥80% (with `· /compact` hint).\n */\nexport function ContextCell({\n ratio,\n promptTokens,\n ctxMax,\n showBar,\n}: {\n ratio: number;\n promptTokens: number;\n ctxMax: number;\n showBar?: boolean;\n}): React.ReactElement {\n if (promptTokens === 0) {\n return (\n <Text>\n <Text color={COLOR.info} dimColor>\n {\"▣ ctx \"}\n </Text>\n <Text dimColor>{`\\u2014 ${t(\"common.noTurns\")}`}</Text>\n </Text>\n );\n }\n const color = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;\n const pct = Math.round(ratio * 100);\n return (\n <Text>\n <Text color={COLOR.info}>{\"▣ ctx \"}</Text>\n <Bar ratio={ratio} color={color} cells={showBar ? 14 : 10} />\n <Text> </Text>\n <Text color={color} bold>\n {formatTokens(promptTokens)}/{formatTokens(ctxMax)}\n </Text>\n <Text dimColor> ({pct}%)</Text>\n {ratio >= 0.8 ? (\n <Text color={COLOR.err} bold>\n {\" · /compact\"}\n </Text>\n ) : null}\n </Text>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,IAAO,sBAAQ,MAAM;AAEpB,SAAO;AACR;;;ACCA,IAAM,YAAY,IAAI,KAAK,UAAU;AAErC,IAAM,iCAAiC,WAAC,uCAAmC,GAAC;AAE7D,SAAR,YAA6B,QAAQ,UAAU,CAAC,GAAG;AACzD,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;AACtD,WAAO;AAAA,EACR;AAEA,QAAM;AAAA,IACL,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,EACxB,IAAI;AAEJ,MAAI,CAAC,sBAAsB;AAC1B,aAAS,UAAU,MAAM;AAAA,EAC1B;AAEA,MAAI,OAAO,WAAW,GAAG;AACxB,WAAO;AAAA,EACR;AAEA,MAAI,QAAQ;AACZ,QAAM,wBAAwB,EAAC,iBAAiB,CAAC,kBAAiB;AAElE,aAAW,EAAC,SAAS,UAAS,KAAK,UAAU,QAAQ,MAAM,GAAG;AAC7D,UAAM,YAAY,UAAU,YAAY,CAAC;AAGzC,QAAI,aAAa,MAAS,aAAa,OAAQ,aAAa,KAAO;AAClE;AAAA,IACD;AAGA,QACE,aAAa,QAAW,aAAa,QACnC,cAAc,OAChB;AACD;AAAA,IACD;AAGA,QACE,aAAa,OAAU,aAAa,OACjC,aAAa,QAAW,aAAa,QACrC,aAAa,QAAW,aAAa,QACrC,aAAa,QAAW,aAAa,QACrC,aAAa,SAAW,aAAa,OACxC;AACD;AAAA,IACD;AAGA,QAAI,aAAa,SAAW,aAAa,OAAS;AACjD;AAAA,IACD;AAGA,QAAI,aAAa,SAAW,aAAa,OAAS;AACjD;AAAA,IACD;AAGA,QAAI,+BAA+B,KAAK,SAAS,GAAG;AACnD;AAAA,IACD;AAGA,QAAI,oBAAW,EAAE,KAAK,SAAS,GAAG;AACjC,eAAS;AACT;AAAA,IACD;AAEA,aAAS,eAAe,WAAW,qBAAqB;AAAA,EACzD;AAEA,SAAO;AACR;;;AC/EA,mBAAkB;AAUX,SAAS,aAAiC;AAC/C,QAAM,EAAE,OAAO,IAAI,mBAAU;AAC7B,QAAM,OAAO,QAAQ,WAAW;AAChC,QAAM,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC;AAC/B,SAAO,6BAAAA,QAAA,cAAC,QAAK,UAAQ,QAAE,SAAI,OAAO,CAAC,CAAE;AACvC;AAGO,SAAS,aAAa,GAAmB;AAC9C,MAAI,IAAI,IAAM,QAAO,OAAO,CAAC;AAC7B,QAAM,IAAI,IAAI;AACd,SAAO,KAAK,MAAM,GAAG,EAAE,QAAQ,CAAC,CAAC,MAAM,GAAG,EAAE,QAAQ,CAAC,CAAC;AACxD;AAMO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AACF,GAKuB;AACrB,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,MAAM,QAAQ,KAAK,CAAC,CAAC;AACrE,SACE,6BAAAA,QAAA,cAAC,YACC,6BAAAA,QAAA,cAAC,QAAK,OAAc,UAAU,OAC3B,SAAI,OAAO,MAAM,CACpB,GACA,6BAAAA,QAAA,cAAC,QAAK,UAAQ,QAAE,SAAI,OAAO,QAAQ,MAAM,CAAE,CAC7C;AAEJ;","names":["React"]}