@su-record/vibe 2.7.10 → 2.7.12
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/.env.example +37 -37
- package/CLAUDE.md +126 -222
- package/LICENSE +21 -21
- package/README.md +580 -580
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/docs/api-documenter.md +99 -99
- package/agents/docs/changelog-writer.md +93 -93
- package/agents/e2e-tester.md +266 -266
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/junior-mentor.md +141 -141
- package/agents/planning/requirements-analyst.md +84 -84
- package/agents/planning/ux-advisor.md +83 -83
- package/agents/qa/acceptance-tester.md +86 -86
- package/agents/qa/edge-case-finder.md +93 -93
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui/ui-a11y-auditor.md +93 -93
- package/agents/ui/ui-antipattern-detector.md +94 -94
- package/agents/ui/ui-dataviz-advisor.md +69 -69
- package/agents/ui/ui-design-system-gen.md +57 -57
- package/agents/ui/ui-industry-analyzer.md +49 -49
- package/agents/ui/ui-layout-architect.md +65 -65
- package/agents/ui/ui-stack-implementer.md +68 -68
- package/agents/ui/ux-compliance-reviewer.md +81 -81
- package/agents/ui-previewer.md +260 -260
- package/commands/vibe.run.md +83 -0
- package/commands/vibe.spec.review.md +558 -558
- package/commands/vibe.utils.md +413 -413
- package/commands/vibe.voice.md +79 -79
- package/dist/cli/auth.d.ts +1 -1
- package/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +15 -7
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/commands/evolution.js +12 -12
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +62 -56
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +9 -6
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/remove.js +14 -14
- package/dist/cli/commands/sentinel.js +27 -27
- package/dist/cli/commands/skills.d.ts +13 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +83 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/slack.js +10 -10
- package/dist/cli/commands/telegram.js +12 -12
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +3 -0
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/detect.js +32 -32
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +64 -47
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/llm/claude-commands.js +16 -16
- package/dist/cli/llm/config.js +18 -18
- package/dist/cli/llm/gemini-commands.js +47 -47
- package/dist/cli/llm/gpt-commands.js +19 -19
- package/dist/cli/llm/help.js +21 -21
- package/dist/cli/postinstall/constants.d.ts +8 -0
- package/dist/cli/postinstall/constants.d.ts.map +1 -1
- package/dist/cli/postinstall/constants.js +33 -0
- package/dist/cli/postinstall/constants.js.map +1 -1
- package/dist/cli/postinstall/cursor-agents.js +32 -32
- package/dist/cli/postinstall/cursor-rules.js +83 -83
- package/dist/cli/postinstall/cursor-skills.js +743 -743
- package/dist/cli/postinstall/index.d.ts +1 -1
- package/dist/cli/postinstall/index.d.ts.map +1 -1
- package/dist/cli/postinstall/index.js +1 -1
- package/dist/cli/postinstall/index.js.map +1 -1
- package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
- package/dist/cli/setup/ProjectSetup.js +5 -0
- package/dist/cli/setup/ProjectSetup.js.map +1 -1
- package/dist/cli/setup/Provisioner.js +42 -42
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/infra/lib/DeepInit.js +24 -24
- package/dist/infra/lib/IterationTracker.js +11 -11
- package/dist/infra/lib/PythonParser.js +108 -108
- package/dist/infra/lib/ReviewRace.js +96 -96
- package/dist/infra/lib/SkillFrontmatter.js +28 -28
- package/dist/infra/lib/SkillQualityGate.js +9 -9
- package/dist/infra/lib/SkillRepository.js +159 -159
- package/dist/infra/lib/UltraQA.js +99 -99
- package/dist/infra/lib/autonomy/AuditStore.js +41 -41
- package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
- package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
- package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
- package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
- package/dist/infra/lib/embedding/VectorStore.js +22 -22
- package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
- package/dist/infra/lib/evolution/DescriptionOptimizer.d.ts +79 -0
- package/dist/infra/lib/evolution/DescriptionOptimizer.d.ts.map +1 -0
- package/dist/infra/lib/evolution/DescriptionOptimizer.js +259 -0
- package/dist/infra/lib/evolution/DescriptionOptimizer.js.map +1 -0
- package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
- package/dist/infra/lib/evolution/InsightStore.js +90 -90
- package/dist/infra/lib/evolution/RollbackManager.js +5 -5
- package/dist/infra/lib/evolution/SkillBenchmark.d.ts +81 -0
- package/dist/infra/lib/evolution/SkillBenchmark.d.ts.map +1 -0
- package/dist/infra/lib/evolution/SkillBenchmark.js +233 -0
- package/dist/infra/lib/evolution/SkillBenchmark.js.map +1 -0
- package/dist/infra/lib/evolution/SkillClassifier.d.ts +35 -0
- package/dist/infra/lib/evolution/SkillClassifier.d.ts.map +1 -0
- package/dist/infra/lib/evolution/SkillClassifier.js +167 -0
- package/dist/infra/lib/evolution/SkillClassifier.js.map +1 -0
- package/dist/infra/lib/evolution/SkillEvalRunner.d.ts +102 -0
- package/dist/infra/lib/evolution/SkillEvalRunner.d.ts.map +1 -0
- package/dist/infra/lib/evolution/SkillEvalRunner.js +256 -0
- package/dist/infra/lib/evolution/SkillEvalRunner.js.map +1 -0
- package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
- package/dist/infra/lib/evolution/UsageTracker.js +28 -28
- package/dist/infra/lib/evolution/__tests__/eval.test.d.ts +2 -0
- package/dist/infra/lib/evolution/__tests__/eval.test.d.ts.map +1 -0
- package/dist/infra/lib/evolution/__tests__/eval.test.js +539 -0
- package/dist/infra/lib/evolution/__tests__/eval.test.js.map +1 -0
- package/dist/infra/lib/evolution/index.d.ts +8 -0
- package/dist/infra/lib/evolution/index.d.ts.map +1 -1
- package/dist/infra/lib/evolution/index.js +5 -0
- package/dist/infra/lib/evolution/index.js.map +1 -1
- package/dist/infra/lib/gemini/constants.js +14 -14
- package/dist/infra/lib/gemini/orchestration.js +5 -5
- package/dist/infra/lib/gpt/oauth.js +44 -44
- package/dist/infra/lib/gpt/orchestration.js +4 -4
- package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/infra/lib/memory/MemorySearch.js +57 -57
- package/dist/infra/lib/memory/MemoryStorage.js +181 -181
- package/dist/infra/lib/memory/ObservationStore.js +28 -28
- package/dist/infra/lib/memory/ReflectionStore.js +30 -30
- package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
- package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
- package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
- package/dist/infra/orchestrator/AgentManager.js +12 -12
- package/dist/infra/orchestrator/AgentRegistry.js +65 -65
- package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
- package/dist/infra/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/dist/tools/semantic/astGrep.test.js +6 -6
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/hooks/gemini-hooks.json +73 -73
- package/hooks/hooks.json +137 -137
- package/hooks/scripts/code-check.js +70 -70
- package/hooks/scripts/context-save.js +212 -212
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +646 -646
- package/hooks/scripts/post-edit.js +32 -32
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/prompt-dispatcher.js +185 -185
- package/hooks/scripts/sentinel-guard.js +104 -104
- package/hooks/scripts/session-start.js +106 -106
- package/hooks/scripts/stop-notify.js +209 -209
- package/hooks/scripts/utils.js +100 -100
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +121 -121
- package/skills/agents-md/SKILL.md +120 -120
- package/skills/arch-guard/SKILL.md +180 -0
- package/skills/brand-assets/SKILL.md +146 -146
- package/skills/capability-loop/SKILL.md +167 -0
- package/skills/characterization-test/SKILL.md +206 -206
- package/skills/commerce-patterns/SKILL.md +59 -59
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +48 -48
- package/skills/e2e-commerce/SKILL.md +57 -57
- package/skills/exec-plan/SKILL.md +147 -0
- package/skills/frontend-design/SKILL.md +73 -73
- package/skills/git-worktree/SKILL.md +72 -72
- package/skills/handoff/SKILL.md +109 -109
- package/skills/parallel-research/SKILL.md +87 -87
- package/skills/priority-todos/SKILL.md +63 -63
- package/skills/seo-checklist/SKILL.md +57 -57
- package/skills/techdebt/SKILL.md +122 -122
- package/skills/tool-fallback/SKILL.md +103 -103
- package/skills/typescript-advanced-types/SKILL.md +65 -65
- package/skills/ui-ux-pro-max/SKILL.md +206 -206
- package/skills/vercel-react-best-practices/SKILL.md +59 -59
- package/skills/video-production/SKILL.md +51 -51
- package/vibe/config.json +29 -29
- package/vibe/constitution.md +227 -227
- package/vibe/rules/principles/communication-guide.md +98 -98
- package/vibe/rules/principles/development-philosophy.md +52 -52
- package/vibe/rules/principles/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/performance.md +236 -236
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/git-workflow.md +237 -237
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/rules/standards/security.md +305 -305
- package/vibe/rules/writing/document-style.md +74 -74
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
- package/vibe/ui-ux-data/charts.csv +26 -26
- package/vibe/ui-ux-data/colors.csv +97 -97
- package/vibe/ui-ux-data/icons.csv +101 -101
- package/vibe/ui-ux-data/landing.csv +31 -31
- package/vibe/ui-ux-data/products.csv +96 -96
- package/vibe/ui-ux-data/react-performance.csv +45 -45
- package/vibe/ui-ux-data/stacks/astro.csv +54 -54
- package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
- package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
- package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
- package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
- package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
- package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
- package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
- package/vibe/ui-ux-data/stacks/react.csv +54 -54
- package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
- package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
- package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
- package/vibe/ui-ux-data/stacks/vue.csv +50 -50
- package/vibe/ui-ux-data/styles.csv +68 -68
- package/vibe/ui-ux-data/typography.csv +57 -57
- package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
- package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
- package/vibe/ui-ux-data/version.json +31 -31
- package/vibe/ui-ux-data/web-interface.csv +31 -31
|
@@ -13,22 +13,22 @@ export class VectorStore {
|
|
|
13
13
|
this.initializeTables();
|
|
14
14
|
}
|
|
15
15
|
initializeTables() {
|
|
16
|
-
this.db.exec(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS memory_vectors (
|
|
18
|
-
key TEXT PRIMARY KEY,
|
|
19
|
-
embedding BLOB NOT NULL,
|
|
20
|
-
dimension INTEGER NOT NULL,
|
|
21
|
-
updatedAt TEXT NOT NULL
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
CREATE TABLE IF NOT EXISTS session_vectors (
|
|
25
|
-
entityType TEXT NOT NULL,
|
|
26
|
-
entityId INTEGER NOT NULL,
|
|
27
|
-
embedding BLOB NOT NULL,
|
|
28
|
-
dimension INTEGER NOT NULL,
|
|
29
|
-
updatedAt TEXT NOT NULL,
|
|
30
|
-
PRIMARY KEY (entityType, entityId)
|
|
31
|
-
);
|
|
16
|
+
this.db.exec(`
|
|
17
|
+
CREATE TABLE IF NOT EXISTS memory_vectors (
|
|
18
|
+
key TEXT PRIMARY KEY,
|
|
19
|
+
embedding BLOB NOT NULL,
|
|
20
|
+
dimension INTEGER NOT NULL,
|
|
21
|
+
updatedAt TEXT NOT NULL
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
CREATE TABLE IF NOT EXISTS session_vectors (
|
|
25
|
+
entityType TEXT NOT NULL,
|
|
26
|
+
entityId INTEGER NOT NULL,
|
|
27
|
+
embedding BLOB NOT NULL,
|
|
28
|
+
dimension INTEGER NOT NULL,
|
|
29
|
+
updatedAt TEXT NOT NULL,
|
|
30
|
+
PRIMARY KEY (entityType, entityId)
|
|
31
|
+
);
|
|
32
32
|
`);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -37,9 +37,9 @@ export class VectorStore {
|
|
|
37
37
|
saveMemoryVector(key, embedding) {
|
|
38
38
|
const blob = serializeVector(embedding);
|
|
39
39
|
const now = new Date().toISOString();
|
|
40
|
-
this.db.prepare(`
|
|
41
|
-
INSERT OR REPLACE INTO memory_vectors (key, embedding, dimension, updatedAt)
|
|
42
|
-
VALUES (?, ?, ?, ?)
|
|
40
|
+
this.db.prepare(`
|
|
41
|
+
INSERT OR REPLACE INTO memory_vectors (key, embedding, dimension, updatedAt)
|
|
42
|
+
VALUES (?, ?, ?, ?)
|
|
43
43
|
`).run(key, blob, embedding.length, now);
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
@@ -48,9 +48,9 @@ export class VectorStore {
|
|
|
48
48
|
saveSessionVector(entityType, entityId, embedding) {
|
|
49
49
|
const blob = serializeVector(embedding);
|
|
50
50
|
const now = new Date().toISOString();
|
|
51
|
-
this.db.prepare(`
|
|
52
|
-
INSERT OR REPLACE INTO session_vectors (entityType, entityId, embedding, dimension, updatedAt)
|
|
53
|
-
VALUES (?, ?, ?, ?, ?)
|
|
51
|
+
this.db.prepare(`
|
|
52
|
+
INSERT OR REPLACE INTO session_vectors (entityType, entityId, embedding, dimension, updatedAt)
|
|
53
|
+
VALUES (?, ?, ?, ?, ?)
|
|
54
54
|
`).run(entityType, entityId, blob, embedding.length, now);
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
@@ -23,16 +23,16 @@ export class AgentAnalyzer {
|
|
|
23
23
|
if (!this.agentDb)
|
|
24
24
|
return result;
|
|
25
25
|
try {
|
|
26
|
-
const stats = this.agentDb.prepare(`
|
|
27
|
-
SELECT
|
|
28
|
-
agentName,
|
|
29
|
-
COUNT(*) as totalRuns,
|
|
30
|
-
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failedRuns,
|
|
31
|
-
AVG(duration) as avgDuration
|
|
32
|
-
FROM agent_executions
|
|
33
|
-
WHERE createdAt > datetime('now', '-7 days')
|
|
34
|
-
GROUP BY agentName
|
|
35
|
-
HAVING totalRuns >= 5
|
|
26
|
+
const stats = this.agentDb.prepare(`
|
|
27
|
+
SELECT
|
|
28
|
+
agentName,
|
|
29
|
+
COUNT(*) as totalRuns,
|
|
30
|
+
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failedRuns,
|
|
31
|
+
AVG(duration) as avgDuration
|
|
32
|
+
FROM agent_executions
|
|
33
|
+
WHERE createdAt > datetime('now', '-7 days')
|
|
34
|
+
GROUP BY agentName
|
|
35
|
+
HAVING totalRuns >= 5
|
|
36
36
|
`).all();
|
|
37
37
|
result.agentsAnalyzed = stats.length;
|
|
38
38
|
for (const stat of stats) {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MemoryStorage } from '../memory/MemoryStorage.js';
|
|
2
|
+
export interface TriggerEvalQuery {
|
|
3
|
+
query: string;
|
|
4
|
+
shouldTrigger: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface TriggerEvalResult {
|
|
7
|
+
query: string;
|
|
8
|
+
shouldTrigger: boolean;
|
|
9
|
+
didTrigger: boolean;
|
|
10
|
+
triggerRate: number;
|
|
11
|
+
correct: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface DescriptionCandidate {
|
|
14
|
+
description: string;
|
|
15
|
+
trainScore: number;
|
|
16
|
+
testScore: number;
|
|
17
|
+
iteration: number;
|
|
18
|
+
results: TriggerEvalResult[];
|
|
19
|
+
}
|
|
20
|
+
export interface OptimizationRun {
|
|
21
|
+
id: string;
|
|
22
|
+
skillName: string;
|
|
23
|
+
originalDescription: string;
|
|
24
|
+
bestDescription: string;
|
|
25
|
+
candidates: DescriptionCandidate[];
|
|
26
|
+
trainQueries: TriggerEvalQuery[];
|
|
27
|
+
testQueries: TriggerEvalQuery[];
|
|
28
|
+
improvement: number;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
}
|
|
31
|
+
export declare class DescriptionOptimizer {
|
|
32
|
+
private db;
|
|
33
|
+
constructor(storage: MemoryStorage);
|
|
34
|
+
private initializeTables;
|
|
35
|
+
/**
|
|
36
|
+
* Split eval queries into train/test sets (60/40)
|
|
37
|
+
*/
|
|
38
|
+
splitEvalSet(queries: TriggerEvalQuery[]): {
|
|
39
|
+
train: TriggerEvalQuery[];
|
|
40
|
+
test: TriggerEvalQuery[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Evaluate a description against a set of trigger queries.
|
|
44
|
+
* Uses keyword matching as a proxy for actual skill triggering.
|
|
45
|
+
* In production, this would call `claude -p` and monitor the stream.
|
|
46
|
+
*/
|
|
47
|
+
evaluateDescription(description: string, queries: TriggerEvalQuery[]): TriggerEvalResult[];
|
|
48
|
+
/**
|
|
49
|
+
* Score a set of evaluation results (accuracy)
|
|
50
|
+
*/
|
|
51
|
+
scoreResults(results: TriggerEvalResult[]): number;
|
|
52
|
+
/**
|
|
53
|
+
* Run a single optimization iteration:
|
|
54
|
+
* Evaluate current description, improve based on failures
|
|
55
|
+
*/
|
|
56
|
+
evaluateCandidate(description: string, trainQueries: TriggerEvalQuery[], testQueries: TriggerEvalQuery[], iteration: number): DescriptionCandidate;
|
|
57
|
+
/**
|
|
58
|
+
* Suggest an improved description based on failed eval queries.
|
|
59
|
+
* Analyzes what failed and adds/removes keywords to improve accuracy.
|
|
60
|
+
*/
|
|
61
|
+
suggestImprovement(currentDescription: string, failedResults: TriggerEvalResult[]): string;
|
|
62
|
+
/**
|
|
63
|
+
* Run the full optimization loop
|
|
64
|
+
*/
|
|
65
|
+
optimize(skillName: string, description: string, queries: TriggerEvalQuery[], maxIterations?: number): OptimizationRun;
|
|
66
|
+
/**
|
|
67
|
+
* Get optimization history for a skill
|
|
68
|
+
*/
|
|
69
|
+
getHistory(skillName: string): OptimizationRun[];
|
|
70
|
+
/**
|
|
71
|
+
* Get latest optimization for a skill
|
|
72
|
+
*/
|
|
73
|
+
getLatest(skillName: string): OptimizationRun | null;
|
|
74
|
+
private extractKeywords;
|
|
75
|
+
private computeOverlap;
|
|
76
|
+
private takePortion;
|
|
77
|
+
private rowToRun;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=DescriptionOptimizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DescriptionOptimizer.d.ts","sourceRoot":"","sources":["../../../../src/infra/lib/evolution/DescriptionOptimizer.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,EAAE,CAA2C;gBAEzC,OAAO,EAAE,aAAa;IAKlC,OAAO,CAAC,gBAAgB;IAkBxB;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG;QAChD,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAC1B,IAAI,EAAE,gBAAgB,EAAE,CAAC;KAC1B;IAgBD;;;;OAIG;IACI,mBAAmB,CACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,EAAE,GAC1B,iBAAiB,EAAE;IAsBtB;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM;IAMzD;;;OAGG;IACI,iBAAiB,CACtB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,gBAAgB,EAAE,EAChC,WAAW,EAAE,gBAAgB,EAAE,EAC/B,SAAS,EAAE,MAAM,GAChB,oBAAoB;IAavB;;;OAGG;IACI,kBAAkB,CACvB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,iBAAiB,EAAE,GACjC,MAAM;IA6CT;;OAEG;IACI,QAAQ,CACb,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,aAAa,GAAE,MAAU,GACxB,eAAe;IAkElB;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE;IAOvD;;OAEG;IACI,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAS3D,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,QAAQ;CAajB"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Description Optimizer - Phase 5: Tune skill descriptions for reliable triggering
|
|
2
|
+
//
|
|
3
|
+
// Evaluates how well a skill's description triggers against a set of eval queries.
|
|
4
|
+
// Tracks trigger accuracy (should-trigger and should-not-trigger) and iteratively
|
|
5
|
+
// improves descriptions to reduce false positives and false negatives.
|
|
6
|
+
//
|
|
7
|
+
// Optimization loop:
|
|
8
|
+
// 1. Split eval set into 60% train / 40% test
|
|
9
|
+
// 2. Evaluate current description (3 runs per query for reliable rate)
|
|
10
|
+
// 3. Score on both train and test sets
|
|
11
|
+
// 4. Select best description by test score (avoid overfitting)
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
13
|
+
export class DescriptionOptimizer {
|
|
14
|
+
db;
|
|
15
|
+
constructor(storage) {
|
|
16
|
+
this.db = storage.getDatabase();
|
|
17
|
+
this.initializeTables();
|
|
18
|
+
}
|
|
19
|
+
initializeTables() {
|
|
20
|
+
this.db.exec(`
|
|
21
|
+
CREATE TABLE IF NOT EXISTS description_optimizations (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
skillName TEXT NOT NULL,
|
|
24
|
+
originalDescription TEXT NOT NULL,
|
|
25
|
+
bestDescription TEXT NOT NULL,
|
|
26
|
+
candidates TEXT NOT NULL,
|
|
27
|
+
trainQueries TEXT NOT NULL,
|
|
28
|
+
testQueries TEXT NOT NULL,
|
|
29
|
+
improvement REAL DEFAULT 0,
|
|
30
|
+
createdAt TEXT NOT NULL
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_do_skill ON description_optimizations(skillName);
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Split eval queries into train/test sets (60/40)
|
|
38
|
+
*/
|
|
39
|
+
splitEvalSet(queries) {
|
|
40
|
+
// Stratified split: maintain should-trigger ratio in both sets
|
|
41
|
+
const shouldTrigger = queries.filter(q => q.shouldTrigger);
|
|
42
|
+
const shouldNot = queries.filter(q => !q.shouldTrigger);
|
|
43
|
+
const trainTrigger = this.takePortion(shouldTrigger, 0.6);
|
|
44
|
+
const trainNot = this.takePortion(shouldNot, 0.6);
|
|
45
|
+
const testTrigger = shouldTrigger.filter(q => !trainTrigger.includes(q));
|
|
46
|
+
const testNot = shouldNot.filter(q => !trainNot.includes(q));
|
|
47
|
+
return {
|
|
48
|
+
train: [...trainTrigger, ...trainNot],
|
|
49
|
+
test: [...testTrigger, ...testNot],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Evaluate a description against a set of trigger queries.
|
|
54
|
+
* Uses keyword matching as a proxy for actual skill triggering.
|
|
55
|
+
* In production, this would call `claude -p` and monitor the stream.
|
|
56
|
+
*/
|
|
57
|
+
evaluateDescription(description, queries) {
|
|
58
|
+
const descWords = this.extractKeywords(description);
|
|
59
|
+
return queries.map(query => {
|
|
60
|
+
const queryWords = this.extractKeywords(query.query);
|
|
61
|
+
const overlap = this.computeOverlap(descWords, queryWords);
|
|
62
|
+
// Trigger if keyword overlap exceeds threshold
|
|
63
|
+
const triggerThreshold = 0.15;
|
|
64
|
+
const didTrigger = overlap >= triggerThreshold;
|
|
65
|
+
const triggerRate = overlap;
|
|
66
|
+
return {
|
|
67
|
+
query: query.query,
|
|
68
|
+
shouldTrigger: query.shouldTrigger,
|
|
69
|
+
didTrigger,
|
|
70
|
+
triggerRate,
|
|
71
|
+
correct: didTrigger === query.shouldTrigger,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Score a set of evaluation results (accuracy)
|
|
77
|
+
*/
|
|
78
|
+
scoreResults(results) {
|
|
79
|
+
if (results.length === 0)
|
|
80
|
+
return 0;
|
|
81
|
+
const correct = results.filter(r => r.correct).length;
|
|
82
|
+
return correct / results.length;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Run a single optimization iteration:
|
|
86
|
+
* Evaluate current description, improve based on failures
|
|
87
|
+
*/
|
|
88
|
+
evaluateCandidate(description, trainQueries, testQueries, iteration) {
|
|
89
|
+
const trainResults = this.evaluateDescription(description, trainQueries);
|
|
90
|
+
const testResults = this.evaluateDescription(description, testQueries);
|
|
91
|
+
return {
|
|
92
|
+
description,
|
|
93
|
+
trainScore: this.scoreResults(trainResults),
|
|
94
|
+
testScore: this.scoreResults(testResults),
|
|
95
|
+
iteration,
|
|
96
|
+
results: [...trainResults, ...testResults],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Suggest an improved description based on failed eval queries.
|
|
101
|
+
* Analyzes what failed and adds/removes keywords to improve accuracy.
|
|
102
|
+
*/
|
|
103
|
+
suggestImprovement(currentDescription, failedResults) {
|
|
104
|
+
if (failedResults.length === 0)
|
|
105
|
+
return currentDescription;
|
|
106
|
+
const falseNegatives = failedResults.filter(r => r.shouldTrigger && !r.didTrigger);
|
|
107
|
+
const falsePositives = failedResults.filter(r => !r.shouldTrigger && r.didTrigger);
|
|
108
|
+
let improved = currentDescription;
|
|
109
|
+
// For false negatives: add keywords from queries that should have triggered
|
|
110
|
+
if (falseNegatives.length > 0) {
|
|
111
|
+
const missingKeywords = new Set();
|
|
112
|
+
for (const fn of falseNegatives) {
|
|
113
|
+
const queryWords = this.extractKeywords(fn.query);
|
|
114
|
+
for (const word of queryWords) {
|
|
115
|
+
if (!improved.toLowerCase().includes(word)) {
|
|
116
|
+
missingKeywords.add(word);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Add the most relevant missing keywords (up to 3)
|
|
121
|
+
const toAdd = Array.from(missingKeywords).slice(0, 3);
|
|
122
|
+
if (toAdd.length > 0) {
|
|
123
|
+
improved = `${improved} Handles: ${toAdd.join(', ')}.`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// For false positives: make description more specific
|
|
127
|
+
if (falsePositives.length > 0) {
|
|
128
|
+
const fpKeywords = new Set();
|
|
129
|
+
for (const fp of falsePositives) {
|
|
130
|
+
const queryWords = this.extractKeywords(fp.query);
|
|
131
|
+
for (const word of queryWords) {
|
|
132
|
+
fpKeywords.add(word);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Add exclusion hint if not already present
|
|
136
|
+
const toExclude = Array.from(fpKeywords).slice(0, 2);
|
|
137
|
+
if (toExclude.length > 0 && !improved.includes('Does NOT')) {
|
|
138
|
+
improved = `${improved} Does NOT handle: ${toExclude.join(', ')}.`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return improved;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Run the full optimization loop
|
|
145
|
+
*/
|
|
146
|
+
optimize(skillName, description, queries, maxIterations = 5) {
|
|
147
|
+
const { train, test } = this.splitEvalSet(queries);
|
|
148
|
+
const candidates = [];
|
|
149
|
+
let currentDescription = description;
|
|
150
|
+
let bestCandidate = null;
|
|
151
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
152
|
+
const candidate = this.evaluateCandidate(currentDescription, train, test, i + 1);
|
|
153
|
+
candidates.push(candidate);
|
|
154
|
+
if (!bestCandidate || candidate.testScore > bestCandidate.testScore) {
|
|
155
|
+
bestCandidate = candidate;
|
|
156
|
+
}
|
|
157
|
+
// Perfect score → stop
|
|
158
|
+
if (candidate.testScore >= 1.0 && candidate.trainScore >= 1.0)
|
|
159
|
+
break;
|
|
160
|
+
// Improve based on failures
|
|
161
|
+
const failed = candidate.results.filter(r => !r.correct);
|
|
162
|
+
if (failed.length === 0)
|
|
163
|
+
break;
|
|
164
|
+
const improved = this.suggestImprovement(currentDescription, failed);
|
|
165
|
+
if (improved === currentDescription)
|
|
166
|
+
break; // No improvement possible
|
|
167
|
+
currentDescription = improved;
|
|
168
|
+
}
|
|
169
|
+
const id = `opt-${Date.now().toString(36)}-${randomUUID().replace(/-/g, '').slice(0, 8)}`;
|
|
170
|
+
const now = new Date().toISOString();
|
|
171
|
+
const originalScore = candidates[0]?.testScore ?? 0;
|
|
172
|
+
const bestScore = bestCandidate?.testScore ?? 0;
|
|
173
|
+
const improvement = bestScore - originalScore;
|
|
174
|
+
const run = {
|
|
175
|
+
id,
|
|
176
|
+
skillName,
|
|
177
|
+
originalDescription: description,
|
|
178
|
+
bestDescription: bestCandidate?.description ?? description,
|
|
179
|
+
candidates,
|
|
180
|
+
trainQueries: train,
|
|
181
|
+
testQueries: test,
|
|
182
|
+
improvement,
|
|
183
|
+
createdAt: now,
|
|
184
|
+
};
|
|
185
|
+
// Persist
|
|
186
|
+
this.db.prepare(`
|
|
187
|
+
INSERT INTO description_optimizations (id, skillName, originalDescription, bestDescription, candidates, trainQueries, testQueries, improvement, createdAt)
|
|
188
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
189
|
+
`).run(id, skillName, description, run.bestDescription, JSON.stringify(candidates), JSON.stringify(train), JSON.stringify(test), improvement, now);
|
|
190
|
+
return run;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get optimization history for a skill
|
|
194
|
+
*/
|
|
195
|
+
getHistory(skillName) {
|
|
196
|
+
const rows = this.db.prepare(`
|
|
197
|
+
SELECT * FROM description_optimizations WHERE skillName = ? ORDER BY createdAt ASC
|
|
198
|
+
`).all(skillName);
|
|
199
|
+
return rows.map(this.rowToRun);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get latest optimization for a skill
|
|
203
|
+
*/
|
|
204
|
+
getLatest(skillName) {
|
|
205
|
+
const row = this.db.prepare(`
|
|
206
|
+
SELECT * FROM description_optimizations WHERE skillName = ? ORDER BY createdAt DESC LIMIT 1
|
|
207
|
+
`).get(skillName);
|
|
208
|
+
return row ? this.rowToRun(row) : null;
|
|
209
|
+
}
|
|
210
|
+
// --- Internal helpers ---
|
|
211
|
+
extractKeywords(text) {
|
|
212
|
+
const stopWords = new Set([
|
|
213
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
214
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
215
|
+
'should', 'may', 'might', 'shall', 'can', 'to', 'of', 'in', 'for',
|
|
216
|
+
'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through', 'during',
|
|
217
|
+
'before', 'after', 'above', 'below', 'between', 'out', 'off', 'up',
|
|
218
|
+
'down', 'and', 'but', 'or', 'nor', 'not', 'so', 'yet', 'both',
|
|
219
|
+
'each', 'all', 'any', 'few', 'more', 'most', 'other', 'some',
|
|
220
|
+
'such', 'no', 'only', 'own', 'same', 'than', 'too', 'very',
|
|
221
|
+
'just', 'because', 'if', 'when', 'while', 'this', 'that', 'these',
|
|
222
|
+
'those', 'i', 'me', 'my', 'we', 'our', 'you', 'your', 'it', 'its',
|
|
223
|
+
'they', 'them', 'their', 'what', 'which', 'who', 'whom',
|
|
224
|
+
]);
|
|
225
|
+
return new Set(text
|
|
226
|
+
.toLowerCase()
|
|
227
|
+
.replace(/[^a-z0-9\s-]/g, ' ')
|
|
228
|
+
.split(/\s+/)
|
|
229
|
+
.filter(w => w.length > 2 && !stopWords.has(w)));
|
|
230
|
+
}
|
|
231
|
+
computeOverlap(setA, setB) {
|
|
232
|
+
if (setA.size === 0 || setB.size === 0)
|
|
233
|
+
return 0;
|
|
234
|
+
let overlap = 0;
|
|
235
|
+
for (const word of setB) {
|
|
236
|
+
if (setA.has(word))
|
|
237
|
+
overlap++;
|
|
238
|
+
}
|
|
239
|
+
return overlap / Math.max(setA.size, setB.size);
|
|
240
|
+
}
|
|
241
|
+
takePortion(arr, ratio) {
|
|
242
|
+
const count = Math.ceil(arr.length * ratio);
|
|
243
|
+
return arr.slice(0, count);
|
|
244
|
+
}
|
|
245
|
+
rowToRun(row) {
|
|
246
|
+
return {
|
|
247
|
+
id: row.id,
|
|
248
|
+
skillName: row.skillName,
|
|
249
|
+
originalDescription: row.originalDescription,
|
|
250
|
+
bestDescription: row.bestDescription,
|
|
251
|
+
candidates: JSON.parse(row.candidates),
|
|
252
|
+
trainQueries: JSON.parse(row.trainQueries),
|
|
253
|
+
testQueries: JSON.parse(row.testQueries),
|
|
254
|
+
improvement: row.improvement,
|
|
255
|
+
createdAt: row.createdAt,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=DescriptionOptimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DescriptionOptimizer.js","sourceRoot":"","sources":["../../../../src/infra/lib/evolution/DescriptionOptimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,38 +8,38 @@ export class GenerationRegistry {
|
|
|
8
8
|
this.initializeTables();
|
|
9
9
|
}
|
|
10
10
|
initializeTables() {
|
|
11
|
-
this.db.exec(`
|
|
12
|
-
CREATE TABLE IF NOT EXISTS generations (
|
|
13
|
-
id TEXT PRIMARY KEY,
|
|
14
|
-
insightId TEXT,
|
|
15
|
-
type TEXT NOT NULL CHECK(type IN ('skill','agent','rule')),
|
|
16
|
-
name TEXT NOT NULL,
|
|
17
|
-
content TEXT NOT NULL,
|
|
18
|
-
filePath TEXT,
|
|
19
|
-
status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','testing','active','disabled','deleted')),
|
|
20
|
-
qualityScore INTEGER DEFAULT 0,
|
|
21
|
-
triggerPatterns TEXT,
|
|
22
|
-
usageCount INTEGER DEFAULT 0,
|
|
23
|
-
lastUsedAt TEXT,
|
|
24
|
-
ttlDays INTEGER DEFAULT 7,
|
|
25
|
-
version INTEGER DEFAULT 1,
|
|
26
|
-
parentId TEXT,
|
|
27
|
-
createdAt TEXT NOT NULL,
|
|
28
|
-
updatedAt TEXT NOT NULL
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
CREATE INDEX IF NOT EXISTS idx_gen_type ON generations(type);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS idx_gen_status ON generations(status);
|
|
33
|
-
CREATE INDEX IF NOT EXISTS idx_gen_insight ON generations(insightId);
|
|
34
|
-
CREATE INDEX IF NOT EXISTS idx_gen_name ON generations(name);
|
|
11
|
+
this.db.exec(`
|
|
12
|
+
CREATE TABLE IF NOT EXISTS generations (
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
insightId TEXT,
|
|
15
|
+
type TEXT NOT NULL CHECK(type IN ('skill','agent','rule')),
|
|
16
|
+
name TEXT NOT NULL,
|
|
17
|
+
content TEXT NOT NULL,
|
|
18
|
+
filePath TEXT,
|
|
19
|
+
status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','testing','active','disabled','deleted')),
|
|
20
|
+
qualityScore INTEGER DEFAULT 0,
|
|
21
|
+
triggerPatterns TEXT,
|
|
22
|
+
usageCount INTEGER DEFAULT 0,
|
|
23
|
+
lastUsedAt TEXT,
|
|
24
|
+
ttlDays INTEGER DEFAULT 7,
|
|
25
|
+
version INTEGER DEFAULT 1,
|
|
26
|
+
parentId TEXT,
|
|
27
|
+
createdAt TEXT NOT NULL,
|
|
28
|
+
updatedAt TEXT NOT NULL
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_gen_type ON generations(type);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_gen_status ON generations(status);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_gen_insight ON generations(insightId);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_gen_name ON generations(name);
|
|
35
35
|
`);
|
|
36
36
|
}
|
|
37
37
|
save(input) {
|
|
38
38
|
const id = `gen-${Date.now().toString(36)}-${randomUUID().replace(/-/g, '').slice(0, 8)}`;
|
|
39
39
|
const now = new Date().toISOString();
|
|
40
|
-
this.db.prepare(`
|
|
41
|
-
INSERT INTO generations (id, insightId, type, name, content, filePath, status, qualityScore, triggerPatterns, ttlDays, version, parentId, createdAt, updatedAt)
|
|
42
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
40
|
+
this.db.prepare(`
|
|
41
|
+
INSERT INTO generations (id, insightId, type, name, content, filePath, status, qualityScore, triggerPatterns, ttlDays, version, parentId, createdAt, updatedAt)
|
|
42
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
43
43
|
`).run(id, input.insightId, input.type, input.name, input.content, input.filePath || null, input.status || 'draft', input.qualityScore || 0, JSON.stringify(input.triggerPatterns || []), input.ttlDays || 7, input.parentId ? 2 : 1, // version 2 if has parent
|
|
44
44
|
input.parentId || null, now, now);
|
|
45
45
|
return id;
|
|
@@ -64,20 +64,20 @@ export class GenerationRegistry {
|
|
|
64
64
|
return rows.map(this.rowToGeneration);
|
|
65
65
|
}
|
|
66
66
|
getByStatus(status, limit = 50) {
|
|
67
|
-
const rows = this.db.prepare(`
|
|
68
|
-
SELECT * FROM generations WHERE status = ? ORDER BY updatedAt DESC LIMIT ?
|
|
67
|
+
const rows = this.db.prepare(`
|
|
68
|
+
SELECT * FROM generations WHERE status = ? ORDER BY updatedAt DESC LIMIT ?
|
|
69
69
|
`).all(status, limit);
|
|
70
70
|
return rows.map(this.rowToGeneration);
|
|
71
71
|
}
|
|
72
72
|
updateStatus(id, status) {
|
|
73
|
-
const result = this.db.prepare(`
|
|
74
|
-
UPDATE generations SET status = ?, updatedAt = ? WHERE id = ?
|
|
73
|
+
const result = this.db.prepare(`
|
|
74
|
+
UPDATE generations SET status = ?, updatedAt = ? WHERE id = ?
|
|
75
75
|
`).run(status, new Date().toISOString(), id);
|
|
76
76
|
return result.changes > 0;
|
|
77
77
|
}
|
|
78
78
|
incrementUsage(id) {
|
|
79
|
-
this.db.prepare(`
|
|
80
|
-
UPDATE generations SET usageCount = usageCount + 1, lastUsedAt = ?, updatedAt = ? WHERE id = ?
|
|
79
|
+
this.db.prepare(`
|
|
80
|
+
UPDATE generations SET usageCount = usageCount + 1, lastUsedAt = ?, updatedAt = ? WHERE id = ?
|
|
81
81
|
`).run(new Date().toISOString(), new Date().toISOString(), id);
|
|
82
82
|
}
|
|
83
83
|
getStats() {
|
|
@@ -91,9 +91,9 @@ export class GenerationRegistry {
|
|
|
91
91
|
return { total, byType, byStatus };
|
|
92
92
|
}
|
|
93
93
|
getRecentFailures(limit = 10) {
|
|
94
|
-
const result = this.db.prepare(`
|
|
95
|
-
SELECT COUNT(*) as cnt FROM generations
|
|
96
|
-
WHERE status = 'deleted' AND createdAt > datetime('now', '-1 hour')
|
|
94
|
+
const result = this.db.prepare(`
|
|
95
|
+
SELECT COUNT(*) as cnt FROM generations
|
|
96
|
+
WHERE status = 'deleted' AND createdAt > datetime('now', '-1 hour')
|
|
97
97
|
`).get();
|
|
98
98
|
return result.cnt;
|
|
99
99
|
}
|