@nghyane/arcane 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (738) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/README.md +12 -0
  3. package/examples/README.md +21 -0
  4. package/examples/custom-tools/README.md +109 -0
  5. package/examples/custom-tools/hello/index.ts +20 -0
  6. package/examples/custom-tools/todo/index.ts +206 -0
  7. package/examples/extensions/README.md +143 -0
  8. package/examples/extensions/api-demo.ts +89 -0
  9. package/examples/extensions/chalk-logger.ts +25 -0
  10. package/examples/extensions/hello.ts +32 -0
  11. package/examples/extensions/pirate.ts +43 -0
  12. package/examples/extensions/plan-mode.ts +550 -0
  13. package/examples/extensions/reload-runtime.ts +37 -0
  14. package/examples/extensions/todo.ts +296 -0
  15. package/examples/extensions/tools.ts +144 -0
  16. package/examples/extensions/with-deps/index.ts +35 -0
  17. package/examples/extensions/with-deps/package-lock.json +31 -0
  18. package/examples/extensions/with-deps/package.json +16 -0
  19. package/examples/hooks/README.md +56 -0
  20. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  21. package/examples/hooks/confirm-destructive.ts +58 -0
  22. package/examples/hooks/custom-compaction.ts +116 -0
  23. package/examples/hooks/dirty-repo-guard.ts +51 -0
  24. package/examples/hooks/file-trigger.ts +40 -0
  25. package/examples/hooks/git-checkpoint.ts +52 -0
  26. package/examples/hooks/handoff.ts +150 -0
  27. package/examples/hooks/permission-gate.ts +33 -0
  28. package/examples/hooks/protected-paths.ts +29 -0
  29. package/examples/hooks/qna.ts +119 -0
  30. package/examples/hooks/status-line.ts +39 -0
  31. package/examples/sdk/01-minimal.ts +21 -0
  32. package/examples/sdk/02-custom-model.ts +49 -0
  33. package/examples/sdk/03-custom-prompt.ts +43 -0
  34. package/examples/sdk/04-skills.ts +43 -0
  35. package/examples/sdk/06-extensions.ts +80 -0
  36. package/examples/sdk/06-hooks.ts +61 -0
  37. package/examples/sdk/07-context-files.ts +35 -0
  38. package/examples/sdk/08-prompt-templates.ts +36 -0
  39. package/examples/sdk/08-slash-commands.ts +41 -0
  40. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  41. package/examples/sdk/11-sessions.ts +47 -0
  42. package/examples/sdk/README.md +150 -0
  43. package/package.json +464 -0
  44. package/scripts/format-prompts.ts +184 -0
  45. package/scripts/generate-docs-index.ts +40 -0
  46. package/scripts/generate-template.ts +32 -0
  47. package/src/bun-imports.d.ts +22 -0
  48. package/src/capability/context-file.ts +39 -0
  49. package/src/capability/extension-module.ts +33 -0
  50. package/src/capability/extension.ts +47 -0
  51. package/src/capability/fs.ts +89 -0
  52. package/src/capability/hook.ts +39 -0
  53. package/src/capability/index.ts +432 -0
  54. package/src/capability/instruction.ts +36 -0
  55. package/src/capability/mcp.ts +60 -0
  56. package/src/capability/prompt.ts +34 -0
  57. package/src/capability/rule.ts +223 -0
  58. package/src/capability/settings.ts +34 -0
  59. package/src/capability/skill.ts +48 -0
  60. package/src/capability/slash-command.ts +39 -0
  61. package/src/capability/ssh.ts +41 -0
  62. package/src/capability/system-prompt.ts +34 -0
  63. package/src/capability/tool.ts +37 -0
  64. package/src/capability/types.ts +156 -0
  65. package/src/cli/args.ts +259 -0
  66. package/src/cli/config-cli.ts +357 -0
  67. package/src/cli/file-processor.ts +124 -0
  68. package/src/cli/grep-cli.ts +152 -0
  69. package/src/cli/jupyter-cli.ts +106 -0
  70. package/src/cli/list-models.ts +103 -0
  71. package/src/cli/plugin-cli.ts +661 -0
  72. package/src/cli/session-picker.ts +42 -0
  73. package/src/cli/setup-cli.ts +376 -0
  74. package/src/cli/shell-cli.ts +174 -0
  75. package/src/cli/ssh-cli.ts +179 -0
  76. package/src/cli/stats-cli.ts +197 -0
  77. package/src/cli/update-cli.ts +286 -0
  78. package/src/cli/web-search-cli.ts +143 -0
  79. package/src/cli.ts +65 -0
  80. package/src/commands/commit.ts +36 -0
  81. package/src/commands/config.ts +51 -0
  82. package/src/commands/grep.ts +41 -0
  83. package/src/commands/jupyter.ts +32 -0
  84. package/src/commands/launch.ts +139 -0
  85. package/src/commands/plugin.ts +70 -0
  86. package/src/commands/setup.ts +42 -0
  87. package/src/commands/shell.ts +29 -0
  88. package/src/commands/ssh.ts +60 -0
  89. package/src/commands/stats.ts +29 -0
  90. package/src/commands/update.ts +21 -0
  91. package/src/commands/web-search.ts +42 -0
  92. package/src/commit/agentic/agent.ts +311 -0
  93. package/src/commit/agentic/fallback.ts +96 -0
  94. package/src/commit/agentic/index.ts +359 -0
  95. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  96. package/src/commit/agentic/prompts/session-user.md +25 -0
  97. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  98. package/src/commit/agentic/prompts/system.md +38 -0
  99. package/src/commit/agentic/state.ts +69 -0
  100. package/src/commit/agentic/tools/analyze-file.ts +118 -0
  101. package/src/commit/agentic/tools/git-file-diff.ts +194 -0
  102. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  103. package/src/commit/agentic/tools/git-overview.ts +84 -0
  104. package/src/commit/agentic/tools/index.ts +56 -0
  105. package/src/commit/agentic/tools/propose-changelog.ts +128 -0
  106. package/src/commit/agentic/tools/propose-commit.ts +154 -0
  107. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  108. package/src/commit/agentic/tools/split-commit.ts +280 -0
  109. package/src/commit/agentic/topo-sort.ts +44 -0
  110. package/src/commit/agentic/trivial.ts +51 -0
  111. package/src/commit/agentic/validation.ts +200 -0
  112. package/src/commit/analysis/conventional.ts +165 -0
  113. package/src/commit/analysis/index.ts +4 -0
  114. package/src/commit/analysis/scope.ts +242 -0
  115. package/src/commit/analysis/summary.ts +112 -0
  116. package/src/commit/analysis/validation.ts +66 -0
  117. package/src/commit/changelog/detect.ts +37 -0
  118. package/src/commit/changelog/generate.ts +110 -0
  119. package/src/commit/changelog/index.ts +234 -0
  120. package/src/commit/changelog/parse.ts +44 -0
  121. package/src/commit/cli.ts +93 -0
  122. package/src/commit/git/diff.ts +148 -0
  123. package/src/commit/git/errors.ts +9 -0
  124. package/src/commit/git/index.ts +211 -0
  125. package/src/commit/git/operations.ts +54 -0
  126. package/src/commit/index.ts +5 -0
  127. package/src/commit/map-reduce/index.ts +64 -0
  128. package/src/commit/map-reduce/map-phase.ts +178 -0
  129. package/src/commit/map-reduce/reduce-phase.ts +145 -0
  130. package/src/commit/map-reduce/utils.ts +9 -0
  131. package/src/commit/message.ts +11 -0
  132. package/src/commit/model-selection.ts +69 -0
  133. package/src/commit/pipeline.ts +243 -0
  134. package/src/commit/prompts/analysis-system.md +148 -0
  135. package/src/commit/prompts/analysis-user.md +38 -0
  136. package/src/commit/prompts/changelog-system.md +50 -0
  137. package/src/commit/prompts/changelog-user.md +18 -0
  138. package/src/commit/prompts/file-observer-system.md +24 -0
  139. package/src/commit/prompts/file-observer-user.md +8 -0
  140. package/src/commit/prompts/reduce-system.md +50 -0
  141. package/src/commit/prompts/reduce-user.md +17 -0
  142. package/src/commit/prompts/summary-retry.md +3 -0
  143. package/src/commit/prompts/summary-system.md +38 -0
  144. package/src/commit/prompts/summary-user.md +13 -0
  145. package/src/commit/prompts/types-description.md +2 -0
  146. package/src/commit/types.ts +109 -0
  147. package/src/commit/utils/exclusions.ts +42 -0
  148. package/src/config/file-lock.ts +121 -0
  149. package/src/config/keybindings.ts +280 -0
  150. package/src/config/model-registry.ts +1140 -0
  151. package/src/config/model-resolver.ts +812 -0
  152. package/src/config/prompt-templates.ts +526 -0
  153. package/src/config/resolve-config-value.ts +92 -0
  154. package/src/config/settings-schema.ts +1236 -0
  155. package/src/config/settings.ts +706 -0
  156. package/src/config.ts +414 -0
  157. package/src/cursor.ts +239 -0
  158. package/src/debug/index.ts +431 -0
  159. package/src/debug/log-formatting.ts +60 -0
  160. package/src/debug/log-viewer.ts +903 -0
  161. package/src/debug/profiler.ts +158 -0
  162. package/src/debug/report-bundle.ts +366 -0
  163. package/src/debug/system-info.ts +112 -0
  164. package/src/discovery/agents-md.ts +68 -0
  165. package/src/discovery/agents.ts +199 -0
  166. package/src/discovery/builtin.ts +815 -0
  167. package/src/discovery/claude-plugins.ts +205 -0
  168. package/src/discovery/claude.ts +506 -0
  169. package/src/discovery/cline.ts +83 -0
  170. package/src/discovery/codex.ts +532 -0
  171. package/src/discovery/cursor.ts +218 -0
  172. package/src/discovery/gemini.ts +395 -0
  173. package/src/discovery/github.ts +117 -0
  174. package/src/discovery/helpers.ts +698 -0
  175. package/src/discovery/index.ts +89 -0
  176. package/src/discovery/mcp-json.ts +156 -0
  177. package/src/discovery/opencode.ts +394 -0
  178. package/src/discovery/ssh.ts +160 -0
  179. package/src/discovery/vscode.ts +103 -0
  180. package/src/discovery/windsurf.ts +145 -0
  181. package/src/exa/company.ts +57 -0
  182. package/src/exa/index.ts +62 -0
  183. package/src/exa/linkedin.ts +57 -0
  184. package/src/exa/mcp-client.ts +289 -0
  185. package/src/exa/render.ts +244 -0
  186. package/src/exa/researcher.ts +89 -0
  187. package/src/exa/search.ts +330 -0
  188. package/src/exa/types.ts +166 -0
  189. package/src/exa/websets.ts +247 -0
  190. package/src/exec/bash-executor.ts +184 -0
  191. package/src/exec/exec.ts +53 -0
  192. package/src/export/custom-share.ts +65 -0
  193. package/src/export/html/index.ts +162 -0
  194. package/src/export/html/template.css +889 -0
  195. package/src/export/html/template.generated.ts +2 -0
  196. package/src/export/html/template.html +45 -0
  197. package/src/export/html/template.js +1329 -0
  198. package/src/export/html/template.macro.ts +24 -0
  199. package/src/export/html/vendor/highlight.min.js +1213 -0
  200. package/src/export/html/vendor/marked.min.js +6 -0
  201. package/src/export/ttsr.ts +434 -0
  202. package/src/extensibility/custom-commands/bundled/review/index.ts +433 -0
  203. package/src/extensibility/custom-commands/index.ts +15 -0
  204. package/src/extensibility/custom-commands/loader.ts +231 -0
  205. package/src/extensibility/custom-commands/types.ts +111 -0
  206. package/src/extensibility/custom-tools/index.ts +22 -0
  207. package/src/extensibility/custom-tools/loader.ts +235 -0
  208. package/src/extensibility/custom-tools/types.ts +226 -0
  209. package/src/extensibility/custom-tools/wrapper.ts +45 -0
  210. package/src/extensibility/extensions/index.ts +136 -0
  211. package/src/extensibility/extensions/loader.ts +520 -0
  212. package/src/extensibility/extensions/runner.ts +774 -0
  213. package/src/extensibility/extensions/types.ts +1293 -0
  214. package/src/extensibility/extensions/wrapper.ts +188 -0
  215. package/src/extensibility/hooks/index.ts +16 -0
  216. package/src/extensibility/hooks/loader.ts +273 -0
  217. package/src/extensibility/hooks/runner.ts +441 -0
  218. package/src/extensibility/hooks/tool-wrapper.ts +106 -0
  219. package/src/extensibility/hooks/types.ts +817 -0
  220. package/src/extensibility/plugins/doctor.ts +65 -0
  221. package/src/extensibility/plugins/git-url.ts +281 -0
  222. package/src/extensibility/plugins/index.ts +33 -0
  223. package/src/extensibility/plugins/installer.ts +192 -0
  224. package/src/extensibility/plugins/loader.ts +338 -0
  225. package/src/extensibility/plugins/manager.ts +716 -0
  226. package/src/extensibility/plugins/parser.ts +105 -0
  227. package/src/extensibility/plugins/types.ts +190 -0
  228. package/src/extensibility/skills.ts +385 -0
  229. package/src/extensibility/slash-commands.ts +287 -0
  230. package/src/extensibility/tool-proxy.ts +25 -0
  231. package/src/index.ts +275 -0
  232. package/src/internal-urls/agent-protocol.ts +136 -0
  233. package/src/internal-urls/artifact-protocol.ts +97 -0
  234. package/src/internal-urls/docs-index.generated.ts +54 -0
  235. package/src/internal-urls/docs-protocol.ts +84 -0
  236. package/src/internal-urls/index.ts +31 -0
  237. package/src/internal-urls/json-query.ts +126 -0
  238. package/src/internal-urls/memory-protocol.ts +133 -0
  239. package/src/internal-urls/router.ts +70 -0
  240. package/src/internal-urls/rule-protocol.ts +55 -0
  241. package/src/internal-urls/skill-protocol.ts +111 -0
  242. package/src/internal-urls/types.ts +52 -0
  243. package/src/ipy/executor.ts +556 -0
  244. package/src/ipy/gateway-coordinator.ts +426 -0
  245. package/src/ipy/kernel.ts +892 -0
  246. package/src/ipy/modules.ts +109 -0
  247. package/src/ipy/prelude.py +831 -0
  248. package/src/ipy/prelude.ts +3 -0
  249. package/src/ipy/runtime.ts +222 -0
  250. package/src/lsp/client.ts +867 -0
  251. package/src/lsp/clients/biome-client.ts +202 -0
  252. package/src/lsp/clients/index.ts +50 -0
  253. package/src/lsp/clients/lsp-linter-client.ts +93 -0
  254. package/src/lsp/clients/swiftlint-client.ts +120 -0
  255. package/src/lsp/config.ts +397 -0
  256. package/src/lsp/defaults.json +464 -0
  257. package/src/lsp/edits.ts +109 -0
  258. package/src/lsp/index.ts +1268 -0
  259. package/src/lsp/lspmux.ts +250 -0
  260. package/src/lsp/render.ts +689 -0
  261. package/src/lsp/types.ts +414 -0
  262. package/src/lsp/utils.ts +549 -0
  263. package/src/main.ts +773 -0
  264. package/src/mcp/client.ts +239 -0
  265. package/src/mcp/config-writer.ts +215 -0
  266. package/src/mcp/config.ts +363 -0
  267. package/src/mcp/index.ts +55 -0
  268. package/src/mcp/json-rpc.ts +84 -0
  269. package/src/mcp/loader.ts +124 -0
  270. package/src/mcp/manager.ts +490 -0
  271. package/src/mcp/oauth-discovery.ts +274 -0
  272. package/src/mcp/oauth-flow.ts +229 -0
  273. package/src/mcp/render.ts +123 -0
  274. package/src/mcp/tool-bridge.ts +372 -0
  275. package/src/mcp/tool-cache.ts +121 -0
  276. package/src/mcp/transports/http.ts +332 -0
  277. package/src/mcp/transports/index.ts +6 -0
  278. package/src/mcp/transports/stdio.ts +281 -0
  279. package/src/mcp/types.ts +248 -0
  280. package/src/memories/index.ts +1099 -0
  281. package/src/memories/storage.ts +563 -0
  282. package/src/modes/components/agent-dashboard.ts +1130 -0
  283. package/src/modes/components/assistant-message.ts +144 -0
  284. package/src/modes/components/bash-execution.ts +218 -0
  285. package/src/modes/components/bordered-loader.ts +41 -0
  286. package/src/modes/components/branch-summary-message.ts +45 -0
  287. package/src/modes/components/codemode-group.ts +369 -0
  288. package/src/modes/components/compaction-summary-message.ts +51 -0
  289. package/src/modes/components/countdown-timer.ts +46 -0
  290. package/src/modes/components/custom-editor.ts +181 -0
  291. package/src/modes/components/custom-message.ts +91 -0
  292. package/src/modes/components/diff.ts +186 -0
  293. package/src/modes/components/dynamic-border.ts +25 -0
  294. package/src/modes/components/extensions/extension-dashboard.ts +325 -0
  295. package/src/modes/components/extensions/extension-list.ts +484 -0
  296. package/src/modes/components/extensions/index.ts +9 -0
  297. package/src/modes/components/extensions/inspector-panel.ts +321 -0
  298. package/src/modes/components/extensions/state-manager.ts +586 -0
  299. package/src/modes/components/extensions/types.ts +191 -0
  300. package/src/modes/components/footer.ts +315 -0
  301. package/src/modes/components/history-search.ts +157 -0
  302. package/src/modes/components/hook-editor.ts +101 -0
  303. package/src/modes/components/hook-input.ts +72 -0
  304. package/src/modes/components/hook-message.ts +100 -0
  305. package/src/modes/components/hook-selector.ts +155 -0
  306. package/src/modes/components/index.ts +41 -0
  307. package/src/modes/components/keybinding-hints.ts +65 -0
  308. package/src/modes/components/login-dialog.ts +164 -0
  309. package/src/modes/components/mcp-add-wizard.ts +1295 -0
  310. package/src/modes/components/model-selector.ts +625 -0
  311. package/src/modes/components/oauth-selector.ts +210 -0
  312. package/src/modes/components/plugin-settings.ts +477 -0
  313. package/src/modes/components/python-execution.ts +196 -0
  314. package/src/modes/components/queue-mode-selector.ts +56 -0
  315. package/src/modes/components/read-tool-group.ts +119 -0
  316. package/src/modes/components/session-selector.ts +242 -0
  317. package/src/modes/components/settings-defs.ts +340 -0
  318. package/src/modes/components/settings-selector.ts +529 -0
  319. package/src/modes/components/show-images-selector.ts +45 -0
  320. package/src/modes/components/skill-message.ts +90 -0
  321. package/src/modes/components/status-line/index.ts +4 -0
  322. package/src/modes/components/status-line/presets.ts +94 -0
  323. package/src/modes/components/status-line/segments.ts +352 -0
  324. package/src/modes/components/status-line/separators.ts +55 -0
  325. package/src/modes/components/status-line/types.ts +75 -0
  326. package/src/modes/components/status-line-segment-editor.ts +354 -0
  327. package/src/modes/components/status-line.ts +421 -0
  328. package/src/modes/components/theme-selector.ts +63 -0
  329. package/src/modes/components/thinking-selector.ts +64 -0
  330. package/src/modes/components/todo-display.ts +115 -0
  331. package/src/modes/components/todo-reminder.ts +40 -0
  332. package/src/modes/components/tool-execution.ts +703 -0
  333. package/src/modes/components/tree-selector.ts +904 -0
  334. package/src/modes/components/ttsr-notification.ts +80 -0
  335. package/src/modes/components/user-message-selector.ts +146 -0
  336. package/src/modes/components/user-message.ts +22 -0
  337. package/src/modes/components/visual-truncate.ts +63 -0
  338. package/src/modes/components/welcome.ts +247 -0
  339. package/src/modes/controllers/command-controller.ts +1120 -0
  340. package/src/modes/controllers/event-controller.ts +479 -0
  341. package/src/modes/controllers/extension-ui-controller.ts +778 -0
  342. package/src/modes/controllers/input-controller.ts +671 -0
  343. package/src/modes/controllers/mcp-command-controller.ts +1315 -0
  344. package/src/modes/controllers/selector-controller.ts +712 -0
  345. package/src/modes/controllers/ssh-command-controller.ts +452 -0
  346. package/src/modes/index.ts +15 -0
  347. package/src/modes/interactive-mode.ts +1027 -0
  348. package/src/modes/print-mode.ts +191 -0
  349. package/src/modes/rpc/rpc-client.ts +583 -0
  350. package/src/modes/rpc/rpc-mode.ts +700 -0
  351. package/src/modes/rpc/rpc-types.ts +236 -0
  352. package/src/modes/theme/dark.json +95 -0
  353. package/src/modes/theme/defaults/alabaster.json +93 -0
  354. package/src/modes/theme/defaults/amethyst.json +96 -0
  355. package/src/modes/theme/defaults/anthracite.json +93 -0
  356. package/src/modes/theme/defaults/basalt.json +91 -0
  357. package/src/modes/theme/defaults/birch.json +95 -0
  358. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  359. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  360. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  361. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  362. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  363. package/src/modes/theme/defaults/dark-copper.json +95 -0
  364. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  365. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  366. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  367. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  368. package/src/modes/theme/defaults/dark-ember.json +95 -0
  369. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  370. package/src/modes/theme/defaults/dark-forest.json +96 -0
  371. package/src/modes/theme/defaults/dark-github.json +105 -0
  372. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  373. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  374. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  375. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  376. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  377. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  378. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  379. package/src/modes/theme/defaults/dark-nord.json +97 -0
  380. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  381. package/src/modes/theme/defaults/dark-one.json +100 -0
  382. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  383. package/src/modes/theme/defaults/dark-reef.json +91 -0
  384. package/src/modes/theme/defaults/dark-retro.json +92 -0
  385. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  386. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  387. package/src/modes/theme/defaults/dark-slate.json +95 -0
  388. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  389. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  390. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  391. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  392. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  393. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  394. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  395. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  396. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  397. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  398. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  399. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  400. package/src/modes/theme/defaults/graphite.json +92 -0
  401. package/src/modes/theme/defaults/index.ts +195 -0
  402. package/src/modes/theme/defaults/light-arctic.json +107 -0
  403. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  404. package/src/modes/theme/defaults/light-canyon.json +91 -0
  405. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  406. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  407. package/src/modes/theme/defaults/light-coral.json +95 -0
  408. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  409. package/src/modes/theme/defaults/light-dawn.json +90 -0
  410. package/src/modes/theme/defaults/light-dunes.json +91 -0
  411. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  412. package/src/modes/theme/defaults/light-forest.json +100 -0
  413. package/src/modes/theme/defaults/light-frost.json +95 -0
  414. package/src/modes/theme/defaults/light-github.json +115 -0
  415. package/src/modes/theme/defaults/light-glacier.json +91 -0
  416. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  417. package/src/modes/theme/defaults/light-haze.json +90 -0
  418. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  419. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  420. package/src/modes/theme/defaults/light-lavender.json +95 -0
  421. package/src/modes/theme/defaults/light-meadow.json +91 -0
  422. package/src/modes/theme/defaults/light-mint.json +95 -0
  423. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  424. package/src/modes/theme/defaults/light-ocean.json +99 -0
  425. package/src/modes/theme/defaults/light-one.json +99 -0
  426. package/src/modes/theme/defaults/light-opal.json +91 -0
  427. package/src/modes/theme/defaults/light-orchard.json +91 -0
  428. package/src/modes/theme/defaults/light-paper.json +95 -0
  429. package/src/modes/theme/defaults/light-prism.json +90 -0
  430. package/src/modes/theme/defaults/light-retro.json +98 -0
  431. package/src/modes/theme/defaults/light-sand.json +95 -0
  432. package/src/modes/theme/defaults/light-savanna.json +91 -0
  433. package/src/modes/theme/defaults/light-solarized.json +102 -0
  434. package/src/modes/theme/defaults/light-soleil.json +90 -0
  435. package/src/modes/theme/defaults/light-sunset.json +99 -0
  436. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  437. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  438. package/src/modes/theme/defaults/light-wetland.json +91 -0
  439. package/src/modes/theme/defaults/light-zenith.json +89 -0
  440. package/src/modes/theme/defaults/limestone.json +94 -0
  441. package/src/modes/theme/defaults/mahogany.json +97 -0
  442. package/src/modes/theme/defaults/marble.json +93 -0
  443. package/src/modes/theme/defaults/obsidian.json +91 -0
  444. package/src/modes/theme/defaults/onyx.json +91 -0
  445. package/src/modes/theme/defaults/pearl.json +93 -0
  446. package/src/modes/theme/defaults/porcelain.json +91 -0
  447. package/src/modes/theme/defaults/quartz.json +96 -0
  448. package/src/modes/theme/defaults/sandstone.json +95 -0
  449. package/src/modes/theme/defaults/titanium.json +90 -0
  450. package/src/modes/theme/light.json +93 -0
  451. package/src/modes/theme/mermaid-cache.ts +111 -0
  452. package/src/modes/theme/theme-schema.json +429 -0
  453. package/src/modes/theme/theme.ts +2333 -0
  454. package/src/modes/types.ts +216 -0
  455. package/src/modes/utils/ui-helpers.ts +529 -0
  456. package/src/patch/applicator.ts +1482 -0
  457. package/src/patch/diff.ts +425 -0
  458. package/src/patch/fuzzy.ts +784 -0
  459. package/src/patch/hashline.ts +972 -0
  460. package/src/patch/index.ts +964 -0
  461. package/src/patch/normalize.ts +397 -0
  462. package/src/patch/normative.ts +72 -0
  463. package/src/patch/parser.ts +532 -0
  464. package/src/patch/shared.ts +400 -0
  465. package/src/patch/types.ts +292 -0
  466. package/src/priority.json +35 -0
  467. package/src/prompts/agents/explore.md +48 -0
  468. package/src/prompts/agents/frontmatter.md +9 -0
  469. package/src/prompts/agents/init.md +36 -0
  470. package/src/prompts/agents/librarian.md +53 -0
  471. package/src/prompts/agents/oracle.md +51 -0
  472. package/src/prompts/agents/reviewer.md +70 -0
  473. package/src/prompts/agents/task.md +14 -0
  474. package/src/prompts/compaction/branch-summary-context.md +5 -0
  475. package/src/prompts/compaction/branch-summary-preamble.md +2 -0
  476. package/src/prompts/compaction/branch-summary.md +30 -0
  477. package/src/prompts/compaction/compaction-short-summary.md +9 -0
  478. package/src/prompts/compaction/compaction-summary-context.md +5 -0
  479. package/src/prompts/compaction/compaction-summary.md +38 -0
  480. package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
  481. package/src/prompts/compaction/compaction-update-summary.md +45 -0
  482. package/src/prompts/memories/consolidation.md +30 -0
  483. package/src/prompts/memories/read_path.md +11 -0
  484. package/src/prompts/memories/stage_one_input.md +6 -0
  485. package/src/prompts/memories/stage_one_system.md +21 -0
  486. package/src/prompts/review-request.md +64 -0
  487. package/src/prompts/system/agent-creation-architect.md +65 -0
  488. package/src/prompts/system/agent-creation-user.md +6 -0
  489. package/src/prompts/system/custom-system-prompt.md +68 -0
  490. package/src/prompts/system/file-operations.md +10 -0
  491. package/src/prompts/system/subagent-submit-reminder.md +11 -0
  492. package/src/prompts/system/subagent-system-prompt.md +31 -0
  493. package/src/prompts/system/subagent-user-prompt.md +8 -0
  494. package/src/prompts/system/summarization-system.md +3 -0
  495. package/src/prompts/system/system-prompt.md +300 -0
  496. package/src/prompts/system/title-system.md +2 -0
  497. package/src/prompts/system/ttsr-interrupt.md +7 -0
  498. package/src/prompts/system/web-search.md +28 -0
  499. package/src/prompts/tools/ask.md +44 -0
  500. package/src/prompts/tools/bash.md +24 -0
  501. package/src/prompts/tools/browser.md +33 -0
  502. package/src/prompts/tools/calculator.md +12 -0
  503. package/src/prompts/tools/explore.md +29 -0
  504. package/src/prompts/tools/fetch.md +16 -0
  505. package/src/prompts/tools/find.md +18 -0
  506. package/src/prompts/tools/gemini-image.md +23 -0
  507. package/src/prompts/tools/grep.md +28 -0
  508. package/src/prompts/tools/hashline.md +232 -0
  509. package/src/prompts/tools/librarian.md +24 -0
  510. package/src/prompts/tools/lsp.md +28 -0
  511. package/src/prompts/tools/oracle.md +26 -0
  512. package/src/prompts/tools/patch.md +74 -0
  513. package/src/prompts/tools/python.md +66 -0
  514. package/src/prompts/tools/read.md +36 -0
  515. package/src/prompts/tools/replace.md +38 -0
  516. package/src/prompts/tools/reviewer.md +41 -0
  517. package/src/prompts/tools/ssh.md +51 -0
  518. package/src/prompts/tools/task-summary.md +28 -0
  519. package/src/prompts/tools/task.md +275 -0
  520. package/src/prompts/tools/todo-write.md +65 -0
  521. package/src/prompts/tools/undo-edit.md +7 -0
  522. package/src/prompts/tools/web-search.md +19 -0
  523. package/src/prompts/tools/write.md +18 -0
  524. package/src/sdk.ts +1287 -0
  525. package/src/secrets/index.ts +116 -0
  526. package/src/secrets/obfuscator.ts +269 -0
  527. package/src/secrets/regex.ts +21 -0
  528. package/src/session/agent-session.ts +4669 -0
  529. package/src/session/agent-storage.ts +621 -0
  530. package/src/session/artifacts.ts +132 -0
  531. package/src/session/auth-storage.ts +1433 -0
  532. package/src/session/blob-store.ts +103 -0
  533. package/src/session/compaction/branch-summarization.ts +315 -0
  534. package/src/session/compaction/compaction.ts +864 -0
  535. package/src/session/compaction/index.ts +7 -0
  536. package/src/session/compaction/pruning.ts +91 -0
  537. package/src/session/compaction/utils.ts +171 -0
  538. package/src/session/history-storage.ts +170 -0
  539. package/src/session/messages.ts +317 -0
  540. package/src/session/session-manager.ts +2276 -0
  541. package/src/session/session-storage.ts +342 -0
  542. package/src/session/streaming-output.ts +565 -0
  543. package/src/slash-commands/builtin-registry.ts +439 -0
  544. package/src/ssh/config-writer.ts +183 -0
  545. package/src/ssh/connection-manager.ts +444 -0
  546. package/src/ssh/ssh-executor.ts +127 -0
  547. package/src/ssh/sshfs-mount.ts +135 -0
  548. package/src/stt/downloader.ts +71 -0
  549. package/src/stt/index.ts +3 -0
  550. package/src/stt/recorder.ts +351 -0
  551. package/src/stt/setup.ts +52 -0
  552. package/src/stt/stt-controller.ts +160 -0
  553. package/src/stt/transcribe.py +70 -0
  554. package/src/stt/transcriber.ts +91 -0
  555. package/src/system-prompt.ts +685 -0
  556. package/src/task/agents.ts +155 -0
  557. package/src/task/batch.ts +102 -0
  558. package/src/task/commands.ts +134 -0
  559. package/src/task/discovery.ts +126 -0
  560. package/src/task/executor.ts +908 -0
  561. package/src/task/index.ts +223 -0
  562. package/src/task/output-manager.ts +107 -0
  563. package/src/task/parallel.ts +84 -0
  564. package/src/task/render.ts +326 -0
  565. package/src/task/subprocess-tool-registry.ts +88 -0
  566. package/src/task/template.ts +32 -0
  567. package/src/task/types.ts +144 -0
  568. package/src/tools/ask.ts +523 -0
  569. package/src/tools/bash-interactive.ts +419 -0
  570. package/src/tools/bash-interceptor.ts +105 -0
  571. package/src/tools/bash-normalize.ts +107 -0
  572. package/src/tools/bash-skill-urls.ts +177 -0
  573. package/src/tools/bash.ts +347 -0
  574. package/src/tools/browser.ts +1374 -0
  575. package/src/tools/calculator.ts +537 -0
  576. package/src/tools/context.ts +39 -0
  577. package/src/tools/explore.ts +23 -0
  578. package/src/tools/fetch.ts +1091 -0
  579. package/src/tools/find.ts +540 -0
  580. package/src/tools/fs-cache-invalidation.ts +28 -0
  581. package/src/tools/gemini-image.ts +907 -0
  582. package/src/tools/grep.ts +489 -0
  583. package/src/tools/index.ts +337 -0
  584. package/src/tools/json-tree.ts +231 -0
  585. package/src/tools/jtd-to-json-schema.ts +247 -0
  586. package/src/tools/jtd-to-typescript.ts +198 -0
  587. package/src/tools/librarian.ts +33 -0
  588. package/src/tools/list-limit.ts +40 -0
  589. package/src/tools/notebook.ts +287 -0
  590. package/src/tools/oracle.ts +40 -0
  591. package/src/tools/output-meta.ts +459 -0
  592. package/src/tools/output-utils.ts +63 -0
  593. package/src/tools/path-utils.ts +116 -0
  594. package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
  595. package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
  596. package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
  597. package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
  598. package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
  599. package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
  600. package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
  601. package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
  602. package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
  603. package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
  604. package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
  605. package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
  606. package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
  607. package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
  608. package/src/tools/python.ts +1118 -0
  609. package/src/tools/read.ts +1193 -0
  610. package/src/tools/render-utils.ts +680 -0
  611. package/src/tools/renderers.ts +60 -0
  612. package/src/tools/reviewer-tool.ts +41 -0
  613. package/src/tools/ssh.ts +326 -0
  614. package/src/tools/subagent-tool.ts +169 -0
  615. package/src/tools/submit-result.ts +152 -0
  616. package/src/tools/todo-write.ts +255 -0
  617. package/src/tools/tool-errors.ts +92 -0
  618. package/src/tools/tool-result.ts +86 -0
  619. package/src/tools/undo-edit.ts +145 -0
  620. package/src/tools/undo-history.ts +22 -0
  621. package/src/tools/write.ts +274 -0
  622. package/src/tui/code-cell.ts +108 -0
  623. package/src/tui/file-list.ts +47 -0
  624. package/src/tui/index.ts +11 -0
  625. package/src/tui/output-block.ts +144 -0
  626. package/src/tui/status-line.ts +39 -0
  627. package/src/tui/tree-list.ts +53 -0
  628. package/src/tui/types.ts +16 -0
  629. package/src/tui/utils.ts +116 -0
  630. package/src/utils/changelog.ts +98 -0
  631. package/src/utils/event-bus.ts +33 -0
  632. package/src/utils/external-editor.ts +59 -0
  633. package/src/utils/file-display-mode.ts +36 -0
  634. package/src/utils/file-mentions.ts +384 -0
  635. package/src/utils/frontmatter.ts +101 -0
  636. package/src/utils/fuzzy.ts +108 -0
  637. package/src/utils/ignore-files.ts +119 -0
  638. package/src/utils/image-convert.ts +27 -0
  639. package/src/utils/image-resize.ts +236 -0
  640. package/src/utils/mime.ts +30 -0
  641. package/src/utils/open.ts +20 -0
  642. package/src/utils/shell-snapshot.ts +199 -0
  643. package/src/utils/timings.ts +26 -0
  644. package/src/utils/title-generator.ts +167 -0
  645. package/src/utils/tools-manager.ts +362 -0
  646. package/src/web/scrapers/artifacthub.ts +215 -0
  647. package/src/web/scrapers/arxiv.ts +88 -0
  648. package/src/web/scrapers/aur.ts +175 -0
  649. package/src/web/scrapers/biorxiv.ts +141 -0
  650. package/src/web/scrapers/bluesky.ts +284 -0
  651. package/src/web/scrapers/brew.ts +177 -0
  652. package/src/web/scrapers/cheatsh.ts +78 -0
  653. package/src/web/scrapers/chocolatey.ts +158 -0
  654. package/src/web/scrapers/choosealicense.ts +110 -0
  655. package/src/web/scrapers/cisa-kev.ts +100 -0
  656. package/src/web/scrapers/clojars.ts +180 -0
  657. package/src/web/scrapers/coingecko.ts +184 -0
  658. package/src/web/scrapers/crates-io.ts +128 -0
  659. package/src/web/scrapers/crossref.ts +149 -0
  660. package/src/web/scrapers/devto.ts +177 -0
  661. package/src/web/scrapers/discogs.ts +307 -0
  662. package/src/web/scrapers/discourse.ts +221 -0
  663. package/src/web/scrapers/dockerhub.ts +160 -0
  664. package/src/web/scrapers/fdroid.ts +158 -0
  665. package/src/web/scrapers/firefox-addons.ts +214 -0
  666. package/src/web/scrapers/flathub.ts +239 -0
  667. package/src/web/scrapers/github-gist.ts +68 -0
  668. package/src/web/scrapers/github.ts +490 -0
  669. package/src/web/scrapers/gitlab.ts +456 -0
  670. package/src/web/scrapers/go-pkg.ts +275 -0
  671. package/src/web/scrapers/hackage.ts +94 -0
  672. package/src/web/scrapers/hackernews.ts +208 -0
  673. package/src/web/scrapers/hex.ts +121 -0
  674. package/src/web/scrapers/huggingface.ts +385 -0
  675. package/src/web/scrapers/iacr.ts +86 -0
  676. package/src/web/scrapers/index.ts +249 -0
  677. package/src/web/scrapers/jetbrains-marketplace.ts +169 -0
  678. package/src/web/scrapers/lemmy.ts +220 -0
  679. package/src/web/scrapers/lobsters.ts +186 -0
  680. package/src/web/scrapers/mastodon.ts +310 -0
  681. package/src/web/scrapers/maven.ts +152 -0
  682. package/src/web/scrapers/mdn.ts +172 -0
  683. package/src/web/scrapers/metacpan.ts +253 -0
  684. package/src/web/scrapers/musicbrainz.ts +272 -0
  685. package/src/web/scrapers/npm.ts +114 -0
  686. package/src/web/scrapers/nuget.ts +205 -0
  687. package/src/web/scrapers/nvd.ts +243 -0
  688. package/src/web/scrapers/ollama.ts +265 -0
  689. package/src/web/scrapers/open-vsx.ts +119 -0
  690. package/src/web/scrapers/opencorporates.ts +275 -0
  691. package/src/web/scrapers/openlibrary.ts +319 -0
  692. package/src/web/scrapers/orcid.ts +298 -0
  693. package/src/web/scrapers/osv.ts +192 -0
  694. package/src/web/scrapers/packagist.ts +174 -0
  695. package/src/web/scrapers/pub-dev.ts +185 -0
  696. package/src/web/scrapers/pubmed.ts +177 -0
  697. package/src/web/scrapers/pypi.ts +129 -0
  698. package/src/web/scrapers/rawg.ts +124 -0
  699. package/src/web/scrapers/readthedocs.ts +125 -0
  700. package/src/web/scrapers/reddit.ts +104 -0
  701. package/src/web/scrapers/repology.ts +262 -0
  702. package/src/web/scrapers/rfc.ts +209 -0
  703. package/src/web/scrapers/rubygems.ts +117 -0
  704. package/src/web/scrapers/searchcode.ts +217 -0
  705. package/src/web/scrapers/sec-edgar.ts +274 -0
  706. package/src/web/scrapers/semantic-scholar.ts +190 -0
  707. package/src/web/scrapers/snapcraft.ts +200 -0
  708. package/src/web/scrapers/sourcegraph.ts +373 -0
  709. package/src/web/scrapers/spdx.ts +121 -0
  710. package/src/web/scrapers/spotify.ts +217 -0
  711. package/src/web/scrapers/stackoverflow.ts +124 -0
  712. package/src/web/scrapers/terraform.ts +304 -0
  713. package/src/web/scrapers/tldr.ts +51 -0
  714. package/src/web/scrapers/twitter.ts +97 -0
  715. package/src/web/scrapers/types.ts +200 -0
  716. package/src/web/scrapers/utils.ts +142 -0
  717. package/src/web/scrapers/vimeo.ts +152 -0
  718. package/src/web/scrapers/vscode-marketplace.ts +195 -0
  719. package/src/web/scrapers/w3c.ts +163 -0
  720. package/src/web/scrapers/wikidata.ts +357 -0
  721. package/src/web/scrapers/wikipedia.ts +95 -0
  722. package/src/web/scrapers/youtube.ts +312 -0
  723. package/src/web/search/auth.ts +178 -0
  724. package/src/web/search/index.ts +598 -0
  725. package/src/web/search/provider.ts +77 -0
  726. package/src/web/search/providers/anthropic.ts +284 -0
  727. package/src/web/search/providers/base.ts +22 -0
  728. package/src/web/search/providers/brave.ts +165 -0
  729. package/src/web/search/providers/codex.ts +377 -0
  730. package/src/web/search/providers/exa.ts +158 -0
  731. package/src/web/search/providers/gemini.ts +437 -0
  732. package/src/web/search/providers/jina.ts +99 -0
  733. package/src/web/search/providers/kimi.ts +196 -0
  734. package/src/web/search/providers/perplexity.ts +546 -0
  735. package/src/web/search/providers/synthetic.ts +136 -0
  736. package/src/web/search/providers/zai.ts +352 -0
  737. package/src/web/search/render.ts +299 -0
  738. package/src/web/search/types.ts +437 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Types for the Extension Control Center dashboard.
3
+ */
4
+ import type { SourceMeta } from "../../../capability/types";
5
+
6
+ /**
7
+ * Extension kinds matching capability types.
8
+ */
9
+ export type ExtensionKind =
10
+ | "extension-module"
11
+ | "skill"
12
+ | "rule"
13
+ | "tool"
14
+ | "mcp"
15
+ | "prompt"
16
+ | "instruction"
17
+ | "context-file"
18
+ | "hook"
19
+ | "slash-command";
20
+
21
+ /**
22
+ * Extension state (active, disabled, or shadowed).
23
+ */
24
+ export type ExtensionState = "active" | "disabled" | "shadowed";
25
+
26
+ /**
27
+ * Reason why an extension is disabled.
28
+ */
29
+ export type DisabledReason = "provider-disabled" | "item-disabled" | "shadowed";
30
+
31
+ /**
32
+ * Unified extension representation for the dashboard.
33
+ * Normalizes all capability types into a common shape.
34
+ */
35
+ export interface Extension {
36
+ /** Unique ID: `${kind}:${name}` */
37
+ id: string;
38
+ /** Extension kind */
39
+ kind: ExtensionKind;
40
+ /** Extension name */
41
+ name: string;
42
+ /** Display name (may differ from name) */
43
+ displayName: string;
44
+ /** Description if available */
45
+ description?: string;
46
+ /** Trigger pattern (slash command, glob, regex) */
47
+ trigger?: string;
48
+ /** Absolute path to source file */
49
+ path: string;
50
+ /** Source metadata */
51
+ source: {
52
+ provider: string;
53
+ providerName: string;
54
+ level: "user" | "project" | "native";
55
+ };
56
+ /** Current state */
57
+ state: ExtensionState;
58
+ /** Reason for disabled state */
59
+ disabledReason?: DisabledReason;
60
+ /** If shadowed, what shadows it */
61
+ shadowedBy?: string;
62
+ /** Raw item data for inspector */
63
+ raw: unknown;
64
+ }
65
+
66
+ /**
67
+ * Tree node types for sidebar hierarchy.
68
+ */
69
+ export type TreeNodeType = "provider" | "kind" | "item";
70
+
71
+ /**
72
+ * Sidebar tree node.
73
+ */
74
+ export interface TreeNode {
75
+ /** Unique ID */
76
+ id: string;
77
+ /** Display label */
78
+ label: string;
79
+ /** Node type (provider can be toggled, kind groups items) */
80
+ type: TreeNodeType;
81
+ /** Whether this node/provider is enabled */
82
+ enabled: boolean;
83
+ /** Whether collapsed */
84
+ collapsed: boolean;
85
+ /** Child nodes */
86
+ children: TreeNode[];
87
+ /** Extension count (for display) */
88
+ count?: number;
89
+ }
90
+
91
+ /**
92
+ * Flattened tree item for navigation.
93
+ */
94
+ export interface FlatTreeItem {
95
+ node: TreeNode;
96
+ depth: number;
97
+ index: number;
98
+ }
99
+
100
+ /**
101
+ * Focus region in the tabbed dashboard.
102
+ */
103
+ export type FocusRegion = "tabs" | "list";
104
+
105
+ /**
106
+ * Provider tab representation.
107
+ */
108
+ export interface ProviderTab {
109
+ /** Provider ID (or "all" for the ALL tab) */
110
+ id: string;
111
+ /** Display label */
112
+ label: string;
113
+ /** Whether provider is enabled (always true for "all") */
114
+ enabled: boolean;
115
+ /** Extension count for this provider */
116
+ count: number;
117
+ }
118
+
119
+ /**
120
+ * Tabbed dashboard state.
121
+ */
122
+ export interface DashboardState {
123
+ /** Provider tabs */
124
+ tabs: ProviderTab[];
125
+ /** Active tab index */
126
+ activeTabIndex: number;
127
+
128
+ /** All extensions (unfiltered) */
129
+ extensions: Extension[];
130
+ /** Extensions filtered by active tab */
131
+ tabFiltered: Extension[];
132
+ /** Extensions filtered by search (applied after tab filter) */
133
+ searchFiltered: Extension[];
134
+ /** Current search query */
135
+ searchQuery: string;
136
+
137
+ /** Selected index in main list */
138
+ listIndex: number;
139
+ /** Scroll offset for main list */
140
+ scrollOffset: number;
141
+
142
+ /** Currently selected extension for inspector */
143
+ selected: Extension | null;
144
+ }
145
+
146
+ /**
147
+ * @deprecated Use FocusRegion instead
148
+ */
149
+ export type FocusPane = "sidebar" | "main" | "inspector";
150
+
151
+ /**
152
+ * Callbacks from dashboard to parent.
153
+ */
154
+ export interface DashboardCallbacks {
155
+ /** Called when provider is toggled */
156
+ onProviderToggle: (providerId: string, enabled: boolean) => void;
157
+ /** Called when extension item is toggled */
158
+ onExtensionToggle: (extensionId: string, enabled: boolean) => void;
159
+ /** Called when dashboard is closed */
160
+ onClose: () => void;
161
+ }
162
+
163
+ /**
164
+ * Create extension ID from kind and name.
165
+ */
166
+ export function makeExtensionId(kind: ExtensionKind, name: string): string {
167
+ return `${kind}:${name}`;
168
+ }
169
+
170
+ /**
171
+ * Parse extension ID into kind and name.
172
+ */
173
+ export function parseExtensionId(id: string): { kind: ExtensionKind; name: string } | null {
174
+ const colonIdx = id.indexOf(":");
175
+ if (colonIdx === -1) return null;
176
+ return {
177
+ kind: id.slice(0, colonIdx) as ExtensionKind,
178
+ name: id.slice(colonIdx + 1),
179
+ };
180
+ }
181
+
182
+ /**
183
+ * Map SourceMeta to extension source shape.
184
+ */
185
+ export function sourceFromMeta(meta: SourceMeta): Extension["source"] {
186
+ return {
187
+ provider: meta.provider,
188
+ providerName: meta.providerName,
189
+ level: meta.level,
190
+ };
191
+ }
@@ -0,0 +1,315 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { type Component, padding, truncateToWidth, visibleWidth } from "@nghyane/arcane-tui";
4
+ import { isEnoent } from "@nghyane/arcane-utils";
5
+ import { getProjectDir } from "@nghyane/arcane-utils/dirs";
6
+ import { theme } from "../../modes/theme/theme";
7
+ import type { AgentSession } from "../../session/agent-session";
8
+ import { shortenPath } from "../../tools/render-utils";
9
+
10
+ /**
11
+ * Sanitize text for display in a single-line status.
12
+ * Removes newlines, tabs, carriage returns, and other control characters.
13
+ */
14
+ function sanitizeStatusText(text: string): string {
15
+ // Replace newlines, tabs, carriage returns with space, then collapse multiple spaces
16
+ return text
17
+ .replace(/[\r\n\t]/g, " ")
18
+ .replace(/ +/g, " ")
19
+ .trim();
20
+ }
21
+
22
+ /** Find the git root by walking up from cwd. Returns path and content of .git/HEAD if found. */
23
+ async function findGitHeadPath(): Promise<{ path: string; content: string } | null> {
24
+ let dir = getProjectDir();
25
+ while (true) {
26
+ const gitHeadPath = path.join(dir, ".git", "HEAD");
27
+ try {
28
+ const content = await Bun.file(gitHeadPath).text();
29
+ return { path: gitHeadPath, content };
30
+ } catch (err) {
31
+ if (!isEnoent(err)) throw err;
32
+ }
33
+ const parent = path.dirname(dir);
34
+ if (parent === dir) {
35
+ return null;
36
+ }
37
+ dir = parent;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Footer component that shows pwd, token stats, and context usage
43
+ */
44
+ export class FooterComponent implements Component {
45
+ #cachedBranch: string | null | undefined = undefined; // undefined = not checked yet, null = not in git repo, string = branch name
46
+ #gitWatcher: fs.FSWatcher | null = null;
47
+ #onBranchChange: (() => void) | null = null;
48
+ #autoCompactEnabled: boolean = true;
49
+ #extensionStatuses: Map<string, string> = new Map();
50
+
51
+ constructor(private readonly session: AgentSession) {}
52
+
53
+ setAutoCompactEnabled(enabled: boolean): void {
54
+ this.#autoCompactEnabled = enabled;
55
+ }
56
+
57
+ /**
58
+ * Set extension status text to display in the footer.
59
+ * Text is sanitized (newlines/tabs replaced with spaces) and truncated to terminal width.
60
+ * ANSI escape codes for styling are preserved.
61
+ * @param key - Unique key to identify this status
62
+ * @param text - Status text, or undefined to clear
63
+ */
64
+ setExtensionStatus(key: string, text: string | undefined): void {
65
+ if (text === undefined) {
66
+ this.#extensionStatuses.delete(key);
67
+ } else {
68
+ this.#extensionStatuses.set(key, text);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Set up a file watcher on .git/HEAD to detect branch changes.
74
+ * Call the provided callback when branch changes.
75
+ */
76
+ watchBranch(onBranchChange: () => void): void {
77
+ this.#onBranchChange = onBranchChange;
78
+ this.#setupGitWatcher();
79
+ }
80
+
81
+ #setupGitWatcher(): void {
82
+ // Clean up existing watcher
83
+ if (this.#gitWatcher) {
84
+ this.#gitWatcher.close();
85
+ this.#gitWatcher = null;
86
+ }
87
+
88
+ findGitHeadPath().then(result => {
89
+ if (!result) {
90
+ return;
91
+ }
92
+
93
+ try {
94
+ this.#gitWatcher = fs.watch(result.path, () => {
95
+ this.#cachedBranch = undefined; // Invalidate cache
96
+ if (this.#onBranchChange) {
97
+ this.#onBranchChange();
98
+ }
99
+ });
100
+ } catch {
101
+ // Silently fail if we can't watch
102
+ }
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Clean up the file watcher
108
+ */
109
+ dispose(): void {
110
+ if (this.#gitWatcher) {
111
+ this.#gitWatcher.close();
112
+ this.#gitWatcher = null;
113
+ }
114
+ }
115
+
116
+ invalidate(): void {
117
+ // Invalidate cached branch so it gets re-read on next render
118
+ this.#cachedBranch = undefined;
119
+ }
120
+
121
+ /**
122
+ * Get current git branch by reading .git/HEAD directly.
123
+ * Returns null if not in a git repo, branch name otherwise.
124
+ */
125
+ #getCurrentBranch(): string | null {
126
+ // Return cached value if available
127
+ if (this.#cachedBranch !== undefined) {
128
+ return this.#cachedBranch;
129
+ }
130
+
131
+ // Note: fire-and-forget async call - will return undefined on first call
132
+ // This is acceptable since it's a cached value that will update on next render
133
+ findGitHeadPath().then(result => {
134
+ if (!result) {
135
+ this.#cachedBranch = null;
136
+ if (this.#onBranchChange) {
137
+ this.#onBranchChange();
138
+ }
139
+ return;
140
+ }
141
+ const content = result.content.trim();
142
+
143
+ if (content.startsWith("ref: refs/heads/")) {
144
+ this.#cachedBranch = content.slice(16);
145
+ } else {
146
+ this.#cachedBranch = "detached";
147
+ }
148
+ if (this.#onBranchChange) {
149
+ this.#onBranchChange();
150
+ }
151
+ });
152
+
153
+ // Return undefined while loading (will show on next render once loaded)
154
+ return null;
155
+ }
156
+
157
+ render(width: number): string[] {
158
+ const state = this.session.state;
159
+
160
+ // Calculate cumulative usage from ALL session entries (not just post-compaction messages)
161
+ let totalInput = 0;
162
+ let totalOutput = 0;
163
+ let totalCacheRead = 0;
164
+ let totalCacheWrite = 0;
165
+ let totalCost = 0;
166
+
167
+ for (const entry of this.session.sessionManager.getEntries()) {
168
+ if (entry.type === "message" && entry.message.role === "assistant") {
169
+ totalInput += entry.message.usage.input;
170
+ totalOutput += entry.message.usage.output;
171
+ totalCacheRead += entry.message.usage.cacheRead;
172
+ totalCacheWrite += entry.message.usage.cacheWrite;
173
+ totalCost += entry.message.usage.cost.total;
174
+ }
175
+ }
176
+
177
+ // Calculate context usage from session (handles compaction correctly).
178
+ // After compaction, tokens are unknown until the next LLM response.
179
+ const contextUsage = this.session.getContextUsage();
180
+ const contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;
181
+ const contextPercentValue = contextUsage?.percent ?? 0;
182
+ const contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : "?";
183
+
184
+ // Format token counts (similar to web-ui)
185
+ const formatTokens = (count: number): string => {
186
+ if (count < 1000) return count.toString();
187
+ if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
188
+ if (count < 1000000) return `${Math.round(count / 1000)}k`;
189
+ if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;
190
+ return `${Math.round(count / 1000000)}M`;
191
+ };
192
+
193
+ // Replace home directory with ~
194
+ let pwd = shortenPath(getProjectDir());
195
+
196
+ // Add git branch if available
197
+ const branch = this.#getCurrentBranch();
198
+ if (branch) {
199
+ pwd = `${pwd} (${branch})`;
200
+ }
201
+
202
+ // Truncate path if too long to fit width
203
+ if (pwd.length > width) {
204
+ const half = Math.floor(width / 2) - 1;
205
+ if (half > 1) {
206
+ const start = pwd.slice(0, half);
207
+ const end = pwd.slice(-(half - 1));
208
+ pwd = `${start}…${end}`;
209
+ } else {
210
+ pwd = pwd.slice(0, Math.max(1, width));
211
+ }
212
+ }
213
+
214
+ // Build stats line
215
+ const statsParts = [];
216
+ if (totalInput) statsParts.push(`↑${formatTokens(totalInput)}`);
217
+ if (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);
218
+ if (totalCacheRead) statsParts.push(`R${formatTokens(totalCacheRead)}`);
219
+ if (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);
220
+
221
+ // Show cost with "(sub)" indicator if using OAuth subscription
222
+ const usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;
223
+ if (totalCost || usingSubscription) {
224
+ const costStr = `$${totalCost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`;
225
+ statsParts.push(costStr);
226
+ }
227
+
228
+ // Colorize context percentage based on usage
229
+ let contextPercentStr: string;
230
+ const autoIndicator = this.#autoCompactEnabled ? " (auto)" : "";
231
+ const contextPercentDisplay =
232
+ contextPercent === "?"
233
+ ? `?/${formatTokens(contextWindow)}${autoIndicator}`
234
+ : `${contextPercent}%/${formatTokens(contextWindow)}${autoIndicator}`;
235
+ if (contextPercentValue > 90) {
236
+ contextPercentStr = theme.fg("error", contextPercentDisplay);
237
+ } else if (contextPercentValue > 70) {
238
+ contextPercentStr = theme.fg("warning", contextPercentDisplay);
239
+ } else {
240
+ contextPercentStr = contextPercentDisplay;
241
+ }
242
+ statsParts.push(contextPercentStr);
243
+
244
+ let statsLeft = statsParts.join(" ");
245
+
246
+ // Add model name on the right side, plus thinking level if model supports it
247
+ const modelName = state.model?.id || "no-model";
248
+
249
+ // Add thinking level hint if model supports reasoning and thinking is enabled
250
+ let rightSide = modelName;
251
+ if (state.model?.reasoning) {
252
+ const thinkingLevel = state.thinkingLevel || "off";
253
+ if (thinkingLevel !== "off") {
254
+ rightSide = `${modelName} • ${thinkingLevel}`;
255
+ }
256
+ }
257
+
258
+ let statsLeftWidth = visibleWidth(statsLeft);
259
+ const rightSideWidth = visibleWidth(rightSide);
260
+
261
+ // If statsLeft is too wide, truncate it
262
+ if (statsLeftWidth > width) {
263
+ // Truncate statsLeft to fit width (no room for right side)
264
+ const plainStatsLeft = statsLeft.replace(/\x1b\[[0-9;]*m/g, "");
265
+ statsLeft = `${plainStatsLeft.substring(0, width - 1)}…`;
266
+ statsLeftWidth = visibleWidth(statsLeft);
267
+ }
268
+
269
+ // Calculate available space for padding (minimum 2 spaces between stats and model)
270
+ const minPadding = 2;
271
+ const totalNeeded = statsLeftWidth + minPadding + rightSideWidth;
272
+
273
+ let statsLine: string;
274
+ if (totalNeeded <= width) {
275
+ // Both fit - add padding to right-align model
276
+ const pad = padding(width - statsLeftWidth - rightSideWidth);
277
+ statsLine = statsLeft + pad + rightSide;
278
+ } else {
279
+ // Need to truncate right side
280
+ const availableForRight = width - statsLeftWidth - minPadding;
281
+ if (availableForRight > 3) {
282
+ // Truncate to fit (strip ANSI codes for length calculation, then truncate raw string)
283
+ const plainRightSide = rightSide.replace(/\x1b\[[0-9;]*m/g, "");
284
+ const truncatedPlain = plainRightSide.substring(0, availableForRight);
285
+ // For simplicity, just use plain truncated version (loses color, but fits)
286
+ const pad = padding(width - statsLeftWidth - truncatedPlain.length);
287
+ statsLine = statsLeft + pad + truncatedPlain;
288
+ } else {
289
+ // Not enough space for right side at all
290
+ statsLine = statsLeft;
291
+ }
292
+ }
293
+
294
+ // Apply dim to each part separately. statsLeft may contain color codes (for context %)
295
+ // that end with a reset, which would clear an outer dim wrapper. So we dim the parts
296
+ // before and after the colored section independently.
297
+ const dimStatsLeft = theme.fg("dim", statsLeft);
298
+ const remainder = statsLine.slice(statsLeft.length); // padding + rightSide
299
+ const dimRemainder = theme.fg("dim", remainder);
300
+
301
+ const lines = [theme.fg("dim", pwd), dimStatsLeft + dimRemainder];
302
+
303
+ // Add extension statuses on a single line, sorted by key alphabetically
304
+ if (this.#extensionStatuses.size > 0) {
305
+ const sortedStatuses = Array.from(this.#extensionStatuses.entries())
306
+ .sort(([a], [b]) => a.localeCompare(b))
307
+ .map(([, text]) => sanitizeStatusText(text));
308
+ const statusLine = sortedStatuses.join(" ");
309
+ // Truncate to terminal width with dim ellipsis for consistency with footer style
310
+ lines.push(truncateToWidth(statusLine, width));
311
+ }
312
+
313
+ return lines;
314
+ }
315
+ }
@@ -0,0 +1,157 @@
1
+ import {
2
+ type Component,
3
+ Container,
4
+ Ellipsis,
5
+ Input,
6
+ matchesKey,
7
+ padding,
8
+ Spacer,
9
+ Text,
10
+ truncateToWidth,
11
+ visibleWidth,
12
+ } from "@nghyane/arcane-tui";
13
+ import { theme } from "../../modes/theme/theme";
14
+ import type { HistoryEntry, HistoryStorage } from "../../session/history-storage";
15
+ import { DynamicBorder } from "./dynamic-border";
16
+
17
+ class HistoryResultsList implements Component {
18
+ #results: HistoryEntry[] = [];
19
+ #selectedIndex = 0;
20
+ #maxVisible = 10;
21
+
22
+ setResults(results: HistoryEntry[], selectedIndex: number): void {
23
+ this.#results = results;
24
+ this.#selectedIndex = selectedIndex;
25
+ }
26
+
27
+ setSelectedIndex(selectedIndex: number): void {
28
+ this.#selectedIndex = selectedIndex;
29
+ }
30
+
31
+ invalidate(): void {
32
+ // No cached state to invalidate currently
33
+ }
34
+
35
+ render(width: number): string[] {
36
+ const lines: string[] = [];
37
+
38
+ if (this.#results.length === 0) {
39
+ lines.push(theme.fg("muted", " No matching history"));
40
+ return lines;
41
+ }
42
+
43
+ const startIndex = Math.max(
44
+ 0,
45
+ Math.min(this.#selectedIndex - Math.floor(this.#maxVisible / 2), this.#results.length - this.#maxVisible),
46
+ );
47
+ const endIndex = Math.min(startIndex + this.#maxVisible, this.#results.length);
48
+
49
+ for (let i = startIndex; i < endIndex; i++) {
50
+ const entry = this.#results[i];
51
+ const isSelected = i === this.#selectedIndex;
52
+
53
+ const cursorSymbol = `${theme.nav.cursor} `;
54
+ const cursorWidth = visibleWidth(cursorSymbol);
55
+ const cursor = isSelected ? theme.fg("accent", cursorSymbol) : padding(cursorWidth);
56
+ const maxWidth = width - cursorWidth;
57
+
58
+ const normalized = entry.prompt.replace(/\s+/g, " ").trim();
59
+ const truncated = truncateToWidth(normalized, maxWidth);
60
+ lines.push(cursor + (isSelected ? theme.bold(truncated) : truncated));
61
+ }
62
+
63
+ if (startIndex > 0 || endIndex < this.#results.length) {
64
+ const scrollText = ` (${this.#selectedIndex + 1}/${this.#results.length})`;
65
+ lines.push(theme.fg("muted", truncateToWidth(scrollText, width, Ellipsis.Omit)));
66
+ }
67
+
68
+ return lines;
69
+ }
70
+ }
71
+
72
+ export class HistorySearchComponent extends Container {
73
+ #historyStorage: HistoryStorage;
74
+ #searchInput: Input;
75
+ #results: HistoryEntry[] = [];
76
+ #selectedIndex = 0;
77
+ #resultsList: HistoryResultsList;
78
+ #onSelect: (prompt: string) => void;
79
+ #onCancel: () => void;
80
+ #resultLimit = 100;
81
+
82
+ constructor(historyStorage: HistoryStorage, onSelect: (prompt: string) => void, onCancel: () => void) {
83
+ super();
84
+ this.#historyStorage = historyStorage;
85
+ this.#onSelect = onSelect;
86
+ this.#onCancel = onCancel;
87
+
88
+ this.#searchInput = new Input();
89
+ this.#searchInput.onSubmit = () => {
90
+ const selected = this.#results[this.#selectedIndex];
91
+ if (selected) {
92
+ this.#onSelect(selected.prompt);
93
+ }
94
+ };
95
+ this.#searchInput.onEscape = () => {
96
+ this.#onCancel();
97
+ };
98
+
99
+ this.#resultsList = new HistoryResultsList();
100
+
101
+ this.addChild(new Spacer(1));
102
+ this.addChild(new Text(theme.bold("Search History (Ctrl+R)"), 1, 0));
103
+ this.addChild(new Spacer(1));
104
+ this.addChild(new DynamicBorder());
105
+ this.addChild(new Spacer(1));
106
+ this.addChild(this.#searchInput);
107
+ this.addChild(new Spacer(1));
108
+ this.addChild(this.#resultsList);
109
+ this.addChild(new Spacer(1));
110
+ this.addChild(new Text(theme.fg("muted", "up/down navigate enter select esc cancel"), 1, 0));
111
+ this.addChild(new Spacer(1));
112
+ this.addChild(new DynamicBorder());
113
+
114
+ this.#updateResults();
115
+ }
116
+
117
+ handleInput(keyData: string): void {
118
+ if (matchesKey(keyData, "up")) {
119
+ if (this.#results.length === 0) return;
120
+ this.#selectedIndex = Math.max(0, this.#selectedIndex - 1);
121
+ this.#resultsList.setSelectedIndex(this.#selectedIndex);
122
+ return;
123
+ }
124
+
125
+ if (matchesKey(keyData, "down")) {
126
+ if (this.#results.length === 0) return;
127
+ this.#selectedIndex = Math.min(this.#results.length - 1, this.#selectedIndex + 1);
128
+ this.#resultsList.setSelectedIndex(this.#selectedIndex);
129
+ return;
130
+ }
131
+
132
+ if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
133
+ const selected = this.#results[this.#selectedIndex];
134
+ if (selected) {
135
+ this.#onSelect(selected.prompt);
136
+ }
137
+ return;
138
+ }
139
+
140
+ if (matchesKey(keyData, "escape") || matchesKey(keyData, "esc")) {
141
+ this.#onCancel();
142
+ return;
143
+ }
144
+
145
+ this.#searchInput.handleInput(keyData);
146
+ this.#updateResults();
147
+ }
148
+
149
+ #updateResults(): void {
150
+ const query = this.#searchInput.getValue().trim();
151
+ this.#results = query
152
+ ? this.#historyStorage.search(query, this.#resultLimit)
153
+ : this.#historyStorage.getRecent(this.#resultLimit);
154
+ this.#selectedIndex = 0;
155
+ this.#resultsList.setResults(this.#results, this.#selectedIndex);
156
+ }
157
+ }