synabun 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +2 -2
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +17 -8
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +1 -1
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +228 -0
  24. package/lib/virustotal.mjs +192 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  42. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  44. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  45. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  46. package/mcp-server/dist/services/neural-interface.js +67 -11
  47. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  48. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  49. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  50. package/mcp-server/dist/services/server-instructions.js +20 -62
  51. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  52. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  53. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  54. package/mcp-server/dist/services/tool-catalog.js +339 -0
  55. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  56. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  60. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  61. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  62. package/mcp-server/dist/services/tool-list.js +334 -0
  63. package/mcp-server/dist/services/tool-list.js.map +1 -0
  64. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  66. package/mcp-server/dist/services/tool-runtime.js +400 -0
  67. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  68. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  70. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  71. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  72. package/mcp-server/dist/tools/agents.d.ts +10 -10
  73. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  74. package/mcp-server/dist/tools/agents.js +22 -13
  75. package/mcp-server/dist/tools/agents.js.map +1 -1
  76. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  77. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  78. package/mcp-server/dist/tools/image-tools.js +1 -1
  79. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  80. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  81. package/mcp-server/dist/tools/skill-tools.js +639 -0
  82. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  83. package/mcp-server/dist/tools/skill.d.ts +7 -0
  84. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  85. package/mcp-server/dist/tools/skill.js +11 -0
  86. package/mcp-server/dist/tools/skill.js.map +1 -0
  87. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  89. package/mcp-server/dist/tools/tool-groups.js +147 -0
  90. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  91. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  93. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  94. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  97. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  98. package/mcp-server/package-lock.json +2 -2
  99. package/mcp-server/package.json +1 -1
  100. package/mcp-server/src/http.ts +75 -12
  101. package/mcp-server/src/index.ts +147 -154
  102. package/mcp-server/src/preload.ts +12 -12
  103. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  104. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  105. package/mcp-server/src/services/neural-interface.ts +79 -20
  106. package/mcp-server/src/services/server-instructions.ts +27 -63
  107. package/mcp-server/src/services/tool-catalog.ts +403 -0
  108. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  109. package/mcp-server/src/services/tool-list.ts +410 -0
  110. package/mcp-server/src/services/tool-runtime.ts +457 -0
  111. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  112. package/mcp-server/src/tools/agents.ts +22 -14
  113. package/mcp-server/src/tools/image-tools.ts +1 -1
  114. package/mcp-server/src/tools/skill-tools.ts +589 -0
  115. package/mcp-server/src/tools/skill.ts +13 -0
  116. package/mcp-server/src/tools/tool-groups.ts +164 -0
  117. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  118. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  119. package/neural-interface/i18n/en.json +3463 -200
  120. package/neural-interface/i18n/pt-BR.json +3411 -151
  121. package/neural-interface/lib/assistant-api.js +127 -28
  122. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  123. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  124. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  125. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  126. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  127. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  128. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  129. package/neural-interface/lib/assistant-catalog.js +6 -7
  130. package/neural-interface/lib/assistant-dispatch.js +871 -156
  131. package/neural-interface/lib/assistant-envelope.js +3 -1
  132. package/neural-interface/lib/assistant-persona.js +80 -11
  133. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  134. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  135. package/neural-interface/lib/assistant-route-gate.js +6 -4
  136. package/neural-interface/lib/assistant-router.js +13 -8
  137. package/neural-interface/lib/assistant-runtime.js +56 -18
  138. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  139. package/neural-interface/lib/assistant-tools.js +51 -0
  140. package/neural-interface/lib/backup-service.js +620 -3
  141. package/neural-interface/lib/backup-zip-reader.js +10 -5
  142. package/neural-interface/lib/backup-zip-writer.js +257 -0
  143. package/neural-interface/lib/browser-execution.js +10 -2
  144. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  145. package/neural-interface/lib/browser-network-guard.js +284 -0
  146. package/neural-interface/lib/browser-policy-roots.js +64 -0
  147. package/neural-interface/lib/browser-tool-policy.js +186 -31
  148. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  149. package/neural-interface/lib/claude-hooks-status.js +103 -0
  150. package/neural-interface/lib/claude-temporary.js +5 -11
  151. package/neural-interface/lib/cli-install.js +18 -138
  152. package/neural-interface/lib/cli-resolver.js +4 -1
  153. package/neural-interface/lib/cli-update-planner.js +32 -31
  154. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  155. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  156. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  157. package/neural-interface/lib/confined-fs.js +30 -3
  158. package/neural-interface/lib/crash-notice-api.js +98 -0
  159. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  160. package/neural-interface/lib/exec-loop-command.js +4 -8
  161. package/neural-interface/lib/http-guards.js +8 -2
  162. package/neural-interface/lib/install-details.js +4 -1
  163. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  164. package/neural-interface/lib/mcp-client-config.js +0 -29
  165. package/neural-interface/lib/mcp-external-servers.js +323 -0
  166. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  167. package/neural-interface/lib/morelogin.js +30 -0
  168. package/neural-interface/lib/native-loop-providers.js +547 -47
  169. package/neural-interface/lib/native-loop-runtime.js +268 -41
  170. package/neural-interface/lib/opencode-config.js +557 -0
  171. package/neural-interface/lib/opencode-db-schema.js +17 -34
  172. package/neural-interface/lib/opencode-history.js +48 -218
  173. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  174. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  175. package/neural-interface/lib/opencode-protocol.js +249 -112
  176. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  177. package/neural-interface/lib/opencode-serve-records.js +39 -21
  178. package/neural-interface/lib/opencode-v2-client.js +48 -153
  179. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  180. package/neural-interface/lib/opencode-worker-data.js +27 -0
  181. package/neural-interface/lib/opencode2-client.js +73 -37
  182. package/neural-interface/lib/opencode2-proxy.js +23 -63
  183. package/neural-interface/lib/opencode2-translate.js +51 -2
  184. package/neural-interface/lib/owner-authority.js +249 -0
  185. package/neural-interface/lib/page-session.js +275 -0
  186. package/neural-interface/lib/peer-identity.js +763 -0
  187. package/neural-interface/lib/request-gate.js +17 -2
  188. package/neural-interface/lib/rulesets/api.js +1 -1
  189. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  190. package/neural-interface/lib/rulesets/installer.js +92 -27
  191. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  192. package/neural-interface/lib/session-cache-builder.js +17 -30
  193. package/neural-interface/lib/session-title-generator.js +58 -36
  194. package/neural-interface/lib/skills/api-v2.js +495 -0
  195. package/neural-interface/lib/skills/bundle.js +418 -0
  196. package/neural-interface/lib/skills/catalog.js +294 -0
  197. package/neural-interface/lib/skills/creation-api.js +191 -0
  198. package/neural-interface/lib/skills/creation-brief.js +247 -0
  199. package/neural-interface/lib/skills/creation-sources.js +267 -0
  200. package/neural-interface/lib/skills/creation.js +843 -0
  201. package/neural-interface/lib/skills/deploy.js +564 -0
  202. package/neural-interface/lib/skills/digest.js +119 -0
  203. package/neural-interface/lib/skills/discover.js +111 -0
  204. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  205. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  206. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  207. package/neural-interface/lib/skills/eval-trace.js +119 -0
  208. package/neural-interface/lib/skills/evals-api.js +212 -0
  209. package/neural-interface/lib/skills/evals.js +1573 -0
  210. package/neural-interface/lib/skills/export.js +200 -0
  211. package/neural-interface/lib/skills/frontmatter.js +64 -0
  212. package/neural-interface/lib/skills/health.js +75 -0
  213. package/neural-interface/lib/skills/json-edit.js +165 -0
  214. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  215. package/neural-interface/lib/skills/known-bridges.js +96 -0
  216. package/neural-interface/lib/skills/library.js +823 -0
  217. package/neural-interface/lib/skills/local-store.js +21 -0
  218. package/neural-interface/lib/skills/migration.js +433 -0
  219. package/neural-interface/lib/skills/operations.js +45 -0
  220. package/neural-interface/lib/skills/ownership.js +427 -0
  221. package/neural-interface/lib/skills/packages.js +88 -0
  222. package/neural-interface/lib/skills/reviews.js +212 -0
  223. package/neural-interface/lib/skills/revision.js +80 -0
  224. package/neural-interface/lib/skills/roots.js +262 -0
  225. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  226. package/neural-interface/lib/skills/scan-assets.js +252 -0
  227. package/neural-interface/lib/skills/scan-context.js +26 -0
  228. package/neural-interface/lib/skills/scan-shell.js +324 -0
  229. package/neural-interface/lib/skills/scan.js +364 -0
  230. package/neural-interface/lib/skills/scanners.js +54 -0
  231. package/neural-interface/lib/skills/service.js +522 -0
  232. package/neural-interface/lib/skills/telemetry.js +113 -0
  233. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  234. package/neural-interface/lib/tool-lists.js +124 -0
  235. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  236. package/neural-interface/lib/worker-confinement.js +1192 -0
  237. package/neural-interface/lib/worker-guard-setting.js +56 -0
  238. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  239. package/neural-interface/lib/worker-relay-ports.js +227 -0
  240. package/neural-interface/lib/worker-resume.js +229 -0
  241. package/neural-interface/lib/worker-sandbox.js +299 -0
  242. package/neural-interface/package-lock.json +18 -12
  243. package/neural-interface/package.json +2 -2
  244. package/neural-interface/public/index.html +3 -1
  245. package/neural-interface/public/index2d.html +19 -11
  246. package/neural-interface/public/onboarding.html +2 -2
  247. package/neural-interface/public/shared/account-menu.js +8 -5
  248. package/neural-interface/public/shared/agent-runtime-options.js +35 -19
  249. package/neural-interface/public/shared/api.js +1527 -1336
  250. package/neural-interface/public/shared/app-frame.js +192 -0
  251. package/neural-interface/public/shared/assistant/asst-agents-dock.js +33 -2
  252. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  253. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  254. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  255. package/neural-interface/public/shared/assistant/asst-brain-picker.js +49 -35
  256. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  257. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  258. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  259. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  260. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  261. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  262. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  263. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  264. package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
  265. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  266. package/neural-interface/public/shared/assistant/asst-render.js +401 -77
  267. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  268. package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
  269. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  270. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  271. package/neural-interface/public/shared/assistant/asst-state.js +11 -15
  272. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  273. package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
  274. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
  275. package/neural-interface/public/shared/automation-context.js +5 -2
  276. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  277. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  278. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  279. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  280. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  281. package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
  282. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  283. package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
  284. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  285. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  286. package/neural-interface/public/shared/cdx/cdx-styles.js +11 -3
  287. package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
  288. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  289. package/neural-interface/public/shared/cli-install-view.js +4 -8
  290. package/neural-interface/public/shared/cli-status.js +2 -2
  291. package/neural-interface/public/shared/constants.js +2 -2
  292. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  293. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  294. package/neural-interface/public/shared/context-menu-model.js +366 -0
  295. package/neural-interface/public/shared/context-menu.js +372 -0
  296. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  297. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  298. package/neural-interface/public/shared/desktop-update-view.js +20 -0
  299. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  300. package/neural-interface/public/shared/html-shell.js +9 -11
  301. package/neural-interface/public/shared/i18n.js +2 -0
  302. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  303. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  304. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  305. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  306. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  307. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  308. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  309. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  310. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  311. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  312. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  313. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +47 -252
  314. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  315. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  316. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +6 -21
  317. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  318. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  319. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  320. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  321. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  322. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  323. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  324. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +0 -21
  325. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  326. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +14 -47
  327. package/neural-interface/public/shared/page-session.js +96 -0
  328. package/neural-interface/public/shared/registry.js +5 -3
  329. package/neural-interface/public/shared/retired-2d.js +3 -0
  330. package/neural-interface/public/shared/schedules-view.js +195 -61
  331. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  332. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  333. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  334. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  335. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  336. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  337. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  338. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  339. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  340. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  341. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  342. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  343. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  344. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  345. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  346. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  347. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  348. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  349. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  350. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  351. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  352. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  353. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  354. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  355. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  356. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  357. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  358. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  359. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  360. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  361. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  362. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  363. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  364. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  365. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  366. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  367. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  368. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  369. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  370. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  371. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  372. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  373. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  374. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  375. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  376. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  377. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  378. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  379. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  380. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  381. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  382. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  383. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  384. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  385. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  386. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  387. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  388. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  389. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  390. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  391. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  392. package/neural-interface/public/shared/styles.css +1525 -1779
  393. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  394. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  395. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  396. package/neural-interface/public/shared/tool-list-view.js +112 -0
  397. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  398. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  399. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  400. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  401. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  402. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  403. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  404. package/neural-interface/public/shared/tour/tour.css +144 -0
  405. package/neural-interface/public/shared/ui-automation-studio.js +91 -128
  406. package/neural-interface/public/shared/ui-claude-panel.js +77 -5
  407. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  408. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  409. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  410. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  411. package/neural-interface/public/shared/ui-detail.js +15 -3
  412. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  413. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  414. package/neural-interface/public/shared/ui-menubar.js +8 -18
  415. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  416. package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
  417. package/neural-interface/public/shared/ui-navbar.js +4 -24
  418. package/neural-interface/public/shared/ui-panels.js +96 -65
  419. package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
  420. package/neural-interface/public/shared/ui-sessions.js +5 -3
  421. package/neural-interface/public/shared/ui-settings.js +594 -462
  422. package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
  423. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  424. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  425. package/neural-interface/public/shared/ui-skills.js +33 -2830
  426. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  427. package/neural-interface/public/shared/ui-sync.js +15 -5
  428. package/neural-interface/public/shared/ui-terminal.js +124 -180
  429. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  430. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  431. package/neural-interface/public/shared/ui-trash.js +6 -4
  432. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  433. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  434. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  435. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  436. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  437. package/neural-interface/public/shared/ui-update.js +38 -2
  438. package/neural-interface/public/shared/ui-whiteboard.js +311 -58
  439. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  440. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  441. package/neural-interface/public/shared/view-variant.js +66 -0
  442. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  443. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  444. package/neural-interface/public/shared/worker-end.js +10 -3
  445. package/neural-interface/public/shared/worker-restart.js +12 -0
  446. package/neural-interface/public/sidepanel-session.html +1 -1
  447. package/neural-interface/public/variant/2d/background.js +2 -1
  448. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  449. package/neural-interface/public/variant/2d/graph.js +42 -20
  450. package/neural-interface/public/variant/2d/hulls.js +14 -9
  451. package/neural-interface/public/variant/2d/lasso.js +11 -7
  452. package/neural-interface/public/variant/2d/main.js +32 -1
  453. package/neural-interface/public/variant/2d/minimap.js +11 -13
  454. package/neural-interface/public/variant/3d/main.js +69 -6
  455. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  456. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  457. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  458. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  459. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  460. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  461. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  462. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  463. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  464. package/neural-interface/scripts/build-vendor.mjs +32 -0
  465. package/neural-interface/server.js +3934 -2454
  466. package/neural-interface/templates/rulesets/core.md +1 -1
  467. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  468. package/neural-interface/templates/rulesets/manifest.json +8 -8
  469. package/npm-shrinkwrap.json +18 -12
  470. package/package.json +16 -3
  471. package/postinstall.js +9 -4
  472. package/preuninstall.js +1 -1
  473. package/setup.js +97 -322
  474. package/skills/skill-forge/SKILL.md +177 -0
  475. package/skills/skill-forge/evals/evals.json +54 -0
  476. package/skills/skill-forge/references/package.md +105 -0
  477. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  478. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  479. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  480. package/skills/synabun/SKILL.md +10 -7
  481. package/skills/synabun/modules/audit.md +1 -5
  482. package/skills/synabun/modules/changelog.md +1 -5
  483. package/skills/synabun/modules/idea.md +1 -1
  484. package/skills/synabun/modules/memorize.md +6 -9
  485. package/skills/synabun/modules/schedule.md +4 -4
  486. package/mcp-server/dist/services/profiles.d.ts +0 -120
  487. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  488. package/mcp-server/dist/services/profiles.js +0 -387
  489. package/mcp-server/dist/services/profiles.js.map +0 -1
  490. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  491. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  492. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  493. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  494. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  495. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  496. package/mcp-server/dist/tools/leonardo.js +0 -21
  497. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  498. package/mcp-server/dist/tools/profile.d.ts +0 -17
  499. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  500. package/mcp-server/dist/tools/profile.js +0 -114
  501. package/mcp-server/dist/tools/profile.js.map +0 -1
  502. package/mcp-server/src/services/profiles.ts +0 -428
  503. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  504. package/mcp-server/src/tools/leonardo.ts +0 -30
  505. package/mcp-server/src/tools/profile.ts +0 -122
  506. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  507. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  508. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  509. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  510. package/skills/leonardo/SKILL.md +0 -168
  511. package/skills/leonardo/icon.svg +0 -1
  512. package/skills/leonardo/modules/browser-guide.md +0 -378
  513. package/skills/leonardo/modules/image-prompter.md +0 -283
  514. package/skills/leonardo/modules/model-advisor.md +0 -100
  515. package/skills/leonardo/modules/prompt-library.md +0 -110
  516. package/skills/leonardo/modules/style-guide.md +0 -186
  517. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -1,3 +1,6 @@
1
+ import { migrateStoredTools } from './tool-list-storage.js';
2
+ import { wireDropdowns } from './cc-dropdown.js';
3
+ import { configureToolPickerTranslation, toolPickerHTML, readToolPicker, updateToolPicker, taskToolHost as strictToolHost, toolWord } from './tool-list-picker.js';
1
4
  // ═══════════════════════════════════════════
2
5
  // SynaBun Neural Interface — Automation Studio
3
6
  // Browse, configure, launch, and track loop automations.
@@ -18,7 +21,8 @@ import {
18
21
  import {
19
22
  CLI_PROFILES,
20
23
  ensureModelsForProfile,
21
- fetchMcpProfilePresets,
24
+ fetchToolCatalog,
25
+ getCachedToolCatalog,
22
26
  fetchCodexAccounts,
23
27
  getCachedCodexAccounts,
24
28
  getEffortLevelsForProfile,
@@ -68,6 +72,7 @@ import {
68
72
  cancelQuickTimer,
69
73
  triggerQuickTimerNow,
70
74
  } from './api.js';
75
+ import { centeredInFrame, placementArea } from './app-frame.js';
71
76
 
72
77
  const $ = (id) => document.getElementById(id);
73
78
 
@@ -180,7 +185,6 @@ const AS_ICONS = {
180
185
  claude: `<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" fill-rule="evenodd"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"/></svg>`,
181
186
  openai: `<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" fill-rule="evenodd"><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"/></svg>`,
182
187
  gemini: `<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" fill-rule="evenodd"><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"/></svg>`,
183
- leonardo: `<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M9.5 2l1.5 3.5L14.5 7l-3.5 1.5L9.5 12l-1.5-3.5L4.5 7l3.5-1.5L9.5 2zM19 10l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2zM5 17l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2z"/></svg>`,
184
188
  pin: _s('<path d="M8 14v-3"/><path d="M4 11h8"/><path d="M10.5 2.5l3 3-2 2 .5 2-4.5.5.5-4.5 2-.5z"/>'),
185
189
 
186
190
  // UI chrome
@@ -211,10 +215,10 @@ let _launchContextMode = _initialLaunchSelection.contextMode || 'default';
211
215
  storage.setItem('as-launch-model', _launchModel || '');
212
216
  storage.setItem('as-launch-context-mode', _launchContextMode);
213
217
  let _launchEffort = storage.getItem('as-launch-effort') || 'off';
214
- let _launchMcpProfile = storage.getItem('as-launch-mcp-profile') || 'full';
218
+ let _launchTools = (() => { try { return JSON.parse(storage.getItem('as-launch-tools') || 'null'); } catch { return null; } })();
215
219
  let _launchAccount = storage.getItem('as-launch-account') || 'default'; // Codex ChatGPT account (CODEX_HOME)
216
220
  let _qtAccountsRequested = false; // lazy-fetch guard for quick-timer account chips
217
- let _mcpProfilePresets = null; // cached presets from API
221
+ let _dropdownAbort = null;
218
222
 
219
223
  // Render the Codex account selector chips (one button per saved ChatGPT account).
220
224
  function renderAccountChips(selectedId) {
@@ -264,34 +268,17 @@ function loadLaunchAccounts(root) {
264
268
  }).catch(() => {});
265
269
  }
266
270
 
267
- async function fetchMcpProfiles() {
268
- if (_mcpProfilePresets) return _mcpProfilePresets;
269
- try {
270
- const presets = await fetchMcpProfilePresets();
271
- if (presets && Object.keys(presets).length) {
272
- _mcpProfilePresets = presets;
273
- return _mcpProfilePresets;
274
- }
275
- } catch {}
276
- return {};
277
- }
278
-
279
- function renderMcpProfileChips(presets, selected) {
280
- const entries = Object.entries(presets);
281
- if (entries.length > 5) {
282
- const options = entries.map(([id, p]) => ({
283
- id,
284
- label: p.label || id,
285
- desc: `${p.tools} tools`,
286
- }));
287
- return renderLaunchSelect('mcp', options, selected);
288
- }
289
- return entries.map(([id, p]) => `
290
- <button class="as-launch-mcp-profile${id === selected ? ' active' : ''}" data-mcp-profile="${_escLaunch(id)}">
291
- <span class="as-launch-mcp-profile-name">${_escLaunch(p.label || id)}</span>
292
- <span class="as-launch-mcp-profile-tools">${_escLaunch(p.tools)} tools</span>
293
- </button>
294
- `).join('');
271
+ async function renderLaunchToolPicker(root, provider) {
272
+ let catalog = await fetchToolCatalog(false, { cwd: _pendingLaunchParams?.cwd || '' });
273
+ if (_launchMode === 'agent' && !root.querySelector('#as-agent-synabun')?.checked && catalog) catalog = { ...catalog, defaultTools: [] };
274
+ const container = root.querySelector('#as-launch-tools');
275
+ if (!container) return;
276
+ container.innerHTML = strictToolHost(provider) ? toolPickerHTML('as-launch-tool-list', _launchTools, { catalog, provider, inheritLabel: toolWord('default'), usesBrowser: !!_pendingLaunchParams?.usesBrowser }) : toolWord('focus');
277
+ container.querySelector('#as-launch-tool-list')?.addEventListener('change', (event) => {
278
+ _launchTools = readToolPicker(event.target);
279
+ storage.setItem('as-launch-tools', JSON.stringify(_launchTools));
280
+ updateToolPicker(event.target, _launchTools, { inheritLabel: toolWord('default'), usesBrowser: !!_pendingLaunchParams?.usesBrowser });
281
+ });
295
282
  }
296
283
 
297
284
  // ── Preset Templates with Wizard Steps ──
@@ -894,7 +881,7 @@ function showLaunchInline(params) {
894
881
  if (params.usesBrowser && (!params.context || !params.context.includes('BROWSER REQUIRED'))) {
895
882
  params.context = BROWSER_CONTEXT;
896
883
  }
897
- // Apply template-preset launch defaults (CLI / model / effort / MCP profile)
884
+ // Apply template-preset launch defaults (CLI / model / effort / tool list)
898
885
  if (params.profile) {
899
886
  if (params.profile !== _launchProfile && !params.model) {
900
887
  _launchModel = null;
@@ -910,7 +897,7 @@ function showLaunchInline(params) {
910
897
  storage.setItem('as-launch-model', _launchModel || '');
911
898
  }
912
899
  if (params.effort) { _launchEffort = params.effort; storage.setItem('as-launch-effort', _launchEffort); }
913
- if (params.mcpProfile) { _launchMcpProfile = params.mcpProfile; storage.setItem('as-launch-mcp-profile', _launchMcpProfile); }
900
+ if (params.tools !== undefined) { _launchTools = params.tools; storage.setItem('as-launch-tools', JSON.stringify(_launchTools)); }
914
901
  if (params.codexAccountId) { _launchAccount = params.codexAccountId; storage.setItem('as-launch-account', _launchAccount); }
915
902
  _pendingLaunchParams = params;
916
903
  _launchPanelActive = true;
@@ -985,11 +972,9 @@ function showLaunchInline(params) {
985
972
  ${renderEffortChips(profile, _launchEffort)}
986
973
  </div>
987
974
  </div>
988
- <div class="as-launch-section" id="as-launch-mcp-section" style="${profile !== 'claude-code' ? '' : 'display:none'}">
989
- <label class="as-launch-label">MCP Profile</label>
990
- <div class="as-launch-mcp-profiles" id="as-launch-mcp-profiles">
991
- <span class="as-launch-mcp-loading">Loading profiles...</span>
992
- </div>
975
+ <div class="as-launch-section" id="as-launch-tools-section">
976
+ <label class="as-launch-label">${toolWord('label')}</label>
977
+ <div id="as-launch-tools">${strictToolHost(profile) ? '' : toolWord('focus')}</div>
993
978
  </div>
994
979
  <div class="as-launch-section" id="as-launch-account-section" style="${profile === 'codex' ? '' : 'display:none'}">
995
980
  <label class="as-launch-label">OpenAI Account</label>
@@ -1056,16 +1041,7 @@ function showLaunchInline(params) {
1056
1041
 
1057
1042
  wireLaunchInline(contentEl);
1058
1043
 
1059
- // Async-load MCP profiles for codex/gemini
1060
- if (profile !== 'claude-code') {
1061
- fetchMcpProfiles().then(presets => {
1062
- const container = contentEl.querySelector('#as-launch-mcp-profiles');
1063
- if (container && presets && Object.keys(presets).length) {
1064
- container.innerHTML = renderMcpProfileChips(presets, _launchMcpProfile);
1065
- wireMcpProfileChips(contentEl);
1066
- }
1067
- });
1068
- }
1044
+ void renderLaunchToolPicker(contentEl, profile);
1069
1045
 
1070
1046
  // Async-load dynamic models and re-render chips when ready.
1071
1047
  // Retries a couple of times in case OpenCode is still booting.
@@ -1347,6 +1323,7 @@ function wireLaunchInline(container) {
1347
1323
  const root = container.querySelector('.as-launch-inline');
1348
1324
  if (!root) return;
1349
1325
  applyAgentModeGating(root, _launchProfile);
1326
+ root.querySelector('#as-agent-synabun')?.addEventListener('change', () => { void renderLaunchToolPicker(root, _launchProfile); });
1350
1327
 
1351
1328
  // Mode toggle (Loop vs Agent)
1352
1329
  root.querySelectorAll('.as-launch-mode').forEach(btn => {
@@ -1360,6 +1337,7 @@ function wireLaunchInline(container) {
1360
1337
  if (agentFields) agentFields.style.display = _launchMode === 'agent' ? '' : 'none';
1361
1338
  const confirmBtn = root.querySelector('#as-launch-confirm-btn');
1362
1339
  if (confirmBtn) confirmBtn.textContent = _launchMode === 'agent' ? 'Launch Agent' : 'Launch';
1340
+ void renderLaunchToolPicker(root, _launchProfile);
1363
1341
  });
1364
1342
  });
1365
1343
 
@@ -1419,20 +1397,7 @@ function wireLaunchInline(container) {
1419
1397
  }
1420
1398
  }
1421
1399
  applyAgentModeGating(root, profileId);
1422
- // Show/hide MCP profile section (Codex/Gemini only — Claude Code has tool search)
1423
- const mcpSection = root.querySelector('#as-launch-mcp-section');
1424
- if (mcpSection) {
1425
- mcpSection.style.display = profileId !== 'claude-code' ? '' : 'none';
1426
- if (profileId !== 'claude-code') {
1427
- fetchMcpProfiles().then(presets => {
1428
- const container = root.querySelector('#as-launch-mcp-profiles');
1429
- if (container && presets && Object.keys(presets).length) {
1430
- container.innerHTML = renderMcpProfileChips(presets, _launchMcpProfile);
1431
- wireMcpProfileChips(root);
1432
- }
1433
- });
1434
- }
1435
- }
1400
+ void renderLaunchToolPicker(root, profileId);
1436
1401
  // Show/hide OpenAI account section (Codex only — selects which ChatGPT login the loop runs under)
1437
1402
  const accountSection = root.querySelector('#as-launch-account-section');
1438
1403
  if (accountSection) {
@@ -1496,21 +1461,6 @@ function wireEffortChips(container) {
1496
1461
  });
1497
1462
  }
1498
1463
 
1499
- function wireMcpProfileChips(container) {
1500
- container.querySelectorAll('.as-launch-mcp-profile').forEach(btn => {
1501
- btn.addEventListener('click', () => {
1502
- container.querySelectorAll('.as-launch-mcp-profile').forEach(b => b.classList.remove('active'));
1503
- btn.classList.add('active');
1504
- _launchMcpProfile = btn.dataset.mcpProfile;
1505
- storage.setItem('as-launch-mcp-profile', _launchMcpProfile);
1506
- });
1507
- });
1508
- wireLaunchSelect(container, 'mcp', (value) => {
1509
- _launchMcpProfile = value;
1510
- storage.setItem('as-launch-mcp-profile', _launchMcpProfile);
1511
- });
1512
- }
1513
-
1514
1464
  function closeLaunchInline() {
1515
1465
  _pendingLaunchParams = null;
1516
1466
  _launchPanelActive = false;
@@ -1534,7 +1484,7 @@ async function confirmLaunch() {
1534
1484
  return;
1535
1485
  }
1536
1486
  const effort = normalizeEffortForProfile(_launchProfile, _launchEffort) || undefined;
1537
- const mcpProfile = _launchProfile !== 'claude-code' ? _launchMcpProfile : undefined;
1487
+ const tools = strictToolHost(_launchProfile) ? _launchTools : undefined;
1538
1488
  const codexAccountId = _launchProfile === 'codex' ? (_launchAccount || 'default') : undefined;
1539
1489
  const params = {
1540
1490
  ..._pendingLaunchParams,
@@ -1542,7 +1492,7 @@ async function confirmLaunch() {
1542
1492
  model: _launchModel,
1543
1493
  contextMode: _launchContextMode,
1544
1494
  effort,
1545
- mcpProfile,
1495
+ tools,
1546
1496
  codexAccountId,
1547
1497
  sidepanelWindowId: getNativeLoopRouterWindowId(),
1548
1498
  sidepanelClaimToken: getNativeLoopRouterClaimToken(),
@@ -1571,6 +1521,7 @@ async function confirmLaunch() {
1571
1521
  cwd: params.cwd || undefined,
1572
1522
  maxTurns: params.usesBrowser ? 100 : 75,
1573
1523
  withSynabun,
1524
+ tools: tools ?? (withSynabun ? getCachedToolCatalog()?.defaultTools ?? ['mcp:*'] : []),
1574
1525
  browserProfile: (withSynabun && params.usesBrowser) ? true : undefined,
1575
1526
  mode: agentSubmode,
1576
1527
  iterations: agentSubmode === 'loop' ? agentIterations : 1,
@@ -1758,14 +1709,31 @@ async function openPanel(opts = {}) {
1758
1709
  document.body.appendChild(_backdrop);
1759
1710
 
1760
1711
  _panel = document.createElement('div');
1712
+ _dropdownAbort?.abort();
1713
+ _dropdownAbort = new AbortController();
1714
+ wireDropdowns(_panel, { signal: _dropdownAbort.signal });
1715
+ _panel.addEventListener('change', event => {
1716
+ if (event.target.id === 'as-qt-tools') {
1717
+ _launchTools = readToolPicker(event.target);
1718
+ storage.setItem('as-launch-tools', JSON.stringify(_launchTools));
1719
+ updateToolPicker(event.target, _launchTools, { inheritLabel: toolWord('templateDefault'), usesBrowser: !!$('as-qt-browser')?.checked });
1720
+ }
1721
+ if (['as-qt-browser', 'as-qt-template', 'as-f-browser'].includes(event.target.id)) queueMicrotask(() => {
1722
+ const detail = event.target.id === 'as-f-browser';
1723
+ const input = $(detail ? 'as-f-mcp' : 'as-qt-tools');
1724
+ updateToolPicker(input, readToolPicker(input, { requested: true }), { inheritLabel: toolWord(detail ? 'default' : 'templateDefault'), usesBrowser: !!$(detail ? 'as-f-browser' : 'as-qt-browser')?.checked });
1725
+ });
1726
+ }, { signal: _dropdownAbort.signal });
1727
+ void fetchToolCatalog();
1761
1728
  _panel.className = 'automation-studio-panel glass resizable';
1762
1729
  _panel.id = 'automation-studio-panel';
1763
1730
  _panel.innerHTML = buildPanelHTML();
1764
1731
  document.body.appendChild(_panel);
1765
1732
 
1766
- // Always open centered at default size
1767
- _panel.style.left = Math.max(20, (window.innerWidth - 900) / 2) + 'px';
1768
- _panel.style.top = Math.max(48, (window.innerHeight - 520) / 2) + 'px';
1733
+ // Always open centered at default size, in the app frame
1734
+ const at = centeredInFrame(900, 520);
1735
+ _panel.style.left = at.left + 'px';
1736
+ _panel.style.top = at.top + 'px';
1769
1737
 
1770
1738
  wirePanel();
1771
1739
  const kept = _keptData;
@@ -1815,6 +1783,7 @@ function closePanel() {
1815
1783
  for (const [evt, fn] of _docListeners) document.removeEventListener(evt, fn);
1816
1784
  _docListeners = [];
1817
1785
  if (_backdrop) { _backdrop.remove(); _backdrop = null; }
1786
+ _dropdownAbort?.abort();
1818
1787
  _panel.remove(); _panel = null;
1819
1788
  _templates = []; _activeLoop = null;
1820
1789
  _view = 'welcome'; _selected = null;
@@ -2178,11 +2147,12 @@ function positionFloating(el, x, y) {
2178
2147
  el.style.left = `${x}px`;
2179
2148
  el.style.top = `${y}px`;
2180
2149
  el.style.zIndex = '300010';
2181
- // Adjust after mounting to keep in viewport
2150
+ // Adjust after mounting to keep in the app frame (the window for a point outside it)
2182
2151
  requestAnimationFrame(() => {
2183
2152
  const r = el.getBoundingClientRect();
2184
- if (r.right > window.innerWidth - 8) el.style.left = `${Math.max(8, window.innerWidth - r.width - 8)}px`;
2185
- if (r.bottom > window.innerHeight - 8) el.style.top = `${Math.max(8, window.innerHeight - r.height - 8)}px`;
2153
+ const b = placementArea(x, y);
2154
+ if (r.right > b.right - 8) el.style.left = `${Math.max(b.left + 8, b.right - r.width - 8)}px`;
2155
+ if (r.bottom > b.bottom - 8) el.style.top = `${Math.max(b.top + 8, b.bottom - r.height - 8)}px`;
2186
2156
  });
2187
2157
  }
2188
2158
 
@@ -2364,6 +2334,8 @@ async function promptCreateFolder() {
2364
2334
  // ═══════════════════════════════════════════
2365
2335
 
2366
2336
  async function loadData() {
2337
+ _launchTools = await migrateStoredTools(storage, 'as-launch-tools', 'as-launch-mcp-profile');
2338
+ await fetchToolCatalog();
2367
2339
  // One round trip for the three lists (they were asked one after another), then the agents.
2368
2340
  const [templates, folders, active] = await Promise.allSettled([fetchLoopTemplates(), fetchLoopFolders(), fetchActiveLoop()]);
2369
2341
  _templates = templates.status === 'fulfilled' ? templates.value : [];
@@ -2721,7 +2693,7 @@ function buildDetailMeta(t, isPreset) {
2721
2693
  const tModel = (t.model && tModelsList.some(m => modelMatchesSelector(m, t.model))) ? normalizeAutomationSelection(tProfile, t.model).model : (modelSelectorValue(tDefaultModel) || '');
2722
2694
  const tContextMode = t.contextMode || normalizeAutomationSelection(tProfile, t.model).contextMode || 'default';
2723
2695
  const tEffort = t.effort || 'off';
2724
- const tMcp = t.mcpProfile || 'full';
2696
+ const tTools = t.tools ?? null;
2725
2697
  return `
2726
2698
  <div class="as-meta-section">
2727
2699
  <div class="as-field">
@@ -2838,11 +2810,9 @@ function buildDetailMeta(t, isPreset) {
2838
2810
  ${getEffortLevelsForProfile(tProfile).map(e => `<option value="${esc(e.id)}"${e.id === tEffort ? ' selected' : ''}>${esc(e.label)} \u2014 ${esc(e.desc)}</option>`).join('')}
2839
2811
  </select>
2840
2812
  </div>
2841
- <div class="as-runtime-field" id="as-f-mcp-field" style="${tProfile !== 'claude-code' ? '' : 'display:none'}">
2842
- <label>MCP</label>
2843
- <select class="as-input as-select" id="as-f-mcp">
2844
- <option value="${esc(tMcp)}" selected>${esc(tMcp)} (loading\u2026)</option>
2845
- </select>
2813
+ <div class="as-runtime-field" id="as-f-mcp-field">
2814
+ <label>${toolWord('label')}</label>
2815
+ ${strictToolHost(tProfile) ? toolPickerHTML('as-f-mcp', tTools, { provider: tProfile, inheritLabel: toolWord('default'), usesBrowser: t.usesBrowser }) : toolWord('focus')}
2846
2816
  </div>
2847
2817
  </div>
2848
2818
  </div>
@@ -2901,7 +2871,7 @@ function wireDetailView(isPreset) {
2901
2871
  wireCategoryPicker(isPreset);
2902
2872
  wireFolderPicker(isPreset);
2903
2873
 
2904
- // Launch defaults (CLI profile / model / effort / MCP profile)
2874
+ // Launch defaults (CLI profile / model / effort / tool list)
2905
2875
  wireLaunchDefaults(isPreset);
2906
2876
 
2907
2877
  // Markdown toolbar
@@ -3050,7 +3020,7 @@ function wireLaunchDefaults(isPreset) {
3050
3020
  const modelSel = $('as-f-model');
3051
3021
  const contextSel = $('as-f-context');
3052
3022
  const effortSel = $('as-f-effort');
3053
- const mcpSel = $('as-f-mcp');
3023
+ let mcpSel = $('as-f-mcp');
3054
3024
  const effortField = $('as-f-effort-field');
3055
3025
  const mcpField = $('as-f-mcp-field');
3056
3026
  const templateAccountId = _selected?.codexAccountId || 'default';
@@ -3058,23 +3028,14 @@ function wireLaunchDefaults(isPreset) {
3058
3028
 
3059
3029
  effortSel?.addEventListener('change', () => { if (!isPreset) markDirty(); });
3060
3030
 
3061
- const loadMcpOptions = () => {
3062
- if (!mcpSel) return;
3063
- const current = mcpSel.value || 'full';
3064
- fetchMcpProfiles().then(presets => {
3065
- if (!presets || !Object.keys(presets).length) return;
3066
- const opts = Object.entries(presets).map(([id, p]) => {
3067
- const label = p.label || id;
3068
- const tools = p.tools != null ? ` — ${p.tools} tools` : '';
3069
- const sel = id === current ? ' selected' : '';
3070
- return `<option value="${esc(id)}"${sel}>${esc(label)}${esc(tools)}</option>`;
3071
- }).join('');
3072
- mcpSel.innerHTML = opts;
3073
- if (!presets[current]) {
3074
- const first = Object.keys(presets)[0];
3075
- if (first) mcpSel.value = first;
3076
- }
3077
- });
3031
+ const loadToolOptions = async () => {
3032
+ const tools = mcpSel ? readToolPicker(mcpSel) : _selected?.tools ?? null;
3033
+ const catalog = await fetchToolCatalog();
3034
+ if (!mcpField?.isConnected) return;
3035
+ const provider = profileSel.value;
3036
+ mcpField.innerHTML = `<label>${toolWord('label')}</label>${strictToolHost(provider) ? toolPickerHTML('as-f-mcp', tools, { catalog, provider, inheritLabel: toolWord('default'), usesBrowser: !!$('as-f-browser')?.checked }) : toolWord('focus')}`;
3037
+ mcpSel = $('as-f-mcp');
3038
+ mcpSel?.addEventListener('change', () => { if (!isPreset) markDirty(); updateToolPicker(mcpSel, readToolPicker(mcpSel), { inheritLabel: toolWord('default'), usesBrowser: !!$('as-f-browser')?.checked }); });
3078
3039
  };
3079
3040
 
3080
3041
  const renderModelOptions = (profileId, preferredId) => {
@@ -3124,8 +3085,7 @@ function wireLaunchDefaults(isPreset) {
3124
3085
  renderEffortOptions(profileId, 'off');
3125
3086
  if (effortField) effortField.style.display = profileSupportsEffort(profileId) ? '' : 'none';
3126
3087
  if (mcpField) {
3127
- mcpField.style.display = profileId !== 'claude-code' ? '' : 'none';
3128
- if (profileId !== 'claude-code') loadMcpOptions();
3088
+ void loadToolOptions();
3129
3089
  }
3130
3090
  if (!isPreset) markDirty();
3131
3091
  });
@@ -3137,7 +3097,7 @@ function wireLaunchDefaults(isPreset) {
3137
3097
  contextSel?.addEventListener('change', () => { if (!isPreset) markDirty(); });
3138
3098
  mcpSel?.addEventListener('change', () => { if (!isPreset) markDirty(); });
3139
3099
 
3140
- if (profileSel.value !== 'claude-code') loadMcpOptions();
3100
+ void loadToolOptions();
3141
3101
  renderEffortOptions(profileSel.value, effortSel?.value || 'off');
3142
3102
  if (effortField) effortField.style.display = profileSupportsEffort(profileSel.value) ? '' : 'none';
3143
3103
  refreshDynamicModelOptionsIfNeeded(profileSel.value, modelSel?.value || null);
@@ -3175,7 +3135,7 @@ async function saveCurrentTemplate() {
3175
3135
  const model = $('as-f-model')?.value || null;
3176
3136
  const contextMode = $('as-f-context')?.value || 'default';
3177
3137
  const effort = normalizeEffortForProfile(profile || 'claude-code', $('as-f-effort')?.value || null);
3178
- const mcpProfile = profile && profile !== 'claude-code' ? ($('as-f-mcp')?.value || null) : null;
3138
+ const tools = strictToolHost(profile) ? ($('as-f-mcp') ? readToolPicker($('as-f-mcp')) : _selected?.tools ?? null) : null;
3179
3139
  const folderIdRaw = $('as-f-folder')?.value;
3180
3140
  const folderId = folderIdRaw ? folderIdRaw : null;
3181
3141
 
@@ -3188,7 +3148,7 @@ async function saveCurrentTemplate() {
3188
3148
  showToast('This context window is unavailable for the selected model'); return;
3189
3149
  }
3190
3150
 
3191
- const payload = { name, icon: iconKey, category, task, context: '', description: description || task.slice(0, 120), iterations, maxMinutes, usesBrowser, profile, model, contextMode, effort, mcpProfile, folderId };
3151
+ const payload = { name, icon: iconKey, category, task, context: '', description: description || task.slice(0, 120), iterations, maxMinutes, usesBrowser, profile, model, contextMode, effort, tools, folderId };
3192
3152
 
3193
3153
  try {
3194
3154
  if (_selected.id) { await updateLoopTemplate(_selected.id, payload); }
@@ -3295,7 +3255,7 @@ async function customizePreset(preset) {
3295
3255
  model: $('as-f-model')?.value || null,
3296
3256
  contextMode: $('as-f-context')?.value || 'default',
3297
3257
  effort: normalizeEffortForProfile($('as-f-profile')?.value || 'claude-code', $('as-f-effort')?.value || null),
3298
- mcpProfile: ($('as-f-profile')?.value || 'claude-code') !== 'claude-code' ? ($('as-f-mcp')?.value || null) : null,
3258
+ tools: strictToolHost($('as-f-profile')?.value) ? readToolPicker($('as-f-mcp')) : null,
3299
3259
  };
3300
3260
  const result = await createLoopTemplate(payload);
3301
3261
  if (result?.id) {
@@ -3322,13 +3282,13 @@ function handleTestRun() {
3322
3282
  const model = $('as-f-model')?.value || _selected.model || null;
3323
3283
  const contextMode = $('as-f-context')?.value || _selected.contextMode || 'default';
3324
3284
  const effort = normalizeEffortForProfile(profile || 'claude-code', $('as-f-effort')?.value || _selected.effort || null);
3325
- const mcpProfile = profile && profile !== 'claude-code' ? ($('as-f-mcp')?.value || _selected.mcpProfile || null) : null;
3285
+ const tools = strictToolHost(profile) ? ($('as-f-mcp') ? readToolPicker($('as-f-mcp')) : _selected?.tools ?? null) : null;
3326
3286
  serverLaunchLoop({
3327
3287
  task: cmd,
3328
3288
  context: null,
3329
3289
  iterations: 1, maxMinutes: 10,
3330
3290
  usesBrowser,
3331
- profile, model, contextMode, effort, mcpProfile,
3291
+ profile, model, contextMode, effort, tools,
3332
3292
  });
3333
3293
  }
3334
3294
 
@@ -3357,12 +3317,12 @@ function proceedWithLaunch() {
3357
3317
  const model = $('as-f-model')?.value || _selected.model || null;
3358
3318
  const contextMode = $('as-f-context')?.value || _selected.contextMode || 'default';
3359
3319
  const effort = normalizeEffortForProfile(profile || 'claude-code', $('as-f-effort')?.value || _selected.effort || null);
3360
- const mcpProfile = profile && profile !== 'claude-code' ? ($('as-f-mcp')?.value || _selected.mcpProfile || null) : null;
3320
+ const tools = strictToolHost(profile) ? ($('as-f-mcp') ? readToolPicker($('as-f-mcp')) : _selected?.tools ?? null) : null;
3361
3321
  serverLaunchLoop({
3362
3322
  task: cmd,
3363
3323
  context: null,
3364
3324
  iterations, maxMinutes, usesBrowser,
3365
- profile, model, contextMode, effort, mcpProfile,
3325
+ profile, model, contextMode, effort, tools,
3366
3326
  });
3367
3327
  }
3368
3328
 
@@ -3960,7 +3920,7 @@ function setupScheduleWebSocket() {
3960
3920
  // Quick timer events
3961
3921
  on('sync:quick-timer:set', (data) => {
3962
3922
  if (data?.timerId && !_quickTimers.some(t => t.id === data.timerId)) {
3963
- _quickTimers.push({ id: data.timerId, templateName: data.templateName, firesAt: data.firesAt, minutes: data.minutes, profile: data.profile, model: data.model, contextMode: data.contextMode, effort: data.effort, mcpProfile: data.mcpProfile, usesBrowser: data.usesBrowser });
3923
+ _quickTimers.push({ id: data.timerId, templateName: data.templateName, firesAt: data.firesAt, minutes: data.minutes, profile: data.profile, model: data.model, contextMode: data.contextMode, effort: data.effort, tools: data.tools, usesBrowser: data.usesBrowser });
3964
3924
  if (_view === 'schedules') renderSchedulesMain();
3965
3925
  }
3966
3926
  });
@@ -4419,13 +4379,13 @@ async function handlePanelClick(e) {
4419
4379
  if (!automationContextAvailable(qtProfile, qtModel, qtContextMode)) { showToast('This context window is unavailable for the selected model and account'); break; }
4420
4380
  const qtBrowser = !!$('as-qt-browser')?.checked;
4421
4381
  const qtEffort = normalizeEffortForProfile(qtProfile, _launchEffort) || undefined;
4422
- const qtMcpProfile = qtProfile !== 'claude-code' ? _launchMcpProfile : undefined;
4382
+ const qtTools = strictToolHost(qtProfile) ? readToolPicker($('as-qt-tools')) : undefined;
4423
4383
  const qtAccount = qtProfile === 'codex' ? (_launchAccount || 'default') : undefined;
4424
4384
  try {
4425
- const result = await createQuickTimer(templateId, mins, { profile: qtProfile, model: qtModel, contextMode: qtContextMode, usesBrowser: qtBrowser, effort: qtEffort, mcpProfile: qtMcpProfile, codexAccountId: qtAccount });
4385
+ const result = await createQuickTimer(templateId, mins, { profile: qtProfile, model: qtModel, contextMode: qtContextMode, usesBrowser: qtBrowser, effort: qtEffort, tools: qtTools, codexAccountId: qtAccount });
4426
4386
  // Guard: WebSocket sync:quick-timer:set may arrive before this HTTP response
4427
4387
  if (!_quickTimers.some(t => t.id === result.timerId)) {
4428
- _quickTimers.push({ id: result.timerId, templateId, templateName: result.templateName, firesAt: result.firesAt, minutes: result.minutes, profile: result.profile, model: result.model, contextMode: result.contextMode, effort: result.effort, mcpProfile: result.mcpProfile, usesBrowser: result.usesBrowser });
4388
+ _quickTimers.push({ id: result.timerId, templateId, templateName: result.templateName, firesAt: result.firesAt, minutes: result.minutes, profile: result.profile, model: result.model, contextMode: result.contextMode, effort: result.effort, tools: result.tools, usesBrowser: result.usesBrowser });
4429
4389
  }
4430
4390
  _selectedQtMinutes = null;
4431
4391
  _qtUsesBrowser = null;
@@ -4446,7 +4406,7 @@ async function handlePanelClick(e) {
4446
4406
  if (!automationContextAvailable(qtProfile, qtModel, qtContextMode)) { showToast('This context window is unavailable for the selected model and account'); break; }
4447
4407
  const qtBrowser = !!$('as-qt-browser')?.checked;
4448
4408
  const qtEffort = normalizeEffortForProfile(qtProfile, _launchEffort) || undefined;
4449
- const qtMcpProfile = qtProfile !== 'claude-code' ? _launchMcpProfile : undefined;
4409
+ const qtTools = strictToolHost(qtProfile) ? readToolPicker($('as-qt-tools')) : undefined;
4450
4410
  const qtAccount = qtProfile === 'codex' ? (_launchAccount || 'default') : undefined;
4451
4411
  try {
4452
4412
  const result = await triggerQuickTimerNow(templateId, {
@@ -4455,7 +4415,7 @@ async function handlePanelClick(e) {
4455
4415
  contextMode: qtContextMode,
4456
4416
  usesBrowser: qtBrowser,
4457
4417
  effort: qtEffort,
4458
- mcpProfile: qtMcpProfile,
4418
+ tools: qtTools,
4459
4419
  codexAccountId: qtAccount,
4460
4420
  sidepanelWindowId: getNativeLoopRouterWindowId(),
4461
4421
  sidepanelClaimToken: getNativeLoopRouterClaimToken(),
@@ -4728,7 +4688,7 @@ function renderSchedulesMain() {
4728
4688
  const profileLabel = CLI_PROFILES.find(p => p.id === qt.profile)?.label || qt.profile || 'Claude Code';
4729
4689
  const modelObj = qt.model ? getModelsForProfile(qt.profile || 'claude-code').find(m => modelMatchesSelector(m, qt.model)) : null;
4730
4690
  const modelLabel = modelObj?.label || (qt.profile === 'opencode' ? qt.model : '');
4731
- const metaParts = [profileLabel, modelLabel, qt.contextMode && qt.contextMode !== 'default' ? `context:${qt.contextMode}` : '', qt.effort ? `think:${qt.effort}` : '', qt.mcpProfile ? `mcp:${qt.mcpProfile}` : '', qt.usesBrowser ? 'Browser' : ''].filter(Boolean);
4691
+ const metaParts = [profileLabel, modelLabel, qt.contextMode && qt.contextMode !== 'default' ? `context:${qt.contextMode}` : '', qt.effort ? `think:${qt.effort}` : '', qt.tools ? `${toolWord('label')}: ${qt.tools.join(', ')}` : '', qt.usesBrowser ? 'Browser' : ''].filter(Boolean);
4732
4692
  timerCards += `
4733
4693
  <div class="as-qt-active-card">
4734
4694
  <div class="as-qt-active-pulse"></div>
@@ -4834,6 +4794,7 @@ function renderSchedulesMain() {
4834
4794
  <span class="as-launch-label">Think</span>
4835
4795
  <div class="as-launch-efforts" id="as-qt-efforts">${qtEffortChips}</div>
4836
4796
  </div>
4797
+ <div class="as-qt-group"><label>${toolWord('label')}</label>${strictToolHost(qtProfile) ? toolPickerHTML('as-qt-tools', _launchTools, { provider: qtProfile, inheritLabel: toolWord('templateDefault'), usesBrowser: qtBrowserDefault }) : toolWord('focus')}</div>
4837
4798
  <div class="as-qt-group" id="as-qt-account-section" style="${qtProfile === 'codex' ? '' : 'display:none'}">
4838
4799
  <span class="as-launch-label">OpenAI Account</span>
4839
4800
  <div class="as-launch-accounts" id="as-qt-accounts">${qtAccountChips}</div>
@@ -5143,3 +5104,5 @@ function triggerImport() {
5143
5104
  document.body.appendChild(input);
5144
5105
  input.click();
5145
5106
  }
5107
+
5108
+ configureToolPickerTranslation(t);