jonsoc 1.1.50 → 1.1.51

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 (420) hide show
  1. package/AGENTS.md +27 -0
  2. package/Dockerfile +18 -0
  3. package/PUBLISHING_GUIDE.md +151 -0
  4. package/README.md +58 -0
  5. package/bin/jonsoc +256 -256
  6. package/bunfig.toml +7 -0
  7. package/package.json +142 -8
  8. package/package.json.placeholder +11 -0
  9. package/parsers-config.ts +253 -0
  10. package/script/build.ts +115 -0
  11. package/script/publish-registries.ts +197 -0
  12. package/script/publish.ts +149 -0
  13. package/script/schema.ts +47 -0
  14. package/script/seed-e2e.ts +50 -0
  15. package/src/acp/README.md +164 -0
  16. package/src/acp/agent.ts +1437 -0
  17. package/src/acp/session.ts +105 -0
  18. package/src/acp/types.ts +22 -0
  19. package/src/agent/agent.ts +345 -0
  20. package/src/agent/generate.txt +75 -0
  21. package/src/agent/prompt/compaction.txt +12 -0
  22. package/src/agent/prompt/explore.txt +18 -0
  23. package/src/agent/prompt/summary.txt +11 -0
  24. package/src/agent/prompt/title.txt +44 -0
  25. package/src/auth/index.ts +73 -0
  26. package/src/brand/index.ts +89 -0
  27. package/src/bun/index.ts +139 -0
  28. package/src/bus/bus-event.ts +43 -0
  29. package/src/bus/global.ts +10 -0
  30. package/src/bus/index.ts +105 -0
  31. package/src/cli/bootstrap.ts +17 -0
  32. package/src/cli/cmd/acp.ts +69 -0
  33. package/src/cli/cmd/agent.ts +257 -0
  34. package/src/cli/cmd/auth.ts +405 -0
  35. package/src/cli/cmd/cmd.ts +7 -0
  36. package/src/cli/cmd/debug/agent.ts +166 -0
  37. package/src/cli/cmd/debug/config.ts +16 -0
  38. package/src/cli/cmd/debug/file.ts +97 -0
  39. package/src/cli/cmd/debug/index.ts +48 -0
  40. package/src/cli/cmd/debug/lsp.ts +52 -0
  41. package/src/cli/cmd/debug/ripgrep.ts +87 -0
  42. package/src/cli/cmd/debug/scrap.ts +16 -0
  43. package/src/cli/cmd/debug/skill.ts +16 -0
  44. package/src/cli/cmd/debug/snapshot.ts +52 -0
  45. package/src/cli/cmd/export.ts +88 -0
  46. package/src/cli/cmd/generate.ts +38 -0
  47. package/src/cli/cmd/github.ts +1547 -0
  48. package/src/cli/cmd/import.ts +99 -0
  49. package/src/cli/cmd/mcp.ts +765 -0
  50. package/src/cli/cmd/models.ts +77 -0
  51. package/src/cli/cmd/pr.ts +112 -0
  52. package/src/cli/cmd/run.ts +395 -0
  53. package/src/cli/cmd/serve.ts +20 -0
  54. package/src/cli/cmd/session.ts +135 -0
  55. package/src/cli/cmd/stats.ts +402 -0
  56. package/src/cli/cmd/tui/app.tsx +923 -0
  57. package/src/cli/cmd/tui/attach.ts +39 -0
  58. package/src/cli/cmd/tui/component/border.tsx +21 -0
  59. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  60. package/src/cli/cmd/tui/component/dialog-command.tsx +162 -0
  61. package/src/cli/cmd/tui/component/dialog-error-log.tsx +155 -0
  62. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  63. package/src/cli/cmd/tui/component/dialog-model.tsx +234 -0
  64. package/src/cli/cmd/tui/component/dialog-provider.tsx +256 -0
  65. package/src/cli/cmd/tui/component/dialog-session-list.tsx +114 -0
  66. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  67. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  68. package/src/cli/cmd/tui/component/dialog-status.tsx +164 -0
  69. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  70. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  71. package/src/cli/cmd/tui/component/dynamic-layout.tsx +86 -0
  72. package/src/cli/cmd/tui/component/inspector-overlay.tsx +247 -0
  73. package/src/cli/cmd/tui/component/logo.tsx +88 -0
  74. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +653 -0
  75. package/src/cli/cmd/tui/component/prompt/frecency.tsx +89 -0
  76. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  77. package/src/cli/cmd/tui/component/prompt/index.tsx +1347 -0
  78. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  79. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  80. package/src/cli/cmd/tui/component/tips.tsx +153 -0
  81. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  82. package/src/cli/cmd/tui/context/args.tsx +14 -0
  83. package/src/cli/cmd/tui/context/directory.ts +13 -0
  84. package/src/cli/cmd/tui/context/error-log.tsx +56 -0
  85. package/src/cli/cmd/tui/context/exit.tsx +26 -0
  86. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  87. package/src/cli/cmd/tui/context/inspector.tsx +57 -0
  88. package/src/cli/cmd/tui/context/keybind.tsx +108 -0
  89. package/src/cli/cmd/tui/context/kv.tsx +53 -0
  90. package/src/cli/cmd/tui/context/layout.tsx +240 -0
  91. package/src/cli/cmd/tui/context/local.tsx +402 -0
  92. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  93. package/src/cli/cmd/tui/context/route.tsx +51 -0
  94. package/src/cli/cmd/tui/context/sdk.tsx +94 -0
  95. package/src/cli/cmd/tui/context/sync.tsx +449 -0
  96. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  97. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  98. package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
  99. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  100. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  101. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  102. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  103. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  104. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  105. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  106. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  107. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  108. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  109. package/src/cli/cmd/tui/context/theme/jonsoc.json +245 -0
  110. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  111. package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
  112. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  113. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  114. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  115. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  116. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  117. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  118. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  119. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  120. package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
  121. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  122. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  123. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  124. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  125. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  126. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  127. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  128. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  129. package/src/cli/cmd/tui/context/theme.tsx +1152 -0
  130. package/src/cli/cmd/tui/event.ts +48 -0
  131. package/src/cli/cmd/tui/hooks/use-command-registry.tsx +184 -0
  132. package/src/cli/cmd/tui/routes/home.tsx +198 -0
  133. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
  134. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
  135. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  136. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  137. package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
  138. package/src/cli/cmd/tui/routes/session/git-commit.tsx +59 -0
  139. package/src/cli/cmd/tui/routes/session/git-history.tsx +122 -0
  140. package/src/cli/cmd/tui/routes/session/header.tsx +185 -0
  141. package/src/cli/cmd/tui/routes/session/index.tsx +2363 -0
  142. package/src/cli/cmd/tui/routes/session/navigator-ui.tsx +214 -0
  143. package/src/cli/cmd/tui/routes/session/navigator.tsx +1124 -0
  144. package/src/cli/cmd/tui/routes/session/panel-explorer.tsx +553 -0
  145. package/src/cli/cmd/tui/routes/session/panel-viewer.tsx +386 -0
  146. package/src/cli/cmd/tui/routes/session/permission.tsx +501 -0
  147. package/src/cli/cmd/tui/routes/session/question.tsx +507 -0
  148. package/src/cli/cmd/tui/routes/session/sidebar.tsx +365 -0
  149. package/src/cli/cmd/tui/routes/session/vcs-diff-viewer.tsx +37 -0
  150. package/src/cli/cmd/tui/routes/ui-settings.tsx +449 -0
  151. package/src/cli/cmd/tui/thread.ts +172 -0
  152. package/src/cli/cmd/tui/ui/dialog-alert.tsx +90 -0
  153. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
  154. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +204 -0
  155. package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
  156. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +77 -0
  157. package/src/cli/cmd/tui/ui/dialog-select.tsx +384 -0
  158. package/src/cli/cmd/tui/ui/dialog.tsx +170 -0
  159. package/src/cli/cmd/tui/ui/link.tsx +28 -0
  160. package/src/cli/cmd/tui/ui/spinner.ts +375 -0
  161. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  162. package/src/cli/cmd/tui/util/clipboard.ts +255 -0
  163. package/src/cli/cmd/tui/util/editor.ts +32 -0
  164. package/src/cli/cmd/tui/util/signal.ts +7 -0
  165. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  166. package/src/cli/cmd/tui/util/transcript.ts +98 -0
  167. package/src/cli/cmd/tui/worker.ts +152 -0
  168. package/src/cli/cmd/uninstall.ts +362 -0
  169. package/src/cli/cmd/upgrade.ts +73 -0
  170. package/src/cli/cmd/web.ts +81 -0
  171. package/src/cli/error.ts +57 -0
  172. package/src/cli/network.ts +53 -0
  173. package/src/cli/ui.ts +119 -0
  174. package/src/cli/upgrade.ts +25 -0
  175. package/src/command/index.ts +131 -0
  176. package/src/command/template/initialize.txt +10 -0
  177. package/src/command/template/review.txt +99 -0
  178. package/src/config/config.ts +1404 -0
  179. package/src/config/markdown.ts +93 -0
  180. package/src/env/index.ts +26 -0
  181. package/src/file/ignore.ts +83 -0
  182. package/src/file/index.ts +432 -0
  183. package/src/file/ripgrep.ts +407 -0
  184. package/src/file/time.ts +69 -0
  185. package/src/file/watcher.ts +127 -0
  186. package/src/flag/flag.ts +80 -0
  187. package/src/format/formatter.ts +357 -0
  188. package/src/format/index.ts +137 -0
  189. package/src/global/index.ts +58 -0
  190. package/src/id/id.ts +83 -0
  191. package/src/ide/index.ts +76 -0
  192. package/src/index.ts +208 -0
  193. package/src/installation/index.ts +258 -0
  194. package/src/lsp/client.ts +252 -0
  195. package/src/lsp/index.ts +485 -0
  196. package/src/lsp/language.ts +119 -0
  197. package/src/lsp/server.ts +2046 -0
  198. package/src/mcp/auth.ts +135 -0
  199. package/src/mcp/index.ts +934 -0
  200. package/src/mcp/oauth-callback.ts +200 -0
  201. package/src/mcp/oauth-provider.ts +155 -0
  202. package/src/patch/index.ts +680 -0
  203. package/src/permission/arity.ts +163 -0
  204. package/src/permission/index.ts +210 -0
  205. package/src/permission/next.ts +280 -0
  206. package/src/plugin/codex.ts +500 -0
  207. package/src/plugin/copilot.ts +283 -0
  208. package/src/plugin/index.ts +135 -0
  209. package/src/project/bootstrap.ts +35 -0
  210. package/src/project/instance.ts +91 -0
  211. package/src/project/project.ts +371 -0
  212. package/src/project/state.ts +66 -0
  213. package/src/project/vcs.ts +151 -0
  214. package/src/provider/auth.ts +147 -0
  215. package/src/provider/models-macro.ts +14 -0
  216. package/src/provider/models.ts +114 -0
  217. package/src/provider/provider.ts +1220 -0
  218. package/src/provider/sdk/openai-compatible/src/README.md +5 -0
  219. package/src/provider/sdk/openai-compatible/src/index.ts +2 -0
  220. package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +100 -0
  221. package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +303 -0
  222. package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +22 -0
  223. package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +18 -0
  224. package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +22 -0
  225. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +207 -0
  226. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +1732 -0
  227. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +177 -0
  228. package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +1 -0
  229. package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +88 -0
  230. package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +128 -0
  231. package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +115 -0
  232. package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +65 -0
  233. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +104 -0
  234. package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +103 -0
  235. package/src/provider/transform.ts +742 -0
  236. package/src/pty/index.ts +241 -0
  237. package/src/question/index.ts +176 -0
  238. package/src/scheduler/index.ts +61 -0
  239. package/src/server/error.ts +36 -0
  240. package/src/server/event.ts +7 -0
  241. package/src/server/mdns.ts +59 -0
  242. package/src/server/routes/config.ts +92 -0
  243. package/src/server/routes/experimental.ts +208 -0
  244. package/src/server/routes/file.ts +227 -0
  245. package/src/server/routes/global.ts +135 -0
  246. package/src/server/routes/mcp.ts +225 -0
  247. package/src/server/routes/permission.ts +68 -0
  248. package/src/server/routes/project.ts +82 -0
  249. package/src/server/routes/provider.ts +165 -0
  250. package/src/server/routes/pty.ts +169 -0
  251. package/src/server/routes/question.ts +98 -0
  252. package/src/server/routes/session.ts +939 -0
  253. package/src/server/routes/tui.ts +379 -0
  254. package/src/server/server.ts +663 -0
  255. package/src/session/compaction.ts +225 -0
  256. package/src/session/index.ts +498 -0
  257. package/src/session/llm.ts +288 -0
  258. package/src/session/message-v2.ts +740 -0
  259. package/src/session/message.ts +189 -0
  260. package/src/session/processor.ts +406 -0
  261. package/src/session/prompt/anthropic-20250930.txt +168 -0
  262. package/src/session/prompt/anthropic.txt +172 -0
  263. package/src/session/prompt/anthropic_spoof.txt +1 -0
  264. package/src/session/prompt/beast.txt +149 -0
  265. package/src/session/prompt/build-switch.txt +5 -0
  266. package/src/session/prompt/codex_header.txt +81 -0
  267. package/src/session/prompt/copilot-gpt-5.txt +145 -0
  268. package/src/session/prompt/gemini.txt +157 -0
  269. package/src/session/prompt/max-steps.txt +16 -0
  270. package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
  271. package/src/session/prompt/plan.txt +26 -0
  272. package/src/session/prompt/qwen.txt +111 -0
  273. package/src/session/prompt.ts +1815 -0
  274. package/src/session/retry.ts +90 -0
  275. package/src/session/revert.ts +121 -0
  276. package/src/session/status.ts +76 -0
  277. package/src/session/summary.ts +150 -0
  278. package/src/session/system.ts +156 -0
  279. package/src/session/todo.ts +37 -0
  280. package/src/share/share-next.ts +205 -0
  281. package/src/share/share.ts +95 -0
  282. package/src/shell/shell.ts +67 -0
  283. package/src/skill/index.ts +1 -0
  284. package/src/skill/skill.ts +135 -0
  285. package/src/snapshot/index.ts +236 -0
  286. package/src/storage/storage.ts +227 -0
  287. package/src/tool/apply_patch.ts +279 -0
  288. package/src/tool/apply_patch.txt +33 -0
  289. package/src/tool/bash.ts +258 -0
  290. package/src/tool/bash.txt +115 -0
  291. package/src/tool/batch.ts +175 -0
  292. package/src/tool/batch.txt +24 -0
  293. package/src/tool/codesearch.ts +132 -0
  294. package/src/tool/codesearch.txt +12 -0
  295. package/src/tool/edit.ts +645 -0
  296. package/src/tool/edit.txt +10 -0
  297. package/src/tool/external-directory.ts +32 -0
  298. package/src/tool/glob.ts +77 -0
  299. package/src/tool/glob.txt +6 -0
  300. package/src/tool/grep.ts +154 -0
  301. package/src/tool/grep.txt +8 -0
  302. package/src/tool/invalid.ts +17 -0
  303. package/src/tool/ls.ts +121 -0
  304. package/src/tool/ls.txt +1 -0
  305. package/src/tool/lsp.ts +96 -0
  306. package/src/tool/lsp.txt +19 -0
  307. package/src/tool/multiedit.ts +46 -0
  308. package/src/tool/multiedit.txt +41 -0
  309. package/src/tool/plan-enter.txt +14 -0
  310. package/src/tool/plan-exit.txt +13 -0
  311. package/src/tool/plan.ts +130 -0
  312. package/src/tool/question.ts +33 -0
  313. package/src/tool/question.txt +10 -0
  314. package/src/tool/read.ts +202 -0
  315. package/src/tool/read.txt +12 -0
  316. package/src/tool/registry.ts +162 -0
  317. package/src/tool/skill.ts +82 -0
  318. package/src/tool/task.ts +188 -0
  319. package/src/tool/task.txt +60 -0
  320. package/src/tool/todo.ts +53 -0
  321. package/src/tool/todoread.txt +14 -0
  322. package/src/tool/todowrite.txt +167 -0
  323. package/src/tool/tool.ts +88 -0
  324. package/src/tool/truncation.ts +106 -0
  325. package/src/tool/webfetch.ts +182 -0
  326. package/src/tool/webfetch.txt +13 -0
  327. package/src/tool/websearch.ts +150 -0
  328. package/src/tool/websearch.txt +14 -0
  329. package/src/tool/write.ts +80 -0
  330. package/src/tool/write.txt +8 -0
  331. package/src/util/archive.ts +16 -0
  332. package/src/util/color.ts +19 -0
  333. package/src/util/context.ts +25 -0
  334. package/src/util/defer.ts +12 -0
  335. package/src/util/eventloop.ts +20 -0
  336. package/src/util/filesystem.ts +93 -0
  337. package/src/util/fn.ts +11 -0
  338. package/src/util/format.ts +20 -0
  339. package/src/util/iife.ts +3 -0
  340. package/src/util/keybind.ts +103 -0
  341. package/src/util/lazy.ts +18 -0
  342. package/src/util/locale.ts +81 -0
  343. package/src/util/lock.ts +98 -0
  344. package/src/util/log.ts +180 -0
  345. package/src/util/queue.ts +32 -0
  346. package/src/util/rpc.ts +66 -0
  347. package/src/util/scrap.ts +10 -0
  348. package/src/util/signal.ts +12 -0
  349. package/src/util/timeout.ts +14 -0
  350. package/src/util/token.ts +7 -0
  351. package/src/util/wildcard.ts +56 -0
  352. package/src/worktree/index.ts +524 -0
  353. package/sst-env.d.ts +9 -0
  354. package/test/acp/agent-interface.test.ts +51 -0
  355. package/test/acp/event-subscription.test.ts +436 -0
  356. package/test/agent/agent.test.ts +638 -0
  357. package/test/bun.test.ts +53 -0
  358. package/test/cli/cmd/tui/fileref.test.ts +30 -0
  359. package/test/cli/github-action.test.ts +129 -0
  360. package/test/cli/github-remote.test.ts +80 -0
  361. package/test/cli/tui/navigator_logic.test.ts +99 -0
  362. package/test/cli/tui/transcript.test.ts +297 -0
  363. package/test/cli/ui.test.ts +80 -0
  364. package/test/config/agent-color.test.ts +66 -0
  365. package/test/config/config.test.ts +1613 -0
  366. package/test/config/fixtures/empty-frontmatter.md +4 -0
  367. package/test/config/fixtures/frontmatter.md +28 -0
  368. package/test/config/fixtures/no-frontmatter.md +1 -0
  369. package/test/config/markdown.test.ts +192 -0
  370. package/test/file/ignore.test.ts +10 -0
  371. package/test/file/path-traversal.test.ts +198 -0
  372. package/test/fixture/fixture.ts +45 -0
  373. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  374. package/test/ide/ide.test.ts +82 -0
  375. package/test/keybind.test.ts +421 -0
  376. package/test/lsp/client.test.ts +95 -0
  377. package/test/mcp/headers.test.ts +153 -0
  378. package/test/mcp/oauth-browser.test.ts +261 -0
  379. package/test/patch/patch.test.ts +348 -0
  380. package/test/permission/arity.test.ts +33 -0
  381. package/test/permission/next.test.ts +690 -0
  382. package/test/permission-task.test.ts +319 -0
  383. package/test/plugin/codex.test.ts +123 -0
  384. package/test/preload.ts +67 -0
  385. package/test/project/project.test.ts +120 -0
  386. package/test/provider/amazon-bedrock.test.ts +268 -0
  387. package/test/provider/gitlab-duo.test.ts +286 -0
  388. package/test/provider/provider.test.ts +2149 -0
  389. package/test/provider/transform.test.ts +1631 -0
  390. package/test/question/question.test.ts +300 -0
  391. package/test/scheduler.test.ts +73 -0
  392. package/test/server/session-list.test.ts +39 -0
  393. package/test/server/session-select.test.ts +78 -0
  394. package/test/session/compaction.test.ts +293 -0
  395. package/test/session/llm.test.ts +90 -0
  396. package/test/session/message-v2.test.ts +786 -0
  397. package/test/session/retry.test.ts +131 -0
  398. package/test/session/revert-compact.test.ts +285 -0
  399. package/test/session/session.test.ts +71 -0
  400. package/test/skill/skill.test.ts +185 -0
  401. package/test/snapshot/snapshot.test.ts +939 -0
  402. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  403. package/test/tool/apply_patch.test.ts +499 -0
  404. package/test/tool/bash.test.ts +320 -0
  405. package/test/tool/external-directory.test.ts +126 -0
  406. package/test/tool/fixtures/large-image.png +0 -0
  407. package/test/tool/fixtures/models-api.json +33453 -0
  408. package/test/tool/grep.test.ts +109 -0
  409. package/test/tool/question.test.ts +105 -0
  410. package/test/tool/read.test.ts +332 -0
  411. package/test/tool/registry.test.ts +76 -0
  412. package/test/tool/truncation.test.ts +159 -0
  413. package/test/util/filesystem.test.ts +39 -0
  414. package/test/util/format.test.ts +59 -0
  415. package/test/util/iife.test.ts +36 -0
  416. package/test/util/lazy.test.ts +50 -0
  417. package/test/util/lock.test.ts +72 -0
  418. package/test/util/timeout.test.ts +21 -0
  419. package/test/util/wildcard.test.ts +75 -0
  420. package/tsconfig.json +16 -0
@@ -0,0 +1,73 @@
1
+ import path from "path"
2
+ import { Global } from "../global"
3
+ import fs from "fs/promises"
4
+ import z from "zod"
5
+
6
+ export const OAUTH_DUMMY_KEY = "jonsoc-oauth-dummy-key"
7
+
8
+ export namespace Auth {
9
+ export const Oauth = z
10
+ .object({
11
+ type: z.literal("oauth"),
12
+ refresh: z.string(),
13
+ access: z.string(),
14
+ expires: z.number(),
15
+ accountId: z.string().optional(),
16
+ enterpriseUrl: z.string().optional(),
17
+ })
18
+ .meta({ ref: "OAuth" })
19
+
20
+ export const Api = z
21
+ .object({
22
+ type: z.literal("api"),
23
+ key: z.string(),
24
+ })
25
+ .meta({ ref: "ApiAuth" })
26
+
27
+ export const WellKnown = z
28
+ .object({
29
+ type: z.literal("wellknown"),
30
+ key: z.string(),
31
+ token: z.string(),
32
+ })
33
+ .meta({ ref: "WellKnownAuth" })
34
+
35
+ export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).meta({ ref: "Auth" })
36
+ export type Info = z.infer<typeof Info>
37
+
38
+ const filepath = path.join(Global.Path.data, "auth.json")
39
+
40
+ export async function get(providerID: string) {
41
+ const auth = await all()
42
+ return auth[providerID]
43
+ }
44
+
45
+ export async function all(): Promise<Record<string, Info>> {
46
+ const file = Bun.file(filepath)
47
+ const data = await file.json().catch(() => ({}) as Record<string, unknown>)
48
+ return Object.entries(data).reduce(
49
+ (acc, [key, value]) => {
50
+ const parsed = Info.safeParse(value)
51
+ if (!parsed.success) return acc
52
+ acc[key] = parsed.data
53
+ return acc
54
+ },
55
+ {} as Record<string, Info>,
56
+ )
57
+ }
58
+
59
+ export async function set(key: string, info: Info) {
60
+ const file = Bun.file(filepath)
61
+ const data = await all()
62
+ await Bun.write(file, JSON.stringify({ ...data, [key]: info }, null, 2))
63
+ await fs.chmod(file.name!, 0o600)
64
+ }
65
+
66
+ export async function remove(key: string) {
67
+ const file = Bun.file(filepath)
68
+ const data = await all()
69
+ delete data[key]
70
+ await Bun.write(file, JSON.stringify(data, null, 2))
71
+ await fs.chmod(file.name!, 0o600)
72
+ }
73
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Brand configuration for JonsOC
3
+ *
4
+ * JonsOC is an open-source fork of OpenCode (https://opencode.ai)
5
+ * This namespace defines all branding constants and URLs.
6
+ *
7
+ * The code supports both JONSOC_* and OPENCODE_* environment variable prefixes
8
+ * to maintain backward compatibility with the original project.
9
+ *
10
+ * 💐 Built with gratitude for the OpenCode team and community
11
+ */
12
+ export namespace Brand {
13
+ export const BRAND_NAME = process.env.JONSOC_BRAND ?? process.env.OPENCODE_BRAND ?? "jonsoc"
14
+
15
+ /** Reference to the original upstream project */
16
+ export const UPSTREAM_NAME = "OpenCode"
17
+ export const UPSTREAM_URL = "https://opencode.ai"
18
+ export const UPSTREAM_REPO = "https://github.com/opencode-ai/opencode"
19
+
20
+ export const BRAND_LOWER = BRAND_NAME.toLowerCase()
21
+
22
+ export const CLI_NAME = process.env.JONSOC_CLI_NAME ?? process.env.OPENCODE_CLI_NAME ?? BRAND_LOWER
23
+
24
+ export const DOMAIN = process.env.JONSOC_DOMAIN ?? process.env.OPENCODE_DOMAIN ?? `${BRAND_LOWER}.com`
25
+
26
+ export const DOMAIN_WITH_PROTOCOL = `https://${DOMAIN}`
27
+
28
+ export const API_DOMAIN = process.env.JONSOC_API_DOMAIN ?? process.env.OPENCODE_API_DOMAIN ?? `api.${DOMAIN}`
29
+
30
+ export const API_URL = `https://${API_DOMAIN}`
31
+
32
+ export const DOCS_DOMAIN = process.env.JONSOC_DOCS_DOMAIN ?? process.env.OPENCODE_DOCS_DOMAIN ?? `docs.${DOMAIN}`
33
+
34
+ export const DOCS_URL = `https://${DOCS_DOMAIN}`
35
+
36
+ // MODELS_URL defaults to opencode.ai's models.dev infrastructure
37
+ // This is intentionally NOT customizable by default because:
38
+ // 1. Models like minimax/m2.1 are hosted by opencode.ai
39
+ // 2. Forks typically want their own branding but still use opencode.ai's model infrastructure
40
+ // 3. To use your own models, you must explicitly set OPENCODE_MODELS_URL
41
+ export const MODELS_URL = process.env.OPENCODE_MODELS_URL ?? "https://models.dev"
42
+
43
+ export const INSTALL_URL =
44
+ process.env.JONSOC_INSTALL_URL ?? process.env.OPENCODE_INSTALL_URL ?? `${DOMAIN_WITH_PROTOCOL}/install`
45
+
46
+ export const CONFIG_SCHEMA_URL =
47
+ process.env.JONSOC_CONFIG_SCHEMA ?? process.env.OPENCODE_CONFIG_SCHEMA ?? `${DOMAIN_WITH_PROTOCOL}/config.json`
48
+
49
+ export const WELL_KNOWN_PATH = `/.well-known/${BRAND_LOWER}`
50
+
51
+ export const LEGACY_WELL_KNOWN_PATH = "/.well-known/jonsoc"
52
+
53
+ export const CONFIG_DIR = `.${BRAND_LOWER}`
54
+
55
+ export const LEGACY_CONFIG_DIR = ".jonsoc"
56
+
57
+ export const ALLOW_LEGACY_OPENCODE_CONFIGS = true
58
+
59
+ export const CONFIG_FILES: string[] = (() => {
60
+ const files = [`${BRAND_LOWER}.jsonc`, `${BRAND_LOWER}.json`]
61
+ if (ALLOW_LEGACY_OPENCODE_CONFIGS) {
62
+ files.push("jonsoc.jsonc", "jonsoc.json")
63
+ }
64
+ return files
65
+ })()
66
+
67
+ export const APP_NAME = process.env.JONSOC_APP_NAME ?? process.env.OPENCODE_APP_NAME ?? BRAND_LOWER
68
+
69
+ export const REPO = process.env.JONSOC_REPO ?? process.env.OPENCODE_REPO ?? `Noisemaker111/Jonsoc`
70
+
71
+ export const NPM_PACKAGE = process.env.JONSOC_NPM_PACKAGE ?? process.env.OPENCODE_NPM_PACKAGE ?? "jonsoc"
72
+
73
+ export const LEGACY_NPM_PACKAGE = "jonsoc"
74
+
75
+ export const LEGACY_CLI_NAME = "jonsoc"
76
+
77
+ export const HOMEBREW_TAP =
78
+ process.env.JONSOC_HOMEBREW_TAP ?? process.env.OPENCODE_HOMEBREW_TAP ?? "Noisemaker111/homebrew-tap"
79
+
80
+ export const USER_AGENT = `${CLI_NAME}/cli/local/local/cli`
81
+
82
+ export const CONFIG_TARGETS: string[] = (() => {
83
+ const targets = [`.${BRAND_LOWER}`]
84
+ if (ALLOW_LEGACY_OPENCODE_CONFIGS) {
85
+ targets.unshift(".jonsoc")
86
+ }
87
+ return targets
88
+ })()
89
+ }
@@ -0,0 +1,139 @@
1
+ import z from "zod"
2
+ import { Global } from "../global"
3
+ import { Log } from "../util/log"
4
+ import path from "path"
5
+ import { Filesystem } from "../util/filesystem"
6
+ import { NamedError } from "@jonsoc/util/error"
7
+ import { readableStreamToText } from "bun"
8
+ import { createRequire } from "module"
9
+ import { Lock } from "../util/lock"
10
+
11
+ export namespace BunProc {
12
+ const log = Log.create({ service: "bun" })
13
+ const req = createRequire(import.meta.url)
14
+
15
+ export async function run(cmd: string[], options?: Bun.SpawnOptions.OptionsObject<any, any, any>) {
16
+ log.info("running", {
17
+ cmd: [which(), ...cmd],
18
+ ...options,
19
+ })
20
+ const result = Bun.spawn([which(), ...cmd], {
21
+ ...options,
22
+ stdout: "pipe",
23
+ stderr: "pipe",
24
+ env: {
25
+ ...process.env,
26
+ ...options?.env,
27
+ BUN_BE_BUN: "1",
28
+ },
29
+ })
30
+ const code = await result.exited
31
+ const stdout = result.stdout
32
+ ? typeof result.stdout === "number"
33
+ ? result.stdout
34
+ : await readableStreamToText(result.stdout)
35
+ : undefined
36
+ const stderr = result.stderr
37
+ ? typeof result.stderr === "number"
38
+ ? result.stderr
39
+ : await readableStreamToText(result.stderr)
40
+ : undefined
41
+ log.info("done", {
42
+ code,
43
+ stdout,
44
+ stderr,
45
+ })
46
+ if (code !== 0) {
47
+ log.error("Command failed", {
48
+ code,
49
+ stdout,
50
+ stderr,
51
+ })
52
+ throw new Error(`Command failed with exit code ${result.exitCode}: ${stderr}`)
53
+ }
54
+ return result
55
+ }
56
+
57
+ export function which() {
58
+ return process.execPath
59
+ }
60
+
61
+ export const InstallFailedError = NamedError.create(
62
+ "BunInstallFailedError",
63
+ z.object({
64
+ pkg: z.string(),
65
+ version: z.string(),
66
+ }),
67
+ )
68
+
69
+ export async function install(pkg: string, version = "latest") {
70
+ // Use lock to ensure only one install at a time
71
+ using _ = await Lock.write("bun-install")
72
+
73
+ const mod = path.join(Global.Path.cache, "node_modules", pkg)
74
+ const pkgjson = Bun.file(path.join(Global.Path.cache, "package.json"))
75
+ const parsed = await pkgjson.json().catch(async () => {
76
+ const result = { dependencies: {} }
77
+ await Bun.write(pkgjson.name!, JSON.stringify(result, null, 2))
78
+ return result
79
+ })
80
+ const dependencies = parsed.dependencies ?? {}
81
+ if (!parsed.dependencies) parsed.dependencies = dependencies
82
+ const modExists = await Filesystem.exists(mod)
83
+ if (dependencies[pkg] === version && modExists) return mod
84
+
85
+ const proxied = !!(
86
+ process.env.HTTP_PROXY ||
87
+ process.env.HTTPS_PROXY ||
88
+ process.env.http_proxy ||
89
+ process.env.https_proxy
90
+ )
91
+
92
+ // Build command arguments
93
+ const args = [
94
+ "add",
95
+ "--force",
96
+ "--exact",
97
+ // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936)
98
+ ...(proxied ? ["--no-cache"] : []),
99
+ "--cwd",
100
+ Global.Path.cache,
101
+ pkg + "@" + version,
102
+ ]
103
+
104
+ // Let Bun handle registry resolution:
105
+ // - If .npmrc files exist, Bun will use them automatically
106
+ // - If no .npmrc files exist, Bun will default to https://registry.npmjs.org
107
+ // - No need to pass --registry flag
108
+ log.info("installing package using Bun's default registry resolution", {
109
+ pkg,
110
+ version,
111
+ })
112
+
113
+ await BunProc.run(args, {
114
+ cwd: Global.Path.cache,
115
+ }).catch((e) => {
116
+ throw new InstallFailedError(
117
+ { pkg, version },
118
+ {
119
+ cause: e,
120
+ },
121
+ )
122
+ })
123
+
124
+ // Resolve actual version from installed package when using "latest"
125
+ // This ensures subsequent starts use the cached version until explicitly updated
126
+ let resolvedVersion = version
127
+ if (version === "latest") {
128
+ const installedPkgJson = Bun.file(path.join(mod, "package.json"))
129
+ const installedPkg = await installedPkgJson.json().catch(() => null)
130
+ if (installedPkg?.version) {
131
+ resolvedVersion = installedPkg.version
132
+ }
133
+ }
134
+
135
+ parsed.dependencies[pkg] = resolvedVersion
136
+ await Bun.write(pkgjson.name!, JSON.stringify(parsed, null, 2))
137
+ return mod
138
+ }
139
+ }
@@ -0,0 +1,43 @@
1
+ import z from "zod"
2
+ import type { ZodType } from "zod"
3
+ import { Log } from "../util/log"
4
+
5
+ export namespace BusEvent {
6
+ const log = Log.create({ service: "event" })
7
+
8
+ export type Definition = ReturnType<typeof define>
9
+
10
+ const registry = new Map<string, Definition>()
11
+
12
+ export function define<Type extends string, Properties extends ZodType>(type: Type, properties: Properties) {
13
+ const result = {
14
+ type,
15
+ properties,
16
+ }
17
+ registry.set(type, result)
18
+ return result
19
+ }
20
+
21
+ export function payloads() {
22
+ return z
23
+ .discriminatedUnion(
24
+ "type",
25
+ registry
26
+ .entries()
27
+ .map(([type, def]) => {
28
+ return z
29
+ .object({
30
+ type: z.literal(type),
31
+ properties: def.properties,
32
+ })
33
+ .meta({
34
+ ref: "Event" + "." + def.type,
35
+ })
36
+ })
37
+ .toArray() as any,
38
+ )
39
+ .meta({
40
+ ref: "Event",
41
+ })
42
+ }
43
+ }
@@ -0,0 +1,10 @@
1
+ import { EventEmitter } from "events"
2
+
3
+ export const GlobalBus = new EventEmitter<{
4
+ event: [
5
+ {
6
+ directory?: string
7
+ payload: any
8
+ },
9
+ ]
10
+ }>()
@@ -0,0 +1,105 @@
1
+ import z from "zod"
2
+ import { Log } from "../util/log"
3
+ import { Instance } from "../project/instance"
4
+ import { BusEvent } from "./bus-event"
5
+ import { GlobalBus } from "./global"
6
+
7
+ export namespace Bus {
8
+ const log = Log.create({ service: "bus" })
9
+ type Subscription = (event: any) => void
10
+
11
+ export const InstanceDisposed = BusEvent.define(
12
+ "server.instance.disposed",
13
+ z.object({
14
+ directory: z.string(),
15
+ }),
16
+ )
17
+
18
+ const state = Instance.state(
19
+ () => {
20
+ const subscriptions = new Map<any, Subscription[]>()
21
+
22
+ return {
23
+ subscriptions,
24
+ }
25
+ },
26
+ async (entry) => {
27
+ const wildcard = entry.subscriptions.get("*")
28
+ if (!wildcard) return
29
+ const event = {
30
+ type: InstanceDisposed.type,
31
+ properties: {
32
+ directory: Instance.directory,
33
+ },
34
+ }
35
+ for (const sub of [...wildcard]) {
36
+ sub(event)
37
+ }
38
+ },
39
+ )
40
+
41
+ export async function publish<Definition extends BusEvent.Definition>(
42
+ def: Definition,
43
+ properties: z.output<Definition["properties"]>,
44
+ ) {
45
+ const payload = {
46
+ type: def.type,
47
+ properties,
48
+ }
49
+ log.info("publishing", {
50
+ type: def.type,
51
+ })
52
+ const pending = []
53
+ for (const key of [def.type, "*"]) {
54
+ const match = state().subscriptions.get(key)
55
+ for (const sub of match ?? []) {
56
+ pending.push(sub(payload))
57
+ }
58
+ }
59
+ GlobalBus.emit("event", {
60
+ directory: Instance.directory,
61
+ payload,
62
+ })
63
+ return Promise.all(pending)
64
+ }
65
+
66
+ export function subscribe<Definition extends BusEvent.Definition>(
67
+ def: Definition,
68
+ callback: (event: { type: Definition["type"]; properties: z.infer<Definition["properties"]> }) => void,
69
+ ) {
70
+ return raw(def.type, callback)
71
+ }
72
+
73
+ export function once<Definition extends BusEvent.Definition>(
74
+ def: Definition,
75
+ callback: (event: {
76
+ type: Definition["type"]
77
+ properties: z.infer<Definition["properties"]>
78
+ }) => "done" | undefined,
79
+ ) {
80
+ const unsub = subscribe(def, (event) => {
81
+ if (callback(event)) unsub()
82
+ })
83
+ }
84
+
85
+ export function subscribeAll(callback: (event: any) => void) {
86
+ return raw("*", callback)
87
+ }
88
+
89
+ function raw(type: string, callback: (event: any) => void) {
90
+ log.info("subscribing", { type })
91
+ const subscriptions = state().subscriptions
92
+ let match = subscriptions.get(type) ?? []
93
+ match.push(callback)
94
+ subscriptions.set(type, match)
95
+
96
+ return () => {
97
+ log.info("unsubscribing", { type })
98
+ const match = subscriptions.get(type)
99
+ if (!match) return
100
+ const index = match.indexOf(callback)
101
+ if (index === -1) return
102
+ match.splice(index, 1)
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,17 @@
1
+ import { InstanceBootstrap } from "../project/bootstrap"
2
+ import { Instance } from "../project/instance"
3
+
4
+ export async function bootstrap<T>(directory: string, cb: () => Promise<T>) {
5
+ return Instance.provide({
6
+ directory,
7
+ init: InstanceBootstrap,
8
+ fn: async () => {
9
+ try {
10
+ const result = await cb()
11
+ return result
12
+ } finally {
13
+ await Instance.dispose()
14
+ }
15
+ },
16
+ })
17
+ }
@@ -0,0 +1,69 @@
1
+ import { Log } from "@/util/log"
2
+ import { bootstrap } from "../bootstrap"
3
+ import { cmd } from "./cmd"
4
+ import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
5
+ import { ACP } from "@/acp/agent"
6
+ import { Server } from "@/server/server"
7
+ import { createOpencodeClient } from "@jonsoc/sdk/v2"
8
+ import { withNetworkOptions, resolveNetworkOptions } from "../network"
9
+
10
+ const log = Log.create({ service: "acp-command" })
11
+
12
+ export const AcpCommand = cmd({
13
+ command: "acp",
14
+ describe: "start ACP (Agent Client Protocol) server",
15
+ builder: (yargs) => {
16
+ return withNetworkOptions(yargs).option("cwd", {
17
+ describe: "working directory",
18
+ type: "string",
19
+ default: process.cwd(),
20
+ })
21
+ },
22
+ handler: async (args) => {
23
+ await bootstrap(process.cwd(), async () => {
24
+ const opts = await resolveNetworkOptions(args)
25
+ const server = Server.listen(opts)
26
+
27
+ const sdk = createOpencodeClient({
28
+ baseUrl: `http://${server.hostname}:${server.port}`,
29
+ })
30
+
31
+ const input = new WritableStream<Uint8Array>({
32
+ write(chunk) {
33
+ return new Promise<void>((resolve, reject) => {
34
+ process.stdout.write(chunk, (err) => {
35
+ if (err) {
36
+ reject(err)
37
+ } else {
38
+ resolve()
39
+ }
40
+ })
41
+ })
42
+ },
43
+ })
44
+ const output = new ReadableStream<Uint8Array>({
45
+ start(controller) {
46
+ process.stdin.on("data", (chunk: Buffer) => {
47
+ controller.enqueue(new Uint8Array(chunk))
48
+ })
49
+ process.stdin.on("end", () => controller.close())
50
+ process.stdin.on("error", (err) => controller.error(err))
51
+ },
52
+ })
53
+
54
+ const stream = ndJsonStream(input, output)
55
+ const agent = await ACP.init({ sdk })
56
+
57
+ new AgentSideConnection((conn) => {
58
+ return agent.create(conn, { sdk })
59
+ }, stream)
60
+
61
+ log.info("setup connection")
62
+ process.stdin.resume()
63
+ await new Promise((resolve, reject) => {
64
+ process.stdin.on("end", resolve)
65
+ process.stdin.on("error", reject)
66
+ })
67
+ })
68
+ },
69
+ })