@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,116 @@
1
+ /**
2
+ * Custom Compaction Hook
3
+ *
4
+ * Replaces the default compaction behavior with a full summary of the entire context.
5
+ * Instead of keeping the last 20k tokens of conversation turns, this hook:
6
+ * 1. Summarizes ALL messages (messagesToSummarize + turnPrefixMessages)
7
+ * 2. Discards all old turns completely, keeping only the summary
8
+ *
9
+ * This example also demonstrates using a different model (Gemini Flash) for summarization,
10
+ * which can be cheaper/faster than the main conversation model.
11
+ *
12
+ * Usage:
13
+ * arcane --hook examples/hooks/custom-compaction.ts
14
+ */
15
+
16
+ import type { HookAPI } from "@nghyane/arcane";
17
+ import { convertToLlm, serializeConversation } from "@nghyane/arcane";
18
+ import { complete, getModel } from "@nghyane/arcane-ai";
19
+
20
+ export default function (pi: HookAPI) {
21
+ pi.on("session_before_compact", async (event, ctx) => {
22
+ ctx.ui.notify("Custom compaction hook triggered", "info");
23
+
24
+ const { preparation, branchEntries: _, signal } = event;
25
+ const { messagesToSummarize, turnPrefixMessages, tokensBefore, firstKeptEntryId, previousSummary } = preparation;
26
+
27
+ // Use Gemini Flash for summarization (cheaper/faster than most conversation models)
28
+ const model = getModel("google", "gemini-2.5-flash");
29
+ if (!model) {
30
+ ctx.ui.notify(`Could not find Gemini Flash model, using default compaction`, "warning");
31
+ return;
32
+ }
33
+
34
+ // Resolve API key for the summarization model
35
+ const apiKey = await ctx.modelRegistry.getApiKey(model);
36
+ if (!apiKey) {
37
+ ctx.ui.notify(`No API key for ${model.provider}, using default compaction`, "warning");
38
+ return;
39
+ }
40
+
41
+ // Combine all messages for full summary
42
+ const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
43
+
44
+ ctx.ui.notify(
45
+ `Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${
46
+ model.id
47
+ }...`,
48
+ "info",
49
+ );
50
+
51
+ // Convert messages to readable text format
52
+ const conversationText = serializeConversation(convertToLlm(allMessages));
53
+
54
+ // Include previous summary context if available
55
+ const previousContext = previousSummary ? `\n\nPrevious session summary for context:\n${previousSummary}` : "";
56
+
57
+ // Build messages that ask for a comprehensive summary
58
+ const summaryMessages = [
59
+ {
60
+ role: "user" as const,
61
+ content: [
62
+ {
63
+ type: "text" as const,
64
+ text: `You are a conversation summarizer. Create a comprehensive summary of this conversation that captures:${previousContext}
65
+
66
+ 1. The main goals and objectives discussed
67
+ 2. Key decisions made and their rationale
68
+ 3. Important code changes, file modifications, or technical details
69
+ 4. Current state of any ongoing work
70
+ 5. Any blockers, issues, or open questions
71
+ 6. Next steps that were planned or suggested
72
+
73
+ Be thorough but concise. The summary will replace the ENTIRE conversation history, so include all information needed to continue the work effectively.
74
+
75
+ Format the summary as structured markdown with clear sections.
76
+
77
+ <conversation>
78
+ ${conversationText}
79
+ </conversation>`,
80
+ },
81
+ ],
82
+ timestamp: Date.now(),
83
+ },
84
+ ];
85
+
86
+ try {
87
+ // Pass signal to honor abort requests (e.g., user cancels compaction)
88
+ const response = await complete(model, { messages: summaryMessages }, { apiKey, maxTokens: 8192, signal });
89
+
90
+ const summary = response.content
91
+ .filter((c): c is { type: "text"; text: string } => c.type === "text")
92
+ .map(c => c.text)
93
+ .join("\n");
94
+
95
+ if (!summary.trim()) {
96
+ if (!signal.aborted) ctx.ui.notify("Compaction summary was empty, using default compaction", "warning");
97
+ return;
98
+ }
99
+
100
+ // Return compaction content - SessionManager adds id/parentId
101
+ // Use firstKeptEntryId from preparation to keep recent messages
102
+ return {
103
+ compaction: {
104
+ summary,
105
+ firstKeptEntryId,
106
+ tokensBefore,
107
+ },
108
+ };
109
+ } catch (error) {
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ ctx.ui.notify(`Compaction failed: ${message}`, "error");
112
+ // Fall back to default compaction on error
113
+ return;
114
+ }
115
+ });
116
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Dirty Repo Guard Hook
3
+ *
4
+ * Prevents session changes when there are uncommitted git changes.
5
+ * Useful to ensure work is committed before switching context.
6
+ */
7
+ import type { HookAPI, HookContext } from "@nghyane/arcane";
8
+
9
+ async function checkDirtyRepo(pi: HookAPI, ctx: HookContext, action: string): Promise<{ cancel: boolean } | undefined> {
10
+ // Check for uncommitted changes
11
+ const { stdout, code } = await pi.exec("git", ["status", "--porcelain"]);
12
+
13
+ if (code !== 0) {
14
+ // Not a git repo, allow the action
15
+ return;
16
+ }
17
+
18
+ const hasChanges = stdout.trim().length > 0;
19
+ if (!hasChanges) {
20
+ return;
21
+ }
22
+
23
+ if (!ctx.hasUI) {
24
+ // In non-interactive mode, block by default
25
+ return { cancel: true };
26
+ }
27
+
28
+ // Count changed files
29
+ const changedFiles = stdout.trim().split("\n").filter(Boolean).length;
30
+
31
+ const choice = await ctx.ui.select(`You have ${changedFiles} uncommitted file(s). ${action} anyway?`, [
32
+ "Yes, proceed anyway",
33
+ "No, let me commit first",
34
+ ]);
35
+
36
+ if (choice !== "Yes, proceed anyway") {
37
+ ctx.ui.notify("Commit your changes first", "warning");
38
+ return { cancel: true };
39
+ }
40
+ }
41
+
42
+ export default function (pi: HookAPI) {
43
+ pi.on("session_before_switch", async (event, ctx) => {
44
+ const action = event.reason === "new" ? "new session" : "switch session";
45
+ return checkDirtyRepo(pi, ctx, action);
46
+ });
47
+
48
+ pi.on("session_before_branch", async (_event, ctx) => {
49
+ return checkDirtyRepo(pi, ctx, "branch");
50
+ });
51
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * File Trigger Hook
3
+ *
4
+ * Watches a trigger file and injects its contents into the conversation.
5
+ * Useful for external systems to send messages to the agent.
6
+ *
7
+ * Usage:
8
+ * echo "Run the tests" > /tmp/agent-trigger.txt
9
+ */
10
+ import * as fs from "node:fs";
11
+ import type { HookAPI } from "@nghyane/arcane";
12
+
13
+ export default function (pi: HookAPI) {
14
+ pi.on("session_start", async (_event, ctx) => {
15
+ const triggerFile = "/tmp/agent-trigger.txt";
16
+
17
+ fs.watch(triggerFile, async () => {
18
+ try {
19
+ const content = (await Bun.file(triggerFile).text()).trim();
20
+ if (content) {
21
+ pi.sendMessage(
22
+ {
23
+ customType: "file-trigger",
24
+ content: `External trigger: ${content}`,
25
+ display: true,
26
+ },
27
+ true, // triggerTurn - get LLM to respond
28
+ );
29
+ await Bun.write(triggerFile, ""); // Clear after reading
30
+ }
31
+ } catch {
32
+ // File might not exist yet
33
+ }
34
+ });
35
+
36
+ if (ctx.hasUI) {
37
+ ctx.ui.notify(`Watching ${triggerFile}`, "info");
38
+ }
39
+ });
40
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Git Checkpoint Hook
3
+ *
4
+ * Creates git stash checkpoints at each turn so /branch can restore code state.
5
+ * When branching, offers to restore code to that point in history.
6
+ */
7
+ import type { HookAPI } from "@nghyane/arcane";
8
+
9
+ export default function (pi: HookAPI) {
10
+ const checkpoints = new Map<string, string>();
11
+ let currentEntryId: string | undefined;
12
+
13
+ // Track the current entry ID when user messages are saved
14
+ pi.on("tool_result", async (_event, ctx) => {
15
+ const leaf = ctx.sessionManager.getLeafEntry();
16
+ if (leaf) currentEntryId = leaf.id;
17
+ });
18
+
19
+ pi.on("turn_start", async () => {
20
+ // Create a git stash entry before LLM makes changes
21
+ const { stdout } = await pi.exec("git", ["stash", "create"]);
22
+ const ref = stdout.trim();
23
+ if (ref && currentEntryId) {
24
+ checkpoints.set(currentEntryId, ref);
25
+ }
26
+ });
27
+
28
+ pi.on("session_before_branch", async (event, ctx) => {
29
+ const ref = checkpoints.get(event.entryId);
30
+ if (!ref) return;
31
+
32
+ if (!ctx.hasUI) {
33
+ // In non-interactive mode, don't restore automatically
34
+ return;
35
+ }
36
+
37
+ const choice = await ctx.ui.select("Restore code state?", [
38
+ "Yes, restore code to that point",
39
+ "No, keep current code",
40
+ ]);
41
+
42
+ if (choice?.startsWith("Yes")) {
43
+ await pi.exec("git", ["stash", "apply", ref]);
44
+ ctx.ui.notify("Code restored to checkpoint", "info");
45
+ }
46
+ });
47
+
48
+ pi.on("agent_end", async () => {
49
+ // Clear checkpoints after agent completes
50
+ checkpoints.clear();
51
+ });
52
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Handoff hook - transfer context to a new focused session
3
+ *
4
+ * Instead of compacting (which is lossy), handoff extracts what matters
5
+ * for your next task and creates a new session with a generated prompt.
6
+ *
7
+ * Usage:
8
+ * /handoff now implement this for teams as well
9
+ * /handoff execute phase one of the plan
10
+ * /handoff check other places that need this fix
11
+ *
12
+ * The generated prompt appears as a draft in the editor for review/editing.
13
+ */
14
+
15
+ import type { HookAPI, SessionEntry } from "@nghyane/arcane";
16
+ import { BorderedLoader, convertToLlm, serializeConversation } from "@nghyane/arcane";
17
+ import { complete, type Message } from "@nghyane/arcane-ai";
18
+
19
+ const SYSTEM_PROMPT = `You are a context transfer assistant. Given a conversation history and the user's goal for a new thread, generate a focused prompt that:
20
+
21
+ 1. Summarizes relevant context from the conversation (decisions made, approaches taken, key findings)
22
+ 2. Lists any relevant files that were discussed or modified
23
+ 3. Clearly states the next task based on the user's goal
24
+ 4. Is self-contained - the new thread should be able to proceed without the old conversation
25
+
26
+ Format your response as a prompt the user can send to start the new thread. Be concise but include all necessary context. Do not include any preamble like "Here's the prompt" - just output the prompt itself.
27
+
28
+ Example output format:
29
+ ## Context
30
+ We've been working on X. Key decisions:
31
+ - Decision 1
32
+ - Decision 2
33
+
34
+ Files involved:
35
+ - path/to/file1.ts
36
+ - path/to/file2.ts
37
+
38
+ ## Task
39
+ [Clear description of what to do next based on user's goal]`;
40
+
41
+ export default function (pi: HookAPI) {
42
+ pi.registerCommand("handoff", {
43
+ description: "Transfer context to a new focused session",
44
+ handler: async (args, ctx) => {
45
+ if (!ctx.hasUI) {
46
+ ctx.ui.notify("handoff requires interactive mode", "error");
47
+ return;
48
+ }
49
+
50
+ if (!ctx.model) {
51
+ ctx.ui.notify("No model selected", "error");
52
+ return;
53
+ }
54
+
55
+ const goal = args.trim();
56
+ if (!goal) {
57
+ ctx.ui.notify("Usage: /handoff <goal for new thread>", "error");
58
+ return;
59
+ }
60
+
61
+ // Gather conversation context from current branch
62
+ const branch = ctx.sessionManager.getBranch();
63
+ const messages = branch
64
+ .filter((entry): entry is SessionEntry & { type: "message" } => entry.type === "message")
65
+ .map(entry => entry.message);
66
+
67
+ if (messages.length === 0) {
68
+ ctx.ui.notify("No conversation to hand off", "error");
69
+ return;
70
+ }
71
+
72
+ // Convert to LLM format and serialize
73
+ const llmMessages = convertToLlm(messages);
74
+ const conversationText = serializeConversation(llmMessages);
75
+ const currentSessionFile = ctx.sessionManager.getSessionFile();
76
+
77
+ // Generate the handoff prompt with loader UI
78
+ const result = await ctx.ui.custom<string | null>((tui, theme, done) => {
79
+ const loader = new BorderedLoader(tui, theme, `Generating handoff prompt...`);
80
+ loader.onAbort = () => done(null);
81
+
82
+ const doGenerate = async () => {
83
+ const apiKey = await ctx.modelRegistry.getApiKey(ctx.model!);
84
+
85
+ const userMessage: Message = {
86
+ role: "user",
87
+ content: [
88
+ {
89
+ type: "text",
90
+ text: `## Conversation History\n\n${conversationText}\n\n## User's Goal for New Thread\n\n${goal}`,
91
+ },
92
+ ],
93
+ timestamp: Date.now(),
94
+ };
95
+
96
+ const response = await complete(
97
+ ctx.model!,
98
+ { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
99
+ { apiKey, signal: loader.signal },
100
+ );
101
+
102
+ if (response.stopReason === "aborted") {
103
+ return null;
104
+ }
105
+
106
+ return response.content
107
+ .filter((c): c is { type: "text"; text: string } => c.type === "text")
108
+ .map(c => c.text)
109
+ .join("\n");
110
+ };
111
+
112
+ doGenerate()
113
+ .then(done)
114
+ .catch(err => {
115
+ console.error("Handoff generation failed:", err);
116
+ done(null);
117
+ });
118
+
119
+ return loader;
120
+ });
121
+
122
+ if (result === null) {
123
+ ctx.ui.notify("Cancelled", "info");
124
+ return;
125
+ }
126
+
127
+ // Let user edit the generated prompt
128
+ const editedPrompt = await ctx.ui.editor("Edit handoff prompt (ctrl+enter to submit, esc to cancel)", result);
129
+
130
+ if (editedPrompt === undefined) {
131
+ ctx.ui.notify("Cancelled", "info");
132
+ return;
133
+ }
134
+
135
+ // Create new session with parent tracking
136
+ const newSessionResult = await ctx.newSession({
137
+ parentSession: currentSessionFile,
138
+ });
139
+
140
+ if (newSessionResult.cancelled) {
141
+ ctx.ui.notify("New session cancelled", "info");
142
+ return;
143
+ }
144
+
145
+ // Set the edited prompt in the main editor for submission
146
+ ctx.ui.setEditorText(editedPrompt);
147
+ ctx.ui.notify("Handoff ready. Submit when ready.", "info");
148
+ },
149
+ });
150
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Permission Gate Hook
3
+ *
4
+ * Prompts for confirmation before running potentially dangerous bash commands.
5
+ * Patterns checked: rm -rf, sudo, chmod/chown 777
6
+ */
7
+ import type { HookAPI } from "@nghyane/arcane";
8
+
9
+ export default function (pi: HookAPI) {
10
+ const dangerousPatterns = [/\brm\s+(-rf?|--recursive)/i, /\bsudo\b/i, /\b(chmod|chown)\b.*777/i];
11
+
12
+ pi.on("tool_call", async (event, ctx) => {
13
+ if (event.toolName !== "bash") return undefined;
14
+
15
+ const command = event.input.command as string;
16
+ const isDangerous = dangerousPatterns.some(p => p.test(command));
17
+
18
+ if (isDangerous) {
19
+ if (!ctx.hasUI) {
20
+ // In non-interactive mode, block by default
21
+ return { block: true, reason: "Dangerous command blocked (no UI for confirmation)" };
22
+ }
23
+
24
+ const choice = await ctx.ui.select(`⚠️ Dangerous command:\n\n ${command}\n\nAllow?`, ["Yes", "No"]);
25
+
26
+ if (choice !== "Yes") {
27
+ return { block: true, reason: "Blocked by user" };
28
+ }
29
+ }
30
+
31
+ return undefined;
32
+ });
33
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Protected Paths Hook
3
+ *
4
+ * Blocks write and edit operations to protected paths.
5
+ * Useful for preventing accidental modifications to sensitive files.
6
+ */
7
+ import type { HookAPI } from "@nghyane/arcane";
8
+
9
+ export default function (pi: HookAPI) {
10
+ const protectedPaths = [".env", ".git/", "node_modules/"];
11
+
12
+ pi.on("tool_call", async (event, ctx) => {
13
+ if (event.toolName !== "write" && event.toolName !== "edit") {
14
+ return undefined;
15
+ }
16
+
17
+ const path = event.input.path as string;
18
+ const isProtected = protectedPaths.some(p => path.includes(p));
19
+
20
+ if (isProtected) {
21
+ if (ctx.hasUI) {
22
+ ctx.ui.notify(`Blocked write to protected path: ${path}`, "warning");
23
+ }
24
+ return { block: true, reason: `Path "${path}" is protected` };
25
+ }
26
+
27
+ return undefined;
28
+ });
29
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Q&A extraction hook - extracts questions from assistant responses
3
+ *
4
+ * Demonstrates the "prompt generator" pattern:
5
+ * 1. /qna command gets the last assistant message
6
+ * 2. Shows a spinner while extracting (hides editor)
7
+ * 3. Loads the result into the editor for user to fill in answers
8
+ */
9
+
10
+ import type { HookAPI } from "@nghyane/arcane";
11
+ import { BorderedLoader } from "@nghyane/arcane";
12
+ import { complete, type UserMessage } from "@nghyane/arcane-ai";
13
+
14
+ const SYSTEM_PROMPT = `You are a question extractor. Given text from a conversation, extract any questions that need answering and format them for the user to fill in.
15
+
16
+ Output format:
17
+ - List each question on its own line, prefixed with "Q: "
18
+ - After each question, add a blank line for the answer prefixed with "A: "
19
+ - If no questions are found, output "No questions found in the last message."
20
+
21
+ Example output:
22
+ Q: What is your preferred database?
23
+ A:
24
+
25
+ Q: Should we use TypeScript or JavaScript?
26
+ A:
27
+
28
+ Keep questions in the order they appeared. Be concise.`;
29
+
30
+ export default function (pi: HookAPI) {
31
+ pi.registerCommand("qna", {
32
+ description: "Extract questions from last assistant message into editor",
33
+ handler: async (_args, ctx) => {
34
+ if (!ctx.hasUI) {
35
+ ctx.ui.notify("qna requires interactive mode", "error");
36
+ return;
37
+ }
38
+
39
+ if (!ctx.model) {
40
+ ctx.ui.notify("No model selected", "error");
41
+ return;
42
+ }
43
+
44
+ // Find the last assistant message on the current branch
45
+ const branch = ctx.sessionManager.getBranch();
46
+ let lastAssistantText: string | undefined;
47
+
48
+ for (let i = branch.length - 1; i >= 0; i--) {
49
+ const entry = branch[i];
50
+ if (entry.type === "message") {
51
+ const msg = entry.message;
52
+ if ("role" in msg && msg.role === "assistant") {
53
+ if (msg.stopReason !== "stop") {
54
+ ctx.ui.notify(`Last assistant message incomplete (${msg.stopReason})`, "error");
55
+ return;
56
+ }
57
+ const textParts = msg.content
58
+ .filter((c): c is { type: "text"; text: string } => c.type === "text")
59
+ .map(c => c.text);
60
+ if (textParts.length > 0) {
61
+ lastAssistantText = textParts.join("\n");
62
+ break;
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ if (!lastAssistantText) {
69
+ ctx.ui.notify("No assistant messages found", "error");
70
+ return;
71
+ }
72
+
73
+ // Run extraction with loader UI
74
+ const result = await ctx.ui.custom<string | null>((tui, theme, done) => {
75
+ const loader = new BorderedLoader(tui, theme, `Extracting questions using ${ctx.model!.id}…`);
76
+ loader.onAbort = () => done(null);
77
+
78
+ // Do the work
79
+ const doExtract = async () => {
80
+ const apiKey = await ctx.modelRegistry.getApiKey(ctx.model!);
81
+ const userMessage: UserMessage = {
82
+ role: "user",
83
+ content: [{ type: "text", text: lastAssistantText! }],
84
+ timestamp: Date.now(),
85
+ };
86
+
87
+ const response = await complete(
88
+ ctx.model!,
89
+ { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
90
+ { apiKey, signal: loader.signal },
91
+ );
92
+
93
+ if (response.stopReason === "aborted") {
94
+ return null;
95
+ }
96
+
97
+ return response.content
98
+ .filter((c): c is { type: "text"; text: string } => c.type === "text")
99
+ .map(c => c.text)
100
+ .join("\n");
101
+ };
102
+
103
+ doExtract()
104
+ .then(done)
105
+ .catch(() => done(null));
106
+
107
+ return loader;
108
+ });
109
+
110
+ if (result === null) {
111
+ ctx.ui.notify("Cancelled", "info");
112
+ return;
113
+ }
114
+
115
+ ctx.ui.setEditorText(result);
116
+ ctx.ui.notify("Questions loaded. Edit and submit when ready.", "info");
117
+ },
118
+ });
119
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Status Line Hook
3
+ *
4
+ * Demonstrates ctx.ui.setStatus() for displaying persistent status text in the footer.
5
+ * Shows turn progress with themed colors.
6
+ */
7
+ import type { HookAPI } from "@nghyane/arcane";
8
+
9
+ export default function (pi: HookAPI) {
10
+ let turnCount = 0;
11
+
12
+ pi.on("session_start", async (_event, ctx) => {
13
+ const theme = ctx.ui.theme;
14
+ ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
15
+ });
16
+
17
+ pi.on("turn_start", async (_event, ctx) => {
18
+ turnCount++;
19
+ const theme = ctx.ui.theme;
20
+ const spinner = theme.fg("accent", "●");
21
+ const text = theme.fg("dim", ` Turn ${turnCount}…`);
22
+ ctx.ui.setStatus("status-demo", spinner + text);
23
+ });
24
+
25
+ pi.on("turn_end", async (_event, ctx) => {
26
+ const theme = ctx.ui.theme;
27
+ const check = theme.fg("success", "✓");
28
+ const text = theme.fg("dim", ` Turn ${turnCount} complete`);
29
+ ctx.ui.setStatus("status-demo", check + text);
30
+ });
31
+
32
+ pi.on("session_switch", async (event, ctx) => {
33
+ if (event.reason === "new") {
34
+ turnCount = 0;
35
+ const theme = ctx.ui.theme;
36
+ ctx.ui.setStatus("status-demo", theme.fg("dim", "Ready"));
37
+ }
38
+ });
39
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Minimal SDK Usage
3
+ *
4
+ * Uses all defaults: discovers skills, hooks, tools, context files
5
+ * from cwd and ~/.arcane/agent. Model chosen from settings or first available.
6
+ */
7
+ import { createAgentSession } from "@nghyane/arcane";
8
+
9
+ const { session } = await createAgentSession();
10
+
11
+ session.subscribe(event => {
12
+ if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
13
+ process.stdout.write(event.assistantMessageEvent.delta);
14
+ }
15
+ });
16
+
17
+ await session.prompt("What files are in the current directory?");
18
+ session.state.messages.forEach(msg => {
19
+ console.log(msg);
20
+ });
21
+ console.log();