@trusty-squire/mcp 1.1.14-rc.8 → 1.1.14

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 (346) hide show
  1. package/README.md +150 -242
  2. package/dist/api-client.d.ts +53 -7
  3. package/dist/api-client.d.ts.map +1 -1
  4. package/dist/api-client.js +12 -12
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/bin.js +2 -8
  7. package/dist/bin.js.map +1 -1
  8. package/dist/bot/act/act.d.ts +25 -0
  9. package/dist/bot/act/act.d.ts.map +1 -0
  10. package/dist/bot/act/act.js +849 -0
  11. package/dist/bot/act/act.js.map +1 -0
  12. package/dist/bot/act/targets.d.ts +76 -0
  13. package/dist/bot/act/targets.d.ts.map +1 -0
  14. package/dist/bot/act/targets.js +310 -0
  15. package/dist/bot/act/targets.js.map +1 -0
  16. package/dist/bot/broker/admission-context.d.ts +3 -4
  17. package/dist/bot/broker/admission-context.d.ts.map +1 -1
  18. package/dist/bot/broker/admission-context.js +3 -8
  19. package/dist/bot/broker/admission-context.js.map +1 -1
  20. package/dist/bot/broker/authority.d.ts +27 -38
  21. package/dist/bot/broker/authority.d.ts.map +1 -1
  22. package/dist/bot/broker/authority.js +122 -277
  23. package/dist/bot/broker/authority.js.map +1 -1
  24. package/dist/bot/broker/custody.d.ts +3 -2
  25. package/dist/bot/broker/custody.d.ts.map +1 -1
  26. package/dist/bot/broker/custody.js.map +1 -1
  27. package/dist/bot/broker/daemon.d.ts +2 -2
  28. package/dist/bot/broker/daemon.d.ts.map +1 -1
  29. package/dist/bot/broker/daemon.js +96 -147
  30. package/dist/bot/broker/daemon.js.map +1 -1
  31. package/dist/bot/broker/discovery.d.ts +25 -3
  32. package/dist/bot/broker/discovery.d.ts.map +1 -1
  33. package/dist/bot/broker/discovery.js +239 -77
  34. package/dist/bot/broker/discovery.js.map +1 -1
  35. package/dist/bot/broker/forwarder.d.ts +10 -15
  36. package/dist/bot/broker/forwarder.d.ts.map +1 -1
  37. package/dist/bot/broker/forwarder.js +127 -90
  38. package/dist/bot/broker/forwarder.js.map +1 -1
  39. package/dist/bot/broker/maintenance.d.ts +12 -2
  40. package/dist/bot/broker/maintenance.d.ts.map +1 -1
  41. package/dist/bot/broker/maintenance.js +40 -28
  42. package/dist/bot/broker/maintenance.js.map +1 -1
  43. package/dist/bot/broker/operator.d.ts +23 -31
  44. package/dist/bot/broker/operator.d.ts.map +1 -1
  45. package/dist/bot/broker/operator.js +243 -340
  46. package/dist/bot/broker/operator.js.map +1 -1
  47. package/dist/bot/broker/protocol.d.ts +73 -0
  48. package/dist/bot/broker/protocol.d.ts.map +1 -0
  49. package/dist/bot/broker/protocol.js +24 -0
  50. package/dist/bot/broker/protocol.js.map +1 -0
  51. package/dist/bot/broker/refusal.d.ts +5 -0
  52. package/dist/bot/broker/refusal.d.ts.map +1 -0
  53. package/dist/bot/broker/refusal.js +9 -0
  54. package/dist/bot/broker/refusal.js.map +1 -0
  55. package/dist/bot/broker/runtime.d.ts +18 -2
  56. package/dist/bot/broker/runtime.d.ts.map +1 -1
  57. package/dist/bot/broker/runtime.js +117 -13
  58. package/dist/bot/broker/runtime.js.map +1 -1
  59. package/dist/bot/broker/transport.d.ts +37 -10
  60. package/dist/bot/broker/transport.d.ts.map +1 -1
  61. package/dist/bot/broker/transport.js +246 -49
  62. package/dist/bot/broker/transport.js.map +1 -1
  63. package/dist/bot/browser-process-owner.d.ts.map +1 -1
  64. package/dist/bot/browser-process-owner.js +6 -9
  65. package/dist/bot/browser-process-owner.js.map +1 -1
  66. package/dist/bot/browser-process-runtime.d.ts +1 -0
  67. package/dist/bot/browser-process-runtime.d.ts.map +1 -1
  68. package/dist/bot/browser-process-runtime.js +25 -1
  69. package/dist/bot/browser-process-runtime.js.map +1 -1
  70. package/dist/bot/browser-use-capture.d.ts +61 -3
  71. package/dist/bot/browser-use-capture.d.ts.map +1 -1
  72. package/dist/bot/browser-use-capture.js +541 -77
  73. package/dist/bot/browser-use-capture.js.map +1 -1
  74. package/dist/bot/browser-use-serializer.d.ts +38 -0
  75. package/dist/bot/browser-use-serializer.d.ts.map +1 -1
  76. package/dist/bot/browser-use-serializer.js +124 -7
  77. package/dist/bot/browser-use-serializer.js.map +1 -1
  78. package/dist/bot/browser.d.ts +149 -482
  79. package/dist/bot/browser.d.ts.map +1 -1
  80. package/dist/bot/browser.js +3786 -11250
  81. package/dist/bot/browser.js.map +1 -1
  82. package/dist/bot/captcha-solve.d.ts +37 -0
  83. package/dist/bot/captcha-solve.d.ts.map +1 -0
  84. package/dist/bot/captcha-solve.js +356 -0
  85. package/dist/bot/captcha-solve.js.map +1 -0
  86. package/dist/bot/{captcha-solver-2captcha.d.ts → captcha.d.ts} +43 -1
  87. package/dist/bot/captcha.d.ts.map +1 -0
  88. package/dist/bot/captcha.js +1437 -0
  89. package/dist/bot/captcha.js.map +1 -0
  90. package/dist/bot/capture/capture.d.ts +48 -0
  91. package/dist/bot/capture/capture.d.ts.map +1 -0
  92. package/dist/bot/capture/capture.js +662 -0
  93. package/dist/bot/capture/capture.js.map +1 -0
  94. package/dist/bot/capture/verification.d.ts +36 -0
  95. package/dist/bot/capture/verification.d.ts.map +1 -0
  96. package/dist/bot/capture/verification.js +245 -0
  97. package/dist/bot/capture/verification.js.map +1 -0
  98. package/dist/bot/card-release-approval.d.ts +64 -0
  99. package/dist/bot/card-release-approval.d.ts.map +1 -0
  100. package/dist/bot/card-release-approval.js +746 -0
  101. package/dist/bot/card-release-approval.js.map +1 -0
  102. package/dist/bot/card-secret-tokens.d.ts +54 -0
  103. package/dist/bot/card-secret-tokens.d.ts.map +1 -0
  104. package/dist/bot/card-secret-tokens.js +72 -0
  105. package/dist/bot/card-secret-tokens.js.map +1 -0
  106. package/dist/bot/card-value-output-mask.d.ts +48 -0
  107. package/dist/bot/card-value-output-mask.d.ts.map +1 -0
  108. package/dist/bot/card-value-output-mask.js +267 -0
  109. package/dist/bot/card-value-output-mask.js.map +1 -0
  110. package/dist/bot/checkout.d.ts +27 -0
  111. package/dist/bot/checkout.d.ts.map +1 -0
  112. package/dist/bot/checkout.js +10 -0
  113. package/dist/bot/checkout.js.map +1 -0
  114. package/dist/bot/click-dispatch.d.ts +7 -0
  115. package/dist/bot/click-dispatch.d.ts.map +1 -0
  116. package/dist/bot/click-dispatch.js +16 -0
  117. package/dist/bot/click-dispatch.js.map +1 -0
  118. package/dist/bot/compact-observation-v2.d.ts +95 -1
  119. package/dist/bot/compact-observation-v2.d.ts.map +1 -1
  120. package/dist/bot/compact-observation-v2.js +804 -57
  121. package/dist/bot/compact-observation-v2.js.map +1 -1
  122. package/dist/bot/credential-capture.d.ts +86 -0
  123. package/dist/bot/credential-capture.d.ts.map +1 -0
  124. package/dist/bot/credential-capture.js +50 -0
  125. package/dist/bot/credential-capture.js.map +1 -0
  126. package/dist/bot/credential-shape.js +5 -4
  127. package/dist/bot/credential-shape.js.map +1 -1
  128. package/dist/bot/driver/types.d.ts +45 -0
  129. package/dist/bot/driver/types.d.ts.map +1 -0
  130. package/dist/bot/driver/types.js +14 -0
  131. package/dist/bot/driver/types.js.map +1 -0
  132. package/dist/bot/element-fingerprint.js +3 -3
  133. package/dist/bot/element-fingerprint.js.map +1 -1
  134. package/dist/bot/google-auth-state.d.ts +23 -0
  135. package/dist/bot/google-auth-state.d.ts.map +1 -0
  136. package/dist/bot/google-auth-state.js +64 -0
  137. package/dist/bot/google-auth-state.js.map +1 -0
  138. package/dist/bot/google-login.d.ts +3 -4
  139. package/dist/bot/google-login.d.ts.map +1 -1
  140. package/dist/bot/google-login.js +6 -65
  141. package/dist/bot/google-login.js.map +1 -1
  142. package/dist/bot/identity-runtime.d.ts +5 -4
  143. package/dist/bot/identity-runtime.d.ts.map +1 -1
  144. package/dist/bot/identity-runtime.js +17 -19
  145. package/dist/bot/identity-runtime.js.map +1 -1
  146. package/dist/bot/mutation-dispatch-evidence.d.ts +13 -0
  147. package/dist/bot/mutation-dispatch-evidence.d.ts.map +1 -0
  148. package/dist/bot/mutation-dispatch-evidence.js +19 -0
  149. package/dist/bot/mutation-dispatch-evidence.js.map +1 -0
  150. package/dist/bot/oauth-login.d.ts +86 -0
  151. package/dist/bot/oauth-login.d.ts.map +1 -0
  152. package/dist/bot/oauth-login.js +1723 -0
  153. package/dist/bot/oauth-login.js.map +1 -0
  154. package/dist/bot/oauth-providers.d.ts +1 -1
  155. package/dist/bot/oauth-providers.d.ts.map +1 -1
  156. package/dist/bot/oauth-providers.js +1 -1
  157. package/dist/bot/oauth-providers.js.map +1 -1
  158. package/dist/bot/observe/observe.d.ts +39 -0
  159. package/dist/bot/observe/observe.d.ts.map +1 -0
  160. package/dist/bot/observe/observe.js +854 -0
  161. package/dist/bot/observe/observe.js.map +1 -0
  162. package/dist/bot/observe/refs.d.ts +12 -0
  163. package/dist/bot/observe/refs.d.ts.map +1 -0
  164. package/dist/bot/observe/refs.js +200 -0
  165. package/dist/bot/observe/refs.js.map +1 -0
  166. package/dist/bot/operation-receipt.d.ts +26 -0
  167. package/dist/bot/operation-receipt.d.ts.map +1 -0
  168. package/dist/bot/operation-receipt.js +13 -0
  169. package/dist/bot/operation-receipt.js.map +1 -0
  170. package/dist/bot/operator-evidence.d.ts +91 -0
  171. package/dist/bot/operator-evidence.d.ts.map +1 -0
  172. package/dist/bot/operator-evidence.js +194 -0
  173. package/dist/bot/operator-evidence.js.map +1 -0
  174. package/dist/bot/owned-pages.d.ts +3 -2
  175. package/dist/bot/owned-pages.d.ts.map +1 -1
  176. package/dist/bot/owned-pages.js +12 -5
  177. package/dist/bot/owned-pages.js.map +1 -1
  178. package/dist/bot/owner-process-reaper.d.ts +1 -1
  179. package/dist/bot/owner-process-reaper.d.ts.map +1 -1
  180. package/dist/bot/owner-process-reaper.js +5 -1
  181. package/dist/bot/owner-process-reaper.js.map +1 -1
  182. package/dist/bot/page-driver.d.ts +5 -1
  183. package/dist/bot/page-driver.d.ts.map +1 -1
  184. package/dist/bot/page-driver.js +29 -1
  185. package/dist/bot/page-driver.js.map +1 -1
  186. package/dist/bot/profile.d.ts +9 -0
  187. package/dist/bot/profile.d.ts.map +1 -1
  188. package/dist/bot/profile.js +29 -4
  189. package/dist/bot/profile.js.map +1 -1
  190. package/dist/bot/provision-session.d.ts +46 -423
  191. package/dist/bot/provision-session.d.ts.map +1 -1
  192. package/dist/bot/provision-session.js +324 -6817
  193. package/dist/bot/provision-session.js.map +1 -1
  194. package/dist/bot/provision-types.d.ts +1 -4
  195. package/dist/bot/provision-types.d.ts.map +1 -1
  196. package/dist/bot/provision-types.js +1 -1
  197. package/dist/bot/provision-types.js.map +1 -1
  198. package/dist/bot/request-cancellation.d.ts +37 -0
  199. package/dist/bot/request-cancellation.d.ts.map +1 -0
  200. package/dist/bot/request-cancellation.js +126 -0
  201. package/dist/bot/request-cancellation.js.map +1 -0
  202. package/dist/bot/screenshot-click.d.ts +42 -0
  203. package/dist/bot/screenshot-click.d.ts.map +1 -0
  204. package/dist/bot/screenshot-click.js +403 -0
  205. package/dist/bot/screenshot-click.js.map +1 -0
  206. package/dist/bot/session/hosts.d.ts +0 -3
  207. package/dist/bot/session/hosts.d.ts.map +1 -1
  208. package/dist/bot/session/hosts.js +1 -16
  209. package/dist/bot/session/hosts.js.map +1 -1
  210. package/dist/bot/session/lifecycle.d.ts +12 -10
  211. package/dist/bot/session/lifecycle.d.ts.map +1 -1
  212. package/dist/bot/session/lifecycle.js +187 -701
  213. package/dist/bot/session/lifecycle.js.map +1 -1
  214. package/dist/bot/session/model.d.ts +20 -98
  215. package/dist/bot/session/model.d.ts.map +1 -1
  216. package/dist/bot/session/model.js +42 -26
  217. package/dist/bot/session/model.js.map +1 -1
  218. package/dist/bot/session/registry.d.ts +4 -0
  219. package/dist/bot/session/registry.d.ts.map +1 -0
  220. package/dist/bot/session/registry.js +41 -0
  221. package/dist/bot/session/registry.js.map +1 -0
  222. package/dist/bot/session/slots.d.ts +9 -0
  223. package/dist/bot/session/slots.d.ts.map +1 -0
  224. package/dist/bot/session/slots.js +42 -0
  225. package/dist/bot/session/slots.js.map +1 -0
  226. package/dist/bot/skill-hint.d.ts +0 -4
  227. package/dist/bot/skill-hint.d.ts.map +1 -1
  228. package/dist/bot/skill-hint.js +2 -101
  229. package/dist/bot/skill-hint.js.map +1 -1
  230. package/dist/install/agents.d.ts +1 -0
  231. package/dist/install/agents.d.ts.map +1 -1
  232. package/dist/install/agents.js +104 -0
  233. package/dist/install/agents.js.map +1 -1
  234. package/dist/install/cli.d.ts +12 -1
  235. package/dist/install/cli.d.ts.map +1 -1
  236. package/dist/install/cli.js +113 -37
  237. package/dist/install/cli.js.map +1 -1
  238. package/dist/server-instance-registry.d.ts +18 -6
  239. package/dist/server-instance-registry.d.ts.map +1 -1
  240. package/dist/server-instance-registry.js +49 -28
  241. package/dist/server-instance-registry.js.map +1 -1
  242. package/dist/server.d.ts +3 -2
  243. package/dist/server.d.ts.map +1 -1
  244. package/dist/server.js +147 -90
  245. package/dist/server.js.map +1 -1
  246. package/dist/tools/card-mutations.d.ts +27 -0
  247. package/dist/tools/card-mutations.d.ts.map +1 -0
  248. package/dist/tools/card-mutations.js +106 -0
  249. package/dist/tools/card-mutations.js.map +1 -0
  250. package/dist/tools/credential-mutations.d.ts +16 -16
  251. package/dist/tools/index.d.ts +7 -4
  252. package/dist/tools/index.d.ts.map +1 -1
  253. package/dist/tools/index.js +7 -6
  254. package/dist/tools/index.js.map +1 -1
  255. package/dist/tools/inject-card.d.ts +94 -0
  256. package/dist/tools/inject-card.d.ts.map +1 -0
  257. package/dist/tools/inject-card.js +193 -0
  258. package/dist/tools/inject-card.js.map +1 -0
  259. package/dist/tools/list-credentials.d.ts +10 -1
  260. package/dist/tools/list-credentials.d.ts.map +1 -1
  261. package/dist/tools/list-credentials.js +65 -5
  262. package/dist/tools/list-credentials.js.map +1 -1
  263. package/dist/tools/list-payment-cards.d.ts +3 -0
  264. package/dist/tools/list-payment-cards.d.ts.map +1 -0
  265. package/dist/tools/list-payment-cards.js +15 -0
  266. package/dist/tools/list-payment-cards.js.map +1 -0
  267. package/dist/tools/provision-drive.d.ts +1183 -327
  268. package/dist/tools/provision-drive.d.ts.map +1 -1
  269. package/dist/tools/provision-drive.js +615 -596
  270. package/dist/tools/provision-drive.js.map +1 -1
  271. package/package.json +4 -5
  272. package/dist/bot/broker/dispatch-journal.d.ts +0 -51
  273. package/dist/bot/broker/dispatch-journal.d.ts.map +0 -1
  274. package/dist/bot/broker/dispatch-journal.js +0 -197
  275. package/dist/bot/broker/dispatch-journal.js.map +0 -1
  276. package/dist/bot/broker/identity-lane.d.ts +0 -3
  277. package/dist/bot/broker/identity-lane.d.ts.map +0 -1
  278. package/dist/bot/broker/identity-lane.js +0 -15
  279. package/dist/bot/broker/identity-lane.js.map +0 -1
  280. package/dist/bot/broker/lineage.d.ts +0 -3
  281. package/dist/bot/broker/lineage.d.ts.map +0 -1
  282. package/dist/bot/broker/lineage.js +0 -16
  283. package/dist/bot/broker/lineage.js.map +0 -1
  284. package/dist/bot/broker/qualification.d.ts +0 -5
  285. package/dist/bot/broker/qualification.d.ts.map +0 -1
  286. package/dist/bot/broker/qualification.js +0 -67
  287. package/dist/bot/broker/qualification.js.map +0 -1
  288. package/dist/bot/broker/scheduler.d.ts +0 -20
  289. package/dist/bot/broker/scheduler.d.ts.map +0 -1
  290. package/dist/bot/broker/scheduler.js +0 -94
  291. package/dist/bot/broker/scheduler.js.map +0 -1
  292. package/dist/bot/captcha-solver-2captcha.d.ts.map +0 -1
  293. package/dist/bot/captcha-solver-2captcha.js +0 -305
  294. package/dist/bot/captcha-solver-2captcha.js.map +0 -1
  295. package/dist/bot/near-text-hint.d.ts +0 -8
  296. package/dist/bot/near-text-hint.d.ts.map +0 -1
  297. package/dist/bot/near-text-hint.js +0 -71
  298. package/dist/bot/near-text-hint.js.map +0 -1
  299. package/dist/bot/onboarding-capture.d.ts +0 -85
  300. package/dist/bot/onboarding-capture.d.ts.map +0 -1
  301. package/dist/bot/onboarding-capture.js +0 -468
  302. package/dist/bot/onboarding-capture.js.map +0 -1
  303. package/dist/bot/operator-recipe.d.ts +0 -115
  304. package/dist/bot/operator-recipe.d.ts.map +0 -1
  305. package/dist/bot/operator-recipe.js +0 -675
  306. package/dist/bot/operator-recipe.js.map +0 -1
  307. package/dist/bot/pay-operator.d.ts +0 -110
  308. package/dist/bot/pay-operator.d.ts.map +0 -1
  309. package/dist/bot/pay-operator.js +0 -1400
  310. package/dist/bot/pay-operator.js.map +0 -1
  311. package/dist/bot/promote-to-skill.d.ts +0 -94
  312. package/dist/bot/promote-to-skill.d.ts.map +0 -1
  313. package/dist/bot/promote-to-skill.js +0 -2465
  314. package/dist/bot/promote-to-skill.js.map +0 -1
  315. package/dist/bot/session/multisession-flag.d.ts +0 -2
  316. package/dist/bot/session/multisession-flag.d.ts.map +0 -1
  317. package/dist/bot/session/multisession-flag.js +0 -23
  318. package/dist/bot/session/multisession-flag.js.map +0 -1
  319. package/dist/provision-gate.d.ts +0 -16
  320. package/dist/provision-gate.d.ts.map +0 -1
  321. package/dist/provision-gate.js +0 -66
  322. package/dist/provision-gate.js.map +0 -1
  323. package/dist/skill-cli/cli.d.ts +0 -35
  324. package/dist/skill-cli/cli.d.ts.map +0 -1
  325. package/dist/skill-cli/cli.js +0 -932
  326. package/dist/skill-cli/cli.js.map +0 -1
  327. package/dist/skill-cli/errors.d.ts +0 -36
  328. package/dist/skill-cli/errors.d.ts.map +0 -1
  329. package/dist/skill-cli/errors.js +0 -47
  330. package/dist/skill-cli/errors.js.map +0 -1
  331. package/dist/skill-cli/registry-http.d.ts +0 -28
  332. package/dist/skill-cli/registry-http.d.ts.map +0 -1
  333. package/dist/skill-cli/registry-http.js +0 -116
  334. package/dist/skill-cli/registry-http.js.map +0 -1
  335. package/dist/skill-cli/signing.d.ts +0 -21
  336. package/dist/skill-cli/signing.d.ts.map +0 -1
  337. package/dist/skill-cli/signing.js +0 -71
  338. package/dist/skill-cli/signing.js.map +0 -1
  339. package/dist/skill-registry-client.d.ts +0 -260
  340. package/dist/skill-registry-client.d.ts.map +0 -1
  341. package/dist/skill-registry-client.js +0 -607
  342. package/dist/skill-registry-client.js.map +0 -1
  343. package/dist/tools/operate-pay.d.ts +0 -73
  344. package/dist/tools/operate-pay.d.ts.map +0 -1
  345. package/dist/tools/operate-pay.js +0 -708
  346. package/dist/tools/operate-pay.js.map +0 -1
package/README.md CHANGED
@@ -15,169 +15,66 @@
15
15
  </p>
16
16
 
17
17
  <p align="center"><strong>Empower agents with auth and payments.</strong></p>
18
- <p align="center">MCP tools to automate auth and pay — your keys and card never leave the vault.</p>
18
+ <p align="center">MCP tools to automate auth and pay — your keys and card stay out of agent context.</p>
19
19
 
20
20
  Trusty Squire is an **MCP server that lets Claude Code, Codex, Cursor, OpenCode, Goose, and other coding agents sign up, provision, and purchase on your behalf**. It opens a real browser, works through signup, sign-in, setup, and checkout flows one step at a time, clears the bot-detection and email-verification steps that make operator tools stall, and hands the job back to a person only when one is actually required. That covers wiring up OAuth and API keys for the app you're building as much as it covers paying a checkout, sending a gift, or booking something — the same operator primitives drive all of it.
21
21
 
22
22
  Provider secrets and payment cards are write-only: the agent's credential tools return references and authenticated results, never stored plaintext. The raw secret never needs to enter the agent's context, so it can't be pasted into a commit, leaked in a log, or read back out over chat. When a task genuinely needs the plaintext somewhere the agent controls, `fetch_credential` releases it — for one credential, once, and only after you sign that exact request with your passkey. Backend access is a host-scoped, rate-limited, independently revocable grant, so a leaked token is killed without rotating the provider key — and you connect Google or GitHub yourself in a real browser, so the agent never types your password. Full [threat model below](#security-and-threat-model).
23
23
 
24
- ## One prompt
25
-
26
- ```text
27
- Add Google OAuth to this app in one prompt: create the OAuth client, save the client secret, and wire it in without putting the raw key in chat, code, or .env.
28
- ```
29
-
30
- Your coding agent plans the job. Trusty Squire operates the website, stores the generated key, and can issue your backend a scoped grant. The backend calls the provider through Trusty Squire, which injects the provider key on the server side.
31
-
32
- Other useful asks:
33
-
34
- - “Set up Stripe payments for this app and keep the API key out of this conversation.”
35
- - “Create a Render API key for deployment automation and keep it out of this conversation.”
36
- - “Pay this checkout with my saved work card and ask me to approve it on my phone.”
37
- - “Send a gift to my friend without sharing their address with me.”
38
- - “Book this dinner reservation for me.”
39
- - “That app grant leaked. Revoke it without rotating the provider key.”
40
-
41
- For supported card checkouts, save a card in the Vault from a passkey-capable
42
- device or let your first `operate_pay` approval link collect one just in time.
43
- When no card is specified, Trusty Squire uses the only saved card, starts the
44
- add-card ceremony if none exists, or asks you to choose when several exist. The
45
- new card is encrypted in your browser with a passkey-derived key and bound to
46
- that purchase before approval; if you add it but do not approve in time, it
47
- remains saved for a faster retry.
48
-
49
- Recognized Visa, Mastercard, Amex, Discover, Diners Club, and JCB cards show
50
- their network mark in the Vault while keeping the full bank/network label. Open
51
- a card row to see its masked number; `reveal` runs the passkey ceremony in your
52
- browser before showing the number, name, expiry, and billing address. The CVV is
53
- never shown, even after reveal. The Activity page also records card additions
54
- and removals, payments, and app-grant changes without storing a PAN or CVV.
55
-
56
- `operate_pay` requires a non-empty item and reason (calls that omit either
57
- receive a validation error). On a single-page checkout it prefers a machine-read
58
- checkout total, sends you a short-lived approval link, and submits only after you
59
- approve the purchase. A clean visible labeled total wins; when none is readable,
60
- strict schema.org `Order`/`Invoice.totalPaymentDue` structured data can supply the
61
- amount and currency. If neither source exposes a total, caller-supplied
62
- `amount_cents` and `currency` become the authoritative approval amount; an omitted
63
- merchant name falls back to the checkout URL's hostname. Product and offer prices
64
- never qualify as machine-read checkout totals. An unambiguous ISO currency on the
65
- page remains authoritative. A notation that cannot identify one ISO currency by
66
- itself, such as a shared currency symbol or an FX-preview selector, falls through to
67
- the currency already selected or approved for the purchase instead of refusing the
68
- checkout. Any live amount or currency drift still fails closed; the authoritative
69
- binding contract lives in the [security model](SECURITY.md#client-encrypted-card-data).
70
- Approval, 3-D Secure, Activity, and notification amounts use the currency's minor-unit
71
- precision (for example, whole yen for JPY and two decimals for USD). After you
72
- sign in, the owner-only approval page shows the merchant, checkout origin, amount
73
- and currency, item, and reason directly from the short-lived server record before
74
- one passkey ceremony authorizes those canonical payment values. You also see the
75
- requesting MCP client (for example, Hermes) and the bound card's label plus last
76
- four digits (or its label alone for a legacy card) before clicking **Approve
77
- payment** to relay the operator-sealed final authorization. Before submitting that
78
- authorization, you can instead choose **Deny payment**; a denial closes that
79
- approval attempt and prevents any later operator confirmation. When the pre-submission
80
- checkout can be machine-read, the payment is refused if its merchant, origin, amount,
81
- or currency has changed since approval. If that resume read cannot recover a total,
82
- Trusty Squire reuses the original mandate-bound checkout values. Card entry requires the PAN,
83
- expiry, and CVV fields; cardholder name and other explicitly labeled billing fields
84
- are filled best-effort, so a missing name field does not abort the payment. Sealing
85
- and cleanup touch only those selected payment controls; merchant shipping address and
86
- country controls remain untouched. If the checkout has a selected merchant-saved card
87
- alongside the newly filled card, Trusty Squire selects the sole unambiguous new-card
88
- radio and verifies both that choice and the filled fields again immediately before
89
- submission; ambiguous choices, selected saved-card options, and failed verification
90
- are refused with `payment_card_selection_ambiguous`. A charge is treated as
91
- dispatched only after the browser observes a concrete charge/order request, a
92
- terminal merchant outcome, or genuine 3-D Secure evidence; native form validation
93
- alone does not claim a dispatch. A submit is reported as `payment_submitted` only
94
- after the checkout reaches a new merchant order-confirmation URL with a substantive
95
- order or receipt identity. The browser completes 3-D Secure natively, including
96
- out-of-band bank-app challenges — Trusty Squire never manipulates or intercepts the
97
- challenge; it uses read-only checks while polling for that same order-confirmation
98
- signal. At that last observable boundary, a mismatch between the released card and
99
- issuer, network, or last-four evidence rendered by the 3-D Secure issuer/app is
100
- returned as a structured `warning` with `kind: "payment_instrument_mismatch"` and
101
- expected-versus-observed evidence. The warning persists through resumable
102
- `operate_payment_status` calls; it neither changes the payment status nor cancels,
103
- approves, or modifies the challenge, so the cardholder retains the decision whether
104
- to continue. A dispatched attempt with no confirmed merchant outcome and no genuine
105
- 3-D Secure evidence remains `payment_outcome_unknown`, including across resumable
106
- status checks; Trusty Squire never relabels that uncertainty as 3-D Secure. A detected
107
- challenge that remains unresolved on timeout stays `payment_3ds_required` with
108
- `needs_user.wall: "3ds"`, handing control back for user completion. Neither status is
109
- success or permits blind resubmission: manually check the merchant's order state
110
- before any retry.
111
-
112
- `operate_pay` surfaces the approval link before its bounded server-side wait. It
113
- may wait up to one minute for approval, denial, or expiry; if it returns
114
- `approval_pending` first, call `operate_pay` again with the same arguments. That
115
- call resumes the same approval and one-passkey boundary instead of creating a new
116
- link. `operate_payment_status` is a non-charging alternative for inspecting the
117
- pre-charge approval and is the continuation tool for an already-submitted unknown
118
- or 3-D Secure outcome. Its `wait_seconds` accepts 0-60 (default 0) to bound-wait
119
- instead of taking an instant peek. Denial or expiry is terminal for that session's
120
- attempt: repeated calls return the same result and never mint a replacement
121
- approval. Close the session and start a fresh one before making a genuinely new
122
- payment attempt.
123
-
124
- Every payment response includes its `session_id`. Pass that same ID to every
125
- follow-up payment call. Omitting `session_id` remains compatible only while this
126
- MCP process has exactly one session; it never selects a newest or arbitrary checkout.
127
-
128
- Some split checkouts collect the card before the final order-confirmation step. On the
129
- card-entry page, `operate_pay { phase: "fill_card" }` first reads the live total. A
130
- subtotal qualifies as that payable amount only when the same order summary says
131
- shipping is free; recommendation and related-product prices are excluded. If that
132
- page exposes no total, caller-supplied `amount_cents` and `currency` take precedence
133
- as the approval amount. If they are omitted, Trusty Squire may use the most recent real
134
- total observed earlier in the same browser session, such as the cart subtotal, only
135
- when the checkout origin still matches. One phone approval
136
- binds that amount and releases the card; Trusty Squire fills the card without
137
- submitting and its role in the purchase ends there. It fills only the merchant's own
138
- HTTPS frames or recognized payment-provider frames. The card stays in the page as
139
- filled fields while the agent advances to the review step and places the order;
140
- those fields are ordinary page content in `operate_observe` and
141
- `operate_screenshot`, not masked. Verify the live final total against the approved
142
- `amount_cents`/currency yourself before placing the order; Trusty Squire no longer
143
- re-reads the total or submits anything. For `operate_click`, a control whose
144
- label looks like pay/place-order may fire only once for that approval. A second
145
- recognized attempt is refused and requires a fresh `operate_pay` approval in a new
146
- session. Non-charge-labeled clicks, key presses, and OAuth controls remain ungated.
147
- After a recognized click dispatches, Trusty Squire best-effort records a secret-free
148
- `payment_place_order_attempted` Activity event bound to the approval, optional
149
- mandate, approved amount/currency, merchant, and opaque card reference. This records
150
- an attempt, not a verified charge outcome.
151
-
152
- `operate_pay { phase: "confirm" }` just releases the session's pending-fill lock and
153
- reports the approved terms back — it makes no browser or provider call, records no
154
- audit event itself, and never charges. It can be called any time after the fill — it does not
155
- need to happen before you place the order, and it never reads a total or verifies an
156
- amount. If a payment gets stuck or a card is declined, recover with `operate_finish`
157
- and start a fresh session; `operate_pay` does not support refilling a different card
158
- mid-session.
159
-
160
- Before an initial single-page or `fill_card` call, Trusty Squire follows the actual
161
- visible card-number field and hands the checkout back when that field is hosted by
162
- PayPal or Braintree. A separate PayPal express button does not block fillable merchant
163
- or Shopify PCI card fields. Trusty Squire does not sign in to PayPal or use vaulted
164
- PayPal credentials. After any submit that has not yet reached a confirmed order,
165
- Trusty Squire waits 180 seconds by default for native completion, including
166
- out-of-band bank-app approval. A linked Telegram chat receives a challenge-specific
167
- nudge only after 3-D Secure is detected. Standard cross-processor 3-D Secure signals and recognized
168
- CardinalCommerce or Stripe challenge frames classify the first case only when the
169
- containing frame is visibly rendered. Hidden 3-D Secure Method pre-authentication and
170
- captcha-hosted frames never count as 3-D Secure, and an ordinary Shopify PCI card-field
171
- host alone does not either. It reports a visible decline and hands an unresolved outcome
172
- back on timeout, noting whether the Telegram nudge actually went out.
173
- `three_ds_wait_seconds` accepts whole seconds from 0 to 600; set it to `0` on
174
- `operate_pay` to skip the notification and waiting and receive the handoff
175
- immediately.
176
-
177
- Connect Telegram under Vault Settings to receive secret-free alerts for
178
- credential, card, payment, and app-grant lifecycle changes. Routine credential
179
- retrieval and proxy access stay in Activity instead of sending a push for every
180
- request.
24
+ ## Direct payment observation
25
+
26
+ The agent drives the live checkout from ordinary browser evidence. It reads the
27
+ amount, currency, DCC choice, card controls, validation errors, requests, and
28
+ rendered state with `operate_observe`, `operate_network`, and
29
+ `operate_screenshot`, then uses the ordinary click, type, select, press, scroll,
30
+ and wait loop to advance the purchase. A spinner is evidence; the operator does
31
+ not translate it into a payment stage.
32
+
33
+ When card fields are ready, call `list_payment_cards` and then
34
+ `inject_card` with the addressed session, the purchase terms, the selected
35
+ `card_ref`, and an observation ref for each field to fill. `inject_card` uses the
36
+ existing single human approval for that purchase, verifies the signed release,
37
+ and opens the card only inside the operator. A pending approval is resumed with
38
+ the returned `approval_id`; retries may supply changed field refs under that same
39
+ still-valid approval. The primitive fills only the named fields and returns a
40
+ per-field `filled`, `not_found`, `detached`, or `native_error` result. It never
41
+ searches for a provider, chooses a saved-card UI, rereads the total, submits,
42
+ clears fields, or diagnoses the checkout.
43
+
44
+ Hosted-field providers can render decoy autofill or focus-helper inputs beside
45
+ the actual field (notably Braintree and Stripe). Choose the ref for the visible
46
+ card control, not a helper input. Before placing the order, re-observe and
47
+ confirm that no competing merchant-saved-card radio or option remains selected.
48
+ If a 3-D Secure challenge appears, the operator detects it on the next
49
+ observation or action result, notifies the cardholder once through the purchase
50
+ notification path, and reports `three_ds` with state `challenge_detected`; keep
51
+ observing the live checkout while the cardholder completes it. `three_ds` can
52
+ also carry state `sdk_error_retryable`: no challenge rendered and nothing
53
+ notified, because the processor's own SDK failed to launch its challenge UI
54
+ (e.g. `THREEDS_CARDINAL_SDK_ERROR` in the page's error telemetry). That failure
55
+ is transient — the checkout re-arms, and resubmitting the payment is expected
56
+ to launch the challenge. It is advisory only: nothing is gated, and a detected
57
+ challenge always takes precedence. Once a challenge has rendered in the
58
+ session, the advisory is never reported again, so a resubmit prompt can never
59
+ ride a checkout that already completed one.
60
+
61
+ Before the first card write, the operator installs a session-lifetime output
62
+ mask for that released PAN and security code. Normal DOM/AX observations, raw
63
+ attribute/subtree reads, network headers and bodies, errors, console evidence,
64
+ and screenshots replace or cover complete values and ordinary PAN prefixes of
65
+ at least eight digits. Merchant last4, brand, name, expiry, billing address,
66
+ amounts, currency/DCC, HTTP errors, API keys, and 3-D Secure controls remain
67
+ visible. The agent re-observes partial fills, retries targets if needed, selects
68
+ currency, clicks place order, and follows 3-D Secure from the same generic
69
+ evidence stream. There is no `operate_payment_status` or operator-owned
70
+ submit/outcome state machine.
71
+
72
+ This is a narrow ordinary-checkout boundary, not hostile-page information-flow
73
+ containment. It is designed for ordinary forms and reachable hosted fields;
74
+ provider-specific behavior still has to be verified from the returned field
75
+ results and fresh observations. A hostile page can split, encode, or
76
+ canvas-render a card value so it no longer matches the released value; the
77
+ operator does not add a broad secret scanner or claim to defeat that page.
181
78
 
182
79
  ## Install
183
80
 
@@ -272,16 +169,19 @@ The result contains a host-scoped egress `base_url` and a `token`, not the Clerk
272
169
  - App grants are host-scoped, auditable, rate-limitable, and independently revocable. A leaked grant can be revoked without rotating the provider key.
273
170
  - You connect Google or GitHub in a real browser. Trusty Squire does not ask the coding agent to type those passwords.
274
171
  - Saved cards are encrypted in your browser with a passkey-derived key. For a
275
- single-page payment, your phone releases the card only after approving the
276
- exact purchase details shown on the approval page. On a split checkout, one
277
- amount-bound approval releases the card; Trusty Squire's role ends at the fill
278
- and the caller places the order and verifies the final total itself. The API
172
+ purchase, your phone releases the card only after approving the exact purchase
173
+ details shown on the approval page. The caller then observes the live checkout,
174
+ places the order, and verifies the result through the generic operator tools. The API
279
175
  temporarily relays only operator-sealed card ciphertext and its signed mandate.
280
- Trusty Squire's API and the coding-agent model never receive plaintext PAN or
281
- CVV. See the
176
+ Trusty Squire's API never receives plaintext PAN or CVV. The normal operator
177
+ read path masks the released PAN (including ordinary formatted spellings and
178
+ prefixes of at least eight digits) and security code before model-facing
179
+ output; hostile transformed page output is outside that narrow boundary. See the
282
180
  [security model](https://github.com/trusty-squire/trusty-squire/blob/main/SECURITY.md#client-encrypted-card-data)
283
181
  for the signed mandate's binding contract.
284
- - Browser screenshots and diagnostics can contain whatever a website visibly rendered. Treat diagnostic artifacts as sensitive and do not ask an agent to re-observe a page after a secret is shown.
182
+ - Browser screenshots and diagnostics remain verbatim except for the released
183
+ card's narrow PAN/security-code mask. Treat all other rendered values as
184
+ potentially sensitive.
285
185
  - Trusty Squire does not bypass phone verification, hard CAPTCHAs, 3-D Secure,
286
186
  payment authorization, or decisions that belong to a person. It stops for
287
187
  human input.
@@ -294,22 +194,24 @@ for the system and data flows.
294
194
  ## MCP tools
295
195
 
296
196
  The default MCP registry exposes 29 tools (31 when maintainer diagnostics are
297
- enabled). The 18-tool operator driving surface uses flat, single-purpose verbs:
197
+ enabled). The 20-tool operator driving surface uses flat, single-purpose verbs:
298
198
  `operate_start`, `operate_finish`, `operate_observe`, `operate_screenshot`,
299
- `operate_navigate`, `operate_click`, `operate_type`, `operate_select`,
300
- `operate_press`, `operate_scroll`, `operate_allow_host`, `operate_login`,
301
- `operate_fill_credential`, `operate_extract`, `operate_pay`,
302
- `operate_payment_status`, `list_credentials`, and `list_payment_cards`.
199
+ `operate_network`, `operate_navigate`, `operate_click`, `operate_type`, `operate_select`,
200
+ `operate_press`, `operate_scroll`, `operate_wait`, `operate_read_inbox`, `operate_login`,
201
+ `operate_fill_credential`, `operate_extract`, `inject_card`, `list_credentials`,
202
+ `list_payment_cards`, and `edit_payment_card`.
303
203
  Recipe and vault/account tools remain separate surfaces. The complete migration
304
204
  table and input contracts are in [operator-tool-surface.md](docs/operator-tool-surface.md).
305
- Continue a pending pre-charge approval by re-calling
306
- `operate_pay` with the same arguments; use
307
- `operate_payment_status(wait_seconds)` as a non-charging alternative and for
308
- post-submit outcome checks. `operate_screenshot(session_id,
205
+ The evidence required to qualify an operator build is in
206
+ [operator-acceptance-runbook.md](docs/operator-acceptance-runbook.md).
207
+ Continue a pending card release by re-calling `inject_card` with its returned
208
+ `approval_id`. `operate_screenshot(session_id,
309
209
  frame_index?, frame_url_contains?, full_page?)` is a read-only debugging capture
310
210
  (page or one isolated frame, e.g. a cross-origin 3-D Secure/captcha challenge)
311
- returned as an actual MCP image. It returns the page's real pixels: there is no
312
- redaction pass and no refusal when the page is showing a secret or a card value.
211
+ returned as an actual MCP image. It returns real pixels, with only injected
212
+ PAN/security-code controls and identified ordinary copies covered after card release.
213
+ For controls visible only in the image, see
214
+ [screenshot-coordinate clicks](docs/operator-tool-surface.md#clicking-a-screenshot-visible-control).
313
215
  The maintainer-only `list_extract_failures` → `get_extract_failure`
314
216
  DOM-diagnostics pair is excluded from that surface; set
315
217
  `TRUSTY_SQUIRE_DIAGNOSTICS=1` in the MCP server environment to opt into the
@@ -321,21 +223,21 @@ button, link, textbox, select, checkbox, radio, tab, menuitem, and file
321
223
  control, including those outside the viewport. Non-control markup and page text
322
224
  are absent from that shape by construction, never redacted. Use `query`,
323
225
  `role`, or `cursor` to filter or page the same map, then scroll or act on a
324
- returned ref. Use `format:"full"` only when the unchanged, verbatim
325
- `browser-use-dom` tree is needed for page text, attributes, or layout context;
326
- neither format masks or screens emitted content. The authoritative observation
226
+ returned ref. Use `format:"full"` only when the DOM tree is needed for page
227
+ text, attributes, or layout context. Both formats are otherwise verbatim, with
228
+ the same narrow released-card value mask. The authoritative observation
327
229
  contract is [observation-model.md](docs/observation-model.md), and the detailed
328
230
  full-DOM structure is in
329
231
  [browser-use-serializer-port.md](docs/browser-use-serializer-port.md). A browser action can
330
- require re-observation before a ref is used again. Maintainers can select the
331
- legacy V1 `el_table`/snapshot contract with
332
- `TRUSTY_SQUIRE_OBSERVE_V2=off`, or exercise the browser-use DOM serializer
333
- without emitting it with `shadow`; the detailed DOM-tree contract lives in
334
- [browser-use-serializer-port.md](docs/browser-use-serializer-port.md).
232
+ require re-observation before a ref is used again. Click, type, select, press,
233
+ and scroll also default to compact observations; pass `format:"full"` on that
234
+ action only when its verbatim DOM is needed. See the observation contract above
235
+ for delta handling and response envelopes. The detailed DOM-tree contract lives
236
+ in [browser-use-serializer-port.md](docs/browser-use-serializer-port.md).
335
237
 
336
238
  - Rejected tool calls return a JSON `error` envelope with a stable `code` and
337
239
  message. Malformed and unknown calls fail only that request; they do not stop
338
- the shared stdio process or discard its active in-memory operator session.
240
+ the stdio process or discard the broker-owned operator session.
339
241
  `server_unavailable` includes `retry.max_attempts: 1`: retry once, and never
340
242
  kill or restart the shared operator process.
341
243
  - `operate_start` opens a scoped website session and `operate_observe` reads its
@@ -345,31 +247,26 @@ without emitting it with `shadow`; the detailed DOM-tree contract lives in
345
247
  `operate_type` accepts either literal `text` or a protected session `slot`,
346
248
  never both. `operate_click` alone may use its guarded internal DOM-dispatch
347
249
  fallback after a proven non-dispatch; it is not a public alternative action.
348
- Frame scope and stale-ref handling remain fail-closed. For ordinary actions,
349
- an owned popup becomes the active page; unrelated/no-opener pages do not.
250
+ Frame scope and stale-ref handling remain fail-closed. For click-triggered
251
+ pickers, follow the [picker and popup guidance](docs/operator-tool-surface.md#pickers-and-popup-return).
350
252
  Use `operate_login` for atomic OAuth and the username/password lifecycle,
351
- `operate_extract` to capture
352
- credentials, and `operate_fill_credential` to load protected slots. CAPTCHA
353
- solving, inbox polling, local upload, and specialized cart mutation are not
354
- operator verbs; inspect and drive the page's ordinary UI or hand the task back
355
- to the user.
356
- In a live operator session, in-page XHR/fetch calls to merchant API sibling
357
- subdomains are automatically in scope only when they share the registrable
358
- domain of a host trusted at session start. Calls outside the session scope fail
359
- promptly instead of hanging; page-load resources continue normally, and a
360
- mid-session `allow_host` does not seed sibling-domain widening. A small set of
361
- always-in-scope hosts (recognized payment-provider frames, OAuth/captcha
362
- providers, and 3-D Secure ACS/directory-server hosts) is exempt from that
363
- session-start-trust requirement — otherwise a checkout's own out-of-band 3DS
364
- challenge could never complete its own status poll.
365
- Every operator task uses the user's Chrome profile directly. Before it starts,
253
+ `operate_extract` to [capture credentials](docs/operator-tool-surface.md#credential-capture-and-retrieval),
254
+ and `operate_fill_credential` to load protected slots. The only mailbox
255
+ access is `operate_read_inbox`, the consent-gated Gmail verification read;
256
+ CAPTCHA solving, general inbox polling, local upload, and specialized cart
257
+ mutation are not operator verbs; inspect and drive the page's ordinary UI or
258
+ hand the task back to the user.
259
+ Browser requests need no host declarations. See the
260
+ [egress contract](docs/operator-tool-surface.md#browser-egress-is-unrestricted)
261
+ for legacy parameter compatibility and the unchanged payment/vault boundaries.
262
+ Operator servers automatically share the [browser broker](docs/browser-broker.md),
263
+ which owns the user's Chrome profile. Before a session starts,
366
264
  the operator checks the live Google My Account identity; if the profile is
367
265
  signed out, it returns a clear login handoff before navigating to the service.
368
- To route only that browser session through a proxy, pass `proxy` to
369
- `operate_start` as an HTTP or HTTPS URL (credentials are optional), or as an
370
- unauthenticated SOCKS5 URL. The value is launch-only and sensitive: it is not
371
- returned in session status, action traces, or saved recipes. Omitting it uses
372
- direct egress.
266
+ If a restart or reconnect leaves the browser profile busy, follow the
267
+ [reconnect recovery guide](docs/DESIGN-warm-browser-reuse.md#recovering-after-reconnect).
268
+ For proxy configuration and shared-browser compatibility, see the
269
+ [broker configuration guide](docs/browser-broker.md#configuration-and-operation).
373
270
  Under the browser-use DOM format, an expired, forged, wrong-generation, cross-page, or drifted
374
271
  `@e:` handle fails opaquely with `reobserve_required`; re-observe and choose a
375
272
  current handle. Under V1, DOM churn returns `target_stale` with the last
@@ -378,8 +275,13 @@ without emitting it with `shadow`; the detailed DOM-tree contract lives in
378
275
  Malformed flat-verb calls return `error.code: "invalid_arguments"` without
379
276
  ending the shared server process or discarding the active session. For a
380
277
  provider login, pass the observed provider-button ref to `operate_login`.
381
- It retains the product tab across provider-owned popup
382
- redirects and closes. When it observes the authorized return destination still
278
+ It retains the product tab across provider-owned popup redirects and closes.
279
+ Completion requires attempt-local navigation evidence from the selected
280
+ provider to the exact declared return path and fixed query. A declared chain
281
+ may contain one return destination or one callback followed by one dashboard;
282
+ in the two-destination case, only the terminal dashboard completes login. An
283
+ unrelated same-origin page, a longer chain, or a chain that returns to the
284
+ provider remains pending. When the authorized completion destination is still
383
285
  open, that destination becomes the session's operation page: its post-login
384
286
  observation and later page-bound operations (actions, reads, screenshots,
385
287
  navigation, verification, and checkout) stay bound to it, leaving the retained
@@ -404,27 +306,33 @@ without emitting it with `shadow`; the detailed DOM-tree contract lives in
404
306
  the session. A consent screen or a 2FA/verification challenge is usually still
405
307
  showing, so re-observe and drive it; the session stays open and usable. A
406
308
  denial the provider actually reported (an OAuth `error=` code on the return
407
- URL) is the one case that fails the action, with that code in the message. If
408
- an observation races the transition, it reports `oauth.state: "in_progress"`
309
+ URL) fails the action, with that code in the message. For interrupted clicks,
310
+ retained popups, and pre-dispatch failures, follow the
311
+ [OAuth error and recovery contract](docs/operator-tool-surface.md#using-the-rest-of-the-surface).
312
+ If an observation races the transition, it reports `oauth.state: "in_progress"`
409
313
  and directs the host to observe again.
410
- - Observed card controls are marked `payment_field` and
411
- `interaction: "vaulted_card_only"`, with `operate_pay { phase: "fill_card" }`
412
- as the recommended action. Typing a Luhn-valid, card-number-shaped value
413
- manually through `operate_type` is refused with `safe_alternative: "operate_pay"`
414
- and the missing prerequisite `verified_cart_total`.
415
- - `operate_finish` closes the session and optionally accepts a nested `outcome`.
416
- `none` only closes; `credentials` requires `store` and preserves credential
417
- extraction, vault storage, and auto-promotion; `result` requires `summary` or
418
- `data`. A result is eligible to save portable login state only when
419
- `verify_recipe` confirms it or `data.confirmed` is `true`; credential outcomes
420
- qualify only after unblocked extraction and vault storage. `none`, failed or
421
- unconfirmed outcomes, and payment-sensitive sessions preserve the prior saved
422
- snapshot. Finish first stops new calls and drains calls already using that
423
- session within a bounded terminal transition, then closes its browser and
424
- schedules private-profile removal. Sessions also close automatically after 10 minutes without an
425
- operation and begin terminal teardown at 30 minutes; only an active payment
426
- receives the short bounded close grace. Callers should finish promptly instead
427
- of treating an open browser as durable background state.
314
+ - Call `inject_card` with the exact observed refs for the card-entry fields.
315
+ It fills only those refs under the existing purchase approval; the agent
316
+ observes partial results and drives every later checkout action itself. Pick
317
+ the real visible field rather than a hosted-provider autofill/focus helper;
318
+ before placing the order, re-observe for a competing selected saved card. A
319
+ rendered 3-D Secure challenge is detected by the operator, which notifies the
320
+ cardholder once and reports `three_ds` with state `challenge_detected`; keep
321
+ observing while the cardholder completes it. The other state,
322
+ `sdk_error_retryable`, reports that the processor's SDK failed to launch the
323
+ challenge UI at all nothing is notified and nothing is gated; the checkout
324
+ re-arms and a resubmitted payment is expected to launch the challenge.
325
+ - `operate_finish` closes the session with a flat `outcome` enum — never a
326
+ nested union. `none` only closes; `credentials` requires `store` and preserves
327
+ credential extraction and vault storage; `result` requires `summary` or
328
+ `data`. Agent-provided result data is reported information, not proof that a
329
+ login, provisioning operation, or mutation completed. Finish first fences new
330
+ calls and drives the owned terminal transition; callers must not infer closure
331
+ merely from a delivery timeout. Callers should finish promptly instead of
332
+ treating an open browser as durable background state. The current server advertises an additive receipt through `tools/list` with `session_id`,
333
+ `operation_id`, `execution`, `mutation`, `cleanup`, and `closed:boolean`.
334
+ Closure is established only when `closed` is true. Older servers may omit
335
+ these fields; a missing receipt never proves cleanup.
428
336
  - `operate_recipe_save` saves a postcondition-verified local recipe under a
429
337
  closed task verb plus the service's registrable domain. It records stable target
430
338
  attributes and exact provenance for Squire-supplied values, not observed refs
@@ -438,20 +346,20 @@ without emitting it with `shadow`; the detailed DOM-tree contract lives in
438
346
  navigation and continues with cold driving. On one ordinary missed step,
439
347
  replay returns a local repair point and can continue in the same session.
440
348
  Older name-only recipes remain planning hints.
441
- - `list_payment_cards` returns saved-card labels and opaque references;
442
- `operate_pay` accepts an explicit `session_id` and `phase` of `"single"`
443
- (the default, also implied by omitting phase), `"fill_card"`, or `"confirm"`.
444
- It can use a selected card, the only card on file, or a just-in-time
445
- add-card approval. The single-page flow fills the checkout and applies the
446
- post-submit outcome wait described above before handing back unresolved
447
- outcomes. Split checkouts use the `fill_card` then `confirm` flow described
448
- above.
449
- `operate_payment_status` follows the [payment guide](#one-prompt) bounded-wait
450
- contract. It returns the session ID and includes it in every follow-up tool
451
- hint, so an approval or submitted outcome is always observed in its originating
452
- browser. Malformed calls return normal `invalid_arguments` handling, including a safe resolution
453
- when `card_ref` and `card_label` conflict.
349
+ - `list_payment_cards` returns saved-card labels and opaque references.
350
+ `inject_card` takes one explicit `card_ref`, purchase terms, and per-field
351
+ refs plus the addressed `session_id`. It creates or resumes the single approval
352
+ and returns per-field browser outcomes plus approval metadata and last4; it
353
+ never returns PAN/CVV or submits.
454
354
  - `list_credentials` and `use_credential` find saved credentials and make authenticated API calls without returning raw values.
355
+ Before provisioning, call `list_credentials` with
356
+ `{"service":["exa","groq","cartesia"],"fields":"summary"}` to check for
357
+ existing keys without returning the whole inventory. `service` accepts one
358
+ string or a nonempty array and matches exact service names after trimming
359
+ whitespace and ignoring case. `fields: "summary"` selects compact metadata;
360
+ calling with `{}` preserves the full metadata inventory. Discover the exact
361
+ projection and inputs through the installed server's `tools/list` description
362
+ and schema.
455
363
  - `fetch_credential` returns a credential's raw value to the agent — the one path that does. It first returns an approval link and no value; you open it and sign with your passkey; the agent resumes with the returned `approval_id` and receives the value once. Denial or expiry releases nothing, and a mutation or payment approval cannot be used here. Reach for it only when the key must land somewhere the agent controls (a GitHub Actions secret, a `.env`) with no server-side injection path — `use_credential` is the right tool for calling an API.
456
364
  - `edit_credential` changes only an existing credential's non-secret name,
457
365
  `allowed_hosts`, or `login_hosts`; `delete_credential` soft-deletes one. Each
@@ -16,11 +16,6 @@ export interface ApiClientConfig {
16
16
  agentIdentity?: string;
17
17
  accountId?: string;
18
18
  }
19
- export interface ApiAuditContext {
20
- taskId: string;
21
- invocationId: string;
22
- purpose: string;
23
- }
24
19
  export interface ProvisionInput {
25
20
  service: string;
26
21
  plan: string;
@@ -66,6 +61,7 @@ export interface VaultCredentialSummary {
66
61
  created_at: string;
67
62
  last_retrieved_at: string | null;
68
63
  retrieval_count: number;
64
+ stale?: boolean;
69
65
  }
70
66
  export interface CredentialMutationApproval {
71
67
  approval_id: string;
@@ -92,6 +88,30 @@ export interface CredentialMutationApproval {
92
88
  expires_at: string;
93
89
  error?: string;
94
90
  }
91
+ export interface CardMutationApproval {
92
+ approval_id: string;
93
+ approval_url: string;
94
+ status: "pending" | "approved" | "failed" | "expired";
95
+ operation: "edit_card";
96
+ card: {
97
+ id: string;
98
+ label: string;
99
+ brand: string | null;
100
+ last4: string | null;
101
+ };
102
+ before: {
103
+ label: string;
104
+ brand: string | null;
105
+ last4: string | null;
106
+ };
107
+ after: {
108
+ label: string;
109
+ brand: string | null;
110
+ last4: string | null;
111
+ } | null;
112
+ expires_at: string;
113
+ error?: string;
114
+ }
95
115
  export interface CredentialFetchApproval {
96
116
  approval_id: string;
97
117
  approval_url: string;
@@ -143,14 +163,32 @@ export interface PaymentApproval {
143
163
  sealed_card: string | null;
144
164
  expires_at: string;
145
165
  }
166
+ export interface HeightenedAuthNotificationInput {
167
+ service: string;
168
+ attempt_id: string;
169
+ challenge_revision: string;
170
+ digit: string | null;
171
+ observed_at: string;
172
+ expires_at: string | null;
173
+ window_seconds: number;
174
+ }
175
+ export interface HeightenedAuthNotificationResult {
176
+ sent: boolean;
177
+ deduped: boolean;
178
+ attempt_id: string;
179
+ challenge_revision: string;
180
+ delivery: {
181
+ channel: "telegram" | "email" | null;
182
+ status: "sent" | "failed";
183
+ error?: string;
184
+ };
185
+ }
146
186
  export declare class ApiClient {
147
187
  private readonly config;
148
188
  private readonly fetchImpl;
149
189
  private requestingAgent;
150
- private readonly auditContext;
151
190
  constructor(config: ApiClientConfig);
152
191
  setRequestingAgent(name: string): void;
153
- withAuditContext<T>(context: ApiAuditContext, fn: () => Promise<T>): Promise<T>;
154
192
  createRun(input: ProvisionInput): Promise<CreateRunResponse>;
155
193
  getRun(runId: string): Promise<RunSummary>;
156
194
  createPaymentApproval(input: {
@@ -188,6 +226,7 @@ export declare class ApiClient {
188
226
  notifyThreeDs(approvalId: string, mode: "detected_challenge" | "possible_out_of_band"): Promise<{
189
227
  sent: boolean;
190
228
  }>;
229
+ notifyHeightenedAuth(input: HeightenedAuthNotificationInput, signal?: AbortSignal): Promise<HeightenedAuthNotificationResult>;
191
230
  auditPayment(input: {
192
231
  merchant: string;
193
232
  amount_cents: number;
@@ -204,6 +243,7 @@ export declare class ApiClient {
204
243
  credentials: VaultCredentialSummary[];
205
244
  }>;
206
245
  storeCredential(input: {
246
+ write_id?: string;
207
247
  service: string;
208
248
  label?: string;
209
249
  value?: string;
@@ -245,6 +285,12 @@ export declare class ApiClient {
245
285
  };
246
286
  }): Promise<CredentialMutationApproval>;
247
287
  getCredentialMutationApproval(id: string): Promise<CredentialMutationApproval>;
288
+ createCardMutationApproval(input: {
289
+ operation: "edit_card";
290
+ card_id?: string;
291
+ label?: string;
292
+ }): Promise<CardMutationApproval>;
293
+ getCardMutationApproval(id: string): Promise<CardMutationApproval>;
248
294
  createCredentialFetchApproval(input: {
249
295
  reference?: string;
250
296
  service?: string;