@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
package/dist/cli.js ADDED
@@ -0,0 +1,1139 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Copyright 2026 harrylabsj
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * kiwi — standalone commerce negotiation agent runtime.
19
+ *
20
+ * Commands:
21
+ * kiwi doctor --profile <file> Read-only diagnostics.
22
+ * kiwi agent run --profile <file> --once Process at most one claimed message.
23
+ * kiwi agent run --profile <file> Foreground serial polling until
24
+ * SIGINT/SIGTERM (exit 0).
25
+ * kiwi tui --profile <file> Interactive operator TUI
26
+ * (supervised by default).
27
+ * kiwi init|up|status|logs|down --dir <instance-dir>
28
+ * Managed-local product lifecycle.
29
+ */
30
+ import { existsSync, realpathSync } from "node:fs";
31
+ import path from "node:path";
32
+ import { fileURLToPath } from "node:url";
33
+ import { agentDataDir, ensurePathsForDir } from "./agent/agent-db.js";
34
+ import { startA2aNode } from "./a2a/node.js";
35
+ import { runChatTui } from "./agent/chat-tui.js";
36
+ import { createFakeChatModels } from "./agent/fake-chat-model.js";
37
+ import { isAgentMode } from "./agent/mode.js";
38
+ import { AgentKernel } from "./agent/kernel.js";
39
+ import { loadProfile, ProfileError, resolveSecret, RUNTIME_VERSION } from "./config/profile.js";
40
+ import { HttpCommerceClient } from "./commerce/http-client.js";
41
+ import { CommerceError } from "./commerce/types.js";
42
+ import { runDoctor } from "./doctor.js";
43
+ import { EXIT } from "./exit-codes.js";
44
+ import { createDeterministicStreamFn } from "./runtime/fake-model.js";
45
+ import { runForeground } from "./runtime/foreground.js";
46
+ import { runNegotiationTurn } from "./runtime/negotiation-turn.js";
47
+ import { isFakeProvider, realStreamFn, resolveThinkingLevel } from "./runtime/model.js";
48
+ import { OperatorController } from "./operator/controller.js";
49
+ import { DeterministicNegotiationRunner } from "./operator/runner.js";
50
+ import { FileOperatorEventStore, OperatorStoreError } from "./operator/store.js";
51
+ import { createStrategyEngine } from "./operator/strategy.js";
52
+ import { runTui } from "./operator/tui.js";
53
+ import { runInit } from "./supervisor/init.js";
54
+ import { runDown, runStatus, runUp, SupervisorError } from "./supervisor/manage.js";
55
+ import { parseLogLines, runLogs } from "./supervisor/logs.js";
56
+ import { StackConfigError } from "./supervisor/stack-config.js";
57
+ import { cmdProductDoctor, productHelp, PRODUCT_VERSION, DEFAULT_CATALOG_URL } from "./product-cli.js";
58
+ import { merchantInit } from "./product-init.js";
59
+ import { buyerInit, buyerSearch, buyerTasks } from "./product-buyer.js";
60
+ import { merchantPublish } from "./product-publish.js";
61
+ const USAGE = `kiwi ${PRODUCT_VERSION} — commerce negotiation agent runtime
62
+
63
+ Usage:
64
+ kiwi init --dir <dir> [--shopping-cli-src <path>] [--fake]
65
+ Create a managed-local instance
66
+ kiwi up --dir <dir> Start gateway + enabled agents (idempotent)
67
+ kiwi status --dir <dir> Structured JSON instance status
68
+ kiwi logs --dir <dir> [--lines N] Redacted, labeled tail of instance logs
69
+ kiwi down --dir <dir> Verified shutdown of this instance only
70
+ kiwi doctor --profile <file> Read-only diagnostics (no writes)
71
+ kiwi agent run --profile <file> --once Run one negotiation turn, then exit
72
+ kiwi agent run --profile <file> Foreground serial polling (SIGINT/SIGTERM to stop)
73
+ kiwi agent serve --profile <file> [--catalog <url>] [--port N] [--no-chat]
74
+ Run a merchant A2A server + register in kiwi-catalog
75
+ (default: also opens the kiwi> conversation)
76
+ kiwi tui --profile <file> [--data-dir <dir>]
77
+ Interactive operator TUI (supervised by default;
78
+ approves candidates before any formal submit)
79
+ kiwi [--no-a2a] Conversation TUI + auto A2A node (merchant
80
+ registers in kiwi-catalog); /profile /a2a
81
+ /discover /negotiate /register in-session
82
+ kiwi chat --profile <file> [--data-dir <dir>]
83
+ Main conversation with Principal Memory (v0.3.0-A)
84
+ kiwi metrics --dir <dir> Handoff/negotiation ledger metrics (JSONL)
85
+
86
+ Product layer (product-strategy rev1.1 §10/§19):
87
+ kiwi buyer --help Kiwi Buyer command tree
88
+ kiwi merchant --help Kiwi Merchant command tree
89
+ kiwi network --help Kiwi Network command tree
90
+ kiwi doctor Aggregate health: kiwi runtime +
91
+ shopping-cli presence + kiwi-catalog
92
+ reachability (no --profile needed)
93
+
94
+ kiwi --version Print version
95
+ kiwi --help This help
96
+
97
+ Profiles select the role (buyer or merchant); both share the same runtime.
98
+ Turn reports are printed as JSONL (one JSON object per line) and never
99
+ contain secrets or private policy values. Secrets come from environment
100
+ variables named in the profile (commerce.token_env, model.api_key_env);
101
+ they are never read from or written to the profile file.
102
+ `;
103
+ function parseArgs(argv) {
104
+ const command = [];
105
+ let profile;
106
+ let dir;
107
+ let lines;
108
+ let shoppingCliSrc;
109
+ let shoppingCliDb;
110
+ let shoppingCliPath;
111
+ let shoppingCliMerchant;
112
+ let merchantId;
113
+ let merchantName;
114
+ let output;
115
+ let force = false;
116
+ let noInstall = false;
117
+ let agentId;
118
+ let ownerId;
119
+ let autoNegotiate = false;
120
+ let limit;
121
+ let category;
122
+ let region;
123
+ let listingType;
124
+ let dataDir;
125
+ let catalog;
126
+ let port;
127
+ let once = false;
128
+ let fake = false;
129
+ let noChat = false;
130
+ let noA2a = false;
131
+ for (let i = 0; i < argv.length; i++) {
132
+ const arg = argv[i];
133
+ if (arg === "--profile") {
134
+ profile = argv[++i];
135
+ }
136
+ else if (arg === "--dir") {
137
+ dir = argv[++i];
138
+ }
139
+ else if (arg === "--lines") {
140
+ lines = argv[++i];
141
+ }
142
+ else if (arg === "--shopping-cli-src") {
143
+ shoppingCliSrc = argv[++i];
144
+ }
145
+ else if (arg === "--shopping-cli-db") {
146
+ shoppingCliDb = argv[++i];
147
+ }
148
+ else if (arg === "--shopping-cli-path") {
149
+ shoppingCliPath = argv[++i];
150
+ }
151
+ else if (arg === "--shopping-cli-merchant") {
152
+ shoppingCliMerchant = argv[++i];
153
+ }
154
+ else if (arg === "--merchant-id") {
155
+ merchantId = argv[++i];
156
+ }
157
+ else if (arg === "--name") {
158
+ merchantName = argv[++i];
159
+ }
160
+ else if (arg === "--output") {
161
+ output = argv[++i];
162
+ }
163
+ else if (arg === "--force") {
164
+ force = true;
165
+ }
166
+ else if (arg === "--no-install") {
167
+ noInstall = true;
168
+ }
169
+ else if (arg === "--agent-id") {
170
+ agentId = argv[++i];
171
+ }
172
+ else if (arg === "--owner-id") {
173
+ ownerId = argv[++i];
174
+ }
175
+ else if (arg === "--auto-negotiate") {
176
+ autoNegotiate = true;
177
+ }
178
+ else if (arg === "--limit") {
179
+ limit = argv[++i];
180
+ }
181
+ else if (arg === "--category") {
182
+ category = argv[++i];
183
+ }
184
+ else if (arg === "--region") {
185
+ region = argv[++i];
186
+ }
187
+ else if (arg === "--listing-type") {
188
+ listingType = argv[++i];
189
+ }
190
+ else if (arg === "--data-dir") {
191
+ dataDir = argv[++i];
192
+ }
193
+ else if (arg === "--catalog") {
194
+ catalog = argv[++i];
195
+ }
196
+ else if (arg === "--port") {
197
+ // 只接受十进制正整数(评审项 L5:Number("abc")=NaN 会流入 server.listen)
198
+ const raw = argv[++i];
199
+ const parsed = /^\d+$/.test(raw ?? "") ? Number(raw) : Number.NaN;
200
+ port = Number.isInteger(parsed) ? parsed : undefined;
201
+ }
202
+ else if (arg === "--once") {
203
+ once = true;
204
+ }
205
+ else if (arg === "--fake") {
206
+ fake = true;
207
+ }
208
+ else if (arg === "--no-chat") {
209
+ noChat = true;
210
+ }
211
+ else if (arg === "--no-a2a") {
212
+ noA2a = true;
213
+ }
214
+ else if (arg !== undefined && arg.startsWith("--profile=")) {
215
+ profile = arg.slice("--profile=".length);
216
+ }
217
+ else if (arg !== undefined && arg.startsWith("--dir=")) {
218
+ dir = arg.slice("--dir=".length);
219
+ }
220
+ else if (arg !== undefined && arg.startsWith("--lines=")) {
221
+ lines = arg.slice("--lines=".length);
222
+ }
223
+ else if (arg !== undefined && arg.startsWith("--shopping-cli-src=")) {
224
+ shoppingCliSrc = arg.slice("--shopping-cli-src=".length);
225
+ }
226
+ else if (arg !== undefined && arg.startsWith("--merchant-id=")) {
227
+ merchantId = arg.slice("--merchant-id=".length);
228
+ }
229
+ else if (arg !== undefined && arg.startsWith("--name=")) {
230
+ merchantName = arg.slice("--name=".length);
231
+ }
232
+ else if (arg !== undefined && arg.startsWith("--data-dir=")) {
233
+ dataDir = arg.slice("--data-dir=".length);
234
+ }
235
+ else if (arg !== undefined && !arg.startsWith("-")) {
236
+ command.push(arg);
237
+ }
238
+ else {
239
+ throw new ProfileError(`Unknown argument: ${arg ?? ""}`);
240
+ }
241
+ }
242
+ const out = { command, once, fake, noChat, noA2a, force, noInstall, autoNegotiate };
243
+ if (profile !== undefined)
244
+ out.profile = profile;
245
+ if (dir !== undefined)
246
+ out.dir = dir;
247
+ if (lines !== undefined)
248
+ out.lines = lines;
249
+ if (shoppingCliSrc !== undefined)
250
+ out.shoppingCliSrc = shoppingCliSrc;
251
+ if (shoppingCliDb !== undefined)
252
+ out.shoppingCliDb = shoppingCliDb;
253
+ if (shoppingCliPath !== undefined)
254
+ out.shoppingCliPath = shoppingCliPath;
255
+ if (shoppingCliMerchant !== undefined)
256
+ out.shoppingCliMerchant = shoppingCliMerchant;
257
+ if (merchantId !== undefined)
258
+ out.merchantId = merchantId;
259
+ if (merchantName !== undefined)
260
+ out.merchantName = merchantName;
261
+ if (output !== undefined)
262
+ out.output = output;
263
+ if (agentId !== undefined)
264
+ out.agentId = agentId;
265
+ if (ownerId !== undefined)
266
+ out.ownerId = ownerId;
267
+ if (limit !== undefined)
268
+ out.limit = limit;
269
+ if (category !== undefined)
270
+ out.category = category;
271
+ if (region !== undefined)
272
+ out.region = region;
273
+ if (listingType !== undefined)
274
+ out.listingType = listingType;
275
+ if (dataDir !== undefined)
276
+ out.dataDir = dataDir;
277
+ if (catalog !== undefined)
278
+ out.catalog = catalog;
279
+ if (port !== undefined)
280
+ out.port = port;
281
+ return out;
282
+ }
283
+ function requireDir(args) {
284
+ if (!args.dir) {
285
+ throw new ProfileError("--dir <instance-dir> is required");
286
+ }
287
+ return args.dir;
288
+ }
289
+ function requireProfile(args) {
290
+ if (!args.profile) {
291
+ throw new ProfileError("--profile <file> is required");
292
+ }
293
+ return loadProfile(args.profile);
294
+ }
295
+ function buildClient(profile) {
296
+ const token = resolveSecret(profile.commerce.token_env, "commerce token");
297
+ return new HttpCommerceClient({
298
+ baseUrl: profile.commerce.base_url,
299
+ token,
300
+ });
301
+ }
302
+ function printReportJsonl(report) {
303
+ process.stdout.write(`${JSON.stringify(report)}\n`);
304
+ }
305
+ // A closed stdout (e.g. `kiwi ... | head -1`) must not crash the CLI.
306
+ process.stdout.on("error", (err) => {
307
+ if (err.code !== "EPIPE")
308
+ throw err;
309
+ });
310
+ function printJson(value) {
311
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
312
+ }
313
+ async function cmdDoctor(args) {
314
+ const profile = requireProfile(args);
315
+ let client;
316
+ try {
317
+ client = buildClient(profile);
318
+ }
319
+ catch {
320
+ // doctor reports the missing env var as a failed check instead of dying
321
+ client = undefined;
322
+ }
323
+ const report = await runDoctor(args.profile, client);
324
+ printJson(report);
325
+ if (report.ok)
326
+ return EXIT.OK;
327
+ const authFailed = report.checks.some((c) => !c.ok && (c.name === "commerce_token_env" || c.detail.startsWith("auth:")));
328
+ return authFailed ? EXIT.AUTH : EXIT.CONFIG;
329
+ }
330
+ function commerceErrorExit(err) {
331
+ process.stderr.write(`commerce error (${err.kind}): ${err.message}\n`);
332
+ return err.kind === "auth" ? EXIT.AUTH : err.kind === "transient" ? EXIT.TRANSIENT : EXIT.CONFIG;
333
+ }
334
+ function outcomeExit(report) {
335
+ switch (report.outcome.kind) {
336
+ case "accepted":
337
+ case "no_work":
338
+ case "already_claimed":
339
+ return EXIT.OK;
340
+ case "human_required":
341
+ return EXIT.HUMAN;
342
+ case "no_decision":
343
+ case "timeout":
344
+ case "aborted":
345
+ return EXIT.TRANSIENT;
346
+ case "failed":
347
+ return report.outcome.retriable ? EXIT.TRANSIENT : EXIT.MODEL;
348
+ }
349
+ }
350
+ async function cmdAgentRun(args) {
351
+ const profile = requireProfile(args);
352
+ let client;
353
+ try {
354
+ client = buildClient(profile);
355
+ }
356
+ catch (err) {
357
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
358
+ return EXIT.CONFIG;
359
+ }
360
+ const fake = isFakeProvider(profile);
361
+ const streamFn = fake ? createDeterministicStreamFn(profile) : realStreamFn();
362
+ const getApiKey = fake
363
+ ? undefined
364
+ : () => {
365
+ const envName = profile.model.api_key_env;
366
+ if (!envName)
367
+ return undefined;
368
+ return process.env[envName];
369
+ };
370
+ if (args.once) {
371
+ // Same shutdown semantics as the foreground loop: SIGINT/SIGTERM aborts
372
+ // the in-flight turn, which abandons an unsettled claim (never
373
+ // completes it) instead of orphaning it until the stale-claim TTL.
374
+ const shutdown = new AbortController();
375
+ const onSignal = () => shutdown.abort();
376
+ process.once("SIGINT", onSignal);
377
+ process.once("SIGTERM", onSignal);
378
+ let report;
379
+ try {
380
+ report = await runNegotiationTurn({
381
+ profile,
382
+ client,
383
+ streamFn,
384
+ ...(getApiKey !== undefined ? { getApiKey } : {}),
385
+ signal: shutdown.signal,
386
+ });
387
+ }
388
+ catch (err) {
389
+ if (err instanceof CommerceError)
390
+ return commerceErrorExit(err);
391
+ process.stderr.write(`unexpected error: ${err instanceof Error ? err.message : String(err)}\n`);
392
+ return EXIT.TRANSIENT;
393
+ }
394
+ finally {
395
+ process.removeListener("SIGINT", onSignal);
396
+ process.removeListener("SIGTERM", onSignal);
397
+ }
398
+ printReportJsonl(report);
399
+ return outcomeExit(report);
400
+ }
401
+ // Foreground serial polling. SIGINT/SIGTERM abort the in-flight turn
402
+ // (unsettled claims are abandoned, never completed) and stop the loop
403
+ // cleanly with exit 0.
404
+ const shutdown = new AbortController();
405
+ const onSignal = () => shutdown.abort();
406
+ process.once("SIGINT", onSignal);
407
+ process.once("SIGTERM", onSignal);
408
+ try {
409
+ await runForeground({
410
+ profile,
411
+ client,
412
+ streamFn,
413
+ ...(getApiKey !== undefined ? { getApiKey } : {}),
414
+ signal: shutdown.signal,
415
+ onReport: printReportJsonl,
416
+ });
417
+ return EXIT.OK;
418
+ }
419
+ catch (err) {
420
+ if (err instanceof CommerceError)
421
+ return commerceErrorExit(err);
422
+ process.stderr.write(`unexpected error: ${err instanceof Error ? err.message : String(err)}\n`);
423
+ return EXIT.TRANSIENT;
424
+ }
425
+ finally {
426
+ process.removeListener("SIGINT", onSignal);
427
+ process.removeListener("SIGTERM", onSignal);
428
+ }
429
+ }
430
+ /**
431
+ * Interactive operator TUI (v0.2). Candidate generation uses the
432
+ * deterministic runner wired to the real CommerceClient boundary — formal
433
+ * writes still go through CommerceClient and the gateway policy gate. The
434
+ * embedded-Pi candidate backend is the documented next integration hook.
435
+ */
436
+ async function cmdTui(args) {
437
+ const profile = requireProfile(args);
438
+ let client;
439
+ try {
440
+ client = buildClient(profile);
441
+ }
442
+ catch (err) {
443
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
444
+ return EXIT.CONFIG;
445
+ }
446
+ const dataDir = args.dataDir ?? path.resolve(".kiwi", "agents", profile.agent_id);
447
+ const controller = new OperatorController({
448
+ profile,
449
+ store: new FileOperatorEventStore(dataDir),
450
+ engine: createStrategyEngine(),
451
+ runner: new DeterministicNegotiationRunner(profile, client),
452
+ });
453
+ try {
454
+ await controller.start();
455
+ return await runTui({ controller, input: process.stdin, output: process.stdout });
456
+ }
457
+ catch (err) {
458
+ if (err instanceof CommerceError)
459
+ return commerceErrorExit(err);
460
+ if (err instanceof OperatorStoreError) {
461
+ process.stderr.write(`${err.message}\n`);
462
+ return EXIT.CONFIG;
463
+ }
464
+ process.stderr.write(`unexpected error: ${err instanceof Error ? err.message : String(err)}\n`);
465
+ return EXIT.TRANSIENT;
466
+ }
467
+ }
468
+ /**
469
+ * `kiwi agent serve`:把 merchant profile 变成可被 catalog 发现的 A2A merchant。
470
+ *
471
+ * 从 merchant profile 构建身份 + Agent Card,起 A2AServer(生产 KNP merchant
472
+ * handler),启动时注册进 kiwi-catalog,buyer 可经 catalog 发现并磋商。
473
+ *
474
+ * kiwi agent serve --profile <merchant.yaml> [--catalog <url>] # 缺省官方 catalog,本地自托管用 --catalog http://127.0.0.1:8600
475
+ * [--port 9000] [--data-dir <dir>]
476
+ */
477
+ async function cmdAgentServe(args) {
478
+ const profile = requireProfile(args);
479
+ if (profile.role !== "merchant") {
480
+ process.stderr.write("kiwi agent serve 需要 merchant profile(role: merchant)\n");
481
+ return EXIT.CONFIG;
482
+ }
483
+ const catalog = args.catalog ?? process.env.KIWI_CATALOG_URL ?? DEFAULT_CATALOG_URL;
484
+ let node = await startA2aNode({
485
+ profile,
486
+ catalog,
487
+ preferredPort: args.port,
488
+ ownerTokenSecret: process.env.KIWI_CATALOG_OWNER_TOKEN_SECRET,
489
+ });
490
+ console.log(`[agent serve] merchant ${profile.agent_id} A2A server: ${node.agentCardUrl}`);
491
+ console.log(`[agent serve] registered in catalog ${catalog}: ${node.catalogAgentId ?? "?"}`);
492
+ const a2aNode = {
493
+ status: () => node === null
494
+ ? null
495
+ : {
496
+ role: node.role,
497
+ url: node.url,
498
+ agentCardUrl: node.agentCardUrl,
499
+ ...(node.catalogAgentId !== undefined ? { catalogAgentId: node.catalogAgentId } : {}),
500
+ },
501
+ rebuild: async (p) => {
502
+ await node?.stop().catch(() => undefined);
503
+ node = await startA2aNode({
504
+ profile: p,
505
+ catalog,
506
+ preferredPort: args.port,
507
+ ownerTokenSecret: process.env.KIWI_CATALOG_OWNER_TOKEN_SECRET,
508
+ });
509
+ },
510
+ stop: async () => {
511
+ await node?.stop().catch(() => undefined);
512
+ node = null;
513
+ },
514
+ };
515
+ // --no-chat 或非交互 stdin(后台/重定向):仅 A2A server 常驻,不进入对话。
516
+ if (args.noChat === true || process.stdin.isTTY !== true) {
517
+ const shutdown = async () => {
518
+ await a2aNode.stop();
519
+ process.exit(0);
520
+ };
521
+ process.on("SIGINT", shutdown);
522
+ process.on("SIGTERM", shutdown);
523
+ console.log(args.noChat === true
524
+ ? "[agent serve] listening(--no-chat)— Ctrl+C to stop"
525
+ : "[agent serve] listening(非交互 stdin,仅 A2A server)— Ctrl+C to stop");
526
+ await new Promise(() => { });
527
+ return EXIT.OK;
528
+ }
529
+ // 内置对话(缺省):同一进程既是 A2A 节点又能 `kiwi>` 对话。/quit 退出整个进程。
530
+ const kernel = await buildChatKernel(profile, args.dataDir, catalog);
531
+ const kernels = [kernel];
532
+ const reload = async (file) => {
533
+ const next = await buildChatKernel(loadProfile(resolveProfilePath(file)), args.dataDir, catalog);
534
+ kernels.push(next);
535
+ return next;
536
+ };
537
+ const shutdown = async () => {
538
+ await a2aNode.stop();
539
+ for (const k of kernels)
540
+ await k.close().catch(() => undefined);
541
+ process.exit(0);
542
+ };
543
+ process.on("SIGINT", shutdown);
544
+ process.on("SIGTERM", shutdown);
545
+ console.log("[agent serve] A2A server + 内置对话(/quit 退出整个进程)");
546
+ try {
547
+ return await runChatTui({ kernel, input: process.stdin, output: process.stdout, reload, a2aNode, catalog });
548
+ }
549
+ finally {
550
+ await a2aNode.stop();
551
+ for (const k of kernels)
552
+ await k.close().catch(() => undefined);
553
+ }
554
+ }
555
+ /**
556
+ * 裸 `kiwi` 的默认聊天 profile:底层大模型**可配置**(从环境变量读取,不 hardcode)。
557
+ * - KIWI_MODEL_PROVIDER(默认 deepseek)
558
+ * - KIWI_MODEL(默认 deepseek-v4-flash)
559
+ * - KIWI_MODEL_API_KEY_ENV(默认 DEEPSEEK_API_KEY)
560
+ * - KIWI_MODEL_BASE_URL(可选覆盖)
561
+ */
562
+ function defaultChatProfile() {
563
+ const provider = process.env.KIWI_MODEL_PROVIDER ?? "deepseek";
564
+ const model = process.env.KIWI_MODEL ?? "deepseek-v4-flash";
565
+ const apiKeyEnv = process.env.KIWI_MODEL_API_KEY_ENV ?? "DEEPSEEK_API_KEY";
566
+ const baseUrl = process.env.KIWI_MODEL_BASE_URL;
567
+ return {
568
+ runtime_version: RUNTIME_VERSION,
569
+ protocol_version: "shopping.negotiation/0.1",
570
+ agent_id: "kiwi-assistant",
571
+ role: "buyer",
572
+ owner_id: "kiwi-user",
573
+ commerce: {
574
+ base_url: "http://127.0.0.1:8765",
575
+ token_env: "SHOPPING_BUYER_TOKEN",
576
+ backend: "local_marketplace",
577
+ },
578
+ model: {
579
+ provider,
580
+ model,
581
+ api_key_env: apiKeyEnv,
582
+ ...(baseUrl !== undefined ? { base_url: baseUrl } : {}),
583
+ },
584
+ runtime: {
585
+ mode: "once",
586
+ poll_interval_seconds: 5,
587
+ turn_timeout_seconds: 90,
588
+ max_model_steps: 4,
589
+ max_retries: 2,
590
+ },
591
+ buyer_policy: {
592
+ target_skus: [],
593
+ quantity: 1,
594
+ max_total_price_private: 1_000_000,
595
+ acceptable_eta_latest: "2099-12-31T23:59:59+08:00",
596
+ required_after_sales_terms: [],
597
+ auto_negotiate: true,
598
+ human_review_on: [],
599
+ },
600
+ };
601
+ }
602
+ /**
603
+ * Main conversation (v0.3.0-A): build the AgentKernel for a profile.
604
+ * provider=fake runs the deterministic offline chat fake; real providers
605
+ * resolve models and auth through pi-ai's built-in provider catalog.
606
+ * `catalog` 是 agent catalog base URL(buyer 的 negotiate_buyer_task 发现商家用)。
607
+ */
608
+ async function buildChatKernel(profile, dataDir, catalog) {
609
+ const paths = ensurePathsForDir(dataDir ?? agentDataDir(profile.agent_id));
610
+ let models;
611
+ let model;
612
+ let connector;
613
+ let thinkingLevel;
614
+ let merchantClient;
615
+ let broker;
616
+ let commerceClient;
617
+ if (isFakeProvider(profile)) {
618
+ ({ models, model } = createFakeChatModels());
619
+ if (profile.role === "buyer") {
620
+ const { FakeCommerceConnector, fakeConnectorProduct } = await import("./agent/connector/fake-connector.js");
621
+ connector = new FakeCommerceConnector([
622
+ fakeConnectorProduct(),
623
+ fakeConnectorProduct({
624
+ sku: "sku-002",
625
+ title: "机制陶瓷杯",
626
+ price: 59,
627
+ stock: 0,
628
+ merchant_id: "merchant-002",
629
+ }),
630
+ ]);
631
+ }
632
+ else {
633
+ // Offline merchant chat: deterministic catalog client + dummy-scope
634
+ // credentials so the capability pack is exercisable without a gateway.
635
+ const { FakeMerchantClient, fakeMerchantProduct } = await import("./agent/merchant/fake-merchant-client.js");
636
+ const { StaticCredentialBroker } = await import("./agent/merchant/credential-broker.js");
637
+ merchantClient = new FakeMerchantClient({
638
+ products: [fakeMerchantProduct()],
639
+ });
640
+ broker = new StaticCredentialBroker({
641
+ negotiation: "fake-negotiation-token",
642
+ catalog: "fake-catalog-token",
643
+ inventory: "fake-inventory-token",
644
+ });
645
+ }
646
+ }
647
+ else {
648
+ const { builtinModels } = await import("@earendil-works/pi-ai/providers/all");
649
+ const collection = builtinModels();
650
+ const found = collection.getModel(profile.model.provider, profile.model.model);
651
+ if (found === undefined) {
652
+ process.stderr.write(`no built-in model ${profile.model.provider}/${profile.model.model}; check the profile\n`);
653
+ throw new ProfileError(`no built-in model ${profile.model.provider}/${profile.model.model}`);
654
+ }
655
+ models = collection;
656
+ model = found;
657
+ thinkingLevel = resolveThinkingLevel(profile);
658
+ if (profile.role === "buyer") {
659
+ const { ShoppingCliConnector } = await import("./agent/connector/http-connector.js");
660
+ connector = new ShoppingCliConnector(profile.commerce.base_url, {
661
+ buyerBootstrapToken: process.env.SHOPPING_BUYER_BOOTSTRAP_TOKEN,
662
+ });
663
+ }
664
+ // Real gateway: negotiation client + scoped merchant client + broker.
665
+ const { ProfileCredentialBroker } = await import("./agent/merchant/credential-broker.js");
666
+ broker = new ProfileCredentialBroker(profile);
667
+ try {
668
+ commerceClient = buildClient(profile);
669
+ }
670
+ catch {
671
+ // No negotiation token: negotiation tools fail closed at call time.
672
+ // Catalog/inventory 只读工具走公开搜索端点,不依赖该 token,仍会挂载。
673
+ commerceClient = undefined;
674
+ if (profile.role === "merchant") {
675
+ process.stderr.write(`[kiwi] 未设置 ${profile.commerce.token_env}:磋商工具停用(fail closed),` +
676
+ "目录/库存只读工具仍可用。\n");
677
+ }
678
+ }
679
+ if (profile.role === "merchant") {
680
+ const { HttpMerchantClient } = await import("./agent/merchant/merchant-client.js");
681
+ merchantClient = new HttpMerchantClient(profile.commerce.base_url, broker);
682
+ }
683
+ }
684
+ // KIWI_MODE env: start the chat already in the given write mode (e.g.
685
+ // autopilot for autonomous negotiation) — no manual /mode needed.
686
+ const kiwiMode = process.env.KIWI_MODE;
687
+ const mode = isAgentMode(kiwiMode) ? kiwiMode : undefined;
688
+ if (kiwiMode !== undefined && mode === undefined) {
689
+ process.stderr.write(`unknown KIWI_MODE ${kiwiMode}(可选 ${["manual", "supervised", "autopilot"].join("/")})\n`);
690
+ }
691
+ return AgentKernel.open({
692
+ profile,
693
+ paths,
694
+ models,
695
+ model,
696
+ ...(mode !== undefined ? { mode } : {}),
697
+ ...(connector !== undefined ? { connector } : {}),
698
+ ...(commerceClient !== undefined ? { commerceClient } : {}),
699
+ ...(merchantClient !== undefined ? { merchantClient } : {}),
700
+ ...(broker !== undefined ? { broker } : {}),
701
+ ...(catalog !== undefined ? { catalog } : {}),
702
+ ...(thinkingLevel !== undefined ? { thinkingLevel } : {}),
703
+ });
704
+ }
705
+ /** kiwi 包根目录(dist/cli.js 的上级)——全局 `kiwi` 在任意 cwd 也能解析示例 profile。 */
706
+ function packageRoot() {
707
+ const here = path.dirname(fileURLToPath(import.meta.url));
708
+ return path.resolve(here, "..");
709
+ }
710
+ /**
711
+ * `/profile <name>` 快捷解析:`merchant` → <包根>/examples/profiles/merchant.fake.yaml
712
+ * (依次试 fake/local/裸名)。含路径或 .yaml/.yml 后缀时原样使用(相对 cwd)。
713
+ */
714
+ function resolveProfilePath(file) {
715
+ if (file.includes("/") || file.endsWith(".yaml") || file.endsWith(".yml"))
716
+ return file;
717
+ const root = packageRoot();
718
+ const candidates = [
719
+ path.join(root, "examples", "profiles", `${file}.fake.yaml`),
720
+ path.join(root, "examples", "profiles", `${file}.local.yaml`),
721
+ path.join(root, "examples", "profiles", `${file}.yaml`),
722
+ ];
723
+ for (const candidate of candidates) {
724
+ if (existsSync(candidate))
725
+ return candidate;
726
+ }
727
+ return file; // 原路径,让 loadProfile 抛原始错误
728
+ }
729
+ /**
730
+ * Main conversation (v0.3.0-A): the AgentKernel with persistent session and
731
+ * Principal Memory. 裸 `kiwi`(无 --profile)用 defaultChatProfile 直接进入
732
+ * `kiwi>` 对话;`/profile <file>` 在对话内切换 kernel。
733
+ */
734
+ async function cmdChat(args) {
735
+ const profile = args.profile !== undefined ? loadProfile(args.profile) : defaultChatProfile();
736
+ // A2A 节点 + buyer 磋商工具共用一个 catalog:kernel 构建前先解析。
737
+ const catalog = args.catalog ?? process.env.KIWI_CATALOG_URL ?? DEFAULT_CATALOG_URL;
738
+ const kernel = await buildChatKernel(profile, args.dataDir, catalog);
739
+ const kernels = [kernel];
740
+ const reload = async (file) => {
741
+ const next = await buildChatKernel(loadProfile(resolveProfilePath(file)), args.dataDir, catalog);
742
+ kernels.push(next);
743
+ return next;
744
+ };
745
+ let node = null;
746
+ const a2aNode = {
747
+ status: () => node === null
748
+ ? null
749
+ : {
750
+ role: node.role,
751
+ url: node.url,
752
+ agentCardUrl: node.agentCardUrl,
753
+ ...(node.catalogAgentId !== undefined ? { catalogAgentId: node.catalogAgentId } : {}),
754
+ },
755
+ rebuild: async (p) => {
756
+ await node?.stop().catch(() => undefined);
757
+ node = await startA2aNode({
758
+ profile: p,
759
+ catalog,
760
+ preferredPort: args.port,
761
+ ownerTokenSecret: process.env.KIWI_CATALOG_OWNER_TOKEN_SECRET,
762
+ });
763
+ process.stderr.write(`[a2a] ${node.role}@${node.url}${node.catalogAgentId !== undefined ? ` registered ${node.catalogAgentId}` : ""}\n`);
764
+ },
765
+ stop: async () => {
766
+ await node?.stop().catch(() => undefined);
767
+ node = null;
768
+ },
769
+ };
770
+ if (!args.noA2a) {
771
+ try {
772
+ await a2aNode.rebuild(profile);
773
+ }
774
+ catch (err) {
775
+ process.stderr.write(`[a2a] 节点启动失败(对话继续):${err instanceof Error ? err.message : String(err)}\n`);
776
+ }
777
+ }
778
+ // SIGINT/SIGTERM → 优雅关闭(flush harness 会话 + close kernel/DB)。
779
+ // 此前裸 `kiwi`/`kiwi chat` 在模型回合中途 Ctrl+C 直接终止,kernel.close()
780
+ // 被跳过(与 agent serve 的信号处理对齐)。
781
+ const shutdown = async () => {
782
+ for (const k of kernels)
783
+ await k.close().catch(() => undefined);
784
+ await a2aNode.stop().catch(() => undefined);
785
+ process.exit(0);
786
+ };
787
+ process.on("SIGINT", shutdown);
788
+ process.on("SIGTERM", shutdown);
789
+ try {
790
+ return await runChatTui({
791
+ kernel,
792
+ input: process.stdin,
793
+ output: process.stdout,
794
+ reload,
795
+ a2aNode,
796
+ catalog,
797
+ });
798
+ }
799
+ catch (err) {
800
+ process.stderr.write(`unexpected error: ${err instanceof Error ? err.message : String(err)}\n`);
801
+ return EXIT.TRANSIENT;
802
+ }
803
+ finally {
804
+ process.removeListener("SIGINT", shutdown);
805
+ process.removeListener("SIGTERM", shutdown);
806
+ for (const k of kernels)
807
+ await k.close().catch(() => undefined);
808
+ await a2aNode.stop().catch(() => undefined);
809
+ }
810
+ }
811
+ /**
812
+ * 产品层 buyer 命令树(rev1.1 §2.2/§19 D4)。
813
+ * - start = chat 别名(Buyer 对话入口,既有实现);
814
+ * - init/search/tasks = D4 骨架(输出"尚未实现"提示,不假装可用)。
815
+ */
816
+ async function routeBuyer(sub, args) {
817
+ if (sub === undefined) {
818
+ process.stdout.write(productHelp("buyer"));
819
+ return EXIT.OK;
820
+ }
821
+ if (sub === "start")
822
+ return await cmdChat(args);
823
+ if (sub === "init")
824
+ return await cmdBuyerInit(args);
825
+ if (sub === "search")
826
+ return await cmdBuyerSearch(args);
827
+ if (sub === "tasks")
828
+ return await cmdBuyerTasks(args);
829
+ process.stderr.write(`unknown buyer command: ${sub}\n`);
830
+ return EXIT.CONFIG;
831
+ }
832
+ /** `kiwi buyer init`(D4):生成 buyer profile(无需 shopping-cli)。 */
833
+ async function cmdBuyerInit(args) {
834
+ // 身份可选:缺省自动生成(buyer-<hostname>-<随机>);显式指定用于跨设备延续
835
+ const agentId = args.agentId ?? process.env.KIWI_BUYER_AGENT_ID ?? "";
836
+ const report = buyerInit({
837
+ agentId,
838
+ ...(args.ownerId !== undefined ? { ownerId: args.ownerId } : {}),
839
+ ...(args.autoNegotiate ? { autoNegotiate: true } : {}),
840
+ ...(args.output !== undefined ? { outputPath: args.output } : {}),
841
+ ...(args.force ? { force: true } : {}),
842
+ });
843
+ printJson(report);
844
+ return report.ok ? EXIT.OK : EXIT.CONFIG;
845
+ }
846
+ /** `kiwi buyer search`(D4):Product-first 搜索(M3 链路)。 */
847
+ async function cmdBuyerSearch(args) {
848
+ // command = ["buyer", "search", <query...>]
849
+ const query = args.command.slice(2).join(" ");
850
+ if (!query) {
851
+ process.stderr.write("search 需要一个查询描述(如:kiwi buyer search 21.5寸工业触摸屏)\n");
852
+ return EXIT.CONFIG;
853
+ }
854
+ const catalog = args.catalog ?? process.env.KIWI_CATALOG_URL ?? DEFAULT_CATALOG_URL;
855
+ const limit = args.limit !== undefined ? Number(args.limit) : undefined;
856
+ if (args.limit !== undefined && (!Number.isInteger(limit) || (limit ?? 0) <= 0)) {
857
+ process.stderr.write("--limit 必须是正整数\n");
858
+ return EXIT.CONFIG;
859
+ }
860
+ try {
861
+ const hits = await buyerSearch({
862
+ query,
863
+ catalogUrl: catalog,
864
+ ...(limit !== undefined ? { limit } : {}),
865
+ ...(args.category !== undefined ? { category: args.category } : {}),
866
+ ...(args.region !== undefined ? { region: args.region } : {}),
867
+ ...(args.listingType === "product" || args.listingType === "capability"
868
+ ? { listingType: args.listingType }
869
+ : {}),
870
+ });
871
+ printJson({ ok: true, count: hits.length, results: hits });
872
+ return hits.length > 0 ? EXIT.OK : EXIT.CONFIG;
873
+ }
874
+ catch (err) {
875
+ process.stderr.write(`搜索失败:${err instanceof Error ? err.message : String(err)}(Kiwi Network ${catalog} 不可达?)\n`);
876
+ return EXIT.CONFIG;
877
+ }
878
+ }
879
+ /** `kiwi buyer tasks`(D4):读本地任务列表。 */
880
+ async function cmdBuyerTasks(args) {
881
+ try {
882
+ const tasks = await buyerTasks({
883
+ ...(args.dataDir !== undefined ? { dataDir: args.dataDir } : {}),
884
+ ...(args.agentId !== undefined ? { agentId: args.agentId } : {}),
885
+ });
886
+ printJson({ ok: true, count: tasks.length, tasks });
887
+ return EXIT.OK;
888
+ }
889
+ catch (err) {
890
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
891
+ return EXIT.CONFIG;
892
+ }
893
+ }
894
+ /**
895
+ * 产品层 merchant 命令树(rev1.1 §2.3/§19 D1-D3)。
896
+ * - start = agent serve 别名(Merchant A2A server + 注册 Kiwi Network);
897
+ * - init/publish/listings/status/doctor = 骨架(对应 D1/D2/D3)。
898
+ */
899
+ async function routeMerchant(sub, args) {
900
+ if (sub === undefined) {
901
+ process.stdout.write(productHelp("merchant"));
902
+ return EXIT.OK;
903
+ }
904
+ if (sub === "start")
905
+ return await cmdAgentServe(args);
906
+ if (sub === "init")
907
+ return await cmdMerchantInit(args);
908
+ if (sub === "publish")
909
+ return await cmdMerchantPublish(args);
910
+ if (sub === "listings")
911
+ return notImplementedProduct("kiwi merchant listings", "D2");
912
+ if (sub === "status")
913
+ return notImplementedProduct("kiwi merchant status", "D1");
914
+ if (sub === "doctor")
915
+ return notImplementedProduct("kiwi merchant doctor", "D3");
916
+ process.stderr.write(`unknown merchant command: ${sub}\n`);
917
+ return EXIT.CONFIG;
918
+ }
919
+ /**
920
+ * `kiwi merchant init`(D1):首次初始化引导(rev1.1 §3.2/§19 D1)。
921
+ * 生成可直接使用的 merchant profile(agent_id = shopping-cli merchant_id,
922
+ * D2 身份统一);shopping-cli 缺失/不可达记 warning 不阻塞。
923
+ */
924
+ async function cmdMerchantInit(args) {
925
+ // --merchant-id / --name flag 优先,env 回退(历史教训:help 文案承诺的
926
+ // flag 从未被 parseArgs 解析,按 help 执行 100% Unknown argument)。
927
+ const merchantId = args.merchantId ?? process.env.KIWI_MERCHANT_ID ?? "";
928
+ const name = args.merchantName ?? process.env.KIWI_MERCHANT_NAME ?? "";
929
+ if (!name) {
930
+ process.stderr.write("--name <商家名称> 是必需的(或 KIWI_MERCHANT_NAME)——它是你在网络上的" +
931
+ "公开商家名称,Kiwi 不能替商家起名。\n");
932
+ return EXIT.CONFIG;
933
+ }
934
+ const report = await merchantInit({
935
+ merchantName: name,
936
+ ...(merchantId !== "" ? { merchantId } : {}),
937
+ shoppingCliUrl: process.env.SHOPPING_CLI_URL ?? "http://127.0.0.1:8765",
938
+ shoppingCliDb: process.env.SHOPPING_DB_PATH,
939
+ catalogUrl: args.catalog ?? process.env.KIWI_CATALOG_URL ?? DEFAULT_CATALOG_URL,
940
+ floorPriceMinor: 0,
941
+ ...(args.output !== undefined ? { outputPath: args.output } : {}),
942
+ ...(args.force ? { force: true } : {}),
943
+ // 数据引擎默认自动安装(合一体验);--no-install 显式禁用(受限/CI)
944
+ autoInstallShoppingCli: !args.noInstall,
945
+ });
946
+ printJson(report);
947
+ for (const warning of report.warnings) {
948
+ process.stderr.write(`warning: ${warning}\n`);
949
+ }
950
+ return report.ok ? EXIT.OK : EXIT.CONFIG;
951
+ }
952
+ /**
953
+ * `kiwi merchant publish`(D2):编排 agent 注册 + listing 发布(rev1.1 §4.5)。
954
+ * fail-closed:任一步失败 → 非零退出 + 分步报告,不假装全成功。
955
+ */
956
+ async function cmdMerchantPublish(args) {
957
+ const profile = requireProfile(args);
958
+ if (profile.role !== "merchant") {
959
+ process.stderr.write("kiwi merchant publish 需要 merchant profile(role: merchant)\n");
960
+ return EXIT.CONFIG;
961
+ }
962
+ const shoppingCliDb = args.shoppingCliDb ?? process.env.SHOPPING_DB_PATH;
963
+ if (!shoppingCliDb) {
964
+ process.stderr.write("--shopping-cli-db <path>(或 SHOPPING_DB_PATH)是必需的:shopping-cli 的 SQLite 数据库路径\n");
965
+ return EXIT.CONFIG;
966
+ }
967
+ if (!existsSync(shoppingCliDb)) {
968
+ process.stderr.write(`shopping-cli 数据库不存在:${shoppingCliDb}\n`);
969
+ return EXIT.CONFIG;
970
+ }
971
+ const ownerTokenSecret = process.env.KIWI_CATALOG_OWNER_TOKEN_SECRET;
972
+ if (!ownerTokenSecret) {
973
+ process.stderr.write("KIWI_CATALOG_OWNER_TOKEN_SECRET 是必需的(owner token 派生,与 kiwi-catalog 一致)\n");
974
+ return EXIT.CONFIG;
975
+ }
976
+ const catalog = args.catalog ?? process.env.KIWI_CATALOG_URL ?? DEFAULT_CATALOG_URL;
977
+ const report = await merchantPublish({
978
+ profile,
979
+ catalogBaseUrl: catalog,
980
+ ownerTokenSecret,
981
+ shoppingCliDb,
982
+ ...(args.shoppingCliPath !== undefined ? { shoppingCliPath: args.shoppingCliPath } : {}),
983
+ ...(args.shoppingCliMerchant !== undefined
984
+ ? { shoppingCliMerchant: args.shoppingCliMerchant }
985
+ : {}),
986
+ });
987
+ printJson(report);
988
+ return report.ok ? EXIT.OK : EXIT.CONFIG;
989
+ }
990
+ /** 产品层 network 命令树(rev1.1 §5)——Operator 面规划中,全部骨架。 */
991
+ async function routeNetwork(sub) {
992
+ if (sub === undefined) {
993
+ process.stdout.write(productHelp("network"));
994
+ return EXIT.OK;
995
+ }
996
+ return notImplementedProduct(`kiwi network ${sub}`, "§5(Network Operator 面)");
997
+ }
998
+ function notImplementedProduct(name, target) {
999
+ process.stderr.write(`${name} 尚未实现(产品层完成定义 ${target},见 docs/kiwi-product-layer-refactor-rev1.1.md §19)。\n`);
1000
+ return EXIT.CONFIG;
1001
+ }
1002
+ export async function main(argv = process.argv.slice(2)) {
1003
+ const hasHelp = argv.includes("--help") || argv.includes("-h");
1004
+ const firstArg = argv.find((a) => !a.startsWith("-"));
1005
+ // 产品层命令组帮助优先于全局帮助(`kiwi buyer --help` → buyer 帮助)
1006
+ if (hasHelp && (firstArg === "buyer" || firstArg === "merchant" || firstArg === "network")) {
1007
+ const help = productHelp(firstArg);
1008
+ if (help !== "") {
1009
+ process.stdout.write(help);
1010
+ return EXIT.OK;
1011
+ }
1012
+ }
1013
+ if (hasHelp) {
1014
+ process.stdout.write(USAGE);
1015
+ return EXIT.OK;
1016
+ }
1017
+ if (argv.includes("--version")) {
1018
+ process.stdout.write(`kiwi ${PRODUCT_VERSION}\n`);
1019
+ return EXIT.OK;
1020
+ }
1021
+ let args;
1022
+ try {
1023
+ args = parseArgs(argv);
1024
+ }
1025
+ catch (err) {
1026
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
1027
+ return EXIT.CONFIG;
1028
+ }
1029
+ const [cmd, sub] = args.command;
1030
+ try {
1031
+ // 裸 `kiwi`:直接进入 `kiwi>` 自由对话(默认 deepseek-v4-flash,模型可配置)。
1032
+ if (cmd === undefined)
1033
+ return await cmdChat(args);
1034
+ // 产品层命令树(product-strategy rev1.1 §10/§19;别名保留旧命令)
1035
+ if (cmd === "buyer")
1036
+ return await routeBuyer(sub, args);
1037
+ if (cmd === "merchant")
1038
+ return await routeMerchant(sub, args);
1039
+ if (cmd === "network")
1040
+ return await routeNetwork(sub);
1041
+ if (cmd === "doctor") {
1042
+ // 无 --profile → 三组件聚合健康(D0);有 → 既有 profile doctor
1043
+ return args.profile !== undefined ? await cmdDoctor(args) : await cmdProductDoctor();
1044
+ }
1045
+ if (cmd === "agent" && sub === "run")
1046
+ return await cmdAgentRun(args);
1047
+ if (cmd === "agent" && sub === "serve")
1048
+ return await cmdAgentServe(args); // 旧命令别名保留
1049
+ if (cmd === "tui")
1050
+ return await cmdTui(args);
1051
+ if (cmd === "chat")
1052
+ return await cmdChat(args);
1053
+ if (cmd === "init") {
1054
+ const result = await runInit({
1055
+ dir: requireDir(args),
1056
+ ...(args.shoppingCliSrc !== undefined ? { shoppingCliSrc: args.shoppingCliSrc } : {}),
1057
+ ...(args.fake ? { fake: true } : {}),
1058
+ });
1059
+ printJson(result);
1060
+ return EXIT.OK;
1061
+ }
1062
+ if (cmd === "up") {
1063
+ printJson(await runUp(requireDir(args)));
1064
+ return EXIT.OK;
1065
+ }
1066
+ if (cmd === "status") {
1067
+ const result = await runStatus(requireDir(args));
1068
+ printJson(result);
1069
+ return result.ok ? EXIT.OK : EXIT.TRANSIENT;
1070
+ }
1071
+ if (cmd === "logs") {
1072
+ const result = runLogs(requireDir(args), parseLogLines(args.lines));
1073
+ for (const line of result.lines)
1074
+ process.stdout.write(`${line}\n`);
1075
+ if (result.lines.length === 0) {
1076
+ process.stderr.write("no log lines (processes not started yet or logs empty)\n");
1077
+ }
1078
+ return EXIT.OK;
1079
+ }
1080
+ if (cmd === "metrics") {
1081
+ // v0.7.0 #21:从 buyer agent data dir 的 Ledger 事件计算 KTH 指标。
1082
+ const dir = requireDir(args);
1083
+ const { HandoffEventStore, computeHandoffMetrics } = await import("./handoff/index.js");
1084
+ const ledger = new HandoffEventStore({ dir });
1085
+ const byNegotiation = new Map();
1086
+ for (const nid of ledger.listNegotiations())
1087
+ byNegotiation.set(nid, ledger.events(nid));
1088
+ printJson(computeHandoffMetrics(byNegotiation));
1089
+ return EXIT.OK;
1090
+ }
1091
+ if (cmd === "down") {
1092
+ const result = await runDown(requireDir(args));
1093
+ printJson(result);
1094
+ const failed = result.results.some((r) => r.outcome === "unverified");
1095
+ return failed ? EXIT.TRANSIENT : EXIT.OK;
1096
+ }
1097
+ process.stderr.write(USAGE);
1098
+ return EXIT.CONFIG;
1099
+ }
1100
+ catch (err) {
1101
+ if (err instanceof ProfileError || err instanceof StackConfigError) {
1102
+ process.stderr.write(`${err.message}\n`);
1103
+ return EXIT.CONFIG;
1104
+ }
1105
+ if (err instanceof SupervisorError) {
1106
+ process.stderr.write(`${err.message}\n`);
1107
+ return EXIT.TRANSIENT;
1108
+ }
1109
+ throw err;
1110
+ }
1111
+ }
1112
+ // Run only when executed as the CLI entrypoint (importable for tests).
1113
+ // Robust against npm .bin symlinks: argv[1] is the symlink path while
1114
+ // import.meta.url is the real file — compare both after realpath.
1115
+ export function isInvokedAsScript() {
1116
+ const argv1 = process.argv[1];
1117
+ if (argv1 === undefined || argv1 === "")
1118
+ return false;
1119
+ const selfPath = fileURLToPath(import.meta.url);
1120
+ const argvPath = path.resolve(argv1);
1121
+ try {
1122
+ return realpathSync(selfPath) === realpathSync(argvPath);
1123
+ }
1124
+ catch {
1125
+ // Missing/deleted argv path (or self): fall back to unresolved compare.
1126
+ return selfPath === argvPath;
1127
+ }
1128
+ }
1129
+ if (isInvokedAsScript()) {
1130
+ main()
1131
+ .then((code) => {
1132
+ process.exitCode = code;
1133
+ })
1134
+ .catch((err) => {
1135
+ process.stderr.write(`fatal: ${err instanceof Error ? err.message : String(err)}\n`);
1136
+ process.exitCode = EXIT.TRANSIENT;
1137
+ });
1138
+ }
1139
+ //# sourceMappingURL=cli.js.map