oh-my-agent-commandcode 0.0.0-stage → 20.38.4

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 (334) hide show
  1. package/README.md +35 -2
  2. package/filter-test-output.sh +52 -0
  3. package/mods/oma.ts +347 -0
  4. package/package.json +30 -4
  5. package/skills/_shared/conditional/experiment-ledger.md +28 -0
  6. package/skills/_shared/conditional/exploration-loop.md +22 -0
  7. package/skills/_shared/conditional/quality-score.md +33 -0
  8. package/skills/_shared/core/anti-ai-prose.md +191 -0
  9. package/skills/_shared/core/api-contracts/README.md +28 -0
  10. package/skills/_shared/core/api-contracts/template.md +90 -0
  11. package/skills/_shared/core/clarification-protocol.md +23 -0
  12. package/skills/_shared/core/code-intelligence.md +46 -0
  13. package/skills/_shared/core/collaboration-policy.md +28 -0
  14. package/skills/_shared/core/common-checklist.md +28 -0
  15. package/skills/_shared/core/context-budget.md +22 -0
  16. package/skills/_shared/core/context-loading.md +34 -0
  17. package/skills/_shared/core/difficulty-guide.md +26 -0
  18. package/skills/_shared/core/execution-policy.md +31 -0
  19. package/skills/_shared/core/lessons-learned.md +33 -0
  20. package/skills/_shared/core/prompt-structure.md +18 -0
  21. package/skills/_shared/core/quality-principles.md +11 -0
  22. package/skills/_shared/core/session-metrics.md +35 -0
  23. package/skills/_shared/core/skill-routing.md +39 -0
  24. package/skills/_shared/core/test-approach.md +54 -0
  25. package/skills/_shared/core/vendor-detection.md +52 -0
  26. package/skills/_shared/runtime/memory-protocol.md +118 -0
  27. package/skills/_shared/runtime/result-contract.md +64 -0
  28. package/skills/_shared/ui-interaction-quality.md +133 -0
  29. package/skills/oma-academic-writing/SKILL.md +181 -0
  30. package/skills/oma-academic-writing/resources/abstract-guide.md +51 -0
  31. package/skills/oma-academic-writing/resources/academic-verb-tiers.md +42 -0
  32. package/skills/oma-academic-writing/resources/anti-ai-checklist.md +52 -0
  33. package/skills/oma-academic-writing/resources/hedging-guide.md +132 -0
  34. package/skills/oma-academic-writing/resources/sentence-structure-reference.md +151 -0
  35. package/skills/oma-architecture/SKILL.md +203 -0
  36. package/skills/oma-architecture/resources/api-evolution.md +41 -0
  37. package/skills/oma-architecture/resources/checklist.md +42 -0
  38. package/skills/oma-architecture/resources/execution-protocol.md +115 -0
  39. package/skills/oma-architecture/resources/methodology-selection.md +92 -0
  40. package/skills/oma-architecture/resources/migration-patterns.md +28 -0
  41. package/skills/oma-architecture/resources/output-templates.md +111 -0
  42. package/skills/oma-architecture/resources/stakeholder-synthesis.md +80 -0
  43. package/skills/oma-backend/SKILL.md +202 -0
  44. package/skills/oma-backend/resources/checklist.md +45 -0
  45. package/skills/oma-backend/resources/error-playbook.md +97 -0
  46. package/skills/oma-backend/resources/execution-protocol.md +39 -0
  47. package/skills/oma-backend/resources/orm-reference.md +61 -0
  48. package/skills/oma-backend/variants/node/api-template.ts +315 -0
  49. package/skills/oma-backend/variants/node/snippets.md +475 -0
  50. package/skills/oma-backend/variants/node/stack.yaml +21 -0
  51. package/skills/oma-backend/variants/node/tech-stack.md +33 -0
  52. package/skills/oma-backend/variants/python/api-template.py +378 -0
  53. package/skills/oma-backend/variants/python/snippets.md +199 -0
  54. package/skills/oma-backend/variants/python/stack.yaml +18 -0
  55. package/skills/oma-backend/variants/python/tech-stack.md +45 -0
  56. package/skills/oma-backend/variants/rust/api-template.rs +635 -0
  57. package/skills/oma-backend/variants/rust/snippets.md +471 -0
  58. package/skills/oma-backend/variants/rust/stack.yaml +20 -0
  59. package/skills/oma-backend/variants/rust/tech-stack.md +36 -0
  60. package/skills/oma-backend/variants/stack.schema.json +73 -0
  61. package/skills/oma-brainstorm/SKILL.md +166 -0
  62. package/skills/oma-brainstorm/resources/triz-lite.md +117 -0
  63. package/skills/oma-coordination/SKILL.md +171 -0
  64. package/skills/oma-db/SKILL.md +201 -0
  65. package/skills/oma-db/resources/anti-patterns.md +177 -0
  66. package/skills/oma-db/resources/checklist.md +67 -0
  67. package/skills/oma-db/resources/document-templates.md +107 -0
  68. package/skills/oma-db/resources/error-playbook.md +50 -0
  69. package/skills/oma-db/resources/examples.md +170 -0
  70. package/skills/oma-db/resources/execution-protocol.md +127 -0
  71. package/skills/oma-db/resources/iso-controls.md +98 -0
  72. package/skills/oma-db/resources/migration-playbook.md +93 -0
  73. package/skills/oma-db/resources/query-tuning.md +57 -0
  74. package/skills/oma-db/resources/vector-db.md +159 -0
  75. package/skills/oma-debug/SKILL.md +146 -0
  76. package/skills/oma-debug/resources/bug-report-template.md +327 -0
  77. package/skills/oma-debug/resources/checklist.md +31 -0
  78. package/skills/oma-debug/resources/common-patterns.md +734 -0
  79. package/skills/oma-debug/resources/debugging-checklist.md +364 -0
  80. package/skills/oma-debug/resources/error-playbook.md +94 -0
  81. package/skills/oma-debug/resources/execution-protocol.md +40 -0
  82. package/skills/oma-design/SKILL.md +135 -0
  83. package/skills/oma-design/resources/asset-strategy.md +34 -0
  84. package/skills/oma-design/resources/checklist.md +63 -0
  85. package/skills/oma-design/resources/data-grid.md +48 -0
  86. package/skills/oma-design/resources/design-md-spec.md +107 -0
  87. package/skills/oma-design/resources/design-tokens.md +53 -0
  88. package/skills/oma-design/resources/error-playbook.md +18 -0
  89. package/skills/oma-design/resources/execution-protocol.md +95 -0
  90. package/skills/oma-design/resources/external-design-skills.md +130 -0
  91. package/skills/oma-design/resources/getdesign-fetcher.md +104 -0
  92. package/skills/oma-design/resources/product-interface-review.md +59 -0
  93. package/skills/oma-design/resources/redesign-protocol.md +52 -0
  94. package/skills/oma-design/resources/stitch-integration.md +244 -0
  95. package/skills/oma-dev-workflow/SKILL.md +375 -0
  96. package/skills/oma-dev-workflow/resources/affected-checks.py +58 -0
  97. package/skills/oma-dev-workflow/resources/api-workflows.md +58 -0
  98. package/skills/oma-dev-workflow/resources/database-patterns.md +107 -0
  99. package/skills/oma-dev-workflow/resources/i18n-patterns.md +63 -0
  100. package/skills/oma-dev-workflow/resources/release-coordination.md +240 -0
  101. package/skills/oma-dev-workflow/resources/tooling-profiles.md +217 -0
  102. package/skills/oma-dev-workflow/resources/troubleshooting.md +78 -0
  103. package/skills/oma-dev-workflow/resources/validation-pipeline.md +246 -0
  104. package/skills/oma-docs/SKILL.md +77 -0
  105. package/skills/oma-docs/resources/commands.md +76 -0
  106. package/skills/oma-explanation/SKILL.md +212 -0
  107. package/skills/oma-explanation/resources/document-structure.md +115 -0
  108. package/skills/oma-explanation/resources/draft-format.md +199 -0
  109. package/skills/oma-explanation/resources/html-contract.md +102 -0
  110. package/skills/oma-frontend/SKILL.md +227 -0
  111. package/skills/oma-frontend/resources/angular-rules.md +110 -0
  112. package/skills/oma-frontend/resources/checklist.md +76 -0
  113. package/skills/oma-frontend/resources/error-playbook.md +125 -0
  114. package/skills/oma-frontend/resources/execution-protocol.md +46 -0
  115. package/skills/oma-frontend/resources/snippets.md +354 -0
  116. package/skills/oma-frontend/resources/specialized-visual-implementation.md +193 -0
  117. package/skills/oma-frontend/resources/tailwind-rules.md +83 -0
  118. package/skills/oma-frontend/resources/tech-stack.md +156 -0
  119. package/skills/oma-hwp/SKILL.md +166 -0
  120. package/skills/oma-hwp/config/hwp-config.yaml +35 -0
  121. package/skills/oma-hwp/resources/balanced-tables.ts +39 -0
  122. package/skills/oma-hwp/resources/execution-protocol.md +145 -0
  123. package/skills/oma-hwp/resources/flatten-tables.ts +101 -0
  124. package/skills/oma-hwp/resources/package.json +13 -0
  125. package/skills/oma-hwp/resources/troubleshooting.md +70 -0
  126. package/skills/oma-hwp/resources/tsconfig.json +10 -0
  127. package/skills/oma-hwp/resources/turndown-plugin-gfm.d.ts +9 -0
  128. package/skills/oma-image/SKILL.md +142 -0
  129. package/skills/oma-image/config/image-config.yaml +70 -0
  130. package/skills/oma-image/resources/checklist.md +18 -0
  131. package/skills/oma-image/resources/execution-protocol.md +117 -0
  132. package/skills/oma-image/resources/invocation.md +105 -0
  133. package/skills/oma-image/resources/prompt-tips.md +71 -0
  134. package/skills/oma-image/resources/vendor-matrix.md +90 -0
  135. package/skills/oma-market/SKILL.md +142 -0
  136. package/skills/oma-market/resources/checklist.md +12 -0
  137. package/skills/oma-market/resources/error-playbook.md +12 -0
  138. package/skills/oma-market/resources/execution-protocol.md +60 -0
  139. package/skills/oma-market/resources/frameworks/pestel.md +101 -0
  140. package/skills/oma-market/resources/frameworks/porters-5f.md +90 -0
  141. package/skills/oma-market/resources/frameworks/swot.md +61 -0
  142. package/skills/oma-market/resources/intent-rules.md +35 -0
  143. package/skills/oma-market/resources/output-laws.md +53 -0
  144. package/skills/oma-mobile/SKILL.md +168 -0
  145. package/skills/oma-mobile/resources/checklist.md +77 -0
  146. package/skills/oma-mobile/resources/error-playbook.md +198 -0
  147. package/skills/oma-mobile/resources/execution-protocol.md +47 -0
  148. package/skills/oma-mobile/resources/screen-template.dart +331 -0
  149. package/skills/oma-mobile/resources/screen-template.swift +239 -0
  150. package/skills/oma-mobile/resources/screen-template.tsx +179 -0
  151. package/skills/oma-mobile/resources/tech-stack.md +69 -0
  152. package/skills/oma-mobile/variants/README.md +45 -0
  153. package/skills/oma-mobile/variants/flutter/api-template.dart +461 -0
  154. package/skills/oma-mobile/variants/flutter/snippets.md +1353 -0
  155. package/skills/oma-mobile/variants/flutter/stack.yaml +21 -0
  156. package/skills/oma-mobile/variants/flutter/tech-stack.md +201 -0
  157. package/skills/oma-mobile/variants/kotlin-android/api-template.kt +182 -0
  158. package/skills/oma-mobile/variants/kotlin-android/snippets.md +871 -0
  159. package/skills/oma-mobile/variants/kotlin-android/stack.yaml +32 -0
  160. package/skills/oma-mobile/variants/kotlin-android/tech-stack.md +159 -0
  161. package/skills/oma-mobile/variants/react-native/api-template.ts +531 -0
  162. package/skills/oma-mobile/variants/react-native/snippets.md +1014 -0
  163. package/skills/oma-mobile/variants/react-native/stack.yaml +22 -0
  164. package/skills/oma-mobile/variants/react-native/tech-stack.md +192 -0
  165. package/skills/oma-mobile/variants/stack.schema.json +68 -0
  166. package/skills/oma-mobile/variants/swift-ios/api-template.swift +165 -0
  167. package/skills/oma-mobile/variants/swift-ios/snippets.md +1028 -0
  168. package/skills/oma-mobile/variants/swift-ios/stack.yaml +25 -0
  169. package/skills/oma-mobile/variants/swift-ios/tech-stack.md +174 -0
  170. package/skills/oma-observability/SKILL.md +225 -0
  171. package/skills/oma-observability/resources/anti-patterns.md +555 -0
  172. package/skills/oma-observability/resources/boundaries/cross-application.md +348 -0
  173. package/skills/oma-observability/resources/boundaries/multi-tenant.md +290 -0
  174. package/skills/oma-observability/resources/boundaries/release.md +372 -0
  175. package/skills/oma-observability/resources/boundaries/slo.md +225 -0
  176. package/skills/oma-observability/resources/checklist.md +123 -0
  177. package/skills/oma-observability/resources/examples.md +448 -0
  178. package/skills/oma-observability/resources/execution-protocol.md +166 -0
  179. package/skills/oma-observability/resources/incident-forensics.md +348 -0
  180. package/skills/oma-observability/resources/intent-rules.md +307 -0
  181. package/skills/oma-observability/resources/layers/L3-network.md +281 -0
  182. package/skills/oma-observability/resources/layers/L4-transport.md +299 -0
  183. package/skills/oma-observability/resources/layers/L7-application/crash-analytics.md +359 -0
  184. package/skills/oma-observability/resources/layers/L7-application/mobile-rum.md +278 -0
  185. package/skills/oma-observability/resources/layers/L7-application/waf.md +246 -0
  186. package/skills/oma-observability/resources/layers/L7-application/web-rum.md +350 -0
  187. package/skills/oma-observability/resources/layers/mesh.md +368 -0
  188. package/skills/oma-observability/resources/matrix.md +177 -0
  189. package/skills/oma-observability/resources/meta-observability.md +605 -0
  190. package/skills/oma-observability/resources/observability-as-code.md +666 -0
  191. package/skills/oma-observability/resources/signals/audit.md +310 -0
  192. package/skills/oma-observability/resources/signals/cost.md +303 -0
  193. package/skills/oma-observability/resources/signals/logs.md +263 -0
  194. package/skills/oma-observability/resources/signals/metrics.md +478 -0
  195. package/skills/oma-observability/resources/signals/privacy.md +351 -0
  196. package/skills/oma-observability/resources/signals/profiles.md +245 -0
  197. package/skills/oma-observability/resources/signals/traces.md +360 -0
  198. package/skills/oma-observability/resources/standards.md +214 -0
  199. package/skills/oma-observability/resources/transport/collector-topology.md +308 -0
  200. package/skills/oma-observability/resources/transport/otlp-grpc-vs-http.md +256 -0
  201. package/skills/oma-observability/resources/transport/sampling-recipes.md +297 -0
  202. package/skills/oma-observability/resources/transport/udp-statsd-mtu.md +167 -0
  203. package/skills/oma-observability/resources/vendor-categories.md +352 -0
  204. package/skills/oma-orchestration/SKILL.md +302 -0
  205. package/skills/oma-orchestration/config/cli-config.yaml +92 -0
  206. package/skills/oma-orchestration/resources/memory-schema.md +232 -0
  207. package/skills/oma-orchestration/resources/subagent-prompt-template.md +30 -0
  208. package/skills/oma-orchestration/scripts/parallel-run.sh +6 -0
  209. package/skills/oma-orchestration/scripts/spawn-agent.sh +5 -0
  210. package/skills/oma-orchestration/scripts/verify.sh +20 -0
  211. package/skills/oma-orchestration/templates/backend-task.md +19 -0
  212. package/skills/oma-orchestration/templates/debug-task.md +16 -0
  213. package/skills/oma-orchestration/templates/frontend-task.md +18 -0
  214. package/skills/oma-orchestration/templates/mobile-task.md +18 -0
  215. package/skills/oma-orchestration/templates/qa-task.md +16 -0
  216. package/skills/oma-orchestration/templates/tasks-example.yaml +15 -0
  217. package/skills/oma-pdf/SKILL.md +162 -0
  218. package/skills/oma-pdf/config/pdf-config.yaml +27 -0
  219. package/skills/oma-pdf/resources/execution-protocol.md +127 -0
  220. package/skills/oma-pm/SKILL.md +157 -0
  221. package/skills/oma-pm/resources/error-playbook.md +75 -0
  222. package/skills/oma-pm/resources/examples.md +439 -0
  223. package/skills/oma-pm/resources/execution-protocol.md +62 -0
  224. package/skills/oma-pm/resources/iso-planning.md +110 -0
  225. package/skills/oma-pm/resources/plan-phase-protocol.md +66 -0
  226. package/skills/oma-pm/resources/task-template.json +86 -0
  227. package/skills/oma-qa/SKILL.md +141 -0
  228. package/skills/oma-qa/resources/checklist.md +339 -0
  229. package/skills/oma-qa/resources/error-playbook.md +98 -0
  230. package/skills/oma-qa/resources/execution-protocol.md +169 -0
  231. package/skills/oma-qa/resources/iso-quality.md +82 -0
  232. package/skills/oma-qa/resources/verify-ship-protocol.md +116 -0
  233. package/skills/oma-recap/SKILL.md +245 -0
  234. package/skills/oma-recap/resources/output-formats.md +83 -0
  235. package/skills/oma-refactor/SKILL.md +184 -0
  236. package/skills/oma-refactor/resources/definition.md +108 -0
  237. package/skills/oma-refactor/resources/governance.md +33 -0
  238. package/skills/oma-refactor/resources/hotspots.py +44 -0
  239. package/skills/oma-refactor/resources/measurement.md +93 -0
  240. package/skills/oma-scholar/SKILL.md +276 -0
  241. package/skills/oma-scholar/config/scholar-config.yaml +79 -0
  242. package/skills/oma-scholar/resources/api-endpoints.md +174 -0
  243. package/skills/oma-scholar/resources/checklist.md +92 -0
  244. package/skills/oma-scholar/resources/execution-protocol.md +224 -0
  245. package/skills/oma-scholar/resources/fallback-providers.md +143 -0
  246. package/skills/oma-scholar/resources/setup-openalex.md +85 -0
  247. package/skills/oma-scholar/resources/sidecar-spec.md +341 -0
  248. package/skills/oma-scholar/resources/upstream-spec-cache.md +972 -0
  249. package/skills/oma-scm/SKILL.md +103 -0
  250. package/skills/oma-scm/resources/cm-operations.md +56 -0
  251. package/skills/oma-scm/resources/codeowners-playbook.md +45 -0
  252. package/skills/oma-scm/resources/conventional-commits.md +108 -0
  253. package/skills/oma-scm/resources/merge-risk.md +76 -0
  254. package/skills/oma-scm/resources/onboarding-risk-signals.md +71 -0
  255. package/skills/oma-search/SKILL.md +125 -0
  256. package/skills/oma-search/resources/checklist.md +36 -0
  257. package/skills/oma-search/resources/error-playbook.md +66 -0
  258. package/skills/oma-search/resources/examples.md +80 -0
  259. package/skills/oma-search/resources/execution-protocol.md +86 -0
  260. package/skills/oma-search/resources/intent-rules.md +47 -0
  261. package/skills/oma-search/resources/trust-registry.md +53 -0
  262. package/skills/oma-security/SKILL.md +172 -0
  263. package/skills/oma-security/resources/artex.md +108 -0
  264. package/skills/oma-security/resources/ci.md +134 -0
  265. package/skills/oma-security/resources/cisco-source.md +108 -0
  266. package/skills/oma-security/resources/deepsec-config.md +45 -0
  267. package/skills/oma-security/resources/deepsec-matchers.md +35 -0
  268. package/skills/oma-security/resources/deepsec-scanning.md +45 -0
  269. package/skills/oma-security/resources/deepsec-setup.md +41 -0
  270. package/skills/oma-security/resources/findings-contract.md +408 -0
  271. package/skills/oma-security/resources/mcp-scanning.md +122 -0
  272. package/skills/oma-security/resources/skill-scanning.md +106 -0
  273. package/skills/oma-security/resources/validation.md +71 -0
  274. package/skills/oma-skill-creation/SKILL.md +84 -0
  275. package/skills/oma-skill-creation/resources/prompt-evaluation.md +36 -0
  276. package/skills/oma-skill-creation/resources/ssl-lite-template.md +108 -0
  277. package/skills/oma-skill-creation/resources/validation-checklist.md +101 -0
  278. package/skills/oma-slide/SKILL.md +277 -0
  279. package/skills/oma-slide/resources/animation-patterns.md +245 -0
  280. package/skills/oma-slide/resources/assets/deck-stage.js +514 -0
  281. package/skills/oma-slide/resources/assets/viewport-base.css +257 -0
  282. package/skills/oma-slide/resources/canva-integration.md +203 -0
  283. package/skills/oma-slide/resources/checklist.md +46 -0
  284. package/skills/oma-slide/resources/design-doctrine.md +260 -0
  285. package/skills/oma-slide/resources/fixed-stage.md +232 -0
  286. package/skills/oma-slide/resources/generation-protocol.md +393 -0
  287. package/skills/oma-slide/resources/native-pptx.md +84 -0
  288. package/skills/oma-slide/resources/selection-index.json +461 -0
  289. package/skills/oma-slide/resources/style-presets.LICENSE +10 -0
  290. package/skills/oma-slide/resources/style-presets.md +520 -0
  291. package/skills/oma-tf-infra/SKILL.md +201 -0
  292. package/skills/oma-tf-infra/resources/checklist.md +53 -0
  293. package/skills/oma-tf-infra/resources/cost-optimization.md +574 -0
  294. package/skills/oma-tf-infra/resources/error-playbook.md +68 -0
  295. package/skills/oma-tf-infra/resources/examples.md +38 -0
  296. package/skills/oma-tf-infra/resources/execution-protocol.md +129 -0
  297. package/skills/oma-tf-infra/resources/iso-42001-infra.md +229 -0
  298. package/skills/oma-tf-infra/resources/multi-cloud-examples.md +241 -0
  299. package/skills/oma-tf-infra/resources/policy-testing-examples.md +332 -0
  300. package/skills/oma-translation/SKILL.md +229 -0
  301. package/skills/oma-translation/resources/anti-ai-patterns.md +104 -0
  302. package/skills/oma-translation/resources/lang/_template.md +73 -0
  303. package/skills/oma-translation/resources/lang/en.md +123 -0
  304. package/skills/oma-translation/resources/lang/ja.md +274 -0
  305. package/skills/oma-translation/resources/lang/ko.md +228 -0
  306. package/skills/oma-translation/resources/lang/zh.md +285 -0
  307. package/skills/oma-translation/resources/style-skills.md +104 -0
  308. package/skills/oma-translation/resources/translation-rubric.md +126 -0
  309. package/skills/oma-video/SKILL.md +229 -0
  310. package/skills/oma-video/config/video-config.yaml +60 -0
  311. package/skills/oma-video/resources/checklist.md +26 -0
  312. package/skills/oma-video/resources/execution-protocol.md +122 -0
  313. package/skills/oma-video/resources/existing-media.md +185 -0
  314. package/skills/oma-video/resources/hyperframes-authoring/README.md +44 -0
  315. package/skills/oma-video/resources/hyperframes-authoring/demo.md +31 -0
  316. package/skills/oma-video/resources/hyperframes-authoring/explainer.md +10 -0
  317. package/skills/oma-video/resources/hyperframes-authoring/shorts.md +10 -0
  318. package/skills/oma-video/resources/motion-principles.md +81 -0
  319. package/skills/oma-video/resources/mpt/driver.py +301 -0
  320. package/skills/oma-video/resources/prompt-tips.md +75 -0
  321. package/skills/oma-video/resources/script-schema.md +81 -0
  322. package/skills/oma-video/resources/sound-design.md +127 -0
  323. package/skills/oma-video/resources/strudel/package.json +11 -0
  324. package/skills/oma-video/resources/strudel/page.html +87 -0
  325. package/skills/oma-video/resources/strudel/render.mjs +295 -0
  326. package/skills/oma-video/resources/vendor-matrix.md +124 -0
  327. package/skills/oma-voice/SKILL.md +249 -0
  328. package/skills/oma-voice/config/voice-config.yaml +30 -0
  329. package/skills/oma-voice/resources/audio-processing.md +119 -0
  330. package/skills/oma-voice/resources/checklist.md +47 -0
  331. package/skills/oma-voice/resources/execution-protocol.md +215 -0
  332. package/skills/oma-voice/resources/prompt-tips.md +43 -0
  333. package/skills/oma-voice/resources/voice-matrix.md +51 -0
  334. package/skills/oma-voice/resources/voicestudio.md +87 -0
@@ -0,0 +1,514 @@
1
+ /**
2
+ * deck-stage.js — oma-slide fixed-stage controller
3
+ *
4
+ * Provides a <deck-stage> Custom Element (Web Component) that:
5
+ * 1. Scales the 1920×1080 stage uniformly to fit the viewport (letterbox / pillarbox).
6
+ * 2. Handles keyboard navigation (←/→, Space/Shift+Space, PgUp/PgDn, Home/End, 0-9 digits,
7
+ * n = toggle speaker-notes panel).
8
+ * 3. Handles touch swipe (horizontal) and mouse-wheel navigation.
9
+ * 4. Reads speaker notes from <script type="application/json" id="speaker-notes">
10
+ * and shows them in an on-screen panel toggled with the `n` key (presenter view).
11
+ * 5. Posts { type: "slideIndexChanged", index, total, note } to window.parent (embed integration).
12
+ * 6. Dispatches a native "slidechange" CustomEvent on <deck-stage>.
13
+ * 7. Manages .active / .visible CSS classes (never display:none).
14
+ * 8. Tags each slide with data-screen-label and data-om-validate on first connect.
15
+ * 9. Provides clean @media print behaviour (removes transform so PDF prints at design size).
16
+ *
17
+ * Usage:
18
+ * <!-- Wrap .deck-viewport + .deck-stage in <deck-stage> -->
19
+ * <deck-stage>
20
+ * <div class="deck-viewport">
21
+ * <div class="deck-stage">
22
+ * <section class="slide" id="slide-01">...</section>
23
+ * <section class="slide" id="slide-02">...</section>
24
+ * </div>
25
+ * </div>
26
+ * </deck-stage>
27
+ *
28
+ * <!-- Optional speaker notes (JSON object keyed by slide index, 0-based) -->
29
+ * <script type="application/json" id="speaker-notes">
30
+ * { "0": "Opening remarks...", "1": "Talk about the problem..." }
31
+ * </script>
32
+ *
33
+ * No build step required. ES2022 class syntax; no external dependencies.
34
+ *
35
+ * Validator contract:
36
+ * Each slide receives:
37
+ * data-screen-label="Slide N / M"
38
+ * data-om-validate="no_overflowing_text,no_overlapping_text,slide_sized_text"
39
+ * These attributes are read by `oma slide validate` (puppeteer-core) to locate
40
+ * slides and know which checks to run on each one.
41
+ */
42
+
43
+ "use strict";
44
+
45
+ /* ─── Constants ──────────────────────────────────────────────────────── */
46
+ const STAGE_W = 1920;
47
+ const STAGE_H = 1080;
48
+ const VALIDATOR_CHECKS = "no_overflowing_text,no_overlapping_text,slide_sized_text";
49
+
50
+ /* ─── Utility: clamp ─────────────────────────────────────────────────── */
51
+ function clamp(value, min, max) {
52
+ return Math.max(min, Math.min(max, value));
53
+ }
54
+
55
+ /* ─── Utility: debounce ──────────────────────────────────────────────── */
56
+ function debounce(fn, ms) {
57
+ let timer = null;
58
+ return function (...args) {
59
+ clearTimeout(timer);
60
+ timer = setTimeout(() => fn.apply(this, args), ms);
61
+ };
62
+ }
63
+
64
+ /* ─── Utility: parse speaker notes ──────────────────────────────────── */
65
+ function parseSpeakerNotes() {
66
+ const el = document.getElementById("speaker-notes");
67
+ if (!el) return {};
68
+ try {
69
+ const parsed = JSON.parse(el.textContent || "{}");
70
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
71
+ return parsed;
72
+ }
73
+ } catch {
74
+ /* malformed JSON — silently ignore */
75
+ }
76
+ return {};
77
+ }
78
+
79
+ /* ─── <deck-stage> Web Component ────────────────────────────────────── */
80
+ class DeckStage extends HTMLElement {
81
+ /* ── Internal state ── */
82
+ #slides = [];
83
+ #currentIndex = 0;
84
+ #notes = {};
85
+ #stageEl = null;
86
+ #resizeObserver = null;
87
+ #touchStartX = 0;
88
+ #touchStartY = 0;
89
+ #touchStartTime = 0;
90
+ #wheelLocked = false;
91
+ #notesPanel = null;
92
+ #notesVisible = false;
93
+
94
+ /* ── Lifecycle ── */
95
+
96
+ connectedCallback() {
97
+ /*
98
+ * The element may be upgraded BEFORE its children are parsed — this
99
+ * happens whenever deck-stage.js is loaded in <head> without defer:
100
+ * customElements.define() runs during parsing and connectedCallback
101
+ * fires at the <deck-stage> start tag, when .deck-stage / .slide do
102
+ * not exist yet. Querying then returns null, init bails, and slide 0
103
+ * never gets .active → blank render (and export PNG/PDF come out blank).
104
+ *
105
+ * Detect that case (no .deck-stage yet AND the document is still
106
+ * parsing) and defer init until DOMContentLoaded, when the full
107
+ * subtree is guaranteed to exist.
108
+ */
109
+ if (!this.querySelector(".deck-stage") && document.readyState === "loading") {
110
+ document.addEventListener("DOMContentLoaded", this.#init, { once: true });
111
+ return;
112
+ }
113
+ this.#init();
114
+ }
115
+
116
+ #init = () => {
117
+ this.#stageEl = this.querySelector(".deck-stage");
118
+ if (!this.#stageEl) {
119
+ console.warn("[deck-stage] .deck-stage element not found inside <deck-stage>.");
120
+ return;
121
+ }
122
+
123
+ this.#slides = Array.from(this.#stageEl.querySelectorAll(".slide"));
124
+ if (this.#slides.length === 0) {
125
+ console.warn("[deck-stage] No .slide elements found.");
126
+ return;
127
+ }
128
+
129
+ this.#notes = parseSpeakerNotes();
130
+
131
+ this.#annotateSlides();
132
+ this.#bindKeyboard();
133
+ this.#bindTouch();
134
+ this.#bindWheel();
135
+ this.#startResizeObserver();
136
+ this.#scaleStage();
137
+ this.#goTo(0, /* initial */ true);
138
+ };
139
+
140
+ disconnectedCallback() {
141
+ this.#resizeObserver?.disconnect();
142
+ document.removeEventListener("DOMContentLoaded", this.#init);
143
+ document.removeEventListener("keydown", this.#onKeyDown);
144
+ window.removeEventListener("beforeprint", this.#onBeforePrint);
145
+ window.removeEventListener("afterprint", this.#onAfterPrint);
146
+ }
147
+
148
+ /* ── Public API ── */
149
+
150
+ /** Navigate to a specific slide index (0-based). */
151
+ goTo(index) {
152
+ this.#goTo(index);
153
+ }
154
+
155
+ /** Navigate one slide forward. */
156
+ next() {
157
+ if (this.#currentIndex < this.#slides.length - 1) {
158
+ this.#goTo(this.#currentIndex + 1);
159
+ }
160
+ }
161
+
162
+ /** Navigate one slide backward. */
163
+ prev() {
164
+ if (this.#currentIndex > 0) {
165
+ this.#goTo(this.#currentIndex - 1);
166
+ }
167
+ }
168
+
169
+ get currentIndex() {
170
+ return this.#currentIndex;
171
+ }
172
+
173
+ get total() {
174
+ return this.#slides.length;
175
+ }
176
+
177
+ /* ── Private: slide annotation ── */
178
+
179
+ /**
180
+ * Tags each slide with data-screen-label and data-om-validate.
181
+ * Called once on connect. Required by the validator contract.
182
+ */
183
+ #annotateSlides() {
184
+ const total = this.#slides.length;
185
+ this.#slides.forEach((slide, i) => {
186
+ // data-screen-label: human-readable label consumed by the validator
187
+ if (!slide.dataset.screenLabel) {
188
+ slide.dataset.screenLabel = `Slide ${i + 1} / ${total}`;
189
+ }
190
+ // data-om-validate: comma-separated list of checks the validator runs
191
+ if (!slide.dataset.omValidate) {
192
+ slide.dataset.omValidate = VALIDATOR_CHECKS;
193
+ }
194
+ });
195
+ }
196
+
197
+ /* ── Private: navigation ── */
198
+
199
+ #goTo(index, initial = false) {
200
+ if (!Number.isInteger(index) || this.#slides.length === 0) return;
201
+
202
+ const prev = this.#currentIndex;
203
+ const next = clamp(index, 0, this.#slides.length - 1);
204
+ const incoming = this.#slides[next];
205
+ if (!incoming) return;
206
+
207
+ if (prev === next && !initial) return;
208
+
209
+ /* Outgoing: drop .active, briefly keep .visible so it fades out */
210
+ if (!initial && prev !== next) {
211
+ const outgoing = this.#slides[prev];
212
+ outgoing.classList.remove("active");
213
+ outgoing.classList.add("visible");
214
+
215
+ /* Remove .visible after the CSS transition (400 ms guard) */
216
+ const outgoingEl = outgoing;
217
+ const clearVisible = () => {
218
+ outgoingEl.classList.remove("visible");
219
+ outgoingEl.removeEventListener("transitionend", clearVisible);
220
+ };
221
+ outgoing.addEventListener("transitionend", clearVisible, { once: true });
222
+ setTimeout(() => outgoing.classList.remove("visible"), 400);
223
+ }
224
+
225
+ /* Incoming: make active */
226
+ incoming.classList.remove("visible");
227
+ incoming.classList.add("active");
228
+ this.#currentIndex = next;
229
+
230
+ /* Update counter element if present */
231
+ const counter = document.querySelector(".deck-counter");
232
+ if (counter) {
233
+ counter.textContent = `${next + 1} / ${this.#slides.length}`;
234
+ }
235
+
236
+ /* Dispatch slidechange event */
237
+ const note = this.#notes[String(next)] ?? this.#notes[next] ?? "";
238
+ const payload = { index: next, total: this.#slides.length, note };
239
+
240
+ this.dispatchEvent(
241
+ new CustomEvent("slidechange", { detail: payload, bubbles: true, composed: true })
242
+ );
243
+
244
+ /* Post message to parent frame for presenter view */
245
+ if (window.parent && window.parent !== window) {
246
+ window.parent.postMessage(
247
+ { type: "slideIndexChanged", ...payload },
248
+ "*"
249
+ );
250
+ }
251
+
252
+ /* Keep the on-screen notes panel in sync */
253
+ this.#updateNotesPanel();
254
+ }
255
+
256
+ /* ── Private: speaker-notes panel (toggle with `n`) ── */
257
+
258
+ #ensureNotesPanel() {
259
+ if (this.#notesPanel) return this.#notesPanel;
260
+ const panel = document.createElement("div");
261
+ panel.className = "deck-notes-panel";
262
+ panel.setAttribute("role", "note");
263
+ panel.setAttribute("aria-label", "Speaker notes");
264
+ /* Hidden by default (display:none — never intercepts clicks when hidden). */
265
+ panel.style.cssText = [
266
+ "position: fixed",
267
+ "left: 16px",
268
+ "right: 16px",
269
+ "bottom: 16px",
270
+ "max-height: 30vh",
271
+ "overflow-y: auto",
272
+ "padding: 16px 20px",
273
+ "background: rgba(10, 12, 18, 0.85)",
274
+ "color: #f2f2f2",
275
+ "font: 16px/1.5 system-ui, sans-serif",
276
+ "border-radius: 8px",
277
+ "white-space: pre-wrap",
278
+ "z-index: 2147483647",
279
+ "display: none",
280
+ ].join("; ");
281
+ document.body.appendChild(panel);
282
+ this.#notesPanel = panel;
283
+ return panel;
284
+ }
285
+
286
+ #toggleNotesPanel() {
287
+ const panel = this.#ensureNotesPanel();
288
+ this.#notesVisible = !this.#notesVisible;
289
+ panel.style.display = this.#notesVisible ? "block" : "none";
290
+ this.#updateNotesPanel();
291
+ }
292
+
293
+ #updateNotesPanel() {
294
+ if (!this.#notesVisible || !this.#notesPanel) return;
295
+ const note =
296
+ this.#notes[String(this.#currentIndex)] ?? this.#notes[this.#currentIndex] ?? "";
297
+ this.#notesPanel.textContent = note || "(no speaker note for this slide)";
298
+ }
299
+
300
+ /* ── Private: scaling ── */
301
+
302
+ /**
303
+ * Computes scale = Math.min(viewportW / 1920, viewportH / 1080)
304
+ * and applies transform: scale(s) + translate to centre the stage.
305
+ *
306
+ * The stage is positioned so (scaledW, scaledH) is centred in the viewport.
307
+ * With transform-origin: top left, the on-screen box is scaledW × scaledH,
308
+ * so centring must use the SCALED dimensions:
309
+ * left: (vw - 1920 * s) / 2 (works for both scale < 1 and scale > 1)
310
+ * top: (vh - 1080 * s) / 2
311
+ * and then transform: scale(s).
312
+ */
313
+ #scaleStage() {
314
+ if (!this.#stageEl) return;
315
+ if (window.matchMedia("print").matches) return;
316
+
317
+ const vw = window.innerWidth;
318
+ const vh = window.innerHeight;
319
+ const scale = Math.min(vw / STAGE_W, vh / STAGE_H);
320
+
321
+ const scaledW = STAGE_W * scale;
322
+ const scaledH = STAGE_H * scale;
323
+
324
+ const offsetLeft = (vw - scaledW) / 2;
325
+ const offsetTop = (vh - scaledH) / 2;
326
+
327
+ this.#stageEl.style.transform = `scale(${scale})`;
328
+ this.#stageEl.style.left = `${offsetLeft}px`;
329
+ this.#stageEl.style.top = `${offsetTop}px`;
330
+ this.#stageEl.style.position = "absolute";
331
+ }
332
+
333
+ /* ── Private: resize observer ── */
334
+
335
+ #startResizeObserver() {
336
+ const debouncedScale = debounce(() => this.#scaleStage(), 50);
337
+
338
+ this.#resizeObserver = new ResizeObserver(debouncedScale);
339
+ this.#resizeObserver.observe(document.documentElement);
340
+
341
+ /* Print: remove transform before print so the browser lays out at design size */
342
+ window.addEventListener("beforeprint", this.#onBeforePrint);
343
+ window.addEventListener("afterprint", this.#onAfterPrint);
344
+ }
345
+
346
+ #onBeforePrint = () => {
347
+ /* Notes panel must not overlay printed slides */
348
+ if (this.#notesPanel) this.#notesPanel.style.display = "none";
349
+ if (!this.#stageEl) return;
350
+ this.#stageEl.style.transform = "none";
351
+ this.#stageEl.style.left = "";
352
+ this.#stageEl.style.top = "";
353
+ this.#stageEl.style.position = "";
354
+ };
355
+
356
+ #onAfterPrint = () => {
357
+ if (this.#notesPanel && this.#notesVisible) {
358
+ this.#notesPanel.style.display = "block";
359
+ }
360
+ this.#scaleStage();
361
+ };
362
+
363
+ /* ── Private: keyboard navigation ── */
364
+
365
+ #bindKeyboard() {
366
+ document.addEventListener("keydown", this.#onKeyDown);
367
+ }
368
+
369
+ #onKeyDown = (e) => {
370
+ /* Skip if focus is in an input/textarea/select to not block typing */
371
+ const tag = document.activeElement?.tagName?.toLowerCase();
372
+ if (tag === "input" || tag === "textarea" || tag === "select") return;
373
+
374
+ switch (e.key) {
375
+ case "ArrowRight":
376
+ case "ArrowDown":
377
+ case " ":
378
+ case "PageDown":
379
+ e.preventDefault();
380
+ if (e.shiftKey && e.key === " ") {
381
+ this.prev();
382
+ } else {
383
+ this.next();
384
+ }
385
+ break;
386
+
387
+ case "ArrowLeft":
388
+ case "ArrowUp":
389
+ case "PageUp":
390
+ e.preventDefault();
391
+ this.prev();
392
+ break;
393
+
394
+ case "Home":
395
+ e.preventDefault();
396
+ this.#goTo(0);
397
+ break;
398
+
399
+ case "End":
400
+ e.preventDefault();
401
+ this.#goTo(this.#slides.length - 1);
402
+ break;
403
+
404
+ case "n":
405
+ case "N":
406
+ e.preventDefault();
407
+ this.#toggleNotesPanel();
408
+ break;
409
+
410
+ default:
411
+ /* Number keys 1-9 and 0 (for slide 10) */
412
+ if (e.key >= "0" && e.key <= "9") {
413
+ const n = e.key === "0" ? 10 : parseInt(e.key, 10);
414
+ this.#goTo(n - 1);
415
+ }
416
+ break;
417
+ }
418
+ };
419
+
420
+ /* ── Private: touch / swipe ── */
421
+
422
+ #bindTouch() {
423
+ this.addEventListener("touchstart", this.#onTouchStart, { passive: true });
424
+ this.addEventListener("touchend", this.#onTouchEnd, { passive: true });
425
+ }
426
+
427
+ #onTouchStart = (e) => {
428
+ const touch = e.changedTouches[0];
429
+ this.#touchStartX = touch.clientX;
430
+ this.#touchStartY = touch.clientY;
431
+ this.#touchStartTime = Date.now();
432
+ };
433
+
434
+ #onTouchEnd = (e) => {
435
+ const touch = e.changedTouches[0];
436
+ const dx = touch.clientX - this.#touchStartX;
437
+ const dy = touch.clientY - this.#touchStartY;
438
+ const dt = Date.now() - this.#touchStartTime;
439
+
440
+ /* Minimum swipe: 40px horizontal, less than 300ms, more horizontal than vertical */
441
+ if (Math.abs(dx) > 40 && Math.abs(dx) > Math.abs(dy) * 1.5 && dt < 300) {
442
+ if (dx < 0) {
443
+ this.next();
444
+ } else {
445
+ this.prev();
446
+ }
447
+ }
448
+ };
449
+
450
+ /* ── Private: mouse-wheel navigation ── */
451
+
452
+ #bindWheel() {
453
+ this.addEventListener("wheel", this.#onWheel, { passive: false });
454
+ }
455
+
456
+ /**
457
+ * Wheel navigation with a short lock to prevent multi-slide jumping on
458
+ * trackpads that fire many small delta events per gesture.
459
+ */
460
+ #onWheel = (e) => {
461
+ e.preventDefault();
462
+ if (this.#wheelLocked) return;
463
+
464
+ if (e.deltaY > 0 || e.deltaX > 0) {
465
+ this.next();
466
+ } else if (e.deltaY < 0 || e.deltaX < 0) {
467
+ this.prev();
468
+ }
469
+
470
+ /* Lock for 600 ms to absorb momentum scrolling */
471
+ this.#wheelLocked = true;
472
+ setTimeout(() => {
473
+ this.#wheelLocked = false;
474
+ }, 600);
475
+ };
476
+ }
477
+
478
+ /* ─── Registration ───────────────────────────────────────────────────── */
479
+ customElements.define("deck-stage", DeckStage);
480
+
481
+ /* ─── Convenience: auto-init for plain HTML decks ───────────────────── */
482
+ /*
483
+ * If the page does NOT use <deck-stage> as a wrapper element but instead
484
+ * has a bare .deck-viewport / .deck-stage structure, auto-wrap it.
485
+ * This allows quick standalone previews without changing the HTML.
486
+ */
487
+ document.addEventListener("DOMContentLoaded", () => {
488
+ /* If a <deck-stage> is already in the DOM, do nothing */
489
+ if (document.querySelector("deck-stage")) return;
490
+
491
+ const viewport = document.querySelector(".deck-viewport");
492
+ if (!viewport) return;
493
+
494
+ const wrapper = document.createElement("deck-stage");
495
+ const parent = viewport.parentNode;
496
+ const nextSibling = viewport.nextSibling;
497
+ wrapper.appendChild(viewport);
498
+ parent.insertBefore(wrapper, nextSibling);
499
+ });
500
+
501
+ /* ─── Presenter-view helper ──────────────────────────────────────────── */
502
+ /*
503
+ * When this page is loaded inside an <iframe> for a presenter view,
504
+ * the parent frame can post { type: "navigateTo", index: N } to control it.
505
+ */
506
+ window.addEventListener("message", (e) => {
507
+ if (!e.data || typeof e.data !== "object") return;
508
+ if (e.data.type !== "navigateTo") return;
509
+
510
+ const deckEl = document.querySelector("deck-stage");
511
+ if (deckEl && typeof deckEl.goTo === "function") {
512
+ deckEl.goTo(e.data.index);
513
+ }
514
+ });