@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,698 @@
1
+ /**
2
+ * Shared helpers for discovery providers.
3
+ */
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import type { ThinkingLevel } from "@nghyane/arcane-agent";
7
+ import { FileType, glob } from "@nghyane/arcane-natives";
8
+ import { CONFIG_DIR_NAME } from "@nghyane/arcane-utils/dirs";
9
+ import { readFile } from "../capability/fs";
10
+ import { parseRuleConditionAndScope, type Rule, type RuleFrontmatter } from "../capability/rule";
11
+ import type { Skill, SkillFrontmatter } from "../capability/skill";
12
+ import type { LoadContext, LoadResult, SourceMeta } from "../capability/types";
13
+ import { parseFrontmatter } from "../utils/frontmatter";
14
+ import type { IgnoreMatcher } from "../utils/ignore-files";
15
+
16
+ const VALID_THINKING_LEVELS: readonly string[] = ["off", "minimal", "low", "medium", "high", "xhigh"];
17
+ const UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
18
+
19
+ /**
20
+ * Normalize unicode spaces to regular spaces.
21
+ */
22
+ export function normalizeUnicodeSpaces(str: string): string {
23
+ return str.replace(UNICODE_SPACES, " ");
24
+ }
25
+
26
+ /**
27
+ * Expand ~ to home directory and normalize unicode spaces.
28
+ */
29
+ export function expandPath(p: string): string {
30
+ const normalized = normalizeUnicodeSpaces(p);
31
+ if (normalized.startsWith("~/")) {
32
+ return path.join(os.homedir(), normalized.slice(2));
33
+ }
34
+ if (normalized.startsWith("~")) {
35
+ return path.join(os.homedir(), normalized.slice(1));
36
+ }
37
+ return normalized;
38
+ }
39
+
40
+ /**
41
+ * Standard paths for each config source.
42
+ */
43
+ export const SOURCE_PATHS = {
44
+ native: {
45
+ userBase: CONFIG_DIR_NAME,
46
+ userAgent: `${CONFIG_DIR_NAME}/agent`,
47
+ projectDir: CONFIG_DIR_NAME,
48
+ },
49
+ claude: {
50
+ userBase: ".claude",
51
+ userAgent: ".claude",
52
+ projectDir: ".claude",
53
+ },
54
+ codex: {
55
+ userBase: ".codex",
56
+ userAgent: ".codex",
57
+ projectDir: ".codex",
58
+ },
59
+ gemini: {
60
+ userBase: ".gemini",
61
+ userAgent: ".gemini",
62
+ projectDir: ".gemini",
63
+ },
64
+ opencode: {
65
+ userBase: ".config/opencode",
66
+ userAgent: ".config/opencode",
67
+ projectDir: ".opencode",
68
+ },
69
+ cursor: {
70
+ userBase: ".cursor",
71
+ userAgent: ".cursor",
72
+ projectDir: ".cursor",
73
+ },
74
+ windsurf: {
75
+ userBase: ".codeium/windsurf",
76
+ userAgent: ".codeium/windsurf",
77
+ projectDir: ".windsurf",
78
+ },
79
+ cline: {
80
+ userBase: ".cline",
81
+ userAgent: ".cline",
82
+ projectDir: null, // Cline uses root-level .clinerules
83
+ },
84
+ github: {
85
+ userBase: null,
86
+ userAgent: null,
87
+ projectDir: ".github",
88
+ },
89
+ vscode: {
90
+ userBase: ".vscode",
91
+ userAgent: ".vscode",
92
+ projectDir: ".vscode",
93
+ },
94
+ } as const;
95
+
96
+ export type SourceId = keyof typeof SOURCE_PATHS;
97
+
98
+ /**
99
+ * Get user-level path for a source.
100
+ */
101
+ export function getUserPath(ctx: LoadContext, source: SourceId, subpath: string): string | null {
102
+ const paths = SOURCE_PATHS[source];
103
+ if (!paths.userAgent) return null;
104
+ return path.join(ctx.home, paths.userAgent, subpath);
105
+ }
106
+
107
+ /**
108
+ * Get project-level path for a source (cwd only).
109
+ */
110
+ export function getProjectPath(ctx: LoadContext, source: SourceId, subpath: string): string | null {
111
+ const paths = SOURCE_PATHS[source];
112
+ if (!paths.projectDir) return null;
113
+
114
+ return path.join(ctx.cwd, paths.projectDir, subpath);
115
+ }
116
+
117
+ /**
118
+ * Create source metadata for an item.
119
+ */
120
+ export function createSourceMeta(provider: string, filePath: string, level: "user" | "project"): SourceMeta {
121
+ return {
122
+ provider,
123
+ providerName: "", // Filled in by registry
124
+ path: path.resolve(filePath),
125
+ level,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Parse thinking level from frontmatter.
131
+ * Supports keys: thinkingLevel, thinking-level, thinking
132
+ */
133
+ export function parseThinkingLevel(frontmatter: Record<string, unknown>): ThinkingLevel | undefined {
134
+ const raw = frontmatter.thinkingLevel ?? frontmatter["thinking-level"] ?? frontmatter.thinking;
135
+ if (typeof raw === "string" && VALID_THINKING_LEVELS.includes(raw)) {
136
+ return raw as ThinkingLevel;
137
+ }
138
+ return undefined;
139
+ }
140
+
141
+ /**
142
+ * Parse a comma-separated string into an array of trimmed, non-empty strings.
143
+ */
144
+ export function parseCSV(value: string): string[] {
145
+ return value
146
+ .split(",")
147
+ .map(s => s.trim())
148
+ .filter(Boolean);
149
+ }
150
+
151
+ /**
152
+ * Parse a value that may be an array of strings or a comma-separated string.
153
+ * Returns undefined if the result would be empty.
154
+ */
155
+ export function parseArrayOrCSV(value: unknown): string[] | undefined {
156
+ if (Array.isArray(value)) {
157
+ const filtered = value.filter((item): item is string => typeof item === "string");
158
+ return filtered.length > 0 ? filtered : undefined;
159
+ }
160
+ if (typeof value === "string") {
161
+ const parsed = parseCSV(value);
162
+ return parsed.length > 0 ? parsed : undefined;
163
+ }
164
+ return undefined;
165
+ }
166
+
167
+ /**
168
+ * Build a canonical rule item from a markdown/markdown-frontmatter document.
169
+ */
170
+ export function buildRuleFromMarkdown(
171
+ name: string,
172
+ content: string,
173
+ filePath: string,
174
+ source: SourceMeta,
175
+ options?: {
176
+ ruleName?: string;
177
+ stripNamePattern?: RegExp;
178
+ },
179
+ ): Rule {
180
+ const { frontmatter, body } = parseFrontmatter(content, { source: filePath });
181
+ const { condition, scope } = parseRuleConditionAndScope(frontmatter as RuleFrontmatter);
182
+
183
+ let globs: string[] | undefined;
184
+ if (Array.isArray(frontmatter.globs)) {
185
+ globs = frontmatter.globs.filter((item): item is string => typeof item === "string");
186
+ } else if (typeof frontmatter.globs === "string") {
187
+ globs = [frontmatter.globs];
188
+ }
189
+
190
+ const resolvedName = options?.ruleName ?? name.replace(options?.stripNamePattern ?? /\.(md|mdc)$/, "");
191
+ return {
192
+ name: resolvedName,
193
+ path: filePath,
194
+ content: body,
195
+ globs,
196
+ alwaysApply: frontmatter.alwaysApply === true,
197
+ description: typeof frontmatter.description === "string" ? frontmatter.description : undefined,
198
+ condition,
199
+ scope,
200
+ _source: source,
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Parse model field into a prioritized list.
206
+ */
207
+ export function parseModelList(value: unknown): string[] | undefined {
208
+ const parsed = parseArrayOrCSV(value);
209
+ if (!parsed) return undefined;
210
+ const normalized = parsed.map(entry => entry.trim()).filter(Boolean);
211
+ return normalized.length > 0 ? normalized : undefined;
212
+ }
213
+
214
+ /** Parsed agent fields from frontmatter (excludes source/filePath/systemPrompt) */
215
+ export interface ParsedAgentFields {
216
+ name: string;
217
+ description: string;
218
+ tools?: string[];
219
+ model?: string[];
220
+ thinkingLevel?: ThinkingLevel;
221
+ }
222
+
223
+ /**
224
+ * Parse agent fields from frontmatter.
225
+ * Returns null if required fields (name, description) are missing.
226
+ */
227
+ export function parseAgentFields(frontmatter: Record<string, unknown>): ParsedAgentFields | null {
228
+ const name = typeof frontmatter.name === "string" ? frontmatter.name : undefined;
229
+ const description = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
230
+
231
+ if (!name || !description) {
232
+ return null;
233
+ }
234
+
235
+ let tools = parseArrayOrCSV(frontmatter.tools);
236
+
237
+ // Subagents with output schema need submit_result to return structured data
238
+ if (tools && frontmatter.output && !tools.includes("submit_result")) {
239
+ tools = [...tools, "submit_result"];
240
+ }
241
+
242
+ const model = parseModelList(frontmatter.model);
243
+ const thinkingLevel = parseThinkingLevel(frontmatter);
244
+
245
+ return { name, description, tools, model, thinkingLevel };
246
+ }
247
+
248
+ async function globIf(
249
+ dir: string,
250
+ pattern: string,
251
+ fileType: FileType,
252
+ recursive: boolean = true,
253
+ ): Promise<Array<{ path: string }>> {
254
+ try {
255
+ const result = await glob({ pattern, path: dir, gitignore: true, hidden: false, fileType, recursive });
256
+ return result.matches;
257
+ } catch {
258
+ return [];
259
+ }
260
+ }
261
+
262
+ export async function loadSkillsFromDir(
263
+ _ctx: LoadContext,
264
+ options: {
265
+ dir: string;
266
+ providerId: string;
267
+ level: "user" | "project";
268
+ requireDescription?: boolean;
269
+ },
270
+ ): Promise<LoadResult<Skill>> {
271
+ const items: Skill[] = [];
272
+ const warnings: string[] = [];
273
+ const { dir, level, providerId, requireDescription = false } = options;
274
+ // Use native glob to find all SKILL.md files one level deep
275
+ // Pattern */SKILL.md matches <dir>/<subdir>/SKILL.md
276
+ const discoveredMatches = new Set<string>();
277
+ for (const match of await globIf(dir, "*/SKILL.md", FileType.File)) {
278
+ discoveredMatches.add(match.path);
279
+ }
280
+ for (const match of await globIf(dir, "*", FileType.Dir, false)) {
281
+ const skillRelPath = `${match.path}/SKILL.md`;
282
+ const content = await readFile(path.join(dir, skillRelPath));
283
+ if (content !== null) {
284
+ discoveredMatches.add(skillRelPath);
285
+ }
286
+ }
287
+ const matches = [...discoveredMatches].map(path => ({ path }));
288
+ if (matches.length === 0) {
289
+ return { items, warnings };
290
+ }
291
+
292
+ // Read all skill files in parallel
293
+ const results = await Promise.all(
294
+ matches.map(async match => {
295
+ const skillFile = path.join(dir, match.path);
296
+ const content = await readFile(skillFile);
297
+ if (!content) {
298
+ return { item: null as Skill | null, warning: null as string | null };
299
+ }
300
+ const { frontmatter, body } = parseFrontmatter(content, { source: skillFile });
301
+ if (requireDescription && !frontmatter.description) {
302
+ return { item: null as Skill | null, warning: null as string | null };
303
+ }
304
+
305
+ // Extract skill name from path: "<skilldir>/SKILL.md" -> "<skilldir>"
306
+ const skillDirName = path.basename(path.dirname(skillFile));
307
+ return {
308
+ item: {
309
+ name: (frontmatter.name as string) || skillDirName,
310
+ path: skillFile,
311
+ content: body,
312
+ frontmatter: frontmatter as SkillFrontmatter,
313
+ level,
314
+ _source: createSourceMeta(providerId, skillFile, level),
315
+ },
316
+ warning: null as string | null,
317
+ };
318
+ }),
319
+ );
320
+ for (const result of results) {
321
+ if (result.warning) warnings.push(result.warning);
322
+ if (result.item) items.push(result.item);
323
+ }
324
+ return { items, warnings };
325
+ }
326
+
327
+ /**
328
+ * Expand environment variables in a string.
329
+ * Supports ${VAR} and ${VAR:-default} syntax.
330
+ */
331
+ export function expandEnvVars(value: string, extraEnv?: Record<string, string>): string {
332
+ return value.replace(/\$\{([^}:]+)(?::-([^}]*))?\}/g, (_, varName: string, defaultValue?: string) => {
333
+ const envValue = extraEnv?.[varName] ?? Bun.env[varName];
334
+ if (envValue !== undefined) return envValue;
335
+ if (defaultValue !== undefined) return defaultValue;
336
+ return `\${${varName}}`;
337
+ });
338
+ }
339
+
340
+ /**
341
+ * Recursively expand environment variables in an object.
342
+ */
343
+ export function expandEnvVarsDeep<T>(obj: T, extraEnv?: Record<string, string>): T {
344
+ if (typeof obj === "string") {
345
+ return expandEnvVars(obj, extraEnv) as T;
346
+ }
347
+ if (Array.isArray(obj)) {
348
+ return obj.map(item => expandEnvVarsDeep(item, extraEnv)) as T;
349
+ }
350
+ if (obj !== null && typeof obj === "object") {
351
+ const result: Record<string, unknown> = {};
352
+ for (const [key, value] of Object.entries(obj)) {
353
+ result[key] = expandEnvVarsDeep(value, extraEnv);
354
+ }
355
+ return result as T;
356
+ }
357
+ return obj;
358
+ }
359
+
360
+ /**
361
+ * Load files from a directory matching extensions.
362
+ * Uses native glob for fast filesystem scanning with gitignore support.
363
+ */
364
+ export async function loadFilesFromDir<T>(
365
+ _ctx: LoadContext,
366
+ dir: string,
367
+ provider: string,
368
+ level: "user" | "project",
369
+ options: {
370
+ /** File extensions to match (without dot) */
371
+ extensions?: string[];
372
+ /** Transform file to item (return null to skip) */
373
+ transform: (name: string, content: string, path: string, source: SourceMeta) => T | null;
374
+ /** Whether to recurse into subdirectories (default: false) */
375
+ recursive?: boolean;
376
+ /** Root directory for ignore file handling (unused, kept for API compat) */
377
+ rootDir?: string;
378
+ /** Ignore matcher (unused, kept for API compat) */
379
+ ignoreMatcher?: IgnoreMatcher;
380
+ },
381
+ ): Promise<LoadResult<T>> {
382
+ const items: T[] = [];
383
+ const warnings: string[] = [];
384
+ // Build glob pattern based on extensions and recursion
385
+ const { extensions, recursive = false } = options;
386
+
387
+ let pattern: string;
388
+ if (extensions && extensions.length > 0) {
389
+ const extPattern = extensions.length === 1 ? extensions[0] : `{${extensions.join(",")}}`;
390
+ pattern = recursive ? `**/*.${extPattern}` : `*.${extPattern}`;
391
+ } else {
392
+ pattern = recursive ? "**/*" : "*";
393
+ }
394
+
395
+ // Use native glob for fast scanning with gitignore support
396
+ let matches: Array<{ path: string }>;
397
+ try {
398
+ const result = await glob({
399
+ pattern,
400
+ path: dir,
401
+ gitignore: true,
402
+ hidden: false,
403
+ fileType: FileType.File,
404
+ });
405
+ matches = result.matches;
406
+ } catch {
407
+ // Directory doesn't exist or isn't readable
408
+ return { items, warnings };
409
+ }
410
+
411
+ // Read all matching files in parallel
412
+ const fileResults = await Promise.all(
413
+ matches.map(async match => {
414
+ const filePath = path.join(dir, match.path);
415
+ const content = await readFile(filePath);
416
+ return { filePath, content };
417
+ }),
418
+ );
419
+
420
+ for (const { filePath, content } of fileResults) {
421
+ if (content === null) {
422
+ warnings.push(`Failed to read file: ${filePath}`);
423
+ continue;
424
+ }
425
+
426
+ const name = path.basename(filePath);
427
+ const source = createSourceMeta(provider, filePath, level);
428
+
429
+ try {
430
+ const item = options.transform(name, content, filePath, source);
431
+ if (item !== null) {
432
+ items.push(item);
433
+ }
434
+ } catch (err) {
435
+ warnings.push(`Failed to parse ${filePath}: ${err}`);
436
+ }
437
+ }
438
+ return { items, warnings };
439
+ }
440
+
441
+ /**
442
+ * Parse JSON safely.
443
+ */
444
+ export function parseJSON<T>(content: string): T | null {
445
+ try {
446
+ return JSON.parse(content) as T;
447
+ } catch {
448
+ return null;
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Calculate depth of target directory relative to current working directory.
454
+ * Depth is the number of directory levels from cwd to target.
455
+ * - Positive depth: target is above cwd (parent/ancestor)
456
+ * - Zero depth: target is cwd
457
+ * - This uses path splitting to count directory levels
458
+ */
459
+ export function calculateDepth(cwd: string, targetDir: string, separator: string): number {
460
+ return cwd.split(separator).length - targetDir.split(separator).length;
461
+ }
462
+
463
+ interface ExtensionModuleManifest {
464
+ extensions?: string[];
465
+ }
466
+
467
+ async function readExtensionModuleManifest(
468
+ _ctx: LoadContext,
469
+ packageJsonPath: string,
470
+ ): Promise<ExtensionModuleManifest | null> {
471
+ const content = await readFile(packageJsonPath);
472
+ if (!content) return null;
473
+
474
+ const pkg = parseJSON<{ arcane?: ExtensionModuleManifest }>(content);
475
+ const manifest = pkg?.arcane;
476
+ if (manifest && typeof manifest === "object") {
477
+ return manifest;
478
+ }
479
+ return null;
480
+ }
481
+
482
+ /**
483
+ * Discover extension module entry points in a directory.
484
+ *
485
+ * Discovery rules:
486
+ * 1. Direct files: `extensions/*.ts` or `*.js` → load
487
+ * 2. Subdirectory with index: `extensions/<ext>/index.ts` or `index.js` → load
488
+ * 3. Subdirectory with package.json: `extensions/<ext>/package.json` with "arcane"/"pi" field → load declared paths
489
+ *
490
+ * No recursion beyond one level. Complex packages must use package.json manifest.
491
+ * Uses native glob for fast filesystem scanning with gitignore support.
492
+ */
493
+ export async function discoverExtensionModulePaths(_ctx: LoadContext, dir: string): Promise<string[]> {
494
+ const discovered = new Set<string>();
495
+ // Find all candidate files in parallel using glob
496
+ const [directFiles, indexFiles, packageJsonFiles] = await Promise.all([
497
+ // 1. Direct *.ts or *.js files
498
+ globIf(dir, "*.{ts,js}", FileType.File, false),
499
+ // 2. Subdirectory index files
500
+ globIf(dir, "*/index.{ts,js}", FileType.File),
501
+ // 3. Subdirectory package.json files
502
+ globIf(dir, "*/package.json", FileType.File),
503
+ ]);
504
+
505
+ // Process direct files
506
+ for (const match of directFiles) {
507
+ if (match.path.includes("/")) continue;
508
+ discovered.add(path.join(dir, match.path));
509
+ }
510
+ // Track which subdirectories have package.json manifests with declared extensions
511
+ const subdirsWithDeclaredExtensions = new Set<string>();
512
+ for (const match of packageJsonFiles) {
513
+ const subdir = path.dirname(match.path); // e.g., "my-extension"
514
+ const packageJsonPath = path.join(dir, match.path);
515
+ const manifest = await readExtensionModuleManifest(_ctx, packageJsonPath);
516
+ const declaredExtensions =
517
+ manifest?.extensions?.filter((extPath): extPath is string => typeof extPath === "string") ?? [];
518
+ if (declaredExtensions.length === 0) continue;
519
+ subdirsWithDeclaredExtensions.add(subdir);
520
+ const subdirPath = path.join(dir, subdir);
521
+ for (const extPath of declaredExtensions) {
522
+ const resolvedExtPath = path.resolve(subdirPath, extPath);
523
+ const content = await readFile(resolvedExtPath);
524
+ if (content !== null) {
525
+ discovered.add(resolvedExtPath);
526
+ }
527
+ }
528
+ }
529
+ const preferredIndexBySubdir = new Map<string, string>();
530
+ for (const match of indexFiles) {
531
+ if (match.path.split("/").length !== 2) continue;
532
+ const subdir = path.dirname(match.path);
533
+ if (subdirsWithDeclaredExtensions.has(subdir)) continue;
534
+ const existing = preferredIndexBySubdir.get(subdir);
535
+ if (!existing || (existing.endsWith("index.js") && match.path.endsWith("index.ts"))) {
536
+ preferredIndexBySubdir.set(subdir, match.path);
537
+ }
538
+ }
539
+ for (const preferredPath of preferredIndexBySubdir.values()) {
540
+ discovered.add(path.join(dir, preferredPath));
541
+ }
542
+ return [...discovered];
543
+ }
544
+
545
+ /**
546
+ * Derive a stable extension name from a path.
547
+ */
548
+ export function getExtensionNameFromPath(extensionPath: string): string {
549
+ const base = extensionPath.replace(/\\/g, "/").split("/").pop() ?? extensionPath;
550
+
551
+ if (base === "index.ts" || base === "index.js") {
552
+ const parts = extensionPath.replace(/\\/g, "/").split("/");
553
+ const parent = parts[parts.length - 2];
554
+ return parent ?? base;
555
+ }
556
+
557
+ const dot = base.lastIndexOf(".");
558
+ if (dot > 0) {
559
+ return base.slice(0, dot);
560
+ }
561
+
562
+ return base;
563
+ }
564
+
565
+ // =============================================================================
566
+ // Claude Code Plugin Cache Helpers
567
+ // =============================================================================
568
+
569
+ /**
570
+ * Entry for an installed Claude Code plugin.
571
+ */
572
+ export interface ClaudePluginEntry {
573
+ scope: "user" | "project";
574
+ installPath: string;
575
+ version: string;
576
+ installedAt: string;
577
+ lastUpdated: string;
578
+ gitCommitSha?: string;
579
+ }
580
+
581
+ /**
582
+ * Claude Code installed_plugins.json registry format.
583
+ */
584
+ export interface ClaudePluginsRegistry {
585
+ version: number;
586
+ plugins: Record<string, ClaudePluginEntry[]>;
587
+ }
588
+
589
+ /**
590
+ * Resolved plugin root for loading.
591
+ */
592
+ export interface ClaudePluginRoot {
593
+ /** Plugin ID (e.g., "simpleclaude-core@simpleclaude") */
594
+ id: string;
595
+ /** Marketplace name */
596
+ marketplace: string;
597
+ /** Plugin name */
598
+ plugin: string;
599
+ /** Version string */
600
+ version: string;
601
+ /** Absolute path to plugin root */
602
+ path: string;
603
+ /** Whether this is a user or project scope plugin */
604
+ scope: "user" | "project";
605
+ }
606
+
607
+ /**
608
+ * Parse Claude Code installed_plugins.json content.
609
+ */
610
+ export function parseClaudePluginsRegistry(content: string): ClaudePluginsRegistry | null {
611
+ const data = parseJSON<ClaudePluginsRegistry>(content);
612
+ if (!data || typeof data !== "object") return null;
613
+ if (
614
+ typeof data.version !== "number" ||
615
+ !data.plugins ||
616
+ typeof data.plugins !== "object" ||
617
+ Array.isArray(data.plugins)
618
+ )
619
+ return null;
620
+ return data;
621
+ }
622
+
623
+ /**
624
+ * List all installed Claude Code plugin roots from the plugin cache.
625
+ * Reads ~/.claude/plugins/installed_plugins.json and resolves plugin paths.
626
+ *
627
+ * Results are cached per home directory to avoid repeated parsing.
628
+ */
629
+ const pluginRootsCache = new Map<string, { roots: ClaudePluginRoot[]; warnings: string[] }>();
630
+
631
+ export async function listClaudePluginRoots(home: string): Promise<{ roots: ClaudePluginRoot[]; warnings: string[] }> {
632
+ const cached = pluginRootsCache.get(home);
633
+ if (cached) return cached;
634
+
635
+ const roots: ClaudePluginRoot[] = [];
636
+ const warnings: string[] = [];
637
+
638
+ const registryPath = path.join(home, ".claude", "plugins", "installed_plugins.json");
639
+ const content = await readFile(registryPath);
640
+
641
+ if (!content) {
642
+ // No registry file - not an error, just no plugins
643
+ const result = { roots, warnings };
644
+ pluginRootsCache.set(home, result);
645
+ return result;
646
+ }
647
+
648
+ const registry = parseClaudePluginsRegistry(content);
649
+ if (!registry) {
650
+ warnings.push(`Failed to parse Claude Code plugin registry: ${registryPath}`);
651
+ const result = { roots, warnings };
652
+ pluginRootsCache.set(home, result);
653
+ return result;
654
+ }
655
+
656
+ for (const [pluginId, entries] of Object.entries(registry.plugins)) {
657
+ if (!Array.isArray(entries) || entries.length === 0) continue;
658
+
659
+ // Parse plugin ID format: "plugin-name@marketplace"
660
+ const atIndex = pluginId.lastIndexOf("@");
661
+ if (atIndex === -1) {
662
+ warnings.push(`Invalid plugin ID format (missing @marketplace): ${pluginId}`);
663
+ continue;
664
+ }
665
+
666
+ const pluginName = pluginId.slice(0, atIndex);
667
+ const marketplace = pluginId.slice(atIndex + 1);
668
+
669
+ // Process all valid entries, not just the first one.
670
+ // This handles plugins with multiple installs (different scopes/versions).
671
+ for (const entry of entries) {
672
+ if (!entry.installPath || typeof entry.installPath !== "string") {
673
+ warnings.push(`Plugin ${pluginId} entry has no installPath`);
674
+ continue;
675
+ }
676
+
677
+ roots.push({
678
+ id: pluginId,
679
+ marketplace,
680
+ plugin: pluginName,
681
+ version: entry.version || "unknown",
682
+ path: entry.installPath,
683
+ scope: entry.scope || "user",
684
+ });
685
+ }
686
+ }
687
+
688
+ const result = { roots, warnings };
689
+ pluginRootsCache.set(home, result);
690
+ return result;
691
+ }
692
+
693
+ /**
694
+ * Clear the plugin roots cache (useful for testing or when plugins change).
695
+ */
696
+ export function clearClaudePluginRootsCache(): void {
697
+ pluginRootsCache.clear();
698
+ }