@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,40 @@
1
+ /**
2
+ * A minimal SOCKS5 CONNECT forwarder: listens on a local TCP port and pipes
3
+ * each client connection through a SOCKS5 proxy (no-auth) to a fixed target.
4
+ *
5
+ * Presents the same plain `localhost:PORT` contract the SSM tunnels give today,
6
+ * so an app (e.g. a Temporal gRPC client) connects with no proxy awareness —
7
+ * the SOCKS5 proxy is the userspace-Tailscale daemon (MESH-2040 / MESH-2036).
8
+ */
9
+ import * as net from "node:net";
10
+ /** `"10.0.137.203"` → `[10,0,137,203]`; throws on anything that isn't IPv4. */
11
+ export declare function ipv4ToBytes(ip: string): number[];
12
+ /** SOCKS5 CONNECT request for an IPv4 target (VER, CMD=CONNECT, RSV, ATYP=IPv4, addr, port). */
13
+ export declare function socks5ConnectRequest(ip: string, port: number): Buffer;
14
+ /** Interpret the SOCKS5 reply code (byte 1 of the CONNECT reply). */
15
+ export declare function interpretSocksReply(code: number): {
16
+ ok: boolean;
17
+ message: string;
18
+ };
19
+ export interface ForwarderOptions {
20
+ /** Local TCP port to listen on (0 = ephemeral, useful in tests). */
21
+ listenPort: number;
22
+ socksHost?: string;
23
+ socksPort: number;
24
+ targetIp: string;
25
+ targetPort: number;
26
+ /**
27
+ * Observes server errors — above all a bind failure (`EADDRINUSE`). The
28
+ * forwarder still never crashes the process, but the error must not be
29
+ * INVISIBLE: an unbound forwarder whose port is held by a foreign process is
30
+ * the silent-dead-tunnel class (MESH-2407), so callers record it and the
31
+ * ownership handshake reports the port as not-listening.
32
+ */
33
+ onError?: (err: NodeJS.ErrnoException) => void;
34
+ }
35
+ /**
36
+ * Create (and start) a forwarder server. Each inbound client is spliced to
37
+ * `targetIp:targetPort` via a SOCKS5 CONNECT through `socksHost:socksPort`.
38
+ */
39
+ export declare function createForwarder(opts: ForwarderOptions): net.Server;
40
+ //# sourceMappingURL=socks-forward.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-forward.d.ts","sourceRoot":"","sources":["../../../src/utils/socks-forward.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAUhD;AAED,gGAAgG;AAChG,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AAcD,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAElF;AAED,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,KAAK,IAAI,CAAC;CAChD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,GAAG,CAAC,MAAM,CA8ClE"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * A minimal SOCKS5 CONNECT forwarder: listens on a local TCP port and pipes
3
+ * each client connection through a SOCKS5 proxy (no-auth) to a fixed target.
4
+ *
5
+ * Presents the same plain `localhost:PORT` contract the SSM tunnels give today,
6
+ * so an app (e.g. a Temporal gRPC client) connects with no proxy awareness —
7
+ * the SOCKS5 proxy is the userspace-Tailscale daemon (MESH-2040 / MESH-2036).
8
+ */
9
+ import * as net from "node:net";
10
+ /** `"10.0.137.203"` → `[10,0,137,203]`; throws on anything that isn't IPv4. */
11
+ export function ipv4ToBytes(ip) {
12
+ const parts = ip.split(".");
13
+ if (parts.length !== 4)
14
+ throw new Error(`not an IPv4 address: ${ip}`);
15
+ return parts.map((p) => {
16
+ const n = Number(p);
17
+ if (!Number.isInteger(n) || n < 0 || n > 255 || !/^\d+$/.test(p)) {
18
+ throw new Error(`not an IPv4 address: ${ip}`);
19
+ }
20
+ return n;
21
+ });
22
+ }
23
+ /** SOCKS5 CONNECT request for an IPv4 target (VER, CMD=CONNECT, RSV, ATYP=IPv4, addr, port). */
24
+ export function socks5ConnectRequest(ip, port) {
25
+ return Buffer.from([0x05, 0x01, 0x00, 0x01, ...ipv4ToBytes(ip), (port >> 8) & 0xff, port & 0xff]);
26
+ }
27
+ const SOCKS_REPLY_MESSAGES = {
28
+ 0: "succeeded",
29
+ 1: "general SOCKS server failure",
30
+ 2: "connection not allowed by ruleset",
31
+ 3: "network unreachable",
32
+ 4: "host unreachable",
33
+ 5: "connection refused",
34
+ 6: "TTL expired",
35
+ 7: "command not supported",
36
+ 8: "address type not supported",
37
+ };
38
+ /** Interpret the SOCKS5 reply code (byte 1 of the CONNECT reply). */
39
+ export function interpretSocksReply(code) {
40
+ return { ok: code === 0, message: SOCKS_REPLY_MESSAGES[code] ?? `unknown SOCKS reply ${code}` };
41
+ }
42
+ /**
43
+ * Create (and start) a forwarder server. Each inbound client is spliced to
44
+ * `targetIp:targetPort` via a SOCKS5 CONNECT through `socksHost:socksPort`.
45
+ */
46
+ export function createForwarder(opts) {
47
+ const socksHost = opts.socksHost ?? "127.0.0.1";
48
+ const server = net.createServer((client) => {
49
+ const up = net.connect(opts.socksPort, socksHost);
50
+ let buf = Buffer.alloc(0);
51
+ let phase = 0; // 0=await method-select, 1=await connect reply, 2=streaming
52
+ up.on("connect", () => up.write(Buffer.from([0x05, 0x01, 0x00]))); // greet, no-auth
53
+ up.on("data", (d) => {
54
+ if (phase === 2)
55
+ return;
56
+ buf = Buffer.concat([buf, d]);
57
+ if (phase === 0) {
58
+ if (buf.length < 2)
59
+ return;
60
+ buf = buf.subarray(2);
61
+ phase = 1;
62
+ up.write(socks5ConnectRequest(opts.targetIp, opts.targetPort));
63
+ }
64
+ if (phase === 1) {
65
+ if (buf.length < 10)
66
+ return;
67
+ const reply = interpretSocksReply(buf[1]);
68
+ const leftover = buf.subarray(10);
69
+ phase = 2;
70
+ if (!reply.ok) {
71
+ up.destroy();
72
+ client.destroy();
73
+ return;
74
+ }
75
+ if (leftover.length)
76
+ client.write(leftover);
77
+ client.pipe(up);
78
+ up.pipe(client);
79
+ }
80
+ });
81
+ client.on("error", () => up.destroy());
82
+ up.on("error", () => client.destroy());
83
+ // A cleanly-closed client (clean FIN, no "error") must still tear down the
84
+ // upstream SOCKS→target leg — otherwise a probe that connects then closes
85
+ // strands a real VPC-target connection until the target times out.
86
+ client.on("close", () => up.destroy());
87
+ up.on("close", () => client.destroy());
88
+ });
89
+ // A bind failure (e.g. the port is already held by an SSM tunnel) must not
90
+ // crash the process running this forwarder — but it must be OBSERVED, not
91
+ // swallowed: the runner records it and ownership checks fail the port.
92
+ // Attach before listen() so the error is caught.
93
+ server.on("error", (err) => opts.onError?.(err));
94
+ server.listen(opts.listenPort, "127.0.0.1");
95
+ return server;
96
+ }
97
+ //# sourceMappingURL=socks-forward.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-forward.js","sourceRoot":"","sources":["../../../src/utils/socks-forward.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface StackSelector {
2
+ /** Canonical Pulumi stack name. */
3
+ stack?: string;
4
+ /** @deprecated SST-era alias for {@link StackSelector.stack}; still accepted. */
5
+ stage?: string;
6
+ }
7
+ /**
8
+ * Resolve the stack selector, preferring the canonical `--stack` over the
9
+ * deprecated `--stage` alias. Pure: reports whether the deprecated alias supplied
10
+ * the value so the caller can warn. `--stack` wins when both are present.
11
+ */
12
+ export declare function resolveStackSelector(opts: StackSelector): {
13
+ stack: string | undefined;
14
+ usedDeprecatedStage: boolean;
15
+ };
16
+ /** Test-only: reset the once-per-process deprecation-warning latch. */
17
+ export declare function resetStackFlagWarning(): void;
18
+ /**
19
+ * Resolve `--stack`/`--stage` to the effective stack for use at a consumption
20
+ * site, warning ONCE per process when the deprecated `--stage` alias supplied it.
21
+ */
22
+ export declare function resolveStackOption(opts: StackSelector): string | undefined;
23
+ //# sourceMappingURL=stack-flag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-flag.d.ts","sourceRoot":"","sources":["../../../src/utils/stack-flag.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG;IACzD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAIA;AAID,uEAAuE;AACvE,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAS1E"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Stack-selection flag resolution (MESH-2154).
3
+ *
4
+ * `mesh` subcommands historically disagreed on the stack-selection flag:
5
+ * `deploy`/`cluster` use `--stack` (Pulumi-native), while `dev`/`secrets` used
6
+ * `--stage` (the SST-era term the platform has moved off). So `mesh kubectl
7
+ * --stage dev` and `mesh dev --stack …` each errored on muscle memory. We
8
+ * consolidate on `--stack` everywhere and keep `--stage` as a HIDDEN, deprecated
9
+ * alias that still works but warns — removable after a transition window.
10
+ */
11
+ import { logWarn } from './log.js';
12
+ /**
13
+ * Resolve the stack selector, preferring the canonical `--stack` over the
14
+ * deprecated `--stage` alias. Pure: reports whether the deprecated alias supplied
15
+ * the value so the caller can warn. `--stack` wins when both are present.
16
+ */
17
+ export function resolveStackSelector(opts) {
18
+ if (opts.stack != null)
19
+ return { stack: opts.stack, usedDeprecatedStage: false };
20
+ if (opts.stage != null)
21
+ return { stack: opts.stage, usedDeprecatedStage: true };
22
+ return { stack: undefined, usedDeprecatedStage: false };
23
+ }
24
+ let warnedOnce = false;
25
+ /** Test-only: reset the once-per-process deprecation-warning latch. */
26
+ export function resetStackFlagWarning() {
27
+ warnedOnce = false;
28
+ }
29
+ /**
30
+ * Resolve `--stack`/`--stage` to the effective stack for use at a consumption
31
+ * site, warning ONCE per process when the deprecated `--stage` alias supplied it.
32
+ */
33
+ export function resolveStackOption(opts) {
34
+ const { stack, usedDeprecatedStage } = resolveStackSelector(opts);
35
+ if (usedDeprecatedStage && !warnedOnce) {
36
+ warnedOnce = true;
37
+ logWarn('--stage is deprecated; use --stack (the Pulumi-native name). --stage still works for now.');
38
+ }
39
+ return stack;
40
+ }
41
+ //# sourceMappingURL=stack-flag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-flag.js","sourceRoot":"","sources":["../../../src/utils/stack-flag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AASnC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAmB;IAItD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC;IACjF,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC;IAChF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC;AAC1D,CAAC;AAED,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,uEAAuE;AACvE,MAAM,UAAU,qBAAqB;IACnC,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAmB;IACpD,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,mBAAmB,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,UAAU,GAAG,IAAI,CAAC;QAClB,OAAO,CACL,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Resolve a tenant's VPC tunnel targets from the platform bastion's service
3
+ * map — the same source `startSsmTunnels` reads — mapping bastion service keys
4
+ * to the app's tunnel names, resolving each ELB/RDS hostname to its private IP,
5
+ * and assigning collision-free localhost ports via the SSM port convention.
6
+ * (MESH-2040 / Slice 1 of MESH-2014.)
7
+ */
8
+ /** Local-port block width per tenant — wider than the canonical port span so
9
+ * two tenants' port blocks never overlap. */
10
+ export declare const PORT_BLOCK = 3000;
11
+ /**
12
+ * Deterministic per-tenant index for local-port offsetting. Reads a machine-global
13
+ * registry (`~/.config/mesh/tailscale/port-registry.json`), seeded `{ mesh: 0 }` so
14
+ * the hub's canonical ports are grandfathered regardless of registration order.
15
+ * Assigns the next index to an unseen tenant and persists it. `registryPath` is
16
+ * injectable for tests.
17
+ */
18
+ export declare function tenantPortIndex(tenant: string, registryPath?: string): number;
19
+ export interface TunnelTarget {
20
+ /** App-facing tunnel name (e.g. "temporal"). */
21
+ name: string;
22
+ /** Local port the forwarder listens on (SSM convention: base + remotePort). */
23
+ localPort: number;
24
+ /** VPC hostname (internal ELB / RDS endpoint). */
25
+ targetHost: string;
26
+ /** Resolved private IP of `targetHost`. */
27
+ targetIp: string;
28
+ /** Port on the VPC service. */
29
+ remotePort: number;
30
+ }
31
+ /**
32
+ * Bastion service key → app tunnel name. Mirrors `tunnelToBastionKey` in dev.ts
33
+ * (inverted): the bastion exposes `temporal-frontend`; the app calls it `temporal`.
34
+ */
35
+ export declare const TUNNEL_NAME_BY_BASTION_KEY: Record<string, string>;
36
+ /**
37
+ * Build the tunnel target set. `resolveIp` is injected for testability (the
38
+ * command passes `resolveElbIp`). Services not in the name map are skipped;
39
+ * services whose host can't be resolved are skipped (the forwarder needs an IP).
40
+ */
41
+ export declare function resolveTunnelTargets(services: Record<string, {
42
+ host: string;
43
+ port: number;
44
+ }>, resolveIp: (host: string) => string | null, portOffset?: number): TunnelTarget[];
45
+ /**
46
+ * Resolve an AWS-internal ELB/RDS hostname to its private IP via a public
47
+ * resolver — these names publish their private (10.x) address to public DNS
48
+ * but the host's default resolver may not answer for them. Returns null on
49
+ * failure (caller skips that tunnel).
50
+ */
51
+ export declare function resolveElbIp(host: string): string | null;
52
+ //# sourceMappingURL=tailscale-targets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailscale-targets.d.ts","sourceRoot":"","sources":["../../../src/utils/tailscale-targets.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;6CAC6C;AAC7C,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAc7E;AAED,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAI7D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACxD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAC1C,UAAU,SAAI,GACb,YAAY,EAAE,CAiBhB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAexD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Resolve a tenant's VPC tunnel targets from the platform bastion's service
3
+ * map — the same source `startSsmTunnels` reads — mapping bastion service keys
4
+ * to the app's tunnel names, resolving each ELB/RDS hostname to its private IP,
5
+ * and assigning collision-free localhost ports via the SSM port convention.
6
+ * (MESH-2040 / Slice 1 of MESH-2014.)
7
+ */
8
+ import { execFileSync } from "node:child_process";
9
+ import * as fs from "node:fs";
10
+ import * as path from "node:path";
11
+ import { reserveSsmLocalPortCandidate, preferredSsmLocalPort } from "../commands/dev.js";
12
+ import { CONFIG_DIR, atomicWriteFileSync } from "../commands/login.js";
13
+ /** Local-port block width per tenant — wider than the canonical port span so
14
+ * two tenants' port blocks never overlap. */
15
+ export const PORT_BLOCK = 3000;
16
+ /**
17
+ * Deterministic per-tenant index for local-port offsetting. Reads a machine-global
18
+ * registry (`~/.config/mesh/tailscale/port-registry.json`), seeded `{ mesh: 0 }` so
19
+ * the hub's canonical ports are grandfathered regardless of registration order.
20
+ * Assigns the next index to an unseen tenant and persists it. `registryPath` is
21
+ * injectable for tests.
22
+ */
23
+ export function tenantPortIndex(tenant, registryPath) {
24
+ const p = registryPath ?? path.join(CONFIG_DIR, "tailscale", "port-registry.json");
25
+ let reg;
26
+ try {
27
+ reg = JSON.parse(fs.readFileSync(p, "utf8"));
28
+ }
29
+ catch {
30
+ reg = { mesh: 0 };
31
+ }
32
+ if (tenant in reg)
33
+ return reg[tenant];
34
+ const idx = Math.max(-1, ...Object.values(reg)) + 1;
35
+ reg[tenant] = idx;
36
+ fs.mkdirSync(path.dirname(p), { recursive: true });
37
+ atomicWriteFileSync(p, JSON.stringify(reg, null, 2), 0o600);
38
+ return idx;
39
+ }
40
+ /**
41
+ * Bastion service key → app tunnel name. Mirrors `tunnelToBastionKey` in dev.ts
42
+ * (inverted): the bastion exposes `temporal-frontend`; the app calls it `temporal`.
43
+ */
44
+ export const TUNNEL_NAME_BY_BASTION_KEY = {
45
+ "temporal-frontend": "temporal",
46
+ "temporal-ui": "temporal-ui",
47
+ rds: "rds",
48
+ };
49
+ /**
50
+ * Build the tunnel target set. `resolveIp` is injected for testability (the
51
+ * command passes `resolveElbIp`). Services not in the name map are skipped;
52
+ * services whose host can't be resolved are skipped (the forwarder needs an IP).
53
+ */
54
+ export function resolveTunnelTargets(services, resolveIp, portOffset = 0) {
55
+ const reserved = new Set();
56
+ const targets = [];
57
+ for (const [key, svc] of Object.entries(services)) {
58
+ const name = TUNNEL_NAME_BY_BASTION_KEY[key];
59
+ if (!name)
60
+ continue;
61
+ const targetIp = resolveIp(svc.host);
62
+ if (!targetIp)
63
+ continue;
64
+ // Per-tenant offset keeps concurrent platform tenants off each other's ports.
65
+ const localPort = reserveSsmLocalPortCandidate(svc.port, reserved, preferredSsmLocalPort(svc.port) + portOffset);
66
+ targets.push({ name, localPort, targetHost: svc.host, targetIp, remotePort: svc.port });
67
+ }
68
+ return targets;
69
+ }
70
+ /**
71
+ * Resolve an AWS-internal ELB/RDS hostname to its private IP via a public
72
+ * resolver — these names publish their private (10.x) address to public DNS
73
+ * but the host's default resolver may not answer for them. Returns null on
74
+ * failure (caller skips that tunnel).
75
+ */
76
+ export function resolveElbIp(host) {
77
+ try {
78
+ const out = execFileSync("dig", ["+short", host, "@1.1.1.1"], {
79
+ encoding: "utf8",
80
+ stdio: ["ignore", "pipe", "ignore"],
81
+ });
82
+ const ip = out
83
+ .trim()
84
+ .split("\n")
85
+ .map((l) => l.trim())
86
+ .find((l) => /^\d+\.\d+\.\d+\.\d+$/.test(l));
87
+ return ip ?? null;
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ }
93
+ //# sourceMappingURL=tailscale-targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailscale-targets.js","sourceRoot":"","sources":["../../../src/utils/tailscale-targets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Userspace-Tailscale daemon management + tunnel-session state for
3
+ * `mesh vpn tunnel` (MESH-2040 / Slice 1 of MESH-2014).
4
+ *
5
+ * A per-tenant `tailscaled` runs in userspace-networking mode (brew formula,
6
+ * NOT the GUI app) exposing a SOCKS5 proxy; forwarders bridge `localhost:PORT`
7
+ * to VPC services through it. State lives under `~/.config/mesh/tailscale/<tenant>/`
8
+ * (r+w-granted under safehouse — see the MESH-2036 spike).
9
+ */
10
+ import type { PidSource } from "./pid.js";
11
+ import type { OwnershipCheck } from "./tunnel-ownership.js";
12
+ import type { TunnelTarget } from "./tailscale-targets.js";
13
+ import type { DevOutput } from "../commands/dev.js";
14
+ export declare function tenantStateDir(tenant: string): string;
15
+ export declare function socketPath(tenant: string): string;
16
+ export declare function logPath(tenant: string): string;
17
+ export declare function statePath(tenant: string): string;
18
+ /**
19
+ * Daemon-scoped metadata, written by `ensureDaemon` when it actually spawns the
20
+ * daemon. Unlike `tunnel-state.json` (which `down` clears), this survives `down`
21
+ * so a later `up` reuses the RUNNING daemon's SOCKS port instead of minting a
22
+ * fresh one the daemon isn't listening on (which would leave every forwarder
23
+ * dialing a dead port). Also records the daemon pid so `stopDaemon` can kill it.
24
+ */
25
+ export declare function daemonMetaPath(tenant: string): string;
26
+ /**
27
+ * Ownership manifest written by the RUNNER (the process that binds the
28
+ * forwarder ports) — pid, process-group id, per-run token, control port. The
29
+ * ownership handshake (MESH-2407) verifies against it; teardown signals the
30
+ * recorded process group.
31
+ */
32
+ export declare function runnerManifestPath(tenant: string): string;
33
+ export interface TunnelState {
34
+ tenant: string;
35
+ env: string;
36
+ socksPort: number;
37
+ loginServer: string;
38
+ /** PID of the detached forwarder supervisor (null until spawned). */
39
+ supervisorPid: number | null;
40
+ /** How the runner is supervised. Defaults to "detached" when absent. */
41
+ managed?: "launchd" | "detached";
42
+ startedAt: string;
43
+ tunnels: TunnelTarget[];
44
+ }
45
+ export declare function readTunnelState(tenant: string): TunnelState | null;
46
+ export declare function writeTunnelState(tenant: string, state: TunnelState): void;
47
+ export declare function clearTunnelState(tenant: string): void;
48
+ export interface DaemonMeta {
49
+ /** The `--socks5-server` port the running daemon actually listens on. */
50
+ socksPort: number;
51
+ /** PID of the detached `tailscaled` process (for `stopDaemon`). */
52
+ pid: number;
53
+ }
54
+ export declare function readDaemonMeta(tenant: string): DaemonMeta | null;
55
+ export declare function writeDaemonMeta(tenant: string, meta: DaemonMeta): void;
56
+ export declare function clearDaemonMeta(tenant: string): void;
57
+ /** Parse `tailscale status --json` → the fields we care about. */
58
+ export declare function parseDaemonState(statusJson: string): {
59
+ backendState: string;
60
+ selfName?: string;
61
+ };
62
+ /** The brew `tailscaled` (NOT the GUI app, which ships no standalone daemon). */
63
+ export declare function tailscaledBinPath(): string;
64
+ /** The brew `tailscale` CLI (prefer it over the GUI shim, which aborts under sandbox). */
65
+ export declare function tailscaleBinPath(): string;
66
+ /** Backend state via the tenant's control socket; "Down" when no daemon answers. */
67
+ export declare function daemonState(tenant: string): {
68
+ backendState: string;
69
+ selfName?: string;
70
+ };
71
+ /**
72
+ * Extract the `--socks5-server` port from a `tailscaled` command line. Pure so
73
+ * it's unit-testable. Accepts both `--socks5-server=127.0.0.1:PORT` and the
74
+ * space-separated form, and a `localhost` host literal. Returns null if absent
75
+ * or malformed.
76
+ */
77
+ export declare function parseSocksPortFromArgv(argv: string): number | null;
78
+ /**
79
+ * Find the running userspace `tailscaled` for a tenant by its unique
80
+ * `--socket=<path>` argument, returning its pid and the SOCKS port it ACTUALLY
81
+ * bound (parsed from argv). Authoritative when `daemon.json` is missing or stale
82
+ * (e.g. a daemon left by an older build that predates the meta file). Returns
83
+ * null when no matching process is found or `ps` is unavailable.
84
+ */
85
+ export declare function findRunningDaemon(tenant: string): {
86
+ pid: number;
87
+ socksPort: number | null;
88
+ } | null;
89
+ /** True if something accepts TCP on 127.0.0.1:port within `timeoutMs`. */
90
+ export declare function portAccepts(port: number, timeoutMs?: number): Promise<boolean>;
91
+ /**
92
+ * Ensure a userspace `tailscaled` is running for the tenant and return the SOCKS
93
+ * port the forwarders should dial. Idempotent — reuses a live daemon, but
94
+ * RECONCILES the port: a daemon that's up on a different port than requested
95
+ * (older build with no `daemon.json`, or stale meta) would otherwise leave every
96
+ * forwarder dialing a dead port (MESH-2169). Trust `opts.socksPort` only if it
97
+ * truly accepts; else adopt the running daemon's real port; else restart fresh.
98
+ */
99
+ export declare function ensureDaemon(tenant: string, opts: {
100
+ region: string;
101
+ socksPort: number;
102
+ }): Promise<number>;
103
+ /**
104
+ * Stop the detached `tailscaled` for a tenant (SIGTERM its pid) and remove the
105
+ * socket + daemon metadata. Leaves the Headscale node identity in `tailscaled.state`
106
+ * so a later `up` re-spawns and rejoins without an interactive re-login — unless
107
+ * the caller logged out first.
108
+ *
109
+ * Best-effort, and that includes a corrupt `daemon.json`: an unsignalable
110
+ * recorded pid is REFUSED (never handed to `kill`) but only warns — the socket
111
+ * and meta are still cleared. `ensureDaemon` calls this on the UP path to
112
+ * recycle a daemon it can't verify, so throwing here would dead-end
113
+ * `mesh vpn tunnel up` / `mesh dev` on the very file this function deletes.
114
+ * Safe to call when nothing is running.
115
+ */
116
+ export declare function stopDaemon(tenant: string): void;
117
+ /**
118
+ * Build the `tailscale up` argument vector. Pure so it can be unit-tested and so
119
+ * the interactive (browser-register) and zero-touch (pre-auth key) forms differ
120
+ * only by the trailing `--authkey`.
121
+ */
122
+ export declare function buildTailscaleUpArgs(opts: {
123
+ socket: string;
124
+ loginServer: string;
125
+ hostname: string;
126
+ preAuthKey?: string;
127
+ }): string[];
128
+ /**
129
+ * Join the tenant's Headscale tailnet via Zitadel OIDC if not already Running.
130
+ * Prints the device-flow registration URL and polls until registered. When a
131
+ * pre-auth key is supplied the join is non-interactive: no `/register/` URL is
132
+ * emitted, so the scrape/relay is skipped and we just wait for Running.
133
+ */
134
+ export declare function joinHeadscale(tenant: string, loginServer: string, opts?: {
135
+ preAuthKey?: string;
136
+ }): Promise<void>;
137
+ /** Log the tenant daemon out of Headscale (disconnect). Daemon process persists. */
138
+ export declare function logout(tenant: string): void;
139
+ /**
140
+ * True iff two target sets are identical down to targetIp + remotePort. A live
141
+ * runner pins each forwarder's target at startup, so if the ELB IP rotated (or a
142
+ * port changed) the running forwarders point at a dead address and must be
143
+ * respawned, not reused. Pid-agnostic (a launchd runner records no supervisor pid).
144
+ */
145
+ export declare function tunnelTargetsEqual(a: TunnelTarget[], b: TunnelTarget[]): boolean;
146
+ /** True iff `state` has a supervisor pid and its target set equals `targets`. */
147
+ export declare function supervisorTargetsMatch(state: TunnelState | null, targets: TunnelTarget[]): boolean;
148
+ /**
149
+ * SIGTERM the supervisor's whole process GROUP, not the bare pid.
150
+ *
151
+ * `state.supervisorPid` is the pid of the detached spawn — which, under the
152
+ * canonical source launcher, is `bin/mesh.mjs`. That launcher blocks in
153
+ * `execFileSync` around the *real* runner (a `node --import tsx … mesh.ts`
154
+ * grandchild that actually binds the forwarder ports), and `execFileSync` does
155
+ * not forward signals. So signalling the bare pid kills only the launcher and
156
+ * ORPHANS the runner, which keeps its ports bound — the orphan then answers
157
+ * `allForwardersListening`'s ownership-less liveness dial and silently pins
158
+ * every tunnel to a stale target (the MESH-2169 / MESH-2014 failure class).
159
+ *
160
+ * The launcher is spawned `detached: true`, so it is a process-group leader
161
+ * (`pgid === pid`); `process.kill(-pid, …)` reaps the launcher and the runner
162
+ * together. Falls back to the bare pid for a legacy state file whose pid was
163
+ * not a group leader, and tolerates ESRCH (already gone).
164
+ *
165
+ * `pid` is always recovered — from `tunnel-state.json`, `runner.json`, or a
166
+ * `ps` scan — never constructed here, so it is guarded first. The guard rejects
167
+ * anything below 2, which is what makes the NEGATED form safe: `pid >= 2` ⇒
168
+ * `-pid <= -2`, a real process group, never `kill(0)` (this shell's own group)
169
+ * or `kill(-1)` (broadcast to everything the user can signal). See utils/pid.ts.
170
+ *
171
+ * @throws {MeshCliError} when `pid` is unsignalable. Callers reaping SEVERAL
172
+ * independently-recovered pids must catch per-pid (see `stopTunnelRunners`) —
173
+ * letting one refusal propagate would skip the other pids and leave a live
174
+ * runner holding ports.
175
+ */
176
+ export declare function killSupervisor(pid: number, source?: PidSource): void;
177
+ /**
178
+ * The ownership handshake for a tenant's tunnel runner (MESH-2407): manifest →
179
+ * live pid → control endpoint → token + SOCKS port + port coverage. This is
180
+ * the ONLY readiness/reuse signal — a bare TCP dial proves a listener exists,
181
+ * not that it is ours, and adopting a foreign listener is exactly the
182
+ * silent-dead-tunnel class (MESH-2169 / MESH-2014 / #2991). As a bonus the
183
+ * handshake reads listening state from the runner's in-process servers, so it
184
+ * opens no SOCKS→VPC data connection the way port dials do.
185
+ */
186
+ export declare function verifyTunnelOwnership(tenant: string, expected: {
187
+ socksPort: number;
188
+ ports: number[];
189
+ }): Promise<OwnershipCheck>;
190
+ /**
191
+ * Tear down EVERY runner we can attribute to the tenant: the recorded
192
+ * supervisor pid (as a process group — see `killSupervisor`), the launchd
193
+ * agent, the manifest's process group, and any `__run`/`__supervise` process
194
+ * discovered from argv (a runner from an older build, or one whose state file
195
+ * was lost). This is the single teardown path — the #2991 lesson generalized:
196
+ * no kill path may leave a grandchild with ports still bound.
197
+ */
198
+ export declare function stopTunnelRunners(tenant: string, prior: TunnelState | null): void;
199
+ /**
200
+ * Ensure the per-tenant forwarder supervisor is running for `state.tunnels`.
201
+ * Idempotent: reuses a live runner ONLY when it passes the ownership handshake
202
+ * (our manifest token, our SOCKS port, every target port listening in-process);
203
+ * otherwise tears down every attributable runner, verifies the ports actually
204
+ * freed (a still-held port is a foreign squatter → loud failure, never spawn
205
+ * over it), and (re)spawns a fresh runner — whose readiness is again the
206
+ * handshake, not a bare port dial. Persists the state and returns the pid.
207
+ */
208
+ export declare function ensureForwarders(state: TunnelState): Promise<number>;
209
+ /**
210
+ * Rewrite `devOutput.tunnels` so each resolved target points at its local
211
+ * forwarder (`localhost:localPort`) — the same shape `startSsmTunnels`
212
+ * produces. Unmatched tunnels are left untouched. Pure (no mutation of input).
213
+ */
214
+ export declare function rewriteTunnelsForTargets(devOutput: DevOutput, targets: TunnelTarget[]): DevOutput;
215
+ /** True when the brew `tailscaled` binary is resolvable (Tailscale transport is usable). */
216
+ export declare function tailscaleAvailable(): boolean;
217
+ /**
218
+ * Ensure the tenant's Tailscale tunnels are fully up: the shared per-tenant
219
+ * daemon (started + OIDC-joined if needed), the resolved VPC targets, and the
220
+ * forwarder supervisor. Idempotent (shared across worktrees/invocations of the
221
+ * same tenant). Returns the resolved targets. Used by both `mesh vpn tunnel up`
222
+ * and `mesh dev --transport=tailscale`.
223
+ */
224
+ export declare function ensureTailscaleTunnels(tenant: string, env: string, opts: {
225
+ region: string;
226
+ loginServer: string;
227
+ socksPort: number;
228
+ preAuthKey?: string;
229
+ }): Promise<TunnelTarget[]>;
230
+ /**
231
+ * `startSsmTunnels` drop-in for `mesh dev`: ensure the tenant's Tailscale
232
+ * tunnels, then rewrite `devOutput.tunnels` to the local forwarder ports.
233
+ */
234
+ export declare function startTailscaleTunnels(devOutput: DevOutput, ctx: {
235
+ tenant: string;
236
+ env: string;
237
+ region: string;
238
+ loginServer: string;
239
+ socksPort: number;
240
+ preAuthKey?: string;
241
+ }): Promise<DevOutput>;
242
+ export declare function launchAgentLabel(tenant: string): string;
243
+ /** Render the per-tenant LaunchAgent plist (pure). */
244
+ export declare function renderLaunchAgentPlist(args: {
245
+ tenant: string;
246
+ meshBin: string;
247
+ nodeBin: string;
248
+ logPath: string;
249
+ /** PATH for the agent — must include the dir of `tailscaled` so daemon reheal
250
+ * works under launchd's minimal PATH (esp. Intel `/usr/local/bin`). */
251
+ pathEnv?: string;
252
+ }): string;
253
+ /** Targets whose local forwarder port isn't currently accepting connections. */
254
+ export declare function forwardersNeedingRebind(targets: TunnelTarget[], listening: Set<number>): TunnelTarget[];
255
+ export declare function launchAgentPath(tenant: string): string;
256
+ /** True when launchctl works for this user (blocked under the seatbelt sandbox → false). */
257
+ export declare function launchdAvailable(): boolean;
258
+ /**
259
+ * Write + (re)load the per-tenant LaunchAgent. Returns true iff it fully
260
+ * succeeded — any failure (plist write blocked by the sandbox, `launchctl`
261
+ * bootstrap denied, …) returns false so the caller falls back to a detached
262
+ * runner. Never throws.
263
+ */
264
+ export declare function installLaunchAgent(tenant: string, meshBin: string): boolean;
265
+ /** Unload + remove the per-tenant LaunchAgent (best-effort). */
266
+ export declare function uninstallLaunchAgent(tenant: string): void;
267
+ /**
268
+ * Long-lived runner for a tenant's tunnels — used both under launchd and as the
269
+ * detached fallback. Runs a forwarder per target and, every ~5s, self-heals:
270
+ * respawns the daemon if its process died, and rebinds any forwarder whose port
271
+ * stopped listening. As the process that actually binds the ports, it is the
272
+ * sole author of the ownership manifest + control endpoint (MESH-2407) that
273
+ * callers verify against. Needs no AWS (targets come from tunnel-state). Never
274
+ * returns.
275
+ */
276
+ export declare function runTunnels(tenant: string): Promise<never>;
277
+ //# sourceMappingURL=tailscale.d.ts.map