@jaimevalasek/aioson 1.4.0 → 1.6.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/CHANGELOG.md +31 -1
- package/LICENSE +661 -21
- package/README.md +9 -1
- package/docs/design-previews/aurora-command-ui-website.html +884 -0
- package/docs/design-previews/aurora-command-ui.html +682 -0
- package/docs/design-previews/bold-editorial-ui-website.html +658 -0
- package/docs/design-previews/bold-editorial-ui.html +717 -0
- package/docs/design-previews/clean-saas-ui-website.html +1202 -0
- package/docs/design-previews/clean-saas-ui.html +549 -0
- package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
- package/docs/design-previews/cognitive-core-ui.html +463 -0
- package/docs/design-previews/glassmorphism-ui-website.html +572 -0
- package/docs/design-previews/glassmorphism-ui.html +886 -0
- package/docs/design-previews/index.html +699 -0
- package/docs/design-previews/interface-design-website.html +1187 -0
- package/docs/design-previews/interface-design.html +513 -0
- package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
- package/docs/design-previews/neo-brutalist-ui.html +797 -0
- package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
- package/docs/design-previews/premium-command-center-ui.html +552 -0
- package/docs/design-previews/warm-craft-ui-website.html +684 -0
- package/docs/design-previews/warm-craft-ui.html +739 -0
- package/docs/en/cli-reference.md +20 -9
- package/docs/en/squad-dashboard.md +372 -0
- package/docs/openclaw-bridge.md +308 -0
- package/docs/pt/README.md +7 -0
- package/docs/pt/agent-sharding.md +132 -0
- package/docs/pt/agentes.md +131 -11
- package/docs/pt/busca-de-contexto.md +129 -0
- package/docs/pt/cache-de-contexto.md +156 -0
- package/docs/pt/cenarios.md +46 -2
- package/docs/pt/comandos-cli.md +88 -1
- package/docs/pt/design-hybrid-forge.md +107 -0
- package/docs/pt/inicio-rapido.md +72 -5
- package/docs/pt/inteligencia-adaptativa.md +324 -0
- package/docs/pt/monitor-de-contexto.md +104 -0
- package/docs/pt/recuperacao-de-sessao.md +125 -0
- package/docs/pt/sandbox.md +125 -0
- package/docs/pt/skills.md +98 -6
- package/docs/pt/squad-dashboard.md +373 -0
- package/docs/testing/genome-2.0-matrix.md +5 -5
- package/docs/testing/genome-2.0-rollout.md +9 -9
- package/package.json +2 -2
- package/src/agent-loader.js +280 -0
- package/src/backup-local.js +74 -0
- package/src/cli.js +192 -0
- package/src/commands/agent-loader.js +85 -0
- package/src/commands/backup-local-cmd.js +25 -0
- package/src/commands/context-cache.js +90 -0
- package/src/commands/context-monitor.js +92 -0
- package/src/commands/context-search.js +66 -0
- package/src/commands/design-hybrid-options.js +385 -0
- package/src/commands/health.js +214 -0
- package/src/commands/init.js +54 -13
- package/src/commands/install.js +52 -13
- package/src/commands/learning-evolve.js +355 -0
- package/src/commands/live.js +34 -0
- package/src/commands/recovery.js +43 -0
- package/src/commands/runtime.js +242 -0
- package/src/commands/sandbox.js +37 -0
- package/src/commands/setup-context.js +29 -4
- package/src/commands/setup.js +178 -0
- package/src/commands/skill.js +79 -32
- 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 +52 -0
- package/src/commands/squad-mcp.js +270 -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 +37 -1
- package/src/commands/squad-validate.js +62 -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/tool-registry-cmd.js +232 -0
- package/src/commands/update.js +7 -0
- package/src/commands/web-map.js +70 -0
- package/src/commands/web-scrape.js +71 -0
- package/src/constants.js +17 -0
- package/src/context-cache.js +159 -0
- package/src/context-search.js +326 -0
- package/src/context-writer.js +45 -1
- package/src/design-variation-catalog.js +503 -0
- package/src/i18n/messages/en.js +159 -3
- package/src/i18n/messages/es.js +147 -2
- package/src/i18n/messages/fr.js +147 -2
- package/src/i18n/messages/pt-BR.js +158 -3
- package/src/install-animation.js +260 -0
- package/src/install-profile.js +143 -0
- package/src/install-wizard.js +474 -0
- package/src/installer.js +38 -10
- package/src/lib/webhook-server.js +328 -0
- package/src/mcp-connectors/registry.js +602 -0
- package/src/parser.js +7 -1
- package/src/recovery-context-session.js +154 -0
- package/src/runtime-store.js +355 -2
- package/src/sandbox.js +177 -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/tool-executor.js +94 -0
- package/src/updater.js +11 -3
- package/src/web.js +284 -0
- package/src/worker-runner.js +339 -0
- package/template/.aioson/agents/analyst.md +62 -3
- package/template/.aioson/agents/architect.md +42 -0
- package/template/.aioson/agents/design-hybrid-forge.md +127 -0
- package/template/.aioson/agents/dev.md +223 -11
- package/template/.aioson/agents/deyvin.md +65 -0
- package/template/.aioson/agents/neo.md +152 -0
- package/template/.aioson/agents/orache.md +17 -0
- package/template/.aioson/agents/orchestrator.md +26 -0
- package/template/.aioson/agents/pm.md +58 -0
- package/template/.aioson/agents/product.md +88 -12
- package/template/.aioson/agents/qa.md +80 -0
- package/template/.aioson/agents/setup.md +128 -22
- package/template/.aioson/agents/sheldon.md +704 -0
- package/template/.aioson/agents/squad.md +191 -0
- package/template/.aioson/agents/tester.md +410 -0
- package/template/.aioson/agents/ux-ui.md +12 -0
- package/template/.aioson/config.md +21 -0
- package/template/.aioson/context/forensics/.gitkeep +0 -0
- package/template/.aioson/context/seeds/seed-example.md +27 -0
- package/template/.aioson/context/user-profile.md +42 -0
- package/template/.aioson/locales/en/agents/analyst.md +8 -0
- package/template/.aioson/locales/en/agents/architect.md +8 -0
- package/template/.aioson/locales/en/agents/dev.md +66 -7
- package/template/.aioson/locales/en/agents/deyvin.md +8 -0
- package/template/.aioson/locales/en/agents/neo.md +8 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/en/agents/qa.md +49 -0
- package/template/.aioson/locales/en/agents/setup.md +35 -2
- package/template/.aioson/locales/en/agents/sheldon.md +340 -0
- package/template/.aioson/locales/en/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/es/agents/analyst.md +8 -0
- package/template/.aioson/locales/es/agents/architect.md +8 -0
- package/template/.aioson/locales/es/agents/dev.md +66 -7
- package/template/.aioson/locales/es/agents/deyvin.md +8 -0
- package/template/.aioson/locales/es/agents/neo.md +48 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/es/agents/qa.md +26 -0
- package/template/.aioson/locales/es/agents/setup.md +35 -2
- package/template/.aioson/locales/es/agents/sheldon.md +192 -0
- package/template/.aioson/locales/es/agents/squad.md +63 -0
- package/template/.aioson/locales/es/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/fr/agents/analyst.md +8 -0
- package/template/.aioson/locales/fr/agents/architect.md +8 -0
- package/template/.aioson/locales/fr/agents/dev.md +66 -7
- package/template/.aioson/locales/fr/agents/deyvin.md +8 -0
- package/template/.aioson/locales/fr/agents/neo.md +48 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/fr/agents/qa.md +26 -0
- package/template/.aioson/locales/fr/agents/setup.md +35 -2
- package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
- package/template/.aioson/locales/fr/agents/squad.md +63 -0
- package/template/.aioson/locales/fr/agents/ux-ui.md +8 -0
- package/template/.aioson/locales/pt-BR/agents/analyst.md +19 -0
- package/template/.aioson/locales/pt-BR/agents/architect.md +19 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +75 -12
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +8 -0
- package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/pt-BR/agents/product.md +8 -3
- package/template/.aioson/locales/pt-BR/agents/qa.md +60 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +35 -2
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
- package/template/.aioson/locales/pt-BR/agents/squad.md +105 -0
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +8 -0
- package/template/.aioson/schemas/squad-blueprint.schema.json +21 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +178 -1
- package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
- 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 +55 -9
- 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 +1 -1
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +100 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +43 -9
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +40 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +99 -12
- package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -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/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/process/aioson-spec-driven/SKILL.md +45 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +66 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
- package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +144 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +291 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +117 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +188 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -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/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/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 +19 -0
- package/template/.aioson/tasks/squad-design.md +28 -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/.claude/commands/aioson/agent/neo.md +5 -0
- package/template/.claude/commands/aioson/agent/tester.md +5 -0
- package/template/.gemini/GEMINI.md +1 -0
- package/template/.gemini/commands/aios-neo.toml +4 -0
- package/template/.gemini/commands/aios-tester.toml +6 -0
- package/template/AGENTS.md +26 -1
- package/template/CLAUDE.md +6 -2
- package/template/OPENCODE.md +2 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { execFile } = require('node:child_process');
|
|
6
|
+
const { promisify } = require('node:util');
|
|
7
|
+
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
|
|
10
|
+
const CONTEXT_DIR = path.join('.aioson', 'context');
|
|
11
|
+
const RECOVERY_FILE = 'recovery-context.md';
|
|
12
|
+
const MAX_TOKENS = 2000;
|
|
13
|
+
|
|
14
|
+
function estimateTokens(str) {
|
|
15
|
+
return Math.ceil(str.length / 4);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function readRecentGitLog(cwd, limit = 10) {
|
|
19
|
+
try {
|
|
20
|
+
const { stdout } = await execFileAsync('git', [
|
|
21
|
+
'log', `--max-count=${limit}`, '--oneline', '--no-merges'
|
|
22
|
+
], { cwd });
|
|
23
|
+
return stdout.trim().split('\n').filter(Boolean);
|
|
24
|
+
} catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function readModifiedFiles(cwd) {
|
|
30
|
+
try {
|
|
31
|
+
const { stdout } = await execFileAsync('git', [
|
|
32
|
+
'diff', '--name-only', 'HEAD'
|
|
33
|
+
], { cwd });
|
|
34
|
+
return stdout.trim().split('\n').filter(Boolean);
|
|
35
|
+
} catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function buildSessionRecoveryMarkdown(sessionState, gitLog, modifiedFiles) {
|
|
41
|
+
const lines = [];
|
|
42
|
+
|
|
43
|
+
lines.push('# Recovery Context — Direct Session');
|
|
44
|
+
lines.push(`> Generated: ${new Date().toISOString()}`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
|
|
47
|
+
// Session goal/task
|
|
48
|
+
if (sessionState.goal) {
|
|
49
|
+
lines.push('## Current Goal');
|
|
50
|
+
lines.push(sessionState.goal);
|
|
51
|
+
lines.push('');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Active agent
|
|
55
|
+
if (sessionState.agent) {
|
|
56
|
+
lines.push('## Active Agent');
|
|
57
|
+
lines.push(sessionState.agent);
|
|
58
|
+
lines.push('');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Tasks
|
|
62
|
+
const tasks = Array.isArray(sessionState.tasks) ? sessionState.tasks : [];
|
|
63
|
+
if (tasks.length > 0) {
|
|
64
|
+
lines.push('## Tasks');
|
|
65
|
+
for (const t of tasks.slice(-5)) {
|
|
66
|
+
const status = t.status || 'unknown';
|
|
67
|
+
const title = t.title || t.id || '(untitled)';
|
|
68
|
+
lines.push(`- [${status}] ${title}`);
|
|
69
|
+
}
|
|
70
|
+
lines.push('');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Notes
|
|
74
|
+
const notes = Array.isArray(sessionState.notes) ? sessionState.notes : [];
|
|
75
|
+
if (notes.length > 0) {
|
|
76
|
+
lines.push('## Notes');
|
|
77
|
+
for (const note of notes.slice(-5)) {
|
|
78
|
+
lines.push(`- ${note}`);
|
|
79
|
+
}
|
|
80
|
+
lines.push('');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Modified files
|
|
84
|
+
if (modifiedFiles.length > 0) {
|
|
85
|
+
lines.push('## Modified Files');
|
|
86
|
+
for (const f of modifiedFiles.slice(0, 10)) {
|
|
87
|
+
lines.push(`- ${f}`);
|
|
88
|
+
}
|
|
89
|
+
lines.push('');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Recent git commits
|
|
93
|
+
if (gitLog.length > 0) {
|
|
94
|
+
lines.push('## Recent Commits');
|
|
95
|
+
for (const entry of gitLog.slice(0, 5)) {
|
|
96
|
+
lines.push(`- ${entry}`);
|
|
97
|
+
}
|
|
98
|
+
lines.push('');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
lines.push('---');
|
|
102
|
+
lines.push('*Inject this file at the top of your next session to restore context after a compact.*');
|
|
103
|
+
|
|
104
|
+
return lines.join('\n');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Generate and write recovery-context.md for a direct session (no squad).
|
|
109
|
+
* @param {string} cwd — project root directory
|
|
110
|
+
* @param {object} sessionState — { goal?, agent?, tasks?, notes? }
|
|
111
|
+
* @returns {{ ok: boolean, path: string, tokens: number }}
|
|
112
|
+
*/
|
|
113
|
+
async function generateSessionRecovery(cwd, sessionState = {}) {
|
|
114
|
+
const [gitLog, modifiedFiles] = await Promise.all([
|
|
115
|
+
readRecentGitLog(cwd),
|
|
116
|
+
readModifiedFiles(cwd)
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
let content = buildSessionRecoveryMarkdown(sessionState, gitLog, modifiedFiles);
|
|
120
|
+
|
|
121
|
+
// Enforce token budget
|
|
122
|
+
if (estimateTokens(content) > MAX_TOKENS) {
|
|
123
|
+
content = buildSessionRecoveryMarkdown(sessionState, gitLog.slice(0, 3), modifiedFiles.slice(0, 5));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const tokens = estimateTokens(content);
|
|
127
|
+
const outDir = path.join(cwd, CONTEXT_DIR);
|
|
128
|
+
const outPath = path.join(outDir, RECOVERY_FILE);
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
132
|
+
await fs.writeFile(outPath, content, 'utf8');
|
|
133
|
+
} catch (err) {
|
|
134
|
+
return { ok: false, error: err.message, path: outPath, tokens };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { ok: true, path: outPath, tokens };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Read the current session recovery-context.md (returns null if missing).
|
|
142
|
+
* @param {string} cwd
|
|
143
|
+
* @returns {string|null}
|
|
144
|
+
*/
|
|
145
|
+
async function readSessionRecovery(cwd) {
|
|
146
|
+
const p = path.join(cwd, CONTEXT_DIR, RECOVERY_FILE);
|
|
147
|
+
try {
|
|
148
|
+
return await fs.readFile(p, 'utf8');
|
|
149
|
+
} catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = { generateSessionRecovery, readSessionRecovery };
|
package/src/runtime-store.js
CHANGED
|
@@ -496,6 +496,100 @@ async function openRuntimeDb(targetDir, options = {}) {
|
|
|
496
496
|
CREATE INDEX IF NOT EXISTS idx_squad_learnings_status ON squad_learnings(status);
|
|
497
497
|
CREATE INDEX IF NOT EXISTS idx_project_learnings_type ON project_learnings(type);
|
|
498
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
|
+
);
|
|
499
593
|
`);
|
|
500
594
|
|
|
501
595
|
ensureLegacyColumns(db);
|
|
@@ -597,6 +691,36 @@ function ensureLegacyColumns(db) {
|
|
|
597
691
|
if (!contentItemColumnNames.has('used_skills_json')) {
|
|
598
692
|
db.exec('ALTER TABLE content_items ADD COLUMN used_skills_json TEXT');
|
|
599
693
|
}
|
|
694
|
+
|
|
695
|
+
try { db.exec('ALTER TABLE worker_runs ADD COLUMN conversation_id TEXT'); } catch { /* já existe */ }
|
|
696
|
+
|
|
697
|
+
// Dynamic Tools (Feature: Tool Registry)
|
|
698
|
+
db.exec(`
|
|
699
|
+
CREATE TABLE IF NOT EXISTS dynamic_tools (
|
|
700
|
+
name TEXT PRIMARY KEY,
|
|
701
|
+
description TEXT NOT NULL,
|
|
702
|
+
input_schema TEXT NOT NULL DEFAULT '{}',
|
|
703
|
+
handler_type TEXT NOT NULL DEFAULT 'shell',
|
|
704
|
+
handler_code TEXT,
|
|
705
|
+
handler_path TEXT,
|
|
706
|
+
squad_slug TEXT,
|
|
707
|
+
registered_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
708
|
+
registered_by TEXT
|
|
709
|
+
);
|
|
710
|
+
CREATE INDEX IF NOT EXISTS idx_dynamic_tools_squad ON dynamic_tools(squad_slug);
|
|
711
|
+
`);
|
|
712
|
+
|
|
713
|
+
// Evolution Log (Feature: Learning Evolution Pipeline)
|
|
714
|
+
db.exec(`
|
|
715
|
+
CREATE TABLE IF NOT EXISTS evolution_log (
|
|
716
|
+
id TEXT PRIMARY KEY,
|
|
717
|
+
applied_at TEXT NOT NULL,
|
|
718
|
+
deltas_count INTEGER NOT NULL DEFAULT 0,
|
|
719
|
+
squad_slug TEXT,
|
|
720
|
+
files_json TEXT,
|
|
721
|
+
source_learning_ids_json TEXT
|
|
722
|
+
);
|
|
723
|
+
`);
|
|
600
724
|
}
|
|
601
725
|
|
|
602
726
|
function insertEvent(db, record) {
|
|
@@ -2019,7 +2143,7 @@ function getSquadPlanRounds(db, planSlug) {
|
|
|
2019
2143
|
// --- Squad Learnings CRUD ---
|
|
2020
2144
|
|
|
2021
2145
|
function insertSquadLearning(db, options = {}) {
|
|
2022
|
-
const learningId = options.learningId || `sl-${slugify(options.squadSlug || 'squad')}-${Date.now()}`;
|
|
2146
|
+
const learningId = options.learningId || `sl-${slugify(options.squadSlug || 'squad')}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
2023
2147
|
const now = nowIso();
|
|
2024
2148
|
db.prepare(`
|
|
2025
2149
|
INSERT OR REPLACE INTO squad_learnings
|
|
@@ -2185,6 +2309,210 @@ function getProjectLearningStats(db) {
|
|
|
2185
2309
|
`).all();
|
|
2186
2310
|
}
|
|
2187
2311
|
|
|
2312
|
+
// --- Squad Metrics CRUD ---
|
|
2313
|
+
|
|
2314
|
+
function upsertSquadMetric(db, { squadSlug, metricKey, value, unit, period, baseline, target, source, notes }) {
|
|
2315
|
+
db.prepare(`
|
|
2316
|
+
INSERT INTO squad_metrics (squad_slug, metric_key, metric_value, metric_unit, period, baseline, target, source, notes)
|
|
2317
|
+
VALUES (@squad_slug, @metric_key, @metric_value, @metric_unit, @period, @baseline, @target, @source, @notes)
|
|
2318
|
+
ON CONFLICT(squad_slug, metric_key, period) DO UPDATE SET
|
|
2319
|
+
metric_value = excluded.metric_value,
|
|
2320
|
+
metric_unit = excluded.metric_unit,
|
|
2321
|
+
baseline = COALESCE(excluded.baseline, squad_metrics.baseline),
|
|
2322
|
+
target = COALESCE(excluded.target, squad_metrics.target),
|
|
2323
|
+
source = excluded.source,
|
|
2324
|
+
notes = COALESCE(excluded.notes, squad_metrics.notes)
|
|
2325
|
+
`).run({
|
|
2326
|
+
squad_slug: String(squadSlug).trim(),
|
|
2327
|
+
metric_key: String(metricKey).trim(),
|
|
2328
|
+
metric_value: Number(value),
|
|
2329
|
+
metric_unit: unit ? String(unit).trim() : null,
|
|
2330
|
+
period: period ? String(period).trim() : null,
|
|
2331
|
+
baseline: baseline != null ? Number(baseline) : null,
|
|
2332
|
+
target: target != null ? Number(target) : null,
|
|
2333
|
+
source: source ? String(source).trim() : 'manual',
|
|
2334
|
+
notes: notes ? String(notes).trim() : null
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
function listSquadMetrics(db, squadSlug, period) {
|
|
2339
|
+
if (period) {
|
|
2340
|
+
return db.prepare(
|
|
2341
|
+
'SELECT * FROM squad_metrics WHERE squad_slug = ? AND period = ? ORDER BY metric_key ASC'
|
|
2342
|
+
).all(squadSlug, period);
|
|
2343
|
+
}
|
|
2344
|
+
return db.prepare(
|
|
2345
|
+
'SELECT * FROM squad_metrics WHERE squad_slug = ? ORDER BY period DESC, metric_key ASC'
|
|
2346
|
+
).all(squadSlug);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
function deleteSquadMetric(db, squadSlug, metricKey, period) {
|
|
2350
|
+
db.prepare(
|
|
2351
|
+
'DELETE FROM squad_metrics WHERE squad_slug = ? AND metric_key = ? AND period = ?'
|
|
2352
|
+
).run(squadSlug, metricKey, period);
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
// --- Worker Runs CRUD ---
|
|
2356
|
+
|
|
2357
|
+
function insertWorkerRun(db, { squadSlug, workerSlug, triggerType, inputJson, outputJson, status, errorMessage, durationMs, attempt, conversationId }) {
|
|
2358
|
+
const now = nowIso();
|
|
2359
|
+
return db.prepare(`
|
|
2360
|
+
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)
|
|
2361
|
+
VALUES (@squad_slug, @worker_slug, @trigger_type, @input_json, @output_json, @status, @error_message, @duration_ms, @attempt, @conversation_id, @created_at, @completed_at)
|
|
2362
|
+
`).run({
|
|
2363
|
+
squad_slug: String(squadSlug).trim(),
|
|
2364
|
+
worker_slug: String(workerSlug).trim(),
|
|
2365
|
+
trigger_type: String(triggerType || 'manual').trim(),
|
|
2366
|
+
input_json: inputJson || null,
|
|
2367
|
+
output_json: outputJson || null,
|
|
2368
|
+
status: String(status || 'running').trim(),
|
|
2369
|
+
error_message: errorMessage || null,
|
|
2370
|
+
duration_ms: durationMs != null ? Number(durationMs) : null,
|
|
2371
|
+
attempt: Number(attempt || 1),
|
|
2372
|
+
conversation_id: conversationId || null,
|
|
2373
|
+
created_at: now,
|
|
2374
|
+
completed_at: (status === 'completed' || status === 'failed') ? now : null
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
function listWorkerRuns(db, squadSlug, limit = 50) {
|
|
2379
|
+
return db.prepare(
|
|
2380
|
+
'SELECT * FROM worker_runs WHERE squad_slug = ? ORDER BY created_at DESC, id DESC LIMIT ?'
|
|
2381
|
+
).all(squadSlug, limit);
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
function getWorkerRunStats(db, squadSlug) {
|
|
2385
|
+
return db.prepare(`
|
|
2386
|
+
SELECT worker_slug, status, COUNT(*) as count,
|
|
2387
|
+
AVG(duration_ms) as avg_duration_ms
|
|
2388
|
+
FROM worker_runs WHERE squad_slug = ?
|
|
2389
|
+
GROUP BY worker_slug, status
|
|
2390
|
+
ORDER BY worker_slug, status
|
|
2391
|
+
`).all(squadSlug);
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
// --- MCP Status CRUD ---
|
|
2395
|
+
|
|
2396
|
+
function upsertMcpStatus(db, { squadSlug, mcpSlug, connector, status, lastError }) {
|
|
2397
|
+
db.prepare(`
|
|
2398
|
+
INSERT INTO mcp_status (squad_slug, mcp_slug, connector, status, last_check, last_error)
|
|
2399
|
+
VALUES (?, ?, ?, ?, datetime('now'), ?)
|
|
2400
|
+
ON CONFLICT(squad_slug, mcp_slug) DO UPDATE SET
|
|
2401
|
+
connector = excluded.connector,
|
|
2402
|
+
status = excluded.status,
|
|
2403
|
+
last_check = excluded.last_check,
|
|
2404
|
+
last_error = excluded.last_error
|
|
2405
|
+
`).run(squadSlug, mcpSlug, connector, status || 'unconfigured', lastError || null);
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
function incrementMcpCalls(db, squadSlug, mcpSlug, failed) {
|
|
2409
|
+
if (failed) {
|
|
2410
|
+
db.prepare(`
|
|
2411
|
+
UPDATE mcp_status SET calls_total = calls_total + 1, calls_failed = calls_failed + 1
|
|
2412
|
+
WHERE squad_slug = ? AND mcp_slug = ?
|
|
2413
|
+
`).run(squadSlug, mcpSlug);
|
|
2414
|
+
} else {
|
|
2415
|
+
db.prepare(`
|
|
2416
|
+
UPDATE mcp_status SET calls_total = calls_total + 1
|
|
2417
|
+
WHERE squad_slug = ? AND mcp_slug = ?
|
|
2418
|
+
`).run(squadSlug, mcpSlug);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
function listMcpStatus(db, squadSlug) {
|
|
2423
|
+
return db.prepare('SELECT * FROM mcp_status WHERE squad_slug = ? ORDER BY mcp_slug').all(squadSlug);
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
function getMcpStatus(db, squadSlug, mcpSlug) {
|
|
2427
|
+
return db.prepare('SELECT * FROM mcp_status WHERE squad_slug = ? AND mcp_slug = ?').get(squadSlug, mcpSlug);
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
// --- ROI Config CRUD ---
|
|
2431
|
+
|
|
2432
|
+
function upsertROIConfig(db, { squadSlug, pricingModel, setupFee, monthlyFee, percentageFee, percentageBase, currency, contractMonths }) {
|
|
2433
|
+
db.prepare(`
|
|
2434
|
+
INSERT INTO squad_roi_config (squad_slug, pricing_model, setup_fee, monthly_fee, percentage_fee, percentage_base, currency, contract_months)
|
|
2435
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
2436
|
+
ON CONFLICT(squad_slug) DO UPDATE SET
|
|
2437
|
+
pricing_model = excluded.pricing_model,
|
|
2438
|
+
setup_fee = excluded.setup_fee,
|
|
2439
|
+
monthly_fee = excluded.monthly_fee,
|
|
2440
|
+
percentage_fee = excluded.percentage_fee,
|
|
2441
|
+
percentage_base = excluded.percentage_base,
|
|
2442
|
+
currency = excluded.currency,
|
|
2443
|
+
contract_months = excluded.contract_months,
|
|
2444
|
+
updated_at = datetime('now')
|
|
2445
|
+
`).run(squadSlug, pricingModel || 'fixed', setupFee || null, monthlyFee || null, percentageFee || null, percentageBase || null, currency || 'BRL', contractMonths || 12);
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
function getROIConfig(db, squadSlug) {
|
|
2449
|
+
return db.prepare('SELECT * FROM squad_roi_config WHERE squad_slug = ?').get(squadSlug);
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
function deleteROIConfig(db, squadSlug) {
|
|
2453
|
+
return db.prepare('DELETE FROM squad_roi_config WHERE squad_slug = ?').run(squadSlug);
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
// ─── Dynamic Tools CRUD ───────────────────────────────────────────────────────
|
|
2457
|
+
|
|
2458
|
+
function registerDynamicTool(db, opts) {
|
|
2459
|
+
const now = nowIso();
|
|
2460
|
+
db.prepare(`
|
|
2461
|
+
INSERT OR REPLACE INTO dynamic_tools
|
|
2462
|
+
(name, description, input_schema, handler_type, handler_code, handler_path, squad_slug, registered_at, registered_by)
|
|
2463
|
+
VALUES
|
|
2464
|
+
(@name, @description, @inputSchema, @handlerType, @handlerCode, @handlerPath, @squadSlug, @registeredAt, @registeredBy)
|
|
2465
|
+
`).run({
|
|
2466
|
+
name: String(opts.name),
|
|
2467
|
+
description: String(opts.description),
|
|
2468
|
+
inputSchema: opts.inputSchema ? JSON.stringify(opts.inputSchema) : '{}',
|
|
2469
|
+
handlerType: String(opts.handlerType || 'shell'),
|
|
2470
|
+
handlerCode: opts.handlerCode || null,
|
|
2471
|
+
handlerPath: opts.handlerPath || null,
|
|
2472
|
+
squadSlug: opts.squadSlug || null,
|
|
2473
|
+
registeredAt: now,
|
|
2474
|
+
registeredBy: opts.registeredBy || null
|
|
2475
|
+
});
|
|
2476
|
+
return opts.name;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
function unregisterDynamicTool(db, name) {
|
|
2480
|
+
return db.prepare('DELETE FROM dynamic_tools WHERE name = ?').run(name);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
function getDynamicTool(db, name) {
|
|
2484
|
+
return db.prepare('SELECT * FROM dynamic_tools WHERE name = ?').get(name) || null;
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
function listDynamicTools(db, squadSlug = null) {
|
|
2488
|
+
if (squadSlug) {
|
|
2489
|
+
return db.prepare('SELECT * FROM dynamic_tools WHERE squad_slug = ? ORDER BY registered_at DESC').all(squadSlug);
|
|
2490
|
+
}
|
|
2491
|
+
return db.prepare('SELECT * FROM dynamic_tools ORDER BY registered_at DESC').all();
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// ─── Evolution Log CRUD ───────────────────────────────────────────────────────
|
|
2495
|
+
|
|
2496
|
+
function insertEvolutionLog(db, opts) {
|
|
2497
|
+
const id = `evo-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
2498
|
+
db.prepare(`
|
|
2499
|
+
INSERT INTO evolution_log (id, applied_at, deltas_count, squad_slug, files_json, source_learning_ids_json)
|
|
2500
|
+
VALUES (@id, @appliedAt, @deltasCount, @squadSlug, @filesJson, @sourceIdsJson)
|
|
2501
|
+
`).run({
|
|
2502
|
+
id,
|
|
2503
|
+
appliedAt: nowIso(),
|
|
2504
|
+
deltasCount: Number(opts.deltasCount || 0),
|
|
2505
|
+
squadSlug: opts.squadSlug || null,
|
|
2506
|
+
filesJson: JSON.stringify(opts.files || []),
|
|
2507
|
+
sourceIdsJson: JSON.stringify(opts.sourceLearningIds || [])
|
|
2508
|
+
});
|
|
2509
|
+
return id;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
function listEvolutionLog(db, limit = 20) {
|
|
2513
|
+
return db.prepare('SELECT * FROM evolution_log ORDER BY applied_at DESC LIMIT ?').all(limit);
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2188
2516
|
module.exports = {
|
|
2189
2517
|
resolveRuntimePaths,
|
|
2190
2518
|
runtimeStoreExists,
|
|
@@ -2261,5 +2589,30 @@ module.exports = {
|
|
|
2261
2589
|
updateProjectLearningStatus,
|
|
2262
2590
|
reinforceProjectLearning,
|
|
2263
2591
|
promoteProjectLearning,
|
|
2264
|
-
getProjectLearningStats
|
|
2592
|
+
getProjectLearningStats,
|
|
2593
|
+
// Squad Metrics CRUD
|
|
2594
|
+
upsertSquadMetric,
|
|
2595
|
+
listSquadMetrics,
|
|
2596
|
+
deleteSquadMetric,
|
|
2597
|
+
// Worker Runs CRUD
|
|
2598
|
+
insertWorkerRun,
|
|
2599
|
+
listWorkerRuns,
|
|
2600
|
+
getWorkerRunStats,
|
|
2601
|
+
// MCP Status CRUD
|
|
2602
|
+
upsertMcpStatus,
|
|
2603
|
+
incrementMcpCalls,
|
|
2604
|
+
listMcpStatus,
|
|
2605
|
+
getMcpStatus,
|
|
2606
|
+
// ROI Config CRUD
|
|
2607
|
+
upsertROIConfig,
|
|
2608
|
+
getROIConfig,
|
|
2609
|
+
deleteROIConfig,
|
|
2610
|
+
// Dynamic Tools CRUD
|
|
2611
|
+
registerDynamicTool,
|
|
2612
|
+
unregisterDynamicTool,
|
|
2613
|
+
getDynamicTool,
|
|
2614
|
+
listDynamicTools,
|
|
2615
|
+
// Evolution Log CRUD
|
|
2616
|
+
insertEvolutionLog,
|
|
2617
|
+
listEvolutionLog
|
|
2265
2618
|
};
|