@stage-labs/metro 0.1.0-beta.9 → 0.1.0-beta.91

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 (287) hide show
  1. package/dist/api.js +14 -0
  2. package/dist/claude-settings.js +40 -0
  3. package/dist/claude.js +129 -0
  4. package/dist/cli.js +101 -0
  5. package/dist/control.js +74 -0
  6. package/dist/hold.js +211 -0
  7. package/dist/local.js +93 -0
  8. package/dist/node-name.js +71 -0
  9. package/dist/plugin.js +80 -0
  10. package/dist/provider-flags.js +9 -0
  11. package/dist/runtime-install.js +87 -0
  12. package/dist/runtime.js +74 -0
  13. package/dist/serve.js +150 -0
  14. package/dist/service.js +242 -0
  15. package/dist/tail.js +119 -0
  16. package/dist/update.js +45 -0
  17. package/dist/version.js +97 -0
  18. package/package.json +14 -25
  19. package/runtime/node_modules/@metro-labs/core/package.json +43 -0
  20. package/runtime/node_modules/@metro-labs/core/src/address.ts +6 -0
  21. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  22. package/runtime/node_modules/@metro-labs/core/src/events.ts +120 -0
  23. package/runtime/node_modules/@metro-labs/core/src/identity.ts +7 -0
  24. package/runtime/node_modules/@metro-labs/core/src/ids.ts +21 -0
  25. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  26. package/runtime/node_modules/@metro-labs/core/src/lines.ts +82 -0
  27. package/runtime/node_modules/@metro-labs/core/src/log.ts +42 -0
  28. package/runtime/node_modules/@metro-labs/core/src/protocol.ts +226 -0
  29. package/runtime/node_modules/@metro-labs/core/src/secure-fs.ts +57 -0
  30. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +12 -0
  31. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +60 -0
  32. package/runtime/node_modules/@metro-labs/core/src/stations/attachments.ts +196 -0
  33. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +88 -0
  34. package/runtime/node_modules/@metro-labs/core/src/stations/station-runtime.ts +64 -0
  35. package/runtime/node_modules/@metro-labs/core/src/stations/types.ts +107 -0
  36. package/runtime/node_modules/@metro-labs/core/src/str.ts +5 -0
  37. package/runtime/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  38. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  39. package/runtime/node_modules/@metro-labs/daemon/package.json +47 -0
  40. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  41. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +368 -0
  42. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +43 -0
  43. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +37 -0
  44. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +302 -0
  45. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +111 -0
  46. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +345 -0
  47. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +155 -0
  48. package/runtime/node_modules/@metro-labs/daemon/src/agents/keys.ts +45 -0
  49. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +88 -0
  50. package/runtime/node_modules/@metro-labs/daemon/src/agents/scope.ts +64 -0
  51. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  52. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +193 -0
  53. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +39 -0
  54. package/runtime/node_modules/@metro-labs/daemon/src/boot/crash-guard.ts +49 -0
  55. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +14 -0
  56. package/runtime/node_modules/@metro-labs/daemon/src/boot/paths.ts +106 -0
  57. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +25 -0
  58. package/runtime/node_modules/@metro-labs/daemon/src/channels/dedupe.ts +24 -0
  59. package/runtime/node_modules/@metro-labs/daemon/src/channels/inbound.ts +377 -0
  60. package/runtime/node_modules/@metro-labs/daemon/src/channels/media-note.ts +85 -0
  61. package/runtime/node_modules/@metro-labs/daemon/src/channels/pending.ts +75 -0
  62. package/runtime/node_modules/@metro-labs/daemon/src/channels/relay.ts +129 -0
  63. package/runtime/node_modules/@metro-labs/daemon/src/channels/webhook-note.ts +51 -0
  64. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +176 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +329 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +167 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +117 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +154 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/connectors/api.ts +307 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/connectors/cli-api.ts +63 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/connectors/config.ts +144 -0
  72. package/runtime/node_modules/@metro-labs/daemon/src/connectors/json.ts +21 -0
  73. package/runtime/node_modules/@metro-labs/daemon/src/connectors/model.ts +69 -0
  74. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-client.ts +159 -0
  75. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-discovery.ts +117 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-pending.ts +65 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-routes.ts +157 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth.ts +127 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/connectors/plugin-sync.ts +112 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-target.ts +39 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay.ts +295 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +277 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +98 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/connectors/url.ts +70 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/connectors/verify.ts +330 -0
  86. package/runtime/node_modules/@metro-labs/daemon/src/connectors/watch.ts +54 -0
  87. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-grant.ts +99 -0
  88. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-owner.ts +32 -0
  89. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-serve.ts +121 -0
  90. package/runtime/node_modules/@metro-labs/daemon/src/files/upload-api.ts +294 -0
  91. package/runtime/node_modules/@metro-labs/daemon/src/files/upload-store.ts +181 -0
  92. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +252 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +231 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +91 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +288 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +203 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +220 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  99. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +182 -0
  100. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +208 -0
  101. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +195 -0
  102. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +198 -0
  103. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +40 -0
  104. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +17 -0
  105. package/runtime/node_modules/@metro-labs/daemon/src/mcp/accounts.ts +139 -0
  106. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-tools.ts +216 -0
  107. package/runtime/node_modules/@metro-labs/daemon/src/mcp/channel-owner.ts +29 -0
  108. package/runtime/node_modules/@metro-labs/daemon/src/mcp/ctx.ts +62 -0
  109. package/runtime/node_modules/@metro-labs/daemon/src/mcp/event-store.ts +91 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-scope.ts +21 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/mcp/group-tools.ts +129 -0
  112. package/runtime/node_modules/@metro-labs/daemon/src/mcp/index.ts +191 -0
  113. package/runtime/node_modules/@metro-labs/daemon/src/mcp/member-tools.ts +72 -0
  114. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +66 -0
  115. package/runtime/node_modules/@metro-labs/daemon/src/mcp/raw-get-stream.ts +207 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +47 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-registry.ts +172 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-route.ts +43 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session.ts +215 -0
  120. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-dispatch.ts +215 -0
  121. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-schemas.ts +400 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/mcp/upload-tool.ts +66 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +237 -0
  124. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +389 -0
  125. package/runtime/node_modules/@metro-labs/daemon/src/routes/http.ts +390 -0
  126. package/runtime/node_modules/@metro-labs/daemon/src/routes/identity.ts +54 -0
  127. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +198 -0
  128. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +60 -0
  129. package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +64 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +61 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +116 -0
  133. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  134. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-inline.ts +100 -0
  135. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-interactive.ts +161 -0
  136. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-resolve.ts +202 -0
  137. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-session.ts +280 -0
  138. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-xmtp.ts +111 -0
  139. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach.ts +184 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/stations/materialize.ts +248 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/stations/registry.ts +35 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +82 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/stations/supervisor-io.ts +97 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/stations/supervisor.ts +320 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/stations/train-call.ts +22 -0
  146. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +91 -0
  147. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +123 -0
  148. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +40 -0
  149. package/runtime/node_modules/@metro-labs/discord-bot/package.json +28 -0
  150. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +118 -0
  151. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +388 -0
  152. package/runtime/node_modules/@metro-labs/discord-bot/src/api-base.ts +1 -0
  153. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +29 -0
  154. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +220 -0
  155. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +50 -0
  156. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +115 -0
  157. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +127 -0
  158. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +215 -0
  159. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +43 -0
  160. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +19 -0
  161. package/runtime/node_modules/@metro-labs/discord-bot/src/verify.ts +82 -0
  162. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +195 -0
  163. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +292 -0
  164. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +197 -0
  165. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +5 -0
  166. package/runtime/node_modules/@metro-labs/http/package.json +33 -0
  167. package/runtime/node_modules/@metro-labs/http/src/api-error.ts +8 -0
  168. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +95 -0
  169. package/runtime/node_modules/@metro-labs/http/src/cors.ts +29 -0
  170. package/runtime/node_modules/@metro-labs/http/src/identity-key.ts +33 -0
  171. package/runtime/node_modules/@metro-labs/http/src/identity-registry.ts +13 -0
  172. package/runtime/node_modules/@metro-labs/http/src/mode-api.ts +32 -0
  173. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +21 -0
  174. package/runtime/node_modules/@metro-labs/http/src/signed-identity.ts +36 -0
  175. package/runtime/node_modules/@metro-labs/telegram/package.json +26 -0
  176. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +80 -0
  177. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +254 -0
  178. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +87 -0
  179. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +77 -0
  180. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +156 -0
  181. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +261 -0
  182. package/runtime/node_modules/@metro-labs/telegram/src/history.ts +52 -0
  183. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +78 -0
  184. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +46 -0
  185. package/runtime/node_modules/@metro-labs/telegram/src/login.ts +166 -0
  186. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +80 -0
  187. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +75 -0
  188. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +22 -0
  189. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +167 -0
  190. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +24 -0
  191. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +7 -0
  192. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +1 -0
  193. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +25 -0
  194. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +120 -0
  195. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +295 -0
  196. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +128 -0
  197. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +201 -0
  198. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +109 -0
  199. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +166 -0
  200. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +47 -0
  201. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +17 -0
  202. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +58 -0
  203. package/runtime/node_modules/@metro-labs/telegram-bot/src/verify.ts +38 -0
  204. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +3 -0
  205. package/runtime/node_modules/@metro-labs/webhook/package.json +23 -0
  206. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +37 -0
  207. package/runtime/node_modules/@metro-labs/whatsapp/package.json +27 -0
  208. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +66 -0
  209. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +101 -0
  210. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +178 -0
  211. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +72 -0
  212. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +129 -0
  213. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +327 -0
  214. package/runtime/node_modules/@metro-labs/whatsapp/src/delivery.ts +49 -0
  215. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +138 -0
  216. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +57 -0
  217. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +40 -0
  218. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +59 -0
  219. package/runtime/node_modules/@metro-labs/whatsapp/src/logger.ts +60 -0
  220. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +176 -0
  221. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +84 -0
  222. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +22 -0
  223. package/runtime/node_modules/@metro-labs/whatsapp/src/outbox.ts +38 -0
  224. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +185 -0
  225. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +17 -0
  226. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +98 -0
  227. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +6 -0
  228. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +5 -0
  229. package/runtime/node_modules/@metro-labs/xmtp/package.json +33 -0
  230. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +112 -0
  231. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +110 -0
  232. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +299 -0
  233. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +157 -0
  234. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +87 -0
  235. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +375 -0
  236. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +107 -0
  237. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +171 -0
  238. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +239 -0
  239. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +55 -0
  240. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +335 -0
  241. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +80 -0
  242. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +34 -0
  243. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +56 -0
  244. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +33 -0
  245. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +125 -0
  246. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +157 -0
  247. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +40 -0
  248. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +349 -0
  249. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +13 -0
  250. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +126 -0
  251. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +212 -0
  252. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +90 -0
  253. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +84 -0
  254. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +53 -0
  255. package/runtime/runtime.json +3 -0
  256. package/runtime/server.ts +1 -0
  257. package/runtime/stations.json +36 -0
  258. package/runtime/trains/.keep +0 -0
  259. package/LICENSE +0 -21
  260. package/README.md +0 -249
  261. package/dist/cache.js +0 -75
  262. package/dist/cli/actions.js +0 -139
  263. package/dist/cli/config.js +0 -185
  264. package/dist/cli/index.js +0 -177
  265. package/dist/cli/skill.js +0 -62
  266. package/dist/cli/util.js +0 -72
  267. package/dist/cli/webhook.js +0 -83
  268. package/dist/codex-rc.js +0 -245
  269. package/dist/dispatcher.js +0 -122
  270. package/dist/history.js +0 -99
  271. package/dist/ipc.js +0 -72
  272. package/dist/log.js +0 -15
  273. package/dist/paths.js +0 -68
  274. package/dist/registry.js +0 -48
  275. package/dist/stations/claude.js +0 -45
  276. package/dist/stations/codex.js +0 -68
  277. package/dist/stations/discord.js +0 -200
  278. package/dist/stations/index.js +0 -133
  279. package/dist/stations/telegram-md.js +0 -34
  280. package/dist/stations/telegram-upload.js +0 -113
  281. package/dist/stations/telegram.js +0 -213
  282. package/dist/stations/webhook.js +0 -100
  283. package/dist/tunnel.js +0 -66
  284. package/dist/webhooks.js +0 -40
  285. package/docs/agents.md +0 -216
  286. package/docs/uri-scheme.md +0 -125
  287. package/skills/metro/SKILL.md +0 -249
@@ -0,0 +1,167 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { spawnSync } from 'node:child_process';
3
+ import { ApiError } from '@metro-labs/http/api-error';
4
+ import { isRecord } from '@metro-labs/core/is-record';
5
+ import { errMsg, log } from '@metro-labs/core/log';
6
+
7
+ const LOGIN_COMMAND = ['claude', 'auth', 'login', '--claudeai'];
8
+ const STATUS_COMMAND = ['auth', 'status', '--json'];
9
+ const TTL_MS = 10 * 60_000;
10
+ const OUTPUT_MAX = 8_000;
11
+ const COLS = 100;
12
+ const ROWS = 40;
13
+ const ESC = String.fromCharCode(27);
14
+ const CSI = /^\[[0-9;?]*[a-zA-Z]/;
15
+ const URL_RE = /https:\/\/[^\s"'`]+/g;
16
+
17
+ export type LoginState = 'pending' | 'done' | 'failed';
18
+
19
+ export interface LoginView {
20
+ id: string;
21
+ state: LoginState;
22
+ url: string | null;
23
+ output: string;
24
+ error: string | null;
25
+ }
26
+
27
+ interface Live {
28
+ id: string;
29
+ startedAt: number;
30
+ state: LoginState;
31
+ output: string;
32
+ error: string | null;
33
+ write: (text: string) => void;
34
+ kill: () => void;
35
+ }
36
+
37
+ export interface LoginDeps {
38
+ command?: string[];
39
+ }
40
+
41
+ let live: Live | null = null;
42
+
43
+ export function plainText(raw: string): string {
44
+ return raw
45
+ .split(ESC)
46
+ .map((part, index) => (index === 0 ? part : part.replace(CSI, '')))
47
+ .join('');
48
+ }
49
+
50
+ export function loginUrlIn(output: string): string | null {
51
+ const found = output.match(URL_RE) ?? [];
52
+ const trimmed = found.map((url) => url.replace(/[.,)]+$/, ''));
53
+ return trimmed.find((url) => url.includes('claude.ai') || url.includes('anthropic.com')) ?? trimmed[0] ?? null;
54
+ }
55
+
56
+ const view = (session: Live): LoginView => ({
57
+ id: session.id,
58
+ state: session.state,
59
+ url: loginUrlIn(session.output),
60
+ output: session.output,
61
+ error: session.error,
62
+ });
63
+
64
+ function sweep(now: number): void {
65
+ if (live !== null && live.state !== 'pending') return;
66
+ if (live !== null && now - live.startedAt > TTL_MS) {
67
+ live.kill();
68
+ live = null;
69
+ }
70
+ }
71
+
72
+ export function claudeInstalled(): boolean {
73
+ const run = spawnSync('claude', ['--version'], { stdio: 'ignore' });
74
+ return run.error === undefined && run.status === 0;
75
+ }
76
+
77
+ export function claudeAccount(): { signedIn: boolean; account: string | null } {
78
+ const run = spawnSync('claude', STATUS_COMMAND, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
79
+ if (run.error !== undefined || typeof run.stdout !== 'string') return { signedIn: false, account: null };
80
+ try {
81
+ const parsed: unknown = JSON.parse(run.stdout);
82
+ if (!isRecord(parsed)) return { signedIn: false, account: null };
83
+ const account = typeof parsed.email === 'string' ? parsed.email : typeof parsed.organization === 'string' ? parsed.organization : null;
84
+ return { signedIn: parsed.authenticated === true || parsed.loggedIn === true || account !== null, account };
85
+ } catch {
86
+ return { signedIn: false, account: null };
87
+ }
88
+ }
89
+
90
+ function note(session: Live, chunk: string): void {
91
+ const next = session.output + plainText(chunk);
92
+ session.output = next.length > OUTPUT_MAX ? next.slice(next.length - OUTPUT_MAX) : next;
93
+ }
94
+
95
+ export function startClaudeLogin(deps: LoginDeps = {}, now = Date.now()): LoginView {
96
+ sweep(now);
97
+ if (live !== null && live.state === 'pending') return view(live);
98
+ const command = deps.command ?? LOGIN_COMMAND;
99
+ const session: Live = {
100
+ id: randomBytes(9).toString('base64url'),
101
+ startedAt: now,
102
+ state: 'pending',
103
+ output: '',
104
+ error: null,
105
+ write: () => undefined,
106
+ kill: () => undefined,
107
+ };
108
+ const terminal = new Bun.Terminal({
109
+ cols: COLS,
110
+ rows: ROWS,
111
+ data: (_term, chunk: Uint8Array) => {
112
+ note(session, Buffer.from(chunk).toString('utf8'));
113
+ },
114
+ });
115
+ const proc = Bun.spawn(command, { terminal, env: { ...process.env, TERM: 'xterm-256color' } });
116
+ session.write = (text: string) => {
117
+ terminal.write(Buffer.from(`${text}\r`, 'utf8'));
118
+ };
119
+ session.kill = () => {
120
+ proc.kill();
121
+ terminal.close();
122
+ };
123
+ proc.exited
124
+ .then((code) => {
125
+ session.state = code === 0 ? 'done' : 'failed';
126
+ if (code !== 0) session.error = `the login ended with status ${String(code)}`;
127
+ terminal.close();
128
+ log.info({ state: session.state }, 'claude-login: the official login finished');
129
+ })
130
+ .catch((err: unknown) => {
131
+ session.state = 'failed';
132
+ session.error = errMsg(err);
133
+ });
134
+ live = session;
135
+ log.info({ command: command[0] }, 'claude-login: started');
136
+ return view(session);
137
+ }
138
+
139
+ function current(id: string): Live {
140
+ const session = live;
141
+ if (session?.id !== id) throw new ApiError('that sign-in is over; start another one', 404);
142
+ return session;
143
+ }
144
+
145
+ export function claudeLoginView(id: string, now = Date.now()): LoginView {
146
+ sweep(now);
147
+ return view(current(id));
148
+ }
149
+
150
+ export function answerClaudeLogin(id: string, text: string): LoginView {
151
+ const session = current(id);
152
+ if (session.state !== 'pending') throw new ApiError('that sign-in has already finished', 409);
153
+ session.write(text);
154
+ return view(session);
155
+ }
156
+
157
+ export function endClaudeLogin(id: string): { ended: true } {
158
+ const session = current(id);
159
+ session.kill();
160
+ live = null;
161
+ return { ended: true };
162
+ }
163
+
164
+ export const forgetClaudeLogin = (): void => {
165
+ live?.kill();
166
+ live = null;
167
+ };
@@ -0,0 +1,117 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { ApiError } from '@metro-labs/http/api-error';
4
+ import { claudeDir, listClaudeProjects } from './files.js';
5
+ import { isRecord } from '@metro-labs/core/is-record';
6
+ import { errMsg } from '@metro-labs/core/log';
7
+
8
+ export const SETTINGS_MAX = 256 * 1024;
9
+ const USER_ID = 'user';
10
+ const LOCAL_SUFFIX = '.local';
11
+ const DEFAULT_MODE = 0o644;
12
+
13
+ export type SettingsScope = 'user' | 'project' | 'local';
14
+
15
+ export interface ClaudeSettingsFile {
16
+ id: string;
17
+ scope: SettingsScope;
18
+ label: string;
19
+ path: string;
20
+ exists: boolean;
21
+ editable: boolean;
22
+ text: string;
23
+ modifiedAt: string | null;
24
+ }
25
+
26
+ const missing = (id: string, scope: SettingsScope, label: string, path: string): ClaudeSettingsFile => ({
27
+ id,
28
+ scope,
29
+ label,
30
+ path,
31
+ exists: false,
32
+ editable: true,
33
+ text: '',
34
+ modifiedAt: null,
35
+ });
36
+
37
+ function entryOf(id: string, scope: SettingsScope, label: string, path: string): ClaudeSettingsFile {
38
+ if (!existsSync(path)) return missing(id, scope, label, path);
39
+ const stat = statSync(path);
40
+ const editable = stat.size <= SETTINGS_MAX;
41
+ return {
42
+ id,
43
+ scope,
44
+ label,
45
+ path,
46
+ exists: true,
47
+ editable,
48
+ text: editable ? readFileSync(path, 'utf8') : '',
49
+ modifiedAt: stat.mtime.toISOString(),
50
+ };
51
+ }
52
+
53
+ const PROJECT_FILES: [string, SettingsScope, string][] = [
54
+ ['', 'project', 'settings.json'],
55
+ [LOCAL_SUFFIX, 'local', 'settings.local.json'],
56
+ ];
57
+
58
+ function projectEntries(dir: string): ClaudeSettingsFile[] {
59
+ const out: ClaudeSettingsFile[] = [];
60
+ for (const project of listClaudeProjects(dir)) {
61
+ const cwd = project.cwd;
62
+ if (cwd === null) continue;
63
+ for (const [suffix, scope, name] of PROJECT_FILES) {
64
+ const path = join(cwd, '.claude', name);
65
+ if (existsSync(path)) out.push(entryOf(`${project.id}${suffix}`, scope, cwd, path));
66
+ }
67
+ }
68
+ return out;
69
+ }
70
+
71
+ export function listClaudeSettings(dir = claudeDir()): ClaudeSettingsFile[] {
72
+ return [entryOf(USER_ID, 'user', 'This machine', join(dir, 'settings.json')), ...projectEntries(dir)];
73
+ }
74
+
75
+ function assertSettingsJson(text: string): void {
76
+ if (text.length > SETTINGS_MAX) throw new ApiError('that is more text than a settings file may hold', 413);
77
+ let parsed: unknown;
78
+ try {
79
+ parsed = JSON.parse(text);
80
+ } catch (err) {
81
+ throw new ApiError(`that is not valid JSON: ${errMsg(err)}`, 400);
82
+ }
83
+ if (!isRecord(parsed)) throw new ApiError('Claude Code settings must be a JSON object', 400);
84
+ }
85
+
86
+ function modeOf(path: string): number {
87
+ try {
88
+ return statSync(path).mode & 0o777;
89
+ } catch {
90
+ return DEFAULT_MODE;
91
+ }
92
+ }
93
+
94
+ function writeAtomic(path: string, text: string): void {
95
+ const mode = existsSync(path) ? modeOf(path) : DEFAULT_MODE;
96
+ mkdirSync(dirname(path), { recursive: true });
97
+ const tmp = `${path}.metro-${String(process.pid)}`;
98
+ writeFileSync(tmp, text, { mode });
99
+ chmodSync(tmp, mode);
100
+ renameSync(tmp, path);
101
+ }
102
+
103
+ export function writeClaudeSettings(
104
+ id: string,
105
+ text: string,
106
+ seenAt: string | null | undefined,
107
+ dir = claudeDir(),
108
+ ): ClaudeSettingsFile {
109
+ const target = listClaudeSettings(dir).find((file) => file.id === id);
110
+ if (target === undefined) throw new ApiError('no such settings file', 404);
111
+ if (!target.editable) throw new ApiError('that settings file is too large to edit here', 409);
112
+ assertSettingsJson(text);
113
+ if (seenAt !== undefined && seenAt !== target.modifiedAt)
114
+ throw new ApiError('that file changed on disk since you opened it; reload it before saving', 409);
115
+ writeAtomic(target.path, text);
116
+ return entryOf(target.id, target.scope, target.label, target.path);
117
+ }
@@ -0,0 +1,154 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
2
+ import { basename, dirname, join } from 'node:path';
3
+ import { ApiError } from '@metro-labs/http/api-error';
4
+ import { claudeDir, listClaudeProjects } from './files.js';
5
+
6
+ export const SKILL_MAX = 256 * 1024;
7
+ export const SKILL_NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
8
+ const USER_SCOPE = 'user';
9
+ const FILE = 'SKILL.md';
10
+ const DEFAULT_MODE = 0o644;
11
+ const SUMMARY_MAX = 300;
12
+
13
+ export type SkillScope = 'user' | 'project';
14
+
15
+ export interface ClaudeSkill {
16
+ id: string;
17
+ name: string;
18
+ title: string;
19
+ description: string;
20
+ scope: SkillScope;
21
+ where: string;
22
+ path: string;
23
+ editable: boolean;
24
+ updatedAt: string | null;
25
+ }
26
+
27
+ const frontmatterField = (text: string, field: string): string => {
28
+ const head = text.startsWith('---') ? text.slice(3, text.indexOf('\n---', 3)) : '';
29
+ for (const line of head.split('\n')) {
30
+ const at = line.indexOf(':');
31
+ if (at > 0 && line.slice(0, at).trim() === field) return line.slice(at + 1).trim().replace(/^["']|["']$/g, '').slice(0, SUMMARY_MAX);
32
+ }
33
+ return '';
34
+ };
35
+
36
+ function entryOf(id: string, name: string, scope: SkillScope, where: string, path: string): ClaudeSkill {
37
+ const stat = statSync(path);
38
+ const editable = stat.size <= SKILL_MAX;
39
+ const text = editable ? readFileSync(path, 'utf8') : '';
40
+ return {
41
+ id,
42
+ name,
43
+ title: frontmatterField(text, 'name') || name,
44
+ description: frontmatterField(text, 'description'),
45
+ scope,
46
+ where,
47
+ path,
48
+ editable,
49
+ updatedAt: stat.mtime.toISOString(),
50
+ };
51
+ }
52
+
53
+ function skillsIn(root: string, prefix: string, scope: SkillScope, where: string): ClaudeSkill[] {
54
+ if (!existsSync(root)) return [];
55
+ const out: ClaudeSkill[] = [];
56
+ for (const entry of readdirSync(root, { withFileTypes: true })) {
57
+ if (!entry.isDirectory() || !SKILL_NAME_RE.test(entry.name)) continue;
58
+ const path = join(root, entry.name, FILE);
59
+ if (existsSync(path)) out.push(entryOf(`${prefix}:${entry.name}`, entry.name, scope, where, path));
60
+ }
61
+ return out;
62
+ }
63
+
64
+ export const userSkillsRoot = (dir: string): string => join(dir, 'skills');
65
+
66
+ export interface SkillHome {
67
+ prefix: string;
68
+ scope: SkillScope;
69
+ where: string;
70
+ root: string;
71
+ }
72
+
73
+ export function skillHomes(dir = claudeDir()): SkillHome[] {
74
+ const homes: SkillHome[] = [{ prefix: USER_SCOPE, scope: USER_SCOPE, where: 'This machine', root: userSkillsRoot(dir) }];
75
+ for (const project of listClaudeProjects(dir)) {
76
+ const cwd = project.cwd;
77
+ if (cwd === null || !existsSync(cwd)) continue;
78
+ homes.push({ prefix: project.id, scope: 'project', where: cwd, root: join(cwd, '.claude', 'skills') });
79
+ }
80
+ return homes;
81
+ }
82
+
83
+ export function listClaudeSkills(dir = claudeDir()): ClaudeSkill[] {
84
+ const out = skillHomes(dir).flatMap((home) => skillsIn(home.root, home.prefix, home.scope, home.where));
85
+ return out.sort((a, b) => (b.updatedAt ?? '').localeCompare(a.updatedAt ?? '') || a.name.localeCompare(b.name));
86
+ }
87
+
88
+ function found(id: string, dir: string): ClaudeSkill {
89
+ const skill = listClaudeSkills(dir).find((entry) => entry.id === id);
90
+ if (skill === undefined) throw new ApiError('no such skill', 404);
91
+ return skill;
92
+ }
93
+
94
+ export function readClaudeSkill(id: string, dir = claudeDir()): ClaudeSkill & { text: string } {
95
+ const skill = found(id, dir);
96
+ return { ...skill, text: skill.editable ? readFileSync(skill.path, 'utf8') : '' };
97
+ }
98
+
99
+ function writeAtomic(path: string, text: string): void {
100
+ mkdirSync(dirname(path), { recursive: true });
101
+ const tmp = `${path}.metro-${String(process.pid)}`;
102
+ writeFileSync(tmp, text, { mode: DEFAULT_MODE });
103
+ renameSync(tmp, path);
104
+ }
105
+
106
+ function assertText(text: string): void {
107
+ if (text.length > SKILL_MAX) throw new ApiError('that is more text than a skill may hold', 413);
108
+ if (text.trim() === '') throw new ApiError('a skill needs some text', 400);
109
+ }
110
+
111
+ export function writeClaudeSkill(
112
+ id: string,
113
+ text: string,
114
+ seenAt: string | null | undefined,
115
+ dir = claudeDir(),
116
+ ): ClaudeSkill {
117
+ const skill = found(id, dir);
118
+ if (!skill.editable) throw new ApiError('that skill is too large to edit here', 409);
119
+ assertText(text);
120
+ if (seenAt !== undefined && seenAt !== skill.updatedAt)
121
+ throw new ApiError('that skill changed on disk since you opened it; reload it before saving', 409);
122
+ writeAtomic(skill.path, text);
123
+ return entryOf(skill.id, skill.name, skill.scope, skill.where, skill.path);
124
+ }
125
+
126
+ export const skillTemplate = (name: string): string =>
127
+ ['---', `name: ${name}`, 'description: what this skill does, and when Claude should reach for it', '---', '', `# ${name}`, '', 'Write the instructions here.', ''].join('\n');
128
+
129
+ export function createClaudeSkill(
130
+ name: string,
131
+ scope: string | undefined,
132
+ text: string | undefined,
133
+ dir = claudeDir(),
134
+ ): ClaudeSkill {
135
+ if (typeof name !== 'string' || !SKILL_NAME_RE.test(name))
136
+ throw new ApiError('a skill name is lowercase letters, digits and dashes, up to 64 characters', 400);
137
+ const prefix = scope === undefined || scope === '' ? USER_SCOPE : scope;
138
+ const home = skillHomes(dir).find((h) => h.prefix === prefix);
139
+ if (home === undefined) throw new ApiError('no such place to keep a skill', 404);
140
+ const path = join(home.root, name, FILE);
141
+ if (existsSync(path)) throw new ApiError('a skill by that name already lives there', 409);
142
+ const body = text === undefined || text.trim() === '' ? skillTemplate(name) : text;
143
+ assertText(body);
144
+ writeAtomic(path, body);
145
+ return entryOf(`${home.prefix}:${name}`, name, home.scope, home.where, path);
146
+ }
147
+
148
+ export function deleteClaudeSkill(id: string, dir = claudeDir()): string {
149
+ const skill = found(id, dir);
150
+ const folder = dirname(skill.path);
151
+ if (basename(folder) !== skill.name) throw new ApiError('that skill does not live in its own folder', 409);
152
+ rmSync(folder, { recursive: true, force: true });
153
+ return id;
154
+ }