@aiworker/web 1.22.0 → 1.22.2

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 (354) hide show
  1. package/README.md +4 -4
  2. package/bin/cli.js +7 -4
  3. package/bin/cli.test.js +165 -73
  4. package/bin/lib/cli-api-target.js +2 -2
  5. package/bin/lib/cli-args.js +119 -119
  6. package/bin/lib/cli-lifecycle.js +9 -9
  7. package/bin/lib/cli-network.js +3 -3
  8. package/bin/lib/cli-paths.js +3 -3
  9. package/bin/lib/cli-ports.js +2 -2
  10. package/bin/lib/cli-process.js +4 -4
  11. package/bin/lib/cli-startup.js +64 -15
  12. package/bin/lib/cli-tunnel-profiles.js +1 -1
  13. package/bin/lib/cli-tunnel-utils.js +2 -2
  14. package/bin/lib/commands-connect-url.js +19 -19
  15. package/bin/lib/commands-lifecycle.js +27 -27
  16. package/bin/lib/commands-logs.js +5 -5
  17. package/bin/lib/commands-models.js +1 -1
  18. package/bin/lib/commands-projects.js +1 -1
  19. package/bin/lib/commands-schedule.js +1 -1
  20. package/bin/lib/commands-serve.js +29 -29
  21. package/bin/lib/commands-session.js +1 -1
  22. package/bin/lib/commands-startup.js +45 -10
  23. package/bin/lib/commands-status.js +1 -1
  24. package/bin/lib/commands-tunnel.js +40 -40
  25. package/bin/lib/commands-update.js +1 -1
  26. package/bin/lib/commands-update.test.js +6 -6
  27. package/dist/assets/{CodeMirrorCommentWidgets-B3u7UIcE.js → CodeMirrorCommentWidgets-CSICpWQD.js} +1 -1
  28. package/dist/assets/{DiffView-DluiRSla.js → DiffView-hDBKesA_.js} +3 -3
  29. package/dist/assets/DirtyBranchSwitchDialog-C22HdWj4.js +1 -0
  30. package/dist/assets/FilesView-CdWzeOp9.js +17 -0
  31. package/dist/assets/GitView-VQQkYuUw.js +6 -0
  32. package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-6lrhwD3q.js} +1 -1
  33. package/dist/assets/LinearIssuesView-Ba6Q9569.js +1 -0
  34. package/dist/assets/{MarkdownImageGallery-ClOvuZxC.js → MarkdownImageGallery-Czv_mhvS.js} +1 -1
  35. package/dist/assets/MarkdownRendererImpl-BrMcswiy.js +12 -0
  36. package/dist/assets/{OnboardingScreen-D2DG7K6b.js → OnboardingScreen-ChxQoAkx.js} +1 -1
  37. package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-BzcZPlOq.js} +1 -1
  38. package/dist/assets/{PierreDiffViewer-B7m3f0d7.js → PierreDiffViewer-BchBtZlp.js} +2 -2
  39. package/dist/assets/PlanView-DyDt_nZ_.js +5 -0
  40. package/dist/assets/SettingsView-BKf5xBsP.js +28 -0
  41. package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-DDQYaKWQ.js} +1 -1
  42. package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-iYF8Y2bz.js} +6 -6
  43. package/dist/assets/ToolPartDiffPreview-CdjbOVMM.js +8 -0
  44. package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-fFFm2QgH.js} +1 -1
  45. package/dist/assets/{WalkthroughView-egQgxel3.js → WalkthroughView-DOeCsMju.js} +2 -2
  46. package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-CzgLum_K.js} +2 -2
  47. package/dist/assets/{contextPanelEmbeddedChat-C3fjDbdg.js → contextPanelEmbeddedChat-C0ZLAepL.js} +1 -1
  48. package/dist/assets/{de-C1P6X5Rs.js → de-B5JaA3SA.js} +6 -5
  49. package/dist/assets/{es-CDgaF1_t.js → es-EPIH88ii.js} +6 -5
  50. package/dist/assets/{fr-Bgxqvvz_.js → fr-CAMfxUdZ.js} +6 -5
  51. package/dist/assets/{index-CODwDsU_.js → index-Bl3LSbjn.js} +1 -1
  52. package/dist/assets/index-DF5kMP-i.js +39 -0
  53. package/dist/assets/index-Dl3xbAB_.css +1 -0
  54. package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-Dx-dB_8l.js} +1 -1
  55. package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-CWFPwmnU.js} +1 -1
  56. package/dist/assets/{ja-BDRrEcNP.js → ja-CifOE1VN.js} +7 -6
  57. package/dist/assets/{ko-Ba8sQV79.js → ko-BBDyAyYQ.js} +7 -6
  58. package/dist/assets/{main-C5DVOxc6.js → main-DnBAoktx.js} +2 -2
  59. package/dist/assets/main-MhSaOZoB.js +930 -0
  60. package/dist/assets/{markdownCore-CZwzz5gw.js → markdownCore-BrBwOOMn.js} +2 -2
  61. package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-BKyvLseN.js} +2 -2
  62. package/dist/assets/{mobile-CcaxB0n4.js → mobile-DKjeFgMN.js} +2 -2
  63. package/dist/assets/{patchFileDiff-yNfWXN4E.js → patchFileDiff-o8ms1me8.js} +1 -1
  64. package/dist/assets/pl-DgEHYfFM.js +16 -0
  65. package/dist/assets/{pt-BR-DIs6ElwV.js → pt-BR-DuWHojUw.js} +6 -5
  66. package/dist/assets/{renderElectronMiniChatApp-BcKLHXKe.js → renderElectronMiniChatApp-CDgBwwCS.js} +2 -2
  67. package/dist/assets/renderMobileApp-DJIKIK1r.js +25 -0
  68. package/dist/assets/runtimeEndpointReset-CYJ9O_xX.js +17 -0
  69. package/dist/assets/{scheduledTasksApi-DLW0mkQK.js → scheduledTasksApi-D8yamh1b.js} +1 -1
  70. package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-TEQCmzW8.js} +1 -1
  71. package/dist/assets/tr-D5m2yIWL.js +7 -0
  72. package/dist/assets/{uk-ZrCNjM7Y.js → uk-D_q60oog.js} +6 -5
  73. package/dist/assets/{useAppFontEffects-CjrntdL0.js → useAppFontEffects-D7sNpuL2.js} +161 -190
  74. package/dist/assets/useInlineCommentController-Brz_cLcQ.js +2 -0
  75. package/dist/assets/{useRootScrollLock-BHYPkrLv.js → useRootScrollLock-lXEnWlaU.js} +1 -1
  76. package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Dp3KMRQG.js} +2 -2
  77. package/dist/assets/vendor-zod-CK21ihK-.js +39 -0
  78. package/dist/assets/{web-components-Bhg83tjf.js → web-components-_mNEMjFY.js} +1 -1
  79. package/dist/assets/{zh-CN-iv_AV4EC.js → zh-CN-D8QvsVeg.js} +6 -5
  80. package/dist/assets/{zh-TW-CzEUk38j.js → zh-TW-B9t7rQQO.js} +6 -5
  81. package/dist/index.html +22 -22
  82. package/dist/mini-chat.html +7 -7
  83. package/dist/mobile.html +5 -5
  84. package/package.json +3 -3
  85. package/server/index.js +118 -85
  86. package/server/lib/agent-memory/actions.js +2 -2
  87. package/server/lib/agent-memory/feature-flag.js +1 -1
  88. package/server/lib/agent-memory/feature-flag.test.js +8 -8
  89. package/server/lib/agent-memory/routes.js +2 -2
  90. package/server/lib/agent-tool/runtime.js +37 -54
  91. package/server/lib/agent-tool/runtime.test.js +59 -59
  92. package/server/lib/browser-control/broker.js +3 -3
  93. package/server/lib/browser-control/broker.test.js +1 -1
  94. package/server/lib/changelog/update-notes.js +82 -0
  95. package/server/lib/changelog/update-notes.test.js +59 -0
  96. package/server/lib/client-auth/remote-clients.test.js +5 -5
  97. package/server/lib/context-obligatory/runtime.js +7 -7
  98. package/server/lib/context-obligatory/runtime.test.js +5 -5
  99. package/server/lib/dev-servers/parse.js +2 -2
  100. package/server/lib/dev-servers/parse.test.js +2 -2
  101. package/server/lib/dev-servers/routes.js +1 -1
  102. package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
  103. package/server/lib/dev-tunnel/client.js +1 -1
  104. package/server/lib/dev-tunnel/runtime.js +5 -5
  105. package/server/lib/dev-tunnel/tunnel.test.js +21 -1
  106. package/server/lib/dictation/local/model-catalog.js +1 -1
  107. package/server/lib/dictation/local/worker-process.js +2 -2
  108. package/server/lib/event-stream/directory-ws-bridge.js +1 -1
  109. package/server/lib/event-stream/global-ws-bridge.js +1 -1
  110. package/server/lib/event-stream/protocol.test.js +4 -4
  111. package/server/lib/event-stream/runtime.test.js +6 -6
  112. package/server/lib/fs/DOCUMENTATION.md +2 -0
  113. package/server/lib/fs/routes.js +37 -26
  114. package/server/lib/fs/routes.test.js +98 -21
  115. package/server/lib/git/DOCUMENTATION.md +3 -1
  116. package/server/lib/git/identity-storage.js +1 -1
  117. package/server/lib/git/issue-2746-longpaths.test.js +4 -4
  118. package/server/lib/git/routes.js +17 -1
  119. package/server/lib/git/service.js +116 -26
  120. package/server/lib/git/service.test.js +174 -3
  121. package/server/lib/github/auth.js +8 -8
  122. package/server/lib/github/pr-status.js +1 -1
  123. package/server/lib/github/routes.js +2 -2
  124. package/server/lib/inherited-env.js +1 -1
  125. package/server/lib/inherited-env.test.js +2 -2
  126. package/server/lib/linear/auth.js +8 -8
  127. package/server/lib/linear/auth.test.js +24 -24
  128. package/server/lib/linear/issues.test.js +6 -6
  129. package/server/lib/linear/mapping.test.js +4 -4
  130. package/server/lib/linear/oauth.js +2 -2
  131. package/server/lib/linear/oauth.test.js +14 -14
  132. package/server/lib/linear/routes.js +5 -5
  133. package/server/lib/linear/routes.test.js +16 -16
  134. package/server/lib/linear/status-runtime.test.js +9 -9
  135. package/server/lib/linear/status.js +1 -1
  136. package/server/lib/linear/status.test.js +15 -15
  137. package/server/lib/linear/teams.test.js +4 -4
  138. package/server/lib/magic-prompts/routes.js +2 -2
  139. package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
  140. package/server/lib/mcp-reconnect/runtime.js +122 -0
  141. package/server/lib/mcp-reconnect/runtime.test.js +140 -0
  142. package/server/lib/message-queue/DOCUMENTATION.md +158 -0
  143. package/server/lib/message-queue/runtime.js +870 -0
  144. package/server/lib/message-queue/runtime.test.js +482 -0
  145. package/server/lib/notifications/apns-runtime.js +17 -17
  146. package/server/lib/notifications/apns-runtime.test.js +11 -11
  147. package/server/lib/notifications/emitter-runtime.js +1 -1
  148. package/server/lib/notifications/emitter-runtime.test.js +1 -1
  149. package/server/lib/notifications/push-runtime.js +7 -7
  150. package/server/lib/notifications/routes.js +1 -1
  151. package/server/lib/notifications/runtime.js +1 -1
  152. package/server/lib/openchamber-control/action-resolution.test.js +10 -10
  153. package/server/lib/openchamber-control/actions.js +24 -24
  154. package/server/lib/openchamber-control/error.js +4 -4
  155. package/server/lib/openchamber-control/routes.js +2 -2
  156. package/server/lib/openchamber-control/routes.test.js +5 -5
  157. package/server/lib/openchamber-control/screenshots.js +1 -1
  158. package/server/lib/openchamber-control/screenshots.test.js +1 -1
  159. package/server/lib/openchamber-control/service.js +50 -50
  160. package/server/lib/openchamber-control/service.test.js +5 -5
  161. package/server/lib/openchamber-sessions/routes.js +124 -22
  162. package/server/lib/openchamber-sessions/routes.test.js +99 -11
  163. package/server/lib/opencode/DOCUMENTATION.md +13 -5
  164. package/server/lib/opencode/auth.js +1 -1
  165. package/server/lib/opencode/bootstrap-runtime.js +6 -6
  166. package/server/lib/opencode/cli-options.js +8 -8
  167. package/server/lib/opencode/config-paths.test.js +116 -0
  168. package/server/lib/opencode/core-routes.js +8 -7
  169. package/server/lib/opencode/core-routes.test.js +11 -11
  170. package/server/lib/opencode/env-config.js +5 -5
  171. package/server/lib/opencode/env-config.test.js +7 -7
  172. package/server/lib/opencode/env-runtime.js +10 -10
  173. package/server/lib/opencode/env-runtime.test.js +18 -18
  174. package/server/lib/opencode/feature-routes-runtime.js +17 -12
  175. package/server/lib/opencode/hmr-state-runtime.js +2 -2
  176. package/server/lib/opencode/hmr-state-runtime.test.js +1 -1
  177. package/server/lib/opencode/input-history-scope.js +14 -0
  178. package/server/lib/opencode/lifecycle.js +8 -8
  179. package/server/lib/opencode/lifecycle.test.js +4 -4
  180. package/server/lib/opencode/managed-plugin-config.js +35 -0
  181. package/server/lib/opencode/managed-process-registry.js +3 -3
  182. package/server/lib/opencode/mcp-oauth-callback.test.js +2 -2
  183. package/server/lib/opencode/openchamber-routes.js +15 -15
  184. package/server/lib/opencode/openchamber-routes.test.js +11 -11
  185. package/server/lib/opencode/plugins.js +2 -2
  186. package/server/lib/opencode/plugins.test.js +1 -1
  187. package/server/lib/opencode/project-icon-routes.js +2 -2
  188. package/server/lib/opencode/project-icon-routes.test.js +1 -1
  189. package/server/lib/opencode/providers.js +44 -2
  190. package/server/lib/opencode/providers.test.js +131 -4
  191. package/server/lib/opencode/proxy.js +2 -2
  192. package/server/lib/opencode/pwa-manifest-routes.js +1 -1
  193. package/server/lib/opencode/restart-session-recovery.test.js +1 -1
  194. package/server/lib/opencode/routes-upgrade.test.js +4 -4
  195. package/server/lib/opencode/routes.js +14 -14
  196. package/server/lib/opencode/server-startup-runtime.js +6 -6
  197. package/server/lib/opencode/session-runtime.js +3 -3
  198. package/server/lib/opencode/session-runtime.test.js +6 -6
  199. package/server/lib/opencode/settings-helpers.js +31 -3
  200. package/server/lib/opencode/settings-helpers.test.js +189 -12
  201. package/server/lib/opencode/settings-runtime.js +2 -2
  202. package/server/lib/opencode/settings-runtime.test.js +29 -0
  203. package/server/lib/opencode/shared.js +5 -2
  204. package/server/lib/opencode/shared.test.js +7 -7
  205. package/server/lib/opencode/shutdown-runtime.js +2 -0
  206. package/server/lib/opencode/skill-routes.js +2 -1
  207. package/server/lib/opencode/snippets.js +1 -2
  208. package/server/lib/opencode/startup-performance.js +1 -1
  209. package/server/lib/opencode/startup-performance.test.js +6 -6
  210. package/server/lib/opencode/static-routes-runtime.js +8 -8
  211. package/server/lib/opencode/static-routes-runtime.test.js +7 -7
  212. package/server/lib/opencode/upgrade-capability.js +2 -2
  213. package/server/lib/opencode/upgrade-capability.test.js +3 -3
  214. package/server/lib/package-manager.js +17 -42
  215. package/server/lib/package-manager.test.js +19 -19
  216. package/server/lib/permission-auto-accept/runtime.js +1 -1
  217. package/server/lib/project-context/routes.js +1 -1
  218. package/server/lib/projects/project-config.js +2 -2
  219. package/server/lib/quota/DOCUMENTATION.md +9 -1
  220. package/server/lib/quota/credentials/providers.js +4 -0
  221. package/server/lib/quota/credentials/store.js +4 -4
  222. package/server/lib/quota/credentials/store.test.js +8 -8
  223. package/server/lib/quota/index.js +1 -0
  224. package/server/lib/quota/providers/exe-dev.js +75 -0
  225. package/server/lib/quota/providers/exe-dev.test.js +47 -0
  226. package/server/lib/quota/providers/hyper.js +118 -0
  227. package/server/lib/quota/providers/hyper.test.js +126 -0
  228. package/server/lib/quota/providers/index.js +15 -0
  229. package/server/lib/quota/providers/ollama-cloud.js +1 -1
  230. package/server/lib/quota/providers/opencode-go.js +2 -1
  231. package/server/lib/quota/providers/opencode-go.test.js +9 -5
  232. package/server/lib/quota/providers/xai.js +1 -1
  233. package/server/lib/quota/routes.js +2 -0
  234. package/server/lib/quota/utils/auth.js +1 -1
  235. package/server/lib/relay/DOCUMENTATION.md +1 -1
  236. package/server/lib/relay/host-client.js +1 -1
  237. package/server/lib/relay/host-client.test.js +9 -1
  238. package/server/lib/relay/host-lock.js +1 -1
  239. package/server/lib/relay/service.js +5 -5
  240. package/server/lib/relay/tunnel-host.js +3 -1
  241. package/server/lib/relay/tunnel-host.test.js +9 -1
  242. package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +2 -2
  243. package/server/lib/scheduled-tasks/routes.js +5 -5
  244. package/server/lib/scheduled-tasks/service.js +25 -25
  245. package/server/lib/scheduled-tasks/service.test.js +1 -1
  246. package/server/lib/security/bind-host.js +4 -4
  247. package/server/lib/security/bind-host.test.js +1 -1
  248. package/server/lib/security/request-security.js +11 -5
  249. package/server/lib/security/request-security.test.js +14 -14
  250. package/server/lib/session-assist/runtime.js +10 -9
  251. package/server/lib/session-folders/routes.js +2 -2
  252. package/server/lib/session-folders/routes.test.js +8 -8
  253. package/server/lib/session-goal/DOCUMENTATION.md +20 -7
  254. package/server/lib/session-goal/create.js +4 -2
  255. package/server/lib/session-goal/create.test.js +1 -1
  256. package/server/lib/session-goal/objectives.js +4 -4
  257. package/server/lib/session-goal/routes.js +1 -1
  258. package/server/lib/session-goal/runtime.js +88 -22
  259. package/server/lib/session-goal/runtime.test.js +428 -2
  260. package/server/lib/session-knowledge/runtime.js +11 -11
  261. package/server/lib/session-knowledge/runtime.test.js +5 -5
  262. package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
  263. package/server/lib/skills-catalog/cache.test.js +2 -2
  264. package/server/lib/skills-catalog/disk-cache.js +5 -5
  265. package/server/lib/skills-catalog/github-meta.test.js +2 -2
  266. package/server/lib/skills-catalog/install.js +3 -2
  267. package/server/lib/small-model/DOCUMENTATION.md +4 -0
  268. package/server/lib/small-model/call.js +9 -3
  269. package/server/lib/small-model/call.test.js +29 -6
  270. package/server/lib/small-model/index.js +8 -7
  271. package/server/lib/small-model/index.test.js +1 -1
  272. package/server/lib/small-model/resolve.js +1 -1
  273. package/server/lib/small-model/resolve.test.js +1 -1
  274. package/server/lib/small-model/routes.js +2 -1
  275. package/server/lib/system-prompt/runtime.js +3 -22
  276. package/server/lib/system-prompt/runtime.test.js +3 -3
  277. package/server/lib/terminal/DOCUMENTATION.md +11 -7
  278. package/server/lib/terminal/runtime.js +180 -26
  279. package/server/lib/terminal/runtime.test.js +554 -27
  280. package/server/lib/terminal/shells.js +20 -3
  281. package/server/lib/terminal/shells.test.js +33 -2
  282. package/server/lib/tts/base-url.js +3 -3
  283. package/server/lib/tts/routes.test.js +20 -20
  284. package/server/lib/ui-auth/ui-auth.js +12 -9
  285. package/server/lib/ui-auth/ui-auth.test.js +19 -3
  286. package/server/lib/ui-auth/ui-passkeys.js +7 -7
  287. package/server/lib/walkthrough/index.js +1 -0
  288. package/server/lib/walkthrough/jobs.test.js +1 -1
  289. package/server/lib/walkthrough/language.test.js +1 -1
  290. package/server/lib/walkthrough/model-settings.js +3 -3
  291. package/server/lib/walkthrough/model-settings.test.js +1 -1
  292. package/server/lib/walkthrough/pull-request.test.js +5 -5
  293. package/server/lib/walkthrough/reproduce-2607.test.js +2 -2
  294. package/server/lib/walkthrough/routes.test.js +26 -5
  295. package/server/lib/walkthrough/store.js +3 -3
  296. package/server/lib/walkthrough/store.test.js +1 -1
  297. package/server/opencode-proxy.test.js +2 -2
  298. package/server/proxy-headers.js +1 -1
  299. package/server/sse-routes.test.js +4 -4
  300. package/README.md.bak +0 -250
  301. package/bin/lib/DOCUMENTATION.md.bak +0 -163
  302. package/dist/assets/CommitSection-SGBCAW0w.js +0 -1
  303. package/dist/assets/FilesView-Bdq8ppva.js +0 -17
  304. package/dist/assets/GitView-Znn7VJcP.js +0 -6
  305. package/dist/assets/LinearIssuesView-jP-hXyac.js +0 -1
  306. package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
  307. package/dist/assets/PlanView-B0F3BtPZ.js +0 -5
  308. package/dist/assets/SettingsView-BBW-S-gh.js +0 -28
  309. package/dist/assets/ToolPartDiffPreview-CUNe28U1.js +0 -8
  310. package/dist/assets/index-C57jT0Sa.css +0 -1
  311. package/dist/assets/index-DW_E3rnL.js +0 -7
  312. package/dist/assets/main-Bv5Pkngh.js +0 -928
  313. package/dist/assets/pl-Dioz29BI.js +0 -15
  314. package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
  315. package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
  316. package/dist/assets/tr-DFnMlPxY.js +0 -6
  317. package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
  318. package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
  319. package/server/index.d.ts.bak +0 -39
  320. package/server/lib/agent-tool/DOCUMENTATION.md.bak +0 -119
  321. package/server/lib/browser-control/DOCUMENTATION.md.bak +0 -50
  322. package/server/lib/context-obligatory/DOCUMENTATION.md.bak +0 -19
  323. package/server/lib/dev-tunnel/DOCUMENTATION.md.bak +0 -57
  324. package/server/lib/dictation/DOCUMENTATION.md.bak +0 -100
  325. package/server/lib/event-stream/DOCUMENTATION.md.bak +0 -62
  326. package/server/lib/fs/DOCUMENTATION.md.bak +0 -47
  327. package/server/lib/git/DOCUMENTATION.md.bak +0 -193
  328. package/server/lib/github/DOCUMENTATION.md.bak +0 -183
  329. package/server/lib/linear/DOCUMENTATION.md.bak +0 -97
  330. package/server/lib/linear/OAUTH-BROKER-HANDOFF.md.bak +0 -91
  331. package/server/lib/markdown-image-grants/DOCUMENTATION.md.bak +0 -40
  332. package/server/lib/notifications/APNS.md.bak +0 -135
  333. package/server/lib/notifications/DOCUMENTATION.md.bak +0 -138
  334. package/server/lib/openchamber-control/DOCUMENTATION.md.bak +0 -64
  335. package/server/lib/opencode/DOCUMENTATION.md.bak +0 -431
  336. package/server/lib/opencode/managed-process-registry.d.ts.bak +0 -13
  337. package/server/lib/opencode/provider-env-aliases.d.ts.bak +0 -3
  338. package/server/lib/permission-auto-accept/DOCUMENTATION.md.bak +0 -34
  339. package/server/lib/project-context/DOCUMENTATION.md.bak +0 -160
  340. package/server/lib/quota/DOCUMENTATION.md.bak +0 -123
  341. package/server/lib/relay/DOCUMENTATION.md.bak +0 -100
  342. package/server/lib/scheduled-tasks/DOCUMENTATION.md.bak +0 -182
  343. package/server/lib/session-assist/DOCUMENTATION.md.bak +0 -66
  344. package/server/lib/session-goal/DOCUMENTATION.md.bak +0 -213
  345. package/server/lib/session-knowledge/DOCUMENTATION.md.bak +0 -89
  346. package/server/lib/skills-catalog/DOCUMENTATION.md.bak +0 -151
  347. package/server/lib/small-model/DOCUMENTATION.md.bak +0 -212
  348. package/server/lib/system-prompt/DOCUMENTATION.md.bak +0 -36
  349. package/server/lib/terminal/DOCUMENTATION.md.bak +0 -50
  350. package/server/lib/text/DOCUMENTATION.md.bak +0 -35
  351. package/server/lib/tts/DOCUMENTATION.md.bak +0 -147
  352. package/server/lib/tunnels/DOCUMENTATION.md.bak +0 -21
  353. package/server/lib/ui-auth/DOCUMENTATION.md.bak +0 -44
  354. package/server/lib/walkthrough/DOCUMENTATION.md.bak +0 -411
@@ -1,66 +0,0 @@
1
- # Session Assist
2
-
3
- Server-side watcher that generates a short recap of the agent's last reply
4
- and one suggested user follow-up with the small model
5
- (`lib/small-model`), storing both on the session's metadata under
6
- `metadata.aiworker.assist`.
7
-
8
- ## Flow
9
-
10
- 1. `createSessionAssistRuntime` is a consumer of the server's global SSE
11
- fan-out (`index.js` → `onPayload`), riding the same upstream connection as
12
- notifications. Purely event-driven — dormant sessions never generate
13
- anything, there is no backfill and no session scanning.
14
- 2. `session.status: idle` arms a 60-second per-session timer; any `busy`/
15
- `retry` status or a user `message.updated` clears it (the "1 minute of
16
- quiet" rule).
17
- 3. On fire: fetch the session (skip sub-agent sessions with `parentID`),
18
- take the LAST exchange only — the final assistant reply plus the user
19
- message it answered (assistant `parentID` → user id) — and call
20
- `generateSmallModelText` with the
21
- session's own provider/model taken from the last assistant message — so
22
- the utility call spends the same subscription as the conversation.
23
- `restrictToPreferredProvider` forbids the resolver's global fallback:
24
- conversation content never goes to a provider the user didn't pick for
25
- the session, unless the small model was chosen explicitly (settings
26
- override or opencode config). A resolver 404 is silently skipped.
27
- 4. The requested JSON fields (`recap`, `suggestion`, or both) are clamped and
28
- PATCHed onto the session metadata together with `forMessageID` (the last
29
- assistant message id) and `generatedAt`. Before writing, the session tail is
30
- re-checked (a stale result is dropped) and the metadata is merged from a
31
- fresh session read so concurrent metadata writes made during generation are
32
- preserved.
33
-
34
- ## Settings gate
35
-
36
- `sessionRecapEnabled` and `sessionSuggestionEnabled` in AiWorker settings
37
- (Settings → Chat, default on) are hard generation switches checked at fire
38
- time. When both are off, no small-model calls run and nothing is written. When
39
- one is on, the runtime still makes at most one small-model call and asks only
40
- for that field. The UI also hides disabled payload types immediately.
41
-
42
- ## Freshness contract (no clearing writes)
43
-
44
- Clients do not need the payload to be deleted: they render it only while
45
- `assist.forMessageID` still equals the session's last assistant message id
46
- (and the session is idle). Any new message invalidates the payload
47
- everywhere instantly and offline; the next idle cycle overwrites it.
48
-
49
- ## UI consumers (packages/ui)
50
-
51
- - `lib/sessionAssistMetadata.ts` — payload parsing.
52
- - `hooks/useSessionAssist.ts` — freshness gating + the 1-minute quiet window
53
- for the recap (single timeout to the boundary, no polling).
54
- - `components/chat/SessionRecapSpacer.tsx` — renders the recap inside the
55
- fixed-height reserved gap under the last message (height never changes).
56
- - `components/chat/SessionSuggestionChip.tsx` — one tappable suggestion chip
57
- near the composer (desktop chips row + above the mobile pill); hidden as
58
- soon as the composer has any content. Tap fills the input, never sends.
59
-
60
- ## Limitations
61
-
62
- - The watcher lives in the web server, so VS Code (extension-only, no web
63
- server) does not generate assists; it still renders payloads produced by a
64
- web/desktop instance of the same OpenCode server via `session.updated`.
65
- - Metadata payloads ride every `session.updated` event — keep the clamps
66
- (`RECAP_CHAR_LIMIT`, `SUGGESTION_CHAR_LIMIT`) small.
@@ -1,213 +0,0 @@
1
- # Session Goal
2
-
3
- Server-side control loop that keeps a session working toward a user-defined
4
- objective stored under `metadata.aiworker.goal`, with the small model as
5
- an independent progress auditor. Built on AiWorker's backend-driven
6
- architecture (session-assist is the structural template): the loop lives in
7
- the web server and survives UI disconnects.
8
-
9
- ## Goal payload (`metadata.aiworker.goal`)
10
-
11
- ```
12
- {
13
- id, // opaque per-logical-goal id; stale-write guard
14
- objective, // inline user text (fallback), <= 5000 chars
15
- objectiveFile, // true: objective text lives in a server-side file
16
- status, // active | paused | blocked | budgetLimited | complete
17
- tokenBudget, // optional positive int
18
- tokensUsed, // tokensCommitted + current segment (snapshot - baseline)
19
- tokensBaseline, // segment start snapshot (pre-goal turn; 0 after compaction)
20
- tokensCommitted, // closed segments' total (one segment per compaction)
21
- turnsUsed, // auto-continuations sent (capped at MAX_AUTO_TURNS)
22
- blockedStreak, // consecutive blocked audit verdicts
23
- auditFailStreak, // consecutive failed/unavailable audit calls
24
- note, // latest audit progress note, <= 280 chars
25
- statusReason, // why settled; 'resumed' is a kickoff signal from UI
26
- evaluationProviderID, // provider used by the latest successful audit
27
- evaluationModelID, // model used by the latest successful audit
28
- lastAccountedMessageID, // incremental accounting cursor
29
- createdAt, updatedAt
30
- }
31
- ```
32
-
33
- The UI writes goals (create/edit/pause/resume/clear) by patching this
34
- metadata; the runtime never creates a goal on its own. Goal creation happens
35
- at send time via the arm store (`useSessionGoalArmStore`): the composer
36
- target button arms "the next prompt is the objective", and the run-as-goal
37
- flows (fork-from-answer dialog, plan implement dialog) arm the same way —
38
- the plan flow additionally supplies an objective OVERRIDE carrying the plan
39
- content, since "Implement this plan: X" alone gives the audit nothing to
40
- judge against. The armed send also attaches a synthetic system-reminder
41
- part telling the agent goal mode is active and that each turn should end
42
- with a factual done/verified/remaining statement for the independent audit.
43
- Freshness/stale-write protection is by `id`: every runtime write re-reads the
44
- session and drops the write when the stored goal id no longer matches.
45
-
46
- ## File-backed objectives
47
-
48
- The objective TEXT lives in `<data-dir>/goals/<sessionId>.md` (data dir =
49
- `AIWORKER_DATA_DIR` or `~/.config/openchamber`), keyed by the SESSION ID:
50
- sessions are globally unique and carry one goal at a time, so the mapping is
51
- deterministic and a new goal simply overwrites the file. Metadata carries
52
- only `objectiveFile: true` — never a path — so user-writable metadata cannot
53
- become a file-read vector (`objectives.js` also validates the id shape
54
- before touching the filesystem). Rationale: metadata rides every
55
- `session.updated`, so multi-KB objectives must not live there.
56
-
57
- - `objectives.js` — write/read/delete, 5000-char clamp.
58
- - `routes.js` — `PUT/GET/DELETE /api/goals/objective/:sessionId`
59
- (AiWorker-owned, registered before the generic proxy; JSON parsing via
60
- the `/api/goals` family in core-routes). The UI writes the file BEFORE
61
- patching the goal metadata and falls back to an inline objective when the
62
- write fails; `clearSessionGoal` deletes the file best-effort.
63
- - The tick resolves the effective objective fresh on every cycle (the file
64
- is live-editable mid-goal) and falls back to the inline `objective` when
65
- the file is unreadable — a goal never dies because a file went away.
66
- - UI display fetches content via the GET route
67
- (`useGoalObjectiveContent`); in VS Code the route is unavailable, so the
68
- strip degrades to the audit note (display-only fallback by design).
69
- - Server-created goals write the file through `create.js`, which also owns
70
- objective fitting, inline fallback, metadata creation, and the synthetic
71
- first-turn reminder shared by scheduled tasks and CLI-created sessions.
72
-
73
- ## Flow
74
-
75
- 1. `createSessionGoalRuntime` subscribes to the global SSE hub (same pattern
76
- as session-assist — it needs the envelope's `directory`).
77
- 2. `session.status: idle` arms a 15s per-session timer; `busy`/`retry` clears
78
- it. A `session.updated` carrying a fresh active goal (`turnsUsed === 0` or
79
- `statusReason === 'resumed'`) arms a kickoff timer — 3s for fresh goals,
80
- ~250ms for an explicit Resume so the nudge feels immediate — since setting
81
- a goal on an idle session emits no status transition.
82
- 3. On fire (`tick`), gated by the `sessionGoalEnabled` setting:
83
- - fetch session (skip sub-agent sessions), require an `active` goal;
84
- - authoritative live-activity check after the quiet window: re-read the
85
- session status map, bail if the parent resumed, then list direct child
86
- sessions and bail while any child is `busy`/`retry`. A background
87
- subagent leaves its parent idle, then injects its result into the parent
88
- when done; that parent `busy` → `idle` cycle re-arms the loop without
89
- polling. Status/children fetch failure is unknown, not empty, so it skips
90
- the audit and retries after another quiet window;
91
- - quiescence check via the message tail (trailing user message or
92
- unfinished assistant reply → bail; the next idle transition re-arms);
93
- - token accounting as a SNAPSHOT of the latest completed assistant turn:
94
- `input + cache.read + output`. Earlier turns' inputs and outputs fold
95
- into the next turn's cache, so the latest snapshot already carries the
96
- whole run's paid tokens — no summing across messages. Goal-relative via
97
- `tokensBaseline` (the same snapshot of the newest pre-goal turn,
98
- captured on the first tick). Compaction (an assistant message with
99
- `summary: true`) breaks the snapshot chain, so accounting is segmented:
100
- the summary message closes the segment into `tokensCommitted` (the
101
- summary turn read the whole context, so its snapshot prices the
102
- compaction itself) and the next segment starts with a zero baseline.
103
- `tokensUsed = tokensCommitted + current segment`, kept monotonic so
104
- unflagged context shrinks never move the budget backwards;
105
- - a user abort pauses the goal instead of blocking it: the event path in
106
- `processPayload` pauses immediately on the MessageAbortedError message
107
- (before any tick could send a continuation over the user's explicit
108
- stop), with a tick-side safety net. Messages sent while paused leave
109
- the goal alone; Resume re-arms the loop, and resuming over an aborted
110
- tail skips the audit and goes straight to a continuation nudge;
111
- - terminal checks, cheapest first: assistant turn error → `blocked`;
112
- `tokensUsed >= tokenBudget` → `budgetLimited`;
113
- `turnsUsed >= MAX_AUTO_TURNS` (20) → `blocked`;
114
- - if the latest message is a compaction summary, skip the audit and
115
- continue unconditionally — running into the context window mid-work is
116
- by definition "in progress, not finished" (the summary is a retelling,
117
- not evidence, and must not be judged);
118
- - otherwise, small-model audit of the objective + the last assistant turn
119
- only — no conversation history and no continuation prompts
120
- (`restrictToPreferredProvider`, session's own provider/model preferred):
121
- JSON `{verdict: continue|complete|blocked, note}`. The audit is the SOLE
122
- termination authority besides the hard stops above — the working agent
123
- has no channel to settle its own goal. `complete` settles; `blocked`
124
- increments `blockedStreak` and settles only after 3 consecutive blocked
125
- verdicts, so a one-off snag cannot end the goal. Audit failure/absence
126
- tolerates ONE consecutive unaudited continuation (`auditFailStreak`); a
127
- second consecutive failure settles the goal as `blocked` ("progress
128
- audit unavailable") — resumable, and settling resets the streak so
129
- Resume gets fresh tolerance. A dead small model can never drive the
130
- loop blind to the turn cap;
131
- - continue: persist accounting + `turnsUsed` first (a crash after the
132
- write just waits for the next idle tick; the reverse could double-send),
133
- re-check the tail, then `POST /session/:id/prompt_async` with the
134
- continuation prompt using the last assistant message's
135
- provider/model/agent — the goal spends the session's own subscription.
136
- 4. Settling (`complete`/`blocked`/`budgetLimited`) fires the injected
137
- `emitGoalNotification` so the user hears about it even with the UI closed:
138
- desktop + UI broadcast + the standard push fanout (web-push with full
139
- text; APNs with a generic per-type title and the session name as body).
140
- It obeys the notify-on-completion setting. Conversely, while a goal is
141
- ACTIVE the notifications runtime suppresses per-turn "ready"
142
- notifications on every channel — they would only echo the loop's own
143
- continuations; error/question/permission notifications are untouched.
144
- Pausing a goal from the UI also aborts the running turn (and vice versa —
145
- an abort pauses the goal), so "stop" means stop on both axes.
146
-
147
- ## Continuation prompt
148
-
149
- Built inline in `runtime.js`: the objective as untrusted user data in an
150
- XML-escaped `<objective>` block, budget numbers, keep-the-full-objective and
151
- work-from-evidence rules, a completion-audit instruction, and the requirement
152
- to end every turn with a factual done/verified/remaining report — the audit
153
- sees only that final turn, so the report is its evidence.
154
-
155
- ## UI consumers (packages/ui)
156
-
157
- - `lib/sessionGoalMetadata.ts` — payload parsing/types.
158
- - `lib/sessionGoalActions.ts` — create/edit/pause/resume/clear via
159
- `patchSessionMetadata`; `lib/sessionGoalPresentation.ts` — status
160
- colors/labels shared across surfaces.
161
- - `stores/useSessionGoalArmStore.ts` — the "next prompt starts a goal" flag,
162
- consumed by `sendMessage` in `sync/session-ui-store.ts` (works for drafts).
163
- Armed slash commands resolve their authoritative command template and apply
164
- OpenCode argument expansion (`$ARGUMENTS`, positional placeholders, or the
165
- implicit argument suffix) for the audit objective before goal metadata is
166
- written and before `session.command` dispatch. If command details cannot be
167
- loaded, the raw invocation remains the objective rather than blocking command
168
- execution.
169
- - `hooks/useSessionGoal.ts` — live goal state.
170
- - `components/chat/SessionGoalButton.tsx` — composer target button
171
- (arm / status color / cancel confirm); `SessionGoalRow.tsx` — goal strip
172
- above the composer; `SessionGoalDialog.tsx` — manage dialog
173
- (edit/pause/resume/complete/clear).
174
- - Sidebar glyph next to the date in `SessionNodeItem`.
175
-
176
- ## Scheduled goals
177
-
178
- Scheduled tasks can run as goals: `execution.goalEnabled` (+ optional
179
- `execution.goalTokenBudget`) on a task makes the scheduled-tasks runtime
180
- stamp `metadata.aiworker.goal` onto the fresh session (objective = the
181
- expanded task prompt, or the argument-expanded command template for a slash
182
- command) and attach the goal-mode intro part to normal prompts.
183
- The loop here picks it up from session events like any other goal.
184
-
185
- ## CLI-created goals
186
-
187
- `aiworker session create --prompt <text> --goal` uses the explicit
188
- `POST /api/openchamber/sessions` orchestration route. The server creates the
189
- session, fits and stores the expanded prompt as its objective, patches active
190
- goal metadata, appends the synthetic goal reminder, and only then dispatches
191
- the prompt. `--goal-token-budget` applies the same optional budget contract as
192
- scheduled goals. Slash commands retain command dispatch semantics and cannot
193
- carry the synthetic prompt part. Their command template with OpenCode argument
194
- expansion becomes the audit objective; goal metadata
195
- is still installed before the command runs. A missing command template falls
196
- back to the raw invocation.
197
-
198
- `aiworker session send --goal` and `aiworker session fork --goal` use
199
- the same server-owned prompt orchestration. Send installs a fresh goal on the
200
- target session; fork first uses the official OpenCode fork operation (at the
201
- optional message boundary), then installs the goal on the new session. Both
202
- preserve the objective-file-before-metadata and metadata-before-dispatch
203
- ordering used by create and scheduled goals.
204
-
205
- ## Limitations
206
-
207
- - Web-server feature: VS Code (extension-only) renders goal state via
208
- `session.updated` but does not run the loop.
209
- - A goal on a session with no assistant reply yet starts after the first
210
- user exchange completes (no provider/model to continue with before that).
211
- - `tokensUsed` only counts completed assistant messages seen within the
212
- 40-message fetch window per tick; extremely long busy stretches between
213
- idles undercount (acceptable: budget is a guardrail, not billing).
@@ -1,89 +0,0 @@
1
- # Session Knowledge
2
-
3
- What a session must be told about the project — that session's pinned notes and
4
- plans, and the index of what the agent has remembered — and whether it has been
5
- told yet.
6
-
7
- ## Why it is here and not in the UI
8
-
9
- The client used to own this: it assembled the text, decided when to send it, and
10
- remembered what it had sent in a module-scoped map. Two consequences followed.
11
-
12
- A session started without a UI got nothing at all. Scheduled tasks and sessions
13
- the agent dispatches build their prompts on the server and never touch the
14
- browser, so pinned context and the memory index simply did not exist for them.
15
-
16
- And a tab's memory of what it sent survives compaction, while the conversation
17
- does not. After a summary the agent no longer holds the block, but the tab goes
18
- on believing it does and never sends it again.
19
-
20
- ## The contract
21
-
22
- `session.metadata.aiworker.project_context_pins` owns the note and plan ids
23
- attached to that session. Pins never come from project-wide note or plan state.
24
- A new-session draft passes its pins into this metadata when its first message
25
- creates the session.
26
-
27
- Directories beneath the managed `~/.config/openchamber/chats` root resolve to that root before project context and project memory are read. Every ordinary chat therefore shares one Chats knowledge owner instead of creating an unreachable context store for each dated session directory.
28
-
29
- `session.metadata.aiworker.knowledge_context_delivered` holds the signature
30
- of what the session is carrying. It lives with the session, so it survives the
31
- tab closing and is visible to every sender, including the ones with no tab.
32
-
33
- The signature covers content revisions, not just identity: editing a pinned note
34
- must re-send it, not merely renaming one.
35
-
36
- ## Three moments, two deliveries
37
-
38
- | Moment | Delivery |
39
- |---|---|
40
- | A message from the UI | synthetic part on that message |
41
- | A scheduled task, a session the agent dispatched | synthetic part on that prompt |
42
- | After compaction | its own `prompt_async`, alongside the pinned messages |
43
-
44
- The first two attach to an outgoing message because there is one. Compaction has
45
- none, which is why it re-sends on its own — and it travels with
46
- `context-obligatory`'s pinned messages in a single turn, since two synthetic
47
- messages back to back read as the agent being interrupted twice.
48
-
49
- ## Failure behaviour
50
-
51
- Nothing here may fail a send. A message without its background costs the agent
52
- some context; a failed send costs the user their message. Every caller treats an
53
- error as "no block this time".
54
-
55
- A source that will not load never blanks the rest: an unreadable memory store
56
- still delivers the pinned notes. A memory scope that failed to load is left out
57
- rather than indexed as empty, which would teach the agent to store again what it
58
- already has.
59
-
60
- Delivery is recorded only after the send is accepted. Recording it when the text
61
- is handed over would leave a failed send believing the agent had context it never
62
- received.
63
-
64
- ## Entries that read as instructions
65
-
66
- Memory is the one place where text from outside can settle permanently. The
67
- agent reads a page, decides a line is worth keeping, saves it — and from then on
68
- it rides into every session in every project. An injection anywhere else lives
69
- for one conversation.
70
-
71
- `agent-memory/threat-patterns` scans on write and again on every read, so an
72
- entry written before a pattern existed, or edited on disk since, is judged now.
73
- A match never deletes: the entry is stored, flagged, kept out of what sessions
74
- are told, and shown in the panel with a warning. Silently dropping it would hide
75
- the attempt from the only person able to judge it.
76
-
77
- Patterns, not a model — this runs on every index build. That buys the blunt
78
- cases only, which is the honest expectation.
79
-
80
- ## Shipping dark
81
-
82
- Agent memory is complete but unreleased. `AIWORKER_MEMORY_ENABLE` decides
83
- whether it exists in a given process at all: unset, there is no tool, no routes,
84
- no session index, no settings row and no panel tab — absent rather than switched
85
- off, which would invite turning on something never announced. The setting itself
86
- also defaults to off, so setting the variable does not enable memory by itself.
87
-
88
- Pinned notes and plans are unaffected by the memory switch and remain scoped to
89
- the session that pinned them.
@@ -1,151 +0,0 @@
1
- # Skills Catalog Module Documentation
2
-
3
- ## Purpose
4
- This module provides skill discovery, scanning, and installation capabilities for OpenCode. It supports skill sources backed by git repositories, with caching and conflict resolution for skill installation.
5
-
6
- ## Entrypoints and structure
7
- - `packages/web/server/lib/skills-catalog/`: Skills catalog module directory containing all skill-related functionality.
8
- - `cache.js`: In-memory cache for scan results with TTL support.
9
- - `curated-sources.js`: Predefined skill sources (Anthropic, OpenAI, Cursor, Matt Pocock).
10
- - `github-meta.js`: Best-effort GitHub repository metadata (stars, last push) with in-memory TTL cache.
11
- - `git.js`: Git operations helpers for cloning and auth error detection.
12
- - `install.js`: Skills installation from git repositories.
13
- - `scan.js`: Skills scanning from git repositories.
14
- - `source.js`: Source string parsing for git repositories.
15
-
16
- ## Public API
17
-
18
- The following functions are exported and used by the web server:
19
-
20
- ### Cache (`cache.js`)
21
- - `getCacheKey({ normalizedRepo, subpath, identityId })`: Generate cache key for scan results.
22
- - `getCachedScan(key)`: Retrieve cached scan result if not expired.
23
- - `setCachedScan(key, value, ttlMs)`: Store scan result with TTL (default 3 hours).
24
- - `scanWithCache(key, loader, { refresh })`: Run a scan loader with cache lookup, in-flight deduplication, and a global concurrency limit (2 concurrent scans); only `ok: true` results are cached.
25
- - `clearCache()`: Clear all cached scan results.
26
- - Scan results persist to `skills-catalog-cache.json` in the AiWorker data dir (debounced, atomic rename) and survive server restarts within the TTL.
27
-
28
- ### Curated Sources (`curated-sources.js`)
29
- - `getCuratedSkillsSources()`: Return list of curated skill sources (Anthropic, OpenAI, Cursor, Matt Pocock).
30
- - `CURATED_SKILLS_SOURCES`: Constant array of predefined sources.
31
-
32
- ### GitHub Repository Metadata (`github-meta.js`)
33
- - `fetchGitHubRepoMetas(normalizedRepos)`: Fetch `{ stars, repoUpdatedAt }` for GitHub `owner/repo` strings. Best-effort: failures resolve to `null`; in-flight requests deduplicate; results cached in memory and on disk (`skills-github-meta.json`) for three hours.
34
- - `clearGitHubMetaCache()`: Test-only cache reset.
35
-
36
- ### Source Parsing (`source.js`)
37
- - `parseSkillRepoSource(source, { subpath })`: Parse git repository source string into structured object with SSH/HTTPS clone URLs, normalized repo, and effective subpath. Supports SSH URLs, HTTPS URLs, and shorthand `owner/repo[/subpath]` format.
38
-
39
- ### Git Repository Scanning (`scan.js`)
40
- - `scanSkillsRepository({ source, subpath, defaultSubpath, identity })`: Scan git repository for skills by cloning and analyzing SKILL.md files. Returns array of skill items with metadata.
41
-
42
- ### Git Repository Installation (`install.js`)
43
- - `installSkillsFromRepository({ source, subpath, defaultSubpath, identity, scope, targetSource, workingDirectory, userSkillDir, selections, conflictPolicy, conflictDecisions })`: Install skills from git repository. Supports user/project scopes, opencode/agents targets, conflict resolution (prompt/skipAll/overwriteAll), and sparse checkout for efficiency.
44
-
45
- ## Internal Helpers
46
-
47
- The following functions are internal helpers used by exported functions:
48
-
49
- ### Git Helpers (`git.js`)
50
- - `runGit(args, options)`: Execute git command with optional SSH identity, timeout, and max buffer. Returns `{ ok, stdout, stderr, message, code, signal }`.
51
- - `looksLikeAuthError(message)`: Detect if error message indicates authentication failure (permission denied, publickey, etc.).
52
- - `assertGitAvailable()`: Check if git is available in PATH.
53
-
54
- ### Skill Name Validation (used in `install.js`, `scan.js`)
55
- - `validateSkillName(skillName)`: Validate skill name against pattern `/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/` (1-64 chars, lowercase alphanumeric with hyphens).
56
-
57
- ### File System Helpers (`install.js`, `scan.js`)
58
- - `safeRm(dir)`: Safely remove directory recursively (ignores errors).
59
- - `ensureDir(dirPath)`: Ensure directory exists with recursive creation.
60
- - `copyDirectoryNoSymlinks(srcDir, dstDir)`: Copy directory contents without symlinks, with path traversal protection.
61
- - `normalizeUserSkillDir(userSkillDir)`: Normalize user skill directory path (handles legacy `~/.config/opencode/skill` → `~/.config/opencode/skills` migration).
62
-
63
- ### Git Clone Helpers (`install.js`, `scan.js`)
64
- - `cloneRepo({ cloneUrl, identity, tempDir })`: Clone git repository with preferred partial clone (`--filter=blob:none`) and fallback. Uses non-interactive mode.
65
-
66
- ### SKILL.md Parsing (`scan.js`)
67
- - `parseSkillMd(content)`: Parse YAML frontmatter from SKILL.md content. Returns `{ ok, frontmatter, warnings }`.
68
-
69
- ### Path Helpers (`install.js`)
70
- - `toFsPath(repoDir, repoRelPosixPath)`: Convert POSIX path to filesystem path.
71
- - `getTargetSkillDir({ scope, targetSource, workingDirectory, userSkillDir, skillName })`: Determine target installation directory based on scope (user/project), targetSource (opencode/agents), and skill name.
72
-
73
- ## Response Contracts
74
-
75
- ### Scan Skills Repository Response
76
- - `ok`: Boolean indicating success.
77
- - `normalizedRepo`: Normalized repo string (`owner/repo`).
78
- - `effectiveSubpath`: Effective subpath used for scanning (may be from source string or defaultSubpath).
79
- - `items`: Array of skill items with `{ repoSource, repoSubpath, skillDir, skillName, frontmatterName, description, installable, warnings }`.
80
- - `error`: Error object with `{ kind, message }` on failure.
81
-
82
- ### Install Skills Response
83
- - `ok`: Boolean indicating success.
84
- - `installed`: Array of installed skills with `{ skillName, scope, source }`.
85
- - `skipped`: Array of skipped skills with `{ skillName, reason }`.
86
- - `error`: Error object with `{ kind, message, conflicts? }` on failure. Kinds: `authRequired`, `networkError`, `conflicts`, `invalidSource`, `unknown`.
87
-
88
- ### Parse Source Response
89
- - `ok`: Boolean indicating success.
90
- - `host`: Git host (e.g., `github.com`, `gitlab.com`).
91
- - `owner`: Repository owner.
92
- - `repo`: Repository name.
93
- - `cloneUrlSsh`: SSH clone URL.
94
- - `cloneUrlHttps`: HTTPS clone URL.
95
- - `effectiveSubpath`: Subpath for scanning (from source string or options).
96
- - `normalizedRepo`: Normalized repo string (`owner/repo`).
97
- - `error`: Error object with `{ kind, message }` on failure.
98
-
99
- ## Notes for Contributors
100
-
101
- ### Adding a New Skill Source
102
- 1. Create a new subdirectory under `packages/web/server/lib/skills-catalog/` (e.g., `newsource/`).
103
- 2. Implement `scan.js` with a function that returns `{ ok, items, error? }` matching the SkillsCatalogItem contract.
104
- 3. Implement `install.js` with a function that accepts selections and returns `{ ok, installed, skipped, error? }`.
105
- 4. Add the source to `CURATED_SKILLS_SOURCES` in `curated-sources.js` if it should appear in the default catalog.
106
- 5. Update `packages/web/server/index.js` to import and wire up the new source.
107
-
108
- ### Skill Name Validation
109
- - All skill names must match `/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/` (1-64 chars).
110
- - Skill names are derived from directory basenames for git repos.
111
- - Invalid names result in non-installable skills with appropriate warnings.
112
-
113
- ### Git Cloning Strategy
114
- - Use sparse checkout to minimize clone size: `sparse-checkout init`, `sparse-checkout set`, `checkout HEAD`.
115
- - Preferred clone uses `--depth=1 --filter=blob:none` for partial clone with fallback to `--depth=1`.
116
- - Always use non-interactive mode (`GIT_TERMINAL_PROMPT=0`) to avoid hangs.
117
- - SSH keys are injected via `core.sshCommand` in git config.
118
-
119
- ### Conflict Resolution
120
- - Installation checks for existing skills before downloading/cloning.
121
- - Three conflict policies: `prompt`, `skipAll`, `overwriteAll`.
122
- - Per-skill decisions override global policy via `conflictDecisions` map.
123
- - Conflict response includes `{ skillName, scope, source }` for each conflict.
124
-
125
- ### Cache Management
126
- - Cache keys include `normalizedRepo`, `subpath`, and `identityId` for isolation.
127
- - Default TTL is 3 hours for both scan results and GitHub repository metadata.
128
- - Scan and GitHub metadata caches persist to JSON files in the AiWorker data dir, so app restarts and page refreshes reuse previous results instead of re-hitting GitHub.
129
- - Scans run through a global concurrency limiter (2 at a time) with per-key in-flight deduplication.
130
- - The refresh button passes `refresh: true` and bypasses the cache.
131
-
132
- ### Security Considerations
133
- - Path traversal protection in `copyDirectoryNoSymlinks`: resolves real paths and checks containment.
134
- - Symlinks are explicitly rejected to prevent escape from skill directory.
135
- - SSH key paths are trimmed but not escaped in `git.js` (assumes safe input from profiles).
136
- - Temporary directories are cleaned up in `finally` blocks.
137
-
138
- ### Error Handling
139
- - All exported functions return `{ ok, ... }` result objects, not throw.
140
- - Error kinds: `authRequired`, `networkError`, `conflicts`, `invalidSource`, `unknown`.
141
- - Use `looksLikeAuthError` to detect SSH/HTTPS auth failures for better UX.
142
- - Log errors to console for debugging but return structured errors to callers.
143
-
144
- ### Testing
145
- - Run `bun run type-check`, `bun run lint`, and `bun run build` before finalizing changes.
146
- - Consider edge cases: non-existent repos, private repos without auth, missing SKILL.md files, invalid skill names, conflicts, network failures.
147
-
148
- ## Verification Commands
149
- - Type-check: `bun run type-check`
150
- - Lint: `bun run lint`
151
- - Build: `bun run build`