codymaster 5.2.0 → 7.0.1

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 (380) hide show
  1. package/CHANGELOG.md +276 -0
  2. package/README.md +216 -333
  3. package/dist/agent/antigravity.js +152 -0
  4. package/dist/agent/backend.js +2 -0
  5. package/dist/agent/claude.js +196 -0
  6. package/dist/agent/codex.js +204 -0
  7. package/dist/agent/copilot.js +284 -0
  8. package/dist/agent/cursor.js +211 -0
  9. package/dist/agent/factory.js +30 -0
  10. package/dist/agent/gemini.js +142 -0
  11. package/dist/agent/opencode.js +205 -0
  12. package/dist/agent/spawn-helper.js +237 -0
  13. package/dist/agent/version.js +25 -0
  14. package/dist/browse/adapter-factory.js +69 -0
  15. package/dist/browse/adapters/agent-browser-adapter.js +305 -0
  16. package/dist/browse/adapters/playwright-adapter.js +309 -0
  17. package/dist/browse/adapters/types.js +6 -0
  18. package/dist/browse/error-collector.js +132 -0
  19. package/dist/browse/event-log.js +109 -0
  20. package/dist/browse/index.js +17 -0
  21. package/dist/browse-server.js +204 -120
  22. package/dist/cli/command-registry.js +12 -0
  23. package/dist/cli/commands/dashboard.js +76 -2
  24. package/dist/cli/commands/engineering.js +218 -4
  25. package/dist/cli/commands/install.js +160 -0
  26. package/dist/cli/commands/learn.js +181 -0
  27. package/dist/cli/commands/parallel.js +138 -0
  28. package/dist/cli/commands/quality.js +105 -0
  29. package/dist/cli/commands/stack.js +49 -0
  30. package/dist/cli/commands/update.js +159 -0
  31. package/dist/cli/update-check.js +94 -10
  32. package/dist/continuity.js +3 -1
  33. package/dist/dashboard.js +47 -6
  34. package/dist/data.js +35 -0
  35. package/dist/execution/tdd-gate.js +113 -0
  36. package/dist/executor/cancel.js +34 -0
  37. package/dist/executor/gc.js +74 -0
  38. package/dist/executor/index.js +14 -0
  39. package/dist/executor/runner.js +70 -0
  40. package/dist/executor/workdir.js +31 -0
  41. package/dist/handoff/contracts.js +22 -0
  42. package/dist/handoff/index.js +18 -0
  43. package/dist/handoff/io.js +121 -0
  44. package/dist/index.js +7 -3
  45. package/dist/indexer/stack-detect.js +219 -0
  46. package/dist/install/copy.js +98 -0
  47. package/dist/install/engine.js +42 -0
  48. package/dist/install/paths.js +70 -0
  49. package/dist/install/platforms/_simple.js +85 -0
  50. package/dist/install/platforms/antigravity.js +91 -0
  51. package/dist/install/platforms/claude-code.js +107 -0
  52. package/dist/install/platforms/cursor.js +77 -0
  53. package/dist/install/platforms/index.js +27 -0
  54. package/dist/install/platforms/simple.js +163 -0
  55. package/dist/install/profiles.js +75 -0
  56. package/dist/install/types.js +2 -0
  57. package/dist/learnings.js +208 -0
  58. package/dist/mcp-context-server.js +1 -1
  59. package/dist/middleware/metrics.js +30 -0
  60. package/dist/middleware/security-headers.js +14 -0
  61. package/dist/realtime/event-bus.js +29 -0
  62. package/dist/realtime/ws-hub.js +91 -0
  63. package/dist/schemas/task-schema.js +48 -0
  64. package/dist/schemas/validate.js +18 -0
  65. package/dist/skills-lock.js +96 -0
  66. package/dist/sprint-pipeline.js +26 -0
  67. package/dist/storage/index.js +21 -0
  68. package/dist/storage/repos/activity-repo.js +46 -0
  69. package/dist/storage/repos/message-repo.js +39 -0
  70. package/dist/storage/repos/project-repo.js +56 -0
  71. package/dist/storage/repos/task-repo.js +142 -0
  72. package/dist/storage/services/project-service.js +49 -0
  73. package/dist/storage/services/task-service.js +97 -0
  74. package/dist/storage/sqlite.js +113 -0
  75. package/dist/tier-classify.js +131 -0
  76. package/dist/ui/onboarding.js +51 -15
  77. package/dist/utils/cli-utils.js +7 -2
  78. package/dist/utils/design-taste.js +108 -0
  79. package/dist/utils/output-compress.js +143 -0
  80. package/dist/vibecoding-index.js +126 -0
  81. package/package.json +27 -4
  82. package/public/dashboard/app.js +52 -1
  83. package/scripts/build-skills-lock.mjs +88 -0
  84. package/scripts/build-skills.mjs +187 -28
  85. package/scripts/compress-skill.mjs +73 -0
  86. package/scripts/deprecate-skill.mjs +72 -0
  87. package/scripts/install.sh +170 -0
  88. package/scripts/mcp-bridge.js +2 -2
  89. package/scripts/postinstall.js +54 -287
  90. package/scripts/release.sh +126 -0
  91. package/scripts/update-changelog.sh +88 -0
  92. package/scripts/validate-skills.mjs +101 -4
  93. package/skills/_shared/SKILL_TEMPLATE.md +62 -0
  94. package/skills/cm-autopilot/scripts/autopilot.py +19 -2
  95. package/skills/cm-brainstorm-idea/SKILL.md +9 -0
  96. package/skills/cm-clean-code/SKILL.md +20 -0
  97. package/skills/cm-code-review/SKILL.md +21 -0
  98. package/skills/cm-codeintell/SKILL.md +9 -0
  99. package/skills/cm-conductor-worktrees/SKILL.archive.md +28 -0
  100. package/skills/cm-conductor-worktrees/SKILL.md +17 -19
  101. package/skills/cm-continuity/SKILL.md +9 -0
  102. package/skills/cm-dashboard/SKILL.archive.md +15 -0
  103. package/skills/cm-dashboard/SKILL.md +20 -9
  104. package/skills/cm-dashboard/ui/app.js +9 -1
  105. package/skills/cm-debugging/SKILL.md +9 -0
  106. package/skills/cm-design-studio/SKILL.archive.md +34 -0
  107. package/skills/cm-design-studio/SKILL.md +17 -25
  108. package/skills/cm-design-system/SKILL.md +1 -0
  109. package/skills/cm-engineering-meta/SKILL.archive.md +73 -0
  110. package/skills/cm-engineering-meta/SKILL.md +16 -63
  111. package/skills/cm-execution/SKILL.md +98 -0
  112. package/skills/cm-git-worktrees/SKILL.archive.md +157 -0
  113. package/skills/cm-git-worktrees/SKILL.md +15 -146
  114. package/skills/cm-identity-guard/SKILL.md +8 -0
  115. package/skills/cm-planning/SKILL.md +63 -92
  116. package/skills/cm-post-deploy-canary/SKILL.archive.md +22 -0
  117. package/skills/cm-post-deploy-canary/SKILL.md +17 -13
  118. package/skills/cm-qa-visual-cli/SKILL.archive.md +22 -0
  119. package/skills/cm-qa-visual-cli/SKILL.md +16 -12
  120. package/skills/cm-quality-gate/SKILL.md +38 -0
  121. package/skills/cm-safe-deploy/SKILL.md +9 -0
  122. package/skills/cm-second-opinion-cli/SKILL.archive.md +23 -0
  123. package/skills/cm-second-opinion-cli/SKILL.md +17 -14
  124. package/skills/cm-secret-shield/SKILL.archive.md +580 -0
  125. package/skills/cm-secret-shield/SKILL.md +15 -569
  126. package/skills/cm-security-gate/SKILL.archive.md +239 -0
  127. package/skills/cm-security-gate/SKILL.md +15 -228
  128. package/skills/cm-skill-health/SKILL.archive.md +83 -0
  129. package/skills/cm-skill-health/SKILL.md +16 -73
  130. package/skills/cm-skill-index/SKILL.md +8 -0
  131. package/skills/cm-skill-mastery/SKILL.archive.md +156 -0
  132. package/skills/cm-skill-mastery/SKILL.md +16 -146
  133. package/skills/cm-skill-search/SKILL.archive.md +49 -0
  134. package/skills/cm-skill-search/SKILL.md +17 -40
  135. package/skills/cm-skill-share/SKILL.archive.md +58 -0
  136. package/skills/cm-skill-share/SKILL.md +17 -49
  137. package/skills/cm-sprint-bus/SKILL.md +9 -0
  138. package/skills/cm-start/SKILL.md +17 -0
  139. package/skills/cm-tdd/SKILL.md +19 -0
  140. package/skills/cm-terminal/SKILL.md +15 -0
  141. package/skills/cm-test-gate/SKILL.archive.md +245 -0
  142. package/skills/cm-test-gate/SKILL.md +15 -234
  143. package/skills/cm-ui-preview/SKILL.archive.md +153 -0
  144. package/skills/cm-ui-preview/SKILL.md +16 -143
  145. package/skills/cm-ux-master/cli/uxmaster/commands/mcp.py +1 -1
  146. package/skills/cm-ux-master/mcp/mcp-config.json +1 -1
  147. package/skills/cm-ux-master/mcp/server.py +2 -2
  148. package/skills/profiles/design.txt +1 -1
  149. package/skills/profiles/full.txt +0 -10
  150. package/skills/profiles/growth.txt +8 -8
  151. package/skills/profiles/knowledge.txt +1 -1
  152. package/skills/profiles/top35.json +41 -0
  153. package/adapters/antigravity.js +0 -15
  154. package/adapters/claude-code.js +0 -17
  155. package/adapters/cursor.js +0 -16
  156. package/skills/cm-ads-tracker/SKILL.md +0 -401
  157. package/skills/cm-ads-tracker/evals/evals.json +0 -55
  158. package/skills/cm-ads-tracker/references/gtm-architecture.md +0 -321
  159. package/skills/cm-ads-tracker/references/industry-events.md +0 -294
  160. package/skills/cm-ads-tracker/references/platforms-api.md +0 -238
  161. package/skills/cm-ads-tracker/templates/capi-payload.md +0 -79
  162. package/skills/cm-ads-tracker/templates/datalayer-push.js +0 -104
  163. package/skills/cm-ads-tracker/templates/gtm-variables.js +0 -56
  164. package/skills/cm-auto-publisher/SKILL.md +0 -81
  165. package/skills/cm-booking-calendar/SKILL.md +0 -521
  166. package/skills/cm-booking-calendar/references/industry-patterns.md +0 -527
  167. package/skills/cm-booking-calendar/templates/booking-form.css +0 -626
  168. package/skills/cm-booking-calendar/templates/booking-form.html +0 -477
  169. package/skills/cm-booking-calendar/templates/calendar-engine.js +0 -419
  170. package/skills/cm-booking-calendar/templates/calendar-export.js +0 -395
  171. package/skills/cm-booking-calendar/templates/reminder-config.js +0 -629
  172. package/skills/cm-content-factory/.content-factory-state.json +0 -132
  173. package/skills/cm-content-factory/.git 2/logs/refs/heads/main +0 -1
  174. package/skills/cm-content-factory/.git 2/logs/refs/remotes/origin/main +0 -1
  175. package/skills/cm-content-factory/.git 2/objects/02/fb0956734b5f8ba3f918b7defd04a89cfe0076 +0 -0
  176. package/skills/cm-content-factory/.git 2/objects/08/1e129d75dc6feac6c02037272e6bd1a04e3324 +0 -0
  177. package/skills/cm-content-factory/.git 2/objects/0c/5393416f3c5e01c9a655a802bff0dd52f76f0a +0 -0
  178. package/skills/cm-content-factory/.git 2/objects/10/0b9be46978a946a77188f68be725098a122001 +0 -0
  179. package/skills/cm-content-factory/.git 2/objects/10/cf041167fc9843610eb3d90259ef3396315fdc +0 -0
  180. package/skills/cm-content-factory/.git 2/objects/12/5e19538dd6e1338ffe74f6c4c165b00435bf48 +0 -0
  181. package/skills/cm-content-factory/.git 2/objects/16/a9b9d0088d5c1347628b45a2620b479d8ad57c +0 -0
  182. package/skills/cm-content-factory/.git 2/objects/17/8c2a9ef93c33ae4eec9d58e82321f9229843a1 +0 -0
  183. package/skills/cm-content-factory/.git 2/objects/25/397ae41d09104d763bdcac2695209d85cdea89 +0 -0
  184. package/skills/cm-content-factory/.git 2/objects/2f/a836b7947f2d458e1f639788bf4bb0983a3305 +0 -0
  185. package/skills/cm-content-factory/.git 2/objects/3a/baaaf0a1c0909c0828335791557125fba911e0 +0 -0
  186. package/skills/cm-content-factory/.git 2/objects/42/2924221b81f5ce3c4e4daac9a64a24f9b01f9a +0 -0
  187. package/skills/cm-content-factory/.git 2/objects/42/ec0ce707447dc11446a34c9995fb8533801731 +0 -0
  188. package/skills/cm-content-factory/.git 2/objects/46/e43ce92866d56ce74b1d750db307cfe6154a15 +0 -0
  189. package/skills/cm-content-factory/.git 2/objects/48/5e41b633c63f55b8277bcc59f44f67681f671a +0 -0
  190. package/skills/cm-content-factory/.git 2/objects/49/49c596a3a89fa240642acd95dd3258e261eb09 +0 -0
  191. package/skills/cm-content-factory/.git 2/objects/50/9d42d8412ef8eaf7f7e138476bac2e4d10ce60 +0 -0
  192. package/skills/cm-content-factory/.git 2/objects/55/0c8c389d981b463ef849aeb792d8be3ccb6ec8 +0 -0
  193. package/skills/cm-content-factory/.git 2/objects/5d/82d3b18410cdda3ace3677436f0cb599dbe2d2 +0 -0
  194. package/skills/cm-content-factory/.git 2/objects/60/0617c58e871a38b33bf29e282d132bb3c381ad +0 -0
  195. package/skills/cm-content-factory/.git 2/objects/6a/8369a99c687b7245c92ffaf0e0f0dab9014504 +0 -0
  196. package/skills/cm-content-factory/.git 2/objects/79/bea435d40ab531c1aaf6be0432c6a5b7aaed21 +0 -0
  197. package/skills/cm-content-factory/.git 2/objects/7e/5ebd79251c2f14e4aceb86c74b6b6daae6b500 +0 -0
  198. package/skills/cm-content-factory/.git 2/objects/81/98a822a60178d6d5023ddb3e222cddf048742e +0 -0
  199. package/skills/cm-content-factory/.git 2/objects/86/0a0e1943dfe53411d2e499a1f16f46a96ef758 +0 -0
  200. package/skills/cm-content-factory/.git 2/objects/86/971fb55fdc081fdbae52376f0f13e57a4e9b04 +0 -0
  201. package/skills/cm-content-factory/.git 2/objects/88/b89dd609a0a03f8d4fe8bfde20d5b8fc1d326d +0 -0
  202. package/skills/cm-content-factory/.git 2/objects/90/8737edb6b7809e32cc01590b4e08ba42a9d40d +0 -0
  203. package/skills/cm-content-factory/.git 2/objects/93/d5a8a9a7d4fb7f11491cb596a6880528725118 +0 -0
  204. package/skills/cm-content-factory/.git 2/objects/98/46a2ab81d0c3b3eb00ef88fc56989aa7e9f316 +0 -0
  205. package/skills/cm-content-factory/.git 2/objects/9b/d8dd1e49cf274eaf9c555f3ab39dce7af5715e +0 -0
  206. package/skills/cm-content-factory/.git 2/objects/a1/13329fb0cec96ae78b222d33a24c3b5bc7fa1f +0 -0
  207. package/skills/cm-content-factory/.git 2/objects/a9/e6effe626e8a3aea3a8fc3364b492191c6e7d0 +0 -0
  208. package/skills/cm-content-factory/.git 2/objects/ad/6de7e48d9782cca9353d1ff0aa1aab7fe1df85 +0 -0
  209. package/skills/cm-content-factory/.git 2/objects/af/54ae316f771ff692e299ffcd8bf2f06b413b59 +0 -0
  210. package/skills/cm-content-factory/.git 2/objects/b0/4cb8b0b00dad633e731c1472161419e738d674 +0 -0
  211. package/skills/cm-content-factory/.git 2/objects/b3/094abb0b9ed46419b269e4a4e36a459690e3b0 +0 -0
  212. package/skills/cm-content-factory/.git 2/objects/b9/435c5d4baac2cfc5c83009ddd27b46b60db5f1 +0 -0
  213. package/skills/cm-content-factory/.git 2/objects/ba/5da17dbaec5ec2dcfdfd126aead518d1171d5c +0 -0
  214. package/skills/cm-content-factory/.git 2/objects/c0/bf58703aa258ba5dd63083bebaec8f223d844c +0 -0
  215. package/skills/cm-content-factory/.git 2/objects/c4/701a34edf1fc1bad58ccc57bd03f9426acb59a +0 -0
  216. package/skills/cm-content-factory/.git 2/objects/c7/5ccce9a4e5cc74d9b3174550cf6d993ca43638 +0 -0
  217. package/skills/cm-content-factory/.git 2/objects/c7/710d59b5a35b0f1f0a0399386643a0bd94c929 +0 -0
  218. package/skills/cm-content-factory/.git 2/objects/d1/fe58237112e953e5fec52da22cf38e08be3df9 +0 -5
  219. package/skills/cm-content-factory/.git 2/objects/d2/2bbe9fd2f74c95bc5583e803f5e435f1e2cd86 +0 -0
  220. package/skills/cm-content-factory/.git 2/objects/d7/e72852ea2bff74581dbf247d400120086229f4 +0 -0
  221. package/skills/cm-content-factory/.git 2/objects/d8/d4c3b5553e4fd72807e1d4b49ef07d9ef3ac35 +0 -0
  222. package/skills/cm-content-factory/.git 2/objects/dc/75050c2876f6a02ae2a53a3c886f395b622977 +0 -0
  223. package/skills/cm-content-factory/.git 2/objects/ee/e8546f95acec500187c08a28a8b9ee02db0dec +0 -0
  224. package/skills/cm-content-factory/.git 2/objects/ef/263c059208b416c2146434f10cb2b9fabcba16 +0 -0
  225. package/skills/cm-content-factory/.git 2/objects/f3/ae597e84d9a59b88acd21c99bde2eaf686d785 +0 -0
  226. package/skills/cm-content-factory/.git 2/objects/f3/f6f5673c821d3d8e76fa267a9e882e7a5387ea +0 -0
  227. package/skills/cm-content-factory/.git 2/objects/f9/6e6d0ad02624dd11d5848594d056caef7a5e8b +0 -0
  228. package/skills/cm-content-factory/.git 2/objects/ff/278988fc1edf0db3abcf18de795f4cc0b4f3e1 +0 -0
  229. package/skills/cm-content-factory/.git 2/refs/heads/main +0 -1
  230. package/skills/cm-content-factory/.git 2/refs/remotes/origin/main +0 -1
  231. package/skills/cm-content-factory/.pytest_cache 2/v/cache/nodeids +0 -76
  232. package/skills/cm-content-factory/.pytest_cache 2/v/cache/stepwise +0 -1
  233. package/skills/cm-content-factory/AGENTS.md +0 -61
  234. package/skills/cm-content-factory/CLAUDE.md +0 -63
  235. package/skills/cm-content-factory/CURSOR.md +0 -43
  236. package/skills/cm-content-factory/Content Factory.zip +0 -0
  237. package/skills/cm-content-factory/SKILL.md +0 -416
  238. package/skills/cm-content-factory/cf +0 -313
  239. package/skills/cm-content-factory/config.schema.json +0 -397
  240. package/skills/cm-content-factory/dashboard/app.js +0 -556
  241. package/skills/cm-content-factory/dashboard/index.html +0 -397
  242. package/skills/cm-content-factory/dashboard/style.css +0 -1211
  243. package/skills/cm-content-factory/examples/01-real-estate.config.json +0 -146
  244. package/skills/cm-content-factory/examples/02-personal-finance.config.json +0 -146
  245. package/skills/cm-content-factory/examples/03-health-wellness.config.json +0 -147
  246. package/skills/cm-content-factory/examples/04-saas-software.config.json +0 -147
  247. package/skills/cm-content-factory/examples/05-legal-services.config.json +0 -147
  248. package/skills/cm-content-factory/examples/06-insurance.config.json +0 -146
  249. package/skills/cm-content-factory/examples/07-ecommerce-dropship.config.json +0 -146
  250. package/skills/cm-content-factory/examples/08-online-education.config.json +0 -147
  251. package/skills/cm-content-factory/examples/09-crypto-defi.config.json +0 -147
  252. package/skills/cm-content-factory/examples/10-beauty-skincare.config.json +0 -147
  253. package/skills/cm-content-factory/examples/11-home-services.config.json +0 -146
  254. package/skills/cm-content-factory/examples/12-dental-clinic.config.json +0 -147
  255. package/skills/cm-content-factory/examples/13-pet-care.config.json +0 -147
  256. package/skills/cm-content-factory/examples/14-travel-hospitality.config.json +0 -147
  257. package/skills/cm-content-factory/examples/15-ai-automation.config.json +0 -147
  258. package/skills/cm-content-factory/examples/16-wedding-events.config.json +0 -147
  259. package/skills/cm-content-factory/examples/17-fitness-coaching.config.json +0 -148
  260. package/skills/cm-content-factory/examples/18-cybersecurity.config.json +0 -147
  261. package/skills/cm-content-factory/examples/19-food-restaurant.config.json +0 -148
  262. package/skills/cm-content-factory/examples/20-solar-energy.config.json +0 -147
  263. package/skills/cm-content-factory/examples/fitness-blog.config.json +0 -116
  264. package/skills/cm-content-factory/examples/tech-blog.config.json +0 -107
  265. package/skills/cm-content-factory/extensions/EXTENSION_GUIDE.md +0 -72
  266. package/skills/cm-content-factory/extensions/hooks.py +0 -126
  267. package/skills/cm-content-factory/extensions/openclaw_adapter.py +0 -132
  268. package/skills/cm-content-factory/landing/docs/content/changelog.md +0 -36
  269. package/skills/cm-content-factory/landing/docs/content/deployment.md +0 -46
  270. package/skills/cm-content-factory/landing/docs/content/execution-flow.md +0 -67
  271. package/skills/cm-content-factory/landing/docs/content/memory-system.md +0 -38
  272. package/skills/cm-content-factory/landing/docs/content/openspace.md +0 -27
  273. package/skills/cm-content-factory/landing/docs/content/use-cases.md +0 -26
  274. package/skills/cm-content-factory/landing/docs/content/v5-intro.md +0 -28
  275. package/skills/cm-content-factory/landing/docs/index.html +0 -240
  276. package/skills/cm-content-factory/landing/index.html +0 -680
  277. package/skills/cm-content-factory/landing/script.js +0 -143
  278. package/skills/cm-content-factory/landing/style.css +0 -1216
  279. package/skills/cm-content-factory/landing/translations.js +0 -508
  280. package/skills/cm-content-factory/logs/events.jsonl +0 -11
  281. package/skills/cm-content-factory/profiles/_template.profile.json +0 -231
  282. package/skills/cm-content-factory/profiles/finance.profile.json +0 -278
  283. package/skills/cm-content-factory/profiles/legal.profile.json +0 -263
  284. package/skills/cm-content-factory/profiles/medical-research.profile.json +0 -321
  285. package/skills/cm-content-factory/profiles/technology.profile.json +0 -275
  286. package/skills/cm-content-factory/scripts/agent_dispatcher.py +0 -266
  287. package/skills/cm-content-factory/scripts/audit.py +0 -106
  288. package/skills/cm-content-factory/scripts/dashboard_server.py +0 -225
  289. package/skills/cm-content-factory/scripts/deploy.py +0 -146
  290. package/skills/cm-content-factory/scripts/extract.py +0 -132
  291. package/skills/cm-content-factory/scripts/landing_generator.py +0 -459
  292. package/skills/cm-content-factory/scripts/memory.py +0 -521
  293. package/skills/cm-content-factory/scripts/monetize.py +0 -239
  294. package/skills/cm-content-factory/scripts/pipeline.py +0 -357
  295. package/skills/cm-content-factory/scripts/plan.py +0 -163
  296. package/skills/cm-content-factory/scripts/publish.py +0 -145
  297. package/skills/cm-content-factory/scripts/research.py +0 -337
  298. package/skills/cm-content-factory/scripts/scaffold.py +0 -464
  299. package/skills/cm-content-factory/scripts/scoreboard.py +0 -336
  300. package/skills/cm-content-factory/scripts/seo.py +0 -90
  301. package/skills/cm-content-factory/scripts/state_manager.py +0 -320
  302. package/skills/cm-content-factory/scripts/token_manager.py +0 -268
  303. package/skills/cm-content-factory/scripts/validate.py +0 -221
  304. package/skills/cm-content-factory/scripts/wizard.py +0 -329
  305. package/skills/cm-content-factory/scripts/write.py +0 -93
  306. package/skills/cm-content-factory/sites/docs-site/src/assets/houston.webp +0 -0
  307. package/skills/cm-content-factory/sites/docs-site/src/content/docs/architecture.md +0 -90
  308. package/skills/cm-content-factory/sites/docs-site/src/content/docs/data-flow.md +0 -54
  309. package/skills/cm-content-factory/sites/docs-site/src/content/docs/deployment.md +0 -38
  310. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/index.md +0 -65
  311. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/lc-content-lifecycle.md +0 -48
  312. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/seq-write-mode.md +0 -39
  313. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/uj-first-batch.md +0 -42
  314. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/wf-content-pipeline.md +0 -51
  315. package/skills/cm-content-factory/sites/docs-site/src/content/docs/flows/wf-learning-cycle.md +0 -52
  316. package/skills/cm-content-factory/sites/docs-site/src/content/docs/getting-started/configuration.md +0 -86
  317. package/skills/cm-content-factory/sites/docs-site/src/content/docs/getting-started/installation.md +0 -80
  318. package/skills/cm-content-factory/sites/docs-site/src/content/docs/getting-started/intro.md +0 -58
  319. package/skills/cm-content-factory/sites/docs-site/src/content/docs/index.md +0 -102
  320. package/skills/cm-content-factory/sites/docs-site/src/content/docs/jtbd/index.md +0 -45
  321. package/skills/cm-content-factory/sites/docs-site/src/content/docs/jtbd/optimize-seo.md +0 -29
  322. package/skills/cm-content-factory/sites/docs-site/src/content/docs/jtbd/scale-content-production.md +0 -55
  323. package/skills/cm-content-factory/sites/docs-site/src/content/docs/jtbd/standardize-quality.md +0 -29
  324. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/buyer-cmo-huong.md +0 -41
  325. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/buyer-content-lead-khoa.md +0 -40
  326. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/index.md +0 -56
  327. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/user-content-manager-lan.md +0 -46
  328. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/user-seo-minh.md +0 -45
  329. package/skills/cm-content-factory/sites/docs-site/src/content/docs/personas/user-writer-tu.md +0 -45
  330. package/skills/cm-content-factory/sites/docs-site/src/content/docs/sop/content-pipeline.md +0 -108
  331. package/skills/cm-content-factory/sites/docs-site/src/content/docs/sop/index.md +0 -22
  332. package/skills/cm-content-factory/sites/docs-site/src/content/docs/sop/memory-system.md +0 -52
  333. package/skills/cm-content-factory/sites/docs-site/src/content/docs/sop/seo-optimization.md +0 -58
  334. package/skills/cm-content-factory/sites/docs-site/src/content/docs/sop/troubleshooting-guide.md +0 -92
  335. package/skills/cm-content-factory/sites/docs-site/src/styles/custom.css +0 -575
  336. package/skills/cm-content-factory/tests/conftest.py +0 -66
  337. package/skills/cm-content-factory/tests/test_agent_dispatcher.py +0 -125
  338. package/skills/cm-content-factory/tests/test_memory.py +0 -128
  339. package/skills/cm-content-factory/tests/test_pipeline.py +0 -107
  340. package/skills/cm-content-factory/tests/test_research.py +0 -56
  341. package/skills/cm-content-factory/tests/test_state_manager.py +0 -131
  342. package/skills/cm-content-factory/tests/test_token_manager.py +0 -110
  343. package/skills/cm-content-factory/tests/test_wizard.py +0 -121
  344. package/skills/cm-cro-methodology/SKILL.md +0 -290
  345. package/skills/cm-cro-methodology/references/COPYWRITING.md +0 -178
  346. package/skills/cm-cro-methodology/references/OBJECTIONS.md +0 -135
  347. package/skills/cm-cro-methodology/references/PERSUASION.md +0 -158
  348. package/skills/cm-cro-methodology/references/RESEARCH.md +0 -220
  349. package/skills/cm-cro-methodology/references/funnel-analysis.md +0 -365
  350. package/skills/cm-cro-methodology/references/testing-methodology.md +0 -330
  351. package/skills/cm-google-form/SKILL.md +0 -266
  352. package/skills/cm-google-form/templates/apps-script.js +0 -55
  353. package/skills/cm-google-form/templates/form-markup.html +0 -110
  354. package/skills/cm-google-form/templates/form-submit.js +0 -201
  355. package/skills/cm-google-form/templates/toast.css +0 -152
  356. package/skills/cm-growth-hacking/SKILL.md +0 -282
  357. package/skills/cm-growth-hacking/bottom-sheet-engine.md +0 -261
  358. package/skills/cm-growth-hacking/calendar-integration.md +0 -264
  359. package/skills/cm-growth-hacking/references/engagement-patterns.md +0 -346
  360. package/skills/cm-growth-hacking/templates/bottom-sheet.css +0 -528
  361. package/skills/cm-growth-hacking/templates/bottom-sheet.js +0 -269
  362. package/skills/cm-growth-hacking/templates/calendar-cta.js +0 -213
  363. package/skills/cm-growth-hacking/templates/tracking-events.js +0 -211
  364. package/skills/cm-growth-hacking/templates/trigger-manager.js +0 -254
  365. package/skills/cm-growth-hacking/tracking-events.md +0 -246
  366. package/skills/cm-growth-hacking/trigger-system.md +0 -342
  367. package/skills/cm-jtbd/SKILL.md +0 -98
  368. package/skills/cm-notebooklm/SKILL.md +0 -156
  369. package/skills/cm-notebooklm/references/command_reference.md +0 -94
  370. package/skills/cm-notebooklm/references/workflows.md +0 -60
  371. package/skills/cm-notebooklm/resources/knowledge_sources.md +0 -106
  372. package/skills/cm-notebooklm/scripts/brain-sync.sh +0 -453
  373. package/skills/cm-notebooklm/scripts/graduate_wisdom.py +0 -101
  374. package/skills/cm-readit/SKILL.md +0 -289
  375. package/skills/cm-readit/audio-player.md +0 -206
  376. package/skills/cm-readit/examples/blog-reader.js +0 -352
  377. package/skills/cm-readit/examples/voice-cro.js +0 -390
  378. package/skills/cm-readit/tts-engine.md +0 -262
  379. package/skills/cm-readit/ui-patterns.md +0 -362
  380. package/skills/cm-readit/voice-cro.md +0 -223
@@ -1,101 +0,0 @@
1
- #!/usr/bin/env python3
2
- import os
3
- import json
4
- from datetime import datetime
5
- import re
6
-
7
- BRAIN_DIR = os.path.expanduser("~/.codymaster")
8
- GRADUATED_FILE = os.path.join(BRAIN_DIR, "graduated_wisdom.md")
9
-
10
- def get_existing_ids():
11
- if not os.path.exists(GRADUATED_FILE):
12
- return set()
13
- with open(GRADUATED_FILE, 'r', encoding='utf-8') as f:
14
- content = f.read()
15
- # Find all **ID:** patterns
16
- ids = set(re.findall(r'\*\*ID:\*\*\s+([A-Z0-9_-]+)', content))
17
- return ids
18
-
19
- def append_to_graduated(text):
20
- os.makedirs(BRAIN_DIR, exist_ok=True)
21
- with open(GRADUATED_FILE, 'a', encoding='utf-8') as f:
22
- f.write(text)
23
-
24
- def graduate_learnings(existing_ids):
25
- learnings_path = os.path.join(os.getcwd(), ".cm", "learnings.json")
26
- if not os.path.exists(learnings_path):
27
- return 0
28
-
29
- count = 0
30
- try:
31
- with open(learnings_path, 'r', encoding='utf-8') as f:
32
- learnings = json.load(f)
33
-
34
- for l in learnings:
35
- lid = str(l.get('id', ''))
36
- status = l.get('status', 'active')
37
- reinforce_count = int(l.get('reinforceCount', 0))
38
-
39
- if status == "active" and reinforce_count >= 3 and lid and lid not in existing_ids:
40
- md = f"""
41
- ### Learning: {l.get('error', 'Unknown Error')}
42
- **ID:** {lid}
43
- **Date Graduated:** {datetime.now().strftime('%Y-%m-%d')}
44
- **Scope:** {l.get('scope', 'global')}
45
- **Cause:** {l.get('cause', '')}
46
- **Prevention:** {l.get('prevention', '')}
47
- **Reinforced:** {reinforce_count} times
48
-
49
- """
50
- append_to_graduated(md)
51
- existing_ids.add(lid)
52
- count += 1
53
- except Exception as e:
54
- print(f"Error processing {learnings_path}: {e}")
55
- return count
56
-
57
- def graduate_decisions(existing_ids):
58
- decisions_path = os.path.join(os.getcwd(), ".cm", "decisions.json")
59
- if not os.path.exists(decisions_path):
60
- return 0
61
-
62
- count = 0
63
- try:
64
- with open(decisions_path, 'r', encoding='utf-8') as f:
65
- decisions = json.load(f)
66
-
67
- for d in decisions:
68
- did = str(d.get('id', ''))
69
- status = d.get('status', 'active')
70
-
71
- if status == "active" and did and did not in existing_ids:
72
- md = f"""
73
- ### Architecture Decision: {d.get('decision', 'Unknown')}
74
- **ID:** {did}
75
- **Date Graduated:** {datetime.now().strftime('%Y-%m-%d')}
76
- **Scope:** {d.get('scope', 'global')}
77
- **Rationale:** {d.get('rationale', '')}
78
-
79
- """
80
- append_to_graduated(md)
81
- existing_ids.add(did)
82
- count += 1
83
- except Exception as e:
84
- print(f"Error processing {decisions_path}: {e}")
85
- return count
86
-
87
- def main():
88
- existing_ids = get_existing_ids()
89
- start_count = len(existing_ids)
90
-
91
- l_count = graduate_learnings(existing_ids)
92
- d_count = graduate_decisions(existing_ids)
93
-
94
- if l_count > 0 or d_count > 0:
95
- print(f"✅ Graduated {l_count} learnings and {d_count} decisions to NotebookLM Brain.")
96
- print(f" → Saved to {GRADUATED_FILE}")
97
- else:
98
- print("💡 No new highly-reinforced learnings or active decisions to graduate.")
99
-
100
- if __name__ == "__main__":
101
- main()
@@ -1,289 +0,0 @@
1
- ---
2
- name: cm-readit
3
- description: Turn any website into an audio-enabled experience. Covers TTS reading mode (SpeechSynthesis API), pre-recorded MP3 audio player, and Voice CRO trigger system. Zero dependencies, works on any static or dynamic site. Use when adding read-aloud, audio player, or voice-based conversion features.
4
- allowed-tools: Read, Write, Edit, Glob, Grep, Bash
5
- ---
6
-
7
- # CM ReadIt — Web Audio Experience Skill
8
-
9
- > **Philosophy:** Reading is passive. Listening is intimate. Voice builds trust faster than any headline.
10
- > **Core Principle:** Zero dependencies. Progressive enhancement. Respect user's device and preferences.
11
-
12
- ---
13
-
14
- ## 🎯 Selective Reading Rule (MANDATORY)
15
-
16
- | File | Status | When to Read |
17
- |------|--------|--------------|
18
- | [tts-engine.md](tts-engine.md) | 🔴 **REQUIRED** | Adding TTS / read-aloud to any page |
19
- | [audio-player.md](audio-player.md) | ⚪ Optional | Pre-recorded MP3 playback |
20
- | [voice-cro.md](voice-cro.md) | ⚪ Optional | Trigger-based voice sales / CRO |
21
- | [ui-patterns.md](ui-patterns.md) | ⚪ Optional | Player bar & bottom sheet design |
22
-
23
- > 🔴 **tts-engine.md = ALWAYS READ when implementing TTS. Others = only if relevant.**
24
-
25
- ---
26
-
27
- ## Quick Decision Tree
28
-
29
- ```
30
- "I need audio on my website"
31
-
32
- ├─ Read article content aloud (text-to-speech)
33
- │ └─ Use: TTS Engine → tts-engine.md
34
- │ ├─ Blog / article pages → Content Reader pattern
35
- │ ├─ Documentation → Section Reader pattern
36
- │ └─ E-commerce → Product Description Reader pattern
37
-
38
- ├─ Play pre-recorded audio files (MP3/WAV)
39
- │ └─ Use: Audio Player → audio-player.md
40
- │ ├─ Podcasts / interviews → Playlist pattern
41
- │ ├─ Sales pitch / welcome → Triggered playback
42
- │ └─ Background ambient → Loop pattern
43
-
44
- ├─ Voice-based conversion optimization (CRO)
45
- │ └─ Use: Voice CRO → voice-cro.md
46
- │ ├─ Landing pages → Trigger-based bottom sheet
47
- │ ├─ Service pages → Per-page audio scripts
48
- │ └─ Course pages → Social proof audio
49
-
50
- └─ Combination (TTS + CRO)
51
- └─ Read tts-engine.md + voice-cro.md
52
- └─ Ensure no conflict (TTS reader vs CRO player)
53
- ```
54
-
55
- ---
56
-
57
- ## 🧠 Core Principles (Internalize These)
58
-
59
- ### 1. The 3 Audio Engines
60
-
61
- | Engine | API | Source | Best For |
62
- |--------|-----|--------|----------|
63
- | **TTS Reader** | `SpeechSynthesis` | Page text content | Blogs, articles, docs |
64
- | **Audio Player** | `HTMLAudioElement` | Pre-recorded MP3 | Sales, podcasts, guides |
65
- | **Voice CRO** | `Audio` + triggers | MP3 + behavior detection | Landing pages, sales |
66
-
67
- ### 2. Progressive Enhancement
68
-
69
- ```
70
- Feature detection → Graceful degradation → Never break the page
71
-
72
- if (!('speechSynthesis' in window)) return; // TTS
73
- if (!window.Audio) return; // Audio
74
- ```
75
-
76
- **Rule:** Audio features are ENHANCEMENTS. The page must function 100% without them.
77
-
78
- ### 3. Content Extraction Principle
79
-
80
- ```
81
- Clone → Strip → Clean → Split → Speak
82
-
83
- DON'T read the raw DOM.
84
- DO clone, remove noise, extract clean text.
85
- ```
86
-
87
- **Strip list (always remove before speaking):**
88
- - CTAs, promotions, ads
89
- - Navigation, footer, sidebar
90
- - Images, videos, iframes, SVGs
91
- - Scripts, styles, hidden elements
92
- - Tags, badges, metadata
93
-
94
- ### 4. The Chunking Problem
95
-
96
- Browsers have a **hard limit** on utterance length (~3000-5000 chars depending on browser/OS). Long text must be split into chunks.
97
-
98
- ```
99
- Split Strategy:
100
- ├─ Split on sentence boundaries (. ! ? \n)
101
- ├─ Max chunk: 2500 chars (safe across all browsers)
102
- ├─ Preserve sentence integrity (never split mid-sentence)
103
- └─ Chain chunks via onend callback
104
- ```
105
-
106
- ### 5. Voice Selection Priority
107
-
108
- ```
109
- Language voices:
110
- 1. Local service voice (faster, works offline)
111
- 2. Network voice (higher quality, needs internet)
112
- 3. Any voice matching language prefix
113
- 4. null (browser default)
114
- ```
115
-
116
- ### 6. Chrome Keep-Alive Bug
117
-
118
- > ⚠️ **CRITICAL:** Chrome silently stops SpeechSynthesis after ~15 seconds of continuous speech. This is the #1 gotcha.
119
-
120
- ```javascript
121
- // Workaround: pause/resume every 10s
122
- setInterval(() => {
123
- if (synth.speaking && !synth.paused) {
124
- synth.pause();
125
- synth.resume();
126
- }
127
- }, 10000);
128
- ```
129
-
130
- ### 7. synth.cancel() Triggers onerror
131
-
132
- > ⚠️ **GOTCHA:** Calling `synth.cancel()` fires the `onerror` event on any active utterance with error type `'canceled'` or `'interrupted'`.
133
-
134
- **Solution:** Use a guard flag or check error type:
135
- ```javascript
136
- u.onerror = function(e) {
137
- if (e.error === 'canceled' || e.error === 'interrupted') return;
138
- stopReading();
139
- };
140
- ```
141
-
142
- ---
143
-
144
- ## 🏗️ Architecture Pattern
145
-
146
- ### Minimal TTS Reader (Copy-Paste Starting Point)
147
-
148
- ```
149
- ┌─────────────────────────────────────────┐
150
- │ IIFE │
151
- │ │
152
- │ ┌─ Feature Detection ─┐ │
153
- │ │ speechSynthesis? │ │
154
- │ └──────────┬───────────┘ │
155
- │ ▼ │
156
- │ ┌─ Content Extraction ─┐ │
157
- │ │ Clone → Strip → Clean│ │
158
- │ └──────────┬────────────┘ │
159
- │ ▼ │
160
- │ ┌─ Chunking Engine ────┐ │
161
- │ │ Split on sentences │ │
162
- │ │ Max 2500 chars │ │
163
- │ └──────────┬────────────┘ │
164
- │ ▼ │
165
- │ ┌─ Utterance Builder ──┐ │
166
- │ │ Set voice/rate/pitch │ │
167
- │ │ Chain via onend │ │
168
- │ └──────────┬────────────┘ │
169
- │ ▼ │
170
- │ ┌─ Player UI ──────────┐ │
171
- │ │ Bar: play/pause/stop │ │
172
- │ │ Progress indicator │ │
173
- │ │ Trigger button │ │
174
- │ └──────────┬────────────┘ │
175
- │ ▼ │
176
- │ ┌─ Keep-Alive Timer ───┐ │
177
- │ │ pause/resume @ 10s │ │
178
- │ └───────────────────────┘ │
179
- └──────────────────────────────────────────┘
180
- ```
181
-
182
- ### Lifecycle
183
-
184
- ```
185
- Init → Detect → Inject Trigger Button
186
-
187
- User clicks ▶
188
-
189
- Extract Text → Chunk → Build Utterances
190
-
191
- synth.speak(chunk[0])
192
-
193
- chunk[0].onend → speak(chunk[1]) → ... → speak(chunk[N])
194
- │ │
195
- Keep-Alive Timer running chunk[N].onend
196
- │ │
197
- User clicks ⏸ → synth.pause() stopReading()
198
- User clicks ▶ → synth.resume() cleanup UI
199
- User clicks ✕ → synth.cancel()
200
- ```
201
-
202
- ---
203
-
204
- ## 📐 Implementation Checklist
205
-
206
- ### For TTS Reader
207
- - [ ] Feature detection (`speechSynthesis` in window)
208
- - [ ] Content container identified (ID or selector)
209
- - [ ] Strip list defined (what to remove before reading)
210
- - [ ] Chunk size set (default 2500)
211
- - [ ] Voice selection logic (language-specific)
212
- - [ ] Player bar UI (play/pause/close + progress)
213
- - [ ] Trigger button injected (topbar or floating)
214
- - [ ] Chrome keep-alive timer (10s interval)
215
- - [ ] `onerror` guard (handle cancel/interrupted)
216
- - [ ] `beforeunload` cleanup
217
- - [ ] `prefers-reduced-motion` respect
218
- - [ ] Mobile safe-area padding
219
-
220
- ### For Audio Player
221
- - [ ] Audio files hosted and accessible
222
- - [ ] Preload strategy (`none` → load on demand)
223
- - [ ] Play/pause toggle with state management
224
- - [ ] Progress bar with `currentTime/duration`
225
- - [ ] Error handling (network, format, autoplay policy)
226
- - [ ] Session state (dismissed = don't show again)
227
-
228
- ### For Voice CRO
229
- - [ ] Per-page config object (delay, scroll threshold, audio URLs)
230
- - [ ] Trigger conditions (time + scroll AND/OR interaction)
231
- - [ ] Bottom sheet UI (icon, text, CTA, dismiss)
232
- - [ ] Player bar UI (toggle, progress, CTA button)
233
- - [ ] Session dismissal tracking
234
- - [ ] Stats tracking (shown/listened/dismissed)
235
- - [ ] No conflict with TTS Reader
236
-
237
- ---
238
-
239
- ## ⚠️ Common Pitfalls
240
-
241
- | Pitfall | Symptom | Fix |
242
- |---------|---------|-----|
243
- | Chrome stops after 15s | Audio cuts mid-sentence | Keep-alive timer (pause/resume) |
244
- | `synth.cancel()` fires onerror | Settings sheet closes immediately | Guard flag or check error type |
245
- | Voices not loaded | No voice available | Listen for `voiceschanged` event |
246
- | Chunk too large | Utterance fails silently | Max 2500 chars per chunk |
247
- | Reading CTA text | TTS reads "Book Now" button text | Strip non-content elements |
248
- | Autoplay blocked | Audio won't start on mobile | Require user interaction first |
249
- | Multiple audio conflicts | TTS + CRO play simultaneously | Mutual exclusion check |
250
- | No cleanup on nav | Audio keeps playing | `beforeunload` → `synth.cancel()` |
251
-
252
- ---
253
-
254
- ## 🌐 Multi-Language Support
255
-
256
- ```
257
- Voice selection by language:
258
- ├─ Vietnamese: v.lang === 'vi-VN' || v.lang.startsWith('vi')
259
- ├─ English: v.lang === 'en-US' || v.lang.startsWith('en')
260
- ├─ Japanese: v.lang === 'ja-JP' || v.lang.startsWith('ja')
261
- ├─ Korean: v.lang === 'ko-KR' || v.lang.startsWith('ko')
262
- └─ Any: Pass language code as config parameter
263
- ```
264
-
265
- Set `utterance.lang` to match the content language for correct pronunciation.
266
-
267
- ---
268
-
269
- ## 📚 Reference Files
270
-
271
- | File | Content |
272
- |------|---------|
273
- | [tts-engine.md](tts-engine.md) | Complete SpeechSynthesis API reference, chunking strategies, voice selection |
274
- | [audio-player.md](audio-player.md) | HTMLAudioElement patterns, preload strategies, error handling |
275
- | [voice-cro.md](voice-cro.md) | Trigger system, bottom sheet patterns, CRO analytics |
276
- | [ui-patterns.md](ui-patterns.md) | Player bar CSS, bottom sheet CSS, animations, responsive design |
277
-
278
- ---
279
-
280
- ## 🔗 Reference Implementations
281
-
282
- | File | Description |
283
- |------|-------------|
284
- | [examples/blog-reader.js](examples/blog-reader.js) | Complete TTS reader — Substack-style, 350 LOC |
285
- | [examples/voice-cro.js](examples/voice-cro.js) | Complete Voice CRO trigger system — 390 LOC |
286
-
287
- ---
288
-
289
- > **Remember:** Voice is the most personal interface. A well-placed audio feature can increase engagement 3-5x. But unwanted audio is the fastest way to lose a user. **Always require user initiation. Never autoplay.**
@@ -1,206 +0,0 @@
1
- # Audio Player — Pre-Recorded MP3 Patterns
2
-
3
- > For when you have pre-recorded audio files (sales pitch, podcast, guide) instead of generating speech from text.
4
-
5
- ---
6
-
7
- ## API Quick Reference
8
-
9
- ```javascript
10
- const audio = new Audio('/path/to/file.mp3');
11
-
12
- // Core methods
13
- audio.play() // Returns Promise (may reject: autoplay policy)
14
- audio.pause()
15
- audio.load() // Reload source
16
-
17
- // Properties
18
- audio.src // Source URL
19
- audio.currentTime // Current position (seconds)
20
- audio.duration // Total duration (NaN until loaded)
21
- audio.paused // boolean
22
- audio.ended // boolean
23
- audio.volume // 0.0 — 1.0
24
- audio.playbackRate // 0.25 — 4.0
25
- audio.preload // 'none' | 'metadata' | 'auto'
26
-
27
- // Events
28
- audio.onplay = fn;
29
- audio.onpause = fn;
30
- audio.onended = fn;
31
- audio.onerror = fn;
32
- audio.ontimeupdate = fn; // Fires during playback (~4x/second)
33
- audio.onloadedmetadata = fn; // duration now available
34
- audio.oncanplay = fn; // Enough data to start playing
35
- ```
36
-
37
- ---
38
-
39
- ## Patterns
40
-
41
- ### Simple Play/Pause Toggle
42
-
43
- ```javascript
44
- let audio = null;
45
- let isPlaying = false;
46
-
47
- function play(src) {
48
- if (!audio) audio = new Audio(src);
49
-
50
- const promise = audio.play();
51
- if (promise) {
52
- promise
53
- .then(() => { isPlaying = true; updateUI(); })
54
- .catch(() => { isPlaying = false; updateUI(); });
55
- }
56
- }
57
-
58
- function togglePause() {
59
- if (!audio) return;
60
- if (audio.paused) {
61
- audio.play();
62
- isPlaying = true;
63
- } else {
64
- audio.pause();
65
- isPlaying = false;
66
- }
67
- updateUI();
68
- }
69
-
70
- function stop() {
71
- if (audio) {
72
- audio.pause();
73
- audio.currentTime = 0;
74
- audio = null;
75
- }
76
- isPlaying = false;
77
- updateUI();
78
- }
79
- ```
80
-
81
- ### Progress Tracking
82
-
83
- ```javascript
84
- function startProgressTracking(audioEl, barEl) {
85
- const update = () => {
86
- if (!audioEl || !barEl) return;
87
- if (audioEl.duration) {
88
- barEl.style.width = (audioEl.currentTime / audioEl.duration * 100) + '%';
89
- }
90
- if (!audioEl.paused && !audioEl.ended) {
91
- requestAnimationFrame(update);
92
- }
93
- };
94
-
95
- audioEl.addEventListener('play', () => requestAnimationFrame(update));
96
- requestAnimationFrame(update);
97
- }
98
- ```
99
-
100
- ### 2-Part Audio Flow (Intro → Full)
101
-
102
- ```javascript
103
- function playIntro(cfg) {
104
- playingPart = 1;
105
- showPlayer();
106
-
107
- playAudio(cfg.audio[0], () => {
108
- // Intro done → offer full version
109
- showNextButton();
110
- updateLabel('Bạn muốn nghe thêm?');
111
- });
112
- }
113
-
114
- function playFull(cfg) {
115
- playingPart = 2;
116
- hideNextButton();
117
-
118
- playAudio(cfg.audio[1], () => {
119
- // Full done → show CTA
120
- updateLabel('Cảm ơn bạn đã lắng nghe!');
121
- showCTA();
122
- });
123
- }
124
- ```
125
-
126
- ---
127
-
128
- ## Preload Strategies
129
-
130
- | Strategy | Value | When to Use |
131
- |----------|-------|------------|
132
- | `none` | Don't preload | Default. Save bandwidth. Load on demand. |
133
- | `metadata` | Load duration/size | When showing duration in UI |
134
- | `auto` | Preload full file | Small files (<500KB) that will definitely play |
135
-
136
- **Recommendation:** Always default to `'none'`. Only preload when user has indicated intent to listen.
137
-
138
- ---
139
-
140
- ## Autoplay Policy
141
-
142
- > ⚠️ All modern browsers block autoplay of audio without user interaction.
143
-
144
- **Rule:** NEVER try to autoplay. Always require a user gesture (click/tap) before first `audio.play()`.
145
-
146
- ```javascript
147
- // ❌ WRONG: This will be blocked
148
- window.onload = () => new Audio('/intro.mp3').play();
149
-
150
- // ✅ CORRECT: User initiates
151
- button.addEventListener('click', () => {
152
- new Audio('/intro.mp3').play();
153
- });
154
- ```
155
-
156
- ---
157
-
158
- ## Error Handling
159
-
160
- ```javascript
161
- audio.addEventListener('error', (e) => {
162
- switch (audio.error?.code) {
163
- case MediaError.MEDIA_ERR_ABORTED:
164
- // User aborted — ignore
165
- break;
166
- case MediaError.MEDIA_ERR_NETWORK:
167
- // Network error — show retry
168
- showRetryButton();
169
- break;
170
- case MediaError.MEDIA_ERR_DECODE:
171
- // Decode error — file corrupted
172
- showError('File audio bị lỗi');
173
- break;
174
- case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
175
- // Format not supported
176
- showError('Trình duyệt không hỗ trợ');
177
- break;
178
- }
179
- });
180
- ```
181
-
182
- ---
183
-
184
- ## Format Support
185
-
186
- | Format | Chrome | Safari | Firefox | Edge |
187
- |--------|--------|--------|---------|------|
188
- | MP3 | ✅ | ✅ | ✅ | ✅ |
189
- | AAC | ✅ | ✅ | ✅ | ✅ |
190
- | OGG | ✅ | ❌ | ✅ | ✅ |
191
- | WAV | ✅ | ✅ | ✅ | ✅ |
192
- | WebM | ✅ | ❌ | ✅ | ✅ |
193
-
194
- **Recommendation:** Use **MP3** for maximum compatibility. 128kbps is sufficient for voice.
195
-
196
- ---
197
-
198
- ## File Size Guidelines
199
-
200
- | Content Type | Duration | Recommended Bitrate | Approx. Size |
201
- |-------------|----------|-------------------|--------------|
202
- | Voice only | 30s | 64 kbps | ~240 KB |
203
- | Voice + ambient | 60s | 128 kbps | ~960 KB |
204
- | High quality | 2 min | 192 kbps | ~2.8 MB |
205
-
206
- **Rule of thumb:** Keep audio files under **1 MB** for mobile users. Split long content into intro + full.