@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,301 @@
1
+ // tunnel.mjs 拆分:配置/状态/路径/日志/HTTP 工具。
2
+ // 不包含任何业务逻辑(代理 / 长轮询 / 心跳),只是基础设施。
3
+ //
4
+ // 这层做三件事:
5
+ // 1. ~/.agentlink/tunnels/{port}.json 状态文件读写
6
+ // 2. tunnel-agent 的统一日志格式 (key=value)
7
+ // 3. fetchJson / fetchWithTimeout / withServerToken / extractJsonError 等 HTTP helper
8
+
9
+ import fs from "node:fs";
10
+ import os from "node:os";
11
+ import path from "node:path";
12
+ import process from "node:process";
13
+
14
+ import { normalizeBaseUrl, trimSlash } from "./core.mjs";
15
+
16
+ export const DEFAULT_POLL_WAIT_SECONDS = 20;
17
+ export const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
18
+ export const DEFAULT_HEARTBEAT_INTERVAL_MS = 10000;
19
+ export const DEFAULT_HEARTBEAT_TIMEOUT_MS = 10000;
20
+ export const DEFAULT_STREAM_WAIT_TIMEOUT_MS = 30000;
21
+ export const LOCAL_TARGET_HOST = "127.0.0.1";
22
+ export const TUNNEL_IDLE_LOG_EVERY = 6;
23
+ export const TUNNEL_HEARTBEAT_ERROR_LOG_EVERY = 3;
24
+ export const TUNNEL_STREAM_IDLE_LOG_EVERY = 4;
25
+ export const TUNNEL_PROTOCOL_HTTP = "http";
26
+ export const TUNNEL_PROTOCOL_WS = "ws";
27
+ export const TUNNEL_PROTOCOL_TCP = "tcp";
28
+
29
+ // ---- relay url / protocol / port 解析 ----
30
+
31
+ export function resolveRelayUrl(override, fallback, fail) {
32
+ const resolved = resolveRelayOverride(override, fallback);
33
+ if (!resolved) {
34
+ fail("relay URL is required");
35
+ }
36
+ return resolved;
37
+ }
38
+
39
+ export function normalizeTunnelProtocol(raw, fail, allowEmpty = false) {
40
+ const value = String(raw ?? "").trim().toLowerCase();
41
+ if (!value) {
42
+ return allowEmpty ? "" : TUNNEL_PROTOCOL_HTTP;
43
+ }
44
+ if (value === TUNNEL_PROTOCOL_HTTP || value === TUNNEL_PROTOCOL_WS || value === TUNNEL_PROTOCOL_TCP) {
45
+ return value;
46
+ }
47
+ fail(`invalid tunnel protocol: ${value}`);
48
+ }
49
+
50
+ export function buildTunnelTargetBaseUrl(protocol, port) {
51
+ switch (protocol) {
52
+ case TUNNEL_PROTOCOL_WS:
53
+ return `ws://${LOCAL_TARGET_HOST}:${port}`;
54
+ case TUNNEL_PROTOCOL_TCP:
55
+ return `${LOCAL_TARGET_HOST}:${port}`;
56
+ default:
57
+ return `http://${LOCAL_TARGET_HOST}:${port}`;
58
+ }
59
+ }
60
+
61
+ export function resolveRelayOverride(override, fallback) {
62
+ return (
63
+ normalizeBaseUrl(override) ||
64
+ normalizeBaseUrl(process.env.AGENTLINK_RELAY_URL) ||
65
+ normalizeBaseUrl(process.env.TESTNEXTIM_RELAY_URL) ||
66
+ normalizeBaseUrl(fallback)
67
+ );
68
+ }
69
+
70
+ export function parsePort(raw, fail) {
71
+ const text = String(raw ?? "").trim();
72
+ const parsed = Number.parseInt(text, 10);
73
+ if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 65535) {
74
+ fail(`invalid port: ${text || "(empty)"}`);
75
+ }
76
+ return parsed;
77
+ }
78
+
79
+ // ---- HTTP helpers ----
80
+
81
+ export function fetchJson(url, options = {}, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) {
82
+ const headers = new Headers(options.headers ?? {});
83
+ if (options.body != null && !headers.has("content-type")) {
84
+ headers.set("content-type", "application/json");
85
+ }
86
+ return fetchWithTimeout(url, { ...options, headers }, timeoutMs).then(async (response) => {
87
+ const text = await response.text();
88
+ let body = null;
89
+ if (text) {
90
+ try { body = JSON.parse(text); }
91
+ catch { body = { error: text }; }
92
+ }
93
+ return { ok: response.ok, status: response.status, body };
94
+ });
95
+ }
96
+
97
+ export function fetchWithTimeout(url, options = {}, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) {
98
+ const controller = new AbortController();
99
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
100
+ return fetch(url, { ...options, signal: controller.signal }).finally(() => clearTimeout(timeout));
101
+ }
102
+
103
+ export function extractJsonError(body, fallback) {
104
+ if (body && typeof body === "object") {
105
+ if (typeof body.error === "string" && body.error.trim()) return body.error.trim();
106
+ if (typeof body.message === "string" && body.message.trim()) return body.message.trim();
107
+ }
108
+ return fallback;
109
+ }
110
+
111
+ export function withServerToken(token) {
112
+ if (!token) return { "content-type": "application/json" };
113
+ return {
114
+ "content-type": "application/json",
115
+ Authorization: `Bearer ${token}`,
116
+ };
117
+ }
118
+
119
+ // ---- ~/.agentlink/tunnels 状态文件 ----
120
+
121
+ export function ensureTunnelStateDir() {
122
+ fs.mkdirSync(tunnelStateDir(), { recursive: true });
123
+ }
124
+
125
+ export function tunnelStateDir() {
126
+ return path.join(resolveAgentlinkHome(), "tunnels");
127
+ }
128
+
129
+ export function ensureTunnelLogsDir() {
130
+ fs.mkdirSync(resolveTunnelLogsDir(), { recursive: true });
131
+ }
132
+
133
+ export function resolveTunnelLogsDir() {
134
+ return path.join(resolveAgentlinkHome(), "logs");
135
+ }
136
+
137
+ export function resolveTunnelLogPath(port) {
138
+ return path.join(resolveTunnelLogsDir(), `tunnel-${port}.log`);
139
+ }
140
+
141
+ export function tunnelStatePath(port) {
142
+ return path.join(tunnelStateDir(), `${port}.json`);
143
+ }
144
+
145
+ export function resolveAgentlinkHome() {
146
+ const fromEnv = String(process.env.AGENTLINK_HOME ?? "").trim();
147
+ if (fromEnv) return fromEnv;
148
+ const home = String(process.env.HOME ?? process.env.USERPROFILE ?? "").trim() || os.homedir();
149
+ if (!home || home === "/") {
150
+ if (process.platform === "win32") {
151
+ const appData = String(process.env.APPDATA ?? "").trim();
152
+ if (appData) return path.join(appData, ".agentlink");
153
+ const userProfile = String(process.env.USERPROFILE ?? "").trim();
154
+ if (userProfile) return path.join(userProfile, ".agentlink");
155
+ }
156
+ let username = "";
157
+ try { username = os.userInfo().username || ""; } catch { username = ""; }
158
+ if (username) {
159
+ const bases = username === "root" ? ["/root"] : ["/home", "/Users"];
160
+ for (const base of bases) {
161
+ const candidate = username === "root"
162
+ ? path.join(base, ".agentlink")
163
+ : path.join(base, username, ".agentlink");
164
+ if (fs.existsSync(candidate)) return candidate;
165
+ }
166
+ if (username === "root") return "/root/.agentlink";
167
+ if (process.platform === "darwin") return path.join("/Users", username, ".agentlink");
168
+ return path.join("/home", username, ".agentlink");
169
+ }
170
+ }
171
+ return path.join(home, ".agentlink");
172
+ }
173
+
174
+ export function readTunnelState(filePath) {
175
+ try { return JSON.parse(fs.readFileSync(filePath, "utf8")); }
176
+ catch { return null; }
177
+ }
178
+
179
+ export function writeTunnelState(filePath, state) {
180
+ fs.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}\n`);
181
+ }
182
+
183
+ export function safeUnlink(filePath) {
184
+ try { fs.unlinkSync(filePath); } catch { /* noop */ }
185
+ }
186
+
187
+ export function safeReaddir(dirPath) {
188
+ try { return fs.readdirSync(dirPath); }
189
+ catch { return []; }
190
+ }
191
+
192
+ export function isPidAlive(pid) {
193
+ if (!pid || !Number.isInteger(pid)) return false;
194
+ try { process.kill(pid, 0); return true; }
195
+ catch { return false; }
196
+ }
197
+
198
+ export function safeKill(pid) {
199
+ try { process.kill(pid, "SIGTERM"); } catch { /* noop */ }
200
+ }
201
+
202
+ // ---- HTTP / proxy 通用 ----
203
+
204
+ export function isHopByHopHeader(name) {
205
+ switch (String(name ?? "").trim().toLowerCase()) {
206
+ case "connection":
207
+ case "keep-alive":
208
+ case "proxy-authenticate":
209
+ case "proxy-authorization":
210
+ case "te":
211
+ case "trailer":
212
+ case "transfer-encoding":
213
+ case "upgrade":
214
+ case "content-length":
215
+ return true;
216
+ default:
217
+ return false;
218
+ }
219
+ }
220
+
221
+ export function joinTunnelTargetUrl(baseUrl, requestPath, rawQuery) {
222
+ const pathName = typeof requestPath === "string" && requestPath.trim() ? requestPath : "/";
223
+ const url = new URL(trimSlash(baseUrl) + pathName);
224
+ if (typeof rawQuery === "string" && rawQuery) url.search = rawQuery;
225
+ return url.toString();
226
+ }
227
+
228
+ export function parseTunnelTCPAddress(value) {
229
+ const raw = String(value ?? "").trim();
230
+ const match = raw.match(/^(.+):(\d{1,5})$/u);
231
+ if (!match) throw new Error(`invalid tcp target address: ${raw}`);
232
+ return { host: match[1], port: Number.parseInt(match[2], 10) };
233
+ }
234
+
235
+ export async function normalizeWebSocketPayload(data) {
236
+ if (typeof data === "string") return Buffer.from(data, "utf8");
237
+ if (data instanceof ArrayBuffer) return Buffer.from(data);
238
+ if (ArrayBuffer.isView(data)) return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
239
+ if (typeof Blob !== "undefined" && data instanceof Blob) return Buffer.from(await data.arrayBuffer());
240
+ return Buffer.from([]);
241
+ }
242
+
243
+ // ---- 渲染 / 摘要 / 日志格式 ----
244
+
245
+ export function renderOutput(json, payload, lines) {
246
+ if (json) {
247
+ console.log(JSON.stringify(payload, null, 2));
248
+ return;
249
+ }
250
+ console.log(lines.join("\n"));
251
+ }
252
+
253
+ export function summarizeTunnelRequest(request) {
254
+ const pathName = typeof request?.path === "string" && request.path.trim() ? request.path.trim() : "/";
255
+ const rawQuery = typeof request?.rawQuery === "string" ? request.rawQuery : "";
256
+ return {
257
+ requestId: String(request?.requestId ?? "").trim() || "-",
258
+ method: String(request?.method ?? "GET").trim().toUpperCase(),
259
+ path: rawQuery ? `${pathName}?${rawQuery}` : pathName,
260
+ };
261
+ }
262
+
263
+ export function decodeBase64Length(value) {
264
+ if (typeof value !== "string" || value.length === 0) return 0;
265
+ return Buffer.from(value, "base64").byteLength;
266
+ }
267
+
268
+ export function createTunnelLogger({ localPort, tunnelID, targetBaseUrl, relayUrl }) {
269
+ const base = { port: localPort, tunnel: tunnelID, target: targetBaseUrl, relay: relayUrl };
270
+ return {
271
+ info(message, fields = {}) {
272
+ console.log(formatTunnelLogLine("info", message, { ...base, ...fields }));
273
+ },
274
+ error(message, fields = {}) {
275
+ console.error(formatTunnelLogLine("error", message, { ...base, ...fields }));
276
+ },
277
+ };
278
+ }
279
+
280
+ function formatTunnelLogLine(level, message, fields = {}) {
281
+ const parts = [
282
+ new Date().toISOString(),
283
+ `[tunnel-agent]`,
284
+ `level=${level}`,
285
+ `message=${quoteTunnelLogValue(message)}`,
286
+ ];
287
+ for (const [key, value] of Object.entries(fields)) {
288
+ if (value == null || value === "") continue;
289
+ parts.push(`${key}=${quoteTunnelLogValue(value)}`);
290
+ }
291
+ return parts.join(" ");
292
+ }
293
+
294
+ function quoteTunnelLogValue(value) {
295
+ const text = String(value);
296
+ return /[\s"]/u.test(text) ? JSON.stringify(text) : text;
297
+ }
298
+
299
+ export function sleep(ms) {
300
+ return new Promise((resolve) => setTimeout(resolve, ms));
301
+ }
@@ -0,0 +1,259 @@
1
+ /**
2
+ * unified_producer.mjs — C1.1.1 + C1.2.1
3
+ *
4
+ * createUnifiedProducer({ relayUrl, bridgeToken, threadId })
5
+ * → { postEvents(envelopes), close() }
6
+ *
7
+ * ensureUnifiedThread({ relayUrl, bridgeToken, runtime, config })
8
+ * → threadId (string)
9
+ */
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // AgentBridgeError
13
+ // ---------------------------------------------------------------------------
14
+
15
+ export class AgentBridgeError extends Error {
16
+ constructor(message, status) {
17
+ super(message);
18
+ this.name = "AgentBridgeError";
19
+ this.status = status;
20
+ }
21
+ }
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // C1.1.1 — createUnifiedProducer
25
+ // ---------------------------------------------------------------------------
26
+
27
+ /**
28
+ * @param {{ relayUrl: string, bridgeToken: string, threadId: string }} opts
29
+ * @returns {{ postEvents(envelopes: any[]): Promise<{accepted:number, rejected:number}>, close(): void }}
30
+ */
31
+ export function createUnifiedProducer({ relayUrl, bridgeToken, threadId }) {
32
+ if (!relayUrl) throw new Error("createUnifiedProducer: relayUrl required");
33
+ if (!bridgeToken) throw new Error("createUnifiedProducer: bridgeToken required");
34
+ if (!threadId) throw new Error("createUnifiedProducer: threadId required");
35
+
36
+ const base = relayUrl.replace(/\/$/, "");
37
+ const url = `${base}/v1/agents/threads/${encodeURIComponent(threadId)}/events`;
38
+ const headers = {
39
+ "Content-Type": "application/json",
40
+ "X-Agent-Bridge-Token": bridgeToken,
41
+ };
42
+
43
+ /**
44
+ * envelope 补全:server 端 schema 要求每个 envelope 都带 `thread_id` / `role` /
45
+ * `source` 三个 top-level 字段,但 `src-shared/envelope_builder.mjs` 的 build*
46
+ * 系列只构造 `{type, run_id, payload}`。openclaw 走 openclaw-plugin/index.cjs
47
+ * 的 enrichEnvelope() 补全后再发;hermes/claude/codex 走的就是当前模块,
48
+ * 不补就会被 server 退 400 schema.invalid(实测过 codex run 全 batch 拒绝、
49
+ * App 端永远转圈)。规则与 openclaw-plugin 对齐:
50
+ * - heartbeat / error → role=system, source=relay
51
+ * - 其他(run.* / content_block.* / 大多数)→ role=assistant, source=runtime
52
+ * 若 envelope 已经带了这些字段(来自 hook / 测试 stub),保留不覆盖。
53
+ */
54
+ function enrichEnvelope(env) {
55
+ const type = String(env?.type || "");
56
+ const isSystem = type === "heartbeat" || type === "error";
57
+ return {
58
+ thread_id: env?.thread_id || threadId,
59
+ role: env?.role || (isSystem ? "system" : "assistant"),
60
+ source: env?.source || (isSystem ? "relay" : "runtime"),
61
+ ...env,
62
+ };
63
+ }
64
+
65
+ /**
66
+ * POST a batch of envelopes to the relay.
67
+ * @param {any[]} envelopes
68
+ */
69
+ async function postEvents(envelopes) {
70
+ const enriched = Array.isArray(envelopes)
71
+ ? envelopes.map((env) => enrichEnvelope(env))
72
+ : envelopes;
73
+ const body = JSON.stringify({ events: enriched });
74
+ let resp;
75
+ try {
76
+ resp = await fetch(url, { method: "POST", headers, body });
77
+ } catch (networkErr) {
78
+ throw new AgentBridgeError(`network error: ${networkErr.message}`, 0);
79
+ }
80
+ if (!resp.ok) {
81
+ const text = await resp.text().catch(() => "");
82
+ const err = new AgentBridgeError(
83
+ `POST /events failed HTTP ${resp.status}: ${text}`,
84
+ resp.status,
85
+ );
86
+ if (resp.status === 413) {
87
+ err.code = "stream.payload_too_large";
88
+ }
89
+ throw err;
90
+ }
91
+ const json = await resp.json().catch(() => ({ accepted: 0, rejected: 0 }));
92
+ return json;
93
+ }
94
+
95
+ function close() {
96
+ // no persistent connection to close in Phase 1
97
+ }
98
+
99
+ return { postEvents, close };
100
+ }
101
+
102
+ // ---------------------------------------------------------------------------
103
+ // createHookedUnifiedProducer — wraps createUnifiedProducer with outgoing hooks
104
+ //
105
+ // 为 bridge-auto-tunnel(src-ext/core/bridgeHooks.mjs)等场景把 envelopes 上行
106
+ // 前的 hook chain 应用到 postEvents 调用。失败 / 超时一律不阻塞主链路。
107
+ // ---------------------------------------------------------------------------
108
+
109
+ /**
110
+ * @param {{
111
+ * relayUrl: string,
112
+ * bridgeToken: string,
113
+ * threadId: string,
114
+ * applyHooks?: (envelopes: any[], opts?: any) => Promise<any[]>,
115
+ * logger?: any,
116
+ * hookTimeoutMs?: number,
117
+ * }} opts
118
+ * applyHooks 默认懒加载 src-ext/core/bridgeHooks.mjs#applyOutgoingHooks,
119
+ * 方便单测时注入桩函数。
120
+ * @returns {{ postEvents(envelopes: any[]): Promise<{accepted:number, rejected:number}>, close(): void }}
121
+ */
122
+ export function createHookedUnifiedProducer(opts) {
123
+ const inner = createUnifiedProducer({
124
+ relayUrl: opts.relayUrl,
125
+ bridgeToken: opts.bridgeToken,
126
+ threadId: opts.threadId,
127
+ });
128
+ const hookTimeoutMs = opts.hookTimeoutMs;
129
+ const logger = opts.logger;
130
+ let applyHooks = opts.applyHooks;
131
+
132
+ async function ensureApplyHooks() {
133
+ if (applyHooks) return applyHooks;
134
+ const mod = await import("../src-ext/core/bridgeHooks.mjs");
135
+ applyHooks = mod.applyOutgoingHooks;
136
+ return applyHooks;
137
+ }
138
+
139
+ return {
140
+ async postEvents(envelopes) {
141
+ const apply = await ensureApplyHooks();
142
+ let transformed;
143
+ try {
144
+ transformed = await apply(envelopes, {
145
+ logger,
146
+ timeoutMs: hookTimeoutMs,
147
+ thread_id: opts.threadId,
148
+ });
149
+ } catch (err) {
150
+ // applyOutgoingHooks 已自己吞错;走到这说明 import 链路本身炸了。
151
+ logger?.warn?.("producer.hooks.bootstrap_err",
152
+ "failed to apply outgoing hooks, posting raw envelopes",
153
+ { err: err?.message || String(err) });
154
+ transformed = envelopes;
155
+ }
156
+ return inner.postEvents(Array.isArray(transformed) ? transformed : envelopes);
157
+ },
158
+ close() {
159
+ inner.close();
160
+ },
161
+ };
162
+ }
163
+
164
+ // ---------------------------------------------------------------------------
165
+ // C1.2.2 — processOpenClawStreamWithUnified (bridge integration helper)
166
+ // ---------------------------------------------------------------------------
167
+
168
+ /**
169
+ * Process a sequence of openclaw stream chunks, translate each to unified
170
+ * envelopes, and POST them to the relay via the micro-batched flusher.
171
+ *
172
+ * Each chunk's envelopes are enqueued immediately after translation (真流式),
173
+ * rather than accumulated for a single batch POST at the end. This eliminates
174
+ * the fake-streaming behavior that caused relay 413 errors on long turns.
175
+ *
176
+ * @param {{
177
+ * chunks: Array<{ event: string, delta?: string }>,
178
+ * relayUrl: string,
179
+ * bridgeToken: string,
180
+ * threadId: string,
181
+ * runId: string,
182
+ * flushPolicy?: { size?: number, timeMs?: number },
183
+ * }} opts
184
+ */
185
+ export async function processOpenClawStreamWithUnified({
186
+ chunks,
187
+ relayUrl,
188
+ bridgeToken,
189
+ threadId,
190
+ runId,
191
+ flushPolicy,
192
+ }) {
193
+ const { translateOpenClawChunkToEnvelope, newBlockState } = await import("../src-shared/envelope_builder.mjs");
194
+ const { createEnvelopeFlusher } = await import("../src-ext/core/unifiedDispatchHandler.mjs");
195
+
196
+ const producer = createUnifiedProducer({ relayUrl, bridgeToken, threadId });
197
+ const flusher = createEnvelopeFlusher({
198
+ postEvents: (envs) => producer.postEvents(envs),
199
+ flushPolicy,
200
+ });
201
+
202
+ let blockState = newBlockState();
203
+
204
+ for (const chunk of chunks) {
205
+ const { envelopes, blockState: next } = translateOpenClawChunkToEnvelope(chunk, runId, blockState);
206
+ blockState = next;
207
+ if (envelopes.length > 0) {
208
+ flusher.enqueue(envelopes);
209
+ }
210
+ }
211
+
212
+ await flusher.waitAll();
213
+ }
214
+
215
+ // ---------------------------------------------------------------------------
216
+ // C1.2.1 — ensureUnifiedThread
217
+ // ---------------------------------------------------------------------------
218
+
219
+ /**
220
+ * If config.unifiedThreadId is set, return it immediately.
221
+ * Otherwise POST /v1/agents/threads (with bridge_token), store in config, return.
222
+ *
223
+ * @param {{ relayUrl: string, bridgeToken: string, runtime: string, config: object }} opts
224
+ * @returns {Promise<string>} threadId
225
+ */
226
+ export async function ensureUnifiedThread({ relayUrl, bridgeToken, runtime, config }) {
227
+ if (config.unifiedThreadId) {
228
+ return config.unifiedThreadId;
229
+ }
230
+
231
+ const base = relayUrl.replace(/\/$/, "");
232
+ const url = `${base}/v1/agents/threads`;
233
+ let resp;
234
+ try {
235
+ resp = await fetch(url, {
236
+ method: "POST",
237
+ headers: {
238
+ "Content-Type": "application/json",
239
+ "X-Agent-Bridge-Token": bridgeToken,
240
+ },
241
+ body: JSON.stringify({ runtime: runtime || "openclaw" }),
242
+ });
243
+ } catch (networkErr) {
244
+ throw new AgentBridgeError(`ensureUnifiedThread network error: ${networkErr.message}`, 0);
245
+ }
246
+ if (!resp.ok) {
247
+ const text = await resp.text().catch(() => "");
248
+ throw new AgentBridgeError(
249
+ `POST /threads failed HTTP ${resp.status}: ${text}`,
250
+ resp.status,
251
+ );
252
+ }
253
+ const json = await resp.json();
254
+ const threadId = json.thread_id;
255
+ if (!threadId) throw new AgentBridgeError("POST /threads returned no thread_id", 0);
256
+
257
+ config.unifiedThreadId = threadId;
258
+ return threadId;
259
+ }
@@ -0,0 +1,75 @@
1
+ # `src-ext/` — External Agents (Hermes / Claude / Codex) 桥接
2
+
3
+ **平行世界**:整个目录对老 `src/` 零依赖。即使这里全删,老 `agentlink bridge`
4
+ (OpenClaw)完全不受影响。
5
+
6
+ ## 隔离契约
7
+
8
+ | 允许 | 禁止 |
9
+ | ------------------------------- | ------------------------------------- |
10
+ | `import '../src-shared/*'` | `import '../src/**'` |
11
+ | `import '../../node_modules/*'` | 反向依赖、跨目录 relative |
12
+ | 独立 bin `agentlink-agent` | 在老 `agentlink` 里注册命令 |
13
+ | 独立持久化目录 / 日志 / 配置 | 混用老的 OpenClaw gateway 凭证 |
14
+
15
+ ## 目录
16
+
17
+ ```
18
+ src-ext/
19
+ ├── bin.mjs # agentlink-agent 入口分发
20
+ ├── commands/
21
+ │ ├── agent.mjs # agentlink-agent <runtime> 子命令
22
+ │ ├── pair.mjs # agentlink-agent pair(pair-code consume)
23
+ │ ├── service.mjs # agentlink-agent service install/...
24
+ │ ├── reload.mjs # 配置 / 凭证热重载
25
+ │ └── help.mjs
26
+ ├── core/
27
+ │ ├── pairCodeClient.mjs # POST /v1/pair-codes/<code>/consume + 状态持久化
28
+ │ ├── relayWorker.mjs # 4 个 bridge 共用的 long-poll 主循环
29
+ │ ├── relayWorkerHttp.mjs # bridge_token Bearer header / fetchJson 工具
30
+ │ ├── sessionSlot.mjs # 单 session 槽状态机
31
+ │ ├── stateMachine.mjs # 通用 FSM
32
+ │ ├── approvalGateway.mjs # HITL 工具审批
33
+ │ ├── mcpStdioClient.mjs # MCP stdio 客户端(Codex 用)
34
+ │ ├── agentlinkToolsRegistry.mjs # 反向工具注册表
35
+ │ ├── agentlinkToolsServer.mjs # 反向 MCP 工具服务器
36
+ │ ├── accountResolver.mjs # accountId / clientUserId 解析
37
+ │ └── usageReporter.mjs # token 用量上报
38
+ ├── runtime/
39
+ │ ├── hermes/
40
+ │ │ └── index.mjs # Hermes bridge(OpenAI-compatible HTTP / 子进程,256 行)
41
+ │ ├── claude/
42
+ │ │ └── index.mjs # Claude bridge(spawn `claude` CLI + stream-json,223 行)
43
+ │ └── codex/
44
+ │ └── index.mjs # Codex bridge(spawn `codex` MCP stdio,240 行)
45
+ ├── service/
46
+ │ └── serviceManager.mjs # launchd / systemd / Task Scheduler 跨平台保活
47
+ └── openclaw-plugin/ # agentlink-hooks OpenClaw 插件源码(pair openclaw 时 link 进 OpenClaw)
48
+ ```
49
+
50
+ ## 重构后的关键事实
51
+
52
+ - **不再有 `src-ext/core/unified_relay_shim.mjs`** —— 整个文件已删除。CLI 端不再做
53
+ legacy native event → unified envelope 的协议翻译。bridge 把 native 事件
54
+ (Claude stream-json / Codex `codex/event` / Hermes OpenAI SSE chunk)**直接**
55
+ POST 给服务端,由 `agentlink-server/internal/adapter/<runtime>/` 翻译为
56
+ unified envelope 写入 `agent_events` 表。
57
+ - **不再有 `usageReporter` 的 envelope 翻译辅助** —— 现在只是把 native usage
58
+ 事件作为一种 chunk 透传。
59
+ - **4 个 runtime bridge 走完全统一的主循环**(`core/relayWorker.mjs`):
60
+ 1. 调 `pairCodeClient.consume()` 拿 `{gw_id, bridge_token}`
61
+ 2. `GET /v1/gateways/<gw>/requests/next?waitSeconds=25` 长轮询
62
+ 3. 调本地 runtime(HTTP / spawn CLI / MCP stdio)
63
+ 4. `POST /v1/gateways/<gw>/requests/<rid>/events` 推 native 事件
64
+ 5. `POST /v1/gateways/<gw>/meta` 每 10s 心跳
65
+
66
+ ## 运行
67
+
68
+ ```bash
69
+ node ./bin/agentlink-agent --help
70
+
71
+ # 各 runtime 的前台调试入口
72
+ AGENTLINK_AGENT_LOG_LEVEL=debug node ./bin/agentlink-agent hermes
73
+ AGENTLINK_AGENT_LOG_LEVEL=debug node ./bin/agentlink-agent claude
74
+ AGENTLINK_AGENT_LOG_LEVEL=debug node ./bin/agentlink-agent codex
75
+ ```