@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.
Files changed (416) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/LICENSE +98 -0
  3. package/README.md +165 -0
  4. package/bin/omega +2 -0
  5. package/bin/omg +2 -0
  6. package/claude-plugin/.claude-plugin/plugin.json +11 -0
  7. package/claude-plugin/.mcp.json +9 -0
  8. package/claude-plugin/README.md +139 -0
  9. package/claude-plugin/hooks/gate/mark.sh +58 -0
  10. package/claude-plugin/hooks/gate/run.sh +97 -0
  11. package/claude-plugin/hooks/guard/run.sh +249 -0
  12. package/claude-plugin/hooks/hooks.json +63 -0
  13. package/claude-plugin/hooks/inject/run.sh +127 -0
  14. package/claude-plugin/hooks/lib/omega-gate.sh +20 -0
  15. package/claude-plugin/hooks/lib/omega-scope.sh +41 -0
  16. package/claude-plugin/hooks/lib/omega-skills.sh +209 -0
  17. package/claude-plugin/hooks/quality/run.sh +132 -0
  18. package/claude-plugin/hooks/shape/run.sh +45 -0
  19. package/claude-plugin/mcp-router-launch.js +29 -0
  20. package/claude-plugin/skills/README.md +48 -0
  21. package/claude-plugin/skills/accessibility/SKILL.md +31 -0
  22. package/claude-plugin/skills/analytics/SKILL.md +30 -0
  23. package/claude-plugin/skills/backend/SKILL.md +25 -0
  24. package/claude-plugin/skills/brandcheck/SKILL.md +29 -0
  25. package/claude-plugin/skills/browser/SKILL.md +64 -0
  26. package/claude-plugin/skills/client/SKILL.md +24 -0
  27. package/claude-plugin/skills/desktop/SKILL.md +25 -0
  28. package/claude-plugin/skills/extension/SKILL.md +25 -0
  29. package/claude-plugin/skills/main/SKILL.md +54 -0
  30. package/claude-plugin/skills/manager/SKILL.md +25 -0
  31. package/claude-plugin/skills/seo/SKILL.md +36 -0
  32. package/claude-plugin/skills/theme/SKILL.md +33 -0
  33. package/claude-plugin/skills/web/SKILL.md +29 -0
  34. package/dist/cli-run.js +34 -0
  35. package/dist/cli.js +29 -0
  36. package/dist/commands/build.js +17 -0
  37. package/dist/commands/clean.js +16 -0
  38. package/dist/commands/company.js +46 -0
  39. package/dist/commands/deploy.js +143 -0
  40. package/dist/commands/dev.js +437 -0
  41. package/dist/commands/devlog.js +25 -0
  42. package/dist/commands/help.js +48 -0
  43. package/dist/commands/manage.js +53 -0
  44. package/dist/commands/migrate.js +76 -0
  45. package/dist/commands/onboard.js +31 -0
  46. package/dist/commands/pipeline.js +319 -0
  47. package/dist/commands/test.js +380 -0
  48. package/dist/commands/update.js +128 -0
  49. package/dist/commands/version.js +8 -0
  50. package/dist/company-init.js +167 -0
  51. package/dist/company.js +283 -0
  52. package/dist/config.js +1359 -0
  53. package/dist/devlog/index.js +226 -0
  54. package/dist/devlog/lib/collect-commits.js +136 -0
  55. package/dist/devlog/lib/generate-post.js +201 -0
  56. package/dist/devlog/lib/ghostii.js +122 -0
  57. package/dist/devlog/lib/project-map.js +98 -0
  58. package/dist/devlog/lib/publish-website.js +88 -0
  59. package/dist/index.js +45 -0
  60. package/dist/lib/agents-md.js +201 -0
  61. package/dist/lib/analytics-secret.js +22 -0
  62. package/dist/lib/argv.js +21 -0
  63. package/dist/lib/auth-admin.js +120 -0
  64. package/dist/lib/automation-client.js +210 -0
  65. package/dist/lib/backend-marketing.js +49 -0
  66. package/dist/lib/brand.js +240 -0
  67. package/dist/lib/bundle-id.js +53 -0
  68. package/dist/lib/claude-settings.js +125 -0
  69. package/dist/lib/company-scaffold.js +213 -0
  70. package/dist/lib/company.js +227 -0
  71. package/dist/lib/config-flow.js +350 -0
  72. package/dist/lib/config-write.js +41 -0
  73. package/dist/lib/custom-target.js +75 -0
  74. package/dist/lib/domain-utils.js +19 -0
  75. package/dist/lib/duration.js +39 -0
  76. package/dist/lib/env-order.js +236 -0
  77. package/dist/lib/env-secret.js +78 -0
  78. package/dist/lib/firestore-rest.js +326 -0
  79. package/dist/lib/framework-bin.js +156 -0
  80. package/dist/lib/gitignore.js +63 -0
  81. package/dist/lib/google-auth.js +495 -0
  82. package/dist/lib/google-token.js +66 -0
  83. package/dist/lib/jwt.js +31 -0
  84. package/dist/lib/legacy-oauth.js +59 -0
  85. package/dist/lib/node-version.js +127 -0
  86. package/dist/lib/owner-plan.js +78 -0
  87. package/dist/lib/package-scripts.js +152 -0
  88. package/dist/lib/preflight.js +470 -0
  89. package/dist/lib/product-create.js +144 -0
  90. package/dist/lib/run-command.js +74 -0
  91. package/dist/lib/run-gates.js +70 -0
  92. package/dist/lib/run-output.js +42 -0
  93. package/dist/lib/run-summary.js +384 -0
  94. package/dist/lib/scaffold.js +427 -0
  95. package/dist/lib/service-input.js +207 -0
  96. package/dist/lib/service-runner.js +466 -0
  97. package/dist/lib/stale.js +24 -0
  98. package/dist/lib/target-selection.js +155 -0
  99. package/dist/lib/verb-fanout.js +128 -0
  100. package/dist/lib/verify-live.js +188 -0
  101. package/dist/manage.js +311 -0
  102. package/dist/omega-bin.js +7 -0
  103. package/dist/onboard.js +532 -0
  104. package/dist/services/account/ensure/users.js +259 -0
  105. package/dist/services/account/index.js +97 -0
  106. package/dist/services/account/lib/backend-client.js +107 -0
  107. package/dist/services/account/lib/password.js +36 -0
  108. package/dist/services/account/lib/resolve-password.js +100 -0
  109. package/dist/services/advertising/ensure/sites.js +101 -0
  110. package/dist/services/advertising/index.js +101 -0
  111. package/dist/services/advertising/lib/adsense-api.js +41 -0
  112. package/dist/services/ai/ensure/keys.js +21 -0
  113. package/dist/services/ai/index.js +36 -0
  114. package/dist/services/analytics/ensure/google-firebase-link.js +230 -0
  115. package/dist/services/analytics/ensure/google-streams.js +256 -0
  116. package/dist/services/analytics/ensure/meta-pixel.js +22 -0
  117. package/dist/services/analytics/ensure/tiktok-pixel.js +22 -0
  118. package/dist/services/analytics/index.js +134 -0
  119. package/dist/services/analytics/lib/analytics-api.js +156 -0
  120. package/dist/services/analytics/lib/meta-api.js +83 -0
  121. package/dist/services/analytics/lib/pixel-account.js +78 -0
  122. package/dist/services/analytics/lib/pixel-provision.js +152 -0
  123. package/dist/services/analytics/lib/pixel-specs.js +57 -0
  124. package/dist/services/analytics/lib/pixel-token.js +88 -0
  125. package/dist/services/analytics/lib/property-flow.js +77 -0
  126. package/dist/services/analytics/lib/tiktok-api.js +157 -0
  127. package/dist/services/analytics/lib/tiktok-auth.js +153 -0
  128. package/dist/services/assets/ensure/logo-gen.js +68 -0
  129. package/dist/services/assets/index.js +109 -0
  130. package/dist/services/assets/lib/assets-config.js +168 -0
  131. package/dist/services/assets/lib/brandmark-api.js +160 -0
  132. package/dist/services/assets/lib/derived.js +113 -0
  133. package/dist/services/assets/lib/font-loader.js +67 -0
  134. package/dist/services/assets/lib/reconcile.js +122 -0
  135. package/dist/services/assets/lib/reset.js +118 -0
  136. package/dist/services/assets/lib/svg-logo-generator.js +154 -0
  137. package/dist/services/assets/lib/svg-to-black.js +32 -0
  138. package/dist/services/assets/write/favicons.js +82 -0
  139. package/dist/services/assets/write/icons.js +64 -0
  140. package/dist/services/assets/write/process.js +96 -0
  141. package/dist/services/assets/write/reconcile.js +30 -0
  142. package/dist/services/assets/write/social-icons.js +108 -0
  143. package/dist/services/assets/write/templates.js +345 -0
  144. package/dist/services/bookmark/ensure/sync.js +255 -0
  145. package/dist/services/bookmark/index.js +17 -0
  146. package/dist/services/campaigns/ensure/contact-person.js +40 -0
  147. package/dist/services/campaigns/ensure/custom-fields.js +84 -0
  148. package/dist/services/campaigns/ensure/domain-auth.js +92 -0
  149. package/dist/services/campaigns/ensure/event-webhook.js +89 -0
  150. package/dist/services/campaigns/ensure/link-branding.js +187 -0
  151. package/dist/services/campaigns/ensure/list.js +50 -0
  152. package/dist/services/campaigns/ensure/segments.js +109 -0
  153. package/dist/services/campaigns/ensure/sender-identity.js +153 -0
  154. package/dist/services/campaigns/ensure/unsubscribe-groups.js +116 -0
  155. package/dist/services/campaigns/index.js +79 -0
  156. package/dist/services/campaigns/lib/dns-sync.js +81 -0
  157. package/dist/services/campaigns/lib/segment-query.js +138 -0
  158. package/dist/services/campaigns/lib/sendgrid-api.js +287 -0
  159. package/dist/services/captcha/ensure/site-key.js +83 -0
  160. package/dist/services/captcha/index.js +78 -0
  161. package/dist/services/captcha/lib/console-url.js +45 -0
  162. package/dist/services/captcha/lib/recaptcha-api.js +36 -0
  163. package/dist/services/certificates/ensure/api-key.js +22 -0
  164. package/dist/services/certificates/ensure/bundle-ids.js +115 -0
  165. package/dist/services/certificates/ensure/certificates.js +187 -0
  166. package/dist/services/certificates/ensure/profiles.js +143 -0
  167. package/dist/services/certificates/index.js +225 -0
  168. package/dist/services/certificates/lib/apple-api.js +183 -0
  169. package/dist/services/certificates/lib/certificate-manager.js +252 -0
  170. package/dist/services/certificates/lib/identifier-manager.js +107 -0
  171. package/dist/services/certificates/lib/keychain.js +135 -0
  172. package/dist/services/certificates/lib/manual-walkthrough.js +165 -0
  173. package/dist/services/certificates/lib/profile-manager.js +115 -0
  174. package/dist/services/chat/data/baseline-knowledge.md +96 -0
  175. package/dist/services/chat/ensure/chat.js +106 -0
  176. package/dist/services/chat/ensure/user.js +45 -0
  177. package/dist/services/chat/index.js +139 -0
  178. package/dist/services/chat/lib/baseline-knowledge.js +137 -0
  179. package/dist/services/cloud/ensure/authentication.js +267 -0
  180. package/dist/services/cloud/ensure/billing.js +120 -0
  181. package/dist/services/cloud/ensure/cloud-messaging.js +105 -0
  182. package/dist/services/cloud/ensure/database.js +60 -0
  183. package/dist/services/cloud/ensure/firestore.js +79 -0
  184. package/dist/services/cloud/ensure/functions.js +49 -0
  185. package/dist/services/cloud/ensure/hosting.js +398 -0
  186. package/dist/services/cloud/ensure/oauth-consent.js +248 -0
  187. package/dist/services/cloud/ensure/project-settings.js +72 -0
  188. package/dist/services/cloud/ensure/sdk-config.js +95 -0
  189. package/dist/services/cloud/ensure/service-account.js +152 -0
  190. package/dist/services/cloud/ensure/services.js +103 -0
  191. package/dist/services/cloud/ensure/storage.js +47 -0
  192. package/dist/services/cloud/index.js +130 -0
  193. package/dist/services/cloud/lib/access-heal.js +130 -0
  194. package/dist/services/cloud/lib/firebase-api.js +662 -0
  195. package/dist/services/cloud/lib/project-flow.js +102 -0
  196. package/dist/services/directory/ensure/entry.js +48 -0
  197. package/dist/services/directory/index.js +64 -0
  198. package/dist/services/directory/lib/blocks.js +104 -0
  199. package/dist/services/disperse/index.js +45 -0
  200. package/dist/services/disperse/write/certs.js +117 -0
  201. package/dist/services/domain/ensure/nameservers.js +179 -0
  202. package/dist/services/domain/index.js +69 -0
  203. package/dist/services/domain/lib/namecheap-api.js +167 -0
  204. package/dist/services/domain/lib/registrars.js +46 -0
  205. package/dist/services/domain/lib/whitelist-walkthrough.js +76 -0
  206. package/dist/services/edge/ensure/cache-rules.js +105 -0
  207. package/dist/services/edge/ensure/dns-records.js +304 -0
  208. package/dist/services/edge/ensure/email-routing.js +292 -0
  209. package/dist/services/edge/ensure/rules-configuration.js +98 -0
  210. package/dist/services/edge/ensure/rules-managed-transforms.js +101 -0
  211. package/dist/services/edge/ensure/rules-redirect.js +107 -0
  212. package/dist/services/edge/ensure/rules-response-headers.js +90 -0
  213. package/dist/services/edge/ensure/rules-security.js +142 -0
  214. package/dist/services/edge/ensure/speed-scheduled-tests.js +98 -0
  215. package/dist/services/edge/ensure/workers.js +219 -0
  216. package/dist/services/edge/ensure/zone-settings.js +108 -0
  217. package/dist/services/edge/ensure/zone.js +183 -0
  218. package/dist/services/edge/index.js +73 -0
  219. package/dist/services/edge/lib/cloudflare-api.js +84 -0
  220. package/dist/services/edge/lib/dns-records-helpers.js +518 -0
  221. package/dist/services/edge/lib/read-cache.js +16 -0
  222. package/dist/services/edge/lib/ruleset-helper.js +108 -0
  223. package/dist/services/edge/workers/omega-api-proxy.js +43 -0
  224. package/dist/services/email/data/baseline-filter.md +4 -0
  225. package/dist/services/email/data/baseline-knowledge.md +86 -0
  226. package/dist/services/email/ensure/agent.js +107 -0
  227. package/dist/services/email/ensure/user.js +45 -0
  228. package/dist/services/email/index.js +138 -0
  229. package/dist/services/email/lib/baseline.js +82 -0
  230. package/dist/services/email/lib/knowledge-file.js +53 -0
  231. package/dist/services/forms/ensure/form.js +46 -0
  232. package/dist/services/forms/ensure/user.js +45 -0
  233. package/dist/services/forms/index.js +138 -0
  234. package/dist/services/migrations/ensure/notifications.js +189 -0
  235. package/dist/services/migrations/ensure/orders.js +34 -0
  236. package/dist/services/migrations/ensure/payment-provider.js +132 -0
  237. package/dist/services/migrations/ensure/payments-intents.js +34 -0
  238. package/dist/services/migrations/ensure/state-retirement.js +266 -0
  239. package/dist/services/migrations/ensure/targets-rename.js +124 -0
  240. package/dist/services/migrations/ensure/users.js +1176 -0
  241. package/dist/services/migrations/index.js +101 -0
  242. package/dist/services/migrations/lib/attribution-touch.js +64 -0
  243. package/dist/services/migrations/lib/ensure-metadata.js +144 -0
  244. package/dist/services/migrations/lib/migration-runner.js +473 -0
  245. package/dist/services/migrations/lib/sanitize-strings.js +112 -0
  246. package/dist/services/migrations/lib/schema-validator.js +154 -0
  247. package/dist/services/monitoring/ensure/dsn.js +54 -0
  248. package/dist/services/monitoring/ensure/projects.js +135 -0
  249. package/dist/services/monitoring/index.js +54 -0
  250. package/dist/services/monitoring/lib/sentry-api.js +94 -0
  251. package/dist/services/newsletter/ensure/custom-fields.js +90 -0
  252. package/dist/services/newsletter/ensure/publication.js +94 -0
  253. package/dist/services/newsletter/ensure/segments.js +140 -0
  254. package/dist/services/newsletter/ensure/webhook.js +108 -0
  255. package/dist/services/newsletter/index.js +64 -0
  256. package/dist/services/newsletter/lib/beehiiv-api.js +124 -0
  257. package/dist/services/newsletter/lib/segment-automation.js +577 -0
  258. package/dist/services/payment/ensure/chargebee-account.js +30 -0
  259. package/dist/services/payment/ensure/chargebee-products.js +359 -0
  260. package/dist/services/payment/ensure/chargebee-webhook.js +113 -0
  261. package/dist/services/payment/ensure/paypal-account.js +36 -0
  262. package/dist/services/payment/ensure/paypal-products.js +374 -0
  263. package/dist/services/payment/ensure/paypal-webhook.js +128 -0
  264. package/dist/services/payment/ensure/stripe-account.js +93 -0
  265. package/dist/services/payment/ensure/stripe-disputes.js +56 -0
  266. package/dist/services/payment/ensure/stripe-products.js +245 -0
  267. package/dist/services/payment/ensure/stripe-radar.js +74 -0
  268. package/dist/services/payment/ensure/stripe-webhook.js +130 -0
  269. package/dist/services/payment/index.js +163 -0
  270. package/dist/services/payment/lib/chargebee-api.js +338 -0
  271. package/dist/services/payment/lib/payment-utils.js +116 -0
  272. package/dist/services/payment/lib/paypal-api.js +354 -0
  273. package/dist/services/payment/lib/provider-setup.js +134 -0
  274. package/dist/services/payment/lib/stripe-api.js +152 -0
  275. package/dist/services/repo/ensure/org.js +70 -0
  276. package/dist/services/repo/ensure/pages.js +72 -0
  277. package/dist/services/repo/ensure/repo.js +90 -0
  278. package/dist/services/repo/index.js +52 -0
  279. package/dist/services/repo/lib/github-api.js +196 -0
  280. package/dist/services/search/ensure/ga-link.js +57 -0
  281. package/dist/services/search/ensure/property.js +137 -0
  282. package/dist/services/search/ensure/sitemaps.js +70 -0
  283. package/dist/services/search/index.js +61 -0
  284. package/dist/services/search/lib/search-console-api.js +92 -0
  285. package/dist/services/seo/ensure/github-repos.js +271 -0
  286. package/dist/services/seo/index.js +55 -0
  287. package/dist/services/seo/lib/gh-api.js +161 -0
  288. package/dist/services/seo/templates/developer-tool/.github/workflows/maintenance.yml +25 -0
  289. package/dist/services/seo/templates/developer-tool/.nvmrc +1 -0
  290. package/dist/services/seo/templates/developer-tool/_README.md.js +121 -0
  291. package/dist/services/seo/templates/developer-tool/_package.json.js +33 -0
  292. package/dist/services/seo/templates/developer-tool/src/index.js +120 -0
  293. package/dist/services/seo/templates/index.js +57 -0
  294. package/dist/services/server/ensure/brands.js +63 -0
  295. package/dist/services/server/index.js +42 -0
  296. package/dist/services/testing/ensure/target-checks.js +97 -0
  297. package/dist/services/testing/index.js +11 -0
  298. package/dist/services/testing/lib/checks.js +467 -0
  299. package/dist/services/update/index.js +20 -0
  300. package/dist/services/update/lib/cache.js +59 -0
  301. package/dist/services/update/lib/fingerprint.js +157 -0
  302. package/dist/services/update/write/targets.js +206 -0
  303. package/dist/services/workspace/ensure/agents.js +42 -0
  304. package/dist/services/workspace/ensure/claude-settings.js +34 -0
  305. package/dist/services/workspace/ensure/config.js +54 -0
  306. package/dist/services/workspace/ensure/defaults.js +60 -0
  307. package/dist/services/workspace/ensure/env-keys.js +55 -0
  308. package/dist/services/workspace/ensure/env-order.js +66 -0
  309. package/dist/services/workspace/ensure/env-rules.js +97 -0
  310. package/dist/services/workspace/ensure/gitignore.js +18 -0
  311. package/dist/services/workspace/ensure/scripts.js +126 -0
  312. package/dist/services/workspace/ensure/structure.js +97 -0
  313. package/dist/services/workspace/ensure/translation-sdk.js +148 -0
  314. package/dist/services/workspace/ensure/workflows.js +54 -0
  315. package/dist/services/workspace/index.js +8 -0
  316. package/dist/vendor/account/engine.js +182 -0
  317. package/dist/vendor/account/features.js +220 -0
  318. package/dist/vendor/account/index.js +53 -0
  319. package/dist/vendor/account/schema.js +272 -0
  320. package/dist/vendor/account/subscription.js +38 -0
  321. package/dist/vendor/config/company.js +31 -0
  322. package/dist/vendor/config/defaults.js +173 -0
  323. package/dist/vendor/config/demo.js +18 -0
  324. package/dist/vendor/config/desktop-artifacts.js +110 -0
  325. package/dist/vendor/config/edit.js +769 -0
  326. package/dist/vendor/config/env-delivery.js +145 -0
  327. package/dist/vendor/config/env-rules.js +93 -0
  328. package/dist/vendor/config/env-schema.js +1078 -0
  329. package/dist/vendor/config/env.js +445 -0
  330. package/dist/vendor/config/hooks.js +97 -0
  331. package/dist/vendor/config/index.js +237 -0
  332. package/dist/vendor/config/instances.js +208 -0
  333. package/dist/vendor/config/load.js +490 -0
  334. package/dist/vendor/config/merge.js +68 -0
  335. package/dist/vendor/config/order.js +139 -0
  336. package/dist/vendor/config/ports.js +374 -0
  337. package/dist/vendor/config/providers.js +32 -0
  338. package/dist/vendor/config/repo.js +142 -0
  339. package/dist/vendor/config/retired-keys.js +430 -0
  340. package/dist/vendor/config/schema.js +1610 -0
  341. package/dist/vendor/config/secrets.js +50 -0
  342. package/dist/vendor/config/seed.js +34 -0
  343. package/dist/vendor/config/site-global.js +205 -0
  344. package/dist/vendor/config/validate.js +554 -0
  345. package/dist/vendor/config/winback.js +61 -0
  346. package/dist/vendor/devkit/attach-log-file.js +262 -0
  347. package/dist/vendor/devkit/certs.js +199 -0
  348. package/dist/vendor/devkit/ci-workflows.js +520 -0
  349. package/dist/vendor/devkit/cli-router.js +156 -0
  350. package/dist/vendor/devkit/command-path.js +46 -0
  351. package/dist/vendor/devkit/deploy-record.js +180 -0
  352. package/dist/vendor/devkit/flows.js +317 -0
  353. package/dist/vendor/devkit/local-https.js +360 -0
  354. package/dist/vendor/devkit/local.js +1905 -0
  355. package/dist/vendor/devkit/logger.js +128 -0
  356. package/dist/vendor/devkit/omega-bin.js +345 -0
  357. package/dist/vendor/devkit/prompt.js +187 -0
  358. package/dist/vendor/devkit/safe-install.js +18 -0
  359. package/dist/vendor/devkit/stop-signals.js +28 -0
  360. package/dist/vendor/devkit/test/scope.js +162 -0
  361. package/dist/vendor/devkit/translate/cache.js +84 -0
  362. package/dist/vendor/devkit/translate/engine.js +243 -0
  363. package/dist/vendor/devkit/translate/index.js +49 -0
  364. package/dist/vendor/devkit/translate/languages.js +134 -0
  365. package/dist/vendor/devkit/translate/providers.js +188 -0
  366. package/dist/vendor/devkit/update.js +569 -0
  367. package/docs/AGENTS.md +200 -0
  368. package/docs/account.md +45 -0
  369. package/docs/advertising.md +46 -0
  370. package/docs/ai.md +34 -0
  371. package/docs/analytics.md +69 -0
  372. package/docs/assets.md +57 -0
  373. package/docs/bookmark.md +26 -0
  374. package/docs/brand.md +151 -0
  375. package/docs/campaigns.md +96 -0
  376. package/docs/captcha.md +46 -0
  377. package/docs/certificates.md +68 -0
  378. package/docs/chat.md +47 -0
  379. package/docs/cloud.md +110 -0
  380. package/docs/company.md +64 -0
  381. package/docs/directory.md +140 -0
  382. package/docs/disperse.md +46 -0
  383. package/docs/domain.md +56 -0
  384. package/docs/edge.md +234 -0
  385. package/docs/email.md +42 -0
  386. package/docs/forms.md +48 -0
  387. package/docs/index.md +109 -0
  388. package/docs/migration.md +203 -0
  389. package/docs/migrations.md +56 -0
  390. package/docs/monitoring.md +41 -0
  391. package/docs/newsletter.md +48 -0
  392. package/docs/payment.md +83 -0
  393. package/docs/repo.md +48 -0
  394. package/docs/search.md +44 -0
  395. package/docs/seo.md +34 -0
  396. package/docs/server.md +37 -0
  397. package/docs/shared/agent-docs.md +89 -0
  398. package/docs/shared/analytics.md +612 -0
  399. package/docs/shared/brands.md +51 -0
  400. package/docs/shared/breaking-changes.md +497 -0
  401. package/docs/shared/config.md +1387 -0
  402. package/docs/shared/deploys.md +215 -0
  403. package/docs/shared/icons.md +201 -0
  404. package/docs/shared/local-dev.md +147 -0
  405. package/docs/shared/logging.md +202 -0
  406. package/docs/shared/monitoring.md +153 -0
  407. package/docs/shared/publishing.md +183 -0
  408. package/docs/shared/rulings.md +34 -0
  409. package/docs/shared/testing.md +147 -0
  410. package/docs/shared/theming.md +604 -0
  411. package/docs/shared/translation.md +291 -0
  412. package/docs/shared/updates.md +61 -0
  413. package/docs/testing.md +34 -0
  414. package/docs/update.md +36 -0
  415. package/docs/workspace.md +64 -0
  416. package/package.json +88 -0
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env bash
2
+ # omega:inject — UserPromptSubmit hook
3
+ # Reads the project's package.json and asks the session to invoke the matching
4
+ # framework skill. At a BRAND root the nearest manifest carries the manager
5
+ # alone, so the brand's targets are discovered too (config/omega.json5 and
6
+ # every targets/*/package.json) and the whole set is asked for at once, with
7
+ # the framework map named as required reading.
8
+ # Once per session per skill; fails open on anything unexpected.
9
+
10
+ set -euo pipefail
11
+
12
+ input=$(cat)
13
+
14
+ command -v jq >/dev/null 2>&1 || exit 0
15
+
16
+ session_id=$(jq -r '.session_id // ""' <<<"$input" 2>/dev/null || true)
17
+ cwd=$(jq -r '.cwd // ""' <<<"$input" 2>/dev/null || true)
18
+ [ -n "$cwd" ] && [ -d "$cwd" ] || exit 0
19
+
20
+ # The project's package.json: the cwd's own, else the nearest one above it —
21
+ # stopping at the git root, since past it is somebody else's project.
22
+ manifest=""
23
+ dir="$cwd"
24
+ while [ -n "$dir" ] && [ "$dir" != "/" ]; do
25
+ if [ -f "$dir/package.json" ]; then
26
+ manifest="$dir/package.json"
27
+ break
28
+ fi
29
+ [ -e "$dir/.git" ] && break
30
+ dir=$(dirname "$dir")
31
+ done
32
+ [ -n "$manifest" ] || exit 0
33
+
34
+ # Backend apps keep @omega.js/backend in functions/package.json with a plain
35
+ # app manifest at the root, so the functions manifest joins the dep pool.
36
+ fn_manifest="$(dirname "$manifest")/functions/package.json"
37
+
38
+ own_name=$(jq -r '.name // empty' "$manifest" 2>/dev/null || true)
39
+ deps=$(jq -r '((.dependencies // {}) | keys) + ((.devDependencies // {}) | keys) | .[]' "$manifest" 2>/dev/null || true)
40
+ if [ -f "$fn_manifest" ]; then
41
+ fn_deps=$(jq -r '((.dependencies // {}) | keys) + ((.devDependencies // {}) | keys) | .[]' "$fn_manifest" 2>/dev/null || true)
42
+ deps=$(printf '%s\n%s' "$deps" "$fn_deps")
43
+ fi
44
+
45
+ # package → skill lives in the shared table (hooks/lib/omega-skills.sh), the one
46
+ # the gate hook reads too. These rows only say HOW a package matches: every row
47
+ # matches the manifest's OWN name, which is what covers working inside
48
+ # `packages/<pkg>` in the monorepo, and `name` rows match ONLY that way —
49
+ # web, desktop, and extension all depend on the client runtime, so a dependency
50
+ # on it says nothing about what the session works on.
51
+ skills_lib="$(dirname "${BASH_SOURCE[0]}")/../lib/omega-skills.sh"
52
+ [ -r "$skills_lib" ] || exit 0
53
+ # shellcheck source-path=SCRIPTDIR source=../lib/omega-skills.sh
54
+ . "$skills_lib"
55
+
56
+ matched=()
57
+ while read -r pkg signal; do
58
+ [ -n "$pkg" ] || continue
59
+ skill=$(omega_skill_for "$pkg")
60
+ [ -n "$skill" ] || continue
61
+ if [ "$own_name" = "$pkg" ]; then
62
+ matched+=("$skill")
63
+ elif [ "$signal" != "name" ] && grep -qxF "$pkg" <<<"$deps"; then
64
+ matched+=("$skill")
65
+ fi
66
+ done <<'MAP'
67
+ @omega.js/web any
68
+ @omega.js/backend any
69
+ @omega.js/desktop any
70
+ @omega.js/extension any
71
+ @omega.js/manager any
72
+ @omega.js/client name
73
+ omega name
74
+ MAP
75
+
76
+ # Brand-level discovery. A brand root's manifest carries @omega.js/manager and
77
+ # nothing else, so the frameworks a brand actually runs live one level down, in
78
+ # config/omega.json5 and each targets/*/package.json. Read them all: a session
79
+ # at a brand root has to know about every target before it edits one.
80
+ brand_root=$(omega_brand_root "$cwd")
81
+ if [ -n "$brand_root" ]; then
82
+ while read -r skill; do
83
+ [ -n "$skill" ] || continue
84
+ matched+=("$skill")
85
+ done < <(omega_brand_skills "$brand_root")
86
+ fi
87
+
88
+ [ "${#matched[@]}" -gt 0 ] || exit 0
89
+
90
+ # One injection per session per skill.
91
+ marker_dir="${TMPDIR:-/tmp}/omega-inject"
92
+ mkdir -p "$marker_dir" 2>/dev/null || true
93
+ safe_session="${session_id//[^a-zA-Z0-9]/_}"
94
+
95
+ fresh=()
96
+ for skill in $(printf '%s\n' "${matched[@]}" | sort -u); do
97
+ marker="$marker_dir/${safe_session}__${skill//[:\/]/_}.loaded"
98
+ [ -f "$marker" ] && continue
99
+ : > "$marker" 2>/dev/null || true
100
+ fresh+=("$skill")
101
+ done
102
+
103
+ [ "${#fresh[@]}" -gt 0 ] || exit 0
104
+
105
+ if [ "${#fresh[@]}" -eq 1 ]; then
106
+ ctx="OMEGA project detected: invoke the ${fresh[0]} skill via the Skill tool before responding. Follow its rules and the framework docs it routes to for any work in this project. (Injected once per session; do not re-invoke on later prompts unless the work shifts.)"
107
+ else
108
+ skill_list=$(printf ', %s' "${fresh[@]}")
109
+ skill_list="${skill_list:2}"
110
+ ctx="OMEGA project detected: invoke these skills via the Skill tool before responding: ${skill_list}. Follow their rules and the framework docs they route to for any work in this project. (Injected once per session; do not re-invoke on later prompts unless the work shifts.)"
111
+ fi
112
+
113
+ # In a brand, the skills and the framework map are REQUIRED reading before the
114
+ # first edit, not a suggestion — the gate hook refuses a target edit until the
115
+ # skill that owns it was invoked.
116
+ if [ -n "$brand_root" ]; then
117
+ ctx="$ctx
118
+ This is an OMEGA brand monorepo: every skill above, plus the framework map it points at (the brand AGENTS.md import line — node_modules/@omega.js/AGENTS.md), is required reading BEFORE the first edit. Writes under targets/ and to config/omega.json5 are refused until the skill owning that surface has been invoked."
119
+ fi
120
+
121
+ jq -n --arg ctx "$ctx" '{
122
+ "hookSpecificOutput": {
123
+ "hookEventName": "UserPromptSubmit",
124
+ "additionalContext": $ctx
125
+ }
126
+ }'
127
+ exit 0
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bash
2
+ # omega gate markers — sourced by the two writers of a gate marker: the gate
3
+ # hook itself (PostToolUse Skill) and mark.sh (the one command an agent with no
4
+ # Skill tool runs after reading the guide). ONE home for where a marker lives
5
+ # and what it is called, so the two lanes can never disagree about the name.
6
+
7
+ # omega_gate_state_dir
8
+ # The marker directory. Under TMPDIR so it dies with the machine's temp state;
9
+ # never created here — each caller decides what an unusable directory means.
10
+ omega_gate_state_dir() {
11
+ printf '%s/omega-gate\n' "${TMPDIR:-/tmp}"
12
+ }
13
+
14
+ # omega_gate_marker <session_id> <skill>
15
+ # The marker path for one skill in one session. Both halves are flattened to
16
+ # safe filename characters, so a session id or a skill spelling can never walk
17
+ # out of the state directory.
18
+ omega_gate_marker() {
19
+ printf '%s/%s__%s.invoked\n' "$(omega_gate_state_dir)" "${1//[^a-zA-Z0-9]/_}" "${2//[:\/]/_}"
20
+ }
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env bash
2
+ # omega scope guard — sourced by the hooks that police a FILE path (shape,
3
+ # quality). One home for the question "is this file inside an omega project?",
4
+ # so the two guards can never disagree about what they police.
5
+ # The inject hook asks a different question (a project from a cwd, with its
6
+ # functions/ manifest joined in) and keeps its own walk.
7
+
8
+ # omega_scope <file_path>
9
+ # Walks up from the file to the nearest package.json, stopping at the git root
10
+ # (past it is somebody else's project), and succeeds only when that manifest IS
11
+ # or DEPENDS ON an @omega.js/* package. Returns 1 on no manifest, no jq, or
12
+ # unparseable JSON — the fail-open answer for a hook.
13
+ omega_scope() {
14
+ local file_path="$1"
15
+ [ -n "$file_path" ] || return 1
16
+ command -v jq >/dev/null 2>&1 || return 1
17
+
18
+ local dir manifest omega_linked
19
+ dir=$(dirname "$file_path")
20
+ manifest=""
21
+ while [ -n "$dir" ] && [ "$dir" != "/" ]; do
22
+ if [ -f "$dir/package.json" ]; then
23
+ manifest="$dir/package.json"
24
+ break
25
+ fi
26
+ if [ -e "$dir/.git" ]; then
27
+ break
28
+ fi
29
+ dir=$(dirname "$dir")
30
+ done
31
+ [ -n "$manifest" ] || return 1
32
+
33
+ omega_linked=$(jq -r '
34
+ [.name // ""] + ((.dependencies // {}) | keys) + ((.devDependencies // {}) | keys)
35
+ | map(select(startswith("@omega.js/"))) | length
36
+ ' "$manifest" 2>/dev/null || echo 0)
37
+ case "$omega_linked" in
38
+ ''|*[!0-9]*) return 1 ;;
39
+ esac
40
+ [ "$omega_linked" -gt 0 ] || return 1
41
+ }
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env bash
2
+ # omega skill map — sourced by the hooks that answer "which skill owns this?"
3
+ # (inject, gate). ONE home for the framework → skill table and for the brand
4
+ # walk. The two hooks share the map but ask different questions of it: inject
5
+ # also reads config target keys, while the gate resolves a target from its
6
+ # manifest alone — a config-declared target with no manifest yet is asked for
7
+ # and not gated (fail-open by design).
8
+ # Every function fails open: unreadable files and unparseable JSON answer
9
+ # "nothing here", never an error.
10
+
11
+ # omega_skill_for <token>
12
+ # The one table — every hook that maps a thing to a skill reads THIS. Takes a
13
+ # package name (@omega.js/web), a config target key (web), or a monorepo
14
+ # package directory name (web): three spellings of the same fact. Prints the
15
+ # skill, or nothing when no skill owns the token:
16
+ # a custom target, `mobile` (parked), and the internal packages (devkit,
17
+ # config, account, analytics, monitoring, template-kit, mcp-router) all land
18
+ # here deliberately.
19
+ omega_skill_for() {
20
+ case "$1" in
21
+ @omega.js/web|web|website) echo 'omega:web' ;;
22
+ @omega.js/backend|backend) echo 'omega:backend' ;;
23
+ @omega.js/desktop|desktop) echo 'omega:desktop' ;;
24
+ @omega.js/extension|extension) echo 'omega:extension' ;;
25
+ @omega.js/manager|manager) echo 'omega:manager' ;;
26
+ @omega.js/client|client) echo 'omega:client' ;;
27
+ omega) echo 'omega:main' ;;
28
+ esac
29
+ }
30
+
31
+ # omega_manifest_deps <manifest>
32
+ # Every dependency name in a package.json, both blocks, one per line.
33
+ omega_manifest_deps() {
34
+ [ -f "$1" ] || return 0
35
+ jq -r '((.dependencies // {}) | keys) + ((.devDependencies // {}) | keys) | .[]' "$1" 2>/dev/null || true
36
+ }
37
+
38
+ # omega_brand_root <dir>
39
+ # Walks up from a directory to the git root (inclusive) and prints the first
40
+ # BRAND root it finds: a directory carrying config/omega.json5, or one whose
41
+ # package.json depends on @omega.js/manager. Prints nothing when the walk
42
+ # leaves no brand behind — a framework package, a plain project, the monorepo
43
+ # root itself.
44
+ omega_brand_root() {
45
+ local dir="$1"
46
+ [ -n "$dir" ] || return 0
47
+ # `dirname` bottoms out at "." for a relative path and stays there forever,
48
+ # so the walk below would never terminate. Nothing to resolve, answer nothing.
49
+ case "$dir" in /*) ;; *) return 0 ;; esac
50
+ while [ -n "$dir" ] && [ "$dir" != "/" ]; do
51
+ if [ -f "$dir/config/omega.json5" ]; then
52
+ printf '%s\n' "$dir"
53
+ return 0
54
+ fi
55
+ if [ -f "$dir/package.json" ] && omega_manifest_deps "$dir/package.json" | grep -qxF '@omega.js/manager'; then
56
+ printf '%s\n' "$dir"
57
+ return 0
58
+ fi
59
+ [ -e "$dir/.git" ] && return 0
60
+ dir=$(dirname "$dir")
61
+ done
62
+ }
63
+
64
+ # omega_config_target_keys <config/omega.json5>
65
+ # The immediate child keys of the config's `targets` block, one per line. The
66
+ # config is JSON5 (comments, unquoted keys, trailing commas), so jq cannot read
67
+ # it and a key scan is the whole job: brace-depth tracking from the `targets:`
68
+ # line, printing keys at depth 1. Nothing here is load-bearing — a miss just
69
+ # means the key's skill has to come from the target's own manifest.
70
+ omega_config_target_keys() {
71
+ [ -r "$1" ] || return 0
72
+ awk '
73
+ BEGIN { started = 0; depth = 0 }
74
+ {
75
+ line = $0
76
+ # A comment starts at line start or after whitespace — never mid-token,
77
+ # which is what keeps a "https://…" value from eating its own braces.
78
+ sub(/^[[:space:]]*\/\/.*$/, "", line)
79
+ sub(/[[:space:]]\/\/.*$/, "", line)
80
+ }
81
+ !started {
82
+ if (line ~ /^[[:space:]]*"?targets"?[[:space:]]*:[[:space:]]*\{/) { started = 1; depth = 1 }
83
+ next
84
+ }
85
+ {
86
+ if (depth == 1 && line ~ /^[[:space:]]*["'"'"']?[A-Za-z_][A-Za-z0-9_-]*["'"'"']?[[:space:]]*:/) {
87
+ key = line
88
+ sub(/^[[:space:]]*/, "", key)
89
+ sub(/[[:space:]]*:.*$/, "", key)
90
+ gsub(/["'"'"']/, "", key)
91
+ print key
92
+ }
93
+ depth += gsub(/\{/, "{", line) - gsub(/\}/, "}", line)
94
+ if (depth <= 0) exit
95
+ }
96
+ ' "$1" 2>/dev/null || true
97
+ }
98
+
99
+ # omega_brand_skills <brand_root>
100
+ # Every skill a brand session needs, one per line, unsorted and possibly
101
+ # repeated: omega:main and omega:manager (always, in a brand), plus one skill
102
+ # per target — read from every targets/*/package.json (and the functions/
103
+ # manifest a Firebase backend keeps its framework in) AND from the config's
104
+ # own target keys, so a target declared before its directory exists still
105
+ # counts. A target no framework owns contributes nothing.
106
+ omega_brand_skills() {
107
+ local root="$1" manifest dep key
108
+ echo 'omega:main'
109
+ echo 'omega:manager'
110
+
111
+ for manifest in "$root"/targets/*/package.json "$root"/targets/*/functions/package.json; do
112
+ [ -f "$manifest" ] || continue
113
+ while read -r dep; do
114
+ [ -n "$dep" ] || continue
115
+ omega_skill_for "$dep"
116
+ done < <(omega_manifest_deps "$manifest")
117
+ done
118
+
119
+ while read -r key; do
120
+ [ -n "$key" ] || continue
121
+ omega_skill_for "$key"
122
+ done < <(omega_config_target_keys "$root/config/omega.json5")
123
+ }
124
+
125
+ # omega_theme_surface <path-relative-to-a-package-or-target-root>
126
+ # Whether a path is one of the theme cascade's OWN surfaces — the layers
127
+ # `resolveThemeLayers`/`overrideLanes` walk (packages/web's packaged themes, a
128
+ # consumer-local theme at src/themes/<id>, the section folders a consumer
129
+ # shadows — `_sections` AND `_components`, which overrideLanes resolves as one
130
+ # lane — and the tier-1 scss entry). One table serves the monorepo and a
131
+ # brand alike, since the caller passes the path relative to the package or
132
+ # target root.
133
+ omega_theme_surface() {
134
+ case "$1" in
135
+ themes/*|src/themes/*|src/_sections/*|src/_components/*|src/assets/css/main.scss) return 0 ;;
136
+ esac
137
+ return 1
138
+ }
139
+
140
+ # omega_skill_for_file <file_path>
141
+ # The skill(s) that OWN an editable surface, one per line, or nothing when no
142
+ # skill does. The surface's own skill comes first; omega:theme joins it on a
143
+ # theme surface (omega_theme_surface above), so a theme edit answers to both.
144
+ # Three surfaces gate, and only these three:
145
+ # <brand>/targets/<t>/** the target's own framework skill
146
+ # <brand>/config/omega.json5 omega:manager — the file the manage walk reconciles
147
+ # <monorepo>/packages/<pkg>/** that package's skill, where one exists
148
+ # Everything else — docs, scripts, the plugin's own files, a brand's root
149
+ # files, an internal package — answers nothing and stays free.
150
+ omega_skill_for_file() {
151
+ local file_path="$1"
152
+ [ -n "$file_path" ] || return 0
153
+ command -v jq >/dev/null 2>&1 || return 0
154
+
155
+ local brand rest target manifest skill
156
+
157
+ # The monorepo's own packages, ASKED FIRST: a package tree owns everything
158
+ # inside it, so a brand-shaped fixture living in one (devkit's test fixtures)
159
+ # is that package's business and never a brand of its own. The FIRST
160
+ # packages/ segment names the package — a nested packages/ inside a fixture
161
+ # cannot answer — and the manifest has to BE @omega.js/<pkg>; any other
162
+ # repo's packages/ directory falls through to the brand walk below.
163
+ case "$file_path" in
164
+ */packages/*/*)
165
+ rest="${file_path#*/packages/}"
166
+ target="${rest%%/*}"
167
+ manifest="${file_path%/packages/"$rest"}/packages/$target/package.json"
168
+ if [ -f "$manifest" ] && [ "$(jq -r '.name // ""' "$manifest" 2>/dev/null || true)" = "@omega.js/$target" ]; then
169
+ skill=$(omega_skill_for "@omega.js/$target")
170
+ [ -n "$skill" ] && printf '%s\n' "$skill"
171
+ if [ "$skill" = 'omega:web' ] && omega_theme_surface "${rest#"$target"/}"; then
172
+ echo 'omega:theme'
173
+ fi
174
+ return 0
175
+ fi
176
+ ;;
177
+ esac
178
+
179
+ brand=$(omega_brand_root "$(dirname "$file_path")")
180
+ if [ -n "$brand" ]; then
181
+ case "$file_path" in
182
+ "$brand"/config/omega.json5)
183
+ echo 'omega:manager'
184
+ return 0
185
+ ;;
186
+ "$brand"/targets/*/*)
187
+ rest="${file_path#"$brand"/targets/}"
188
+ target="${rest%%/*}"
189
+ for manifest in "$brand/targets/$target/package.json" "$brand/targets/$target/functions/package.json"; do
190
+ [ -f "$manifest" ] || continue
191
+ while read -r dep; do
192
+ [ -n "$dep" ] || continue
193
+ skill=$(omega_skill_for "$dep")
194
+ if [ -n "$skill" ]; then
195
+ printf '%s\n' "$skill"
196
+ # The cascade is a web mechanism, so only a website target's own
197
+ # theme surfaces add it — a themes/ dir in a backend is not one.
198
+ if [ "$skill" = 'omega:web' ] && omega_theme_surface "${rest#"$target"/}"; then
199
+ echo 'omega:theme'
200
+ fi
201
+ return 0
202
+ fi
203
+ done < <(omega_manifest_deps "$manifest")
204
+ done
205
+ return 0
206
+ ;;
207
+ esac
208
+ fi
209
+ }
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ # omega:quality — PostToolUse (Write|Edit) + Stop hook
3
+ # Fires the quality skills deterministically instead of by model judgment: a
4
+ # write to a web surface asks for the skills that own it (omega:seo,
5
+ # omega:accessibility, omega:brandcheck), a write to a flow or money surface
6
+ # asks for omega:analytics, and the Stop pass refuses a sign-off
7
+ # that never went through their checklists. One script for both events so the
8
+ # surface table has ONE home; the event comes off hook_event_name.
9
+ # Fails open on anything unexpected, and only polices projects that depend on
10
+ # (or are) @omega.js/*.
11
+
12
+ set -euo pipefail
13
+
14
+ input=$(cat)
15
+
16
+ command -v jq >/dev/null 2>&1 || exit 0
17
+
18
+ event=$(jq -r '.hook_event_name // ""' <<<"$input" 2>/dev/null || true)
19
+ session_id=$(jq -r '.session_id // ""' <<<"$input" 2>/dev/null || true)
20
+
21
+ state_dir="${TMPDIR:-/tmp}/omega-quality"
22
+ safe_session="${session_id//[^a-zA-Z0-9]/_}"
23
+ pending="$state_dir/${safe_session}.pending"
24
+
25
+ # --- Stop: the re-check -------------------------------------------------------
26
+ # Blocks once on the web surfaces edited since the last block, then clears the
27
+ # list so a re-armed session needs a fresh edit. stop_hook_active means the
28
+ # block already ran on this turn.
29
+ if [ "$event" = "Stop" ]; then
30
+ stop_hook_active=$(jq -r '.stop_hook_active // false' <<<"$input" 2>/dev/null || true)
31
+ if [ "$stop_hook_active" = "true" ]; then
32
+ exit 0
33
+ fi
34
+ [ -s "$pending" ] || exit 0
35
+
36
+ # TAB-delimited on both sides: a path may contain spaces.
37
+ files=$(cut -d"$(printf '\t')" -f1 <"$pending" | sort -u)
38
+ skills=$(cut -d"$(printf '\t')" -f2 <"$pending" | tr ',' '\n' | sed '/^$/d' | sort -u | tr '\n' ',' | sed 's/,$//; s/,/, /g')
39
+ count=$(printf '%s\n' "$files" | grep -c . || true)
40
+ rm -f "$pending" 2>/dev/null || true
41
+
42
+ ctx="omega:quality — $count web surface(s) were edited this session:
43
+ $files
44
+
45
+ Before signing off, walk each edited surface against the checklists in: ${skills}. Invoke the skill via the Skill tool if it is not loaded, report what you checked, and fix what fails. If a checklist item does not apply to the change, say so — do not skip the pass silently."
46
+
47
+ jq -n --arg ctx "$ctx" '{
48
+ "decision": "block",
49
+ "reason": "omega:quality — edited web surfaces have not been reviewed against the quality checklists.",
50
+ "hookSpecificOutput": {
51
+ "hookEventName": "Stop",
52
+ "additionalContext": $ctx
53
+ }
54
+ }'
55
+ exit 0
56
+ fi
57
+
58
+ # --- PostToolUse: the surface match ------------------------------------------
59
+ file_path=$(jq -r '.tool_input.file_path // ""' <<<"$input" 2>/dev/null || true)
60
+ [ -n "$file_path" ] || exit 0
61
+
62
+ # The surface table: a path pattern → the skills that own that surface. Rows
63
+ # accumulate, so head.html matches both its include row and its seo row.
64
+ matched=()
65
+ while read -r pattern skills; do
66
+ [ -n "$pattern" ] || continue
67
+ # The unquoted pattern is the point — case globs it.
68
+ # shellcheck disable=SC2254
69
+ case "$file_path" in
70
+ $pattern) matched+=("$skills") ;;
71
+ esac
72
+ done <<'MAP'
73
+ */pages/*.html omega:seo,omega:accessibility
74
+ */pages/*.md omega:seo,omega:accessibility
75
+ */_layouts/* omega:seo,omega:accessibility
76
+ *.liquid omega:seo,omega:accessibility
77
+ */_includes/core/head.html omega:seo
78
+ */_includes/core/foot.html omega:seo
79
+ */_includes/*.html omega:accessibility
80
+ */sections/*.html omega:accessibility
81
+ */components/*.html omega:accessibility
82
+ */assets/js/*.js omega:accessibility
83
+ */core/js/*.js omega:accessibility
84
+ *.scss omega:accessibility,omega:brandcheck
85
+ *.css omega:accessibility,omega:brandcheck
86
+ */omega.json5 omega:brandcheck
87
+ */_includes/*.json omega:brandcheck
88
+ */sections/*.json5 omega:brandcheck
89
+ */core/js/pages/* omega:analytics
90
+ */core/js/libs/auth/* omega:analytics
91
+ */routes/payments/* omega:analytics
92
+ */events/firestore/payments-webhooks/* omega:analytics
93
+ */events/auth/* omega:analytics
94
+ */packages/analytics/* omega:analytics
95
+ MAP
96
+
97
+ [ "${#matched[@]}" -gt 0 ] || exit 0
98
+
99
+ # Scope guard: only police projects that depend on (or are) @omega.js/*.
100
+ scope_lib="$(dirname "${BASH_SOURCE[0]}")/../lib/omega-scope.sh"
101
+ [ -r "$scope_lib" ] || exit 0
102
+ # shellcheck source-path=SCRIPTDIR source=../lib/omega-scope.sh
103
+ . "$scope_lib"
104
+ omega_scope "$file_path" || exit 0
105
+
106
+ owners=$(printf '%s\n' "${matched[@]}" | tr ',' '\n' | sort -u | paste -sd, -)
107
+
108
+ # Arm the Stop re-check with this surface.
109
+ mkdir -p "$state_dir" 2>/dev/null || true
110
+ printf '%s\t%s\n' "$file_path" "$owners" >>"$pending" 2>/dev/null || true
111
+
112
+ # The reminder itself is once per session per skill — the same rule the inject
113
+ # hook follows. The Stop pass is what carries the per-file accounting.
114
+ fresh=()
115
+ for skill in $(printf '%s' "$owners" | tr ',' '\n'); do
116
+ marker="$state_dir/${safe_session}__${skill//[:\/]/_}.asked"
117
+ [ -f "$marker" ] && continue
118
+ : > "$marker" 2>/dev/null || true
119
+ fresh+=("$skill")
120
+ done
121
+ [ "${#fresh[@]}" -gt 0 ] || exit 0
122
+
123
+ skill_list=$(printf ', %s' "${fresh[@]}")
124
+ skill_list="${skill_list:2}"
125
+
126
+ jq -n --arg ctx "omega:quality — web surface edited ($file_path): invoke ${skill_list} via the Skill tool and hold this work to the checklists you find there. (Named once per session per skill; the Stop pass re-checks every edited surface before sign-off.)" '{
127
+ "hookSpecificOutput": {
128
+ "hookEventName": "PostToolUse",
129
+ "additionalContext": $ctx
130
+ }
131
+ }'
132
+ exit 0
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bash
2
+ # omega:shape — PreToolUse (Write|Edit) hook
3
+ # Bounces test files written in the three always-wrong shapes for this
4
+ # ecosystem: a __tests__/ path segment, a *.spec.js filename, and a
5
+ # test/tests/ nesting. The layer CHOICE stays judgment (docs/shared/testing.md
6
+ # owns the mantra); this guards only the mechanical suite shape. Fails open on
7
+ # anything unexpected, and only polices projects that depend on @omega.js/*.
8
+
9
+ set -euo pipefail
10
+
11
+ input=$(cat)
12
+
13
+ command -v jq >/dev/null 2>&1 || exit 0
14
+
15
+ file_path=$(jq -r '.tool_input.file_path // ""' <<<"$input" 2>/dev/null || true)
16
+ [ -n "$file_path" ] || exit 0
17
+
18
+ # Only test-shaped writes are in scope at all.
19
+ base=$(basename "$file_path")
20
+ case "$file_path" in
21
+ *__tests__/*|*/test/tests/*) ;;
22
+ *)
23
+ case "$base" in
24
+ *.spec.js|*.spec.ts|*.spec.mjs|*.spec.cjs) ;;
25
+ *) exit 0 ;;
26
+ esac
27
+ ;;
28
+ esac
29
+
30
+ # Scope guard: only police projects that depend on (or are) @omega.js/*.
31
+ scope_lib="$(dirname "${BASH_SOURCE[0]}")/../lib/omega-scope.sh"
32
+ [ -r "$scope_lib" ] || exit 0
33
+ # shellcheck source-path=SCRIPTDIR source=../lib/omega-scope.sh
34
+ . "$scope_lib"
35
+ omega_scope "$file_path" || exit 0
36
+
37
+ cat >&2 <<EOF
38
+ omega:shape — test suite shape violation: $file_path
39
+ The omega ecosystem's mirrored suite shape (docs/shared/testing.md in the
40
+ Omega repo) has one home for tests: top-level test/ mirroring the source
41
+ tree, *.test.js filenames (desktop/extension FRAMEWORK suites live at
42
+ src/test/ — the recorded exception). Never __tests__/ directories, *.spec.*
43
+ names, or test/tests/ nesting. Write it as test/<mirror>/<name>.test.js.
44
+ EOF
45
+ exit 2
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * The plugin's MCP entry — ONE launcher, correct in both eras
4
+ * ([#144](https://github.com/Omega-JS-Stack/omega/issues/144)).
5
+ *
6
+ * `.mcp.json` points at this file through `${CLAUDE_PLUGIN_ROOT}`, so the
7
+ * declaration never addresses a path outside the plugin. Node resolution from
8
+ * the plugin's OWN directory then finds the router wherever it lives: the
9
+ * workspace copy when the plugin is read live from this monorepo, and the
10
+ * installed `@omega.js/mcp-router` — wherever npm hoisted it — when the plugin
11
+ * is vendored into `@omega.js/manager` inside a consumer brand.
12
+ *
13
+ * The router package declares no `exports` map, so its bin is resolvable by
14
+ * subpath; requiring it starts the stdio server (which self-bootstraps its own
15
+ * dependencies on a bare checkout). Stdout is the MCP wire — the failure path
16
+ * speaks on stderr only, in the router's own voice.
17
+ */
18
+
19
+ const ROUTER_BIN = '@omega.js/mcp-router/bin/mcp-router.js';
20
+
21
+ let entry;
22
+ try {
23
+ entry = require.resolve(ROUTER_BIN, { paths: [__dirname] });
24
+ } catch {
25
+ process.stderr.write(`[mcp-router fatal] cannot resolve ${ROUTER_BIN} from ${__dirname} — install @omega.js/mcp-router beside the plugin\n`);
26
+ process.exit(1);
27
+ }
28
+
29
+ require(entry);
@@ -0,0 +1,48 @@
1
+ # Skills — the authoring contract
2
+
3
+ One directory per skill, holding a `SKILL.md`. The directory name and the frontmatter `name` must match exactly, and both are BARE — no namespace. The plugin supplies the namespace, so `skills/web` surfaces in a session as `omega:web`.
4
+
5
+ The roster follows the packages a session works in: `main` (the hub) plus `web`, `backend`, `desktop`, `extension`, `client`, and `manager` — plus `browser`, which is not a package router but the usage pattern for the plugin's one MCP declaration, the `@omega.js/mcp-router` endpoint.
6
+
7
+ Four more are checklists rather than routers, and the quality hook fires them on the surfaces they own (the table is in the plugin README):
8
+
9
+ | Skill | The checklist |
10
+ |---|---|
11
+ | `seo` | A page's search surface: meta title/description, canonical + social tags, structured data, one h1, sitemap/robots, link shape |
12
+ | `accessibility` | Front-end surfaces: landmarks and heading order, alt text, control names, color through the tokens, focus visibility, reduced motion |
13
+ | `brandcheck` | Config and copy consistency: brand facts read from omega.json5, one brand hex, the merge chain, no secrets in config |
14
+ | `analytics` | Event tracking: every flow fires through the catalog, a new event is a catalog entry first, the placement rule, consent and attribution carried not hand-rolled |
15
+
16
+ One more is a checklist the GATE fires, not the quality hook — the theme surfaces it owns are the same ones the gate refuses without it (the table is in the plugin README):
17
+
18
+ | Skill | The checklist |
19
+ |---|---|
20
+ | `theme` | The theme cascade: which layer a change belongs to, base/skin/fork and the declared forks, the tokens, whole-folder overrides and `inherit`, the two consumer tiers |
21
+
22
+ ```
23
+ skills/
24
+ └── <name>/
25
+ └── SKILL.md
26
+ ```
27
+
28
+ ## Frontmatter
29
+
30
+ ```yaml
31
+ ---
32
+ name: <name>
33
+ description: <when to use it — one sentence, 300 characters or less>
34
+ user-invocable: true
35
+ ---
36
+ ```
37
+
38
+ The `description` is the whole loading decision — it is the only part Claude reads before choosing to load the skill — and every skill's sits in EVERY session, so it is a shared context budget. One tight sentence naming WHEN to invoke this skill: the package, the surfaces, the situations. Nothing about what the skill knows — the body and the docs carry that. `scripts/skill-descriptions.test.js` fails the structure lane on anything over 300 characters.
39
+
40
+ ## The body points; the repo docs are the source
41
+
42
+ A skill is a router. It names where the truth lives for BOTH worlds — `docs/<framework>/index.md` plus `docs/shared/` when the session is in this monorepo, the top-level map through `node_modules/@omega.js/AGENTS.md` (the scope symlink the workspace service maintains) plus `docs/manager/brand.md` when the session is in a consumer project — and carries only what a session needs before it knows which document to open: the hard rules, the shape of the thing, and the paths.
43
+
44
+ Content copied out of the docs into a skill is a second home for the same fact, and the copy is what goes stale. Point instead.
45
+
46
+ ## Keeping it honest
47
+
48
+ Every skill has to be checkable against the code it describes. Prefer claims a test can verify — an exported name, a config key, a CLI command, a file path — over prose that can drift without any signal. See the "staleness mechanism" section in the plugin README.