@thierrynakoa/fire-flow 12.2.1 → 13.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 (500) hide show
  1. package/CREDITS.md +25 -0
  2. package/DOMINION-FLOW-OVERVIEW.md +182 -38
  3. package/README.md +399 -455
  4. package/TROUBLESHOOTING.md +264 -264
  5. package/agents/fire-debugger.md +54 -0
  6. package/agents/fire-executor.md +1610 -1033
  7. package/agents/fire-fact-checker.md +1 -1
  8. package/agents/fire-planner.md +85 -17
  9. package/agents/fire-project-researcher.md +1 -1
  10. package/agents/fire-researcher.md +4 -22
  11. package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
  12. package/agents/fire-reviewer.md +552 -499
  13. package/agents/fire-verifier.md +114 -19
  14. package/bin/cli.js +18 -101
  15. package/commands/fire-0-orient.md +2 -2
  16. package/commands/fire-1a-new.md +50 -15
  17. package/commands/fire-1c-setup.md +33 -5
  18. package/commands/fire-1d-discuss.md +87 -1
  19. package/commands/fire-2-plan.md +556 -527
  20. package/commands/fire-3-execute.md +2046 -1356
  21. package/commands/fire-4-verify.md +975 -906
  22. package/commands/fire-5-handoff.md +46 -5
  23. package/commands/fire-6-resume.md +2 -31
  24. package/commands/fire-add-new-skill.md +138 -19
  25. package/commands/fire-autonomous.md +14 -2
  26. package/commands/fire-complete-milestone.md +1 -1
  27. package/commands/fire-cost.md +179 -183
  28. package/commands/fire-debug.md +1 -6
  29. package/commands/fire-loop-resume.md +2 -2
  30. package/commands/fire-loop-stop.md +1 -1
  31. package/commands/fire-loop.md +2 -15
  32. package/commands/fire-map-codebase.md +1 -1
  33. package/commands/fire-migrate-database.md +548 -0
  34. package/commands/fire-new-milestone.md +1 -1
  35. package/commands/fire-reflect.md +1 -2
  36. package/commands/fire-research.md +142 -21
  37. package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
  38. package/commands/fire-scaffold.md +297 -0
  39. package/commands/fire-search.md +1 -2
  40. package/commands/fire-security-scan.md +483 -484
  41. package/commands/fire-setup.md +359 -0
  42. package/commands/fire-skill.md +770 -0
  43. package/commands/fire-skills-diff.md +506 -506
  44. package/commands/fire-skills-history.md +388 -388
  45. package/commands/fire-skills-rollback.md +7 -7
  46. package/commands/fire-skills-sync.md +470 -470
  47. package/commands/fire-test.md +5 -5
  48. package/commands/fire-todos.md +1 -1
  49. package/commands/fire-update.md +5 -5
  50. package/commands/fire-validate-skills.md +282 -0
  51. package/commands/fire-vuln-scan.md +492 -493
  52. package/hooks/run-hook.sh +8 -8
  53. package/hooks/run-session-end.sh +7 -7
  54. package/hooks/session-end.sh +90 -90
  55. package/hooks/session-start.sh +1 -1
  56. package/package.json +4 -24
  57. package/plugin.json +7 -7
  58. package/references/autonomy-levels.md +235 -0
  59. package/references/behavioral-directives.md +95 -3
  60. package/references/blocker-tracking.md +1 -1
  61. package/references/circuit-breaker.md +93 -2
  62. package/references/context-engineering.md +227 -9
  63. package/references/honesty-protocols.md +70 -1
  64. package/references/issue-to-pr-pipeline.md +149 -150
  65. package/references/metrics-and-trends.md +1 -2
  66. package/references/research-improvements.md +4 -108
  67. package/references/sdlc-mapping.md +73 -0
  68. package/references/state-machine.md +151 -0
  69. package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
  70. package/skills-library/SKILLS-INDEX.md +57 -558
  71. package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
  72. package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
  73. package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
  74. package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
  75. package/skills-library/_general/automation/settings-gui-generator.md +172 -0
  76. package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
  77. package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
  78. package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
  79. package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
  80. package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
  81. package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
  82. package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
  83. package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
  84. package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
  85. package/skills-library/_general/frontend/color-token-migration.md +112 -0
  86. package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
  87. package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
  88. package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
  89. package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
  90. package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
  91. package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
  92. package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
  93. package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
  94. package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
  95. package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
  96. package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
  97. package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
  98. package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
  99. package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
  100. package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
  101. package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
  102. package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
  103. package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
  104. package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
  105. package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
  106. package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
  107. package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
  108. package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
  109. package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
  110. package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
  111. package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
  112. package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
  113. package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
  114. package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
  115. package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
  116. package/skills-library/_general/methodology/dead-code-activation.md +123 -0
  117. package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
  118. package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
  119. package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
  120. package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
  121. package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
  122. package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
  123. package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
  124. package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
  125. package/skills-library/_general/performance/liveclock-extraction.md +112 -0
  126. package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
  127. package/skills-library/_general/performance/use-visible-interval.md +131 -0
  128. package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
  129. package/skills-library/_quarantine/README.md +30 -0
  130. package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
  131. package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
  132. package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
  133. package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
  134. package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
  135. package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
  136. package/skills-library/api-patterns/graphql-content-queries.md +708 -0
  137. package/skills-library/appointment-scheduler-design.md +423 -0
  138. package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
  139. package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
  140. package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
  141. package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
  142. package/skills-library/automation/scheduled-content-publishing.md +608 -0
  143. package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
  144. package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
  145. package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
  146. package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
  147. package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
  148. package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
  149. package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
  150. package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
  151. package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
  152. package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
  153. package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
  154. package/skills-library/cms-patterns/content-branch-preview.md +515 -0
  155. package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
  156. package/skills-library/cms-patterns/mdx-component-content.md +649 -0
  157. package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
  158. package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
  159. package/skills-library/complexity-metrics/complexity-divider.md +707 -0
  160. package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
  161. package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
  162. package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
  163. package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
  164. package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
  165. package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
  166. package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
  167. package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
  168. package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
  169. package/skills-library/creative-multimedia/og-image-generator.md +635 -0
  170. package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
  171. package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
  172. package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
  173. package/skills-library/creative-multimedia/svg-generation.md +750 -0
  174. package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
  175. package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
  176. package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
  177. package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
  178. package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
  179. package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
  180. package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
  181. package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
  182. package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
  183. package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
  184. package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
  185. package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
  186. package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
  187. package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
  188. package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
  189. package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
  190. package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
  191. package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
  192. package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
  193. package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
  194. package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
  195. package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
  196. package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
  197. package/skills-library/database-solutions/content-publishing-states.md +631 -0
  198. package/skills-library/database-solutions/database-schema-designer.md +522 -0
  199. package/skills-library/database-solutions/er-diagram-components.md +569 -0
  200. package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
  201. package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
  202. package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
  203. package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
  204. package/skills-library/database-solutions/normalization-validator.md +778 -0
  205. package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
  206. package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
  207. package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
  208. package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
  209. package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
  210. package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
  211. package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
  212. package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
  213. package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
  214. package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
  215. package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
  216. package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
  217. package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
  218. package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
  219. package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
  220. package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
  221. package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
  222. package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
  223. package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
  224. package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
  225. package/skills-library/deployment-security/SECURITY.md +41 -0
  226. package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
  227. package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
  228. package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
  229. package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
  230. package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
  231. package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
  232. package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
  233. package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
  234. package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
  235. package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
  236. package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
  237. package/skills-library/deployment-security/vps-deployment.md +135 -0
  238. package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
  239. package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
  240. package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
  241. package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
  242. package/skills-library/document-processing/md-to-word-converter.md +318 -0
  243. package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
  244. package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
  245. package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
  246. package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
  247. package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
  248. package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
  249. package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
  250. package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
  251. package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
  252. package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
  253. package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
  254. package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
  255. package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
  256. package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
  257. package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
  258. package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
  259. package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
  260. package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
  261. package/skills-library/ecommerce/inventory-stock-management.md +270 -0
  262. package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
  263. package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
  264. package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
  265. package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
  266. package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
  267. package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
  268. package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
  269. package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
  270. package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
  271. package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
  272. package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
  273. package/skills-library/excalidraw-diagrams/LICENSE +21 -0
  274. package/skills-library/excalidraw-diagrams/README.md +178 -0
  275. package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
  276. package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
  277. package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
  278. package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
  279. package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
  280. package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
  281. package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
  282. package/skills-library/infrastructure/observability-designer.md +264 -0
  283. package/skills-library/infrastructure/performance-profiler.md +621 -0
  284. package/skills-library/installer-wizard-patterns.md +249 -0
  285. package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
  286. package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
  287. package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
  288. package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
  289. package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
  290. package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
  291. package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
  292. package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
  293. package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
  294. package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
  295. package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
  296. package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
  297. package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
  298. package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
  299. package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
  300. package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
  301. package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
  302. package/skills-library/integrations/headless-cms-architecture.md +484 -0
  303. package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
  304. package/skills-library/integrations/payload-cms-patterns.md +674 -0
  305. package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
  306. package/skills-library/integrations/rss-podcast-integration.md +300 -0
  307. package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
  308. package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
  309. package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
  310. package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
  311. package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
  312. package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
  313. package/skills-library/marketing/campaign-analytics.md +97 -0
  314. package/skills-library/marketing/content-creator.md +105 -0
  315. package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
  316. package/skills-library/marketing/social-media-analyzer.md +81 -0
  317. package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
  318. package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
  319. package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
  320. package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
  321. package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
  322. package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
  323. package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
  324. package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
  325. package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
  326. package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
  327. package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
  328. package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
  329. package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
  330. package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
  331. package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
  332. package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
  333. package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
  334. package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
  335. package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
  336. package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
  337. package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
  338. package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
  339. package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
  340. package/skills-library/methodology/tech-debt-tracker.md +570 -0
  341. package/skills-library/parallel-debug/SKILL.md +60 -0
  342. package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
  343. package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
  344. package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
  345. package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
  346. package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
  347. package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
  348. package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
  349. package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
  350. package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
  351. package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
  352. package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
  353. package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
  354. package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
  355. package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
  356. package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
  357. package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
  358. package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
  359. package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
  360. package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
  361. package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
  362. package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
  363. package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
  364. package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
  365. package/skills-library/security/admin-deletion-safety.md +396 -0
  366. package/skills-library/security/application-vuln-patterns.md +477 -0
  367. package/skills-library/security/env-secrets-manager.md +686 -0
  368. package/skills-library/security/secure-ai-application-templates.md +347 -0
  369. package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
  370. package/skills-library/supabase-connection-pooler-fix.md +102 -0
  371. package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
  372. package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
  373. package/skills-library/system-context/SKILL.md +40 -0
  374. package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
  375. package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
  376. package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
  377. package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
  378. package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
  379. package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
  380. package/skills-library/testing/playwright-api-security-tests.md +202 -0
  381. package/skills-library/toolbox/SKILL.md +84 -0
  382. package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
  383. package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
  384. package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
  385. package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
  386. package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
  387. package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
  388. package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
  389. package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
  390. package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
  391. package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
  392. package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
  393. package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  394. package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  395. package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  396. package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  397. package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  398. package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  399. package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  400. package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  401. package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
  402. package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  403. package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  404. package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  405. package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  406. package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
  407. package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
  408. package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  409. package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  410. package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
  411. package/skills-library/wordpress-style-theme-components.md +1526 -0
  412. package/templates/ASSUMPTIONS.md +1 -1
  413. package/templates/DECISION_LOG.md +0 -1
  414. package/templates/phase-prompt.md +1 -1
  415. package/templates/phoenix-comparison.md +6 -6
  416. package/templates/skill-api-integration.md +106 -0
  417. package/templates/skill-architecture-pattern.md +92 -0
  418. package/templates/skill-debug-pattern.md +98 -0
  419. package/templates/skill-devops-recipe.md +107 -0
  420. package/templates/skill-general.md +65 -0
  421. package/templates/skill-ui-component.md +113 -0
  422. package/tools/uat-runner.py +179 -0
  423. package/version.json +7 -3
  424. package/workflows/handoff-session.md +2 -2
  425. package/workflows/new-project.md +2 -2
  426. package/workflows/plan-phase.md +1 -1
  427. package/.claude-plugin/plugin.json +0 -64
  428. package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
  429. package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
  430. package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
  431. package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
  432. package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
  433. package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
  434. package/skills-library/specialists/api-architecture/api-designer.md +0 -49
  435. package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
  436. package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
  437. package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
  438. package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
  439. package/skills-library/specialists/backend/django-expert.md +0 -52
  440. package/skills-library/specialists/backend/fastapi-expert.md +0 -52
  441. package/skills-library/specialists/backend/laravel-specialist.md +0 -52
  442. package/skills-library/specialists/backend/nestjs-expert.md +0 -51
  443. package/skills-library/specialists/backend/rails-expert.md +0 -53
  444. package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
  445. package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
  446. package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
  447. package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
  448. package/skills-library/specialists/data-ml/rag-architect.md +0 -51
  449. package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
  450. package/skills-library/specialists/frontend/angular-architect.md +0 -52
  451. package/skills-library/specialists/frontend/flutter-expert.md +0 -51
  452. package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
  453. package/skills-library/specialists/frontend/react-native-expert.md +0 -50
  454. package/skills-library/specialists/frontend/vue-expert.md +0 -51
  455. package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
  456. package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
  457. package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
  458. package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
  459. package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
  460. package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
  461. package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
  462. package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
  463. package/skills-library/specialists/languages/cpp-pro.md +0 -74
  464. package/skills-library/specialists/languages/csharp-developer.md +0 -69
  465. package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
  466. package/skills-library/specialists/languages/golang-pro.md +0 -51
  467. package/skills-library/specialists/languages/java-architect.md +0 -49
  468. package/skills-library/specialists/languages/javascript-pro.md +0 -68
  469. package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
  470. package/skills-library/specialists/languages/php-pro.md +0 -49
  471. package/skills-library/specialists/languages/python-pro.md +0 -52
  472. package/skills-library/specialists/languages/react-expert.md +0 -51
  473. package/skills-library/specialists/languages/rust-engineer.md +0 -50
  474. package/skills-library/specialists/languages/sql-pro.md +0 -56
  475. package/skills-library/specialists/languages/swift-expert.md +0 -69
  476. package/skills-library/specialists/languages/typescript-pro.md +0 -51
  477. package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
  478. package/skills-library/specialists/platform/embedded-systems.md +0 -53
  479. package/skills-library/specialists/platform/game-developer.md +0 -53
  480. package/skills-library/specialists/platform/salesforce-developer.md +0 -53
  481. package/skills-library/specialists/platform/shopify-expert.md +0 -49
  482. package/skills-library/specialists/platform/wordpress-pro.md +0 -49
  483. package/skills-library/specialists/quality/code-documenter.md +0 -51
  484. package/skills-library/specialists/quality/code-reviewer.md +0 -67
  485. package/skills-library/specialists/quality/debugging-wizard.md +0 -51
  486. package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
  487. package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
  488. package/skills-library/specialists/quality/playwright-expert.md +0 -65
  489. package/skills-library/specialists/quality/spec-miner.md +0 -56
  490. package/skills-library/specialists/quality/test-master.md +0 -65
  491. package/skills-library/specialists/security/secure-code-guardian.md +0 -55
  492. package/skills-library/specialists/security/security-reviewer.md +0 -53
  493. package/skills-library/specialists/workflow/architecture-designer.md +0 -53
  494. package/skills-library/specialists/workflow/cli-developer.md +0 -70
  495. package/skills-library/specialists/workflow/feature-forge.md +0 -65
  496. package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
  497. package/skills-library/specialists/workflow/the-fool.md +0 -62
  498. /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
  499. /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
  500. /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
@@ -0,0 +1,827 @@
1
+ # Media Manager Abstraction
2
+
3
+ > One upload component that works with local disk, S3, or Cloudinary — swap providers without changing app code
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ A media manager that abstracts where files are stored. Upload an image in your app — it works the same whether files go to the local server, Amazon S3, Cloudinary, or any future provider. Switch providers by changing one config line, not rewriting upload code.
9
+
10
+ **Why this matters:**
11
+ - **Local dev:** Files go to `./uploads/` — no cloud accounts needed
12
+ - **Small VPS:** Files go to disk — no monthly cloud bills
13
+ - **Scale up:** Switch to S3 or Cloudinary — zero code changes
14
+ - **Ministry context:** Start free (local), upgrade when the church grows
15
+
16
+ ---
17
+
18
+ ## Architecture
19
+
20
+ ```
21
+ ┌─────────────────────────────────┐
22
+ │ React: MediaUploader Component │
23
+ │ (drag & drop, paste, browse) │
24
+ │ │
25
+ │ POST /api/media/upload │
26
+ └──────────────┬──────────────────┘
27
+
28
+ ┌──────────────▼──────────────────┐
29
+ │ Express: MediaService │
30
+ │ │
31
+ │ ┌───────────────────────────┐ │
32
+ │ │ Provider Interface │ │
33
+ │ │ │ │
34
+ │ │ upload(file) → url │ │
35
+ │ │ delete(key) → void │ │
36
+ │ │ list(prefix) → files[] │ │
37
+ │ │ getSignedUrl(key) → url │ │
38
+ │ └───────────┬───────────────┘ │
39
+ │ │ │
40
+ │ ┌──────────┼──────────┐ │
41
+ │ ▼ ▼ ▼ │
42
+ │ Local S3 Cloudinary │
43
+ │ Disk Bucket Account │
44
+ └─────────────────────────────────┘
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Provider Interface
50
+
51
+ ```js
52
+ // server/services/media/MediaProvider.js
53
+
54
+ /**
55
+ * Abstract interface for media storage providers.
56
+ * All providers must implement these methods.
57
+ */
58
+ class MediaProvider {
59
+ /**
60
+ * Upload a file and return its public URL.
61
+ * @param {Buffer} buffer - File content
62
+ * @param {string} filename - Original filename
63
+ * @param {string} mimeType - MIME type (e.g., 'image/jpeg')
64
+ * @param {string} folder - Optional subfolder (e.g., 'lessons', 'avatars')
65
+ * @returns {Promise<{ url: string, key: string, size: number }>}
66
+ */
67
+ async upload(buffer, filename, mimeType, folder = '') {
68
+ throw new Error('upload() not implemented');
69
+ }
70
+
71
+ /**
72
+ * Delete a file by its storage key.
73
+ * @param {string} key - Storage key returned from upload()
74
+ * @returns {Promise<void>}
75
+ */
76
+ async delete(key) {
77
+ throw new Error('delete() not implemented');
78
+ }
79
+
80
+ /**
81
+ * List files in a folder.
82
+ * @param {string} prefix - Folder prefix to list
83
+ * @param {number} limit - Max results
84
+ * @returns {Promise<Array<{ key: string, url: string, size: number, lastModified: Date }>>}
85
+ */
86
+ async list(prefix = '', limit = 50) {
87
+ throw new Error('list() not implemented');
88
+ }
89
+
90
+ /**
91
+ * Get a temporary signed URL for private files.
92
+ * For public providers (local, Cloudinary), this just returns the public URL.
93
+ * @param {string} key - Storage key
94
+ * @param {number} expiresInSeconds - URL expiry (default 3600)
95
+ * @returns {Promise<string>}
96
+ */
97
+ async getSignedUrl(key, expiresInSeconds = 3600) {
98
+ throw new Error('getSignedUrl() not implemented');
99
+ }
100
+ }
101
+
102
+ module.exports = MediaProvider;
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Provider: Local Disk
108
+
109
+ ```js
110
+ // server/services/media/LocalProvider.js
111
+ const fs = require('fs').promises;
112
+ const path = require('path');
113
+ const crypto = require('crypto');
114
+ const MediaProvider = require('./MediaProvider');
115
+
116
+ class LocalProvider extends MediaProvider {
117
+ constructor(config = {}) {
118
+ super();
119
+ this.uploadDir = config.uploadDir || path.join(process.cwd(), 'uploads');
120
+ this.publicPath = config.publicPath || '/uploads';
121
+ }
122
+
123
+ async upload(buffer, filename, mimeType, folder = '') {
124
+ const ext = path.extname(filename);
125
+ const hash = crypto.randomBytes(8).toString('hex');
126
+ const safeFilename = `${Date.now()}-${hash}${ext}`;
127
+
128
+ const dir = folder
129
+ ? path.join(this.uploadDir, folder)
130
+ : this.uploadDir;
131
+
132
+ await fs.mkdir(dir, { recursive: true });
133
+
134
+ const filePath = path.join(dir, safeFilename);
135
+ await fs.writeFile(filePath, buffer);
136
+
137
+ const key = folder ? `${folder}/${safeFilename}` : safeFilename;
138
+ const url = `${this.publicPath}/${key}`;
139
+
140
+ return { url, key, size: buffer.length };
141
+ }
142
+
143
+ async delete(key) {
144
+ const filePath = path.join(this.uploadDir, key);
145
+ try {
146
+ await fs.unlink(filePath);
147
+ } catch (err) {
148
+ if (err.code !== 'ENOENT') throw err;
149
+ }
150
+ }
151
+
152
+ async list(prefix = '', limit = 50) {
153
+ const dir = prefix
154
+ ? path.join(this.uploadDir, prefix)
155
+ : this.uploadDir;
156
+
157
+ try {
158
+ const files = await fs.readdir(dir);
159
+ const results = [];
160
+
161
+ for (const file of files.slice(0, limit)) {
162
+ const filePath = path.join(dir, file);
163
+ const stat = await fs.stat(filePath);
164
+ if (stat.isFile()) {
165
+ const key = prefix ? `${prefix}/${file}` : file;
166
+ results.push({
167
+ key,
168
+ url: `${this.publicPath}/${key}`,
169
+ size: stat.size,
170
+ lastModified: stat.mtime,
171
+ });
172
+ }
173
+ }
174
+
175
+ return results;
176
+ } catch (err) {
177
+ if (err.code === 'ENOENT') return [];
178
+ throw err;
179
+ }
180
+ }
181
+
182
+ async getSignedUrl(key) {
183
+ return `${this.publicPath}/${key}`;
184
+ }
185
+ }
186
+
187
+ module.exports = LocalProvider;
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Provider: Amazon S3
193
+
194
+ ```js
195
+ // server/services/media/S3Provider.js
196
+ const { S3Client, PutObjectCommand, DeleteObjectCommand,
197
+ ListObjectsV2Command, GetObjectCommand } = require('@aws-sdk/client-s3');
198
+ const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
199
+ const crypto = require('crypto');
200
+ const path = require('path');
201
+ const MediaProvider = require('./MediaProvider');
202
+
203
+ class S3Provider extends MediaProvider {
204
+ constructor(config) {
205
+ super();
206
+ this.bucket = config.bucket;
207
+ this.region = config.region || 'us-east-1';
208
+ this.prefix = config.prefix || '';
209
+ this.cdnUrl = config.cdnUrl || null; // Optional CloudFront URL
210
+
211
+ this.client = new S3Client({
212
+ region: this.region,
213
+ credentials: config.credentials || undefined, // Uses env vars if not provided
214
+ });
215
+ }
216
+
217
+ async upload(buffer, filename, mimeType, folder = '') {
218
+ const ext = path.extname(filename);
219
+ const hash = crypto.randomBytes(8).toString('hex');
220
+ const key = [this.prefix, folder, `${Date.now()}-${hash}${ext}`]
221
+ .filter(Boolean)
222
+ .join('/');
223
+
224
+ await this.client.send(new PutObjectCommand({
225
+ Bucket: this.bucket,
226
+ Key: key,
227
+ Body: buffer,
228
+ ContentType: mimeType,
229
+ }));
230
+
231
+ const url = this.cdnUrl
232
+ ? `${this.cdnUrl}/${key}`
233
+ : `https://${this.bucket}.s3.${this.region}.amazonaws.com/${key}`;
234
+
235
+ return { url, key, size: buffer.length };
236
+ }
237
+
238
+ async delete(key) {
239
+ await this.client.send(new DeleteObjectCommand({
240
+ Bucket: this.bucket,
241
+ Key: key,
242
+ }));
243
+ }
244
+
245
+ async list(prefix = '', limit = 50) {
246
+ const fullPrefix = [this.prefix, prefix].filter(Boolean).join('/');
247
+ const response = await this.client.send(new ListObjectsV2Command({
248
+ Bucket: this.bucket,
249
+ Prefix: fullPrefix,
250
+ MaxKeys: limit,
251
+ }));
252
+
253
+ return (response.Contents || []).map((obj) => ({
254
+ key: obj.Key,
255
+ url: this.cdnUrl
256
+ ? `${this.cdnUrl}/${obj.Key}`
257
+ : `https://${this.bucket}.s3.${this.region}.amazonaws.com/${obj.Key}`,
258
+ size: obj.Size,
259
+ lastModified: obj.LastModified,
260
+ }));
261
+ }
262
+
263
+ async getSignedUrl(key, expiresInSeconds = 3600) {
264
+ const command = new GetObjectCommand({ Bucket: this.bucket, Key: key });
265
+ return getSignedUrl(this.client, command, { expiresIn: expiresInSeconds });
266
+ }
267
+ }
268
+
269
+ module.exports = S3Provider;
270
+ ```
271
+
272
+ ---
273
+
274
+ ## Provider: Cloudinary
275
+
276
+ ```js
277
+ // server/services/media/CloudinaryProvider.js
278
+ const cloudinary = require('cloudinary').v2;
279
+ const crypto = require('crypto');
280
+ const MediaProvider = require('./MediaProvider');
281
+
282
+ class CloudinaryProvider extends MediaProvider {
283
+ constructor(config) {
284
+ super();
285
+ cloudinary.config({
286
+ cloud_name: config.cloudName,
287
+ api_key: config.apiKey,
288
+ api_secret: config.apiSecret,
289
+ });
290
+ this.folder = config.folder || '';
291
+ }
292
+
293
+ async upload(buffer, filename, mimeType, folder = '') {
294
+ const uploadFolder = [this.folder, folder].filter(Boolean).join('/');
295
+
296
+ return new Promise((resolve, reject) => {
297
+ const stream = cloudinary.uploader.upload_stream(
298
+ {
299
+ folder: uploadFolder,
300
+ resource_type: 'auto',
301
+ },
302
+ (err, result) => {
303
+ if (err) return reject(err);
304
+ resolve({
305
+ url: result.secure_url,
306
+ key: result.public_id,
307
+ size: result.bytes,
308
+ });
309
+ }
310
+ );
311
+ stream.end(buffer);
312
+ });
313
+ }
314
+
315
+ async delete(key) {
316
+ await cloudinary.uploader.destroy(key);
317
+ }
318
+
319
+ async list(prefix = '', limit = 50) {
320
+ const fullPrefix = [this.folder, prefix].filter(Boolean).join('/');
321
+ const result = await cloudinary.api.resources({
322
+ type: 'upload',
323
+ prefix: fullPrefix,
324
+ max_results: limit,
325
+ });
326
+
327
+ return result.resources.map((r) => ({
328
+ key: r.public_id,
329
+ url: r.secure_url,
330
+ size: r.bytes,
331
+ lastModified: new Date(r.created_at),
332
+ }));
333
+ }
334
+
335
+ async getSignedUrl(key) {
336
+ return cloudinary.url(key, { sign_url: true, type: 'authenticated' });
337
+ }
338
+ }
339
+
340
+ module.exports = CloudinaryProvider;
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Media Service (Factory + Database Tracking)
346
+
347
+ ```js
348
+ // server/services/media/MediaService.js
349
+ const LocalProvider = require('./LocalProvider');
350
+ const S3Provider = require('./S3Provider');
351
+ const CloudinaryProvider = require('./CloudinaryProvider');
352
+
353
+ class MediaService {
354
+ constructor(db, config = {}) {
355
+ this.db = db;
356
+ this.provider = MediaService.createProvider(config);
357
+ }
358
+
359
+ static createProvider(config) {
360
+ switch (config.provider || 'local') {
361
+ case 'local':
362
+ return new LocalProvider(config.local);
363
+ case 's3':
364
+ return new S3Provider(config.s3);
365
+ case 'cloudinary':
366
+ return new CloudinaryProvider(config.cloudinary);
367
+ default:
368
+ throw new Error(`Unknown media provider: ${config.provider}`);
369
+ }
370
+ }
371
+
372
+ async upload(file, folder, userId) {
373
+ // Upload to provider
374
+ const result = await this.provider.upload(file.buffer, file.originalname, file.mimetype, folder);
375
+
376
+ // Track in database
377
+ await this.db.query(
378
+ `INSERT INTO media_files (storage_key, url, filename, mime_type, size_bytes, folder, uploaded_by)
379
+ VALUES (?, ?, ?, ?, ?, ?, ?)`,
380
+ [result.key, result.url, file.originalname, file.mimetype, result.size, folder || null, userId]
381
+ );
382
+
383
+ return result;
384
+ }
385
+
386
+ async delete(key, userId) {
387
+ await this.provider.delete(key);
388
+ await this.db.query(`DELETE FROM media_files WHERE storage_key = ?`, [key]);
389
+ }
390
+
391
+ async list(folder = '', page = 1, limit = 20) {
392
+ const offset = (page - 1) * limit;
393
+ let query = `SELECT * FROM media_files`;
394
+ const params = [];
395
+
396
+ if (folder) {
397
+ query += ` WHERE folder = ?`;
398
+ params.push(folder);
399
+ }
400
+
401
+ query += ` ORDER BY created_at DESC LIMIT ? OFFSET ?`;
402
+ params.push(limit, offset);
403
+
404
+ return this.db.query(query, params);
405
+ }
406
+
407
+ async search(term) {
408
+ return this.db.query(
409
+ `SELECT * FROM media_files WHERE filename LIKE ? ORDER BY created_at DESC LIMIT 50`,
410
+ [`%${term}%`]
411
+ );
412
+ }
413
+ }
414
+
415
+ module.exports = MediaService;
416
+ ```
417
+
418
+ ---
419
+
420
+ ## Database Schema for Media Tracking
421
+
422
+ ### MySQL
423
+
424
+ ```sql
425
+ CREATE TABLE media_files (
426
+ id INT AUTO_INCREMENT PRIMARY KEY,
427
+ storage_key VARCHAR(500) NOT NULL,
428
+ url VARCHAR(1000) NOT NULL,
429
+ filename VARCHAR(255) NOT NULL,
430
+ mime_type VARCHAR(100) NOT NULL,
431
+ size_bytes INT NOT NULL,
432
+ folder VARCHAR(255),
433
+ alt_text VARCHAR(500),
434
+ uploaded_by VARCHAR(36) NOT NULL,
435
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
436
+
437
+ INDEX idx_folder (folder),
438
+ INDEX idx_mime (mime_type),
439
+ INDEX idx_uploader (uploaded_by),
440
+ FOREIGN KEY (uploaded_by) REFERENCES users(id)
441
+ );
442
+ ```
443
+
444
+ ### PostgreSQL
445
+
446
+ ```sql
447
+ CREATE TABLE media_files (
448
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
449
+ storage_key VARCHAR(500) NOT NULL,
450
+ url VARCHAR(1000) NOT NULL,
451
+ filename VARCHAR(255) NOT NULL,
452
+ mime_type VARCHAR(100) NOT NULL,
453
+ size_bytes INT NOT NULL,
454
+ folder VARCHAR(255),
455
+ alt_text VARCHAR(500),
456
+ uploaded_by UUID NOT NULL REFERENCES users(id),
457
+ created_at TIMESTAMPTZ DEFAULT NOW()
458
+ );
459
+
460
+ CREATE INDEX idx_mf_folder ON media_files(folder);
461
+ CREATE INDEX idx_mf_mime ON media_files(mime_type);
462
+ ```
463
+
464
+ ---
465
+
466
+ ## Configuration
467
+
468
+ ```js
469
+ // config/media.js
470
+ // Change provider by setting MEDIA_PROVIDER env var
471
+
472
+ module.exports = {
473
+ provider: process.env.MEDIA_PROVIDER || 'local',
474
+
475
+ local: {
476
+ uploadDir: process.env.UPLOAD_DIR || './uploads',
477
+ publicPath: '/uploads',
478
+ },
479
+
480
+ s3: {
481
+ bucket: process.env.AWS_S3_BUCKET,
482
+ region: process.env.AWS_REGION || 'us-east-1',
483
+ cdnUrl: process.env.CDN_URL || null,
484
+ credentials: process.env.AWS_ACCESS_KEY_ID ? {
485
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
486
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
487
+ } : undefined,
488
+ },
489
+
490
+ cloudinary: {
491
+ cloudName: process.env.CLOUDINARY_CLOUD_NAME,
492
+ apiKey: process.env.CLOUDINARY_API_KEY,
493
+ apiSecret: process.env.CLOUDINARY_API_SECRET,
494
+ folder: process.env.CLOUDINARY_FOLDER || 'ministry-lms',
495
+ },
496
+ };
497
+ ```
498
+
499
+ ---
500
+
501
+ ## React: Media Upload Component
502
+
503
+ ```jsx
504
+ // components/cms/MediaUploader.jsx
505
+ import { useState, useCallback } from 'react';
506
+
507
+ /**
508
+ * Drag-and-drop media uploader with preview.
509
+ *
510
+ * Props:
511
+ * folder — upload folder (e.g., 'lessons', 'avatars')
512
+ * accept — accepted MIME types (default: images)
513
+ * maxSizeMB — max file size in MB (default: 10)
514
+ * onUpload — callback(result) when upload succeeds
515
+ */
516
+ export default function MediaUploader({
517
+ folder = '',
518
+ accept = 'image/*',
519
+ maxSizeMB = 10,
520
+ onUpload,
521
+ }) {
522
+ const [uploading, setUploading] = useState(false);
523
+ const [preview, setPreview] = useState(null);
524
+ const [error, setError] = useState(null);
525
+ const [dragOver, setDragOver] = useState(false);
526
+
527
+ const handleFile = useCallback(async (file) => {
528
+ setError(null);
529
+
530
+ // Validate size
531
+ if (file.size > maxSizeMB * 1024 * 1024) {
532
+ setError(`File too large. Maximum ${maxSizeMB}MB.`);
533
+ return;
534
+ }
535
+
536
+ // Validate type
537
+ if (accept !== '*' && !file.type.match(accept.replace('*', '.*'))) {
538
+ setError(`Invalid file type. Accepted: ${accept}`);
539
+ return;
540
+ }
541
+
542
+ // Show preview for images
543
+ if (file.type.startsWith('image/')) {
544
+ const reader = new FileReader();
545
+ reader.onload = (e) => setPreview(e.target.result);
546
+ reader.readAsDataURL(file);
547
+ }
548
+
549
+ // Upload
550
+ setUploading(true);
551
+ try {
552
+ const formData = new FormData();
553
+ formData.append('file', file);
554
+ formData.append('folder', folder);
555
+
556
+ const res = await fetch('/api/media/upload', {
557
+ method: 'POST',
558
+ body: formData,
559
+ });
560
+
561
+ if (!res.ok) throw new Error('Upload failed');
562
+
563
+ const result = await res.json();
564
+ onUpload?.(result);
565
+ } catch (err) {
566
+ setError('Upload failed. Please try again.');
567
+ console.error(err);
568
+ } finally {
569
+ setUploading(false);
570
+ }
571
+ }, [folder, accept, maxSizeMB, onUpload]);
572
+
573
+ const handleDrop = (e) => {
574
+ e.preventDefault();
575
+ setDragOver(false);
576
+ const file = e.dataTransfer.files[0];
577
+ if (file) handleFile(file);
578
+ };
579
+
580
+ const handlePaste = (e) => {
581
+ const file = e.clipboardData?.files[0];
582
+ if (file) handleFile(file);
583
+ };
584
+
585
+ return (
586
+ <div
587
+ onDrop={handleDrop}
588
+ onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
589
+ onDragLeave={() => setDragOver(false)}
590
+ onPaste={handlePaste}
591
+ style={{
592
+ border: `2px dashed ${dragOver ? '#3b82f6' : '#d1d5db'}`,
593
+ borderRadius: '8px',
594
+ padding: '24px',
595
+ textAlign: 'center',
596
+ background: dragOver ? '#eff6ff' : '#fafafa',
597
+ transition: 'all 0.2s',
598
+ cursor: 'pointer',
599
+ }}
600
+ >
601
+ {preview && (
602
+ <img
603
+ src={preview}
604
+ alt="Preview"
605
+ style={{ maxWidth: '200px', maxHeight: '120px', borderRadius: '4px', marginBottom: '12px' }}
606
+ />
607
+ )}
608
+
609
+ {uploading ? (
610
+ <p>Uploading...</p>
611
+ ) : (
612
+ <>
613
+ <p style={{ margin: '0 0 8px', fontWeight: '500' }}>
614
+ Drop a file here, paste from clipboard, or click to browse
615
+ </p>
616
+ <input
617
+ type="file"
618
+ accept={accept}
619
+ onChange={(e) => e.target.files[0] && handleFile(e.target.files[0])}
620
+ style={{ display: 'none' }}
621
+ id="media-upload-input"
622
+ />
623
+ <label
624
+ htmlFor="media-upload-input"
625
+ style={{
626
+ background: '#3b82f6',
627
+ color: 'white',
628
+ padding: '8px 20px',
629
+ borderRadius: '6px',
630
+ cursor: 'pointer',
631
+ fontSize: '14px',
632
+ }}
633
+ >
634
+ Browse Files
635
+ </label>
636
+ <p style={{ color: '#9ca3af', fontSize: '13px', marginTop: '8px' }}>
637
+ Max {maxSizeMB}MB | {accept}
638
+ </p>
639
+ </>
640
+ )}
641
+
642
+ {error && (
643
+ <p style={{ color: '#ef4444', fontSize: '13px', marginTop: '8px' }}>{error}</p>
644
+ )}
645
+ </div>
646
+ );
647
+ }
648
+ ```
649
+
650
+ ---
651
+
652
+ ## React: Media Library Browser
653
+
654
+ ```jsx
655
+ // components/cms/MediaLibrary.jsx
656
+ import { useState, useEffect } from 'react';
657
+
658
+ /**
659
+ * Browse and select from uploaded media files.
660
+ * Use as a modal/panel when user needs to pick an image.
661
+ */
662
+ export default function MediaLibrary({ folder, onSelect, onClose }) {
663
+ const [files, setFiles] = useState([]);
664
+ const [loading, setLoading] = useState(true);
665
+ const [search, setSearch] = useState('');
666
+
667
+ useEffect(() => {
668
+ const url = search
669
+ ? `/api/media/search?q=${encodeURIComponent(search)}`
670
+ : `/api/media?folder=${folder || ''}`;
671
+
672
+ fetch(url)
673
+ .then((r) => r.json())
674
+ .then(setFiles)
675
+ .finally(() => setLoading(false));
676
+ }, [folder, search]);
677
+
678
+ return (
679
+ <div style={{
680
+ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)',
681
+ display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: 10000,
682
+ }}>
683
+ <div style={{
684
+ background: 'white', borderRadius: '12px', width: '90%', maxWidth: '800px',
685
+ maxHeight: '80vh', overflow: 'auto', padding: '24px',
686
+ }}>
687
+ <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '16px' }}>
688
+ <h3 style={{ margin: 0 }}>Media Library</h3>
689
+ <button onClick={onClose} style={{ background: 'none', border: 'none', fontSize: '20px', cursor: 'pointer' }}>
690
+ x
691
+ </button>
692
+ </div>
693
+
694
+ <input
695
+ type="text"
696
+ placeholder="Search files..."
697
+ value={search}
698
+ onChange={(e) => setSearch(e.target.value)}
699
+ style={{
700
+ width: '100%', padding: '8px 12px', border: '1px solid #d1d5db',
701
+ borderRadius: '6px', marginBottom: '16px', boxSizing: 'border-box',
702
+ }}
703
+ />
704
+
705
+ {loading ? (
706
+ <div>Loading...</div>
707
+ ) : (
708
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: '12px' }}>
709
+ {files.map((file) => (
710
+ <div
711
+ key={file.storage_key || file.key}
712
+ onClick={() => onSelect(file)}
713
+ style={{
714
+ cursor: 'pointer', border: '2px solid transparent', borderRadius: '8px',
715
+ overflow: 'hidden', transition: 'border-color 0.2s',
716
+ }}
717
+ onMouseEnter={(e) => e.currentTarget.style.borderColor = '#3b82f6'}
718
+ onMouseLeave={(e) => e.currentTarget.style.borderColor = 'transparent'}
719
+ >
720
+ {file.mime_type?.startsWith('image/') ? (
721
+ <img src={file.url} alt={file.filename} style={{ width: '100%', height: '100px', objectFit: 'cover' }} />
722
+ ) : (
723
+ <div style={{ width: '100%', height: '100px', background: '#f3f4f6', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
724
+ {file.mime_type?.split('/')[1] || 'file'}
725
+ </div>
726
+ )}
727
+ <div style={{ padding: '4px 6px', fontSize: '11px', color: '#6b7280', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
728
+ {file.filename}
729
+ </div>
730
+ </div>
731
+ ))}
732
+ </div>
733
+ )}
734
+ </div>
735
+ </div>
736
+ );
737
+ }
738
+ ```
739
+
740
+ ---
741
+
742
+ ## Express Routes
743
+
744
+ ```js
745
+ // server/routes/media.js
746
+ const multer = require('multer');
747
+ const MediaService = require('../services/media/MediaService');
748
+ const mediaConfig = require('../../config/media');
749
+
750
+ const upload = multer({
751
+ storage: multer.memoryStorage(),
752
+ limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
753
+ });
754
+
755
+ const mediaService = new MediaService(db, mediaConfig);
756
+
757
+ // Upload
758
+ router.post('/api/media/upload', authenticate, authorize(['admin', 'teacher']), upload.single('file'), async (req, res) => {
759
+ const result = await mediaService.upload(req.file, req.body.folder, req.user.id);
760
+ res.json(result);
761
+ });
762
+
763
+ // List
764
+ router.get('/api/media', authenticate, async (req, res) => {
765
+ const files = await mediaService.list(req.query.folder, parseInt(req.query.page) || 1);
766
+ res.json(files);
767
+ });
768
+
769
+ // Search
770
+ router.get('/api/media/search', authenticate, async (req, res) => {
771
+ const files = await mediaService.search(req.query.q);
772
+ res.json(files);
773
+ });
774
+
775
+ // Delete
776
+ router.delete('/api/media/:key(*)', authenticate, authorize(['admin']), async (req, res) => {
777
+ await mediaService.delete(req.params.key, req.user.id);
778
+ res.json({ message: 'Deleted' });
779
+ });
780
+ ```
781
+
782
+ ---
783
+
784
+ ## Switching Providers
785
+
786
+ ```bash
787
+ # Local development (default — no config needed)
788
+ # Files go to ./uploads/
789
+
790
+ # Switch to S3
791
+ MEDIA_PROVIDER=s3
792
+ AWS_S3_BUCKET=ministry-lms-media
793
+ AWS_REGION=us-east-1
794
+ AWS_ACCESS_KEY_ID=...
795
+ AWS_SECRET_ACCESS_KEY=...
796
+
797
+ # Switch to Cloudinary
798
+ MEDIA_PROVIDER=cloudinary
799
+ CLOUDINARY_CLOUD_NAME=your-cloud
800
+ CLOUDINARY_API_KEY=...
801
+ CLOUDINARY_API_SECRET=...
802
+ ```
803
+
804
+ Zero code changes. Same upload component, same API endpoints, different storage backend.
805
+
806
+ ---
807
+
808
+ ## Integration With Existing Skills
809
+
810
+ | Skill | How It Connects |
811
+ |-------|----------------|
812
+ | `inline-visual-editing.md` | Image field type uses MediaUploader + MediaLibrary |
813
+ | `schema-driven-form-generator.md` | `image` field type renders MediaUploader instead of text input |
814
+ | `image-optimization-pipeline.md` | Process images (resize, compress, WebP) before upload |
815
+ | `content-repurposing-pipeline.md` | Store generated media (thumbnails, audiograms) via same service |
816
+
817
+ ---
818
+
819
+ ## Security Checklist
820
+
821
+ - [ ] Validate file types on server (don't trust client MIME type — check magic bytes)
822
+ - [ ] Enforce file size limits in multer config
823
+ - [ ] Sanitize filenames (remove path traversal characters)
824
+ - [ ] Serve uploads from a separate domain or path (prevent XSS via uploaded HTML)
825
+ - [ ] Use signed URLs for private content (S3 pre-signed URLs)
826
+ - [ ] Rate limit upload endpoints
827
+ - [ ] Scan uploads for malware (optional — ClamAV integration)