@xyagent/cli 0.0.1

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 (385) hide show
  1. package/README.md +860 -0
  2. package/bin/agentlink +8585 -0
  3. package/bin/agentlink-agent +7 -0
  4. package/bin/agentlink-mcp-stdio +173 -0
  5. package/docs/LOGGING.md +159 -0
  6. package/package.json +38 -0
  7. package/src/core.mjs +320 -0
  8. package/src/tunnel.mjs +291 -0
  9. package/src/tunnel_proxy.mjs +913 -0
  10. package/src/tunnel_service.mjs +699 -0
  11. package/src/tunnel_state.mjs +301 -0
  12. package/src/unified_producer.mjs +259 -0
  13. package/src-ext/README.md +75 -0
  14. package/src-ext/bin.mjs +128 -0
  15. package/src-ext/commands/agent.mjs +66 -0
  16. package/src-ext/commands/help.mjs +31 -0
  17. package/src-ext/commands/pair.mjs +455 -0
  18. package/src-ext/commands/reload.mjs +78 -0
  19. package/src-ext/commands/service.mjs +64 -0
  20. package/src-ext/core/accountResolver.mjs +137 -0
  21. package/src-ext/core/activeRuns.mjs +76 -0
  22. package/src-ext/core/agentlinkToolsBootstrap.mjs +75 -0
  23. package/src-ext/core/agentlinkToolsRegistry.mjs +323 -0
  24. package/src-ext/core/agentlinkToolsServer.mjs +109 -0
  25. package/src-ext/core/approvalGateway.mjs +132 -0
  26. package/src-ext/core/attachAuditLog.mjs +79 -0
  27. package/src-ext/core/attachDenylist.mjs +128 -0
  28. package/src-ext/core/autoTunnelDetector.mjs +98 -0
  29. package/src-ext/core/autoTunnelGateway.mjs +393 -0
  30. package/src-ext/core/autoTunnelWiring.mjs +184 -0
  31. package/src-ext/core/boundedMap.mjs +98 -0
  32. package/src-ext/core/bridgeAttachAutoScanner.mjs +237 -0
  33. package/src-ext/core/bridgeHooks.mjs +168 -0
  34. package/src-ext/core/bridgeSelfUninstall.mjs +133 -0
  35. package/src-ext/core/claudeTrust.mjs +74 -0
  36. package/src-ext/core/codexTrust.mjs +77 -0
  37. package/src-ext/core/cosUploadClient.mjs +326 -0
  38. package/src-ext/core/createWorkspace.mjs +170 -0
  39. package/src-ext/core/daemonRestart.mjs +49 -0
  40. package/src-ext/core/defaultWorkspace.mjs +65 -0
  41. package/src-ext/core/ensureGitRepo.mjs +57 -0
  42. package/src-ext/core/hermesProfile.mjs +75 -0
  43. package/src-ext/core/interruptGateway.mjs +119 -0
  44. package/src-ext/core/interruptRunListener.mjs +106 -0
  45. package/src-ext/core/mcpRuntimeFanout.mjs +236 -0
  46. package/src-ext/core/mcpStdioClient.mjs +316 -0
  47. package/src-ext/core/openclawGatewayClient.mjs +230 -0
  48. package/src-ext/core/pairCodeClient.mjs +331 -0
  49. package/src-ext/core/pairInventory.mjs +59 -0
  50. package/src-ext/core/pathExpand.mjs +34 -0
  51. package/src-ext/core/preprocessAttachments.mjs +113 -0
  52. package/src-ext/core/relayWorker.mjs +284 -0
  53. package/src-ext/core/relayWorkerHttp.mjs +58 -0
  54. package/src-ext/core/scanWorkspaces.mjs +842 -0
  55. package/src-ext/core/sessionSlot.mjs +70 -0
  56. package/src-ext/core/stateMachine.mjs +85 -0
  57. package/src-ext/core/toolsServerLifecycle.mjs +169 -0
  58. package/src-ext/core/unifiedDispatchHandler.mjs +439 -0
  59. package/src-ext/core/usageReporter.mjs +207 -0
  60. package/src-ext/openclaw-plugin/envelope-builder.cjs +619 -0
  61. package/src-ext/openclaw-plugin/index.cjs +1919 -0
  62. package/src-ext/openclaw-plugin/openclaw.plugin.json +20 -0
  63. package/src-ext/openclaw-plugin/package.json +12 -0
  64. package/src-ext/openclaw-plugin/relay-defaults.json +3 -0
  65. package/src-ext/openclaw-plugin/todoTranslatorUtils.cjs +101 -0
  66. package/src-ext/runtime/_shared/cliExec.mjs +138 -0
  67. package/src-ext/runtime/_shared/cosTextRefs.mjs +120 -0
  68. package/src-ext/runtime/_shared/fetchAndBase64Encode.mjs +52 -0
  69. package/src-ext/runtime/_shared/relayObjectToBlock.mjs +307 -0
  70. package/src-ext/runtime/_shared/sessionPicker.mjs +418 -0
  71. package/src-ext/runtime/_shared/slashCommandRouter.mjs +1346 -0
  72. package/src-ext/runtime/_shared/todoTranslatorUtils.mjs +94 -0
  73. package/src-ext/runtime/claude/askUserQuestionTranslator.mjs +241 -0
  74. package/src-ext/runtime/claude/customCommandsCollector.mjs +132 -0
  75. package/src-ext/runtime/claude/handleRequest.mjs +1418 -0
  76. package/src-ext/runtime/claude/index.mjs +160 -0
  77. package/src-ext/runtime/claude/internalCommandNames.mjs +58 -0
  78. package/src-ext/runtime/claude/launcher.mjs +313 -0
  79. package/src-ext/runtime/claude/mcpConfigAdapter.mjs +174 -0
  80. package/src-ext/runtime/claude/mcpConfigWriter.mjs +57 -0
  81. package/src-ext/runtime/claude/modelContextWindow.mjs +30 -0
  82. package/src-ext/runtime/claude/modelScanner.mjs +257 -0
  83. package/src-ext/runtime/claude/permissionInterruptBlock.mjs +86 -0
  84. package/src-ext/runtime/claude/permissionPromptServer.mjs +170 -0
  85. package/src-ext/runtime/claude/permissionPromptServerWorker.mjs +214 -0
  86. package/src-ext/runtime/claude/preflight.mjs +62 -0
  87. package/src-ext/runtime/claude/stdoutParser.mjs +365 -0
  88. package/src-ext/runtime/claude/todoTranslator.mjs +66 -0
  89. package/src-ext/runtime/claude/usageProbe.mjs +576 -0
  90. package/src-ext/runtime/claude/usageProbeStrip.mjs +14 -0
  91. package/src-ext/runtime/codex/codexCustomCommandsCollector.mjs +87 -0
  92. package/src-ext/runtime/codex/elicitationHandler.mjs +91 -0
  93. package/src-ext/runtime/codex/eventMapper.mjs +154 -0
  94. package/src-ext/runtime/codex/handleRequest.mjs +1152 -0
  95. package/src-ext/runtime/codex/index.mjs +142 -0
  96. package/src-ext/runtime/codex/mcpConfigAdapter.mjs +155 -0
  97. package/src-ext/runtime/codex/modelScanner.mjs +305 -0
  98. package/src-ext/runtime/codex/planNotificationHandler.mjs +61 -0
  99. package/src-ext/runtime/codex/preflight.mjs +67 -0
  100. package/src-ext/runtime/hermes/commandBackend.mjs +117 -0
  101. package/src-ext/runtime/hermes/envSetup.mjs +229 -0
  102. package/src-ext/runtime/hermes/gatewayManager.mjs +625 -0
  103. package/src-ext/runtime/hermes/handleRequest.mjs +1257 -0
  104. package/src-ext/runtime/hermes/httpBackend.mjs +219 -0
  105. package/src-ext/runtime/hermes/index.mjs +196 -0
  106. package/src-ext/runtime/hermes/mcpConfigAdapter.mjs +189 -0
  107. package/src-ext/runtime/hermes/preflight.mjs +359 -0
  108. package/src-ext/runtime/hermes/responsesBackend.mjs +276 -0
  109. package/src-ext/runtime/hermes/sessionStore.mjs +78 -0
  110. package/src-ext/runtime/hermes/todoTranslator.mjs +90 -0
  111. package/src-ext/runtime/hermes/workspaceRpc.mjs +124 -0
  112. package/src-ext/runtime/openclaw/buildOpenclawDaemonInput.mjs +143 -0
  113. package/src-ext/runtime/openclaw/mcpConfigAdapter.mjs +91 -0
  114. package/src-ext/runtime/openclaw/openclawConfig.mjs +145 -0
  115. package/src-ext/runtime/picoclaw/constants.mjs +39 -0
  116. package/src-ext/runtime/picoclaw/handleRequest.mjs +289 -0
  117. package/src-ext/runtime/picoclaw/index.mjs +314 -0
  118. package/src-ext/runtime/picoclaw/pairFlow.mjs +224 -0
  119. package/src-ext/runtime/picoclaw/state.mjs +78 -0
  120. package/src-ext/runtime/picoclaw/todoTranslator.mjs +67 -0
  121. package/src-ext/runtime/picoclaw/translator.mjs +272 -0
  122. package/src-ext/runtime/picoclaw/wsClient.mjs +129 -0
  123. package/src-ext/service/serviceManager.mjs +521 -0
  124. package/src-shared/README.md +44 -0
  125. package/src-shared/chat_push_normalizer.mjs +113 -0
  126. package/src-shared/correlation.mjs +25 -0
  127. package/src-shared/envelope_builder.mjs +612 -0
  128. package/src-shared/logger.mjs +167 -0
  129. package/src-shared/relay-defaults.json +3 -0
  130. package/src-shared/relay_revoke.mjs +46 -0
  131. package/src-shared/vendor/README.md +60 -0
  132. package/src-shared/vendor/smol-toml/LICENSE +24 -0
  133. package/src-shared/vendor/smol-toml/README.md +236 -0
  134. package/src-shared/vendor/smol-toml/VENDORED.md +37 -0
  135. package/src-shared/vendor/smol-toml/dist/date.d.ts +41 -0
  136. package/src-shared/vendor/smol-toml/dist/date.js +127 -0
  137. package/src-shared/vendor/smol-toml/dist/error.d.ts +38 -0
  138. package/src-shared/vendor/smol-toml/dist/error.js +63 -0
  139. package/src-shared/vendor/smol-toml/dist/extract.d.ts +30 -0
  140. package/src-shared/vendor/smol-toml/dist/extract.js +109 -0
  141. package/src-shared/vendor/smol-toml/dist/index.cjs +900 -0
  142. package/src-shared/vendor/smol-toml/dist/index.d.ts +43 -0
  143. package/src-shared/vendor/smol-toml/dist/index.js +33 -0
  144. package/src-shared/vendor/smol-toml/dist/parse.d.ts +37 -0
  145. package/src-shared/vendor/smol-toml/dist/parse.js +148 -0
  146. package/src-shared/vendor/smol-toml/dist/primitive.d.ts +31 -0
  147. package/src-shared/vendor/smol-toml/dist/primitive.js +178 -0
  148. package/src-shared/vendor/smol-toml/dist/stringify.d.ts +31 -0
  149. package/src-shared/vendor/smol-toml/dist/stringify.js +163 -0
  150. package/src-shared/vendor/smol-toml/dist/struct.d.ts +32 -0
  151. package/src-shared/vendor/smol-toml/dist/struct.js +194 -0
  152. package/src-shared/vendor/smol-toml/dist/util.d.ts +42 -0
  153. package/src-shared/vendor/smol-toml/dist/util.js +100 -0
  154. package/src-shared/vendor/smol-toml/package.json +54 -0
  155. package/src-shared/vendor/yaml/LICENSE +13 -0
  156. package/src-shared/vendor/yaml/README.md +155 -0
  157. package/src-shared/vendor/yaml/VENDORED.md +29 -0
  158. package/src-shared/vendor/yaml/bin.mjs +11 -0
  159. package/src-shared/vendor/yaml/browser/dist/compose/compose-collection.js +88 -0
  160. package/src-shared/vendor/yaml/browser/dist/compose/compose-doc.js +42 -0
  161. package/src-shared/vendor/yaml/browser/dist/compose/compose-node.js +92 -0
  162. package/src-shared/vendor/yaml/browser/dist/compose/compose-scalar.js +80 -0
  163. package/src-shared/vendor/yaml/browser/dist/compose/composer.js +217 -0
  164. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-map.js +113 -0
  165. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  166. package/src-shared/vendor/yaml/browser/dist/compose/resolve-block-seq.js +47 -0
  167. package/src-shared/vendor/yaml/browser/dist/compose/resolve-end.js +37 -0
  168. package/src-shared/vendor/yaml/browser/dist/compose/resolve-flow-collection.js +203 -0
  169. package/src-shared/vendor/yaml/browser/dist/compose/resolve-flow-scalar.js +223 -0
  170. package/src-shared/vendor/yaml/browser/dist/compose/resolve-props.js +148 -0
  171. package/src-shared/vendor/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  172. package/src-shared/vendor/yaml/browser/dist/compose/util-empty-scalar-position.js +27 -0
  173. package/src-shared/vendor/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  174. package/src-shared/vendor/yaml/browser/dist/compose/util-map-includes.js +17 -0
  175. package/src-shared/vendor/yaml/browser/dist/doc/Document.js +334 -0
  176. package/src-shared/vendor/yaml/browser/dist/doc/anchors.js +72 -0
  177. package/src-shared/vendor/yaml/browser/dist/doc/applyReviver.js +55 -0
  178. package/src-shared/vendor/yaml/browser/dist/doc/createNode.js +89 -0
  179. package/src-shared/vendor/yaml/browser/dist/doc/directives.js +176 -0
  180. package/src-shared/vendor/yaml/browser/dist/errors.js +57 -0
  181. package/src-shared/vendor/yaml/browser/dist/index.js +17 -0
  182. package/src-shared/vendor/yaml/browser/dist/log.js +14 -0
  183. package/src-shared/vendor/yaml/browser/dist/nodes/Alias.js +101 -0
  184. package/src-shared/vendor/yaml/browser/dist/nodes/Collection.js +147 -0
  185. package/src-shared/vendor/yaml/browser/dist/nodes/Node.js +38 -0
  186. package/src-shared/vendor/yaml/browser/dist/nodes/Pair.js +36 -0
  187. package/src-shared/vendor/yaml/browser/dist/nodes/Scalar.js +24 -0
  188. package/src-shared/vendor/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  189. package/src-shared/vendor/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  190. package/src-shared/vendor/yaml/browser/dist/nodes/addPairToJSMap.js +104 -0
  191. package/src-shared/vendor/yaml/browser/dist/nodes/identity.js +36 -0
  192. package/src-shared/vendor/yaml/browser/dist/nodes/toJS.js +37 -0
  193. package/src-shared/vendor/yaml/browser/dist/parse/cst-scalar.js +214 -0
  194. package/src-shared/vendor/yaml/browser/dist/parse/cst-stringify.js +61 -0
  195. package/src-shared/vendor/yaml/browser/dist/parse/cst-visit.js +97 -0
  196. package/src-shared/vendor/yaml/browser/dist/parse/cst.js +98 -0
  197. package/src-shared/vendor/yaml/browser/dist/parse/lexer.js +717 -0
  198. package/src-shared/vendor/yaml/browser/dist/parse/line-counter.js +39 -0
  199. package/src-shared/vendor/yaml/browser/dist/parse/parser.js +954 -0
  200. package/src-shared/vendor/yaml/browser/dist/public-api.js +99 -0
  201. package/src-shared/vendor/yaml/browser/dist/schema/Schema.js +38 -0
  202. package/src-shared/vendor/yaml/browser/dist/schema/common/map.js +17 -0
  203. package/src-shared/vendor/yaml/browser/dist/schema/common/null.js +15 -0
  204. package/src-shared/vendor/yaml/browser/dist/schema/common/seq.js +17 -0
  205. package/src-shared/vendor/yaml/browser/dist/schema/common/string.js +14 -0
  206. package/src-shared/vendor/yaml/browser/dist/schema/core/bool.js +19 -0
  207. package/src-shared/vendor/yaml/browser/dist/schema/core/float.js +43 -0
  208. package/src-shared/vendor/yaml/browser/dist/schema/core/int.js +38 -0
  209. package/src-shared/vendor/yaml/browser/dist/schema/core/schema.js +23 -0
  210. package/src-shared/vendor/yaml/browser/dist/schema/json/schema.js +62 -0
  211. package/src-shared/vendor/yaml/browser/dist/schema/tags.js +83 -0
  212. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/binary.js +66 -0
  213. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  214. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  215. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  216. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  217. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  218. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/schema.js +37 -0
  219. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  220. package/src-shared/vendor/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  221. package/src-shared/vendor/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  222. package/src-shared/vendor/yaml/browser/dist/stringify/stringify.js +124 -0
  223. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyCollection.js +143 -0
  224. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  225. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  226. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyNumber.js +24 -0
  227. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  228. package/src-shared/vendor/yaml/browser/dist/stringify/stringifyString.js +328 -0
  229. package/src-shared/vendor/yaml/browser/dist/util.js +11 -0
  230. package/src-shared/vendor/yaml/browser/dist/visit.js +233 -0
  231. package/src-shared/vendor/yaml/browser/index.js +5 -0
  232. package/src-shared/vendor/yaml/browser/package.json +3 -0
  233. package/src-shared/vendor/yaml/dist/cli.d.ts +8 -0
  234. package/src-shared/vendor/yaml/dist/cli.mjs +199 -0
  235. package/src-shared/vendor/yaml/dist/compose/compose-collection.d.ts +11 -0
  236. package/src-shared/vendor/yaml/dist/compose/compose-collection.js +90 -0
  237. package/src-shared/vendor/yaml/dist/compose/compose-doc.d.ts +7 -0
  238. package/src-shared/vendor/yaml/dist/compose/compose-doc.js +44 -0
  239. package/src-shared/vendor/yaml/dist/compose/compose-node.d.ts +28 -0
  240. package/src-shared/vendor/yaml/dist/compose/compose-node.js +95 -0
  241. package/src-shared/vendor/yaml/dist/compose/compose-scalar.d.ts +5 -0
  242. package/src-shared/vendor/yaml/dist/compose/compose-scalar.js +82 -0
  243. package/src-shared/vendor/yaml/dist/compose/composer.d.ts +62 -0
  244. package/src-shared/vendor/yaml/dist/compose/composer.js +221 -0
  245. package/src-shared/vendor/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  246. package/src-shared/vendor/yaml/dist/compose/resolve-block-map.js +115 -0
  247. package/src-shared/vendor/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  248. package/src-shared/vendor/yaml/dist/compose/resolve-block-scalar.js +200 -0
  249. package/src-shared/vendor/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  250. package/src-shared/vendor/yaml/dist/compose/resolve-block-seq.js +49 -0
  251. package/src-shared/vendor/yaml/dist/compose/resolve-end.d.ts +6 -0
  252. package/src-shared/vendor/yaml/dist/compose/resolve-end.js +39 -0
  253. package/src-shared/vendor/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  254. package/src-shared/vendor/yaml/dist/compose/resolve-flow-collection.js +205 -0
  255. package/src-shared/vendor/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  256. package/src-shared/vendor/yaml/dist/compose/resolve-flow-scalar.js +225 -0
  257. package/src-shared/vendor/yaml/dist/compose/resolve-props.d.ts +23 -0
  258. package/src-shared/vendor/yaml/dist/compose/resolve-props.js +150 -0
  259. package/src-shared/vendor/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  260. package/src-shared/vendor/yaml/dist/compose/util-contains-newline.js +36 -0
  261. package/src-shared/vendor/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  262. package/src-shared/vendor/yaml/dist/compose/util-empty-scalar-position.js +29 -0
  263. package/src-shared/vendor/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  264. package/src-shared/vendor/yaml/dist/compose/util-flow-indent-check.js +17 -0
  265. package/src-shared/vendor/yaml/dist/compose/util-map-includes.d.ts +4 -0
  266. package/src-shared/vendor/yaml/dist/compose/util-map-includes.js +19 -0
  267. package/src-shared/vendor/yaml/dist/doc/Document.d.ts +141 -0
  268. package/src-shared/vendor/yaml/dist/doc/Document.js +336 -0
  269. package/src-shared/vendor/yaml/dist/doc/anchors.d.ts +24 -0
  270. package/src-shared/vendor/yaml/dist/doc/anchors.js +77 -0
  271. package/src-shared/vendor/yaml/dist/doc/applyReviver.d.ts +9 -0
  272. package/src-shared/vendor/yaml/dist/doc/applyReviver.js +57 -0
  273. package/src-shared/vendor/yaml/dist/doc/createNode.d.ts +17 -0
  274. package/src-shared/vendor/yaml/dist/doc/createNode.js +91 -0
  275. package/src-shared/vendor/yaml/dist/doc/directives.d.ts +49 -0
  276. package/src-shared/vendor/yaml/dist/doc/directives.js +178 -0
  277. package/src-shared/vendor/yaml/dist/errors.d.ts +21 -0
  278. package/src-shared/vendor/yaml/dist/errors.js +62 -0
  279. package/src-shared/vendor/yaml/dist/index.d.ts +22 -0
  280. package/src-shared/vendor/yaml/dist/index.js +50 -0
  281. package/src-shared/vendor/yaml/dist/log.d.ts +3 -0
  282. package/src-shared/vendor/yaml/dist/log.js +17 -0
  283. package/src-shared/vendor/yaml/dist/nodes/Alias.d.ts +28 -0
  284. package/src-shared/vendor/yaml/dist/nodes/Alias.js +103 -0
  285. package/src-shared/vendor/yaml/dist/nodes/Collection.d.ts +73 -0
  286. package/src-shared/vendor/yaml/dist/nodes/Collection.js +151 -0
  287. package/src-shared/vendor/yaml/dist/nodes/Node.d.ts +47 -0
  288. package/src-shared/vendor/yaml/dist/nodes/Node.js +40 -0
  289. package/src-shared/vendor/yaml/dist/nodes/Pair.d.ts +21 -0
  290. package/src-shared/vendor/yaml/dist/nodes/Pair.js +39 -0
  291. package/src-shared/vendor/yaml/dist/nodes/Scalar.d.ts +42 -0
  292. package/src-shared/vendor/yaml/dist/nodes/Scalar.js +27 -0
  293. package/src-shared/vendor/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  294. package/src-shared/vendor/yaml/dist/nodes/YAMLMap.js +147 -0
  295. package/src-shared/vendor/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  296. package/src-shared/vendor/yaml/dist/nodes/YAMLSeq.js +115 -0
  297. package/src-shared/vendor/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  298. package/src-shared/vendor/yaml/dist/nodes/addPairToJSMap.js +106 -0
  299. package/src-shared/vendor/yaml/dist/nodes/identity.d.ts +23 -0
  300. package/src-shared/vendor/yaml/dist/nodes/identity.js +53 -0
  301. package/src-shared/vendor/yaml/dist/nodes/toJS.d.ts +27 -0
  302. package/src-shared/vendor/yaml/dist/nodes/toJS.js +39 -0
  303. package/src-shared/vendor/yaml/dist/options.d.ts +338 -0
  304. package/src-shared/vendor/yaml/dist/parse/cst-scalar.d.ts +64 -0
  305. package/src-shared/vendor/yaml/dist/parse/cst-scalar.js +218 -0
  306. package/src-shared/vendor/yaml/dist/parse/cst-stringify.d.ts +8 -0
  307. package/src-shared/vendor/yaml/dist/parse/cst-stringify.js +63 -0
  308. package/src-shared/vendor/yaml/dist/parse/cst-visit.d.ts +39 -0
  309. package/src-shared/vendor/yaml/dist/parse/cst-visit.js +99 -0
  310. package/src-shared/vendor/yaml/dist/parse/cst.d.ts +108 -0
  311. package/src-shared/vendor/yaml/dist/parse/cst.js +112 -0
  312. package/src-shared/vendor/yaml/dist/parse/lexer.d.ts +87 -0
  313. package/src-shared/vendor/yaml/dist/parse/lexer.js +719 -0
  314. package/src-shared/vendor/yaml/dist/parse/line-counter.d.ts +22 -0
  315. package/src-shared/vendor/yaml/dist/parse/line-counter.js +41 -0
  316. package/src-shared/vendor/yaml/dist/parse/parser.d.ts +84 -0
  317. package/src-shared/vendor/yaml/dist/parse/parser.js +958 -0
  318. package/src-shared/vendor/yaml/dist/public-api.d.ts +43 -0
  319. package/src-shared/vendor/yaml/dist/public-api.js +104 -0
  320. package/src-shared/vendor/yaml/dist/schema/Schema.d.ts +18 -0
  321. package/src-shared/vendor/yaml/dist/schema/Schema.js +40 -0
  322. package/src-shared/vendor/yaml/dist/schema/common/map.d.ts +2 -0
  323. package/src-shared/vendor/yaml/dist/schema/common/map.js +19 -0
  324. package/src-shared/vendor/yaml/dist/schema/common/null.d.ts +4 -0
  325. package/src-shared/vendor/yaml/dist/schema/common/null.js +17 -0
  326. package/src-shared/vendor/yaml/dist/schema/common/seq.d.ts +2 -0
  327. package/src-shared/vendor/yaml/dist/schema/common/seq.js +19 -0
  328. package/src-shared/vendor/yaml/dist/schema/common/string.d.ts +2 -0
  329. package/src-shared/vendor/yaml/dist/schema/common/string.js +16 -0
  330. package/src-shared/vendor/yaml/dist/schema/core/bool.d.ts +4 -0
  331. package/src-shared/vendor/yaml/dist/schema/core/bool.js +21 -0
  332. package/src-shared/vendor/yaml/dist/schema/core/float.d.ts +4 -0
  333. package/src-shared/vendor/yaml/dist/schema/core/float.js +47 -0
  334. package/src-shared/vendor/yaml/dist/schema/core/int.d.ts +4 -0
  335. package/src-shared/vendor/yaml/dist/schema/core/int.js +42 -0
  336. package/src-shared/vendor/yaml/dist/schema/core/schema.d.ts +1 -0
  337. package/src-shared/vendor/yaml/dist/schema/core/schema.js +25 -0
  338. package/src-shared/vendor/yaml/dist/schema/json/schema.d.ts +2 -0
  339. package/src-shared/vendor/yaml/dist/schema/json/schema.js +64 -0
  340. package/src-shared/vendor/yaml/dist/schema/json-schema.d.ts +69 -0
  341. package/src-shared/vendor/yaml/dist/schema/tags.d.ts +40 -0
  342. package/src-shared/vendor/yaml/dist/schema/tags.js +86 -0
  343. package/src-shared/vendor/yaml/dist/schema/types.d.ts +90 -0
  344. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  345. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/binary.js +68 -0
  346. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  347. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  348. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  349. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/float.js +50 -0
  350. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  351. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/int.js +76 -0
  352. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/omap.d.ts +28 -0
  353. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  354. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  355. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  356. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  357. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/schema.js +39 -0
  358. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  359. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/set.js +96 -0
  360. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  361. package/src-shared/vendor/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  362. package/src-shared/vendor/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  363. package/src-shared/vendor/yaml/dist/stringify/foldFlowLines.js +151 -0
  364. package/src-shared/vendor/yaml/dist/stringify/stringify.d.ts +21 -0
  365. package/src-shared/vendor/yaml/dist/stringify/stringify.js +127 -0
  366. package/src-shared/vendor/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  367. package/src-shared/vendor/yaml/dist/stringify/stringifyCollection.js +145 -0
  368. package/src-shared/vendor/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  369. package/src-shared/vendor/yaml/dist/stringify/stringifyComment.js +24 -0
  370. package/src-shared/vendor/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  371. package/src-shared/vendor/yaml/dist/stringify/stringifyDocument.js +87 -0
  372. package/src-shared/vendor/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  373. package/src-shared/vendor/yaml/dist/stringify/stringifyNumber.js +26 -0
  374. package/src-shared/vendor/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  375. package/src-shared/vendor/yaml/dist/stringify/stringifyPair.js +152 -0
  376. package/src-shared/vendor/yaml/dist/stringify/stringifyString.d.ts +9 -0
  377. package/src-shared/vendor/yaml/dist/stringify/stringifyString.js +330 -0
  378. package/src-shared/vendor/yaml/dist/test-events.d.ts +4 -0
  379. package/src-shared/vendor/yaml/dist/test-events.js +134 -0
  380. package/src-shared/vendor/yaml/dist/util.d.ts +12 -0
  381. package/src-shared/vendor/yaml/dist/util.js +28 -0
  382. package/src-shared/vendor/yaml/dist/visit.d.ts +102 -0
  383. package/src-shared/vendor/yaml/dist/visit.js +236 -0
  384. package/src-shared/vendor/yaml/package.json +96 -0
  385. package/src-shared/vendor/yaml/util.js +2 -0
@@ -0,0 +1,224 @@
1
+ // 巴布配对流程。
2
+ //
3
+ // 步骤(daemon 主循环未持有 token 时执行):
4
+ //
5
+ // 1. POST <relay>/v1/pair-codes/picoclaw/create
6
+ // Body: { label, ttl_seconds, device_id }
7
+ // Resp: { code, qr_payload, qr_png_base64, fetch_token, expires_at, poll_interval_seconds }
8
+ //
9
+ // 2. 把 qr_png_base64 解码写到 QR_PNG_OUTPUT_PATH(通常 /tmp/bubu/pair-qr.png)。
10
+ // 巴布开发板的屏幕显示模块独立读取这个文件,在屏幕上展示 QR。
11
+ //
12
+ // 3. 每 poll_interval_seconds 调一次:
13
+ // GET <relay>/v1/pair-codes/picoclaw/<code>/status
14
+ // Header: X-Pair-Fetch-Token: <fetch_token>
15
+ // Resp:
16
+ // { state: "pending", expires_at }
17
+ // { state: "consumed", gw_id, bridge_token, client_user_id, runtime, label }
18
+ // { state: "expired" }
19
+ //
20
+ // 4. consumed 命中 → 返回 {gw_id, bridge_token, client_user_id, label, relay_url}
21
+ // expired → 抛错,主循环重新走步骤 1
22
+ // poll 超时 → 抛错,主循环重新走步骤 1
23
+ //
24
+ // 全程不需要用户在 cli 上输入任何东西;所有信息走二维码 ↔ App。
25
+
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ import process from "node:process";
29
+
30
+ import {
31
+ PAIR_STATUS_POLL_INTERVAL_SEC,
32
+ PAIR_STATUS_POLL_MAX_SEC,
33
+ QR_PNG_OUTPUT_PATH,
34
+ RUNTIME_NAME,
35
+ } from "./constants.mjs";
36
+
37
+ const PAIR_LABEL_DEFAULT = "我的巴布";
38
+
39
+ /**
40
+ * 调 server 创建一个 picoclaw pair-code。
41
+ * @returns {Promise<{code, qr_payload, qr_png_base64, fetch_token, expires_at, poll_interval_seconds}>}
42
+ */
43
+ export async function createPairCode({ relayUrl, label, deviceId, ttlSeconds, fetchImpl, log }) {
44
+ const f = fetchImpl || globalThis.fetch;
45
+ const url = `${trimRight(relayUrl)}/v1/pair-codes/picoclaw/create`;
46
+ const body = {
47
+ label: label || PAIR_LABEL_DEFAULT,
48
+ device_id: deviceId || "",
49
+ ttl_seconds: ttlSeconds > 0 ? ttlSeconds : undefined,
50
+ };
51
+ const res = await f(url, {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/json" },
54
+ body: JSON.stringify(body),
55
+ });
56
+ if (!res.ok) {
57
+ const text = await safeText(res);
58
+ throw new Error(`picoclaw pair-code create failed: HTTP ${res.status} ${text}`);
59
+ }
60
+ const j = await res.json();
61
+ if (!j || j.status !== "ok" || !j.code || !j.fetch_token || !j.qr_png_base64) {
62
+ throw new Error(`picoclaw pair-code create: malformed response ${JSON.stringify(j).slice(0, 200)}`);
63
+ }
64
+ if (log) {
65
+ log.info("picoclaw.pair.created", "pair-code created", {
66
+ code: j.code, expires_at: j.expires_at,
67
+ });
68
+ }
69
+ return j;
70
+ }
71
+
72
+ /**
73
+ * 把 base64 PNG 写到约定路径,屏幕模块读取。
74
+ */
75
+ export function writeQRImage(b64, outputPath) {
76
+ const target = outputPath || QR_PNG_OUTPUT_PATH;
77
+ const dir = path.dirname(target);
78
+ try {
79
+ fs.mkdirSync(dir, { recursive: true });
80
+ } catch {}
81
+ const buf = Buffer.from(b64, "base64");
82
+ fs.writeFileSync(target, buf);
83
+ return target;
84
+ }
85
+
86
+ /**
87
+ * 删除 QR 图片(配对成功后清理)。
88
+ */
89
+ export function clearQRImage(outputPath) {
90
+ const target = outputPath || QR_PNG_OUTPUT_PATH;
91
+ try {
92
+ fs.unlinkSync(target);
93
+ } catch {}
94
+ }
95
+
96
+ /**
97
+ * dev 测试钩子:把 code + fetch_token + relay 等关键信息以 plain JSON 写到本地,
98
+ * 让端到端测试脚本能扮演 App 角色拿到 code 调 consume。
99
+ *
100
+ * 仅当环境变量 `BUBU_DEV_DUMP_PAIR_INFO=1` 时才写。
101
+ * **生产环境严禁开启** —— fetch_token 落地会被任何能读这台机器文件的进程拿走。
102
+ *
103
+ * 输出路径默认 /tmp/bubu/pair-info.json,可由 `BUBU_DEV_PAIR_INFO_PATH` 覆盖。
104
+ */
105
+ export function writeDevPairInfo(info) {
106
+ if (process.env.BUBU_DEV_DUMP_PAIR_INFO !== "1") return null;
107
+ const target =
108
+ process.env.BUBU_DEV_PAIR_INFO_PATH?.trim() || "/tmp/bubu/pair-info.json";
109
+ const dir = path.dirname(target);
110
+ try {
111
+ fs.mkdirSync(dir, { recursive: true });
112
+ } catch {}
113
+ const obj = {
114
+ code: info.code,
115
+ fetch_token: info.fetch_token,
116
+ relay: info.relay,
117
+ label: info.label || "",
118
+ expires_at: info.expires_at || "",
119
+ // qr_payload 是完整 deeplink(agentlink://pair/picoclaw?...),直接粘到
120
+ // App 输入框就能完成绑定,省去自己拼 URL 的麻烦。
121
+ qr_payload: info.qr_payload || "",
122
+ written_at: new Date().toISOString(),
123
+ warning: "BUBU_DEV_DUMP_PAIR_INFO=1; do NOT enable in production.",
124
+ };
125
+ try {
126
+ fs.writeFileSync(target, JSON.stringify(obj, null, 2) + "\n", "utf8");
127
+ return target;
128
+ } catch {
129
+ return null;
130
+ }
131
+ }
132
+
133
+ /**
134
+ * 删除 dev pair-info(配对成功后清理 fetch_token 落地文件)。
135
+ */
136
+ export function clearDevPairInfo() {
137
+ if (process.env.BUBU_DEV_DUMP_PAIR_INFO !== "1") return;
138
+ const target =
139
+ process.env.BUBU_DEV_PAIR_INFO_PATH?.trim() || "/tmp/bubu/pair-info.json";
140
+ try {
141
+ fs.unlinkSync(target);
142
+ } catch {}
143
+ }
144
+
145
+ /**
146
+ * 轮询 status 端点直到 consumed 或 expired。
147
+ * @returns {Promise<{gw_id, bridge_token, client_user_id, runtime, label}>} consumed payload
148
+ */
149
+ export async function pollPairStatus({ relayUrl, code, fetchToken, intervalSec, maxSec, fetchImpl, log, signal }) {
150
+ const f = fetchImpl || globalThis.fetch;
151
+ const interval = (intervalSec > 0 ? intervalSec : PAIR_STATUS_POLL_INTERVAL_SEC) * 1000;
152
+ const maxMs = (maxSec > 0 ? maxSec : PAIR_STATUS_POLL_MAX_SEC) * 1000;
153
+ const startedAt = Date.now();
154
+ const url = `${trimRight(relayUrl)}/v1/pair-codes/picoclaw/${encodeURIComponent(code)}/status`;
155
+ for (;;) {
156
+ if (signal?.aborted) {
157
+ throw new Error("picoclaw pair poll aborted");
158
+ }
159
+ let res;
160
+ try {
161
+ res = await f(url, {
162
+ method: "GET",
163
+ headers: { "X-Pair-Fetch-Token": fetchToken },
164
+ });
165
+ } catch (err) {
166
+ // 网络抖动 — 等下次重试,日志一下
167
+ if (log) log.warn("picoclaw.pair.poll.err", "status poll error", { err: String(err?.message || err) });
168
+ await sleep(interval);
169
+ continue;
170
+ }
171
+ if (res.status === 401) {
172
+ throw new Error("picoclaw pair status: fetch_token rejected (401)");
173
+ }
174
+ if (!res.ok) {
175
+ const text = await safeText(res);
176
+ if (log) log.warn("picoclaw.pair.poll.bad", "non-ok status", { status: res.status, text });
177
+ await sleep(interval);
178
+ continue;
179
+ }
180
+ const j = await res.json().catch(() => null);
181
+ if (!j || typeof j.state !== "string") {
182
+ await sleep(interval);
183
+ continue;
184
+ }
185
+ if (j.state === "consumed") {
186
+ if (!j.bridge_token || !j.gw_id) {
187
+ throw new Error("picoclaw pair status: consumed but missing bridge_token/gw_id");
188
+ }
189
+ return {
190
+ gw_id: j.gw_id,
191
+ bridge_token: j.bridge_token,
192
+ client_user_id: j.client_user_id || "",
193
+ runtime: j.runtime || RUNTIME_NAME,
194
+ label: j.label || "",
195
+ };
196
+ }
197
+ if (j.state === "expired") {
198
+ throw new Error("picoclaw pair-code expired before consume");
199
+ }
200
+ // pending
201
+ if (Date.now() - startedAt >= maxMs) {
202
+ throw new Error("picoclaw pair-code poll timeout");
203
+ }
204
+ await sleep(interval);
205
+ }
206
+ }
207
+
208
+ // ── helpers ──────────────────────────────────────────────────────
209
+
210
+ function trimRight(s) {
211
+ return String(s || "").replace(/\/+$/, "");
212
+ }
213
+
214
+ function sleep(ms) {
215
+ return new Promise((r) => setTimeout(r, ms));
216
+ }
217
+
218
+ async function safeText(res) {
219
+ try {
220
+ return await res.text();
221
+ } catch {
222
+ return "";
223
+ }
224
+ }
@@ -0,0 +1,78 @@
1
+ // 巴布(PicoClaw)本地配对状态持久化。
2
+ //
3
+ // 文件: ~/.agentlink/picoclaw-state.json
4
+ //
5
+ // 内容:
6
+ // {
7
+ // gw_id, bridge_token, relay_url, client_user_id, label, runtime: "picoclaw",
8
+ // saved_at: <ISO timestamp>
9
+ // }
10
+ //
11
+ // 缺/损坏时返回 null,daemon 主循环会触发新一轮 pair-code create + QR 显示。
12
+
13
+ import fs from "node:fs";
14
+ import os from "node:os";
15
+ import path from "node:path";
16
+
17
+ const STATE_DIR = path.join(os.homedir(), ".agentlink");
18
+ const STATE_FILE = path.join(STATE_DIR, "picoclaw-state.json");
19
+
20
+ function ensureDir() {
21
+ try {
22
+ fs.mkdirSync(STATE_DIR, { recursive: true });
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ export function readState() {
30
+ try {
31
+ const raw = fs.readFileSync(STATE_FILE, "utf8");
32
+ const obj = JSON.parse(raw);
33
+ if (!obj || typeof obj !== "object") return null;
34
+ if (obj.runtime !== "picoclaw") return null;
35
+ const gwId = String(obj.gw_id || "").trim();
36
+ const relayUrl = String(obj.relay_url || "").trim();
37
+ const bridgeToken = String(obj.bridge_token || "").trim();
38
+ if (!gwId || !relayUrl || !bridgeToken) return null;
39
+ return {
40
+ gw_id: gwId,
41
+ bridge_token: bridgeToken,
42
+ relay_url: relayUrl,
43
+ client_user_id: String(obj.client_user_id || "").trim(),
44
+ label: String(obj.label || "").trim(),
45
+ saved_at: obj.saved_at || null,
46
+ };
47
+ } catch {
48
+ return null;
49
+ }
50
+ }
51
+
52
+ export function writeState(state) {
53
+ if (!ensureDir()) return false;
54
+ const obj = {
55
+ runtime: "picoclaw",
56
+ gw_id: state.gw_id,
57
+ bridge_token: state.bridge_token,
58
+ relay_url: state.relay_url,
59
+ client_user_id: state.client_user_id || "",
60
+ label: state.label || "",
61
+ saved_at: new Date().toISOString(),
62
+ };
63
+ try {
64
+ fs.writeFileSync(STATE_FILE, JSON.stringify(obj, null, 2) + "\n", "utf8");
65
+ return true;
66
+ } catch {
67
+ return false;
68
+ }
69
+ }
70
+
71
+ export function clearState() {
72
+ try {
73
+ fs.unlinkSync(STATE_FILE);
74
+ return true;
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * todoTranslator.mjs — picoclaw runtime update_plan → todo_list block translator
3
+ *
4
+ * 按 translator-spec.md 和 npm-cli-todo-translator-picoclaw spec 实现:
5
+ * - 识别 PicoMessage type==="message.update" && payload.kind==="tool_calls"
6
+ * - 检查 tool_calls 中是否含 update_plan
7
+ * - 若含:转写为 content_block.started + content_block.completed,拦截不透传
8
+ * - 否则:原样透传(返回 [msg])
9
+ */
10
+
11
+ import {
12
+ buildBlockStarted,
13
+ buildBlockCompleted,
14
+ newBlockId,
15
+ } from "../../../src-shared/envelope_builder.mjs";
16
+ import { buildTodoItems } from "../_shared/todoTranslatorUtils.mjs";
17
+
18
+ /**
19
+ * 创建 picoclaw update_plan translator 实例。
20
+ *
21
+ * @param {string} runId 当前 run 的 run_id,用于构造 envelope
22
+ * @returns {{ intercept(msg: object): object[] }}
23
+ */
24
+ export function createPicoTodoTranslator(runId) {
25
+ return {
26
+ /**
27
+ * @param {object} msg PicoMessage({ type, id, session_id, payload })
28
+ * @returns {object[]} 2 个 envelope(update_plan)或 [msg](透传)
29
+ */
30
+ intercept(msg) {
31
+ if (!msg || typeof msg !== "object") return [msg];
32
+
33
+ // 只处理 message.update(kind=tool_calls)
34
+ if (msg.type !== "message.update") return [msg];
35
+ const payload = msg.payload;
36
+ if (!payload || payload.kind !== "tool_calls") return [msg];
37
+
38
+ // 从 tool_calls 数组中找 update_plan
39
+ const toolCalls = Array.isArray(payload.tool_calls)
40
+ ? payload.tool_calls
41
+ : (Array.isArray(payload.content) ? payload.content : []);
42
+ const updatePlanCall = toolCalls.find(
43
+ (tc) => tc && typeof tc === "object" && tc.name === "update_plan",
44
+ );
45
+ if (!updatePlanCall) return [msg];
46
+
47
+ // 解析 arguments
48
+ let args = {};
49
+ if (updatePlanCall.arguments) {
50
+ try {
51
+ args = JSON.parse(String(updatePlanCall.arguments));
52
+ } catch { /* 保持空对象 */ }
53
+ }
54
+
55
+ // plan 数组映射为 TodoItem[](explanation 忽略)
56
+ const rawPlan = Array.isArray(args.plan) ? args.plan : [];
57
+ const items = buildTodoItems(rawPlan);
58
+ const blockId = newBlockId();
59
+ const block = { id: blockId, type: "todo_list", items };
60
+
61
+ return [
62
+ buildBlockStarted(runId, block),
63
+ buildBlockCompleted(runId, { ...block }),
64
+ ];
65
+ },
66
+ };
67
+ }
@@ -0,0 +1,272 @@
1
+ // Pico Protocol ↔ OpenAI Responses API 风格 native event 翻译器。
2
+ //
3
+ // CLI 把巴布(PicoClaw)WebSocket 上的 PicoMessage 翻译成服务端
4
+ // `internal/adapter/picoclaw` 期望的 native event 流(与 openclaw 共享 mapper)。
5
+ //
6
+ // PicoMessage 格式:
7
+ // { type, id, session_id, timestamp, payload }
8
+ //
9
+ // CLI 出参格式(与 openclaw bridge 现有产物对齐):
10
+ // { event: "start" }
11
+ // { event: "chunk", data: JSON.stringify({ type: "response.output_text.delta", delta: "..." }) }
12
+ // { event: "chunk", data: JSON.stringify({ type: "response.reasoning_summary_text.delta", delta: "..." }) }
13
+ // { event: "chunk", data: JSON.stringify({ type: "response.function_call_arguments.delta", call_id, name, arguments }) }
14
+ // { event: "chunk", data: JSON.stringify({ type: "response.output_text.done", text: "<full>" }) }
15
+ // { event: "end" }
16
+ // { event: "error", error: "msg" }
17
+ //
18
+ // **Pico → OpenClaw 映射表**:
19
+ //
20
+ // | Pico (server→client) | OpenClaw native (CLI emits) |
21
+ // |----------------------|------------------------------|
22
+ // | message.create | { event: "start" }(每个 turn 起头一次)|
23
+ // | message.update (default kind, payload.content) | response.output_text.delta(算 delta) |
24
+ // | message.update (kind=thought) | response.reasoning_summary_text.delta |
25
+ // | message.update (kind=tool_calls) | response.function_call_arguments.delta(简化:把 tool_calls JSON 序列化进 arguments) |
26
+ // | typing.stop / 最后一条 update | response.output_text.done + { event: "end" } |
27
+ // | media.create | 一期降级:转成 response.output_text.delta 加占位文本(支持 base64/url 二期) |
28
+ // | error | { event: "error", error: msg } + { event: "end" } |
29
+ // | pong | drop |
30
+ //
31
+ // **Delta 计算**: PicoClaw 的 message.update 通常发"累积全文",CLI 通过比对
32
+ // 内部 lastText 字段算出 delta 增量再发。如果服务端遇到回退场景(content
33
+ // 比上次短),按"重置 + 全量重发"处理(不应发生,但写防御代码)。
34
+
35
+ const KIND_THOUGHT = "thought";
36
+ const KIND_TOOL_CALLS = "tool_calls";
37
+
38
+ // 单条 turn 的累积状态。每个 turn 一个,`reset()` 后复用。
39
+ export function createTurnState() {
40
+ return {
41
+ started: false,
42
+ finalized: false,
43
+ // 主回复正文的累积值
44
+ textAccum: "",
45
+ // 思考链的累积值
46
+ thoughtAccum: "",
47
+ // tool_calls 列表的累积 JSON(上次发送的)
48
+ toolCallsAccum: "",
49
+ // 上次响应的 PicoClaw message_id
50
+ lastMessageID: "",
51
+ };
52
+ }
53
+
54
+ /**
55
+ * 翻译一条 PicoMessage 为 0..N 个 native event。
56
+ *
57
+ * @param {object} msg PicoMessage `{ type, id, session_id, timestamp, payload }`
58
+ * @param {object} state createTurnState() 返回的状态
59
+ * @returns {Array<{event:string, data?:string, error?:string}>} native events
60
+ */
61
+ export function translatePicoMessage(msg, state) {
62
+ if (!msg || typeof msg !== "object") return [];
63
+ // Bug 4 防御:turn 已 finalized 后再来 update/media 等都直接丢弃,避免发出
64
+ // 服务端 run 已 completed 之后的 delta 导致状态机错位。pong/error 仍处理
65
+ // (error 即使在 finalize 后也要透传)。
66
+ if (state.finalized && msg.type !== "error" && msg.type !== "pong") {
67
+ return [];
68
+ }
69
+ const out = [];
70
+ switch (msg.type) {
71
+ case "message.create": {
72
+ // 一个 turn 的起始 — 服务端 openclaw mapper 期望 "start"。
73
+ if (!state.started) {
74
+ state.started = true;
75
+ out.push({ event: "start" });
76
+ }
77
+ // payload.content 可能携带初始文本,按 update 处理一次。
78
+ const content = readContent(msg);
79
+ if (content) {
80
+ emitDeltaForKind(out, state, msg, content);
81
+ }
82
+ return out;
83
+ }
84
+ case "message.update": {
85
+ if (!state.started) {
86
+ state.started = true;
87
+ out.push({ event: "start" });
88
+ }
89
+ const content = readContent(msg);
90
+ if (content !== null && content !== undefined) {
91
+ emitDeltaForKind(out, state, msg, content);
92
+ }
93
+ return out;
94
+ }
95
+ case "media.create": {
96
+ // 一期:把 media 描述 inline 成正文占位文字,告诉用户"这里有一张图"。
97
+ // 二期会接 /pico/media/<id> 下载 + 转 base64 + response.output_text.delta with image。
98
+ if (!state.started) {
99
+ state.started = true;
100
+ out.push({ event: "start" });
101
+ }
102
+ const placeholder = describeMedia(msg);
103
+ if (placeholder) {
104
+ appendDelta(out, state, "text", placeholder);
105
+ }
106
+ return out;
107
+ }
108
+ case "typing.stop": {
109
+ // 流结束信号 — 收到后 finalize。
110
+ finalizeTurn(out, state);
111
+ return out;
112
+ }
113
+ case "error": {
114
+ const errMsg = (msg.payload && (msg.payload.message || msg.payload.error)) || "picoclaw error";
115
+ out.push({ event: "error", error: String(errMsg) });
116
+ // error 后强制 end,避免服务端 adapter 觉得 turn 悬空
117
+ if (!state.finalized) {
118
+ state.finalized = true;
119
+ out.push({ event: "end" });
120
+ }
121
+ return out;
122
+ }
123
+ case "typing.start":
124
+ case "pong":
125
+ return [];
126
+ default:
127
+ // 未识别消息类型 — 一期忽略,日志侧记录(translator 不持有 logger;调用方记)。
128
+ return [];
129
+ }
130
+ }
131
+
132
+ /**
133
+ * 在调用方决定 turn 已结束时(比如 WS 端关闭、超时、显式 typing.stop 都没拿到),
134
+ * 强制 finalize。幂等。
135
+ */
136
+ export function forceFinalize(state) {
137
+ const out = [];
138
+ finalizeTurn(out, state);
139
+ return out;
140
+ }
141
+
142
+ // ── internal ────────────────────────────────────────────────────
143
+
144
+ function emitDeltaForKind(out, state, msg, content) {
145
+ const kind = readKind(msg);
146
+ if (kind === KIND_THOUGHT) {
147
+ appendDelta(out, state, "thought", content);
148
+ return;
149
+ }
150
+ if (kind === KIND_TOOL_CALLS) {
151
+ // tool_calls 的 content 期望是 JSON(数组或对象);序列化成 arguments string。
152
+ const argsJSON = typeof content === "string" ? content : safeJSON(content);
153
+ if (argsJSON !== state.toolCallsAccum) {
154
+ state.toolCallsAccum = argsJSON;
155
+ out.push({
156
+ event: "chunk",
157
+ data: JSON.stringify({
158
+ type: "response.function_call_arguments.delta",
159
+ call_id: String(msg.id || msg.session_id || ""),
160
+ name: pickToolName(msg) || "tool_call",
161
+ arguments: argsJSON,
162
+ }),
163
+ });
164
+ }
165
+ return;
166
+ }
167
+ // 默认:正文 delta
168
+ appendDelta(out, state, "text", content);
169
+ }
170
+
171
+ function appendDelta(out, state, kind, content) {
172
+ const text = typeof content === "string" ? content : String(content);
173
+ let delta;
174
+ if (kind === "text") {
175
+ delta = computeDelta(state.textAccum, text);
176
+ if (delta == null) return;
177
+ state.textAccum = text;
178
+ out.push({
179
+ event: "chunk",
180
+ data: JSON.stringify({
181
+ type: "response.output_text.delta",
182
+ delta,
183
+ }),
184
+ });
185
+ } else if (kind === "thought") {
186
+ delta = computeDelta(state.thoughtAccum, text);
187
+ if (delta == null) return;
188
+ state.thoughtAccum = text;
189
+ out.push({
190
+ event: "chunk",
191
+ data: JSON.stringify({
192
+ type: "response.reasoning_summary_text.delta",
193
+ delta,
194
+ }),
195
+ });
196
+ }
197
+ }
198
+
199
+ // computeDelta: 优先按"累积全文"模型计算增量;若新文本比旧短(异常 reset),
200
+ // 把 prev 当空,delta = full new。返回 null 表示没增量(同文本)。
201
+ function computeDelta(prev, next) {
202
+ if (next === prev) return null;
203
+ if (next.startsWith(prev)) return next.slice(prev.length);
204
+ // 回退/重置 — 直接整段重发
205
+ return next;
206
+ }
207
+
208
+ function finalizeTurn(out, state) {
209
+ if (state.finalized) return;
210
+ state.finalized = true;
211
+ if (state.started && state.textAccum) {
212
+ out.push({
213
+ event: "chunk",
214
+ data: JSON.stringify({
215
+ type: "response.output_text.done",
216
+ text: state.textAccum,
217
+ }),
218
+ });
219
+ }
220
+ if (state.started) {
221
+ out.push({ event: "end" });
222
+ }
223
+ }
224
+
225
+ function readContent(msg) {
226
+ if (!msg || typeof msg.payload !== "object" || msg.payload === null) return null;
227
+ const c = msg.payload.content;
228
+ if (c === undefined || c === null) return null;
229
+ if (typeof c === "string") return c;
230
+ return c; // 留给 emitDeltaForKind 决定如何处理(tool_calls 用 JSON)
231
+ }
232
+
233
+ function readKind(msg) {
234
+ if (!msg || typeof msg.payload !== "object" || msg.payload === null) return "";
235
+ const k = msg.payload.kind;
236
+ if (typeof k === "string") return k.trim().toLowerCase();
237
+ // legacy: payload.thought=true
238
+ if (msg.payload.thought === true) return KIND_THOUGHT;
239
+ return "";
240
+ }
241
+
242
+ function pickToolName(msg) {
243
+ if (!msg || typeof msg.payload !== "object" || msg.payload === null) return "";
244
+ if (Array.isArray(msg.payload.tool_calls) && msg.payload.tool_calls[0]) {
245
+ const t = msg.payload.tool_calls[0];
246
+ if (t && typeof t === "object") {
247
+ if (typeof t.name === "string") return t.name;
248
+ if (t.function && typeof t.function.name === "string") return t.function.name;
249
+ }
250
+ }
251
+ return "";
252
+ }
253
+
254
+ function describeMedia(msg) {
255
+ if (!msg || typeof msg.payload !== "object" || msg.payload === null) return "";
256
+ const p = msg.payload;
257
+ if (typeof p.url === "string" && p.url.length > 0) {
258
+ return `\n[media: ${p.url}]\n`;
259
+ }
260
+ if (typeof p.id === "string" && p.id.length > 0) {
261
+ return `\n[media:${p.id}]\n`;
262
+ }
263
+ return "\n[media]\n";
264
+ }
265
+
266
+ function safeJSON(v) {
267
+ try {
268
+ return JSON.stringify(v);
269
+ } catch {
270
+ return "";
271
+ }
272
+ }