sinapse-ai 1.7.0 → 1.9.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/.claude/CLAUDE.md +5 -11
- package/.claude/hooks/README.md +14 -1
- package/.claude/hooks/code-intel-pretool.cjs +115 -0
- package/.claude/hooks/enforce-delegation.cjs +31 -3
- package/.claude/hooks/enforce-framework-boundary.cjs +324 -0
- package/.claude/hooks/enforce-permission-mode.cjs +249 -0
- package/.claude/hooks/mind-clone-governance.py +212 -212
- package/.claude/hooks/read-protection.py +152 -152
- package/.claude/hooks/secret-scanning.cjs +34 -43
- package/.claude/hooks/slug-validation.py +175 -175
- package/.claude/hooks/sql-governance.py +183 -183
- package/.claude/hooks/synapse-engine.cjs +23 -23
- package/.claude/hooks/telemetry-post-tool.cjs +128 -0
- package/.claude/hooks/telemetry-stop.cjs +132 -0
- package/.claude/hooks/verify-packages.cjs +9 -2
- package/.claude/rules/documentation-first.md +1 -1
- package/.claude/rules/hook-governance.md +3 -1
- package/.claude/rules/project-intelligence.md +1 -1
- package/.codex/agents/analyst.md +4 -371
- package/.codex/agents/animations-orqx.md +4 -57
- package/.codex/agents/architect.md +4 -560
- package/.codex/agents/brand-orqx.md +4 -95
- package/.codex/agents/claude-mastery-chief.md +4 -0
- package/.codex/agents/cloning-orqx.md +4 -70
- package/.codex/agents/commercial-orqx.md +4 -67
- package/.codex/agents/config-engineer.md +2 -2
- package/.codex/agents/content-orqx.md +4 -77
- package/.codex/agents/copy-orqx.md +4 -65
- package/.codex/agents/cost-optimizer.md +4 -0
- package/.codex/agents/council-orqx.md +4 -68
- package/.codex/agents/courses-orqx.md +4 -64
- package/.codex/agents/cro-persuasion.md +4 -0
- package/.codex/agents/cyber-orqx.md +4 -67
- package/.codex/agents/data-engineer.md +4 -542
- package/.codex/agents/design-orqx.md +4 -65
- package/.codex/agents/design-system.md +4 -210
- package/.codex/agents/developer.md +4 -666
- package/.codex/agents/devops.md +4 -668
- package/.codex/agents/finance-orqx.md +4 -57
- package/.codex/agents/fiscal-compliance-br.md +4 -0
- package/.codex/agents/forecast-strategist.md +4 -0
- package/.codex/agents/growth-orqx.md +4 -75
- package/.codex/agents/hooks-architect.md +2 -2
- package/.codex/agents/mcp-integrator.md +2 -2
- package/.codex/agents/paidmedia-orqx.md +4 -67
- package/.codex/agents/platform-aesthetic-director.md +4 -0
- package/.codex/agents/premium-packaging-strategist.md +4 -0
- package/.codex/agents/product-lead.md +4 -371
- package/.codex/agents/product-orqx.md +4 -57
- package/.codex/agents/product-surface-director.md +4 -0
- package/.codex/agents/project-integrator.md +2 -2
- package/.codex/agents/project-lead.md +4 -414
- package/.codex/agents/quality-gate.md +4 -547
- package/.codex/agents/research-orqx.md +4 -67
- package/.codex/agents/roadmap-sentinel.md +2 -2
- package/.codex/agents/skill-craftsman.md +2 -2
- package/.codex/agents/snps-orqx.md +4 -684
- package/.codex/agents/sop-extractor.md +4 -61
- package/.codex/agents/sprint-lead.md +4 -324
- package/.codex/agents/squad-creator.md +4 -402
- package/.codex/agents/storytelling-orqx.md +4 -65
- package/.codex/agents/swarm-orqx.md +4 -64
- package/.codex/agents/ux-design-expert.md +4 -532
- package/.codex/agents/ux-designer.md +4 -124
- package/.codex/command-registry.json +9 -9
- package/.codex/delegation-matrix.json +373 -838
- package/.codex/delegation-parity.json +657 -0
- package/.codex/handoff-packet.parity.schema.json +148 -0
- package/.codex/handoff-packet.template.json +26 -0
- package/.codex/instructions.md +6 -6
- package/.codex/scripts/resolve-codex-agent.js +482 -0
- package/.codex/scripts/resolve-codex-command.js +75 -12
- package/.codex/scripts/resolve-codex-delegation.js +131 -92
- package/.codex/skills/sinapse-claude/SKILL.md +3 -3
- package/.codex/skills/sinapse-po/SKILL.md +1 -1
- package/.codex/tasks/resolve-sinapse-conflict.md +1 -1
- package/.sinapse-ai/cli/commands/health/index.js +24 -0
- package/.sinapse-ai/constitution.md +5 -5
- package/.sinapse-ai/core/README.md +11 -0
- package/.sinapse-ai/core/config/config-loader.js +19 -0
- package/.sinapse-ai/core/doctor/checks/git-hooks.js +97 -19
- package/.sinapse-ai/core/events/dashboard-emitter.js +30 -9
- package/.sinapse-ai/core/execution/build-orchestrator.js +4 -1
- package/.sinapse-ai/core/execution/parallel-executor.js +7 -1
- package/.sinapse-ai/core/execution/subagent-dispatcher.js +126 -28
- package/.sinapse-ai/core/execution/wave-executor.js +4 -1
- package/.sinapse-ai/core/grounding/README.md +71 -11
- package/.sinapse-ai/core/health-check/checks/project/framework-config.js +38 -2
- package/.sinapse-ai/core/health-check/checks/project/package-json.js +47 -3
- package/.sinapse-ai/core/health-check/checks/services/gemini-cli.js +117 -0
- package/.sinapse-ai/core/health-check/checks/services/index.js +2 -0
- package/.sinapse-ai/core/health-check/healers/index.js +40 -3
- package/.sinapse-ai/core/ideation/ideation-engine.js +170 -121
- package/.sinapse-ai/core/ids/gate-evaluator.js +318 -0
- package/.sinapse-ai/core/ids/gates/g5-semantic-handshake.js +190 -0
- package/.sinapse-ai/core/ids/gates/g6-ci-integrity.js +162 -0
- package/.sinapse-ai/core/ids/index.js +30 -0
- package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +11 -0
- package/.sinapse-ai/core/orchestration/agent-invoker.js +29 -6
- package/.sinapse-ai/core/orchestration/brownfield-handler.js +36 -3
- package/.sinapse-ai/core/orchestration/executors/epic-3-executor.js +76 -5
- package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +63 -17
- package/.sinapse-ai/core/orchestration/executors/epic-6-executor.js +153 -41
- package/.sinapse-ai/core/orchestration/executors/epic-executor.js +40 -0
- package/.sinapse-ai/core/orchestration/greenfield-handler.js +87 -3
- package/.sinapse-ai/core/orchestration/master-orchestrator.js +105 -7
- package/.sinapse-ai/core/orchestration/parallel-executor.js +6 -1
- package/.sinapse-ai/core/orchestration/workflow-executor.js +41 -0
- package/.sinapse-ai/core/registry/squad-agent-resolver.js +253 -0
- package/.sinapse-ai/core/telemetry/ids-sink.js +188 -0
- package/.sinapse-ai/core/ui/observability-panel.js +240 -0
- package/.sinapse-ai/core/utils/output-formatter.js +8 -290
- package/.sinapse-ai/core-config.yaml +29 -1
- package/.sinapse-ai/data/entity-registry.yaml +15056 -13761
- package/.sinapse-ai/development/agents/developer.md +2 -0
- package/.sinapse-ai/development/agents/devops.md +9 -0
- package/.sinapse-ai/development/agents/snps-orqx.md +12 -22
- package/.sinapse-ai/development/external-executors/README.md +18 -0
- package/.sinapse-ai/development/external-executors/codex.md +56 -0
- package/.sinapse-ai/development/scripts/populate-entity-registry.js +65 -9
- package/.sinapse-ai/development/scripts/squad/squad-downloader.js +54 -11
- package/.sinapse-ai/development/tasks/build-autonomous.md +11 -1
- package/.sinapse-ai/development/tasks/build-resume.md +8 -0
- package/.sinapse-ai/development/tasks/build-status.md +8 -0
- package/.sinapse-ai/development/tasks/build.md +8 -0
- package/.sinapse-ai/development/tasks/cleanup-worktrees.md +8 -1
- package/.sinapse-ai/development/tasks/delegate-to-external-executor.md +152 -0
- package/.sinapse-ai/development/tasks/github-devops-pre-push-quality-gate.md +46 -29
- package/.sinapse-ai/development/tasks/gotcha.md +8 -0
- package/.sinapse-ai/development/tasks/gotchas.md +8 -0
- package/.sinapse-ai/development/tasks/ids-health.md +14 -6
- package/.sinapse-ai/development/tasks/list-mcps.md +15 -0
- package/.sinapse-ai/development/tasks/merge-worktree.md +8 -1
- package/.sinapse-ai/development/tasks/qa-review-build.md +18 -0
- package/.sinapse-ai/development/tasks/remove-mcp.md +8 -1
- package/.sinapse-ai/development/tasks/update-sinapse.md +3 -3
- package/.sinapse-ai/development/tasks/validate-agents.md +26 -14
- package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
- package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
- package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
- package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
- package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
- package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
- package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
- package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
- package/.sinapse-ai/git-hooks/lib/framework-guard.js +258 -0
- package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +283 -0
- package/.sinapse-ai/git-hooks/lib/staged-secret-scan.js +179 -0
- package/.sinapse-ai/git-hooks/lib/staged-sql-guard.js +204 -0
- package/.sinapse-ai/git-hooks/post-commit +28 -0
- package/.sinapse-ai/git-hooks/pre-commit +81 -0
- package/.sinapse-ai/git-hooks/pre-push +77 -0
- package/.sinapse-ai/hooks/ids-post-commit.js +13 -11
- package/.sinapse-ai/hooks/ids-pre-push.js +9 -7
- package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +4 -7
- package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +4 -7
- package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +4 -7
- package/.sinapse-ai/infrastructure/integrations/ai-providers/ai-provider-factory.js +4 -1
- package/.sinapse-ai/infrastructure/integrations/ai-providers/claude-provider.js +57 -55
- package/.sinapse-ai/infrastructure/scripts/codex-parity/resolve.js +161 -0
- package/.sinapse-ai/infrastructure/scripts/dashboard-status-writer.js +6 -2
- package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +139 -21
- package/.sinapse-ai/infrastructure/scripts/ide-sync/persona-renderer.js +97 -0
- package/.sinapse-ai/infrastructure/scripts/sync-codex-local-first.js +156 -1
- package/.sinapse-ai/infrastructure/scripts/validate-codex-delegation.js +1 -4
- package/.sinapse-ai/infrastructure/scripts/validate-codex-integration.js +41 -5
- package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
- package/.sinapse-ai/infrastructure/templates/config/env.example +16 -16
- package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -59
- package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -12
- package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
- package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
- package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
- package/.sinapse-ai/infrastructure/templates/safe-collab/CODEOWNERS.template +16 -16
- package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
- package/.sinapse-ai/install-manifest.yaml +239 -223
- package/.sinapse-ai/local-config.yaml.template +65 -65
- package/.sinapse-ai/product/templates/adr.hbs +126 -126
- package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
- package/.sinapse-ai/product/templates/epic.hbs +213 -213
- package/.sinapse-ai/product/templates/ide-rules/codex-rules.md +30 -0
- package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
- package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
- package/.sinapse-ai/product/templates/prd.hbs +202 -202
- package/.sinapse-ai/product/templates/statusline/statusline-script.js +31 -8
- package/.sinapse-ai/product/templates/statusline/track-agent-clear.cjs +79 -0
- package/.sinapse-ai/product/templates/statusline/track-agent.cjs +218 -0
- package/.sinapse-ai/product/templates/story.hbs +264 -264
- package/.sinapse-ai/product/templates/task.hbs +171 -171
- package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
- package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
- package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
- package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
- package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
- package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
- package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
- package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
- package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
- package/.sinapse-ai/scripts/pm.sh +18 -6
- package/AGENTS.md +193 -0
- package/LICENSE +63 -63
- package/README.en.md +17 -18
- package/README.md +18 -19
- package/bin/cli.js +18 -1
- package/bin/commands/agents.js +96 -0
- package/bin/commands/doctor.js +15 -0
- package/bin/commands/ideate.js +129 -0
- package/bin/commands/install.js +194 -22
- package/bin/commands/status.js +14 -1
- package/bin/commands/uninstall.js +40 -0
- package/bin/commands/update.js +52 -0
- package/bin/lib/setup-statusline.js +191 -0
- package/bin/postinstall.js +50 -4
- package/bin/sinapse-init.js +11 -83
- package/bin/sinapse.js +146 -2
- package/bin/utils/framework-guard.js +17 -4
- package/bin/utils/secret-scanner-core.js +283 -0
- package/bin/utils/staged-secret-scan.js +106 -40
- package/bin/utils/staged-sql-guard.js +204 -0
- package/bin/utils/validate-publish.js +63 -0
- package/docs/agent-reference-guide.md +4 -6
- package/docs/framework/agent-prefix-convention.md +58 -0
- package/docs/framework/collaboration-activation.md +45 -0
- package/docs/security/overview.md +1 -1
- package/package.json +16 -8
- package/packages/installer/src/index.js +26 -0
- package/packages/installer/src/installer/git-hooks-installer.js +546 -0
- package/packages/installer/src/installer/sinapse-ai-installer.js +87 -0
- package/packages/installer/src/wizard/feedback.js +1 -1
- package/packages/installer/src/wizard/ide-config-generator.js +40 -25
- package/packages/installer/src/wizard/index.js +50 -0
- package/packages/installer/src/wizard/validators.js +38 -1
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +24 -1
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +42 -3
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +10 -4
- package/packages/installer/tests/unit/git-hooks-installer.test.js +262 -0
- package/packages/sinapse-install/bin/edmcp.js +0 -0
- package/packages/sinapse-install/bin/sinapse-install.js +0 -0
- package/scripts/audit-tasks.cjs +112 -91
- package/scripts/check-markdown-links.py +352 -352
- package/scripts/eval-runner.js +422 -0
- package/scripts/generate-install-manifest.js +13 -9
- package/scripts/generate-synapse-runtime.js +51 -0
- package/scripts/prepare-hooks.js +58 -0
- package/scripts/regenerate-orqx-stubs.ps1 +2 -2
- package/scripts/validate-agents-md.js +128 -0
- package/scripts/validate-all.js +2 -0
- package/scripts/validate-evals.js +466 -0
- package/scripts/validate-schemas.js +539 -0
- package/scripts/validate-squad-orqx.js +9 -2
- package/sinapse/agents/sinapse-orqx.md +12 -22
- package/sinapse/agents/snps-orqx.md +11 -21
- package/squads/claude-code-mastery/squad.yaml +8 -0
- package/squads/squad-animations/squad.yaml +1 -1
- package/squads/squad-brand/squad.yaml +1 -1
- package/squads/squad-cloning/squad.yaml +1 -1
- package/squads/squad-commercial/squad.yaml +2 -3
- package/squads/squad-content/squad.yaml +1 -1
- package/squads/squad-copy/squad.yaml +2 -3
- package/squads/squad-courses/squad.yaml +1 -1
- package/squads/squad-cybersecurity/squad.yaml +2 -3
- package/squads/{squad-artdir → squad-design}/agents/cro-persuasion.md +1 -1
- package/squads/{squad-artdir → squad-design}/agents/platform-aesthetic-director.md +2 -2
- package/squads/{squad-artdir → squad-design}/agents/premium-packaging-strategist.md +2 -2
- package/squads/{squad-artdir → squad-design}/agents/product-surface-director.md +3 -3
- package/squads/squad-design/squad.yaml +6 -3
- package/squads/squad-finance/squad.yaml +7 -1
- package/squads/squad-growth/squad.yaml +1 -1
- package/squads/squad-paidmedia/squad.yaml +2 -3
- package/squads/squad-product/squad.yaml +1 -1
- package/squads/squad-research/squad.yaml +2 -3
- package/squads/squad-storytelling/squad.yaml +2 -3
- package/.codex/agents/brad-frost.md +0 -46
- package/.codex/agents/claude-orqx.md +0 -72
- package/.codex/agents/copy-chief.md +0 -162
- package/.codex/agents/cyber-chief.md +0 -169
- package/.codex/agents/dan-mall.md +0 -43
- package/.codex/agents/data-chief.md +0 -198
- package/.codex/agents/dave-malouf.md +0 -43
- package/.codex/agents/db-sage.md +0 -152
- package/.codex/agents/design-chief.md +0 -226
- package/.codex/agents/dev.md +0 -102
- package/.codex/agents/legal-chief.md +0 -199
- package/.codex/agents/nano-banana-generator.md +0 -42
- package/.codex/agents/pm.md +0 -81
- package/.codex/agents/po.md +0 -85
- package/.codex/agents/qa.md +0 -98
- package/.codex/agents/sm.md +0 -77
- package/.codex/agents/squad-chief.md +0 -1553
- package/.codex/agents/squad.md +0 -66
- package/.codex/agents/story-chief.md +0 -180
- package/.codex/agents/tools-orqx.md +0 -219
- package/.codex/agents/traffic-masters-chief.md +0 -211
- package/.sinapse-ai/data/registry-update-log.jsonl +0 -72
- package/.sinapse-ai/development/scripts/elicitation-engine.js +0 -385
- package/.sinapse-ai/development/scripts/elicitation-session-manager.js +0 -300
- package/.sinapse-ai/development/tasks/test-validation-task.md +0 -172
- package/.sinapse-ai/monitor/hooks/lib/__init__.py +0 -2
- package/.sinapse-ai/monitor/hooks/lib/enrich.py +0 -59
- package/.sinapse-ai/monitor/hooks/lib/send_event.py +0 -48
- package/.sinapse-ai/monitor/hooks/notification.py +0 -30
- package/.sinapse-ai/monitor/hooks/post_tool_use.py +0 -46
- package/.sinapse-ai/monitor/hooks/pre_compact.py +0 -30
- package/.sinapse-ai/monitor/hooks/pre_tool_use.py +0 -41
- package/.sinapse-ai/monitor/hooks/stop.py +0 -30
- package/.sinapse-ai/monitor/hooks/subagent_stop.py +0 -30
- package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +0 -39
- package/.sinapse-ai/product/templates/statusline/track-agent.sh +0 -69
- package/bin/sinapse-graph.js +0 -19
- package/docs/codex-integration-process.md +0 -22
- package/docs/codex-parity-program.md +0 -27
- package/scripts/install-monitor-hooks.sh +0 -82
- package/squads/squad-artdir/README.md +0 -90
- package/squads/squad-artdir/agents/accessibility-guardian.md +0 -184
- package/squads/squad-artdir/agents/artdir-orqx.md +0 -222
- package/squads/squad-artdir/agents/color-psychologist.md +0 -166
- package/squads/squad-artdir/agents/design-system-architect.md +0 -100
- package/squads/squad-artdir/agents/ia-architect.md +0 -169
- package/squads/squad-artdir/agents/interaction-designer.md +0 -162
- package/squads/squad-artdir/agents/layout-engineer.md +0 -163
- package/squads/squad-artdir/agents/motion-architect.md +0 -185
- package/squads/squad-artdir/agents/type-systemist.md +0 -138
- package/squads/squad-artdir/agents/visual-strategist.md +0 -127
- package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +0 -172
- package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +0 -289
- package/squads/squad-artdir/knowledge-base/deliverables-templates.md +0 -457
- package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +0 -247
- package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +0 -133
- package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +0 -229
- package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +0 -242
- package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +0 -289
- package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +0 -221
- package/squads/squad-artdir/package.json +0 -20
- package/squads/squad-artdir/squad.yaml +0 -299
- package/squads/squad-artdir/tasks/audit-conversion.md +0 -97
- package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +0 -55
- package/squads/squad-artdir/tasks/consult-saas-canon.md +0 -54
- package/squads/squad-artdir/tasks/create-art-direction-brief.md +0 -110
- package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +0 -61
- package/squads/squad-artdir/tasks/create-wireflow.md +0 -84
- package/squads/squad-artdir/tasks/design-color-system.md +0 -81
- package/squads/squad-artdir/tasks/design-product-surface.md +0 -60
- package/squads/squad-artdir/tasks/design-token-system.md +0 -58
- package/squads/squad-artdir/tasks/diagnose-visual-language.md +0 -92
- package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +0 -65
- package/squads/squad-artdir/tasks/specify-motion-system.md +0 -84
- package/squads/squad-artdir/tasks/validate-against-pillars.md +0 -143
- package/squads/squad-artdir/templates/art-direction-brief-template.md +0 -215
- package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +0 -142
- package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +0 -179
- package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +0 -338
- package/squads/squad-commercial/agents/legal-chief.md +0 -199
- package/squads/squad-copy/agents/copy-chief.md +0 -162
- package/squads/squad-cybersecurity/agents/cyber-chief.md +0 -169
- package/squads/squad-design/agents/design-chief.md +0 -226
- package/squads/squad-paidmedia/agents/traffic-masters-chief.md +0 -211
- package/squads/squad-research/agents/data-chief.md +0 -198
- package/squads/squad-storytelling/agents/story-chief.md +0 -180
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
-- Materialized View Template
|
|
2
|
-
-- View: :view_name
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
-- Author: :author
|
|
5
|
-
-- Description: :description
|
|
6
|
-
--
|
|
7
|
-
-- Materialized views cache query results for performance
|
|
8
|
-
-- IMPORTANT: Data is not live - must be refreshed periodically
|
|
9
|
-
|
|
10
|
-
-- =============================================================================
|
|
11
|
-
-- BASIC MATERIALIZED VIEW
|
|
12
|
-
-- =============================================================================
|
|
13
|
-
|
|
14
|
-
-- Drop existing view if exists
|
|
15
|
-
DROP MATERIALIZED VIEW IF EXISTS :view_name CASCADE;
|
|
16
|
-
|
|
17
|
-
-- Create materialized view
|
|
18
|
-
CREATE MATERIALIZED VIEW :view_name AS
|
|
19
|
-
SELECT
|
|
20
|
-
t.id,
|
|
21
|
-
t.name,
|
|
22
|
-
t.category,
|
|
23
|
-
t.created_at,
|
|
24
|
-
-- Aggregations
|
|
25
|
-
COUNT(r.id) AS related_count,
|
|
26
|
-
SUM(r.amount) AS total_amount,
|
|
27
|
-
AVG(r.rating) AS avg_rating,
|
|
28
|
-
-- Computed columns
|
|
29
|
-
CASE
|
|
30
|
-
WHEN t.status = 'active' THEN true
|
|
31
|
-
ELSE false
|
|
32
|
-
END AS is_active
|
|
33
|
-
FROM :base_table t
|
|
34
|
-
LEFT JOIN :related_table r ON r.parent_id = t.id
|
|
35
|
-
WHERE t.deleted_at IS NULL
|
|
36
|
-
GROUP BY t.id, t.name, t.category, t.created_at, t.status
|
|
37
|
-
-- Store data sorted for efficient access
|
|
38
|
-
WITH DATA;
|
|
39
|
-
|
|
40
|
-
-- =============================================================================
|
|
41
|
-
-- INDEXES ON MATERIALIZED VIEW
|
|
42
|
-
-- =============================================================================
|
|
43
|
-
|
|
44
|
-
-- Unique index (required for CONCURRENT refresh)
|
|
45
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_:view_name_id
|
|
46
|
-
ON :view_name (id);
|
|
47
|
-
|
|
48
|
-
-- Additional indexes for common queries
|
|
49
|
-
CREATE INDEX IF NOT EXISTS idx_:view_name_category
|
|
50
|
-
ON :view_name (category);
|
|
51
|
-
|
|
52
|
-
CREATE INDEX IF NOT EXISTS idx_:view_name_created_at
|
|
53
|
-
ON :view_name (created_at DESC);
|
|
54
|
-
|
|
55
|
-
-- =============================================================================
|
|
56
|
-
-- REFRESH FUNCTION
|
|
57
|
-
-- =============================================================================
|
|
58
|
-
|
|
59
|
-
-- Function to refresh the materialized view
|
|
60
|
-
CREATE OR REPLACE FUNCTION refresh_:view_name()
|
|
61
|
-
RETURNS void
|
|
62
|
-
LANGUAGE plpgsql
|
|
63
|
-
SECURITY DEFINER
|
|
64
|
-
AS $$
|
|
65
|
-
BEGIN
|
|
66
|
-
-- CONCURRENTLY allows queries during refresh (requires unique index)
|
|
67
|
-
REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
68
|
-
|
|
69
|
-
-- Log refresh
|
|
70
|
-
RAISE NOTICE 'Materialized view :view_name refreshed at %', NOW();
|
|
71
|
-
END;
|
|
72
|
-
$$;
|
|
73
|
-
|
|
74
|
-
-- Grant execute to service role (for scheduled refresh)
|
|
75
|
-
GRANT EXECUTE ON FUNCTION refresh_:view_name() TO service_role;
|
|
76
|
-
|
|
77
|
-
-- =============================================================================
|
|
78
|
-
-- SCHEDULED REFRESH (pg_cron)
|
|
79
|
-
-- =============================================================================
|
|
80
|
-
--
|
|
81
|
-
-- If using pg_cron extension (available in Supabase):
|
|
82
|
-
--
|
|
83
|
-
-- Enable extension (one-time, requires superuser)
|
|
84
|
-
-- CREATE EXTENSION IF NOT EXISTS pg_cron;
|
|
85
|
-
--
|
|
86
|
-
-- Schedule refresh every hour
|
|
87
|
-
-- SELECT cron.schedule(
|
|
88
|
-
-- 'refresh-:view_name',
|
|
89
|
-
-- '0 * * * *', -- Every hour at minute 0
|
|
90
|
-
-- $$SELECT refresh_:view_name()$$
|
|
91
|
-
-- );
|
|
92
|
-
--
|
|
93
|
-
-- To remove schedule:
|
|
94
|
-
-- SELECT cron.unschedule('refresh-:view_name');
|
|
95
|
-
|
|
96
|
-
-- =============================================================================
|
|
97
|
-
-- TRIGGER-BASED REFRESH (Alternative)
|
|
98
|
-
-- =============================================================================
|
|
99
|
-
|
|
100
|
-
-- Refresh when base table changes (use with caution - can be slow)
|
|
101
|
-
-- CREATE OR REPLACE FUNCTION refresh_:view_name_trigger()
|
|
102
|
-
-- RETURNS TRIGGER AS $$
|
|
103
|
-
-- BEGIN
|
|
104
|
-
-- REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
105
|
-
-- RETURN NULL;
|
|
106
|
-
-- END;
|
|
107
|
-
-- $$ LANGUAGE plpgsql;
|
|
108
|
-
--
|
|
109
|
-
-- CREATE TRIGGER trigger_refresh_:view_name
|
|
110
|
-
-- AFTER INSERT OR UPDATE OR DELETE ON :base_table
|
|
111
|
-
-- FOR EACH STATEMENT
|
|
112
|
-
-- EXECUTE FUNCTION refresh_:view_name_trigger();
|
|
113
|
-
|
|
114
|
-
-- =============================================================================
|
|
115
|
-
-- VIEW METADATA
|
|
116
|
-
-- =============================================================================
|
|
117
|
-
|
|
118
|
-
COMMENT ON MATERIALIZED VIEW :view_name IS ':description. Refresh: hourly or on-demand.';
|
|
119
|
-
|
|
120
|
-
-- =============================================================================
|
|
121
|
-
-- USAGE
|
|
122
|
-
-- =============================================================================
|
|
123
|
-
--
|
|
124
|
-
-- Query the view (cached data, very fast):
|
|
125
|
-
-- SELECT * FROM :view_name WHERE category = 'example';
|
|
126
|
-
--
|
|
127
|
-
-- Manual refresh (use during low-traffic periods):
|
|
128
|
-
-- REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
129
|
-
-- OR
|
|
130
|
-
-- SELECT refresh_:view_name();
|
|
131
|
-
--
|
|
132
|
-
-- Check last refresh time (approximate):
|
|
133
|
-
-- SELECT pg_stat_get_last_analyze_time(':view_name'::regclass);
|
|
134
|
-
|
|
1
|
+
-- Materialized View Template
|
|
2
|
+
-- View: :view_name
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
-- Author: :author
|
|
5
|
+
-- Description: :description
|
|
6
|
+
--
|
|
7
|
+
-- Materialized views cache query results for performance
|
|
8
|
+
-- IMPORTANT: Data is not live - must be refreshed periodically
|
|
9
|
+
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
-- BASIC MATERIALIZED VIEW
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
|
|
14
|
+
-- Drop existing view if exists
|
|
15
|
+
DROP MATERIALIZED VIEW IF EXISTS :view_name CASCADE;
|
|
16
|
+
|
|
17
|
+
-- Create materialized view
|
|
18
|
+
CREATE MATERIALIZED VIEW :view_name AS
|
|
19
|
+
SELECT
|
|
20
|
+
t.id,
|
|
21
|
+
t.name,
|
|
22
|
+
t.category,
|
|
23
|
+
t.created_at,
|
|
24
|
+
-- Aggregations
|
|
25
|
+
COUNT(r.id) AS related_count,
|
|
26
|
+
SUM(r.amount) AS total_amount,
|
|
27
|
+
AVG(r.rating) AS avg_rating,
|
|
28
|
+
-- Computed columns
|
|
29
|
+
CASE
|
|
30
|
+
WHEN t.status = 'active' THEN true
|
|
31
|
+
ELSE false
|
|
32
|
+
END AS is_active
|
|
33
|
+
FROM :base_table t
|
|
34
|
+
LEFT JOIN :related_table r ON r.parent_id = t.id
|
|
35
|
+
WHERE t.deleted_at IS NULL
|
|
36
|
+
GROUP BY t.id, t.name, t.category, t.created_at, t.status
|
|
37
|
+
-- Store data sorted for efficient access
|
|
38
|
+
WITH DATA;
|
|
39
|
+
|
|
40
|
+
-- =============================================================================
|
|
41
|
+
-- INDEXES ON MATERIALIZED VIEW
|
|
42
|
+
-- =============================================================================
|
|
43
|
+
|
|
44
|
+
-- Unique index (required for CONCURRENT refresh)
|
|
45
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_:view_name_id
|
|
46
|
+
ON :view_name (id);
|
|
47
|
+
|
|
48
|
+
-- Additional indexes for common queries
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_:view_name_category
|
|
50
|
+
ON :view_name (category);
|
|
51
|
+
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_:view_name_created_at
|
|
53
|
+
ON :view_name (created_at DESC);
|
|
54
|
+
|
|
55
|
+
-- =============================================================================
|
|
56
|
+
-- REFRESH FUNCTION
|
|
57
|
+
-- =============================================================================
|
|
58
|
+
|
|
59
|
+
-- Function to refresh the materialized view
|
|
60
|
+
CREATE OR REPLACE FUNCTION refresh_:view_name()
|
|
61
|
+
RETURNS void
|
|
62
|
+
LANGUAGE plpgsql
|
|
63
|
+
SECURITY DEFINER
|
|
64
|
+
AS $$
|
|
65
|
+
BEGIN
|
|
66
|
+
-- CONCURRENTLY allows queries during refresh (requires unique index)
|
|
67
|
+
REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
68
|
+
|
|
69
|
+
-- Log refresh
|
|
70
|
+
RAISE NOTICE 'Materialized view :view_name refreshed at %', NOW();
|
|
71
|
+
END;
|
|
72
|
+
$$;
|
|
73
|
+
|
|
74
|
+
-- Grant execute to service role (for scheduled refresh)
|
|
75
|
+
GRANT EXECUTE ON FUNCTION refresh_:view_name() TO service_role;
|
|
76
|
+
|
|
77
|
+
-- =============================================================================
|
|
78
|
+
-- SCHEDULED REFRESH (pg_cron)
|
|
79
|
+
-- =============================================================================
|
|
80
|
+
--
|
|
81
|
+
-- If using pg_cron extension (available in Supabase):
|
|
82
|
+
--
|
|
83
|
+
-- Enable extension (one-time, requires superuser)
|
|
84
|
+
-- CREATE EXTENSION IF NOT EXISTS pg_cron;
|
|
85
|
+
--
|
|
86
|
+
-- Schedule refresh every hour
|
|
87
|
+
-- SELECT cron.schedule(
|
|
88
|
+
-- 'refresh-:view_name',
|
|
89
|
+
-- '0 * * * *', -- Every hour at minute 0
|
|
90
|
+
-- $$SELECT refresh_:view_name()$$
|
|
91
|
+
-- );
|
|
92
|
+
--
|
|
93
|
+
-- To remove schedule:
|
|
94
|
+
-- SELECT cron.unschedule('refresh-:view_name');
|
|
95
|
+
|
|
96
|
+
-- =============================================================================
|
|
97
|
+
-- TRIGGER-BASED REFRESH (Alternative)
|
|
98
|
+
-- =============================================================================
|
|
99
|
+
|
|
100
|
+
-- Refresh when base table changes (use with caution - can be slow)
|
|
101
|
+
-- CREATE OR REPLACE FUNCTION refresh_:view_name_trigger()
|
|
102
|
+
-- RETURNS TRIGGER AS $$
|
|
103
|
+
-- BEGIN
|
|
104
|
+
-- REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
105
|
+
-- RETURN NULL;
|
|
106
|
+
-- END;
|
|
107
|
+
-- $$ LANGUAGE plpgsql;
|
|
108
|
+
--
|
|
109
|
+
-- CREATE TRIGGER trigger_refresh_:view_name
|
|
110
|
+
-- AFTER INSERT OR UPDATE OR DELETE ON :base_table
|
|
111
|
+
-- FOR EACH STATEMENT
|
|
112
|
+
-- EXECUTE FUNCTION refresh_:view_name_trigger();
|
|
113
|
+
|
|
114
|
+
-- =============================================================================
|
|
115
|
+
-- VIEW METADATA
|
|
116
|
+
-- =============================================================================
|
|
117
|
+
|
|
118
|
+
COMMENT ON MATERIALIZED VIEW :view_name IS ':description. Refresh: hourly or on-demand.';
|
|
119
|
+
|
|
120
|
+
-- =============================================================================
|
|
121
|
+
-- USAGE
|
|
122
|
+
-- =============================================================================
|
|
123
|
+
--
|
|
124
|
+
-- Query the view (cached data, very fast):
|
|
125
|
+
-- SELECT * FROM :view_name WHERE category = 'example';
|
|
126
|
+
--
|
|
127
|
+
-- Manual refresh (use during low-traffic periods):
|
|
128
|
+
-- REFRESH MATERIALIZED VIEW CONCURRENTLY :view_name;
|
|
129
|
+
-- OR
|
|
130
|
+
-- SELECT refresh_:view_name();
|
|
131
|
+
--
|
|
132
|
+
-- Check last refresh time (approximate):
|
|
133
|
+
-- SELECT pg_stat_get_last_analyze_time(':view_name'::regclass);
|
|
134
|
+
|
|
@@ -1,178 +1,178 @@
|
|
|
1
|
-
-- View Template
|
|
2
|
-
-- View: :view_name
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
-- Author: :author
|
|
5
|
-
-- Description: :description
|
|
6
|
-
--
|
|
7
|
-
-- Views are virtual tables that provide a simplified interface
|
|
8
|
-
-- Data is always live (not cached like materialized views)
|
|
9
|
-
|
|
10
|
-
-- =============================================================================
|
|
11
|
-
-- BASIC VIEW
|
|
12
|
-
-- =============================================================================
|
|
13
|
-
|
|
14
|
-
-- Drop existing view if exists
|
|
15
|
-
DROP VIEW IF EXISTS :view_name CASCADE;
|
|
16
|
-
|
|
17
|
-
-- Create view
|
|
18
|
-
CREATE OR REPLACE VIEW :view_name AS
|
|
19
|
-
SELECT
|
|
20
|
-
t.id,
|
|
21
|
-
t.name,
|
|
22
|
-
t.description,
|
|
23
|
-
t.status,
|
|
24
|
-
t.created_at,
|
|
25
|
-
t.updated_at,
|
|
26
|
-
-- Related data
|
|
27
|
-
u.email AS owner_email,
|
|
28
|
-
u.raw_user_meta_data->>'full_name' AS owner_name,
|
|
29
|
-
-- Computed columns
|
|
30
|
-
CASE
|
|
31
|
-
WHEN t.status = 'active' THEN 'Active'
|
|
32
|
-
WHEN t.status = 'pending' THEN 'Pending'
|
|
33
|
-
WHEN t.status = 'archived' THEN 'Archived'
|
|
34
|
-
ELSE 'Unknown'
|
|
35
|
-
END AS status_label,
|
|
36
|
-
-- Age calculation
|
|
37
|
-
EXTRACT(DAY FROM NOW() - t.created_at) AS days_old
|
|
38
|
-
FROM :base_table t
|
|
39
|
-
LEFT JOIN auth.users u ON u.id = t.user_id
|
|
40
|
-
WHERE t.deleted_at IS NULL;
|
|
41
|
-
|
|
42
|
-
-- =============================================================================
|
|
43
|
-
-- VIEW WITH AGGREGATIONS
|
|
44
|
-
-- =============================================================================
|
|
45
|
-
|
|
46
|
-
CREATE OR REPLACE VIEW :view_name_summary AS
|
|
47
|
-
SELECT
|
|
48
|
-
t.category,
|
|
49
|
-
COUNT(*) AS total_count,
|
|
50
|
-
COUNT(*) FILTER (WHERE t.status = 'active') AS active_count,
|
|
51
|
-
COUNT(*) FILTER (WHERE t.status = 'pending') AS pending_count,
|
|
52
|
-
MIN(t.created_at) AS earliest,
|
|
53
|
-
MAX(t.created_at) AS latest,
|
|
54
|
-
AVG(t.value)::NUMERIC(10,2) AS avg_value
|
|
55
|
-
FROM :base_table t
|
|
56
|
-
WHERE t.deleted_at IS NULL
|
|
57
|
-
GROUP BY t.category;
|
|
58
|
-
|
|
59
|
-
-- =============================================================================
|
|
60
|
-
-- VIEW WITH RLS CONSIDERATION
|
|
61
|
-
-- =============================================================================
|
|
62
|
-
|
|
63
|
-
-- Views inherit RLS from underlying tables
|
|
64
|
-
-- If base table has RLS, view will respect it
|
|
65
|
-
--
|
|
66
|
-
-- For views that need custom RLS-like behavior,
|
|
67
|
-
-- wrap in a SECURITY DEFINER function:
|
|
68
|
-
|
|
69
|
-
CREATE OR REPLACE FUNCTION get_:view_name_for_user()
|
|
70
|
-
RETURNS TABLE (
|
|
71
|
-
id UUID,
|
|
72
|
-
name TEXT,
|
|
73
|
-
status TEXT,
|
|
74
|
-
created_at TIMESTAMPTZ
|
|
75
|
-
)
|
|
76
|
-
LANGUAGE plpgsql
|
|
77
|
-
SECURITY INVOKER
|
|
78
|
-
STABLE
|
|
79
|
-
AS $$
|
|
80
|
-
BEGIN
|
|
81
|
-
RETURN QUERY
|
|
82
|
-
SELECT
|
|
83
|
-
v.id,
|
|
84
|
-
v.name,
|
|
85
|
-
v.status,
|
|
86
|
-
v.created_at
|
|
87
|
-
FROM :view_name v
|
|
88
|
-
WHERE v.user_id = auth.uid()
|
|
89
|
-
ORDER BY v.created_at DESC;
|
|
90
|
-
END;
|
|
91
|
-
$$;
|
|
92
|
-
|
|
93
|
-
-- =============================================================================
|
|
94
|
-
-- VIEW WITH JOINED DATA
|
|
95
|
-
-- =============================================================================
|
|
96
|
-
|
|
97
|
-
CREATE OR REPLACE VIEW :view_name_detailed AS
|
|
98
|
-
SELECT
|
|
99
|
-
t.id,
|
|
100
|
-
t.name,
|
|
101
|
-
t.status,
|
|
102
|
-
-- One-to-one relationship
|
|
103
|
-
d.detail_field,
|
|
104
|
-
-- One-to-many aggregation
|
|
105
|
-
(
|
|
106
|
-
SELECT json_agg(json_build_object(
|
|
107
|
-
'id', c.id,
|
|
108
|
-
'name', c.name,
|
|
109
|
-
'created_at', c.created_at
|
|
110
|
-
))
|
|
111
|
-
FROM :child_table c
|
|
112
|
-
WHERE c.parent_id = t.id
|
|
113
|
-
) AS children,
|
|
114
|
-
-- Count
|
|
115
|
-
(
|
|
116
|
-
SELECT COUNT(*)
|
|
117
|
-
FROM :child_table c
|
|
118
|
-
WHERE c.parent_id = t.id
|
|
119
|
-
) AS children_count,
|
|
120
|
-
t.created_at,
|
|
121
|
-
t.updated_at
|
|
122
|
-
FROM :base_table t
|
|
123
|
-
LEFT JOIN :detail_table d ON d.id = t.detail_id
|
|
124
|
-
WHERE t.deleted_at IS NULL;
|
|
125
|
-
|
|
126
|
-
-- =============================================================================
|
|
127
|
-
-- UPDATEABLE VIEW (with INSTEAD OF triggers)
|
|
128
|
-
-- =============================================================================
|
|
129
|
-
|
|
130
|
-
-- Simple updateable view (for basic cases)
|
|
131
|
-
CREATE OR REPLACE VIEW :view_name_editable AS
|
|
132
|
-
SELECT
|
|
133
|
-
id,
|
|
134
|
-
name,
|
|
135
|
-
description,
|
|
136
|
-
status,
|
|
137
|
-
updated_at
|
|
138
|
-
FROM :base_table
|
|
139
|
-
WHERE deleted_at IS NULL;
|
|
140
|
-
|
|
141
|
-
-- Make it updateable via trigger
|
|
142
|
-
CREATE OR REPLACE FUNCTION :view_name_editable_update()
|
|
143
|
-
RETURNS TRIGGER AS $$
|
|
144
|
-
BEGIN
|
|
145
|
-
UPDATE :base_table
|
|
146
|
-
SET
|
|
147
|
-
name = NEW.name,
|
|
148
|
-
description = NEW.description,
|
|
149
|
-
status = NEW.status,
|
|
150
|
-
updated_at = NOW()
|
|
151
|
-
WHERE id = NEW.id
|
|
152
|
-
AND user_id = auth.uid(); -- RLS check
|
|
153
|
-
|
|
154
|
-
RETURN NEW;
|
|
155
|
-
END;
|
|
156
|
-
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
157
|
-
|
|
158
|
-
CREATE TRIGGER trigger_:view_name_editable_update
|
|
159
|
-
INSTEAD OF UPDATE ON :view_name_editable
|
|
160
|
-
FOR EACH ROW
|
|
161
|
-
EXECUTE FUNCTION :view_name_editable_update();
|
|
162
|
-
|
|
163
|
-
-- =============================================================================
|
|
164
|
-
-- VIEW METADATA
|
|
165
|
-
-- =============================================================================
|
|
166
|
-
|
|
167
|
-
COMMENT ON VIEW :view_name IS ':description';
|
|
168
|
-
|
|
169
|
-
-- =============================================================================
|
|
170
|
-
-- PERMISSIONS
|
|
171
|
-
-- =============================================================================
|
|
172
|
-
|
|
173
|
-
-- Grant SELECT on view (inherits base table RLS)
|
|
174
|
-
GRANT SELECT ON :view_name TO authenticated;
|
|
175
|
-
|
|
176
|
-
-- For updateable views, also grant UPDATE
|
|
177
|
-
-- GRANT UPDATE ON :view_name_editable TO authenticated;
|
|
178
|
-
|
|
1
|
+
-- View Template
|
|
2
|
+
-- View: :view_name
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
-- Author: :author
|
|
5
|
+
-- Description: :description
|
|
6
|
+
--
|
|
7
|
+
-- Views are virtual tables that provide a simplified interface
|
|
8
|
+
-- Data is always live (not cached like materialized views)
|
|
9
|
+
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
-- BASIC VIEW
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
|
|
14
|
+
-- Drop existing view if exists
|
|
15
|
+
DROP VIEW IF EXISTS :view_name CASCADE;
|
|
16
|
+
|
|
17
|
+
-- Create view
|
|
18
|
+
CREATE OR REPLACE VIEW :view_name AS
|
|
19
|
+
SELECT
|
|
20
|
+
t.id,
|
|
21
|
+
t.name,
|
|
22
|
+
t.description,
|
|
23
|
+
t.status,
|
|
24
|
+
t.created_at,
|
|
25
|
+
t.updated_at,
|
|
26
|
+
-- Related data
|
|
27
|
+
u.email AS owner_email,
|
|
28
|
+
u.raw_user_meta_data->>'full_name' AS owner_name,
|
|
29
|
+
-- Computed columns
|
|
30
|
+
CASE
|
|
31
|
+
WHEN t.status = 'active' THEN 'Active'
|
|
32
|
+
WHEN t.status = 'pending' THEN 'Pending'
|
|
33
|
+
WHEN t.status = 'archived' THEN 'Archived'
|
|
34
|
+
ELSE 'Unknown'
|
|
35
|
+
END AS status_label,
|
|
36
|
+
-- Age calculation
|
|
37
|
+
EXTRACT(DAY FROM NOW() - t.created_at) AS days_old
|
|
38
|
+
FROM :base_table t
|
|
39
|
+
LEFT JOIN auth.users u ON u.id = t.user_id
|
|
40
|
+
WHERE t.deleted_at IS NULL;
|
|
41
|
+
|
|
42
|
+
-- =============================================================================
|
|
43
|
+
-- VIEW WITH AGGREGATIONS
|
|
44
|
+
-- =============================================================================
|
|
45
|
+
|
|
46
|
+
CREATE OR REPLACE VIEW :view_name_summary AS
|
|
47
|
+
SELECT
|
|
48
|
+
t.category,
|
|
49
|
+
COUNT(*) AS total_count,
|
|
50
|
+
COUNT(*) FILTER (WHERE t.status = 'active') AS active_count,
|
|
51
|
+
COUNT(*) FILTER (WHERE t.status = 'pending') AS pending_count,
|
|
52
|
+
MIN(t.created_at) AS earliest,
|
|
53
|
+
MAX(t.created_at) AS latest,
|
|
54
|
+
AVG(t.value)::NUMERIC(10,2) AS avg_value
|
|
55
|
+
FROM :base_table t
|
|
56
|
+
WHERE t.deleted_at IS NULL
|
|
57
|
+
GROUP BY t.category;
|
|
58
|
+
|
|
59
|
+
-- =============================================================================
|
|
60
|
+
-- VIEW WITH RLS CONSIDERATION
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
|
|
63
|
+
-- Views inherit RLS from underlying tables
|
|
64
|
+
-- If base table has RLS, view will respect it
|
|
65
|
+
--
|
|
66
|
+
-- For views that need custom RLS-like behavior,
|
|
67
|
+
-- wrap in a SECURITY DEFINER function:
|
|
68
|
+
|
|
69
|
+
CREATE OR REPLACE FUNCTION get_:view_name_for_user()
|
|
70
|
+
RETURNS TABLE (
|
|
71
|
+
id UUID,
|
|
72
|
+
name TEXT,
|
|
73
|
+
status TEXT,
|
|
74
|
+
created_at TIMESTAMPTZ
|
|
75
|
+
)
|
|
76
|
+
LANGUAGE plpgsql
|
|
77
|
+
SECURITY INVOKER
|
|
78
|
+
STABLE
|
|
79
|
+
AS $$
|
|
80
|
+
BEGIN
|
|
81
|
+
RETURN QUERY
|
|
82
|
+
SELECT
|
|
83
|
+
v.id,
|
|
84
|
+
v.name,
|
|
85
|
+
v.status,
|
|
86
|
+
v.created_at
|
|
87
|
+
FROM :view_name v
|
|
88
|
+
WHERE v.user_id = auth.uid()
|
|
89
|
+
ORDER BY v.created_at DESC;
|
|
90
|
+
END;
|
|
91
|
+
$$;
|
|
92
|
+
|
|
93
|
+
-- =============================================================================
|
|
94
|
+
-- VIEW WITH JOINED DATA
|
|
95
|
+
-- =============================================================================
|
|
96
|
+
|
|
97
|
+
CREATE OR REPLACE VIEW :view_name_detailed AS
|
|
98
|
+
SELECT
|
|
99
|
+
t.id,
|
|
100
|
+
t.name,
|
|
101
|
+
t.status,
|
|
102
|
+
-- One-to-one relationship
|
|
103
|
+
d.detail_field,
|
|
104
|
+
-- One-to-many aggregation
|
|
105
|
+
(
|
|
106
|
+
SELECT json_agg(json_build_object(
|
|
107
|
+
'id', c.id,
|
|
108
|
+
'name', c.name,
|
|
109
|
+
'created_at', c.created_at
|
|
110
|
+
))
|
|
111
|
+
FROM :child_table c
|
|
112
|
+
WHERE c.parent_id = t.id
|
|
113
|
+
) AS children,
|
|
114
|
+
-- Count
|
|
115
|
+
(
|
|
116
|
+
SELECT COUNT(*)
|
|
117
|
+
FROM :child_table c
|
|
118
|
+
WHERE c.parent_id = t.id
|
|
119
|
+
) AS children_count,
|
|
120
|
+
t.created_at,
|
|
121
|
+
t.updated_at
|
|
122
|
+
FROM :base_table t
|
|
123
|
+
LEFT JOIN :detail_table d ON d.id = t.detail_id
|
|
124
|
+
WHERE t.deleted_at IS NULL;
|
|
125
|
+
|
|
126
|
+
-- =============================================================================
|
|
127
|
+
-- UPDATEABLE VIEW (with INSTEAD OF triggers)
|
|
128
|
+
-- =============================================================================
|
|
129
|
+
|
|
130
|
+
-- Simple updateable view (for basic cases)
|
|
131
|
+
CREATE OR REPLACE VIEW :view_name_editable AS
|
|
132
|
+
SELECT
|
|
133
|
+
id,
|
|
134
|
+
name,
|
|
135
|
+
description,
|
|
136
|
+
status,
|
|
137
|
+
updated_at
|
|
138
|
+
FROM :base_table
|
|
139
|
+
WHERE deleted_at IS NULL;
|
|
140
|
+
|
|
141
|
+
-- Make it updateable via trigger
|
|
142
|
+
CREATE OR REPLACE FUNCTION :view_name_editable_update()
|
|
143
|
+
RETURNS TRIGGER AS $$
|
|
144
|
+
BEGIN
|
|
145
|
+
UPDATE :base_table
|
|
146
|
+
SET
|
|
147
|
+
name = NEW.name,
|
|
148
|
+
description = NEW.description,
|
|
149
|
+
status = NEW.status,
|
|
150
|
+
updated_at = NOW()
|
|
151
|
+
WHERE id = NEW.id
|
|
152
|
+
AND user_id = auth.uid(); -- RLS check
|
|
153
|
+
|
|
154
|
+
RETURN NEW;
|
|
155
|
+
END;
|
|
156
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
157
|
+
|
|
158
|
+
CREATE TRIGGER trigger_:view_name_editable_update
|
|
159
|
+
INSTEAD OF UPDATE ON :view_name_editable
|
|
160
|
+
FOR EACH ROW
|
|
161
|
+
EXECUTE FUNCTION :view_name_editable_update();
|
|
162
|
+
|
|
163
|
+
-- =============================================================================
|
|
164
|
+
-- VIEW METADATA
|
|
165
|
+
-- =============================================================================
|
|
166
|
+
|
|
167
|
+
COMMENT ON VIEW :view_name IS ':description';
|
|
168
|
+
|
|
169
|
+
-- =============================================================================
|
|
170
|
+
-- PERMISSIONS
|
|
171
|
+
-- =============================================================================
|
|
172
|
+
|
|
173
|
+
-- Grant SELECT on view (inherits base table RLS)
|
|
174
|
+
GRANT SELECT ON :view_name TO authenticated;
|
|
175
|
+
|
|
176
|
+
-- For updateable views, also grant UPDATE
|
|
177
|
+
-- GRANT UPDATE ON :view_name_editable TO authenticated;
|
|
178
|
+
|
|
@@ -381,24 +381,36 @@ spawn_terminal() {
|
|
|
381
381
|
# Add agent activation
|
|
382
382
|
agent_cmd="${agent_cmd} --print-only" # Just for testing, real impl would use actual claude flags
|
|
383
383
|
|
|
384
|
+
# SECURITY (SHELL-INJECTION-PM-SH): AGENT/TASK/PARAMS/CONTEXT_FILE come from
|
|
385
|
+
# CLI args and are interpolated into a command string run by a shell in the
|
|
386
|
+
# spawned terminal. Escape every interpolated value with `printf %q` so shell
|
|
387
|
+
# metacharacters (`;`, `$()`, backticks, quotes) cannot break out and execute.
|
|
388
|
+
local q_agent q_task q_params q_context q_output q_lock
|
|
389
|
+
printf -v q_agent '%q' "$AGENT"
|
|
390
|
+
printf -v q_task '%q' "$TASK"
|
|
391
|
+
printf -v q_params '%q' "$PARAMS"
|
|
392
|
+
printf -v q_context '%q' "$CONTEXT_FILE"
|
|
393
|
+
printf -v q_output '%q' "$OUTPUT_FILE"
|
|
394
|
+
printf -v q_lock '%q' "$LOCK_FILE"
|
|
395
|
+
|
|
384
396
|
# For now, we'll create a simpler command that demonstrates the concept
|
|
385
397
|
# The actual claude CLI integration will depend on how claude accepts agent/task args
|
|
386
398
|
local full_cmd="echo '=== SINAPSE Agent Session ===' && "
|
|
387
|
-
full_cmd+="echo
|
|
388
|
-
full_cmd+="echo
|
|
389
|
-
[[ -n "$PARAMS" ]] && full_cmd+="echo
|
|
390
|
-
[[ -n "$CONTEXT_FILE" ]] && full_cmd+="echo
|
|
399
|
+
full_cmd+="echo Agent: ${q_agent} && "
|
|
400
|
+
full_cmd+="echo Task: ${q_task} && "
|
|
401
|
+
[[ -n "$PARAMS" ]] && full_cmd+="echo Params: ${q_params} && "
|
|
402
|
+
[[ -n "$CONTEXT_FILE" ]] && full_cmd+="echo Context: ${q_context} && "
|
|
391
403
|
full_cmd+="echo '' && "
|
|
392
404
|
|
|
393
405
|
# Actual execution would be something like:
|
|
394
406
|
# full_cmd+="${CLAUDE_CMD} @${AGENT} *${TASK} ${PARAMS}"
|
|
395
407
|
# For now, simulate the output
|
|
396
|
-
full_cmd+="echo
|
|
408
|
+
full_cmd+="echo Executing: @${q_agent} '*'${q_task} ${q_params} && "
|
|
397
409
|
full_cmd+="echo 'Agent execution would happen here...' && "
|
|
398
410
|
full_cmd+="echo '=== Session Complete ===' "
|
|
399
411
|
|
|
400
412
|
# Redirect output to file and remove lock when done
|
|
401
|
-
full_cmd+=" >
|
|
413
|
+
full_cmd+=" > ${q_output} 2>&1; rm -f ${q_lock}"
|
|
402
414
|
|
|
403
415
|
# Spawn based on OS
|
|
404
416
|
case "$os" in
|