@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.
- package/assets/intent/agents-fence.md +10 -0
- package/assets/intent/intent-claude-gate.mjs +255 -0
- package/assets/log-shipper.mjs +94 -0
- package/bin/mesh.mjs +80 -0
- package/dist/bin/mesh.d.ts +7 -9
- package/dist/bin/mesh.d.ts.map +1 -1
- package/dist/bin/mesh.js +20826 -37
- package/dist/bin/mesh.js.map +7 -1
- package/dist/build-info.json +4 -0
- package/dist/src/commands/agent-api-client.d.ts +79 -0
- package/dist/src/commands/agent-api-client.d.ts.map +1 -0
- package/dist/src/commands/agent-api-client.js +170 -0
- package/dist/src/commands/agent-api-client.js.map +1 -0
- package/dist/src/commands/artifacts.d.ts +13 -0
- package/dist/src/commands/artifacts.d.ts.map +1 -0
- package/dist/src/commands/artifacts.js +140 -0
- package/dist/src/commands/artifacts.js.map +1 -0
- package/dist/src/commands/cluster.d.ts +45 -0
- package/dist/src/commands/cluster.d.ts.map +1 -0
- package/dist/src/commands/cluster.js +259 -0
- package/dist/src/commands/cluster.js.map +1 -0
- package/dist/src/commands/conversations.d.ts +61 -0
- package/dist/src/commands/conversations.d.ts.map +1 -0
- package/dist/src/commands/conversations.js +239 -0
- package/dist/src/commands/conversations.js.map +1 -0
- package/dist/src/commands/create-app.d.ts +26 -3
- package/dist/src/commands/create-app.d.ts.map +1 -1
- package/dist/src/commands/create-app.js +465 -107
- package/dist/src/commands/create-app.js.map +1 -1
- package/dist/src/commands/deploy.d.ts +19 -0
- package/dist/src/commands/deploy.d.ts.map +1 -1
- package/dist/src/commands/deploy.js +83 -142
- package/dist/src/commands/deploy.js.map +1 -1
- package/dist/src/commands/dev-doctor.d.ts +137 -0
- package/dist/src/commands/dev-doctor.d.ts.map +1 -0
- package/dist/src/commands/dev-doctor.js +671 -0
- package/dist/src/commands/dev-doctor.js.map +1 -0
- package/dist/src/commands/dev-launch.d.ts +59 -0
- package/dist/src/commands/dev-launch.d.ts.map +1 -0
- package/dist/src/commands/dev-launch.js +118 -0
- package/dist/src/commands/dev-launch.js.map +1 -0
- package/dist/src/commands/dev-token-server.d.ts +32 -0
- package/dist/src/commands/dev-token-server.d.ts.map +1 -0
- package/dist/src/commands/dev-token-server.js +68 -0
- package/dist/src/commands/dev-token-server.js.map +1 -0
- package/dist/src/commands/dev.d.ts +289 -2
- package/dist/src/commands/dev.d.ts.map +1 -1
- package/dist/src/commands/dev.js +2501 -574
- package/dist/src/commands/dev.js.map +1 -1
- package/dist/src/commands/docs.d.ts +3 -0
- package/dist/src/commands/docs.d.ts.map +1 -0
- package/dist/src/commands/docs.js +262 -0
- package/dist/src/commands/docs.js.map +1 -0
- package/dist/src/commands/hub/index.d.ts +99 -0
- package/dist/src/commands/hub/index.d.ts.map +1 -0
- package/dist/src/commands/hub/index.js +452 -0
- package/dist/src/commands/hub/index.js.map +1 -0
- package/dist/src/commands/init.d.ts +65 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +370 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/install-shim.d.ts +21 -0
- package/dist/src/commands/install-shim.d.ts.map +1 -0
- package/dist/src/commands/install-shim.js +132 -0
- package/dist/src/commands/install-shim.js.map +1 -0
- package/dist/src/commands/local/auth-provision.d.ts +71 -0
- package/dist/src/commands/local/auth-provision.d.ts.map +1 -0
- package/dist/src/commands/local/auth-provision.js +286 -0
- package/dist/src/commands/local/auth-provision.js.map +1 -0
- package/dist/src/commands/local/dev-local.d.ts +97 -0
- package/dist/src/commands/local/dev-local.d.ts.map +1 -0
- package/dist/src/commands/local/dev-local.js +306 -0
- package/dist/src/commands/local/dev-local.js.map +1 -0
- package/dist/src/commands/local/docker-runner.d.ts +37 -0
- package/dist/src/commands/local/docker-runner.d.ts.map +1 -0
- package/dist/src/commands/local/docker-runner.js +104 -0
- package/dist/src/commands/local/docker-runner.js.map +1 -0
- package/dist/src/commands/local/helpers.d.ts +22 -0
- package/dist/src/commands/local/helpers.d.ts.map +1 -0
- package/dist/src/commands/local/helpers.js +46 -0
- package/dist/src/commands/local/helpers.js.map +1 -0
- package/dist/src/commands/local/hub-local.d.ts +51 -0
- package/dist/src/commands/local/hub-local.d.ts.map +1 -0
- package/dist/src/commands/local/hub-local.js +197 -0
- package/dist/src/commands/local/hub-local.js.map +1 -0
- package/dist/src/commands/local/index.d.ts +23 -0
- package/dist/src/commands/local/index.d.ts.map +1 -0
- package/dist/src/commands/local/index.js +386 -0
- package/dist/src/commands/local/index.js.map +1 -0
- package/dist/src/commands/local/mocks.d.ts +361 -0
- package/dist/src/commands/local/mocks.d.ts.map +1 -0
- package/dist/src/commands/local/mocks.js +756 -0
- package/dist/src/commands/local/mocks.js.map +1 -0
- package/dist/src/commands/local/seed-zitadel.d.ts +151 -0
- package/dist/src/commands/local/seed-zitadel.d.ts.map +1 -0
- package/dist/src/commands/local/seed-zitadel.js +408 -0
- package/dist/src/commands/local/seed-zitadel.js.map +1 -0
- package/dist/src/commands/local/seed.d.ts +106 -0
- package/dist/src/commands/local/seed.d.ts.map +1 -0
- package/dist/src/commands/local/seed.js +252 -0
- package/dist/src/commands/local/seed.js.map +1 -0
- package/dist/src/commands/local/stack.d.ts +173 -0
- package/dist/src/commands/local/stack.d.ts.map +1 -0
- package/dist/src/commands/local/stack.js +499 -0
- package/dist/src/commands/local/stack.js.map +1 -0
- package/dist/src/commands/login.d.ts +256 -12
- package/dist/src/commands/login.d.ts.map +1 -1
- package/dist/src/commands/login.js +978 -50
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/peer-addressing.d.ts +51 -0
- package/dist/src/commands/peer-addressing.d.ts.map +1 -0
- package/dist/src/commands/peer-addressing.js +64 -0
- package/dist/src/commands/peer-addressing.js.map +1 -0
- package/dist/src/commands/port-ownership.d.ts +69 -0
- package/dist/src/commands/port-ownership.d.ts.map +1 -0
- package/dist/src/commands/port-ownership.js +161 -0
- package/dist/src/commands/port-ownership.js.map +1 -0
- package/dist/src/commands/registry-publish.d.ts +3 -0
- package/dist/src/commands/registry-publish.d.ts.map +1 -0
- package/dist/src/commands/registry-publish.js +161 -0
- package/dist/src/commands/registry-publish.js.map +1 -0
- package/dist/src/commands/registry.d.ts +146 -2
- package/dist/src/commands/registry.d.ts.map +1 -1
- package/dist/src/commands/registry.js +541 -85
- package/dist/src/commands/registry.js.map +1 -1
- package/dist/src/commands/secrets/index.d.ts.map +1 -1
- package/dist/src/commands/secrets/index.js +15 -1
- package/dist/src/commands/secrets/index.js.map +1 -1
- package/dist/src/commands/secrets/migrate-config.d.ts +24 -0
- package/dist/src/commands/secrets/migrate-config.d.ts.map +1 -0
- package/dist/src/commands/secrets/migrate-config.js +277 -0
- package/dist/src/commands/secrets/migrate-config.js.map +1 -0
- package/dist/src/commands/secrets/set.d.ts +1 -0
- package/dist/src/commands/secrets/set.d.ts.map +1 -1
- package/dist/src/commands/secrets/set.js +96 -2
- package/dist/src/commands/secrets/set.js.map +1 -1
- package/dist/src/commands/skills.d.ts +34 -0
- package/dist/src/commands/skills.d.ts.map +1 -0
- package/dist/src/commands/skills.js +207 -0
- package/dist/src/commands/skills.js.map +1 -0
- package/dist/src/commands/stack.d.ts.map +1 -1
- package/dist/src/commands/stack.js +361 -23
- package/dist/src/commands/stack.js.map +1 -1
- package/dist/src/commands/temporal.d.ts +15 -0
- package/dist/src/commands/temporal.d.ts.map +1 -0
- package/dist/src/commands/temporal.js +781 -0
- package/dist/src/commands/temporal.js.map +1 -0
- package/dist/src/commands/tenant.d.ts +56 -0
- package/dist/src/commands/tenant.d.ts.map +1 -0
- package/dist/src/commands/tenant.js +233 -0
- package/dist/src/commands/tenant.js.map +1 -0
- package/dist/src/commands/tunnel/index.d.ts +49 -3
- package/dist/src/commands/tunnel/index.d.ts.map +1 -1
- package/dist/src/commands/tunnel/index.js +331 -8
- package/dist/src/commands/tunnel/index.js.map +1 -1
- package/dist/src/commands/vcs/clone.d.ts +3 -0
- package/dist/src/commands/vcs/clone.d.ts.map +1 -0
- package/dist/src/commands/vcs/clone.js +20 -0
- package/dist/src/commands/vcs/clone.js.map +1 -0
- package/dist/src/commands/vcs/common.d.ts +21 -0
- package/dist/src/commands/vcs/common.d.ts.map +1 -0
- package/dist/src/commands/vcs/common.js +62 -0
- package/dist/src/commands/vcs/common.js.map +1 -0
- package/dist/src/commands/vcs/drafts.d.ts +13 -0
- package/dist/src/commands/vcs/drafts.d.ts.map +1 -0
- package/dist/src/commands/vcs/drafts.js +45 -0
- package/dist/src/commands/vcs/drafts.js.map +1 -0
- package/dist/src/commands/vcs/get.d.ts +8 -0
- package/dist/src/commands/vcs/get.d.ts.map +1 -0
- package/dist/src/commands/vcs/get.js +61 -0
- package/dist/src/commands/vcs/get.js.map +1 -0
- package/dist/src/commands/vcs/index.d.ts +3 -0
- package/dist/src/commands/vcs/index.d.ts.map +1 -0
- package/dist/src/commands/vcs/index.js +58 -0
- package/dist/src/commands/vcs/index.js.map +1 -0
- package/dist/src/commands/vcs/propose.d.ts +23 -0
- package/dist/src/commands/vcs/propose.d.ts.map +1 -0
- package/dist/src/commands/vcs/propose.js +94 -0
- package/dist/src/commands/vcs/propose.js.map +1 -0
- package/dist/src/commands/vcs/review.d.ts +15 -0
- package/dist/src/commands/vcs/review.d.ts.map +1 -0
- package/dist/src/commands/vcs/review.js +35 -0
- package/dist/src/commands/vcs/review.js.map +1 -0
- package/dist/src/commands/vcs-enrich.d.ts +15 -0
- package/dist/src/commands/vcs-enrich.d.ts.map +1 -0
- package/dist/src/commands/vcs-enrich.js +28 -0
- package/dist/src/commands/vcs-enrich.js.map +1 -0
- package/dist/src/commands/vpn/index.d.ts +24 -0
- package/dist/src/commands/vpn/index.d.ts.map +1 -0
- package/dist/src/commands/vpn/index.js +543 -0
- package/dist/src/commands/vpn/index.js.map +1 -0
- package/dist/src/commands/vpn/tunnel.d.ts +11 -0
- package/dist/src/commands/vpn/tunnel.d.ts.map +1 -0
- package/dist/src/commands/vpn/tunnel.js +188 -0
- package/dist/src/commands/vpn/tunnel.js.map +1 -0
- package/dist/src/commands/workflow.d.ts +24 -0
- package/dist/src/commands/workflow.d.ts.map +1 -0
- package/dist/src/commands/workflow.js +577 -0
- package/dist/src/commands/workflow.js.map +1 -0
- package/dist/src/docs/assemble.d.ts +217 -0
- package/dist/src/docs/assemble.d.ts.map +1 -0
- package/dist/src/docs/assemble.js +739 -0
- package/dist/src/docs/assemble.js.map +1 -0
- package/dist/src/docs/cli-reference.d.ts +93 -0
- package/dist/src/docs/cli-reference.d.ts.map +1 -0
- package/dist/src/docs/cli-reference.js +256 -0
- package/dist/src/docs/cli-reference.js.map +1 -0
- package/dist/src/docs/discover.d.ts +60 -0
- package/dist/src/docs/discover.d.ts.map +1 -0
- package/dist/src/docs/discover.js +233 -0
- package/dist/src/docs/discover.js.map +1 -0
- package/dist/src/docs/portal.d.ts +79 -0
- package/dist/src/docs/portal.d.ts.map +1 -0
- package/dist/src/docs/portal.js +242 -0
- package/dist/src/docs/portal.js.map +1 -0
- package/dist/src/docs/registry-docs.d.ts +43 -0
- package/dist/src/docs/registry-docs.d.ts.map +1 -0
- package/dist/src/docs/registry-docs.js +138 -0
- package/dist/src/docs/registry-docs.js.map +1 -0
- package/dist/src/docs/schema.d.ts +48 -0
- package/dist/src/docs/schema.d.ts.map +1 -0
- package/dist/src/docs/schema.js +96 -0
- package/dist/src/docs/schema.js.map +1 -0
- package/dist/src/docs/serve.d.ts +27 -0
- package/dist/src/docs/serve.d.ts.map +1 -0
- package/dist/src/docs/serve.js +102 -0
- package/dist/src/docs/serve.js.map +1 -0
- package/dist/src/docs/start.d.ts +80 -0
- package/dist/src/docs/start.d.ts.map +1 -0
- package/dist/src/docs/start.js +313 -0
- package/dist/src/docs/start.js.map +1 -0
- package/dist/src/eval/agent-eval.d.mts +14 -0
- package/dist/src/eval/agent-eval.d.mts.map +1 -0
- package/dist/src/eval/agent-eval.mjs +273 -0
- package/dist/src/eval/agent-eval.mjs.map +1 -0
- package/dist/src/index.js +624 -7
- package/dist/src/index.js.map +7 -1
- package/dist/src/program.d.ts +26 -0
- package/dist/src/program.d.ts.map +1 -0
- package/dist/src/program.js +76 -0
- package/dist/src/program.js.map +1 -0
- package/dist/src/utils/auth-preflight.d.ts +159 -0
- package/dist/src/utils/auth-preflight.d.ts.map +1 -0
- package/dist/src/utils/auth-preflight.js +298 -0
- package/dist/src/utils/auth-preflight.js.map +1 -0
- package/dist/src/utils/aws-auth.d.ts +181 -0
- package/dist/src/utils/aws-auth.d.ts.map +1 -0
- package/dist/src/utils/aws-auth.js +527 -0
- package/dist/src/utils/aws-auth.js.map +1 -0
- package/dist/src/utils/bastion.d.ts +1 -1
- package/dist/src/utils/bastion.d.ts.map +1 -1
- package/dist/src/utils/bastion.js +29 -8
- package/dist/src/utils/bastion.js.map +1 -1
- package/dist/src/utils/build-info.d.ts +33 -0
- package/dist/src/utils/build-info.d.ts.map +1 -0
- package/dist/src/utils/build-info.js +102 -0
- package/dist/src/utils/build-info.js.map +1 -0
- package/dist/src/utils/capture-history.d.ts +62 -0
- package/dist/src/utils/capture-history.d.ts.map +1 -0
- package/dist/src/utils/capture-history.js +94 -0
- package/dist/src/utils/capture-history.js.map +1 -0
- package/dist/src/utils/deploy-preflight.d.ts +52 -0
- package/dist/src/utils/deploy-preflight.d.ts.map +1 -0
- package/dist/src/utils/deploy-preflight.js +183 -0
- package/dist/src/utils/deploy-preflight.js.map +1 -0
- package/dist/src/utils/errors.d.ts +75 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +106 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/first-party-contexts.d.ts +40 -0
- package/dist/src/utils/first-party-contexts.d.ts.map +1 -0
- package/dist/src/utils/first-party-contexts.js +53 -0
- package/dist/src/utils/first-party-contexts.js.map +1 -0
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +2 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/kubeconfig.d.ts +62 -0
- package/dist/src/utils/kubeconfig.d.ts.map +1 -0
- package/dist/src/utils/kubeconfig.js +118 -0
- package/dist/src/utils/kubeconfig.js.map +1 -0
- package/dist/src/utils/log.d.ts +27 -1
- package/dist/src/utils/log.d.ts.map +1 -1
- package/dist/src/utils/log.js +59 -5
- package/dist/src/utils/log.js.map +1 -1
- package/dist/src/utils/pid.d.ts +47 -0
- package/dist/src/utils/pid.d.ts.map +1 -0
- package/dist/src/utils/pid.js +83 -0
- package/dist/src/utils/pid.js.map +1 -0
- package/dist/src/utils/pulumi-run.d.ts +23 -0
- package/dist/src/utils/pulumi-run.d.ts.map +1 -0
- package/dist/src/utils/pulumi-run.js +112 -0
- package/dist/src/utils/pulumi-run.js.map +1 -0
- package/dist/src/utils/pulumi.d.ts +15 -0
- package/dist/src/utils/pulumi.d.ts.map +1 -1
- package/dist/src/utils/pulumi.js +35 -0
- package/dist/src/utils/pulumi.js.map +1 -1
- package/dist/src/utils/reachability.d.ts +29 -0
- package/dist/src/utils/reachability.d.ts.map +1 -0
- package/dist/src/utils/reachability.js +81 -0
- package/dist/src/utils/reachability.js.map +1 -0
- package/dist/src/utils/recover-conversation.d.ts +154 -0
- package/dist/src/utils/recover-conversation.d.ts.map +1 -0
- package/dist/src/utils/recover-conversation.js +314 -0
- package/dist/src/utils/recover-conversation.js.map +1 -0
- package/dist/src/utils/registry-broker.d.ts +148 -0
- package/dist/src/utils/registry-broker.d.ts.map +1 -0
- package/dist/src/utils/registry-broker.js +180 -0
- package/dist/src/utils/registry-broker.js.map +1 -0
- package/dist/src/utils/socks-forward.d.ts +40 -0
- package/dist/src/utils/socks-forward.d.ts.map +1 -0
- package/dist/src/utils/socks-forward.js +97 -0
- package/dist/src/utils/socks-forward.js.map +1 -0
- package/dist/src/utils/stack-flag.d.ts +23 -0
- package/dist/src/utils/stack-flag.d.ts.map +1 -0
- package/dist/src/utils/stack-flag.js +41 -0
- package/dist/src/utils/stack-flag.js.map +1 -0
- package/dist/src/utils/tailscale-targets.d.ts +52 -0
- package/dist/src/utils/tailscale-targets.d.ts.map +1 -0
- package/dist/src/utils/tailscale-targets.js +93 -0
- package/dist/src/utils/tailscale-targets.js.map +1 -0
- package/dist/src/utils/tailscale.d.ts +277 -0
- package/dist/src/utils/tailscale.d.ts.map +1 -0
- package/dist/src/utils/tailscale.js +1007 -0
- package/dist/src/utils/tailscale.js.map +1 -0
- package/dist/src/utils/temporal-auth.d.ts +43 -0
- package/dist/src/utils/temporal-auth.d.ts.map +1 -0
- package/dist/src/utils/temporal-auth.js +176 -0
- package/dist/src/utils/temporal-auth.js.map +1 -0
- package/dist/src/utils/temporal-codec.d.ts +101 -0
- package/dist/src/utils/temporal-codec.d.ts.map +1 -0
- package/dist/src/utils/temporal-codec.js +319 -0
- package/dist/src/utils/temporal-codec.js.map +1 -0
- package/dist/src/utils/tunnel-ownership.d.ts +130 -0
- package/dist/src/utils/tunnel-ownership.d.ts.map +1 -0
- package/dist/src/utils/tunnel-ownership.js +274 -0
- package/dist/src/utils/tunnel-ownership.js.map +1 -0
- package/dist/src/utils/vpn-join.d.ts +32 -0
- package/dist/src/utils/vpn-join.d.ts.map +1 -0
- package/dist/src/utils/vpn-join.js +62 -0
- package/dist/src/utils/vpn-join.js.map +1 -0
- package/dist/src/utils/vpn.d.ts +62 -0
- package/dist/src/utils/vpn.d.ts.map +1 -0
- package/dist/src/utils/vpn.js +183 -0
- package/dist/src/utils/vpn.js.map +1 -0
- package/dist/src/utils/workflow-fingerprint.d.ts +49 -0
- package/dist/src/utils/workflow-fingerprint.d.ts.map +1 -0
- package/dist/src/utils/workflow-fingerprint.js +135 -0
- package/dist/src/utils/workflow-fingerprint.js.map +1 -0
- package/dist/src/utils/worktree-identity.d.ts +86 -0
- package/dist/src/utils/worktree-identity.d.ts.map +1 -0
- package/dist/src/utils/worktree-identity.js +164 -0
- package/dist/src/utils/worktree-identity.js.map +1 -0
- package/fragments/agents/AGENTS.md.hbs +92 -0
- package/fragments/agents/CLAUDE.md.hbs +8 -0
- package/fragments/base/Pulumi.dev.yaml.hbs +10 -0
- package/fragments/base/Pulumi.yaml.hbs +9 -0
- package/fragments/base/index.ts.hbs +107 -0
- package/fragments/base/package.json.hbs +22 -0
- package/{templates/api-web-db/api → fragments/base}/tsconfig.json +3 -4
- package/fragments/bucket/api/src/storage.ts.hbs +81 -0
- package/fragments/database/api/src/db.ts.hbs +23 -0
- package/fragments/database/prisma/schema.prisma.hbs +18 -0
- package/{templates/api-web-db → fragments/service}/api/.dockerignore +2 -0
- package/fragments/service/api/package.json.hbs +40 -0
- package/fragments/service/api/src/index.ts.hbs +58 -0
- package/{templates/api-web-db → fragments/service/api}/tsconfig.json +5 -3
- package/fragments/temporal/worker/.dockerignore +4 -0
- package/fragments/temporal/worker/Dockerfile +15 -0
- package/{templates/temporal-api-worker → fragments/temporal}/worker/package.json.hbs +3 -2
- package/fragments/temporal/worker/src/activities.ts.hbs +14 -0
- package/fragments/temporal/worker/src/worker.ts.hbs +27 -0
- package/fragments/temporal/worker/src/workflows.ts.hbs +24 -0
- package/fragments/temporal/worker/tsconfig.json +13 -0
- package/package.json +36 -22
- package/skills/core/SKILL.md +365 -0
- package/skills/pull-remote-agent-context/SKILL.md +194 -0
- package/stack/docker-compose.hub.yml +134 -0
- package/stack/docker-compose.yml +447 -0
- package/stack/hub/Dockerfile.api +18 -0
- package/stack/hub/Dockerfile.auth +10 -0
- package/stack/hub/Dockerfile.ui +10 -0
- package/stack/init/01-databases.sql +12 -0
- package/stack/observability/blackbox.yml +20 -0
- package/stack/observability/otel-collector.yaml +73 -0
- package/stack/observability/prometheus.yml +36 -0
- package/stack/observability/tempo.yaml +25 -0
- package/stack/temporal/local.yaml +44 -0
- package/templates/api-auth/AGENTS.md.hbs +16 -0
- package/templates/api-auth/Pulumi.dev.yaml.hbs +8 -0
- package/templates/api-auth/Pulumi.yaml.hbs +8 -0
- package/templates/api-auth/README.md.hbs +67 -0
- package/templates/api-auth/api/package.json.hbs +28 -0
- package/templates/api-auth/api/src/index.ts.hbs +96 -0
- package/templates/api-auth/api/src/schema.ts.hbs +35 -0
- package/templates/api-auth/api/src/seed-authz.ts.hbs +48 -0
- package/templates/api-auth/api/src/spicedb-http-provider.ts.hbs +89 -0
- package/templates/api-auth/index.ts.hbs +65 -0
- package/templates/api-auth/package.json.hbs +20 -0
- package/templates/api-auth/skills/develop/SKILL.md.hbs +32 -0
- package/templates/api-role-gating/AGENTS.md.hbs +20 -0
- package/templates/api-role-gating/Pulumi.dev.yaml.hbs +8 -0
- package/templates/api-role-gating/Pulumi.yaml.hbs +8 -0
- package/templates/api-role-gating/README.md.hbs +64 -0
- package/templates/api-role-gating/api/Dockerfile +17 -0
- package/templates/api-role-gating/api/package.json.hbs +28 -0
- package/templates/api-role-gating/api/src/authn.ts.hbs +29 -0
- package/templates/api-role-gating/api/src/authz.ts.hbs +12 -0
- package/templates/api-role-gating/api/src/main.ts.hbs +58 -0
- package/templates/api-role-gating/api/src/schema.ts.hbs +22 -0
- package/templates/api-role-gating/api/tsconfig.json +13 -0
- package/templates/api-role-gating/index.ts.hbs +107 -0
- package/templates/api-role-gating/package.json.hbs +21 -0
- package/templates/api-role-gating/skills/develop/SKILL.md.hbs +60 -0
- package/templates/api-role-gating/tsconfig.json +10 -0
- package/templates/apps-repo/README.md.hbs +24 -0
- package/templates/apps-repo/gitignore +41 -0
- package/templates/apps-repo/npmrc.hbs +7 -0
- package/templates/apps-repo/package.json.hbs +15 -0
- package/templates/apps-repo/pnpm-workspace.yaml +3 -0
- package/templates/apps-repo/tsconfig.json +18 -0
- package/templates/external-service/AGENTS.md.hbs +20 -0
- package/templates/external-service/Pulumi.dev.yaml.hbs +8 -0
- package/templates/external-service/Pulumi.yaml.hbs +8 -0
- package/templates/external-service/README.md.hbs +56 -0
- package/templates/external-service/api/Dockerfile +15 -0
- package/templates/external-service/api/package.json.hbs +25 -0
- package/templates/external-service/api/src/index.ts.hbs +81 -0
- package/templates/external-service/index.ts.hbs +82 -0
- package/templates/external-service/mocks/vendorpay/package.json.hbs +9 -0
- package/templates/external-service/mocks/vendorpay/server.mjs.hbs +61 -0
- package/templates/external-service/package.json.hbs +34 -0
- package/templates/external-service/skills/develop/SKILL.md.hbs +55 -0
- package/templates/external-service/tsconfig.json +10 -0
- package/templates/platform-repo/AGENTS.md.hbs +18 -0
- package/templates/platform-repo/README.md.hbs +38 -0
- package/templates/platform-repo/core/Pulumi.yaml.hbs +12 -0
- package/templates/platform-repo/core/Pulumi.{{tenant}}-{{env}}.yaml.hbs +57 -0
- package/templates/platform-repo/core/index.ts +62 -0
- package/templates/platform-repo/core/package.json.hbs +22 -0
- package/templates/platform-repo/core/tsconfig.json +8 -0
- package/templates/platform-repo/package.json.hbs +15 -0
- package/templates/platform-repo/platform/Pulumi.yaml.hbs +12 -0
- package/templates/platform-repo/platform/Pulumi.{{tenant}}-{{env}}.yaml.hbs +59 -0
- package/templates/platform-repo/platform/index.ts +95 -0
- package/templates/platform-repo/platform/package.json.hbs +26 -0
- package/templates/platform-repo/platform/tsconfig.json +8 -0
- package/templates/platform-repo/pnpm-workspace.yaml +3 -0
- package/templates/workflow/AGENTS.md.hbs +15 -0
- package/templates/workflow/Pulumi.dev.yaml.hbs +8 -0
- package/templates/workflow/Pulumi.yaml.hbs +8 -0
- package/templates/workflow/README.md.hbs +45 -0
- package/templates/workflow/api/.dockerignore +4 -0
- package/templates/workflow/api/Dockerfile +15 -0
- package/templates/{temporal-api-worker → workflow}/api/package.json.hbs +8 -6
- package/templates/workflow/api/src/index.ts.hbs +130 -0
- package/templates/workflow/api/tsconfig.json +14 -0
- package/templates/workflow/index.ts.hbs +67 -0
- package/templates/workflow/package.json.hbs +20 -0
- package/templates/workflow/skills/develop/SKILL.md.hbs +32 -0
- package/templates/workflow/tsconfig.json +10 -0
- package/templates/workflow/worker/.dockerignore +4 -0
- package/templates/workflow/worker/Dockerfile +13 -0
- package/templates/workflow/worker/package.json.hbs +25 -0
- package/templates/workflow/worker/src/worker.ts.hbs +24 -0
- package/templates/workflow/worker/tsconfig.json +14 -0
- package/dist/src/commands/devbox.d.ts +0 -22
- package/dist/src/commands/devbox.d.ts.map +0 -1
- package/dist/src/commands/devbox.js +0 -463
- package/dist/src/commands/devbox.js.map +0 -1
- package/templates/api-web-db/api/Dockerfile +0 -16
- package/templates/api-web-db/api/package.json.hbs +0 -21
- package/templates/api-web-db/api/src/index.ts.hbs +0 -123
- package/templates/api-web-db/package.json.hbs +0 -27
- package/templates/api-web-db/sst.config.ts.hbs +0 -151
- package/templates/api-web-db/web/.dockerignore +0 -3
- package/templates/api-web-db/web/Dockerfile +0 -17
- package/templates/api-web-db/web/app/lib/db.server.ts +0 -36
- package/templates/api-web-db/web/app/root.tsx +0 -29
- package/templates/api-web-db/web/app/routes/home.tsx.hbs +0 -114
- package/templates/api-web-db/web/app/routes.ts +0 -3
- package/templates/api-web-db/web/package.json.hbs +0 -30
- package/templates/api-web-db/web/prisma/schema.prisma +0 -25
- package/templates/api-web-db/web/prisma.config.ts +0 -18
- package/templates/api-web-db/web/react-router.config.ts +0 -5
- package/templates/api-web-db/web/tsconfig.json +0 -19
- package/templates/api-web-db/web/vite.config.ts +0 -9
- package/templates/temporal-api-worker/README.md.hbs +0 -133
- package/templates/temporal-api-worker/api/src/index.ts.hbs +0 -145
- package/templates/temporal-api-worker/package.json.hbs +0 -29
- package/templates/temporal-api-worker/sst.config.ts.hbs +0 -161
- package/templates/temporal-api-worker/worker/Dockerfile +0 -11
- package/templates/temporal-api-worker/worker/src/bundle-workflows.ts +0 -38
- package/templates/temporal-api-worker/worker/src/worker.ts.hbs +0 -93
- /package/templates/{temporal-api-worker → api-auth}/api/.dockerignore +0 -0
- /package/templates/{temporal-api-worker → api-auth}/api/Dockerfile +0 -0
- /package/templates/{temporal-api-worker → api-auth}/api/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker → api-auth}/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker/worker → api-role-gating/api}/.dockerignore +0 -0
- /package/templates/{temporal-api-worker/worker → external-service/api}/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker → workflow}/api/src/encryption-codec.ts +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/activities.ts.hbs +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/encryption-codec.ts +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/workflows.ts.hbs +0 -0
|
@@ -4,22 +4,33 @@
|
|
|
4
4
|
* Handles CodeArtifact token refresh and project .npmrc setup so that
|
|
5
5
|
* `pnpm install` can resolve @mesh-tech/* packages from the private registry.
|
|
6
6
|
*
|
|
7
|
-
* Credential resolution
|
|
7
|
+
* Credential resolution, in order:
|
|
8
|
+
* 0. The Zitadel-gated registry-auth BROKER — needs no AWS anything on this
|
|
9
|
+
* machine. This is the path a brand-new developer takes.
|
|
8
10
|
* 1. Existing AWS credentials in environment (CI/CD) → use directly
|
|
9
11
|
* 2. Zitadel JWT from `mesh login` → AssumeRoleWithWebIdentity
|
|
10
12
|
* 3. AWS SSO / current profile → use directly
|
|
11
13
|
*
|
|
14
|
+
* Paths 1–3 all shell out to the AWS CLI, so they require it to be installed
|
|
15
|
+
* and credentialed. Path 0 requires only a Mesh account, which is the whole
|
|
16
|
+
* point (design: registry-access-without-aws-sso).
|
|
17
|
+
*
|
|
12
18
|
* Usage:
|
|
13
19
|
* mesh registry login — refresh token, ensure .npmrc
|
|
14
|
-
* mesh registry login mesh.dev —
|
|
20
|
+
* mesh registry login mesh.dev — broker first, then the AWS paths
|
|
15
21
|
* mesh registry login --ci — CI mode (skip .npmrc creation)
|
|
22
|
+
* mesh registry login --no-broker — skip the broker, force the AWS paths
|
|
16
23
|
* mesh registry status — show current auth state
|
|
17
24
|
*/
|
|
18
25
|
import { execFileSync } from "child_process";
|
|
19
26
|
import * as fs from "fs";
|
|
20
27
|
import * as path from "path";
|
|
21
28
|
import { logError, logInfo, logSuccess, logWarn } from "../utils/log.js";
|
|
29
|
+
import { MeshCliError } from "../utils/errors.js";
|
|
30
|
+
import { awsConfigHasProfile, findUnscopedCodeArtifactRegistry, homeNpmrcPath, npmrcAuthKeyForEndpoint, probeRegistryToken, readAwsConfig, REGISTRY_CONTEXT, SSO_SESSION_SNIPPET, stripUnscopedCodeArtifactRegistry, upsertNpmrcLines, } from "../utils/auth-preflight.js";
|
|
31
|
+
import { fetchRegistryGrant, realGrantDeps, DERIVED_BROKER_TIMEOUT_MS, PUBLISHED_BROKER_TIMEOUT_MS, resolveDefaultBrokerContext, resolveRegistryBrokerSource, } from "../utils/registry-broker.js";
|
|
22
32
|
import { readCredentials } from "./login.js";
|
|
33
|
+
import { registerRegistryPublish } from "./registry-publish.js";
|
|
23
34
|
// =============================================================================
|
|
24
35
|
// Constants — platform CodeArtifact registry
|
|
25
36
|
// =============================================================================
|
|
@@ -60,7 +71,7 @@ function getEndpoint(env) {
|
|
|
60
71
|
/**
|
|
61
72
|
* Run `aws codeartifact login` to set the auth token in ~/.npmrc.
|
|
62
73
|
*/
|
|
63
|
-
function codeartifactLogin(env) {
|
|
74
|
+
export function codeartifactLogin(env) {
|
|
64
75
|
try {
|
|
65
76
|
execFileSync("aws", [
|
|
66
77
|
"codeartifact", "login",
|
|
@@ -80,6 +91,57 @@ function codeartifactLogin(env) {
|
|
|
80
91
|
return false;
|
|
81
92
|
}
|
|
82
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Parse a mesh context like "mesh.dev" into tenant + env.
|
|
96
|
+
* Returns null if the context doesn't match the expected {tenant}.{env} pattern.
|
|
97
|
+
*
|
|
98
|
+
* (Mirrors login.ts's parseTenantEnv — kept local/minimal here to avoid
|
|
99
|
+
* expanding login.ts's export surface for a single caller.)
|
|
100
|
+
*/
|
|
101
|
+
function parseTenantEnv(context) {
|
|
102
|
+
const parts = context.split(".");
|
|
103
|
+
if (parts.length !== 2 || !parts[0] || !parts[1])
|
|
104
|
+
return null;
|
|
105
|
+
return { tenant: parts[0], env: parts[1] };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Read the registry's SSM export (published by PackageRegistry, Task 2 of
|
|
109
|
+
* MESH-2168) for a given tenant/env, e.g. /mesh-platform/mesh/dev/registry.
|
|
110
|
+
*
|
|
111
|
+
* Returns null on any failure (missing param, no AWS creds, malformed JSON) —
|
|
112
|
+
* callers treat a null publisherRoleArn as "not configured" and surface an
|
|
113
|
+
* actionable error via resolvePublisherRoleArn.
|
|
114
|
+
*/
|
|
115
|
+
async function getRegistrySsmExport(tenant, env) {
|
|
116
|
+
try {
|
|
117
|
+
const { SSMClient, GetParameterCommand } = await import("@aws-sdk/client-ssm");
|
|
118
|
+
const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? CA_REGION;
|
|
119
|
+
const ssm = new SSMClient({ region });
|
|
120
|
+
const ssmPath = `/mesh-platform/${tenant}/${env}/registry`;
|
|
121
|
+
const response = await ssm.send(new GetParameterCommand({ Name: ssmPath }));
|
|
122
|
+
if (!response.Parameter?.Value)
|
|
123
|
+
return null;
|
|
124
|
+
return JSON.parse(response.Parameter.Value);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Resolve the publisher role ARN to assume for `--publish`.
|
|
132
|
+
*
|
|
133
|
+
* Precedence: explicit --role-arn flag wins, then the registry's SSM export
|
|
134
|
+
* (publisherRoleArn, Task 2 of MESH-2168). Throws an actionable error if
|
|
135
|
+
* neither is available — there's no safe default to fall back to since
|
|
136
|
+
* publishing is an opt-in privileged path (DEFAULT_REGISTRY_ROLE stays null).
|
|
137
|
+
*/
|
|
138
|
+
export function resolvePublisherRoleArn({ roleArnFlag, ssmArn, }) {
|
|
139
|
+
const resolved = roleArnFlag || ssmArn;
|
|
140
|
+
if (!resolved) {
|
|
141
|
+
throw new Error("No publisher role: pass --role or ensure the registry stack exported publisherRoleArn (MESH-2168).");
|
|
142
|
+
}
|
|
143
|
+
return resolved;
|
|
144
|
+
}
|
|
83
145
|
/**
|
|
84
146
|
* Assume an IAM role, return credential env vars.
|
|
85
147
|
*/
|
|
@@ -130,7 +192,7 @@ function assumeRoleWithWebIdentity(roleArn, idToken, sessionName) {
|
|
|
130
192
|
*
|
|
131
193
|
* Returns env var overrides (or empty object if current env is fine).
|
|
132
194
|
*/
|
|
133
|
-
function resolveCredentials(context, roleArn) {
|
|
195
|
+
export function resolveCredentials(context, roleArn) {
|
|
134
196
|
// Path 1: Existing AWS credentials in environment
|
|
135
197
|
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SESSION_TOKEN) {
|
|
136
198
|
logInfo("Using existing AWS credentials from environment");
|
|
@@ -229,26 +291,476 @@ function ensureProjectNpmrc(endpoint) {
|
|
|
229
291
|
return { created: false, updated: true, path: npmrcPath };
|
|
230
292
|
}
|
|
231
293
|
/**
|
|
232
|
-
*
|
|
294
|
+
* Write a broker-issued grant into ~/.npmrc: the scoped registry line and the
|
|
295
|
+
* endpoint's auth token, in exactly the shape `aws codeartifact login
|
|
296
|
+
* --namespace @mesh-tech` would have written.
|
|
297
|
+
*
|
|
298
|
+
* Byte-compatibility with the AWS CLI's output is the requirement, not a nicety:
|
|
299
|
+
* `mesh registry status`, the `mesh start` preflight and the dev doctor all
|
|
300
|
+
* parse ~/.npmrc for that pair, and a machine that gets its token from the
|
|
301
|
+
* broker has to look identical to one that got it from AWS.
|
|
302
|
+
*/
|
|
303
|
+
export function applyGrantToUserNpmrc(grant, npmrcPath = homeNpmrcPath()) {
|
|
304
|
+
let existing = "";
|
|
305
|
+
try {
|
|
306
|
+
existing = fs.readFileSync(npmrcPath, "utf-8");
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
// no ~/.npmrc yet — a clean laptop, which is the case this exists for
|
|
310
|
+
}
|
|
311
|
+
const content = upsertNpmrcLines(existing, [
|
|
312
|
+
{ key: `${grant.scope}:registry`, value: grant.endpoint },
|
|
313
|
+
{ key: `${npmrcAuthKeyForEndpoint(grant.endpoint)}:_authToken`, value: grant.authorizationToken },
|
|
314
|
+
]);
|
|
315
|
+
fs.mkdirSync(path.dirname(npmrcPath), { recursive: true });
|
|
316
|
+
fs.writeFileSync(npmrcPath, content, { mode: 0o600 });
|
|
317
|
+
// `mode` only applies when writeFileSync CREATES the file, so an existing
|
|
318
|
+
// 0644 ~/.npmrc would keep world-readable permissions on a 12h bearer token.
|
|
319
|
+
// Parity with `aws codeartifact login` either way, but one line buys better.
|
|
320
|
+
try {
|
|
321
|
+
fs.chmodSync(npmrcPath, 0o600);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
// A read-only home or an exotic filesystem must not fail an otherwise-good login.
|
|
325
|
+
}
|
|
326
|
+
return { path: npmrcPath };
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Human-facing explanation of a failed broker attempt, plus whether the AWS
|
|
330
|
+
* fallback chain is worth running.
|
|
331
|
+
*
|
|
332
|
+
* `not-authorized` is the one case we do NOT fall through on: the caller has a
|
|
333
|
+
* working Mesh account that simply lacks the grant, and quietly trying AWS next
|
|
334
|
+
* would either succeed (masking a missing grant with an AWS account we're
|
|
335
|
+
* trying to stop requiring) or fail with an unrelated AWS error that buries the
|
|
336
|
+
* real answer.
|
|
337
|
+
*/
|
|
338
|
+
export function describeBrokerFailure(failure, context) {
|
|
339
|
+
switch (failure.kind) {
|
|
340
|
+
case "no-broker":
|
|
341
|
+
return {
|
|
342
|
+
message: "No registry broker published for this context — using the AWS paths.",
|
|
343
|
+
fatal: false,
|
|
344
|
+
};
|
|
345
|
+
case "no-session":
|
|
346
|
+
return {
|
|
347
|
+
message: `No valid Mesh session${context ? ` for ${context}` : ""} — using the AWS paths.`,
|
|
348
|
+
hint: context ? `mesh login ${context}` : "mesh login <context>",
|
|
349
|
+
fatal: false,
|
|
350
|
+
};
|
|
351
|
+
case "unauthenticated":
|
|
352
|
+
return {
|
|
353
|
+
message: "The registry broker rejected your Mesh session (expired or wrong audience).",
|
|
354
|
+
hint: context ? `mesh login ${context}` : "mesh login <context>",
|
|
355
|
+
fatal: false,
|
|
356
|
+
};
|
|
357
|
+
case "not-authorized":
|
|
358
|
+
return {
|
|
359
|
+
// The whole message lives in the body, not in a `remediation.command`:
|
|
360
|
+
// the answer here is "ask a human for a role", which is not a command
|
|
361
|
+
// anyone can run, and rendering a URL behind "→ run:" reads as one.
|
|
362
|
+
message: `Your Mesh account${failure.email ? ` (${failure.email})` : ""} is not authorized to read ` +
|
|
363
|
+
`${CA_NAMESPACE} packages.` +
|
|
364
|
+
(failure.requiredRoles?.length
|
|
365
|
+
? `\n Needs one of these Zitadel roles: ${failure.requiredRoles.join(", ")}`
|
|
366
|
+
: "") +
|
|
367
|
+
(failure.requestUrl
|
|
368
|
+
? `\n Request access: ${failure.requestUrl}`
|
|
369
|
+
: "\n Ask a Mesh platform admin to grant your account registry access."),
|
|
370
|
+
fatal: true,
|
|
371
|
+
};
|
|
372
|
+
case "unavailable":
|
|
373
|
+
return {
|
|
374
|
+
message: `Registry broker unavailable (${failure.detail}) — falling back to the AWS paths.`,
|
|
375
|
+
fatal: false,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Try the broker. Returns true when it produced a working ~/.npmrc, false when
|
|
381
|
+
* the caller should continue to the AWS credential chain.
|
|
382
|
+
*
|
|
383
|
+
* Throws `MeshCliError` only for `not-authorized` — see describeBrokerFailure.
|
|
384
|
+
*/
|
|
385
|
+
async function tryBrokerLogin(contextArg, opts) {
|
|
386
|
+
if (opts.broker === false)
|
|
387
|
+
return null;
|
|
388
|
+
let context = contextArg;
|
|
389
|
+
if (!context) {
|
|
390
|
+
// A context-less invocation used to skip the broker silently — which sent
|
|
391
|
+
// anyone following a remediation that omits the context straight back to
|
|
392
|
+
// the AWS chain. Resolve one when it is unambiguous; say so when it isn't.
|
|
393
|
+
const resolved = resolveDefaultBrokerContext();
|
|
394
|
+
if ("context" in resolved) {
|
|
395
|
+
context = resolved.context;
|
|
396
|
+
logInfo(`No context given — using the only one with a registry broker: ${context}`);
|
|
397
|
+
}
|
|
398
|
+
else if (resolved.reason === "ambiguous") {
|
|
399
|
+
logInfo(`Skipping the registry broker: several contexts publish one (${resolved.candidates.join(", ")}). ` +
|
|
400
|
+
`Name it — e.g. \`mesh registry login ${resolved.candidates[0]}\`.`);
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
logInfo("Skipping the registry broker: no signed-in context publishes one. " +
|
|
405
|
+
`To use it: \`mesh login ${REGISTRY_CONTEXT}\`, then \`mesh registry login ${REGISTRY_CONTEXT}\`.`);
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const { url: brokerUrl, source } = resolveRegistryBrokerSource(context);
|
|
410
|
+
if (!brokerUrl) {
|
|
411
|
+
logInfo("No registry broker published for this context — using the AWS paths.");
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
logInfo(`Requesting a registry token from ${brokerUrl} (no AWS credentials needed)…`);
|
|
415
|
+
const result = await fetchRegistryGrant(context, brokerUrl, {
|
|
416
|
+
...realGrantDeps(),
|
|
417
|
+
// A DERIVED url is a guess at a host that, for every platform not yet
|
|
418
|
+
// redeployed, does not exist — and this wait also sits on the `mesh login`
|
|
419
|
+
// path. Don't make everyone pay the published-broker timeout for a guess.
|
|
420
|
+
timeoutMs: source === "published" ? PUBLISHED_BROKER_TIMEOUT_MS : DERIVED_BROKER_TIMEOUT_MS,
|
|
421
|
+
});
|
|
422
|
+
if (result.ok)
|
|
423
|
+
return result.grant;
|
|
424
|
+
const { message, hint, fatal } = describeBrokerFailure(result.failure, context);
|
|
425
|
+
if (fatal) {
|
|
426
|
+
throw new MeshCliError(message, hint ? { remediation: { command: hint } } : undefined);
|
|
427
|
+
}
|
|
428
|
+
logWarn(message);
|
|
429
|
+
if (hint)
|
|
430
|
+
logInfo(` Try: ${hint}`);
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Whether this `mesh registry login` invocation may rewrite ~/.npmrc.
|
|
435
|
+
*
|
|
436
|
+
* The self-heal is a **laptop** fix. CI pipelines run the unscoped
|
|
437
|
+
* `aws codeartifact login` DELIBERATELY — a host-scoped token is what lets
|
|
438
|
+
* pnpm pull upstream-cached public packages through CodeArtifact — so in a
|
|
439
|
+
* runner the "hijack" line is load-bearing and deleting it would break the
|
|
440
|
+
* install we were asked not to touch. `--ci` is the one signal that says so.
|
|
441
|
+
*
|
|
442
|
+
* Extracted (and tested) rather than left inline because "this changes no CI
|
|
443
|
+
* behaviour" is a promise about the code, not about the workflow files we
|
|
444
|
+
* happen not to have edited.
|
|
445
|
+
*/
|
|
446
|
+
export function shouldRepairUserNpmrc(opts) {
|
|
447
|
+
return !opts.ci;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Repair a hijacked ~/.npmrc: remove an unscoped `registry=<codeartifact>`
|
|
451
|
+
* line if one is present, after taking a timestamped backup.
|
|
452
|
+
*
|
|
453
|
+
* `aws codeartifact login` run WITHOUT `--namespace @mesh-tech` writes that
|
|
454
|
+
* line, and nothing in this CLI used to remove it — so one bare login made
|
|
455
|
+
* CodeArtifact the default registry forever, and every public `npm install`
|
|
456
|
+
* started failing with E401 12 hours later when the token expired. We write
|
|
457
|
+
* the correct (scoped) state; this is the missing repair of the wrong state.
|
|
458
|
+
*
|
|
459
|
+
* Never throws — a repair failure must not fail an otherwise-good login.
|
|
233
460
|
*/
|
|
234
|
-
function
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
461
|
+
export function repairUnscopedRegistry(npmrcPath = homeNpmrcPath()) {
|
|
462
|
+
let original;
|
|
463
|
+
try {
|
|
464
|
+
original = fs.readFileSync(npmrcPath, "utf-8");
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
return { removed: null }; // no ~/.npmrc → nothing to repair
|
|
468
|
+
}
|
|
469
|
+
const { content, removed } = stripUnscopedCodeArtifactRegistry(original);
|
|
470
|
+
if (!removed)
|
|
471
|
+
return { removed: null };
|
|
472
|
+
const backupPath = `${npmrcPath}.bak-${new Date().toISOString().replace(/[:.]/g, "-")}`;
|
|
473
|
+
try {
|
|
474
|
+
fs.writeFileSync(backupPath, original, "utf-8");
|
|
475
|
+
fs.writeFileSync(npmrcPath, content, "utf-8");
|
|
476
|
+
}
|
|
477
|
+
catch (err) {
|
|
478
|
+
return { removed: null, error: err instanceof Error ? err.message : String(err) };
|
|
479
|
+
}
|
|
480
|
+
return { removed, backupPath };
|
|
481
|
+
}
|
|
482
|
+
export async function checkExistingToken() {
|
|
483
|
+
const npmrcPath = homeNpmrcPath();
|
|
484
|
+
if (!fs.existsSync(npmrcPath))
|
|
485
|
+
return { valid: false, state: "missing", reason: "no ~/.npmrc" };
|
|
486
|
+
const hijackLine = findUnscopedCodeArtifactRegistry(fs.readFileSync(npmrcPath, "utf-8")) ?? undefined;
|
|
487
|
+
const probe = await probeRegistryToken({ npmrcPath });
|
|
488
|
+
if (probe.state === "missing") {
|
|
489
|
+
return { valid: false, state: probe.state, reason: "no CodeArtifact token in ~/.npmrc", hijackLine };
|
|
490
|
+
}
|
|
491
|
+
if (probe.state === "expired") {
|
|
492
|
+
return {
|
|
493
|
+
valid: false,
|
|
494
|
+
state: probe.state,
|
|
495
|
+
reason: probe.detail ?? "the CodeArtifact token is expired",
|
|
496
|
+
hijackLine,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
if (probe.state === "unreachable") {
|
|
500
|
+
return {
|
|
501
|
+
valid: false,
|
|
502
|
+
state: probe.state,
|
|
503
|
+
reason: `could not reach the registry to verify the token (${probe.detail ?? "unknown error"})`,
|
|
504
|
+
hijackLine,
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
// Token works — a hijacked default registry still breaks public installs.
|
|
508
|
+
if (hijackLine) {
|
|
509
|
+
return { valid: false, state: probe.state, reason: "unscoped CodeArtifact registry", hijackLine };
|
|
510
|
+
}
|
|
511
|
+
return { valid: true, state: probe.state, endpoint: getEndpoint() ?? undefined };
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* `mesh registry status` — returns the process exit code instead of calling
|
|
515
|
+
* `process.exit`, so the "broken" vs "unverifiable" distinction is testable.
|
|
516
|
+
*
|
|
517
|
+
* Exit 1 is for faults the user can act on right now: a missing or expired
|
|
518
|
+
* token, or an unscoped CodeArtifact `registry=` line (locally detectable, and
|
|
519
|
+
* broken regardless of the network). An **unreachable** registry is neither —
|
|
520
|
+
* it warns and exits 0, because the remediation we'd print (`mesh registry
|
|
521
|
+
* login`) cannot work offline either, and the same rule already governs the
|
|
522
|
+
* `mesh init` doctor.
|
|
523
|
+
*/
|
|
524
|
+
export async function runRegistryStatus(opts) {
|
|
525
|
+
const { valid, state, endpoint, reason, hijackLine } = await (opts?.check ?? checkExistingToken)();
|
|
526
|
+
if (hijackLine) {
|
|
527
|
+
logWarn("~/.npmrc sets CodeArtifact as your DEFAULT registry — every public npm install goes " +
|
|
528
|
+
"through it and will 401 when the 12h token expires:");
|
|
529
|
+
logInfo(` ${hijackLine.trim()}`);
|
|
530
|
+
logInfo("Fix: mesh registry login # removes it (backup taken) and keeps @mesh-tech scoped");
|
|
531
|
+
}
|
|
532
|
+
// A network fault is not an auth fault. Any *other* invalid state is.
|
|
533
|
+
const unverifiable = state === "unreachable" && !hijackLine;
|
|
534
|
+
if (!valid && !unverifiable) {
|
|
535
|
+
logWarn(`Registry auth is not usable${reason ? ` — ${reason}` : ""}. Run: mesh registry login`);
|
|
536
|
+
return 1;
|
|
537
|
+
}
|
|
538
|
+
if (unverifiable) {
|
|
539
|
+
logWarn(`Could not verify the CodeArtifact token in ~/.npmrc — ${reason}.`);
|
|
540
|
+
logInfo("Nothing to fix from here; retry when the registry is reachable.");
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
logSuccess("CodeArtifact token in ~/.npmrc is valid");
|
|
544
|
+
if (endpoint) {
|
|
545
|
+
logInfo(`Endpoint: ${endpoint}`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
// Project .npmrc — worth reporting even when the token couldn't be verified.
|
|
549
|
+
const projectRoot = findProjectRoot();
|
|
550
|
+
if (projectRoot) {
|
|
551
|
+
const npmrcPath = path.join(projectRoot, ".npmrc");
|
|
552
|
+
if (fs.existsSync(npmrcPath)) {
|
|
553
|
+
const content = fs.readFileSync(npmrcPath, "utf-8");
|
|
554
|
+
if (content.includes(`${CA_NAMESPACE}:registry=`)) {
|
|
555
|
+
logSuccess(`Project .npmrc configured (${npmrcPath})`);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
logWarn(`Project .npmrc exists but missing ${CA_NAMESPACE} scope (${npmrcPath})`);
|
|
559
|
+
logInfo("Run: mesh registry login");
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
logWarn(`No .npmrc in project root (${projectRoot})`);
|
|
564
|
+
logInfo("Run: mesh registry login");
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return 0;
|
|
248
568
|
}
|
|
249
569
|
// =============================================================================
|
|
250
570
|
// Commands
|
|
251
571
|
// =============================================================================
|
|
572
|
+
/**
|
|
573
|
+
* Ensure the named AWS SSO profile has a live session — trigger the
|
|
574
|
+
* interactive `aws sso login` (browser) when it's stale.
|
|
575
|
+
*
|
|
576
|
+
* Guardrails (MESH-2479): a missing profile fails fast with the exact
|
|
577
|
+
* `aws configure` setup instead of an opaque CLI error, and the identity
|
|
578
|
+
* probes are time-bounded so a wedged AWS CLI can't hang this silently.
|
|
579
|
+
*/
|
|
580
|
+
function ensureSsoProfile(profile) {
|
|
581
|
+
const awsConfig = readAwsConfig();
|
|
582
|
+
if (awsConfig && !awsConfigHasProfile(awsConfig, profile)) {
|
|
583
|
+
throw new MeshCliError(`AWS profile '${profile}' is not defined in ~/.aws/config — \`aws sso login --profile ${profile}\` cannot work until it exists.\n\n` +
|
|
584
|
+
"If you only need to INSTALL @mesh-tech packages, drop --profile: `mesh login <context>` then\n" +
|
|
585
|
+
"`mesh registry login <context>` uses the Zitadel-gated broker and needs no AWS account at all.\n\n" +
|
|
586
|
+
`If you DEPLOY and genuinely need this profile — one-time setup: \`aws configure sso --profile ${profile}\`,\n` +
|
|
587
|
+
`or add the session + profile by hand:\n` +
|
|
588
|
+
`${SSO_SESSION_SNIPPET}\n[profile ${profile}]\nsso_session = mesh\nsso_account_id = <account id>\nsso_role_name = <role>\nregion = us-east-2`, { remediation: { command: `aws configure sso --profile ${profile}` } });
|
|
589
|
+
}
|
|
590
|
+
const probe = () => execFileSync("aws", ["sts", "get-caller-identity", "--profile", profile], {
|
|
591
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
592
|
+
timeout: 20_000,
|
|
593
|
+
});
|
|
594
|
+
try {
|
|
595
|
+
probe();
|
|
596
|
+
logInfo(`AWS SSO session for profile '${profile}' is live`);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
logInfo(`AWS SSO session for profile '${profile}' is stale — opening browser login…`);
|
|
601
|
+
}
|
|
602
|
+
execFileSync("aws", ["sso", "login", "--profile", profile], { stdio: "inherit" });
|
|
603
|
+
try {
|
|
604
|
+
probe();
|
|
605
|
+
}
|
|
606
|
+
catch (err) {
|
|
607
|
+
throw new MeshCliError(`AWS SSO login for profile '${profile}' completed but the session still fails an identity check.`, {
|
|
608
|
+
remediation: { command: `aws sts get-caller-identity --profile ${profile} # see the underlying error` },
|
|
609
|
+
cause: err,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
logSuccess(`AWS SSO session refreshed (profile '${profile}')`);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* The full registry-auth sequence (CodeArtifact token → ~/.npmrc → project
|
|
616
|
+
* .npmrc). Shared by `mesh registry login` and `mesh login <context>` (F2:
|
|
617
|
+
* login absorbs registry auth).
|
|
618
|
+
*/
|
|
619
|
+
export async function runRegistryLogin(context, opts) {
|
|
620
|
+
// --publish is the opt-in privileged path: resolve the publisher role
|
|
621
|
+
// (explicit --role flag wins, else the registry's SSM export) and feed
|
|
622
|
+
// it through the same Zitadel role-assumption path as the reader flow.
|
|
623
|
+
let roleArn = opts.role;
|
|
624
|
+
if (opts.publish) {
|
|
625
|
+
let ssmArn;
|
|
626
|
+
if (!opts.role) {
|
|
627
|
+
if (!context) {
|
|
628
|
+
logError('`--publish` requires a platform context, e.g. "mesh registry login mesh.dev --publish".');
|
|
629
|
+
process.exit(1);
|
|
630
|
+
}
|
|
631
|
+
const parsed = parseTenantEnv(context);
|
|
632
|
+
if (!parsed) {
|
|
633
|
+
logError(`Could not parse tenant/env from context "${context}" (expected "<tenant>.<env>").`);
|
|
634
|
+
process.exit(1);
|
|
635
|
+
}
|
|
636
|
+
const registryExport = await getRegistrySsmExport(parsed.tenant, parsed.env);
|
|
637
|
+
ssmArn = registryExport?.publisherRoleArn;
|
|
638
|
+
}
|
|
639
|
+
try {
|
|
640
|
+
roleArn = resolvePublisherRoleArn({ roleArnFlag: opts.role, ssmArn });
|
|
641
|
+
}
|
|
642
|
+
catch (err) {
|
|
643
|
+
logError(err.message);
|
|
644
|
+
process.exit(1);
|
|
645
|
+
}
|
|
646
|
+
logInfo(`Publisher role resolved: ${roleArn}`);
|
|
647
|
+
}
|
|
648
|
+
// Step 0: the broker. Tried FIRST for the read path, because it is the only
|
|
649
|
+
// one that works on a machine with no AWS account, no AWS CLI and no
|
|
650
|
+
// ~/.aws/config — the machine this whole feature exists for.
|
|
651
|
+
//
|
|
652
|
+
// Skipped for --publish (a privileged write path that deliberately goes
|
|
653
|
+
// through an assumed IAM role) and for --profile (an explicit "use this AWS
|
|
654
|
+
// profile" instruction we must not silently override).
|
|
655
|
+
if (!opts.publish && !opts.profile) {
|
|
656
|
+
const grant = await tryBrokerLogin(context, opts);
|
|
657
|
+
if (grant) {
|
|
658
|
+
const { path: npmrcPath } = applyGrantToUserNpmrc(grant);
|
|
659
|
+
logSuccess(`Registry token issued by the Mesh broker → ${npmrcPath}` +
|
|
660
|
+
(grant.expiresAt ? ` (expires ${grant.expiresAt})` : ""));
|
|
661
|
+
// Same hijack repair as the AWS path — an unscoped `registry=` line left
|
|
662
|
+
// by a past bare `aws codeartifact login` breaks public installs
|
|
663
|
+
// regardless of where today's token came from.
|
|
664
|
+
if (shouldRepairUserNpmrc(opts)) {
|
|
665
|
+
const repair = repairUnscopedRegistry();
|
|
666
|
+
if (repair.removed) {
|
|
667
|
+
logWarn("Removed an unscoped CodeArtifact `registry=` from ~/.npmrc — it routed ALL npm traffic " +
|
|
668
|
+
"(public packages included) through CodeArtifact.");
|
|
669
|
+
logInfo(` removed: ${repair.removed.trim()}`);
|
|
670
|
+
if (repair.backupPath)
|
|
671
|
+
logInfo(` backup: ${repair.backupPath}`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (!opts.ci && !opts.skipNpmrc) {
|
|
675
|
+
const result = ensureProjectNpmrc(grant.endpoint);
|
|
676
|
+
if (result.created) {
|
|
677
|
+
logSuccess(`Created ${result.path} with ${CA_NAMESPACE} registry scope`);
|
|
678
|
+
}
|
|
679
|
+
else if (result.updated) {
|
|
680
|
+
logSuccess(`Updated ${CA_NAMESPACE} registry in ${result.path}`);
|
|
681
|
+
}
|
|
682
|
+
else {
|
|
683
|
+
logInfo(`${result.path} already configured`);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
logSuccess(`Ready — run pnpm install to fetch ${CA_NAMESPACE} packages`);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
let env;
|
|
691
|
+
if (opts.profile) {
|
|
692
|
+
// Jawad's flow, one command: live SSO session + profile-scoped token.
|
|
693
|
+
// Static creds in the environment would override the profile — drop them.
|
|
694
|
+
ensureSsoProfile(opts.profile);
|
|
695
|
+
env = { ...process.env, AWS_PROFILE: opts.profile };
|
|
696
|
+
for (const key of ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]) {
|
|
697
|
+
delete env[key];
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
const awsCreds = resolveCredentials(context, roleArn);
|
|
702
|
+
env = Object.keys(awsCreds).length > 0
|
|
703
|
+
? { ...process.env, ...awsCreds }
|
|
704
|
+
: undefined;
|
|
705
|
+
}
|
|
706
|
+
// Step 1: Run `aws codeartifact login` (sets token in ~/.npmrc)
|
|
707
|
+
logInfo("Authenticating with CodeArtifact...");
|
|
708
|
+
if (!codeartifactLogin(env)) {
|
|
709
|
+
logError("CodeArtifact login failed.\n\n" +
|
|
710
|
+
"You do NOT need an AWS account to install @mesh-tech packages. The supported path is:\n" +
|
|
711
|
+
` mesh login ${context ?? "<context>"} # browser → Zitadel; then re-run this command\n\n` +
|
|
712
|
+
"This machine fell through to the AWS path, which means one of: the platform publishes no\n" +
|
|
713
|
+
"registry broker yet, your Mesh account is not signed in, or the broker was unreachable —\n" +
|
|
714
|
+
"the warning above says which.\n\n" +
|
|
715
|
+
"AWS SSO is only needed if you DEPLOY (mesh deploy):\n" +
|
|
716
|
+
" mesh registry login --profile mesh-dev # auto-runs `aws sso login`");
|
|
717
|
+
process.exit(1);
|
|
718
|
+
}
|
|
719
|
+
logSuccess("CodeArtifact token refreshed (valid for 12 hours)");
|
|
720
|
+
// Step 1b: Repair a hijacked ~/.npmrc. We always write the SCOPED form
|
|
721
|
+
// above (--namespace @mesh-tech), but a bare `aws codeartifact login` run
|
|
722
|
+
// at any point in the past leaves an unscoped `registry=` line that we
|
|
723
|
+
// never removed — so it survived every subsequent correct login.
|
|
724
|
+
//
|
|
725
|
+
// Laptops only — see shouldRepairUserNpmrc: in `--ci` the unscoped line is
|
|
726
|
+
// doing its job and a "repair" would break the runner's install.
|
|
727
|
+
if (shouldRepairUserNpmrc(opts)) {
|
|
728
|
+
const repair = repairUnscopedRegistry();
|
|
729
|
+
if (repair.removed) {
|
|
730
|
+
logWarn("Removed an unscoped CodeArtifact `registry=` from ~/.npmrc — it routed ALL npm traffic " +
|
|
731
|
+
"(public packages included) through CodeArtifact, so every install broke when the 12h token expired. " +
|
|
732
|
+
`${CA_NAMESPACE} stays scoped; public packages now go to npmjs.`);
|
|
733
|
+
logInfo(` removed: ${repair.removed.trim()}`);
|
|
734
|
+
if (repair.backupPath)
|
|
735
|
+
logInfo(` backup: ${repair.backupPath}`);
|
|
736
|
+
}
|
|
737
|
+
else if (repair.error) {
|
|
738
|
+
logWarn(`Could not repair ~/.npmrc (${repair.error}) — remove any unscoped \`registry=\` line by hand.`);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
// Step 2: Get endpoint URL
|
|
742
|
+
const endpoint = getEndpoint(env);
|
|
743
|
+
if (!endpoint) {
|
|
744
|
+
logWarn("Could not retrieve registry endpoint — .npmrc scope not configured");
|
|
745
|
+
logInfo("You may need to manually add to .npmrc:");
|
|
746
|
+
logInfo(` ${CA_NAMESPACE}:registry=https://mesh-platform-<ACCOUNT>.d.codeartifact.${CA_REGION}.amazonaws.com/npm/${CA_REPOSITORY}/`);
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
// Step 3: Ensure project .npmrc (unless --ci or --skip-npmrc)
|
|
750
|
+
if (!opts.ci && !opts.skipNpmrc) {
|
|
751
|
+
const result = ensureProjectNpmrc(endpoint);
|
|
752
|
+
if (result.created) {
|
|
753
|
+
logSuccess(`Created ${result.path} with ${CA_NAMESPACE} registry scope`);
|
|
754
|
+
}
|
|
755
|
+
else if (result.updated) {
|
|
756
|
+
logSuccess(`Updated ${CA_NAMESPACE} registry in ${result.path}`);
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
logInfo(`${result.path} already configured`);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
logSuccess(`Ready — run pnpm install to fetch ${CA_NAMESPACE} packages`);
|
|
763
|
+
}
|
|
252
764
|
export function registerRegistryCommands(program) {
|
|
253
765
|
const registry = program
|
|
254
766
|
.command("registry")
|
|
@@ -260,77 +772,21 @@ export function registerRegistryCommands(program) {
|
|
|
260
772
|
.option("--role <arn>", "IAM role ARN for registry access")
|
|
261
773
|
.option("--ci", "CI mode — refresh token only, skip project .npmrc setup")
|
|
262
774
|
.option("--skip-npmrc", "Skip project .npmrc setup")
|
|
775
|
+
.option("--profile <name>", "AWS SSO profile (e.g. mesh-dev) — auto-runs `aws sso login` when the session is stale")
|
|
776
|
+
.option("--no-broker", "Skip the Zitadel-gated registry broker and go straight to the AWS credential chain")
|
|
777
|
+
.option("--publish", "Assume the registry's publisher role for CodeArtifact publish access " +
|
|
778
|
+
"(opt-in privileged path — resolves publisherRoleArn from the registry's SSM export unless --role is given)")
|
|
263
779
|
.action(async (context, opts) => {
|
|
264
|
-
|
|
265
|
-
const awsCreds = resolveCredentials(context, opts.role);
|
|
266
|
-
const env = Object.keys(awsCreds).length > 0
|
|
267
|
-
? { ...process.env, ...awsCreds }
|
|
268
|
-
: undefined;
|
|
269
|
-
// Step 1: Run `aws codeartifact login` (sets token in ~/.npmrc)
|
|
270
|
-
logInfo("Authenticating with CodeArtifact...");
|
|
271
|
-
if (!codeartifactLogin(env)) {
|
|
272
|
-
logError("CodeArtifact login failed.\n\n" +
|
|
273
|
-
"Check that your AWS credentials have codeartifact:GetAuthorizationToken permission.\n" +
|
|
274
|
-
"If using AWS SSO, run: aws sso login\n" +
|
|
275
|
-
"If using Zitadel: mesh login <context>");
|
|
276
|
-
process.exit(1);
|
|
277
|
-
}
|
|
278
|
-
logSuccess("CodeArtifact token refreshed (valid for 12 hours)");
|
|
279
|
-
// Step 2: Get endpoint URL
|
|
280
|
-
const endpoint = getEndpoint(env);
|
|
281
|
-
if (!endpoint) {
|
|
282
|
-
logWarn("Could not retrieve registry endpoint — .npmrc scope not configured");
|
|
283
|
-
logInfo("You may need to manually add to .npmrc:");
|
|
284
|
-
logInfo(` ${CA_NAMESPACE}:registry=https://mesh-platform-<ACCOUNT>.d.codeartifact.${CA_REGION}.amazonaws.com/npm/${CA_REPOSITORY}/`);
|
|
285
|
-
process.exit(0);
|
|
286
|
-
}
|
|
287
|
-
// Step 3: Ensure project .npmrc (unless --ci or --skip-npmrc)
|
|
288
|
-
if (!opts.ci && !opts.skipNpmrc) {
|
|
289
|
-
const result = ensureProjectNpmrc(endpoint);
|
|
290
|
-
if (result.created) {
|
|
291
|
-
logSuccess(`Created ${result.path} with ${CA_NAMESPACE} registry scope`);
|
|
292
|
-
}
|
|
293
|
-
else if (result.updated) {
|
|
294
|
-
logSuccess(`Updated ${CA_NAMESPACE} registry in ${result.path}`);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
logInfo(`${result.path} already configured`);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
logSuccess(`Ready — run pnpm install to fetch ${CA_NAMESPACE} packages`);
|
|
780
|
+
await runRegistryLogin(context, opts);
|
|
301
781
|
});
|
|
302
782
|
registry
|
|
303
783
|
.command("status")
|
|
304
784
|
.description("Check current registry authentication status")
|
|
305
|
-
.action(() => {
|
|
306
|
-
const
|
|
307
|
-
if (
|
|
308
|
-
|
|
309
|
-
process.exit(1);
|
|
310
|
-
}
|
|
311
|
-
logSuccess("CodeArtifact token found in ~/.npmrc");
|
|
312
|
-
if (endpoint) {
|
|
313
|
-
logInfo(`Endpoint: ${endpoint}`);
|
|
314
|
-
}
|
|
315
|
-
// Check project .npmrc
|
|
316
|
-
const projectRoot = findProjectRoot();
|
|
317
|
-
if (projectRoot) {
|
|
318
|
-
const npmrcPath = path.join(projectRoot, ".npmrc");
|
|
319
|
-
if (fs.existsSync(npmrcPath)) {
|
|
320
|
-
const content = fs.readFileSync(npmrcPath, "utf-8");
|
|
321
|
-
if (content.includes(`${CA_NAMESPACE}:registry=`)) {
|
|
322
|
-
logSuccess(`Project .npmrc configured (${npmrcPath})`);
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
logWarn(`Project .npmrc exists but missing ${CA_NAMESPACE} scope (${npmrcPath})`);
|
|
326
|
-
logInfo("Run: mesh registry login");
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
else {
|
|
330
|
-
logWarn(`No .npmrc in project root (${projectRoot})`);
|
|
331
|
-
logInfo("Run: mesh registry login");
|
|
332
|
-
}
|
|
333
|
-
}
|
|
785
|
+
.action(async () => {
|
|
786
|
+
const code = await runRegistryStatus();
|
|
787
|
+
if (code !== 0)
|
|
788
|
+
process.exit(code);
|
|
334
789
|
});
|
|
790
|
+
registerRegistryPublish(registry);
|
|
335
791
|
}
|
|
336
792
|
//# sourceMappingURL=registry.js.map
|