reasonix 0.41.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/dashboard/dist/app.js +98 -3
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{acp-64VQZLDJ.js → acp-DAGPCVFZ.js} +33 -28
- package/dist/cli/acp-DAGPCVFZ.js.map +1 -0
- package/dist/cli/chat-7ES4IBNH.js +50 -0
- package/dist/cli/{chunk-E46ECXJD.js → chunk-2425HK6U.js} +2 -1
- package/dist/cli/{chunk-E46ECXJD.js.map → chunk-2425HK6U.js.map} +1 -1
- package/dist/cli/chunk-25T6CVUP.js +172 -0
- package/dist/cli/chunk-25T6CVUP.js.map +1 -0
- package/dist/cli/{chunk-CD4SCQL4.js → chunk-2K65GZBT.js} +11 -2
- package/dist/cli/chunk-2K65GZBT.js.map +1 -0
- package/dist/cli/{chunk-H4OLWRSX.js → chunk-2KDUS647.js} +5 -4
- package/dist/cli/chunk-2KDUS647.js.map +1 -0
- package/dist/cli/chunk-2R4QCDOZ.js +11392 -0
- package/dist/cli/chunk-2R4QCDOZ.js.map +1 -0
- package/dist/cli/{chunk-3Q3C4W66.js → chunk-2UQP6H6T.js} +2 -1
- package/dist/cli/{chunk-3Q3C4W66.js.map → chunk-2UQP6H6T.js.map} +1 -1
- package/dist/cli/chunk-2Z35JOA4.js +96 -0
- package/dist/cli/chunk-2Z35JOA4.js.map +1 -0
- package/dist/cli/chunk-32TIKD5U.js +54 -0
- package/dist/cli/{chunk-L7W3HJZQ.js.map → chunk-32TIKD5U.js.map} +1 -1
- package/dist/cli/{chunk-A3LL4XDV.js → chunk-3BXRZFWS.js} +59 -3
- package/dist/cli/chunk-3BXRZFWS.js.map +1 -0
- package/dist/cli/{chunk-SXLJBFIV.js → chunk-3Z6IBU3D.js} +11 -7
- package/dist/cli/chunk-3Z6IBU3D.js.map +1 -0
- package/dist/cli/{chunk-A7VHMMDE.js → chunk-45U62RI3.js} +12 -5
- package/dist/cli/chunk-45U62RI3.js.map +1 -0
- package/dist/cli/{chunk-7VFNPMKG.js → chunk-4QUNBQQ2.js} +3 -2
- package/dist/cli/{chunk-7VFNPMKG.js.map → chunk-4QUNBQQ2.js.map} +1 -1
- package/dist/cli/{chunk-ARF3N2SY.js → chunk-5JJRUIPA.js} +4 -3
- package/dist/cli/{chunk-ARF3N2SY.js.map → chunk-5JJRUIPA.js.map} +1 -1
- package/dist/cli/{chunk-CFY2XLY6.js → chunk-6AK4EY3D.js} +7 -5
- package/dist/cli/{chunk-CFY2XLY6.js.map → chunk-6AK4EY3D.js.map} +1 -1
- package/dist/cli/chunk-6G3CUUFG.js +34320 -0
- package/dist/cli/chunk-6G3CUUFG.js.map +1 -0
- package/dist/cli/{chunk-YJFKFTAL.js → chunk-6PBZN4VI.js} +15 -3
- package/dist/cli/chunk-6PBZN4VI.js.map +1 -0
- package/dist/cli/{chunk-4W2CICFQ.js → chunk-6PZ3CXBP.js} +71 -60
- package/dist/cli/chunk-6PZ3CXBP.js.map +1 -0
- package/dist/cli/chunk-74EX7SUH.js +25293 -0
- package/dist/cli/chunk-74EX7SUH.js.map +1 -0
- package/dist/cli/{chunk-WE3YZULK.js → chunk-7O5ALB4C.js} +3 -2
- package/dist/cli/{chunk-WE3YZULK.js.map → chunk-7O5ALB4C.js.map} +1 -1
- package/dist/cli/{chunk-2CXPDAWX.js → chunk-DOYHN4KB.js} +3 -2
- package/dist/cli/{chunk-2CXPDAWX.js.map → chunk-DOYHN4KB.js.map} +1 -1
- package/dist/cli/{chunk-VFG4GIT3.js → chunk-F3PXYSNN.js} +3 -2
- package/dist/cli/{chunk-VFG4GIT3.js.map → chunk-F3PXYSNN.js.map} +1 -1
- package/dist/cli/{chunk-7SPOFTMT.js → chunk-FHOGSSCH.js} +4 -3
- package/dist/cli/{chunk-7SPOFTMT.js.map → chunk-FHOGSSCH.js.map} +1 -1
- package/dist/cli/{chunk-LTXADNCO.js → chunk-H6PS7IUE.js} +3 -2
- package/dist/cli/{chunk-LTXADNCO.js.map → chunk-H6PS7IUE.js.map} +1 -1
- package/dist/cli/{chunk-ZTLZO42A.js → chunk-HFEAY5DT.js} +3 -2
- package/dist/cli/{chunk-ZTLZO42A.js.map → chunk-HFEAY5DT.js.map} +1 -1
- package/dist/cli/{chunk-FWGEHRB7.js → chunk-J5XJHLWM.js} +2 -1
- package/dist/cli/{chunk-FWGEHRB7.js.map → chunk-J5XJHLWM.js.map} +1 -1
- package/dist/cli/{chunk-Y5XNV3NX.js → chunk-JMBMLOBP.js} +2 -1
- package/dist/cli/{chunk-Y5XNV3NX.js.map → chunk-JMBMLOBP.js.map} +1 -1
- package/dist/cli/{chunk-BYZGO3BX.js → chunk-O52OLQL3.js} +11 -3
- package/dist/cli/chunk-O52OLQL3.js.map +1 -0
- package/dist/cli/{chunk-4DCHFFEY.js → chunk-OSZC7C6F.js} +3 -2
- package/dist/cli/{chunk-4DCHFFEY.js.map → chunk-OSZC7C6F.js.map} +1 -1
- package/dist/cli/chunk-P7EKE5ZQ.js +60641 -0
- package/dist/cli/chunk-P7EKE5ZQ.js.map +1 -0
- package/dist/cli/{chunk-FM57FNPJ.js → chunk-PLHAZOLZ.js} +2 -1
- package/dist/cli/{chunk-FM57FNPJ.js.map → chunk-PLHAZOLZ.js.map} +1 -1
- package/dist/cli/{chunk-BOFL3T45.js → chunk-PQXPXJBJ.js} +12 -11
- package/dist/cli/chunk-PQXPXJBJ.js.map +1 -0
- package/dist/cli/{chunk-DAEAAVDF.js → chunk-PV55UMTO.js} +2 -1
- package/dist/cli/{chunk-DAEAAVDF.js.map → chunk-PV55UMTO.js.map} +1 -1
- package/dist/cli/{chunk-MHGPBJ2T.js → chunk-RE4RAVFF.js} +45 -10
- package/dist/cli/chunk-RE4RAVFF.js.map +1 -0
- package/dist/cli/chunk-S4XVGLRW.js +499 -0
- package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
- package/dist/cli/{chunk-WJ3YX4PZ.js → chunk-SZ5XES2N.js} +3 -2
- package/dist/cli/{chunk-WJ3YX4PZ.js.map → chunk-SZ5XES2N.js.map} +1 -1
- package/dist/cli/{chunk-UV7XJUJH.js → chunk-TJX6BFZZ.js} +16 -9
- package/dist/cli/{chunk-UV7XJUJH.js.map → chunk-TJX6BFZZ.js.map} +1 -1
- package/dist/cli/chunk-TUK7OWJA.js +51 -0
- package/dist/cli/{chunk-KZYLMMU5.js → chunk-VK5HG73G.js} +13 -12
- package/dist/cli/{chunk-KZYLMMU5.js.map → chunk-VK5HG73G.js.map} +1 -1
- package/dist/cli/{chunk-4H3ZRJ2U.js → chunk-XCGGEJTI.js} +4 -3
- package/dist/cli/{chunk-4H3ZRJ2U.js.map → chunk-XCGGEJTI.js.map} +1 -1
- package/dist/cli/{chunk-SOZE7V7V.js → chunk-XJXDHAES.js} +3 -2
- package/dist/cli/{chunk-SOZE7V7V.js.map → chunk-XJXDHAES.js.map} +1 -1
- package/dist/cli/chunk-XPDVG52A.js +2648 -0
- package/dist/cli/chunk-XPDVG52A.js.map +1 -0
- package/dist/cli/{chunk-CRPQUBP6.js → chunk-XXC2BYTV.js} +2 -1
- package/dist/cli/{chunk-CRPQUBP6.js.map → chunk-XXC2BYTV.js.map} +1 -1
- package/dist/cli/{chunk-AT6GGIBV.js → chunk-YFGF5NKA.js} +17 -14
- package/dist/cli/{chunk-AT6GGIBV.js.map → chunk-YFGF5NKA.js.map} +1 -1
- package/dist/cli/{chunk-ORM6PK57.js → chunk-YQ6NTIIE.js} +2 -1
- package/dist/cli/{chunk-ORM6PK57.js.map → chunk-YQ6NTIIE.js.map} +1 -1
- package/dist/cli/{chunk-RAUPWSYA.js → chunk-YYQAUTTN.js} +3 -2
- package/dist/cli/{chunk-RAUPWSYA.js.map → chunk-YYQAUTTN.js.map} +1 -1
- package/dist/cli/chunk-ZZM6QJ4W.js +109 -0
- package/dist/cli/chunk-ZZM6QJ4W.js.map +1 -0
- package/dist/cli/{code-X3M6ENTQ.js → code-SMKEW6CD.js} +60 -56
- package/dist/cli/code-SMKEW6CD.js.map +1 -0
- package/dist/cli/{commands-QY7MSQG7.js → commands-FVVB5FZF.js} +7 -5
- package/dist/cli/{commands-QY7MSQG7.js.map → commands-FVVB5FZF.js.map} +1 -1
- package/dist/cli/{commit-BRCQ3OQO.js → commit-HE4VSPZ7.js} +7 -4
- package/dist/cli/{commit-BRCQ3OQO.js.map → commit-HE4VSPZ7.js.map} +1 -1
- package/dist/cli/{desktop-ZTMHQR2Y.js → desktop-Q7NDXCON.js} +162 -74
- package/dist/cli/desktop-Q7NDXCON.js.map +1 -0
- package/dist/cli/devtools-YECO25QO.js +3719 -0
- package/dist/cli/devtools-YECO25QO.js.map +1 -0
- package/dist/cli/diff-435UTPC5.js +165 -0
- package/dist/cli/{diff-YASCB7PU.js.map → diff-435UTPC5.js.map} +1 -1
- package/dist/cli/doctor-OT7KH75K.js +27 -0
- package/dist/cli/{events-2AJTXR7I.js → events-XEFAD5VX.js} +6 -4
- package/dist/cli/{events-2AJTXR7I.js.map → events-XEFAD5VX.js.map} +1 -1
- package/dist/cli/index.js +3209 -133
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-YMWBLRR7.js → mcp-WUL2WO75.js} +6 -4
- package/dist/cli/{mcp-YMWBLRR7.js.map → mcp-WUL2WO75.js.map} +1 -1
- package/dist/cli/{mcp-browse-XLDUE6SB.js → mcp-browse-RR7R4XET.js} +32 -21
- package/dist/cli/{mcp-browse-XLDUE6SB.js.map → mcp-browse-RR7R4XET.js.map} +1 -1
- package/dist/cli/{mcp-inspect-H4D2HSJP.js → mcp-inspect-REGLYBWT.js} +8 -5
- package/dist/cli/{mcp-inspect-H4D2HSJP.js.map → mcp-inspect-REGLYBWT.js.map} +1 -1
- package/dist/cli/package.json +3 -0
- package/dist/cli/prompt-UW6EFLVR.js +16 -0
- package/dist/cli/{prune-sessions-4N3BVST2.js → prune-sessions-3RWUBYRS.js} +4 -2
- package/dist/cli/{prune-sessions-4N3BVST2.js.map → prune-sessions-3RWUBYRS.js.map} +1 -1
- package/dist/cli/{replay-3GTWM75X.js → replay-YOURXV4C.js} +42 -30
- package/dist/cli/{replay-3GTWM75X.js.map → replay-YOURXV4C.js.map} +1 -1
- package/dist/cli/{run-BLZPTRDX.js → run-Q6BUXV66.js} +24 -21
- package/dist/cli/{run-BLZPTRDX.js.map → run-Q6BUXV66.js.map} +1 -1
- package/dist/cli/{server-DRFPXXSH.js → server-XGDBRWMB.js} +40 -43
- package/dist/cli/server-XGDBRWMB.js.map +1 -0
- package/dist/cli/{sessions-BOWFPTXT.js → sessions-FH7QVYSY.js} +22 -19
- package/dist/cli/{sessions-BOWFPTXT.js.map → sessions-FH7QVYSY.js.map} +1 -1
- package/dist/cli/setup-VDS6SVEP.js +618 -0
- package/dist/cli/setup-VDS6SVEP.js.map +1 -0
- package/dist/cli/stats-MQVI2XQH.js +14 -0
- package/dist/cli/update-6ITLPRDV.js +15 -0
- package/dist/cli/update-6ITLPRDV.js.map +1 -0
- package/dist/cli/version-DAHGZY5N.js +33 -0
- package/dist/cli/{version-XQXYSJ5L.js.map → version-DAHGZY5N.js.map} +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +182 -97
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/acp-64VQZLDJ.js.map +0 -1
- package/dist/cli/chat-ZAGX52RV.js +0 -46
- package/dist/cli/chunk-4W2CICFQ.js.map +0 -1
- package/dist/cli/chunk-5X7LZJDE.js +0 -36
- package/dist/cli/chunk-5X7LZJDE.js.map +0 -1
- package/dist/cli/chunk-65Q5HQ26.js +0 -892
- package/dist/cli/chunk-65Q5HQ26.js.map +0 -1
- package/dist/cli/chunk-A3LL4XDV.js.map +0 -1
- package/dist/cli/chunk-A7VHMMDE.js.map +0 -1
- package/dist/cli/chunk-AFFZF3MW.js +0 -36
- package/dist/cli/chunk-AFFZF3MW.js.map +0 -1
- package/dist/cli/chunk-BOFL3T45.js.map +0 -1
- package/dist/cli/chunk-BYZGO3BX.js.map +0 -1
- package/dist/cli/chunk-CD4SCQL4.js.map +0 -1
- package/dist/cli/chunk-CPOV2O73.js +0 -39
- package/dist/cli/chunk-CPOV2O73.js.map +0 -1
- package/dist/cli/chunk-F2AV2QDK.js +0 -16514
- package/dist/cli/chunk-F2AV2QDK.js.map +0 -1
- package/dist/cli/chunk-H4OLWRSX.js.map +0 -1
- package/dist/cli/chunk-IEA6JOIP.js +0 -5430
- package/dist/cli/chunk-IEA6JOIP.js.map +0 -1
- package/dist/cli/chunk-L7W3HJZQ.js +0 -46
- package/dist/cli/chunk-LN27AKV3.js +0 -26
- package/dist/cli/chunk-LN27AKV3.js.map +0 -1
- package/dist/cli/chunk-MHGPBJ2T.js.map +0 -1
- package/dist/cli/chunk-SXLJBFIV.js.map +0 -1
- package/dist/cli/chunk-YJFKFTAL.js.map +0 -1
- package/dist/cli/code-X3M6ENTQ.js.map +0 -1
- package/dist/cli/desktop-ZTMHQR2Y.js.map +0 -1
- package/dist/cli/diff-YASCB7PU.js +0 -153
- package/dist/cli/doctor-XCN5ETVP.js +0 -24
- package/dist/cli/prompt-RSIHN62V.js +0 -14
- package/dist/cli/server-DRFPXXSH.js.map +0 -1
- package/dist/cli/setup-FQL2JJC2.js +0 -516
- package/dist/cli/setup-FQL2JJC2.js.map +0 -1
- package/dist/cli/stats-5RJCATCE.js +0 -12
- package/dist/cli/update-GUCWB4UN.js +0 -13
- package/dist/cli/version-XQXYSJ5L.js +0 -30
- /package/dist/cli/{chat-ZAGX52RV.js.map → chat-7ES4IBNH.js.map} +0 -0
- /package/dist/cli/{doctor-XCN5ETVP.js.map → chunk-TUK7OWJA.js.map} +0 -0
- /package/dist/cli/{prompt-RSIHN62V.js.map → doctor-OT7KH75K.js.map} +0 -0
- /package/dist/cli/{stats-5RJCATCE.js.map → prompt-UW6EFLVR.js.map} +0 -0
- /package/dist/cli/{update-GUCWB4UN.js.map → stats-MQVI2XQH.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts","../../src/cli/ui/theme/tokens.ts","../../src/index/config.ts"],"sourcesContent":["/** Library reads only DEEPSEEK_API_KEY from env; the CLI bridges config.json → env var. */\n\nimport { chmodSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { type ThemeName, isThemeName, resolveThemeName } from \"./cli/ui/theme/tokens.js\";\nimport type { LanguageCode } from \"./i18n/types.js\";\nimport {\n type IndexUserConfig,\n type ResolvedIndexConfig,\n resolveIndexConfig,\n} from \"./index/config.js\";\n\n/** Legacy `fast|smart|max` kept for back-compat with existing config.json files. */\nexport type PresetName = \"auto\" | \"flash\" | \"pro\" | \"fast\" | \"smart\" | \"max\";\n\n/** Single trust dial: review queues edits + gates shell; auto applies + gates shell; yolo skips both gates. */\nexport type EditMode = \"review\" | \"auto\" | \"yolo\";\n\nexport type ReasoningEffort = \"high\" | \"max\";\n\nexport type EmbeddingProvider = \"ollama\" | \"openai-compat\";\n\nexport interface OllamaEmbeddingUserConfig {\n baseUrl?: string;\n model?: string;\n}\n\nexport interface OpenAICompatEmbeddingUserConfig {\n baseUrl?: string;\n apiKey?: string;\n model?: string;\n extraBody?: Record<string, unknown>;\n}\n\nexport interface SemanticEmbeddingUserConfig {\n provider?: EmbeddingProvider;\n ollama?: OllamaEmbeddingUserConfig;\n openaiCompat?: OpenAICompatEmbeddingUserConfig;\n}\n\nexport interface ResolvedOllamaEmbeddingConfig {\n provider: \"ollama\";\n baseUrl: string;\n model: string;\n timeoutMs: number;\n}\n\nexport interface ResolvedOpenAICompatEmbeddingConfig {\n provider: \"openai-compat\";\n baseUrl: string;\n apiKey: string;\n model: string;\n extraBody: Record<string, unknown>;\n timeoutMs: number;\n}\n\nexport type ResolvedEmbeddingConfig =\n | ResolvedOllamaEmbeddingConfig\n | ResolvedOpenAICompatEmbeddingConfig;\n\nexport interface SemanticEmbeddingConfigView {\n provider: EmbeddingProvider;\n ollama: {\n baseUrl: string;\n model: string;\n };\n openaiCompat: {\n baseUrl: string;\n apiKey: string;\n apiKeySet: boolean;\n model: string;\n extraBody: Record<string, unknown>;\n };\n}\n\nexport interface ReasonixConfig {\n apiKey?: string;\n baseUrl?: string;\n lang?: LanguageCode;\n preset?: PresetName;\n editMode?: EditMode;\n editModeHintShown?: boolean;\n mouseClipboardHintShown?: boolean;\n reasoningEffort?: ReasoningEffort;\n /** Default workspace root for the desktop client. CLI uses cwd. */\n workspaceDir?: string;\n /** Last N workspace paths the desktop client has opened, most recent first. */\n recentWorkspaces?: string[];\n /** Desktop only — `openWith` value for clicking file links. Empty/undefined = OS default app. Examples: \"code\", \"cursor\", \"C:\\\\path\\\\to\\\\editor.exe\". */\n editor?: string;\n theme?: ThemeName | \"auto\";\n /** Stored as `--mcp`-format strings so one parser handles both flag and config. */\n mcp?: string[];\n /** Names of servers in `mcp` to skip on bridge — see `/mcp disable <name>`. */\n mcpDisabled?: string[];\n /** Env overlay per MCP server name (matches the `name=` prefix of the spec). Stdio transports merge this over process.env; SSE/HTTP ignore it. */\n mcpEnv?: Record<string, Record<string, string>>;\n session?: string | null;\n setupCompleted?: boolean;\n search?: boolean;\n /** Web search engine backend: \"mojeek\" (default, scrapes Mojeek) or \"searxng\" (self-hosted SearXNG). */\n webSearchEngine?: \"mojeek\" | \"searxng\";\n /** Base URL for SearXNG instance (default http://localhost:8080). */\n webSearchEndpoint?: string;\n dashboard?: {\n /** Pin the embedded dashboard to a fixed port — required for stable SSH tunnels. 0/absent → ephemeral. */\n port?: number;\n };\n escalation?: {\n /** Per-turn repair/error signal count required to escalate flash→pro. Defaults to 3. Out-of-range → default. */\n failureThreshold?: number;\n };\n /** Per-field visibility toggles for the bottom status row. All default to true (visible). */\n statusBar?: {\n showBalance?: boolean;\n showSessionCost?: boolean;\n showTurnCost?: boolean;\n showCacheHit?: boolean;\n showVersion?: boolean;\n showFeedbackHint?: boolean;\n };\n projects?: {\n [absoluteRootDir: string]: {\n shellAllowed?: string[];\n /** Absolute directory prefixes the user pre-approved for outside-sandbox file access (#684). */\n pathAllowed?: string[];\n };\n };\n index?: IndexUserConfig;\n semantic?: SemanticEmbeddingUserConfig;\n /** User-declared extensions to the built-in memory types (#709). Unknown types round-trip even without a declaration; declaring one lets you attach a default priority + lifecycle. */\n memory?: {\n customTypes?: CustomMemoryTypeConfig[];\n };\n}\n\nexport interface CustomMemoryTypeConfig {\n name: string;\n description?: string;\n priority?: \"low\" | \"medium\" | \"high\";\n expires?: \"project_end\";\n}\n\nexport interface MemoryTypeRegistryEntry {\n name: string;\n builtin: boolean;\n description?: string;\n priority?: \"low\" | \"medium\" | \"high\";\n expires?: \"project_end\";\n}\n\nconst BUILTIN_TYPE_DOCS: Record<string, string> = {\n user: \"role / skills / preferences\",\n feedback: \"corrections or confirmed approaches\",\n project: \"facts / decisions about the current work\",\n reference: \"pointers to external systems the user uses\",\n};\n\n/** Resolve the merged registry of memory types — built-ins, overlaid by anything in `config.memory.customTypes`. */\nexport function loadMemoryTypeRegistry(\n cfg: ReasonixConfig = readConfig(),\n): MemoryTypeRegistryEntry[] {\n const out: MemoryTypeRegistryEntry[] = [];\n for (const name of [\"user\", \"feedback\", \"project\", \"reference\"]) {\n out.push({ name, builtin: true, description: BUILTIN_TYPE_DOCS[name] });\n }\n const seen = new Set(out.map((e) => e.name));\n for (const raw of cfg.memory?.customTypes ?? []) {\n if (!raw || typeof raw.name !== \"string\") continue;\n const name = raw.name.trim();\n if (!name || !/^[a-zA-Z][a-zA-Z0-9_-]{0,31}$/.test(name)) continue;\n if (seen.has(name)) continue;\n seen.add(name);\n const entry: MemoryTypeRegistryEntry = { name, builtin: false };\n if (typeof raw.description === \"string\") entry.description = raw.description;\n if (raw.priority === \"low\" || raw.priority === \"medium\" || raw.priority === \"high\") {\n entry.priority = raw.priority;\n }\n if (raw.expires === \"project_end\") entry.expires = raw.expires;\n out.push(entry);\n }\n return out;\n}\n\nexport function memoryTypeDefaults(\n typeName: string,\n cfg: ReasonixConfig = readConfig(),\n): { priority?: \"low\" | \"medium\" | \"high\"; expires?: \"project_end\" } {\n const found = loadMemoryTypeRegistry(cfg).find((e) => e.name === typeName);\n if (!found) return {};\n const out: { priority?: \"low\" | \"medium\" | \"high\"; expires?: \"project_end\" } = {};\n if (found.priority) out.priority = found.priority;\n if (found.expires) out.expires = found.expires;\n return out;\n}\n\nconst DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\nconst DEFAULT_EMBED_MODEL = \"nomic-embed-text\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nexport function defaultConfigPath(): string {\n return join(homedir(), \".reasonix\", \"config.json\");\n}\n\nexport function readConfig(path: string = defaultConfigPath()): ReasonixConfig {\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\") return parsed as ReasonixConfig;\n } catch {\n /* missing or malformed → empty config */\n }\n return {};\n}\n\nexport function writeConfig(cfg: ReasonixConfig, path: string = defaultConfigPath()): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(cfg, null, 2), \"utf8\");\n try {\n chmodSync(path, 0o600);\n } catch {\n /* ignore on platforms without chmod */\n }\n}\n\n/** Resolve the language from config file. */\nexport function loadLanguage(path: string = defaultConfigPath()): LanguageCode | undefined {\n return readConfig(path).lang;\n}\n\nexport function mcpEnvFor(\n serverName: string | null | undefined,\n cfg: ReasonixConfig,\n): Record<string, string> | undefined {\n if (!serverName) return undefined;\n const entry = cfg.mcpEnv?.[serverName];\n if (!entry) return undefined;\n // Coerce to string and drop empty values — JSON config could be sloppy.\n const filtered: Record<string, string> = {};\n for (const [k, v] of Object.entries(entry)) {\n if (typeof v === \"string\" && v.length > 0) filtered[k] = v;\n }\n return Object.keys(filtered).length > 0 ? filtered : undefined;\n}\n\n/** Persist the language so it survives a relaunch. */\nexport function saveLanguage(lang: LanguageCode, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.lang = lang;\n writeConfig(cfg, path);\n}\n\n/** Resolve the API key from env var first, then the config file. */\nexport function loadApiKey(path: string = defaultConfigPath()): string | undefined {\n if (process.env.DEEPSEEK_API_KEY) return process.env.DEEPSEEK_API_KEY;\n return readConfig(path).apiKey;\n}\n\n/** env > config > undefined. Client falls back to api.deepseek.com when undefined. */\nexport function loadBaseUrl(path: string = defaultConfigPath()): string | undefined {\n if (process.env.DEEPSEEK_BASE_URL) return process.env.DEEPSEEK_BASE_URL;\n return readConfig(path).baseUrl;\n}\n\nexport function saveBaseUrl(url: string, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n const trimmed = url.trim();\n if (trimmed) {\n cfg.baseUrl = trimmed;\n } else {\n cfg.baseUrl = undefined;\n }\n writeConfig(cfg, path);\n}\n\nexport function searchEnabled(path: string = defaultConfigPath()): boolean {\n const env = process.env.REASONIX_SEARCH;\n if (env === \"off\" || env === \"false\" || env === \"0\") return false;\n const cfg = readConfig(path).search;\n if (cfg === false) return false;\n return true;\n}\n\nexport function webSearchEngine(path: string = defaultConfigPath()): \"mojeek\" | \"searxng\" {\n const cfg = readConfig(path).webSearchEngine;\n if (cfg === \"searxng\") return \"searxng\";\n return \"mojeek\";\n}\n\nexport function webSearchEndpoint(path: string = defaultConfigPath()): string {\n const cfg = readConfig(path).webSearchEndpoint;\n if (cfg && typeof cfg === \"string\") return cfg;\n return \"http://localhost:8080\";\n}\n\nexport function saveApiKey(key: string, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.apiKey = key.trim();\n writeConfig(cfg, path);\n}\n\n/** Windows: case-insensitive — NTFS treats `F:\\Foo` and `f:\\foo` as one directory (#402). */\nfunction findProjectKey(cfg: ReasonixConfig, rootDir: string): string | undefined {\n const projects = cfg.projects;\n if (!projects) return undefined;\n if (Object.hasOwn(projects, rootDir)) return rootDir;\n if (process.platform !== \"win32\") return undefined;\n const lower = rootDir.toLowerCase();\n for (const k of Object.keys(projects)) {\n if (k.toLowerCase() === lower) return k;\n }\n return undefined;\n}\n\nexport function loadProjectShellAllowed(\n rootDir: string,\n path: string = defaultConfigPath(),\n): string[] {\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return [];\n return cfg.projects?.[key]?.shellAllowed ?? [];\n}\n\nexport function addProjectShellAllowed(\n rootDir: string,\n prefix: string,\n path: string = defaultConfigPath(),\n): void {\n const trimmed = prefix.trim();\n if (!trimmed) return;\n const cfg = readConfig(path);\n if (!cfg.projects) cfg.projects = {};\n const key = findProjectKey(cfg, rootDir) ?? rootDir;\n if (!cfg.projects[key]) cfg.projects[key] = {};\n const existing = cfg.projects[key].shellAllowed ?? [];\n if (existing.includes(trimmed)) return;\n cfg.projects[key].shellAllowed = [...existing, trimmed];\n writeConfig(cfg, path);\n}\n\n/** Match is exact after trim — NOT prefix-match: removing `git` MUST NOT drop `git push origin main`. */\nexport function removeProjectShellAllowed(\n rootDir: string,\n prefix: string,\n path: string = defaultConfigPath(),\n): boolean {\n const trimmed = prefix.trim();\n if (!trimmed) return false;\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return false;\n const existing = cfg.projects?.[key]?.shellAllowed ?? [];\n if (!existing.includes(trimmed)) return false;\n const next = existing.filter((p) => p !== trimmed);\n if (!cfg.projects) cfg.projects = {};\n if (!cfg.projects[key]) cfg.projects[key] = {};\n cfg.projects[key].shellAllowed = next;\n writeConfig(cfg, path);\n return true;\n}\n\nexport function clearProjectShellAllowed(\n rootDir: string,\n path: string = defaultConfigPath(),\n): number {\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return 0;\n const existing = cfg.projects?.[key]?.shellAllowed ?? [];\n if (existing.length === 0) return 0;\n if (!cfg.projects) cfg.projects = {};\n if (!cfg.projects[key]) cfg.projects[key] = {};\n cfg.projects[key].shellAllowed = [];\n writeConfig(cfg, path);\n return existing.length;\n}\n\nexport function loadProjectPathAllowed(\n rootDir: string,\n path: string = defaultConfigPath(),\n): string[] {\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return [];\n return cfg.projects?.[key]?.pathAllowed ?? [];\n}\n\nexport function addProjectPathAllowed(\n rootDir: string,\n prefix: string,\n path: string = defaultConfigPath(),\n): void {\n const trimmed = prefix.trim();\n if (!trimmed) return;\n const cfg = readConfig(path);\n if (!cfg.projects) cfg.projects = {};\n const key = findProjectKey(cfg, rootDir) ?? rootDir;\n if (!cfg.projects[key]) cfg.projects[key] = {};\n const existing = cfg.projects[key].pathAllowed ?? [];\n if (existing.includes(trimmed)) return;\n cfg.projects[key].pathAllowed = [...existing, trimmed];\n writeConfig(cfg, path);\n}\n\nexport function removeProjectPathAllowed(\n rootDir: string,\n prefix: string,\n path: string = defaultConfigPath(),\n): boolean {\n const trimmed = prefix.trim();\n if (!trimmed) return false;\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return false;\n const existing = cfg.projects?.[key]?.pathAllowed ?? [];\n if (!existing.includes(trimmed)) return false;\n const next = existing.filter((p) => p !== trimmed);\n if (!cfg.projects) cfg.projects = {};\n if (!cfg.projects[key]) cfg.projects[key] = {};\n cfg.projects[key].pathAllowed = next;\n writeConfig(cfg, path);\n return true;\n}\n\nexport function clearProjectPathAllowed(\n rootDir: string,\n path: string = defaultConfigPath(),\n): number {\n const cfg = readConfig(path);\n const key = findProjectKey(cfg, rootDir);\n if (key === undefined) return 0;\n const existing = cfg.projects?.[key]?.pathAllowed ?? [];\n if (existing.length === 0) return 0;\n if (!cfg.projects) cfg.projects = {};\n if (!cfg.projects[key]) cfg.projects[key] = {};\n cfg.projects[key].pathAllowed = [];\n writeConfig(cfg, path);\n return existing.length;\n}\n\n/** Unknown values fall back to \"review\" so hand-edited bad config gets the safe default. */\nexport function loadEditMode(path: string = defaultConfigPath()): EditMode {\n const v = readConfig(path).editMode;\n if (v === \"auto\" || v === \"yolo\") return v;\n return \"review\";\n}\n\n/** Persist the edit mode so `/mode auto` survives a relaunch. */\nexport function saveEditMode(mode: EditMode, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.editMode = mode;\n writeConfig(cfg, path);\n}\n\n/** True when the onboarding tip for the review/AUTO gate has been shown. */\nexport function editModeHintShown(path: string = defaultConfigPath()): boolean {\n return readConfig(path).editModeHintShown === true;\n}\n\n/** True when the mouse-tracking + clipboard tip has been shown. */\nexport function mouseClipboardHintShown(path: string = defaultConfigPath()): boolean {\n return readConfig(path).mouseClipboardHintShown === true;\n}\n\n/** Unknown / missing fall back to \"max\" so hand-edited bad config can't silently override the default. */\nexport function loadReasoningEffort(path: string = defaultConfigPath()): ReasoningEffort {\n const v = readConfig(path).reasoningEffort;\n return v === \"high\" ? \"high\" : \"max\";\n}\n\nexport function loadTheme(path: string = defaultConfigPath()): ThemeName | \"auto\" | undefined {\n const value = readConfig(path).theme;\n if (value === \"auto\") return \"auto\";\n if (typeof value === \"string\" && isThemeName(value)) return value;\n return undefined;\n}\n\nexport function resolveThemePreference(\n configTheme: ThemeName | \"auto\" | undefined,\n envTheme?: string | null,\n): ThemeName {\n if (configTheme && configTheme !== \"auto\") return configTheme;\n return resolveThemeName(envTheme);\n}\n\nexport function saveTheme(theme: ThemeName | \"auto\", path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.theme = theme;\n writeConfig(cfg, path);\n}\n\n/** Persist the reasoning_effort cap so `/effort high` survives a relaunch. */\nexport function saveReasoningEffort(\n effort: ReasoningEffort,\n path: string = defaultConfigPath(),\n): void {\n const cfg = readConfig(path);\n cfg.reasoningEffort = effort;\n writeConfig(cfg, path);\n}\n\nexport function loadWorkspaceDir(path: string = defaultConfigPath()): string | undefined {\n const v = readConfig(path).workspaceDir;\n return typeof v === \"string\" && v.trim() ? v : undefined;\n}\n\nexport function saveWorkspaceDir(dir: string, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n const trimmed = dir.trim();\n if (trimmed) cfg.workspaceDir = trimmed;\n else cfg.workspaceDir = undefined;\n writeConfig(cfg, path);\n}\n\nexport function loadEditor(path: string = defaultConfigPath()): string | undefined {\n const v = readConfig(path).editor;\n return typeof v === \"string\" && v.trim() ? v : undefined;\n}\n\nexport function saveEditor(editor: string, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n const trimmed = editor.trim();\n if (trimmed) cfg.editor = trimmed;\n else cfg.editor = undefined;\n writeConfig(cfg, path);\n}\n\nexport function loadRecentWorkspaces(path: string = defaultConfigPath()): string[] {\n const v = readConfig(path).recentWorkspaces;\n return Array.isArray(v) ? v.filter((s): s is string => typeof s === \"string\") : [];\n}\n\nconst MAX_RECENT_WORKSPACES = 8;\nexport function pushRecentWorkspace(dir: string, path: string = defaultConfigPath()): void {\n const trimmed = dir.trim();\n if (!trimmed) return;\n const cfg = readConfig(path);\n const list = (cfg.recentWorkspaces ?? []).filter((s) => s !== trimmed);\n list.unshift(trimmed);\n cfg.recentWorkspaces = list.slice(0, MAX_RECENT_WORKSPACES);\n writeConfig(cfg, path);\n}\n\nexport function loadPreset(path: string = defaultConfigPath()): PresetName | undefined {\n return readConfig(path).preset;\n}\n\n/** Persist preset so `/preset pro` (or `/model deepseek-v4-pro`) sticks across relaunches. */\nexport function savePreset(preset: PresetName, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.preset = preset;\n writeConfig(cfg, path);\n}\n\nexport function loadIndexUserConfig(path: string = defaultConfigPath()): IndexUserConfig {\n return readConfig(path).index ?? {};\n}\n\nexport function loadIndexConfig(path: string = defaultConfigPath()): ResolvedIndexConfig {\n return resolveIndexConfig(readConfig(path).index);\n}\n\nexport function saveIndexConfig(user: IndexUserConfig, path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n cfg.index = user;\n writeConfig(cfg, path);\n}\n\nexport function loadSemanticEmbeddingUserConfig(\n path: string = defaultConfigPath(),\n): SemanticEmbeddingUserConfig {\n return normalizeSemanticEmbeddingUserConfig(readConfig(path).semantic);\n}\n\nexport function saveSemanticEmbeddingConfig(\n user: SemanticEmbeddingUserConfig,\n path: string = defaultConfigPath(),\n): void {\n const cfg = readConfig(path);\n cfg.semantic = normalizeSemanticEmbeddingUserConfig(user);\n writeConfig(cfg, path);\n}\n\nexport function resolveSemanticEmbeddingConfig(\n path: string = defaultConfigPath(),\n): ResolvedEmbeddingConfig {\n const user = loadSemanticEmbeddingUserConfig(path);\n const provider = user.provider ?? \"ollama\";\n if (provider === \"openai-compat\") {\n const baseUrl = user.openaiCompat?.baseUrl?.trim() ?? \"\";\n const apiKey = user.openaiCompat?.apiKey?.trim() ?? \"\";\n const model = user.openaiCompat?.model?.trim() ?? \"\";\n if (!baseUrl) throw new Error(\"OpenAI-compatible embeddings require an API URL.\");\n requireValidUrl(baseUrl, \"OpenAI-compatible API URL\");\n if (!apiKey) throw new Error(\"OpenAI-compatible embeddings require an API key.\");\n if (!model) throw new Error(\"OpenAI-compatible embeddings require a model.\");\n return {\n provider,\n baseUrl,\n apiKey,\n model,\n extraBody: normalizeExtraBody(user.openaiCompat?.extraBody),\n timeoutMs: DEFAULT_TIMEOUT_MS,\n };\n }\n return {\n provider: \"ollama\",\n baseUrl: user.ollama?.baseUrl?.trim() || process.env.OLLAMA_URL || DEFAULT_OLLAMA_URL,\n model: user.ollama?.model?.trim() || process.env.REASONIX_EMBED_MODEL || DEFAULT_EMBED_MODEL,\n timeoutMs: DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function redactSemanticEmbeddingConfig(\n user: SemanticEmbeddingUserConfig,\n): SemanticEmbeddingConfigView {\n const normalized = normalizeSemanticEmbeddingUserConfig(user);\n return {\n provider: normalized.provider ?? \"ollama\",\n ollama: {\n baseUrl: normalized.ollama?.baseUrl?.trim() || process.env.OLLAMA_URL || DEFAULT_OLLAMA_URL,\n model:\n normalized.ollama?.model?.trim() || process.env.REASONIX_EMBED_MODEL || DEFAULT_EMBED_MODEL,\n },\n openaiCompat: {\n baseUrl: normalized.openaiCompat?.baseUrl?.trim() ?? \"\",\n apiKey: normalized.openaiCompat?.apiKey ? redactKey(normalized.openaiCompat.apiKey) : \"\",\n apiKeySet: Boolean(normalized.openaiCompat?.apiKey?.trim()),\n model: normalized.openaiCompat?.model?.trim() ?? \"\",\n extraBody: normalizeExtraBody(normalized.openaiCompat?.extraBody),\n },\n };\n}\n\n/** Mark the onboarding tip as shown so subsequent launches skip it. */\nexport function markEditModeHintShown(path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n if (cfg.editModeHintShown === true) return;\n cfg.editModeHintShown = true;\n writeConfig(cfg, path);\n}\n\n/** Mark the mouse + clipboard tip as shown. */\nexport function markMouseClipboardHintShown(path: string = defaultConfigPath()): void {\n const cfg = readConfig(path);\n if (cfg.mouseClipboardHintShown === true) return;\n cfg.mouseClipboardHintShown = true;\n writeConfig(cfg, path);\n}\n\n/** Self-hosted DeepSeek-compatible endpoints may issue any token shape, so we only typo-guard here — the real auth check is the first API call against `baseUrl`. */\nexport function isPlausibleKey(key: string): boolean {\n const trimmed = key.trim();\n if (trimmed.length < 16) return false;\n return !/\\s/.test(trimmed);\n}\n\n/** Mask a key for display: `sk-abcd...wxyz`. */\nexport function redactKey(key: string): string {\n if (!key) return \"\";\n if (key.length <= 12) return \"****\";\n return `${key.slice(0, 6)}…${key.slice(-4)}`;\n}\n\nfunction normalizeSemanticEmbeddingUserConfig(\n cfg: SemanticEmbeddingUserConfig | undefined,\n): SemanticEmbeddingUserConfig {\n return {\n provider: cfg?.provider === \"openai-compat\" ? \"openai-compat\" : \"ollama\",\n ollama: {\n baseUrl: normalizeOptionalString(cfg?.ollama?.baseUrl),\n model: normalizeOptionalString(cfg?.ollama?.model),\n },\n openaiCompat: {\n baseUrl: normalizeOptionalString(cfg?.openaiCompat?.baseUrl),\n apiKey: normalizeOptionalString(cfg?.openaiCompat?.apiKey),\n model: normalizeOptionalString(cfg?.openaiCompat?.model),\n extraBody: normalizeExtraBody(cfg?.openaiCompat?.extraBody),\n },\n };\n}\n\nfunction normalizeOptionalString(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeExtraBody(value: Record<string, unknown> | undefined): Record<string, unknown> {\n if (value === undefined) return {};\n if (!isPlainObject(value)) {\n throw new Error(\"Semantic embedding extraBody must be a JSON object.\");\n }\n return { ...value };\n}\n\nfunction requireValidUrl(value: string, label: string): void {\n try {\n new URL(value);\n } catch {\n throw new Error(`${label} must be a valid URL.`);\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n","export type ThemeName =\n | \"default\"\n | \"dark\"\n | \"light\"\n | \"tokyo-night\"\n | \"github-dark\"\n | \"github-light\"\n | \"high-contrast\";\n\nexport interface ThemeTokens {\n fg: {\n strong: string;\n body: string;\n sub: string;\n meta: string;\n faint: string;\n };\n tone: {\n brand: string;\n accent: string;\n violet: string;\n ok: string;\n warn: string;\n err: string;\n info: string;\n };\n toneActive: ThemeTokens[\"tone\"];\n surface: {\n bg: string;\n bgInput: string;\n bgCode: string;\n bgElev: string;\n };\n card: Record<\n | \"user\"\n | \"reasoning\"\n | \"streaming\"\n | \"task\"\n | \"tool\"\n | \"plan\"\n | \"diff\"\n | \"error\"\n | \"warn\"\n | \"usage\"\n | \"subagent\"\n | \"approval\"\n | \"search\"\n | \"memory\"\n | \"ctx\"\n | \"doctor\"\n | \"branch\",\n { color: string; glyph: string }\n >;\n}\n\ntype ThemeBase = Omit<ThemeTokens, \"card\">;\n\nfunction card(fg: ThemeTokens[\"fg\"], tone: ThemeTokens[\"tone\"]): ThemeTokens[\"card\"] {\n return {\n user: { color: fg.meta, glyph: \"◇\" },\n reasoning: { color: tone.accent, glyph: \"◆\" },\n streaming: { color: tone.brand, glyph: \"◈\" },\n task: { color: tone.warn, glyph: \"▶\" },\n tool: { color: tone.info, glyph: \"▣\" },\n plan: { color: tone.accent, glyph: \"⊞\" },\n diff: { color: tone.ok, glyph: \"±\" },\n error: { color: tone.err, glyph: \"✖\" },\n warn: { color: tone.warn, glyph: \"⚠\" },\n usage: { color: fg.meta, glyph: \"Σ\" },\n subagent: { color: tone.violet, glyph: \"⌬\" },\n approval: { color: tone.warn, glyph: \"?\" },\n search: { color: tone.info, glyph: \"⊙\" },\n memory: { color: fg.meta, glyph: \"⌑\" },\n ctx: { color: tone.brand, glyph: \"◔\" },\n doctor: { color: fg.meta, glyph: \"⚕\" },\n branch: { color: tone.violet, glyph: \"⎇\" },\n };\n}\n\nfunction defineTheme(base: ThemeBase): ThemeTokens {\n return { ...base, card: card(base.fg, base.tone) };\n}\n\nconst githubDark = defineTheme({\n fg: {\n strong: \"#e6edf3\",\n body: \"#c9d1d9\",\n sub: \"#8b949e\",\n meta: \"#6e7681\",\n faint: \"#484f58\",\n },\n tone: {\n brand: \"#79c0ff\",\n accent: \"#d2a8ff\",\n violet: \"#b395f5\",\n ok: \"#7ee787\",\n warn: \"#f0b07d\",\n err: \"#ff8b81\",\n info: \"#79c0ff\",\n },\n toneActive: {\n brand: \"#a5d6ff\",\n accent: \"#e2c5ff\",\n violet: \"#c8aaff\",\n ok: \"#a8f5ad\",\n warn: \"#ffc99e\",\n err: \"#ffaba3\",\n info: \"#a5d6ff\",\n },\n surface: {\n bg: \"#0a0c10\",\n bgInput: \"#0d1015\",\n bgCode: \"#06080c\",\n bgElev: \"#11141a\",\n },\n});\n\nconst dark = defineTheme({\n fg: {\n strong: \"#f4f7fb\",\n body: \"#d8dee9\",\n sub: \"#a7b1c2\",\n meta: \"#778294\",\n faint: \"#4d5666\",\n },\n tone: {\n brand: \"#7dd3fc\",\n accent: \"#c084fc\",\n violet: \"#a78bfa\",\n ok: \"#86efac\",\n warn: \"#fbbf24\",\n err: \"#f87171\",\n info: \"#60a5fa\",\n },\n toneActive: {\n brand: \"#bae6fd\",\n accent: \"#e9d5ff\",\n violet: \"#ddd6fe\",\n ok: \"#bbf7d0\",\n warn: \"#fde68a\",\n err: \"#fecaca\",\n info: \"#bfdbfe\",\n },\n surface: {\n bg: \"#0b1020\",\n bgInput: \"#111827\",\n bgCode: \"#080c16\",\n bgElev: \"#151d2f\",\n },\n});\n\nconst light = defineTheme({\n fg: {\n strong: \"#111827\",\n body: \"#1f2937\",\n sub: \"#4b5563\",\n meta: \"#6b7280\",\n faint: \"#9ca3af\",\n },\n tone: {\n brand: \"#2563eb\",\n accent: \"#7c3aed\",\n violet: \"#6d28d9\",\n ok: \"#15803d\",\n warn: \"#b45309\",\n err: \"#dc2626\",\n info: \"#0369a1\",\n },\n toneActive: {\n brand: \"#1d4ed8\",\n accent: \"#6d28d9\",\n violet: \"#5b21b6\",\n ok: \"#166534\",\n warn: \"#92400e\",\n err: \"#b91c1c\",\n info: \"#075985\",\n },\n surface: {\n bg: \"#ffffff\",\n bgInput: \"#f8fafc\",\n bgCode: \"#f3f4f6\",\n bgElev: \"#eef2f7\",\n },\n});\n\nconst tokyoNight = defineTheme({\n fg: {\n strong: \"#c0caf5\",\n body: \"#a9b1d6\",\n sub: \"#9aa5ce\",\n meta: \"#565f89\",\n faint: \"#414868\",\n },\n tone: {\n brand: \"#7aa2f7\",\n accent: \"#bb9af7\",\n violet: \"#9d7cd8\",\n ok: \"#9ece6a\",\n warn: \"#e0af68\",\n err: \"#f7768e\",\n info: \"#2ac3de\",\n },\n toneActive: {\n brand: \"#a9c7ff\",\n accent: \"#d7b9ff\",\n violet: \"#c6a0f6\",\n ok: \"#b9f27c\",\n warn: \"#ffd089\",\n err: \"#ff9cac\",\n info: \"#7dcfff\",\n },\n surface: {\n bg: \"#1a1b26\",\n bgInput: \"#1f2335\",\n bgCode: \"#16161e\",\n bgElev: \"#24283b\",\n },\n});\n\nconst githubLight = defineTheme({\n fg: {\n strong: \"#1f2328\",\n body: \"#24292f\",\n sub: \"#57606a\",\n meta: \"#6e7781\",\n faint: \"#8c959f\",\n },\n tone: {\n brand: \"#0969da\",\n accent: \"#8250df\",\n violet: \"#6639ba\",\n ok: \"#1a7f37\",\n warn: \"#9a6700\",\n err: \"#cf222e\",\n info: \"#0969da\",\n },\n toneActive: {\n brand: \"#0550ae\",\n accent: \"#6639ba\",\n violet: \"#512a97\",\n ok: \"#116329\",\n warn: \"#7d4e00\",\n err: \"#a40e26\",\n info: \"#0550ae\",\n },\n surface: {\n bg: \"#ffffff\",\n bgInput: \"#f6f8fa\",\n bgCode: \"#f6f8fa\",\n bgElev: \"#eaeef2\",\n },\n});\n\nconst highContrast = defineTheme({\n fg: {\n strong: \"#ffffff\",\n body: \"#f5f5f5\",\n sub: \"#d4d4d4\",\n meta: \"#bdbdbd\",\n faint: \"#8a8a8a\",\n },\n tone: {\n brand: \"#00e5ff\",\n accent: \"#ff4dff\",\n violet: \"#b388ff\",\n ok: \"#00ff66\",\n warn: \"#ffdd00\",\n err: \"#ff4d4d\",\n info: \"#4da3ff\",\n },\n toneActive: {\n brand: \"#80f2ff\",\n accent: \"#ff99ff\",\n violet: \"#d0b3ff\",\n ok: \"#80ffb3\",\n warn: \"#ffee80\",\n err: \"#ff9999\",\n info: \"#99c9ff\",\n },\n surface: {\n bg: \"#000000\",\n bgInput: \"#0a0a0a\",\n bgCode: \"#050505\",\n bgElev: \"#141414\",\n },\n});\n\nexport const THEMES = {\n default: githubDark,\n dark,\n light,\n \"tokyo-night\": tokyoNight,\n \"github-dark\": githubDark,\n \"github-light\": githubLight,\n \"high-contrast\": highContrast,\n} as const satisfies Record<ThemeName, ThemeTokens>;\n\nexport const DEFAULT_THEME_NAME: ThemeName = \"default\";\n\nexport function isThemeName(value: string): value is ThemeName {\n return Object.prototype.hasOwnProperty.call(THEMES, value);\n}\n\nexport function resolveThemeName(value?: string | null): ThemeName {\n if (!value || value === \"auto\") return DEFAULT_THEME_NAME;\n return isThemeName(value) ? value : DEFAULT_THEME_NAME;\n}\n\nexport function listThemeNames(): ThemeName[] {\n return Object.keys(THEMES) as ThemeName[];\n}\n\nexport function themeTokens(name?: string | null): ThemeTokens {\n return THEMES[resolveThemeName(name)];\n}\n\nexport const DEFAULT_THEME = THEMES[DEFAULT_THEME_NAME];\n\nlet activeTheme: ThemeTokens = DEFAULT_THEME;\nlet activeThemeVersion = 0;\n\nexport function setActiveTheme(theme: ThemeTokens): () => void {\n const previousTheme = activeTheme;\n activeTheme = theme;\n activeThemeVersion += 1;\n const version = activeThemeVersion;\n return () => {\n if (activeThemeVersion !== version || activeTheme !== theme) return;\n activeTheme = previousTheme;\n activeThemeVersion += 1;\n };\n}\n\nfunction proxyTokens<T extends object>(select: (theme: ThemeTokens) => T): T {\n const target = select(DEFAULT_THEME);\n return new Proxy(target, {\n get(_target, prop: string | symbol) {\n return select(activeTheme)[prop as keyof T];\n },\n getOwnPropertyDescriptor(_target, prop: string | symbol) {\n return Reflect.getOwnPropertyDescriptor(select(activeTheme), prop);\n },\n has(_target, prop: string | symbol) {\n return prop in select(activeTheme);\n },\n ownKeys() {\n return Reflect.ownKeys(select(activeTheme));\n },\n });\n}\n\nexport const FG = proxyTokens((theme) => theme.fg);\nexport const TONE = proxyTokens((theme) => theme.tone);\nexport const TONE_ACTIVE = proxyTokens((theme) => theme.toneActive);\nexport const SURFACE = proxyTokens((theme) => theme.surface);\nexport const CARD = proxyTokens((theme) => theme.card);\n\nexport type CardTone = keyof ThemeTokens[\"card\"];\n\n/** DeepSeek prices in CNY; our internal table is USD divided by 7.2. Multiply back for display. */\nexport const USD_TO_CNY = 7.2;\n\nconst SYMBOL: Record<string, string> = { USD: \"$\", CNY: \"¥\" };\n\n/** Format an amount already in `currency`. Undefined currency → CNY (matches pre-fix behavior). */\nexport function formatBalance(\n amount: number,\n currency?: string,\n opts?: { fractionDigits?: number; label?: boolean },\n): string {\n const cur = currency ?? \"CNY\";\n const sym = SYMBOL[cur];\n const digits = opts?.fractionDigits ?? 2;\n const body = sym ? `${sym}${amount.toFixed(digits)}` : `${cur} ${amount.toFixed(digits)}`;\n return opts?.label ? `w ${body}` : body;\n}\n\n/** Format an internal USD cost in the wallet's display currency. Undefined currency → CNY. */\nexport function formatCost(costUsd: number, currency?: string, fractionDigits = 4): string {\n const cur = currency ?? \"CNY\";\n const amount = cur === \"CNY\" ? costUsd * USD_TO_CNY : costUsd;\n return formatBalance(amount, cur, { fractionDigits });\n}\n\n/** Threshold color for a wallet balance. USD is converted to CNY before the threshold check. */\nexport function balanceColor(amount: number, currency?: string): string {\n const cny = (currency ?? \"CNY\") === \"USD\" ? amount * USD_TO_CNY : amount;\n if (cny < 5) return TONE.err;\n if (cny < 20) return TONE.warn;\n return TONE.brand;\n}\n","/** Shared exclude defaults + resolver — chunker, directory_tree, and dashboard read from here. */\n\nimport picomatch from \"picomatch\";\n\nexport interface IndexUserConfig {\n excludeDirs?: string[];\n excludeFiles?: string[];\n excludeExts?: string[];\n excludePatterns?: string[];\n respectGitignore?: boolean;\n maxFileBytes?: number;\n}\n\n/** Plain-data shape — JSON-safe so the dashboard endpoint can serialize. */\nexport interface ResolvedIndexConfig {\n excludeDirs: readonly string[];\n excludeFiles: readonly string[];\n excludeExts: readonly string[];\n excludePatterns: readonly string[];\n respectGitignore: boolean;\n maxFileBytes: number;\n}\n\n/** Hot-path lookup wrapper — built once per indexer run, never serialized. */\nexport interface IndexFilters {\n dirSet: ReadonlySet<string>;\n fileSet: ReadonlySet<string>;\n extSet: ReadonlySet<string>;\n patternMatch: (relPath: string) => boolean;\n respectGitignore: boolean;\n maxFileBytes: number;\n}\n\nexport const DEFAULT_INDEX_EXCLUDES = {\n dirs: [\n \"node_modules\",\n \".git\",\n \".hg\",\n \".svn\",\n \"dist\",\n \"build\",\n \"out\",\n \".next\",\n \".nuxt\",\n \"target\",\n \".venv\",\n \"venv\",\n \"__pycache__\",\n \".pytest_cache\",\n \".mypy_cache\",\n \".cache\",\n \"coverage\",\n \".turbo\",\n \".vercel\",\n \".reasonix\",\n ] as const,\n files: [\n \"package-lock.json\",\n \"yarn.lock\",\n \"pnpm-lock.yaml\",\n \"Cargo.lock\",\n \"poetry.lock\",\n \"Pipfile.lock\",\n \"go.sum\",\n \".DS_Store\",\n ] as const,\n exts: [\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".webp\",\n \".bmp\",\n \".ico\",\n \".tiff\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".otf\",\n \".eot\",\n \".zip\",\n \".tar\",\n \".gz\",\n \".bz2\",\n \".xz\",\n \".rar\",\n \".7z\",\n \".exe\",\n \".dll\",\n \".so\",\n \".dylib\",\n \".bin\",\n \".class\",\n \".jar\",\n \".war\",\n \".wasm\",\n \".o\",\n \".obj\",\n \".lib\",\n \".a\",\n \".pyc\",\n \".pyo\",\n \".mp3\",\n \".mp4\",\n \".wav\",\n \".ogg\",\n \".webm\",\n \".mov\",\n \".avi\",\n \".pdf\",\n \".sqlite\",\n \".db\",\n ] as const,\n} as const;\n\nexport const DEFAULT_MAX_FILE_BYTES = 256 * 1024;\nexport const DEFAULT_RESPECT_GITIGNORE = true;\n\nexport function defaultIndexConfig(): ResolvedIndexConfig {\n return {\n excludeDirs: [...DEFAULT_INDEX_EXCLUDES.dirs],\n excludeFiles: [...DEFAULT_INDEX_EXCLUDES.files],\n excludeExts: [...DEFAULT_INDEX_EXCLUDES.exts],\n excludePatterns: [],\n respectGitignore: DEFAULT_RESPECT_GITIGNORE,\n maxFileBytes: DEFAULT_MAX_FILE_BYTES,\n };\n}\n\n/** A field present in user config fully replaces the default for that field. Absent → default. */\nexport function resolveIndexConfig(user?: IndexUserConfig | null): ResolvedIndexConfig {\n const d = defaultIndexConfig();\n if (!user) return d;\n return {\n excludeDirs: Array.isArray(user.excludeDirs) ? [...user.excludeDirs] : d.excludeDirs,\n excludeFiles: Array.isArray(user.excludeFiles) ? [...user.excludeFiles] : d.excludeFiles,\n excludeExts: Array.isArray(user.excludeExts)\n ? user.excludeExts.map((e) => e.toLowerCase())\n : d.excludeExts,\n excludePatterns: Array.isArray(user.excludePatterns) ? [...user.excludePatterns] : [],\n respectGitignore:\n typeof user.respectGitignore === \"boolean\" ? user.respectGitignore : d.respectGitignore,\n maxFileBytes:\n typeof user.maxFileBytes === \"number\" && user.maxFileBytes > 0\n ? user.maxFileBytes\n : d.maxFileBytes,\n };\n}\n\nexport function compileFilters(cfg: ResolvedIndexConfig): IndexFilters {\n const matcher =\n cfg.excludePatterns.length === 0\n ? () => false\n : picomatch(cfg.excludePatterns as string[], { dot: true });\n return {\n dirSet: new Set(cfg.excludeDirs),\n fileSet: new Set(cfg.excludeFiles),\n extSet: new Set(cfg.excludeExts.map((e) => e.toLowerCase())),\n patternMatch: matcher as (p: string) => boolean,\n respectGitignore: cfg.respectGitignore,\n maxFileBytes: cfg.maxFileBytes,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/code/checkpoints.ts","../../src/code/plan-store.ts","../../src/cli/ui/slash/commands.ts"],"sourcesContent":["/** One file per checkpoint (not jsonl) so delete/restore is cheap and a corrupt snapshot only loses itself. */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\n\n/** One file's state at the time of snapshot. `content === null` → didn't exist. */\nexport interface CheckpointFile {\n path: string;\n content: string | null;\n}\n\nexport interface Checkpoint {\n id: string;\n /** User-given name, or `auto-<reason>` for system-created snapshots. */\n name: string;\n /** Absolute workspace root the snapshot belongs to. */\n rootDir: string;\n createdAt: number;\n source: \"manual\" | \"auto-session-start\" | \"auto-pre-restore\";\n files: CheckpointFile[];\n /** Total bytes of file content captured (sum of `content?.length`). */\n bytes: number;\n}\n\nexport interface CheckpointMeta {\n id: string;\n name: string;\n createdAt: number;\n source: Checkpoint[\"source\"];\n fileCount: number;\n bytes: number;\n}\n\n/** Sanitize a directory path into a safe filesystem name for the store. */\nfunction sanitizeRoot(rootDir: string): string {\n return resolve(rootDir)\n .replace(/[\\\\/:]+/g, \"_\")\n .replace(/^_+/, \"\");\n}\n\nfunction storeRoot(rootDir: string): string {\n return join(homedir(), \".reasonix\", \"sessions\", sanitizeRoot(rootDir), \"checkpoints\");\n}\n\nfunction indexPath(rootDir: string): string {\n return join(storeRoot(rootDir), \"index.json\");\n}\n\nfunction snapshotPath(rootDir: string, id: string): string {\n return join(storeRoot(rootDir), `${id}.json`);\n}\n\n/** Load the index of checkpoint metadata for a workspace. Empty when missing. */\nexport function listCheckpoints(rootDir: string): CheckpointMeta[] {\n const path = indexPath(rootDir);\n if (!existsSync(path)) return [];\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n // Defensive: filter out malformed entries rather than throwing on\n // a single bad row. A stale entry is annoying; a thrown listCheckpoints\n // would break /checkpoint list entirely.\n return parsed.filter(\n (m): m is CheckpointMeta =>\n typeof m === \"object\" &&\n m !== null &&\n typeof m.id === \"string\" &&\n typeof m.name === \"string\" &&\n typeof m.createdAt === \"number\" &&\n typeof m.source === \"string\" &&\n typeof m.fileCount === \"number\" &&\n typeof m.bytes === \"number\",\n );\n } catch {\n return [];\n }\n}\n\nfunction writeIndex(rootDir: string, items: CheckpointMeta[]): void {\n const path = indexPath(rootDir);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(items, null, 2), \"utf8\");\n}\n\n/** Read a single checkpoint by id. Returns null when missing or corrupt. */\nexport function loadCheckpoint(rootDir: string, id: string): Checkpoint | null {\n const path = snapshotPath(rootDir, id);\n if (!existsSync(path)) return null;\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && Array.isArray(parsed.files)) {\n return parsed as Checkpoint;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport interface CreateCheckpointOptions {\n rootDir: string;\n name: string;\n source?: Checkpoint[\"source\"];\n paths: readonly string[];\n}\n\n/** Missing files recorded as `content: null` so restore knows to delete; ID has random suffix to avoid same-ms collision. */\nexport function createCheckpoint(opts: CreateCheckpointOptions): CheckpointMeta {\n const absRoot = resolve(opts.rootDir);\n const id = `cp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;\n const files: CheckpointFile[] = [];\n let bytes = 0;\n const seen = new Set<string>();\n for (const p of opts.paths) {\n if (seen.has(p)) continue;\n seen.add(p);\n const abs = resolve(absRoot, p);\n // Path-escape guard. A snapshot of `../../../etc/passwd` is not\n // something we want — refuse silently rather than abort the whole\n // checkpoint.\n if (abs !== absRoot && !abs.startsWith(`${absRoot}${sep}`)) continue;\n const rel = relative(absRoot, abs).split(sep).join(\"/\");\n if (existsSync(abs)) {\n try {\n const content = readFileSync(abs, \"utf8\");\n files.push({ path: rel, content });\n bytes += content.length;\n } catch {\n // Unreadable (binary, perms) — record as null so restore knows\n // to delete on revert. Wrong for binary files but consistent.\n files.push({ path: rel, content: null });\n }\n } else {\n files.push({ path: rel, content: null });\n }\n }\n\n const checkpoint: Checkpoint = {\n id,\n name: opts.name,\n rootDir: absRoot,\n createdAt: Date.now(),\n source: opts.source ?? \"manual\",\n files,\n bytes,\n };\n const cpPath = snapshotPath(absRoot, id);\n mkdirSync(dirname(cpPath), { recursive: true });\n writeFileSync(cpPath, JSON.stringify(checkpoint), \"utf8\");\n\n const meta: CheckpointMeta = {\n id,\n name: opts.name,\n createdAt: checkpoint.createdAt,\n source: checkpoint.source,\n fileCount: files.length,\n bytes,\n };\n const items = listCheckpoints(absRoot);\n items.push(meta);\n writeIndex(absRoot, items);\n return meta;\n}\n\n/** Most-recent name wins on collision. */\nexport function findCheckpoint(rootDir: string, idOrName: string): CheckpointMeta | null {\n const items = listCheckpoints(rootDir);\n // Prefer exact id match, then most-recent name match.\n const byId = items.find((m) => m.id === idOrName);\n if (byId) return byId;\n const byName = [...items].reverse().find((m) => m.name === idOrName);\n return byName ?? null;\n}\n\nexport interface RestoreResult {\n /** Files we wrote back to disk. */\n restored: string[];\n /** Files we removed (snapshot had `content: null`, file existed). */\n removed: string[];\n /** Files we couldn't touch (errors), with the reason. */\n skipped: Array<{ path: string; reason: string }>;\n}\n\n/** Path-escape rechecked against live `rootDir` since snapshot's may differ (project moved). */\nexport function restoreCheckpoint(rootDir: string, id: string): RestoreResult {\n const cp = loadCheckpoint(rootDir, id);\n const absRoot = resolve(rootDir);\n const result: RestoreResult = { restored: [], removed: [], skipped: [] };\n if (!cp) {\n result.skipped.push({ path: \"(checkpoint)\", reason: `not found: ${id}` });\n return result;\n }\n for (const f of cp.files) {\n const abs = resolve(absRoot, f.path);\n if (abs !== absRoot && !abs.startsWith(`${absRoot}${sep}`)) {\n result.skipped.push({ path: f.path, reason: \"path escapes rootDir\" });\n continue;\n }\n try {\n if (f.content === null) {\n if (existsSync(abs)) {\n rmSync(abs);\n result.removed.push(f.path);\n }\n } else {\n mkdirSync(dirname(abs), { recursive: true });\n writeFileSync(abs, f.content, \"utf8\");\n result.restored.push(f.path);\n }\n } catch (err) {\n result.skipped.push({ path: f.path, reason: (err as Error).message });\n }\n }\n return result;\n}\n\nexport function deleteCheckpoint(rootDir: string, id: string): boolean {\n const cpPath = snapshotPath(rootDir, id);\n let removed = false;\n if (existsSync(cpPath)) {\n try {\n rmSync(cpPath);\n removed = true;\n } catch {\n return false;\n }\n }\n const items = listCheckpoints(rootDir);\n const next = items.filter((m) => m.id !== id);\n if (next.length !== items.length) {\n writeIndex(rootDir, next);\n removed = true;\n }\n return removed;\n}\n\n/** Format ms-timestamp diff as human-readable relative age. */\nexport function fmtAgo(ms: number): string {\n const now = Date.now();\n const diff = Math.max(0, now - ms);\n const s = Math.floor(diff / 1000);\n if (s < 60) return `${s}s ago`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ago`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h}h ago`;\n const d = Math.floor(h / 24);\n return `${d}d ago`;\n}\n","/** Persists structured plan state alongside the JSONL log; markdown body lives in the log (it was a tool result) and replays on resume. */\n\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n readdirSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { sanitizeName, sessionsDir } from \"../memory/session.js\";\nimport type { PlanStep } from \"../tools/plan.js\";\n\nexport interface PlanStateOnDisk {\n /** File format version — bump when shape changes. */\n version: 1;\n steps: PlanStep[];\n completedStepIds: string[];\n /** ISO8601 timestamp of the last write. */\n updatedAt: string;\n body?: string;\n summary?: string;\n}\n\nexport function planStatePath(sessionName: string): string {\n return join(sessionsDir(), `${sanitizeName(sessionName)}.plan.json`);\n}\n\nexport function loadPlanState(sessionName: string): PlanStateOnDisk | null {\n const path = planStatePath(sessionName);\n if (!existsSync(path)) return null;\n try {\n const raw = readFileSync(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<PlanStateOnDisk>;\n if (!parsed || typeof parsed !== \"object\") return null;\n if (parsed.version !== 1) return null;\n if (!Array.isArray(parsed.steps)) return null;\n if (!Array.isArray(parsed.completedStepIds)) return null;\n if (typeof parsed.updatedAt !== \"string\") return null;\n // Defensive: filter out any malformed step entries so a partially\n // corrupted file still yields a usable subset.\n const steps: PlanStep[] = [];\n for (const s of parsed.steps) {\n if (!s || typeof s !== \"object\") continue;\n const e = s as unknown as Record<string, unknown>;\n if (typeof e.id !== \"string\" || !e.id) continue;\n if (typeof e.title !== \"string\" || !e.title) continue;\n if (typeof e.action !== \"string\" || !e.action) continue;\n const step: PlanStep = { id: e.id, title: e.title, action: e.action };\n if (e.risk === \"low\" || e.risk === \"med\" || e.risk === \"high\") step.risk = e.risk;\n steps.push(step);\n }\n if (steps.length === 0) return null;\n const completedStepIds = parsed.completedStepIds.filter(\n (id): id is string => typeof id === \"string\" && id.length > 0,\n );\n const out: PlanStateOnDisk = {\n version: 1,\n steps,\n completedStepIds,\n updatedAt: parsed.updatedAt,\n };\n if (typeof parsed.body === \"string\" && parsed.body) out.body = parsed.body;\n if (typeof parsed.summary === \"string\" && parsed.summary) out.summary = parsed.summary;\n return out;\n } catch {\n return null;\n }\n}\n\n/** Best-effort: write failure logs to stderr instead of crashing the TUI. */\nexport function savePlanState(\n sessionName: string,\n steps: PlanStep[],\n completedStepIds: Iterable<string>,\n extras?: { body?: string; summary?: string },\n): void {\n const path = planStatePath(sessionName);\n try {\n mkdirSync(dirname(path), { recursive: true });\n const state: PlanStateOnDisk = {\n version: 1,\n steps,\n completedStepIds: [...completedStepIds],\n updatedAt: new Date().toISOString(),\n };\n if (extras?.body) state.body = extras.body;\n if (extras?.summary) state.summary = extras.summary;\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n } catch (err) {\n process.stderr.write(\n `▸ plan-store: failed to save plan for \"${sessionName}\": ${(err as Error).message}\\n`,\n );\n }\n}\n\n/** Remove the persisted plan, if any. Used on cancel / clean reset. */\nexport function clearPlanState(sessionName: string): void {\n const path = planStatePath(sessionName);\n try {\n if (existsSync(path)) unlinkSync(path);\n } catch {\n /* nothing to do — leftover file is harmless, will be overwritten next save */\n }\n}\n\n/** Random suffix avoids same-millisecond collision; `:`/`.` swapped for Windows-safe filenames. */\nexport function archivePlanState(sessionName: string): string | null {\n const active = planStatePath(sessionName);\n if (!existsSync(active)) return null;\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const suffix = Math.random().toString(36).slice(2, 6);\n const archive = join(\n sessionsDir(),\n `${sanitizeName(sessionName)}.plan.${stamp}-${suffix}.done.json`,\n );\n try {\n renameSync(active, archive);\n return archive;\n } catch (err) {\n process.stderr.write(\n `▸ plan-store: failed to archive plan for \"${sessionName}\": ${(err as Error).message}\\n`,\n );\n return null;\n }\n}\n\nexport interface PlanArchiveSummary {\n path: string;\n completedAt: string;\n steps: PlanStep[];\n completedStepIds: string[];\n /** Markdown body, when the archive carried it. */\n body?: string;\n /** One-line human-friendly title, when supplied. */\n summary?: string;\n}\n\nexport function listPlanArchives(sessionName: string): PlanArchiveSummary[] {\n const dir = sessionsDir();\n if (!existsSync(dir)) return [];\n const prefix = `${sanitizeName(sessionName)}.plan.`;\n const suffix = \".done.json\";\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return [];\n }\n const summaries: PlanArchiveSummary[] = [];\n for (const name of entries) {\n if (!name.startsWith(prefix) || !name.endsWith(suffix)) continue;\n const full = join(dir, name);\n try {\n const raw = readFileSync(full, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<PlanStateOnDisk>;\n if (parsed.version !== 1) continue;\n if (!Array.isArray(parsed.steps) || parsed.steps.length === 0) continue;\n const steps = parsed.steps.filter(\n (s): s is PlanStep =>\n !!s &&\n typeof s === \"object\" &&\n typeof (s as PlanStep).id === \"string\" &&\n typeof (s as PlanStep).title === \"string\" &&\n typeof (s as PlanStep).action === \"string\",\n );\n if (steps.length === 0) continue;\n const completedStepIds = Array.isArray(parsed.completedStepIds)\n ? parsed.completedStepIds.filter((id): id is string => typeof id === \"string\" && !!id)\n : [];\n // Prefer the file's own updatedAt; fall back to mtime if missing\n // or unparseable so a hand-edited archive still sorts sensibly.\n let completedAt = typeof parsed.updatedAt === \"string\" ? parsed.updatedAt : \"\";\n if (!completedAt || Number.isNaN(Date.parse(completedAt))) {\n try {\n completedAt = statSync(full).mtime.toISOString();\n } catch {\n completedAt = new Date(0).toISOString();\n }\n }\n const entry: PlanArchiveSummary = { path: full, completedAt, steps, completedStepIds };\n if (typeof parsed.body === \"string\" && parsed.body) entry.body = parsed.body;\n if (typeof parsed.summary === \"string\" && parsed.summary) entry.summary = parsed.summary;\n summaries.push(entry);\n } catch {\n // Skip the corrupt archive entirely.\n }\n }\n summaries.sort((a, b) => b.completedAt.localeCompare(a.completedAt));\n return summaries;\n}\n\n/** Falls back to raw ISO string past a week — \"47 days ago\" misleads more than it helps. */\nexport function relativeTime(updatedAt: string, now: number = Date.now()): string {\n const t = Date.parse(updatedAt);\n if (Number.isNaN(t)) return updatedAt;\n const diffMs = Math.max(0, now - t);\n const sec = Math.floor(diffMs / 1000);\n if (sec < 60) return `${sec}s ago`;\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.floor(hr / 24);\n if (day < 7) return `${day}d ago`;\n return updatedAt.slice(0, 10);\n}\n","import type { SlashArgContext, SlashCommandSpec, SlashGroup } from \"./types.js\";\n\nexport const SLASH_GROUP_ORDER = [\n \"setup\",\n \"info\",\n \"chat\",\n \"extend\",\n \"session\",\n \"code\",\n \"jobs\",\n \"advanced\",\n] as const satisfies readonly SlashGroup[];\n\nexport const SLASH_GROUP_LABEL: Record<SlashGroup, string> = {\n setup: \"SETUP\",\n info: \"INFO\",\n chat: \"CHAT\",\n extend: \"EXTEND\",\n session: \"SESSION\",\n code: \"CODE\",\n jobs: \"JOBS\",\n advanced: \"ADVANCED\",\n};\n\nconst SLASH_GROUP_RANK = new Map<SlashGroup, number>(\n SLASH_GROUP_ORDER.map((group, index) => [group, index]),\n);\n\nexport function orderSlashCommandsByGroup<T extends Pick<SlashCommandSpec, \"group\">>(\n commands: readonly T[],\n): T[] {\n return commands\n .map((command, index) => ({ command, index }))\n .sort((a, b) => {\n const groupDiff =\n SLASH_GROUP_RANK.get(a.command.group)! - SLASH_GROUP_RANK.get(b.command.group)!;\n if (groupDiff !== 0) return groupDiff;\n return a.index - b.index;\n })\n .map((entry) => entry.command);\n}\n\nexport const SLASH_COMMANDS: readonly SlashCommandSpec[] = [\n { cmd: \"help\", group: \"chat\", summary: \"show the full command reference\", aliases: [\"?\"] },\n {\n cmd: \"new\",\n group: \"chat\",\n summary: \"start a fresh conversation (clear context + scrollback)\",\n aliases: [\"reset\", \"clear\"],\n },\n { cmd: \"retry\", group: \"chat\", summary: \"truncate & resend your last message (fresh sample)\" },\n {\n cmd: \"compact\",\n group: \"chat\",\n summary:\n \"fold older turns into a summary message (cache-safe). Auto-fires at 50% ctx; this is the manual trigger.\",\n },\n {\n cmd: \"stop\",\n group: \"chat\",\n summary: \"abort the current model turn (typed alternative to Esc)\",\n },\n {\n cmd: \"btw\",\n group: \"chat\",\n argsHint: \"<question>\",\n summary:\n \"ask a quick side question — answered from a blank slate, never added to the conversation context\",\n },\n\n {\n cmd: \"preset\",\n group: \"setup\",\n argsHint: \"<auto|flash|pro>\",\n summary: \"model bundle — auto escalates flash → pro, flash/pro lock. Bare opens picker.\",\n argCompleter: [\"auto\", \"flash\", \"pro\"],\n },\n {\n cmd: \"model\",\n group: \"setup\",\n argsHint: \"<id>\",\n summary: \"switch DeepSeek model id. Bare opens picker.\",\n argCompleter: \"models\",\n },\n {\n cmd: \"language\",\n group: \"setup\",\n argsHint: \"<EN|zh-CN>\",\n summary: \"switch the runtime language\",\n argCompleter: [\"EN\", \"zh-CN\"],\n aliases: [\"lang\"],\n },\n {\n cmd: \"theme\",\n group: \"setup\",\n argsHint: \"[auto|default|dark|light|tokyo-night|github-dark|github-light|high-contrast]\",\n summary: \"show or persist the terminal theme preference. Bare opens picker.\",\n argCompleter: [\n \"auto\",\n \"default\",\n \"dark\",\n \"light\",\n \"tokyo-night\",\n \"github-dark\",\n \"github-light\",\n \"high-contrast\",\n ],\n },\n\n { cmd: \"status\", group: \"info\", summary: \"current model, flags, context, session\" },\n {\n cmd: \"cost\",\n group: \"info\",\n argsHint: \"[text]\",\n summary:\n \"bare → last turn's spend (Usage card); with text → estimate cost of sending it next (worst-case + likely-cache)\",\n },\n {\n cmd: \"context\",\n group: \"info\",\n summary: \"show context-window breakdown (system / tools / log / input)\",\n },\n {\n cmd: \"stats\",\n group: \"info\",\n summary:\n \"cross-session cost dashboard (today / week / month / all-time · cache hit · vs Claude)\",\n },\n {\n cmd: \"doctor\",\n group: \"info\",\n summary: \"health check (api / config / api-reach / index / hooks / project)\",\n },\n {\n cmd: \"keys\",\n group: \"info\",\n summary: \"keyboard + mouse + copy/paste reference\",\n },\n {\n cmd: \"copy\",\n group: \"chat\",\n summary: \"vim/tmux-style copy mode — j/k navigate, v select, y yank to clipboard\",\n },\n {\n cmd: \"feedback\",\n group: \"info\",\n summary: \"open a GitHub issue with diagnostic info copied to clipboard\",\n },\n\n { cmd: \"sessions\", group: \"session\", summary: \"list saved sessions (current marked with ▸)\" },\n\n { cmd: \"mcp\", group: \"extend\", summary: \"list MCP servers + tools attached to this session\" },\n {\n cmd: \"resource\",\n group: \"extend\",\n argsHint: \"[uri]\",\n summary: \"browse + read MCP resources (no arg → list URIs; <uri> → fetch contents)\",\n argCompleter: \"mcp-resources\",\n },\n {\n cmd: \"prompt\",\n group: \"extend\",\n argsHint: \"[name]\",\n summary: \"browse + fetch MCP prompts (no arg → list names; <name> → render prompt)\",\n argCompleter: \"mcp-prompts\",\n },\n {\n cmd: \"memory\",\n group: \"extend\",\n argsHint: \"[list|show <name>|forget <name>|clear <scope> confirm]\",\n summary: \"show / manage pinned memory (REASONIX.md + ~/.reasonix/memory)\",\n },\n {\n cmd: \"skill\",\n group: \"extend\",\n argsHint: \"[list|show <name>|new <name>|<name> [args]]\",\n summary: \"list / run / scaffold user skills (<project>/.reasonix/skills + ~/.reasonix/skills)\",\n },\n\n {\n cmd: \"init\",\n group: \"code\",\n argsHint: \"[force]\",\n summary:\n \"scan the project and synthesize a baseline REASONIX.md (model writes; review with /apply). `force` overwrites an existing file.\",\n contextual: \"code\",\n argCompleter: [\"force\"],\n },\n {\n cmd: \"apply\",\n group: \"code\",\n argsHint: \"[N|N,M|N-M]\",\n summary:\n \"commit pending edit blocks to disk (no arg → all; `1`, `1,3`, or `1-4` → that subset, rest stay pending)\",\n contextual: \"code\",\n },\n {\n cmd: \"discard\",\n group: \"code\",\n argsHint: \"[N|N,M|N-M]\",\n summary: \"drop pending edit blocks without writing (no arg → all; indices → that subset)\",\n contextual: \"code\",\n },\n {\n cmd: \"walk\",\n group: \"code\",\n summary:\n \"step through pending edits one block at a time (git-add-p style: y/n per block, a apply rest, A flip AUTO)\",\n contextual: \"code\",\n },\n {\n cmd: \"undo\",\n group: \"code\",\n summary: \"roll back the last applied edit batch\",\n contextual: \"code\",\n },\n {\n cmd: \"history\",\n group: \"code\",\n summary: \"list every edit batch this session (ids for /show, undone markers)\",\n contextual: \"code\",\n },\n {\n cmd: \"show\",\n group: \"code\",\n argsHint: \"[id]\",\n summary: \"dump a stored edit diff (omit id for newest non-undone)\",\n contextual: \"code\",\n },\n {\n cmd: \"commit\",\n group: \"code\",\n argsHint: '\"msg\"',\n summary: \"git add -A && git commit -m ...\",\n contextual: \"code\",\n },\n {\n cmd: \"mode\",\n group: \"code\",\n argsHint: \"[review|auto|yolo]\",\n summary:\n \"edit-gate: review (queue) · auto (apply+undo) · yolo (apply+auto-shell). Shift+Tab cycles.\",\n contextual: \"code\",\n argCompleter: [\"review\", \"auto\", \"yolo\"],\n },\n {\n cmd: \"plan\",\n group: \"code\",\n argsHint: \"[on|off]\",\n summary: \"toggle read-only plan mode (writes bounced until submit_plan + approval)\",\n contextual: \"code\",\n argCompleter: [\"on\", \"off\"],\n },\n {\n cmd: \"checkpoint\",\n group: \"code\",\n argsHint: \"[name|list|forget <id>]\",\n summary:\n \"snapshot every file the session has touched (Cursor-style internal store, not git). /checkpoint alone lists.\",\n contextual: \"code\",\n argCompleter: [\"list\", \"forget\"],\n },\n {\n cmd: \"restore\",\n group: \"code\",\n argsHint: \"<name|id>\",\n summary: \"roll back files to a named checkpoint (see /checkpoint list)\",\n contextual: \"code\",\n },\n {\n cmd: \"cwd\",\n group: \"code\",\n argsHint: \"<path>\",\n summary:\n \"switch the workspace root mid-session — re-points fs / shell / memory tools, reloads project hooks, refreshes the at-mention walker\",\n contextual: \"code\",\n aliases: [\"sandbox\"],\n },\n\n {\n cmd: \"jobs\",\n group: \"jobs\",\n summary: \"list background jobs started by run_background\",\n contextual: \"code\",\n },\n {\n cmd: \"kill\",\n group: \"jobs\",\n argsHint: \"<id>\",\n summary: \"stop a background job by id (SIGTERM → SIGKILL after grace)\",\n contextual: \"code\",\n },\n {\n cmd: \"logs\",\n group: \"jobs\",\n argsHint: \"<id> [lines]\",\n summary: \"tail a background job's output (default last 80 lines)\",\n contextual: \"code\",\n },\n\n {\n cmd: \"pro\",\n group: \"advanced\",\n argsHint: \"[off]\",\n summary: \"arm v4-pro for the NEXT turn only (one-shot · auto-disarms after turn)\",\n argCompleter: [\"off\"],\n },\n {\n cmd: \"budget\",\n group: \"advanced\",\n argsHint: \"[usd|off]\",\n summary:\n \"session USD cap — warns at 80%, refuses next turn at 100%. Off by default. /budget alone shows status\",\n argCompleter: [\"off\", \"1\", \"5\", \"10\", \"20\", \"50\"],\n },\n {\n cmd: \"search-engine\",\n group: \"advanced\",\n argsHint: \"<mojeek|searxng> [<endpoint>]\",\n summary: \"switch web search backend — mojeek (default, no deps) or searxng (self-hosted)\",\n argCompleter: [\"mojeek\", \"searxng\"],\n aliases: [\"se\"],\n },\n {\n cmd: \"hooks\",\n group: \"advanced\",\n argsHint: \"[reload]\",\n summary: \"list active hooks (settings.json under .reasonix/) · reload re-reads from disk\",\n },\n {\n cmd: \"permissions\",\n group: \"advanced\",\n argsHint: \"[list|add <prefix>|remove <prefix|N>|clear confirm]\",\n summary:\n \"show / edit shell allowlist (builtin read-only · per-project: ~/.reasonix/config.json)\",\n argCompleter: [\"list\", \"add\", \"remove\", \"clear\"],\n },\n {\n cmd: \"dashboard\",\n group: \"advanced\",\n argsHint: \"[stop]\",\n summary: \"launch the embedded web dashboard (127.0.0.1, token-gated)\",\n argCompleter: [\"stop\"],\n },\n {\n cmd: \"loop\",\n group: \"advanced\",\n argsHint: \"<5s..6h> <prompt> · stop · (no args = status)\",\n summary: \"auto-resubmit <prompt> every <interval> until you type something / Esc / /loop stop\",\n },\n {\n cmd: \"plans\",\n group: \"advanced\",\n summary: \"list this session's active + archived plans, newest first\",\n },\n {\n cmd: \"replay\",\n group: \"advanced\",\n summary: \"load an archived plan as a read-only Time Travel snapshot (default: newest)\",\n argsHint: \"[N]\",\n },\n {\n cmd: \"update\",\n group: \"advanced\",\n summary: \"show current vs latest version + the shell command to upgrade\",\n },\n { cmd: \"exit\", group: \"advanced\", summary: \"quit the TUI\", aliases: [\"quit\", \"q\"] },\n];\n\nexport function suggestSlashCommands(\n prefix: string,\n codeMode = false,\n counts?: Readonly<Record<string, number>>,\n): SlashCommandSpec[] {\n const p = prefix.toLowerCase();\n const matches = SLASH_COMMANDS.filter((c) => {\n // Empty prefix = browsing the menu — show the full release command surface except\n // advanced rows, which remain collapsed behind the footer hint.\n if (p === \"\") return c.group !== \"advanced\";\n if (c.contextual === \"code\" && !codeMode) return false;\n if (c.cmd.startsWith(p)) return true;\n return c.aliases?.some((a) => a.startsWith(p)) ?? false;\n });\n if (p === \"\") return orderSlashCommandsByGroup(matches);\n if (!counts) return matches;\n const indexOf = new Map(matches.map((s, i) => [s.cmd, i]));\n return [...matches].sort((a, b) => {\n const diff = (counts[b.cmd] ?? 0) - (counts[a.cmd] ?? 0);\n if (diff !== 0) return diff;\n return (indexOf.get(a.cmd) ?? 0) - (indexOf.get(b.cmd) ?? 0);\n });\n}\n\nexport function countAdvancedCommands(codeMode: boolean): number {\n return SLASH_COMMANDS.filter(\n (c) => c.group === \"advanced\" && (c.contextual !== \"code\" || codeMode),\n ).length;\n}\n\n/** alias → canonical cmd map, derived from SLASH_COMMANDS at module init. */\nconst ALIAS_TO_CMD: Readonly<Record<string, string>> = (() => {\n const m: Record<string, string> = {};\n for (const spec of SLASH_COMMANDS) {\n if (!spec.aliases) continue;\n for (const a of spec.aliases) m[a] = spec.cmd;\n }\n return m;\n})();\n\nexport function resolveSlashAlias(name: string): string {\n return ALIAS_TO_CMD[name] ?? name;\n}\n\n/** Picker fires only when arg tail has no internal whitespace; past that it's a usage hint. */\nexport function detectSlashArgContext(input: string, codeMode = false): SlashArgContext | null {\n const m = /^\\/(\\S+) ([\\s\\S]*)$/.exec(input);\n if (!m) return null;\n const cmdName = resolveSlashAlias(m[1]!.toLowerCase());\n const tail = m[2] ?? \"\";\n const spec = SLASH_COMMANDS.find(\n (s) => s.cmd === cmdName && (s.contextual !== \"code\" || codeMode),\n );\n if (!spec) return null;\n const hasInternalSpace = /\\s/.test(tail);\n const partialOffset = input.length - tail.length;\n if (hasInternalSpace) {\n return { spec, partial: tail, partialOffset, kind: \"hint\" };\n }\n return {\n spec,\n partial: tail,\n partialOffset,\n kind: spec.argCompleter ? \"picker\" : \"hint\",\n };\n}\n\nexport function parseSlash(text: string): { cmd: string; args: string[] } | null {\n if (!text.startsWith(\"/\")) return null;\n const parts = text.slice(1).trim().split(/\\s+/);\n const cmd = parts[0]?.toLowerCase() ?? \"\";\n if (!cmd) return null;\n return { cmd, args: parts.slice(1) };\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readFileSync","readdirSync","writeFileSync","dirname","join","join","existsSync","readFileSync","mkdirSync","dirname","writeFileSync","readdirSync"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/event-redaction.ts","../../src/core/eventize.ts","../../src/core/pause-policy.ts","../../src/tools/skills.ts"],"sourcesContent":["const SECRET_KEY_RE =\n /(secret|token|password|passphrase|api[-_]?key|authorization|cookie|credential|passwd|pwd)/i;\n\nexport function redactEventValue<T>(value: T): T {\n return redactUnknown(value, null) as T;\n}\n\nfunction redactUnknown(value: unknown, key: string | null): unknown {\n if (Array.isArray(value)) return value.map((item) => redactUnknown(item, null));\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactUnknown(childValue, childKey);\n }\n return out;\n }\n if (typeof value === \"string\") {\n if ((key && SECRET_KEY_RE.test(key)) || /^Bearer\\s+/i.test(value)) return \"[redacted]\";\n }\n return value;\n}\n","import type { LoopEvent } from \"../loop.js\";\nimport type { ChatMessage, RawUsage, ToolCall } from \"../types.js\";\nimport { redactEventValue } from \"./event-redaction.js\";\nimport type {\n Event,\n ErrorEvent as KernelErrorEvent,\n ModelDeltaEvent,\n ModelFinalEvent,\n ModelTurnStartedEvent,\n SessionCompactedEvent,\n SessionOpenedEvent,\n SlashInvokedEvent,\n StatusEvent,\n ToolCallEvent,\n ToolConfirmAllowEvent,\n ToolConfirmAlwaysAllowEvent,\n ToolConfirmDenyEvent,\n ToolDispatchedEvent,\n ToolIntentEvent,\n ToolPreparingEvent,\n ToolResultEvent,\n UserMessageEvent,\n} from \"./events.js\";\n\nexport interface EventizeContext {\n model: string;\n prefixHash: string;\n reasoningEffort: \"high\" | \"max\";\n}\n\nexport class Eventizer {\n private nextId = 0;\n private lastTurn = -1;\n private nextToolSeq = 0;\n /** Tool calls announced via tool_call_delta but not yet dispatched. FIFO upgraded by tool_start. */\n private preparingCallIds: string[] = [];\n /** Tool calls dispatched but not yet finished. FIFO popped by tool result. */\n private inflightCallIds: string[] = [];\n /** Per-turn dedupe so each toolCallIndex emits exactly one tool.preparing. */\n private announcedToolIdx = new Set<string>();\n\n consume(ev: LoopEvent, ctx: EventizeContext): Event[] {\n const out: Event[] = [];\n if (ev.turn !== this.lastTurn) {\n this.lastTurn = ev.turn;\n this.announcedToolIdx.clear();\n out.push(this.turnStartedEvent(ev.turn, ctx));\n }\n switch (ev.role) {\n case \"assistant_delta\":\n if (ev.content) out.push(this.deltaEvent(ev.turn, \"content\", ev.content));\n if (ev.reasoningDelta) out.push(this.deltaEvent(ev.turn, \"reasoning\", ev.reasoningDelta));\n break;\n case \"tool_call_delta\": {\n const idx = ev.toolCallIndex;\n const name = ev.toolName;\n if (idx === undefined || !name) break;\n const key = `${ev.turn}:${idx}`;\n if (this.announcedToolIdx.has(key)) break;\n this.announcedToolIdx.add(key);\n const callId = `tc-${++this.nextToolSeq}`;\n this.preparingCallIds.push(callId);\n out.push(this.toolPreparingEvent(ev.turn, callId, name));\n break;\n }\n case \"assistant_final\":\n out.push(this.finalEvent(ev));\n break;\n case \"tool_start\": {\n const callId = this.preparingCallIds.shift() ?? `tc-${++this.nextToolSeq}`;\n this.inflightCallIds.push(callId);\n out.push(this.toolIntentEvent(ev.turn, callId, ev.toolName ?? \"\", ev.toolArgs ?? \"\"));\n out.push(this.toolDispatchedEvent(ev.turn, callId));\n break;\n }\n case \"tool\": {\n const callId = this.inflightCallIds.shift() ?? `tc-orphan-${++this.nextToolSeq}`;\n const ok = !looksLikeToolError(ev.content, ev.toolName);\n out.push(this.toolResultEvent(ev.turn, callId, ok, ev.content, 0));\n break;\n }\n case \"warning\":\n out.push(this.classifyWarning(ev));\n break;\n case \"error\":\n out.push(this.errorEvent(ev.turn, ev.error ?? ev.content, false));\n break;\n case \"status\":\n out.push(this.statusEvent(ev.turn, ev.content));\n break;\n // `done` / `branch_*` intentionally drop — no kernel-level event.\n default:\n break;\n }\n return out;\n }\n\n emitUserMessage(turn: number, text: string): UserMessageEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"user.message\",\n text,\n };\n }\n\n emitSlashInvoked(turn: number, name: string, args: string): SlashInvokedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"slash.invoked\",\n name,\n args,\n };\n }\n\n emitSessionOpened(turn: number, name: string, resumedFromTurn: number): SessionOpenedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"session.opened\",\n name,\n resumedFromTurn,\n };\n }\n\n emitSessionCompacted(\n turn: number,\n before: number,\n after: number,\n reason: \"user\" | \"auto-context-pressure\",\n replacementMessages: ReadonlyArray<ChatMessage>,\n ): SessionCompactedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"session.compacted\",\n beforeMessages: before,\n afterMessages: after,\n reason,\n replacementMessages,\n };\n }\n\n emitToolCall(turn: number, name: string, args: Record<string, unknown>): ToolCallEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.call\",\n name,\n args: redactEventValue(args),\n };\n }\n\n emitToolConfirmAllow(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n ): ToolConfirmAllowEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.allow\",\n kind,\n payload: redactEventValue(payload),\n };\n }\n\n emitToolConfirmDeny(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n denyContext?: string,\n ): ToolConfirmDenyEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.deny\",\n kind,\n payload: redactEventValue(payload),\n denyContext,\n };\n }\n\n emitToolConfirmAlwaysAllow(\n turn: number,\n kind: \"run_command\" | \"run_background\",\n payload: { command: string },\n prefix: string,\n ): ToolConfirmAlwaysAllowEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.confirm.always_allow\",\n kind,\n payload: redactEventValue(payload),\n prefix,\n };\n }\n\n private turnStartedEvent(turn: number, ctx: EventizeContext): ModelTurnStartedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"model.turn.started\",\n model: ctx.model,\n reasoningEffort: ctx.reasoningEffort,\n prefixHash: ctx.prefixHash,\n };\n }\n\n private deltaEvent(\n turn: number,\n channel: \"content\" | \"reasoning\" | \"tool_args\",\n text: string,\n ): ModelDeltaEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"model.delta\",\n channel,\n text,\n };\n }\n\n private finalEvent(ev: LoopEvent): ModelFinalEvent {\n const usage: RawUsage = ev.stats\n ? {\n prompt_tokens: ev.stats.usage.promptTokens,\n completion_tokens: ev.stats.usage.completionTokens,\n total_tokens: ev.stats.usage.totalTokens,\n prompt_cache_hit_tokens: ev.stats.usage.promptCacheHitTokens,\n prompt_cache_miss_tokens: ev.stats.usage.promptCacheMissTokens,\n }\n : {};\n const costUsd = ev.stats?.cost ?? 0;\n const out: ModelFinalEvent = {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: \"model.final\",\n content: ev.content,\n // toolCalls land later via tool_start → tool.intent — not in this event.\n toolCalls: [] as ReadonlyArray<ToolCall>,\n usage,\n costUsd,\n };\n if (ev.forcedSummary) out.forcedSummary = true;\n return out;\n }\n\n private toolPreparingEvent(turn: number, callId: string, name: string): ToolPreparingEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.preparing\",\n callId,\n name,\n };\n }\n\n private toolIntentEvent(\n turn: number,\n callId: string,\n name: string,\n args: string,\n ): ToolIntentEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.intent\",\n callId,\n name,\n args,\n };\n }\n\n private toolDispatchedEvent(turn: number, callId: string): ToolDispatchedEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.dispatched\",\n callId,\n };\n }\n\n private toolResultEvent(\n turn: number,\n callId: string,\n ok: boolean,\n output: string,\n durationMs: number,\n ): ToolResultEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"tool.result\",\n callId,\n ok,\n output,\n durationMs,\n };\n }\n\n private statusEvent(turn: number, text: string): StatusEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"status\",\n text,\n };\n }\n\n private errorEvent(turn: number, message: string, recoverable: boolean): KernelErrorEvent {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn,\n type: \"error\",\n message,\n recoverable,\n };\n }\n\n /** Pattern-match warning text since LoopEvent doesn't carry a typed kind. */\n private classifyWarning(ev: LoopEvent): Event {\n const c = ev.content;\n if (/\\bauto-escalating to\\b|\\barmed\\b.*pro|NEEDS_PRO/.test(c)) {\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: \"policy.escalated\",\n fromModel: \"\",\n toModel: \"\",\n reason: c.includes(\"armed\") ? \"user-request\" : \"self-report\",\n };\n }\n if (/budget\\b.*\\$|\\$\\d.*\\/\\s*\\$\\d/.test(c)) {\n const blocked = /blocked|exceeded|refus/i.test(c);\n return {\n id: ++this.nextId,\n ts: new Date().toISOString(),\n turn: ev.turn,\n type: blocked ? \"policy.budget.blocked\" : \"policy.budget.warning\",\n spentUsd: 0,\n capUsd: 0,\n };\n }\n return this.errorEvent(ev.turn, c, true);\n }\n}\n\nfunction looksLikeToolError(content: string, _toolName: string | undefined): boolean {\n if (!content) return false;\n if (content.startsWith(\"ERROR:\")) return true;\n if (content.startsWith(\"[hook block]\")) return true;\n if (/^\\{\"error\"\\s*:/.test(content)) return true;\n if (/\\bConfirmationError:|\\bNeedsConfirmationError\\b/.test(content)) return true;\n return false;\n}\n","/** Shared editMode → auto-resolve rules so CLI TUI + Tauri desktop don't drift. */\n\nimport type { EditMode } from \"../config.js\";\nimport type { PauseRequest } from \"./pause-gate.js\";\n\n/** Mirrors shell.ts's allowAll bypass: only review still pauses on checkpoints. */\nexport function shouldAutoResolveCheckpoint(editMode: EditMode): boolean {\n return editMode === \"auto\" || editMode === \"yolo\";\n}\n\n/** null = surface to user; non-null = resolve gate immediately with this verdict. */\nexport function autoResolveVerdict(req: PauseRequest, editMode: EditMode): unknown | null {\n if (req.kind === \"plan_checkpoint\" && shouldAutoResolveCheckpoint(editMode)) {\n return { type: \"continue\" };\n }\n return null;\n}\n","/** runAs: inline appends the body to the parent log; subagent spawns an isolated child loop and only returns the final answer. */\n\nimport { type Skill, SkillStore } from \"../skills.js\";\nimport type { ToolRegistry } from \"../tools.js\";\n\n/** Returns serialized tool-result string — dispatch path is pure pass-through. */\nexport type SubagentRunner = (skill: Skill, task: string, signal?: AbortSignal) => Promise<string>;\n\nexport interface SkillToolsOptions {\n /** Override `$HOME` — tests set this to a tmpdir. */\n homeDir?: string;\n projectRoot?: string;\n /** When omitted, subagent skills error rather than silently falling back to inline (loses isolation). */\n subagentRunner?: SubagentRunner;\n /** Hide built-in skills (test-only knob; production callers leave off). */\n disableBuiltins?: boolean;\n}\n\nexport function registerSkillTools(\n registry: ToolRegistry,\n opts: SkillToolsOptions = {},\n): ToolRegistry {\n const store = new SkillStore({\n homeDir: opts.homeDir,\n projectRoot: opts.projectRoot,\n disableBuiltins: opts.disableBuiltins,\n });\n const subagentRunner = opts.subagentRunner;\n\n registry.register({\n name: \"run_skill\",\n description:\n \"Invoke a playbook from the Skills index pinned in the system prompt. Each entry is a self-contained instruction block. Pass `name` as the BARE skill identifier (e.g. 'explore'), NOT the `[🧬 subagent]` tag that appears after it in the index. Entries tagged `[🧬 subagent]` spawn an isolated subagent — only the final distilled answer comes back, the model's tool calls + reasoning during the run never enter your context. Plain skills are inlined: the body becomes a tool result you read and follow. For subagent skills, supply 'arguments' describing the concrete task — they'll be the only context the subagent has.\",\n readOnly: true,\n parallelSafe: true,\n parameters: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"Skill identifier as it appears in the pinned Skills index (e.g. 'explore', 'review', 'security-review'). Case-sensitive.\",\n },\n arguments: {\n type: \"string\",\n description:\n \"Free-form arguments the skill should act on. For inline skills: appended to the body as an 'Arguments:' line; the skill's own instructions decide how to consume them. For `[🧬 subagent]` skills: REQUIRED — becomes the entire task description the subagent receives, since it has no other context.\",\n },\n },\n required: [\"name\"],\n },\n fn: async (args: { name?: unknown; arguments?: unknown }, ctx) => {\n const raw = typeof args.name === \"string\" ? args.name.trim() : \"\";\n if (!raw) {\n return JSON.stringify({ error: \"run_skill requires a 'name' argument\" });\n }\n // Defensive: The Skills index writes entries like\n // `explore [🧬 subagent]`, and models sometimes copy the\n // decoration verbatim into the `name` argument instead of just\n // the identifier. Rather than reject those calls:\n // 1. Drop any `[...]` bracketed tag (possibly containing\n // emoji + \"subagent\" label).\n // 2. Find the first whitespace-delimited token whose first\n // char is alphanumeric — that's the skill identifier,\n // whether the tag came before or after the name.\n const stripped = raw.replace(/\\[[^\\]]*\\]/g, \" \").trim();\n const tokens = stripped.split(/\\s+/).filter(Boolean);\n const name = tokens.find((t) => /^[a-zA-Z0-9]/.test(t)) ?? \"\";\n if (!name) {\n return JSON.stringify({\n error: \"run_skill requires a 'name' argument\",\n hint: `'${raw}' is just a marker/tag, not a skill name`,\n });\n }\n const skill = store.read(name);\n if (!skill) {\n const available = store\n .list()\n .map((s) => s.name)\n .join(\", \");\n return JSON.stringify({\n error: `unknown skill: ${JSON.stringify(name)}`,\n available: available || \"(none — user has not defined any skills)\",\n });\n }\n const rawArgs = typeof args.arguments === \"string\" ? args.arguments.trim() : \"\";\n\n if (skill.runAs === \"subagent\") {\n if (!subagentRunner) {\n return JSON.stringify({\n error: `run_skill: skill ${JSON.stringify(name)} is marked runAs=subagent but no subagent runner is configured for this session. Skill authors who need isolation should run inside reasonix code (or a library setup that passes subagentRunner to registerSkillTools).`,\n });\n }\n if (!rawArgs) {\n return JSON.stringify({\n error: `run_skill: skill ${JSON.stringify(name)} is a subagent and requires 'arguments' — the subagent has no other context, so describe the concrete task in the arguments field.`,\n });\n }\n return subagentRunner(skill, rawArgs, ctx?.signal);\n }\n\n // inline path — body becomes the tool result.\n const header = [\n `# Skill: ${skill.name}`,\n skill.description ? `> ${skill.description}` : \"\",\n `(scope: ${skill.scope} · ${skill.path})`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n const argsBlock = rawArgs ? `\\n\\nArguments: ${rawArgs}` : \"\";\n // The body is handed to the model verbatim. No truncation — the\n // user authored it, we trust their length choice. The append-only\n // log pays the token cost exactly once per invocation.\n return `${header}\\n\\n${skill.body}${argsBlock}`;\n },\n });\n\n return registry;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/net/proxy.ts
|
|
4
|
-
import { ProxyAgent, setGlobalDispatcher } from "undici";
|
|
5
|
-
var PROXY_ENV_KEYS = [
|
|
6
|
-
"HTTPS_PROXY",
|
|
7
|
-
"https_proxy",
|
|
8
|
-
"HTTP_PROXY",
|
|
9
|
-
"http_proxy",
|
|
10
|
-
"ALL_PROXY",
|
|
11
|
-
"all_proxy"
|
|
12
|
-
];
|
|
13
|
-
function detectProxyUrl(env = process.env) {
|
|
14
|
-
for (const key of PROXY_ENV_KEYS) {
|
|
15
|
-
const raw = env[key];
|
|
16
|
-
if (typeof raw !== "string") continue;
|
|
17
|
-
const trimmed = raw.trim();
|
|
18
|
-
if (trimmed) return trimmed;
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
var installed = false;
|
|
23
|
-
function installProxyIfConfigured(env = process.env) {
|
|
24
|
-
const url = detectProxyUrl(env);
|
|
25
|
-
if (!url) return null;
|
|
26
|
-
const reinstalled = installed;
|
|
27
|
-
setGlobalDispatcher(new ProxyAgent(url));
|
|
28
|
-
installed = true;
|
|
29
|
-
return { url, reinstalled };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export {
|
|
33
|
-
detectProxyUrl,
|
|
34
|
-
installProxyIfConfigured
|
|
35
|
-
};
|
|
36
|
-
//# sourceMappingURL=chunk-AFFZF3MW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/net/proxy.ts"],"sourcesContent":["/** Node's built-in fetch ignores HTTPS_PROXY env vars — undici's ProxyAgent has to be wired in explicitly. */\n\nimport { ProxyAgent, setGlobalDispatcher } from \"undici\";\n\n/** Env-var precedence matches curl: HTTPS_PROXY → HTTP_PROXY → ALL_PROXY, upper-case first then lower. */\nconst PROXY_ENV_KEYS = [\n \"HTTPS_PROXY\",\n \"https_proxy\",\n \"HTTP_PROXY\",\n \"http_proxy\",\n \"ALL_PROXY\",\n \"all_proxy\",\n] as const;\n\nexport function detectProxyUrl(env: NodeJS.ProcessEnv = process.env): string | null {\n for (const key of PROXY_ENV_KEYS) {\n const raw = env[key];\n if (typeof raw !== \"string\") continue;\n const trimmed = raw.trim();\n if (trimmed) return trimmed;\n }\n return null;\n}\n\nlet installed = false;\n\n/** Sets the undici global dispatcher to a ProxyAgent. Returns the proxy URL or null if no env var is set. Idempotent. */\nexport function installProxyIfConfigured(\n env: NodeJS.ProcessEnv = process.env,\n): { url: string; reinstalled: boolean } | null {\n const url = detectProxyUrl(env);\n if (!url) return null;\n const reinstalled = installed;\n setGlobalDispatcher(new ProxyAgent(url));\n installed = true;\n return { url, reinstalled };\n}\n\n/** Test-only escape hatch so the installed flag doesn't leak between vitest cases. */\nexport function _resetForTests(): void {\n installed = false;\n}\n"],"mappings":";;;AAEA,SAAS,YAAY,2BAA2B;AAGhD,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,eAAe,MAAyB,QAAQ,KAAoB;AAClF,aAAW,OAAO,gBAAgB;AAChC,UAAM,MAAM,IAAI,GAAG;AACnB,QAAI,OAAO,QAAQ,SAAU;AAC7B,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,QAAS,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAEA,IAAI,YAAY;AAGT,SAAS,yBACd,MAAyB,QAAQ,KACa;AAC9C,QAAM,MAAM,eAAe,GAAG;AAC9B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,cAAc;AACpB,sBAAoB,IAAI,WAAW,GAAG,CAAC;AACvC,cAAY;AACZ,SAAO,EAAE,KAAK,YAAY;AAC5B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/transport-from-spec.ts","../../src/mcp/preflight.ts"],"sourcesContent":["import type { McpSpec } from \"./spec.js\";\nimport { SseTransport } from \"./sse.js\";\nimport { type McpTransport, StdioTransport } from \"./stdio.js\";\nimport { StreamableHttpTransport } from \"./streamable-http.js\";\n\nexport interface BuildTransportOptions {\n /** Stdio-only env overlay — merged over process.env. SSE/Streamable-HTTP ignore it. */\n env?: Record<string, string>;\n}\n\nexport function buildTransportFromSpec(\n spec: McpSpec,\n opts: BuildTransportOptions = {},\n): McpTransport {\n if (spec.transport === \"sse\") return new SseTransport({ url: spec.url });\n if (spec.transport === \"streamable-http\") return new StreamableHttpTransport({ url: spec.url });\n return new StdioTransport({ command: spec.command, args: spec.args, env: opts.env });\n}\n","import { type Stats, statSync } from \"node:fs\";\nimport type { StdioMcpSpec } from \"./spec.js\";\n\nconst FILESYSTEM_PKG = \"@modelcontextprotocol/server-filesystem\";\n\nexport function preflightStdioSpec(spec: StdioMcpSpec): void {\n const pkgIndex = spec.args.indexOf(FILESYSTEM_PKG);\n if (pkgIndex < 0) return;\n const positional = spec.args.slice(pkgIndex + 1).filter((a) => !a.startsWith(\"-\"));\n for (const dir of positional) {\n let stat: Stats;\n try {\n stat = statSync(dir);\n } catch {\n throw new Error(\n `MCP filesystem sandbox '${dir}' does not exist — create it with: mkdir -p '${dir}'`,\n );\n }\n if (!stat.isDirectory()) {\n throw new Error(`MCP filesystem sandbox '${dir}' exists but is not a directory`);\n }\n }\n}\n"],"mappings":";;;;;;;;AAUO,SAAS,uBACd,MACA,OAA8B,CAAC,GACjB;AACd,MAAI,KAAK,cAAc,MAAO,QAAO,IAAI,aAAa,EAAE,KAAK,KAAK,IAAI,CAAC;AACvE,MAAI,KAAK,cAAc,kBAAmB,QAAO,IAAI,wBAAwB,EAAE,KAAK,KAAK,IAAI,CAAC;AAC9F,SAAO,IAAI,eAAe,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC;AACrF;;;ACjBA,SAAqB,gBAAgB;AAGrC,IAAM,iBAAiB;AAEhB,SAAS,mBAAmB,MAA0B;AAC3D,QAAM,WAAW,KAAK,KAAK,QAAQ,cAAc;AACjD,MAAI,WAAW,EAAG;AAClB,QAAM,aAAa,KAAK,KAAK,MAAM,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AACjF,aAAW,OAAO,YAAY;AAC5B,QAAI;AACJ,QAAI;AACF,aAAO,SAAS,GAAG;AAAA,IACrB,QAAQ;AACN,YAAM,IAAI;AAAA,QACR,2BAA2B,GAAG,qDAAgD,GAAG;AAAA,MACnF;AAAA,IACF;AACA,QAAI,CAAC,KAAK,YAAY,GAAG;AACvB,YAAM,IAAI,MAAM,2BAA2B,GAAG,iCAAiC;AAAA,IACjF;AAAA,EACF;AACF;","names":[]}
|