@mesh-tech/mesh-cli 0.1.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (504) hide show
  1. package/assets/intent/agents-fence.md +10 -0
  2. package/assets/intent/intent-claude-gate.mjs +255 -0
  3. package/assets/log-shipper.mjs +94 -0
  4. package/bin/mesh.mjs +80 -0
  5. package/dist/bin/mesh.d.ts +7 -9
  6. package/dist/bin/mesh.d.ts.map +1 -1
  7. package/dist/bin/mesh.js +20826 -37
  8. package/dist/bin/mesh.js.map +7 -1
  9. package/dist/build-info.json +4 -0
  10. package/dist/src/commands/agent-api-client.d.ts +79 -0
  11. package/dist/src/commands/agent-api-client.d.ts.map +1 -0
  12. package/dist/src/commands/agent-api-client.js +170 -0
  13. package/dist/src/commands/agent-api-client.js.map +1 -0
  14. package/dist/src/commands/artifacts.d.ts +13 -0
  15. package/dist/src/commands/artifacts.d.ts.map +1 -0
  16. package/dist/src/commands/artifacts.js +140 -0
  17. package/dist/src/commands/artifacts.js.map +1 -0
  18. package/dist/src/commands/cluster.d.ts +45 -0
  19. package/dist/src/commands/cluster.d.ts.map +1 -0
  20. package/dist/src/commands/cluster.js +259 -0
  21. package/dist/src/commands/cluster.js.map +1 -0
  22. package/dist/src/commands/conversations.d.ts +61 -0
  23. package/dist/src/commands/conversations.d.ts.map +1 -0
  24. package/dist/src/commands/conversations.js +239 -0
  25. package/dist/src/commands/conversations.js.map +1 -0
  26. package/dist/src/commands/create-app.d.ts +26 -3
  27. package/dist/src/commands/create-app.d.ts.map +1 -1
  28. package/dist/src/commands/create-app.js +465 -107
  29. package/dist/src/commands/create-app.js.map +1 -1
  30. package/dist/src/commands/deploy.d.ts +19 -0
  31. package/dist/src/commands/deploy.d.ts.map +1 -1
  32. package/dist/src/commands/deploy.js +83 -142
  33. package/dist/src/commands/deploy.js.map +1 -1
  34. package/dist/src/commands/dev-doctor.d.ts +137 -0
  35. package/dist/src/commands/dev-doctor.d.ts.map +1 -0
  36. package/dist/src/commands/dev-doctor.js +671 -0
  37. package/dist/src/commands/dev-doctor.js.map +1 -0
  38. package/dist/src/commands/dev-launch.d.ts +59 -0
  39. package/dist/src/commands/dev-launch.d.ts.map +1 -0
  40. package/dist/src/commands/dev-launch.js +118 -0
  41. package/dist/src/commands/dev-launch.js.map +1 -0
  42. package/dist/src/commands/dev-token-server.d.ts +32 -0
  43. package/dist/src/commands/dev-token-server.d.ts.map +1 -0
  44. package/dist/src/commands/dev-token-server.js +68 -0
  45. package/dist/src/commands/dev-token-server.js.map +1 -0
  46. package/dist/src/commands/dev.d.ts +289 -2
  47. package/dist/src/commands/dev.d.ts.map +1 -1
  48. package/dist/src/commands/dev.js +2501 -574
  49. package/dist/src/commands/dev.js.map +1 -1
  50. package/dist/src/commands/docs.d.ts +3 -0
  51. package/dist/src/commands/docs.d.ts.map +1 -0
  52. package/dist/src/commands/docs.js +262 -0
  53. package/dist/src/commands/docs.js.map +1 -0
  54. package/dist/src/commands/hub/index.d.ts +99 -0
  55. package/dist/src/commands/hub/index.d.ts.map +1 -0
  56. package/dist/src/commands/hub/index.js +452 -0
  57. package/dist/src/commands/hub/index.js.map +1 -0
  58. package/dist/src/commands/init.d.ts +65 -0
  59. package/dist/src/commands/init.d.ts.map +1 -0
  60. package/dist/src/commands/init.js +370 -0
  61. package/dist/src/commands/init.js.map +1 -0
  62. package/dist/src/commands/install-shim.d.ts +21 -0
  63. package/dist/src/commands/install-shim.d.ts.map +1 -0
  64. package/dist/src/commands/install-shim.js +132 -0
  65. package/dist/src/commands/install-shim.js.map +1 -0
  66. package/dist/src/commands/local/auth-provision.d.ts +71 -0
  67. package/dist/src/commands/local/auth-provision.d.ts.map +1 -0
  68. package/dist/src/commands/local/auth-provision.js +286 -0
  69. package/dist/src/commands/local/auth-provision.js.map +1 -0
  70. package/dist/src/commands/local/dev-local.d.ts +97 -0
  71. package/dist/src/commands/local/dev-local.d.ts.map +1 -0
  72. package/dist/src/commands/local/dev-local.js +306 -0
  73. package/dist/src/commands/local/dev-local.js.map +1 -0
  74. package/dist/src/commands/local/docker-runner.d.ts +37 -0
  75. package/dist/src/commands/local/docker-runner.d.ts.map +1 -0
  76. package/dist/src/commands/local/docker-runner.js +104 -0
  77. package/dist/src/commands/local/docker-runner.js.map +1 -0
  78. package/dist/src/commands/local/helpers.d.ts +22 -0
  79. package/dist/src/commands/local/helpers.d.ts.map +1 -0
  80. package/dist/src/commands/local/helpers.js +46 -0
  81. package/dist/src/commands/local/helpers.js.map +1 -0
  82. package/dist/src/commands/local/hub-local.d.ts +51 -0
  83. package/dist/src/commands/local/hub-local.d.ts.map +1 -0
  84. package/dist/src/commands/local/hub-local.js +197 -0
  85. package/dist/src/commands/local/hub-local.js.map +1 -0
  86. package/dist/src/commands/local/index.d.ts +23 -0
  87. package/dist/src/commands/local/index.d.ts.map +1 -0
  88. package/dist/src/commands/local/index.js +386 -0
  89. package/dist/src/commands/local/index.js.map +1 -0
  90. package/dist/src/commands/local/mocks.d.ts +361 -0
  91. package/dist/src/commands/local/mocks.d.ts.map +1 -0
  92. package/dist/src/commands/local/mocks.js +756 -0
  93. package/dist/src/commands/local/mocks.js.map +1 -0
  94. package/dist/src/commands/local/seed-zitadel.d.ts +151 -0
  95. package/dist/src/commands/local/seed-zitadel.d.ts.map +1 -0
  96. package/dist/src/commands/local/seed-zitadel.js +408 -0
  97. package/dist/src/commands/local/seed-zitadel.js.map +1 -0
  98. package/dist/src/commands/local/seed.d.ts +106 -0
  99. package/dist/src/commands/local/seed.d.ts.map +1 -0
  100. package/dist/src/commands/local/seed.js +252 -0
  101. package/dist/src/commands/local/seed.js.map +1 -0
  102. package/dist/src/commands/local/stack.d.ts +173 -0
  103. package/dist/src/commands/local/stack.d.ts.map +1 -0
  104. package/dist/src/commands/local/stack.js +499 -0
  105. package/dist/src/commands/local/stack.js.map +1 -0
  106. package/dist/src/commands/login.d.ts +256 -12
  107. package/dist/src/commands/login.d.ts.map +1 -1
  108. package/dist/src/commands/login.js +978 -50
  109. package/dist/src/commands/login.js.map +1 -1
  110. package/dist/src/commands/peer-addressing.d.ts +51 -0
  111. package/dist/src/commands/peer-addressing.d.ts.map +1 -0
  112. package/dist/src/commands/peer-addressing.js +64 -0
  113. package/dist/src/commands/peer-addressing.js.map +1 -0
  114. package/dist/src/commands/port-ownership.d.ts +69 -0
  115. package/dist/src/commands/port-ownership.d.ts.map +1 -0
  116. package/dist/src/commands/port-ownership.js +161 -0
  117. package/dist/src/commands/port-ownership.js.map +1 -0
  118. package/dist/src/commands/registry-publish.d.ts +3 -0
  119. package/dist/src/commands/registry-publish.d.ts.map +1 -0
  120. package/dist/src/commands/registry-publish.js +161 -0
  121. package/dist/src/commands/registry-publish.js.map +1 -0
  122. package/dist/src/commands/registry.d.ts +146 -2
  123. package/dist/src/commands/registry.d.ts.map +1 -1
  124. package/dist/src/commands/registry.js +541 -85
  125. package/dist/src/commands/registry.js.map +1 -1
  126. package/dist/src/commands/secrets/index.d.ts.map +1 -1
  127. package/dist/src/commands/secrets/index.js +15 -1
  128. package/dist/src/commands/secrets/index.js.map +1 -1
  129. package/dist/src/commands/secrets/migrate-config.d.ts +24 -0
  130. package/dist/src/commands/secrets/migrate-config.d.ts.map +1 -0
  131. package/dist/src/commands/secrets/migrate-config.js +277 -0
  132. package/dist/src/commands/secrets/migrate-config.js.map +1 -0
  133. package/dist/src/commands/secrets/set.d.ts +4 -0
  134. package/dist/src/commands/secrets/set.d.ts.map +1 -1
  135. package/dist/src/commands/secrets/set.js +243 -64
  136. package/dist/src/commands/secrets/set.js.map +1 -1
  137. package/dist/src/commands/skills.d.ts +34 -0
  138. package/dist/src/commands/skills.d.ts.map +1 -0
  139. package/dist/src/commands/skills.js +207 -0
  140. package/dist/src/commands/skills.js.map +1 -0
  141. package/dist/src/commands/stack.d.ts.map +1 -1
  142. package/dist/src/commands/stack.js +361 -23
  143. package/dist/src/commands/stack.js.map +1 -1
  144. package/dist/src/commands/temporal.d.ts +15 -0
  145. package/dist/src/commands/temporal.d.ts.map +1 -0
  146. package/dist/src/commands/temporal.js +781 -0
  147. package/dist/src/commands/temporal.js.map +1 -0
  148. package/dist/src/commands/tenant.d.ts +56 -0
  149. package/dist/src/commands/tenant.d.ts.map +1 -0
  150. package/dist/src/commands/tenant.js +233 -0
  151. package/dist/src/commands/tenant.js.map +1 -0
  152. package/dist/src/commands/tunnel/index.d.ts +49 -3
  153. package/dist/src/commands/tunnel/index.d.ts.map +1 -1
  154. package/dist/src/commands/tunnel/index.js +331 -8
  155. package/dist/src/commands/tunnel/index.js.map +1 -1
  156. package/dist/src/commands/vcs/clone.d.ts +3 -0
  157. package/dist/src/commands/vcs/clone.d.ts.map +1 -0
  158. package/dist/src/commands/vcs/clone.js +20 -0
  159. package/dist/src/commands/vcs/clone.js.map +1 -0
  160. package/dist/src/commands/vcs/common.d.ts +21 -0
  161. package/dist/src/commands/vcs/common.d.ts.map +1 -0
  162. package/dist/src/commands/vcs/common.js +62 -0
  163. package/dist/src/commands/vcs/common.js.map +1 -0
  164. package/dist/src/commands/vcs/drafts.d.ts +13 -0
  165. package/dist/src/commands/vcs/drafts.d.ts.map +1 -0
  166. package/dist/src/commands/vcs/drafts.js +45 -0
  167. package/dist/src/commands/vcs/drafts.js.map +1 -0
  168. package/dist/src/commands/vcs/get.d.ts +8 -0
  169. package/dist/src/commands/vcs/get.d.ts.map +1 -0
  170. package/dist/src/commands/vcs/get.js +61 -0
  171. package/dist/src/commands/vcs/get.js.map +1 -0
  172. package/dist/src/commands/vcs/index.d.ts +3 -0
  173. package/dist/src/commands/vcs/index.d.ts.map +1 -0
  174. package/dist/src/commands/vcs/index.js +58 -0
  175. package/dist/src/commands/vcs/index.js.map +1 -0
  176. package/dist/src/commands/vcs/propose.d.ts +23 -0
  177. package/dist/src/commands/vcs/propose.d.ts.map +1 -0
  178. package/dist/src/commands/vcs/propose.js +94 -0
  179. package/dist/src/commands/vcs/propose.js.map +1 -0
  180. package/dist/src/commands/vcs/review.d.ts +15 -0
  181. package/dist/src/commands/vcs/review.d.ts.map +1 -0
  182. package/dist/src/commands/vcs/review.js +35 -0
  183. package/dist/src/commands/vcs/review.js.map +1 -0
  184. package/dist/src/commands/vcs-enrich.d.ts +15 -0
  185. package/dist/src/commands/vcs-enrich.d.ts.map +1 -0
  186. package/dist/src/commands/vcs-enrich.js +28 -0
  187. package/dist/src/commands/vcs-enrich.js.map +1 -0
  188. package/dist/src/commands/vpn/index.d.ts +24 -0
  189. package/dist/src/commands/vpn/index.d.ts.map +1 -0
  190. package/dist/src/commands/vpn/index.js +543 -0
  191. package/dist/src/commands/vpn/index.js.map +1 -0
  192. package/dist/src/commands/vpn/tunnel.d.ts +11 -0
  193. package/dist/src/commands/vpn/tunnel.d.ts.map +1 -0
  194. package/dist/src/commands/vpn/tunnel.js +188 -0
  195. package/dist/src/commands/vpn/tunnel.js.map +1 -0
  196. package/dist/src/commands/workflow.d.ts +24 -0
  197. package/dist/src/commands/workflow.d.ts.map +1 -0
  198. package/dist/src/commands/workflow.js +577 -0
  199. package/dist/src/commands/workflow.js.map +1 -0
  200. package/dist/src/docs/assemble.d.ts +217 -0
  201. package/dist/src/docs/assemble.d.ts.map +1 -0
  202. package/dist/src/docs/assemble.js +739 -0
  203. package/dist/src/docs/assemble.js.map +1 -0
  204. package/dist/src/docs/cli-reference.d.ts +93 -0
  205. package/dist/src/docs/cli-reference.d.ts.map +1 -0
  206. package/dist/src/docs/cli-reference.js +256 -0
  207. package/dist/src/docs/cli-reference.js.map +1 -0
  208. package/dist/src/docs/discover.d.ts +60 -0
  209. package/dist/src/docs/discover.d.ts.map +1 -0
  210. package/dist/src/docs/discover.js +233 -0
  211. package/dist/src/docs/discover.js.map +1 -0
  212. package/dist/src/docs/portal.d.ts +79 -0
  213. package/dist/src/docs/portal.d.ts.map +1 -0
  214. package/dist/src/docs/portal.js +242 -0
  215. package/dist/src/docs/portal.js.map +1 -0
  216. package/dist/src/docs/registry-docs.d.ts +43 -0
  217. package/dist/src/docs/registry-docs.d.ts.map +1 -0
  218. package/dist/src/docs/registry-docs.js +138 -0
  219. package/dist/src/docs/registry-docs.js.map +1 -0
  220. package/dist/src/docs/schema.d.ts +48 -0
  221. package/dist/src/docs/schema.d.ts.map +1 -0
  222. package/dist/src/docs/schema.js +96 -0
  223. package/dist/src/docs/schema.js.map +1 -0
  224. package/dist/src/docs/serve.d.ts +27 -0
  225. package/dist/src/docs/serve.d.ts.map +1 -0
  226. package/dist/src/docs/serve.js +102 -0
  227. package/dist/src/docs/serve.js.map +1 -0
  228. package/dist/src/docs/start.d.ts +80 -0
  229. package/dist/src/docs/start.d.ts.map +1 -0
  230. package/dist/src/docs/start.js +313 -0
  231. package/dist/src/docs/start.js.map +1 -0
  232. package/dist/src/eval/agent-eval.d.mts +14 -0
  233. package/dist/src/eval/agent-eval.d.mts.map +1 -0
  234. package/dist/src/eval/agent-eval.mjs +273 -0
  235. package/dist/src/eval/agent-eval.mjs.map +1 -0
  236. package/dist/src/index.js +624 -7
  237. package/dist/src/index.js.map +7 -1
  238. package/dist/src/program.d.ts +26 -0
  239. package/dist/src/program.d.ts.map +1 -0
  240. package/dist/src/program.js +76 -0
  241. package/dist/src/program.js.map +1 -0
  242. package/dist/src/utils/auth-preflight.d.ts +159 -0
  243. package/dist/src/utils/auth-preflight.d.ts.map +1 -0
  244. package/dist/src/utils/auth-preflight.js +298 -0
  245. package/dist/src/utils/auth-preflight.js.map +1 -0
  246. package/dist/src/utils/aws-auth.d.ts +181 -0
  247. package/dist/src/utils/aws-auth.d.ts.map +1 -0
  248. package/dist/src/utils/aws-auth.js +527 -0
  249. package/dist/src/utils/aws-auth.js.map +1 -0
  250. package/dist/src/utils/bastion.d.ts +1 -1
  251. package/dist/src/utils/bastion.d.ts.map +1 -1
  252. package/dist/src/utils/bastion.js +29 -8
  253. package/dist/src/utils/bastion.js.map +1 -1
  254. package/dist/src/utils/build-info.d.ts +33 -0
  255. package/dist/src/utils/build-info.d.ts.map +1 -0
  256. package/dist/src/utils/build-info.js +102 -0
  257. package/dist/src/utils/build-info.js.map +1 -0
  258. package/dist/src/utils/capture-history.d.ts +62 -0
  259. package/dist/src/utils/capture-history.d.ts.map +1 -0
  260. package/dist/src/utils/capture-history.js +94 -0
  261. package/dist/src/utils/capture-history.js.map +1 -0
  262. package/dist/src/utils/deploy-preflight.d.ts +52 -0
  263. package/dist/src/utils/deploy-preflight.d.ts.map +1 -0
  264. package/dist/src/utils/deploy-preflight.js +183 -0
  265. package/dist/src/utils/deploy-preflight.js.map +1 -0
  266. package/dist/src/utils/errors.d.ts +75 -0
  267. package/dist/src/utils/errors.d.ts.map +1 -0
  268. package/dist/src/utils/errors.js +106 -0
  269. package/dist/src/utils/errors.js.map +1 -0
  270. package/dist/src/utils/first-party-contexts.d.ts +40 -0
  271. package/dist/src/utils/first-party-contexts.d.ts.map +1 -0
  272. package/dist/src/utils/first-party-contexts.js +53 -0
  273. package/dist/src/utils/first-party-contexts.js.map +1 -0
  274. package/dist/src/utils/index.d.ts +2 -0
  275. package/dist/src/utils/index.d.ts.map +1 -1
  276. package/dist/src/utils/index.js +2 -0
  277. package/dist/src/utils/index.js.map +1 -1
  278. package/dist/src/utils/kubeconfig.d.ts +62 -0
  279. package/dist/src/utils/kubeconfig.d.ts.map +1 -0
  280. package/dist/src/utils/kubeconfig.js +118 -0
  281. package/dist/src/utils/kubeconfig.js.map +1 -0
  282. package/dist/src/utils/log.d.ts +27 -1
  283. package/dist/src/utils/log.d.ts.map +1 -1
  284. package/dist/src/utils/log.js +59 -5
  285. package/dist/src/utils/log.js.map +1 -1
  286. package/dist/src/utils/pid.d.ts +47 -0
  287. package/dist/src/utils/pid.d.ts.map +1 -0
  288. package/dist/src/utils/pid.js +83 -0
  289. package/dist/src/utils/pid.js.map +1 -0
  290. package/dist/src/utils/pulumi-run.d.ts +23 -0
  291. package/dist/src/utils/pulumi-run.d.ts.map +1 -0
  292. package/dist/src/utils/pulumi-run.js +112 -0
  293. package/dist/src/utils/pulumi-run.js.map +1 -0
  294. package/dist/src/utils/pulumi.d.ts +15 -0
  295. package/dist/src/utils/pulumi.d.ts.map +1 -1
  296. package/dist/src/utils/pulumi.js +35 -0
  297. package/dist/src/utils/pulumi.js.map +1 -1
  298. package/dist/src/utils/reachability.d.ts +29 -0
  299. package/dist/src/utils/reachability.d.ts.map +1 -0
  300. package/dist/src/utils/reachability.js +81 -0
  301. package/dist/src/utils/reachability.js.map +1 -0
  302. package/dist/src/utils/recover-conversation.d.ts +154 -0
  303. package/dist/src/utils/recover-conversation.d.ts.map +1 -0
  304. package/dist/src/utils/recover-conversation.js +314 -0
  305. package/dist/src/utils/recover-conversation.js.map +1 -0
  306. package/dist/src/utils/registry-broker.d.ts +148 -0
  307. package/dist/src/utils/registry-broker.d.ts.map +1 -0
  308. package/dist/src/utils/registry-broker.js +180 -0
  309. package/dist/src/utils/registry-broker.js.map +1 -0
  310. package/dist/src/utils/socks-forward.d.ts +40 -0
  311. package/dist/src/utils/socks-forward.d.ts.map +1 -0
  312. package/dist/src/utils/socks-forward.js +97 -0
  313. package/dist/src/utils/socks-forward.js.map +1 -0
  314. package/dist/src/utils/stack-flag.d.ts +23 -0
  315. package/dist/src/utils/stack-flag.d.ts.map +1 -0
  316. package/dist/src/utils/stack-flag.js +41 -0
  317. package/dist/src/utils/stack-flag.js.map +1 -0
  318. package/dist/src/utils/tailscale-targets.d.ts +52 -0
  319. package/dist/src/utils/tailscale-targets.d.ts.map +1 -0
  320. package/dist/src/utils/tailscale-targets.js +93 -0
  321. package/dist/src/utils/tailscale-targets.js.map +1 -0
  322. package/dist/src/utils/tailscale.d.ts +277 -0
  323. package/dist/src/utils/tailscale.d.ts.map +1 -0
  324. package/dist/src/utils/tailscale.js +1007 -0
  325. package/dist/src/utils/tailscale.js.map +1 -0
  326. package/dist/src/utils/temporal-auth.d.ts +43 -0
  327. package/dist/src/utils/temporal-auth.d.ts.map +1 -0
  328. package/dist/src/utils/temporal-auth.js +176 -0
  329. package/dist/src/utils/temporal-auth.js.map +1 -0
  330. package/dist/src/utils/temporal-codec.d.ts +101 -0
  331. package/dist/src/utils/temporal-codec.d.ts.map +1 -0
  332. package/dist/src/utils/temporal-codec.js +319 -0
  333. package/dist/src/utils/temporal-codec.js.map +1 -0
  334. package/dist/src/utils/tunnel-ownership.d.ts +130 -0
  335. package/dist/src/utils/tunnel-ownership.d.ts.map +1 -0
  336. package/dist/src/utils/tunnel-ownership.js +274 -0
  337. package/dist/src/utils/tunnel-ownership.js.map +1 -0
  338. package/dist/src/utils/vpn-join.d.ts +32 -0
  339. package/dist/src/utils/vpn-join.d.ts.map +1 -0
  340. package/dist/src/utils/vpn-join.js +62 -0
  341. package/dist/src/utils/vpn-join.js.map +1 -0
  342. package/dist/src/utils/vpn.d.ts +62 -0
  343. package/dist/src/utils/vpn.d.ts.map +1 -0
  344. package/dist/src/utils/vpn.js +183 -0
  345. package/dist/src/utils/vpn.js.map +1 -0
  346. package/dist/src/utils/workflow-fingerprint.d.ts +49 -0
  347. package/dist/src/utils/workflow-fingerprint.d.ts.map +1 -0
  348. package/dist/src/utils/workflow-fingerprint.js +135 -0
  349. package/dist/src/utils/workflow-fingerprint.js.map +1 -0
  350. package/dist/src/utils/worktree-identity.d.ts +86 -0
  351. package/dist/src/utils/worktree-identity.d.ts.map +1 -0
  352. package/dist/src/utils/worktree-identity.js +164 -0
  353. package/dist/src/utils/worktree-identity.js.map +1 -0
  354. package/fragments/agents/AGENTS.md.hbs +92 -0
  355. package/fragments/agents/CLAUDE.md.hbs +8 -0
  356. package/fragments/base/Pulumi.dev.yaml.hbs +10 -0
  357. package/fragments/base/Pulumi.yaml.hbs +9 -0
  358. package/fragments/base/index.ts.hbs +107 -0
  359. package/fragments/base/package.json.hbs +22 -0
  360. package/{templates/api-web-db/api → fragments/base}/tsconfig.json +3 -4
  361. package/fragments/bucket/api/src/storage.ts.hbs +81 -0
  362. package/fragments/database/api/src/db.ts.hbs +23 -0
  363. package/fragments/database/prisma/schema.prisma.hbs +18 -0
  364. package/{templates/api-web-db → fragments/service}/api/.dockerignore +2 -0
  365. package/fragments/service/api/package.json.hbs +40 -0
  366. package/fragments/service/api/src/index.ts.hbs +58 -0
  367. package/{templates/api-web-db → fragments/service/api}/tsconfig.json +5 -3
  368. package/fragments/temporal/worker/.dockerignore +4 -0
  369. package/fragments/temporal/worker/Dockerfile +15 -0
  370. package/{templates/temporal-api-worker → fragments/temporal}/worker/package.json.hbs +3 -2
  371. package/fragments/temporal/worker/src/activities.ts.hbs +14 -0
  372. package/fragments/temporal/worker/src/worker.ts.hbs +27 -0
  373. package/fragments/temporal/worker/src/workflows.ts.hbs +24 -0
  374. package/fragments/temporal/worker/tsconfig.json +13 -0
  375. package/package.json +35 -21
  376. package/skills/core/SKILL.md +365 -0
  377. package/skills/pull-remote-agent-context/SKILL.md +194 -0
  378. package/stack/docker-compose.hub.yml +134 -0
  379. package/stack/docker-compose.yml +447 -0
  380. package/stack/hub/Dockerfile.api +18 -0
  381. package/stack/hub/Dockerfile.auth +10 -0
  382. package/stack/hub/Dockerfile.ui +10 -0
  383. package/stack/init/01-databases.sql +12 -0
  384. package/stack/observability/blackbox.yml +20 -0
  385. package/stack/observability/otel-collector.yaml +73 -0
  386. package/stack/observability/prometheus.yml +36 -0
  387. package/stack/observability/tempo.yaml +25 -0
  388. package/stack/temporal/local.yaml +44 -0
  389. package/templates/api-auth/AGENTS.md.hbs +16 -0
  390. package/templates/api-auth/Pulumi.dev.yaml.hbs +8 -0
  391. package/templates/api-auth/Pulumi.yaml.hbs +8 -0
  392. package/templates/api-auth/README.md.hbs +67 -0
  393. package/templates/api-auth/api/package.json.hbs +28 -0
  394. package/templates/api-auth/api/src/index.ts.hbs +96 -0
  395. package/templates/api-auth/api/src/schema.ts.hbs +35 -0
  396. package/templates/api-auth/api/src/seed-authz.ts.hbs +48 -0
  397. package/templates/api-auth/api/src/spicedb-http-provider.ts.hbs +89 -0
  398. package/templates/api-auth/index.ts.hbs +65 -0
  399. package/templates/api-auth/package.json.hbs +20 -0
  400. package/templates/api-auth/skills/develop/SKILL.md.hbs +32 -0
  401. package/templates/api-role-gating/AGENTS.md.hbs +20 -0
  402. package/templates/api-role-gating/Pulumi.dev.yaml.hbs +8 -0
  403. package/templates/api-role-gating/Pulumi.yaml.hbs +8 -0
  404. package/templates/api-role-gating/README.md.hbs +64 -0
  405. package/templates/api-role-gating/api/Dockerfile +17 -0
  406. package/templates/api-role-gating/api/package.json.hbs +28 -0
  407. package/templates/api-role-gating/api/src/authn.ts.hbs +29 -0
  408. package/templates/api-role-gating/api/src/authz.ts.hbs +12 -0
  409. package/templates/api-role-gating/api/src/main.ts.hbs +58 -0
  410. package/templates/api-role-gating/api/src/schema.ts.hbs +22 -0
  411. package/templates/api-role-gating/api/tsconfig.json +13 -0
  412. package/templates/api-role-gating/index.ts.hbs +107 -0
  413. package/templates/api-role-gating/package.json.hbs +21 -0
  414. package/templates/api-role-gating/skills/develop/SKILL.md.hbs +60 -0
  415. package/templates/api-role-gating/tsconfig.json +10 -0
  416. package/templates/apps-repo/README.md.hbs +24 -0
  417. package/templates/apps-repo/gitignore +41 -0
  418. package/templates/apps-repo/npmrc.hbs +7 -0
  419. package/templates/apps-repo/package.json.hbs +15 -0
  420. package/templates/apps-repo/pnpm-workspace.yaml +3 -0
  421. package/templates/apps-repo/tsconfig.json +18 -0
  422. package/templates/external-service/AGENTS.md.hbs +20 -0
  423. package/templates/external-service/Pulumi.dev.yaml.hbs +8 -0
  424. package/templates/external-service/Pulumi.yaml.hbs +8 -0
  425. package/templates/external-service/README.md.hbs +56 -0
  426. package/templates/external-service/api/Dockerfile +15 -0
  427. package/templates/external-service/api/package.json.hbs +25 -0
  428. package/templates/external-service/api/src/index.ts.hbs +81 -0
  429. package/templates/external-service/index.ts.hbs +82 -0
  430. package/templates/external-service/mocks/vendorpay/package.json.hbs +9 -0
  431. package/templates/external-service/mocks/vendorpay/server.mjs.hbs +61 -0
  432. package/templates/external-service/package.json.hbs +34 -0
  433. package/templates/external-service/skills/develop/SKILL.md.hbs +55 -0
  434. package/templates/external-service/tsconfig.json +10 -0
  435. package/templates/platform-repo/AGENTS.md.hbs +18 -0
  436. package/templates/platform-repo/README.md.hbs +38 -0
  437. package/templates/platform-repo/core/Pulumi.yaml.hbs +12 -0
  438. package/templates/platform-repo/core/Pulumi.{{tenant}}-{{env}}.yaml.hbs +57 -0
  439. package/templates/platform-repo/core/index.ts +62 -0
  440. package/templates/platform-repo/core/package.json.hbs +22 -0
  441. package/templates/platform-repo/core/tsconfig.json +8 -0
  442. package/templates/platform-repo/package.json.hbs +15 -0
  443. package/templates/platform-repo/platform/Pulumi.yaml.hbs +12 -0
  444. package/templates/platform-repo/platform/Pulumi.{{tenant}}-{{env}}.yaml.hbs +59 -0
  445. package/templates/platform-repo/platform/index.ts +95 -0
  446. package/templates/platform-repo/platform/package.json.hbs +26 -0
  447. package/templates/platform-repo/platform/tsconfig.json +8 -0
  448. package/templates/platform-repo/pnpm-workspace.yaml +3 -0
  449. package/templates/workflow/AGENTS.md.hbs +15 -0
  450. package/templates/workflow/Pulumi.dev.yaml.hbs +8 -0
  451. package/templates/workflow/Pulumi.yaml.hbs +8 -0
  452. package/templates/workflow/README.md.hbs +45 -0
  453. package/templates/workflow/api/.dockerignore +4 -0
  454. package/templates/workflow/api/Dockerfile +15 -0
  455. package/templates/{temporal-api-worker → workflow}/api/package.json.hbs +8 -6
  456. package/templates/workflow/api/src/index.ts.hbs +130 -0
  457. package/templates/workflow/api/tsconfig.json +14 -0
  458. package/templates/workflow/index.ts.hbs +67 -0
  459. package/templates/workflow/package.json.hbs +20 -0
  460. package/templates/workflow/skills/develop/SKILL.md.hbs +32 -0
  461. package/templates/workflow/tsconfig.json +10 -0
  462. package/templates/workflow/worker/.dockerignore +4 -0
  463. package/templates/workflow/worker/Dockerfile +13 -0
  464. package/templates/workflow/worker/package.json.hbs +25 -0
  465. package/templates/workflow/worker/src/worker.ts.hbs +24 -0
  466. package/templates/workflow/worker/tsconfig.json +14 -0
  467. package/dist/src/commands/devbox.d.ts +0 -22
  468. package/dist/src/commands/devbox.d.ts.map +0 -1
  469. package/dist/src/commands/devbox.js +0 -463
  470. package/dist/src/commands/devbox.js.map +0 -1
  471. package/templates/api-web-db/api/Dockerfile +0 -16
  472. package/templates/api-web-db/api/package.json.hbs +0 -21
  473. package/templates/api-web-db/api/src/index.ts.hbs +0 -123
  474. package/templates/api-web-db/package.json.hbs +0 -27
  475. package/templates/api-web-db/sst.config.ts.hbs +0 -151
  476. package/templates/api-web-db/web/.dockerignore +0 -3
  477. package/templates/api-web-db/web/Dockerfile +0 -17
  478. package/templates/api-web-db/web/app/lib/db.server.ts +0 -36
  479. package/templates/api-web-db/web/app/root.tsx +0 -29
  480. package/templates/api-web-db/web/app/routes/home.tsx.hbs +0 -114
  481. package/templates/api-web-db/web/app/routes.ts +0 -3
  482. package/templates/api-web-db/web/package.json.hbs +0 -30
  483. package/templates/api-web-db/web/prisma/schema.prisma +0 -25
  484. package/templates/api-web-db/web/prisma.config.ts +0 -18
  485. package/templates/api-web-db/web/react-router.config.ts +0 -5
  486. package/templates/api-web-db/web/tsconfig.json +0 -19
  487. package/templates/api-web-db/web/vite.config.ts +0 -9
  488. package/templates/temporal-api-worker/README.md.hbs +0 -133
  489. package/templates/temporal-api-worker/api/src/index.ts.hbs +0 -145
  490. package/templates/temporal-api-worker/package.json.hbs +0 -29
  491. package/templates/temporal-api-worker/sst.config.ts.hbs +0 -161
  492. package/templates/temporal-api-worker/worker/Dockerfile +0 -11
  493. package/templates/temporal-api-worker/worker/src/bundle-workflows.ts +0 -38
  494. package/templates/temporal-api-worker/worker/src/worker.ts.hbs +0 -93
  495. /package/templates/{temporal-api-worker → api-auth}/api/.dockerignore +0 -0
  496. /package/templates/{temporal-api-worker → api-auth}/api/Dockerfile +0 -0
  497. /package/templates/{temporal-api-worker → api-auth}/api/tsconfig.json +0 -0
  498. /package/templates/{temporal-api-worker → api-auth}/tsconfig.json +0 -0
  499. /package/templates/{temporal-api-worker/worker → api-role-gating/api}/.dockerignore +0 -0
  500. /package/templates/{temporal-api-worker/worker → external-service/api}/tsconfig.json +0 -0
  501. /package/templates/{temporal-api-worker → workflow}/api/src/encryption-codec.ts +0 -0
  502. /package/templates/{temporal-api-worker → workflow}/worker/src/activities.ts.hbs +0 -0
  503. /package/templates/{temporal-api-worker → workflow}/worker/src/encryption-codec.ts +0 -0
  504. /package/templates/{temporal-api-worker → workflow}/worker/src/workflows.ts.hbs +0 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Shared CLI error type with structured remediation.
3
+ *
4
+ * Every failure along the golden path should tell the user the exact `mesh`
5
+ * command (or doc) that fixes it. Remediation strings must be commands or
6
+ * docs — never "ask <person>".
7
+ */
8
+ import chalk from "chalk";
9
+ export class MeshCliError extends Error {
10
+ remediation;
11
+ exitCode;
12
+ constructor(message, options = {}) {
13
+ super(message, options.cause !== undefined ? { cause: options.cause } : undefined);
14
+ this.name = "MeshCliError";
15
+ this.remediation = options.remediation;
16
+ this.exitCode = options.exitCode ?? 1;
17
+ }
18
+ }
19
+ /**
20
+ * Render an error's BODY — the message plus its "→ run: <command>" /
21
+ * "→ see: <docs>" remediation lines, with no leading severity glyph.
22
+ *
23
+ * Use this when the caller supplies its own glyph: a recovery path that logs a
24
+ * refusal through `logWarn` (which prefixes ⚠) and carries on would otherwise
25
+ * print "⚠ ✗ …". The remediation lines are the part that must survive — they
26
+ * name the corrupt file to delete.
27
+ */
28
+ export function renderErrorBody(err) {
29
+ const message = err instanceof Error ? err.message : String(err);
30
+ if (!(err instanceof MeshCliError))
31
+ return message;
32
+ const lines = [message];
33
+ if (err.remediation?.command) {
34
+ lines.push(chalk.cyan(" → run: ") + err.remediation.command);
35
+ }
36
+ if (err.remediation?.docs) {
37
+ lines.push(chalk.cyan(" → see: ") + err.remediation.docs);
38
+ }
39
+ return lines.join("\n");
40
+ }
41
+ /**
42
+ * Render an error for humans. MeshCliError gets its remediation appended as
43
+ * "→ run: <command>" / "→ see: <docs>" lines; anything else renders its message.
44
+ */
45
+ export function renderError(err) {
46
+ return chalk.red("✗") + " " + renderErrorBody(err);
47
+ }
48
+ /**
49
+ * Render an error as JSON for agents. Same structure as the human output:
50
+ * { error, remediation?: { command?, docs?, autoFixable? } }.
51
+ */
52
+ export function renderErrorJson(err) {
53
+ if (err instanceof MeshCliError) {
54
+ return JSON.stringify({
55
+ error: err.message,
56
+ ...(err.remediation ? { remediation: err.remediation } : {}),
57
+ });
58
+ }
59
+ return JSON.stringify({ error: err instanceof Error ? err.message : String(err) });
60
+ }
61
+ let jsonPayloadEmitted = false;
62
+ /**
63
+ * Print a command's `--json` payload — the single machine-readable document on
64
+ * stdout — and record that it happened.
65
+ *
66
+ * A command that emits a payload and *then* throws (the `mesh init` doctor
67
+ * throws by design whenever a check fails) used to produce TWO concatenated
68
+ * JSON documents on stdout, because `handleCliError` appended `{"error":…}`.
69
+ * Two documents is not JSON: `mesh init app-tenant --json | jq` failed to parse
70
+ * on exactly the failure path a script cares about. Routing every payload
71
+ * through here lets the handler know stdout is already spoken for.
72
+ */
73
+ export function emitJsonPayload(payload) {
74
+ console.log(JSON.stringify(payload, null, 2));
75
+ jsonPayloadEmitted = true;
76
+ }
77
+ /** True once a command has written its `--json` payload to stdout. */
78
+ export function hasEmittedJsonPayload() {
79
+ return jsonPayloadEmitted;
80
+ }
81
+ /** Test seam — the flag is module state, so specs have to be able to clear it. */
82
+ export function resetJsonPayloadEmitted() {
83
+ jsonPayloadEmitted = false;
84
+ }
85
+ /**
86
+ * Top-level handler for bin/mesh.ts. Prints the error (JSON when the
87
+ * invocation asked for --json anywhere, since per-command flags aren't
88
+ * parsed once dispatch has failed) and exits with the error's code.
89
+ *
90
+ * When the command already emitted a `--json` payload, that payload IS the
91
+ * machine surface — and it says strictly more than this error would (the
92
+ * doctor's payload carries `ok:false` plus a per-check `fix` command). So the
93
+ * error goes to stderr as human diagnostics and stdout keeps exactly one
94
+ * parseable document.
95
+ */
96
+ export function handleCliError(err) {
97
+ const wantsJson = process.argv.includes("--json");
98
+ if (wantsJson && !hasEmittedJsonPayload()) {
99
+ console.log(renderErrorJson(err));
100
+ }
101
+ else {
102
+ console.error(renderError(err));
103
+ }
104
+ process.exit(err instanceof MeshCliError ? err.exitCode : 1);
105
+ }
106
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/utils/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pinned short-name → FQDN map for FIRST-PARTY Mesh platforms.
3
+ *
4
+ * ## Why this file exists
5
+ *
6
+ * `mesh login mesh.dev` on a clean laptop used to be unresolvable. Discovery
7
+ * has two paths: SSM (needs AWS credentials — the thing we are removing) and
8
+ * the anonymous `https://cli.<domain>/.well-known/mesh.json` endpoint. The
9
+ * HTTPS path is deliberately gated to contexts with ≥2 dots, because hitting
10
+ * `https://cli.<short-name>/…` for an arbitrary short context would let whoever
11
+ * registers that domain seed our cached issuer/clientId — login phishing.
12
+ *
13
+ * So the short context every internal doc tells a new developer to use was
14
+ * exactly the one that could not resolve without AWS.
15
+ *
16
+ * ## Why a compiled-in map is the safe fix
17
+ *
18
+ * The alias is resolved from THIS table, which ships inside the CLI and is
19
+ * changed only by a reviewed commit. It is not read from the network, from
20
+ * `~/.config/mesh`, or from an environment variable, so it cannot be seeded by
21
+ * an attacker — which is the property the ≥2-dot guard protects and the reason
22
+ * that guard must NOT be loosened instead.
23
+ *
24
+ * ## Adding an entry
25
+ *
26
+ * Only add a domain Trabian controls and has verified serves
27
+ * `/.well-known/mesh.json`. The map is the trust anchor; a typo here is a
28
+ * phishing vector, so treat additions as a security review, not a config edit.
29
+ */
30
+ export declare const FIRST_PARTY_CONTEXTS: Readonly<Record<string, string>>;
31
+ /**
32
+ * The FQDN to run anonymous HTTPS discovery against for a short first-party
33
+ * context, or null when the context is not a pinned alias.
34
+ *
35
+ * `Object.hasOwn` rather than a bare lookup: a plain-object index answers
36
+ * `constructor` / `toString` from the prototype chain, and this function's
37
+ * answer decides which host we trust with our issuer + client id.
38
+ */
39
+ export declare function firstPartyDomainFor(context: string): string | null;
40
+ //# sourceMappingURL=first-party-contexts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-party-contexts.d.ts","sourceRoot":"","sources":["../../../src/utils/first-party-contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhE,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIlE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Pinned short-name → FQDN map for FIRST-PARTY Mesh platforms.
3
+ *
4
+ * ## Why this file exists
5
+ *
6
+ * `mesh login mesh.dev` on a clean laptop used to be unresolvable. Discovery
7
+ * has two paths: SSM (needs AWS credentials — the thing we are removing) and
8
+ * the anonymous `https://cli.<domain>/.well-known/mesh.json` endpoint. The
9
+ * HTTPS path is deliberately gated to contexts with ≥2 dots, because hitting
10
+ * `https://cli.<short-name>/…` for an arbitrary short context would let whoever
11
+ * registers that domain seed our cached issuer/clientId — login phishing.
12
+ *
13
+ * So the short context every internal doc tells a new developer to use was
14
+ * exactly the one that could not resolve without AWS.
15
+ *
16
+ * ## Why a compiled-in map is the safe fix
17
+ *
18
+ * The alias is resolved from THIS table, which ships inside the CLI and is
19
+ * changed only by a reviewed commit. It is not read from the network, from
20
+ * `~/.config/mesh`, or from an environment variable, so it cannot be seeded by
21
+ * an attacker — which is the property the ≥2-dot guard protects and the reason
22
+ * that guard must NOT be loosened instead.
23
+ *
24
+ * ## Adding an entry
25
+ *
26
+ * Only add a domain Trabian controls and has verified serves
27
+ * `/.well-known/mesh.json`. The map is the trust anchor; a typo here is a
28
+ * phishing vector, so treat additions as a security review, not a config edit.
29
+ */
30
+ export const FIRST_PARTY_CONTEXTS = Object.freeze({
31
+ // Verified 2026-08-14: https://cli.dev.platform.meshtech.io/.well-known/mesh.json
32
+ // answers with the platform's issuer + CLI client id + registryBroker,
33
+ // anonymously. (Repointed from dev.trabian.meshtech.io — the trabian tenant
34
+ // platform lives in a different AWS account with no registry; the
35
+ // platform-dev stack in the registry-owning account is the developer front
36
+ // door. mesh-sandbox#32 / #3587.)
37
+ "mesh.dev": "dev.platform.meshtech.io",
38
+ });
39
+ /**
40
+ * The FQDN to run anonymous HTTPS discovery against for a short first-party
41
+ * context, or null when the context is not a pinned alias.
42
+ *
43
+ * `Object.hasOwn` rather than a bare lookup: a plain-object index answers
44
+ * `constructor` / `toString` from the prototype chain, and this function's
45
+ * answer decides which host we trust with our issuer + client id.
46
+ */
47
+ export function firstPartyDomainFor(context) {
48
+ if (!Object.hasOwn(FIRST_PARTY_CONTEXTS, context))
49
+ return null;
50
+ const domain = FIRST_PARTY_CONTEXTS[context];
51
+ return typeof domain === "string" && domain ? domain : null;
52
+ }
53
+ //# sourceMappingURL=first-party-contexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-party-contexts.js","sourceRoot":"","sources":["../../../src/utils/first-party-contexts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAqC,MAAM,CAAC,MAAM,CAAC;IAClF,kFAAkF;IAClF,uEAAuE;IACvE,4EAA4E;IAC5E,kEAAkE;IAClE,2EAA2E;IAC3E,kCAAkC;IAClC,UAAU,EAAE,0BAA0B;CACvC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/D,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC"}
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Utility exports
3
3
  */
4
+ export * from "./errors.js";
4
5
  export * from "./log.js";
5
6
  export * from "./context.js";
6
7
  export * from "./bastion.js";
7
8
  export * from "./credentials.js";
8
9
  export * from "./pulumi.js";
10
+ export * from "./vpn.js";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Utility exports
3
3
  */
4
+ export * from "./errors.js";
4
5
  export * from "./log.js";
5
6
  export * from "./context.js";
6
7
  export * from "./bastion.js";
7
8
  export * from "./credentials.js";
8
9
  export * from "./pulumi.js";
10
+ export * from "./vpn.js";
9
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,62 @@
1
+ interface EksClusterData {
2
+ clusterEndpoint: string;
3
+ clusterCaData: string;
4
+ clusterName: string;
5
+ }
6
+ /**
7
+ * Build a kubeconfig YAML that authenticates to `cluster` via `aws eks get-token`.
8
+ * Pure — no I/O. The `region` is for the get-token exec args (the active AWS
9
+ * identity is whatever the process runs as: deployer / SSO / CI).
10
+ */
11
+ export declare function buildKubeconfig(cluster: EksClusterData, region: string): string;
12
+ /**
13
+ * Deterministic path of the session-scoped kubeconfig written by
14
+ * {@link ensureKubeconfig}. Exposed so callers can point `KUBECONFIG` at the
15
+ * last-good file when a fresh SSM re-resolve isn't available (e.g. on
16
+ * `mesh dev restart --refresh-env`), rather than letting kubectl fall back to
17
+ * `~/.kube/config`.
18
+ */
19
+ export declare function sessionKubeconfigPath(sessionName: string): string;
20
+ /** Why {@link ensureKubeconfig} couldn't resolve the cluster. */
21
+ export interface EnsureKubeconfigFailure {
22
+ /** The SSM parameter name that was read (or attempted). */
23
+ parameter: string;
24
+ /** The exception thrown, or a synthetic Error for empty/malformed data. */
25
+ error: unknown;
26
+ }
27
+ export interface EnsureKubeconfigDeps {
28
+ /** SSM GetParameter (decrypted value or undefined) — injectable for tests. */
29
+ getParameter?: (name: string) => Promise<string | undefined>;
30
+ /**
31
+ * Invoked when cluster resolution fails, with the parameter tried and the
32
+ * underlying error — so callers can say WHAT failed instead of guessing
33
+ * "check your SSM read access" at the user (MESH-2515).
34
+ */
35
+ onError?: (failure: EnsureKubeconfigFailure) => void;
36
+ }
37
+ /**
38
+ * The HUB platform name for platform-level resource lookups (EKS export,
39
+ * bastion). `platform.name` in the dev output is the hub (e.g. "trabian");
40
+ * when absent — outputs predating the field — fall back to the default hub
41
+ * "mesh", NEVER to the app tenant. This one definition pins the axis that
42
+ * regressed in the original MESH-2515 bug.
43
+ */
44
+ export declare function resolveHubPlatformName(platform: {
45
+ name?: string;
46
+ tenant?: string;
47
+ env?: string;
48
+ } | undefined): string;
49
+ /**
50
+ * Resolve the hub EKS cluster from SSM and write a session-scoped kubeconfig.
51
+ *
52
+ * Reads `/mesh-platform/{platformName}/{env}/core/eks` — platform-level cluster
53
+ * data lives under the app's HUB platform (`platform.name` in the dev output,
54
+ * e.g. "trabian"; "mesh" is only the default hub, MESH-2515). Writes to
55
+ * `${tmpdir}/mesh-dev-sessions/{sessionName}.kubeconfig` (never touches
56
+ * ~/.kube/config). Returns the path, or `null` if the cluster data can't be
57
+ * resolved (best-effort — the caller continues without it; the failure detail
58
+ * goes to `deps.onError`).
59
+ */
60
+ export declare function ensureKubeconfig(platformName: string, env: string, sessionName: string, deps?: EnsureKubeconfigDeps): Promise<string | null>;
61
+ export {};
62
+ //# sourceMappingURL=kubeconfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubeconfig.d.ts","sourceRoot":"","sources":["../../../src/utils/kubeconfig.ts"],"names":[],"mappings":"AAiBA,UAAU,cAAc;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA4B/E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,iEAAiE;AACjE,MAAM,WAAW,uBAAuB;IACtC,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7D;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GACrE,MAAM,CAER;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6BxB"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Turnkey kubeconfig for `mesh dev`.
3
+ *
4
+ * `mesh dev` shells out to `kubectl` (Temporal encoding-key read, temporal-pod
5
+ * env fallback). Rather than depend on the operator's ambient ~/.kube/config
6
+ * (which may be unset/stale, and which the apps-deployer role can't populate via
7
+ * `aws eks update-kubeconfig` — it lacks `eks:DescribeCluster`), we build a
8
+ * kubeconfig from the platform EKS cluster data in SSM and authenticate via
9
+ * `aws eks get-token` (STS-only — needs just the cluster name).
10
+ *
11
+ * Mirrors the kubeconfig the Pulumi k8s provider builds in
12
+ * `@mesh-tech/infra-components` AppEnvironment.buildExecKubeconfig.
13
+ */
14
+ import * as fs from 'fs';
15
+ import * as os from 'os';
16
+ import * as path from 'path';
17
+ /**
18
+ * Build a kubeconfig YAML that authenticates to `cluster` via `aws eks get-token`.
19
+ * Pure — no I/O. The `region` is for the get-token exec args (the active AWS
20
+ * identity is whatever the process runs as: deployer / SSO / CI).
21
+ */
22
+ export function buildKubeconfig(cluster, region) {
23
+ return `apiVersion: v1
24
+ kind: Config
25
+ clusters:
26
+ - cluster:
27
+ server: ${cluster.clusterEndpoint}
28
+ certificate-authority-data: ${cluster.clusterCaData}
29
+ name: eks-cluster
30
+ contexts:
31
+ - context:
32
+ cluster: eks-cluster
33
+ user: eks-user
34
+ name: eks-context
35
+ current-context: eks-context
36
+ users:
37
+ - name: eks-user
38
+ user:
39
+ exec:
40
+ apiVersion: client.authentication.k8s.io/v1beta1
41
+ command: aws
42
+ args:
43
+ - eks
44
+ - get-token
45
+ - --cluster-name
46
+ - ${cluster.clusterName}
47
+ - --region
48
+ - ${region}
49
+ `;
50
+ }
51
+ /**
52
+ * Deterministic path of the session-scoped kubeconfig written by
53
+ * {@link ensureKubeconfig}. Exposed so callers can point `KUBECONFIG` at the
54
+ * last-good file when a fresh SSM re-resolve isn't available (e.g. on
55
+ * `mesh dev restart --refresh-env`), rather than letting kubectl fall back to
56
+ * `~/.kube/config`.
57
+ */
58
+ export function sessionKubeconfigPath(sessionName) {
59
+ return path.join(os.tmpdir(), 'mesh-dev-sessions', `${sessionName}.kubeconfig`);
60
+ }
61
+ /**
62
+ * The HUB platform name for platform-level resource lookups (EKS export,
63
+ * bastion). `platform.name` in the dev output is the hub (e.g. "trabian");
64
+ * when absent — outputs predating the field — fall back to the default hub
65
+ * "mesh", NEVER to the app tenant. This one definition pins the axis that
66
+ * regressed in the original MESH-2515 bug.
67
+ */
68
+ export function resolveHubPlatformName(platform) {
69
+ return platform?.name ?? 'mesh';
70
+ }
71
+ async function ssmGetParameter(name) {
72
+ const { SSMClient, GetParameterCommand } = await import('@aws-sdk/client-ssm');
73
+ const ssm = new SSMClient({ region: process.env.AWS_REGION || 'us-east-2' });
74
+ const resp = await ssm.send(new GetParameterCommand({ Name: name, WithDecryption: true }));
75
+ return resp.Parameter?.Value;
76
+ }
77
+ /**
78
+ * Resolve the hub EKS cluster from SSM and write a session-scoped kubeconfig.
79
+ *
80
+ * Reads `/mesh-platform/{platformName}/{env}/core/eks` — platform-level cluster
81
+ * data lives under the app's HUB platform (`platform.name` in the dev output,
82
+ * e.g. "trabian"; "mesh" is only the default hub, MESH-2515). Writes to
83
+ * `${tmpdir}/mesh-dev-sessions/{sessionName}.kubeconfig` (never touches
84
+ * ~/.kube/config). Returns the path, or `null` if the cluster data can't be
85
+ * resolved (best-effort — the caller continues without it; the failure detail
86
+ * goes to `deps.onError`).
87
+ */
88
+ export async function ensureKubeconfig(platformName, env, sessionName, deps = {}) {
89
+ const parameter = `/mesh-platform/${platformName}/${env}/core/eks`;
90
+ const getParameter = deps.getParameter ?? ssmGetParameter;
91
+ let cluster;
92
+ try {
93
+ const value = await getParameter(parameter);
94
+ if (!value)
95
+ throw new Error('parameter is empty or missing');
96
+ const parsed = JSON.parse(value);
97
+ if (!parsed.clusterEndpoint || !parsed.clusterCaData || !parsed.clusterName) {
98
+ throw new Error('cluster data is missing clusterEndpoint/clusterCaData/clusterName');
99
+ }
100
+ cluster = {
101
+ clusterEndpoint: parsed.clusterEndpoint,
102
+ clusterCaData: parsed.clusterCaData,
103
+ clusterName: parsed.clusterName,
104
+ };
105
+ }
106
+ catch (error) {
107
+ deps.onError?.({ parameter, error });
108
+ return null;
109
+ }
110
+ const region = process.env.AWS_REGION || 'us-east-2';
111
+ const kubeconfigPath = sessionKubeconfigPath(sessionName);
112
+ if (!fs.existsSync(path.dirname(kubeconfigPath))) {
113
+ fs.mkdirSync(path.dirname(kubeconfigPath), { recursive: true });
114
+ }
115
+ fs.writeFileSync(kubeconfigPath, buildKubeconfig(cluster, region), { mode: 0o600 });
116
+ return kubeconfigPath;
117
+ }
118
+ //# sourceMappingURL=kubeconfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubeconfig.js","sourceRoot":"","sources":["../../../src/utils/kubeconfig.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,34 @@
1
1
  /**
2
- * Logging utilities with colored output
2
+ * Logging utilities with colored output.
3
+ *
4
+ * Non-TTY streams (CI, agent runs, piped output) get an [HH:MM:SS] prefix on
5
+ * every line so long quiet stretches are attributable after the fact
6
+ * (MESH-2479); interactive terminals stay clean. Override with
7
+ * MESH_LOG_TIMESTAMPS=1 (force on) / =0 (force off).
3
8
  */
9
+ /**
10
+ * Pure prefix decision, exported for tests: timestamps when the env flag says
11
+ * so, else whenever stderr is not a TTY.
12
+ */
13
+ export declare function logPrefix(opts: {
14
+ isTTY: boolean;
15
+ envFlag: string | undefined;
16
+ now: Date;
17
+ }): string;
4
18
  export declare function logInfo(message: string): void;
5
19
  export declare function logSuccess(message: string): void;
6
20
  export declare function logWarn(message: string): void;
7
21
  export declare function logError(message: string): void;
22
+ /** Render elapsed milliseconds compactly: "45s", "2m 30s", "1h 5m". */
23
+ export declare function formatElapsed(ms: number): string;
24
+ /**
25
+ * Periodic "still working" line during a long silent operation (registry
26
+ * fetches, image builds) so a non-TTY first run never sits at 0 bytes of
27
+ * output for minutes (MESH-2479). `touch()` marks recent real output, which
28
+ * suppresses the next beat — the heartbeat only fills silence.
29
+ */
30
+ export declare function startHeartbeat(label: string, intervalMs?: number): {
31
+ stop: () => void;
32
+ touch: () => void;
33
+ };
8
34
  //# sourceMappingURL=log.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../src/utils/log.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C"}
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../src/utils/log.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,EAAE,IAAI,CAAC;CACX,GAAG,MAAM,CAGT;AAYD,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,UAAU,SAAS,GAClB;IAAE,IAAI,EAAE,MAAM,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAczC"}
@@ -1,17 +1,71 @@
1
1
  /**
2
- * Logging utilities with colored output
2
+ * Logging utilities with colored output.
3
+ *
4
+ * Non-TTY streams (CI, agent runs, piped output) get an [HH:MM:SS] prefix on
5
+ * every line so long quiet stretches are attributable after the fact
6
+ * (MESH-2479); interactive terminals stay clean. Override with
7
+ * MESH_LOG_TIMESTAMPS=1 (force on) / =0 (force off).
3
8
  */
4
9
  import chalk from "chalk";
10
+ /**
11
+ * Pure prefix decision, exported for tests: timestamps when the env flag says
12
+ * so, else whenever stderr is not a TTY.
13
+ */
14
+ export function logPrefix(opts) {
15
+ const enabled = opts.envFlag === "1" || (opts.envFlag !== "0" && !opts.isTTY);
16
+ return enabled ? `[${opts.now.toISOString().slice(11, 19)}] ` : "";
17
+ }
18
+ function prefix() {
19
+ return chalk.dim(logPrefix({
20
+ isTTY: !!process.stderr.isTTY,
21
+ envFlag: process.env.MESH_LOG_TIMESTAMPS,
22
+ now: new Date(),
23
+ }));
24
+ }
5
25
  export function logInfo(message) {
6
- console.error(chalk.blue("ℹ"), message);
26
+ console.error(prefix() + chalk.blue("ℹ"), message);
7
27
  }
8
28
  export function logSuccess(message) {
9
- console.error(chalk.green("✓"), message);
29
+ console.error(prefix() + chalk.green("✓"), message);
10
30
  }
11
31
  export function logWarn(message) {
12
- console.error(chalk.yellow("⚠"), message);
32
+ console.error(prefix() + chalk.yellow("⚠"), message);
13
33
  }
14
34
  export function logError(message) {
15
- console.error(chalk.red("✗"), message);
35
+ console.error(prefix() + chalk.red("✗"), message);
36
+ }
37
+ /** Render elapsed milliseconds compactly: "45s", "2m 30s", "1h 5m". */
38
+ export function formatElapsed(ms) {
39
+ const totalSec = Math.max(0, Math.round(ms / 1000));
40
+ const h = Math.floor(totalSec / 3600);
41
+ const m = Math.floor((totalSec % 3600) / 60);
42
+ const s = totalSec % 60;
43
+ if (h > 0)
44
+ return `${h}h ${m}m`;
45
+ if (m > 0)
46
+ return `${m}m ${s}s`;
47
+ return `${s}s`;
48
+ }
49
+ /**
50
+ * Periodic "still working" line during a long silent operation (registry
51
+ * fetches, image builds) so a non-TTY first run never sits at 0 bytes of
52
+ * output for minutes (MESH-2479). `touch()` marks recent real output, which
53
+ * suppresses the next beat — the heartbeat only fills silence.
54
+ */
55
+ export function startHeartbeat(label, intervalMs = 15_000) {
56
+ const startedAt = Date.now();
57
+ let lastOutputAt = startedAt;
58
+ const timer = setInterval(() => {
59
+ if (Date.now() - lastOutputAt < intervalMs)
60
+ return;
61
+ logInfo(`… still working: ${label} (${formatElapsed(Date.now() - startedAt)} elapsed)`);
62
+ }, intervalMs);
63
+ timer.unref?.();
64
+ return {
65
+ stop: () => clearInterval(timer),
66
+ touch: () => {
67
+ lastOutputAt = Date.now();
68
+ },
69
+ };
16
70
  }
17
71
  //# sourceMappingURL=log.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"log.js","sourceRoot":"","sources":["../../../src/utils/log.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../../src/utils/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Guard for pids the CLI reads back rather than constructs.
3
+ *
4
+ * Every teardown path in the CLI signals a pid it recovered from somewhere:
5
+ * `tunnel-state.json`, `runner.json`, `daemon.json`, or a `ps` argv scan. None
6
+ * of those are trustworthy — a truncated write, a stale file from an older
7
+ * build, or a hand-edited state dir can put any integer there. POSIX `kill(2)`
8
+ * overloads the pid argument, so the wrong integer is not a no-op:
9
+ *
10
+ * - `kill(0, sig)` → every process in the CALLER'S OWN process group.
11
+ * - `kill(-1, sig)` → every process the caller is permitted to signal.
12
+ * - `kill(1, sig)` → init. And teardown negates before signalling, so a `1`
13
+ * on disk becomes `kill(-1)` — the broadcast.
14
+ *
15
+ * That is not hypothetical: a `pid: -1` written by a unit test SIGTERM'd the
16
+ * author's entire login session (tmux server, every pane, an in-flight
17
+ * `mesh login`) on 2026-08-01. Refuse the input instead of signalling it.
18
+ *
19
+ * The guard is intentionally strict about the LOW end (`pid >= 2`) so the
20
+ * NEGATED form used for process-group teardown is safe by construction: if
21
+ * `pid >= 2` then `-pid <= -2`, which is always a real process group and never
22
+ * `0` (own group) or `-1` (broadcast). Callers signalling `-pid` need no
23
+ * second check — see `killSupervisor`.
24
+ */
25
+ /** Where a recovered pid came from, for the refusal message + remediation. */
26
+ export interface PidSource {
27
+ /** What the pid claims to be, e.g. "tunnel supervisor pid". */
28
+ what: string;
29
+ /**
30
+ * Absolute path of the state file it was read from, when there is one.
31
+ * Present ⇒ the refusal tells the user the exact file to delete, so a corrupt
32
+ * state dir does not brick `mesh tunnel down` (which is the command that
33
+ * would otherwise clear it).
34
+ */
35
+ file?: string;
36
+ }
37
+ /**
38
+ * Throw unless `pid` is safe to pass to `process.kill` (directly or negated).
39
+ *
40
+ * Call this at the top of any function that signals a pid it did not construct
41
+ * itself. Existence checks (`process.kill(pid, 0)`) do not need it — signal 0
42
+ * delivers nothing — but they gain nothing from skipping it either.
43
+ *
44
+ * @throws {MeshCliError} with `rm <file>` remediation when `source.file` is set.
45
+ */
46
+ export declare function assertSignalablePid(pid: unknown, source: PidSource): void;
47
+ //# sourceMappingURL=pid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid.d.ts","sourceRoot":"","sources":["../../../src/utils/pid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAczE"}