@jaimevalasek/aioson 1.3.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -1
- package/LICENSE +661 -21
- package/README.md +22 -3
- package/docs/en/squad-dashboard.md +372 -0
- package/docs/openclaw-bridge.md +308 -0
- package/docs/pt/README.md +62 -2
- package/docs/pt/advisor-spec.md +5 -5
- package/docs/pt/agentes-customizados.md +670 -0
- package/docs/pt/agentes.md +235 -23
- package/docs/pt/automacao-squads.md +407 -0
- package/docs/pt/cenarios.md +49 -5
- package/docs/pt/clientes-ai.md +62 -0
- package/docs/pt/comandos-cli.md +226 -17
- package/docs/pt/deyvin.md +115 -0
- package/docs/pt/genome-3.0-spec.md +11 -11
- package/docs/pt/inicio-rapido.md +63 -2
- package/docs/pt/memoria-contexto.md +255 -0
- package/docs/pt/output-strategy-delivery.md +655 -0
- package/docs/pt/profiler-system.md +17 -17
- package/docs/pt/runtime-observability.md +5 -1
- package/docs/pt/skills.md +175 -0
- package/docs/pt/squad-dashboard.md +373 -0
- package/docs/pt/{squad-genoma.md → squad-genome.md} +81 -75
- package/docs/testing/genome-2.0-matrix.md +5 -5
- package/docs/testing/genome-2.0-rollout.md +10 -10
- package/package.json +4 -4
- package/src/agents.js +21 -5
- package/src/backup-local.js +74 -0
- package/src/backup-provider.js +303 -0
- package/src/cli.js +276 -2
- package/src/commands/agents.js +22 -4
- package/src/commands/backup-local-cmd.js +25 -0
- package/src/commands/backup.js +533 -0
- package/src/commands/cloud.js +17 -17
- package/src/commands/context-pack.js +45 -0
- package/src/commands/implementation-plan.js +340 -0
- package/src/commands/learning.js +134 -0
- package/src/commands/live.js +1583 -0
- package/src/commands/runtime.js +1075 -2
- package/src/commands/scan-project.js +288 -24
- package/src/commands/setup-context.js +30 -2
- package/src/commands/skill.js +558 -0
- package/src/commands/squad-agent-create.js +788 -0
- package/src/commands/squad-daemon.js +209 -0
- package/src/commands/squad-dashboard.js +39 -0
- package/src/commands/squad-deploy.js +64 -0
- package/src/commands/squad-doctor.js +103 -1
- package/src/commands/squad-investigate.js +261 -0
- package/src/commands/squad-learning.js +209 -0
- package/src/commands/squad-mcp.js +270 -0
- package/src/commands/squad-pipeline.js +247 -1
- package/src/commands/squad-plan.js +329 -0
- package/src/commands/squad-processes.js +56 -0
- package/src/commands/squad-recovery.js +42 -0
- package/src/commands/squad-roi.js +291 -0
- package/src/commands/squad-score.js +250 -0
- package/src/commands/squad-status.js +38 -2
- package/src/commands/squad-validate.js +118 -1
- package/src/commands/squad-webhook.js +160 -0
- package/src/commands/squad-worker.js +191 -0
- package/src/commands/squad-worktrees.js +75 -0
- package/src/commands/test-agents.js +6 -1
- package/src/commands/web-map.js +70 -0
- package/src/commands/web-scrape.js +71 -0
- package/src/commands/workflow-next.js +8 -1
- package/src/commands/workflow-status.js +250 -0
- package/src/constants.js +88 -16
- package/src/context-memory.js +837 -0
- package/src/context-writer.js +47 -1
- package/src/delivery-runner.js +319 -0
- package/src/genome-files.js +1 -1
- package/src/genome-format.js +1 -1
- package/src/i18n/messages/en.js +333 -8
- package/src/i18n/messages/es.js +240 -6
- package/src/i18n/messages/fr.js +239 -5
- package/src/i18n/messages/pt-BR.js +330 -12
- package/src/installer.js +30 -2
- package/src/lib/genomes/compat.js +1 -1
- package/src/lib/webhook-server.js +328 -0
- package/src/mcp-connectors/registry.js +602 -0
- package/src/runtime-store.js +1037 -42
- package/src/session-handoff.js +77 -0
- package/src/squad/external-session.js +180 -0
- package/src/squad/inter-squad.js +74 -0
- package/src/squad/recovery-context.js +201 -0
- package/src/squad/worktree-manager.js +114 -0
- package/src/squad-daemon.js +490 -0
- package/src/squad-dashboard/api.js +223 -0
- package/src/squad-dashboard/attachment-handler.js +93 -0
- package/src/squad-dashboard/context-monitor.js +157 -0
- package/src/squad-dashboard/execution-logs.js +115 -0
- package/src/squad-dashboard/hunk-review.js +209 -0
- package/src/squad-dashboard/metrics.js +133 -0
- package/src/squad-dashboard/process-monitor.js +125 -0
- package/src/squad-dashboard/renderer.js +858 -0
- package/src/squad-dashboard/server.js +232 -0
- package/src/squad-dashboard/styles.js +525 -0
- package/src/squad-dashboard/token-tracker.js +99 -0
- package/src/web.js +284 -0
- package/src/worker-runner.js +339 -0
- package/template/.aioson/agents/analyst.md +40 -9
- package/template/.aioson/agents/architect.md +24 -5
- package/template/.aioson/agents/dev.md +254 -25
- package/template/.aioson/agents/deyvin.md +174 -0
- package/template/.aioson/agents/discovery-design-doc.md +25 -1
- package/template/.aioson/agents/{genoma.md → genome.md} +20 -20
- package/template/.aioson/agents/neo.md +152 -0
- package/template/.aioson/agents/orache.md +388 -0
- package/template/.aioson/agents/orchestrator.md +63 -2
- package/template/.aioson/agents/pair.md +5 -0
- package/template/.aioson/agents/pm.md +17 -5
- package/template/.aioson/agents/product.md +113 -29
- package/template/.aioson/agents/profiler-enricher.md +1 -1
- package/template/.aioson/agents/profiler-forge.md +9 -9
- package/template/.aioson/agents/profiler-researcher.md +1 -1
- package/template/.aioson/agents/qa.md +18 -5
- package/template/.aioson/agents/setup.md +138 -18
- package/template/.aioson/agents/sheldon.md +603 -0
- package/template/.aioson/agents/squad.md +866 -28
- package/template/.aioson/agents/tester.md +254 -0
- package/template/.aioson/agents/ux-ui.md +289 -34
- package/template/.aioson/config.md +181 -0
- package/template/.aioson/context/spec.md.template +17 -0
- package/template/.aioson/genomes/.gitkeep +0 -0
- package/template/.aioson/installed-skills/.gitkeep +0 -0
- package/template/.aioson/locales/en/agents/analyst.md +34 -4
- package/template/.aioson/locales/en/agents/architect.md +18 -0
- package/template/.aioson/locales/en/agents/dev.md +155 -11
- package/template/.aioson/locales/en/agents/deyvin.md +137 -0
- package/template/.aioson/locales/en/agents/{genoma.md → genome.md} +14 -14
- package/template/.aioson/locales/en/agents/neo.md +8 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/en/agents/pair.md +5 -0
- package/template/.aioson/locales/en/agents/pm.md +7 -0
- package/template/.aioson/locales/en/agents/product.md +35 -17
- package/template/.aioson/locales/en/agents/qa.md +56 -0
- package/template/.aioson/locales/en/agents/setup.md +53 -6
- package/template/.aioson/locales/en/agents/sheldon.md +340 -0
- package/template/.aioson/locales/en/agents/squad.md +203 -15
- package/template/.aioson/locales/en/agents/ux-ui.md +383 -35
- package/template/.aioson/locales/es/agents/analyst.md +24 -4
- package/template/.aioson/locales/es/agents/architect.md +18 -0
- package/template/.aioson/locales/es/agents/dev.md +136 -9
- package/template/.aioson/locales/es/agents/deyvin.md +97 -0
- package/template/.aioson/locales/es/agents/{genoma.md → genome.md} +13 -13
- package/template/.aioson/locales/es/agents/neo.md +48 -0
- package/template/.aioson/locales/es/agents/orache.md +103 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/es/agents/pair.md +5 -0
- package/template/.aioson/locales/es/agents/pm.md +7 -0
- package/template/.aioson/locales/es/agents/product.md +13 -3
- package/template/.aioson/locales/es/agents/qa.md +33 -0
- package/template/.aioson/locales/es/agents/setup.md +30 -6
- package/template/.aioson/locales/es/agents/sheldon.md +192 -0
- package/template/.aioson/locales/es/agents/squad.md +284 -15
- package/template/.aioson/locales/es/agents/ux-ui.md +34 -25
- package/template/.aioson/locales/fr/agents/analyst.md +24 -4
- package/template/.aioson/locales/fr/agents/architect.md +18 -0
- package/template/.aioson/locales/fr/agents/dev.md +136 -9
- package/template/.aioson/locales/fr/agents/deyvin.md +97 -0
- package/template/.aioson/locales/fr/agents/{genoma.md → genome.md} +7 -7
- package/template/.aioson/locales/fr/agents/neo.md +48 -0
- package/template/.aioson/locales/fr/agents/orache.md +104 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/fr/agents/pair.md +5 -0
- package/template/.aioson/locales/fr/agents/pm.md +7 -0
- package/template/.aioson/locales/fr/agents/product.md +13 -3
- package/template/.aioson/locales/fr/agents/qa.md +33 -0
- package/template/.aioson/locales/fr/agents/setup.md +30 -6
- package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
- package/template/.aioson/locales/fr/agents/squad.md +279 -10
- package/template/.aioson/locales/fr/agents/ux-ui.md +34 -25
- package/template/.aioson/locales/pt-BR/agents/analyst.md +45 -4
- package/template/.aioson/locales/pt-BR/agents/architect.md +29 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +167 -15
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +137 -0
- package/template/.aioson/locales/pt-BR/agents/{genoma.md → genome.md} +49 -49
- package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
- package/template/.aioson/locales/pt-BR/agents/orache.md +137 -0
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/pt-BR/agents/pair.md +5 -0
- package/template/.aioson/locales/pt-BR/agents/pm.md +7 -0
- package/template/.aioson/locales/pt-BR/agents/product.md +43 -20
- package/template/.aioson/locales/pt-BR/agents/qa.md +67 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +53 -6
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
- package/template/.aioson/locales/pt-BR/agents/squad.md +591 -47
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +369 -22
- package/template/.aioson/my-agents/.gitkeep +0 -0
- package/template/.aioson/rules/.gitkeep +0 -0
- package/template/.aioson/rules/squad/.gitkeep +0 -0
- package/template/.aioson/rules/squad/README.md +50 -0
- package/template/.aioson/schemas/genome-meta.schema.json +1 -1
- package/template/.aioson/schemas/genome.schema.json +1 -1
- package/template/.aioson/schemas/squad-blueprint.schema.json +32 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +434 -1
- package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +203 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +407 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +272 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +524 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +277 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +289 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +437 -0
- package/template/.aioson/skills/design/interface-design/SKILL.md +47 -0
- package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -0
- package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -0
- package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +71 -0
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -0
- package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -0
- package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +62 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -0
- package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
- package/template/.aioson/skills/design-system/SKILL.md +92 -0
- package/template/.aioson/skills/design-system/cognitive-core-ui.skill +0 -0
- package/template/.aioson/skills/design-system/components/SKILL.md +274 -0
- package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md +184 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md +250 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md +197 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/patterns/SKILL.md +231 -0
- package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
- package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
- package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
- package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
- package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
- package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
- package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
- package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
- package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
- package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
- package/template/.aioson/skills/squad/SKILL.md +58 -0
- package/template/.aioson/skills/squad/domains/.gitkeep +0 -0
- package/template/.aioson/skills/squad/formats/.gitkeep +0 -0
- package/template/.aioson/skills/squad/formats/catalog.json +15 -0
- package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
- package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
- package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
- package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
- package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
- package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
- package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
- package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
- package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
- package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
- package/template/.aioson/skills/squad/patterns/.gitkeep +0 -0
- package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
- package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
- package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
- package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
- package/template/.aioson/skills/squad/references/.gitkeep +0 -0
- package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
- package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
- package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
- package/template/.aioson/skills/static/debugging-protocol.md +42 -0
- package/template/.aioson/skills/static/git-worktrees.md +36 -0
- package/template/.aioson/tasks/implementation-plan.md +307 -0
- package/template/.aioson/tasks/squad-create.md +1 -1
- package/template/.aioson/tasks/squad-design.md +28 -0
- package/template/.aioson/tasks/squad-execution-plan.md +279 -0
- package/template/.aioson/tasks/squad-export.md +1 -1
- package/template/.aioson/tasks/squad-investigate.md +44 -0
- package/template/.aioson/tasks/squad-learning-review.md +44 -0
- package/template/.aioson/tasks/squad-output-config.md +177 -0
- package/template/.aioson/tasks/squad-profile.md +48 -0
- package/template/.aioson/tasks/squad-review.md +61 -0
- package/template/.aioson/tasks/squad-task-decompose.md +66 -0
- package/template/.aioson/tasks/squad-validate.md +1 -1
- package/template/.claude/commands/aioson/agent/deyvin.md +5 -0
- package/template/.claude/commands/aioson/agent/discovery-design-doc.md +5 -0
- package/template/.claude/commands/aioson/agent/genome.md +5 -0
- package/template/.claude/commands/aioson/agent/neo.md +5 -0
- package/template/.claude/commands/aioson/agent/product.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-enricher.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-forge.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-researcher.md +5 -0
- package/template/.claude/commands/aioson/agent/squad.md +5 -0
- package/template/.claude/commands/aioson/agent/tester.md +5 -0
- package/template/.gemini/GEMINI.md +3 -0
- package/template/.gemini/commands/aios-deyvin.toml +6 -0
- package/template/.gemini/commands/aios-neo.toml +4 -0
- package/template/.gemini/commands/aios-pair.toml +6 -0
- package/template/.gemini/commands/aios-tester.toml +6 -0
- package/template/AGENTS.md +37 -6
- package/template/CLAUDE.md +34 -4
- package/template/OPENCODE.md +8 -2
- package/template/squad-searches/.gitkeep +0 -0
- package/template/.aioson/skills/static/interface-design.md +0 -372
- package/template/.aioson/skills/static/premium-command-center-ui.md +0 -190
- /package/template/.aioson/{genomas → docs}/.gitkeep +0 -0
- /package/template/.claude/commands/aioson/{analyst.md → agent/analyst.md} +0 -0
- /package/template/.claude/commands/aioson/{architect.md → agent/architect.md} +0 -0
- /package/template/.claude/commands/aioson/{dev.md → agent/dev.md} +0 -0
- /package/template/.claude/commands/aioson/{orchestrator.md → agent/orchestrator.md} +0 -0
- /package/template/.claude/commands/aioson/{pm.md → agent/pm.md} +0 -0
- /package/template/.claude/commands/aioson/{qa.md → agent/qa.md} +0 -0
- /package/template/.claude/commands/aioson/{setup.md → agent/setup.md} +0 -0
- /package/template/.claude/commands/aioson/{ux-ui.md → agent/ux-ui.md} +0 -0
package/src/runtime-store.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
|
|
13
13
|
const RUNTIME_DIR = path.join('.aioson', 'runtime');
|
|
14
14
|
const DB_FILE = 'aios.sqlite';
|
|
15
|
+
const LOGS_DIR = 'aioson-logs';
|
|
15
16
|
const SESSIONS_DIR = '.sessions';
|
|
16
17
|
const VALID_STATUSES = new Set(['queued', 'running', 'completed', 'failed']);
|
|
17
18
|
const VALID_TASK_STATUSES = new Set(['queued', 'running', 'completed', 'failed']);
|
|
@@ -32,7 +33,8 @@ function resolveRuntimePaths(targetDir) {
|
|
|
32
33
|
const runtimeDir = path.join(targetDir, RUNTIME_DIR);
|
|
33
34
|
return {
|
|
34
35
|
runtimeDir,
|
|
35
|
-
dbPath: path.join(runtimeDir, DB_FILE)
|
|
36
|
+
dbPath: path.join(runtimeDir, DB_FILE),
|
|
37
|
+
logsDir: path.join(targetDir, LOGS_DIR)
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -42,7 +44,7 @@ async function runtimeStoreExists(targetDir) {
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
async function openRuntimeDb(targetDir, options = {}) {
|
|
45
|
-
const { runtimeDir, dbPath } = resolveRuntimePaths(targetDir);
|
|
47
|
+
const { runtimeDir, dbPath, logsDir } = resolveRuntimePaths(targetDir);
|
|
46
48
|
const mustExist = Boolean(options.mustExist);
|
|
47
49
|
|
|
48
50
|
if (mustExist && !(await exists(dbPath))) {
|
|
@@ -50,6 +52,7 @@ async function openRuntimeDb(targetDir, options = {}) {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
await ensureDir(runtimeDir);
|
|
55
|
+
await ensureDir(logsDir);
|
|
53
56
|
|
|
54
57
|
const db = new Database(dbPath);
|
|
55
58
|
db.pragma('journal_mode = WAL');
|
|
@@ -125,8 +128,11 @@ async function openRuntimeDb(targetDir, options = {}) {
|
|
|
125
128
|
task_key TEXT PRIMARY KEY,
|
|
126
129
|
squad_slug TEXT,
|
|
127
130
|
session_key TEXT,
|
|
131
|
+
task_kind TEXT,
|
|
132
|
+
parent_task_key TEXT,
|
|
128
133
|
title TEXT NOT NULL,
|
|
129
134
|
goal TEXT,
|
|
135
|
+
meta_json TEXT,
|
|
130
136
|
status TEXT NOT NULL,
|
|
131
137
|
created_by TEXT,
|
|
132
138
|
created_at TEXT NOT NULL,
|
|
@@ -351,6 +357,239 @@ async function openRuntimeDb(targetDir, options = {}) {
|
|
|
351
357
|
|
|
352
358
|
CREATE INDEX IF NOT EXISTS idx_artisan_squads_status ON artisan_squads(status, updated_at DESC);
|
|
353
359
|
CREATE INDEX IF NOT EXISTS idx_artisan_messages_artisan ON artisan_messages(artisan_id, created_at ASC);
|
|
360
|
+
|
|
361
|
+
CREATE TABLE IF NOT EXISTS delivery_log (
|
|
362
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
363
|
+
squad_slug TEXT NOT NULL,
|
|
364
|
+
content_key TEXT,
|
|
365
|
+
webhook_slug TEXT,
|
|
366
|
+
trigger_type TEXT NOT NULL,
|
|
367
|
+
url TEXT NOT NULL,
|
|
368
|
+
status_code INTEGER,
|
|
369
|
+
response_body TEXT,
|
|
370
|
+
error_message TEXT,
|
|
371
|
+
attempt INTEGER DEFAULT 1,
|
|
372
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
CREATE INDEX IF NOT EXISTS idx_delivery_log_squad ON delivery_log(squad_slug);
|
|
376
|
+
CREATE INDEX IF NOT EXISTS idx_delivery_log_content ON delivery_log(content_key);
|
|
377
|
+
|
|
378
|
+
CREATE TABLE IF NOT EXISTS backup_manifest (
|
|
379
|
+
record_key TEXT PRIMARY KEY,
|
|
380
|
+
record_type TEXT NOT NULL,
|
|
381
|
+
content_hash TEXT NOT NULL,
|
|
382
|
+
backed_up_at TEXT NOT NULL,
|
|
383
|
+
remote_key TEXT NOT NULL
|
|
384
|
+
);
|
|
385
|
+
CREATE INDEX IF NOT EXISTS idx_backup_manifest_type ON backup_manifest(record_type, backed_up_at DESC);
|
|
386
|
+
|
|
387
|
+
CREATE TABLE IF NOT EXISTS squad_investigations (
|
|
388
|
+
investigation_slug TEXT PRIMARY KEY,
|
|
389
|
+
domain TEXT NOT NULL,
|
|
390
|
+
mode TEXT DEFAULT 'full',
|
|
391
|
+
dimensions_covered INTEGER DEFAULT 0,
|
|
392
|
+
total_dimensions INTEGER DEFAULT 7,
|
|
393
|
+
confidence REAL DEFAULT 0,
|
|
394
|
+
report_path TEXT,
|
|
395
|
+
linked_squad_slug TEXT,
|
|
396
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
397
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
CREATE INDEX IF NOT EXISTS idx_squad_investigations_domain ON squad_investigations(domain);
|
|
401
|
+
CREATE INDEX IF NOT EXISTS idx_squad_investigations_squad ON squad_investigations(linked_squad_slug);
|
|
402
|
+
|
|
403
|
+
CREATE TABLE IF NOT EXISTS implementation_plans (
|
|
404
|
+
plan_id TEXT PRIMARY KEY,
|
|
405
|
+
project_name TEXT,
|
|
406
|
+
scope TEXT DEFAULT 'project',
|
|
407
|
+
feature_slug TEXT,
|
|
408
|
+
status TEXT DEFAULT 'draft',
|
|
409
|
+
classification TEXT,
|
|
410
|
+
phases_total INTEGER DEFAULT 0,
|
|
411
|
+
phases_completed INTEGER DEFAULT 0,
|
|
412
|
+
source_artifacts TEXT,
|
|
413
|
+
source_hash TEXT,
|
|
414
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
415
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
CREATE TABLE IF NOT EXISTS plan_phases (
|
|
419
|
+
plan_id TEXT NOT NULL,
|
|
420
|
+
phase_number INTEGER NOT NULL,
|
|
421
|
+
title TEXT NOT NULL,
|
|
422
|
+
status TEXT DEFAULT 'pending',
|
|
423
|
+
completed_at TEXT,
|
|
424
|
+
notes TEXT,
|
|
425
|
+
PRIMARY KEY (plan_id, phase_number),
|
|
426
|
+
FOREIGN KEY (plan_id) REFERENCES implementation_plans(plan_id)
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
CREATE TABLE IF NOT EXISTS squad_execution_plans (
|
|
430
|
+
plan_slug TEXT PRIMARY KEY,
|
|
431
|
+
squad_slug TEXT NOT NULL,
|
|
432
|
+
status TEXT DEFAULT 'draft',
|
|
433
|
+
rounds_total INTEGER DEFAULT 0,
|
|
434
|
+
rounds_completed INTEGER DEFAULT 0,
|
|
435
|
+
based_on_blueprint TEXT,
|
|
436
|
+
based_on_investigation TEXT,
|
|
437
|
+
source_hash TEXT,
|
|
438
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
439
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
CREATE TABLE IF NOT EXISTS squad_plan_rounds (
|
|
443
|
+
plan_slug TEXT NOT NULL,
|
|
444
|
+
round_number INTEGER NOT NULL,
|
|
445
|
+
executor_slug TEXT NOT NULL,
|
|
446
|
+
title TEXT NOT NULL,
|
|
447
|
+
status TEXT DEFAULT 'pending',
|
|
448
|
+
completed_at TEXT,
|
|
449
|
+
notes TEXT,
|
|
450
|
+
PRIMARY KEY (plan_slug, round_number),
|
|
451
|
+
FOREIGN KEY (plan_slug) REFERENCES squad_execution_plans(plan_slug)
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
CREATE TABLE IF NOT EXISTS squad_learnings (
|
|
455
|
+
learning_id TEXT PRIMARY KEY,
|
|
456
|
+
squad_slug TEXT NOT NULL,
|
|
457
|
+
type TEXT NOT NULL CHECK (type IN ('preference', 'process', 'domain', 'quality')),
|
|
458
|
+
title TEXT NOT NULL,
|
|
459
|
+
signal TEXT DEFAULT 'explicit' CHECK (signal IN ('explicit', 'implicit')),
|
|
460
|
+
confidence TEXT DEFAULT 'medium' CHECK (confidence IN ('high', 'medium', 'low')),
|
|
461
|
+
frequency INTEGER DEFAULT 1,
|
|
462
|
+
last_reinforced TEXT,
|
|
463
|
+
applies_to TEXT DEFAULT 'squad',
|
|
464
|
+
file_path TEXT,
|
|
465
|
+
promoted_to TEXT,
|
|
466
|
+
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'stale', 'archived', 'promoted')),
|
|
467
|
+
source_session TEXT,
|
|
468
|
+
evidence TEXT,
|
|
469
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
470
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
CREATE TABLE IF NOT EXISTS project_learnings (
|
|
474
|
+
learning_id TEXT PRIMARY KEY,
|
|
475
|
+
project_name TEXT,
|
|
476
|
+
feature_slug TEXT,
|
|
477
|
+
type TEXT NOT NULL CHECK (type IN ('preference', 'process', 'domain', 'quality')),
|
|
478
|
+
title TEXT NOT NULL,
|
|
479
|
+
confidence TEXT DEFAULT 'medium',
|
|
480
|
+
frequency INTEGER DEFAULT 1,
|
|
481
|
+
last_reinforced TEXT,
|
|
482
|
+
applies_to TEXT DEFAULT 'project',
|
|
483
|
+
promoted_to TEXT,
|
|
484
|
+
status TEXT DEFAULT 'active' CHECK (status IN ('active', 'stale', 'archived', 'promoted')),
|
|
485
|
+
source_session TEXT,
|
|
486
|
+
evidence TEXT,
|
|
487
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
488
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
CREATE INDEX IF NOT EXISTS idx_impl_plans_status ON implementation_plans(status);
|
|
492
|
+
CREATE INDEX IF NOT EXISTS idx_squad_exec_plans_squad ON squad_execution_plans(squad_slug);
|
|
493
|
+
CREATE INDEX IF NOT EXISTS idx_squad_exec_plans_status ON squad_execution_plans(status);
|
|
494
|
+
CREATE INDEX IF NOT EXISTS idx_squad_learnings_squad ON squad_learnings(squad_slug);
|
|
495
|
+
CREATE INDEX IF NOT EXISTS idx_squad_learnings_type ON squad_learnings(type);
|
|
496
|
+
CREATE INDEX IF NOT EXISTS idx_squad_learnings_status ON squad_learnings(status);
|
|
497
|
+
CREATE INDEX IF NOT EXISTS idx_project_learnings_type ON project_learnings(type);
|
|
498
|
+
CREATE INDEX IF NOT EXISTS idx_project_learnings_status ON project_learnings(status);
|
|
499
|
+
|
|
500
|
+
CREATE TABLE IF NOT EXISTS squad_metrics (
|
|
501
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
502
|
+
squad_slug TEXT NOT NULL,
|
|
503
|
+
metric_key TEXT NOT NULL,
|
|
504
|
+
metric_value REAL NOT NULL,
|
|
505
|
+
metric_unit TEXT,
|
|
506
|
+
period TEXT,
|
|
507
|
+
baseline REAL,
|
|
508
|
+
target REAL,
|
|
509
|
+
source TEXT DEFAULT 'manual',
|
|
510
|
+
notes TEXT,
|
|
511
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
512
|
+
UNIQUE(squad_slug, metric_key, period)
|
|
513
|
+
);
|
|
514
|
+
CREATE INDEX IF NOT EXISTS idx_squad_metrics_squad ON squad_metrics(squad_slug, period DESC);
|
|
515
|
+
|
|
516
|
+
CREATE TABLE IF NOT EXISTS worker_runs (
|
|
517
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
518
|
+
squad_slug TEXT NOT NULL,
|
|
519
|
+
worker_slug TEXT NOT NULL,
|
|
520
|
+
trigger_type TEXT NOT NULL DEFAULT 'manual',
|
|
521
|
+
input_json TEXT,
|
|
522
|
+
output_json TEXT,
|
|
523
|
+
status TEXT DEFAULT 'running',
|
|
524
|
+
error_message TEXT,
|
|
525
|
+
duration_ms INTEGER,
|
|
526
|
+
attempt INTEGER DEFAULT 1,
|
|
527
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
528
|
+
completed_at TEXT
|
|
529
|
+
);
|
|
530
|
+
CREATE INDEX IF NOT EXISTS idx_worker_runs_squad ON worker_runs(squad_slug, created_at DESC);
|
|
531
|
+
|
|
532
|
+
CREATE TABLE IF NOT EXISTS squad_daemons (
|
|
533
|
+
squad_slug TEXT PRIMARY KEY,
|
|
534
|
+
status TEXT DEFAULT 'stopped',
|
|
535
|
+
pid INTEGER,
|
|
536
|
+
port INTEGER,
|
|
537
|
+
started_at TEXT,
|
|
538
|
+
last_heartbeat TEXT,
|
|
539
|
+
config_json TEXT,
|
|
540
|
+
error_message TEXT
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
CREATE TABLE IF NOT EXISTS mcp_status (
|
|
544
|
+
squad_slug TEXT NOT NULL,
|
|
545
|
+
mcp_slug TEXT NOT NULL,
|
|
546
|
+
connector TEXT NOT NULL,
|
|
547
|
+
status TEXT DEFAULT 'unconfigured',
|
|
548
|
+
last_check TEXT,
|
|
549
|
+
last_error TEXT,
|
|
550
|
+
calls_total INTEGER DEFAULT 0,
|
|
551
|
+
calls_failed INTEGER DEFAULT 0,
|
|
552
|
+
PRIMARY KEY (squad_slug, mcp_slug)
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
CREATE TABLE IF NOT EXISTS workflow_reviews (
|
|
556
|
+
review_id TEXT PRIMARY KEY,
|
|
557
|
+
squad_slug TEXT NOT NULL,
|
|
558
|
+
workflow_slug TEXT NOT NULL,
|
|
559
|
+
phase_id TEXT NOT NULL,
|
|
560
|
+
attempt_number INTEGER DEFAULT 1,
|
|
561
|
+
reviewer_slug TEXT NOT NULL,
|
|
562
|
+
verdict TEXT NOT NULL,
|
|
563
|
+
score REAL,
|
|
564
|
+
feedback TEXT,
|
|
565
|
+
veto_triggered TEXT,
|
|
566
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
567
|
+
);
|
|
568
|
+
CREATE INDEX IF NOT EXISTS idx_workflow_reviews_squad ON workflow_reviews(squad_slug, workflow_slug);
|
|
569
|
+
|
|
570
|
+
CREATE TABLE IF NOT EXISTS squad_scores (
|
|
571
|
+
squad_slug TEXT NOT NULL,
|
|
572
|
+
dimension TEXT NOT NULL,
|
|
573
|
+
score INTEGER NOT NULL,
|
|
574
|
+
max_score INTEGER NOT NULL,
|
|
575
|
+
details_json TEXT,
|
|
576
|
+
scored_at TEXT DEFAULT (datetime('now')),
|
|
577
|
+
PRIMARY KEY (squad_slug, dimension, scored_at)
|
|
578
|
+
);
|
|
579
|
+
CREATE INDEX IF NOT EXISTS idx_squad_scores_squad ON squad_scores(squad_slug);
|
|
580
|
+
|
|
581
|
+
CREATE TABLE IF NOT EXISTS squad_roi_config (
|
|
582
|
+
squad_slug TEXT PRIMARY KEY,
|
|
583
|
+
pricing_model TEXT DEFAULT 'fixed',
|
|
584
|
+
setup_fee REAL,
|
|
585
|
+
monthly_fee REAL,
|
|
586
|
+
percentage_fee REAL,
|
|
587
|
+
percentage_base TEXT,
|
|
588
|
+
currency TEXT DEFAULT 'BRL',
|
|
589
|
+
contract_months INTEGER DEFAULT 12,
|
|
590
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
591
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
592
|
+
);
|
|
354
593
|
`);
|
|
355
594
|
|
|
356
595
|
ensureLegacyColumns(db);
|
|
@@ -381,6 +620,25 @@ function normalizeTaskStatus(value, fallback) {
|
|
|
381
620
|
}
|
|
382
621
|
|
|
383
622
|
function ensureLegacyColumns(db) {
|
|
623
|
+
const taskColumns = db.prepare('PRAGMA table_info(tasks)').all();
|
|
624
|
+
const taskColumnNames = new Set(taskColumns.map((column) => column.name));
|
|
625
|
+
|
|
626
|
+
if (!taskColumnNames.has('task_kind')) {
|
|
627
|
+
db.exec('ALTER TABLE tasks ADD COLUMN task_kind TEXT');
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
if (!taskColumnNames.has('parent_task_key')) {
|
|
631
|
+
db.exec('ALTER TABLE tasks ADD COLUMN parent_task_key TEXT');
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (!taskColumnNames.has('meta_json')) {
|
|
635
|
+
db.exec('ALTER TABLE tasks ADD COLUMN meta_json TEXT');
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_tasks_session ON tasks(session_key, updated_at DESC)');
|
|
639
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task_key, updated_at DESC)');
|
|
640
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_tasks_kind ON tasks(task_kind, updated_at DESC)');
|
|
641
|
+
|
|
384
642
|
const agentRunColumns = db.prepare('PRAGMA table_info(agent_runs)').all();
|
|
385
643
|
const agentRunColumnNames = new Set(agentRunColumns.map((column) => column.name));
|
|
386
644
|
|
|
@@ -433,6 +691,8 @@ function ensureLegacyColumns(db) {
|
|
|
433
691
|
if (!contentItemColumnNames.has('used_skills_json')) {
|
|
434
692
|
db.exec('ALTER TABLE content_items ADD COLUMN used_skills_json TEXT');
|
|
435
693
|
}
|
|
694
|
+
|
|
695
|
+
try { db.exec('ALTER TABLE worker_runs ADD COLUMN conversation_id TEXT'); } catch { /* já existe */ }
|
|
436
696
|
}
|
|
437
697
|
|
|
438
698
|
function insertEvent(db, record) {
|
|
@@ -498,56 +758,66 @@ function appendRunEvent(db, options) {
|
|
|
498
758
|
const now = options.createdAt || nowIso();
|
|
499
759
|
const payloadJson = options.payload ? JSON.stringify(options.payload) : null;
|
|
500
760
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
761
|
+
const doInsert = db.transaction(() => {
|
|
762
|
+
insertEvent(db, {
|
|
763
|
+
run_key: run.run_key,
|
|
764
|
+
event_type: String(options.eventType || 'update'),
|
|
765
|
+
message: String(options.message || ''),
|
|
766
|
+
payload_json: payloadJson,
|
|
767
|
+
created_at: now
|
|
768
|
+
});
|
|
508
769
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
770
|
+
insertExecutionEvent(db, {
|
|
771
|
+
task_key: run.task_key,
|
|
772
|
+
run_key: run.run_key,
|
|
773
|
+
agent_name: run.agent_name,
|
|
774
|
+
agent_kind: run.agent_kind,
|
|
775
|
+
squad_slug: run.squad_slug,
|
|
776
|
+
session_key: run.session_key,
|
|
777
|
+
source: run.source,
|
|
778
|
+
workflow_id: run.workflow_id,
|
|
779
|
+
workflow_stage: run.workflow_stage,
|
|
780
|
+
parent_run_key: run.parent_run_key,
|
|
781
|
+
event_type: String(options.eventType || 'update'),
|
|
782
|
+
phase: options.phase ? String(options.phase).trim() : null,
|
|
783
|
+
status: options.status ? String(options.status).trim() : run.status || null,
|
|
784
|
+
tool_name: options.toolName ? String(options.toolName).trim() : null,
|
|
785
|
+
message: String(options.message || ''),
|
|
786
|
+
payload_json: payloadJson,
|
|
787
|
+
sequence_no: nextExecutionSequence(db, run.run_key),
|
|
788
|
+
parent_event_id: options.parentEventId || null,
|
|
789
|
+
created_at: now
|
|
790
|
+
});
|
|
529
791
|
});
|
|
792
|
+
|
|
793
|
+
doInsert();
|
|
530
794
|
}
|
|
531
795
|
|
|
532
796
|
function startTask(db, options) {
|
|
533
797
|
const now = nowIso();
|
|
534
798
|
const taskKey = String(options.taskKey || createTaskKey(options.title));
|
|
535
799
|
const status = normalizeTaskStatus(options.status, 'running');
|
|
800
|
+
const metaJson = options.metaJson && typeof options.metaJson === 'object'
|
|
801
|
+
? JSON.stringify(options.metaJson)
|
|
802
|
+
: (typeof options.metaJson === 'string' && options.metaJson.trim() ? options.metaJson.trim() : null);
|
|
536
803
|
|
|
537
804
|
db.prepare(`
|
|
538
805
|
INSERT INTO tasks (
|
|
539
|
-
task_key, squad_slug, session_key,
|
|
540
|
-
created_at, updated_at, finished_at
|
|
806
|
+
task_key, squad_slug, session_key, task_kind, parent_task_key,
|
|
807
|
+
title, goal, meta_json, status, created_by, created_at, updated_at, finished_at
|
|
541
808
|
) VALUES (
|
|
542
|
-
@task_key, @squad_slug, @session_key, @
|
|
543
|
-
@created_at, @updated_at, @finished_at
|
|
809
|
+
@task_key, @squad_slug, @session_key, @task_kind, @parent_task_key,
|
|
810
|
+
@title, @goal, @meta_json, @status, @created_by, @created_at, @updated_at, @finished_at
|
|
544
811
|
)
|
|
545
812
|
`).run({
|
|
546
813
|
task_key: taskKey,
|
|
547
814
|
squad_slug: options.squadSlug ? String(options.squadSlug).trim() : null,
|
|
548
815
|
session_key: options.sessionKey ? String(options.sessionKey).trim() : null,
|
|
816
|
+
task_kind: options.taskKind ? String(options.taskKind).trim() : null,
|
|
817
|
+
parent_task_key: options.parentTaskKey ? String(options.parentTaskKey).trim() : null,
|
|
549
818
|
title: String(options.title).trim(),
|
|
550
819
|
goal: options.goal ? String(options.goal).trim() : null,
|
|
820
|
+
meta_json: metaJson,
|
|
551
821
|
status,
|
|
552
822
|
created_by: options.createdBy ? String(options.createdBy).trim() : null,
|
|
553
823
|
created_at: now,
|
|
@@ -566,12 +836,18 @@ function updateTask(db, options) {
|
|
|
566
836
|
|
|
567
837
|
const now = nowIso();
|
|
568
838
|
const nextStatus = normalizeTaskStatus(options.status, existing.status || 'running');
|
|
839
|
+
const metaJson = options.metaJson && typeof options.metaJson === 'object'
|
|
840
|
+
? JSON.stringify(options.metaJson)
|
|
841
|
+
: (typeof options.metaJson === 'string' && options.metaJson.trim() ? options.metaJson.trim() : null);
|
|
569
842
|
|
|
570
843
|
db.prepare(`
|
|
571
844
|
UPDATE tasks
|
|
572
845
|
SET
|
|
573
846
|
status = @status,
|
|
574
847
|
goal = COALESCE(@goal, goal),
|
|
848
|
+
task_kind = COALESCE(@task_kind, task_kind),
|
|
849
|
+
parent_task_key = COALESCE(@parent_task_key, parent_task_key),
|
|
850
|
+
meta_json = COALESCE(@meta_json, meta_json),
|
|
575
851
|
updated_at = @updated_at,
|
|
576
852
|
finished_at = CASE
|
|
577
853
|
WHEN @status IN ('completed', 'failed') THEN @updated_at
|
|
@@ -582,6 +858,9 @@ function updateTask(db, options) {
|
|
|
582
858
|
task_key: String(options.taskKey),
|
|
583
859
|
status: nextStatus,
|
|
584
860
|
goal: options.goal ? String(options.goal).trim() : null,
|
|
861
|
+
task_kind: options.taskKind ? String(options.taskKind).trim() : null,
|
|
862
|
+
parent_task_key: options.parentTaskKey ? String(options.parentTaskKey).trim() : null,
|
|
863
|
+
meta_json: metaJson,
|
|
585
864
|
updated_at: now
|
|
586
865
|
});
|
|
587
866
|
|
|
@@ -696,6 +975,52 @@ function parseJsonArray(value) {
|
|
|
696
975
|
}
|
|
697
976
|
}
|
|
698
977
|
|
|
978
|
+
|
|
979
|
+
function parseJsonObject(value) {
|
|
980
|
+
if (!value) return null;
|
|
981
|
+
try {
|
|
982
|
+
const parsed = JSON.parse(value);
|
|
983
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
984
|
+
} catch {
|
|
985
|
+
return null;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
function getTaskPlanProgress(meta) {
|
|
990
|
+
const steps = Array.isArray(meta?.plan_steps) ? meta.plan_steps : [];
|
|
991
|
+
return {
|
|
992
|
+
plan_steps_done: steps.filter((step) => step && step.done).length,
|
|
993
|
+
plan_steps_total: steps.length
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
function decorateTaskSnapshotRow(row) {
|
|
998
|
+
const meta = parseJsonObject(row.meta_json);
|
|
999
|
+
const progress = getTaskPlanProgress(meta);
|
|
1000
|
+
row.meta = meta;
|
|
1001
|
+
row.plan_steps_done = progress.plan_steps_done;
|
|
1002
|
+
row.plan_steps_total = progress.plan_steps_total;
|
|
1003
|
+
row.is_live_session = row.task_kind === 'live_session';
|
|
1004
|
+
row.is_micro_task = row.task_kind === 'micro_task';
|
|
1005
|
+
return row;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
function decorateRunSnapshotRow(row) {
|
|
1009
|
+
row.used_skills = parseJsonArray(row.used_skills_json);
|
|
1010
|
+
row.is_live = row.source === 'live';
|
|
1011
|
+
row.is_handoff_child = Boolean(row.parent_run_key);
|
|
1012
|
+
return row;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function decorateExecutionEventSnapshotRow(row) {
|
|
1016
|
+
const payload = parseJsonObject(row.payload_json);
|
|
1017
|
+
row.payload = payload;
|
|
1018
|
+
row.is_handoff = row.event_type === 'handoff';
|
|
1019
|
+
row.handoff_from = payload?.from || row.agent_name || null;
|
|
1020
|
+
row.handoff_to = payload?.to || null;
|
|
1021
|
+
return row;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
699
1024
|
function upsertSquadManifest(db, options) {
|
|
700
1025
|
const now = nowIso();
|
|
701
1026
|
const slug = String(options.slug).trim();
|
|
@@ -1110,7 +1435,7 @@ function startRun(db, options) {
|
|
|
1110
1435
|
|
|
1111
1436
|
appendRunEvent(db, {
|
|
1112
1437
|
runKey,
|
|
1113
|
-
eventType: 'start',
|
|
1438
|
+
eventType: String(options.eventType || 'start'),
|
|
1114
1439
|
phase: options.phase || 'run',
|
|
1115
1440
|
status,
|
|
1116
1441
|
message: String(options.message || options.title || 'Agent started'),
|
|
@@ -1242,7 +1567,7 @@ function getStatusSnapshot(db) {
|
|
|
1242
1567
|
|
|
1243
1568
|
const activeTasks = db.prepare(`
|
|
1244
1569
|
SELECT
|
|
1245
|
-
task_key, squad_slug, session_key, title, goal, status, created_by, created_at, updated_at,
|
|
1570
|
+
task_key, squad_slug, session_key, task_kind, parent_task_key, title, goal, meta_json, status, created_by, created_at, updated_at,
|
|
1246
1571
|
(
|
|
1247
1572
|
SELECT COUNT(*)
|
|
1248
1573
|
FROM agent_runs
|
|
@@ -1252,7 +1577,29 @@ function getStatusSnapshot(db) {
|
|
|
1252
1577
|
SELECT COUNT(*)
|
|
1253
1578
|
FROM artifacts
|
|
1254
1579
|
WHERE artifacts.task_key = tasks.task_key
|
|
1255
|
-
) AS artifact_count
|
|
1580
|
+
) AS artifact_count,
|
|
1581
|
+
(
|
|
1582
|
+
SELECT agent_name
|
|
1583
|
+
FROM agent_runs
|
|
1584
|
+
WHERE agent_runs.task_key = tasks.task_key
|
|
1585
|
+
ORDER BY CASE WHEN agent_runs.status IN ('queued', 'running') THEN 0 ELSE 1 END, updated_at DESC, started_at DESC
|
|
1586
|
+
LIMIT 1
|
|
1587
|
+
) AS latest_agent_name,
|
|
1588
|
+
(
|
|
1589
|
+
SELECT COUNT(*)
|
|
1590
|
+
FROM tasks AS child_tasks
|
|
1591
|
+
WHERE child_tasks.parent_task_key = tasks.task_key
|
|
1592
|
+
) AS child_task_count,
|
|
1593
|
+
(
|
|
1594
|
+
SELECT COUNT(*)
|
|
1595
|
+
FROM tasks AS child_tasks
|
|
1596
|
+
WHERE child_tasks.parent_task_key = tasks.task_key AND child_tasks.status = 'completed'
|
|
1597
|
+
) AS completed_child_task_count,
|
|
1598
|
+
(
|
|
1599
|
+
SELECT COUNT(*)
|
|
1600
|
+
FROM agent_runs AS handoff_runs
|
|
1601
|
+
WHERE handoff_runs.task_key = tasks.task_key AND handoff_runs.parent_run_key IS NOT NULL
|
|
1602
|
+
) AS handoff_count
|
|
1256
1603
|
FROM tasks
|
|
1257
1604
|
WHERE status IN ('queued', 'running')
|
|
1258
1605
|
ORDER BY updated_at DESC, created_at DESC
|
|
@@ -1260,7 +1607,7 @@ function getStatusSnapshot(db) {
|
|
|
1260
1607
|
|
|
1261
1608
|
const recentTasks = db.prepare(`
|
|
1262
1609
|
SELECT
|
|
1263
|
-
task_key, squad_slug, session_key, title, goal, status, created_by, created_at, updated_at, finished_at,
|
|
1610
|
+
task_key, squad_slug, session_key, task_kind, parent_task_key, title, goal, meta_json, status, created_by, created_at, updated_at, finished_at,
|
|
1264
1611
|
(
|
|
1265
1612
|
SELECT COUNT(*)
|
|
1266
1613
|
FROM agent_runs
|
|
@@ -1270,7 +1617,29 @@ function getStatusSnapshot(db) {
|
|
|
1270
1617
|
SELECT COUNT(*)
|
|
1271
1618
|
FROM artifacts
|
|
1272
1619
|
WHERE artifacts.task_key = tasks.task_key
|
|
1273
|
-
) AS artifact_count
|
|
1620
|
+
) AS artifact_count,
|
|
1621
|
+
(
|
|
1622
|
+
SELECT agent_name
|
|
1623
|
+
FROM agent_runs
|
|
1624
|
+
WHERE agent_runs.task_key = tasks.task_key
|
|
1625
|
+
ORDER BY CASE WHEN agent_runs.status IN ('queued', 'running') THEN 0 ELSE 1 END, updated_at DESC, started_at DESC
|
|
1626
|
+
LIMIT 1
|
|
1627
|
+
) AS latest_agent_name,
|
|
1628
|
+
(
|
|
1629
|
+
SELECT COUNT(*)
|
|
1630
|
+
FROM tasks AS child_tasks
|
|
1631
|
+
WHERE child_tasks.parent_task_key = tasks.task_key
|
|
1632
|
+
) AS child_task_count,
|
|
1633
|
+
(
|
|
1634
|
+
SELECT COUNT(*)
|
|
1635
|
+
FROM tasks AS child_tasks
|
|
1636
|
+
WHERE child_tasks.parent_task_key = tasks.task_key AND child_tasks.status = 'completed'
|
|
1637
|
+
) AS completed_child_task_count,
|
|
1638
|
+
(
|
|
1639
|
+
SELECT COUNT(*)
|
|
1640
|
+
FROM agent_runs AS handoff_runs
|
|
1641
|
+
WHERE handoff_runs.task_key = tasks.task_key AND handoff_runs.parent_run_key IS NOT NULL
|
|
1642
|
+
) AS handoff_count
|
|
1274
1643
|
FROM tasks
|
|
1275
1644
|
ORDER BY updated_at DESC, created_at DESC
|
|
1276
1645
|
LIMIT 20
|
|
@@ -1303,17 +1672,35 @@ function getStatusSnapshot(db) {
|
|
|
1303
1672
|
`).all();
|
|
1304
1673
|
|
|
1305
1674
|
for (const row of activeRuns) {
|
|
1306
|
-
|
|
1675
|
+
decorateRunSnapshotRow(row);
|
|
1307
1676
|
}
|
|
1308
1677
|
|
|
1309
1678
|
for (const row of recentRuns) {
|
|
1310
|
-
|
|
1679
|
+
decorateRunSnapshotRow(row);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
for (const row of activeTasks) {
|
|
1683
|
+
decorateTaskSnapshotRow(row);
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
for (const row of recentTasks) {
|
|
1687
|
+
decorateTaskSnapshotRow(row);
|
|
1311
1688
|
}
|
|
1312
1689
|
|
|
1313
1690
|
for (const row of recentContentItems) {
|
|
1314
1691
|
row.used_skills = parseJsonArray(row.used_skills_json);
|
|
1315
1692
|
}
|
|
1316
1693
|
|
|
1694
|
+
for (const row of recentExecutionEvents) {
|
|
1695
|
+
decorateExecutionEventSnapshotRow(row);
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
const activeLiveSessions = activeTasks.filter((task) => task.task_kind === 'live_session');
|
|
1699
|
+
const activeMicroTasks = activeTasks.filter((task) => task.task_kind === 'micro_task');
|
|
1700
|
+
const recentLiveSessions = recentTasks.filter((task) => task.task_kind === 'live_session');
|
|
1701
|
+
const recentMicroTasks = recentTasks.filter((task) => task.task_kind === 'micro_task');
|
|
1702
|
+
const recentHandoffs = recentExecutionEvents.filter((event) => event.event_type === 'handoff');
|
|
1703
|
+
|
|
1317
1704
|
return {
|
|
1318
1705
|
taskCounts,
|
|
1319
1706
|
counts,
|
|
@@ -1321,6 +1708,11 @@ function getStatusSnapshot(db) {
|
|
|
1321
1708
|
recentTasks,
|
|
1322
1709
|
activeRuns,
|
|
1323
1710
|
recentRuns,
|
|
1711
|
+
activeLiveSessions,
|
|
1712
|
+
activeMicroTasks,
|
|
1713
|
+
recentLiveSessions,
|
|
1714
|
+
recentMicroTasks,
|
|
1715
|
+
recentHandoffs,
|
|
1324
1716
|
recentArtifacts,
|
|
1325
1717
|
recentContentItems,
|
|
1326
1718
|
recentExecutionEvents
|
|
@@ -1374,6 +1766,7 @@ async function clearAgentSession(runtimeDir, agentName) {
|
|
|
1374
1766
|
async function logAgentEvent(db, runtimeDir, options) {
|
|
1375
1767
|
const agentName = String(options.agentName || 'unknown').trim();
|
|
1376
1768
|
const squadSlug = options.squadSlug ? String(options.squadSlug).trim() : null;
|
|
1769
|
+
const sessionKey = options.sessionKey ? String(options.sessionKey).trim() : null;
|
|
1377
1770
|
const isFinish = Boolean(options.finish);
|
|
1378
1771
|
const now = nowIso();
|
|
1379
1772
|
|
|
@@ -1442,6 +1835,7 @@ async function logAgentEvent(db, runtimeDir, options) {
|
|
|
1442
1835
|
taskKey = startTask(db, {
|
|
1443
1836
|
title: taskTitle,
|
|
1444
1837
|
squadSlug: null,
|
|
1838
|
+
sessionKey,
|
|
1445
1839
|
status: 'running',
|
|
1446
1840
|
createdBy: agentName
|
|
1447
1841
|
});
|
|
@@ -1450,10 +1844,11 @@ async function logAgentEvent(db, runtimeDir, options) {
|
|
|
1450
1844
|
agentName,
|
|
1451
1845
|
agentKind: 'official',
|
|
1452
1846
|
squadSlug: null,
|
|
1847
|
+
sessionKey,
|
|
1453
1848
|
title: taskTitle,
|
|
1454
1849
|
message: options.message || 'Iniciando'
|
|
1455
1850
|
});
|
|
1456
|
-
await writeAgentSession(runtimeDir, agentName, { runKey, taskKey, startedAt: now, finished: false });
|
|
1851
|
+
await writeAgentSession(runtimeDir, agentName, { runKey, taskKey, sessionKey, startedAt: now, finished: false });
|
|
1457
1852
|
} else {
|
|
1458
1853
|
appendRunEvent(db, {
|
|
1459
1854
|
runKey,
|
|
@@ -1487,6 +1882,549 @@ async function logAgentEvent(db, runtimeDir, options) {
|
|
|
1487
1882
|
return { runKey, taskKey };
|
|
1488
1883
|
}
|
|
1489
1884
|
|
|
1885
|
+
// --- Squad Investigations CRUD ---
|
|
1886
|
+
|
|
1887
|
+
function insertInvestigation(db, options = {}) {
|
|
1888
|
+
const slug = options.investigationSlug || `inv-${slugify(options.domain || 'unknown')}-${Date.now()}`;
|
|
1889
|
+
const now = nowIso();
|
|
1890
|
+
db.prepare(`
|
|
1891
|
+
INSERT OR REPLACE INTO squad_investigations
|
|
1892
|
+
(investigation_slug, domain, mode, dimensions_covered, total_dimensions,
|
|
1893
|
+
confidence, report_path, linked_squad_slug, created_at, updated_at)
|
|
1894
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1895
|
+
`).run(
|
|
1896
|
+
slug,
|
|
1897
|
+
String(options.domain || ''),
|
|
1898
|
+
String(options.mode || 'full'),
|
|
1899
|
+
Number(options.dimensionsCovered) || 0,
|
|
1900
|
+
Number(options.totalDimensions) || 7,
|
|
1901
|
+
Number(options.confidence) || 0,
|
|
1902
|
+
options.reportPath || null,
|
|
1903
|
+
options.linkedSquadSlug || null,
|
|
1904
|
+
now,
|
|
1905
|
+
now
|
|
1906
|
+
);
|
|
1907
|
+
return slug;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
function listInvestigations(db) {
|
|
1911
|
+
return db.prepare(`
|
|
1912
|
+
SELECT * FROM squad_investigations ORDER BY created_at DESC
|
|
1913
|
+
`).all();
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
function getInvestigation(db, slug) {
|
|
1917
|
+
return db.prepare(`
|
|
1918
|
+
SELECT * FROM squad_investigations WHERE investigation_slug = ?
|
|
1919
|
+
`).get(slug) || null;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
function linkInvestigation(db, investigationSlug, squadSlug) {
|
|
1923
|
+
const now = nowIso();
|
|
1924
|
+
const result = db.prepare(`
|
|
1925
|
+
UPDATE squad_investigations
|
|
1926
|
+
SET linked_squad_slug = ?, updated_at = ?
|
|
1927
|
+
WHERE investigation_slug = ?
|
|
1928
|
+
`).run(squadSlug, now, investigationSlug);
|
|
1929
|
+
return result.changes > 0;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
// --- Implementation Plans CRUD ---
|
|
1933
|
+
|
|
1934
|
+
function upsertImplementationPlan(db, options = {}) {
|
|
1935
|
+
const planId = options.planId || `plan-${slugify(options.projectName || 'proj')}-${Date.now()}`;
|
|
1936
|
+
const now = nowIso();
|
|
1937
|
+
db.prepare(`
|
|
1938
|
+
INSERT OR REPLACE INTO implementation_plans
|
|
1939
|
+
(plan_id, project_name, scope, feature_slug, status, classification,
|
|
1940
|
+
phases_total, phases_completed, source_artifacts, source_hash, created_at, updated_at)
|
|
1941
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1942
|
+
`).run(
|
|
1943
|
+
planId,
|
|
1944
|
+
options.projectName || null,
|
|
1945
|
+
options.scope || 'project',
|
|
1946
|
+
options.featureSlug || null,
|
|
1947
|
+
options.status || 'draft',
|
|
1948
|
+
options.classification || null,
|
|
1949
|
+
Number(options.phasesTotal) || 0,
|
|
1950
|
+
Number(options.phasesCompleted) || 0,
|
|
1951
|
+
options.sourceArtifacts ? JSON.stringify(options.sourceArtifacts) : null,
|
|
1952
|
+
options.sourceHash || null,
|
|
1953
|
+
now,
|
|
1954
|
+
now
|
|
1955
|
+
);
|
|
1956
|
+
return planId;
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
function getImplementationPlan(db, planId) {
|
|
1960
|
+
return db.prepare(`
|
|
1961
|
+
SELECT * FROM implementation_plans WHERE plan_id = ?
|
|
1962
|
+
`).get(planId) || null;
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
function listImplementationPlans(db) {
|
|
1966
|
+
return db.prepare(`
|
|
1967
|
+
SELECT * FROM implementation_plans ORDER BY created_at DESC
|
|
1968
|
+
`).all();
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
function updateImplementationPlanStatus(db, planId, status) {
|
|
1972
|
+
const now = nowIso();
|
|
1973
|
+
const result = db.prepare(`
|
|
1974
|
+
UPDATE implementation_plans SET status = ?, updated_at = ? WHERE plan_id = ?
|
|
1975
|
+
`).run(status, now, planId);
|
|
1976
|
+
return result.changes > 0;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
function upsertPlanPhase(db, planId, phaseNumber, title, status) {
|
|
1980
|
+
db.prepare(`
|
|
1981
|
+
INSERT OR REPLACE INTO plan_phases (plan_id, phase_number, title, status, completed_at)
|
|
1982
|
+
VALUES (?, ?, ?, ?, ?)
|
|
1983
|
+
`).run(
|
|
1984
|
+
planId,
|
|
1985
|
+
phaseNumber,
|
|
1986
|
+
title,
|
|
1987
|
+
status || 'pending',
|
|
1988
|
+
status === 'completed' ? nowIso() : null
|
|
1989
|
+
);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
function updatePlanPhaseStatus(db, planId, phaseNumber, status, notes) {
|
|
1993
|
+
const now = nowIso();
|
|
1994
|
+
const result = db.prepare(`
|
|
1995
|
+
UPDATE plan_phases SET status = ?, completed_at = ?, notes = ?
|
|
1996
|
+
WHERE plan_id = ? AND phase_number = ?
|
|
1997
|
+
`).run(
|
|
1998
|
+
status,
|
|
1999
|
+
status === 'completed' ? now : null,
|
|
2000
|
+
notes || null,
|
|
2001
|
+
planId,
|
|
2002
|
+
phaseNumber
|
|
2003
|
+
);
|
|
2004
|
+
if (result.changes > 0 && status === 'completed') {
|
|
2005
|
+
db.prepare(`
|
|
2006
|
+
UPDATE implementation_plans
|
|
2007
|
+
SET phases_completed = (SELECT COUNT(*) FROM plan_phases WHERE plan_id = ? AND status = 'completed'),
|
|
2008
|
+
updated_at = ?
|
|
2009
|
+
WHERE plan_id = ?
|
|
2010
|
+
`).run(planId, now, planId);
|
|
2011
|
+
}
|
|
2012
|
+
return result.changes > 0;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
function getPlanPhases(db, planId) {
|
|
2016
|
+
return db.prepare(`
|
|
2017
|
+
SELECT * FROM plan_phases WHERE plan_id = ? ORDER BY phase_number
|
|
2018
|
+
`).all(planId);
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
// --- Squad Execution Plans CRUD ---
|
|
2022
|
+
|
|
2023
|
+
function upsertSquadExecutionPlan(db, options = {}) {
|
|
2024
|
+
const planSlug = options.planSlug || `sqplan-${slugify(options.squadSlug || 'squad')}-${Date.now()}`;
|
|
2025
|
+
const now = nowIso();
|
|
2026
|
+
db.prepare(`
|
|
2027
|
+
INSERT OR REPLACE INTO squad_execution_plans
|
|
2028
|
+
(plan_slug, squad_slug, status, rounds_total, rounds_completed,
|
|
2029
|
+
based_on_blueprint, based_on_investigation, source_hash, created_at, updated_at)
|
|
2030
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2031
|
+
`).run(
|
|
2032
|
+
planSlug,
|
|
2033
|
+
options.squadSlug || '',
|
|
2034
|
+
options.status || 'draft',
|
|
2035
|
+
Number(options.roundsTotal) || 0,
|
|
2036
|
+
Number(options.roundsCompleted) || 0,
|
|
2037
|
+
options.basedOnBlueprint || null,
|
|
2038
|
+
options.basedOnInvestigation || null,
|
|
2039
|
+
options.sourceHash || null,
|
|
2040
|
+
now,
|
|
2041
|
+
now
|
|
2042
|
+
);
|
|
2043
|
+
return planSlug;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
function getSquadExecutionPlan(db, planSlug) {
|
|
2047
|
+
return db.prepare(`
|
|
2048
|
+
SELECT * FROM squad_execution_plans WHERE plan_slug = ?
|
|
2049
|
+
`).get(planSlug) || null;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
function getSquadExecutionPlanBySquad(db, squadSlug) {
|
|
2053
|
+
return db.prepare(`
|
|
2054
|
+
SELECT * FROM squad_execution_plans WHERE squad_slug = ? ORDER BY created_at DESC LIMIT 1
|
|
2055
|
+
`).get(squadSlug) || null;
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
function listSquadExecutionPlans(db) {
|
|
2059
|
+
return db.prepare(`
|
|
2060
|
+
SELECT * FROM squad_execution_plans ORDER BY created_at DESC
|
|
2061
|
+
`).all();
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
function updateSquadExecutionPlanStatus(db, planSlug, status) {
|
|
2065
|
+
const now = nowIso();
|
|
2066
|
+
const result = db.prepare(`
|
|
2067
|
+
UPDATE squad_execution_plans SET status = ?, updated_at = ? WHERE plan_slug = ?
|
|
2068
|
+
`).run(status, now, planSlug);
|
|
2069
|
+
return result.changes > 0;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
function upsertSquadPlanRound(db, planSlug, roundNumber, executorSlug, title, status) {
|
|
2073
|
+
db.prepare(`
|
|
2074
|
+
INSERT OR REPLACE INTO squad_plan_rounds (plan_slug, round_number, executor_slug, title, status, completed_at)
|
|
2075
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
2076
|
+
`).run(
|
|
2077
|
+
planSlug,
|
|
2078
|
+
roundNumber,
|
|
2079
|
+
executorSlug,
|
|
2080
|
+
title,
|
|
2081
|
+
status || 'pending',
|
|
2082
|
+
status === 'completed' ? nowIso() : null
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
function updateSquadPlanRoundStatus(db, planSlug, roundNumber, status, notes) {
|
|
2087
|
+
const now = nowIso();
|
|
2088
|
+
const result = db.prepare(`
|
|
2089
|
+
UPDATE squad_plan_rounds SET status = ?, completed_at = ?, notes = ?
|
|
2090
|
+
WHERE plan_slug = ? AND round_number = ?
|
|
2091
|
+
`).run(
|
|
2092
|
+
status,
|
|
2093
|
+
status === 'completed' ? now : null,
|
|
2094
|
+
notes || null,
|
|
2095
|
+
planSlug,
|
|
2096
|
+
roundNumber
|
|
2097
|
+
);
|
|
2098
|
+
if (result.changes > 0 && status === 'completed') {
|
|
2099
|
+
db.prepare(`
|
|
2100
|
+
UPDATE squad_execution_plans
|
|
2101
|
+
SET rounds_completed = (SELECT COUNT(*) FROM squad_plan_rounds WHERE plan_slug = ? AND status = 'completed'),
|
|
2102
|
+
updated_at = ?
|
|
2103
|
+
WHERE plan_slug = ?
|
|
2104
|
+
`).run(planSlug, now, planSlug);
|
|
2105
|
+
}
|
|
2106
|
+
return result.changes > 0;
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
function getSquadPlanRounds(db, planSlug) {
|
|
2110
|
+
return db.prepare(`
|
|
2111
|
+
SELECT * FROM squad_plan_rounds WHERE plan_slug = ? ORDER BY round_number
|
|
2112
|
+
`).all(planSlug);
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
// --- Squad Learnings CRUD ---
|
|
2116
|
+
|
|
2117
|
+
function insertSquadLearning(db, options = {}) {
|
|
2118
|
+
const learningId = options.learningId || `sl-${slugify(options.squadSlug || 'squad')}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
2119
|
+
const now = nowIso();
|
|
2120
|
+
db.prepare(`
|
|
2121
|
+
INSERT OR REPLACE INTO squad_learnings
|
|
2122
|
+
(learning_id, squad_slug, type, title, signal, confidence, frequency,
|
|
2123
|
+
last_reinforced, applies_to, file_path, promoted_to, status,
|
|
2124
|
+
source_session, evidence, created_at, updated_at)
|
|
2125
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2126
|
+
`).run(
|
|
2127
|
+
learningId,
|
|
2128
|
+
options.squadSlug || '',
|
|
2129
|
+
options.type || 'preference',
|
|
2130
|
+
options.title || '',
|
|
2131
|
+
options.signal || 'explicit',
|
|
2132
|
+
options.confidence || 'medium',
|
|
2133
|
+
Number(options.frequency) || 1,
|
|
2134
|
+
options.lastReinforced || now,
|
|
2135
|
+
options.appliesTo || 'squad',
|
|
2136
|
+
options.filePath || null,
|
|
2137
|
+
options.promotedTo || null,
|
|
2138
|
+
options.status || 'active',
|
|
2139
|
+
options.sourceSession || null,
|
|
2140
|
+
options.evidence || null,
|
|
2141
|
+
now,
|
|
2142
|
+
now
|
|
2143
|
+
);
|
|
2144
|
+
return learningId;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
function listSquadLearnings(db, squadSlug, statusFilter) {
|
|
2148
|
+
if (statusFilter) {
|
|
2149
|
+
return db.prepare(`
|
|
2150
|
+
SELECT * FROM squad_learnings WHERE squad_slug = ? AND status = ? ORDER BY created_at DESC
|
|
2151
|
+
`).all(squadSlug, statusFilter);
|
|
2152
|
+
}
|
|
2153
|
+
return db.prepare(`
|
|
2154
|
+
SELECT * FROM squad_learnings WHERE squad_slug = ? ORDER BY created_at DESC
|
|
2155
|
+
`).all(squadSlug);
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
function getSquadLearning(db, learningId) {
|
|
2159
|
+
return db.prepare(`
|
|
2160
|
+
SELECT * FROM squad_learnings WHERE learning_id = ?
|
|
2161
|
+
`).get(learningId) || null;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
function updateSquadLearningStatus(db, learningId, status) {
|
|
2165
|
+
const now = nowIso();
|
|
2166
|
+
const result = db.prepare(`
|
|
2167
|
+
UPDATE squad_learnings SET status = ?, updated_at = ? WHERE learning_id = ?
|
|
2168
|
+
`).run(status, now, learningId);
|
|
2169
|
+
return result.changes > 0;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
function reinforceSquadLearning(db, learningId) {
|
|
2173
|
+
const now = nowIso();
|
|
2174
|
+
const result = db.prepare(`
|
|
2175
|
+
UPDATE squad_learnings SET frequency = frequency + 1, last_reinforced = ?, updated_at = ? WHERE learning_id = ?
|
|
2176
|
+
`).run(now, now, learningId);
|
|
2177
|
+
return result.changes > 0;
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
function promoteSquadLearning(db, learningId, promotedTo) {
|
|
2181
|
+
const now = nowIso();
|
|
2182
|
+
const result = db.prepare(`
|
|
2183
|
+
UPDATE squad_learnings SET status = 'promoted', promoted_to = ?, updated_at = ? WHERE learning_id = ?
|
|
2184
|
+
`).run(promotedTo, now, learningId);
|
|
2185
|
+
return result.changes > 0;
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
function archiveStaleSquadLearnings(db, squadSlug, staleDays) {
|
|
2189
|
+
const days = Number(staleDays) || 90;
|
|
2190
|
+
const cutoff = new Date(Date.now() - days * 86400000).toISOString();
|
|
2191
|
+
const result = db.prepare(`
|
|
2192
|
+
UPDATE squad_learnings SET status = 'stale', updated_at = datetime('now')
|
|
2193
|
+
WHERE squad_slug = ? AND status = 'active' AND last_reinforced < ?
|
|
2194
|
+
`).run(squadSlug, cutoff);
|
|
2195
|
+
return result.changes;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
function getSquadLearningStats(db, squadSlug) {
|
|
2199
|
+
return db.prepare(`
|
|
2200
|
+
SELECT type, status, COUNT(*) as count FROM squad_learnings
|
|
2201
|
+
WHERE squad_slug = ? GROUP BY type, status ORDER BY type, status
|
|
2202
|
+
`).all(squadSlug);
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
// --- Project Learnings CRUD ---
|
|
2206
|
+
|
|
2207
|
+
function insertProjectLearning(db, options = {}) {
|
|
2208
|
+
const learningId = options.learningId || `pl-${slugify(options.projectName || 'proj')}-${Date.now()}`;
|
|
2209
|
+
const now = nowIso();
|
|
2210
|
+
db.prepare(`
|
|
2211
|
+
INSERT OR REPLACE INTO project_learnings
|
|
2212
|
+
(learning_id, project_name, feature_slug, type, title, confidence, frequency,
|
|
2213
|
+
last_reinforced, applies_to, promoted_to, status,
|
|
2214
|
+
source_session, evidence, created_at, updated_at)
|
|
2215
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2216
|
+
`).run(
|
|
2217
|
+
learningId,
|
|
2218
|
+
options.projectName || null,
|
|
2219
|
+
options.featureSlug || null,
|
|
2220
|
+
options.type || 'preference',
|
|
2221
|
+
options.title || '',
|
|
2222
|
+
options.confidence || 'medium',
|
|
2223
|
+
Number(options.frequency) || 1,
|
|
2224
|
+
options.lastReinforced || now,
|
|
2225
|
+
options.appliesTo || 'project',
|
|
2226
|
+
options.promotedTo || null,
|
|
2227
|
+
options.status || 'active',
|
|
2228
|
+
options.sourceSession || null,
|
|
2229
|
+
options.evidence || null,
|
|
2230
|
+
now,
|
|
2231
|
+
now
|
|
2232
|
+
);
|
|
2233
|
+
return learningId;
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
function listProjectLearnings(db, statusFilter) {
|
|
2237
|
+
if (statusFilter) {
|
|
2238
|
+
return db.prepare(`
|
|
2239
|
+
SELECT * FROM project_learnings WHERE status = ? ORDER BY created_at DESC
|
|
2240
|
+
`).all(statusFilter);
|
|
2241
|
+
}
|
|
2242
|
+
return db.prepare(`
|
|
2243
|
+
SELECT * FROM project_learnings ORDER BY created_at DESC
|
|
2244
|
+
`).all();
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
function getProjectLearning(db, learningId) {
|
|
2248
|
+
return db.prepare(`
|
|
2249
|
+
SELECT * FROM project_learnings WHERE learning_id = ?
|
|
2250
|
+
`).get(learningId) || null;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
function updateProjectLearningStatus(db, learningId, status) {
|
|
2254
|
+
const now = nowIso();
|
|
2255
|
+
const result = db.prepare(`
|
|
2256
|
+
UPDATE project_learnings SET status = ?, updated_at = ? WHERE learning_id = ?
|
|
2257
|
+
`).run(status, now, learningId);
|
|
2258
|
+
return result.changes > 0;
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
function reinforceProjectLearning(db, learningId) {
|
|
2262
|
+
const now = nowIso();
|
|
2263
|
+
const result = db.prepare(`
|
|
2264
|
+
UPDATE project_learnings SET frequency = frequency + 1, last_reinforced = ?, updated_at = ? WHERE learning_id = ?
|
|
2265
|
+
`).run(now, now, learningId);
|
|
2266
|
+
return result.changes > 0;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
function promoteProjectLearning(db, learningId, promotedTo) {
|
|
2270
|
+
const now = nowIso();
|
|
2271
|
+
const result = db.prepare(`
|
|
2272
|
+
UPDATE project_learnings SET status = 'promoted', promoted_to = ?, updated_at = ? WHERE learning_id = ?
|
|
2273
|
+
`).run(promotedTo, now, learningId);
|
|
2274
|
+
return result.changes > 0;
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
function getProjectLearningStats(db) {
|
|
2278
|
+
return db.prepare(`
|
|
2279
|
+
SELECT type, status, COUNT(*) as count FROM project_learnings
|
|
2280
|
+
GROUP BY type, status ORDER BY type, status
|
|
2281
|
+
`).all();
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
// --- Squad Metrics CRUD ---
|
|
2285
|
+
|
|
2286
|
+
function upsertSquadMetric(db, { squadSlug, metricKey, value, unit, period, baseline, target, source, notes }) {
|
|
2287
|
+
db.prepare(`
|
|
2288
|
+
INSERT INTO squad_metrics (squad_slug, metric_key, metric_value, metric_unit, period, baseline, target, source, notes)
|
|
2289
|
+
VALUES (@squad_slug, @metric_key, @metric_value, @metric_unit, @period, @baseline, @target, @source, @notes)
|
|
2290
|
+
ON CONFLICT(squad_slug, metric_key, period) DO UPDATE SET
|
|
2291
|
+
metric_value = excluded.metric_value,
|
|
2292
|
+
metric_unit = excluded.metric_unit,
|
|
2293
|
+
baseline = COALESCE(excluded.baseline, squad_metrics.baseline),
|
|
2294
|
+
target = COALESCE(excluded.target, squad_metrics.target),
|
|
2295
|
+
source = excluded.source,
|
|
2296
|
+
notes = COALESCE(excluded.notes, squad_metrics.notes)
|
|
2297
|
+
`).run({
|
|
2298
|
+
squad_slug: String(squadSlug).trim(),
|
|
2299
|
+
metric_key: String(metricKey).trim(),
|
|
2300
|
+
metric_value: Number(value),
|
|
2301
|
+
metric_unit: unit ? String(unit).trim() : null,
|
|
2302
|
+
period: period ? String(period).trim() : null,
|
|
2303
|
+
baseline: baseline != null ? Number(baseline) : null,
|
|
2304
|
+
target: target != null ? Number(target) : null,
|
|
2305
|
+
source: source ? String(source).trim() : 'manual',
|
|
2306
|
+
notes: notes ? String(notes).trim() : null
|
|
2307
|
+
});
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
function listSquadMetrics(db, squadSlug, period) {
|
|
2311
|
+
if (period) {
|
|
2312
|
+
return db.prepare(
|
|
2313
|
+
'SELECT * FROM squad_metrics WHERE squad_slug = ? AND period = ? ORDER BY metric_key ASC'
|
|
2314
|
+
).all(squadSlug, period);
|
|
2315
|
+
}
|
|
2316
|
+
return db.prepare(
|
|
2317
|
+
'SELECT * FROM squad_metrics WHERE squad_slug = ? ORDER BY period DESC, metric_key ASC'
|
|
2318
|
+
).all(squadSlug);
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
function deleteSquadMetric(db, squadSlug, metricKey, period) {
|
|
2322
|
+
db.prepare(
|
|
2323
|
+
'DELETE FROM squad_metrics WHERE squad_slug = ? AND metric_key = ? AND period = ?'
|
|
2324
|
+
).run(squadSlug, metricKey, period);
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
// --- Worker Runs CRUD ---
|
|
2328
|
+
|
|
2329
|
+
function insertWorkerRun(db, { squadSlug, workerSlug, triggerType, inputJson, outputJson, status, errorMessage, durationMs, attempt, conversationId }) {
|
|
2330
|
+
const now = nowIso();
|
|
2331
|
+
return db.prepare(`
|
|
2332
|
+
INSERT INTO worker_runs (squad_slug, worker_slug, trigger_type, input_json, output_json, status, error_message, duration_ms, attempt, conversation_id, created_at, completed_at)
|
|
2333
|
+
VALUES (@squad_slug, @worker_slug, @trigger_type, @input_json, @output_json, @status, @error_message, @duration_ms, @attempt, @conversation_id, @created_at, @completed_at)
|
|
2334
|
+
`).run({
|
|
2335
|
+
squad_slug: String(squadSlug).trim(),
|
|
2336
|
+
worker_slug: String(workerSlug).trim(),
|
|
2337
|
+
trigger_type: String(triggerType || 'manual').trim(),
|
|
2338
|
+
input_json: inputJson || null,
|
|
2339
|
+
output_json: outputJson || null,
|
|
2340
|
+
status: String(status || 'running').trim(),
|
|
2341
|
+
error_message: errorMessage || null,
|
|
2342
|
+
duration_ms: durationMs != null ? Number(durationMs) : null,
|
|
2343
|
+
attempt: Number(attempt || 1),
|
|
2344
|
+
conversation_id: conversationId || null,
|
|
2345
|
+
created_at: now,
|
|
2346
|
+
completed_at: (status === 'completed' || status === 'failed') ? now : null
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
function listWorkerRuns(db, squadSlug, limit = 50) {
|
|
2351
|
+
return db.prepare(
|
|
2352
|
+
'SELECT * FROM worker_runs WHERE squad_slug = ? ORDER BY created_at DESC, id DESC LIMIT ?'
|
|
2353
|
+
).all(squadSlug, limit);
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
function getWorkerRunStats(db, squadSlug) {
|
|
2357
|
+
return db.prepare(`
|
|
2358
|
+
SELECT worker_slug, status, COUNT(*) as count,
|
|
2359
|
+
AVG(duration_ms) as avg_duration_ms
|
|
2360
|
+
FROM worker_runs WHERE squad_slug = ?
|
|
2361
|
+
GROUP BY worker_slug, status
|
|
2362
|
+
ORDER BY worker_slug, status
|
|
2363
|
+
`).all(squadSlug);
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
// --- MCP Status CRUD ---
|
|
2367
|
+
|
|
2368
|
+
function upsertMcpStatus(db, { squadSlug, mcpSlug, connector, status, lastError }) {
|
|
2369
|
+
db.prepare(`
|
|
2370
|
+
INSERT INTO mcp_status (squad_slug, mcp_slug, connector, status, last_check, last_error)
|
|
2371
|
+
VALUES (?, ?, ?, ?, datetime('now'), ?)
|
|
2372
|
+
ON CONFLICT(squad_slug, mcp_slug) DO UPDATE SET
|
|
2373
|
+
connector = excluded.connector,
|
|
2374
|
+
status = excluded.status,
|
|
2375
|
+
last_check = excluded.last_check,
|
|
2376
|
+
last_error = excluded.last_error
|
|
2377
|
+
`).run(squadSlug, mcpSlug, connector, status || 'unconfigured', lastError || null);
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
function incrementMcpCalls(db, squadSlug, mcpSlug, failed) {
|
|
2381
|
+
if (failed) {
|
|
2382
|
+
db.prepare(`
|
|
2383
|
+
UPDATE mcp_status SET calls_total = calls_total + 1, calls_failed = calls_failed + 1
|
|
2384
|
+
WHERE squad_slug = ? AND mcp_slug = ?
|
|
2385
|
+
`).run(squadSlug, mcpSlug);
|
|
2386
|
+
} else {
|
|
2387
|
+
db.prepare(`
|
|
2388
|
+
UPDATE mcp_status SET calls_total = calls_total + 1
|
|
2389
|
+
WHERE squad_slug = ? AND mcp_slug = ?
|
|
2390
|
+
`).run(squadSlug, mcpSlug);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
function listMcpStatus(db, squadSlug) {
|
|
2395
|
+
return db.prepare('SELECT * FROM mcp_status WHERE squad_slug = ? ORDER BY mcp_slug').all(squadSlug);
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
function getMcpStatus(db, squadSlug, mcpSlug) {
|
|
2399
|
+
return db.prepare('SELECT * FROM mcp_status WHERE squad_slug = ? AND mcp_slug = ?').get(squadSlug, mcpSlug);
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
// --- ROI Config CRUD ---
|
|
2403
|
+
|
|
2404
|
+
function upsertROIConfig(db, { squadSlug, pricingModel, setupFee, monthlyFee, percentageFee, percentageBase, currency, contractMonths }) {
|
|
2405
|
+
db.prepare(`
|
|
2406
|
+
INSERT INTO squad_roi_config (squad_slug, pricing_model, setup_fee, monthly_fee, percentage_fee, percentage_base, currency, contract_months)
|
|
2407
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
2408
|
+
ON CONFLICT(squad_slug) DO UPDATE SET
|
|
2409
|
+
pricing_model = excluded.pricing_model,
|
|
2410
|
+
setup_fee = excluded.setup_fee,
|
|
2411
|
+
monthly_fee = excluded.monthly_fee,
|
|
2412
|
+
percentage_fee = excluded.percentage_fee,
|
|
2413
|
+
percentage_base = excluded.percentage_base,
|
|
2414
|
+
currency = excluded.currency,
|
|
2415
|
+
contract_months = excluded.contract_months,
|
|
2416
|
+
updated_at = datetime('now')
|
|
2417
|
+
`).run(squadSlug, pricingModel || 'fixed', setupFee || null, monthlyFee || null, percentageFee || null, percentageBase || null, currency || 'BRL', contractMonths || 12);
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
function getROIConfig(db, squadSlug) {
|
|
2421
|
+
return db.prepare('SELECT * FROM squad_roi_config WHERE squad_slug = ?').get(squadSlug);
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
function deleteROIConfig(db, squadSlug) {
|
|
2425
|
+
return db.prepare('DELETE FROM squad_roi_config WHERE squad_slug = ?').run(squadSlug);
|
|
2426
|
+
}
|
|
2427
|
+
|
|
1490
2428
|
module.exports = {
|
|
1491
2429
|
resolveRuntimePaths,
|
|
1492
2430
|
runtimeStoreExists,
|
|
@@ -1505,6 +2443,7 @@ module.exports = {
|
|
|
1505
2443
|
appendRunEvent,
|
|
1506
2444
|
logAgentEvent,
|
|
1507
2445
|
readAgentSession,
|
|
2446
|
+
writeAgentSession,
|
|
1508
2447
|
clearAgentSession,
|
|
1509
2448
|
// Pipeline CRUD
|
|
1510
2449
|
upsertPipeline,
|
|
@@ -1523,5 +2462,61 @@ module.exports = {
|
|
|
1523
2462
|
listArtisanSquads,
|
|
1524
2463
|
deleteArtisanSquad,
|
|
1525
2464
|
addArtisanMessage,
|
|
1526
|
-
getArtisanMessages
|
|
2465
|
+
getArtisanMessages,
|
|
2466
|
+
// Investigation CRUD
|
|
2467
|
+
insertInvestigation,
|
|
2468
|
+
listInvestigations,
|
|
2469
|
+
getInvestigation,
|
|
2470
|
+
linkInvestigation,
|
|
2471
|
+
// Implementation Plans CRUD
|
|
2472
|
+
upsertImplementationPlan,
|
|
2473
|
+
getImplementationPlan,
|
|
2474
|
+
listImplementationPlans,
|
|
2475
|
+
updateImplementationPlanStatus,
|
|
2476
|
+
upsertPlanPhase,
|
|
2477
|
+
updatePlanPhaseStatus,
|
|
2478
|
+
getPlanPhases,
|
|
2479
|
+
// Squad Execution Plans CRUD
|
|
2480
|
+
upsertSquadExecutionPlan,
|
|
2481
|
+
getSquadExecutionPlan,
|
|
2482
|
+
getSquadExecutionPlanBySquad,
|
|
2483
|
+
listSquadExecutionPlans,
|
|
2484
|
+
updateSquadExecutionPlanStatus,
|
|
2485
|
+
upsertSquadPlanRound,
|
|
2486
|
+
updateSquadPlanRoundStatus,
|
|
2487
|
+
getSquadPlanRounds,
|
|
2488
|
+
// Squad Learnings CRUD
|
|
2489
|
+
insertSquadLearning,
|
|
2490
|
+
listSquadLearnings,
|
|
2491
|
+
getSquadLearning,
|
|
2492
|
+
updateSquadLearningStatus,
|
|
2493
|
+
reinforceSquadLearning,
|
|
2494
|
+
promoteSquadLearning,
|
|
2495
|
+
archiveStaleSquadLearnings,
|
|
2496
|
+
getSquadLearningStats,
|
|
2497
|
+
// Project Learnings CRUD
|
|
2498
|
+
insertProjectLearning,
|
|
2499
|
+
listProjectLearnings,
|
|
2500
|
+
getProjectLearning,
|
|
2501
|
+
updateProjectLearningStatus,
|
|
2502
|
+
reinforceProjectLearning,
|
|
2503
|
+
promoteProjectLearning,
|
|
2504
|
+
getProjectLearningStats,
|
|
2505
|
+
// Squad Metrics CRUD
|
|
2506
|
+
upsertSquadMetric,
|
|
2507
|
+
listSquadMetrics,
|
|
2508
|
+
deleteSquadMetric,
|
|
2509
|
+
// Worker Runs CRUD
|
|
2510
|
+
insertWorkerRun,
|
|
2511
|
+
listWorkerRuns,
|
|
2512
|
+
getWorkerRunStats,
|
|
2513
|
+
// MCP Status CRUD
|
|
2514
|
+
upsertMcpStatus,
|
|
2515
|
+
incrementMcpCalls,
|
|
2516
|
+
listMcpStatus,
|
|
2517
|
+
getMcpStatus,
|
|
2518
|
+
// ROI Config CRUD
|
|
2519
|
+
upsertROIConfig,
|
|
2520
|
+
getROIConfig,
|
|
2521
|
+
deleteROIConfig
|
|
1527
2522
|
};
|