@harrylabsj/kiwi 0.6.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 (636) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +150 -0
  3. package/contracts/candidate-agent-dto-1.0.README.md +39 -0
  4. package/contracts/candidate-agent-dto-1.0.schema.json +172 -0
  5. package/contracts/interop/kiwi-buyer-message-send.json +43 -0
  6. package/contracts/interop/knp-data-part-examples.json +243 -0
  7. package/contracts/kiwi-catalog/1.0/agent-record.schema.json +78 -0
  8. package/contracts/kiwi-catalog/1.0/listing-record.schema.json +88 -0
  9. package/contracts/kiwi-catalog/1.0/listing-search-result.schema.json +60 -0
  10. package/contracts/negotiation/1.0/schema.json +501 -0
  11. package/contracts/shopping.negotiation/0.1/capabilities.schema.json +47 -0
  12. package/contracts/shopping.negotiation/0.1/decision.schema.json +120 -0
  13. package/contracts/shopping.negotiation/0.1/policy-result.schema.json +52 -0
  14. package/contracts/shopping.negotiation/0.1/snapshot.schema.json +172 -0
  15. package/dist/a2a/client/client.d.ts +33 -0
  16. package/dist/a2a/client/client.js +161 -0
  17. package/dist/a2a/client/client.js.map +1 -0
  18. package/dist/a2a/client/error.d.ts +35 -0
  19. package/dist/a2a/client/error.js +34 -0
  20. package/dist/a2a/client/error.js.map +1 -0
  21. package/dist/a2a/client/index.d.ts +29 -0
  22. package/dist/a2a/client/index.js +26 -0
  23. package/dist/a2a/client/index.js.map +1 -0
  24. package/dist/a2a/client/jsonrpc.d.ts +49 -0
  25. package/dist/a2a/client/jsonrpc.js +85 -0
  26. package/dist/a2a/client/jsonrpc.js.map +1 -0
  27. package/dist/a2a/client/parse.d.ts +18 -0
  28. package/dist/a2a/client/parse.js +134 -0
  29. package/dist/a2a/client/parse.js.map +1 -0
  30. package/dist/a2a/client/types.d.ts +102 -0
  31. package/dist/a2a/client/types.js +26 -0
  32. package/dist/a2a/client/types.js.map +1 -0
  33. package/dist/a2a/client/url-policy.d.ts +44 -0
  34. package/dist/a2a/client/url-policy.js +242 -0
  35. package/dist/a2a/client/url-policy.js.map +1 -0
  36. package/dist/a2a/negotiate.d.ts +68 -0
  37. package/dist/a2a/negotiate.js +288 -0
  38. package/dist/a2a/negotiate.js.map +1 -0
  39. package/dist/a2a/node.d.ts +37 -0
  40. package/dist/a2a/node.js +155 -0
  41. package/dist/a2a/node.js.map +1 -0
  42. package/dist/a2a/server/auth.d.ts +38 -0
  43. package/dist/a2a/server/auth.js +112 -0
  44. package/dist/a2a/server/auth.js.map +1 -0
  45. package/dist/a2a/server/card.d.ts +19 -0
  46. package/dist/a2a/server/card.js +81 -0
  47. package/dist/a2a/server/card.js.map +1 -0
  48. package/dist/a2a/server/errors.d.ts +109 -0
  49. package/dist/a2a/server/errors.js +178 -0
  50. package/dist/a2a/server/errors.js.map +1 -0
  51. package/dist/a2a/server/handler.d.ts +22 -0
  52. package/dist/a2a/server/handler.js +57 -0
  53. package/dist/a2a/server/handler.js.map +1 -0
  54. package/dist/a2a/server/inbound-message.d.ts +37 -0
  55. package/dist/a2a/server/inbound-message.js +104 -0
  56. package/dist/a2a/server/inbound-message.js.map +1 -0
  57. package/dist/a2a/server/index.d.ts +43 -0
  58. package/dist/a2a/server/index.js +42 -0
  59. package/dist/a2a/server/index.js.map +1 -0
  60. package/dist/a2a/server/merchant-handler.d.ts +69 -0
  61. package/dist/a2a/server/merchant-handler.js +316 -0
  62. package/dist/a2a/server/merchant-handler.js.map +1 -0
  63. package/dist/a2a/server/pipeline.d.ts +69 -0
  64. package/dist/a2a/server/pipeline.js +329 -0
  65. package/dist/a2a/server/pipeline.js.map +1 -0
  66. package/dist/a2a/server/server.d.ts +64 -0
  67. package/dist/a2a/server/server.js +420 -0
  68. package/dist/a2a/server/server.js.map +1 -0
  69. package/dist/a2a/server/task-registry.d.ts +31 -0
  70. package/dist/a2a/server/task-registry.js +67 -0
  71. package/dist/a2a/server/task-registry.js.map +1 -0
  72. package/dist/a2a/server/throttle.d.ts +154 -0
  73. package/dist/a2a/server/throttle.js +289 -0
  74. package/dist/a2a/server/throttle.js.map +1 -0
  75. package/dist/a2a/server/types.d.ts +191 -0
  76. package/dist/a2a/server/types.js +17 -0
  77. package/dist/a2a/server/types.js.map +1 -0
  78. package/dist/a2a/server/ucp.d.ts +49 -0
  79. package/dist/a2a/server/ucp.js +85 -0
  80. package/dist/a2a/server/ucp.js.map +1 -0
  81. package/dist/a2a/task/index.d.ts +24 -0
  82. package/dist/a2a/task/index.js +22 -0
  83. package/dist/a2a/task/index.js.map +1 -0
  84. package/dist/a2a/task/ledger.d.ts +48 -0
  85. package/dist/a2a/task/ledger.js +65 -0
  86. package/dist/a2a/task/ledger.js.map +1 -0
  87. package/dist/a2a/task/poller.d.ts +93 -0
  88. package/dist/a2a/task/poller.js +184 -0
  89. package/dist/a2a/task/poller.js.map +1 -0
  90. package/dist/a2a/task/state.d.ts +72 -0
  91. package/dist/a2a/task/state.js +119 -0
  92. package/dist/a2a/task/state.js.map +1 -0
  93. package/dist/a2a/ucp-agent.d.ts +49 -0
  94. package/dist/a2a/ucp-agent.js +78 -0
  95. package/dist/a2a/ucp-agent.js.map +1 -0
  96. package/dist/agent/agent-db.d.ts +31 -0
  97. package/dist/agent/agent-db.js +91 -0
  98. package/dist/agent/agent-db.js.map +1 -0
  99. package/dist/agent/buyer/buyer-tools.d.ts +70 -0
  100. package/dist/agent/buyer/buyer-tools.js +1353 -0
  101. package/dist/agent/buyer/buyer-tools.js.map +1 -0
  102. package/dist/agent/buyer/ranker.d.ts +53 -0
  103. package/dist/agent/buyer/ranker.js +153 -0
  104. package/dist/agent/buyer/ranker.js.map +1 -0
  105. package/dist/agent/buyer/scheduler.d.ts +58 -0
  106. package/dist/agent/buyer/scheduler.js +317 -0
  107. package/dist/agent/buyer/scheduler.js.map +1 -0
  108. package/dist/agent/buyer/search-loop.d.ts +42 -0
  109. package/dist/agent/buyer/search-loop.js +280 -0
  110. package/dist/agent/buyer/search-loop.js.map +1 -0
  111. package/dist/agent/buyer/task-store.d.ts +178 -0
  112. package/dist/agent/buyer/task-store.js +637 -0
  113. package/dist/agent/buyer/task-store.js.map +1 -0
  114. package/dist/agent/buyer/types.d.ts +222 -0
  115. package/dist/agent/buyer/types.js +124 -0
  116. package/dist/agent/buyer/types.js.map +1 -0
  117. package/dist/agent/chat-tools.d.ts +41 -0
  118. package/dist/agent/chat-tools.js +193 -0
  119. package/dist/agent/chat-tools.js.map +1 -0
  120. package/dist/agent/chat-tui.d.ts +49 -0
  121. package/dist/agent/chat-tui.js +314 -0
  122. package/dist/agent/chat-tui.js.map +1 -0
  123. package/dist/agent/connector/fake-connector.d.ts +50 -0
  124. package/dist/agent/connector/fake-connector.js +138 -0
  125. package/dist/agent/connector/fake-connector.js.map +1 -0
  126. package/dist/agent/connector/http-connector.d.ts +49 -0
  127. package/dist/agent/connector/http-connector.js +208 -0
  128. package/dist/agent/connector/http-connector.js.map +1 -0
  129. package/dist/agent/connector/types.d.ts +103 -0
  130. package/dist/agent/connector/types.js +97 -0
  131. package/dist/agent/connector/types.js.map +1 -0
  132. package/dist/agent/fake-chat-model.d.ts +22 -0
  133. package/dist/agent/fake-chat-model.js +134 -0
  134. package/dist/agent/fake-chat-model.js.map +1 -0
  135. package/dist/agent/kernel.d.ts +258 -0
  136. package/dist/agent/kernel.js +1099 -0
  137. package/dist/agent/kernel.js.map +1 -0
  138. package/dist/agent/memory/schema.d.ts +32 -0
  139. package/dist/agent/memory/schema.js +291 -0
  140. package/dist/agent/memory/schema.js.map +1 -0
  141. package/dist/agent/memory/store.d.ts +193 -0
  142. package/dist/agent/memory/store.js +881 -0
  143. package/dist/agent/memory/store.js.map +1 -0
  144. package/dist/agent/memory/types.d.ts +139 -0
  145. package/dist/agent/memory/types.js +119 -0
  146. package/dist/agent/memory/types.js.map +1 -0
  147. package/dist/agent/memory/vault.d.ts +49 -0
  148. package/dist/agent/memory/vault.js +125 -0
  149. package/dist/agent/memory/vault.js.map +1 -0
  150. package/dist/agent/merchant/action-candidate.d.ts +106 -0
  151. package/dist/agent/merchant/action-candidate.js +241 -0
  152. package/dist/agent/merchant/action-candidate.js.map +1 -0
  153. package/dist/agent/merchant/credential-broker.d.ts +67 -0
  154. package/dist/agent/merchant/credential-broker.js +76 -0
  155. package/dist/agent/merchant/credential-broker.js.map +1 -0
  156. package/dist/agent/merchant/fake-merchant-client.d.ts +47 -0
  157. package/dist/agent/merchant/fake-merchant-client.js +143 -0
  158. package/dist/agent/merchant/fake-merchant-client.js.map +1 -0
  159. package/dist/agent/merchant/merchant-client.d.ts +49 -0
  160. package/dist/agent/merchant/merchant-client.js +186 -0
  161. package/dist/agent/merchant/merchant-client.js.map +1 -0
  162. package/dist/agent/merchant/merchant-tools.d.ts +74 -0
  163. package/dist/agent/merchant/merchant-tools.js +582 -0
  164. package/dist/agent/merchant/merchant-tools.js.map +1 -0
  165. package/dist/agent/merchant/types.d.ts +119 -0
  166. package/dist/agent/merchant/types.js +133 -0
  167. package/dist/agent/merchant/types.js.map +1 -0
  168. package/dist/agent/mode.d.ts +32 -0
  169. package/dist/agent/mode.js +34 -0
  170. package/dist/agent/mode.js.map +1 -0
  171. package/dist/agent/negotiation-chat.d.ts +81 -0
  172. package/dist/agent/negotiation-chat.js +330 -0
  173. package/dist/agent/negotiation-chat.js.map +1 -0
  174. package/dist/agent/session.d.ts +22 -0
  175. package/dist/agent/session.js +164 -0
  176. package/dist/agent/session.js.map +1 -0
  177. package/dist/agent/system-prompt.d.ts +26 -0
  178. package/dist/agent/system-prompt.js +77 -0
  179. package/dist/agent/system-prompt.js.map +1 -0
  180. package/dist/agent/write-gate.d.ts +98 -0
  181. package/dist/agent/write-gate.js +76 -0
  182. package/dist/agent/write-gate.js.map +1 -0
  183. package/dist/cli.d.ts +18 -0
  184. package/dist/cli.js +1139 -0
  185. package/dist/cli.js.map +1 -0
  186. package/dist/commerce/data-source.d.ts +88 -0
  187. package/dist/commerce/data-source.js +25 -0
  188. package/dist/commerce/data-source.js.map +1 -0
  189. package/dist/commerce/erp-source.d.ts +51 -0
  190. package/dist/commerce/erp-source.js +184 -0
  191. package/dist/commerce/erp-source.js.map +1 -0
  192. package/dist/commerce/fake-client.d.ts +167 -0
  193. package/dist/commerce/fake-client.js +549 -0
  194. package/dist/commerce/fake-client.js.map +1 -0
  195. package/dist/commerce/http-client.d.ts +73 -0
  196. package/dist/commerce/http-client.js +284 -0
  197. package/dist/commerce/http-client.js.map +1 -0
  198. package/dist/commerce/local-db-source.d.ts +50 -0
  199. package/dist/commerce/local-db-source.js +162 -0
  200. package/dist/commerce/local-db-source.js.map +1 -0
  201. package/dist/commerce/shopping-cli-source.d.ts +57 -0
  202. package/dist/commerce/shopping-cli-source.js +206 -0
  203. package/dist/commerce/shopping-cli-source.js.map +1 -0
  204. package/dist/commerce/types.d.ts +146 -0
  205. package/dist/commerce/types.js +31 -0
  206. package/dist/commerce/types.js.map +1 -0
  207. package/dist/config/profile.d.ts +122 -0
  208. package/dist/config/profile.js +386 -0
  209. package/dist/config/profile.js.map +1 -0
  210. package/dist/contracts/negotiation-schema.d.ts +28 -0
  211. package/dist/contracts/negotiation-schema.js +101 -0
  212. package/dist/contracts/negotiation-schema.js.map +1 -0
  213. package/dist/contracts/schemas.d.ts +31 -0
  214. package/dist/contracts/schemas.js +122 -0
  215. package/dist/contracts/schemas.js.map +1 -0
  216. package/dist/counterparty/a2a-direct/index.d.ts +41 -0
  217. package/dist/counterparty/a2a-direct/index.js +330 -0
  218. package/dist/counterparty/a2a-direct/index.js.map +1 -0
  219. package/dist/counterparty/channel.d.ts +200 -0
  220. package/dist/counterparty/channel.js +61 -0
  221. package/dist/counterparty/channel.js.map +1 -0
  222. package/dist/counterparty/index.d.ts +28 -0
  223. package/dist/counterparty/index.js +24 -0
  224. package/dist/counterparty/index.js.map +1 -0
  225. package/dist/counterparty/platform-api/index.d.ts +41 -0
  226. package/dist/counterparty/platform-api/index.js +65 -0
  227. package/dist/counterparty/platform-api/index.js.map +1 -0
  228. package/dist/counterparty/registry.d.ts +51 -0
  229. package/dist/counterparty/registry.js +71 -0
  230. package/dist/counterparty/registry.js.map +1 -0
  231. package/dist/counterparty/shopping-cli-hosted/index.d.ts +36 -0
  232. package/dist/counterparty/shopping-cli-hosted/index.js +337 -0
  233. package/dist/counterparty/shopping-cli-hosted/index.js.map +1 -0
  234. package/dist/discovery/agent-card/error.d.ts +28 -0
  235. package/dist/discovery/agent-card/error.js +31 -0
  236. package/dist/discovery/agent-card/error.js.map +1 -0
  237. package/dist/discovery/agent-card/extensions.d.ts +20 -0
  238. package/dist/discovery/agent-card/extensions.js +59 -0
  239. package/dist/discovery/agent-card/extensions.js.map +1 -0
  240. package/dist/discovery/agent-card/index.d.ts +29 -0
  241. package/dist/discovery/agent-card/index.js +38 -0
  242. package/dist/discovery/agent-card/index.js.map +1 -0
  243. package/dist/discovery/agent-card/secrets.d.ts +30 -0
  244. package/dist/discovery/agent-card/secrets.js +240 -0
  245. package/dist/discovery/agent-card/secrets.js.map +1 -0
  246. package/dist/discovery/agent-card/types.d.ts +110 -0
  247. package/dist/discovery/agent-card/types.js +37 -0
  248. package/dist/discovery/agent-card/types.js.map +1 -0
  249. package/dist/discovery/agent-card/validate.d.ts +31 -0
  250. package/dist/discovery/agent-card/validate.js +210 -0
  251. package/dist/discovery/agent-card/validate.js.map +1 -0
  252. package/dist/discovery/capability/error.d.ts +23 -0
  253. package/dist/discovery/capability/error.js +28 -0
  254. package/dist/discovery/capability/error.js.map +1 -0
  255. package/dist/discovery/capability/index.d.ts +21 -0
  256. package/dist/discovery/capability/index.js +21 -0
  257. package/dist/discovery/capability/index.js.map +1 -0
  258. package/dist/discovery/capability/intersect.d.ts +56 -0
  259. package/dist/discovery/capability/intersect.js +137 -0
  260. package/dist/discovery/capability/intersect.js.map +1 -0
  261. package/dist/discovery/catalog-source/errors.d.ts +32 -0
  262. package/dist/discovery/catalog-source/errors.js +41 -0
  263. package/dist/discovery/catalog-source/errors.js.map +1 -0
  264. package/dist/discovery/catalog-source/index.d.ts +30 -0
  265. package/dist/discovery/catalog-source/index.js +29 -0
  266. package/dist/discovery/catalog-source/index.js.map +1 -0
  267. package/dist/discovery/catalog-source/kiwi-record.d.ts +183 -0
  268. package/dist/discovery/catalog-source/kiwi-record.js +72 -0
  269. package/dist/discovery/catalog-source/kiwi-record.js.map +1 -0
  270. package/dist/discovery/catalog-source/kiwi-schema.d.ts +33 -0
  271. package/dist/discovery/catalog-source/kiwi-schema.js +106 -0
  272. package/dist/discovery/catalog-source/kiwi-schema.js.map +1 -0
  273. package/dist/discovery/catalog-source/kiwi-source.d.ts +38 -0
  274. package/dist/discovery/catalog-source/kiwi-source.js +318 -0
  275. package/dist/discovery/catalog-source/kiwi-source.js.map +1 -0
  276. package/dist/discovery/catalog-source/register.d.ts +48 -0
  277. package/dist/discovery/catalog-source/register.js +83 -0
  278. package/dist/discovery/catalog-source/register.js.map +1 -0
  279. package/dist/discovery/catalog-source/schema.d.ts +21 -0
  280. package/dist/discovery/catalog-source/schema.js +63 -0
  281. package/dist/discovery/catalog-source/schema.js.map +1 -0
  282. package/dist/discovery/catalog-source/source.d.ts +45 -0
  283. package/dist/discovery/catalog-source/source.js +197 -0
  284. package/dist/discovery/catalog-source/source.js.map +1 -0
  285. package/dist/discovery/catalog-source/types.d.ts +122 -0
  286. package/dist/discovery/catalog-source/types.js +30 -0
  287. package/dist/discovery/catalog-source/types.js.map +1 -0
  288. package/dist/discovery/index.d.ts +25 -0
  289. package/dist/discovery/index.js +25 -0
  290. package/dist/discovery/index.js.map +1 -0
  291. package/dist/discovery/resolve.d.ts +175 -0
  292. package/dist/discovery/resolve.js +367 -0
  293. package/dist/discovery/resolve.js.map +1 -0
  294. package/dist/discovery/ucp/error.d.ts +25 -0
  295. package/dist/discovery/ucp/error.js +27 -0
  296. package/dist/discovery/ucp/error.js.map +1 -0
  297. package/dist/discovery/ucp/index.d.ts +33 -0
  298. package/dist/discovery/ucp/index.js +28 -0
  299. package/dist/discovery/ucp/index.js.map +1 -0
  300. package/dist/discovery/ucp/intersect.d.ts +148 -0
  301. package/dist/discovery/ucp/intersect.js +312 -0
  302. package/dist/discovery/ucp/intersect.js.map +1 -0
  303. package/dist/discovery/ucp/resolver.d.ts +62 -0
  304. package/dist/discovery/ucp/resolver.js +214 -0
  305. package/dist/discovery/ucp/resolver.js.map +1 -0
  306. package/dist/discovery/ucp/types.d.ts +97 -0
  307. package/dist/discovery/ucp/types.js +103 -0
  308. package/dist/discovery/ucp/types.js.map +1 -0
  309. package/dist/discovery/ucp/validate.d.ts +38 -0
  310. package/dist/discovery/ucp/validate.js +232 -0
  311. package/dist/discovery/ucp/validate.js.map +1 -0
  312. package/dist/discovery/ucp/vendor.d.ts +60 -0
  313. package/dist/discovery/ucp/vendor.js +61 -0
  314. package/dist/discovery/ucp/vendor.js.map +1 -0
  315. package/dist/doctor.d.ts +26 -0
  316. package/dist/doctor.js +113 -0
  317. package/dist/doctor.js.map +1 -0
  318. package/dist/exit-codes.d.ts +26 -0
  319. package/dist/exit-codes.js +27 -0
  320. package/dist/exit-codes.js.map +1 -0
  321. package/dist/fanout/disclosure.d.ts +138 -0
  322. package/dist/fanout/disclosure.js +188 -0
  323. package/dist/fanout/disclosure.js.map +1 -0
  324. package/dist/fanout/index.d.ts +32 -0
  325. package/dist/fanout/index.js +30 -0
  326. package/dist/fanout/index.js.map +1 -0
  327. package/dist/fanout/orchestrator.d.ts +153 -0
  328. package/dist/fanout/orchestrator.js +439 -0
  329. package/dist/fanout/orchestrator.js.map +1 -0
  330. package/dist/fanout/policy.d.ts +128 -0
  331. package/dist/fanout/policy.js +130 -0
  332. package/dist/fanout/policy.js.map +1 -0
  333. package/dist/handoff/acp-commerce.d.ts +58 -0
  334. package/dist/handoff/acp-commerce.js +69 -0
  335. package/dist/handoff/acp-commerce.js.map +1 -0
  336. package/dist/handoff/authorization.d.ts +127 -0
  337. package/dist/handoff/authorization.js +107 -0
  338. package/dist/handoff/authorization.js.map +1 -0
  339. package/dist/handoff/candidate.d.ts +94 -0
  340. package/dist/handoff/candidate.js +172 -0
  341. package/dist/handoff/candidate.js.map +1 -0
  342. package/dist/handoff/channel.d.ts +88 -0
  343. package/dist/handoff/channel.js +189 -0
  344. package/dist/handoff/channel.js.map +1 -0
  345. package/dist/handoff/completion.d.ts +44 -0
  346. package/dist/handoff/completion.js +136 -0
  347. package/dist/handoff/completion.js.map +1 -0
  348. package/dist/handoff/delivery.d.ts +59 -0
  349. package/dist/handoff/delivery.js +185 -0
  350. package/dist/handoff/delivery.js.map +1 -0
  351. package/dist/handoff/destination.d.ts +39 -0
  352. package/dist/handoff/destination.js +99 -0
  353. package/dist/handoff/destination.js.map +1 -0
  354. package/dist/handoff/errors.d.ts +34 -0
  355. package/dist/handoff/errors.js +47 -0
  356. package/dist/handoff/errors.js.map +1 -0
  357. package/dist/handoff/idempotency.d.ts +51 -0
  358. package/dist/handoff/idempotency.js +168 -0
  359. package/dist/handoff/idempotency.js.map +1 -0
  360. package/dist/handoff/index.d.ts +46 -0
  361. package/dist/handoff/index.js +48 -0
  362. package/dist/handoff/index.js.map +1 -0
  363. package/dist/handoff/ledger.d.ts +94 -0
  364. package/dist/handoff/ledger.js +195 -0
  365. package/dist/handoff/ledger.js.map +1 -0
  366. package/dist/handoff/lifecycle.d.ts +29 -0
  367. package/dist/handoff/lifecycle.js +102 -0
  368. package/dist/handoff/lifecycle.js.map +1 -0
  369. package/dist/handoff/metrics.d.ts +56 -0
  370. package/dist/handoff/metrics.js +78 -0
  371. package/dist/handoff/metrics.js.map +1 -0
  372. package/dist/handoff/operator-approval.d.ts +143 -0
  373. package/dist/handoff/operator-approval.js +287 -0
  374. package/dist/handoff/operator-approval.js.map +1 -0
  375. package/dist/handoff/order-record.d.ts +104 -0
  376. package/dist/handoff/order-record.js +235 -0
  377. package/dist/handoff/order-record.js.map +1 -0
  378. package/dist/handoff/package.d.ts +102 -0
  379. package/dist/handoff/package.js +132 -0
  380. package/dist/handoff/package.js.map +1 -0
  381. package/dist/handoff/transaction.d.ts +96 -0
  382. package/dist/handoff/transaction.js +263 -0
  383. package/dist/handoff/transaction.js.map +1 -0
  384. package/dist/handoff/ucp-checkout/cart-channel.d.ts +111 -0
  385. package/dist/handoff/ucp-checkout/cart-channel.js +370 -0
  386. package/dist/handoff/ucp-checkout/cart-channel.js.map +1 -0
  387. package/dist/handoff/ucp-checkout/cart-parse.d.ts +22 -0
  388. package/dist/handoff/ucp-checkout/cart-parse.js +102 -0
  389. package/dist/handoff/ucp-checkout/cart-parse.js.map +1 -0
  390. package/dist/handoff/ucp-checkout/cart-types.d.ts +93 -0
  391. package/dist/handoff/ucp-checkout/cart-types.js +38 -0
  392. package/dist/handoff/ucp-checkout/cart-types.js.map +1 -0
  393. package/dist/handoff/ucp-checkout/channel.d.ts +159 -0
  394. package/dist/handoff/ucp-checkout/channel.js +636 -0
  395. package/dist/handoff/ucp-checkout/channel.js.map +1 -0
  396. package/dist/handoff/ucp-checkout/client.d.ts +88 -0
  397. package/dist/handoff/ucp-checkout/client.js +228 -0
  398. package/dist/handoff/ucp-checkout/client.js.map +1 -0
  399. package/dist/handoff/ucp-checkout/endpoint.d.ts +36 -0
  400. package/dist/handoff/ucp-checkout/endpoint.js +145 -0
  401. package/dist/handoff/ucp-checkout/endpoint.js.map +1 -0
  402. package/dist/handoff/ucp-checkout/index.d.ts +35 -0
  403. package/dist/handoff/ucp-checkout/index.js +36 -0
  404. package/dist/handoff/ucp-checkout/index.js.map +1 -0
  405. package/dist/handoff/ucp-checkout/parse.d.ts +71 -0
  406. package/dist/handoff/ucp-checkout/parse.js +349 -0
  407. package/dist/handoff/ucp-checkout/parse.js.map +1 -0
  408. package/dist/handoff/ucp-checkout/totals.d.ts +41 -0
  409. package/dist/handoff/ucp-checkout/totals.js +36 -0
  410. package/dist/handoff/ucp-checkout/totals.js.map +1 -0
  411. package/dist/handoff/ucp-checkout/types.d.ts +149 -0
  412. package/dist/handoff/ucp-checkout/types.js +58 -0
  413. package/dist/handoff/ucp-checkout/types.js.map +1 -0
  414. package/dist/handoff/url-safety.d.ts +44 -0
  415. package/dist/handoff/url-safety.js +121 -0
  416. package/dist/handoff/url-safety.js.map +1 -0
  417. package/dist/i18n.d.ts +24 -0
  418. package/dist/i18n.js +27 -0
  419. package/dist/i18n.js.map +1 -0
  420. package/dist/negotiation/action-candidate.d.ts +97 -0
  421. package/dist/negotiation/action-candidate.js +160 -0
  422. package/dist/negotiation/action-candidate.js.map +1 -0
  423. package/dist/negotiation/condition/evaluator.d.ts +36 -0
  424. package/dist/negotiation/condition/evaluator.js +123 -0
  425. package/dist/negotiation/condition/evaluator.js.map +1 -0
  426. package/dist/negotiation/context-map/index.d.ts +23 -0
  427. package/dist/negotiation/context-map/index.js +22 -0
  428. package/dist/negotiation/context-map/index.js.map +1 -0
  429. package/dist/negotiation/context-map/store.d.ts +51 -0
  430. package/dist/negotiation/context-map/store.js +186 -0
  431. package/dist/negotiation/context-map/store.js.map +1 -0
  432. package/dist/negotiation/context-map/types.d.ts +29 -0
  433. package/dist/negotiation/context-map/types.js +57 -0
  434. package/dist/negotiation/context-map/types.js.map +1 -0
  435. package/dist/negotiation/domain/common.d.ts +95 -0
  436. package/dist/negotiation/domain/common.js +216 -0
  437. package/dist/negotiation/domain/common.js.map +1 -0
  438. package/dist/negotiation/domain/envelope.d.ts +55 -0
  439. package/dist/negotiation/domain/envelope.js +110 -0
  440. package/dist/negotiation/domain/envelope.js.map +1 -0
  441. package/dist/negotiation/domain/identifiers.d.ts +65 -0
  442. package/dist/negotiation/domain/identifiers.js +130 -0
  443. package/dist/negotiation/domain/identifiers.js.map +1 -0
  444. package/dist/negotiation/domain/objects.d.ts +149 -0
  445. package/dist/negotiation/domain/objects.js +335 -0
  446. package/dist/negotiation/domain/objects.js.map +1 -0
  447. package/dist/negotiation/idempotency/index.d.ts +26 -0
  448. package/dist/negotiation/idempotency/index.js +25 -0
  449. package/dist/negotiation/idempotency/index.js.map +1 -0
  450. package/dist/negotiation/idempotency/store.d.ts +52 -0
  451. package/dist/negotiation/idempotency/store.js +189 -0
  452. package/dist/negotiation/idempotency/store.js.map +1 -0
  453. package/dist/negotiation/idempotency/types.d.ts +102 -0
  454. package/dist/negotiation/idempotency/types.js +47 -0
  455. package/dist/negotiation/idempotency/types.js.map +1 -0
  456. package/dist/negotiation/jcs.d.ts +21 -0
  457. package/dist/negotiation/jcs.js +114 -0
  458. package/dist/negotiation/jcs.js.map +1 -0
  459. package/dist/negotiation/ledger/event.d.ts +142 -0
  460. package/dist/negotiation/ledger/event.js +206 -0
  461. package/dist/negotiation/ledger/event.js.map +1 -0
  462. package/dist/negotiation/ledger/index.d.ts +26 -0
  463. package/dist/negotiation/ledger/index.js +25 -0
  464. package/dist/negotiation/ledger/index.js.map +1 -0
  465. package/dist/negotiation/ledger/store.d.ts +97 -0
  466. package/dist/negotiation/ledger/store.js +338 -0
  467. package/dist/negotiation/ledger/store.js.map +1 -0
  468. package/dist/negotiation/prompt.d.ts +34 -0
  469. package/dist/negotiation/prompt.js +113 -0
  470. package/dist/negotiation/prompt.js.map +1 -0
  471. package/dist/negotiation/recovery/index.d.ts +26 -0
  472. package/dist/negotiation/recovery/index.js +24 -0
  473. package/dist/negotiation/recovery/index.js.map +1 -0
  474. package/dist/negotiation/recovery/outbound.d.ts +49 -0
  475. package/dist/negotiation/recovery/outbound.js +34 -0
  476. package/dist/negotiation/recovery/outbound.js.map +1 -0
  477. package/dist/negotiation/recovery/recover.d.ts +59 -0
  478. package/dist/negotiation/recovery/recover.js +486 -0
  479. package/dist/negotiation/recovery/recover.js.map +1 -0
  480. package/dist/negotiation/recovery/types.d.ts +85 -0
  481. package/dist/negotiation/recovery/types.js +17 -0
  482. package/dist/negotiation/recovery/types.js.map +1 -0
  483. package/dist/negotiation/state/phase.d.ts +70 -0
  484. package/dist/negotiation/state/phase.js +200 -0
  485. package/dist/negotiation/state/phase.js.map +1 -0
  486. package/dist/negotiation/types.d.ts +139 -0
  487. package/dist/negotiation/types.js +24 -0
  488. package/dist/negotiation/types.js.map +1 -0
  489. package/dist/net/safe-http.d.ts +54 -0
  490. package/dist/net/safe-http.js +116 -0
  491. package/dist/net/safe-http.js.map +1 -0
  492. package/dist/operator/controller.d.ts +181 -0
  493. package/dist/operator/controller.js +784 -0
  494. package/dist/operator/controller.js.map +1 -0
  495. package/dist/operator/runner.d.ts +128 -0
  496. package/dist/operator/runner.js +248 -0
  497. package/dist/operator/runner.js.map +1 -0
  498. package/dist/operator/store.d.ts +39 -0
  499. package/dist/operator/store.js +169 -0
  500. package/dist/operator/store.js.map +1 -0
  501. package/dist/operator/strategy.d.ts +54 -0
  502. package/dist/operator/strategy.js +249 -0
  503. package/dist/operator/strategy.js.map +1 -0
  504. package/dist/operator/tui.d.ts +27 -0
  505. package/dist/operator/tui.js +395 -0
  506. package/dist/operator/tui.js.map +1 -0
  507. package/dist/operator/types.d.ts +224 -0
  508. package/dist/operator/types.js +17 -0
  509. package/dist/operator/types.js.map +1 -0
  510. package/dist/product-buyer.d.ts +74 -0
  511. package/dist/product-buyer.js +161 -0
  512. package/dist/product-buyer.js.map +1 -0
  513. package/dist/product-cli.d.ts +56 -0
  514. package/dist/product-cli.js +175 -0
  515. package/dist/product-cli.js.map +1 -0
  516. package/dist/product-compat.d.ts +50 -0
  517. package/dist/product-compat.js +63 -0
  518. package/dist/product-compat.js.map +1 -0
  519. package/dist/product-init.d.ts +73 -0
  520. package/dist/product-init.js +203 -0
  521. package/dist/product-init.js.map +1 -0
  522. package/dist/product-publish.d.ts +85 -0
  523. package/dist/product-publish.js +216 -0
  524. package/dist/product-publish.js.map +1 -0
  525. package/dist/protocol/legacy-shopping-negotiation/adapter.d.ts +42 -0
  526. package/dist/protocol/legacy-shopping-negotiation/adapter.js +561 -0
  527. package/dist/protocol/legacy-shopping-negotiation/adapter.js.map +1 -0
  528. package/dist/protocol/legacy-shopping-negotiation/mapping.d.ts +78 -0
  529. package/dist/protocol/legacy-shopping-negotiation/mapping.js +321 -0
  530. package/dist/protocol/legacy-shopping-negotiation/mapping.js.map +1 -0
  531. package/dist/protocol/legacy-shopping-negotiation/money.d.ts +49 -0
  532. package/dist/protocol/legacy-shopping-negotiation/money.js +70 -0
  533. package/dist/protocol/legacy-shopping-negotiation/money.js.map +1 -0
  534. package/dist/protocol/legacy-shopping-negotiation/types.d.ts +107 -0
  535. package/dist/protocol/legacy-shopping-negotiation/types.js +34 -0
  536. package/dist/protocol/legacy-shopping-negotiation/types.js.map +1 -0
  537. package/dist/runtime/buyer-policy.d.ts +58 -0
  538. package/dist/runtime/buyer-policy.js +89 -0
  539. package/dist/runtime/buyer-policy.js.map +1 -0
  540. package/dist/runtime/fake-model.d.ts +77 -0
  541. package/dist/runtime/fake-model.js +307 -0
  542. package/dist/runtime/fake-model.js.map +1 -0
  543. package/dist/runtime/foreground.d.ts +56 -0
  544. package/dist/runtime/foreground.js +97 -0
  545. package/dist/runtime/foreground.js.map +1 -0
  546. package/dist/runtime/heartbeat.d.ts +36 -0
  547. package/dist/runtime/heartbeat.js +49 -0
  548. package/dist/runtime/heartbeat.js.map +1 -0
  549. package/dist/runtime/merchant-turn.d.ts +35 -0
  550. package/dist/runtime/merchant-turn.js +20 -0
  551. package/dist/runtime/merchant-turn.js.map +1 -0
  552. package/dist/runtime/model.d.ts +40 -0
  553. package/dist/runtime/model.js +86 -0
  554. package/dist/runtime/model.js.map +1 -0
  555. package/dist/runtime/negotiation-turn.d.ts +101 -0
  556. package/dist/runtime/negotiation-turn.js +317 -0
  557. package/dist/runtime/negotiation-turn.js.map +1 -0
  558. package/dist/runtime/tools.d.ts +64 -0
  559. package/dist/runtime/tools.js +236 -0
  560. package/dist/runtime/tools.js.map +1 -0
  561. package/dist/supervisor/init.d.ts +31 -0
  562. package/dist/supervisor/init.js +222 -0
  563. package/dist/supervisor/init.js.map +1 -0
  564. package/dist/supervisor/logs.d.ts +28 -0
  565. package/dist/supervisor/logs.js +101 -0
  566. package/dist/supervisor/logs.js.map +1 -0
  567. package/dist/supervisor/manage.d.ts +72 -0
  568. package/dist/supervisor/manage.js +419 -0
  569. package/dist/supervisor/manage.js.map +1 -0
  570. package/dist/supervisor/manifest.d.ts +69 -0
  571. package/dist/supervisor/manifest.js +209 -0
  572. package/dist/supervisor/manifest.js.map +1 -0
  573. package/dist/supervisor/stack-config.d.ts +79 -0
  574. package/dist/supervisor/stack-config.js +262 -0
  575. package/dist/supervisor/stack-config.js.map +1 -0
  576. package/dist/supervisor/wrapper.d.ts +17 -0
  577. package/dist/supervisor/wrapper.js +138 -0
  578. package/dist/supervisor/wrapper.js.map +1 -0
  579. package/dist/trust/identity/auth-verifier.d.ts +96 -0
  580. package/dist/trust/identity/auth-verifier.js +166 -0
  581. package/dist/trust/identity/auth-verifier.js.map +1 -0
  582. package/dist/trust/identity/identity-binding.d.ts +63 -0
  583. package/dist/trust/identity/identity-binding.js +59 -0
  584. package/dist/trust/identity/identity-binding.js.map +1 -0
  585. package/dist/trust/identity/index.d.ts +38 -0
  586. package/dist/trust/identity/index.js +31 -0
  587. package/dist/trust/identity/index.js.map +1 -0
  588. package/dist/trust/identity/jws.d.ts +64 -0
  589. package/dist/trust/identity/jws.js +178 -0
  590. package/dist/trust/identity/jws.js.map +1 -0
  591. package/dist/trust/identity/keys.d.ts +71 -0
  592. package/dist/trust/identity/keys.js +118 -0
  593. package/dist/trust/identity/keys.js.map +1 -0
  594. package/dist/trust/identity/message-signature.d.ts +105 -0
  595. package/dist/trust/identity/message-signature.js +297 -0
  596. package/dist/trust/identity/message-signature.js.map +1 -0
  597. package/dist/trust/identity/nonce.d.ts +45 -0
  598. package/dist/trust/identity/nonce.js +50 -0
  599. package/dist/trust/identity/nonce.js.map +1 -0
  600. package/dist/trust/identity/signature-base.d.ts +84 -0
  601. package/dist/trust/identity/signature-base.js +261 -0
  602. package/dist/trust/identity/signature-base.js.map +1 -0
  603. package/dist/trust/identity/trust-policy.d.ts +92 -0
  604. package/dist/trust/identity/trust-policy.js +95 -0
  605. package/dist/trust/identity/trust-policy.js.map +1 -0
  606. package/dist/trust/index.d.ts +21 -0
  607. package/dist/trust/index.js +22 -0
  608. package/dist/trust/index.js.map +1 -0
  609. package/dist/trust/records/evaluator.d.ts +76 -0
  610. package/dist/trust/records/evaluator.js +122 -0
  611. package/dist/trust/records/evaluator.js.map +1 -0
  612. package/dist/trust/records/index.d.ts +28 -0
  613. package/dist/trust/records/index.js +26 -0
  614. package/dist/trust/records/index.js.map +1 -0
  615. package/dist/trust/records/store.d.ts +75 -0
  616. package/dist/trust/records/store.js +339 -0
  617. package/dist/trust/records/store.js.map +1 -0
  618. package/dist/trust/records/types.d.ts +159 -0
  619. package/dist/trust/records/types.js +40 -0
  620. package/dist/trust/records/types.js.map +1 -0
  621. package/dist/tui/banner.d.ts +46 -0
  622. package/dist/tui/banner.js +99 -0
  623. package/dist/tui/banner.js.map +1 -0
  624. package/dist/tui/styles.d.ts +70 -0
  625. package/dist/tui/styles.js +197 -0
  626. package/dist/tui/styles.js.map +1 -0
  627. package/dist/tui/theme.d.ts +63 -0
  628. package/dist/tui/theme.js +136 -0
  629. package/dist/tui/theme.js.map +1 -0
  630. package/examples/profiles/buyer.deepseek.yaml +34 -0
  631. package/examples/profiles/buyer.fake.yaml +36 -0
  632. package/examples/profiles/buyer.local.yaml +40 -0
  633. package/examples/profiles/merchant.deepseek.yaml +32 -0
  634. package/examples/profiles/merchant.fake.yaml +31 -0
  635. package/examples/profiles/merchant.local.yaml +34 -0
  636. package/package.json +55 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * HandoffCandidate —— KTH/0.1 §5 不可变候选(v0.7.0 WP-C1 / 完成定义 #9、#10)。
18
+ *
19
+ * 与 `HandoffPackage`(src/handoff/package.ts,v0.6.0 WP1 的 UCP checkout session
20
+ * 层工件)**不是一回事**:HandoffPackage 是 UCP Checkout 适配层输入;
21
+ * HandoffCandidate 是 KTH 候选——agreement → 策略/批准 → 重验 → 交付链的
22
+ * 第一环。二者并存(术语对齐决策:不重命名、双轨共存)。
23
+ *
24
+ * 不可变性(KTH rev0.3 §5.1):内容全部 readonly + 防御拷贝;
25
+ * lifecycle 状态**不是**候选 JSON 内的字段——它是 Ledger 事件的
26
+ * event-sourced 投影(见 lifecycle.ts / ledger.ts)。
27
+ *
28
+ * digest:candidate_digest = RFC 8785 JCS(contentDigest) 去除自身字段后
29
+ * 的 SHA-256(复用 src/negotiation/jcs.ts,KTH rev0.3 §10.1)。
30
+ */
31
+ import { requireBoolean, requireIsoTimestamp, requireNonEmptyString, requireObject, schemaError, } from "../negotiation/domain/common.js";
32
+ import { generateId, validateIdentifier } from "../negotiation/domain/identifiers.js";
33
+ import { contentDigest } from "../negotiation/jcs.js";
34
+ import { validateDestination } from "./destination.js";
35
+ /** 类型守卫。 */
36
+ export function isHandoffCandidate(value) {
37
+ return (typeof value === "object" &&
38
+ value !== null &&
39
+ value.handoff_candidate_id !== undefined &&
40
+ value.candidate_digest !== undefined);
41
+ }
42
+ /** 计算 candidate_digest:candidate 去除 candidate_digest 后 JCS+SHA-256。 */
43
+ export function computeCandidateDigest(candidate) {
44
+ const { candidate_digest: _digest, ...rest } = candidate;
45
+ return contentDigest(rest);
46
+ }
47
+ /** 校验 candidate_digest 与内容自洽。 */
48
+ export function verifyHandoffCandidateDigest(candidate) {
49
+ return candidate.candidate_digest === computeCandidateDigest(candidate);
50
+ }
51
+ function freezeSummary(summary, path) {
52
+ const obj = requireObject(summary, path);
53
+ return Object.freeze({
54
+ merchant: requireNonEmptyString(obj.merchant, `${path}/merchant`),
55
+ summary: requireNonEmptyString(obj.summary, `${path}/summary`),
56
+ });
57
+ }
58
+ /**
59
+ * 构造即校验(KTH §5):agreement 绑定、terms_digest 一致性(提供
60
+ * agreed_terms 时重算比对)、destination 校验、三 false 不变量、标识符
61
+ * 与时间戳校验。返回不可变候选(防御拷贝)。
62
+ */
63
+ export function createHandoffCandidate(input) {
64
+ const agreementId = validateIdentifier(input.agreement_id, "agreement_id");
65
+ const negotiationId = validateIdentifier(input.negotiation_id, "negotiation_id");
66
+ if (input.buyer_identity_ref !== undefined) {
67
+ validateIdentifier(input.buyer_identity_ref, "buyer_identity_ref");
68
+ }
69
+ if (input.merchant_identity_ref !== undefined) {
70
+ validateIdentifier(input.merchant_identity_ref, "merchant_identity_ref");
71
+ }
72
+ if (input.supersedes_candidate_id !== undefined) {
73
+ validateIdentifier(input.supersedes_candidate_id, "supersedes_candidate_id");
74
+ }
75
+ let termsDigest = input.terms_digest;
76
+ if (input.agreed_terms !== undefined) {
77
+ const recomputed = contentDigest(input.agreed_terms);
78
+ if (termsDigest !== undefined && termsDigest !== recomputed) {
79
+ throw schemaError("terms_digest", `terms_digest does not match recomputed digest of agreed_terms ` +
80
+ `(expected ${termsDigest}, got ${recomputed})`);
81
+ }
82
+ termsDigest = recomputed;
83
+ }
84
+ if (termsDigest === undefined) {
85
+ throw schemaError("terms_digest", "terms_digest is required (or provide agreed_terms)");
86
+ }
87
+ requireNonEmptyString(termsDigest, "terms_digest");
88
+ const destination = validateDestination(input.destination, "destination");
89
+ const displaySummary = freezeSummary(input.display_summary, "display_summary");
90
+ const policyVersion = requireNonEmptyString(input.policy_version, "policy_version");
91
+ requireIsoTimestamp(input.expires_at, "expires_at");
92
+ const createdAt = input.created_at ?? new Date().toISOString();
93
+ requireIsoTimestamp(createdAt, "created_at");
94
+ const candidate = Object.freeze({
95
+ handoff_candidate_id: generateId("handoff_candidate"),
96
+ ...(input.supersedes_candidate_id !== undefined
97
+ ? { supersedes_candidate_id: input.supersedes_candidate_id }
98
+ : {}),
99
+ agreement_id: agreementId,
100
+ negotiation_id: negotiationId,
101
+ terms_digest: termsDigest,
102
+ buyer_identity_ref: input.buyer_identity_ref ?? "principal:unknown",
103
+ merchant_identity_ref: input.merchant_identity_ref ?? "merchant:unknown",
104
+ destination_type: destination.type,
105
+ destination_ref: destination.ref,
106
+ ...(destination.payload !== undefined ? { destination_payload: destination.payload } : {}),
107
+ display_summary: displaySummary,
108
+ policy_version: policyVersion,
109
+ expires_at: input.expires_at,
110
+ requires_user_action: input.requires_user_action ?? true,
111
+ creates_order: false,
112
+ authorizes_payment: false,
113
+ reserves_inventory: false,
114
+ candidate_digest: "",
115
+ created_at: createdAt,
116
+ });
117
+ // digest 依赖内容 → 构造完成后再计算,并整体冻结。
118
+ return Object.freeze({ ...candidate, candidate_digest: computeCandidateDigest(candidate) });
119
+ }
120
+ /**
121
+ * 校验并重建一个候选对象(Ledger 事件重建,§18-13)。
122
+ *
123
+ * 保留输入的 handoff_candidate_id 与 candidate_digest(不重新生成):
124
+ * 字段校验复用 createHandoffCandidate 的规则,然后以输入 id 覆盖,
125
+ * 再核对 digest(提供 digest 时)或按内容重算(缺省时)。
126
+ */
127
+ export function validateHandoffCandidate(value, path = "handoff_candidate") {
128
+ const obj = requireObject(value, path);
129
+ if (obj.creates_order !== false || obj.authorizes_payment !== false || obj.reserves_inventory !== false) {
130
+ throw schemaError(path, "HandoffCandidate 三副作用不变量必须全为 false(KTH/1.0 不创建订单/不授权支付/不预留库存)");
131
+ }
132
+ requireBoolean(obj.requires_user_action, `${path}/requires_user_action`);
133
+ const candidateId = validateIdentifier(obj.handoff_candidate_id, `${path}/handoff_candidate_id`);
134
+ const generated = createHandoffCandidate({
135
+ agreement_id: requireNonEmptyString(obj.agreement_id, `${path}/agreement_id`),
136
+ negotiation_id: requireNonEmptyString(obj.negotiation_id, `${path}/negotiation_id`),
137
+ terms_digest: requireNonEmptyString(obj.terms_digest, `${path}/terms_digest`),
138
+ buyer_identity_ref: obj.buyer_identity_ref,
139
+ merchant_identity_ref: obj.merchant_identity_ref,
140
+ destination: {
141
+ type: obj.destination_type,
142
+ ref: requireNonEmptyString(obj.destination_ref, `${path}/destination_ref`),
143
+ ...(obj.destination_payload !== undefined
144
+ ? { payload: obj.destination_payload }
145
+ : {}),
146
+ },
147
+ display_summary: {
148
+ merchant: requireNonEmptyString(obj.display_summary?.merchant, `${path}/display_summary/merchant`),
149
+ summary: requireNonEmptyString(obj.display_summary?.summary, `${path}/display_summary/summary`),
150
+ },
151
+ policy_version: requireNonEmptyString(obj.policy_version, `${path}/policy_version`),
152
+ expires_at: requireIsoTimestamp(obj.expires_at, `${path}/expires_at`),
153
+ requires_user_action: obj.requires_user_action,
154
+ ...(obj.supersedes_candidate_id !== undefined
155
+ ? { supersedes_candidate_id: obj.supersedes_candidate_id }
156
+ : {}),
157
+ created_at: obj.created_at,
158
+ });
159
+ const withId = { ...generated, handoff_candidate_id: candidateId };
160
+ if (obj.candidate_digest !== undefined) {
161
+ const withDigest = {
162
+ ...withId,
163
+ candidate_digest: requireNonEmptyString(obj.candidate_digest, `${path}/candidate_digest`),
164
+ };
165
+ if (!verifyHandoffCandidateDigest(withDigest)) {
166
+ throw schemaError(`${path}/candidate_digest`, "candidate_digest mismatch on rebuild");
167
+ }
168
+ return Object.freeze(withDigest);
169
+ }
170
+ return Object.freeze({ ...withId, candidate_digest: computeCandidateDigest(withId) });
171
+ }
172
+ //# sourceMappingURL=candidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate.js","sourceRoot":"","sources":["../../src/handoff/candidate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { TermSet } from "../negotiation/domain/common.js";
17
+ import type { PaymentAuthorization, AuthorizationProvider } from "./authorization.js";
18
+ import type { HandoffPackage } from "./package.js";
19
+ export declare const HANDOFF_SESSION_STATUSES: readonly ["created", "updated", "completed", "cancelled"];
20
+ export type HandoffSessionStatus = (typeof HANDOFF_SESSION_STATUSES)[number];
21
+ /**
22
+ * 交易系统上的一个 checkout session。current_terms 可被 updateSession 改变
23
+ * (建模「下单前改购物车」);current_terms_digest 与 current_terms 始终一致。
24
+ * 授权与完成门禁只认 current_terms_digest —— 换 terms 后旧授权即失效。
25
+ */
26
+ export interface HandoffSession {
27
+ session_ref: string;
28
+ /** 创建该 session 的交接工件(原始 agreed_terms 是商业共识来源)。 */
29
+ package: HandoffPackage;
30
+ current_terms: TermSet;
31
+ current_terms_digest: string;
32
+ status: HandoffSessionStatus;
33
+ created_at: string;
34
+ updated_at: string;
35
+ }
36
+ /** HandoffChannel 的结构化结果(公共 `status` 判别)。 */
37
+ export type HandoffResult = {
38
+ status: "ok";
39
+ session_ref: string;
40
+ session: HandoffSession;
41
+ continue_url?: string;
42
+ } | {
43
+ status: "fail_closed";
44
+ reason: string;
45
+ } | {
46
+ status: "requires_user";
47
+ continue_url?: string;
48
+ reason: string;
49
+ };
50
+ /** 交易系统适配接缝(WP2 实现 = UCP Checkout adapter)。 */
51
+ export interface HandoffChannel {
52
+ createSession(pkg: HandoffPackage): HandoffResult;
53
+ getSession(ref: string): HandoffResult;
54
+ updateSession(ref: string, terms: TermSet): HandoffResult;
55
+ requestCompletion(ref: string, authorization: PaymentAuthorization): HandoffResult;
56
+ cancelSession(ref: string): HandoffResult;
57
+ }
58
+ export interface ManualHandoffChannelOptions {
59
+ /** 可注入时钟(RFC 3339);缺省 new Date().toISOString()。 */
60
+ now?: () => string;
61
+ /** AP2 授权提供方;缺省 FailClosedAuthorizationProvider(完成一律拒绝)。 */
62
+ authorizationProvider?: AuthorizationProvider;
63
+ }
64
+ /**
65
+ * 参考实现:内存 Map + JSON 导出 + manual:// continue_url,无任何网络写入。
66
+ * requestCompletion 先跑完成门禁,任何前置不满足 → fail_closed。
67
+ */
68
+ export declare class ManualHandoffChannel implements HandoffChannel {
69
+ private readonly sessions;
70
+ private readonly now;
71
+ private readonly authorizationProvider;
72
+ constructor(options?: ManualHandoffChannelOptions);
73
+ createSession(pkg: HandoffPackage): HandoffResult;
74
+ getSession(ref: string): HandoffResult;
75
+ updateSession(ref: string, terms: TermSet): HandoffResult;
76
+ requestCompletion(ref: string, authorization: PaymentAuthorization): HandoffResult;
77
+ cancelSession(ref: string): HandoffResult;
78
+ /** 导出 session JSON 供展示(Manual 参考实现;不执行任何网络写入)。 */
79
+ exportSessionJson(ref: string): {
80
+ status: "ok";
81
+ json: string;
82
+ } | {
83
+ status: "fail_closed";
84
+ reason: string;
85
+ };
86
+ /** 当前 session 数量(诊断用)。 */
87
+ get sessionCount(): number;
88
+ }
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Kiwi v0.7.0 Transaction Handoff — HandoffChannel 接缝(WP1)。
18
+ *
19
+ * HandoffChannel 是「交易系统适配接口」:真实实现(WP2 的 UCP Checkout adapter)
20
+ * 会在外部交易系统上创建 session / 更新 terms / 请求完成 / 取消。WP1 只定义
21
+ * 接口与结构化结果,并提供一个 ManualHandoffChannel 参考实现:
22
+ *
23
+ * - 内存 Map 存 session,导出 JSON + manual:// continue_url 供展示;
24
+ * - 不执行任何网络写入;
25
+ * - requestCompletion 复用完成门禁(completion.ts)——未配置真实 AP2 时,
26
+ * 默认 FailClosedAuthorizationProvider 保证一律 fail-closed,绝不伪造完成。
27
+ *
28
+ * 结构化结果(用公共 `status` 判别,strict TS 可可靠窄化;对应工作包语义
29
+ * `{ok}` / `{fail_closed, reason}` / `{requires_user, continue_url, reason}`):
30
+ * ok —— 操作成功,携带 session;
31
+ * fail_closed —— 明确拒绝(找不到 session / 状态不可操作 / 门禁不过);
32
+ * requires_user —— 需要用户介入外部 checkout(如需要人去 UCP checkout 页面
33
+ * 确认时),带 continue_url。
34
+ */
35
+ import { uuidv7 } from "../negotiation/domain/identifiers.js";
36
+ import { validateTermSet } from "../negotiation/domain/common.js";
37
+ import { contentDigest } from "../negotiation/jcs.js";
38
+ import { FailClosedAuthorizationProvider } from "./authorization.js";
39
+ import { verifyHandoffPackageDigest } from "./package.js";
40
+ import { evaluateCompletionGate } from "./completion.js";
41
+ // ---------------------------------------------------------------------------
42
+ // Session 与结果类型
43
+ // ---------------------------------------------------------------------------
44
+ export const HANDOFF_SESSION_STATUSES = ["created", "updated", "completed", "cancelled"];
45
+ function sessionNotActionable(session) {
46
+ return session.status === "completed" || session.status === "cancelled";
47
+ }
48
+ function notFound(ref) {
49
+ return { status: "fail_closed", reason: `session_not_found: ${ref}` };
50
+ }
51
+ function notActionable(session) {
52
+ return { status: "fail_closed", reason: `session_not_actionable: status ${session.status}` };
53
+ }
54
+ /**
55
+ * 参考实现:内存 Map + JSON 导出 + manual:// continue_url,无任何网络写入。
56
+ * requestCompletion 先跑完成门禁,任何前置不满足 → fail_closed。
57
+ */
58
+ export class ManualHandoffChannel {
59
+ sessions = new Map();
60
+ now;
61
+ authorizationProvider;
62
+ constructor(options = {}) {
63
+ this.now = options.now ?? (() => new Date().toISOString());
64
+ this.authorizationProvider =
65
+ options.authorizationProvider ?? new FailClosedAuthorizationProvider();
66
+ }
67
+ createSession(pkg) {
68
+ if (!verifyHandoffPackageDigest(pkg)) {
69
+ return {
70
+ status: "fail_closed",
71
+ reason: "createSession rejected: package terms_digest verification failed",
72
+ };
73
+ }
74
+ // 结构加固:agreed_terms 必须是合法 TermSet,且归一化后 digest 仍与
75
+ // terms_digest 一致(防伪造一个 digest 自洽但结构非法的 package)。
76
+ let currentTerms;
77
+ try {
78
+ currentTerms = validateTermSet(pkg.agreed_terms, "agreed_terms");
79
+ }
80
+ catch {
81
+ return {
82
+ status: "fail_closed",
83
+ reason: "createSession rejected: package agreed_terms failed structural validation",
84
+ };
85
+ }
86
+ if (contentDigest(currentTerms) !== pkg.terms_digest) {
87
+ return {
88
+ status: "fail_closed",
89
+ reason: "createSession rejected: package terms_digest does not match validated agreed_terms",
90
+ };
91
+ }
92
+ const sessionRef = `hs_${uuidv7()}`;
93
+ const now = this.now();
94
+ const session = {
95
+ session_ref: sessionRef,
96
+ package: pkg,
97
+ current_terms: currentTerms,
98
+ current_terms_digest: pkg.terms_digest,
99
+ status: "created",
100
+ created_at: now,
101
+ updated_at: now,
102
+ };
103
+ this.sessions.set(sessionRef, session);
104
+ // manual:// scheme 仅用于展示,不触发任何网络写入。
105
+ // 返回拷贝(与 getSession 一致:外部持有者不得持有内部对象引用)。
106
+ return {
107
+ status: "ok",
108
+ session_ref: sessionRef,
109
+ session: { ...session },
110
+ continue_url: `manual://checkout/${sessionRef}`,
111
+ };
112
+ }
113
+ getSession(ref) {
114
+ const session = this.sessions.get(ref);
115
+ if (session === undefined)
116
+ return notFound(ref);
117
+ // 返回拷贝:外部持有者不得绕过 status 机原地改写内部对象
118
+ //(此前引用别名泄漏,篡改 current_terms 靠完成门禁兜底,status 无兜底)。
119
+ return { status: "ok", session_ref: ref, session: { ...session } };
120
+ }
121
+ updateSession(ref, terms) {
122
+ const session = this.sessions.get(ref);
123
+ if (session === undefined)
124
+ return notFound(ref);
125
+ if (sessionNotActionable(session))
126
+ return notActionable(session);
127
+ const nextTerms = validateTermSet(terms, "terms");
128
+ // 不可变更新(新对象替换,不原地突变 Map 内的对象)。
129
+ const next = {
130
+ ...session,
131
+ current_terms: nextTerms,
132
+ current_terms_digest: contentDigest(nextTerms),
133
+ status: "updated",
134
+ updated_at: this.now(),
135
+ };
136
+ this.sessions.set(ref, next);
137
+ return { status: "ok", session_ref: ref, session: next };
138
+ }
139
+ requestCompletion(ref, authorization) {
140
+ const session = this.sessions.get(ref);
141
+ if (session === undefined)
142
+ return notFound(ref);
143
+ if (sessionNotActionable(session))
144
+ return notActionable(session);
145
+ // 完成门禁:授权验证 + terms_digest 一致 + 未 stale,任一不满足 → fail_closed。
146
+ const gate = evaluateCompletionGate({
147
+ authorization,
148
+ session,
149
+ authorizationProvider: this.authorizationProvider,
150
+ now: this.now,
151
+ });
152
+ if (!gate.allowed) {
153
+ return { status: "fail_closed", reason: gate.reason };
154
+ }
155
+ const completed = {
156
+ ...session,
157
+ status: "completed",
158
+ updated_at: this.now(),
159
+ };
160
+ this.sessions.set(ref, completed);
161
+ return { status: "ok", session_ref: ref, session: completed };
162
+ }
163
+ cancelSession(ref) {
164
+ const session = this.sessions.get(ref);
165
+ if (session === undefined)
166
+ return notFound(ref);
167
+ if (sessionNotActionable(session))
168
+ return notActionable(session);
169
+ const cancelled = {
170
+ ...session,
171
+ status: "cancelled",
172
+ updated_at: this.now(),
173
+ };
174
+ this.sessions.set(ref, cancelled);
175
+ return { status: "ok", session_ref: ref, session: cancelled };
176
+ }
177
+ /** 导出 session JSON 供展示(Manual 参考实现;不执行任何网络写入)。 */
178
+ exportSessionJson(ref) {
179
+ const session = this.sessions.get(ref);
180
+ if (session === undefined)
181
+ return { status: "fail_closed", reason: `session_not_found: ${ref}` };
182
+ return { status: "ok", json: JSON.stringify(session, null, 2) };
183
+ }
184
+ /** 当前 session 数量(诊断用)。 */
185
+ get sessionCount() {
186
+ return this.sessions.size;
187
+ }
188
+ }
189
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/handoff/channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { AuthorizationProvider, PaymentAuthorization } from "./authorization.js";
17
+ import type { HandoffSession } from "./channel.js";
18
+ export declare const COMPLETION_GATE_FAILURE_CODES: readonly ["authorization_not_verified", "terms_digest_mismatch", "approval_stale"];
19
+ export type CompletionGateFailureCode = (typeof COMPLETION_GATE_FAILURE_CODES)[number];
20
+ export type CompletionGateDecision = {
21
+ allowed: true;
22
+ } | {
23
+ allowed: false;
24
+ code: CompletionGateFailureCode;
25
+ reason: string;
26
+ };
27
+ export interface CompletionGateContext {
28
+ authorization: PaymentAuthorization;
29
+ /** 待完成的 session(其 current_terms / current_terms_digest 是门禁输入)。 */
30
+ session: HandoffSession;
31
+ authorizationProvider: AuthorizationProvider;
32
+ /** 可注入时钟(RFC 3339);缺省 new Date().toISOString()。 */
33
+ now?: () => string;
34
+ }
35
+ /**
36
+ * authorization 结构守卫:门禁绝不能信任一个字段缺失/格式错误的授权对象。
37
+ * 结构合法 ≠ 授权有效 —— 有效性由第 1 步 provider 验证与第 2/3 步绑定复核决定。
38
+ */
39
+ export declare function isStructurallyValidAuthorization(value: unknown): value is PaymentAuthorization;
40
+ /**
41
+ * 完成门禁判定(纯函数)。判定顺序固定(验授权 → 验 terms 绑定 → 验 stale),
42
+ * 任一失败 fail-closed。
43
+ */
44
+ export declare function evaluateCompletionGate(ctx: CompletionGateContext): CompletionGateDecision;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Kiwi v0.7.0 Transaction Handoff — 完成门禁(WP1 交付 4)。
18
+ *
19
+ * requestCompletion 的调用前置条件(基线 §19 Approval Pipeline 绑定语义的
20
+ * 交接域投影;§4.6 fail closed)。任一不满足即拒绝完成,绝不静默放行:
21
+ *
22
+ * 1. authorization 经 AuthorizationProvider 验证
23
+ * (verifyIntentMandate 必须 verified=true;authorization 结构必须先合法);
24
+ * 2. terms_digest 与 session 当前 terms 一致
25
+ * (session.current_terms 重算 digest 必须等于 current_terms_digest ——
26
+ * 防会话被篡改;且 authorization.terms_digest 必须等于该 digest ——
27
+ * 防授权被挪用到别的 terms);
28
+ * 3. approval 未 stale
29
+ * (authorization.session_ref 必须等于当前 session —— 换 session 即失效;
30
+ * 且未超过 expires_at —— 过期即 stale)。
31
+ *
32
+ * 判定顺序固定,便于审计:先验授权,再验 terms 绑定,最后验 stale。每个失败
33
+ * 都返回结构化 {allowed:false, code, reason},由调用方决定如何转成
34
+ * HandoffResult(ManualHandoffChannel 把它映射为 {fail_closed, reason})。
35
+ */
36
+ import { contentDigest } from "../negotiation/jcs.js";
37
+ export const COMPLETION_GATE_FAILURE_CODES = [
38
+ "authorization_not_verified",
39
+ "terms_digest_mismatch",
40
+ "approval_stale",
41
+ ];
42
+ const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
43
+ const TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
44
+ function isNonEmptyString(value) {
45
+ return typeof value === "string" && value.length > 0;
46
+ }
47
+ /**
48
+ * authorization 结构守卫:门禁绝不能信任一个字段缺失/格式错误的授权对象。
49
+ * 结构合法 ≠ 授权有效 —— 有效性由第 1 步 provider 验证与第 2/3 步绑定复核决定。
50
+ */
51
+ export function isStructurallyValidAuthorization(value) {
52
+ if (value === null || typeof value !== "object")
53
+ return false;
54
+ const a = value;
55
+ const evidence = a.evidence;
56
+ return (isNonEmptyString(a.authorization_id) &&
57
+ isNonEmptyString(a.session_ref) &&
58
+ typeof a.terms_digest === "string" &&
59
+ DIGEST_RE.test(a.terms_digest) &&
60
+ isNonEmptyString(a.intent_mandate) &&
61
+ typeof a.approved_at === "string" &&
62
+ TIMESTAMP_RE.test(a.approved_at) &&
63
+ typeof a.expires_at === "string" &&
64
+ TIMESTAMP_RE.test(a.expires_at) &&
65
+ evidence !== undefined &&
66
+ typeof evidence === "object" &&
67
+ (evidence.kind === "manual" || evidence.kind === "ap2") &&
68
+ isNonEmptyString(evidence.reference) &&
69
+ typeof evidence.confirmed_at === "string" &&
70
+ TIMESTAMP_RE.test(evidence.confirmed_at));
71
+ }
72
+ /**
73
+ * 完成门禁判定(纯函数)。判定顺序固定(验授权 → 验 terms 绑定 → 验 stale),
74
+ * 任一失败 fail-closed。
75
+ */
76
+ export function evaluateCompletionGate(ctx) {
77
+ const { authorization, session, authorizationProvider } = ctx;
78
+ const now = ctx.now ?? (() => new Date().toISOString());
79
+ // 第 1 步:authorization 结构 + provider 验证。
80
+ if (!isStructurallyValidAuthorization(authorization)) {
81
+ return {
82
+ allowed: false,
83
+ code: "authorization_not_verified",
84
+ reason: "authorization is malformed; refusing to trust it",
85
+ };
86
+ }
87
+ const verification = authorizationProvider.verifyIntentMandate(authorization.intent_mandate, {
88
+ session_ref: authorization.session_ref,
89
+ terms_digest: authorization.terms_digest,
90
+ });
91
+ if (!verification.verified) {
92
+ return {
93
+ allowed: false,
94
+ code: "authorization_not_verified",
95
+ reason: verification.reason ?? "intent mandate verification failed",
96
+ };
97
+ }
98
+ // 第 2 步:terms_digest 与 session 当前 terms 一致。
99
+ const sessionCurrentDigest = contentDigest(session.current_terms);
100
+ if (sessionCurrentDigest !== session.current_terms_digest) {
101
+ return {
102
+ allowed: false,
103
+ code: "terms_digest_mismatch",
104
+ reason: "session.current_terms tampered: recomputed digest does not match current_terms_digest",
105
+ };
106
+ }
107
+ if (authorization.terms_digest !== session.current_terms_digest) {
108
+ return {
109
+ allowed: false,
110
+ code: "terms_digest_mismatch",
111
+ reason: "authorization is bound to different terms than session current terms",
112
+ };
113
+ }
114
+ // 第 3 步:approval 未 stale(§19 绑定语义 + 有效期)。
115
+ if (authorization.session_ref !== session.session_ref) {
116
+ return {
117
+ allowed: false,
118
+ code: "approval_stale",
119
+ reason: "authorization is bound to a different session_ref",
120
+ };
121
+ }
122
+ const expiresMs = Date.parse(authorization.expires_at);
123
+ const nowMs = Date.parse(now());
124
+ if (!Number.isFinite(expiresMs) || !Number.isFinite(nowMs)) {
125
+ return {
126
+ allowed: false,
127
+ code: "approval_stale",
128
+ reason: "invalid timestamp on authorization expires_at / clock",
129
+ };
130
+ }
131
+ if (nowMs > expiresMs) {
132
+ return { allowed: false, code: "approval_stale", reason: "authorization has expired" };
133
+ }
134
+ return { allowed: true };
135
+ }
136
+ //# sourceMappingURL=completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../src/handoff/completion.ts"],"names":[],"mappings":"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"}