@mesh-tech/mesh-cli 0.1.1 → 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 +1 -0
  134. package/dist/src/commands/secrets/set.d.ts.map +1 -1
  135. package/dist/src/commands/secrets/set.js +96 -2
  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 +36 -22
  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,365 @@
1
+ ---
2
+ name: core
3
+ description: >
4
+ The `mesh` developer CLI (@mesh-tech/mesh-cli) — Zitadel/OIDC login,
5
+ CodeArtifact registry auth, Pulumi deploy/stack passthrough, app scaffolding
6
+ (create-app), local dev orchestration (dev), SSM tunnels (tunnel), DB access
7
+ (db), Secrets Manager (secrets), Headscale VPN (vpn), Temporal inspection
8
+ (temporal), workflow IR extraction (workflow), agent artifact export
9
+ (artifacts), reading deployed-agent conversations (conversations), and both
10
+ app API docs and the generated developer portal / CLI reference (docs).
11
+ Activate when running any `mesh ...`
12
+ command, scaffolding a tenant app, opening a bastion/DB tunnel, deploying a
13
+ Pulumi stack via the deployer role, wiring local dev, or building the docs
14
+ portal.
15
+ metadata:
16
+ version: '0.1'
17
+ category: 'tooling'
18
+ type: core
19
+ ---
20
+
21
+ # `@mesh-tech/mesh-cli`
22
+
23
+ Developer CLI for Mesh Platform. Binary name is **`mesh`**. Installed standalone or
24
+ transitively via the app-kit bundle.
25
+
26
+ ## Running it (MESH-2261)
27
+
28
+ **In this monorepo the CLI runs from TypeScript source — there is no build step and
29
+ no `dist/` to go stale.** The `bin` is a launcher (`bin/mesh.mjs`) that runs
30
+ `bin/mesh.ts` under `tsx`, so you always get the local source of whatever
31
+ worktree/app you're in. (At publish time `build-for-publish` rewrites the `bin` to
32
+ the built `./dist/bin/mesh.js` for consumers.)
33
+
34
+ - **Any cwd:** `pnpm exec mesh <cmd>` — works in the repo root, any worktree, or an
35
+ app subdir, even in a never-built worktree (no `pnpm build` needed).
36
+ - **Repo/worktree root:** `pnpm mesh <cmd>` (the root `"mesh"` script).
37
+ - **Bare `mesh <cmd>`:** run `pnpm exec mesh install-shim` **once** — it writes a tiny
38
+ cwd-aware resolver to `~/.local/bin/mesh` (build-free; survives worktree switches
39
+ and pulls). After that, `mesh dev` etc. run the local source directly. The shim is
40
+ **not** version-pinned: it walks up from your cwd to the nearest
41
+ `node_modules/.bin/mesh`, so it always runs the mesh-cli the **current workspace**
42
+ resolves — the worktree's live source in-repo, or the repo's pinned published
43
+ version in a standalone consumer repo. One global shim, correct local version.
44
+ - **NEVER** run `node …/dist/bin/mesh.js` directly — that path doesn't exist in-repo
45
+ (the CLI isn't built here) and, if it does from a stray publish, it's stale. Use one
46
+ of the forms above.
47
+ - **Suspect you're running a stale copy?** `mesh --version` prints provenance
48
+ (MESH-2479): `source @ <commit> <date>` means this checkout's TypeScript source;
49
+ `published build <date>, commit <commit>` means a packaged install. If the commit
50
+ isn't your checkout's HEAD (or it says `published build` inside a worktree), your
51
+ resolution is stale — remedy: re-run the scoped install so `.bin/mesh` exists here
52
+ (`pnpm install --frozen-lockfile --filter @mesh-tech/mesh-cli...`), then invoke via
53
+ `pnpm exec mesh` (or re-run `pnpm exec mesh install-shim` once if the shim itself
54
+ was overwritten).
55
+
56
+ ```bash
57
+ # Standalone consumer repo (published package, runs built dist):
58
+ npm i -D @mesh-tech/mesh-cli # or pnpm add -D
59
+ pnpm exec mesh --help
60
+ ```
61
+
62
+ Built on `commander`. Most commands auto-detect tenant/env/stack from Pulumi config
63
+ in the cwd or its parents; AWS-touching commands resolve credentials in this order:
64
+ ambient env creds (CI) → cached Zitadel JWT from `mesh login` (`AssumeRoleWithWebIdentity`) → AWS SSO profile (`AssumeRole`).
65
+
66
+ > **`mesh registry login` is the exception, and tries a step *before* all three:**
67
+ > the Zitadel-gated **registry-auth broker**. It exchanges the id token `mesh login`
68
+ > already cached for a CodeArtifact read token minted with the broker's own AWS
69
+ > identity, so installing `@mesh-tech/*` needs **no AWS account, no AWS CLI and no
70
+ > `~/.aws/config`** — only a Mesh account holding the `registry:read` role. The three
71
+ > AWS paths remain the fallback (CI, client-owned tenant accounts, publishing).
72
+ > See [`docs/guides/new-developer-setup.md`](../../../../docs/guides/new-developer-setup.md).
73
+
74
+ > **`mesh` is the front door — don't run raw `pulumi` or `aws`.** Every Pulumi op
75
+ > goes through `mesh deploy <op>` (up/preview/destroy/refresh/import/state/cancel/
76
+ > stack output) and stack lifecycle through `mesh stack init`/`rm` — all assume the
77
+ > stack's deployer role with an up-front **login preflight** (a clear "run `mesh login
78
+ > --device`" instead of a raw AWS error). This works in a sandbox with **no `~/.aws`
79
+ > access**: creds are passed as env vars (deploy/db/secrets), `mesh dev` writes its
80
+ > self-refreshing profile under the session scratch dir, and `mesh login --export`
81
+ > falls back to a mesh-managed AWS config when `~/.aws` isn't writable. The one
82
+ > genuine bootstrap that still needs raw pulumi: setting the initial
83
+ > `mesh:deployerRole` on a brand-new stack.
84
+
85
+ ## Command reference
86
+
87
+ Top-level commands (each `register*` is wired in `src/program.ts`, which `bin/mesh.ts` runs):
88
+
89
+ | Command | Subcommands | Does | Key flags / args |
90
+ |---|---|---|---|
91
+ | `mesh login <context>` | (also `mesh logout <context>`) | Zitadel OIDC PKCE or device-code auth; caches creds in `~/.config/mesh/`. Context like `mesh.dev`. Auto-discovers config via SSM then HTTPS `.well-known/mesh.json`. | `--status` (reports the cached Zitadel session, or — when there isn't one — the AWS identity the credential chain resolves, so an SSO profile or a key/secret pair passes too; non-zero only when neither works), `--device`, `--export` (print AWS `export`s for `eval`), `--role <arn>`, `--region <r>` |
92
+ | `mesh registry` | `login [context]`, `status`, `publish` | CodeArtifact auth → refreshes `~/.npmrc` token (12h) + adds `@mesh-tech` scope to project `.npmrc` + **strips an unscoped CodeArtifact `registry=` line from `~/.npmrc`** (after writing `~/.npmrc.bak-<ts>`) — that line is what a raw CodeArtifact sign-in *without* `--namespace @mesh-tech` leaves behind, and it makes CodeArtifact your DEFAULT registry so every *public* install 401s at the 12h expiry. Skipped under `--ci`, where the unscoped login is deliberate. `status` probes the registry rather than grepping the file: expired/missing token or a hijack exits 1, an unreachable registry warns and exits 0. **Step 0 is the Zitadel-gated broker:** with a context (`mesh registry login mesh.dev`) the CLI POSTs the cached id token to the platform's `registry-auth` service, which returns a CodeArtifact read token minted with its OWN AWS identity — so this path needs no AWS account, CLI or profile at all. It writes the same two `~/.npmrc` lines the AWS path does. Falls back to the AWS chain when the platform publishes no broker, when the broker is unreachable, or with `--no-broker`; a 403 (a valid Mesh account without the `registry:read` role) is fatal and does **not** fall through. `--publish` and `--profile` deliberately skip the broker — both are AWS-identity paths. `--profile mesh-dev` auto-runs the AWS SSO login when the session is stale. Also runs automatically after `mesh login {tenant}.{env}` (F2). `login --publish` assumes the registry's publisher role (from `--role` or the registry SSM export); `publish` pushes package snapshots. | `login`: `--no-broker`, `--profile <sso>`, `--role <arn>`, `--ci`, `--skip-npmrc`, `--publish`; `publish`: `--snapshot` |
93
+ | `mesh db` | `connect`, `credentials`(alias `creds`), `env`, `psql`, `exec <command...>` | Access tenant DBs through an SSM bastion tunnel. `env` prints `export`s for `eval`; `exec` runs a command with `DATABASE_URL` injected. | `-t/--tenant`, `-e/--env`, `-a/--app`, `--app-tenant`, `--app-stage`; `exec` also: `--secret <arn>`, `--ssl <require\|no-verify\|disable>`, `--port <n>` |
94
+ | `mesh deploy ...` | passthrough | Runs `pulumi` with the stack's `mesh:deployerRole` assumed. Unknown opts/args pass through; defaults to `up` if no subcommand. | `-s/--stack <name>` (stripped before pulumi `up`); everything else → pulumi (`preview`, `up --yes`, `destroy`, `stack output …`) |
95
+ | `mesh dev` | `logs <service>`, `restart <service>`, `list`, `test-user [name]` | Two modes. **Tethered** (deployed stack): reads the Pulumi stack dev output, opens tunnels, injects Secrets Manager secrets; needs VPN/AWS creds. **Local** (`--local`, auto when the app has no `Pulumi.yaml`): synthesizes services from the app layout (subdirs with a `dev` script) and wires them to the `mesh start` platform (Temporal `local-dev`, app DB, Zitadel, ministack via `AWS_ENDPOINT_URL`) — zero AWS/VPN/Pulumi. `--externals` (local mode; `--mock` is an alias) also realizes the app's declared external services (package.json → `mesh.externals`; legacy `mesh.mocks` still read). Each declaration runs in one of three MODES — `mock` (the service is emulated: `openapi` → a Prism mock server from a spec, or `src` → a mock process), `local` (a local version of the real service: a `compose` file + published `port`, e.g. a vendor-shaped DB — up `--wait` before the app's services; a realization another checkout already started is **adopted** instead of failing — declared port already served **by a container this compose file defines** → adopt as-is (a publisher the file doesn't define — a native install or unrelated container — is a hard **conflict**, never adopted, since credentials would seed against the wrong service); a stopped foreign container holding the compose `container_name` → `docker start` + adopt — so startup order across checkouts doesn't matter; adopted externals stay out of session state and `--kill` tears down only externals this session created, volumes kept), `remote` (connect to the ACTUAL service: inline vendor `credentials`, or the credentials the app's tenant environment is configured with via `remote.env`). A declaration may carry SEVERAL realizations; `mode` picks the default and `--externals name=mode` overrides it per run (`--externals plaid-db=remote,plaid`). Remote externals get a blackbox uptime probe against their real endpoint. Failing to realize a remote external is fatal only when you named it; a bare `--externals` warns and keeps going, so the local loop still works with no AWS identity. Every realization seeds its ExternalService credential secret (`{{url}}`/`{{host}}`/`{{port}}` from the stand-in's endpoint, `{{env:VAR}}` from the shell) so `resolveCredentials()` runs the deployed code path against the stand-in. Runners: tmux (default) or `--runner docker` (CI/headless — services run as a docker compose project with host networking; parity `--status`/`--kill`/`logs`/`restart`). | root: `--local`, `--externals [name[=mode],…]` (alias `--mock`), `--runner <tmux\|docker>`, `--app <path>`, `--stage`, `--headless`, `--kill`, `--status`, `--json`, `--session <name>`, `--profile <sso>`; `logs`: `--tail <n>`; `test-user`: `--tenant/--env/--region` |
96
+ | `mesh start` / `mesh stop` / `mesh status` | — | Full-local Mesh platform via docker compose (project `mesh-local`, assets ship in the CLI package): Postgres, Temporal (+UI), Zitadel, SpiceDB, ministack (local AWS fabric: SSM/Secrets/S3 registry), memcached, OpenSearch, **and the hosted observability backends** (OTel collector + Loki + Tempo + Prometheus — the Hub's logs/traces/metrics views run unchanged). Seeds tenant `local`/env `dev` on first boot and reconciles every Zitadel-provisioned app tenant into the registry. **No AWS creds, VPN, or Pulumi state needed — Docker only.** The **Hub is included by default** — three overlay services, `hub-api` + `hub-ui` + `hub-auth` (an oauth2-proxy; it is what binds the front-door port and proxies to `hub-ui`, so front-door 401s/redirect loops are in ITS logs, not `hub-api`'s) — the front door at http://localhost:9000 — `MESH_HUB_PORT=<port>` publishes it elsewhere when 9000 is taken; export it for `mesh status` too (images build once from the published @mesh-tech/hub tarball; needs `mesh registry login` the first time; `--no-hub` opts out). Auth contract (MESH-2479): `--with-hub` refreshes to the latest published hub after preflighting the CodeArtifact token — with an expired/missing token it falls back to the already-built local images (warn + fixing command), or fails fast naming `mesh registry login --profile mesh-dev` when none exist; the default (no-flag) path with an expired/missing token starts hub-less and names the same fix. Non-TTY runs (CI, agents, piped output) get an `[HH:MM:SS]` prefix on every step line plus a heartbeat during long fetches/builds — `MESH_LOG_TIMESTAMPS=1/0` forces the prefix on/off (default: on when stderr is not a TTY). | `start`: `--no-seed`, `--no-hub`, `--with-hub`; `stop`: `--destroy` (drops volumes/seeds); `status`: `--json` |
97
+ | `mesh hub` | `dev` | One-command local Hub over a running dev-local stack. Launches the CURRENT-CODE Hub (apps/hub api+ui from a mesh-platform checkout) pointed at an existing `mesh dev` session — auto-assembles `HUB_TENANT`/`HUB_SCOPE_ENV`/`HUB_SCOPE_TENANTS` (session platform context), `TEMPORAL_ADDRESS` (session tunnel), `AWS_*` (session scratch profile), `DEV_USER_*`+`DEV_USER_TOKEN_URL` (session dev identity; starts its own token-server if the session predates it, so tokens stay fresh past ~1h). Refuses to launch with an empty tenant scope (which the Hub renders as silently blank). Runs in tmux session `mesh-hub-dev`. | `dev`: `--session <name>`, `--tenants <csv>`, `--port` (or `MESH_HUB_DEV_PORT`, default 9000; the containerized `mesh start` Hub uses the separate `MESH_HUB_PORT`), `--api-port <3002>`, `--platform-dir <dir>` (or `MESH_PLATFORM_DIR`), `--print-env`, `--kill` |
98
+ | `mesh create-app` | — | Scaffold a tenant app. Composable mode (primitives) or legacy template mode. Interactive when TTY + missing flags. Run at the root of an **empty** `{tenant}-mesh-apps` git clone (a `.git` with no `package.json`/`apps/`/`tenants/` and no enclosing pnpm workspace), it first generates the repo-level shape — `pnpm-workspace.yaml` over `apps/*`, private root `package.json`, scoped-registry `.npmrc`, base `tsconfig.json`, `.gitignore`, `README.md`, `apps/` — then scaffolds the app. Never overwrites an existing file. | `--tenant`, `--name`, `--primitives <csv>` (`service,database,temporal,bucket`), `--template <workflow\|api-auth\|api-role-gating\|external-service>`, `--test` (writes to `tests/tenants/`) |
99
+ | `mesh init` | `app-tenant` | The repo doctor (A1–A3): read-only check pipeline — CLI auth, registry access, public npm not hijacked, platform reachable (Hub API), app-tenant registration, deployer role, repo shape, agent skills — each failure names the exact `mesh` fix. **Registry access** is a live probe of the CodeArtifact token, not a grep of `~/.npmrc`: an expired token `fail`s (it used to `pass`), an unreachable registry `warn`s (a network fault is not an auth fault). **Public npm not hijacked** fails when `~/.npmrc` carries an unscoped `registry=<codeartifact>` line, which makes CodeArtifact your default registry — one `mesh registry login` fixes both. Exit 0 iff all pass; re-run any time. `--fix` applies developer-scope fixes (registry token, skills sync); operator actions stay remediations — and `--profile <p>` is the SSO profile `--fix` logs into CodeArtifact with, echoed back in the `fix:` command each check prints so the advertised command is the one that runs. | `app-tenant`: `--tenant <name>`, `--context <ctx>` (default `local`), `--hub-url <url>`, `--fix`, `--profile <sso>`, `--json` |
100
+ | `mesh skills` | `sync` | Agent-skill distribution (D1/D2): installs the base building-with-Mesh skills into the repo's `.claude/skills/mesh-*/` (managed-marker files) and wires TanStack-Intent discovery for the pattern skills shipping inside `@mesh-tech/*` packages (`.intent/hooks/` gate + `.claude/settings.json` SessionStart hook + AGENTS.md fence — the PR #2356 mechanism, vendored). Idempotent; runs automatically after `mesh create-app`. | `sync`: `--check` (CI/doctor: exit 1 when missing/stale), `--root <path>` |
101
+ | `mesh docs` | `build`, `portal`, `cli-reference` | `build` builds/validates an **app's** OpenAPI specs from `docs/docs.config.json` (file copy or SymXchange generation). `start`/`stop`/`list` are the simple front door: `start` serves the docs on loopback — DETACHED in a tmux session named `mesh-docs` by default (prints the bare URL once live; `stop` kills the session; `--foreground` or any non-TTY runs in the foreground) — serving the working tree in a mesh-platform checkout, or the published `@mesh-tech/docs` artifact fetched from the role-gated CodeArtifact registry anywhere else (docs version == the @mesh-tech/* baseline it describes; `-v` pins, default latest; cached under `~/.cache/mesh/docs/`). `list` shows the published docs versions. `portal` assembles the **Mesh developer portal** (docs.meshtech.io) from every `docs.json`-opted-in doc root in the repo — a directory publishes its markdown iff it holds a `docs.json`; route/title/order/nav derive from the tree and each file, so adding a doc is adding one file — then hands the assembled tree to Zudoku (`apps/docs/`): default runs `zudoku build`, `--serve` runs `zudoku dev`, `--assemble-only`/`-o` stop after assembly. Links between published files are rewritten to routes; links to unpublished repo files become blob links. Reserved directory names (`plans/`, `designs/`, `incidents/`, … the frozen list in `src/docs/schema.ts`) are excluded at any depth. `cli-reference` regenerates `docs/portal/generated/cli-reference.md` from THIS command tree, so it can't document a flag the binary lacks. `portal --check` is the CI gate (`pnpm check:docs-portal`): docs.json schema validation, reserved-segment fail-close, broken links, and CLI-reference staleness; `--diff-base <ref>` prints the publish-set diff for PR job summaries. Hidden commands and `--version` are excluded from the reference. | `build`: `-c/--config <path>` (default `docs/docs.config.json`); `portal`: `-o/--out <dir>`, `--assemble-only`, `--serve`, `-p/--port <n>` (default `3000`), `--check`, `--print-manifest`, `--diff-base <ref>`, `--manifest-out <path>`; `cli-reference`: `-o/--out <path>`, `--check`; `start`: `-v/--version <v>` (default: latest), `-p/--port <n>` (default `4400`; `0` is foreground-only), `--dev` (foreground HMR), `--foreground`; `stop`: no flags; `list`: no flags |
102
+ | `mesh stack` | `init`, `rm <name>` | `init` creates a personal dev stack `dev-{github-user}`, copying base-stack config, setting `mesh:deploy: false`, inheriting KMS secrets provider; `--worktree` appends the git-worktree token (`dev-{user}-{token}`) so concurrent worktrees deploy to **distinct** stacks (SSM paths, Temporal namespace, Nexus endpoint all derive from the stack name → one discriminator isolates all three; no-op on the primary checkout). `rm <name>` removes a personal stack (backend state + local config), credentialed. Both assume the deployer role — no raw `pulumi` / manual creds needed. | `init`: `--from <stack>`, `--name <stack>`, `--worktree`; `rm`: `--yes` |
103
+ | `mesh tenant` | `add <name>`, `list` | Register/inspect app tenants on a platform stack. Run from the **platform layer** of a tenant platform repo (e.g. `mesh-sandbox/platform`). `add` inserts the tenant under `mesh:tenants` in `Pulumi.<stack>.yaml` via a comment-preserving YAML round-trip (untouched lines don't reformat), refuses a tenant that is already declared (an existing entry may carry fields a re-add would drop), derives the `{name}-{env}` subdomain from the stack name (echoed in the success line), and guards against running on the core layer or an app dir; it then prints the deploy + verify sequence — `mesh deploy up` is what makes the registration live. `list` prints what the stack config declares, so "is it registered?" is answerable without opening YAML (warns when the project doesn't look like a platform layer, so an empty result isn't mistaken for "no tenants"). | `add`: `--display-name <name>`, `--subdomain <sub>`, `--zitadel-org-id <id>`, `--stack <stack>`, `--json`; `list`: `--stack <stack>`, `--json` |
104
+ | `mesh tunnel [group]` | `external <name>` | SSM port-forward to platform services. Groups: `dev` (temporal+db), `temporal`. **`external <name>`** tunnels to a *registered* `ExternalService`: host/port are read from its credential secret (`mesh/{app-tenant}/{app-stage}/external/{name}`) — the same values deployed apps resolve at runtime — so anything the bastion can reach is tunnelable with no per-service CLI entry and no bastion services-map change. `-t/-e` are **optional everywhere** — they fall back to the same Pulumi/SST context detection `mesh dev` uses, and `AWS_REGION`/`AWS_PROFILE` default from the nearest Pulumi config + the `{tenant}-{env}` profile convention (region falls back to the effective profile's own `region` — the `[default]` profile when none was resolved — before the platform default us-east-2). | root: `-t/--tenant`, `-e/--env`, `-l/--list`, `-s/--services <csv\|group>`, `--db-port`, `--temporal-ui-port`, `--temporal-frontend-port`; `external`: `-p/--port` (default: the remote port), `-k/--key <key>` (multi-instance `credentials.keyedBy` externals), `--app-tenant`/`--app-stage` (credential axis; default to `-t`/`-e`) |
105
+ | `mesh secrets` | `exec <command...>`, `set [service]`, `migrate-config` | Manage external-service creds in Secrets Manager. `exec` injects secrets as env; `set` reads field schema from SSM and prompts (or `--json`). | `set`: `--key <id>` (multi-instance), `--all`, `--json <str>`, `--stage`, `--region`; `migrate-config`: `--force`, `--dry-run`, `--stage`, `--region` |
106
+ | `mesh artifacts` | `get <ref>` | Download workflow artifact files from an AI-agent conversation. Ref `<conversationId>:<artifactId>` (artifactId defaults to `workflow-artifact`). | `-o/--output <dir>`, `--target <name>`, `--api-url <url>`, `--context <ctx>` (default `mesh.dev`) |
107
+ | `mesh conversations` (alias `conv`) | `list`, `show <id>`, `artifacts <id>` | Read a deployed Mesh agent's conversations: list the caller's conversations, render a transcript, or list a conversation's artifacts. Resolves against the same `agent-targets` registry the MCP `agent_*` tools use. | all three: `--target <name>`, `--api-url <url>` (overrides `--target`), `--context <ctx>` (used with `--api-url`, default `mesh.dev`), `--json` (default when stdout isn't a TTY) |
108
+ | `mesh vpn` | `connect <context>`, `disconnect`, `status`, `tunnel <up\|down\|status>`, `api-key`, `pre-auth-key`, `users` | Headscale VPN mgmt via Tailscale + kubectl. **`connect` now defaults to the userspace `tailscaled`** (brew formula, NOT the GUI Tailscale.app) — the same daemon `mesh dev --transport tailscale` / `mesh vpn tunnel` use, so it **runs headless / under the sandbox** and exposes a local SOCKS5 proxy (route a tool via `ALL_PROXY=socks5://127.0.0.1:<port>`). It relays a one-time browser-register URL for Zitadel auth. `--system` opts into the whole-machine GUI Tailscale.app (system TUN) — needs the app installed and **cannot run headless/sandboxed** (Sparkle.framework abort). For auto-forwarded VPC services (Temporal/RDS) prefer **`mesh vpn tunnel up`** or `mesh dev`. `tunnel status` reports runner **ownership** (`Runner: owned (verified)` vs `NOT OWNED (<reason>)` — a port answering a dial is not proof it's mesh's, MESH-2407); `--json` adds `owned` (bool) + `ownership` (reason string). Admin subcommands `exec` into the `headscale-0` pod. | root: `-t/--tenant` (default `mesh`), `-e/--env` (default `dev`), `-n/--namespace`; `connect`/`disconnect`: `--system`; `tunnel up`: `--context <ctx>`; `tunnel down`: `--stop` (stop daemon, keep login), `--logout`; `tunnel status`: `--json`; `pre-auth-key`: `-u/--user` (**required**), `--expiration <24h>`, `--reusable`, `--ephemeral` |
109
+ | `mesh workflow` | `extract-ir <path>` | Parse Temporal workflow TS source → WorkflowIR graph (nodes+edges). Prints JSON or uploads to S3. | `--app <name>`, `--upload <bucket>` (both required together for S3) |
110
+ | `mesh temporal` | `describe <wfId> [runId]`, `history <wfId> [runId]`, `recover-conversation <wfId> [runId]`, `capture-history <wfId> [runId]` | Inspect Temporal workflows for the current app/stack; reconstruct an agent conversation transcript from durable history when the worker can't replay it; capture a full history to a local replay fixture. | shared: `--stack`, `--address`, `--namespace`; `history`: `-n/--limit <200>`, `-f/--follow`, `--no-compact`, `-p/--show-payloads` (decrypts via `TEMPORAL_ENCODING_KEY` from the K8s secret); `recover-conversation`: `--out <path>`, `--json`, `--snapshot` (structured `{conversationId,messages,artifacts,focus}` blob); `capture-history`: `--out <path>` (default `~/.mesh/replay-histories/<wfId>.json`, do not commit) | <!-- skill-lint-disable-next-line — row documents the mesh-owned kubectl wrappers; the backticked `aws eks get-token` describes what the CLI runs internally, not an operator step -->
111
+ | `mesh kubectl` / `mesh logs` / `mesh exec` | `kubectl [args…]`, `logs [service\|deployment/x\|k=v]`, `exec <service> -- <cmd>` | Cluster access for a **deployed** app — debug CrashLoops/logs without broader creds. Assumes the app's `mesh:deployerRole`, builds a session kubeconfig from the platform `eks` SSM export (`aws eks get-token` — no `eks:DescribeCluster` / `~/.kube/config` needed), shells out to kubectl. Defaults the namespace to the app's own (deployer RBAC is tenant-namespace-scoped). **Use `--stack <name>` to target the deployed stack (e.g. `dev`, not `dev-local`).** | `--stack <name>`; `logs`: `-f/--follow`, `--tail <200>`, `-c/--container`, `--previous`; `exec`: `-c/--container` |
112
+
113
+ ## Core workflows
114
+
115
+ ### 1. Onboard: auth + install dependencies
116
+
117
+ ```bash
118
+ mesh login mesh.dev # OIDC; auto-uses device flow in remote/headless envs
119
+ mesh login mesh.dev --device # FORCE device flow (browser callback times out over SSH/tailscale)
120
+ mesh registry login mesh.dev # registry token via the Zitadel broker (no AWS needed) + project .npmrc scope
121
+ pnpm install # now resolves @mesh-tech/* from CodeArtifact
122
+ ```
123
+
124
+ ### 1b. Run the platform fully locally (no cloud)
125
+
126
+ ```bash
127
+ mesh start # docker compose up + health waits + first-boot seed
128
+ # (seeds: tenant registry, hub DB, Temporal ns local-dev,
129
+ # Zitadel org/CLI app/test users, artifacts bucket;
130
+ # reconciles Zitadel app tenants into the Hub registry)
131
+ # → open http://localhost:9000 — the Hub, your local operations dashboard
132
+ # (sign in via the local Zitadel: admin@local.mesh or dev@local.mesh / LocalDev1!)
133
+ mesh login local # PKCE against the seeded Zitadel (dev@local.mesh / LocalDev1!)
134
+ mesh status # per-component health, endpoints, ports (--json for agents)
135
+ cd <your app> && mesh dev # local mode auto-wires services to this stack:
136
+ # per-app Temporal namespace {tenant}-dev-{app}, auth
137
+ # auto-provisioning, self-registration in the Hub, and
138
+ # service logs shipped to Loki (Hub logs view)
139
+ mesh stop --destroy # tear down incl. volumes (resets seeds)
140
+ ```
141
+
142
+ **The local platform is a machine-wide singleton** — one compose project
143
+ (`mesh-local`), one set of host ports — shared by every checkout and project
144
+ on the machine. App/tenant work composes safely on top of it: `mesh dev
145
+ --local` provisions only tenant-scoped state (Zitadel org, Temporal
146
+ namespace, registry/secret prefixes, per-app mock compose projects), so
147
+ concurrent projects coexist on one running stack. Only `mesh start`/`mesh
148
+ stop` mutate the shared containers, and both refuse to act on a stack a
149
+ DIFFERENT checkout started (compose config drift would recreate shared
150
+ containers out from under the other project) — `mesh start --takeover` /
151
+ `mesh stop --force` override deliberately.
152
+ Device flow prints a URL + short code (e.g. `identity.dev.mesh-platform.trabian.com/device?user_code=XXXX-XXXX`);
153
+ open it, enter the code, wait for `✓ Logged in as …`. Over SSH always use `--device` — the
154
+ browser-callback flow times out. After login, `mesh dev`/`mesh deploy` resolve AWS creds via a
155
+ self-refreshing credential_process (the deployer role), so no separate `--export` eval is needed for those.
156
+
157
+ ### 2. Scaffold and run an app locally
158
+
159
+ ```bash
160
+ mesh create-app --tenant acme --name billing --primitives service,database,temporal
161
+ cd tenants/acme/apps/billing && pnpm install
162
+ mesh stack init # personal dev-{github-user} stack (deploy:false)
163
+ mesh deploy up --yes # pulumi up via mesh:deployerRole
164
+ mesh dev # tunnels + secrets + tmux (needs VPN for VPC access)
165
+ mesh dev logs api # tail one service; mesh dev --kill to stop
166
+ ```
167
+
168
+ ### 2b. Watch your dev-local stack in the Hub (`mesh hub dev`)
169
+
170
+ ```bash
171
+ cd <your app repo> # a repo with a running `mesh dev` session
172
+ mesh hub dev # → local current-code Hub at http://localhost:9000
173
+ # scoped to this session's tenant: workflow types with
174
+ # live run counts, execution timelines incl. child slices
175
+ mesh hub dev --print-env # inspect the assembled env without launching
176
+ mesh hub dev --kill # tear down (tmux session mesh-hub-dev)
177
+ ```
178
+
179
+ Zero hand-set env vars: the command reads the `mesh dev` session's state file
180
+ and tmux environment — Temporal tunnel address, AWS scratch profile, dev-user
181
+ identity, per-session token-server — and derives the Hub scope
182
+ (`HUB_TENANT`/`HUB_SCOPE_ENV`/`HUB_SCOPE_TENANTS`) from the session's platform
183
+ context. Needs a mesh-platform checkout for the Hub's source (auto-detected
184
+ when you're inside one; otherwise `--platform-dir` / `MESH_PLATFORM_DIR`).
185
+ An empty tenant scope is a loud error, never a blank Hub. On the full-local
186
+ platform (`mesh start`) use its built-in containerized Hub instead.
187
+
188
+ ### 3. Concurrent `mesh dev` across git worktrees and sibling apps (auto-isolation)
189
+
190
+ Run the **same plain `mesh dev`** from each worktree's app dir — there is nothing special to
191
+ configure. `mesh dev` derives a deterministic token from the worktree path and threads it through
192
+ the tmux session name, the tmpdir session-state + env-file dir and the Temporal task-queue suffix, so
193
+ two worktrees don't kill each other's session — as long as their directory basenames differ, since the
194
+ session name carries the worktree's sanitized basename, not the hash. The reserved **service-port
195
+ block is derived from (worktree, app)**, not the worktree alone — a repo can hold several apps whose
196
+ sessions run concurrently (e.g. `scu-mesh-apps`' `plaid-token-manager` + `plaid-reporting`), and one
197
+ block per worktree handed both the same ports.
198
+
199
+ ```bash
200
+ # worktree A
201
+ cd .worktrees/feature-a/tests/tenants/acme/apps/demo-agent
202
+ mesh dev --dry-run # preview: session name, port block, state/env paths, task queue
203
+ mesh dev # launch (attaches tmux; --headless to skip)
204
+
205
+ # worktree B — SAME command, different shell; auto-isolated
206
+ cd .worktrees/feature-b/tests/tenants/acme/apps/demo-agent
207
+ mesh dev
208
+
209
+ # sibling app in worktree A — same worktree, still its own port block
210
+ cd .worktrees/feature-a/tests/tenants/acme/apps/silverlake-demo
211
+ mesh dev
212
+ ```
213
+
214
+ - The **primary checkout** keeps its historical identity (`${project}-dev` session, the app's
215
+ preferred ports). Only **linked worktrees** get an offset session name + a port block in the 40000+
216
+ range. `mesh dev --dry-run` labels which you are (`primary checkout` vs `linked worktree (block N)`).
217
+ - **Port blocks are disjoint by default, not by construction.** The block is a hash bucketed into 63
218
+ slots, so two `(worktree, app)` pairs *can* land on the same block; the in-block free-port probe and
219
+ the ephemeral-port fallback are the backstop when they do — but that backstop is the same
220
+ check-then-bind probe that raced two still-booting sessions onto one port before #2889, so treat a
221
+ shared block as a live hazard, not a handled case. Two consequences worth knowing before you
222
+ debug a collision as a regression:
223
+ - Sibling apps in the **primary checkout** are deliberately excluded — they keep preferred-port
224
+ semantics (block 0) and rely on that probe, so run them from linked worktrees if you need them
225
+ isolated. This is the layout most tenant app repos use day to day.
226
+ - App-scoping raises the number of hashed entities from *#worktrees* to *#worktrees × #apps*, so
227
+ bucket collisions get likelier as you add apps.
228
+
229
+ A deterministic, collision-free allocator that also folds primary checkouts back in is tracked as
230
+ **MESH-2375**.
231
+ - **Do NOT force a shared `--session`** across worktrees — that defeats the auto-isolation and
232
+ reintroduces the collision. Omit `--session` and let it derive per worktree.
233
+ - `mesh dev --kill` / `--status` act only on the current worktree's session.
234
+ - If the stack was last deployed from a *different* worktree, `mesh dev` **refuses** to launch a service
235
+ whose source resolves outside the current worktree (guards against silently running stale code) — re-run
236
+ `mesh deploy up` in this worktree.
237
+ - **Deploying isolated stacks per worktree?** The `mesh dev` isolation above is local-only. To
238
+ `mesh deploy up` a `deploy:false` personal stack from several worktrees at once, give each worktree
239
+ its own stack with `mesh stack init --worktree` — otherwise they collide on SSM export paths
240
+ (`ParameterAlreadyExists`) and the Temporal namespace (both derive from the stack name).
241
+ `mesh deploy up`/`destroy` **warns** when it sees a shared (non-worktree) stack name in a linked worktree.
242
+
243
+ ### 4. Deploy (pulumi passthrough)
244
+
245
+ ```bash
246
+ mesh deploy preview
247
+ mesh deploy up --yes
248
+ mesh deploy stack output dev --json
249
+ mesh deploy destroy
250
+ # Requires `mesh:deployerRole` in Pulumi.<stack>.yaml:
251
+ # pulumi config set mesh:deployerRole arn:aws:iam::<acct>:role/<tenant>-<env>-apps-deployer
252
+ ```
253
+
254
+ `<env>` is the **platform environment** (`dev`, `prod`), which is not always your
255
+ Pulumi stack name — a stack called `dev-jane` still deploys against the `dev`
256
+ platform and so assumes `…-dev-apps-deployer`. The distinction is load-bearing
257
+ beyond the role name: the deployer's KMS-alias grant is scoped to
258
+ `alias/{tenant}-{env}-*`, so an app that creates an alias has to prefix it the
259
+ same way. See [Naming resources so the deployer can create them](https://github.com/mesh-tech/mesh-platform/blob/main/libs/infra-components/docs/concepts/deploying.md#naming-resources-so-the-deployer-can-create-them).
260
+
261
+ ### 5. Database access
262
+
263
+ ```bash
264
+ mesh db exec --ssl=require -- npx prisma migrate dev --name init
265
+ mesh db psql # interactive session through the bastion
266
+ eval "$(mesh db env)" # load DATABASE_URL / DB_* into the shell
267
+ mesh db exec --secret <arn> -- node seed.js # direct mode, skips SSM discovery
268
+ ```
269
+
270
+ ### 6. External secrets
271
+
272
+ ```bash
273
+ mesh secrets set external/symitar # interactive (schema from SSM)
274
+ mesh secrets set external/symitar --json '{"baseUrl":"…"}'
275
+ mesh secrets set external/symitar --key 12345 --json '{…}' # multi-instance (key = FI id)
276
+ mesh secrets exec -- node ./script.js # secrets injected as env
277
+ ```
278
+
279
+ ### 7. Read a remote agent's conversation context
280
+
281
+ ```bash
282
+ mesh conversations list --target fub # discover conversation ids
283
+ mesh conversations show <id> --target fub # transcript
284
+ mesh conversations artifacts <id> --target fub
285
+ mesh artifacts get <id>:<artifactId> --target fub
286
+ ```
287
+
288
+ `--target` resolves the same `~/.config/mesh/agent-targets.json` registry the
289
+ MCP `agent_*` tools use; see the dedicated
290
+ `libs/mesh-cli/skills/pull-remote-agent-context` skill for the full recipe
291
+ (registry format, auth model, the `conversation_unavailable` → `mesh temporal
292
+ recover-conversation` break-glass path, and the MCP-vs-CLI relationship).
293
+
294
+ ### 8. Relaunch safety — don't strand live conversations
295
+
296
+ For a **code-only** change, prefer a scoped `mesh dev restart <service>` over a full
297
+ `mesh dev` relaunch — it's faster and touches only that service. Restart the
298
+ **worker** only when you actually changed worker/workflow code.
299
+
300
+ Both a relaunch and a `restart <worker>` recreate the Temporal worker onto current
301
+ code. If the **workflow** source (`agent-sdk` / `workflow-interpreter` /
302
+ `agent-contracts`) changed since the session started, in-flight conversations replay
303
+ against the new code — a replay-incompatible change **strands** them. `mesh dev` now
304
+ fingerprints that source at launch and **warns + refuses (use `--force`)** when it
305
+ changed on a relaunch/worker-restart. The fix is not `--force`: keep the change
306
+ replay-compatible — gate it with `wf.patched()` and regenerate the replay goldens
307
+ (see the `temporal-workflow-safety` skill + the CI replay gate). Restarting unchanged
308
+ code, or a non-worker service (ui/api), never warns.
309
+
310
+ For **config/deploy** changes (not code): `mesh dev restart <svc> --refresh-env`
311
+ re-reads stack/SSM output; if the *topology* changed, run `mesh deploy up` first
312
+ (`mesh dev doctor` flags config staleness).
313
+
314
+ ## Config / environment requirements
315
+
316
+ | Need | Source |
317
+ |---|---|
318
+ | Tenant / env / stage | flags (`-t/-e`, `--stage`) → `MESH_TENANT`/`MESH_STAGE`/`SST_STAGE` env → Pulumi config in cwd/parents → defaults (`mesh`/`dev`) |
319
+ | AWS creds | ambient env → cached Zitadel JWT (`mesh login`) → AWS SSO profile; region from `AWS_REGION`/`AWS_DEFAULT_REGION` else `us-east-2` |
320
+ | Login config | `~/.config/mesh/config.json`; creds cache `~/.config/mesh/credentials.json` |
321
+ | Deploy role | `mesh:deployerRole` (and optional `mesh:adminDeployerRole`) in `Pulumi.<stack>.yaml` |
322
+ | Login role for `--export` | `--role` → `MESH_AWS_ROLE` → cached `defaultRole` for the context |
323
+ | Registry | `@mesh-tech` scope; CodeArtifact token written to `~/.npmrc` (12h TTL) |
324
+ | `vpn`, `temporal --show-payloads` | a working `kubectl` kubeconfig for the target EKS cluster |
325
+ | Temporal client / S3 upload | optional deps `@temporalio/client`, `@aws-sdk/client-s3` (lazy-loaded) |
326
+
327
+ ## Failure modes / gotchas
328
+
329
+ | Symptom | Cause | Fix |
330
+ |---|---|---|
331
+ | `No Pulumi.yaml found` | run outside a Pulumi app dir | cd into the app (deploy/stack/temporal use `findAppRoot`) |
332
+ | `No mesh:deployerRole found` | stack config missing the role | `mesh deploy config set mesh:deployerRole <arn>` |
333
+ | `Could not determine stack` (deploy) | no selected stack & no `--stack` | `mesh deploy stack select <name>` or pass `--stack` |
334
+ | `artifacts get` → ECONNREFUSED / 404 | agent API down or convo expired | start API (`mesh dev`) or pass `--api-url`; restart API after code changes |
335
+ | `login` config not found | context not discoverable | a known first-party short context (`mesh.dev`) resolves anonymously — no AWS needed. Otherwise use the platform's full domain (`mesh login dev.<tenant>.meshtech.io`). Only if neither works: ensure AWS SSO is active + the platform is deployed (SSM `cliClientId`), or add config to `~/.config/mesh/config.json` |
336
+ | `vpn`/`temporal --show-payloads` fail | kubeconfig not set / expired creds | refresh the tenant cluster kubeconfig (`mesh vpn connect <ctx>` wires it; kubeconfig absorption into `mesh deploy` is planned) then retry | <!-- skill-lint-disable-next-line — next row's backticked `kubectl …` is a quoted ERROR SYMPTOM, not an operator command; the row's fix column already routes through mesh dev -->|
337
+ | `kubectl could not read a kubeconfig … macOS blocks it` (from `mesh kubectl`/`logs`/`exec`/`temporal` in a bare shell) | macOS Full-Disk-Access blocks reading `~/.kube` from a shell outside the `mesh dev` session | run the command **inside** the `mesh dev` tmux window, or `export KUBECONFIG=$TMPDIR/mesh-dev-sessions/<session>.kubeconfig` first |
338
+ | `mesh temporal …` won't authenticate against a **deployed** Temporal | passing `--address` (or `TEMPORAL_ADDRESS`) skips the app/stack resolution that mints a Zitadel **Bearer** — auth falls back to ambient env | omit `--address` and run from the app dir so `mesh temporal` resolves the authenticated frontend over the tunnel; use `--address` only for a local/unauthenticated Temporal |
339
+ | `mesh dev` chose "VPN direct" then api/worker spin on `ECONNREFUSED …:27233` | tailnet-blind VPN *presence* check picked direct routing the mesh VPC doesn't actually serve | **no manual fallback needed** — current `mesh dev` TCP-probes the frontend and auto-falls back to SSM tunnels (MESH-2016); if still stuck, force `--transport ssm` (or `--no-vpn`) |
340
+ | `mesh dev` / `mesh vpn tunnel up` → `Tunnel port(s) for tenant '<t>' are bound by a process mesh does not own` | a foreign or orphaned listener holds a forwarder port; mesh refuses to adopt it rather than route traffic to the wrong upstream (MESH-2407) | `mesh vpn -t <t> tunnel down --stop` to reap mesh-owned runners; if the port is still held, `lsof -nP -iTCP:<port> -sTCP:LISTEN` and stop that process (if it names another mesh runner, it belongs to a different tenant — tear that one down). `mesh vpn -t <t> tunnel status` shows `Runner: owned (verified)` when healthy |
341
+ | `mesh vpn tunnel down`/`up` or `mesh dev` → `Refusing to signal <the tunnel supervisor pid \| the tunnel runner process group \| the VPN daemon pid> recorded for tenant '<t>' — …`, or `Refusing to signal a tunnel runner pid discovered from 'ps' for tenant '<t>' — …` | the pid is corrupt or stale — from `tunnel-state.json` / `runner.json` / `daemon.json` (truncated write, hand edit, older build) for the first three, or from the live `ps` argv scan for the fourth. POSIX `kill(2)` overloads the pid argument and teardown negates before signalling, so a `1` there would SIGTERM every process you can signal — mesh refuses it instead | usually **nothing** — it is a warning, the rest of the teardown still runs and the state file is cleared, so re-running the command is clean. If it recurs: **when the message names a file**, `rm` that exact path; **the `discovered from 'ps'` variant names none** — there is no state file to clear, so just re-run. Either way finish with `mesh vpn -t <t> tunnel status` to confirm |
342
+ | `mesh kubectl`/`logs`/`exec` → `Could not resolve the EKS cluster … Parameter tried: /mesh-platform/<name>/<env>/core/eks`; `mesh dev` → `EKS cluster resolve failed (/mesh-platform/<name>/<env>/core/eks): …` | the platform segment of the SSM path is wrong (or the platform core layer isn't deployed) — cluster data lives under the app's HUB platform name, and an `AccessDeniedException` here usually means the wrong path, not missing SSM permissions | check `mesh:platform` in the app's `Pulumi.<stack>.yaml` (its `name` is the hub, e.g. `trabian`) and log into that platform's context (`mesh login <platform>.<env>`) |
343
+ | 401/403 installing `@mesh-tech/*` | stale CodeArtifact token | `mesh registry login` (or `--ci` in CI) |
344
+ | 401 installing a **public** package (`npm view lodash version` fails) | an unscoped `registry=<codeartifact>` line in `~/.npmrc` makes CodeArtifact the DEFAULT registry, so public packages resolve through it and 401 at the 12h token expiry | `mesh registry login` — it removes the line after backing `~/.npmrc` up; confirm with `npm config get registry` (expect `https://registry.npmjs.org/`) |
345
+ | `--export` prints nothing | no role resolved | pass `--role <arn>` or set `MESH_AWS_ROLE` |
346
+ | `--export` / `EPERM … ~/.aws` in a sandbox | `~/.aws` not writable | it now auto-falls back to a mesh-managed config (`~/.config/mesh/aws-config`) and also exports `AWS_CONFIG_FILE`; or prefer `mesh deploy <op>` (no shell profile needed) |
347
+ | `workflow extract-ir` no S3 upload | only one of `--app`/`--upload` given | pass both, or omit both to print JSON |
348
+
349
+ ## Programmatic API
350
+
351
+ `@mesh-tech/mesh-cli` re-exports its utils (`src/utils/index.ts`):
352
+
353
+ ```ts
354
+ import { detectContext, getPlatformBastionInfo } from "@mesh-tech/mesh-cli";
355
+ const ctx = detectContext(); // { tenant, stage, ... }
356
+ const bastion = await getPlatformBastionInfo(ctx.tenant, ctx.platformEnv);
357
+ ```
358
+
359
+ Exports include `detectContext`, `getPlatformBastionInfo` (bastion), credentials,
360
+ pulumi, vpn, and log helpers.
361
+
362
+ ## See also
363
+
364
+ - `@mesh-tech/app-kit#core` — app-kit bundles this CLI; consumers usually invoke it as `pnpm mesh <cmd>`
365
+ - `@mesh-tech/credentials#core` — credential resolution the auth/deploy flows build on
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: pull-remote-agent-context
3
+ description: >
4
+ Read a deployed Mesh agent's conversation history, artifacts, or workflow
5
+ design from the `mesh` CLI. Activate when asked to pull/read/inspect a
6
+ hosted agent's conversation transcript, list its conversations, fetch a
7
+ workflow artifact/design it produced, or when the `agent_*` MCP tools
8
+ (agent_list_conversations, agent_check_conversation, agent_get_artifacts,
9
+ agent_get_workflow_design) are unavailable and the same read needs to
10
+ happen via the CLI instead.
11
+ metadata:
12
+ version: '0.1'
13
+ category: 'tooling'
14
+ type: intent
15
+ ---
16
+
17
+ # Pull a deployed agent's conversation context
18
+
19
+ `mesh conversations` (alias `mesh conv`) reads a deployed Mesh agent's
20
+ conversations directly from its agent-api, over the same read surface the
21
+ `agent_*` MCP tools use. This is the CLI-native path when those MCP tools
22
+ aren't wired up, or when you're already in a shell.
23
+
24
+ ## The recipe
25
+
26
+ ```bash
27
+ mesh conversations list --target <name> # discover conversation ids
28
+ mesh conversations show <id> --target <name> # render the transcript
29
+ mesh conversations artifacts <id> --target <name> # list its artifacts
30
+ mesh artifacts get <id>:<artifactId> --target <name> # download artifact files
31
+ ```
32
+
33
+ ## One-shot: `mesh conversations pull` (recommended)
34
+
35
+ To pull a whole conversation + everything it produced into a session bundle in
36
+ one command — the fast path when you're feeding a workflow-builder conversation
37
+ into a coding session:
38
+
39
+ ```bash
40
+ mesh conversations pull <id> --target <name> -o <dir>
41
+ ```
42
+
43
+ It writes:
44
+
45
+ ```
46
+ <dir>/
47
+ index.json # conversation meta, artifact map, saveLocations, subagent tree, warnings[]
48
+ conversation.md # the transcript (intent)
49
+ designs/<slug>/
50
+ design-ir.json # the LIVE design IR (authoritative; resolved server-side)
51
+ manifest.json # realized bindings (signals + service ops) — from the design's vcs folder
52
+ README.md # + any other docs the design's folder holds, verbatim
53
+ design-ir.saved.json # ONLY if the saved IR drifted from live (a warning is emitted)
54
+ ui/<slug>.json # agent-built UI specs
55
+ subagents/<childId>.md # recursive delegate transcripts (childId "/" → "__")
56
+ ```
57
+
58
+ Key behaviors:
59
+
60
+ - **Designs come from the agent-api**, which resolves the latest IR itself — no
61
+ draft-branch guessing for the IR.
62
+ - **Each design also pulls its OWN vcs folder verbatim** (a scoped shallow clone
63
+ of just that design's repo, resolving the `drafts/*` ref that carries it), so
64
+ docs/notes beyond the IR ride along. `--no-vcs` skips this (IR-only).
65
+ - **Everything else the conversation referenced is cataloged, never cloned** —
66
+ any tenant's knowledge-base / context repo (a `resource: vcs` drive-ref,
67
+ whatever it's named) and any other artifact kind appears in
68
+ `index.json.references[]` with a ready-to-run `pullHint`, but its content is
69
+ not pulled. Pull a **specific** doc on demand (one path, not the whole repo)
70
+ with `mesh vcs get <repo> <path> --target <name>` (CLI) or `agent_get_repo_doc`
71
+ (MCP) — browse `conversation.md` to see which docs matter.
72
+ - **Subagents recurse by default** (cycle-guarded); `--no-recursive` for direct
73
+ delegates only.
74
+ - **Best-effort**: nothing aborts the pull — per-unit failures land in
75
+ `index.json.warnings[]`.
76
+
77
+ Reach for the granular verbs below when you want just the transcript, just the
78
+ artifact list, or a single artifact's files.
79
+
80
+ `list`/`show`/`artifacts` all accept the same `--target <name>` /
81
+ `--api-url <url>` / `--context <ctx>` / `--json` options (`mesh artifacts get`
82
+ takes `--target`/`--api-url`/`--context` plus `-o/--output <dir>`, no
83
+ `--json` — it always writes files). Start with `list` unless you already have
84
+ a conversation id.
85
+
86
+ ## The shared registry (`--target`)
87
+
88
+ `--target <name>` resolves against `~/.config/mesh/agent-targets.json`
89
+ (override with env `MESH_AGENT_TARGETS`) — **the exact same registry and
90
+ names the MCP `agent_*` tools use** (`@mesh-tech/agent-targets`, consumed by
91
+ both `mesh-cli` and `@mesh-tech/mesh-mcp`). `--target fub` on the CLI and
92
+ `target: "fub"` on `agent_send_message` hit the same origin with the same
93
+ identity. A registry entry looks like:
94
+
95
+ ```json
96
+ {
97
+ "defaultTarget": "hub",
98
+ "targets": {
99
+ "fub": {
100
+ "apiBaseUrl": "https://...",
101
+ "conversationPathPrefix": "/c",
102
+ "tenant": "fub",
103
+ "env": "dev",
104
+ "loginContext": "mesh.dev"
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ **`mesh agent-targets add/refresh/list` (the SSM-backed generator) is NOT
111
+ shipped yet.** Do not tell a user or agent to run it. Until it exists:
112
+ - If the registry file already has the target you need, just pass
113
+ `--target <name>`.
114
+ - If it doesn't (or the file doesn't exist), either hand-author an entry in
115
+ `~/.config/mesh/agent-targets.json` (schema above; see
116
+ `packages/agent-remote/agent-targets.example.json` for a fuller example),
117
+ or skip the registry entirely and pass `--api-url <url>` (+ `--context <ctx>`,
118
+ default `mesh.dev`) ad hoc — no registry lookup happens in that case.
119
+
120
+ Resolution precedence: `--api-url` (if given) > `--target` (if given,
121
+ resolved from the registry) > the registry's `defaultTarget` > the
122
+ `AGENT_API_URL`/`API_URL` env vars > `http://localhost:8787`. An unknown
123
+ `--target` name errors listing the available names.
124
+
125
+ ## Auth model
126
+
127
+ Auth is a Zitadel bearer, the same one `mesh login <context>` already caches
128
+ — no AWS role needed just to read. Each registry entry's `loginContext`
129
+ picks which cached login to use (default `mesh.dev`); with `--api-url`,
130
+ pass `--context <ctx>` to pick it explicitly. One `mesh login mesh.dev`
131
+ (device flow works headless) reaches any deployed agent through its
132
+ oauth2-proxy. A 401/403/redirect from an agent-api call means auth didn't
133
+ reach it — re-run `mesh login <that context>`.
134
+
135
+ ## MCP tools unavailable? Same registry, direct CLI path
136
+
137
+ When the `agent_*` MCP tools (`agent_list_conversations`,
138
+ `agent_check_conversation`, `agent_get_artifacts`,
139
+ `agent_get_workflow_design`, `agent_list_targets`, ...) aren't reachable —
140
+ no MCP server configured, or you're a plain shell/CLI agent — `mesh
141
+ conversations` reaches the identical agent-api directly, with the same
142
+ `--target` name and the same login. Nothing is lost by going CLI-only:
143
+ list → show → artifacts covers list/read/artifacts; `mesh artifacts get`
144
+ covers file export; workflow-design (the MCP's `agent_get_workflow_design`)
145
+ has no direct CLI verb yet — get it via `mesh conversations artifacts <id>`
146
+ (artifact index) plus `mesh artifacts get <id>:<artifactId>` for the IR/files.
147
+
148
+ ## Transcript break-glass: `conversation_unavailable`
149
+
150
+ `mesh conversations show <id>` reads the **live** worker (fast, decoded).
151
+ If the worker can no longer replay that workflow (code drift), it 503s with
152
+ `conversation_unavailable` and the CLI's error message already includes the
153
+ next step:
154
+
155
+ ```bash
156
+ mesh temporal recover-conversation <id>
157
+ ```
158
+
159
+ This reconstructs the transcript from durable Temporal history instead
160
+ (needs the Temporal encoding key; see the `core` skill's `temporal` row).
161
+ Add `--snapshot` for a structured, store-ready `{ messages, artifacts,
162
+ focus }` blob instead of a markdown transcript.
163
+
164
+ ## Output
165
+
166
+ - Piped or redirected (non-TTY), or `--json` passed: compact JSON, one line,
167
+ field names mirroring the agent-api payload — parse this.
168
+ - A TTY without `--json`: an aligned table (`list`: double-space-padded
169
+ columns, `ID TITLE UPDATED` — NOT `·`-separated; `artifacts`:
170
+ `ARTIFACT-ID · KIND · TITLE` + a ready-to-copy `mesh artifacts
171
+ get <id>:<artifactId>` download line; `show`: `role: content` blocks with
172
+ `tool-calls:`/`artifacts:` notes).
173
+
174
+ An agent scripting this should just pipe (`mesh conversations list --target
175
+ fub | jq ...`) rather than pass `--json` — output auto-detects non-TTY.
176
+
177
+ ## Errors, decoded
178
+
179
+ | Symptom | Meaning | Fix |
180
+ |---|---|---|
181
+ | `auth did not reach the agent` | 401/403/redirect | `mesh login <loginContext>` (the target's, or `--context`) |
182
+ | `conversation/artifact not found ... (<id>)` | 404, or not owned by this identity | `mesh conversations list --target <name>` to see valid ids |
183
+ | `... conversation_unavailable ... try: mesh temporal recover-conversation <id>` | 503, worker can't replay | run the suggested `recover-conversation` |
184
+ | `Unknown target "<name>". Available: ...` | `--target` not in the registry | pick a listed name, hand-author the entry, or use `--api-url` |
185
+ | `No agent target given and no registry ...` | no `--target`/`--api-url` and no registry file | pass `--api-url <url>`, or hand-author `~/.config/mesh/agent-targets.json` |
186
+ | `Registry at <path> is invalid: ...` | the JSON fails schema validation | fix the file, or pass `--api-url` |
187
+
188
+ ## See also
189
+
190
+ - `libs/mesh-cli/skills/core/SKILL.md` — full `mesh` command reference,
191
+ including the `conversations`/`artifacts`/`temporal` rows this skill
192
+ builds on.
193
+ - `packages/agent-remote/agent-targets.example.json` — a worked registry
194
+ file with `hub`/`fub`/`acme`/`local` entries.