@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,291 @@
|
|
|
1
|
+
# Translation
|
|
2
|
+
|
|
3
|
+
AI translation for OMEGA consumers — one engine, config-driven, with a
|
|
4
|
+
**committed** per-string cache. Shipped cp96 (Ian directive 2026-07-11),
|
|
5
|
+
replacing both legacy systems: UJM's OpenAI-only gulp task with the
|
|
6
|
+
`cache-uj-translation` GitHub-branch cache, and BXM's Claude-only task with a
|
|
7
|
+
gitignored `.cache/` (which re-translated everything on any change and on
|
|
8
|
+
every fresh clone).
|
|
9
|
+
|
|
10
|
+
## Config (shared `translation` section of omega.json5)
|
|
11
|
+
|
|
12
|
+
```json5
|
|
13
|
+
translation: {
|
|
14
|
+
enabled: true, // optional master switch (default true)
|
|
15
|
+
default: 'en', // source language (default 'en')
|
|
16
|
+
languages: ['es', 'fr'],// target codes — EMPTY/ABSENT = translation off
|
|
17
|
+
providers: { claude: {} },// the engine is a KEY (#425): claude | chatgpt. Absent block = claude
|
|
18
|
+
model: null, // optional override for the chosen engine (claude → 'sonnet' alias, chatgpt → 'gpt-5.4-nano')
|
|
19
|
+
exclude: [], // web only: BRAND page routes/folders to skip (the framework's own default pages are already excluded — #605)
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Shared section (typically brand-level; `SHARED_SECTIONS` includes it, so
|
|
24
|
+
every target inherits it through the merge chain). Language codes
|
|
25
|
+
validate against the SSOT in `@omega.js/devkit/translate` (`LANGUAGE_NAMES`,
|
|
26
|
+
~32 codes) — an unknown code is a hard config error naming the supported set.
|
|
27
|
+
The same SSOT carries `LANGUAGE_LOCALES` + `ogLocale(code)`, the one code →
|
|
28
|
+
Open Graph `language_TERRITORY` map (`es` → `es_ES`).
|
|
29
|
+
|
|
30
|
+
## Providers
|
|
31
|
+
|
|
32
|
+
| Provider | Rides | Credentials |
|
|
33
|
+
|----------|-------|-------------|
|
|
34
|
+
| `claude` (default) | the locally-installed Claude Code via `@anthropic-ai/claude-agent-sdk` | **none** — local auth |
|
|
35
|
+
| `chatgpt` | OpenAI Responses API (native fetch) | `OPENAI_API_KEY` via the .env cascade |
|
|
36
|
+
|
|
37
|
+
The claude provider runs **hermetic** sessions: `settingSources: []` (no user
|
|
38
|
+
CLAUDE.md/hooks — they pollute mechanical output; a stop-hook reply actually
|
|
39
|
+
leaked into a canary before this was locked down), a custom translator system
|
|
40
|
+
prompt instead of the CLI persona, and NO `maxTurns` cap (a plain reply
|
|
41
|
+
already counts as the final turn — `maxTurns: 1` reports `error_max_turns`
|
|
42
|
+
even though the text arrived).
|
|
43
|
+
|
|
44
|
+
**Enabling translation on web means installing the SDK (#37).** `@omega.js/web`
|
|
45
|
+
does NOT ship `@anthropic-ai/claude-agent-sdk`: translation is opt-in and the
|
|
46
|
+
SDK is heavy, so a web brand that turns it on installs it in the target itself
|
|
47
|
+
(`npm install @anthropic-ai/claude-agent-sdk`); `@omega.js/extension` still
|
|
48
|
+
declares it. The SDK is lazy-required at the first claude call, so a brand
|
|
49
|
+
without translation never pays for it, and a brand that enabled translation
|
|
50
|
+
without the SDK gets a hard error naming the package and that install command,
|
|
51
|
+
never a silent skip. The `chatgpt` provider needs no SDK at all (native fetch
|
|
52
|
+
plus `OPENAI_API_KEY`).
|
|
53
|
+
|
|
54
|
+
**The manage cycle provisions it (#168).** Nobody types that install in a
|
|
55
|
+
managed brand: the manager's workspace service reconciles it like every other
|
|
56
|
+
brand file. A web app whose RESOLVED config translates with the `claude`
|
|
57
|
+
provider gets `@anthropic-ai/claude-agent-sdk` written into its package.json
|
|
58
|
+
`dependencies` (at the range `@omega.js/web` declares as its optional peer,
|
|
59
|
+
read from the installed web package), followed by one `npm install` at the
|
|
60
|
+
brand root. Converge-to-config, so: already declared (in `dependencies` or
|
|
61
|
+
`devDependencies`) = zero-mutation no-op that never overwrites a
|
|
62
|
+
consumer-chosen spec, `--dry-run` plans without writing, translation off or
|
|
63
|
+
provider `chatgpt` leaves the target untouched, and turning translation back OFF
|
|
64
|
+
never REMOVES the dep (uninstalling on a config flip is riskier than leaving
|
|
65
|
+
it). Only web targets are provisioned, since backend and extension declare the
|
|
66
|
+
SDK as a real dependency of the framework. The loud error above stays the backstop
|
|
67
|
+
for hand-managed brands (`packages/manager/src/services/workspace/ensure/translation-sdk.js`,
|
|
68
|
+
pinned by `packages/manager/test/workspace-translation-sdk.test.js`).
|
|
69
|
+
|
|
70
|
+
## Engine protocol (`@omega.js/devkit/translate`)
|
|
71
|
+
|
|
72
|
+
`translateStrings({ strings, language, languageName, brand, extraRules, send })`
|
|
73
|
+
→ positionally-aligned translations:
|
|
74
|
+
|
|
75
|
+
- **JSON array in → same-length JSON array out**, batches of 25.
|
|
76
|
+
- **Batches fly concurrently**, `CONCURRENCY` wide (the constant at the top of
|
|
77
|
+
`packages/devkit/src/translate/engine.js`, currently 5 —
|
|
78
|
+
[#604](https://github.com/Omega-JS-Stack/omega/issues/604)). A batch is one
|
|
79
|
+
model call and the model's latency dominates it, so a serial pass paid that
|
|
80
|
+
latency once per 25 strings and one language took minutes it never needed.
|
|
81
|
+
Results are stitched back in BATCH order, never completion order, and
|
|
82
|
+
everything below still happens per batch, unchanged. Raise it only as far as
|
|
83
|
+
the providers' rate limits allow.
|
|
84
|
+
- **Duplicates are deduped before batching** ([#529](https://github.com/Omega-JS-Stack/omega/issues/529)):
|
|
85
|
+
a page sends its title and description once per meta tag (`<title>`,
|
|
86
|
+
`og:title`, `twitter:title`), so the same string used to ride a batch three
|
|
87
|
+
times over — three times the AI spend, and adjacent twins are what a model
|
|
88
|
+
merges. Each unique string is translated ONCE and the translation is fanned
|
|
89
|
+
back to every occurrence. Occurrences key on the exact source string,
|
|
90
|
+
whitespace included, so a batch is 25 UNIQUE strings.
|
|
91
|
+
- The `OMEGA-TRANSLATION-CONTROL` sentinel is appended to EVERY batch and must
|
|
92
|
+
return unchanged at its exact position — alignment proof per batch.
|
|
93
|
+
- Validation failures (parse, length, sentinel) retry up to 2× then throw.
|
|
94
|
+
- An ALIGNMENT failure (length or sentinel) that survives the retries splits the
|
|
95
|
+
batch in half and re-asks each half, down to one string
|
|
96
|
+
([#523](https://github.com/Omega-JS-Stack/omega/issues/523)): a model that
|
|
97
|
+
merges a pair of strings does it every time, so retrying the same array can
|
|
98
|
+
only fail the same way — the playground's ship-the-docs page came back
|
|
99
|
+
25-for-26 on all six attempts, in both languages, and shipped untranslated.
|
|
100
|
+
A single string that still will not come back whole throws, and the caller
|
|
101
|
+
skips that page-language pair whole (never half-translated).
|
|
102
|
+
- Original leading/trailing whitespace is re-applied to every translation.
|
|
103
|
+
- Rules baked into the system prompt: preserve HTML/URLs/placeholders
|
|
104
|
+
(`$1`, `{name}`, `{{ value }}`), never translate the brand name.
|
|
105
|
+
|
|
106
|
+
## The committed cache (`<app>/translations/`)
|
|
107
|
+
|
|
108
|
+
`translations/{lang}/{namespace}.json` maps `sha256(source)[:12]` → translated
|
|
109
|
+
string. Committed to git — that's the whole point:
|
|
110
|
+
|
|
111
|
+
- **Incremental**: editing one source string changes one hash → exactly one
|
|
112
|
+
re-translation. Everything else is a cache hit (zero provider calls).
|
|
113
|
+
- **Survives clones/CI**: a warm cache builds a fully-translated site with NO
|
|
114
|
+
AI credentials (kills the BXM parked finding where fresh clones burned live
|
|
115
|
+
Claude calls).
|
|
116
|
+
- **Human-overridable**: hand-edit a translation VALUE in the cache file and
|
|
117
|
+
it sticks for as long as the source is unchanged (the value is the
|
|
118
|
+
translation; the key only changes when the SOURCE changes).
|
|
119
|
+
- Maps are pruned to the current source set on save — no stale entries.
|
|
120
|
+
|
|
121
|
+
`@omega.js/web` ships a second cache in exactly this shape for its OWN default
|
|
122
|
+
pages, inside the package ([below](#framework-shipped-default-page-translations-621)).
|
|
123
|
+
|
|
124
|
+
## Web (`@omega.js/web`)
|
|
125
|
+
|
|
126
|
+
`omega build` translates everything by default (Ian's #24 final call): warm
|
|
127
|
+
strings come from the committed cache instantly, cold strings translate live
|
|
128
|
+
through the provider — a build ships the COMPLETE translated site whenever
|
|
129
|
+
the provider delivers, and a warm cache means zero provider calls. A provider
|
|
130
|
+
FAILURE skips that page-language pair whole, warning loudly with the page and
|
|
131
|
+
the language (the build still exits 0): no half-translated copy ever ships
|
|
132
|
+
behind full language chrome.
|
|
133
|
+
`omega build --cached-only` skips cold page-language pairs WHOLE instead (no
|
|
134
|
+
mixed-language copies, hreflang stays honest; the warning lists them) for
|
|
135
|
+
provider-free builds.
|
|
136
|
+
`omega translate` still runs the live pass standalone against an existing
|
|
137
|
+
dist/ and exits 1 on failures. `OMEGA_TRANSLATE_ONLY=<route>` limits any of
|
|
138
|
+
these to one page (canary/debug).
|
|
139
|
+
|
|
140
|
+
Per page × language: text nodes/`<title>`/meta/attribute copy translate
|
|
141
|
+
(cache-first), then the copy lands at `dist/{lang}/...` with `<html lang dir>`
|
|
142
|
+
(RTL-aware), canonical + `og:url` + `og:locale` localized, internal links
|
|
143
|
+
rewritten to `/{lang}/...`, and hreflang + `og:locale:alternate` tags
|
|
144
|
+
stitched into BOTH the copy and the original — naming only the languages
|
|
145
|
+
actually PRODUCED for that page (a pair skipped cold or failed is never
|
|
146
|
+
advertised, on the copies as on the originals), so hreflang never lies.
|
|
147
|
+
`og:locale` carries Open Graph's `language_TERRITORY` form (`en_US`,
|
|
148
|
+
`es_ES`) from the devkit language SSOT's locale map — on translated copies
|
|
149
|
+
and on the source pages the head include renders. Cache namespace:
|
|
150
|
+
`pages/{route}` (`pages/home` for `/`).
|
|
151
|
+
|
|
152
|
+
On a site served under a base path ([#355](https://github.com/Omega-JS-Stack/omega/issues/355)),
|
|
153
|
+
link rewriting composes **prefix, then language**: the pass reads the mount
|
|
154
|
+
point off the `<html data-omega-path-prefix>` stamp the build wrote (so
|
|
155
|
+
`omega translate` standalone sees it too), takes the route from underneath it,
|
|
156
|
+
and mounts the language segment after it — `/workkit/es/pricing`, never
|
|
157
|
+
`/es/workkit/pricing` ([#359](https://github.com/Omega-JS-Stack/omega/issues/359)).
|
|
158
|
+
Exclusions are matched on that same underneath-the-prefix route. ABSOLUTE URLs
|
|
159
|
+
(canonical, `og:url`, hreflang alternates, the sitemap entries) are built from
|
|
160
|
+
`brand.url`, which for a mounted site already carries the path — nothing
|
|
161
|
+
prefixes them twice.
|
|
162
|
+
|
|
163
|
+
Never sent to the PROVIDER, and the framework owns the list
|
|
164
|
+
([#605](https://github.com/Omega-JS-Stack/omega/issues/605)): every one of its
|
|
165
|
+
OWN default pages whose layout says it is plumbing rather than marketing copy —
|
|
166
|
+
the auth flows, the `/app` shell, the account/payment/portal screens, the legal
|
|
167
|
+
boilerplate, `404`, and the redirect stubs (`/login`, `/account`, `/cancel`, …).
|
|
168
|
+
Those pages still get their `/{lang}/` copies — from the translations PACKAGED
|
|
169
|
+
with `@omega.js/web`, at no cost to the brand (next section).
|
|
170
|
+
The list is DERIVED from the packaged defaults tree
|
|
171
|
+
(`packages/web/defaults/pages/**`, read by `src/translate/default-routes.js`),
|
|
172
|
+
never typed out, so a default page that moves or arrives cannot drift out of it,
|
|
173
|
+
and each excluded route guards its subtree too. On top of that: socials
|
|
174
|
+
redirects (config `socials` keys), the `admin`/`test`/`team`/`updates` folders,
|
|
175
|
+
every known language-code folder, plus config `translation.exclude` — which is
|
|
176
|
+
for the BRAND's own pages, and only those. A brand that lists `signin` or
|
|
177
|
+
`account` is listing something the framework already skips.
|
|
178
|
+
Element opt-out: `data-omega-no-translate`. Collector fixes vs UJM:
|
|
179
|
+
`aria-describedby`/`aria-labelledby` are NOT collected (ID refs), `value`
|
|
180
|
+
only on button-type inputs (hidden-input tokens stay intact).
|
|
181
|
+
|
|
182
|
+
### Framework-shipped default-page translations ([#621](https://github.com/Omega-JS-Stack/omega/issues/621))
|
|
183
|
+
|
|
184
|
+
The default pages above render the SAME chrome on every brand, so the framework
|
|
185
|
+
translates them ONCE and ships the result: `packages/web/translations/{lang}/pages/{route}.json`,
|
|
186
|
+
the identical `{lang}/{namespace}.json` shape as a consumer's own cache (same
|
|
187
|
+
loader, same `sha256(source)[:12]` keys, same prune-on-save, hand-fixable the
|
|
188
|
+
same way), committed to the package and published under `files`.
|
|
189
|
+
|
|
190
|
+
The keys are brand-NEUTRAL. The generator renders with a fixture brand and
|
|
191
|
+
replaces every occurrence of it with the sentinel `__OMEGA_BRAND__` before
|
|
192
|
+
hashing; the read-through replaces the CONSUMER's `brand.name` with the same
|
|
193
|
+
token before the lookup and puts it back on the way out, so "Sign in to MiniCo"
|
|
194
|
+
and "Sign in to Acme" are one packaged entry (`src/translate/packaged-defaults.js`).
|
|
195
|
+
|
|
196
|
+
Consumer side, on every pass — `omega build`, `--cached-only`, `omega translate`
|
|
197
|
+
alike, since it never touches a provider:
|
|
198
|
+
|
|
199
|
+
- Each default route gets its `dist/{lang}/…` copy with the same localized
|
|
200
|
+
chrome, hreflang and sitemap entry as any other page. Link rewriting is the
|
|
201
|
+
same pass too, which means links OUT to brand pages gain the language segment
|
|
202
|
+
while links between two default routes (signin → signup) do not — those routes
|
|
203
|
+
are excluded from rewriting, and that is unchanged from #605.
|
|
204
|
+
- A string the package does not carry (copy the brand overrode, a page the
|
|
205
|
+
framework has not regenerated for) stays in the source language and is
|
|
206
|
+
COUNTED — one log line per route names the miss count. Never guessed at.
|
|
207
|
+
- A brand whose NAME is a word the chrome itself uses ("Sign") still gets every
|
|
208
|
+
string that does not interpolate the brand — the lookup falls back to the raw
|
|
209
|
+
key when the sentinel-normalized one misses. The strings that DO interpolate
|
|
210
|
+
it (`Sign in to Sign`) miss, and stay in the source language.
|
|
211
|
+
- A route the package carries nothing for gets NO copy, so hreflang keeps
|
|
212
|
+
telling the truth. That is how the legal boilerplate stays one language:
|
|
213
|
+
`terms`/`privacy`/`cookies` are deliberately not generated.
|
|
214
|
+
- A configured language the package does not ship is one log line for the whole
|
|
215
|
+
run, not an error — those routes stay in the source language.
|
|
216
|
+
- A route the brand named in `translation.exclude` is left alone entirely.
|
|
217
|
+
|
|
218
|
+
**Shipped set: `es`, `fa`.** Regenerating, or extending the set, is one command
|
|
219
|
+
in `packages/web` (the ONLY place the framework's own pages ever reach a
|
|
220
|
+
provider):
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm run translate:defaults # the shipped set
|
|
224
|
+
npm run translate:defaults -- --languages es,fa,de # …plus a new one
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
It renders the defaults tree through the real production build against a
|
|
228
|
+
throwaway consumer (no brand repo involved), harvests with the same collector
|
|
229
|
+
the pass uses, translates ONLY the strings the packaged cache is missing —
|
|
230
|
+
across all routes at once, so the header/footer chrome every default page
|
|
231
|
+
repeats is paid for exactly once — and writes the files back. Idempotent: a
|
|
232
|
+
re-run costs nothing, adding a language costs only that language. A provider
|
|
233
|
+
failure, or a translation that dropped the sentinel, STOPS the run and writes
|
|
234
|
+
nothing.
|
|
235
|
+
|
|
236
|
+
`dist/sitemap.xml` (emitted by the build in the source language only) is
|
|
237
|
+
rewritten afterwards so it tells the same story: every PRODUCED copy joins it
|
|
238
|
+
as its own `<url>`, and each entry of a translated set — source and copies
|
|
239
|
+
alike — carries the full `xhtml:link rel="alternate"` list (`x-default` at the
|
|
240
|
+
source language) plus the source entry's `lastmod`/`changefreq`/`priority`.
|
|
241
|
+
Entries stay in loc byte order. The language-prefixed entries are owned by that
|
|
242
|
+
pass: each run drops them all and re-emits only what it produced, so a skipped
|
|
243
|
+
or failed pair is listed nowhere.
|
|
244
|
+
|
|
245
|
+
The visitor-facing **language switcher** is the footer dropup in the shared
|
|
246
|
+
base footer include (`_includes/frontend/sections/footer.html`, the base layer
|
|
247
|
+
every theme inherits). It renders CLIENT-SIDE from the page's own
|
|
248
|
+
`link[rel="alternate"][hreflang]` tags — the produced-only SSOT above — so the
|
|
249
|
+
menu can never offer a copy that was not written: `core/js/core/language-switcher.js`
|
|
250
|
+
drops `x-default`, labels each row with its native name (`Intl.DisplayNames` in
|
|
251
|
+
that language's own locale, upper-cased code as the fallback), marks
|
|
252
|
+
`documentElement.lang` as current, and leaves the mount empty and hidden when
|
|
253
|
+
fewer than two languages exist. Selecting a language is a plain link to that
|
|
254
|
+
alternate's href — never a redirect or a negotiation.
|
|
255
|
+
|
|
256
|
+
Not here yet: no default homepage exists in the D8 set, so brand sites
|
|
257
|
+
translate their own `index` when they add one.
|
|
258
|
+
|
|
259
|
+
## Extension (`@omega.js/extension`)
|
|
260
|
+
|
|
261
|
+
Build-mode gulp `translate` task (setup/dev builds only deploy):
|
|
262
|
+
|
|
263
|
+
- **messages**: per-KEY incremental — unique `message` values without a cache
|
|
264
|
+
entry translate (CWS limits ride the prompt as extra rules; violations warn
|
|
265
|
+
with the file path to shorten). `dist/_locales/{lang}/messages.json` is
|
|
266
|
+
COMPOSED from the EN source + cache (English fallback per missing key, so
|
|
267
|
+
the file is always complete; developer `description` fields stay English).
|
|
268
|
+
- **description**: whole-document per language →
|
|
269
|
+
`translations/{lang}/description.md`, first line
|
|
270
|
+
`<!-- omega:source <hash> -->` (stripped on read; source edit →
|
|
271
|
+
re-translate). The package task ships them as store assets
|
|
272
|
+
(`packaged/assets/description/{lang}.md`).
|
|
273
|
+
|
|
274
|
+
Languages/provider come from resolved config — the old hardcoded 16-language
|
|
275
|
+
list in `gulp/config/locales.js` is gone (only the CWS `limits` remain there).
|
|
276
|
+
|
|
277
|
+
## Testing
|
|
278
|
+
|
|
279
|
+
- devkit `test/translate.test.js` — engine protocol, providers, cache,
|
|
280
|
+
language SSOT, settings reader (fake `send`).
|
|
281
|
+
- web `test/translate.test.js` — handcrafted dist through the real pipeline:
|
|
282
|
+
copies/chrome/links/exclusions/alternates/cache/override/only-filter, the
|
|
283
|
+
produced-languages-only alternates, and the loud failure skip.
|
|
284
|
+
- web `test/language-switcher.test.js` — the switcher's DOM read (x-default
|
|
285
|
+
dropped, duplicates collapsed, current marked, escaping) and the built footer
|
|
286
|
+
mount in classy and newsflash.
|
|
287
|
+
- extension `build/translate.test.js` — compose + description marker glue.
|
|
288
|
+
- Live canary (cp96, local Claude): omega-brand `/about` → es (102 strings,
|
|
289
|
+
rerun 0 calls) and the extension's 4 messages (2 unique) + 2,703-char
|
|
290
|
+
description → es, both idempotent; artifacts committed under each target's
|
|
291
|
+
`translations/`.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Dependency updates (`omega update`)
|
|
2
|
+
|
|
3
|
+
One shared implementation (`@omega.js/devkit/update`) behind every framework's `omega update` verb (aliases: `outdated`, `out` — npu's muscle memory), thin wiring in web/desktop/extension (router commands), backend (colon-style command class), and the manager (brand-root fan-out). Semantics mirror Ian's `npu out` (node-power-user): report first, apply deliberately, and never trust a brand-new release.
|
|
4
|
+
|
|
5
|
+
## The report (default — no flags)
|
|
6
|
+
|
|
7
|
+
For each dependency of the target's `package.json` (prod + dev, grouped):
|
|
8
|
+
|
|
9
|
+
| Column | Meaning |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Current | the base version in `package.json` (`^1.2.3` → `1.2.3`) |
|
|
12
|
+
| Installed | the physical `node_modules` copy (nearest, climbing — npm hoists in brand monorepos) |
|
|
13
|
+
| Wanted | highest published version satisfying the range (npm-outdated semantics) |
|
|
14
|
+
| Latest | the registry `dist-tags.latest` |
|
|
15
|
+
| Bump | `patch` / `minor` / `major` — Current → Latest classification |
|
|
16
|
+
| Released | Latest's publish date + age in days |
|
|
17
|
+
| Status | `QUARANTINED` when Latest is younger than `--min-age` days (default **7**) and not already installed |
|
|
18
|
+
|
|
19
|
+
Only rows needing attention print; a fully-current tree reports one line. Rows sort prod-first.
|
|
20
|
+
|
|
21
|
+
**Quarantine (supply-chain caution, npu's `--min-age` semantics):** a release published < 7 days ago may be a compromised publish — it is flagged and **excluded from `--apply`**. `--min-age N` changes the window; `--min-age 0` or `--force-fresh` disables it. Unpublished packages (the pre-publish `@omega.js/*` set) report `not on the registry (unpublished?)` instead of a version row.
|
|
22
|
+
|
|
23
|
+
**`file:`/`link:`/git specs are SKIPPED** with a dim note — they have no registry story. In the local era every brand's `@omega.js/*` dep is a `file:` spec, so the verb never touches the linked frameworks.
|
|
24
|
+
|
|
25
|
+
## Applying (`--apply`)
|
|
26
|
+
|
|
27
|
+
- Default tier is **non-breaking**: each dep rides to its highest same-major version (npu's minor tier) — quarantined targets are held and listed.
|
|
28
|
+
- **Majors are never auto-applied**: breaking jumps are listed as held; `--apply --major` opts in explicitly.
|
|
29
|
+
- Installs run through **`npu install`** when npu is on the machine (Socket supply-chain firewall); otherwise plain `npm install` with a loud warning. Dev deps install with `--save-dev` in their own pass.
|
|
30
|
+
|
|
31
|
+
## The @omega.js family is pinned, and `omega update` is its ONE mover ([#794](https://github.com/Omega-JS-Stack/omega/issues/794))
|
|
32
|
+
|
|
33
|
+
Every `@omega.js/*` spec the manager writes into a brand is an EXACT pin, never a
|
|
34
|
+
caret: `"@omega.js/manager": "0.1.0"` at the brand root, `"@omega.js/<framework>":
|
|
35
|
+
"0.1.0"` in each target, all at the manager's own version (the family ships
|
|
36
|
+
lockstep — [publishing.md](publishing.md)). A caret would let one target float
|
|
37
|
+
ahead alone on somebody's `npm update`, which is how a brand ends up serving two
|
|
38
|
+
copies of `@omega.js/client` and validating one omega.json5 with two validators.
|
|
39
|
+
|
|
40
|
+
Pinned, the only thing that moves a brand is `omega update --apply` at the brand
|
|
41
|
+
ROOT (a bare run reports and installs nothing), and it moves every target — and
|
|
42
|
+
the root's own manager pin — together. `--apply` installs an `@omega.js/*` dep with
|
|
43
|
+
`--save-exact`, in its own command per dep group, so the mover never un-pins
|
|
44
|
+
what it just moved (npm's default save-prefix would write `^<version>` back);
|
|
45
|
+
every other dependency keeps npm's default prefix, because the pin is the
|
|
46
|
+
FAMILY's rule and not a rule for the whole tree.
|
|
47
|
+
|
|
48
|
+
The manager's boot check enforces the other half: a brand whose installed
|
|
49
|
+
versions have drifted is refused before any service or dev leg runs
|
|
50
|
+
([../manager/brand.md](../manager/brand.md)). The local era is untouched — a
|
|
51
|
+
`file:` spec has no registry story, so the verb skips it and the boot check
|
|
52
|
+
exempts it. `omega i live` (the publish-day flip back off `file:` specs) writes
|
|
53
|
+
the same exact pin ([local-dev.md](local-dev.md) § API surface).
|
|
54
|
+
|
|
55
|
+
## Brand root
|
|
56
|
+
|
|
57
|
+
`omega update` at a brand root (manager) fans out over the brand's targets — cp251's deploy fan-out shape: same target discovery, same `--target=<target|dir>` picker ([#780](https://github.com/Omega-JS-Stack/omega/issues/780)), every other flag forwarded verbatim, each target answering through its own framework's `update` verb. Unlike deploy, targets are **independent**: one failing target never blocks the rest (any failure still exits 1). The brand-root shell `package.json` rides the walk as its LAST leg ([#794](https://github.com/Omega-JS-Stack/omega/issues/794)), scoped to the one `@omega.js/*` dependency it carries — `@omega.js/manager` — and run in-process through the same devkit implementation (there is no framework bin at the root to spawn; it would dispatch straight back into this command). A brand's own root tooling is never touched, and a picked run (`--target=`) skips the root, because the picker names targets. Without that leg a manager-behind brand could never heal itself: the boot check would refuse every verb, and the fix it names would move every target except the one that was wrong.
|
|
58
|
+
|
|
59
|
+
## Testing
|
|
60
|
+
|
|
61
|
+
Registry lookups, the clock, npu detection, and exec are all injectable — the devkit suite (`packages/devkit/test/update.test.js`) runs entirely offline against fixture packuments with a frozen clock; the manager fan-out test spawns fake framework bins; framework structure tests pin the wiring. The live path is the thin defaults (native `fetch` of the full packument — the abbreviated form carries no publish times).
|
package/docs/testing.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# The testing service — health checks after the walk
|
|
2
|
+
|
|
3
|
+
The `testing` service runs LAST: per-target health checks after every other service has had
|
|
4
|
+
its pass. Local checks read the repo; live checks fetch the deployed brand. A dry run never
|
|
5
|
+
touches the network — every live check prints a "would" line instead.
|
|
6
|
+
|
|
7
|
+
## What it checks
|
|
8
|
+
|
|
9
|
+
| Target | Checks |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `web` | `package.json`, `dist/index.html`, the installed framework version vs npm latest, and a homepage fetch. |
|
|
12
|
+
| `backend` | `package.json`, `firebase.json`, the staged `dist/` build output, the installed framework version vs npm latest, and API health + the deployed version (skipped for a shared Firebase project). |
|
|
13
|
+
| every target | `package.json`, and the framework version when declared. |
|
|
14
|
+
| repo-level (once) | A clean working tree, and the latest GitHub Actions run (only with `repo.providers.github.org` configured). |
|
|
15
|
+
|
|
16
|
+
Results roll up honestly: any failed check makes the service an error, any warning makes it
|
|
17
|
+
warned. The output shape matches omega-manager's testing service, so the run summary's
|
|
18
|
+
drill-down works unchanged.
|
|
19
|
+
|
|
20
|
+
## Config
|
|
21
|
+
|
|
22
|
+
No config of its own; it reads the brand's targets, `repo.providers.github.org`, and
|
|
23
|
+
`cloud.shared`. Injection seams for the network-free tests ride `options` (`fetch`, `exec`,
|
|
24
|
+
`retryDelayMs`).
|
|
25
|
+
|
|
26
|
+
## Gotchas
|
|
27
|
+
|
|
28
|
+
- **A custom-mode backend has no `firebase.json`** to demand
|
|
29
|
+
([#584](https://github.com/Omega-JS-Stack/omega/issues/584)): that is the one Firebase-only
|
|
30
|
+
check, noted with its reason instead of failed. The staged `dist/` check still runs — a
|
|
31
|
+
custom backend builds like any other.
|
|
32
|
+
- **Not ported from omega-manager**: the `build.json` check (a UJM artifact — `@omega.js/web`
|
|
33
|
+
has no build manifest) and the stash check (nothing stashes in the new update service).
|
|
34
|
+
GitHub Actions is repo-level here, because a brand is one repo.
|
package/docs/update.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# The update service — install and build every target
|
|
2
|
+
|
|
3
|
+
The `update` service is the install + build pass: one `npm install` at the brand root (npm
|
|
4
|
+
workspaces cover every target), then each target's own `npm run build`. It is the slow tail of
|
|
5
|
+
every walk, and it runs late — after everything that writes a target's inputs, before the
|
|
6
|
+
account and testing services that talk to a deployed brand.
|
|
7
|
+
|
|
8
|
+
## What it reconciles
|
|
9
|
+
|
|
10
|
+
One operation, `targets`:
|
|
11
|
+
|
|
12
|
+
- **Install** is dependency-resolution-gated for idempotency: when every target's declared
|
|
13
|
+
deps already resolve through the `node_modules` climb, the install is skipped — so a second
|
|
14
|
+
run is a no-op, and a brand nested inside a larger workspace never grows a stray
|
|
15
|
+
`node_modules`.
|
|
16
|
+
- **Build** runs each target's `npm run build`. A target with no build script is recorded as
|
|
17
|
+
SKIPPED, not failed (a backend's "build" is its deploy story).
|
|
18
|
+
|
|
19
|
+
The service skips entirely when no dir maps to a target.
|
|
20
|
+
|
|
21
|
+
## The incremental cache
|
|
22
|
+
|
|
23
|
+
The `update` service is incremental ([#445](https://github.com/Omega-JS-Stack/omega/issues/445)): per target it fingerprints TWO input sets, the target's own tree (a stat sweep that excludes `node_modules`, `dist`, `logs`, `.temp`, `.omega`, `.cache`, `.firebase` and log files, so a build can never dirty its own inputs) plus the merge-chain files above it: brand and company `omega.json5` and `.env`, each `.env` counted with its `.env.<environment>` overlays, whose spelling comes from @omega.js/config's `envLayerFiles` rather than a path joined here, so an overlay edit dirties the target exactly like a base-file edit ([#681](https://github.com/Omega-JS-Stack/omega/issues/681)). The second set is the installed identity of every `@omega.js/*` dependency the target declares (an npm install contributes its version string; a local link, whose version stands still inside the monorepo, contributes the link target's version plus a sweep of its build output). Both unchanged since that target's last successful build → it is converged and skips with one line; either one fresh → the full build for that target. The pair lives in `.omega/cache/update.json` — derived data, so it sits with the brand's other caches rather than in config — and `omega manage --force` ignores it. A missing or unreadable cache is not an error: the run treats every target as fresh, builds, and rewrites the file.
|
|
24
|
+
|
|
25
|
+
Both fingerprints are stat walks — relative path, size and mtime — so no file contents are
|
|
26
|
+
ever read.
|
|
27
|
+
|
|
28
|
+
## Gotchas
|
|
29
|
+
|
|
30
|
+
- **A failed cache write warns and the walk continues.** A cache is an optimization, never a
|
|
31
|
+
reason to fail a run.
|
|
32
|
+
- **A brand-config edit invalidates every target.** The merge-chain files fold into each
|
|
33
|
+
target's fingerprint on purpose: a config change that left every target "converged" would
|
|
34
|
+
serve stale output silently.
|
|
35
|
+
- **Phases beyond install/build** (bump, deploy, sync) live in the deliberate verbs, not here —
|
|
36
|
+
see [deploys.md](shared/deploys.md).
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# The workspace service — the brand monorepo itself
|
|
2
|
+
|
|
3
|
+
The `workspace` service runs FIRST in every walk, and on the boot lane too: everything
|
|
4
|
+
downstream assumes a sane brand monorepo. It reconciles the repo's own shape — root
|
|
5
|
+
`package.json` workspaces, a dir per enabled target, config health, the agent-docs chain,
|
|
6
|
+
the `.env` files — and it is the one service that touches no network at all.
|
|
7
|
+
|
|
8
|
+
## What it reconciles
|
|
9
|
+
|
|
10
|
+
| Operation | What it does |
|
|
11
|
+
|---|---|
|
|
12
|
+
| `structure` | Root `package.json` declares `targets/*` and every enabled target has its dir. A dir mapping to no target WARNS; an enabled target with no dir is an ERROR naming the dir to create. Array-form targets expect one dir per instance (`main` → the canonical dir, any other id → `<canonical>-<id>`). |
|
|
13
|
+
| `config` | `config/omega.json5` loads and validates. A brand file that fails to load or validate is an ERROR — there is nothing sound to reconcile against. Per-target findings are warnings; each framework's own audit is the hard gate for its surface. |
|
|
14
|
+
| `defaults` | Materializes the schema-defaulted blocks the brand file does not carry yet ([#478](https://github.com/Omega-JS-Stack/omega/issues/478)), each with the schema's own description as its comment. Never overwrites: a converged config is byte-identical. |
|
|
15
|
+
| `gitignore` | `.omega/` and `logs/` are ignored at the brand root — the secrets store and run output never get committed. |
|
|
16
|
+
| `scripts` | Root `package.json` scripts say `omega` (a legacy omega-manager brand is healed) and a `deploy` script exists; each framework target's scripts sync to its framework's `projectScripts` declaration. Those standard keys are FRAMEWORK-owned ([#689](https://github.com/Omega-JS-Stack/omega/issues/689)): the walk and the framework's own ensureTarget both rewrite them to the defaults on every run, so a hand-edited standard script heals instead of drifting — customize behavior through hook points, never by editing one. Keys the framework never declares are the consumer's own and are never touched. The walk runs it at all as the onboard→dev cycle break (#675): the dev fan-out reaches those verbs THROUGH these scripts. Exceptions: a custom target maps to no framework, so it is skipped whole (#603); a custom-server backend is skipped PER KEY (#584) — it owns `start`, `deploy`, `emulator` and `test:emulator` (the verbs its mode refuses, named by the framework's `projectScriptsCustomOwned`), which are never written and never scaffolded, while `test` and `test:static` stay framework-owned. Script VALUES only; no other key is touched. |
|
|
17
|
+
| `agents` | The brand's agent-docs chain: `node_modules/@omega.js/AGENTS.md` links the framework map, root `AGENTS.md` opens with the import, root `CLAUDE.md` is the one-line pointer. Consumer content is preserved; a content-bearing `CLAUDE.md` warns instead of being clobbered. |
|
|
18
|
+
| `claude-settings` | The committed `.claude/settings.json` that enables the omega plugin (below). |
|
|
19
|
+
| `workflows` | Deletes the brand root's composed `.github/workflows/<target>-*.yml` for targets the config no longer enables ([#636](https://github.com/Omega-JS-Stack/omega/issues/636)). Only files carrying the GENERATED header AND the composed name — the brand's own workflows share that dir and are never candidates. The target's DIR is left alone. |
|
|
20
|
+
| `env-keys` | Mints the env schema's `generated` keys into the brand `.env` when the cascade has none ([#569](https://github.com/Omega-JS-Stack/omega/issues/569)). |
|
|
21
|
+
| `env-order` | Rewrites the brand (and company) `.env` into the canonical group order. The `.env.<environment>` overlays beside it are a human's hand-picked few, not a canonical inventory, so nothing reorders them. |
|
|
22
|
+
| `env-rules` | Names the keys the brand's own config made mandatory and nobody filled in ([#626](https://github.com/Omega-JS-Stack/omega/issues/626)). |
|
|
23
|
+
| `translation-sdk` | A translating web target declares + installs `@anthropic-ai/claude-agent-sdk` ([#168](https://github.com/Omega-JS-Stack/omega/issues/168)). |
|
|
24
|
+
|
|
25
|
+
## Config and credentials
|
|
26
|
+
|
|
27
|
+
No credential of its own — nothing here leaves the machine. It reads `targets` (which dirs
|
|
28
|
+
must exist), the whole of `config/omega.json5` (the `config` and `defaults` ops), and each
|
|
29
|
+
target's own config for the translation check.
|
|
30
|
+
|
|
31
|
+
## The `.env` ops, and why presence is judged on the RESOLVED value
|
|
32
|
+
|
|
33
|
+
`env-keys` and `env-rules` both read `process.env` — which `manage.js` already layered as
|
|
34
|
+
shell > brand `.env` > company `.env`, each of those overlaid by its own
|
|
35
|
+
`.env.<environment>` file ([#586](https://github.com/Omega-JS-Stack/omega/issues/586)) —
|
|
36
|
+
never the brand file alone. A company-managed brand therefore never shadows its company's
|
|
37
|
+
value with a freshly minted one, and neither does a brand whose value lives only in an
|
|
38
|
+
overlay. A minted value is
|
|
39
|
+
published into `process.env` too, so the same run's builds compose it: the key is live one
|
|
40
|
+
manage after the gap, not two. Values are never printed; the run says WHICH key it minted.
|
|
41
|
+
|
|
42
|
+
`env-order` leaves a file it cannot parse (multi-line values, `export` forms) untouched
|
|
43
|
+
with a note. `env-rules` WARNS and never fails — a half-configured brand is a normal step
|
|
44
|
+
on the way to a configured one, and the lanes that truly cannot proceed (a production
|
|
45
|
+
backend boot) refuse on their own. Its rules are evaluated per enabled target against that
|
|
46
|
+
target's resolved config, so a per-surface key is judged where the services write it — and
|
|
47
|
+
a TARGET-LESS rule (a service's own key, like `SENTRY_AUTH_TOKEN`) is owed when its config
|
|
48
|
+
path is truthy in the brand root or in ANY enabled target's resolved config
|
|
49
|
+
([#683](https://github.com/Omega-JS-Stack/omega/issues/683)), because that is where the
|
|
50
|
+
service wrote the value that requires it.
|
|
51
|
+
|
|
52
|
+
## The `claude-settings` op
|
|
53
|
+
|
|
54
|
+
The `claude-settings` op ([#62](https://github.com/Omega-JS-Stack/omega/issues/62)) writes the OTHER half of a brand's agent setup: the committed `.claude/settings.json` that registers the omega marketplace shipped inside the installed manager package (`./node_modules/@omega.js/manager`) and enables `omega@omega`, so every session in that brand — anyone's, on any machine — loads the plugin. Gated on a published install: the installed manager must carry the vendored `.claude-plugin/marketplace.json` ([publishing.md](shared/publishing.md)) and be a real directory rather than a symlink into the monorepo, so the local era skips and the developer's own user-scope install serves those sessions. Idempotent and non-clobbering — the two omega keys are deep-merged, a correct file is not rewritten, and a settings file that doesn't parse is reported, never overwritten (`src/lib/claude-settings.js`, pinned by `test/claude-settings.test.js`).
|
|
55
|
+
|
|
56
|
+
## Gotchas
|
|
57
|
+
|
|
58
|
+
- **Custom targets are checked BY DIR.** A `type: 'custom'` target maps to no framework, so
|
|
59
|
+
`structure` reads the declaration's dir name and never counts it among the unmapped — one
|
|
60
|
+
of only two manage ops that see custom targets at all ([config.md](shared/config.md) § Custom targets).
|
|
61
|
+
- **`defaults` never invents an owner decision.** Keys with no sane framework answer —
|
|
62
|
+
provisioned ids, anything secret-shaped — carry no schema default and are never written.
|
|
63
|
+
- **`translation-sdk` never removes.** Turning translation off leaves the dep in place;
|
|
64
|
+
uninstalling on a config flip is riskier than leaving it.
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@omega.js/manager",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The OMEGA orchestration engine — walks every service in dependency order and reconciles each to the brand's omega.json5, idempotently, against a brand monorepo. omega-manager's brains, ported service by service. Private until first publish.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"bin": {
|
|
11
|
+
"omega": "./bin/omega",
|
|
12
|
+
"omg": "./bin/omg",
|
|
13
|
+
"mgr": "./bin/omega"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
".claude-plugin/",
|
|
17
|
+
"bin/",
|
|
18
|
+
"claude-plugin/",
|
|
19
|
+
"dist/",
|
|
20
|
+
"docs/"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": "./dist/index.js",
|
|
24
|
+
"./cli": "./dist/cli-run.js",
|
|
25
|
+
"./service-runner": "./dist/lib/service-runner.js",
|
|
26
|
+
"./run-summary": "./dist/lib/run-summary.js",
|
|
27
|
+
"./brand": "./dist/lib/brand.js",
|
|
28
|
+
"./manage": "./dist/manage.js"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"start": "npm run prepare:watch",
|
|
32
|
+
"prepare": "node -e \"require('@omega.js/devkit/prepare-guard')() && require('prepare-package')()\"",
|
|
33
|
+
"prepare:watch": "node -e \"require('prepare-package/watch')()\"",
|
|
34
|
+
"test": "node --require @omega.js/devkit/test/stdout-guard --test test/*.test.js"
|
|
35
|
+
},
|
|
36
|
+
"preparePackage": {
|
|
37
|
+
"input": "./src",
|
|
38
|
+
"output": "./dist",
|
|
39
|
+
"replace": {},
|
|
40
|
+
"type": "copy",
|
|
41
|
+
"hooks": {
|
|
42
|
+
"after": [
|
|
43
|
+
"node -e \"require('@omega.js/devkit/vendor')()\"",
|
|
44
|
+
"node -e \"require('@omega.js/devkit/prepare-guard').rewire()\""
|
|
45
|
+
],
|
|
46
|
+
"afterBlocking": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@inquirer/prompts": "^8.5.2",
|
|
51
|
+
"@omega.js/backend": "0.1.0",
|
|
52
|
+
"@omega.js/mcp-router": "0.1.0",
|
|
53
|
+
"ag-psd": "^31.0.2",
|
|
54
|
+
"canvas": "^3.2.3",
|
|
55
|
+
"chalk": "^5.6.2",
|
|
56
|
+
"dotenv": "^17.4.2",
|
|
57
|
+
"fs-jetpack": "^5.1.0",
|
|
58
|
+
"json5": "^2.2.3",
|
|
59
|
+
"node-powertools": "^3.0.0",
|
|
60
|
+
"opentype.js": "^2.0.0",
|
|
61
|
+
"png2icons": "^2.0.1",
|
|
62
|
+
"psl": "^1.15.0",
|
|
63
|
+
"puppeteer": "^24.43.1",
|
|
64
|
+
"sharp": "^0.35.3",
|
|
65
|
+
"stripe": "^22.3.0",
|
|
66
|
+
"ws": "^8.21.0",
|
|
67
|
+
"yargs": "^18.0.0"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"@anthropic-ai/claude-agent-sdk": ">=0.2"
|
|
71
|
+
},
|
|
72
|
+
"peerDependenciesMeta": {
|
|
73
|
+
"@anthropic-ai/claude-agent-sdk": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@omega.js/account": "*",
|
|
79
|
+
"@omega.js/config": "*",
|
|
80
|
+
"@omega.js/devkit": "*",
|
|
81
|
+
"prepare-package": "^2.2.0"
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=22"
|
|
85
|
+
},
|
|
86
|
+
"author": "ITW Creative Works",
|
|
87
|
+
"license": "Elastic-2.0"
|
|
88
|
+
}
|