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.
- package/.gitignore.template +105 -0
- package/.releaserc +44 -0
- package/README.md +45 -0
- package/ai-config/.skillignore +15 -0
- package/ai-config/AUTO_INVOKE.md +300 -0
- package/ai-config/agents/_TEMPLATE.md +93 -0
- package/ai-config/agents/business/api-designer.md +1657 -0
- package/ai-config/agents/business/business-analyst.md +1331 -0
- package/ai-config/agents/business/product-strategist.md +206 -0
- package/ai-config/agents/business/project-manager.md +178 -0
- package/ai-config/agents/business/requirements-analyst.md +1277 -0
- package/ai-config/agents/business/technical-writer.md +1679 -0
- package/ai-config/agents/creative/ux-designer.md +205 -0
- package/ai-config/agents/data-ai/ai-engineer.md +487 -0
- package/ai-config/agents/data-ai/analytics-engineer.md +953 -0
- package/ai-config/agents/data-ai/data-engineer.md +173 -0
- package/ai-config/agents/data-ai/data-scientist.md +672 -0
- package/ai-config/agents/data-ai/mlops-engineer.md +814 -0
- package/ai-config/agents/data-ai/prompt-engineer.md +772 -0
- package/ai-config/agents/development/angular-expert.md +620 -0
- package/ai-config/agents/development/backend-architect.md +795 -0
- package/ai-config/agents/development/database-specialist.md +212 -0
- package/ai-config/agents/development/frontend-specialist.md +686 -0
- package/ai-config/agents/development/fullstack-engineer.md +668 -0
- package/ai-config/agents/development/golang-pro.md +338 -0
- package/ai-config/agents/development/java-enterprise.md +400 -0
- package/ai-config/agents/development/javascript-pro.md +422 -0
- package/ai-config/agents/development/nextjs-pro.md +474 -0
- package/ai-config/agents/development/python-pro.md +570 -0
- package/ai-config/agents/development/react-pro.md +487 -0
- package/ai-config/agents/development/rust-pro.md +246 -0
- package/ai-config/agents/development/spring-boot-4-expert.md +326 -0
- package/ai-config/agents/development/typescript-pro.md +336 -0
- package/ai-config/agents/development/vue-specialist.md +605 -0
- package/ai-config/agents/infrastructure/cloud-architect.md +472 -0
- package/ai-config/agents/infrastructure/deployment-manager.md +358 -0
- package/ai-config/agents/infrastructure/devops-engineer.md +455 -0
- package/ai-config/agents/infrastructure/incident-responder.md +519 -0
- package/ai-config/agents/infrastructure/kubernetes-expert.md +705 -0
- package/ai-config/agents/infrastructure/monitoring-specialist.md +674 -0
- package/ai-config/agents/infrastructure/performance-engineer.md +658 -0
- package/ai-config/agents/orchestrator.md +241 -0
- package/ai-config/agents/quality/accessibility-auditor.md +1204 -0
- package/ai-config/agents/quality/code-reviewer-compact.md +123 -0
- package/ai-config/agents/quality/code-reviewer.md +363 -0
- package/ai-config/agents/quality/dependency-manager.md +743 -0
- package/ai-config/agents/quality/e2e-test-specialist.md +1005 -0
- package/ai-config/agents/quality/performance-tester.md +1086 -0
- package/ai-config/agents/quality/security-auditor.md +133 -0
- package/ai-config/agents/quality/test-engineer.md +453 -0
- package/ai-config/agents/specialists/api-designer.md +87 -0
- package/ai-config/agents/specialists/backend-architect.md +73 -0
- package/ai-config/agents/specialists/code-reviewer.md +77 -0
- package/ai-config/agents/specialists/db-optimizer.md +75 -0
- package/ai-config/agents/specialists/devops-engineer.md +83 -0
- package/ai-config/agents/specialists/documentation-writer.md +78 -0
- package/ai-config/agents/specialists/frontend-developer.md +75 -0
- package/ai-config/agents/specialists/performance-analyst.md +82 -0
- package/ai-config/agents/specialists/refactor-specialist.md +74 -0
- package/ai-config/agents/specialists/security-auditor.md +74 -0
- package/ai-config/agents/specialists/test-engineer.md +81 -0
- package/ai-config/agents/specialists/ux-consultant.md +76 -0
- package/ai-config/agents/specialized/agent-generator.md +1190 -0
- package/ai-config/agents/specialized/blockchain-developer.md +149 -0
- package/ai-config/agents/specialized/code-migrator.md +892 -0
- package/ai-config/agents/specialized/context-manager.md +978 -0
- package/ai-config/agents/specialized/documentation-writer.md +1078 -0
- package/ai-config/agents/specialized/ecommerce-expert.md +1756 -0
- package/ai-config/agents/specialized/embedded-engineer.md +1714 -0
- package/ai-config/agents/specialized/error-detective.md +1034 -0
- package/ai-config/agents/specialized/fintech-specialist.md +1659 -0
- package/ai-config/agents/specialized/freelance-project-planner-v2.md +1988 -0
- package/ai-config/agents/specialized/freelance-project-planner-v3.md +2136 -0
- package/ai-config/agents/specialized/freelance-project-planner-v4.md +4503 -0
- package/ai-config/agents/specialized/freelance-project-planner.md +722 -0
- package/ai-config/agents/specialized/game-developer.md +1963 -0
- package/ai-config/agents/specialized/healthcare-dev.md +1620 -0
- package/ai-config/agents/specialized/mobile-developer.md +188 -0
- package/ai-config/agents/specialized/parallel-plan-executor.md +506 -0
- package/ai-config/agents/specialized/plan-executor.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/00-INDEX.md +485 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/01-CORE.md +3493 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/02-SELF-CORRECTION.md +778 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/03-PROGRESSIVE-SETUP.md +918 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/04-DEPLOYMENT.md +1537 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/05-TESTING.md +2633 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/06-OPERATIONS.md +5610 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/INSTALL.md +335 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/QUICK-REFERENCE.txt +215 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/README.md +260 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/START-HERE.md +379 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/WORKFLOW-DIAGRAM.md +355 -0
- package/ai-config/agents/specialized/solo-dev-planner-modular/solo-dev-planner.md +279 -0
- package/ai-config/agents/specialized/template-writer.md +347 -0
- package/ai-config/agents/specialized/test-runner.md +99 -0
- package/ai-config/agents/specialized/vibekanban-smart-worker.md +244 -0
- package/ai-config/agents/specialized/wave-executor.md +138 -0
- package/ai-config/agents/specialized/workflow-optimizer.md +1114 -0
- package/ai-config/commands/git/changelog.md +32 -0
- package/ai-config/commands/git/ci-local.md +70 -0
- package/ai-config/commands/git/commit.md +35 -0
- package/ai-config/commands/git/fix-issue.md +23 -0
- package/ai-config/commands/git/pr-create.md +42 -0
- package/ai-config/commands/git/pr-review.md +50 -0
- package/ai-config/commands/git/worktree.md +39 -0
- package/ai-config/commands/refactoring/cleanup.md +24 -0
- package/ai-config/commands/refactoring/dead-code.md +40 -0
- package/ai-config/commands/refactoring/extract.md +31 -0
- package/ai-config/commands/testing/e2e.md +30 -0
- package/ai-config/commands/testing/tdd.md +36 -0
- package/ai-config/commands/testing/test-coverage.md +30 -0
- package/ai-config/commands/testing/test-fix.md +24 -0
- package/ai-config/commands/workflow/generate-agents-md.md +85 -0
- package/ai-config/commands/workflow/planning.md +47 -0
- package/ai-config/commands/workflows/compound.md +89 -0
- package/ai-config/commands/workflows/plan.md +77 -0
- package/ai-config/commands/workflows/review.md +78 -0
- package/ai-config/commands/workflows/work.md +75 -0
- package/ai-config/config.yaml +18 -0
- package/ai-config/hooks/_TEMPLATE.md +96 -0
- package/ai-config/hooks/block-dangerous-commands.md +75 -0
- package/ai-config/hooks/commit-guard.md +90 -0
- package/ai-config/hooks/context-loader.md +73 -0
- package/ai-config/hooks/improve-prompt.md +91 -0
- package/ai-config/hooks/learning-log.md +72 -0
- package/ai-config/hooks/model-router.md +86 -0
- package/ai-config/hooks/secret-scanner.md +64 -0
- package/ai-config/hooks/skill-validator.md +102 -0
- package/ai-config/hooks/task-artifact.md +114 -0
- package/ai-config/hooks/validate-workflow.md +100 -0
- package/ai-config/prompts/base.md +71 -0
- package/ai-config/prompts/modes/debug.md +34 -0
- package/ai-config/prompts/modes/deploy.md +40 -0
- package/ai-config/prompts/modes/research.md +32 -0
- package/ai-config/prompts/modes/review.md +33 -0
- package/ai-config/prompts/review-policy.md +79 -0
- package/ai-config/skills/_TEMPLATE.md +157 -0
- package/ai-config/skills/backend/api-gateway/SKILL.md +254 -0
- package/ai-config/skills/backend/bff-concepts/SKILL.md +239 -0
- package/ai-config/skills/backend/bff-spring/SKILL.md +364 -0
- package/ai-config/skills/backend/chi-router/SKILL.md +396 -0
- package/ai-config/skills/backend/error-handling/SKILL.md +255 -0
- package/ai-config/skills/backend/exceptions-spring/SKILL.md +323 -0
- package/ai-config/skills/backend/fastapi/SKILL.md +302 -0
- package/ai-config/skills/backend/gateway-spring/SKILL.md +390 -0
- package/ai-config/skills/backend/go-backend/SKILL.md +457 -0
- package/ai-config/skills/backend/gradle-multimodule/SKILL.md +274 -0
- package/ai-config/skills/backend/graphql-concepts/SKILL.md +352 -0
- package/ai-config/skills/backend/graphql-spring/SKILL.md +398 -0
- package/ai-config/skills/backend/grpc-concepts/SKILL.md +283 -0
- package/ai-config/skills/backend/grpc-spring/SKILL.md +445 -0
- package/ai-config/skills/backend/jwt-auth/SKILL.md +412 -0
- package/ai-config/skills/backend/notifications-concepts/SKILL.md +259 -0
- package/ai-config/skills/backend/recommendations-concepts/SKILL.md +261 -0
- package/ai-config/skills/backend/search-concepts/SKILL.md +263 -0
- package/ai-config/skills/backend/search-spring/SKILL.md +375 -0
- package/ai-config/skills/backend/spring-boot-4/SKILL.md +172 -0
- package/ai-config/skills/backend/websockets/SKILL.md +532 -0
- package/ai-config/skills/data-ai/ai-ml/SKILL.md +423 -0
- package/ai-config/skills/data-ai/analytics-concepts/SKILL.md +195 -0
- package/ai-config/skills/data-ai/analytics-spring/SKILL.md +340 -0
- package/ai-config/skills/data-ai/duckdb-analytics/SKILL.md +440 -0
- package/ai-config/skills/data-ai/langchain/SKILL.md +238 -0
- package/ai-config/skills/data-ai/mlflow/SKILL.md +302 -0
- package/ai-config/skills/data-ai/onnx-inference/SKILL.md +290 -0
- package/ai-config/skills/data-ai/powerbi/SKILL.md +352 -0
- package/ai-config/skills/data-ai/pytorch/SKILL.md +274 -0
- package/ai-config/skills/data-ai/scikit-learn/SKILL.md +321 -0
- package/ai-config/skills/data-ai/vector-db/SKILL.md +301 -0
- package/ai-config/skills/database/graph-databases/SKILL.md +218 -0
- package/ai-config/skills/database/graph-spring/SKILL.md +361 -0
- package/ai-config/skills/database/pgx-postgres/SKILL.md +512 -0
- package/ai-config/skills/database/redis-cache/SKILL.md +343 -0
- package/ai-config/skills/database/sqlite-embedded/SKILL.md +388 -0
- package/ai-config/skills/database/timescaledb/SKILL.md +320 -0
- package/ai-config/skills/docs/api-documentation/SKILL.md +293 -0
- package/ai-config/skills/docs/docs-spring/SKILL.md +377 -0
- package/ai-config/skills/docs/mustache-templates/SKILL.md +190 -0
- package/ai-config/skills/docs/technical-docs/SKILL.md +447 -0
- package/ai-config/skills/frontend/astro-ssr/SKILL.md +441 -0
- package/ai-config/skills/frontend/frontend-design/SKILL.md +54 -0
- package/ai-config/skills/frontend/frontend-web/SKILL.md +368 -0
- package/ai-config/skills/frontend/mantine-ui/SKILL.md +396 -0
- package/ai-config/skills/frontend/tanstack-query/SKILL.md +439 -0
- package/ai-config/skills/frontend/zod-validation/SKILL.md +417 -0
- package/ai-config/skills/frontend/zustand-state/SKILL.md +350 -0
- package/ai-config/skills/infrastructure/chaos-engineering/SKILL.md +244 -0
- package/ai-config/skills/infrastructure/chaos-spring/SKILL.md +378 -0
- package/ai-config/skills/infrastructure/devops-infra/SKILL.md +435 -0
- package/ai-config/skills/infrastructure/docker-containers/SKILL.md +420 -0
- package/ai-config/skills/infrastructure/kubernetes/SKILL.md +456 -0
- package/ai-config/skills/infrastructure/opentelemetry/SKILL.md +546 -0
- package/ai-config/skills/infrastructure/traefik-proxy/SKILL.md +474 -0
- package/ai-config/skills/infrastructure/woodpecker-ci/SKILL.md +315 -0
- package/ai-config/skills/mobile/ionic-capacitor/SKILL.md +504 -0
- package/ai-config/skills/mobile/mobile-ionic/SKILL.md +448 -0
- package/ai-config/skills/prompt-improver/SKILL.md +125 -0
- package/ai-config/skills/quality/ghagga-review/SKILL.md +216 -0
- package/ai-config/skills/references/hooks-patterns/SKILL.md +238 -0
- package/ai-config/skills/references/mcp-servers/SKILL.md +275 -0
- package/ai-config/skills/references/plugins-reference/SKILL.md +110 -0
- package/ai-config/skills/references/skills-reference/SKILL.md +420 -0
- package/ai-config/skills/references/subagent-templates/SKILL.md +193 -0
- package/ai-config/skills/systems-iot/modbus-protocol/SKILL.md +410 -0
- package/ai-config/skills/systems-iot/mqtt-rumqttc/SKILL.md +408 -0
- package/ai-config/skills/systems-iot/rust-systems/SKILL.md +386 -0
- package/ai-config/skills/systems-iot/tokio-async/SKILL.md +324 -0
- package/ai-config/skills/testing/playwright-e2e/SKILL.md +289 -0
- package/ai-config/skills/testing/testcontainers/SKILL.md +299 -0
- package/ai-config/skills/testing/vitest-testing/SKILL.md +381 -0
- package/ai-config/skills/workflow/ci-local-guide/SKILL.md +118 -0
- package/ai-config/skills/workflow/claude-automation-recommender/SKILL.md +299 -0
- package/ai-config/skills/workflow/claude-md-improver/SKILL.md +158 -0
- package/ai-config/skills/workflow/finishing-a-development-branch/SKILL.md +117 -0
- package/ai-config/skills/workflow/git-github/SKILL.md +334 -0
- package/ai-config/skills/workflow/git-github/references/examples.md +160 -0
- package/ai-config/skills/workflow/git-workflow/SKILL.md +214 -0
- package/ai-config/skills/workflow/ide-plugins/SKILL.md +277 -0
- package/ai-config/skills/workflow/ide-plugins-intellij/SKILL.md +401 -0
- package/ai-config/skills/workflow/obsidian-brain-workflow/SKILL.md +199 -0
- package/ai-config/skills/workflow/using-git-worktrees/SKILL.md +100 -0
- package/ai-config/skills/workflow/verification-before-completion/SKILL.md +73 -0
- package/ai-config/skills/workflow/wave-workflow/SKILL.md +178 -0
- package/ci-local/README.md +170 -0
- package/ci-local/ci-local.sh +297 -0
- package/ci-local/hooks/commit-msg +74 -0
- package/ci-local/hooks/pre-commit +162 -0
- package/ci-local/hooks/pre-push +41 -0
- package/ci-local/install.sh +49 -0
- package/ci-local/semgrep.yml +214 -0
- package/dist/commands/analyze.d.ts +9 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +55 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/analyze.test.d.ts +2 -0
- package/dist/commands/analyze.test.d.ts.map +1 -0
- package/dist/commands/analyze.test.js +145 -0
- package/dist/commands/analyze.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +158 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +2 -0
- package/dist/commands/doctor.test.d.ts.map +1 -0
- package/dist/commands/doctor.test.js +200 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +283 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +271 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +201 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +57 -0
- package/dist/constants.js.map +1 -0
- package/dist/e2e/aggressive.e2e.test.d.ts +2 -0
- package/dist/e2e/aggressive.e2e.test.d.ts.map +1 -0
- package/dist/e2e/aggressive.e2e.test.js +350 -0
- package/dist/e2e/aggressive.e2e.test.js.map +1 -0
- package/dist/e2e/commands.e2e.test.d.ts +2 -0
- package/dist/e2e/commands.e2e.test.d.ts.map +1 -0
- package/dist/e2e/commands.e2e.test.js +213 -0
- package/dist/e2e/commands.e2e.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/common.d.ts +17 -0
- package/dist/lib/common.d.ts.map +1 -0
- package/dist/lib/common.js +111 -0
- package/dist/lib/common.js.map +1 -0
- package/dist/lib/common.test.d.ts +2 -0
- package/dist/lib/common.test.d.ts.map +1 -0
- package/dist/lib/common.test.js +316 -0
- package/dist/lib/common.test.js.map +1 -0
- package/dist/lib/frontmatter.d.ts +18 -0
- package/dist/lib/frontmatter.d.ts.map +1 -0
- package/dist/lib/frontmatter.js +61 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lib/frontmatter.test.d.ts +2 -0
- package/dist/lib/frontmatter.test.d.ts.map +1 -0
- package/dist/lib/frontmatter.test.js +257 -0
- package/dist/lib/frontmatter.test.js.map +1 -0
- package/dist/lib/template.d.ts +24 -0
- package/dist/lib/template.d.ts.map +1 -0
- package/dist/lib/template.js +78 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/template.test.d.ts +2 -0
- package/dist/lib/template.test.d.ts.map +1 -0
- package/dist/lib/template.test.js +201 -0
- package/dist/lib/template.test.js.map +1 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/AnalyzeUI.d.ts +7 -0
- package/dist/ui/AnalyzeUI.d.ts.map +1 -0
- package/dist/ui/AnalyzeUI.js +100 -0
- package/dist/ui/AnalyzeUI.js.map +1 -0
- package/dist/ui/App.d.ts +13 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +100 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/CIContext.d.ts +9 -0
- package/dist/ui/CIContext.d.ts.map +1 -0
- package/dist/ui/CIContext.js +9 -0
- package/dist/ui/CIContext.js.map +1 -0
- package/dist/ui/CISelector.d.ts +8 -0
- package/dist/ui/CISelector.d.ts.map +1 -0
- package/dist/ui/CISelector.js +45 -0
- package/dist/ui/CISelector.js.map +1 -0
- package/dist/ui/Doctor.d.ts +3 -0
- package/dist/ui/Doctor.d.ts.map +1 -0
- package/dist/ui/Doctor.js +89 -0
- package/dist/ui/Doctor.js.map +1 -0
- package/dist/ui/Header.d.ts +8 -0
- package/dist/ui/Header.d.ts.map +1 -0
- package/dist/ui/Header.js +30 -0
- package/dist/ui/Header.js.map +1 -0
- package/dist/ui/MemorySelector.d.ts +8 -0
- package/dist/ui/MemorySelector.d.ts.map +1 -0
- package/dist/ui/MemorySelector.js +46 -0
- package/dist/ui/MemorySelector.js.map +1 -0
- package/dist/ui/NameInput.d.ts +8 -0
- package/dist/ui/NameInput.d.ts.map +1 -0
- package/dist/ui/NameInput.js +69 -0
- package/dist/ui/NameInput.js.map +1 -0
- package/dist/ui/OptionSelector.d.ts +12 -0
- package/dist/ui/OptionSelector.d.ts.map +1 -0
- package/dist/ui/OptionSelector.js +69 -0
- package/dist/ui/OptionSelector.js.map +1 -0
- package/dist/ui/Progress.d.ts +11 -0
- package/dist/ui/Progress.d.ts.map +1 -0
- package/dist/ui/Progress.js +58 -0
- package/dist/ui/Progress.js.map +1 -0
- package/dist/ui/StackSelector.d.ts +9 -0
- package/dist/ui/StackSelector.d.ts.map +1 -0
- package/dist/ui/StackSelector.js +65 -0
- package/dist/ui/StackSelector.js.map +1 -0
- package/dist/ui/Summary.d.ts +12 -0
- package/dist/ui/Summary.d.ts.map +1 -0
- package/dist/ui/Summary.js +114 -0
- package/dist/ui/Summary.js.map +1 -0
- package/dist/ui/SyncUI.d.ts +10 -0
- package/dist/ui/SyncUI.d.ts.map +1 -0
- package/dist/ui/SyncUI.js +64 -0
- package/dist/ui/SyncUI.js.map +1 -0
- package/dist/ui/Welcome.d.ts +7 -0
- package/dist/ui/Welcome.d.ts.map +1 -0
- package/dist/ui/Welcome.js +45 -0
- package/dist/ui/Welcome.js.map +1 -0
- package/dist/ui/theme.d.ts +10 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +9 -0
- package/dist/ui/theme.js.map +1 -0
- package/modules/engram/.gitignore-snippet.txt +6 -0
- package/modules/engram/.mcp-config-snippet.json +11 -0
- package/modules/engram/README.md +146 -0
- package/modules/engram/install-engram.sh +216 -0
- package/modules/ghagga/.env.example +43 -0
- package/modules/ghagga/README.md +153 -0
- package/modules/ghagga/docker-compose.yml +80 -0
- package/modules/ghagga/setup-ghagga.sh +139 -0
- package/modules/memory-simple/.project/NOTES.md +22 -0
- package/modules/memory-simple/README.md +23 -0
- package/modules/obsidian-brain/.obsidian/app.json +23 -0
- package/modules/obsidian-brain/.obsidian/appearance.json +5 -0
- package/modules/obsidian-brain/.obsidian/bookmarks.json +34 -0
- package/modules/obsidian-brain/.obsidian/community-plugins.json +1 -0
- package/modules/obsidian-brain/.obsidian/core-plugins-migration.json +21 -0
- package/modules/obsidian-brain/.obsidian/core-plugins.json +18 -0
- package/modules/obsidian-brain/.obsidian/daily-notes.json +5 -0
- package/modules/obsidian-brain/.obsidian/graph.json +37 -0
- package/modules/obsidian-brain/.obsidian/hotkeys.json +14 -0
- package/modules/obsidian-brain/.obsidian/plugins/dataview/data.json +25 -0
- package/modules/obsidian-brain/.obsidian/plugins/obsidian-kanban/data.json +29 -0
- package/modules/obsidian-brain/.obsidian/plugins/templater-obsidian/data.json +18 -0
- package/modules/obsidian-brain/.obsidian/snippets/project-memory.css +71 -0
- package/modules/obsidian-brain/.obsidian-gitignore-snippet.txt +8 -0
- package/modules/obsidian-brain/.project/Attachments/.gitkeep +0 -0
- package/modules/obsidian-brain/.project/Memory/BLOCKERS.md +78 -0
- package/modules/obsidian-brain/.project/Memory/CONTEXT.md +102 -0
- package/modules/obsidian-brain/.project/Memory/DASHBOARD.md +73 -0
- package/modules/obsidian-brain/.project/Memory/DECISIONS.md +87 -0
- package/modules/obsidian-brain/.project/Memory/KANBAN.md +15 -0
- package/modules/obsidian-brain/.project/Memory/README.md +61 -0
- package/modules/obsidian-brain/.project/Memory/WAVES.md +78 -0
- package/modules/obsidian-brain/.project/Sessions/TEMPLATE.md +99 -0
- package/modules/obsidian-brain/.project/Templates/ADR.md +33 -0
- package/modules/obsidian-brain/.project/Templates/Blocker.md +21 -0
- package/modules/obsidian-brain/.project/Templates/Session.md +88 -0
- package/modules/obsidian-brain/README.md +268 -0
- package/modules/obsidian-brain/new-wave.sh +182 -0
- package/package.json +51 -0
- package/schemas/agent.schema.json +34 -0
- package/schemas/ai-config.schema.json +28 -0
- package/schemas/skill.schema.json +44 -0
- package/src/commands/analyze.test.ts +145 -0
- package/src/commands/analyze.ts +69 -0
- package/src/commands/doctor.test.ts +208 -0
- package/src/commands/doctor.ts +163 -0
- package/src/commands/init.test.ts +298 -0
- package/src/commands/init.ts +285 -0
- package/src/constants.ts +69 -0
- package/src/e2e/aggressive.e2e.test.ts +557 -0
- package/src/e2e/commands.e2e.test.ts +298 -0
- package/src/index.tsx +106 -0
- package/src/lib/common.test.ts +318 -0
- package/src/lib/common.ts +127 -0
- package/src/lib/frontmatter.test.ts +291 -0
- package/src/lib/frontmatter.ts +77 -0
- package/src/lib/template.test.ts +226 -0
- package/src/lib/template.ts +99 -0
- package/src/types/index.ts +53 -0
- package/src/ui/AnalyzeUI.tsx +133 -0
- package/src/ui/App.tsx +175 -0
- package/src/ui/CIContext.tsx +25 -0
- package/src/ui/CISelector.tsx +72 -0
- package/src/ui/Doctor.tsx +122 -0
- package/src/ui/Header.tsx +48 -0
- package/src/ui/MemorySelector.tsx +73 -0
- package/src/ui/NameInput.tsx +82 -0
- package/src/ui/OptionSelector.tsx +100 -0
- package/src/ui/Progress.tsx +88 -0
- package/src/ui/StackSelector.tsx +101 -0
- package/src/ui/Summary.tsx +134 -0
- package/src/ui/Welcome.tsx +54 -0
- package/src/ui/theme.ts +10 -0
- package/stryker.config.json +19 -0
- package/tasks/_TEMPLATE/files-edited.md +3 -0
- package/tasks/_TEMPLATE/plan.md +3 -0
- package/tasks/_TEMPLATE/research.md +3 -0
- package/tasks/_TEMPLATE/verification.md +5 -0
- package/templates/common/dependabot/cargo.yml +11 -0
- package/templates/common/dependabot/github-actions.yml +16 -0
- package/templates/common/dependabot/gomod.yml +15 -0
- package/templates/common/dependabot/gradle.yml +15 -0
- package/templates/common/dependabot/header.yml +3 -0
- package/templates/common/dependabot/maven.yml +15 -0
- package/templates/common/dependabot/npm.yml +20 -0
- package/templates/common/dependabot/pip.yml +11 -0
- package/templates/dependabot.yml +162 -0
- package/templates/github/ci-go.yml +41 -0
- package/templates/github/ci-java.yml +45 -0
- package/templates/github/ci-monorepo.yml +150 -0
- package/templates/github/ci-node.yml +42 -0
- package/templates/github/ci-python.yml +42 -0
- package/templates/github/ci-rust.yml +42 -0
- package/templates/github/dependabot-automerge.yml +40 -0
- package/templates/gitlab/gitlab-ci-go.yml +88 -0
- package/templates/gitlab/gitlab-ci-java.yml +79 -0
- package/templates/gitlab/gitlab-ci-monorepo.yml +126 -0
- package/templates/gitlab/gitlab-ci-node.yml +63 -0
- package/templates/gitlab/gitlab-ci-python.yml +147 -0
- package/templates/gitlab/gitlab-ci-rust.yml +67 -0
- package/templates/global/claude-settings.json +98 -0
- package/templates/global/codex-config.toml +8 -0
- package/templates/global/copilot-instructions/base-rules.instructions.md +13 -0
- package/templates/global/copilot-instructions/sdd-orchestrator.instructions.md +37 -0
- package/templates/global/gemini-commands/cleanup.toml +20 -0
- package/templates/global/gemini-commands/commit.toml +15 -0
- package/templates/global/gemini-commands/dead-code.toml +22 -0
- package/templates/global/gemini-commands/plan.toml +30 -0
- package/templates/global/gemini-commands/review.toml +17 -0
- package/templates/global/gemini-commands/sdd-apply.toml +22 -0
- package/templates/global/gemini-commands/sdd-ff.toml +14 -0
- package/templates/global/gemini-commands/sdd-new.toml +21 -0
- package/templates/global/gemini-commands/sdd-verify.toml +21 -0
- package/templates/global/gemini-commands/tdd.toml +26 -0
- package/templates/global/gemini-settings.json +8 -0
- package/templates/global/opencode-config.json +44 -0
- package/templates/global/sdd-instructions.md +47 -0
- package/templates/global/sdd-orchestrator-claude.md +46 -0
- package/templates/global/sdd-orchestrator-copilot.md +34 -0
- package/templates/renovate.json +69 -0
- package/templates/woodpecker/monorepo/backend.yml +34 -0
- package/templates/woodpecker/monorepo/frontend.yml +34 -0
- package/templates/woodpecker/monorepo/summary.yml +25 -0
- package/templates/woodpecker/woodpecker-go.yml +51 -0
- package/templates/woodpecker/woodpecker-java.yml +67 -0
- package/templates/woodpecker/woodpecker-node.yml +47 -0
- package/templates/woodpecker/woodpecker-python.yml +108 -0
- package/templates/woodpecker/woodpecker-rust.yml +57 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +16 -0
- package/workflows/reusable-build-go.yml +111 -0
- package/workflows/reusable-build-java.yml +120 -0
- package/workflows/reusable-build-node.yml +145 -0
- package/workflows/reusable-build-python.yml +159 -0
- package/workflows/reusable-build-rust.yml +135 -0
- package/workflows/reusable-docker.yml +120 -0
- package/workflows/reusable-ghagga-review.yml +165 -0
- package/workflows/reusable-release.yml +91 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: duckdb-analytics
|
|
3
|
+
description: >
|
|
4
|
+
DuckDB OLAP analytics with Parquet, S3, and columnar queries for BI/ML.
|
|
5
|
+
Trigger: duckdb, olap, analytics, parquet, columnar, data warehouse, BI
|
|
6
|
+
|
|
7
|
+
tools:
|
|
8
|
+
- Read
|
|
9
|
+
- Write
|
|
10
|
+
- Bash
|
|
11
|
+
- Grep
|
|
12
|
+
|
|
13
|
+
metadata:
|
|
14
|
+
author: plataforma-industrial
|
|
15
|
+
version: "2.0"
|
|
16
|
+
tags: [duckdb, olap, analytics, parquet, bi]
|
|
17
|
+
updated: "2026-02"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# DuckDB OLAP Analytics
|
|
21
|
+
|
|
22
|
+
> Columnar analytics engine for Parquet files, S3 data lakes, and BI workloads.
|
|
23
|
+
|
|
24
|
+
## Stack
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
DuckDB: 0.10+
|
|
28
|
+
Go Driver: github.com/marcboeker/go-duckdb
|
|
29
|
+
Python: duckdb 0.10+
|
|
30
|
+
Extensions: httpfs, parquet, postgres
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## When to Use
|
|
34
|
+
|
|
35
|
+
- Analytical queries over historical data
|
|
36
|
+
- Reading Parquet files from S3/MinIO
|
|
37
|
+
- BI reports and aggregations
|
|
38
|
+
- ML feature engineering
|
|
39
|
+
- Time-series analysis on archived data
|
|
40
|
+
|
|
41
|
+
### Data Architecture
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
TimescaleDB (OLTP - Hot, <90 days)
|
|
45
|
+
|
|
|
46
|
+
| ETL / Export
|
|
47
|
+
v
|
|
48
|
+
Parquet Files (S3/MinIO - Warm)
|
|
49
|
+
|
|
|
50
|
+
| Direct read
|
|
51
|
+
v
|
|
52
|
+
DuckDB (OLAP - Analytical queries)
|
|
53
|
+
|
|
|
54
|
+
v
|
|
55
|
+
BI Tools / Reports / ML
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Python Setup
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
import duckdb
|
|
62
|
+
|
|
63
|
+
class DuckDBAnalytics:
|
|
64
|
+
def __init__(self, db_path: str = ":memory:"):
|
|
65
|
+
self.conn = duckdb.connect(db_path)
|
|
66
|
+
self._setup()
|
|
67
|
+
|
|
68
|
+
def _setup(self):
|
|
69
|
+
self.conn.execute("INSTALL httpfs; LOAD httpfs;")
|
|
70
|
+
self.conn.execute("INSTALL parquet; LOAD parquet;")
|
|
71
|
+
|
|
72
|
+
def configure_s3(self, endpoint: str, access_key: str, secret_key: str):
|
|
73
|
+
self.conn.execute(f"SET s3_endpoint = '{endpoint}';")
|
|
74
|
+
self.conn.execute(f"SET s3_access_key_id = '{access_key}';")
|
|
75
|
+
self.conn.execute(f"SET s3_secret_access_key = '{secret_key}';")
|
|
76
|
+
self.conn.execute("SET s3_use_ssl = false;")
|
|
77
|
+
|
|
78
|
+
def query_df(self, sql: str):
|
|
79
|
+
return self.conn.execute(sql).fetchdf()
|
|
80
|
+
|
|
81
|
+
def query(self, sql: str) -> list[dict]:
|
|
82
|
+
result = self.conn.execute(sql)
|
|
83
|
+
columns = [desc[0] for desc in result.description]
|
|
84
|
+
return [dict(zip(columns, row)) for row in result.fetchall()]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Go Setup
|
|
88
|
+
|
|
89
|
+
```go
|
|
90
|
+
package analytics
|
|
91
|
+
|
|
92
|
+
import (
|
|
93
|
+
"database/sql"
|
|
94
|
+
_ "github.com/marcboeker/go-duckdb"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
type DuckDB struct {
|
|
98
|
+
db *sql.DB
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
func NewDuckDB(path string) (*DuckDB, error) {
|
|
102
|
+
db, err := sql.Open("duckdb", path)
|
|
103
|
+
if err != nil {
|
|
104
|
+
return nil, err
|
|
105
|
+
}
|
|
106
|
+
db.Exec("INSTALL parquet; LOAD parquet;")
|
|
107
|
+
return &DuckDB{db: db}, nil
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Schema for Analytics
|
|
112
|
+
|
|
113
|
+
### Fact Tables
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
CREATE SCHEMA IF NOT EXISTS analytics;
|
|
117
|
+
|
|
118
|
+
CREATE TABLE IF NOT EXISTS analytics.sensor_readings (
|
|
119
|
+
time TIMESTAMP NOT NULL,
|
|
120
|
+
sensor_id UUID NOT NULL,
|
|
121
|
+
sensor_name VARCHAR,
|
|
122
|
+
tenant_id UUID,
|
|
123
|
+
value DOUBLE,
|
|
124
|
+
unit VARCHAR,
|
|
125
|
+
-- Pre-computed time dimensions
|
|
126
|
+
year INTEGER,
|
|
127
|
+
month INTEGER,
|
|
128
|
+
week INTEGER,
|
|
129
|
+
day_of_week INTEGER,
|
|
130
|
+
hour INTEGER,
|
|
131
|
+
partition_date DATE
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS analytics.events (
|
|
135
|
+
id UUID,
|
|
136
|
+
event_type VARCHAR,
|
|
137
|
+
entity_id UUID,
|
|
138
|
+
tenant_id UUID,
|
|
139
|
+
payload JSON,
|
|
140
|
+
occurred_at TIMESTAMP NOT NULL,
|
|
141
|
+
year INTEGER,
|
|
142
|
+
month INTEGER,
|
|
143
|
+
partition_date DATE
|
|
144
|
+
);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Dimension Tables
|
|
148
|
+
|
|
149
|
+
```sql
|
|
150
|
+
-- Date dimension
|
|
151
|
+
CREATE TABLE IF NOT EXISTS analytics.dim_date (
|
|
152
|
+
date_key DATE PRIMARY KEY,
|
|
153
|
+
year INTEGER,
|
|
154
|
+
quarter INTEGER,
|
|
155
|
+
month INTEGER,
|
|
156
|
+
month_name VARCHAR,
|
|
157
|
+
week INTEGER,
|
|
158
|
+
day_of_week INTEGER,
|
|
159
|
+
day_name VARCHAR,
|
|
160
|
+
is_weekend BOOLEAN
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
-- Populate 10 years
|
|
164
|
+
INSERT INTO analytics.dim_date
|
|
165
|
+
SELECT
|
|
166
|
+
date_key,
|
|
167
|
+
YEAR(date_key), QUARTER(date_key), MONTH(date_key),
|
|
168
|
+
MONTHNAME(date_key), WEEKOFYEAR(date_key),
|
|
169
|
+
DAYOFWEEK(date_key), DAYNAME(date_key),
|
|
170
|
+
DAYOFWEEK(date_key) IN (0, 6)
|
|
171
|
+
FROM (
|
|
172
|
+
SELECT UNNEST(generate_series(
|
|
173
|
+
DATE '2020-01-01', DATE '2030-12-31', INTERVAL 1 DAY
|
|
174
|
+
))::DATE as date_key
|
|
175
|
+
);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Loading from Parquet
|
|
179
|
+
|
|
180
|
+
### Direct Query (No Load)
|
|
181
|
+
|
|
182
|
+
```sql
|
|
183
|
+
-- Query directly from Parquet files
|
|
184
|
+
SELECT
|
|
185
|
+
sensor_id,
|
|
186
|
+
AVG(value) as avg_value,
|
|
187
|
+
COUNT(*) as readings
|
|
188
|
+
FROM read_parquet('s3://data/readings/**/*.parquet')
|
|
189
|
+
WHERE partition_date >= '2024-01-01'
|
|
190
|
+
GROUP BY sensor_id;
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Load into Table
|
|
194
|
+
|
|
195
|
+
```sql
|
|
196
|
+
-- Load with transformation
|
|
197
|
+
INSERT INTO analytics.sensor_readings
|
|
198
|
+
SELECT
|
|
199
|
+
time::TIMESTAMP,
|
|
200
|
+
sensor_id::UUID,
|
|
201
|
+
sensor_name,
|
|
202
|
+
tenant_id::UUID,
|
|
203
|
+
value,
|
|
204
|
+
unit,
|
|
205
|
+
YEAR(time), MONTH(time), WEEKOFYEAR(time),
|
|
206
|
+
DAYOFWEEK(time), HOUR(time),
|
|
207
|
+
time::DATE as partition_date
|
|
208
|
+
FROM read_parquet('s3://data/readings/date=2024-01-15/*.parquet')
|
|
209
|
+
WHERE partition_date NOT IN (SELECT DISTINCT partition_date FROM analytics.sensor_readings);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Python ETL
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from datetime import datetime, timedelta
|
|
216
|
+
|
|
217
|
+
conn = duckdb.connect("analytics.duckdb")
|
|
218
|
+
conn.execute("SET s3_endpoint = 'minio:9000';")
|
|
219
|
+
conn.execute("SET s3_access_key_id = 'admin';")
|
|
220
|
+
conn.execute("SET s3_secret_access_key = 'password';")
|
|
221
|
+
|
|
222
|
+
# Load last 30 days
|
|
223
|
+
for i in range(30):
|
|
224
|
+
date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
|
|
225
|
+
conn.execute(f"""
|
|
226
|
+
INSERT INTO analytics.sensor_readings
|
|
227
|
+
SELECT * FROM read_parquet('s3://data/readings/date={date}/*.parquet')
|
|
228
|
+
""")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Analytical Views
|
|
232
|
+
|
|
233
|
+
### Daily Summary
|
|
234
|
+
|
|
235
|
+
```sql
|
|
236
|
+
CREATE OR REPLACE VIEW reports.daily_summary AS
|
|
237
|
+
SELECT
|
|
238
|
+
partition_date,
|
|
239
|
+
sensor_id,
|
|
240
|
+
sensor_name,
|
|
241
|
+
COUNT(*) as reading_count,
|
|
242
|
+
AVG(value) as avg_value,
|
|
243
|
+
MIN(value) as min_value,
|
|
244
|
+
MAX(value) as max_value,
|
|
245
|
+
STDDEV(value) as stddev_value
|
|
246
|
+
FROM analytics.sensor_readings
|
|
247
|
+
GROUP BY partition_date, sensor_id, sensor_name;
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Monthly KPIs
|
|
251
|
+
|
|
252
|
+
```sql
|
|
253
|
+
CREATE OR REPLACE VIEW reports.monthly_kpis AS
|
|
254
|
+
SELECT
|
|
255
|
+
tenant_id,
|
|
256
|
+
year,
|
|
257
|
+
month,
|
|
258
|
+
COUNT(DISTINCT sensor_id) as active_sensors,
|
|
259
|
+
SUM(reading_count) as total_readings,
|
|
260
|
+
AVG(avg_value) as overall_avg
|
|
261
|
+
FROM reports.daily_summary
|
|
262
|
+
GROUP BY tenant_id, year, month;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Advanced Analytics
|
|
266
|
+
|
|
267
|
+
### Z-Score Anomaly Detection
|
|
268
|
+
|
|
269
|
+
```sql
|
|
270
|
+
WITH stats AS (
|
|
271
|
+
SELECT
|
|
272
|
+
sensor_id,
|
|
273
|
+
AVG(value) as avg_val,
|
|
274
|
+
STDDEV(value) as std_val
|
|
275
|
+
FROM analytics.sensor_readings
|
|
276
|
+
WHERE partition_date >= CURRENT_DATE - INTERVAL 90 DAY
|
|
277
|
+
GROUP BY sensor_id
|
|
278
|
+
)
|
|
279
|
+
SELECT
|
|
280
|
+
r.time,
|
|
281
|
+
r.sensor_id,
|
|
282
|
+
r.value,
|
|
283
|
+
(r.value - s.avg_val) / NULLIF(s.std_val, 0) as z_score,
|
|
284
|
+
CASE
|
|
285
|
+
WHEN ABS(r.value - s.avg_val) > 3 * s.std_val THEN 'ANOMALY'
|
|
286
|
+
WHEN ABS(r.value - s.avg_val) > 2 * s.std_val THEN 'WARNING'
|
|
287
|
+
ELSE 'NORMAL'
|
|
288
|
+
END as status
|
|
289
|
+
FROM analytics.sensor_readings r
|
|
290
|
+
JOIN stats s ON s.sensor_id = r.sensor_id
|
|
291
|
+
WHERE r.partition_date >= CURRENT_DATE - INTERVAL 7 DAY
|
|
292
|
+
AND ABS(r.value - s.avg_val) > 2 * s.std_val;
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Correlation Analysis
|
|
296
|
+
|
|
297
|
+
```sql
|
|
298
|
+
SELECT
|
|
299
|
+
sensor_name,
|
|
300
|
+
CORR(temperature, gas_flow) as temp_gas_correlation,
|
|
301
|
+
COUNT(*) as samples
|
|
302
|
+
FROM analytics.readings
|
|
303
|
+
WHERE partition_date >= CURRENT_DATE - INTERVAL 30 DAY
|
|
304
|
+
GROUP BY sensor_name
|
|
305
|
+
HAVING COUNT(*) > 100;
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Window Functions
|
|
309
|
+
|
|
310
|
+
```sql
|
|
311
|
+
SELECT
|
|
312
|
+
partition_date,
|
|
313
|
+
sensor_id,
|
|
314
|
+
value,
|
|
315
|
+
-- Month cumulative
|
|
316
|
+
SUM(value) OVER (
|
|
317
|
+
PARTITION BY sensor_id, year, month
|
|
318
|
+
ORDER BY partition_date
|
|
319
|
+
) as month_cumulative,
|
|
320
|
+
-- 7-day moving average
|
|
321
|
+
AVG(value) OVER (
|
|
322
|
+
PARTITION BY sensor_id
|
|
323
|
+
ORDER BY partition_date
|
|
324
|
+
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
|
|
325
|
+
) as ma7,
|
|
326
|
+
-- Week-over-week change
|
|
327
|
+
value - LAG(value, 7) OVER (
|
|
328
|
+
PARTITION BY sensor_id ORDER BY partition_date
|
|
329
|
+
) as wow_change
|
|
330
|
+
FROM analytics.daily_agg;
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Percentiles
|
|
334
|
+
|
|
335
|
+
```sql
|
|
336
|
+
SELECT
|
|
337
|
+
sensor_name,
|
|
338
|
+
MIN(value) as min,
|
|
339
|
+
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY value) as p25,
|
|
340
|
+
PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY value) as median,
|
|
341
|
+
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY value) as p75,
|
|
342
|
+
MAX(value) as max
|
|
343
|
+
FROM analytics.sensor_readings
|
|
344
|
+
WHERE partition_date >= CURRENT_DATE - INTERVAL 30 DAY
|
|
345
|
+
GROUP BY sensor_name;
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Export to Parquet
|
|
349
|
+
|
|
350
|
+
```sql
|
|
351
|
+
-- Simple export
|
|
352
|
+
COPY (SELECT * FROM reports.monthly_kpis)
|
|
353
|
+
TO 'monthly_kpis.parquet' (FORMAT PARQUET);
|
|
354
|
+
|
|
355
|
+
-- Partitioned export
|
|
356
|
+
COPY analytics.sensor_readings
|
|
357
|
+
TO 'sensor_readings' (FORMAT PARQUET, PARTITION_BY (year, month));
|
|
358
|
+
|
|
359
|
+
-- Export to S3
|
|
360
|
+
COPY reports.daily_summary
|
|
361
|
+
TO 's3://data/reports/daily_summary.parquet' (FORMAT PARQUET);
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Python/Pandas Integration
|
|
365
|
+
|
|
366
|
+
```python
|
|
367
|
+
# Query to DataFrame
|
|
368
|
+
df = conn.execute("""
|
|
369
|
+
SELECT partition_date, sensor_id, AVG(value) as avg
|
|
370
|
+
FROM analytics.sensor_readings
|
|
371
|
+
GROUP BY partition_date, sensor_id
|
|
372
|
+
""").fetchdf()
|
|
373
|
+
|
|
374
|
+
# DataFrame to DuckDB
|
|
375
|
+
import pandas as pd
|
|
376
|
+
df = pd.DataFrame({'date': [...], 'value': [...]})
|
|
377
|
+
conn.register('temp_data', df)
|
|
378
|
+
conn.execute("INSERT INTO analytics.processed SELECT * FROM temp_data")
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## DuckDB vs TimescaleDB
|
|
382
|
+
|
|
383
|
+
| Aspect | DuckDB | TimescaleDB |
|
|
384
|
+
|--------|--------|-------------|
|
|
385
|
+
| Type | OLAP (analytical) | OLTP (transactional) |
|
|
386
|
+
| Storage | Columnar | Row-based + chunks |
|
|
387
|
+
| Inserts | Batch (slow individual) | Streaming (fast) |
|
|
388
|
+
| Queries | Massive aggregations | Point + range |
|
|
389
|
+
| Latency | Seconds | Milliseconds |
|
|
390
|
+
| Use case | Reports, BI, ML | Dashboard, alerts |
|
|
391
|
+
|
|
392
|
+
## Performance Tips
|
|
393
|
+
|
|
394
|
+
```sql
|
|
395
|
+
-- Filter early (pushdown to Parquet)
|
|
396
|
+
SELECT * FROM read_parquet('data/*.parquet')
|
|
397
|
+
WHERE year = 2024 AND month = 3; -- Good
|
|
398
|
+
|
|
399
|
+
-- Project only needed columns
|
|
400
|
+
SELECT sensor_id, AVG(value)
|
|
401
|
+
FROM read_parquet('data.parquet')
|
|
402
|
+
GROUP BY sensor_id; -- Columnar = efficient
|
|
403
|
+
|
|
404
|
+
-- Configure resources
|
|
405
|
+
SET threads = 4;
|
|
406
|
+
SET memory_limit = '4GB';
|
|
407
|
+
|
|
408
|
+
-- Analyze query plan
|
|
409
|
+
EXPLAIN ANALYZE SELECT ...;
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Quick Reference
|
|
413
|
+
|
|
414
|
+
| Task | Command |
|
|
415
|
+
|------|---------|
|
|
416
|
+
| Load Parquet | `SELECT * FROM read_parquet('file.parquet')` |
|
|
417
|
+
| Load from S3 | `SELECT * FROM read_parquet('s3://bucket/path/*.parquet')` |
|
|
418
|
+
| Export Parquet | `COPY (query) TO 'file.parquet' (FORMAT PARQUET)` |
|
|
419
|
+
| In-memory DB | `duckdb.connect(':memory:')` |
|
|
420
|
+
| Check tables | `SELECT * FROM duckdb_tables()` |
|
|
421
|
+
| Memory usage | `SELECT * FROM duckdb_memory()` |
|
|
422
|
+
|
|
423
|
+
## Resources
|
|
424
|
+
|
|
425
|
+
- [DuckDB Documentation](https://duckdb.org/docs/)
|
|
426
|
+
- [go-duckdb](https://github.com/marcboeker/go-duckdb)
|
|
427
|
+
- [DuckDB Python API](https://duckdb.org/docs/api/python/overview)
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Changelog
|
|
432
|
+
|
|
433
|
+
- **2.0** - Condensed from Plataforma Industrial SKILL-DUCKDB
|
|
434
|
+
|
|
435
|
+
## Related Skills
|
|
436
|
+
|
|
437
|
+
- `timescaledb`: Time-series source data
|
|
438
|
+
- `scikit-learn`: ML data preparation
|
|
439
|
+
- `powerbi`: BI visualization
|
|
440
|
+
- `sqlite-embedded`: Embedded alternative
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: langchain
|
|
3
|
+
description: >
|
|
4
|
+
Build LLM applications with chains, agents, and RAG using LangChain and LangGraph.
|
|
5
|
+
Trigger: langchain, llm app, agent, rag, chains, langgraph
|
|
6
|
+
tools:
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- Bash
|
|
10
|
+
- Grep
|
|
11
|
+
metadata:
|
|
12
|
+
author: plataforma-industrial
|
|
13
|
+
version: "2.0"
|
|
14
|
+
tags: [langchain, llm, agents, rag, ai]
|
|
15
|
+
updated: "2026-02"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# LangChain Skill
|
|
19
|
+
|
|
20
|
+
Build LLM-powered applications with chains, agents, RAG, and streaming.
|
|
21
|
+
|
|
22
|
+
## Stack
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
langchain: 0.1+
|
|
26
|
+
langchain-openai: 0.0.8+
|
|
27
|
+
langchain-community: 0.0.20+
|
|
28
|
+
langgraph: 0.0.26+
|
|
29
|
+
langsmith: 0.1+
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Project Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
src/
|
|
36
|
+
├── agents/ # LangGraph agents
|
|
37
|
+
├── chains/ # LCEL chains
|
|
38
|
+
├── prompts/ # Prompt templates
|
|
39
|
+
├── tools/ # Custom tools
|
|
40
|
+
└── vectorstore/ # RAG components
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Basic Chain with Structured Output
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from langchain_openai import ChatOpenAI
|
|
47
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
48
|
+
from langchain_core.output_parsers import PydanticOutputParser
|
|
49
|
+
from pydantic import BaseModel, Field
|
|
50
|
+
|
|
51
|
+
class Analysis(BaseModel):
|
|
52
|
+
status: str = Field(description="Status: normal, warning, critical")
|
|
53
|
+
findings: list[str] = Field(description="Key findings")
|
|
54
|
+
confidence: float = Field(description="Confidence 0-1")
|
|
55
|
+
|
|
56
|
+
def create_analysis_chain():
|
|
57
|
+
llm = ChatOpenAI(model="gpt-4-turbo-preview", temperature=0)
|
|
58
|
+
parser = PydanticOutputParser(pydantic_object=Analysis)
|
|
59
|
+
|
|
60
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
61
|
+
("system", "Analyze data.\n{format_instructions}"),
|
|
62
|
+
("human", "{input}")
|
|
63
|
+
])
|
|
64
|
+
|
|
65
|
+
chain = prompt | llm | parser
|
|
66
|
+
return chain
|
|
67
|
+
|
|
68
|
+
# Usage
|
|
69
|
+
result = await chain.ainvoke({
|
|
70
|
+
"input": data,
|
|
71
|
+
"format_instructions": parser.get_format_instructions()
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Custom Tools
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from langchain_core.tools import tool
|
|
79
|
+
import httpx
|
|
80
|
+
|
|
81
|
+
@tool
|
|
82
|
+
async def fetch_data(resource_id: str, hours: int = 24) -> str:
|
|
83
|
+
"""Fetch data for a resource.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
resource_id: The resource UUID
|
|
87
|
+
hours: Hours to look back (default 24)
|
|
88
|
+
"""
|
|
89
|
+
async with httpx.AsyncClient() as client:
|
|
90
|
+
response = await client.get(
|
|
91
|
+
f"http://api:8080/resources/{resource_id}",
|
|
92
|
+
params={"hours": hours}
|
|
93
|
+
)
|
|
94
|
+
return response.text
|
|
95
|
+
|
|
96
|
+
@tool
|
|
97
|
+
async def update_status(resource_id: str, status: str) -> str:
|
|
98
|
+
"""Update resource status."""
|
|
99
|
+
async with httpx.AsyncClient() as client:
|
|
100
|
+
response = await client.patch(
|
|
101
|
+
f"http://api:8080/resources/{resource_id}",
|
|
102
|
+
json={"status": status}
|
|
103
|
+
)
|
|
104
|
+
return "Updated" if response.status_code == 200 else f"Failed: {response.text}"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## LangGraph Agent
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from typing import TypedDict, Annotated, Sequence
|
|
111
|
+
from langchain_core.messages import BaseMessage, HumanMessage
|
|
112
|
+
from langgraph.graph import StateGraph, END
|
|
113
|
+
from langgraph.prebuilt import ToolNode
|
|
114
|
+
import operator
|
|
115
|
+
|
|
116
|
+
class AgentState(TypedDict):
|
|
117
|
+
messages: Annotated[Sequence[BaseMessage], operator.add]
|
|
118
|
+
context: dict
|
|
119
|
+
|
|
120
|
+
def create_agent(tools: list):
|
|
121
|
+
llm = ChatOpenAI(model="gpt-4-turbo-preview", temperature=0)
|
|
122
|
+
llm_with_tools = llm.bind_tools(tools)
|
|
123
|
+
|
|
124
|
+
def agent_node(state: AgentState):
|
|
125
|
+
system_message = f"Context: {state['context']}"
|
|
126
|
+
response = llm_with_tools.invoke([
|
|
127
|
+
{"role": "system", "content": system_message},
|
|
128
|
+
*state["messages"]
|
|
129
|
+
])
|
|
130
|
+
return {"messages": [response]}
|
|
131
|
+
|
|
132
|
+
def should_continue(state: AgentState):
|
|
133
|
+
last_message = state["messages"][-1]
|
|
134
|
+
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
|
|
135
|
+
return "tools"
|
|
136
|
+
return END
|
|
137
|
+
|
|
138
|
+
workflow = StateGraph(AgentState)
|
|
139
|
+
workflow.add_node("agent", agent_node)
|
|
140
|
+
workflow.add_node("tools", ToolNode(tools))
|
|
141
|
+
workflow.set_entry_point("agent")
|
|
142
|
+
workflow.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})
|
|
143
|
+
workflow.add_edge("tools", "agent")
|
|
144
|
+
|
|
145
|
+
return workflow.compile()
|
|
146
|
+
|
|
147
|
+
# Usage
|
|
148
|
+
agent = create_agent([fetch_data, update_status])
|
|
149
|
+
result = await agent.ainvoke({
|
|
150
|
+
"messages": [HumanMessage(content="Check resource status")],
|
|
151
|
+
"context": {"user_id": "123"}
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## RAG Chain
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from langchain_openai import OpenAIEmbeddings
|
|
159
|
+
from langchain_community.vectorstores import Chroma
|
|
160
|
+
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
161
|
+
from langchain_core.runnables import RunnablePassthrough
|
|
162
|
+
|
|
163
|
+
def create_rag_chain(vectorstore):
|
|
164
|
+
llm = ChatOpenAI(model="gpt-4-turbo-preview", temperature=0)
|
|
165
|
+
retriever = vectorstore.as_retriever(search_type="mmr", search_kwargs={"k": 5})
|
|
166
|
+
|
|
167
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
168
|
+
("system", "Answer using context:\n{context}"),
|
|
169
|
+
("human", "{question}")
|
|
170
|
+
])
|
|
171
|
+
|
|
172
|
+
def format_docs(docs):
|
|
173
|
+
return "\n\n".join(doc.page_content for doc in docs)
|
|
174
|
+
|
|
175
|
+
chain = (
|
|
176
|
+
{"context": retriever | format_docs, "question": RunnablePassthrough()}
|
|
177
|
+
| prompt
|
|
178
|
+
| llm
|
|
179
|
+
)
|
|
180
|
+
return chain
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Streaming Response (FastAPI)
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from fastapi import APIRouter
|
|
187
|
+
from fastapi.responses import StreamingResponse
|
|
188
|
+
|
|
189
|
+
router = APIRouter()
|
|
190
|
+
|
|
191
|
+
@router.post("/chat/stream")
|
|
192
|
+
async def chat_stream(request: ChatRequest):
|
|
193
|
+
llm = ChatOpenAI(model="gpt-4-turbo-preview", streaming=True)
|
|
194
|
+
prompt = ChatPromptTemplate.from_messages([
|
|
195
|
+
("system", "You are a helpful assistant."),
|
|
196
|
+
("human", "{message}")
|
|
197
|
+
])
|
|
198
|
+
chain = prompt | llm
|
|
199
|
+
|
|
200
|
+
async def generate():
|
|
201
|
+
async for chunk in chain.astream({"message": request.message}):
|
|
202
|
+
if chunk.content:
|
|
203
|
+
yield f"data: {chunk.content}\n\n"
|
|
204
|
+
yield "data: [DONE]\n\n"
|
|
205
|
+
|
|
206
|
+
return StreamingResponse(generate(), media_type="text/event-stream")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## LangSmith Tracing
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
import os
|
|
213
|
+
from langsmith import Client
|
|
214
|
+
|
|
215
|
+
def setup_langsmith():
|
|
216
|
+
os.environ["LANGCHAIN_TRACING_V2"] = "true"
|
|
217
|
+
os.environ["LANGCHAIN_PROJECT"] = "my-project"
|
|
218
|
+
os.environ["LANGCHAIN_API_KEY"] = os.getenv("LANGSMITH_API_KEY")
|
|
219
|
+
|
|
220
|
+
# Add feedback
|
|
221
|
+
async def log_feedback(run_id: str, score: float):
|
|
222
|
+
Client().create_feedback(run_id=run_id, key="user-rating", score=score)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Best Practices
|
|
226
|
+
|
|
227
|
+
1. **Use structured outputs** - PydanticOutputParser for reliable parsing
|
|
228
|
+
2. **Async operations** - Always use `ainvoke`, `astream` for I/O
|
|
229
|
+
3. **Error handling** - Use RunnableConfig with retries and timeouts
|
|
230
|
+
4. **Cache embeddings** - CacheBackedEmbeddings for repeated queries
|
|
231
|
+
5. **Tracing** - Enable LangSmith for debugging and monitoring
|
|
232
|
+
|
|
233
|
+
## Related Skills
|
|
234
|
+
|
|
235
|
+
- `ai-ml`: Full AI/ML patterns
|
|
236
|
+
- `vector-db`: RAG with vector stores
|
|
237
|
+
- `fastapi`: API integration
|
|
238
|
+
- `redis-cache`: LLM response caching
|