cmp-standards 2.0.1 → 2.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/README.md +633 -541
- package/dist/cli/index.js +239 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +203 -39
- package/dist/dashboard/server.js.map +1 -1
- package/dist/db/cloud.d.ts +174 -0
- package/dist/db/cloud.d.ts.map +1 -0
- package/dist/db/cloud.js +241 -0
- package/dist/db/cloud.js.map +1 -0
- package/dist/db/drizzle-client.d.ts +3 -3
- package/dist/db/drizzle-client.d.ts.map +1 -1
- package/dist/db/drizzle-client.js +57 -58
- package/dist/db/drizzle-client.js.map +1 -1
- package/dist/db/errors.d.ts +76 -0
- package/dist/db/errors.d.ts.map +1 -0
- package/dist/db/errors.js +135 -0
- package/dist/db/errors.js.map +1 -0
- package/dist/db/turso-client.d.ts +178 -0
- package/dist/db/turso-client.d.ts.map +1 -0
- package/dist/db/turso-client.js +455 -0
- package/dist/db/turso-client.js.map +1 -0
- package/dist/db/upstash-client.d.ts +161 -0
- package/dist/db/upstash-client.d.ts.map +1 -0
- package/dist/db/upstash-client.js +325 -0
- package/dist/db/upstash-client.js.map +1 -0
- package/dist/eslint/rules/no-async-useeffect.js +6 -6
- package/dist/hooks/cloud-post-tool-use.d.ts +30 -0
- package/dist/hooks/cloud-post-tool-use.d.ts.map +1 -0
- package/dist/hooks/cloud-post-tool-use.js +116 -0
- package/dist/hooks/cloud-post-tool-use.js.map +1 -0
- package/dist/hooks/cloud-pre-tool-use.d.ts +19 -0
- package/dist/hooks/cloud-pre-tool-use.d.ts.map +1 -0
- package/dist/hooks/cloud-pre-tool-use.js +149 -0
- package/dist/hooks/cloud-pre-tool-use.js.map +1 -0
- package/dist/hooks/cloud-session-start.d.ts +32 -0
- package/dist/hooks/cloud-session-start.d.ts.map +1 -0
- package/dist/hooks/cloud-session-start.js +257 -0
- package/dist/hooks/cloud-session-start.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/memory-checkpoint.d.ts.map +1 -1
- package/dist/hooks/memory-checkpoint.js +12 -20
- package/dist/hooks/memory-checkpoint.js.map +1 -1
- package/dist/hooks/pre-tool-use.d.ts +2 -8
- package/dist/hooks/pre-tool-use.d.ts.map +1 -1
- package/dist/hooks/pre-tool-use.js +7 -106
- package/dist/hooks/pre-tool-use.js.map +1 -1
- package/dist/hooks/session-start.d.ts +2 -1
- package/dist/hooks/session-start.d.ts.map +1 -1
- package/dist/hooks/session-start.js +111 -77
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +225 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/schema/plans.d.ts +194 -0
- package/dist/schema/plans.d.ts.map +1 -0
- package/dist/schema/plans.js +180 -0
- package/dist/schema/plans.js.map +1 -0
- package/dist/schema/tracking.d.ts +644 -0
- package/dist/schema/tracking.d.ts.map +1 -0
- package/dist/schema/tracking.js +204 -0
- package/dist/schema/tracking.js.map +1 -0
- package/dist/services/ContextGenerator.d.ts +16 -0
- package/dist/services/ContextGenerator.d.ts.map +1 -0
- package/dist/services/ContextGenerator.js +62 -0
- package/dist/services/ContextGenerator.js.map +1 -0
- package/dist/services/PlanManager.d.ts +99 -0
- package/dist/services/PlanManager.d.ts.map +1 -0
- package/dist/services/PlanManager.js +372 -0
- package/dist/services/PlanManager.js.map +1 -0
- package/dist/services/ProjectScaffold.d.ts.map +1 -1
- package/dist/services/ProjectScaffold.js +109 -81
- package/dist/services/ProjectScaffold.js.map +1 -1
- package/dist/services/TaskTracker.d.ts +1 -1
- package/dist/services/TaskTracker.d.ts.map +1 -1
- package/dist/services/TaskTracker.js +4 -8
- package/dist/services/TaskTracker.js.map +1 -1
- package/dist/services/WorkPlanManager.d.ts +1 -1
- package/dist/services/WorkPlanManager.d.ts.map +1 -1
- package/dist/services/WorkPlanManager.js +8 -14
- package/dist/services/WorkPlanManager.js.map +1 -1
- package/dist/services/auto-inject.d.ts +1 -0
- package/dist/services/auto-inject.d.ts.map +1 -1
- package/dist/services/auto-inject.js +12 -17
- package/dist/services/auto-inject.js.map +1 -1
- package/dist/services/context-injector.d.ts +105 -0
- package/dist/services/context-injector.d.ts.map +1 -0
- package/dist/services/context-injector.js +357 -0
- package/dist/services/context-injector.js.map +1 -0
- package/dist/services/cross-project-sync.d.ts +2 -0
- package/dist/services/cross-project-sync.d.ts.map +1 -1
- package/dist/services/cross-project-sync.js +26 -21
- package/dist/services/cross-project-sync.js.map +1 -1
- package/dist/services/index.d.ts +15 -15
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +18 -20
- package/dist/services/index.js.map +1 -1
- package/dist/services/memory-consolidation.d.ts.map +1 -1
- package/dist/services/memory-consolidation.js +30 -27
- package/dist/services/memory-consolidation.js.map +1 -1
- package/dist/services/memory-router.d.ts +98 -0
- package/dist/services/memory-router.d.ts.map +1 -0
- package/dist/services/memory-router.js +373 -0
- package/dist/services/memory-router.js.map +1 -0
- package/dist/services/pattern-tracker.d.ts +93 -0
- package/dist/services/pattern-tracker.d.ts.map +1 -0
- package/dist/services/pattern-tracker.js +347 -0
- package/dist/services/pattern-tracker.js.map +1 -0
- package/dist/services/semantic-search.d.ts +33 -35
- package/dist/services/semantic-search.d.ts.map +1 -1
- package/dist/services/semantic-search.js +207 -165
- package/dist/services/semantic-search.js.map +1 -1
- package/dist/utils/env-loader.d.ts +41 -0
- package/dist/utils/env-loader.d.ts.map +1 -0
- package/dist/utils/env-loader.js +78 -0
- package/dist/utils/env-loader.js.map +1 -0
- package/dist/utils/git.d.ts +52 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +267 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/paths.d.ts +39 -5
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +88 -7
- package/dist/utils/paths.js.map +1 -1
- package/package.json +100 -94
- package/standards/README.md +50 -0
- package/standards/experts/expert-routing.md +215 -0
- package/standards/general/code-quality.md +86 -0
- package/standards/general/memory-usage.md +205 -0
- package/standards/general/sync-workflow.md +235 -0
- package/standards/general/workflow.md +82 -0
- package/standards/hooks/mandatory-tracking.md +446 -0
- package/standards/infrastructure/cloud-database.md +287 -0
- package/standards/mcp/server-design.md +243 -0
- package/standards/mcp/tool-patterns.md +354 -0
- package/standards/skills/skill-structure.md +286 -0
- package/standards/skills/workflow-design.md +323 -0
- package/standards/tools/tool-design.md +297 -0
- package/templates/agents/architecture-expert.md +61 -61
- package/templates/agents/database-expert.md +62 -62
- package/templates/agents/documentation-expert.md +57 -57
- package/templates/agents/memory-expert.md +88 -88
- package/templates/agents/performance-expert.md +61 -61
- package/templates/agents/security-expert.md +59 -59
- package/templates/agents/ux-expert.md +63 -63
- package/templates/agents/worker.md +75 -75
- package/templates/ai-skills/SKILL_TEMPLATE.md +55 -55
- package/templates/claude-settings.json +72 -0
- package/templates/commands/experts.md +138 -138
- package/templates/hooks/README.md +158 -158
- package/templates/hooks/project.config.json.template +77 -77
- package/templates/hooks/settings.local.json.template +57 -57
- package/templates/memory-config.json +56 -82
- package/templates/memory-config.schema.json +212 -212
- package/templates/settings.json +58 -58
- package/templates/skills/continue.md +205 -0
- package/templates/workflows/business-improvement.md +264 -264
- package/templates/workflows/expert-review.md +153 -153
- package/templates/workflows/internal-app.md +245 -245
- package/templates/workflows/sync-docs.md +187 -187
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pattern Tracker Service
|
|
3
|
+
* @description Tracks code patterns and triggers auto-improvement when threshold is reached
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Track pattern occurrences across sessions
|
|
7
|
+
* - Detect when patterns reach threshold (default: 3)
|
|
8
|
+
* - Generate ESLint rules automatically
|
|
9
|
+
* - Create memory entries for gotchas
|
|
10
|
+
*/
|
|
11
|
+
import type { DevSystem } from '../types/index.js';
|
|
12
|
+
export interface PatternContext {
|
|
13
|
+
file: string;
|
|
14
|
+
line?: number;
|
|
15
|
+
code?: string;
|
|
16
|
+
sessionId?: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}
|
|
19
|
+
export interface TrackedPattern {
|
|
20
|
+
id: string;
|
|
21
|
+
patternId: string;
|
|
22
|
+
description: string;
|
|
23
|
+
count: number;
|
|
24
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
25
|
+
contexts: PatternContext[];
|
|
26
|
+
firstSeen: string;
|
|
27
|
+
lastSeen: string;
|
|
28
|
+
autoImproveTriggered: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface ESLintRuleSpec {
|
|
31
|
+
name: string;
|
|
32
|
+
description: string;
|
|
33
|
+
meta: {
|
|
34
|
+
type: 'problem' | 'suggestion' | 'layout';
|
|
35
|
+
docs: {
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
fixable?: 'code' | 'whitespace';
|
|
39
|
+
messages: Record<string, string>;
|
|
40
|
+
};
|
|
41
|
+
pattern: RegExp | string;
|
|
42
|
+
fix?: string;
|
|
43
|
+
}
|
|
44
|
+
declare class PatternTrackerService {
|
|
45
|
+
private violationThreshold;
|
|
46
|
+
/**
|
|
47
|
+
* Track a pattern occurrence
|
|
48
|
+
*/
|
|
49
|
+
track(patternId: string, context: PatternContext, system: DevSystem): Promise<{
|
|
50
|
+
count: number;
|
|
51
|
+
triggered: boolean;
|
|
52
|
+
rule?: ESLintRuleSpec;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Check current count for a pattern
|
|
56
|
+
*/
|
|
57
|
+
getCount(patternId: string, system: DevSystem): Promise<number>;
|
|
58
|
+
/**
|
|
59
|
+
* Get all patterns near threshold
|
|
60
|
+
*/
|
|
61
|
+
getPendingPatterns(system: DevSystem): Promise<TrackedPattern[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Trigger auto-improvement for a pattern
|
|
64
|
+
*/
|
|
65
|
+
triggerAutoImprovement(pattern: TrackedPattern, system: DevSystem): Promise<ESLintRuleSpec | undefined>;
|
|
66
|
+
/**
|
|
67
|
+
* Generate ESLint rule from pattern
|
|
68
|
+
*/
|
|
69
|
+
private generateEslintRule;
|
|
70
|
+
/**
|
|
71
|
+
* Convert ESLint rule spec to code
|
|
72
|
+
*/
|
|
73
|
+
private eslintRuleToCode;
|
|
74
|
+
/**
|
|
75
|
+
* Format gotcha memory body
|
|
76
|
+
*/
|
|
77
|
+
private formatGotchaBody;
|
|
78
|
+
/**
|
|
79
|
+
* Convert pattern ID to regex
|
|
80
|
+
*/
|
|
81
|
+
private patternToRegex;
|
|
82
|
+
/**
|
|
83
|
+
* Detect domain from contexts
|
|
84
|
+
*/
|
|
85
|
+
private detectDomain;
|
|
86
|
+
private findPattern;
|
|
87
|
+
private createPattern;
|
|
88
|
+
private savePattern;
|
|
89
|
+
private saveAutoImprovement;
|
|
90
|
+
}
|
|
91
|
+
export declare const patternTracker: PatternTrackerService;
|
|
92
|
+
export default patternTracker;
|
|
93
|
+
//# sourceMappingURL=pattern-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-tracker.d.ts","sourceRoot":"","sources":["../../src/services/pattern-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,SAAS,EAA0C,MAAM,mBAAmB,CAAA;AAM1F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IAChD,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,oBAAoB,EAAE,OAAO,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAA;QACzC,IAAI,EAAE;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;QAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAA;QAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACjC,CAAA;IACD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAyDD,cAAM,qBAAqB;IACzB,OAAO,CAAC,kBAAkB,CAAI;IAE9B;;OAEG;IACG,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC;QACT,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,OAAO,CAAA;QAClB,IAAI,CAAC,EAAE,cAAc,CAAA;KACtB,CAAC;IA0CF;;OAEG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrE;;OAEG;IACG,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA8BtE;;OAEG;IACG,sBAAsB,CAC1B,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IA+CtC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,YAAY;YAkBN,WAAW;YA0BX,aAAa;YAab,WAAW;YAYX,mBAAmB;CAalC;AAMD,eAAO,MAAM,cAAc,uBAA8B,CAAA;AACzD,eAAe,cAAc,CAAA"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pattern Tracker Service
|
|
3
|
+
* @description Tracks code patterns and triggers auto-improvement when threshold is reached
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Track pattern occurrences across sessions
|
|
7
|
+
* - Detect when patterns reach threshold (default: 3)
|
|
8
|
+
* - Generate ESLint rules automatically
|
|
9
|
+
* - Create memory entries for gotchas
|
|
10
|
+
*/
|
|
11
|
+
import { turso } from '../db/turso-client.js';
|
|
12
|
+
import { memoryRouter } from './memory-router.js';
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// Pattern Definitions
|
|
15
|
+
// =============================================================================
|
|
16
|
+
const KNOWN_PATTERNS = {
|
|
17
|
+
'finance-no-ledger': {
|
|
18
|
+
severity: 'critical',
|
|
19
|
+
eslintRuleName: 'charter/finance-ledger-sync',
|
|
20
|
+
description: 'Finance table insert without LedgerService.createEntry()'
|
|
21
|
+
},
|
|
22
|
+
'any-type': {
|
|
23
|
+
severity: 'high',
|
|
24
|
+
eslintRuleName: 'charter/no-any-type',
|
|
25
|
+
description: 'Using TypeScript any type'
|
|
26
|
+
},
|
|
27
|
+
'eslint-disable': {
|
|
28
|
+
severity: 'high',
|
|
29
|
+
eslintRuleName: 'charter/no-eslint-disable',
|
|
30
|
+
description: 'ESLint disable comment'
|
|
31
|
+
},
|
|
32
|
+
'raw-sql': {
|
|
33
|
+
severity: 'critical',
|
|
34
|
+
eslintRuleName: 'charter/no-raw-sql',
|
|
35
|
+
description: 'Raw SQL query instead of query builder'
|
|
36
|
+
},
|
|
37
|
+
'missing-zod': {
|
|
38
|
+
severity: 'high',
|
|
39
|
+
eslintRuleName: 'charter/require-zod-validation',
|
|
40
|
+
description: 'TRPC endpoint without Zod input validation'
|
|
41
|
+
},
|
|
42
|
+
'sequential-api-calls': {
|
|
43
|
+
severity: 'medium',
|
|
44
|
+
eslintRuleName: 'charter/no-sequential-api-calls',
|
|
45
|
+
description: 'Sequential API calls that could be parallelized'
|
|
46
|
+
},
|
|
47
|
+
'async-useeffect': {
|
|
48
|
+
severity: 'medium',
|
|
49
|
+
eslintRuleName: 'charter/no-async-useeffect',
|
|
50
|
+
description: 'Async function directly in useEffect'
|
|
51
|
+
},
|
|
52
|
+
'hardcoded-color': {
|
|
53
|
+
severity: 'low',
|
|
54
|
+
eslintRuleName: 'charter/use-semantic-tokens',
|
|
55
|
+
description: 'Hardcoded color value instead of semantic token'
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Pattern Tracker Implementation
|
|
60
|
+
// =============================================================================
|
|
61
|
+
class PatternTrackerService {
|
|
62
|
+
violationThreshold = 3;
|
|
63
|
+
/**
|
|
64
|
+
* Track a pattern occurrence
|
|
65
|
+
*/
|
|
66
|
+
async track(patternId, context, system) {
|
|
67
|
+
const existing = await this.findPattern(patternId, system);
|
|
68
|
+
if (existing) {
|
|
69
|
+
// Increment count
|
|
70
|
+
existing.count++;
|
|
71
|
+
existing.lastSeen = new Date().toISOString();
|
|
72
|
+
existing.contexts.push(context);
|
|
73
|
+
// Keep only last 10 contexts
|
|
74
|
+
if (existing.contexts.length > 10) {
|
|
75
|
+
existing.contexts = existing.contexts.slice(-10);
|
|
76
|
+
}
|
|
77
|
+
await this.savePattern(existing, system);
|
|
78
|
+
// Check if threshold reached
|
|
79
|
+
if (existing.count >= this.violationThreshold && !existing.autoImproveTriggered) {
|
|
80
|
+
const rule = await this.triggerAutoImprovement(existing, system);
|
|
81
|
+
return { count: existing.count, triggered: true, rule };
|
|
82
|
+
}
|
|
83
|
+
return { count: existing.count, triggered: false };
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Create new pattern tracking
|
|
87
|
+
const newPattern = {
|
|
88
|
+
id: `pattern_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
89
|
+
patternId,
|
|
90
|
+
description: KNOWN_PATTERNS[patternId]?.description || context.description,
|
|
91
|
+
count: 1,
|
|
92
|
+
severity: KNOWN_PATTERNS[patternId]?.severity || 'medium',
|
|
93
|
+
contexts: [context],
|
|
94
|
+
firstSeen: new Date().toISOString(),
|
|
95
|
+
lastSeen: new Date().toISOString(),
|
|
96
|
+
autoImproveTriggered: false
|
|
97
|
+
};
|
|
98
|
+
await this.createPattern(newPattern, system);
|
|
99
|
+
return { count: 1, triggered: false };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Check current count for a pattern
|
|
104
|
+
*/
|
|
105
|
+
async getCount(patternId, system) {
|
|
106
|
+
const pattern = await this.findPattern(patternId, system);
|
|
107
|
+
return pattern?.count || 0;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get all patterns near threshold
|
|
111
|
+
*/
|
|
112
|
+
async getPendingPatterns(system) {
|
|
113
|
+
try {
|
|
114
|
+
const db = turso.getClient();
|
|
115
|
+
const result = await db.execute({
|
|
116
|
+
sql: `SELECT id, content FROM items
|
|
117
|
+
WHERE system = ? AND type = 'pattern'
|
|
118
|
+
AND status = 'active'`,
|
|
119
|
+
args: [system]
|
|
120
|
+
});
|
|
121
|
+
const patterns = result.rows
|
|
122
|
+
.map(row => {
|
|
123
|
+
try {
|
|
124
|
+
const content = typeof row.content === 'string'
|
|
125
|
+
? JSON.parse(row.content)
|
|
126
|
+
: row.content;
|
|
127
|
+
return { ...content, id: row.id };
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
.filter((p) => p !== null);
|
|
134
|
+
// Return patterns with count >= 2 (close to threshold)
|
|
135
|
+
return patterns.filter(p => p.count >= 2 && !p.autoImproveTriggered);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Trigger auto-improvement for a pattern
|
|
143
|
+
*/
|
|
144
|
+
async triggerAutoImprovement(pattern, system) {
|
|
145
|
+
console.log(`🔁 [PatternTracker] Auto-improvement triggered for: ${pattern.patternId}`);
|
|
146
|
+
console.log(` Occurrences: ${pattern.count} (threshold: ${this.violationThreshold})`);
|
|
147
|
+
// Mark as triggered
|
|
148
|
+
pattern.autoImproveTriggered = true;
|
|
149
|
+
await this.savePattern(pattern, system);
|
|
150
|
+
// Update status to 'triggered'
|
|
151
|
+
const db = turso.getClient();
|
|
152
|
+
await db.execute({
|
|
153
|
+
sql: `UPDATE items SET status = 'triggered', updated_at = datetime('now')
|
|
154
|
+
WHERE id = ?`,
|
|
155
|
+
args: [pattern.id]
|
|
156
|
+
});
|
|
157
|
+
// Generate ESLint rule if we have a template
|
|
158
|
+
const knownPattern = KNOWN_PATTERNS[pattern.patternId];
|
|
159
|
+
if (knownPattern?.eslintRuleName) {
|
|
160
|
+
const rule = this.generateEslintRule(pattern, knownPattern.eslintRuleName);
|
|
161
|
+
// Save auto-improvement record
|
|
162
|
+
await this.saveAutoImprovement({
|
|
163
|
+
patternId: pattern.patternId,
|
|
164
|
+
action: 'eslint_rule',
|
|
165
|
+
status: 'pending',
|
|
166
|
+
generatedCode: this.eslintRuleToCode(rule),
|
|
167
|
+
filePath: `src/eslint/rules/${rule.name}.ts`
|
|
168
|
+
}, system);
|
|
169
|
+
return rule;
|
|
170
|
+
}
|
|
171
|
+
// Create memory entry for the gotcha
|
|
172
|
+
await memoryRouter.write({
|
|
173
|
+
system,
|
|
174
|
+
title: `Gotcha: ${pattern.description}`,
|
|
175
|
+
body: this.formatGotchaBody(pattern),
|
|
176
|
+
domain: this.detectDomain(pattern.contexts),
|
|
177
|
+
tags: ['gotcha', 'auto-improvement', pattern.patternId],
|
|
178
|
+
source: 'system',
|
|
179
|
+
priority: pattern.severity
|
|
180
|
+
});
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Generate ESLint rule from pattern
|
|
185
|
+
*/
|
|
186
|
+
generateEslintRule(pattern, ruleName) {
|
|
187
|
+
return {
|
|
188
|
+
name: ruleName,
|
|
189
|
+
description: pattern.description,
|
|
190
|
+
meta: {
|
|
191
|
+
type: 'problem',
|
|
192
|
+
docs: {
|
|
193
|
+
description: pattern.description
|
|
194
|
+
},
|
|
195
|
+
messages: {
|
|
196
|
+
violation: pattern.description
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
pattern: this.patternToRegex(pattern.patternId),
|
|
200
|
+
fix: undefined
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Convert ESLint rule spec to code
|
|
205
|
+
*/
|
|
206
|
+
eslintRuleToCode(rule) {
|
|
207
|
+
return `/**
|
|
208
|
+
* @file ${rule.name}
|
|
209
|
+
* @description ${rule.description}
|
|
210
|
+
* Auto-generated by cmp-standards pattern detection
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
module.exports = {
|
|
214
|
+
meta: {
|
|
215
|
+
type: '${rule.meta.type}',
|
|
216
|
+
docs: {
|
|
217
|
+
description: '${rule.description}',
|
|
218
|
+
category: 'Best Practices',
|
|
219
|
+
recommended: true
|
|
220
|
+
},
|
|
221
|
+
messages: ${JSON.stringify(rule.meta.messages, null, 2)}
|
|
222
|
+
},
|
|
223
|
+
create(context) {
|
|
224
|
+
return {
|
|
225
|
+
// TODO: Implement rule logic based on pattern
|
|
226
|
+
// Pattern: ${rule.pattern}
|
|
227
|
+
Program(node) {
|
|
228
|
+
// Rule implementation
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
`;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Format gotcha memory body
|
|
237
|
+
*/
|
|
238
|
+
formatGotchaBody(pattern) {
|
|
239
|
+
const lines = [
|
|
240
|
+
`## Pattern: ${pattern.description}`,
|
|
241
|
+
'',
|
|
242
|
+
`**Severity**: ${pattern.severity}`,
|
|
243
|
+
`**Occurrences**: ${pattern.count}`,
|
|
244
|
+
`**First seen**: ${pattern.firstSeen}`,
|
|
245
|
+
`**Last seen**: ${pattern.lastSeen}`,
|
|
246
|
+
'',
|
|
247
|
+
'## Occurrences',
|
|
248
|
+
''
|
|
249
|
+
];
|
|
250
|
+
for (const ctx of pattern.contexts.slice(-5)) {
|
|
251
|
+
lines.push(`- \`${ctx.file}${ctx.line ? `:${ctx.line}` : ''}\`: ${ctx.description}`);
|
|
252
|
+
}
|
|
253
|
+
lines.push('');
|
|
254
|
+
lines.push('## Prevention');
|
|
255
|
+
lines.push('');
|
|
256
|
+
lines.push('This pattern has been automatically flagged for improvement.');
|
|
257
|
+
return lines.join('\n');
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Convert pattern ID to regex
|
|
261
|
+
*/
|
|
262
|
+
patternToRegex(patternId) {
|
|
263
|
+
const regexMap = {
|
|
264
|
+
'finance-no-ledger': 'insert\\(finance\\)(?!.*LedgerService)',
|
|
265
|
+
'any-type': ':\\s*any\\b',
|
|
266
|
+
'eslint-disable': 'eslint-disable',
|
|
267
|
+
'raw-sql': 'db\\.execute\\([\'"`]',
|
|
268
|
+
'missing-zod': 'publicProcedure\\.mutation\\(async\\s*\\(\\{\\s*input',
|
|
269
|
+
'sequential-api-calls': 'await.*\\nawait',
|
|
270
|
+
'async-useeffect': 'useEffect\\(async',
|
|
271
|
+
'hardcoded-color': '#[0-9a-fA-F]{3,6}'
|
|
272
|
+
};
|
|
273
|
+
return regexMap[patternId] || patternId;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Detect domain from contexts
|
|
277
|
+
*/
|
|
278
|
+
detectDomain(contexts) {
|
|
279
|
+
const domains = ['finances', 'reserves', 'crew', 'boats', 'marketing'];
|
|
280
|
+
for (const ctx of contexts) {
|
|
281
|
+
for (const domain of domains) {
|
|
282
|
+
if (ctx.file.toLowerCase().includes(domain)) {
|
|
283
|
+
return domain;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return 'general';
|
|
288
|
+
}
|
|
289
|
+
// =============================================================================
|
|
290
|
+
// Database Operations
|
|
291
|
+
// =============================================================================
|
|
292
|
+
async findPattern(patternId, system) {
|
|
293
|
+
try {
|
|
294
|
+
const db = turso.getClient();
|
|
295
|
+
const result = await db.execute({
|
|
296
|
+
sql: `SELECT id, content FROM items
|
|
297
|
+
WHERE system = ? AND type = 'pattern'
|
|
298
|
+
AND json_extract(content, '$.patternId') = ?
|
|
299
|
+
LIMIT 1`,
|
|
300
|
+
args: [system, patternId]
|
|
301
|
+
});
|
|
302
|
+
if (result.rows.length === 0)
|
|
303
|
+
return null;
|
|
304
|
+
const row = result.rows[0];
|
|
305
|
+
const content = typeof row.content === 'string'
|
|
306
|
+
? JSON.parse(row.content)
|
|
307
|
+
: row.content;
|
|
308
|
+
return { ...content, id: row.id };
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async createPattern(pattern, system) {
|
|
315
|
+
const db = turso.getClient();
|
|
316
|
+
const now = new Date().toISOString();
|
|
317
|
+
await db.execute({
|
|
318
|
+
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
319
|
+
VALUES (?, ?, 'pattern', 'active', ?, ?, ?)`,
|
|
320
|
+
args: [pattern.id, system, JSON.stringify(pattern), now, now]
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
async savePattern(pattern, _system) {
|
|
324
|
+
const db = turso.getClient();
|
|
325
|
+
await db.execute({
|
|
326
|
+
sql: `UPDATE items SET content = ?, updated_at = datetime('now')
|
|
327
|
+
WHERE id = ?`,
|
|
328
|
+
args: [JSON.stringify(pattern), pattern.id]
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
async saveAutoImprovement(improvement, system) {
|
|
332
|
+
const db = turso.getClient();
|
|
333
|
+
const id = `ai_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
334
|
+
const now = new Date().toISOString();
|
|
335
|
+
await db.execute({
|
|
336
|
+
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
337
|
+
VALUES (?, ?, 'auto_improvement', 'pending', ?, ?, ?)`,
|
|
338
|
+
args: [id, system, JSON.stringify(improvement), now, now]
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// =============================================================================
|
|
343
|
+
// Export Singleton
|
|
344
|
+
// =============================================================================
|
|
345
|
+
export const patternTracker = new PatternTrackerService();
|
|
346
|
+
export default patternTracker;
|
|
347
|
+
//# sourceMappingURL=pattern-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-tracker.js","sourceRoot":"","sources":["../../src/services/pattern-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Semantic Search Service
|
|
3
3
|
*
|
|
4
|
-
* Provides
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - Performs cosine similarity search
|
|
4
|
+
* Provides hybrid search for memories:
|
|
5
|
+
* 1. Vector Search (Upstash): Semantic understanding
|
|
6
|
+
* 2. Text Search (MySQL): Keyword matching
|
|
8
7
|
*/
|
|
9
|
-
import type { DrizzleMemoryClient } from
|
|
10
|
-
import type { DevItem, MemoryContent } from
|
|
8
|
+
import type { DrizzleMemoryClient } from "../db/drizzle-client.js";
|
|
9
|
+
import type { DevItem, MemoryContent } from "../types/index.js";
|
|
11
10
|
export interface SemanticSearchResult {
|
|
12
11
|
item: DevItem;
|
|
13
12
|
score: number;
|
|
14
13
|
content: MemoryContent;
|
|
14
|
+
source: "vector" | "text";
|
|
15
15
|
}
|
|
16
16
|
export interface MemoryWithEmbedding extends MemoryContent {
|
|
17
17
|
embedding?: number[];
|
|
@@ -21,10 +21,11 @@ export interface MemoryWithEmbedding extends MemoryContent {
|
|
|
21
21
|
export declare class SemanticSearchService {
|
|
22
22
|
private embeddingService;
|
|
23
23
|
private client;
|
|
24
|
+
private vectorIndex?;
|
|
24
25
|
private cache;
|
|
25
26
|
constructor(client: DrizzleMemoryClient);
|
|
26
27
|
/**
|
|
27
|
-
* Search
|
|
28
|
+
* Hybrid Search: Vector + Keyword
|
|
28
29
|
*/
|
|
29
30
|
search(query: string, options?: {
|
|
30
31
|
type?: string;
|
|
@@ -33,61 +34,58 @@ export declare class SemanticSearchService {
|
|
|
33
34
|
domain?: string;
|
|
34
35
|
}): Promise<SemanticSearchResult[]>;
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
+
* Search via Upstash Vector
|
|
38
|
+
*/
|
|
39
|
+
private searchVector;
|
|
40
|
+
/**
|
|
41
|
+
* Create memory with embedding and sync to Vector DB
|
|
37
42
|
*/
|
|
38
43
|
createMemoryWithEmbedding(title: string, body: string, options?: {
|
|
39
44
|
domain?: string;
|
|
40
|
-
source?:
|
|
45
|
+
source?: "claude" | "gemini" | "user" | "system" | "checkpoint" | "dashboard";
|
|
41
46
|
tags?: string[];
|
|
42
47
|
relatedFiles?: string[];
|
|
43
48
|
}): Promise<{
|
|
44
49
|
id: string;
|
|
45
50
|
embedded: boolean;
|
|
51
|
+
synced: boolean;
|
|
46
52
|
}>;
|
|
47
53
|
/**
|
|
48
54
|
* Find similar memories to a given memory
|
|
49
55
|
*/
|
|
50
56
|
findSimilar(memoryId: string, limit?: number): Promise<SemanticSearchResult[]>;
|
|
51
57
|
/**
|
|
52
|
-
*
|
|
58
|
+
* Get embedding with caching
|
|
53
59
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
private getEmbedding;
|
|
61
|
+
/**
|
|
62
|
+
* Fallback to text search when embedding fails
|
|
63
|
+
*/
|
|
64
|
+
private fallbackTextSearch;
|
|
65
|
+
/**
|
|
66
|
+
* Batch embed memories that don't have embeddings yet
|
|
67
|
+
*/
|
|
68
|
+
batchEmbed(options: {
|
|
56
69
|
limit?: number;
|
|
57
|
-
force?: boolean;
|
|
58
70
|
}): Promise<{
|
|
59
71
|
processed: number;
|
|
60
|
-
|
|
72
|
+
succeeded: number;
|
|
61
73
|
failed: number;
|
|
74
|
+
synced: number;
|
|
62
75
|
}>;
|
|
63
76
|
/**
|
|
64
77
|
* Get embedding statistics
|
|
65
78
|
*/
|
|
66
79
|
getEmbeddingStats(): Promise<{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
totalMemories: number;
|
|
81
|
+
withEmbeddings: number;
|
|
82
|
+
withoutEmbeddings: number;
|
|
83
|
+
vectorIndexCount: number;
|
|
84
|
+
embeddingRate: string;
|
|
71
85
|
}>;
|
|
72
|
-
/**
|
|
73
|
-
* Get embedding with caching
|
|
74
|
-
*/
|
|
75
|
-
private getEmbedding;
|
|
76
|
-
/**
|
|
77
|
-
* Update memory with embedding
|
|
78
|
-
*/
|
|
79
|
-
private updateWithEmbedding;
|
|
80
|
-
/**
|
|
81
|
-
* Calculate cosine similarity between two vectors
|
|
82
|
-
*/
|
|
83
|
-
private cosineSimilarity;
|
|
84
|
-
/**
|
|
85
|
-
* Fallback to text search when embedding fails
|
|
86
|
-
*/
|
|
87
|
-
private fallbackTextSearch;
|
|
88
86
|
}
|
|
89
87
|
/**
|
|
90
|
-
*
|
|
88
|
+
* Factory
|
|
91
89
|
*/
|
|
92
90
|
export declare function createSemanticSearchService(client: DrizzleMemoryClient): SemanticSearchService;
|
|
93
91
|
//# sourceMappingURL=semantic-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMhE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,KAAK,CAAoC;gBAErC,MAAM,EAAE,mBAAmB;IAgBvC;;OAEG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA6BlC;;OAEG;YACW,YAAY;IAsC1B;;OAEG;IACG,yBAAyB,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EACH,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,YAAY,GACZ,WAAW,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,GACA,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAsD9D;;OAEG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAI,GACR,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAclC;;OAEG;YACW,YAAY;IAgB1B;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACrD,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAmEF;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CA+CH;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,mBAAmB,GAC1B,qBAAqB,CAEvB"}
|