@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,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-mode gates — the standard "may this step do X?" checks and the
|
|
3
|
+
* standard step-asides when it can't.
|
|
4
|
+
*
|
|
5
|
+
* Three primitives every ensure-handler shares:
|
|
6
|
+
* - canPrompt(options) — interactive TTY and not a dry run: the only two
|
|
7
|
+
* conditions that ever gate a prompt. Use it instead of hand-composing
|
|
8
|
+
* isInteractive() with options.dryRun (three spellings of that compound
|
|
9
|
+
* had drifted into the tree before this module existed).
|
|
10
|
+
* - dryRunPlan(message, result) — the canonical dry-run line
|
|
11
|
+
* (`⊘ Dry run — would <message>`) with an optional pass-through return,
|
|
12
|
+
* so the modal gate is one statement:
|
|
13
|
+
* `if (options.dryRun) return dryRunPlan('create it', { output: … });`
|
|
14
|
+
* Loop bodies call it bare and continue.
|
|
15
|
+
* - needsInteractiveSkip(key, action, note) — the warned step-aside return
|
|
16
|
+
* carrying the #32 `needsInteractive` marker that the run summary
|
|
17
|
+
* aggregates into its ⚑ section with a per-service rerun hint.
|
|
18
|
+
*/
|
|
19
|
+
const chalk = require('chalk').default;
|
|
20
|
+
const { isInteractive } = require('../vendor/devkit/prompt.js');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Whether a step may prompt: the input stream is a TTY and this is not a
|
|
24
|
+
* dry run.
|
|
25
|
+
*
|
|
26
|
+
* @param {object} [options] - The run options (may carry `dryRun`).
|
|
27
|
+
* @returns {boolean} True when prompts are allowed.
|
|
28
|
+
*/
|
|
29
|
+
function canPrompt(options) {
|
|
30
|
+
return isInteractive() && !options?.dryRun;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Print the canonical dry-run line and pass `result` back so the modal
|
|
35
|
+
* gate reads `return dryRunPlan('create 3 records', { output: … })`.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} message - What the real run would do ("create list …").
|
|
38
|
+
* @param {*} [result] - Returned verbatim (a handler return, usually).
|
|
39
|
+
* @returns {*} The `result` argument.
|
|
40
|
+
*/
|
|
41
|
+
function dryRunPlan(message, result) {
|
|
42
|
+
console.log(` ${chalk.dim(`⊘ Dry run — would ${message}`)}`);
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The standard warned return for a step that needs a TTY (#32): `action`
|
|
48
|
+
* states what an interactive run would do — the run summary collects it
|
|
49
|
+
* into the ⚑ "needs an interactive run" section, and the `reason` names the
|
|
50
|
+
* step-aside in the summary's warned breakdown (#643).
|
|
51
|
+
*
|
|
52
|
+
* @param {string} key - The operation's output key (e.g. 'cloudMessaging').
|
|
53
|
+
* @param {string} action - What an interactive run would do.
|
|
54
|
+
* @param {string} [note] - Optional per-operation output note.
|
|
55
|
+
* @returns {object} A `{ status: 'warned', reason, output }` handler return.
|
|
56
|
+
*/
|
|
57
|
+
function needsInteractiveSkip(key, action, note) {
|
|
58
|
+
return {
|
|
59
|
+
status: 'warned',
|
|
60
|
+
reason: 'needs an interactive run',
|
|
61
|
+
output: {
|
|
62
|
+
[key]: {
|
|
63
|
+
...(note ? { note } : {}),
|
|
64
|
+
needsInteractive: action,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = { canPrompt, dryRunPlan, needsInteractiveSkip };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-run output — the ONLY thing a manage run writes into `.omega/`:
|
|
3
|
+
*
|
|
4
|
+
* config/omega.json5 → every provisioned fact (ids, slugs, zones,
|
|
5
|
+
* confirmation flags), comment-preserving
|
|
6
|
+
* .env → every secret the run resolves (never config —
|
|
7
|
+
* the loader hard-fails secret-shaped keys)
|
|
8
|
+
* .omega/runs/{ts}.json → this run's transient output (counts, status
|
|
9
|
+
* flags, errors), for post-mortem debugging
|
|
10
|
+
*
|
|
11
|
+
* The old third bucket — the durable cache of derived data `.omega/state.json`
|
|
12
|
+
* carried — is RETIRED ([#434](https://github.com/Omega-JS-Stack/omega/issues/434)):
|
|
13
|
+
* every fact it held either re-derives from the platform on each idempotent
|
|
14
|
+
* ensure, or has an authoritative home in config/.env. The FILE lives on as
|
|
15
|
+
* the per-machine RECORD home ([#479](https://github.com/Omega-JS-Stack/omega/issues/479))
|
|
16
|
+
* — deploy stamps under its `deploy` section, written by
|
|
17
|
+
* `@omega.js/devkit/deploy-record` and by nothing here. `.omega/` is
|
|
18
|
+
* gitignored (the workspace service ensures the entry).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const { join } = require('node:path');
|
|
22
|
+
const jetpack = require('fs-jetpack');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Persist one run's transient output to .omega/runs/{timestamp}.json —
|
|
26
|
+
* failures, counts, and per-service flags for post-mortem debugging.
|
|
27
|
+
*
|
|
28
|
+
* @param {string} brandRoot - Brand-monorepo root
|
|
29
|
+
* @param {string} runTimestamp - Filesystem-safe ISO timestamp for this process
|
|
30
|
+
* @param {string} brandId - Brand ID
|
|
31
|
+
* @param {Array<{ service, status, output, error }>} services - Per-service results
|
|
32
|
+
*/
|
|
33
|
+
function writeRunOutput(brandRoot, runTimestamp, brandId, services) {
|
|
34
|
+
const runFile = join(brandRoot, '.omega', 'runs', `${runTimestamp}.json`);
|
|
35
|
+
jetpack.write(runFile, {
|
|
36
|
+
timestamp: new Date().toISOString(),
|
|
37
|
+
brandId,
|
|
38
|
+
services,
|
|
39
|
+
}, { jsonIndent: 2 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = { writeRunOutput };
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run Summary — collects service results across all brands and prints a
|
|
3
|
+
* summary. Ported from omega-manager's src/lib/run-summary.js: same stats,
|
|
4
|
+
* per-brand breakdown, drilled-down details for update failures and testing
|
|
5
|
+
* warnings, and a copy-pasteable retry command.
|
|
6
|
+
*
|
|
7
|
+
* Created once in runManage(), accumulates across every service (and, in the
|
|
8
|
+
* future company mode, across brands). Always prints a summary at the end.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk').default;
|
|
12
|
+
|
|
13
|
+
const { formatDuration } = require('./duration.js');
|
|
14
|
+
const { stripLeadingVerb } = require('./argv.js');
|
|
15
|
+
|
|
16
|
+
class RunSummary {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.entries = [];
|
|
19
|
+
this.startTime = Date.now();
|
|
20
|
+
this.argv = process.argv.slice(2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Record a service result
|
|
25
|
+
*
|
|
26
|
+
* @param {string} brandId - Brand ID
|
|
27
|
+
* @param {string} brandName - Brand display name
|
|
28
|
+
* @param {string} serviceName - Service that ran
|
|
29
|
+
* @param {Object} result - Result from runService() { status, error?, output? }
|
|
30
|
+
*/
|
|
31
|
+
add(brandId, brandName, serviceName, result) {
|
|
32
|
+
this.entries.push({ brandId, brandName, serviceName, result });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if any service had errors
|
|
37
|
+
*/
|
|
38
|
+
hasErrors() {
|
|
39
|
+
return this.entries.some((entry) => this._isError(entry));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Print full summary (always)
|
|
44
|
+
*/
|
|
45
|
+
printSummary() {
|
|
46
|
+
const elapsed = formatDuration(Date.now() - this.startTime);
|
|
47
|
+
const hasErrors = this.hasErrors();
|
|
48
|
+
|
|
49
|
+
// Gather stats
|
|
50
|
+
const brandSet = new Set();
|
|
51
|
+
const serviceSet = new Set();
|
|
52
|
+
let successCount = 0;
|
|
53
|
+
let warnedCount = 0;
|
|
54
|
+
let errorCount = 0;
|
|
55
|
+
let skippedCount = 0;
|
|
56
|
+
|
|
57
|
+
for (const entry of this.entries) {
|
|
58
|
+
brandSet.add(entry.brandId);
|
|
59
|
+
serviceSet.add(entry.serviceName);
|
|
60
|
+
|
|
61
|
+
if (this._isError(entry)) {
|
|
62
|
+
errorCount++;
|
|
63
|
+
} else if (entry.result.status === 'skipped') {
|
|
64
|
+
skippedCount++;
|
|
65
|
+
} else if (entry.result.status === 'warned') {
|
|
66
|
+
warnedCount++;
|
|
67
|
+
} else {
|
|
68
|
+
successCount++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Header
|
|
73
|
+
const hasWarnings = warnedCount > 0;
|
|
74
|
+
const headerColor = hasErrors ? chalk.yellow : hasWarnings ? chalk.yellow : chalk.green;
|
|
75
|
+
const headerIcon = hasErrors ? '⚠' : hasWarnings ? '⚠' : '✅';
|
|
76
|
+
console.log('');
|
|
77
|
+
console.log(headerColor('━'.repeat(70)));
|
|
78
|
+
console.log(` ${headerColor.bold(`${headerIcon} Summary`)}`);
|
|
79
|
+
console.log(headerColor('━'.repeat(70)));
|
|
80
|
+
|
|
81
|
+
// Stats
|
|
82
|
+
console.log('');
|
|
83
|
+
console.log(` ${chalk.dim('Brands:')} ${brandSet.size}`);
|
|
84
|
+
console.log(` ${chalk.dim('Services:')} ${serviceSet.size}`);
|
|
85
|
+
console.log(` ${chalk.dim('Duration:')} ${elapsed}`);
|
|
86
|
+
const passedTotal = successCount + warnedCount;
|
|
87
|
+
const resultParts = [
|
|
88
|
+
chalk.green(`${passedTotal} passed`),
|
|
89
|
+
errorCount > 0 ? chalk.red(`, ${errorCount} failed`) : chalk.dim(', 0 failed'),
|
|
90
|
+
];
|
|
91
|
+
if (warnedCount > 0) {
|
|
92
|
+
resultParts.push(chalk.yellow(`, ${warnedCount} warned`));
|
|
93
|
+
}
|
|
94
|
+
if (skippedCount > 0) {
|
|
95
|
+
resultParts.push(chalk.dim(`, ${skippedCount} skipped`));
|
|
96
|
+
}
|
|
97
|
+
console.log(` ${chalk.dim('Results:')} ${resultParts.join('')}`);
|
|
98
|
+
|
|
99
|
+
// Per-brand breakdown
|
|
100
|
+
console.log('');
|
|
101
|
+
for (const brandId of brandSet) {
|
|
102
|
+
const brandEntries = this.entries.filter((e) => e.brandId === brandId);
|
|
103
|
+
const brandName = brandEntries[0].brandName;
|
|
104
|
+
const brandErrors = brandEntries.filter((e) => this._isError(e));
|
|
105
|
+
const brandWarnings = brandEntries.filter((e) => e.result.status === 'warned');
|
|
106
|
+
|
|
107
|
+
if (brandErrors.length > 0) {
|
|
108
|
+
console.log(` ${chalk.red('✗')} ${chalk.bold(brandName)}`);
|
|
109
|
+
|
|
110
|
+
for (const entry of brandErrors) {
|
|
111
|
+
const details = this._getErrorDetails(entry.serviceName, entry.result);
|
|
112
|
+
|
|
113
|
+
for (const detail of details) {
|
|
114
|
+
console.log(` ${detail}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
} else if (brandWarnings.length > 0) {
|
|
118
|
+
console.log(` ${chalk.yellow('⚠')} ${chalk.bold(brandName)}`);
|
|
119
|
+
|
|
120
|
+
for (const entry of brandWarnings) {
|
|
121
|
+
const details = this._getWarningDetails(entry.serviceName, entry.result);
|
|
122
|
+
|
|
123
|
+
for (const detail of details) {
|
|
124
|
+
console.log(` ${detail}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
console.log(` ${chalk.green('✓')} ${chalk.bold(brandName)}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Needs-interactive aggregate (#32): steps that stepped aside for lack
|
|
133
|
+
// of a TTY say so HERE, not just in scroll-back
|
|
134
|
+
const needsInteractive = this._getNeedsInteractive();
|
|
135
|
+
if (needsInteractive.length > 0) {
|
|
136
|
+
const multiBrand = brandSet.size > 1;
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(` ${chalk.yellow('⚑')} Skipped — needs an interactive run:`);
|
|
139
|
+
for (const item of needsInteractive) {
|
|
140
|
+
const prefix = multiBrand ? `${item.brandName} · ` : '';
|
|
141
|
+
console.log(` ${prefix}${chalk.bold(`${item.serviceName}/${item.operation}`)}: ${item.what}`);
|
|
142
|
+
}
|
|
143
|
+
for (const serviceName of [...new Set(needsInteractive.map((item) => item.serviceName))]) {
|
|
144
|
+
console.log(` ${chalk.dim(`→ npm run manage -- --service=${serviceName} (from the brand root)`)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Missing-secrets aggregate (cp114): services that skipped for lack of
|
|
149
|
+
// an env var name the exact keys HERE — and an interactive rerun asks
|
|
150
|
+
// for them and saves them to the brand .env
|
|
151
|
+
const missingEnv = this._getMissingEnv();
|
|
152
|
+
if (missingEnv.length > 0) {
|
|
153
|
+
const multiBrand = brandSet.size > 1;
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log(` ${chalk.yellow('🔑')} Missing secrets — add to the brand .env, or rerun interactively to paste them:`);
|
|
156
|
+
for (const item of missingEnv) {
|
|
157
|
+
const prefix = multiBrand ? `${item.brandName} · ` : '';
|
|
158
|
+
console.log(` ${prefix}${chalk.bold(item.serviceName)}: ${item.vars.join(', ')}`);
|
|
159
|
+
}
|
|
160
|
+
for (const serviceName of [...new Set(missingEnv.map((item) => item.serviceName))]) {
|
|
161
|
+
console.log(` ${chalk.dim(`→ npm run manage -- --service=${serviceName} (from the brand root)`)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Retry command
|
|
166
|
+
if (hasErrors) {
|
|
167
|
+
console.log('');
|
|
168
|
+
console.log(` ${chalk.red('✗')} Retry:`);
|
|
169
|
+
console.log(` ${chalk.dim(this._buildRetryCommand())}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log('');
|
|
173
|
+
console.log(headerColor('━'.repeat(70)));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Build a retry command from the original argv. `npm run manage` is the blessed
|
|
178
|
+
* form — npx can be rerouted by shell wrappers (npu) that pipe stdio and
|
|
179
|
+
* kill interactivity.
|
|
180
|
+
*/
|
|
181
|
+
_buildRetryCommand() {
|
|
182
|
+
// The `manage` script IS the verb (#229), so the leading subcommand must
|
|
183
|
+
// not ride along — `npm run manage -- manage --service=x` would run
|
|
184
|
+
// `omega manage manage`.
|
|
185
|
+
const args = stripLeadingVerb(this.argv).join(' ').trim();
|
|
186
|
+
return args ? `npm run manage -- ${args}` : 'npm run manage';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Collect missing-secret skips (cp114): service results carry
|
|
191
|
+
* `missingEnv: ['CLOUDFLARE_TOKEN', …]` when setup skipped for absent
|
|
192
|
+
* env vars (the setup contract, lib/service-input.js).
|
|
193
|
+
*/
|
|
194
|
+
_getMissingEnv() {
|
|
195
|
+
const items = [];
|
|
196
|
+
|
|
197
|
+
for (const entry of this.entries) {
|
|
198
|
+
const vars = entry.result?.missingEnv;
|
|
199
|
+
if (Array.isArray(vars) && vars.length > 0) {
|
|
200
|
+
items.push({
|
|
201
|
+
brandId: entry.brandId,
|
|
202
|
+
brandName: entry.brandName,
|
|
203
|
+
serviceName: entry.serviceName,
|
|
204
|
+
vars,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return items;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Collect needs-interactive markers (#32): any handler output sub-object
|
|
214
|
+
* may carry `needsInteractive: '<what an interactive run would do>'` —
|
|
215
|
+
* the convention for steps that step aside without a TTY.
|
|
216
|
+
*/
|
|
217
|
+
_getNeedsInteractive() {
|
|
218
|
+
const items = [];
|
|
219
|
+
|
|
220
|
+
for (const entry of this.entries) {
|
|
221
|
+
const output = entry.result?.output;
|
|
222
|
+
if (!output || typeof output !== 'object') {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
for (const [operation, data] of Object.entries(output)) {
|
|
227
|
+
if (data && typeof data === 'object' && typeof data.needsInteractive === 'string') {
|
|
228
|
+
items.push({
|
|
229
|
+
brandId: entry.brandId,
|
|
230
|
+
brandName: entry.brandName,
|
|
231
|
+
serviceName: entry.serviceName,
|
|
232
|
+
operation,
|
|
233
|
+
what: data.needsInteractive,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return items;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if an entry represents an error
|
|
244
|
+
*/
|
|
245
|
+
_isError(entry) {
|
|
246
|
+
const { result, serviceName } = entry;
|
|
247
|
+
|
|
248
|
+
// Explicit error status
|
|
249
|
+
if (result.status === 'error') {
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Update service: check for failed targets even when status is 'success'
|
|
254
|
+
if (serviceName === 'update' && result.output?.results) {
|
|
255
|
+
return this._hasFailedTargets(result.output.results);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Check if update results contain failed targets
|
|
263
|
+
*/
|
|
264
|
+
_hasFailedTargets(results) {
|
|
265
|
+
for (const target of Object.keys(results)) {
|
|
266
|
+
const steps = results[target].steps || [];
|
|
267
|
+
|
|
268
|
+
if (steps.some((s) => s.success === false)) {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get human-readable error details for a service result
|
|
278
|
+
*/
|
|
279
|
+
_getErrorDetails(serviceName, result) {
|
|
280
|
+
const details = [];
|
|
281
|
+
|
|
282
|
+
// Update service: show per-target, per-phase failures
|
|
283
|
+
if (serviceName === 'update' && result.output?.results) {
|
|
284
|
+
const failedTargets = this._getFailedTargets(result.output.results);
|
|
285
|
+
|
|
286
|
+
if (failedTargets.length > 0) {
|
|
287
|
+
details.push(`${chalk.red(serviceName)}:`);
|
|
288
|
+
|
|
289
|
+
for (const { target, phase, error } of failedTargets) {
|
|
290
|
+
const errorMsg = error ? chalk.dim(`: ${error}`) : '';
|
|
291
|
+
details.push(` ${chalk.bold(target)} → ${chalk.red(`${phase} failed`)}${errorMsg}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Also show top-level error if present
|
|
296
|
+
if (result.status === 'error' && result.error && failedTargets.length === 0) {
|
|
297
|
+
details.push(`${chalk.red(serviceName)}: ${result.error}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return details;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Testing service: show per-check failures. Stays ahead of the generic
|
|
304
|
+
// failed renderer below — the per-check messages live here, while the
|
|
305
|
+
// runner-level entry for the same run is names-only.
|
|
306
|
+
if (result.output?.results?.failed?.length) {
|
|
307
|
+
details.push(`${chalk.red(serviceName)}:`);
|
|
308
|
+
for (const { name, error } of result.output.results.failed) {
|
|
309
|
+
const msg = error ? chalk.dim(`: ${error}`) : '';
|
|
310
|
+
details.push(` ${chalk.bold(name)}${msg}`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return details;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Every recorded failed operation, by name (#643): the service runner
|
|
317
|
+
// records `{ operation, reason }` on `result.failed`, so a service that
|
|
318
|
+
// ran past its first failure names each one instead of collapsing into a
|
|
319
|
+
// single message.
|
|
320
|
+
if (result.failed?.length) {
|
|
321
|
+
details.push(`${chalk.red(serviceName)}:`);
|
|
322
|
+
for (const { operation, reason } of result.failed) {
|
|
323
|
+
const msg = reason ? chalk.dim(`: ${reason}`) : '';
|
|
324
|
+
details.push(` ${chalk.bold(operation)}${msg}`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return details;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Generic service error
|
|
331
|
+
details.push(`${chalk.red(serviceName)}: ${result.error || 'failed'}`);
|
|
332
|
+
return details;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Get human-readable warning details for a service result
|
|
337
|
+
*
|
|
338
|
+
* ONE generic renderer (#643): the service runner records every warned
|
|
339
|
+
* operation as `{ operation, reason }` on `result.warned`, so the breakdown
|
|
340
|
+
* names what warned and why — no per-service special cases, and no service
|
|
341
|
+
* left saying "some operations had issues".
|
|
342
|
+
*/
|
|
343
|
+
_getWarningDetails(serviceName, result) {
|
|
344
|
+
const details = [];
|
|
345
|
+
|
|
346
|
+
if (result.warned?.length) {
|
|
347
|
+
details.push(`${chalk.yellow(serviceName)}:`);
|
|
348
|
+
for (const { operation, reason } of result.warned) {
|
|
349
|
+
const msg = reason ? chalk.dim(`: ${reason}`) : '';
|
|
350
|
+
details.push(` ${chalk.bold(operation)}${msg}`);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return details;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
details.push(`${chalk.yellow(serviceName)}: some operations had issues`);
|
|
357
|
+
return details;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Extract failed targets from update results
|
|
362
|
+
*/
|
|
363
|
+
_getFailedTargets(results) {
|
|
364
|
+
const failed = [];
|
|
365
|
+
|
|
366
|
+
for (const [target, targetResult] of Object.entries(results)) {
|
|
367
|
+
const steps = targetResult.steps || [];
|
|
368
|
+
|
|
369
|
+
for (const step of steps) {
|
|
370
|
+
if (step.success === false) {
|
|
371
|
+
failed.push({
|
|
372
|
+
target,
|
|
373
|
+
phase: step.phase || 'unknown',
|
|
374
|
+
error: step.error || null,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return failed;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
module.exports = { RunSummary };
|