javi-forge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/.gitignore.template +105 -0
  2. package/.releaserc +44 -0
  3. package/README.md +45 -0
  4. package/ai-config/.skillignore +15 -0
  5. package/ai-config/AUTO_INVOKE.md +300 -0
  6. package/ai-config/agents/_TEMPLATE.md +93 -0
  7. package/ai-config/agents/business/api-designer.md +1657 -0
  8. package/ai-config/agents/business/business-analyst.md +1331 -0
  9. package/ai-config/agents/business/product-strategist.md +206 -0
  10. package/ai-config/agents/business/project-manager.md +178 -0
  11. package/ai-config/agents/business/requirements-analyst.md +1277 -0
  12. package/ai-config/agents/business/technical-writer.md +1679 -0
  13. package/ai-config/agents/creative/ux-designer.md +205 -0
  14. package/ai-config/agents/data-ai/ai-engineer.md +487 -0
  15. package/ai-config/agents/data-ai/analytics-engineer.md +953 -0
  16. package/ai-config/agents/data-ai/data-engineer.md +173 -0
  17. package/ai-config/agents/data-ai/data-scientist.md +672 -0
  18. package/ai-config/agents/data-ai/mlops-engineer.md +814 -0
  19. package/ai-config/agents/data-ai/prompt-engineer.md +772 -0
  20. package/ai-config/agents/development/angular-expert.md +620 -0
  21. package/ai-config/agents/development/backend-architect.md +795 -0
  22. package/ai-config/agents/development/database-specialist.md +212 -0
  23. package/ai-config/agents/development/frontend-specialist.md +686 -0
  24. package/ai-config/agents/development/fullstack-engineer.md +668 -0
  25. package/ai-config/agents/development/golang-pro.md +338 -0
  26. package/ai-config/agents/development/java-enterprise.md +400 -0
  27. package/ai-config/agents/development/javascript-pro.md +422 -0
  28. package/ai-config/agents/development/nextjs-pro.md +474 -0
  29. package/ai-config/agents/development/python-pro.md +570 -0
  30. package/ai-config/agents/development/react-pro.md +487 -0
  31. package/ai-config/agents/development/rust-pro.md +246 -0
  32. package/ai-config/agents/development/spring-boot-4-expert.md +326 -0
  33. package/ai-config/agents/development/typescript-pro.md +336 -0
  34. package/ai-config/agents/development/vue-specialist.md +605 -0
  35. package/ai-config/agents/infrastructure/cloud-architect.md +472 -0
  36. package/ai-config/agents/infrastructure/deployment-manager.md +358 -0
  37. package/ai-config/agents/infrastructure/devops-engineer.md +455 -0
  38. package/ai-config/agents/infrastructure/incident-responder.md +519 -0
  39. package/ai-config/agents/infrastructure/kubernetes-expert.md +705 -0
  40. package/ai-config/agents/infrastructure/monitoring-specialist.md +674 -0
  41. package/ai-config/agents/infrastructure/performance-engineer.md +658 -0
  42. package/ai-config/agents/orchestrator.md +241 -0
  43. package/ai-config/agents/quality/accessibility-auditor.md +1204 -0
  44. package/ai-config/agents/quality/code-reviewer-compact.md +123 -0
  45. package/ai-config/agents/quality/code-reviewer.md +363 -0
  46. package/ai-config/agents/quality/dependency-manager.md +743 -0
  47. package/ai-config/agents/quality/e2e-test-specialist.md +1005 -0
  48. package/ai-config/agents/quality/performance-tester.md +1086 -0
  49. package/ai-config/agents/quality/security-auditor.md +133 -0
  50. package/ai-config/agents/quality/test-engineer.md +453 -0
  51. package/ai-config/agents/specialists/api-designer.md +87 -0
  52. package/ai-config/agents/specialists/backend-architect.md +73 -0
  53. package/ai-config/agents/specialists/code-reviewer.md +77 -0
  54. package/ai-config/agents/specialists/db-optimizer.md +75 -0
  55. package/ai-config/agents/specialists/devops-engineer.md +83 -0
  56. package/ai-config/agents/specialists/documentation-writer.md +78 -0
  57. package/ai-config/agents/specialists/frontend-developer.md +75 -0
  58. package/ai-config/agents/specialists/performance-analyst.md +82 -0
  59. package/ai-config/agents/specialists/refactor-specialist.md +74 -0
  60. package/ai-config/agents/specialists/security-auditor.md +74 -0
  61. package/ai-config/agents/specialists/test-engineer.md +81 -0
  62. package/ai-config/agents/specialists/ux-consultant.md +76 -0
  63. package/ai-config/agents/specialized/agent-generator.md +1190 -0
  64. package/ai-config/agents/specialized/blockchain-developer.md +149 -0
  65. package/ai-config/agents/specialized/code-migrator.md +892 -0
  66. package/ai-config/agents/specialized/context-manager.md +978 -0
  67. package/ai-config/agents/specialized/documentation-writer.md +1078 -0
  68. package/ai-config/agents/specialized/ecommerce-expert.md +1756 -0
  69. package/ai-config/agents/specialized/embedded-engineer.md +1714 -0
  70. package/ai-config/agents/specialized/error-detective.md +1034 -0
  71. package/ai-config/agents/specialized/fintech-specialist.md +1659 -0
  72. package/ai-config/agents/specialized/freelance-project-planner-v2.md +1988 -0
  73. package/ai-config/agents/specialized/freelance-project-planner-v3.md +2136 -0
  74. package/ai-config/agents/specialized/freelance-project-planner-v4.md +4503 -0
  75. package/ai-config/agents/specialized/freelance-project-planner.md +722 -0
  76. package/ai-config/agents/specialized/game-developer.md +1963 -0
  77. package/ai-config/agents/specialized/healthcare-dev.md +1620 -0
  78. package/ai-config/agents/specialized/mobile-developer.md +188 -0
  79. package/ai-config/agents/specialized/parallel-plan-executor.md +506 -0
  80. package/ai-config/agents/specialized/plan-executor.md +485 -0
  81. package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +485 -0
  82. package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +3493 -0
  83. package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +778 -0
  84. package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +918 -0
  85. package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +1537 -0
  86. package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +2633 -0
  87. package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +5610 -0
  88. package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +335 -0
  89. package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +215 -0
  90. package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +260 -0
  91. package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +379 -0
  92. package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +355 -0
  93. package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +279 -0
  94. package/ai-config/agents/specialized/template-writer.md +347 -0
  95. package/ai-config/agents/specialized/test-runner.md +99 -0
  96. package/ai-config/agents/specialized/vibekanban-smart-worker.md +244 -0
  97. package/ai-config/agents/specialized/wave-executor.md +138 -0
  98. package/ai-config/agents/specialized/workflow-optimizer.md +1114 -0
  99. package/ai-config/commands/git/changelog.md +32 -0
  100. package/ai-config/commands/git/ci-local.md +70 -0
  101. package/ai-config/commands/git/commit.md +35 -0
  102. package/ai-config/commands/git/fix-issue.md +23 -0
  103. package/ai-config/commands/git/pr-create.md +42 -0
  104. package/ai-config/commands/git/pr-review.md +50 -0
  105. package/ai-config/commands/git/worktree.md +39 -0
  106. package/ai-config/commands/refactoring/cleanup.md +24 -0
  107. package/ai-config/commands/refactoring/dead-code.md +40 -0
  108. package/ai-config/commands/refactoring/extract.md +31 -0
  109. package/ai-config/commands/testing/e2e.md +30 -0
  110. package/ai-config/commands/testing/tdd.md +36 -0
  111. package/ai-config/commands/testing/test-coverage.md +30 -0
  112. package/ai-config/commands/testing/test-fix.md +24 -0
  113. package/ai-config/commands/workflow/generate-agents-md.md +85 -0
  114. package/ai-config/commands/workflow/planning.md +47 -0
  115. package/ai-config/commands/workflows/compound.md +89 -0
  116. package/ai-config/commands/workflows/plan.md +77 -0
  117. package/ai-config/commands/workflows/review.md +78 -0
  118. package/ai-config/commands/workflows/work.md +75 -0
  119. package/ai-config/config.yaml +18 -0
  120. package/ai-config/hooks/_TEMPLATE.md +96 -0
  121. package/ai-config/hooks/block-dangerous-commands.md +75 -0
  122. package/ai-config/hooks/commit-guard.md +90 -0
  123. package/ai-config/hooks/context-loader.md +73 -0
  124. package/ai-config/hooks/improve-prompt.md +91 -0
  125. package/ai-config/hooks/learning-log.md +72 -0
  126. package/ai-config/hooks/model-router.md +86 -0
  127. package/ai-config/hooks/secret-scanner.md +64 -0
  128. package/ai-config/hooks/skill-validator.md +102 -0
  129. package/ai-config/hooks/task-artifact.md +114 -0
  130. package/ai-config/hooks/validate-workflow.md +100 -0
  131. package/ai-config/prompts/base.md +71 -0
  132. package/ai-config/prompts/modes/debug.md +34 -0
  133. package/ai-config/prompts/modes/deploy.md +40 -0
  134. package/ai-config/prompts/modes/research.md +32 -0
  135. package/ai-config/prompts/modes/review.md +33 -0
  136. package/ai-config/prompts/review-policy.md +79 -0
  137. package/ai-config/skills/_TEMPLATE.md +157 -0
  138. package/ai-config/skills/backend/api-gateway/SKILL.md +254 -0
  139. package/ai-config/skills/backend/bff-concepts/SKILL.md +239 -0
  140. package/ai-config/skills/backend/bff-spring/SKILL.md +364 -0
  141. package/ai-config/skills/backend/chi-router/SKILL.md +396 -0
  142. package/ai-config/skills/backend/error-handling/SKILL.md +255 -0
  143. package/ai-config/skills/backend/exceptions-spring/SKILL.md +323 -0
  144. package/ai-config/skills/backend/fastapi/SKILL.md +302 -0
  145. package/ai-config/skills/backend/gateway-spring/SKILL.md +390 -0
  146. package/ai-config/skills/backend/go-backend/SKILL.md +457 -0
  147. package/ai-config/skills/backend/gradle-multimodule/SKILL.md +274 -0
  148. package/ai-config/skills/backend/graphql-concepts/SKILL.md +352 -0
  149. package/ai-config/skills/backend/graphql-spring/SKILL.md +398 -0
  150. package/ai-config/skills/backend/grpc-concepts/SKILL.md +283 -0
  151. package/ai-config/skills/backend/grpc-spring/SKILL.md +445 -0
  152. package/ai-config/skills/backend/jwt-auth/SKILL.md +412 -0
  153. package/ai-config/skills/backend/notifications-concepts/SKILL.md +259 -0
  154. package/ai-config/skills/backend/recommendations-concepts/SKILL.md +261 -0
  155. package/ai-config/skills/backend/search-concepts/SKILL.md +263 -0
  156. package/ai-config/skills/backend/search-spring/SKILL.md +375 -0
  157. package/ai-config/skills/backend/spring-boot-4/SKILL.md +172 -0
  158. package/ai-config/skills/backend/websockets/SKILL.md +532 -0
  159. package/ai-config/skills/data-ai/ai-ml/SKILL.md +423 -0
  160. package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +195 -0
  161. package/ai-config/skills/data-ai/analytics-spring/SKILL.md +340 -0
  162. package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +440 -0
  163. package/ai-config/skills/data-ai/langchain/SKILL.md +238 -0
  164. package/ai-config/skills/data-ai/mlflow/SKILL.md +302 -0
  165. package/ai-config/skills/data-ai/onnx-inference/SKILL.md +290 -0
  166. package/ai-config/skills/data-ai/powerbi/SKILL.md +352 -0
  167. package/ai-config/skills/data-ai/pytorch/SKILL.md +274 -0
  168. package/ai-config/skills/data-ai/scikit-learn/SKILL.md +321 -0
  169. package/ai-config/skills/data-ai/vector-db/SKILL.md +301 -0
  170. package/ai-config/skills/database/graph-databases/SKILL.md +218 -0
  171. package/ai-config/skills/database/graph-spring/SKILL.md +361 -0
  172. package/ai-config/skills/database/pgx-postgres/SKILL.md +512 -0
  173. package/ai-config/skills/database/redis-cache/SKILL.md +343 -0
  174. package/ai-config/skills/database/sqlite-embedded/SKILL.md +388 -0
  175. package/ai-config/skills/database/timescaledb/SKILL.md +320 -0
  176. package/ai-config/skills/docs/api-documentation/SKILL.md +293 -0
  177. package/ai-config/skills/docs/docs-spring/SKILL.md +377 -0
  178. package/ai-config/skills/docs/mustache-templates/SKILL.md +190 -0
  179. package/ai-config/skills/docs/technical-docs/SKILL.md +447 -0
  180. package/ai-config/skills/frontend/astro-ssr/SKILL.md +441 -0
  181. package/ai-config/skills/frontend/frontend-design/SKILL.md +54 -0
  182. package/ai-config/skills/frontend/frontend-web/SKILL.md +368 -0
  183. package/ai-config/skills/frontend/mantine-ui/SKILL.md +396 -0
  184. package/ai-config/skills/frontend/tanstack-query/SKILL.md +439 -0
  185. package/ai-config/skills/frontend/zod-validation/SKILL.md +417 -0
  186. package/ai-config/skills/frontend/zustand-state/SKILL.md +350 -0
  187. package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +244 -0
  188. package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +378 -0
  189. package/ai-config/skills/infrastructure/devops-infra/SKILL.md +435 -0
  190. package/ai-config/skills/infrastructure/docker-containers/SKILL.md +420 -0
  191. package/ai-config/skills/infrastructure/kubernetes/SKILL.md +456 -0
  192. package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +546 -0
  193. package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +474 -0
  194. package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +315 -0
  195. package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +504 -0
  196. package/ai-config/skills/mobile/mobile-ionic/SKILL.md +448 -0
  197. package/ai-config/skills/prompt-improver/SKILL.md +125 -0
  198. package/ai-config/skills/quality/ghagga-review/SKILL.md +216 -0
  199. package/ai-config/skills/references/hooks-patterns/SKILL.md +238 -0
  200. package/ai-config/skills/references/mcp-servers/SKILL.md +275 -0
  201. package/ai-config/skills/references/plugins-reference/SKILL.md +110 -0
  202. package/ai-config/skills/references/skills-reference/SKILL.md +420 -0
  203. package/ai-config/skills/references/subagent-templates/SKILL.md +193 -0
  204. package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +410 -0
  205. package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +408 -0
  206. package/ai-config/skills/systems-iot/rust-systems/SKILL.md +386 -0
  207. package/ai-config/skills/systems-iot/tokio-async/SKILL.md +324 -0
  208. package/ai-config/skills/testing/playwright-e2e/SKILL.md +289 -0
  209. package/ai-config/skills/testing/testcontainers/SKILL.md +299 -0
  210. package/ai-config/skills/testing/vitest-testing/SKILL.md +381 -0
  211. package/ai-config/skills/workflow/ci-local-guide/SKILL.md +118 -0
  212. package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +299 -0
  213. package/ai-config/skills/workflow/claude-md-improver/SKILL.md +158 -0
  214. package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +117 -0
  215. package/ai-config/skills/workflow/git-github/SKILL.md +334 -0
  216. package/ai-config/skills/workflow/git-github/references/examples.md +160 -0
  217. package/ai-config/skills/workflow/git-workflow/SKILL.md +214 -0
  218. package/ai-config/skills/workflow/ide-plugins/SKILL.md +277 -0
  219. package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +401 -0
  220. package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +199 -0
  221. package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +100 -0
  222. package/ai-config/skills/workflow/verification-before-completion/SKILL.md +73 -0
  223. package/ai-config/skills/workflow/wave-workflow/SKILL.md +178 -0
  224. package/ci-local/README.md +170 -0
  225. package/ci-local/ci-local.sh +297 -0
  226. package/ci-local/hooks/commit-msg +74 -0
  227. package/ci-local/hooks/pre-commit +162 -0
  228. package/ci-local/hooks/pre-push +41 -0
  229. package/ci-local/install.sh +49 -0
  230. package/ci-local/semgrep.yml +214 -0
  231. package/dist/commands/analyze.d.ts +9 -0
  232. package/dist/commands/analyze.d.ts.map +1 -0
  233. package/dist/commands/analyze.js +55 -0
  234. package/dist/commands/analyze.js.map +1 -0
  235. package/dist/commands/analyze.test.d.ts +2 -0
  236. package/dist/commands/analyze.test.d.ts.map +1 -0
  237. package/dist/commands/analyze.test.js +145 -0
  238. package/dist/commands/analyze.test.js.map +1 -0
  239. package/dist/commands/doctor.d.ts +7 -0
  240. package/dist/commands/doctor.d.ts.map +1 -0
  241. package/dist/commands/doctor.js +158 -0
  242. package/dist/commands/doctor.js.map +1 -0
  243. package/dist/commands/doctor.test.d.ts +2 -0
  244. package/dist/commands/doctor.test.d.ts.map +1 -0
  245. package/dist/commands/doctor.test.js +200 -0
  246. package/dist/commands/doctor.test.js.map +1 -0
  247. package/dist/commands/init.d.ts +9 -0
  248. package/dist/commands/init.d.ts.map +1 -0
  249. package/dist/commands/init.js +283 -0
  250. package/dist/commands/init.js.map +1 -0
  251. package/dist/commands/init.test.d.ts +2 -0
  252. package/dist/commands/init.test.d.ts.map +1 -0
  253. package/dist/commands/init.test.js +271 -0
  254. package/dist/commands/init.test.js.map +1 -0
  255. package/dist/commands/sync.d.ts +8 -0
  256. package/dist/commands/sync.d.ts.map +1 -0
  257. package/dist/commands/sync.js +201 -0
  258. package/dist/commands/sync.js.map +1 -0
  259. package/dist/constants.d.ts +21 -0
  260. package/dist/constants.d.ts.map +1 -0
  261. package/dist/constants.js +57 -0
  262. package/dist/constants.js.map +1 -0
  263. package/dist/e2e/aggressive.e2e.test.d.ts +2 -0
  264. package/dist/e2e/aggressive.e2e.test.d.ts.map +1 -0
  265. package/dist/e2e/aggressive.e2e.test.js +350 -0
  266. package/dist/e2e/aggressive.e2e.test.js.map +1 -0
  267. package/dist/e2e/commands.e2e.test.d.ts +2 -0
  268. package/dist/e2e/commands.e2e.test.d.ts.map +1 -0
  269. package/dist/e2e/commands.e2e.test.js +213 -0
  270. package/dist/e2e/commands.e2e.test.js.map +1 -0
  271. package/dist/index.d.ts +3 -0
  272. package/dist/index.d.ts.map +1 -0
  273. package/dist/index.js +82 -0
  274. package/dist/index.js.map +1 -0
  275. package/dist/lib/common.d.ts +17 -0
  276. package/dist/lib/common.d.ts.map +1 -0
  277. package/dist/lib/common.js +111 -0
  278. package/dist/lib/common.js.map +1 -0
  279. package/dist/lib/common.test.d.ts +2 -0
  280. package/dist/lib/common.test.d.ts.map +1 -0
  281. package/dist/lib/common.test.js +316 -0
  282. package/dist/lib/common.test.js.map +1 -0
  283. package/dist/lib/frontmatter.d.ts +18 -0
  284. package/dist/lib/frontmatter.d.ts.map +1 -0
  285. package/dist/lib/frontmatter.js +61 -0
  286. package/dist/lib/frontmatter.js.map +1 -0
  287. package/dist/lib/frontmatter.test.d.ts +2 -0
  288. package/dist/lib/frontmatter.test.d.ts.map +1 -0
  289. package/dist/lib/frontmatter.test.js +257 -0
  290. package/dist/lib/frontmatter.test.js.map +1 -0
  291. package/dist/lib/template.d.ts +24 -0
  292. package/dist/lib/template.d.ts.map +1 -0
  293. package/dist/lib/template.js +78 -0
  294. package/dist/lib/template.js.map +1 -0
  295. package/dist/lib/template.test.d.ts +2 -0
  296. package/dist/lib/template.test.d.ts.map +1 -0
  297. package/dist/lib/template.test.js +201 -0
  298. package/dist/lib/template.test.js.map +1 -0
  299. package/dist/types/index.d.ts +48 -0
  300. package/dist/types/index.d.ts.map +1 -0
  301. package/dist/types/index.js +2 -0
  302. package/dist/types/index.js.map +1 -0
  303. package/dist/ui/AnalyzeUI.d.ts +7 -0
  304. package/dist/ui/AnalyzeUI.d.ts.map +1 -0
  305. package/dist/ui/AnalyzeUI.js +100 -0
  306. package/dist/ui/AnalyzeUI.js.map +1 -0
  307. package/dist/ui/App.d.ts +13 -0
  308. package/dist/ui/App.d.ts.map +1 -0
  309. package/dist/ui/App.js +100 -0
  310. package/dist/ui/App.js.map +1 -0
  311. package/dist/ui/CIContext.d.ts +9 -0
  312. package/dist/ui/CIContext.d.ts.map +1 -0
  313. package/dist/ui/CIContext.js +9 -0
  314. package/dist/ui/CIContext.js.map +1 -0
  315. package/dist/ui/CISelector.d.ts +8 -0
  316. package/dist/ui/CISelector.d.ts.map +1 -0
  317. package/dist/ui/CISelector.js +45 -0
  318. package/dist/ui/CISelector.js.map +1 -0
  319. package/dist/ui/Doctor.d.ts +3 -0
  320. package/dist/ui/Doctor.d.ts.map +1 -0
  321. package/dist/ui/Doctor.js +89 -0
  322. package/dist/ui/Doctor.js.map +1 -0
  323. package/dist/ui/Header.d.ts +8 -0
  324. package/dist/ui/Header.d.ts.map +1 -0
  325. package/dist/ui/Header.js +30 -0
  326. package/dist/ui/Header.js.map +1 -0
  327. package/dist/ui/MemorySelector.d.ts +8 -0
  328. package/dist/ui/MemorySelector.d.ts.map +1 -0
  329. package/dist/ui/MemorySelector.js +46 -0
  330. package/dist/ui/MemorySelector.js.map +1 -0
  331. package/dist/ui/NameInput.d.ts +8 -0
  332. package/dist/ui/NameInput.d.ts.map +1 -0
  333. package/dist/ui/NameInput.js +69 -0
  334. package/dist/ui/NameInput.js.map +1 -0
  335. package/dist/ui/OptionSelector.d.ts +12 -0
  336. package/dist/ui/OptionSelector.d.ts.map +1 -0
  337. package/dist/ui/OptionSelector.js +69 -0
  338. package/dist/ui/OptionSelector.js.map +1 -0
  339. package/dist/ui/Progress.d.ts +11 -0
  340. package/dist/ui/Progress.d.ts.map +1 -0
  341. package/dist/ui/Progress.js +58 -0
  342. package/dist/ui/Progress.js.map +1 -0
  343. package/dist/ui/StackSelector.d.ts +9 -0
  344. package/dist/ui/StackSelector.d.ts.map +1 -0
  345. package/dist/ui/StackSelector.js +65 -0
  346. package/dist/ui/StackSelector.js.map +1 -0
  347. package/dist/ui/Summary.d.ts +12 -0
  348. package/dist/ui/Summary.d.ts.map +1 -0
  349. package/dist/ui/Summary.js +114 -0
  350. package/dist/ui/Summary.js.map +1 -0
  351. package/dist/ui/SyncUI.d.ts +10 -0
  352. package/dist/ui/SyncUI.d.ts.map +1 -0
  353. package/dist/ui/SyncUI.js +64 -0
  354. package/dist/ui/SyncUI.js.map +1 -0
  355. package/dist/ui/Welcome.d.ts +7 -0
  356. package/dist/ui/Welcome.d.ts.map +1 -0
  357. package/dist/ui/Welcome.js +45 -0
  358. package/dist/ui/Welcome.js.map +1 -0
  359. package/dist/ui/theme.d.ts +10 -0
  360. package/dist/ui/theme.d.ts.map +1 -0
  361. package/dist/ui/theme.js +9 -0
  362. package/dist/ui/theme.js.map +1 -0
  363. package/modules/engram/.gitignore-snippet.txt +6 -0
  364. package/modules/engram/.mcp-config-snippet.json +11 -0
  365. package/modules/engram/README.md +146 -0
  366. package/modules/engram/install-engram.sh +216 -0
  367. package/modules/ghagga/.env.example +43 -0
  368. package/modules/ghagga/README.md +153 -0
  369. package/modules/ghagga/docker-compose.yml +80 -0
  370. package/modules/ghagga/setup-ghagga.sh +139 -0
  371. package/modules/memory-simple/.project/NOTES.md +22 -0
  372. package/modules/memory-simple/README.md +23 -0
  373. package/modules/obsidian-brain/.obsidian/app.json +23 -0
  374. package/modules/obsidian-brain/.obsidian/appearance.json +5 -0
  375. package/modules/obsidian-brain/.obsidian/bookmarks.json +34 -0
  376. package/modules/obsidian-brain/.obsidian/community-plugins.json +1 -0
  377. package/modules/obsidian-brain/.obsidian/core-plugins-migration.json +21 -0
  378. package/modules/obsidian-brain/.obsidian/core-plugins.json +18 -0
  379. package/modules/obsidian-brain/.obsidian/daily-notes.json +5 -0
  380. package/modules/obsidian-brain/.obsidian/graph.json +37 -0
  381. package/modules/obsidian-brain/.obsidian/hotkeys.json +14 -0
  382. package/modules/obsidian-brain/.obsidian/plugins/dataview/data.json +25 -0
  383. package/modules/obsidian-brain/.obsidian/plugins/obsidian-kanban/data.json +29 -0
  384. package/modules/obsidian-brain/.obsidian/plugins/templater-obsidian/data.json +18 -0
  385. package/modules/obsidian-brain/.obsidian/snippets/project-memory.css +71 -0
  386. package/modules/obsidian-brain/.obsidian-gitignore-snippet.txt +8 -0
  387. package/modules/obsidian-brain/.project/Attachments/.gitkeep +0 -0
  388. package/modules/obsidian-brain/.project/Memory/BLOCKERS.md +78 -0
  389. package/modules/obsidian-brain/.project/Memory/CONTEXT.md +102 -0
  390. package/modules/obsidian-brain/.project/Memory/DASHBOARD.md +73 -0
  391. package/modules/obsidian-brain/.project/Memory/DECISIONS.md +87 -0
  392. package/modules/obsidian-brain/.project/Memory/KANBAN.md +15 -0
  393. package/modules/obsidian-brain/.project/Memory/README.md +61 -0
  394. package/modules/obsidian-brain/.project/Memory/WAVES.md +78 -0
  395. package/modules/obsidian-brain/.project/Sessions/TEMPLATE.md +99 -0
  396. package/modules/obsidian-brain/.project/Templates/ADR.md +33 -0
  397. package/modules/obsidian-brain/.project/Templates/Blocker.md +21 -0
  398. package/modules/obsidian-brain/.project/Templates/Session.md +88 -0
  399. package/modules/obsidian-brain/README.md +268 -0
  400. package/modules/obsidian-brain/new-wave.sh +182 -0
  401. package/package.json +51 -0
  402. package/schemas/agent.schema.json +34 -0
  403. package/schemas/ai-config.schema.json +28 -0
  404. package/schemas/skill.schema.json +44 -0
  405. package/src/commands/analyze.test.ts +145 -0
  406. package/src/commands/analyze.ts +69 -0
  407. package/src/commands/doctor.test.ts +208 -0
  408. package/src/commands/doctor.ts +163 -0
  409. package/src/commands/init.test.ts +298 -0
  410. package/src/commands/init.ts +285 -0
  411. package/src/constants.ts +69 -0
  412. package/src/e2e/aggressive.e2e.test.ts +557 -0
  413. package/src/e2e/commands.e2e.test.ts +298 -0
  414. package/src/index.tsx +106 -0
  415. package/src/lib/common.test.ts +318 -0
  416. package/src/lib/common.ts +127 -0
  417. package/src/lib/frontmatter.test.ts +291 -0
  418. package/src/lib/frontmatter.ts +77 -0
  419. package/src/lib/template.test.ts +226 -0
  420. package/src/lib/template.ts +99 -0
  421. package/src/types/index.ts +53 -0
  422. package/src/ui/AnalyzeUI.tsx +133 -0
  423. package/src/ui/App.tsx +175 -0
  424. package/src/ui/CIContext.tsx +25 -0
  425. package/src/ui/CISelector.tsx +72 -0
  426. package/src/ui/Doctor.tsx +122 -0
  427. package/src/ui/Header.tsx +48 -0
  428. package/src/ui/MemorySelector.tsx +73 -0
  429. package/src/ui/NameInput.tsx +82 -0
  430. package/src/ui/OptionSelector.tsx +100 -0
  431. package/src/ui/Progress.tsx +88 -0
  432. package/src/ui/StackSelector.tsx +101 -0
  433. package/src/ui/Summary.tsx +134 -0
  434. package/src/ui/Welcome.tsx +54 -0
  435. package/src/ui/theme.ts +10 -0
  436. package/stryker.config.json +19 -0
  437. package/tasks/_TEMPLATE/files-edited.md +3 -0
  438. package/tasks/_TEMPLATE/plan.md +3 -0
  439. package/tasks/_TEMPLATE/research.md +3 -0
  440. package/tasks/_TEMPLATE/verification.md +5 -0
  441. package/templates/common/dependabot/cargo.yml +11 -0
  442. package/templates/common/dependabot/github-actions.yml +16 -0
  443. package/templates/common/dependabot/gomod.yml +15 -0
  444. package/templates/common/dependabot/gradle.yml +15 -0
  445. package/templates/common/dependabot/header.yml +3 -0
  446. package/templates/common/dependabot/maven.yml +15 -0
  447. package/templates/common/dependabot/npm.yml +20 -0
  448. package/templates/common/dependabot/pip.yml +11 -0
  449. package/templates/dependabot.yml +162 -0
  450. package/templates/github/ci-go.yml +41 -0
  451. package/templates/github/ci-java.yml +45 -0
  452. package/templates/github/ci-monorepo.yml +150 -0
  453. package/templates/github/ci-node.yml +42 -0
  454. package/templates/github/ci-python.yml +42 -0
  455. package/templates/github/ci-rust.yml +42 -0
  456. package/templates/github/dependabot-automerge.yml +40 -0
  457. package/templates/gitlab/gitlab-ci-go.yml +88 -0
  458. package/templates/gitlab/gitlab-ci-java.yml +79 -0
  459. package/templates/gitlab/gitlab-ci-monorepo.yml +126 -0
  460. package/templates/gitlab/gitlab-ci-node.yml +63 -0
  461. package/templates/gitlab/gitlab-ci-python.yml +147 -0
  462. package/templates/gitlab/gitlab-ci-rust.yml +67 -0
  463. package/templates/global/claude-settings.json +98 -0
  464. package/templates/global/codex-config.toml +8 -0
  465. package/templates/global/copilot-instructions/base-rules.instructions.md +13 -0
  466. package/templates/global/copilot-instructions/sdd-orchestrator.instructions.md +37 -0
  467. package/templates/global/gemini-commands/cleanup.toml +20 -0
  468. package/templates/global/gemini-commands/commit.toml +15 -0
  469. package/templates/global/gemini-commands/dead-code.toml +22 -0
  470. package/templates/global/gemini-commands/plan.toml +30 -0
  471. package/templates/global/gemini-commands/review.toml +17 -0
  472. package/templates/global/gemini-commands/sdd-apply.toml +22 -0
  473. package/templates/global/gemini-commands/sdd-ff.toml +14 -0
  474. package/templates/global/gemini-commands/sdd-new.toml +21 -0
  475. package/templates/global/gemini-commands/sdd-verify.toml +21 -0
  476. package/templates/global/gemini-commands/tdd.toml +26 -0
  477. package/templates/global/gemini-settings.json +8 -0
  478. package/templates/global/opencode-config.json +44 -0
  479. package/templates/global/sdd-instructions.md +47 -0
  480. package/templates/global/sdd-orchestrator-claude.md +46 -0
  481. package/templates/global/sdd-orchestrator-copilot.md +34 -0
  482. package/templates/renovate.json +69 -0
  483. package/templates/woodpecker/monorepo/backend.yml +34 -0
  484. package/templates/woodpecker/monorepo/frontend.yml +34 -0
  485. package/templates/woodpecker/monorepo/summary.yml +25 -0
  486. package/templates/woodpecker/woodpecker-go.yml +51 -0
  487. package/templates/woodpecker/woodpecker-java.yml +67 -0
  488. package/templates/woodpecker/woodpecker-node.yml +47 -0
  489. package/templates/woodpecker/woodpecker-python.yml +108 -0
  490. package/templates/woodpecker/woodpecker-rust.yml +57 -0
  491. package/tsconfig.json +19 -0
  492. package/vitest.config.ts +16 -0
  493. package/workflows/reusable-build-go.yml +111 -0
  494. package/workflows/reusable-build-java.yml +120 -0
  495. package/workflows/reusable-build-node.yml +145 -0
  496. package/workflows/reusable-build-python.yml +159 -0
  497. package/workflows/reusable-build-rust.yml +135 -0
  498. package/workflows/reusable-docker.yml +120 -0
  499. package/workflows/reusable-ghagga-review.yml +165 -0
  500. package/workflows/reusable-release.yml +91 -0
@@ -0,0 +1,343 @@
1
+ ---
2
+ name: redis-cache
3
+ description: >
4
+ Redis caching, sessions, pub/sub, rate limiting, and distributed locks.
5
+ Trigger: redis, cache, session, pub/sub, rate limiting, distributed lock
6
+
7
+ tools:
8
+ - Read
9
+ - Write
10
+ - Bash
11
+ - Grep
12
+
13
+ metadata:
14
+ author: plataforma-industrial
15
+ version: "2.0"
16
+ tags: [cache, redis, real-time, session]
17
+ updated: "2026-02"
18
+ ---
19
+
20
+ # Redis Cache & Real-time
21
+
22
+ > Caching, sessions, pub/sub, rate limiting, and distributed locks with Redis.
23
+
24
+ ## Stack
25
+
26
+ ```yaml
27
+ Redis: 7.2+
28
+ go-redis/redis: v9
29
+ ioredis (Node): 5.3+
30
+ redis-py: 5.0+
31
+ ```
32
+
33
+ ## When to Use
34
+
35
+ - Caching frequently accessed data with TTL
36
+ - Session management with expiration
37
+ - Real-time pub/sub between services
38
+ - Rate limiting API endpoints
39
+ - Distributed locks for coordination
40
+
41
+ ## Docker Setup
42
+
43
+ ```yaml
44
+ # docker-compose.yml
45
+ services:
46
+ redis:
47
+ image: redis:7-alpine
48
+ ports:
49
+ - "6379:6379"
50
+ volumes:
51
+ - redis_data:/data
52
+ - ./config/redis.conf:/usr/local/etc/redis/redis.conf
53
+ command: redis-server /usr/local/etc/redis/redis.conf
54
+ healthcheck:
55
+ test: ["CMD", "redis-cli", "ping"]
56
+ interval: 5s
57
+ timeout: 3s
58
+ retries: 5
59
+ ```
60
+
61
+ ### Redis Config
62
+
63
+ ```conf
64
+ # redis.conf
65
+ maxmemory 256mb
66
+ maxmemory-policy allkeys-lru
67
+ save 900 1
68
+ save 300 10
69
+ save 60 10000
70
+ appendonly yes
71
+ appendfsync everysec
72
+ # requirepass your-strong-password # Production
73
+ ```
74
+
75
+ ## Go Connection
76
+
77
+ ```go
78
+ package cache
79
+
80
+ import (
81
+ "context"
82
+ "time"
83
+ "github.com/redis/go-redis/v9"
84
+ )
85
+
86
+ type RedisClient struct {
87
+ client *redis.Client
88
+ }
89
+
90
+ func NewRedisClient(addr, password string, db int) (*RedisClient, error) {
91
+ client := redis.NewClient(&redis.Options{
92
+ Addr: addr,
93
+ Password: password,
94
+ DB: db,
95
+ PoolSize: 100,
96
+ MinIdleConns: 10,
97
+ MaxRetries: 3,
98
+ DialTimeout: 5 * time.Second,
99
+ ReadTimeout: 3 * time.Second,
100
+ WriteTimeout: 3 * time.Second,
101
+ })
102
+
103
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
104
+ defer cancel()
105
+
106
+ if err := client.Ping(ctx).Err(); err != nil {
107
+ return nil, err
108
+ }
109
+ return &RedisClient{client: client}, nil
110
+ }
111
+ ```
112
+
113
+ ## Cache-Aside Pattern
114
+
115
+ ```go
116
+ func (c *Cache) GetOrLoad(ctx context.Context, key string, loader func() (any, error)) (any, error) {
117
+ // Try cache first
118
+ data, err := c.redis.Get(ctx, key).Bytes()
119
+ if err == nil {
120
+ var result any
121
+ json.Unmarshal(data, &result)
122
+ return result, nil
123
+ }
124
+ if err != redis.Nil {
125
+ return nil, err
126
+ }
127
+
128
+ // Cache miss - load from source
129
+ result, err := loader()
130
+ if err != nil {
131
+ return nil, err
132
+ }
133
+
134
+ // Store in cache (async)
135
+ go func() {
136
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second)
137
+ defer cancel()
138
+ data, _ := json.Marshal(result)
139
+ c.redis.Set(ctx, key, data, 5*time.Minute)
140
+ }()
141
+
142
+ return result, nil
143
+ }
144
+ ```
145
+
146
+ ## Session Management
147
+
148
+ ```go
149
+ const sessionTTL = 24 * time.Hour
150
+
151
+ type Session struct {
152
+ ID string `json:"id"`
153
+ UserID string `json:"user_id"`
154
+ TenantID string `json:"tenant_id"`
155
+ Role string `json:"role"`
156
+ ExpiresAt time.Time `json:"expires_at"`
157
+ }
158
+
159
+ func (s *SessionStore) Create(ctx context.Context, userID, tenantID, role string) (*Session, error) {
160
+ session := &Session{
161
+ ID: uuid.New().String(),
162
+ UserID: userID,
163
+ TenantID: tenantID,
164
+ Role: role,
165
+ ExpiresAt: time.Now().Add(sessionTTL),
166
+ }
167
+ data, _ := json.Marshal(session)
168
+
169
+ pipe := s.redis.Pipeline()
170
+ pipe.Set(ctx, "session:"+session.ID, data, sessionTTL)
171
+ pipe.SAdd(ctx, "user:"+userID+":sessions", session.ID)
172
+ pipe.Expire(ctx, "user:"+userID+":sessions", sessionTTL)
173
+ _, err := pipe.Exec(ctx)
174
+ return session, err
175
+ }
176
+
177
+ func (s *SessionStore) DeleteAllForUser(ctx context.Context, userID string) error {
178
+ sessionIDs, _ := s.redis.SMembers(ctx, "user:"+userID+":sessions").Result()
179
+ keys := make([]string, len(sessionIDs)+1)
180
+ for i, id := range sessionIDs {
181
+ keys[i] = "session:" + id
182
+ }
183
+ keys[len(sessionIDs)] = "user:" + userID + ":sessions"
184
+ return s.redis.Del(ctx, keys...).Err()
185
+ }
186
+ ```
187
+
188
+ ## Pub/Sub
189
+
190
+ ```go
191
+ // Publisher
192
+ func (p *Publisher) Publish(ctx context.Context, channel string, event Event) error {
193
+ data, _ := json.Marshal(event)
194
+ return p.redis.Publish(ctx, channel, data).Err()
195
+ }
196
+
197
+ // Subscriber
198
+ func (s *Subscriber) Subscribe(ctx context.Context, channels ...string) error {
199
+ pubsub := s.redis.Subscribe(ctx, channels...)
200
+ defer pubsub.Close()
201
+
202
+ for msg := range pubsub.Channel() {
203
+ var event Event
204
+ json.Unmarshal([]byte(msg.Payload), &event)
205
+ for _, handler := range s.handlers[event.Type] {
206
+ handler(ctx, event)
207
+ }
208
+ }
209
+ return nil
210
+ }
211
+ ```
212
+
213
+ ## Rate Limiting (Sliding Window)
214
+
215
+ ```go
216
+ func (rl *RateLimiter) Allow(ctx context.Context, key string) (bool, int, error) {
217
+ now := time.Now().UnixMilli()
218
+ windowStart := now - rl.window.Milliseconds()
219
+ redisKey := "ratelimit:" + key
220
+
221
+ pipe := rl.redis.Pipeline()
222
+ pipe.ZRemRangeByScore(ctx, redisKey, "0", fmt.Sprintf("%d", windowStart))
223
+ countCmd := pipe.ZCard(ctx, redisKey)
224
+ pipe.ZAdd(ctx, redisKey, redis.Z{Score: float64(now), Member: now})
225
+ pipe.Expire(ctx, redisKey, rl.window)
226
+ pipe.Exec(ctx)
227
+
228
+ count := int(countCmd.Val())
229
+ remaining := rl.limit - count - 1
230
+ if remaining < 0 {
231
+ remaining = 0
232
+ }
233
+ return count < rl.limit, remaining, nil
234
+ }
235
+ ```
236
+
237
+ ## Distributed Lock
238
+
239
+ ```go
240
+ func NewLock(redis *redis.Client, key string, ttl time.Duration) *DistributedLock {
241
+ return &DistributedLock{
242
+ redis: redis,
243
+ key: "lock:" + key,
244
+ value: uuid.New().String(),
245
+ ttl: ttl,
246
+ }
247
+ }
248
+
249
+ func (l *DistributedLock) Acquire(ctx context.Context) error {
250
+ success, _ := l.redis.SetNX(ctx, l.key, l.value, l.ttl).Result()
251
+ if !success {
252
+ return ErrLockNotAcquired
253
+ }
254
+ return nil
255
+ }
256
+
257
+ func (l *DistributedLock) Release(ctx context.Context) error {
258
+ script := redis.NewScript(`
259
+ if redis.call("GET", KEYS[1]) == ARGV[1] then
260
+ return redis.call("DEL", KEYS[1])
261
+ end
262
+ return 0
263
+ `)
264
+ _, err := script.Run(ctx, l.redis, []string{l.key}, l.value).Result()
265
+ return err
266
+ }
267
+
268
+ func WithLock(ctx context.Context, redis *redis.Client, key string, ttl time.Duration, fn func() error) error {
269
+ lock := NewLock(redis, key, ttl)
270
+ if err := lock.Acquire(ctx); err != nil {
271
+ return err
272
+ }
273
+ defer lock.Release(ctx)
274
+ return fn()
275
+ }
276
+ ```
277
+
278
+ ## TypeScript/Node.js
279
+
280
+ ```typescript
281
+ import Redis from 'ioredis';
282
+
283
+ export const redis = new Redis({
284
+ host: process.env.REDIS_HOST || 'localhost',
285
+ port: parseInt(process.env.REDIS_PORT || '6379'),
286
+ password: process.env.REDIS_PASSWORD,
287
+ maxRetriesPerRequest: 3,
288
+ });
289
+
290
+ // Pub/Sub requires separate connections
291
+ export const publisher = new Redis(/* config */);
292
+ export const subscriber = new Redis(/* config */);
293
+ ```
294
+
295
+ ## Best Practices
296
+
297
+ | Practice | Description |
298
+ |----------|-------------|
299
+ | Always set TTL | Avoid memory issues with `Set(key, val, TTL)` |
300
+ | Use pipelines | Single round-trip for batch ops |
301
+ | Namespace keys | `tenant:{id}:sensor:{id}` format |
302
+ | Handle redis.Nil | Not an error, just cache miss |
303
+ | Separate pub/sub conn | Pub/sub blocks, use dedicated client |
304
+
305
+ ### Data Structure Selection
306
+
307
+ ```
308
+ String - Simple cache, counters
309
+ Hash - Objects with multiple fields
310
+ List - Queues, recent items
311
+ Set - Tags, unique items
312
+ Sorted Set - Leaderboards, time-series
313
+ Stream - Event logs, message queues
314
+ ```
315
+
316
+ ## Quick Reference
317
+
318
+ | Task | Command |
319
+ |------|---------|
320
+ | Set with TTL | `SET key value EX 300` |
321
+ | Get | `GET key` |
322
+ | Delete | `DEL key1 key2` |
323
+ | Publish | `PUBLISH channel message` |
324
+ | Rate limit check | `ZRANGEBYSCORE + ZADD` |
325
+
326
+ ## Resources
327
+
328
+ - [Redis Documentation](https://redis.io/docs/)
329
+ - [go-redis Guide](https://redis.uptrace.dev/)
330
+ - [ioredis Documentation](https://github.com/redis/ioredis)
331
+
332
+ ---
333
+
334
+ ## Changelog
335
+
336
+ - **2.0** - Condensed from Plataforma Industrial SKILL-REDIS
337
+
338
+ ## Related Skills
339
+
340
+ - `timescaledb`: Database caching layer
341
+ - `pgx-postgres`: Query result caching
342
+ - `chi-router`: Go cache middleware
343
+ - `fastapi`: Python cache patterns
@@ -0,0 +1,388 @@
1
+ ---
2
+ name: sqlite-embedded
3
+ description: >
4
+ SQLite embedded database for edge/offline scenarios with sync queue patterns.
5
+ Trigger: sqlite, embedded database, offline, edge, sync queue, local storage
6
+
7
+ tools:
8
+ - Read
9
+ - Write
10
+ - Bash
11
+ - Grep
12
+
13
+ metadata:
14
+ author: plataforma-industrial
15
+ version: "2.0"
16
+ tags: [sqlite, edge, embedded, offline, database]
17
+ updated: "2026-02"
18
+ ---
19
+
20
+ # SQLite Embedded Database
21
+
22
+ > Edge/offline embedded database with zero configuration and sync queue patterns.
23
+
24
+ ## Stack
25
+
26
+ ```yaml
27
+ SQLite: 3.45+
28
+ Driver Go: modernc.org/sqlite # Pure Go, no CGO
29
+ Driver Rust: rusqlite 0.31+
30
+ Mobile: @capacitor-community/sqlite
31
+ ```
32
+
33
+ ## When to Use
34
+
35
+ - Edge/offline-first applications
36
+ - Local configuration storage
37
+ - Sync queue for pending cloud operations
38
+ - Low-footprint deployments (<5MB RAM)
39
+ - Single-file database with easy backup
40
+
41
+ ## Optimal PRAGMAs
42
+
43
+ ```sql
44
+ PRAGMA journal_mode = WAL; -- Write-Ahead Logging (better concurrency)
45
+ PRAGMA synchronous = NORMAL; -- Balance durability/speed
46
+ PRAGMA foreign_keys = ON; -- Referential integrity
47
+ PRAGMA cache_size = -64000; -- 64MB cache
48
+ PRAGMA mmap_size = 268435456; -- 256MB memory-mapped I/O
49
+ PRAGMA busy_timeout = 5000; -- 5s retry if locked
50
+ PRAGMA temp_store = MEMORY; -- Temp tables in memory
51
+ ```
52
+
53
+ ## Go Connection (Pure Go, No CGO)
54
+
55
+ ```go
56
+ package db
57
+
58
+ import (
59
+ "context"
60
+ "database/sql"
61
+ "fmt"
62
+ "time"
63
+ _ "modernc.org/sqlite"
64
+ )
65
+
66
+ type SQLiteConfig struct {
67
+ Path string
68
+ MaxOpenConns int
69
+ MaxIdleConns int
70
+ ConnMaxLifetime time.Duration
71
+ }
72
+
73
+ func NewSQLiteDB(cfg SQLiteConfig) (*sql.DB, error) {
74
+ dsn := fmt.Sprintf(
75
+ "file:%s?_journal_mode=WAL&_synchronous=NORMAL&_foreign_keys=ON&_busy_timeout=5000&_cache_size=-64000",
76
+ cfg.Path,
77
+ )
78
+
79
+ db, err := sql.Open("sqlite", dsn)
80
+ if err != nil {
81
+ return nil, fmt.Errorf("open sqlite: %w", err)
82
+ }
83
+
84
+ // SQLite: 1 writer, multiple readers
85
+ db.SetMaxOpenConns(cfg.MaxOpenConns) // Typically 1-4
86
+ db.SetMaxIdleConns(cfg.MaxIdleConns)
87
+ db.SetConnMaxLifetime(cfg.ConnMaxLifetime)
88
+
89
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
90
+ defer cancel()
91
+ if err := db.PingContext(ctx); err != nil {
92
+ return nil, fmt.Errorf("ping sqlite: %w", err)
93
+ }
94
+ return db, nil
95
+ }
96
+
97
+ func DefaultConfig(path string) SQLiteConfig {
98
+ return SQLiteConfig{
99
+ Path: path,
100
+ MaxOpenConns: 4,
101
+ MaxIdleConns: 2,
102
+ ConnMaxLifetime: time.Hour,
103
+ }
104
+ }
105
+ ```
106
+
107
+ ## Rust Connection
108
+
109
+ ```rust
110
+ use rusqlite::{Connection, OpenFlags, Result};
111
+ use std::path::Path;
112
+
113
+ pub struct SqliteDb {
114
+ conn: Connection,
115
+ }
116
+
117
+ impl SqliteDb {
118
+ pub fn new(path: &Path) -> Result<Self> {
119
+ let conn = Connection::open_with_flags(
120
+ path,
121
+ OpenFlags::SQLITE_OPEN_READ_WRITE
122
+ | OpenFlags::SQLITE_OPEN_CREATE
123
+ | OpenFlags::SQLITE_OPEN_NO_MUTEX,
124
+ )?;
125
+
126
+ conn.execute_batch("
127
+ PRAGMA journal_mode = WAL;
128
+ PRAGMA synchronous = NORMAL;
129
+ PRAGMA foreign_keys = ON;
130
+ PRAGMA cache_size = -64000;
131
+ PRAGMA busy_timeout = 5000;
132
+ ")?;
133
+
134
+ Ok(Self { conn })
135
+ }
136
+ }
137
+ ```
138
+
139
+ ## Schema Patterns
140
+
141
+ ### Configuration Table
142
+
143
+ ```sql
144
+ CREATE TABLE IF NOT EXISTS sensors (
145
+ id TEXT PRIMARY KEY,
146
+ plant_id TEXT NOT NULL REFERENCES plants(id) ON DELETE CASCADE,
147
+ name TEXT NOT NULL,
148
+ type TEXT NOT NULL,
149
+ unit TEXT NOT NULL,
150
+ modbus_address INTEGER,
151
+ modbus_register INTEGER,
152
+ scale_factor REAL DEFAULT 1.0,
153
+ warning_low REAL,
154
+ warning_high REAL,
155
+ critical_low REAL,
156
+ critical_high REAL,
157
+ read_interval_secs INTEGER DEFAULT 10,
158
+ is_active INTEGER NOT NULL DEFAULT 1,
159
+ metadata TEXT DEFAULT '{}',
160
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
161
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
162
+ );
163
+
164
+ CREATE INDEX idx_sensors_plant ON sensors(plant_id);
165
+ CREATE INDEX idx_sensors_active ON sensors(is_active);
166
+ ```
167
+
168
+ ### Recent Readings Cache (with cleanup trigger)
169
+
170
+ ```sql
171
+ CREATE TABLE IF NOT EXISTS sensor_readings_recent (
172
+ id TEXT PRIMARY KEY,
173
+ sensor_id TEXT NOT NULL REFERENCES sensors(id) ON DELETE CASCADE,
174
+ value REAL NOT NULL,
175
+ quality TEXT DEFAULT 'good' CHECK (quality IN ('good', 'uncertain', 'bad')),
176
+ timestamp TEXT NOT NULL,
177
+ synced INTEGER NOT NULL DEFAULT 0,
178
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
179
+ );
180
+
181
+ CREATE INDEX idx_readings_sensor ON sensor_readings_recent(sensor_id, timestamp DESC);
182
+ CREATE INDEX idx_readings_synced ON sensor_readings_recent(synced) WHERE synced = 0;
183
+
184
+ -- Auto-cleanup: keep only last 1000 per sensor
185
+ CREATE TRIGGER IF NOT EXISTS trg_readings_cleanup
186
+ AFTER INSERT ON sensor_readings_recent
187
+ BEGIN
188
+ DELETE FROM sensor_readings_recent
189
+ WHERE id IN (
190
+ SELECT id FROM sensor_readings_recent
191
+ WHERE sensor_id = NEW.sensor_id
192
+ ORDER BY timestamp DESC
193
+ LIMIT -1 OFFSET 1000
194
+ );
195
+ END;
196
+ ```
197
+
198
+ ### Sync Queue
199
+
200
+ ```sql
201
+ CREATE TABLE IF NOT EXISTS sync_queue (
202
+ id TEXT PRIMARY KEY,
203
+ plant_id TEXT NOT NULL,
204
+ entity_type TEXT NOT NULL,
205
+ entity_id TEXT NOT NULL,
206
+ operation TEXT NOT NULL CHECK (operation IN ('create', 'update', 'delete')),
207
+ payload TEXT NOT NULL,
208
+ priority INTEGER NOT NULL DEFAULT 0,
209
+ retries INTEGER NOT NULL DEFAULT 0,
210
+ max_retries INTEGER NOT NULL DEFAULT 5,
211
+ last_error TEXT,
212
+ next_retry_at TEXT,
213
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
214
+ processed_at TEXT
215
+ );
216
+
217
+ CREATE INDEX idx_sync_queue_pending ON sync_queue(priority DESC, created_at)
218
+ WHERE processed_at IS NULL;
219
+ ```
220
+
221
+ ## Sync Queue Repository
222
+
223
+ ```go
224
+ type SyncItem struct {
225
+ ID string `json:"id"`
226
+ PlantID string `json:"plant_id"`
227
+ EntityType string `json:"entity_type"`
228
+ EntityID string `json:"entity_id"`
229
+ Operation string `json:"operation"`
230
+ Payload json.RawMessage `json:"payload"`
231
+ Priority int `json:"priority"`
232
+ Retries int `json:"retries"`
233
+ MaxRetries int `json:"max_retries"`
234
+ }
235
+
236
+ func (r *SyncQueueRepository) GetPending(ctx context.Context, limit int) ([]SyncItem, error) {
237
+ query := `
238
+ SELECT id, plant_id, entity_type, entity_id, operation, payload,
239
+ priority, retries, max_retries, last_error, created_at
240
+ FROM sync_queue
241
+ WHERE processed_at IS NULL
242
+ AND (next_retry_at IS NULL OR next_retry_at <= datetime('now'))
243
+ ORDER BY priority DESC, created_at ASC
244
+ LIMIT ?
245
+ `
246
+ // ... scan rows
247
+ }
248
+
249
+ func (r *SyncQueueRepository) MarkFailed(ctx context.Context, id string, errMsg string) error {
250
+ query := `
251
+ UPDATE sync_queue
252
+ SET retries = retries + 1,
253
+ last_error = ?,
254
+ next_retry_at = datetime('now', '+' || (retries + 1) * 30 || ' seconds')
255
+ WHERE id = ?
256
+ `
257
+ _, err := r.db.ExecContext(ctx, query, errMsg, id)
258
+ return err
259
+ }
260
+ ```
261
+
262
+ ## Batch Insert Pattern
263
+
264
+ ```go
265
+ func (r *ReadingRepository) InsertBatch(ctx context.Context, readings []Reading) error {
266
+ if len(readings) == 0 {
267
+ return nil
268
+ }
269
+
270
+ tx, err := r.db.BeginTx(ctx, nil)
271
+ if err != nil {
272
+ return err
273
+ }
274
+ defer tx.Rollback()
275
+
276
+ placeholders := make([]string, len(readings))
277
+ args := make([]any, 0, len(readings)*6)
278
+
279
+ for i, rd := range readings {
280
+ placeholders[i] = "(?, ?, ?, ?, ?, ?)"
281
+ args = append(args, rd.ID, rd.SensorID, rd.Value, rd.Quality, rd.RawValue, rd.Timestamp)
282
+ }
283
+
284
+ query := `INSERT INTO sensor_readings_recent (id, sensor_id, value, quality, raw_value, timestamp)
285
+ VALUES ` + strings.Join(placeholders, ", ")
286
+ _, err = tx.ExecContext(ctx, query, args...)
287
+ if err != nil {
288
+ return err
289
+ }
290
+ return tx.Commit()
291
+ }
292
+ ```
293
+
294
+ ## Useful Views
295
+
296
+ ```sql
297
+ -- Latest reading per sensor with status
298
+ CREATE VIEW IF NOT EXISTS v_sensor_latest_readings AS
299
+ SELECT
300
+ s.id AS sensor_id,
301
+ s.name AS sensor_name,
302
+ r.value,
303
+ r.timestamp,
304
+ CASE
305
+ WHEN r.value IS NULL THEN 'no_data'
306
+ WHEN s.critical_low IS NOT NULL AND r.value < s.critical_low THEN 'critical_low'
307
+ WHEN s.critical_high IS NOT NULL AND r.value > s.critical_high THEN 'critical_high'
308
+ WHEN s.warning_low IS NOT NULL AND r.value < s.warning_low THEN 'warning_low'
309
+ WHEN s.warning_high IS NOT NULL AND r.value > s.warning_high THEN 'warning_high'
310
+ ELSE 'normal'
311
+ END AS status
312
+ FROM sensors s
313
+ LEFT JOIN (
314
+ SELECT sensor_id, value, timestamp,
315
+ ROW_NUMBER() OVER (PARTITION BY sensor_id ORDER BY timestamp DESC) AS rn
316
+ FROM sensor_readings_recent
317
+ ) r ON r.sensor_id = s.id AND r.rn = 1
318
+ WHERE s.is_active = 1;
319
+ ```
320
+
321
+ ## Backup (Hot Backup with WAL)
322
+
323
+ ```go
324
+ func BackupDatabase(ctx context.Context, db *sql.DB, destDir string) (string, error) {
325
+ filename := fmt.Sprintf("backup_%s.db", time.Now().Format("20060102_150405"))
326
+ destPath := filepath.Join(destDir, filename)
327
+
328
+ // VACUUM INTO creates consistent backup without stopping
329
+ query := fmt.Sprintf("VACUUM INTO '%s'", destPath)
330
+ _, err := db.ExecContext(ctx, query)
331
+ return destPath, err
332
+ }
333
+ ```
334
+
335
+ ## SQLite vs PostgreSQL Syntax
336
+
337
+ | Aspect | SQLite | PostgreSQL |
338
+ |--------|--------|------------|
339
+ | Datetime | `datetime('now')` | `NOW()` |
340
+ | Interval | `datetime('now', '-1 hour')` | `NOW() - INTERVAL '1 hour'` |
341
+ | Boolean | `INTEGER (0/1)` | `BOOLEAN` |
342
+ | UUID | `TEXT` | `UUID` |
343
+ | Auto-ID | `INTEGER PRIMARY KEY` | `SERIAL` |
344
+ | JSON | `TEXT + json_*()` | `JSONB` |
345
+
346
+ ## Performance Tips
347
+
348
+ ```sql
349
+ -- Partial indexes (smaller, faster)
350
+ CREATE INDEX idx_readings_unsynced ON sensor_readings_recent(synced)
351
+ WHERE synced = 0;
352
+
353
+ -- Check query plan
354
+ EXPLAIN QUERY PLAN
355
+ SELECT * FROM sensor_readings_recent WHERE sensor_id = 'abc';
356
+
357
+ -- Update statistics
358
+ ANALYZE;
359
+ ```
360
+
361
+ ## Quick Reference
362
+
363
+ | Task | Command |
364
+ |------|---------|
365
+ | Check integrity | `PRAGMA integrity_check;` |
366
+ | Enable WAL | `PRAGMA journal_mode = WAL;` |
367
+ | Set busy timeout | `PRAGMA busy_timeout = 5000;` |
368
+ | Hot backup | `VACUUM INTO 'backup.db'` |
369
+ | DB size | `SELECT page_count * page_size FROM pragma_page_count(), pragma_page_size();` |
370
+
371
+ ## Resources
372
+
373
+ - [SQLite Documentation](https://sqlite.org/docs.html)
374
+ - [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite)
375
+ - [rusqlite](https://docs.rs/rusqlite)
376
+
377
+ ---
378
+
379
+ ## Changelog
380
+
381
+ - **2.0** - Condensed from Plataforma Industrial SKILL-SQLITE
382
+
383
+ ## Related Skills
384
+
385
+ - `mobile-ionic`: Offline-first mobile apps
386
+ - `ionic-capacitor`: Native SQLite access
387
+ - `duckdb-analytics`: Embedded analytics
388
+ - `rust-systems`: Embedded Rust apps