@mesh-tech/mesh-cli 0.20.2 → 0.20.3

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 (435) hide show
  1. package/dist/bin/mesh.d.ts +0 -12
  2. package/dist/bin/mesh.js +12 -12
  3. package/dist/bin/mesh.js.map +0 -1
  4. package/dist/build-info.json +2 -2
  5. package/dist/src/commands/agent-api-client.d.ts +0 -70
  6. package/dist/src/commands/agent-api-client.js +0 -80
  7. package/dist/src/commands/app-check.d.ts +0 -56
  8. package/dist/src/commands/app-check.js +0 -72
  9. package/dist/src/commands/artifacts.d.ts +0 -11
  10. package/dist/src/commands/artifacts.js +0 -33
  11. package/dist/src/commands/cluster.d.ts +0 -39
  12. package/dist/src/commands/cluster.js +0 -73
  13. package/dist/src/commands/conversations.d.ts +0 -36
  14. package/dist/src/commands/conversations.js +0 -59
  15. package/dist/src/commands/create-app.d.ts +0 -98
  16. package/dist/src/commands/create-app.js +1 -163
  17. package/dist/src/commands/db/connect.d.ts +0 -7
  18. package/dist/src/commands/db/connect.js +0 -9
  19. package/dist/src/commands/db/credentials.d.ts +0 -7
  20. package/dist/src/commands/db/credentials.js +0 -10
  21. package/dist/src/commands/db/env.d.ts +0 -6
  22. package/dist/src/commands/db/env.js +0 -14
  23. package/dist/src/commands/db/exec.d.ts +0 -43
  24. package/dist/src/commands/db/exec.js +0 -69
  25. package/dist/src/commands/db/index.d.ts +0 -10
  26. package/dist/src/commands/db/index.js +0 -10
  27. package/dist/src/commands/db/psql.d.ts +0 -7
  28. package/dist/src/commands/db/psql.js +0 -18
  29. package/dist/src/commands/deploy.d.ts +0 -38
  30. package/dist/src/commands/deploy.js +1 -76
  31. package/dist/src/commands/dev-doctor.d.ts +0 -82
  32. package/dist/src/commands/dev-doctor.js +3 -132
  33. package/dist/src/commands/dev-launch.d.ts +0 -52
  34. package/dist/src/commands/dev-launch.js +0 -56
  35. package/dist/src/commands/dev-token-server.d.ts +0 -18
  36. package/dist/src/commands/dev-token-server.js +1 -24
  37. package/dist/src/commands/dev.d.ts +0 -246
  38. package/dist/src/commands/dev.js +5 -963
  39. package/dist/src/commands/docs.d.ts +0 -1
  40. package/dist/src/commands/docs.js +0 -12
  41. package/dist/src/commands/hub/index.d.ts +0 -60
  42. package/dist/src/commands/hub/index.js +2 -139
  43. package/dist/src/commands/init/wizard.d.ts +0 -128
  44. package/dist/src/commands/init/wizard.js +0 -109
  45. package/dist/src/commands/init.d.ts +0 -55
  46. package/dist/src/commands/init.js +0 -70
  47. package/dist/src/commands/install-shim.d.ts +0 -23
  48. package/dist/src/commands/install-shim.js +2 -29
  49. package/dist/src/commands/local/auth-provision.d.ts +0 -80
  50. package/dist/src/commands/local/auth-provision.js +0 -109
  51. package/dist/src/commands/local/dev-local.d.ts +0 -91
  52. package/dist/src/commands/local/dev-local.js +0 -147
  53. package/dist/src/commands/local/docker-runner.d.ts +0 -22
  54. package/dist/src/commands/local/docker-runner.js +2 -35
  55. package/dist/src/commands/local/helpers.d.ts +0 -14
  56. package/dist/src/commands/local/helpers.js +0 -13
  57. package/dist/src/commands/local/hub-local.d.ts +0 -96
  58. package/dist/src/commands/local/hub-local.js +0 -111
  59. package/dist/src/commands/local/index.d.ts +0 -14
  60. package/dist/src/commands/local/index.js +0 -86
  61. package/dist/src/commands/local/mocks.d.ts +0 -269
  62. package/dist/src/commands/local/mocks.js +1 -274
  63. package/dist/src/commands/local/seed-hub-catalog.d.ts +0 -25
  64. package/dist/src/commands/local/seed-hub-catalog.js +0 -41
  65. package/dist/src/commands/local/seed-zitadel.d.ts +0 -82
  66. package/dist/src/commands/local/seed-zitadel.js +0 -158
  67. package/dist/src/commands/local/seed.d.ts +0 -64
  68. package/dist/src/commands/local/seed.js +0 -78
  69. package/dist/src/commands/local/stack.d.ts +0 -141
  70. package/dist/src/commands/local/stack.js +0 -153
  71. package/dist/src/commands/login.d.ts +0 -265
  72. package/dist/src/commands/login.js +4 -418
  73. package/dist/src/commands/peer-addressing.d.ts +0 -39
  74. package/dist/src/commands/peer-addressing.js +0 -37
  75. package/dist/src/commands/port-ownership.d.ts +0 -44
  76. package/dist/src/commands/port-ownership.js +0 -47
  77. package/dist/src/commands/registry-publish.d.ts +0 -1
  78. package/dist/src/commands/registry-publish.js +0 -46
  79. package/dist/src/commands/registry.d.ts +4 -237
  80. package/dist/src/commands/registry.js +2 -316
  81. package/dist/src/commands/secrets/exec.d.ts +0 -16
  82. package/dist/src/commands/secrets/exec.js +0 -24
  83. package/dist/src/commands/secrets/index.d.ts +0 -9
  84. package/dist/src/commands/secrets/index.js +0 -10
  85. package/dist/src/commands/secrets/migrate-config.d.ts +0 -17
  86. package/dist/src/commands/secrets/migrate-config.js +0 -40
  87. package/dist/src/commands/secrets/reindex.d.ts +0 -38
  88. package/dist/src/commands/secrets/reindex.js +0 -39
  89. package/dist/src/commands/secrets/set.d.ts +0 -47
  90. package/dist/src/commands/secrets/set.js +0 -107
  91. package/dist/src/commands/site.d.ts +0 -1
  92. package/dist/src/commands/site.js +0 -61
  93. package/dist/src/commands/skills.d.ts +0 -61
  94. package/dist/src/commands/skills.js +0 -83
  95. package/dist/src/commands/stack.d.ts +0 -15
  96. package/dist/src/commands/stack.js +1 -128
  97. package/dist/src/commands/temporal.d.ts +0 -30
  98. package/dist/src/commands/temporal.js.map +0 -1
  99. package/dist/src/commands/tenant.d.ts +0 -31
  100. package/dist/src/commands/tenant.js +0 -55
  101. package/dist/src/commands/tunnel/index.d.ts +0 -40
  102. package/dist/src/commands/tunnel/index.js +0 -141
  103. package/dist/src/commands/vcs/clone.d.ts +0 -1
  104. package/dist/src/commands/vcs/clone.js +0 -4
  105. package/dist/src/commands/vcs/common.d.ts +0 -32
  106. package/dist/src/commands/vcs/common.js +0 -41
  107. package/dist/src/commands/vcs/drafts.d.ts +0 -1
  108. package/dist/src/commands/vcs/drafts.js +0 -1
  109. package/dist/src/commands/vcs/get.d.ts +0 -1
  110. package/dist/src/commands/vcs/get.js +0 -11
  111. package/dist/src/commands/vcs/index.d.ts +0 -1
  112. package/dist/src/commands/vcs/index.js +0 -1
  113. package/dist/src/commands/vcs/propose.d.ts +0 -26
  114. package/dist/src/commands/vcs/propose.js +3 -34
  115. package/dist/src/commands/vcs/review.d.ts +0 -1
  116. package/dist/src/commands/vcs/review.js +0 -1
  117. package/dist/src/commands/vcs/rm.d.ts +0 -11
  118. package/dist/src/commands/vcs/rm.js +0 -14
  119. package/dist/src/commands/vcs-enrich.d.ts +0 -12
  120. package/dist/src/commands/vcs-enrich.js +0 -12
  121. package/dist/src/commands/vpn/index.d.ts +0 -17
  122. package/dist/src/commands/vpn/index.js +0 -102
  123. package/dist/src/commands/vpn/tunnel.d.ts +0 -9
  124. package/dist/src/commands/vpn/tunnel.js +0 -37
  125. package/dist/src/commands/workflow.d.ts +0 -22
  126. package/dist/src/commands/workflow.js +0 -80
  127. package/dist/src/docs/assemble.d.ts +0 -117
  128. package/dist/src/docs/assemble.js +0 -142
  129. package/dist/src/docs/cli-reference.d.ts +0 -58
  130. package/dist/src/docs/cli-reference.js +0 -77
  131. package/dist/src/docs/discover.d.ts +0 -40
  132. package/dist/src/docs/discover.js +2 -60
  133. package/dist/src/docs/portal.d.ts +0 -44
  134. package/dist/src/docs/portal.js +0 -49
  135. package/dist/src/docs/registry-docs.d.ts +0 -29
  136. package/dist/src/docs/registry-docs.js +0 -40
  137. package/dist/src/docs/schema.d.ts +0 -36
  138. package/dist/src/docs/schema.js +0 -52
  139. package/dist/src/docs/serve.d.ts +0 -18
  140. package/dist/src/docs/serve.js +2 -30
  141. package/dist/src/docs/start.d.ts +0 -42
  142. package/dist/src/docs/start.js +0 -70
  143. package/dist/src/eval/agent-eval.d.mts +0 -12
  144. package/dist/src/eval/agent-eval.mjs +0 -22
  145. package/dist/src/index.d.ts +0 -6
  146. package/dist/src/index.js.map +0 -1
  147. package/dist/src/program.d.ts +0 -20
  148. package/dist/src/program.js +0 -24
  149. package/dist/src/utils/auth-preflight.d.ts +0 -137
  150. package/dist/src/utils/auth-preflight.js +0 -149
  151. package/dist/src/utils/aws-auth.d.ts +0 -163
  152. package/dist/src/utils/aws-auth.js +3 -232
  153. package/dist/src/utils/bastion.d.ts +0 -27
  154. package/dist/src/utils/bastion.js +0 -28
  155. package/dist/src/utils/build-info.d.ts +0 -22
  156. package/dist/src/utils/build-info.js +0 -27
  157. package/dist/src/utils/cache-home.d.ts +0 -23
  158. package/dist/src/utils/cache-home.js +0 -25
  159. package/dist/src/utils/capture-history.d.ts +0 -54
  160. package/dist/src/utils/capture-history.js +1 -55
  161. package/dist/src/utils/context.d.ts +0 -23
  162. package/dist/src/utils/context.js +0 -43
  163. package/dist/src/utils/credentials.d.ts +0 -38
  164. package/dist/src/utils/credentials.js +0 -39
  165. package/dist/src/utils/deploy-preflight.d.ts +0 -38
  166. package/dist/src/utils/deploy-preflight.js +1 -71
  167. package/dist/src/utils/errors.d.ts +0 -53
  168. package/dist/src/utils/errors.js +0 -49
  169. package/dist/src/utils/first-party-contexts.d.ts +0 -38
  170. package/dist/src/utils/first-party-contexts.js +0 -44
  171. package/dist/src/utils/index.d.ts +0 -4
  172. package/dist/src/utils/index.js +0 -4
  173. package/dist/src/utils/kubeconfig.d.ts +0 -40
  174. package/dist/src/utils/kubeconfig.js +0 -44
  175. package/dist/src/utils/log.d.ts +0 -20
  176. package/dist/src/utils/log.js +0 -20
  177. package/dist/src/utils/mesh-json.d.ts +0 -46
  178. package/dist/src/utils/mesh-json.js +0 -39
  179. package/dist/src/utils/pid.d.ts +0 -42
  180. package/dist/src/utils/pid.js +0 -48
  181. package/dist/src/utils/pulumi-run.d.ts +0 -14
  182. package/dist/src/utils/pulumi-run.js +0 -42
  183. package/dist/src/utils/pulumi.d.ts +0 -34
  184. package/dist/src/utils/pulumi.js +0 -38
  185. package/dist/src/utils/reachability.d.ts +0 -27
  186. package/dist/src/utils/reachability.js +0 -40
  187. package/dist/src/utils/recover-conversation.d.ts +0 -110
  188. package/dist/src/utils/recover-conversation.js +0 -108
  189. package/dist/src/utils/registry-broker.d.ts +5 -84
  190. package/dist/src/utils/registry-broker.js +0 -62
  191. package/dist/src/utils/registry-identity.d.ts +0 -149
  192. package/dist/src/utils/registry-identity.js +0 -143
  193. package/dist/src/utils/scaffold-versions.d.ts +0 -41
  194. package/dist/src/utils/scaffold-versions.js +0 -42
  195. package/dist/src/utils/socks-forward.d.ts +0 -24
  196. package/dist/src/utils/socks-forward.js +2 -25
  197. package/dist/src/utils/stack-flag.d.ts +0 -13
  198. package/dist/src/utils/stack-flag.js +0 -21
  199. package/dist/src/utils/tailscale-targets.d.ts +0 -37
  200. package/dist/src/utils/tailscale-targets.js +0 -33
  201. package/dist/src/utils/tailscale.d.ts +0 -177
  202. package/dist/src/utils/tailscale.js +6 -337
  203. package/dist/src/utils/temporal-auth.d.ts +0 -41
  204. package/dist/src/utils/temporal-auth.js +0 -52
  205. package/dist/src/utils/temporal-codec.d.ts +0 -89
  206. package/dist/src/utils/temporal-codec.js.map +0 -1
  207. package/dist/src/utils/tunnel-ownership.d.ts +0 -79
  208. package/dist/src/utils/tunnel-ownership.js +0 -74
  209. package/dist/src/utils/vpn-join.d.ts +0 -16
  210. package/dist/src/utils/vpn-join.js +0 -17
  211. package/dist/src/utils/vpn.d.ts +0 -42
  212. package/dist/src/utils/vpn.js +0 -52
  213. package/dist/src/utils/workflow-fingerprint.d.ts +0 -39
  214. package/dist/src/utils/workflow-fingerprint.js +1 -63
  215. package/dist/src/utils/worktree-identity.d.ts +0 -62
  216. package/dist/src/utils/worktree-identity.js +0 -88
  217. package/package.json +1 -1
  218. package/skills/core/SKILL.md +9 -10
  219. package/templates/api-auth/api/src/index.ts.hbs +1 -1
  220. package/templates/api-auth/api/src/spicedb-http-provider.ts.hbs +2 -2
  221. package/templates/api-role-gating/api/src/authn.ts.hbs +2 -2
  222. package/templates/api-role-gating/index.ts.hbs +1 -1
  223. package/templates/api-role-gating/skills/develop/SKILL.md.hbs +1 -1
  224. package/templates/platform-repo/core/Pulumi.{{tenant}}-{{env}}.yaml.hbs +2 -2
  225. package/templates/platform-repo/platform/index.ts +1 -1
  226. package/dist/bin/mesh.d.ts.map +0 -1
  227. package/dist/src/commands/agent-api-client.d.ts.map +0 -1
  228. package/dist/src/commands/agent-api-client.js.map +0 -1
  229. package/dist/src/commands/app-check.d.ts.map +0 -1
  230. package/dist/src/commands/app-check.js.map +0 -1
  231. package/dist/src/commands/artifacts.d.ts.map +0 -1
  232. package/dist/src/commands/artifacts.js.map +0 -1
  233. package/dist/src/commands/cluster.d.ts.map +0 -1
  234. package/dist/src/commands/cluster.js.map +0 -1
  235. package/dist/src/commands/conversations.d.ts.map +0 -1
  236. package/dist/src/commands/conversations.js.map +0 -1
  237. package/dist/src/commands/create-app.d.ts.map +0 -1
  238. package/dist/src/commands/create-app.js.map +0 -1
  239. package/dist/src/commands/db/connect.d.ts.map +0 -1
  240. package/dist/src/commands/db/connect.js.map +0 -1
  241. package/dist/src/commands/db/credentials.d.ts.map +0 -1
  242. package/dist/src/commands/db/credentials.js.map +0 -1
  243. package/dist/src/commands/db/env.d.ts.map +0 -1
  244. package/dist/src/commands/db/env.js.map +0 -1
  245. package/dist/src/commands/db/exec.d.ts.map +0 -1
  246. package/dist/src/commands/db/exec.js.map +0 -1
  247. package/dist/src/commands/db/index.d.ts.map +0 -1
  248. package/dist/src/commands/db/index.js.map +0 -1
  249. package/dist/src/commands/db/psql.d.ts.map +0 -1
  250. package/dist/src/commands/db/psql.js.map +0 -1
  251. package/dist/src/commands/deploy.d.ts.map +0 -1
  252. package/dist/src/commands/deploy.js.map +0 -1
  253. package/dist/src/commands/dev-doctor.d.ts.map +0 -1
  254. package/dist/src/commands/dev-doctor.js.map +0 -1
  255. package/dist/src/commands/dev-launch.d.ts.map +0 -1
  256. package/dist/src/commands/dev-launch.js.map +0 -1
  257. package/dist/src/commands/dev-token-server.d.ts.map +0 -1
  258. package/dist/src/commands/dev-token-server.js.map +0 -1
  259. package/dist/src/commands/dev.d.ts.map +0 -1
  260. package/dist/src/commands/dev.js.map +0 -1
  261. package/dist/src/commands/docs.d.ts.map +0 -1
  262. package/dist/src/commands/docs.js.map +0 -1
  263. package/dist/src/commands/hub/index.d.ts.map +0 -1
  264. package/dist/src/commands/hub/index.js.map +0 -1
  265. package/dist/src/commands/init/wizard.d.ts.map +0 -1
  266. package/dist/src/commands/init/wizard.js.map +0 -1
  267. package/dist/src/commands/init.d.ts.map +0 -1
  268. package/dist/src/commands/init.js.map +0 -1
  269. package/dist/src/commands/install-shim.d.ts.map +0 -1
  270. package/dist/src/commands/install-shim.js.map +0 -1
  271. package/dist/src/commands/local/auth-provision.d.ts.map +0 -1
  272. package/dist/src/commands/local/auth-provision.js.map +0 -1
  273. package/dist/src/commands/local/dev-local.d.ts.map +0 -1
  274. package/dist/src/commands/local/dev-local.js.map +0 -1
  275. package/dist/src/commands/local/docker-runner.d.ts.map +0 -1
  276. package/dist/src/commands/local/docker-runner.js.map +0 -1
  277. package/dist/src/commands/local/helpers.d.ts.map +0 -1
  278. package/dist/src/commands/local/helpers.js.map +0 -1
  279. package/dist/src/commands/local/hub-local.d.ts.map +0 -1
  280. package/dist/src/commands/local/hub-local.js.map +0 -1
  281. package/dist/src/commands/local/index.d.ts.map +0 -1
  282. package/dist/src/commands/local/index.js.map +0 -1
  283. package/dist/src/commands/local/mocks.d.ts.map +0 -1
  284. package/dist/src/commands/local/mocks.js.map +0 -1
  285. package/dist/src/commands/local/seed-hub-catalog.d.ts.map +0 -1
  286. package/dist/src/commands/local/seed-hub-catalog.js.map +0 -1
  287. package/dist/src/commands/local/seed-zitadel.d.ts.map +0 -1
  288. package/dist/src/commands/local/seed-zitadel.js.map +0 -1
  289. package/dist/src/commands/local/seed.d.ts.map +0 -1
  290. package/dist/src/commands/local/seed.js.map +0 -1
  291. package/dist/src/commands/local/stack.d.ts.map +0 -1
  292. package/dist/src/commands/local/stack.js.map +0 -1
  293. package/dist/src/commands/login.d.ts.map +0 -1
  294. package/dist/src/commands/login.js.map +0 -1
  295. package/dist/src/commands/peer-addressing.d.ts.map +0 -1
  296. package/dist/src/commands/peer-addressing.js.map +0 -1
  297. package/dist/src/commands/port-ownership.d.ts.map +0 -1
  298. package/dist/src/commands/port-ownership.js.map +0 -1
  299. package/dist/src/commands/registry-publish.d.ts.map +0 -1
  300. package/dist/src/commands/registry-publish.js.map +0 -1
  301. package/dist/src/commands/registry.d.ts.map +0 -1
  302. package/dist/src/commands/registry.js.map +0 -1
  303. package/dist/src/commands/secrets/exec.d.ts.map +0 -1
  304. package/dist/src/commands/secrets/exec.js.map +0 -1
  305. package/dist/src/commands/secrets/index.d.ts.map +0 -1
  306. package/dist/src/commands/secrets/index.js.map +0 -1
  307. package/dist/src/commands/secrets/migrate-config.d.ts.map +0 -1
  308. package/dist/src/commands/secrets/migrate-config.js.map +0 -1
  309. package/dist/src/commands/secrets/reindex.d.ts.map +0 -1
  310. package/dist/src/commands/secrets/reindex.js.map +0 -1
  311. package/dist/src/commands/secrets/set.d.ts.map +0 -1
  312. package/dist/src/commands/secrets/set.js.map +0 -1
  313. package/dist/src/commands/site.d.ts.map +0 -1
  314. package/dist/src/commands/site.js.map +0 -1
  315. package/dist/src/commands/skills.d.ts.map +0 -1
  316. package/dist/src/commands/skills.js.map +0 -1
  317. package/dist/src/commands/stack.d.ts.map +0 -1
  318. package/dist/src/commands/stack.js.map +0 -1
  319. package/dist/src/commands/temporal.d.ts.map +0 -1
  320. package/dist/src/commands/tenant.d.ts.map +0 -1
  321. package/dist/src/commands/tenant.js.map +0 -1
  322. package/dist/src/commands/tunnel/index.d.ts.map +0 -1
  323. package/dist/src/commands/tunnel/index.js.map +0 -1
  324. package/dist/src/commands/vcs/clone.d.ts.map +0 -1
  325. package/dist/src/commands/vcs/clone.js.map +0 -1
  326. package/dist/src/commands/vcs/common.d.ts.map +0 -1
  327. package/dist/src/commands/vcs/common.js.map +0 -1
  328. package/dist/src/commands/vcs/drafts.d.ts.map +0 -1
  329. package/dist/src/commands/vcs/drafts.js.map +0 -1
  330. package/dist/src/commands/vcs/get.d.ts.map +0 -1
  331. package/dist/src/commands/vcs/get.js.map +0 -1
  332. package/dist/src/commands/vcs/index.d.ts.map +0 -1
  333. package/dist/src/commands/vcs/index.js.map +0 -1
  334. package/dist/src/commands/vcs/propose.d.ts.map +0 -1
  335. package/dist/src/commands/vcs/propose.js.map +0 -1
  336. package/dist/src/commands/vcs/review.d.ts.map +0 -1
  337. package/dist/src/commands/vcs/review.js.map +0 -1
  338. package/dist/src/commands/vcs/rm.d.ts.map +0 -1
  339. package/dist/src/commands/vcs/rm.js.map +0 -1
  340. package/dist/src/commands/vcs-enrich.d.ts.map +0 -1
  341. package/dist/src/commands/vcs-enrich.js.map +0 -1
  342. package/dist/src/commands/vpn/index.d.ts.map +0 -1
  343. package/dist/src/commands/vpn/index.js.map +0 -1
  344. package/dist/src/commands/vpn/tunnel.d.ts.map +0 -1
  345. package/dist/src/commands/vpn/tunnel.js.map +0 -1
  346. package/dist/src/commands/workflow.d.ts.map +0 -1
  347. package/dist/src/commands/workflow.js.map +0 -1
  348. package/dist/src/docs/assemble.d.ts.map +0 -1
  349. package/dist/src/docs/assemble.js.map +0 -1
  350. package/dist/src/docs/cli-reference.d.ts.map +0 -1
  351. package/dist/src/docs/cli-reference.js.map +0 -1
  352. package/dist/src/docs/discover.d.ts.map +0 -1
  353. package/dist/src/docs/discover.js.map +0 -1
  354. package/dist/src/docs/portal.d.ts.map +0 -1
  355. package/dist/src/docs/portal.js.map +0 -1
  356. package/dist/src/docs/registry-docs.d.ts.map +0 -1
  357. package/dist/src/docs/registry-docs.js.map +0 -1
  358. package/dist/src/docs/schema.d.ts.map +0 -1
  359. package/dist/src/docs/schema.js.map +0 -1
  360. package/dist/src/docs/serve.d.ts.map +0 -1
  361. package/dist/src/docs/serve.js.map +0 -1
  362. package/dist/src/docs/start.d.ts.map +0 -1
  363. package/dist/src/docs/start.js.map +0 -1
  364. package/dist/src/eval/agent-eval.d.mts.map +0 -1
  365. package/dist/src/eval/agent-eval.mjs.map +0 -1
  366. package/dist/src/index.d.ts.map +0 -1
  367. package/dist/src/program.d.ts.map +0 -1
  368. package/dist/src/program.js.map +0 -1
  369. package/dist/src/utils/auth-preflight.d.ts.map +0 -1
  370. package/dist/src/utils/auth-preflight.js.map +0 -1
  371. package/dist/src/utils/aws-auth.d.ts.map +0 -1
  372. package/dist/src/utils/aws-auth.js.map +0 -1
  373. package/dist/src/utils/bastion.d.ts.map +0 -1
  374. package/dist/src/utils/bastion.js.map +0 -1
  375. package/dist/src/utils/build-info.d.ts.map +0 -1
  376. package/dist/src/utils/build-info.js.map +0 -1
  377. package/dist/src/utils/cache-home.d.ts.map +0 -1
  378. package/dist/src/utils/cache-home.js.map +0 -1
  379. package/dist/src/utils/capture-history.d.ts.map +0 -1
  380. package/dist/src/utils/capture-history.js.map +0 -1
  381. package/dist/src/utils/context.d.ts.map +0 -1
  382. package/dist/src/utils/context.js.map +0 -1
  383. package/dist/src/utils/credentials.d.ts.map +0 -1
  384. package/dist/src/utils/credentials.js.map +0 -1
  385. package/dist/src/utils/deploy-preflight.d.ts.map +0 -1
  386. package/dist/src/utils/deploy-preflight.js.map +0 -1
  387. package/dist/src/utils/errors.d.ts.map +0 -1
  388. package/dist/src/utils/errors.js.map +0 -1
  389. package/dist/src/utils/first-party-contexts.d.ts.map +0 -1
  390. package/dist/src/utils/first-party-contexts.js.map +0 -1
  391. package/dist/src/utils/index.d.ts.map +0 -1
  392. package/dist/src/utils/index.js.map +0 -1
  393. package/dist/src/utils/kubeconfig.d.ts.map +0 -1
  394. package/dist/src/utils/kubeconfig.js.map +0 -1
  395. package/dist/src/utils/log.d.ts.map +0 -1
  396. package/dist/src/utils/log.js.map +0 -1
  397. package/dist/src/utils/mesh-json.d.ts.map +0 -1
  398. package/dist/src/utils/mesh-json.js.map +0 -1
  399. package/dist/src/utils/pid.d.ts.map +0 -1
  400. package/dist/src/utils/pid.js.map +0 -1
  401. package/dist/src/utils/pulumi-run.d.ts.map +0 -1
  402. package/dist/src/utils/pulumi-run.js.map +0 -1
  403. package/dist/src/utils/pulumi.d.ts.map +0 -1
  404. package/dist/src/utils/pulumi.js.map +0 -1
  405. package/dist/src/utils/reachability.d.ts.map +0 -1
  406. package/dist/src/utils/reachability.js.map +0 -1
  407. package/dist/src/utils/recover-conversation.d.ts.map +0 -1
  408. package/dist/src/utils/recover-conversation.js.map +0 -1
  409. package/dist/src/utils/registry-broker.d.ts.map +0 -1
  410. package/dist/src/utils/registry-broker.js.map +0 -1
  411. package/dist/src/utils/registry-identity.d.ts.map +0 -1
  412. package/dist/src/utils/registry-identity.js.map +0 -1
  413. package/dist/src/utils/scaffold-versions.d.ts.map +0 -1
  414. package/dist/src/utils/scaffold-versions.js.map +0 -1
  415. package/dist/src/utils/socks-forward.d.ts.map +0 -1
  416. package/dist/src/utils/socks-forward.js.map +0 -1
  417. package/dist/src/utils/stack-flag.d.ts.map +0 -1
  418. package/dist/src/utils/stack-flag.js.map +0 -1
  419. package/dist/src/utils/tailscale-targets.d.ts.map +0 -1
  420. package/dist/src/utils/tailscale-targets.js.map +0 -1
  421. package/dist/src/utils/tailscale.d.ts.map +0 -1
  422. package/dist/src/utils/tailscale.js.map +0 -1
  423. package/dist/src/utils/temporal-auth.d.ts.map +0 -1
  424. package/dist/src/utils/temporal-auth.js.map +0 -1
  425. package/dist/src/utils/temporal-codec.d.ts.map +0 -1
  426. package/dist/src/utils/tunnel-ownership.d.ts.map +0 -1
  427. package/dist/src/utils/tunnel-ownership.js.map +0 -1
  428. package/dist/src/utils/vpn-join.d.ts.map +0 -1
  429. package/dist/src/utils/vpn-join.js.map +0 -1
  430. package/dist/src/utils/vpn.d.ts.map +0 -1
  431. package/dist/src/utils/vpn.js.map +0 -1
  432. package/dist/src/utils/workflow-fingerprint.d.ts.map +0 -1
  433. package/dist/src/utils/workflow-fingerprint.js.map +0 -1
  434. package/dist/src/utils/worktree-identity.d.ts.map +0 -1
  435. package/dist/src/utils/worktree-identity.js.map +0 -1
@@ -1,43 +1,2 @@
1
- /**
2
- * Temporal auth resolution for the mesh CLI.
3
- *
4
- * Two responsibilities, kept together because they're always used as a pair:
5
- * 1. `resolveTemporalAuth` — discover the M2M client_credentials + Zitadel
6
- * issuer/project for a tenant/env from SSM (with a kubectl pod-env fallback).
7
- * This is what `mesh dev` injects into worker/service env.
8
- * 2. `acquireTemporalBearer` — exchange those credentials for a Zitadel Bearer
9
- * JWT via the OAuth2 client_credentials grant, so CLI commands that talk to
10
- * an auth-enforcing Temporal frontend (describe/history/terminate) can attach
11
- * `authorization: Bearer <token>` gRPC metadata. Without it the server's
12
- * MeshAuthorizer denies calls with "Request unauthorized".
13
- *
14
- * The token fetch is intentionally reimplemented here (not imported from
15
- * `@mesh-tech/app-kit`, which mirrors it) because app-kit *depends on* mesh-cli —
16
- * importing it back would create a dependency cycle.
17
- */
18
- /**
19
- * Discover Temporal M2M credentials + Zitadel issuer/project for a tenant/env.
20
- *
21
- * Returns an env-var-shaped record (TEMPORAL_AUTH_CLIENT_ID/SECRET,
22
- * ZITADEL_ISSUER, ZITADEL_PROJECT_ID, …). Missing pieces are simply absent —
23
- * callers decide whether what resolved is enough to mint a token.
24
- *
25
- * `platformName` keys the Zitadel issuer lookup and is the platform NAME
26
- * (e.g. "trabian"/"mesh"), NOT the app tenant — getting it wrong means the
27
- * issuer never resolves, so no Bearer, so Temporal denies with "Request
28
- * unauthorized".
29
- */
30
1
  export declare function resolveTemporalAuth(tenant: string, env: string, platformName?: string): Promise<Record<string, string>>;
31
- /**
32
- * Exchange resolved M2M credentials for a Zitadel Bearer access token via the
33
- * OAuth2 client_credentials grant. Reads from the passed record first, then the
34
- * ambient env (which `mesh dev` may already have populated).
35
- *
36
- * Returns `undefined` when credentials are incomplete — the caller then connects
37
- * unauthenticated (correct for local/non-enforcing Temporal servers).
38
- *
39
- * Mirrors `@mesh-tech/app-kit`'s `acquireToken` (kept in sync deliberately; see
40
- * the module doc for why it isn't imported).
41
- */
42
2
  export declare function acquireTemporalBearer(vars?: Record<string, string | undefined>): Promise<string | undefined>;
43
- //# sourceMappingURL=temporal-auth.d.ts.map
@@ -1,40 +1,9 @@
1
- /**
2
- * Temporal auth resolution for the mesh CLI.
3
- *
4
- * Two responsibilities, kept together because they're always used as a pair:
5
- * 1. `resolveTemporalAuth` — discover the M2M client_credentials + Zitadel
6
- * issuer/project for a tenant/env from SSM (with a kubectl pod-env fallback).
7
- * This is what `mesh dev` injects into worker/service env.
8
- * 2. `acquireTemporalBearer` — exchange those credentials for a Zitadel Bearer
9
- * JWT via the OAuth2 client_credentials grant, so CLI commands that talk to
10
- * an auth-enforcing Temporal frontend (describe/history/terminate) can attach
11
- * `authorization: Bearer <token>` gRPC metadata. Without it the server's
12
- * MeshAuthorizer denies calls with "Request unauthorized".
13
- *
14
- * The token fetch is intentionally reimplemented here (not imported from
15
- * `@mesh-tech/app-kit`, which mirrors it) because app-kit *depends on* mesh-cli —
16
- * importing it back would create a dependency cycle.
17
- */
18
1
  import { execFileSync } from "node:child_process";
19
2
  import { logSuccess, logWarn } from "./log.js";
20
- /**
21
- * Discover Temporal M2M credentials + Zitadel issuer/project for a tenant/env.
22
- *
23
- * Returns an env-var-shaped record (TEMPORAL_AUTH_CLIENT_ID/SECRET,
24
- * ZITADEL_ISSUER, ZITADEL_PROJECT_ID, …). Missing pieces are simply absent —
25
- * callers decide whether what resolved is enough to mint a token.
26
- *
27
- * `platformName` keys the Zitadel issuer lookup and is the platform NAME
28
- * (e.g. "trabian"/"mesh"), NOT the app tenant — getting it wrong means the
29
- * issuer never resolves, so no Bearer, so Temporal denies with "Request
30
- * unauthorized".
31
- */
32
3
  export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
33
4
  const { SSMClient, GetParameterCommand } = await import("@aws-sdk/client-ssm");
34
5
  const ssm = new SSMClient({ region: process.env.AWS_REGION || "us-east-2" });
35
6
  const results = {};
36
- // Each SSM lookup is independent so a missing optional parameter
37
- // (e.g. token-exchange-app) doesn't prevent other credentials from resolving.
38
7
  async function trySSM(name) {
39
8
  try {
40
9
  const resp = await ssm.send(new GetParameterCommand({ Name: name, WithDecryption: true }));
@@ -45,7 +14,6 @@ export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
45
14
  }
46
15
  }
47
16
  try {
48
- // ── Scheme 1: Zitadel-managed per-tenant credentials ──
49
17
  const workerPath = `/mesh-platform/${tenant}/${env}/temporal/worker-service-account-key`;
50
18
  const exchangePath = `/mesh-platform/${tenant}/${env}/temporal/token-exchange-app`;
51
19
  const workerJson = await trySSM(workerPath);
@@ -54,15 +22,12 @@ export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
54
22
  results.TEMPORAL_AUTH_CLIENT_ID = worker.clientId;
55
23
  results.TEMPORAL_AUTH_CLIENT_SECRET = worker.clientSecret;
56
24
  }
57
- // Token exchange app credentials (optional — not all tenants have this)
58
25
  const exchangeJson = await trySSM(exchangePath);
59
26
  if (exchangeJson) {
60
27
  const exchange = JSON.parse(exchangeJson);
61
28
  results.ZITADEL_TOKEN_EXCHANGE_CLIENT_ID = exchange.clientId;
62
29
  results.ZITADEL_TOKEN_EXCHANGE_CLIENT_SECRET = exchange.clientSecret;
63
30
  }
64
- // Zitadel issuer URL and project ID from the PLATFORM's config, keyed by the
65
- // platform NAME (not the app tenant, not a hardcoded "mesh").
66
31
  const platformJson = await trySSM(`/mesh-platform/${platformName}/${env}/platform/zitadel`);
67
32
  if (platformJson) {
68
33
  const platform = JSON.parse(platformJson);
@@ -71,7 +36,6 @@ export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
71
36
  if (platform.projectId)
72
37
  results.ZITADEL_PROJECT_ID = platform.projectId;
73
38
  }
74
- // ── Scheme 2: Legacy shared credentials (fallback) ──
75
39
  if (!results.TEMPORAL_AUTH_CLIENT_ID) {
76
40
  const legacyClientId = await trySSM("/platform/temporal/auth/CLIENT_ID");
77
41
  const legacyClientSecret = await trySSM("/platform/temporal/auth/CLIENT_SECRET");
@@ -80,7 +44,6 @@ export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
80
44
  results.TEMPORAL_AUTH_CLIENT_SECRET = legacyClientSecret;
81
45
  }
82
46
  }
83
- // ── Discover Zitadel config from Temporal server pods (final fallback) ──
84
47
  if (!results.ZITADEL_ISSUER) {
85
48
  try {
86
49
  const podEnv = execFileSync("kubectl", [
@@ -127,17 +90,6 @@ export async function resolveTemporalAuth(tenant, env, platformName = tenant) {
127
90
  }
128
91
  return results;
129
92
  }
130
- /**
131
- * Exchange resolved M2M credentials for a Zitadel Bearer access token via the
132
- * OAuth2 client_credentials grant. Reads from the passed record first, then the
133
- * ambient env (which `mesh dev` may already have populated).
134
- *
135
- * Returns `undefined` when credentials are incomplete — the caller then connects
136
- * unauthenticated (correct for local/non-enforcing Temporal servers).
137
- *
138
- * Mirrors `@mesh-tech/app-kit`'s `acquireToken` (kept in sync deliberately; see
139
- * the module doc for why it isn't imported).
140
- */
141
93
  export async function acquireTemporalBearer(vars = {}) {
142
94
  const issuerUrl = vars.ZITADEL_ISSUER ?? process.env.ZITADEL_ISSUER;
143
95
  const projectId = vars.ZITADEL_PROJECT_ID ?? process.env.ZITADEL_PROJECT_ID;
@@ -149,9 +101,6 @@ export async function acquireTemporalBearer(vars = {}) {
149
101
  const scopes = ["openid"];
150
102
  if (projectId) {
151
103
  scopes.push(`urn:zitadel:iam:org:project:id:${projectId}:aud`);
152
- // Request project roles in the token (MeshAuthorizer Path A). Same env gate
153
- // as app-kit: skipping the roles scope falls back to client_id parsing
154
- // (Path B), which currently also yields the reader bit.
155
104
  if (process.env.TEMPORAL_M2M_SKIP_ROLES_SCOPE !== "true") {
156
105
  scopes.push("urn:zitadel:iam:org:projects:roles");
157
106
  }
@@ -173,4 +122,3 @@ export async function acquireTemporalBearer(vars = {}) {
173
122
  const data = (await response.json());
174
123
  return data.access_token;
175
124
  }
176
- //# sourceMappingURL=temporal-auth.js.map
@@ -1,101 +1,12 @@
1
- /**
2
- * Temporal payload decryption helpers for mesh CLI.
3
- *
4
- * Mirrors the AES-256-GCM codec in `@mesh-tech/app-kit/temporal-codec`. The CLI
5
- * can't depend on app-kit directly because app-kit depends on mesh-cli — so
6
- * the codec logic is intentionally duplicated here, kept small, and bounded
7
- * to read-only decryption (the CLI never encrypts).
8
- *
9
- * Wire format (matches app-kit EncryptionCodec):
10
- * metadata["encoding"] = "binary/encrypted"
11
- * metadata["encryption-key-id"] = first 16 hex chars of SHA-256(encodingKey)
12
- * data = IV (12 bytes) || ciphertext || GCM auth tag (16 bytes)
13
- *
14
- * Decryption of `data` yields a serialized Temporal Payload protobuf, whose
15
- * inner `encoding` metadata tells you how to interpret the inner bytes
16
- * (`json/plain`, `binary/plain`, etc.). We hand-decode the Payload message
17
- * (a trivial 2-field protobuf) instead of depending on `@temporalio/proto`,
18
- * so the CLI stays dependency-clean and doesn't need a Temporal SDK peer.
19
- */
20
- /**
21
- * Read the Temporal encoding key from a Kubernetes secret in the given
22
- * namespace. Returns `undefined` when kubectl is unavailable, the secret
23
- * doesn't exist, or the caller isn't authenticated to the cluster.
24
- *
25
- * The K8s secret is preferred over Pulumi stack output because personal dev
26
- * stacks ship a placeholder encoding key that cannot decrypt deployed
27
- * payloads; the K8s secret is always authoritative for a given namespace.
28
- *
29
- * @param namespace - Kubernetes namespace matching the Temporal namespace
30
- * (mesh apps use the same name for both).
31
- */
32
1
  export declare function resolveTemporalEncodingKeyFromK8s(namespace: string): string | undefined;
33
- /**
34
- * Minimal shape of a Temporal Payload we care about.
35
- * Matches `temporal.api.common.v1.Payload` from @temporalio/proto but avoids
36
- * importing the type at module load time (so the CLI still loads without the
37
- * Temporal SDK installed).
38
- */
39
2
  export interface RawPayload {
40
3
  metadata?: Record<string, Uint8Array | null | undefined> | null;
41
4
  data?: Uint8Array | null;
42
5
  }
43
- /**
44
- * A decrypter closure bound to a specific encoding key. Returns a decoded
45
- * human-readable string for a single encrypted Payload, or `null` when the
46
- * payload wasn't encrypted and the caller should fall back to raw decoding.
47
- *
48
- * Error paths (`[undecryptable]`, `[decode error: ...]`) are returned as
49
- * strings rather than thrown — debugging a history is a best-effort read-only
50
- * operation and one bad payload shouldn't abort the whole dump.
51
- */
52
6
  export type PayloadDecrypter = (payload: RawPayload | null | undefined) => Promise<string | null>;
53
- /**
54
- * Build a decrypter closure for the given encoding key.
55
- */
56
7
  export declare function createPayloadDecrypter(encodingKey: string): Promise<PayloadDecrypter>;
57
- /**
58
- * A closure that decrypts a single encrypted Temporal Payload to its INNER
59
- * (plaintext) Payload — the `{ metadata, data }` the worker's codec wrapped —
60
- * rather than the human-readable string {@link PayloadDecrypter} produces.
61
- *
62
- * Returns `null` when the payload isn't encrypted (the caller leaves it as-is).
63
- * Unlike the display decrypter, decryption errors THROW here: a fixture with a
64
- * silently-mangled payload would replay wrong, so the caller must surface it.
65
- */
66
8
  export type RawPayloadDecrypter = (payload: RawPayload | null | undefined) => Promise<RawPayload | null>;
67
- /**
68
- * Build a raw (Payload-in, Payload-out) decrypter for the given encoding key.
69
- *
70
- * This is the fixture-capture counterpart of {@link createPayloadDecrypter}:
71
- * where that one renders a payload for human display (lossy — binary payloads
72
- * become placeholders), this one returns the exact decrypted inner Payload so
73
- * the bytes can be re-serialized into a replayable proto3-JSON history.
74
- */
75
9
  export declare function createRawPayloadDecrypter(encodingKey: string): Promise<RawPayloadDecrypter>;
76
- /**
77
- * Resolve the Temporal encoding key for a namespace, logging where it came
78
- * from (or why it couldn't be found). Prefer the K8s secret (authoritative for
79
- * the namespace); fall back to an explicit TEMPORAL_ENCODING_KEY env var. The
80
- * env fallback lets you decrypt a workflow's history OFFLINE — e.g. to
81
- * reconstruct a conversation, or capture a replay fixture, whose worker can no
82
- * longer replay it — using the key from a running `mesh dev` worker env when
83
- * kubectl/cluster access isn't set up.
84
- *
85
- * Returns `undefined` when neither source yields a key.
86
- */
87
10
  export declare function resolveEncodingKey(namespace: string): string | undefined;
88
- /**
89
- * Resolve the encoding key and build a decrypter for the given namespace.
90
- * Logs a warning and returns `undefined` when the key can't be read; callers
91
- * should fall back to printing events without payloads.
92
- */
93
11
  export declare function buildDecrypterForNamespace(namespace: string): Promise<PayloadDecrypter | undefined>;
94
- /**
95
- * Resolve the encoding key and build a RAW (Payload-in/Payload-out) decrypter
96
- * for the given namespace — used by `capture-history` to decrypt payloads back
97
- * into replayable proto bytes. Returns `undefined` when the key can't be read;
98
- * callers decide whether that's fatal.
99
- */
100
12
  export declare function buildRawDecrypterForNamespace(namespace: string): Promise<RawPayloadDecrypter | undefined>;
101
- //# sourceMappingURL=temporal-codec.d.ts.map
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/utils/temporal-codec.ts", "../../../src/utils/log.ts"],
4
- "sourcesContent": ["/**\n * Temporal payload decryption helpers for mesh CLI.\n *\n * Mirrors the AES-256-GCM codec in `@mesh-tech/app-kit/temporal-codec`. The CLI\n * can't depend on app-kit directly because app-kit depends on mesh-cli \u2014 so\n * the codec logic is intentionally duplicated here, kept small, and bounded\n * to read-only decryption (the CLI never encrypts).\n *\n * Wire format (matches app-kit EncryptionCodec):\n * metadata[\"encoding\"] = \"binary/encrypted\"\n * metadata[\"encryption-key-id\"] = first 16 hex chars of SHA-256(encodingKey)\n * data = IV (12 bytes) || ciphertext || GCM auth tag (16 bytes)\n *\n * Decryption of `data` yields a serialized Temporal Payload protobuf, whose\n * inner `encoding` metadata tells you how to interpret the inner bytes\n * (`json/plain`, `binary/plain`, etc.). We hand-decode the Payload message\n * (a trivial 2-field protobuf) instead of depending on `@temporalio/proto`,\n * so the CLI stays dependency-clean and doesn't need a Temporal SDK peer.\n */\n\nimport { execFileSync } from \"child_process\";\nimport { webcrypto as crypto } from \"node:crypto\";\nimport { logSuccess, logWarn } from \"./log.js\";\n\n// \u2500\u2500 Encoding key resolution \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Read the Temporal encoding key from a Kubernetes secret in the given\n * namespace. Returns `undefined` when kubectl is unavailable, the secret\n * doesn't exist, or the caller isn't authenticated to the cluster.\n *\n * The K8s secret is preferred over Pulumi stack output because personal dev\n * stacks ship a placeholder encoding key that cannot decrypt deployed\n * payloads; the K8s secret is always authoritative for a given namespace.\n *\n * @param namespace - Kubernetes namespace matching the Temporal namespace\n * (mesh apps use the same name for both).\n */\nexport function resolveTemporalEncodingKeyFromK8s(\n namespace: string,\n): string | undefined {\n const secretName = `${namespace}-temporal-encoding-key`;\n try {\n const b64 = execFileSync(\n \"kubectl\",\n [\n \"get\",\n \"secret\",\n secretName,\n \"-n\",\n namespace,\n \"-o\",\n \"jsonpath={.data.TEMPORAL_ENCODING_KEY}\",\n ],\n { encoding: \"utf-8\", timeout: 10_000, stdio: [\"pipe\", \"pipe\", \"pipe\"] },\n ).trim();\n\n if (!b64) return undefined;\n return Buffer.from(b64, \"base64\").toString(\"utf-8\");\n } catch {\n // kubectl missing, secret absent, or no cluster access \u2014 caller decides.\n return undefined;\n }\n}\n\n// \u2500\u2500 AES-256-GCM decryption \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ENCRYPTED_ENCODING = \"binary/encrypted\";\nconst IV_LENGTH = 12;\n\nasync function deriveKey(encodingKey: string): Promise<crypto.CryptoKey> {\n const keyData = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(encodingKey),\n );\n return crypto.subtle.importKey(\n \"raw\",\n keyData,\n { name: \"AES-GCM\" },\n false,\n [\"decrypt\"],\n );\n}\n\nasync function aesGcmDecrypt(\n data: Uint8Array,\n key: crypto.CryptoKey,\n): Promise<Uint8Array> {\n const iv = data.slice(0, IV_LENGTH);\n const ciphertextWithTag = data.slice(IV_LENGTH);\n const decrypted = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv },\n key,\n ciphertextWithTag,\n );\n return new Uint8Array(decrypted);\n}\n\n// \u2500\u2500 Payload decoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Minimal shape of a Temporal Payload we care about.\n * Matches `temporal.api.common.v1.Payload` from @temporalio/proto but avoids\n * importing the type at module load time (so the CLI still loads without the\n * Temporal SDK installed).\n */\nexport interface RawPayload {\n metadata?: Record<string, Uint8Array | null | undefined> | null;\n data?: Uint8Array | null;\n}\n\n/**\n * A decrypter closure bound to a specific encoding key. Returns a decoded\n * human-readable string for a single encrypted Payload, or `null` when the\n * payload wasn't encrypted and the caller should fall back to raw decoding.\n *\n * Error paths (`[undecryptable]`, `[decode error: ...]`) are returned as\n * strings rather than thrown \u2014 debugging a history is a best-effort read-only\n * operation and one bad payload shouldn't abort the whole dump.\n */\nexport type PayloadDecrypter = (\n payload: RawPayload | null | undefined,\n) => Promise<string | null>;\n\n/**\n * Build a decrypter closure for the given encoding key.\n */\nexport async function createPayloadDecrypter(\n encodingKey: string,\n): Promise<PayloadDecrypter> {\n const key = await deriveKey(encodingKey);\n\n return async (payload) => {\n if (!payload?.metadata) return null;\n\n const encodingBytes = payload.metadata[\"encoding\"];\n if (!encodingBytes) return null;\n const encoding = new TextDecoder().decode(encodingBytes);\n if (encoding !== ENCRYPTED_ENCODING) return null;\n\n if (!payload.data) return \"[encrypted payload missing data]\";\n\n let inner: RawPayload;\n try {\n const decrypted = await aesGcmDecrypt(payload.data, key);\n inner = decodePayloadProtobuf(decrypted);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return `[undecryptable: ${msg}]`;\n }\n\n return decodeInnerPayload(inner);\n };\n}\n\n/**\n * A closure that decrypts a single encrypted Temporal Payload to its INNER\n * (plaintext) Payload \u2014 the `{ metadata, data }` the worker's codec wrapped \u2014\n * rather than the human-readable string {@link PayloadDecrypter} produces.\n *\n * Returns `null` when the payload isn't encrypted (the caller leaves it as-is).\n * Unlike the display decrypter, decryption errors THROW here: a fixture with a\n * silently-mangled payload would replay wrong, so the caller must surface it.\n */\nexport type RawPayloadDecrypter = (\n payload: RawPayload | null | undefined,\n) => Promise<RawPayload | null>;\n\n/**\n * Build a raw (Payload-in, Payload-out) decrypter for the given encoding key.\n *\n * This is the fixture-capture counterpart of {@link createPayloadDecrypter}:\n * where that one renders a payload for human display (lossy \u2014 binary payloads\n * become placeholders), this one returns the exact decrypted inner Payload so\n * the bytes can be re-serialized into a replayable proto3-JSON history.\n */\nexport async function createRawPayloadDecrypter(\n encodingKey: string,\n): Promise<RawPayloadDecrypter> {\n const key = await deriveKey(encodingKey);\n\n return async (payload) => {\n if (!payload?.metadata) return null;\n\n const encodingBytes = payload.metadata[\"encoding\"];\n if (!encodingBytes) return null;\n const encoding = new TextDecoder().decode(encodingBytes);\n if (encoding !== ENCRYPTED_ENCODING) return null;\n\n if (!payload.data) {\n throw new Error(\"encrypted payload has no data to decrypt\");\n }\n\n const decrypted = await aesGcmDecrypt(payload.data, key);\n return decodePayloadProtobuf(decrypted);\n };\n}\n\n// \u2500\u2500 Hand-rolled Payload protobuf decoder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// temporal.api.common.v1.Payload has exactly two fields:\n// message Payload {\n// map<string, bytes> metadata = 1; // field 1, length-delimited\n// bytes data = 2; // field 2, length-delimited\n// }\n// A protobuf `map<K, V>` is syntactic sugar for:\n// repeated MapEntry { K key = 1; V value = 2; }\n// so each metadata entry is itself a length-delimited submessage with two\n// inner length-delimited fields.\n//\n// Decoding this by hand avoids pulling in `@temporalio/proto` as a peer dep.\n\nfunction readVarint(buf: Uint8Array, pos: number): { value: number; next: number } {\n let value = 0;\n let shift = 0;\n let next = pos;\n while (next < buf.length) {\n const byte = buf[next]!;\n next += 1;\n value |= (byte & 0x7f) << shift;\n if ((byte & 0x80) === 0) return { value, next };\n shift += 7;\n if (shift >= 32) throw new Error(\"varint too large\");\n }\n throw new Error(\"truncated varint\");\n}\n\nfunction readLengthDelimited(\n buf: Uint8Array,\n pos: number,\n): { bytes: Uint8Array; next: number } {\n const { value: length, next: afterLen } = readVarint(buf, pos);\n const end = afterLen + length;\n if (end > buf.length) throw new Error(\"truncated length-delimited field\");\n return { bytes: buf.slice(afterLen, end), next: end };\n}\n\n/**\n * Decode a serialized `temporal.api.common.v1.Payload`.\n *\n * Unknown fields and wire types are skipped rather than throwing; we only\n * need the two documented fields and Temporal's wire format is stable.\n */\nfunction decodePayloadProtobuf(buf: Uint8Array): RawPayload {\n const metadata: Record<string, Uint8Array> = {};\n let data: Uint8Array | undefined;\n let pos = 0;\n\n while (pos < buf.length) {\n const { value: tag, next: afterTag } = readVarint(buf, pos);\n const fieldNumber = tag >>> 3;\n const wireType = tag & 0x7;\n pos = afterTag;\n\n if (wireType === 2) {\n const { bytes, next } = readLengthDelimited(buf, pos);\n pos = next;\n if (fieldNumber === 1) {\n const entry = decodeMetadataEntry(bytes);\n if (entry) metadata[entry.key] = entry.value;\n } else if (fieldNumber === 2) {\n data = bytes;\n }\n // Other fields: ignore.\n } else if (wireType === 0) {\n // varint \u2014 skip\n pos = readVarint(buf, pos).next;\n } else if (wireType === 1) {\n pos += 8; // fixed64\n } else if (wireType === 5) {\n pos += 4; // fixed32\n } else {\n throw new Error(`unsupported wire type ${wireType} at pos ${pos}`);\n }\n }\n\n return { metadata, data: data ?? new Uint8Array(0) };\n}\n\nfunction decodeMetadataEntry(\n buf: Uint8Array,\n): { key: string; value: Uint8Array } | null {\n let key: string | undefined;\n let value: Uint8Array | undefined;\n let pos = 0;\n\n while (pos < buf.length) {\n const { value: tag, next: afterTag } = readVarint(buf, pos);\n const fieldNumber = tag >>> 3;\n const wireType = tag & 0x7;\n pos = afterTag;\n if (wireType !== 2) {\n // Skip unsupported fields defensively.\n if (wireType === 0) pos = readVarint(buf, pos).next;\n else if (wireType === 1) pos += 8;\n else if (wireType === 5) pos += 4;\n else throw new Error(`unsupported metadata wire type ${wireType}`);\n continue;\n }\n const { bytes, next } = readLengthDelimited(buf, pos);\n pos = next;\n if (fieldNumber === 1) key = new TextDecoder().decode(bytes);\n else if (fieldNumber === 2) value = bytes;\n }\n\n if (key === undefined || value === undefined) return null;\n return { key, value };\n}\n\n/**\n * Render a decrypted inner Payload as a human-readable string.\n *\n * Handles the common encodings Mesh workers emit:\n * - `json/plain` \u2192 pretty-printed JSON\n * - `binary/null` \u2192 literal `null`\n * - `binary/plain` \u2192 `[binary N bytes]`\n * - anything else \u2192 `[encoding=X, N bytes]`\n */\nfunction decodeInnerPayload(payload: RawPayload): string {\n const meta = payload.metadata ?? {};\n const encodingBytes = meta[\"encoding\"];\n const encoding = encodingBytes\n ? new TextDecoder().decode(encodingBytes)\n : \"unknown\";\n const data = payload.data ?? new Uint8Array(0);\n\n if (encoding === \"binary/null\") return \"null\";\n if (encoding === \"json/plain\") {\n const text = new TextDecoder().decode(data);\n try {\n return JSON.stringify(JSON.parse(text), null, 2);\n } catch {\n // Not valid JSON despite the encoding claim \u2014 surface the raw text so\n // the debugger sees whatever garbage the worker actually wrote.\n return text;\n }\n }\n if (encoding === \"binary/plain\") return `[binary, ${data.length} bytes]`;\n return `[encoding=${encoding}, ${data.length} bytes]`;\n}\n\n// \u2500\u2500 High-level helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Resolve the Temporal encoding key for a namespace, logging where it came\n * from (or why it couldn't be found). Prefer the K8s secret (authoritative for\n * the namespace); fall back to an explicit TEMPORAL_ENCODING_KEY env var. The\n * env fallback lets you decrypt a workflow's history OFFLINE \u2014 e.g. to\n * reconstruct a conversation, or capture a replay fixture, whose worker can no\n * longer replay it \u2014 using the key from a running `mesh dev` worker env when\n * kubectl/cluster access isn't set up.\n *\n * Returns `undefined` when neither source yields a key.\n */\nexport function resolveEncodingKey(namespace: string): string | undefined {\n const fromK8s = resolveTemporalEncodingKeyFromK8s(namespace);\n const key = fromK8s ?? process.env.TEMPORAL_ENCODING_KEY;\n if (!key) {\n logWarn(\n `Could not read TEMPORAL_ENCODING_KEY from secret ` +\n `${namespace}/${namespace}-temporal-encoding-key, and TEMPORAL_ENCODING_KEY ` +\n \"is not set. Configure kubectl (namespace read \" +\n \"access), or export TEMPORAL_ENCODING_KEY (e.g. from a `mesh dev` worker env).\",\n );\n return undefined;\n }\n logSuccess(\n fromK8s\n ? `Resolved encoding key from ${namespace}-temporal-encoding-key`\n : \"Resolved encoding key from TEMPORAL_ENCODING_KEY env\",\n );\n return key;\n}\n\n/**\n * Resolve the encoding key and build a decrypter for the given namespace.\n * Logs a warning and returns `undefined` when the key can't be read; callers\n * should fall back to printing events without payloads.\n */\nexport async function buildDecrypterForNamespace(\n namespace: string,\n): Promise<PayloadDecrypter | undefined> {\n const key = resolveEncodingKey(namespace);\n if (!key) return undefined;\n return createPayloadDecrypter(key);\n}\n\n/**\n * Resolve the encoding key and build a RAW (Payload-in/Payload-out) decrypter\n * for the given namespace \u2014 used by `capture-history` to decrypt payloads back\n * into replayable proto bytes. Returns `undefined` when the key can't be read;\n * callers decide whether that's fatal.\n */\nexport async function buildRawDecrypterForNamespace(\n namespace: string,\n): Promise<RawPayloadDecrypter | undefined> {\n const key = resolveEncodingKey(namespace);\n if (!key) return undefined;\n return createRawPayloadDecrypter(key);\n}\n", "/**\n * Logging utilities with colored output.\n *\n * Non-TTY streams (CI, agent runs, piped output) get an [HH:MM:SS] prefix on\n * every line so long quiet stretches are attributable after the fact\n * (MESH-2479); interactive terminals stay clean. Override with\n * MESH_LOG_TIMESTAMPS=1 (force on) / =0 (force off).\n */\n\nimport chalk from \"chalk\";\n\n/**\n * Pure prefix decision, exported for tests: timestamps when the env flag says\n * so, else whenever stderr is not a TTY.\n */\nexport function logPrefix(opts: {\n isTTY: boolean;\n envFlag: string | undefined;\n now: Date;\n}): string {\n const enabled = opts.envFlag === \"1\" || (opts.envFlag !== \"0\" && !opts.isTTY);\n return enabled ? `[${opts.now.toISOString().slice(11, 19)}] ` : \"\";\n}\n\nfunction prefix(): string {\n return chalk.dim(\n logPrefix({\n isTTY: !!process.stderr.isTTY,\n envFlag: process.env.MESH_LOG_TIMESTAMPS,\n now: new Date(),\n }),\n );\n}\n\nexport function logInfo(message: string): void {\n console.error(prefix() + chalk.blue(\"\u2139\"), message);\n}\n\nexport function logSuccess(message: string): void {\n console.error(prefix() + chalk.green(\"\u2713\"), message);\n}\n\nexport function logWarn(message: string): void {\n console.error(prefix() + chalk.yellow(\"\u26A0\"), message);\n}\n\nexport function logError(message: string): void {\n console.error(prefix() + chalk.red(\"\u2717\"), message);\n}\n\n/** Render elapsed milliseconds compactly: \"45s\", \"2m 30s\", \"1h 5m\". */\nexport function formatElapsed(ms: number): string {\n const totalSec = Math.max(0, Math.round(ms / 1000));\n const h = Math.floor(totalSec / 3600);\n const m = Math.floor((totalSec % 3600) / 60);\n const s = totalSec % 60;\n if (h > 0) return `${h}h ${m}m`;\n if (m > 0) return `${m}m ${s}s`;\n return `${s}s`;\n}\n\n/**\n * Periodic \"still working\" line during a long silent operation (registry\n * fetches, image builds) so a non-TTY first run never sits at 0 bytes of\n * output for minutes (MESH-2479). `touch()` marks recent real output, which\n * suppresses the next beat \u2014 the heartbeat only fills silence.\n */\nexport function startHeartbeat(\n label: string,\n intervalMs = 15_000,\n): { stop: () => void; touch: () => void } {\n const startedAt = Date.now();\n let lastOutputAt = startedAt;\n const timer = setInterval(() => {\n if (Date.now() - lastOutputAt < intervalMs) return;\n logInfo(`\u2026 still working: ${label} (${formatElapsed(Date.now() - startedAt)} elapsed)`);\n }, intervalMs);\n timer.unref?.();\n return {\n stop: () => clearInterval(timer),\n touch: () => {\n lastOutputAt = Date.now();\n },\n };\n}\n"],
5
4
  "mappings": "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",
6
5
  "names": []
7
6
  }
@@ -1,97 +1,39 @@
1
- /**
2
- * Ownership contract for the tunnel runner (MESH-2407).
3
- *
4
- * Three silent-dead-tunnel incidents in ten days (MESH-2169, MESH-2014, the
5
- * #2991 re-review) shared one enabler: readiness was inferred from "something
6
- * accepts TCP on the port". That conflates LIVENESS (a listener exists) with
7
- * OWNERSHIP (the listener is OUR runner, wired to OUR SOCKS upstream). This
8
- * module is the ownership half of the contract:
9
- *
10
- * - The runner that actually binds the forwarder ports writes a MANIFEST
11
- * (pid, process-group id, a per-run random token, a loopback control port)
12
- * and answers a one-shot control handshake with that token plus the ports
13
- * it is listening on — read from its in-process `net.Server`s, so the
14
- * answer can't be faked by a foreign listener and probing it opens no
15
- * SOCKS→VPC data connection.
16
- * - Callers verify ownership (manifest → live pid → control handshake →
17
- * token/socks-port/port-coverage match) instead of dialing ports. A port
18
- * that accepts TCP without passing the handshake is a SQUATTER and must be
19
- * a loud failure, never adopt-and-continue.
20
- * - Teardown signals process GROUPS recorded here (plus argv-discovered
21
- * runners), so no kill path can orphan a grandchild with ports still bound.
22
- */
23
1
  import * as net from 'node:net';
24
- /** Written by the runner (the process that binds the ports) — never by callers. */
25
2
  export interface RunnerManifest {
26
3
  tenant: string;
27
- /** Pid of the runner process itself (the port owner), NOT its launcher. */
28
4
  pid: number;
29
- /** Process-group id — all teardown paths signal `-pgid`, never a bare pid. */
30
5
  pgid: number;
31
- /** Per-run random token; the control handshake must echo it. */
32
6
  token: string;
33
- /** Loopback port answering the one-shot ownership handshake. */
34
7
  controlPort: number;
35
- /** SOCKS port the runner's forwarders dial (must match the live daemon's). */
36
8
  socksPort: number;
37
- /** Forwarder ports the runner is responsible for. */
38
9
  ports: number[];
39
10
  startedAt: string;
40
11
  }
41
- /** What the runner's control endpoint answers with. */
42
12
  export interface ControlResponse {
43
13
  token: string;
44
14
  tenant: string;
45
15
  pid: number;
46
16
  socksPort: number;
47
- /** Ports whose in-process `net.Server` is currently listening. */
48
17
  listening: number[];
49
- /** port → error code for forwarders that failed to bind (e.g. EADDRINUSE). */
50
18
  bindErrors: Record<string, string>;
51
19
  }
52
20
  export declare function mintRunnerToken(): string;
53
21
  export declare function readRunnerManifest(file: string): RunnerManifest | null;
54
22
  export declare function writeRunnerManifest(file: string, manifest: RunnerManifest): void;
55
- /**
56
- * Remove the manifest — but only if it is still OURS (`token` matches). A dying
57
- * runner must not clobber the manifest of a newer runner that already replaced it.
58
- * Omit `token` for teardown paths that own the whole tenant state.
59
- */
60
23
  export declare function clearRunnerManifest(file: string, token?: string): void;
61
- /** Process-group id of a pid via `ps` (macOS/BSD); null when undiscoverable. */
62
24
  export declare function getProcessGroupId(pid: number): number | null;
63
- /**
64
- * Pids of tunnel-runner processes for a tenant, parsed from `ps` output
65
- * (`pid command` lines). Matches both `__run` and the legacy `__supervise`
66
- * argv, and skips `exclude` (the calling process, when it IS the runner).
67
- * Pure for unit tests; `discoverRunnerPids` feeds it live `ps` output.
68
- */
69
25
  export declare function parseRunnerPidsFromPs(psOutput: string, tenant: string, exclude?: number): number[];
70
- /** Live argv discovery of runner pids for a tenant (empty when `ps` fails). */
71
26
  export declare function discoverRunnerPids(tenant: string, exclude?: number): number[];
72
- /**
73
- * Start the runner's one-shot control endpoint on a loopback ephemeral port.
74
- * Each connection gets one JSON line (the live payload) and is closed — no
75
- * protocol state, nothing routable, and probing it touches no data plane.
76
- */
77
27
  export declare function startControlServer(payload: () => ControlResponse): Promise<{
78
28
  server: net.Server;
79
29
  port: number;
80
30
  }>;
81
- /** Dial the control endpoint and parse its one-line JSON answer; null on any failure. */
82
31
  export declare function queryControl(port: number, timeoutMs?: number): Promise<ControlResponse | null>;
83
32
  export interface OwnershipCheck {
84
33
  ok: boolean;
85
- /** Machine-readable failure reason ("" when ok). */
86
34
  reason: string;
87
- /** The control answer, when the handshake got that far. */
88
35
  resp?: ControlResponse;
89
36
  }
90
- /**
91
- * The ownership handshake: manifest → live pid → control endpoint → token,
92
- * SOCKS port, and port coverage all match. Anything less is NOT ours — the
93
- * caller must treat an accepting-but-unowned port as a squatter, never reuse it.
94
- */
95
37
  export declare function verifyRunnerOwnership(args: {
96
38
  manifest: RunnerManifest | null;
97
39
  expectedSocksPort: number;
@@ -99,32 +41,11 @@ export declare function verifyRunnerOwnership(args: {
99
41
  isPidAlive?: (pid: number) => boolean;
100
42
  query?: (port: number) => Promise<ControlResponse | null>;
101
43
  }): Promise<OwnershipCheck>;
102
- /**
103
- * Poll an ownership check until it passes or `deadlineMs` of wall-clock elapses;
104
- * returns the last (failing) check otherwise. The deadline bounds TIME, not
105
- * rounds — each check can itself cost up to the control-query timeout, so a
106
- * round-counting loop would multiply the promised deadline several-fold.
107
- * Retrying also matters for correctness, not just latency: two failure reasons
108
- * are transient by design (`ports-not-listening:` while the runner's self-heal
109
- * loop rebinds a forwarder, `no-control-answer` under accept-backlog pressure),
110
- * and a single-shot sample of a healthy shared runner in one of those windows
111
- * would tear it down for every concurrent session on the tenant (MESH-2014).
112
- */
113
44
  export declare function pollOwnership(check: () => Promise<OwnershipCheck>, deadlineMs: number): Promise<OwnershipCheck>;
114
- /** Best-effort `lsof` description of what holds a port ("cmd (pid N)"); null if unknown. */
115
45
  export declare function describePortOwner(port: number): string | null;
116
46
  export interface SquattedPort {
117
47
  port: number;
118
48
  owner: string | null;
119
49
  }
120
- /**
121
- * Of `ports`, the ones something is accepting TCP on. Called AFTER ownership
122
- * failed / teardown ran, so every hit is a foreign or stale listener.
123
- */
124
50
  export declare function findSquattedPorts(ports: number[], accepts: (port: number) => Promise<boolean>): Promise<SquattedPort[]>;
125
- /**
126
- * The loud-failure text for a squatted tunnel port (`mesh dev doctor` style:
127
- * what is wrong, why we refuse, exactly what to run). Never adopt-and-continue.
128
- */
129
51
  export declare function buildSquatterError(tenant: string, squatted: SquattedPort[], detail?: string): string;
130
- //# sourceMappingURL=tunnel-ownership.d.ts.map
@@ -1,25 +1,3 @@
1
- /**
2
- * Ownership contract for the tunnel runner (MESH-2407).
3
- *
4
- * Three silent-dead-tunnel incidents in ten days (MESH-2169, MESH-2014, the
5
- * #2991 re-review) shared one enabler: readiness was inferred from "something
6
- * accepts TCP on the port". That conflates LIVENESS (a listener exists) with
7
- * OWNERSHIP (the listener is OUR runner, wired to OUR SOCKS upstream). This
8
- * module is the ownership half of the contract:
9
- *
10
- * - The runner that actually binds the forwarder ports writes a MANIFEST
11
- * (pid, process-group id, a per-run random token, a loopback control port)
12
- * and answers a one-shot control handshake with that token plus the ports
13
- * it is listening on — read from its in-process `net.Server`s, so the
14
- * answer can't be faked by a foreign listener and probing it opens no
15
- * SOCKS→VPC data connection.
16
- * - Callers verify ownership (manifest → live pid → control handshake →
17
- * token/socks-port/port-coverage match) instead of dialing ports. A port
18
- * that accepts TCP without passing the handshake is a SQUATTER and must be
19
- * a loud failure, never adopt-and-continue.
20
- * - Teardown signals process GROUPS recorded here (plus argv-discovered
21
- * runners), so no kill path can orphan a grandchild with ports still bound.
22
- */
23
1
  import * as crypto from 'node:crypto';
24
2
  import * as fs from 'node:fs';
25
3
  import * as net from 'node:net';
@@ -42,11 +20,6 @@ export function writeRunnerManifest(file, manifest) {
42
20
  fs.mkdirSync(path.dirname(file), { recursive: true });
43
21
  fs.writeFileSync(file, JSON.stringify(manifest, null, 2), { mode: 0o600 });
44
22
  }
45
- /**
46
- * Remove the manifest — but only if it is still OURS (`token` matches). A dying
47
- * runner must not clobber the manifest of a newer runner that already replaced it.
48
- * Omit `token` for teardown paths that own the whole tenant state.
49
- */
50
23
  export function clearRunnerManifest(file, token) {
51
24
  if (token !== undefined && readRunnerManifest(file)?.token !== token)
52
25
  return;
@@ -54,10 +27,8 @@ export function clearRunnerManifest(file, token) {
54
27
  fs.unlinkSync(file);
55
28
  }
56
29
  catch {
57
- /* already gone */
58
30
  }
59
31
  }
60
- /** Process-group id of a pid via `ps` (macOS/BSD); null when undiscoverable. */
61
32
  export function getProcessGroupId(pid) {
62
33
  try {
63
34
  const out = execFileSync('ps', ['-o', 'pgid=', '-p', String(pid)], {
@@ -71,12 +42,6 @@ export function getProcessGroupId(pid) {
71
42
  return null;
72
43
  }
73
44
  }
74
- /**
75
- * Pids of tunnel-runner processes for a tenant, parsed from `ps` output
76
- * (`pid command` lines). Matches both `__run` and the legacy `__supervise`
77
- * argv, and skips `exclude` (the calling process, when it IS the runner).
78
- * Pure for unit tests; `discoverRunnerPids` feeds it live `ps` output.
79
- */
80
45
  export function parseRunnerPidsFromPs(psOutput, tenant, exclude) {
81
46
  const pids = [];
82
47
  for (const line of psOutput.split('\n')) {
@@ -86,8 +51,6 @@ export function parseRunnerPidsFromPs(psOutput, tenant, exclude) {
86
51
  if (!m)
87
52
  continue;
88
53
  const argv = m[2].split(/\s+/);
89
- // The tenant is the argument right after __run/__supervise — an exact
90
- // match, so tenant "enc" never matches a runner for tenant "encore".
91
54
  const i = argv.findIndex((a) => a === '__run' || a === '__supervise');
92
55
  if (i === -1 || argv[i + 1] !== tenant)
93
56
  continue;
@@ -97,7 +60,6 @@ export function parseRunnerPidsFromPs(psOutput, tenant, exclude) {
97
60
  }
98
61
  return pids;
99
62
  }
100
- /** Live argv discovery of runner pids for a tenant (empty when `ps` fails). */
101
63
  export function discoverRunnerPids(tenant, exclude) {
102
64
  try {
103
65
  const out = execFileSync('ps', ['ax', '-o', 'pid=,command='], {
@@ -110,11 +72,6 @@ export function discoverRunnerPids(tenant, exclude) {
110
72
  return [];
111
73
  }
112
74
  }
113
- /**
114
- * Start the runner's one-shot control endpoint on a loopback ephemeral port.
115
- * Each connection gets one JSON line (the live payload) and is closed — no
116
- * protocol state, nothing routable, and probing it touches no data plane.
117
- */
118
75
  export function startControlServer(payload) {
119
76
  return new Promise((resolve, reject) => {
120
77
  const server = net.createServer((socket) => {
@@ -132,7 +89,6 @@ export function startControlServer(payload) {
132
89
  });
133
90
  });
134
91
  }
135
- /** Dial the control endpoint and parse its one-line JSON answer; null on any failure. */
136
92
  export function queryControl(port, timeoutMs = 700) {
137
93
  return new Promise((resolve) => {
138
94
  const s = new net.Socket();
@@ -171,11 +127,6 @@ function defaultPidAlive(pid) {
171
127
  return false;
172
128
  }
173
129
  }
174
- /**
175
- * The ownership handshake: manifest → live pid → control endpoint → token,
176
- * SOCKS port, and port coverage all match. Anything less is NOT ours — the
177
- * caller must treat an accepting-but-unowned port as a squatter, never reuse it.
178
- */
179
130
  export async function verifyRunnerOwnership(args) {
180
131
  const { manifest } = args;
181
132
  if (!manifest)
@@ -198,17 +149,6 @@ export async function verifyRunnerOwnership(args) {
198
149
  }
199
150
  return { ok: true, reason: '', resp };
200
151
  }
201
- /**
202
- * Poll an ownership check until it passes or `deadlineMs` of wall-clock elapses;
203
- * returns the last (failing) check otherwise. The deadline bounds TIME, not
204
- * rounds — each check can itself cost up to the control-query timeout, so a
205
- * round-counting loop would multiply the promised deadline several-fold.
206
- * Retrying also matters for correctness, not just latency: two failure reasons
207
- * are transient by design (`ports-not-listening:` while the runner's self-heal
208
- * loop rebinds a forwarder, `no-control-answer` under accept-backlog pressure),
209
- * and a single-shot sample of a healthy shared runner in one of those windows
210
- * would tear it down for every concurrent session on the tenant (MESH-2014).
211
- */
212
152
  export async function pollOwnership(check, deadlineMs) {
213
153
  let last = { ok: false, reason: 'not-checked' };
214
154
  const end = Date.now() + deadlineMs;
@@ -220,14 +160,12 @@ export async function pollOwnership(check, deadlineMs) {
220
160
  } while (Date.now() < end);
221
161
  return last;
222
162
  }
223
- /** Best-effort `lsof` description of what holds a port ("cmd (pid N)"); null if unknown. */
224
163
  export function describePortOwner(port) {
225
164
  try {
226
165
  const out = execFileSync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fcp'], {
227
166
  encoding: 'utf8',
228
167
  stdio: ['ignore', 'pipe', 'ignore'],
229
168
  });
230
- // -F output: "p<pid>\nc<command>\n…" per process.
231
169
  const pid = out.match(/^p(\d+)$/m)?.[1];
232
170
  const cmd = out.match(/^c(.+)$/m)?.[1];
233
171
  if (!pid && !cmd)
@@ -238,10 +176,6 @@ export function describePortOwner(port) {
238
176
  return null;
239
177
  }
240
178
  }
241
- /**
242
- * Of `ports`, the ones something is accepting TCP on. Called AFTER ownership
243
- * failed / teardown ran, so every hit is a foreign or stale listener.
244
- */
245
179
  export async function findSquattedPorts(ports, accepts) {
246
180
  const squatted = [];
247
181
  for (const port of ports) {
@@ -250,10 +184,6 @@ export async function findSquattedPorts(ports, accepts) {
250
184
  }
251
185
  return squatted;
252
186
  }
253
- /**
254
- * The loud-failure text for a squatted tunnel port (`mesh dev doctor` style:
255
- * what is wrong, why we refuse, exactly what to run). Never adopt-and-continue.
256
- */
257
187
  export function buildSquatterError(tenant, squatted, detail) {
258
188
  const lines = squatted.map((s) => ` 127.0.0.1:${s.port} held by ${s.owner ?? 'an unidentified process'}`);
259
189
  const first = squatted[0]?.port ?? '<port>';
@@ -265,10 +195,6 @@ export function buildSquatterError(tenant, squatted, detail) {
265
195
  ` mesh vpn -t ${tenant} tunnel down --stop # tear down mesh-owned runners + daemon`,
266
196
  ` lsof -nP -iTCP:${first} -sTCP:LISTEN # identify what still holds the port`,
267
197
  ` then stop that process and re-run.`,
268
- // Port blocks are a 63-bucket hash (MESH-2375), so a DIFFERENT tenant's
269
- // runner can collide onto this block — in which case the `down` above is a
270
- // no-op and only lsof identifies the real owner.
271
198
  ` (If lsof names another mesh runner, it belongs to a different tenant — tear that one down instead.)`,
272
199
  ].join('\n');
273
200
  }
274
- //# sourceMappingURL=tunnel-ownership.js.map
@@ -2,31 +2,15 @@ type CtxConfig = {
2
2
  issuer?: string;
3
3
  vpnJoinBroker?: string;
4
4
  } | null;
5
- /**
6
- * Resolve the broker URL, preferring the platform-published value from
7
- * discovery (ContextConfig.vpnJoinBroker) and falling back to DNS-convention
8
- * derivation for platforms not yet redeployed with the payload field.
9
- */
10
5
  export declare function resolveVpnJoinBroker(context: string, getCfg?: (c: string) => CtxConfig): string | null;
11
- /**
12
- * FALLBACK ONLY. Derive by convention — issuer host `identity.<env>.<domain>`
13
- * → `vpn-join.<env>.<domain>` — mirroring deriveLoginServer (dev.ts:1479).
14
- * Prefer resolveVpnJoinBroker, which reads the platform-published URL first.
15
- */
16
6
  export declare function deriveVpnJoinBroker(context: string, getCfg?: (c: string) => CtxConfig): string | null;
17
7
  export interface MintDeps {
18
8
  getValidToken: (context: string) => Promise<string | null>;
19
9
  fetchFn?: typeof fetch;
20
10
  }
21
- /**
22
- * Fetch a single-use pre-auth key from the broker. Returns null on ANY failure
23
- * (no token, non-2xx, network error) so the caller falls back to the browser
24
- * relay join — the broker path is strictly additive.
25
- */
26
11
  export declare function mintPreAuthKey(context: string, brokerUrl: string, deps: MintDeps): Promise<{
27
12
  authKey: string;
28
13
  loginServer: string;
29
14
  } | null>;
30
15
  export declare function realMintDeps(): MintDeps;
31
16
  export {};
32
- //# sourceMappingURL=vpn-join.d.ts.map