@omega.js/manager 0.1.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/.claude-plugin/marketplace.json +14 -0
- package/LICENSE +98 -0
- package/README.md +165 -0
- package/bin/omega +2 -0
- package/bin/omg +2 -0
- package/claude-plugin/.claude-plugin/plugin.json +11 -0
- package/claude-plugin/.mcp.json +9 -0
- package/claude-plugin/README.md +139 -0
- package/claude-plugin/hooks/gate/mark.sh +58 -0
- package/claude-plugin/hooks/gate/run.sh +97 -0
- package/claude-plugin/hooks/guard/run.sh +249 -0
- package/claude-plugin/hooks/hooks.json +63 -0
- package/claude-plugin/hooks/inject/run.sh +127 -0
- package/claude-plugin/hooks/lib/omega-gate.sh +20 -0
- package/claude-plugin/hooks/lib/omega-scope.sh +41 -0
- package/claude-plugin/hooks/lib/omega-skills.sh +209 -0
- package/claude-plugin/hooks/quality/run.sh +132 -0
- package/claude-plugin/hooks/shape/run.sh +45 -0
- package/claude-plugin/mcp-router-launch.js +29 -0
- package/claude-plugin/skills/README.md +48 -0
- package/claude-plugin/skills/accessibility/SKILL.md +31 -0
- package/claude-plugin/skills/analytics/SKILL.md +30 -0
- package/claude-plugin/skills/backend/SKILL.md +25 -0
- package/claude-plugin/skills/brandcheck/SKILL.md +29 -0
- package/claude-plugin/skills/browser/SKILL.md +64 -0
- package/claude-plugin/skills/client/SKILL.md +24 -0
- package/claude-plugin/skills/desktop/SKILL.md +25 -0
- package/claude-plugin/skills/extension/SKILL.md +25 -0
- package/claude-plugin/skills/main/SKILL.md +54 -0
- package/claude-plugin/skills/manager/SKILL.md +25 -0
- package/claude-plugin/skills/seo/SKILL.md +36 -0
- package/claude-plugin/skills/theme/SKILL.md +33 -0
- package/claude-plugin/skills/web/SKILL.md +29 -0
- package/dist/cli-run.js +34 -0
- package/dist/cli.js +29 -0
- package/dist/commands/build.js +17 -0
- package/dist/commands/clean.js +16 -0
- package/dist/commands/company.js +46 -0
- package/dist/commands/deploy.js +143 -0
- package/dist/commands/dev.js +437 -0
- package/dist/commands/devlog.js +25 -0
- package/dist/commands/help.js +48 -0
- package/dist/commands/manage.js +53 -0
- package/dist/commands/migrate.js +76 -0
- package/dist/commands/onboard.js +31 -0
- package/dist/commands/pipeline.js +319 -0
- package/dist/commands/test.js +380 -0
- package/dist/commands/update.js +128 -0
- package/dist/commands/version.js +8 -0
- package/dist/company-init.js +167 -0
- package/dist/company.js +283 -0
- package/dist/config.js +1359 -0
- package/dist/devlog/index.js +226 -0
- package/dist/devlog/lib/collect-commits.js +136 -0
- package/dist/devlog/lib/generate-post.js +201 -0
- package/dist/devlog/lib/ghostii.js +122 -0
- package/dist/devlog/lib/project-map.js +98 -0
- package/dist/devlog/lib/publish-website.js +88 -0
- package/dist/index.js +45 -0
- package/dist/lib/agents-md.js +201 -0
- package/dist/lib/analytics-secret.js +22 -0
- package/dist/lib/argv.js +21 -0
- package/dist/lib/auth-admin.js +120 -0
- package/dist/lib/automation-client.js +210 -0
- package/dist/lib/backend-marketing.js +49 -0
- package/dist/lib/brand.js +240 -0
- package/dist/lib/bundle-id.js +53 -0
- package/dist/lib/claude-settings.js +125 -0
- package/dist/lib/company-scaffold.js +213 -0
- package/dist/lib/company.js +227 -0
- package/dist/lib/config-flow.js +350 -0
- package/dist/lib/config-write.js +41 -0
- package/dist/lib/custom-target.js +75 -0
- package/dist/lib/domain-utils.js +19 -0
- package/dist/lib/duration.js +39 -0
- package/dist/lib/env-order.js +236 -0
- package/dist/lib/env-secret.js +78 -0
- package/dist/lib/firestore-rest.js +326 -0
- package/dist/lib/framework-bin.js +156 -0
- package/dist/lib/gitignore.js +63 -0
- package/dist/lib/google-auth.js +495 -0
- package/dist/lib/google-token.js +66 -0
- package/dist/lib/jwt.js +31 -0
- package/dist/lib/legacy-oauth.js +59 -0
- package/dist/lib/node-version.js +127 -0
- package/dist/lib/owner-plan.js +78 -0
- package/dist/lib/package-scripts.js +152 -0
- package/dist/lib/preflight.js +470 -0
- package/dist/lib/product-create.js +144 -0
- package/dist/lib/run-command.js +74 -0
- package/dist/lib/run-gates.js +70 -0
- package/dist/lib/run-output.js +42 -0
- package/dist/lib/run-summary.js +384 -0
- package/dist/lib/scaffold.js +427 -0
- package/dist/lib/service-input.js +207 -0
- package/dist/lib/service-runner.js +466 -0
- package/dist/lib/stale.js +24 -0
- package/dist/lib/target-selection.js +155 -0
- package/dist/lib/verb-fanout.js +128 -0
- package/dist/lib/verify-live.js +188 -0
- package/dist/manage.js +311 -0
- package/dist/omega-bin.js +7 -0
- package/dist/onboard.js +532 -0
- package/dist/services/account/ensure/users.js +259 -0
- package/dist/services/account/index.js +97 -0
- package/dist/services/account/lib/backend-client.js +107 -0
- package/dist/services/account/lib/password.js +36 -0
- package/dist/services/account/lib/resolve-password.js +100 -0
- package/dist/services/advertising/ensure/sites.js +101 -0
- package/dist/services/advertising/index.js +101 -0
- package/dist/services/advertising/lib/adsense-api.js +41 -0
- package/dist/services/ai/ensure/keys.js +21 -0
- package/dist/services/ai/index.js +36 -0
- package/dist/services/analytics/ensure/google-firebase-link.js +230 -0
- package/dist/services/analytics/ensure/google-streams.js +256 -0
- package/dist/services/analytics/ensure/meta-pixel.js +22 -0
- package/dist/services/analytics/ensure/tiktok-pixel.js +22 -0
- package/dist/services/analytics/index.js +134 -0
- package/dist/services/analytics/lib/analytics-api.js +156 -0
- package/dist/services/analytics/lib/meta-api.js +83 -0
- package/dist/services/analytics/lib/pixel-account.js +78 -0
- package/dist/services/analytics/lib/pixel-provision.js +152 -0
- package/dist/services/analytics/lib/pixel-specs.js +57 -0
- package/dist/services/analytics/lib/pixel-token.js +88 -0
- package/dist/services/analytics/lib/property-flow.js +77 -0
- package/dist/services/analytics/lib/tiktok-api.js +157 -0
- package/dist/services/analytics/lib/tiktok-auth.js +153 -0
- package/dist/services/assets/ensure/logo-gen.js +68 -0
- package/dist/services/assets/index.js +109 -0
- package/dist/services/assets/lib/assets-config.js +168 -0
- package/dist/services/assets/lib/brandmark-api.js +160 -0
- package/dist/services/assets/lib/derived.js +113 -0
- package/dist/services/assets/lib/font-loader.js +67 -0
- package/dist/services/assets/lib/reconcile.js +122 -0
- package/dist/services/assets/lib/reset.js +118 -0
- package/dist/services/assets/lib/svg-logo-generator.js +154 -0
- package/dist/services/assets/lib/svg-to-black.js +32 -0
- package/dist/services/assets/write/favicons.js +82 -0
- package/dist/services/assets/write/icons.js +64 -0
- package/dist/services/assets/write/process.js +96 -0
- package/dist/services/assets/write/reconcile.js +30 -0
- package/dist/services/assets/write/social-icons.js +108 -0
- package/dist/services/assets/write/templates.js +345 -0
- package/dist/services/bookmark/ensure/sync.js +255 -0
- package/dist/services/bookmark/index.js +17 -0
- package/dist/services/campaigns/ensure/contact-person.js +40 -0
- package/dist/services/campaigns/ensure/custom-fields.js +84 -0
- package/dist/services/campaigns/ensure/domain-auth.js +92 -0
- package/dist/services/campaigns/ensure/event-webhook.js +89 -0
- package/dist/services/campaigns/ensure/link-branding.js +187 -0
- package/dist/services/campaigns/ensure/list.js +50 -0
- package/dist/services/campaigns/ensure/segments.js +109 -0
- package/dist/services/campaigns/ensure/sender-identity.js +153 -0
- package/dist/services/campaigns/ensure/unsubscribe-groups.js +116 -0
- package/dist/services/campaigns/index.js +79 -0
- package/dist/services/campaigns/lib/dns-sync.js +81 -0
- package/dist/services/campaigns/lib/segment-query.js +138 -0
- package/dist/services/campaigns/lib/sendgrid-api.js +287 -0
- package/dist/services/captcha/ensure/site-key.js +83 -0
- package/dist/services/captcha/index.js +78 -0
- package/dist/services/captcha/lib/console-url.js +45 -0
- package/dist/services/captcha/lib/recaptcha-api.js +36 -0
- package/dist/services/certificates/ensure/api-key.js +22 -0
- package/dist/services/certificates/ensure/bundle-ids.js +115 -0
- package/dist/services/certificates/ensure/certificates.js +187 -0
- package/dist/services/certificates/ensure/profiles.js +143 -0
- package/dist/services/certificates/index.js +225 -0
- package/dist/services/certificates/lib/apple-api.js +183 -0
- package/dist/services/certificates/lib/certificate-manager.js +252 -0
- package/dist/services/certificates/lib/identifier-manager.js +107 -0
- package/dist/services/certificates/lib/keychain.js +135 -0
- package/dist/services/certificates/lib/manual-walkthrough.js +165 -0
- package/dist/services/certificates/lib/profile-manager.js +115 -0
- package/dist/services/chat/data/baseline-knowledge.md +96 -0
- package/dist/services/chat/ensure/chat.js +106 -0
- package/dist/services/chat/ensure/user.js +45 -0
- package/dist/services/chat/index.js +139 -0
- package/dist/services/chat/lib/baseline-knowledge.js +137 -0
- package/dist/services/cloud/ensure/authentication.js +267 -0
- package/dist/services/cloud/ensure/billing.js +120 -0
- package/dist/services/cloud/ensure/cloud-messaging.js +105 -0
- package/dist/services/cloud/ensure/database.js +60 -0
- package/dist/services/cloud/ensure/firestore.js +79 -0
- package/dist/services/cloud/ensure/functions.js +49 -0
- package/dist/services/cloud/ensure/hosting.js +398 -0
- package/dist/services/cloud/ensure/oauth-consent.js +248 -0
- package/dist/services/cloud/ensure/project-settings.js +72 -0
- package/dist/services/cloud/ensure/sdk-config.js +95 -0
- package/dist/services/cloud/ensure/service-account.js +152 -0
- package/dist/services/cloud/ensure/services.js +103 -0
- package/dist/services/cloud/ensure/storage.js +47 -0
- package/dist/services/cloud/index.js +130 -0
- package/dist/services/cloud/lib/access-heal.js +130 -0
- package/dist/services/cloud/lib/firebase-api.js +662 -0
- package/dist/services/cloud/lib/project-flow.js +102 -0
- package/dist/services/directory/ensure/entry.js +48 -0
- package/dist/services/directory/index.js +64 -0
- package/dist/services/directory/lib/blocks.js +104 -0
- package/dist/services/disperse/index.js +45 -0
- package/dist/services/disperse/write/certs.js +117 -0
- package/dist/services/domain/ensure/nameservers.js +179 -0
- package/dist/services/domain/index.js +69 -0
- package/dist/services/domain/lib/namecheap-api.js +167 -0
- package/dist/services/domain/lib/registrars.js +46 -0
- package/dist/services/domain/lib/whitelist-walkthrough.js +76 -0
- package/dist/services/edge/ensure/cache-rules.js +105 -0
- package/dist/services/edge/ensure/dns-records.js +304 -0
- package/dist/services/edge/ensure/email-routing.js +292 -0
- package/dist/services/edge/ensure/rules-configuration.js +98 -0
- package/dist/services/edge/ensure/rules-managed-transforms.js +101 -0
- package/dist/services/edge/ensure/rules-redirect.js +107 -0
- package/dist/services/edge/ensure/rules-response-headers.js +90 -0
- package/dist/services/edge/ensure/rules-security.js +142 -0
- package/dist/services/edge/ensure/speed-scheduled-tests.js +98 -0
- package/dist/services/edge/ensure/workers.js +219 -0
- package/dist/services/edge/ensure/zone-settings.js +108 -0
- package/dist/services/edge/ensure/zone.js +183 -0
- package/dist/services/edge/index.js +73 -0
- package/dist/services/edge/lib/cloudflare-api.js +84 -0
- package/dist/services/edge/lib/dns-records-helpers.js +518 -0
- package/dist/services/edge/lib/read-cache.js +16 -0
- package/dist/services/edge/lib/ruleset-helper.js +108 -0
- package/dist/services/edge/workers/omega-api-proxy.js +43 -0
- package/dist/services/email/data/baseline-filter.md +4 -0
- package/dist/services/email/data/baseline-knowledge.md +86 -0
- package/dist/services/email/ensure/agent.js +107 -0
- package/dist/services/email/ensure/user.js +45 -0
- package/dist/services/email/index.js +138 -0
- package/dist/services/email/lib/baseline.js +82 -0
- package/dist/services/email/lib/knowledge-file.js +53 -0
- package/dist/services/forms/ensure/form.js +46 -0
- package/dist/services/forms/ensure/user.js +45 -0
- package/dist/services/forms/index.js +138 -0
- package/dist/services/migrations/ensure/notifications.js +189 -0
- package/dist/services/migrations/ensure/orders.js +34 -0
- package/dist/services/migrations/ensure/payment-provider.js +132 -0
- package/dist/services/migrations/ensure/payments-intents.js +34 -0
- package/dist/services/migrations/ensure/state-retirement.js +266 -0
- package/dist/services/migrations/ensure/targets-rename.js +124 -0
- package/dist/services/migrations/ensure/users.js +1176 -0
- package/dist/services/migrations/index.js +101 -0
- package/dist/services/migrations/lib/attribution-touch.js +64 -0
- package/dist/services/migrations/lib/ensure-metadata.js +144 -0
- package/dist/services/migrations/lib/migration-runner.js +473 -0
- package/dist/services/migrations/lib/sanitize-strings.js +112 -0
- package/dist/services/migrations/lib/schema-validator.js +154 -0
- package/dist/services/monitoring/ensure/dsn.js +54 -0
- package/dist/services/monitoring/ensure/projects.js +135 -0
- package/dist/services/monitoring/index.js +54 -0
- package/dist/services/monitoring/lib/sentry-api.js +94 -0
- package/dist/services/newsletter/ensure/custom-fields.js +90 -0
- package/dist/services/newsletter/ensure/publication.js +94 -0
- package/dist/services/newsletter/ensure/segments.js +140 -0
- package/dist/services/newsletter/ensure/webhook.js +108 -0
- package/dist/services/newsletter/index.js +64 -0
- package/dist/services/newsletter/lib/beehiiv-api.js +124 -0
- package/dist/services/newsletter/lib/segment-automation.js +577 -0
- package/dist/services/payment/ensure/chargebee-account.js +30 -0
- package/dist/services/payment/ensure/chargebee-products.js +359 -0
- package/dist/services/payment/ensure/chargebee-webhook.js +113 -0
- package/dist/services/payment/ensure/paypal-account.js +36 -0
- package/dist/services/payment/ensure/paypal-products.js +374 -0
- package/dist/services/payment/ensure/paypal-webhook.js +128 -0
- package/dist/services/payment/ensure/stripe-account.js +93 -0
- package/dist/services/payment/ensure/stripe-disputes.js +56 -0
- package/dist/services/payment/ensure/stripe-products.js +245 -0
- package/dist/services/payment/ensure/stripe-radar.js +74 -0
- package/dist/services/payment/ensure/stripe-webhook.js +130 -0
- package/dist/services/payment/index.js +163 -0
- package/dist/services/payment/lib/chargebee-api.js +338 -0
- package/dist/services/payment/lib/payment-utils.js +116 -0
- package/dist/services/payment/lib/paypal-api.js +354 -0
- package/dist/services/payment/lib/provider-setup.js +134 -0
- package/dist/services/payment/lib/stripe-api.js +152 -0
- package/dist/services/repo/ensure/org.js +70 -0
- package/dist/services/repo/ensure/pages.js +72 -0
- package/dist/services/repo/ensure/repo.js +90 -0
- package/dist/services/repo/index.js +52 -0
- package/dist/services/repo/lib/github-api.js +196 -0
- package/dist/services/search/ensure/ga-link.js +57 -0
- package/dist/services/search/ensure/property.js +137 -0
- package/dist/services/search/ensure/sitemaps.js +70 -0
- package/dist/services/search/index.js +61 -0
- package/dist/services/search/lib/search-console-api.js +92 -0
- package/dist/services/seo/ensure/github-repos.js +271 -0
- package/dist/services/seo/index.js +55 -0
- package/dist/services/seo/lib/gh-api.js +161 -0
- package/dist/services/seo/templates/developer-tool/.github/workflows/maintenance.yml +25 -0
- package/dist/services/seo/templates/developer-tool/.nvmrc +1 -0
- package/dist/services/seo/templates/developer-tool/_README.md.js +121 -0
- package/dist/services/seo/templates/developer-tool/_package.json.js +33 -0
- package/dist/services/seo/templates/developer-tool/src/index.js +120 -0
- package/dist/services/seo/templates/index.js +57 -0
- package/dist/services/server/ensure/brands.js +63 -0
- package/dist/services/server/index.js +42 -0
- package/dist/services/testing/ensure/target-checks.js +97 -0
- package/dist/services/testing/index.js +11 -0
- package/dist/services/testing/lib/checks.js +467 -0
- package/dist/services/update/index.js +20 -0
- package/dist/services/update/lib/cache.js +59 -0
- package/dist/services/update/lib/fingerprint.js +157 -0
- package/dist/services/update/write/targets.js +206 -0
- package/dist/services/workspace/ensure/agents.js +42 -0
- package/dist/services/workspace/ensure/claude-settings.js +34 -0
- package/dist/services/workspace/ensure/config.js +54 -0
- package/dist/services/workspace/ensure/defaults.js +60 -0
- package/dist/services/workspace/ensure/env-keys.js +55 -0
- package/dist/services/workspace/ensure/env-order.js +66 -0
- package/dist/services/workspace/ensure/env-rules.js +97 -0
- package/dist/services/workspace/ensure/gitignore.js +18 -0
- package/dist/services/workspace/ensure/scripts.js +126 -0
- package/dist/services/workspace/ensure/structure.js +97 -0
- package/dist/services/workspace/ensure/translation-sdk.js +148 -0
- package/dist/services/workspace/ensure/workflows.js +54 -0
- package/dist/services/workspace/index.js +8 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/certs.js +199 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/flows.js +317 -0
- package/dist/vendor/devkit/local-https.js +360 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/prompt.js +187 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/translate/cache.js +84 -0
- package/dist/vendor/devkit/translate/engine.js +243 -0
- package/dist/vendor/devkit/translate/index.js +49 -0
- package/dist/vendor/devkit/translate/languages.js +134 -0
- package/dist/vendor/devkit/translate/providers.js +188 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/docs/AGENTS.md +200 -0
- package/docs/account.md +45 -0
- package/docs/advertising.md +46 -0
- package/docs/ai.md +34 -0
- package/docs/analytics.md +69 -0
- package/docs/assets.md +57 -0
- package/docs/bookmark.md +26 -0
- package/docs/brand.md +151 -0
- package/docs/campaigns.md +96 -0
- package/docs/captcha.md +46 -0
- package/docs/certificates.md +68 -0
- package/docs/chat.md +47 -0
- package/docs/cloud.md +110 -0
- package/docs/company.md +64 -0
- package/docs/directory.md +140 -0
- package/docs/disperse.md +46 -0
- package/docs/domain.md +56 -0
- package/docs/edge.md +234 -0
- package/docs/email.md +42 -0
- package/docs/forms.md +48 -0
- package/docs/index.md +109 -0
- package/docs/migration.md +203 -0
- package/docs/migrations.md +56 -0
- package/docs/monitoring.md +41 -0
- package/docs/newsletter.md +48 -0
- package/docs/payment.md +83 -0
- package/docs/repo.md +48 -0
- package/docs/search.md +44 -0
- package/docs/seo.md +34 -0
- package/docs/server.md +37 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/testing.md +34 -0
- package/docs/update.md +36 -0
- package/docs/workspace.md +64 -0
- package/package.json +88 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omega help` โ and what a bare `omega` prints (#229). The manager's own
|
|
3
|
+
* help, not devkit's generated listing: a brand root is where a stranger
|
|
4
|
+
* lands, so the three verbs that matter come first, in the order a brand
|
|
5
|
+
* actually needs them, and every line says what the verb DOES.
|
|
6
|
+
*/
|
|
7
|
+
const chalk = require('chalk').default;
|
|
8
|
+
|
|
9
|
+
// verb โ what it does. Order is the story: reconcile, run, publish, then the
|
|
10
|
+
// rest of the surface.
|
|
11
|
+
const VERBS = [
|
|
12
|
+
['omega manage', 'reconcile every service to config/omega.json5 โ safe to rerun (`npm run manage`)'],
|
|
13
|
+
['omega dev', 'boot the local stack: website + backend emulator (`npm start`)'],
|
|
14
|
+
['omega deploy', 'publish each target, backend first โ deliberate, never automatic (`npm run deploy`)'],
|
|
15
|
+
['omega onboard', 'create a NEW brand monorepo from scratch (the wizard)'],
|
|
16
|
+
['omega company', 'the company workspace: `init` scaffolds one, `adopt <brand>` stamps a brand into it'],
|
|
17
|
+
['omega test', "run every target's test suites"],
|
|
18
|
+
['omega build', 'build every target, backend first'],
|
|
19
|
+
['omega clean', "wipe every target's build output"],
|
|
20
|
+
['omega update', 'dependency-freshness fan-out over the targets'],
|
|
21
|
+
['omega migrate', 'delete retired keys from config/omega.json5 (comments preserved)'],
|
|
22
|
+
['omega pipeline', 'the live full-cycle test: manage โ deploy โ verify'],
|
|
23
|
+
['omega devlog', "the manager's own development log"],
|
|
24
|
+
['omega version', 'print the installed version'],
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
module.exports = async () => {
|
|
28
|
+
const pad = Math.max(...VERBS.map(([verb]) => verb.length));
|
|
29
|
+
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log(chalk.bold('OMEGA โ brand orchestration'));
|
|
32
|
+
console.log(chalk.dim('Usage: omega <command> [options] (`omg` and `mgr` are the same bin)'));
|
|
33
|
+
console.log('');
|
|
34
|
+
for (const [verb, what] of VERBS) {
|
|
35
|
+
console.log(` ${chalk.cyan(verb.padEnd(pad))} ${what}`);
|
|
36
|
+
}
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(chalk.dim(' Common options: --service=<name>, --dry-run, --continue-on-error, --strict'));
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(chalk.bold('New here?'));
|
|
41
|
+
console.log(` ${chalk.dim('1.')} ${chalk.cyan('npx omega onboard')} ${chalk.dim('โ scaffold a brand (skip if you already have one)')}`);
|
|
42
|
+
console.log(` ${chalk.dim('2.')} ${chalk.cyan('npm install')} ${chalk.dim('โ every target gets its framework; the verbs scaffold on first run')}`);
|
|
43
|
+
console.log(` ${chalk.dim('3.')} ${chalk.cyan('npm run manage')} ${chalk.dim('โ reconcile everything; it says what it still needs')}`);
|
|
44
|
+
console.log(` ${chalk.dim('4.')} ${chalk.cyan('npm start')} ${chalk.dim('โ boot the local stack and build')}`);
|
|
45
|
+
console.log('');
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
module.exports.VERBS = VERBS;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omega-manager manage` โ context-sensitive on where it runs:
|
|
3
|
+
* inside a brand monorepo โ run every service (or --service=<name>)
|
|
4
|
+
* against that brand
|
|
5
|
+
* inside a company workspace โ run the same per-brand manage for every
|
|
6
|
+
* discovered brand (--brand=<id[,id]> filters,
|
|
7
|
+
* --parallel runs children concurrently)
|
|
8
|
+
*
|
|
9
|
+
* Sets process.exitCode = 1 when any service errored so CI and scripts can
|
|
10
|
+
* gate on it.
|
|
11
|
+
*/
|
|
12
|
+
const path = require('node:path');
|
|
13
|
+
const attachLogFile = require('../vendor/devkit/attach-log-file.js');
|
|
14
|
+
const { runManage } = require('../manage.js');
|
|
15
|
+
const { runCompany } = require('../company.js');
|
|
16
|
+
const { resolveManageRoot, filterChildArgs } = require('../lib/company.js');
|
|
17
|
+
|
|
18
|
+
module.exports = async (options) => {
|
|
19
|
+
const resolved = resolveManageRoot(process.cwd());
|
|
20
|
+
|
|
21
|
+
// Tee the whole fan-out to <brandRoot>/logs/manage.log (#197) โ one greppable
|
|
22
|
+
// record of the service walk. Outside a brand the verb errors out anyway, so
|
|
23
|
+
// cwd is the honest fallback.
|
|
24
|
+
attachLogFile(path.join(resolved?.root || process.cwd(), 'logs', 'manage.log'));
|
|
25
|
+
|
|
26
|
+
let report;
|
|
27
|
+
if (resolved?.isCompany) {
|
|
28
|
+
// Children get the user's argv minus the company-only flags
|
|
29
|
+
report = await runCompany(resolved.root, {
|
|
30
|
+
brand: options.brand,
|
|
31
|
+
parallel: options.parallel,
|
|
32
|
+
concurrency: options.concurrency,
|
|
33
|
+
}, filterChildArgs(process.argv.slice(2)));
|
|
34
|
+
} else {
|
|
35
|
+
report = await runManage(process.cwd(), {
|
|
36
|
+
service: options.service,
|
|
37
|
+
continueOnError: options.continueOnError,
|
|
38
|
+
dryRun: options.dryRun,
|
|
39
|
+
strict: options.strict,
|
|
40
|
+
verbose: options.verbose,
|
|
41
|
+
migration: options.migration,
|
|
42
|
+
execute: options.execute,
|
|
43
|
+
limit: options.limit,
|
|
44
|
+
ids: options.ids,
|
|
45
|
+
resetAssets: options.resetAssets,
|
|
46
|
+
force: options.force,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (report.hasErrors) {
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omega migrate` at a brand root โ bring an already-converted omega.json5
|
|
3
|
+
* forward: delete every key `@omega.js/config`'s retired-keys table names,
|
|
4
|
+
* in place, comments and formatting preserved.
|
|
5
|
+
*
|
|
6
|
+
* omega migrate โ remove the retired keys, one line each
|
|
7
|
+
* omega migrate --dry-run โ print the same plan and write nothing
|
|
8
|
+
*
|
|
9
|
+
* There is no dual-read anywhere in OMEGA, so a retired key is a setting the
|
|
10
|
+
* brand still believes in and nothing reads โ the validator says so loudly on
|
|
11
|
+
* every load. The UJMโomega converter drops them on its way through
|
|
12
|
+
* (@omega.js/web's `omega migrate`), but a brand ALREADY on omega.json5 had
|
|
13
|
+
* only that error and an edit by hand. Editing an AUTHORED omega.json5 is the
|
|
14
|
+
* manager's lane (#612), so the rule lives here.
|
|
15
|
+
*
|
|
16
|
+
* The file is read raw (JSON5, no merge): the retired key must be deleted
|
|
17
|
+
* where the brand WROTE it, and a merged view would name paths that exist in
|
|
18
|
+
* no file. Idempotent by construction โ a key that isn't there is skipped, so
|
|
19
|
+
* a converged brand's rerun leaves the file byte-identical.
|
|
20
|
+
*/
|
|
21
|
+
const fs = require('node:fs');
|
|
22
|
+
const chalk = require('chalk').default;
|
|
23
|
+
const JSON5 = require('json5');
|
|
24
|
+
|
|
25
|
+
const { findRetiredKeys, resolveConfigPath, removeConfigValues } = require('../vendor/config/index.js');
|
|
26
|
+
const { resolveBrandRoot } = require('../lib/brand.js');
|
|
27
|
+
|
|
28
|
+
module.exports = async (options = {}) => {
|
|
29
|
+
const brandRoot = resolveBrandRoot(process.cwd());
|
|
30
|
+
if (!brandRoot) {
|
|
31
|
+
console.error(chalk.red('โ Not inside a brand monorepo (no config/omega.json5 up the tree) โ run `omega migrate` at the brand root.'));
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const configPath = resolveConfigPath(brandRoot);
|
|
37
|
+
let authored;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
authored = JSON5.parse(fs.readFileSync(configPath, 'utf8'));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error(chalk.red(`โ ${configPath} does not parse โ fix the syntax first: ${e.message}`));
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// One finding per key, in file order. The table can name the same path
|
|
48
|
+
// twice (a key that is both a retired NAME and a retired PATH); the file
|
|
49
|
+
// has one property to delete either way.
|
|
50
|
+
const findings = [];
|
|
51
|
+
for (const finding of findRetiredKeys(authored)) {
|
|
52
|
+
if (!findings.some((seen) => seen.path === finding.path)) findings.push(finding);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const dryRun = !!(options['dry-run'] || options.dryRun);
|
|
56
|
+
|
|
57
|
+
console.log(chalk.bold(`\nOMEGA migrate โ ${configPath}`));
|
|
58
|
+
|
|
59
|
+
if (findings.length === 0) {
|
|
60
|
+
console.log(` ${chalk.green('โ')} no retired keys โ this config is current`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const report = removeConfigValues(brandRoot, findings.map((finding) => finding.path), { dryRun });
|
|
65
|
+
|
|
66
|
+
for (const finding of findings) {
|
|
67
|
+
const verb = dryRun ? chalk.dim('โ would remove') : `${chalk.green('โ')} removed`;
|
|
68
|
+
console.log(` ${verb} ${chalk.cyan(finding.path)} ${chalk.dim(`โ ${finding.replacement}`)}`);
|
|
69
|
+
console.log(` ${chalk.dim(finding.why)}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const count = report.removed.length;
|
|
73
|
+
console.log(dryRun
|
|
74
|
+
? chalk.dim(`\n ${count} retired key${count === 1 ? '' : 's'} would be removed โ nothing written (dry run)`)
|
|
75
|
+
: chalk.dim(`\n ${count} retired key${count === 1 ? '' : 's'} removed โ move each setting to the block named above`));
|
|
76
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omega-manager onboard [id]` โ create (or converge) a brand monorepo.
|
|
3
|
+
*
|
|
4
|
+
* Flags: --id/--name/--url/--description/--tagline/--contactName (plus the
|
|
5
|
+
* optional --contactImage/--contactUrl)/--targets=web,backend pre-answer the
|
|
6
|
+
* wizard (prompts only fill the gaps in a TTY; non-interactive runs derive
|
|
7
|
+
* the rest from the id โ the contact person is never derived). --dry-run
|
|
8
|
+
* prints the file plan without writing or prompting; --manage/--no-manage
|
|
9
|
+
* forces the manage handoff instead of asking.
|
|
10
|
+
*/
|
|
11
|
+
const { runOnboard } = require('../onboard.js');
|
|
12
|
+
|
|
13
|
+
module.exports = async (options) => {
|
|
14
|
+
const report = await runOnboard(process.cwd(), {
|
|
15
|
+
id: options.id ?? options._?.[1],
|
|
16
|
+
name: options.name,
|
|
17
|
+
url: options.url,
|
|
18
|
+
description: options.description,
|
|
19
|
+
tagline: options.tagline,
|
|
20
|
+
contactName: options.contactName,
|
|
21
|
+
contactImage: options.contactImage,
|
|
22
|
+
contactUrl: options.contactUrl,
|
|
23
|
+
targets: options.targets,
|
|
24
|
+
dryRun: options.dryRun,
|
|
25
|
+
manage: options.manage,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (!report.valid || (report.manageExitCode != null && report.manageExitCode !== 0)) {
|
|
29
|
+
process.exitCode = 1;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `omega-manager pipeline` โ the brand's full-pipeline LIVE test (Ian:
|
|
3
|
+
* "automate running the manager CLI as the test โ the playground exists
|
|
4
|
+
* to shit-test the full pipeline").
|
|
5
|
+
*
|
|
6
|
+
* Spawns the REAL manage cycle with stdin detached, so no prompt can ever
|
|
7
|
+
* fire (isInteractive() reads stdin's TTY) โ every answer must already be
|
|
8
|
+
* seeded in its non-interactive home: omega.json5 (choices), the brand
|
|
9
|
+
* .env (secrets), the Google token cache (scopes), state (latches). Then
|
|
10
|
+
* asserts the machine-readable run record (.omega/runs/{ts}.json):
|
|
11
|
+
*
|
|
12
|
+
* - Any service at status "error" fails the pipeline.
|
|
13
|
+
* - CORE services (workspace, repo, edge, domain, firebase,
|
|
14
|
+
* testing) must RUN green (success/warned) โ a core skip means a
|
|
15
|
+
* broken seed (missing token, unconfigured section) and fails.
|
|
16
|
+
* - Everything else may succeed, warn, or skip; skips are listed with
|
|
17
|
+
* reasons for visibility, not failure.
|
|
18
|
+
* - `--require=a,b` promotes more services into the core set (tighten as
|
|
19
|
+
* seeds land: --require=sendgrid,account,captcha).
|
|
20
|
+
* - `--service=<name>` narrows the child run to one service; the
|
|
21
|
+
* core-presence check only applies to full runs.
|
|
22
|
+
* - `--dry-run` forwards to the child (plan-only pass, still asserted).
|
|
23
|
+
* - `--deploy=web,backend,desktop,extension` runs the DEPLOY legs after
|
|
24
|
+
* the service cycle (web = `omega deploy --direct` gh-pages push;
|
|
25
|
+
* backend = a REAL functions deploy). Off by default; each leg lands in
|
|
26
|
+
* the scorecard as `deploy:<target>` and an exit-nonzero leg fails the
|
|
27
|
+
* pipeline. desktop/extension are PUBLISH legs (GH release flow / store
|
|
28
|
+
* CI dispatch โ both Ian-gated): without `--publish` they record as a
|
|
29
|
+
* gated skip instead of running.
|
|
30
|
+
* - After the deploy legs, the VERIFY sweep runs automatically for whatever
|
|
31
|
+
* was deployed (web โ site + domain + cloudflare), landing as
|
|
32
|
+
* `verify:<name>` rows โ a failed check fails the run exactly like a
|
|
33
|
+
* failed deploy leg. `--verify` alone runs the sweep without deploying
|
|
34
|
+
* (the post-hoc "is it still up?" pass); a dry run, a demo-* brand, and a
|
|
35
|
+
* brand with no cloud project all record gated skips and never touch the
|
|
36
|
+
* network (lib/verify-live.js).
|
|
37
|
+
*
|
|
38
|
+
* This spends real API calls and reconciles real infrastructure โ run it
|
|
39
|
+
* on demand, SPARINGLY. It is deliberately NOT part of `npm test` or CI.
|
|
40
|
+
*/
|
|
41
|
+
const fs = require('node:fs');
|
|
42
|
+
const path = require('node:path');
|
|
43
|
+
const { spawn } = require('node:child_process');
|
|
44
|
+
const chalk = require('chalk').default;
|
|
45
|
+
const attachLogFile = require('../vendor/devkit/attach-log-file.js');
|
|
46
|
+
|
|
47
|
+
const { resolveBrandRoot, loadBrand, discoverTargets } = require('../lib/brand.js');
|
|
48
|
+
const { runVerifyLegs, VERIFY_LEGS } = require('../lib/verify-live.js');
|
|
49
|
+
|
|
50
|
+
// deploy target โ the command run in that target's dir (desktop/
|
|
51
|
+
// extension targets carry no deploy script โ their D13 verb is the local bin)
|
|
52
|
+
const DEPLOY_LEGS = {
|
|
53
|
+
web: ['npm', 'run', 'deploy', '--', '--direct'],
|
|
54
|
+
backend: ['npm', 'run', 'deploy'],
|
|
55
|
+
desktop: ['npx', 'omega', 'deploy'],
|
|
56
|
+
extension: ['npx', 'omega', 'deploy'],
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Legs that PUBLISH (desktop โ the GH release flow, extension โ the store
|
|
60
|
+
// CI workflow dispatch). Releases and Actions dispatches are Ian-gated, so
|
|
61
|
+
// these run only with the explicit `--publish` flag โ otherwise the leg
|
|
62
|
+
// records a gated skip.
|
|
63
|
+
const PUBLISH_LEGS = new Set(['desktop', 'extension']);
|
|
64
|
+
|
|
65
|
+
// Services that must RUN green on a full pipeline pass โ these are the
|
|
66
|
+
// provisioning spine; a skip here means a seed is missing, not a choice.
|
|
67
|
+
// search/campaigns/account/captcha graduated into the spine once
|
|
68
|
+
// their seeds converged (cp116โ120): a skip there is a regression now.
|
|
69
|
+
const CORE_SERVICES = [
|
|
70
|
+
'workspace', 'repo', 'edge', 'domain', 'cloud', 'testing',
|
|
71
|
+
'search', 'campaigns', 'account', 'captcha',
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const STATUS_ICONS = { success: chalk.green('โ'), warned: chalk.yellow('โ '), skipped: chalk.dim('โ'), error: chalk.red('โ') };
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Which targets the verify sweep covers: whatever was just deployed, or โ
|
|
78
|
+
* with `--verify` and no deploy โ every target that HAS a live surface (the
|
|
79
|
+
* post-hoc "is it still up?" check).
|
|
80
|
+
*
|
|
81
|
+
* @param {object} argv - Parsed CLI args.
|
|
82
|
+
* @param {string[]} deployTargets - Targets whose deploy legs just ran.
|
|
83
|
+
* @returns {string[]}
|
|
84
|
+
*/
|
|
85
|
+
function resolveVerifyTargets(argv, deployTargets) {
|
|
86
|
+
if (deployTargets.length > 0) {
|
|
87
|
+
return deployTargets;
|
|
88
|
+
}
|
|
89
|
+
return argv.verify ? Object.keys(VERIFY_LEGS) : [];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Judge one run record against the pipeline policy.
|
|
94
|
+
*
|
|
95
|
+
* @param {object} runRecord - Parsed .omega/runs/{ts}.json ({ services: [{ service, status, reason?, error? }] }).
|
|
96
|
+
* @param {object} [options] - { require: string[] (extra core services), scoped: boolean (single-service child run) }.
|
|
97
|
+
* @returns {{ pass: boolean, failures: string[], skips: string[], rows: object[] }}
|
|
98
|
+
*/
|
|
99
|
+
function evaluatePipeline(runRecord, options = {}) {
|
|
100
|
+
const services = runRecord?.services || [];
|
|
101
|
+
const core = new Set([...CORE_SERVICES, ...(options.require || [])]);
|
|
102
|
+
const failures = [];
|
|
103
|
+
const skips = [];
|
|
104
|
+
const rows = [];
|
|
105
|
+
|
|
106
|
+
const byName = new Map(services.map((entry) => [entry.service, entry]));
|
|
107
|
+
|
|
108
|
+
for (const entry of services) {
|
|
109
|
+
rows.push(entry);
|
|
110
|
+
|
|
111
|
+
if (entry.status === 'error') {
|
|
112
|
+
failures.push(`${entry.service}: error${entry.error ? ` โ ${entry.error}` : ''}`);
|
|
113
|
+
} else if (entry.status === 'skipped') {
|
|
114
|
+
if (core.has(entry.service)) {
|
|
115
|
+
failures.push(`${entry.service}: CORE service skipped${entry.reason ? ` โ ${entry.reason}` : ''} (seed missing)`);
|
|
116
|
+
} else {
|
|
117
|
+
skips.push(`${entry.service}${entry.reason ? ` โ ${entry.reason}` : ''}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Full runs must actually contain every core service
|
|
123
|
+
if (!options.scoped) {
|
|
124
|
+
for (const name of core) {
|
|
125
|
+
if (!byName.has(name)) {
|
|
126
|
+
failures.push(`${name}: CORE service missing from the run record`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return { pass: failures.length === 0, failures, skips, rows };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Newest run record written at/after `since` for the brand.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} brandRoot - Brand root directory.
|
|
138
|
+
* @param {number} since - ms timestamp; records older than this are ignored.
|
|
139
|
+
* @returns {{ file: string, record: object }|null}
|
|
140
|
+
*/
|
|
141
|
+
function findRunRecord(brandRoot, since) {
|
|
142
|
+
const runsDir = path.join(brandRoot, '.omega', 'runs');
|
|
143
|
+
if (!fs.existsSync(runsDir)) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const candidates = fs.readdirSync(runsDir)
|
|
148
|
+
.filter((name) => name.endsWith('.json'))
|
|
149
|
+
.map((name) => ({ name, mtime: fs.statSync(path.join(runsDir, name)).mtimeMs }))
|
|
150
|
+
.filter((entry) => entry.mtime >= since)
|
|
151
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
152
|
+
|
|
153
|
+
if (candidates.length === 0) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const file = path.join(runsDir, candidates[0].name);
|
|
158
|
+
return { file, record: JSON.parse(fs.readFileSync(file, 'utf8')) };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The manage child's argv: the VERB first (#229 โ a bare CLI prints help and
|
|
163
|
+
* walks nothing, which would leave the pipeline with no run record), then the
|
|
164
|
+
* run flags the pipeline always imposes.
|
|
165
|
+
*
|
|
166
|
+
* @param {object} [argv] - The pipeline's own options.
|
|
167
|
+
* @returns {string[]} The child invocation's arguments.
|
|
168
|
+
*/
|
|
169
|
+
function buildChildArgs(argv = {}) {
|
|
170
|
+
const args = ['manage', '--continue-on-error'];
|
|
171
|
+
|
|
172
|
+
if (argv.service) {
|
|
173
|
+
args.push(`--service=${argv.service}`);
|
|
174
|
+
}
|
|
175
|
+
if (argv.dryRun || argv['dry-run']) {
|
|
176
|
+
args.push('--dry-run');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return args;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = async (argv = {}) => {
|
|
183
|
+
const brandRoot = resolveBrandRoot(process.cwd());
|
|
184
|
+
if (!brandRoot) {
|
|
185
|
+
console.error(chalk.red('โ Not inside a brand (no config/omega.json5 found walking up)'));
|
|
186
|
+
process.exitCode = 1;
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Tee the run to <brandRoot>/logs/pipeline.log (#623) โ the scorecard is the
|
|
191
|
+
// verdict worth keeping; the children spawn with stdio inherit, so each leg's
|
|
192
|
+
// own output stays in its own log.
|
|
193
|
+
attachLogFile(path.join(brandRoot, 'logs', 'pipeline.log'));
|
|
194
|
+
|
|
195
|
+
const requireExtra = String(argv.require || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
196
|
+
const childArgs = buildChildArgs(argv);
|
|
197
|
+
|
|
198
|
+
console.log(chalk.bold('\n๐งช Pipeline โ live full-cycle test (non-interactive by construction)\n'));
|
|
199
|
+
console.log(` Brand: ${chalk.cyan(brandRoot)}`);
|
|
200
|
+
console.log(` Child: omega ${childArgs.join(' ')}`);
|
|
201
|
+
console.log(` Core: ${[...CORE_SERVICES, ...requireExtra].join(', ')}\n`);
|
|
202
|
+
|
|
203
|
+
const started = Date.now();
|
|
204
|
+
// cli-run.js self-executes when spawned as main โ spawning it directly
|
|
205
|
+
// deliberately bypasses the bin's dispatcher (#276): this child must run
|
|
206
|
+
// THIS manager, never re-dispatch on the child's cwd.
|
|
207
|
+
const bin = path.join(__dirname, '..', 'cli-run.js');
|
|
208
|
+
|
|
209
|
+
// Non-interactive by construction: stdin detached AND the explicit env
|
|
210
|
+
// switch (google-auth counts stdout-TTY as a watching human โ the env
|
|
211
|
+
// beats it, so consent flows fail fast instead of opening browsers).
|
|
212
|
+
const exitCode = await new Promise((resolve) => {
|
|
213
|
+
const child = spawn(process.execPath, [bin, ...childArgs], {
|
|
214
|
+
cwd: brandRoot,
|
|
215
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
216
|
+
env: { ...process.env, OMEGA_NON_INTERACTIVE: '1' },
|
|
217
|
+
});
|
|
218
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const found = findRunRecord(brandRoot, started);
|
|
222
|
+
if (!found) {
|
|
223
|
+
console.error(chalk.red(`\nโ PIPELINE FAIL โ no run record appeared in .omega/runs/ (child exit ${exitCode})`));
|
|
224
|
+
process.exitCode = 1;
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Deploy legs โ spawned in the owning target's dir, same non-interactive
|
|
229
|
+
// construction; results join the record as deploy:<target> rows so the
|
|
230
|
+
// evaluator's any-error rule covers them
|
|
231
|
+
const deployTargets = String(argv.deploy || '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
232
|
+
for (const target of deployTargets) {
|
|
233
|
+
const leg = DEPLOY_LEGS[target];
|
|
234
|
+
const entry = discoverTargets(brandRoot).find((item) => item.target === target);
|
|
235
|
+
|
|
236
|
+
if (!leg || !entry) {
|
|
237
|
+
found.record.services.push({
|
|
238
|
+
service: `deploy:${target}`,
|
|
239
|
+
status: 'error',
|
|
240
|
+
output: null,
|
|
241
|
+
error: leg ? `no ${target} dir in this brand` : `unknown deploy target (${Object.keys(DEPLOY_LEGS).join(', ')})`,
|
|
242
|
+
});
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Publish legs stay behind their own flag: running them means a GH
|
|
247
|
+
// release / store CI dispatch, and both are gated until Ian opens them.
|
|
248
|
+
if (PUBLISH_LEGS.has(target) && !argv.publish) {
|
|
249
|
+
console.log(chalk.yellow(`\nโ Deploy leg ${target}: publish leg gated โ pass --publish to run it (releases/dispatches are gated)`));
|
|
250
|
+
found.record.services.push({
|
|
251
|
+
service: `deploy:${target}`,
|
|
252
|
+
status: 'skipped',
|
|
253
|
+
output: null,
|
|
254
|
+
error: null,
|
|
255
|
+
reason: 'publish leg gated โ pass --publish (releases/dispatches are gated)',
|
|
256
|
+
});
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log(chalk.bold(`\n๐งช Deploy leg: ${target} ${chalk.dim(`(${leg.join(' ')} in ${entry.dir})`)}`));
|
|
261
|
+
const legExit = await new Promise((resolve) => {
|
|
262
|
+
const child = spawn(leg[0], leg.slice(1), {
|
|
263
|
+
cwd: entry.path,
|
|
264
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
265
|
+
env: { ...process.env, OMEGA_NON_INTERACTIVE: '1' },
|
|
266
|
+
});
|
|
267
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
found.record.services.push({
|
|
271
|
+
service: `deploy:${target}`,
|
|
272
|
+
status: legExit === 0 ? 'success' : 'error',
|
|
273
|
+
output: null,
|
|
274
|
+
error: legExit === 0 ? null : `exit ${legExit}`,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Verify sweep โ the last mile: the deploy legs pushed, these prove the
|
|
279
|
+
// launch surface answers. Rows join the record as verify:<name> so a
|
|
280
|
+
// failed check fails the pipeline exactly like a failed deploy leg.
|
|
281
|
+
const verifyTargets = resolveVerifyTargets(argv, deployTargets).filter((target) => VERIFY_LEGS[target]);
|
|
282
|
+
if (verifyTargets.length > 0) {
|
|
283
|
+
const dryRun = Boolean(argv.dryRun || argv['dry-run']);
|
|
284
|
+
console.log(chalk.bold(`\n๐งช Verify sweep: ${verifyTargets.join(', ')}${dryRun ? chalk.dim(' (dry run โ plan only)') : ''}`));
|
|
285
|
+
found.record.services.push(...await runVerifyLegs(verifyTargets, loadBrand(brandRoot).config, {}, { dryRun }));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const verdict = evaluatePipeline(found.record, { require: requireExtra, scoped: Boolean(argv.service) });
|
|
289
|
+
|
|
290
|
+
console.log(chalk.bold('\n๐งช Pipeline scorecard'));
|
|
291
|
+
console.log(` ${chalk.dim(`record: ${path.basename(found.file)}`)}`);
|
|
292
|
+
for (const row of verdict.rows) {
|
|
293
|
+
const icon = STATUS_ICONS[row.status] || chalk.dim('ยท');
|
|
294
|
+
console.log(` ${icon} ${row.service}${row.status === 'skipped' && row.reason ? chalk.dim(` โ ${row.reason}`) : ''}`);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (verdict.skips.length > 0) {
|
|
298
|
+
console.log(`\n ${chalk.dim(`โ acceptable skips: ${verdict.skips.length} (listed above)`)}`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (verdict.pass) {
|
|
302
|
+
console.log(chalk.green.bold('\nโ
PIPELINE PASS\n'));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
console.log(chalk.red.bold('\nโ PIPELINE FAIL'));
|
|
307
|
+
for (const failure of verdict.failures) {
|
|
308
|
+
console.log(` ${chalk.red('โ')} ${failure}`);
|
|
309
|
+
}
|
|
310
|
+
console.log('');
|
|
311
|
+
process.exitCode = 1;
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
module.exports.evaluatePipeline = evaluatePipeline;
|
|
315
|
+
module.exports.findRunRecord = findRunRecord;
|
|
316
|
+
module.exports.resolveVerifyTargets = resolveVerifyTargets;
|
|
317
|
+
module.exports.buildChildArgs = buildChildArgs;
|
|
318
|
+
module.exports.CORE_SERVICES = CORE_SERVICES;
|
|
319
|
+
module.exports.PUBLISH_LEGS = PUBLISH_LEGS;
|