@withbuddi/buddi 0.1.0-pre.38 → 0.1.0-pre.39

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 (253) hide show
  1. package/extension/background.js +635 -21
  2. package/extension/manifest.json +2 -2
  3. package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
  4. package/node_modules/@buddi/cli/dist/access-cmd.d.ts +1 -1
  5. package/node_modules/@buddi/cli/dist/access-cmd.d.ts.map +1 -1
  6. package/node_modules/@buddi/cli/dist/access-cmd.js +23 -3
  7. package/node_modules/@buddi/cli/dist/access-cmd.js.map +1 -1
  8. package/node_modules/@buddi/cli/dist/args.d.ts +2 -2
  9. package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
  10. package/node_modules/@buddi/cli/dist/args.js +7 -2
  11. package/node_modules/@buddi/cli/dist/args.js.map +1 -1
  12. package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
  13. package/node_modules/@buddi/cli/dist/commands.js +11 -0
  14. package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
  15. package/node_modules/@buddi/cli/dist/main.d.ts.map +1 -1
  16. package/node_modules/@buddi/cli/dist/main.js +2 -1
  17. package/node_modules/@buddi/cli/dist/main.js.map +1 -1
  18. package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
  19. package/node_modules/@buddi/gateway/dist/missions/ask-cap.d.ts +26 -0
  20. package/node_modules/@buddi/gateway/dist/missions/ask-cap.d.ts.map +1 -0
  21. package/node_modules/@buddi/gateway/dist/missions/ask-cap.js +83 -0
  22. package/node_modules/@buddi/gateway/dist/missions/ask-cap.js.map +1 -0
  23. package/node_modules/@buddi/gateway/dist/missions/execute.d.ts +12 -1
  24. package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
  25. package/node_modules/@buddi/gateway/dist/missions/execute.js +73 -11
  26. package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
  27. package/node_modules/@buddi/gateway/dist/missions/parked.d.ts +6 -0
  28. package/node_modules/@buddi/gateway/dist/missions/parked.d.ts.map +1 -1
  29. package/node_modules/@buddi/gateway/dist/missions/parked.js +7 -1
  30. package/node_modules/@buddi/gateway/dist/missions/parked.js.map +1 -1
  31. package/node_modules/@buddi/gateway/dist/serve.js +1 -1
  32. package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
  33. package/node_modules/@buddi/gateway/dist/system-context.d.ts +7 -0
  34. package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
  35. package/node_modules/@buddi/gateway/dist/system-context.js +8 -0
  36. package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
  37. package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
  38. package/node_modules/@buddi/gateway/dist/web/api-routes.js +11 -3
  39. package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
  40. package/node_modules/@buddi/gateway/dist/web/extension.d.ts +13 -1
  41. package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
  42. package/node_modules/@buddi/gateway/dist/web/extension.js +125 -5
  43. package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
  44. package/node_modules/@buddi/gateway/dist/web/remote-hand.d.ts.map +1 -1
  45. package/node_modules/@buddi/gateway/dist/web/remote-hand.js +45 -2
  46. package/node_modules/@buddi/gateway/dist/web/remote-hand.js.map +1 -1
  47. package/node_modules/@buddi/gateway/dist/web/secrets.d.ts +26 -1
  48. package/node_modules/@buddi/gateway/dist/web/secrets.d.ts.map +1 -1
  49. package/node_modules/@buddi/gateway/dist/web/secrets.js +66 -3
  50. package/node_modules/@buddi/gateway/dist/web/secrets.js.map +1 -1
  51. package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
  52. package/node_modules/@buddi/gateway/dist/web/server.js +63 -7
  53. package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
  54. package/node_modules/@buddi/gateway/dist/web/version.d.ts +2 -0
  55. package/node_modules/@buddi/gateway/dist/web/version.d.ts.map +1 -1
  56. package/node_modules/@buddi/gateway/dist/web/version.js +5 -1
  57. package/node_modules/@buddi/gateway/dist/web/version.js.map +1 -1
  58. package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
  59. package/node_modules/@buddi/install/dist/app-layout.d.ts +127 -0
  60. package/node_modules/@buddi/install/dist/app-layout.d.ts.map +1 -0
  61. package/node_modules/@buddi/install/dist/app-layout.js +323 -0
  62. package/node_modules/@buddi/install/dist/app-layout.js.map +1 -0
  63. package/node_modules/@buddi/install/dist/index.d.ts +1 -0
  64. package/node_modules/@buddi/install/dist/index.d.ts.map +1 -1
  65. package/node_modules/@buddi/install/dist/index.js +1 -0
  66. package/node_modules/@buddi/install/dist/index.js.map +1 -1
  67. package/node_modules/@buddi/install/dist/launcher.d.ts.map +1 -1
  68. package/node_modules/@buddi/install/dist/launcher.js +18 -4
  69. package/node_modules/@buddi/install/dist/launcher.js.map +1 -1
  70. package/node_modules/@buddi/install/dist/provenance.d.ts +34 -0
  71. package/node_modules/@buddi/install/dist/provenance.d.ts.map +1 -0
  72. package/node_modules/@buddi/install/dist/provenance.js +200 -0
  73. package/node_modules/@buddi/install/dist/provenance.js.map +1 -0
  74. package/node_modules/@buddi/install/dist/supervisor.d.ts.map +1 -1
  75. package/node_modules/@buddi/install/dist/supervisor.js +9 -4
  76. package/node_modules/@buddi/install/dist/supervisor.js.map +1 -1
  77. package/node_modules/@buddi/install/dist/upgrade.d.ts +77 -3
  78. package/node_modules/@buddi/install/dist/upgrade.d.ts.map +1 -1
  79. package/node_modules/@buddi/install/dist/upgrade.js +325 -43
  80. package/node_modules/@buddi/install/dist/upgrade.js.map +1 -1
  81. package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
  82. package/node_modules/@buddi/tool-browser/dist/controller.d.ts +6 -0
  83. package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
  84. package/node_modules/@buddi/tool-browser/dist/controller.js +80 -6
  85. package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
  86. package/node_modules/@buddi/tool-browser/dist/driver.d.ts +3 -1
  87. package/node_modules/@buddi/tool-browser/dist/driver.d.ts.map +1 -1
  88. package/node_modules/@buddi/tool-browser/dist/driver.js +82 -1
  89. package/node_modules/@buddi/tool-browser/dist/driver.js.map +1 -1
  90. package/node_modules/@buddi/tool-browser/dist/extension.d.ts +60 -7
  91. package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
  92. package/node_modules/@buddi/tool-browser/dist/extension.js +90 -13
  93. package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
  94. package/node_modules/@buddi/tool-browser/dist/index.d.ts +6 -4
  95. package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
  96. package/node_modules/@buddi/tool-browser/dist/index.js +7 -4
  97. package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
  98. package/node_modules/@buddi/tool-browser/dist/logins.d.ts +150 -0
  99. package/node_modules/@buddi/tool-browser/dist/logins.d.ts.map +1 -0
  100. package/node_modules/@buddi/tool-browser/dist/logins.js +476 -0
  101. package/node_modules/@buddi/tool-browser/dist/logins.js.map +1 -0
  102. package/node_modules/@buddi/tool-browser/dist/routes.d.ts +22 -1
  103. package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -1
  104. package/node_modules/@buddi/tool-browser/dist/routes.js +51 -3
  105. package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -1
  106. package/node_modules/@buddi/tool-browser/dist/secrets.d.ts +3 -1
  107. package/node_modules/@buddi/tool-browser/dist/secrets.d.ts.map +1 -1
  108. package/node_modules/@buddi/tool-browser/dist/secrets.js +10 -6
  109. package/node_modules/@buddi/tool-browser/dist/secrets.js.map +1 -1
  110. package/node_modules/@buddi/tool-browser/dist/service.d.ts +26 -2
  111. package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
  112. package/node_modules/@buddi/tool-browser/dist/service.js +117 -3
  113. package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
  114. package/node_modules/@buddi/tool-browser/dist/types.d.ts +88 -0
  115. package/node_modules/@buddi/tool-browser/dist/types.d.ts.map +1 -1
  116. package/node_modules/@buddi/tool-browser/dist/types.js +18 -0
  117. package/node_modules/@buddi/tool-browser/dist/types.js.map +1 -1
  118. package/node_modules/hono/dist/cjs/hono-base.js +2 -0
  119. package/node_modules/hono/dist/cjs/middleware/language/language.js +1 -1
  120. package/node_modules/hono/dist/cjs/middleware/mount/index.js +71 -0
  121. package/node_modules/hono/dist/cjs/request.js +4 -4
  122. package/node_modules/hono/dist/hono-base.js +2 -0
  123. package/node_modules/hono/dist/middleware/mount/index.js +70 -0
  124. package/node_modules/hono/dist/request.js +4 -4
  125. package/node_modules/hono/dist/types/hono-base.d.ts +2 -0
  126. package/node_modules/hono/dist/types/jsx/base.d.ts +1 -1
  127. package/node_modules/hono/dist/types/middleware/mount/index.d.ts +46 -0
  128. package/node_modules/hono/dist/types/request.d.ts +4 -4
  129. package/node_modules/hono/package.json +9 -1
  130. package/package.json +2 -2
  131. package/packages/cli/dist/.tsbuildinfo +1 -1
  132. package/packages/cli/dist/access-cmd.d.ts +1 -1
  133. package/packages/cli/dist/access-cmd.d.ts.map +1 -1
  134. package/packages/cli/dist/access-cmd.js +23 -3
  135. package/packages/cli/dist/access-cmd.js.map +1 -1
  136. package/packages/cli/dist/args.d.ts +2 -2
  137. package/packages/cli/dist/args.d.ts.map +1 -1
  138. package/packages/cli/dist/args.js +7 -2
  139. package/packages/cli/dist/args.js.map +1 -1
  140. package/packages/cli/dist/commands.d.ts.map +1 -1
  141. package/packages/cli/dist/commands.js +11 -0
  142. package/packages/cli/dist/commands.js.map +1 -1
  143. package/packages/cli/dist/main.d.ts.map +1 -1
  144. package/packages/cli/dist/main.js +2 -1
  145. package/packages/cli/dist/main.js.map +1 -1
  146. package/packages/gateway/dist/.tsbuildinfo +1 -1
  147. package/packages/gateway/dist/missions/ask-cap.d.ts +26 -0
  148. package/packages/gateway/dist/missions/ask-cap.d.ts.map +1 -0
  149. package/packages/gateway/dist/missions/ask-cap.js +83 -0
  150. package/packages/gateway/dist/missions/ask-cap.js.map +1 -0
  151. package/packages/gateway/dist/missions/execute.d.ts +12 -1
  152. package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
  153. package/packages/gateway/dist/missions/execute.js +73 -11
  154. package/packages/gateway/dist/missions/execute.js.map +1 -1
  155. package/packages/gateway/dist/missions/parked.d.ts +6 -0
  156. package/packages/gateway/dist/missions/parked.d.ts.map +1 -1
  157. package/packages/gateway/dist/missions/parked.js +7 -1
  158. package/packages/gateway/dist/missions/parked.js.map +1 -1
  159. package/packages/gateway/dist/serve.js +1 -1
  160. package/packages/gateway/dist/serve.js.map +1 -1
  161. package/packages/gateway/dist/system-context.d.ts +7 -0
  162. package/packages/gateway/dist/system-context.d.ts.map +1 -1
  163. package/packages/gateway/dist/system-context.js +8 -0
  164. package/packages/gateway/dist/system-context.js.map +1 -1
  165. package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
  166. package/packages/gateway/dist/web/api-routes.js +11 -3
  167. package/packages/gateway/dist/web/api-routes.js.map +1 -1
  168. package/packages/gateway/dist/web/extension.d.ts +13 -1
  169. package/packages/gateway/dist/web/extension.d.ts.map +1 -1
  170. package/packages/gateway/dist/web/extension.js +125 -5
  171. package/packages/gateway/dist/web/extension.js.map +1 -1
  172. package/packages/gateway/dist/web/remote-hand.d.ts.map +1 -1
  173. package/packages/gateway/dist/web/remote-hand.js +45 -2
  174. package/packages/gateway/dist/web/remote-hand.js.map +1 -1
  175. package/packages/gateway/dist/web/secrets.d.ts +26 -1
  176. package/packages/gateway/dist/web/secrets.d.ts.map +1 -1
  177. package/packages/gateway/dist/web/secrets.js +66 -3
  178. package/packages/gateway/dist/web/secrets.js.map +1 -1
  179. package/packages/gateway/dist/web/server.d.ts.map +1 -1
  180. package/packages/gateway/dist/web/server.js +63 -7
  181. package/packages/gateway/dist/web/server.js.map +1 -1
  182. package/packages/gateway/dist/web/version.d.ts +2 -0
  183. package/packages/gateway/dist/web/version.d.ts.map +1 -1
  184. package/packages/gateway/dist/web/version.js +5 -1
  185. package/packages/gateway/dist/web/version.js.map +1 -1
  186. package/packages/install/dist/.tsbuildinfo +1 -1
  187. package/packages/install/dist/app-layout.d.ts +127 -0
  188. package/packages/install/dist/app-layout.d.ts.map +1 -0
  189. package/packages/install/dist/app-layout.js +323 -0
  190. package/packages/install/dist/app-layout.js.map +1 -0
  191. package/packages/install/dist/index.d.ts +1 -0
  192. package/packages/install/dist/index.d.ts.map +1 -1
  193. package/packages/install/dist/index.js +1 -0
  194. package/packages/install/dist/index.js.map +1 -1
  195. package/packages/install/dist/launcher.d.ts.map +1 -1
  196. package/packages/install/dist/launcher.js +18 -4
  197. package/packages/install/dist/launcher.js.map +1 -1
  198. package/packages/install/dist/provenance.d.ts +34 -0
  199. package/packages/install/dist/provenance.d.ts.map +1 -0
  200. package/packages/install/dist/provenance.js +200 -0
  201. package/packages/install/dist/provenance.js.map +1 -0
  202. package/packages/install/dist/supervisor.d.ts.map +1 -1
  203. package/packages/install/dist/supervisor.js +9 -4
  204. package/packages/install/dist/supervisor.js.map +1 -1
  205. package/packages/install/dist/upgrade.d.ts +77 -3
  206. package/packages/install/dist/upgrade.d.ts.map +1 -1
  207. package/packages/install/dist/upgrade.js +325 -43
  208. package/packages/install/dist/upgrade.js.map +1 -1
  209. package/packages/tools/browser/dist/.tsbuildinfo +1 -1
  210. package/packages/tools/browser/dist/controller.d.ts +6 -0
  211. package/packages/tools/browser/dist/controller.d.ts.map +1 -1
  212. package/packages/tools/browser/dist/controller.js +80 -6
  213. package/packages/tools/browser/dist/controller.js.map +1 -1
  214. package/packages/tools/browser/dist/driver.d.ts +3 -1
  215. package/packages/tools/browser/dist/driver.d.ts.map +1 -1
  216. package/packages/tools/browser/dist/driver.js +82 -1
  217. package/packages/tools/browser/dist/driver.js.map +1 -1
  218. package/packages/tools/browser/dist/extension.d.ts +60 -7
  219. package/packages/tools/browser/dist/extension.d.ts.map +1 -1
  220. package/packages/tools/browser/dist/extension.js +90 -13
  221. package/packages/tools/browser/dist/extension.js.map +1 -1
  222. package/packages/tools/browser/dist/index.d.ts +6 -4
  223. package/packages/tools/browser/dist/index.d.ts.map +1 -1
  224. package/packages/tools/browser/dist/index.js +7 -4
  225. package/packages/tools/browser/dist/index.js.map +1 -1
  226. package/packages/tools/browser/dist/logins.d.ts +150 -0
  227. package/packages/tools/browser/dist/logins.d.ts.map +1 -0
  228. package/packages/tools/browser/dist/logins.js +476 -0
  229. package/packages/tools/browser/dist/logins.js.map +1 -0
  230. package/packages/tools/browser/dist/routes.d.ts +22 -1
  231. package/packages/tools/browser/dist/routes.d.ts.map +1 -1
  232. package/packages/tools/browser/dist/routes.js +51 -3
  233. package/packages/tools/browser/dist/routes.js.map +1 -1
  234. package/packages/tools/browser/dist/secrets.d.ts +3 -1
  235. package/packages/tools/browser/dist/secrets.d.ts.map +1 -1
  236. package/packages/tools/browser/dist/secrets.js +10 -6
  237. package/packages/tools/browser/dist/secrets.js.map +1 -1
  238. package/packages/tools/browser/dist/service.d.ts +26 -2
  239. package/packages/tools/browser/dist/service.d.ts.map +1 -1
  240. package/packages/tools/browser/dist/service.js +117 -3
  241. package/packages/tools/browser/dist/service.js.map +1 -1
  242. package/packages/tools/browser/dist/types.d.ts +88 -0
  243. package/packages/tools/browser/dist/types.d.ts.map +1 -1
  244. package/packages/tools/browser/dist/types.js +18 -0
  245. package/packages/tools/browser/dist/types.js.map +1 -1
  246. package/packages/web/dist/assets/index-DYfeUW-0.css +1 -0
  247. package/packages/web/dist/assets/index-vpc904_b.js +146 -0
  248. package/packages/web/dist/assets/{lottie_light-CuiSMqnl.js → lottie_light-BFAMYgLA.js} +1 -1
  249. package/packages/web/dist/build.json +1 -1
  250. package/packages/web/dist/index.html +2 -2
  251. package/packages/web/dist/precache.json +4 -4
  252. package/packages/web/dist/assets/index-Bac-CdD-.css +0 -1
  253. package/packages/web/dist/assets/index-DI8bp_D7.js +0 -146
@@ -64,7 +64,7 @@ import { OnboardingRefusal, WEB_ONBOARDING_STEPS, WEB_ONBOARDING_SURFACE, claimO
64
64
  import { TakeOnRefusal, readTakeOn, startTakeOn } from './take-on.js';
65
65
  import { TelegramWebError, saveTelegramToken, telegramBot, telegramDevices, telegramPairing, telegramStatus, unpairTelegramDevice, } from './telegram.js';
66
66
  import { PAGE_ROUTE, sendPageFile, actOnPage, actRateLimited, listPageDescriptors, runPageQuery, } from './pages.js';
67
- import { listSecrets, secretUses, secretsAct } from './secrets.js';
67
+ import { listSecrets, ownerLoginKey, ownerLoginNames, ownerLoginStore, secretUses, secretsAct } from './secrets.js';
68
68
  import { sayRoute, transcribeRoute } from './speech.js';
69
69
  import { createServer } from 'node:http';
70
70
  import { asksEachTime, getAction, idleRolloverMs, inRecovery, listMissions, listPendingActions, isJobState, parseAgentFile, setSentinelEnabled, snoozeFinding, snoozeFindings, unmuteFindings } from '@buddi/core';
@@ -474,6 +474,15 @@ export function createWebApp(deps) {
474
474
  await chat?.continueAfterGiveBack({ conversationId: info.conversationId, agentId: info.agentId });
475
475
  })().catch((err) => log(`browser: carrying on after the page was given back failed: ${err instanceof Error ? err.message : String(err)}`));
476
476
  });
477
+ /*
478
+ * A sign-in the owner made on a page they held, kept when they say Save
479
+ * (docs/browser.md, "Saving a sign-in"): the browser host's keeper hands the
480
+ * pair to core's owner-secret store, as the owner, and to nothing else.
481
+ */
482
+ {
483
+ const loginDeps = { pool: deps.pool, registry: deps.registry, ctx: deps.ctx, now: deps.now };
484
+ (deps.browser ?? browserHost(deps.env ?? process.env)).logins?.useStore(ownerLoginStore(loginDeps), ownerLoginNames(loginDeps), ownerLoginKey(deps.env ?? process.env));
485
+ }
477
486
  const streams = new StreamBudget();
478
487
  // A bundle script's run asks every time: its card offers no standing permission (`asksEachTime`).
479
488
  const permissionScopes = (tool, envelope) => deps.registry.lookup(tool)?.reusableApproval && !asksEachTime(envelope)
@@ -1219,7 +1228,7 @@ export function createWebApp(deps) {
1219
1228
  agentIds: () => deps.catalog.list().map((a) => a.id),
1220
1229
  });
1221
1230
  /** The Keys and secrets page (docs/owner-secrets.md §6): core's own queries and ownerOnly tools. */
1222
- const secretsDeps = () => ({ pool: deps.pool, registry: deps.registry, ctx: deps.ctx, now: deps.now });
1231
+ const secretsDeps = () => ({ pool: deps.pool, registry: deps.registry, ctx: deps.ctx, now: deps.now, ...(browser.logins ? { logins: browser.logins } : {}) });
1223
1232
  /** Talking to buddi on the dashboard: the speech plugin's two tools, as the owner. */
1224
1233
  const speechDeps = () => ({ pool: deps.pool, registry: deps.registry, ctx: deps.ctx, now: deps.now, agents: () => deps.catalog.list() });
1225
1234
  /** The same, for the version and upgrade routes. */
@@ -2579,12 +2588,33 @@ export function createWebApp(deps) {
2579
2588
  */
2580
2589
  /*
2581
2590
  * "Set it up for me": start a run (202, then poll GET …/setup), stop the
2582
- * health wait, or remove what buddi made. From this machine only, like the
2583
- * setting it fills in.
2591
+ * health wait, remove what buddi made, or forget the kept API token. From
2592
+ * this machine only, like the setting it fills in.
2584
2593
  */
2585
- if (path === '/api/access/cloudflare-access/setup' || path === '/api/access/cloudflare-access/setup/stop' || path === '/api/access/cloudflare-access/setup/remove') {
2594
+ if (path === '/api/access/cloudflare-access/setup' || path === '/api/access/cloudflare-access/setup/stop' || path === '/api/access/cloudflare-access/setup/remove' || path === '/api/access/cloudflare-access/setup/forget-token') {
2586
2595
  if (session.via !== 'local')
2587
2596
  return sendJson(res, 403, { error: 'Change this from the computer buddi runs on.' });
2597
+ /*
2598
+ * Forget the token: drop the owner secret. Not while a run holds it.
2599
+ * Cloudflare still honours it until the owner revokes it there.
2600
+ */
2601
+ if (path.endsWith('/forget-token')) {
2602
+ const lease = claimSetupOperation('setup');
2603
+ if (!lease)
2604
+ return sendJson(res, 409, { error: setupBusySentence(setupOperation()) });
2605
+ try {
2606
+ try {
2607
+ await tokenStore().remove();
2608
+ }
2609
+ catch {
2610
+ return sendJson(res, 409, { error: 'The token could not be forgotten. Check that the vault is unlocked, then try again.' });
2611
+ }
2612
+ return sendJson(res, 200, await setupView());
2613
+ }
2614
+ finally {
2615
+ lease.release();
2616
+ }
2617
+ }
2588
2618
  /*
2589
2619
  * One operation at a time (cloudflare-setup's lock, claimed before the
2590
2620
  * first await and held to the end): a second setup or a removal while
@@ -2623,8 +2653,7 @@ export function createWebApp(deps) {
2623
2653
  setupRun = run;
2624
2654
  const progress = await removeCloudflareSetup({ ...setupDepsFor(token, lease), host: str(body.host) || undefined }, (p) => { run.progress = p; });
2625
2655
  run.progress = progress;
2626
- if (!progress.error)
2627
- await tokens.remove().catch(() => undefined);
2656
+ // The token stays kept: the panel offers to forget it (…/setup/forget-token), and Set it up again reuses it.
2628
2657
  return sendJson(res, 200, await setupView());
2629
2658
  }
2630
2659
  const input = { host: str(body.host), email: str(body.email), zone: str(body.zone) || undefined, adopt: body.adopt === true };
@@ -2787,6 +2816,30 @@ export function createWebApp(deps) {
2787
2816
  const answered = await browser.touch?.({ conversationId: body.conversationId, text: body.answer });
2788
2817
  return sendJson(res, 200, { ...(answered && 'answered' in answered ? answered : {}), status: browser.status({ conversationId: body.conversationId }) });
2789
2818
  }
2819
+ /*
2820
+ * "Save this login for amazon.com?" answered in the Page tab: Save, Not
2821
+ * now or Never for this site. The owner's session and CSRF, like every
2822
+ * write here; the body names the question, never a password — that is in
2823
+ * the browser host's keeper, which hands it to the owner-secret store on
2824
+ * Save and drops it otherwise.
2825
+ */
2826
+ if (path === '/api/browser/login') {
2827
+ const body = await readJsonBody(req);
2828
+ const decision = body?.decision;
2829
+ if (typeof body?.id !== 'string' || body.id.length > 80 || (decision !== 'save' && decision !== 'later' && decision !== 'never')) {
2830
+ return sendJson(res, 400, { error: 'Expected {id: string, decision: save|later|never}' });
2831
+ }
2832
+ if (!browser.logins)
2833
+ return sendJson(res, 409, { error: 'This host keeps no sign-ins.' });
2834
+ try {
2835
+ const answer = await browser.logins.decide(body.id, decision);
2836
+ return sendJson(res, 200, { outcome: answer.outcome, ...(answer.saved ? { saved: { name: answer.saved.name, site: answer.saved.site, username: answer.saved.username, savedAt: answer.saved.savedAt } } : {}) });
2837
+ }
2838
+ catch {
2839
+ // Never the error's own words: they are the store's, and the store had the password.
2840
+ return sendJson(res, 409, { error: 'buddi could not keep that login. Add it in Settings → Keys and secrets.' });
2841
+ }
2842
+ }
2790
2843
  const control = /^\/api\/browser\/(stop|takeover|resume|release)$/.exec(path);
2791
2844
  if (control) {
2792
2845
  const body = await readJsonBody(req);
@@ -2806,6 +2859,9 @@ export function createWebApp(deps) {
2806
2859
  // Whether this screen can be driven from here at all. The dashboard
2807
2860
  // shows the mode's own sentence when it cannot.
2808
2861
  const taken = sessionId ?? status.session?.id;
2862
+ // A page in the owner's Chrome is taken over where it is: its tab came to the front there, so no frame will come.
2863
+ if (action === 'takeover' && status.held)
2864
+ return sendJson(res, 200, { ...status, hand: false });
2809
2865
  const offer = action === 'takeover' && taken ? browser.hand?.({ sessionId: taken }) : undefined;
2810
2866
  /*
2811
2867
  * "Your browser" with Chrome closed: the take-over itself succeeds (the