cmp-standards 3.5.0 → 3.7.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 +399 -633
- package/dist/analytics/CrossProjectAnalytics.js +65 -65
- package/dist/cli/index.js +255 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/tokens.js +173 -173
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +2 -0
- package/dist/db/client.js.map +1 -1
- package/dist/db/cloud.d.ts +1 -0
- package/dist/db/cloud.d.ts.map +1 -1
- package/dist/db/drizzle-client.d.ts +2 -2
- package/dist/db/drizzle-client.d.ts.map +1 -1
- package/dist/db/drizzle-client.js +0 -1
- package/dist/db/drizzle-client.js.map +1 -1
- package/dist/db/migrations.js +256 -256
- package/dist/db/turso-client.js +2 -2
- package/dist/db/upstash-client.d.ts +9 -0
- package/dist/db/upstash-client.d.ts.map +1 -1
- package/dist/db/upstash-client.js +11 -0
- package/dist/db/upstash-client.js.map +1 -1
- package/dist/eslint/rules/no-async-useeffect.js +6 -6
- package/dist/experts/ExpertVotePersistence.js +9 -9
- package/dist/feedback/collector.d.ts.map +1 -1
- package/dist/feedback/collector.js +6 -2
- package/dist/feedback/collector.js.map +1 -1
- package/dist/hooks/cloud-post-tool-use.d.ts.map +1 -1
- package/dist/hooks/cloud-post-tool-use.js +72 -10
- package/dist/hooks/cloud-post-tool-use.js.map +1 -1
- package/dist/hooks/cloud-pre-tool-use.d.ts +12 -9
- package/dist/hooks/cloud-pre-tool-use.d.ts.map +1 -1
- package/dist/hooks/cloud-pre-tool-use.js +227 -99
- package/dist/hooks/cloud-pre-tool-use.js.map +1 -1
- package/dist/hooks/cloud-session-start.d.ts.map +1 -1
- package/dist/hooks/cloud-session-start.js +19 -16
- package/dist/hooks/cloud-session-start.js.map +1 -1
- package/dist/hooks/resilient-hook-runner.d.ts +78 -0
- package/dist/hooks/resilient-hook-runner.d.ts.map +1 -0
- package/dist/hooks/resilient-hook-runner.js +201 -0
- package/dist/hooks/resilient-hook-runner.js.map +1 -0
- package/dist/hooks/session-end.js +14 -14
- package/dist/patterns/registry.js +90 -90
- package/dist/registry/generator.d.ts.map +1 -1
- package/dist/registry/generator.js +31 -21
- package/dist/registry/generator.js.map +1 -1
- package/dist/schema/codewiki-types.d.ts +10 -10
- package/dist/schema/docs-types.d.ts +8 -8
- package/dist/schema/ecosystem-types.d.ts +12 -12
- package/dist/schema/expert-types.d.ts +2 -2
- package/dist/schema/opportunity-types.d.ts +6 -6
- package/dist/schema/tracking.d.ts +2 -2
- package/dist/services/BootstrapService.d.ts +123 -0
- package/dist/services/BootstrapService.d.ts.map +1 -0
- package/dist/services/BootstrapService.js +309 -0
- package/dist/services/BootstrapService.js.map +1 -0
- package/dist/services/CodeWikiIndexer.js +3 -3
- package/dist/services/ContextGenerator.js +7 -7
- package/dist/services/FeedbackCollector.js +11 -11
- package/dist/services/GitIntegration.d.ts.map +1 -1
- package/dist/services/GitIntegration.js +27 -23
- package/dist/services/GitIntegration.js.map +1 -1
- package/dist/services/HookVerifier.js +70 -70
- package/dist/services/KnowledgeGapDetector.d.ts +122 -0
- package/dist/services/KnowledgeGapDetector.d.ts.map +1 -0
- package/dist/services/KnowledgeGapDetector.js +530 -0
- package/dist/services/KnowledgeGapDetector.js.map +1 -0
- package/dist/services/ProjectScaffold.d.ts.map +1 -1
- package/dist/services/ProjectScaffold.js +79 -78
- package/dist/services/ProjectScaffold.js.map +1 -1
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/knowledge-graph.d.ts +121 -0
- package/dist/services/knowledge-graph.d.ts.map +1 -0
- package/dist/services/knowledge-graph.js +446 -0
- package/dist/services/knowledge-graph.js.map +1 -0
- package/dist/services/memory-router.d.ts +25 -0
- package/dist/services/memory-router.d.ts.map +1 -1
- package/dist/services/memory-router.js +236 -98
- package/dist/services/memory-router.js.map +1 -1
- package/dist/services/pattern-learning.d.ts +79 -0
- package/dist/services/pattern-learning.d.ts.map +1 -0
- package/dist/services/pattern-learning.js +312 -0
- package/dist/services/pattern-learning.js.map +1 -0
- package/dist/services/pattern-tracker.js +95 -95
- package/dist/services/semantic-search.d.ts.map +1 -1
- package/dist/services/semantic-search.js +12 -8
- package/dist/services/semantic-search.js.map +1 -1
- package/package.json +124 -116
- package/standards/README.md +94 -50
- package/standards/experts/expert-routing.md +215 -215
- package/standards/general/code-quality.md +86 -86
- package/standards/general/ecosystem.md +243 -0
- package/standards/general/learning-loop.md +192 -0
- package/standards/general/memory-usage.md +205 -205
- package/standards/general/project-onboarding.md +339 -0
- package/standards/general/sync-workflow.md +235 -235
- package/standards/general/workflow.md +82 -82
- package/standards/hooks/mandatory-tracking.md +446 -446
- package/standards/infrastructure/cloud-database.md +287 -287
- package/standards/mcp/server-design.md +243 -243
- package/standards/mcp/tool-patterns.md +354 -354
- package/standards/skills/skill-structure.md +286 -286
- package/standards/skills/workflow-design.md +323 -323
- package/standards/tools/tool-design.md +297 -297
- 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/ecosystem-expert.md +104 -0
- 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 -72
- 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/hooks.config.json +21 -0
- package/templates/memory-config.json +56 -56
- package/templates/memory-config.schema.json +212 -212
- package/templates/settings.json +58 -58
- package/templates/skills/continue.md +205 -205
- 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,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Cross-System Pattern Learning Service
|
|
3
|
+
* @description Enables patterns detected in one system to inform others
|
|
4
|
+
*
|
|
5
|
+
* Key Features:
|
|
6
|
+
* - Pattern propagation across systems
|
|
7
|
+
* - Severity-based filtering
|
|
8
|
+
* - System relationship mapping
|
|
9
|
+
* - Pattern deduplication across systems
|
|
10
|
+
*/
|
|
11
|
+
import { turso } from '../db/turso-client.js';
|
|
12
|
+
import { upstash } from '../db/upstash-client.js';
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// System Relationships
|
|
15
|
+
// =============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Define which systems should share patterns
|
|
18
|
+
* Strong: Same technology stack, share all patterns
|
|
19
|
+
* Moderate: Related domains, share high+ severity
|
|
20
|
+
* Weak: Different domains, share critical only
|
|
21
|
+
*/
|
|
22
|
+
const SYSTEM_RELATIONSHIPS = [
|
|
23
|
+
// PANEL and ECOSYSTEM share TypeScript/React patterns
|
|
24
|
+
{ source: 'PANEL', target: 'ECOSYSTEM', strength: 'strong', domains: ['dev', 'frontend'] },
|
|
25
|
+
{ source: 'ECOSYSTEM', target: 'PANEL', strength: 'strong', domains: ['dev', 'frontend'] },
|
|
26
|
+
// CONNECTA_HOTEL and CONNECTA_CREW share integration patterns
|
|
27
|
+
{ source: 'CONNECTA_HOTEL', target: 'CONNECTA_CREW', strength: 'moderate', domains: ['integrations', 'api'] },
|
|
28
|
+
{ source: 'CONNECTA_CREW', target: 'CONNECTA_HOTEL', strength: 'moderate', domains: ['integrations', 'api'] },
|
|
29
|
+
// SWARMSCALE shares AI patterns with all
|
|
30
|
+
{ source: 'SWARMSCALE', target: 'PANEL', strength: 'moderate', domains: ['ai', 'agents'] },
|
|
31
|
+
{ source: 'SWARMSCALE', target: 'ECOSYSTEM', strength: 'moderate', domains: ['ai', 'agents'] },
|
|
32
|
+
// All systems share critical security patterns
|
|
33
|
+
{ source: 'PANEL', target: 'CONNECTA_HOTEL', strength: 'weak', domains: ['security'] },
|
|
34
|
+
{ source: 'PANEL', target: 'CONNECTA_CREW', strength: 'weak', domains: ['security'] },
|
|
35
|
+
{ source: 'ECOSYSTEM', target: 'CONNECTA_HOTEL', strength: 'weak', domains: ['security'] },
|
|
36
|
+
{ source: 'ECOSYSTEM', target: 'CONNECTA_CREW', strength: 'weak', domains: ['security'] },
|
|
37
|
+
];
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Pattern Learning Service
|
|
40
|
+
// =============================================================================
|
|
41
|
+
class PatternLearningService {
|
|
42
|
+
/**
|
|
43
|
+
* Propagate patterns from one system to related systems
|
|
44
|
+
*/
|
|
45
|
+
async propagatePatterns(sourceSystem, options) {
|
|
46
|
+
const result = { propagated: 0, skipped: 0, systems: [] };
|
|
47
|
+
const minSeverity = options?.minSeverity || 'medium';
|
|
48
|
+
const domains = options?.domains;
|
|
49
|
+
// Get triggered patterns from source system
|
|
50
|
+
const patterns = await this.getTriggeredPatterns(sourceSystem, minSeverity);
|
|
51
|
+
if (patterns.length === 0) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
// Find related systems
|
|
55
|
+
const relationships = this.getRelatedSystems(sourceSystem, domains);
|
|
56
|
+
for (const rel of relationships) {
|
|
57
|
+
// Filter patterns by relationship strength
|
|
58
|
+
const eligiblePatterns = patterns.filter(p => this.isPatternEligible(p, rel.strength));
|
|
59
|
+
if (eligiblePatterns.length === 0)
|
|
60
|
+
continue;
|
|
61
|
+
// Check for existing patterns in target system
|
|
62
|
+
const existingIds = await this.getExistingPatternIds(rel.target);
|
|
63
|
+
// Propagate each pattern
|
|
64
|
+
for (const pattern of eligiblePatterns) {
|
|
65
|
+
const crossSystemId = `${pattern.patternId}_${sourceSystem}_${rel.target}`;
|
|
66
|
+
if (existingIds.has(pattern.patternId) || existingIds.has(crossSystemId)) {
|
|
67
|
+
result.skipped++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (!options?.dryRun) {
|
|
71
|
+
await this.createCrossSystemPattern({
|
|
72
|
+
...pattern,
|
|
73
|
+
id: crossSystemId,
|
|
74
|
+
originSystem: sourceSystem,
|
|
75
|
+
targetSystems: [rel.target],
|
|
76
|
+
propagatedAt: new Date().toISOString()
|
|
77
|
+
}, rel.target);
|
|
78
|
+
}
|
|
79
|
+
result.propagated++;
|
|
80
|
+
}
|
|
81
|
+
if (!result.systems.includes(rel.target)) {
|
|
82
|
+
result.systems.push(rel.target);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
console.log(`[PatternLearning] Propagated ${result.propagated} patterns from ${sourceSystem} to ${result.systems.join(', ')}`);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get patterns that should trigger warnings in related systems
|
|
90
|
+
*/
|
|
91
|
+
async getWarningsForSystem(system) {
|
|
92
|
+
const db = turso.getClient();
|
|
93
|
+
// Get patterns from related systems that apply to this system
|
|
94
|
+
const relationships = SYSTEM_RELATIONSHIPS.filter(r => r.target === system);
|
|
95
|
+
const sourceSystems = [...new Set(relationships.map(r => r.source))];
|
|
96
|
+
if (sourceSystems.length === 0) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
const placeholders = sourceSystems.map(() => '?').join(', ');
|
|
100
|
+
const result = await db.execute({
|
|
101
|
+
sql: `
|
|
102
|
+
SELECT * FROM items
|
|
103
|
+
WHERE type = 'cross_system_pattern'
|
|
104
|
+
AND system = ?
|
|
105
|
+
AND status = 'active'
|
|
106
|
+
AND json_extract(content, '$.originSystem') IN (${placeholders})
|
|
107
|
+
ORDER BY json_extract(content, '$.severity') DESC,
|
|
108
|
+
json_extract(content, '$.occurrences') DESC
|
|
109
|
+
LIMIT 20
|
|
110
|
+
`,
|
|
111
|
+
args: [system, ...sourceSystems]
|
|
112
|
+
});
|
|
113
|
+
return result.rows.map(row => {
|
|
114
|
+
const content = typeof row.content === 'string'
|
|
115
|
+
? JSON.parse(row.content)
|
|
116
|
+
: row.content;
|
|
117
|
+
return content;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Learn from a pattern occurrence and propagate if threshold met
|
|
122
|
+
*/
|
|
123
|
+
async learnFromPattern(system, patternId, occurrence) {
|
|
124
|
+
// Update pattern occurrence count
|
|
125
|
+
const updated = await this.incrementPatternOccurrence(system, patternId, occurrence);
|
|
126
|
+
// Check if pattern has reached propagation threshold
|
|
127
|
+
if (updated.occurrences >= 3 && updated.severity !== 'low') {
|
|
128
|
+
const result = await this.propagatePatterns(system, {
|
|
129
|
+
minSeverity: updated.severity
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
propagated: result.propagated > 0,
|
|
133
|
+
targetSystems: result.systems
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return { propagated: false, targetSystems: [] };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get pattern recommendations for a file based on cross-system learning
|
|
140
|
+
*/
|
|
141
|
+
async getRecommendationsForFile(system, filePath) {
|
|
142
|
+
// Detect domain from file path
|
|
143
|
+
const domain = this.detectDomainFromPath(filePath);
|
|
144
|
+
// Get warnings for this system
|
|
145
|
+
const warnings = await this.getWarningsForSystem(system);
|
|
146
|
+
// Filter by domain relevance
|
|
147
|
+
return warnings.filter(w => {
|
|
148
|
+
// Always include critical patterns
|
|
149
|
+
if (w.severity === 'critical')
|
|
150
|
+
return true;
|
|
151
|
+
// Check if any file in the pattern matches the current domain
|
|
152
|
+
const patternDomains = w.files.map(f => this.detectDomainFromPath(f.path));
|
|
153
|
+
return domain && patternDomains.includes(domain);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// =============================================================================
|
|
157
|
+
// Private Methods
|
|
158
|
+
// =============================================================================
|
|
159
|
+
async getTriggeredPatterns(system, minSeverity) {
|
|
160
|
+
const db = turso.getClient();
|
|
161
|
+
const severityLevels = ['critical', 'high', 'medium', 'low'];
|
|
162
|
+
const minIndex = severityLevels.indexOf(minSeverity);
|
|
163
|
+
const eligibleSeverities = severityLevels.slice(0, minIndex + 1);
|
|
164
|
+
const placeholders = eligibleSeverities.map(() => '?').join(', ');
|
|
165
|
+
const result = await db.execute({
|
|
166
|
+
sql: `
|
|
167
|
+
SELECT * FROM items
|
|
168
|
+
WHERE system = ?
|
|
169
|
+
AND type = 'pattern'
|
|
170
|
+
AND status = 'triggered'
|
|
171
|
+
AND json_extract(content, '$.severity') IN (${placeholders})
|
|
172
|
+
`,
|
|
173
|
+
args: [system, ...eligibleSeverities]
|
|
174
|
+
});
|
|
175
|
+
return result.rows.map(row => {
|
|
176
|
+
const content = typeof row.content === 'string'
|
|
177
|
+
? JSON.parse(row.content)
|
|
178
|
+
: row.content;
|
|
179
|
+
return content;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
getRelatedSystems(source, domains) {
|
|
183
|
+
return SYSTEM_RELATIONSHIPS.filter(r => {
|
|
184
|
+
if (r.source !== source)
|
|
185
|
+
return false;
|
|
186
|
+
if (!domains)
|
|
187
|
+
return true;
|
|
188
|
+
return r.domains.some(d => domains.includes(d));
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
isPatternEligible(pattern, strength) {
|
|
192
|
+
switch (strength) {
|
|
193
|
+
case 'strong':
|
|
194
|
+
return true; // All severities
|
|
195
|
+
case 'moderate':
|
|
196
|
+
return pattern.severity === 'critical' || pattern.severity === 'high';
|
|
197
|
+
case 'weak':
|
|
198
|
+
return pattern.severity === 'critical';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async getExistingPatternIds(system) {
|
|
202
|
+
const db = turso.getClient();
|
|
203
|
+
const result = await db.execute({
|
|
204
|
+
sql: `
|
|
205
|
+
SELECT json_extract(content, '$.patternId') as patternId
|
|
206
|
+
FROM items
|
|
207
|
+
WHERE system = ?
|
|
208
|
+
AND type IN ('pattern', 'cross_system_pattern')
|
|
209
|
+
`,
|
|
210
|
+
args: [system]
|
|
211
|
+
});
|
|
212
|
+
return new Set(result.rows.map(r => r.patternId));
|
|
213
|
+
}
|
|
214
|
+
async createCrossSystemPattern(pattern, targetSystem) {
|
|
215
|
+
const db = turso.getClient();
|
|
216
|
+
const now = new Date().toISOString();
|
|
217
|
+
await db.execute({
|
|
218
|
+
sql: `
|
|
219
|
+
INSERT INTO items (id, type, status, system, content, created_at, updated_at)
|
|
220
|
+
VALUES (?, 'cross_system_pattern', 'active', ?, ?, ?, ?)
|
|
221
|
+
`,
|
|
222
|
+
args: [pattern.id, targetSystem, JSON.stringify(pattern), now, now]
|
|
223
|
+
});
|
|
224
|
+
// Also index in vector for semantic search
|
|
225
|
+
await upstash.upsertVector(pattern.id, `${pattern.description}\n\nOrigin: ${pattern.originSystem}\nSeverity: ${pattern.severity}`, {
|
|
226
|
+
type: 'cross_system_pattern',
|
|
227
|
+
system: targetSystem,
|
|
228
|
+
originSystem: pattern.originSystem,
|
|
229
|
+
severity: pattern.severity,
|
|
230
|
+
patternId: pattern.patternId
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
async incrementPatternOccurrence(system, patternId, occurrence) {
|
|
234
|
+
const db = turso.getClient();
|
|
235
|
+
const now = new Date().toISOString();
|
|
236
|
+
// Get existing pattern
|
|
237
|
+
const existing = await db.execute({
|
|
238
|
+
sql: `
|
|
239
|
+
SELECT * FROM items
|
|
240
|
+
WHERE system = ?
|
|
241
|
+
AND type = 'pattern'
|
|
242
|
+
AND json_extract(content, '$.patternId') = ?
|
|
243
|
+
`,
|
|
244
|
+
args: [system, patternId]
|
|
245
|
+
});
|
|
246
|
+
if (existing.rows.length > 0) {
|
|
247
|
+
const row = existing.rows[0];
|
|
248
|
+
const rawContent = row.content;
|
|
249
|
+
const content = typeof rawContent === 'string'
|
|
250
|
+
? JSON.parse(rawContent)
|
|
251
|
+
: rawContent;
|
|
252
|
+
// Update occurrences
|
|
253
|
+
content.occurrences = (content.occurrences || 0) + 1;
|
|
254
|
+
content.files = [...(content.files || []), occurrence];
|
|
255
|
+
content.lastSeen = now;
|
|
256
|
+
// Update status if threshold reached
|
|
257
|
+
const newStatus = content.occurrences >= 3 ? 'triggered' : 'active';
|
|
258
|
+
await db.execute({
|
|
259
|
+
sql: `
|
|
260
|
+
UPDATE items
|
|
261
|
+
SET content = ?, status = ?, updated_at = ?
|
|
262
|
+
WHERE id = ?
|
|
263
|
+
`,
|
|
264
|
+
args: [JSON.stringify(content), newStatus, now, row.id]
|
|
265
|
+
});
|
|
266
|
+
return content;
|
|
267
|
+
}
|
|
268
|
+
// Pattern doesn't exist, return empty
|
|
269
|
+
return {
|
|
270
|
+
patternId,
|
|
271
|
+
description: 'Unknown pattern',
|
|
272
|
+
occurrences: 1,
|
|
273
|
+
severity: 'medium',
|
|
274
|
+
files: [occurrence],
|
|
275
|
+
firstSeen: now,
|
|
276
|
+
lastSeen: now
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
detectDomainFromPath(filePath) {
|
|
280
|
+
const domains = ['finances', 'reserves', 'crew', 'boats', 'marketing', 'dev', 'api', 'security', 'ai'];
|
|
281
|
+
const pathLower = filePath.toLowerCase();
|
|
282
|
+
for (const domain of domains) {
|
|
283
|
+
if (pathLower.includes(domain) || pathLower.includes(`/${domain}/`)) {
|
|
284
|
+
return domain;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// Detect by file type
|
|
288
|
+
if (pathLower.includes('/api/') || pathLower.includes('route.ts'))
|
|
289
|
+
return 'api';
|
|
290
|
+
if (pathLower.includes('/components/'))
|
|
291
|
+
return 'frontend';
|
|
292
|
+
if (pathLower.includes('/lib/') || pathLower.includes('/utils/'))
|
|
293
|
+
return 'dev';
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// =============================================================================
|
|
298
|
+
// Singleton Export
|
|
299
|
+
// =============================================================================
|
|
300
|
+
let instance = null;
|
|
301
|
+
export function getPatternLearning() {
|
|
302
|
+
if (!instance) {
|
|
303
|
+
instance = new PatternLearningService();
|
|
304
|
+
}
|
|
305
|
+
return instance;
|
|
306
|
+
}
|
|
307
|
+
export function resetPatternLearning() {
|
|
308
|
+
instance = null;
|
|
309
|
+
}
|
|
310
|
+
export const patternLearning = getPatternLearning();
|
|
311
|
+
export default patternLearning;
|
|
312
|
+
//# sourceMappingURL=pattern-learning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-learning.js","sourceRoot":"","sources":["../../src/services/pattern-learning.ts"],"names":[],"mappings":"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"}
|
|
@@ -113,8 +113,8 @@ class PatternTrackerService {
|
|
|
113
113
|
try {
|
|
114
114
|
const db = turso.getClient();
|
|
115
115
|
const result = await db.execute({
|
|
116
|
-
sql: `SELECT id, content FROM items
|
|
117
|
-
WHERE system = ? AND type = 'pattern'
|
|
116
|
+
sql: `SELECT id, content FROM items
|
|
117
|
+
WHERE system = ? AND type = 'pattern'
|
|
118
118
|
AND status = 'active'`,
|
|
119
119
|
args: [system]
|
|
120
120
|
});
|
|
@@ -150,7 +150,7 @@ class PatternTrackerService {
|
|
|
150
150
|
// Update status to 'triggered'
|
|
151
151
|
const db = turso.getClient();
|
|
152
152
|
await db.execute({
|
|
153
|
-
sql: `UPDATE items SET status = 'triggered', updated_at = datetime('now')
|
|
153
|
+
sql: `UPDATE items SET status = 'triggered', updated_at = datetime('now')
|
|
154
154
|
WHERE id = ?`,
|
|
155
155
|
args: [pattern.id]
|
|
156
156
|
});
|
|
@@ -205,28 +205,28 @@ class PatternTrackerService {
|
|
|
205
205
|
*/
|
|
206
206
|
eslintRuleToCode(rule) {
|
|
207
207
|
const ruleBody = this.generateRuleBody(rule.name);
|
|
208
|
-
return `/**
|
|
209
|
-
* @file ${rule.name}
|
|
210
|
-
* @description ${rule.description}
|
|
211
|
-
* Auto-generated by cmp-standards pattern detection
|
|
212
|
-
* @version 1.0.0
|
|
213
|
-
*/
|
|
214
|
-
|
|
215
|
-
module.exports = {
|
|
216
|
-
meta: {
|
|
217
|
-
type: '${rule.meta.type}',
|
|
218
|
-
docs: {
|
|
219
|
-
description: '${rule.description}',
|
|
220
|
-
category: 'Best Practices',
|
|
221
|
-
recommended: true
|
|
222
|
-
},
|
|
223
|
-
schema: [],
|
|
224
|
-
messages: ${JSON.stringify(rule.meta.messages, null, 2)}
|
|
225
|
-
},
|
|
226
|
-
create(context) {
|
|
227
|
-
${ruleBody}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
208
|
+
return `/**
|
|
209
|
+
* @file ${rule.name}
|
|
210
|
+
* @description ${rule.description}
|
|
211
|
+
* Auto-generated by cmp-standards pattern detection
|
|
212
|
+
* @version 1.0.0
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
module.exports = {
|
|
216
|
+
meta: {
|
|
217
|
+
type: '${rule.meta.type}',
|
|
218
|
+
docs: {
|
|
219
|
+
description: '${rule.description}',
|
|
220
|
+
category: 'Best Practices',
|
|
221
|
+
recommended: true
|
|
222
|
+
},
|
|
223
|
+
schema: [],
|
|
224
|
+
messages: ${JSON.stringify(rule.meta.messages, null, 2)}
|
|
225
|
+
},
|
|
226
|
+
create(context) {
|
|
227
|
+
${ruleBody}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
230
|
`;
|
|
231
231
|
}
|
|
232
232
|
/**
|
|
@@ -236,77 +236,77 @@ ${ruleBody}
|
|
|
236
236
|
// Pattern-specific implementations using AST visitors
|
|
237
237
|
switch (ruleName) {
|
|
238
238
|
case 'charter/no-any-type':
|
|
239
|
-
return ` return {
|
|
240
|
-
TSAnyKeyword(node) {
|
|
241
|
-
context.report({ node, messageId: 'violation' });
|
|
242
|
-
}
|
|
239
|
+
return ` return {
|
|
240
|
+
TSAnyKeyword(node) {
|
|
241
|
+
context.report({ node, messageId: 'violation' });
|
|
242
|
+
}
|
|
243
243
|
};`;
|
|
244
244
|
case 'charter/no-eslint-disable':
|
|
245
|
-
return ` const sourceCode = context.getSourceCode();
|
|
246
|
-
return {
|
|
247
|
-
Program() {
|
|
248
|
-
const comments = sourceCode.getAllComments();
|
|
249
|
-
for (const comment of comments) {
|
|
250
|
-
if (comment.value.includes('eslint-disable')) {
|
|
251
|
-
context.report({ loc: comment.loc, messageId: 'violation' });
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
245
|
+
return ` const sourceCode = context.getSourceCode();
|
|
246
|
+
return {
|
|
247
|
+
Program() {
|
|
248
|
+
const comments = sourceCode.getAllComments();
|
|
249
|
+
for (const comment of comments) {
|
|
250
|
+
if (comment.value.includes('eslint-disable')) {
|
|
251
|
+
context.report({ loc: comment.loc, messageId: 'violation' });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
255
|
};`;
|
|
256
256
|
case 'charter/no-async-useeffect':
|
|
257
|
-
return ` return {
|
|
258
|
-
CallExpression(node) {
|
|
259
|
-
if (
|
|
260
|
-
node.callee.type === 'Identifier' &&
|
|
261
|
-
node.callee.name === 'useEffect' &&
|
|
262
|
-
node.arguments[0] &&
|
|
263
|
-
node.arguments[0].async
|
|
264
|
-
) {
|
|
265
|
-
context.report({ node, messageId: 'violation' });
|
|
266
|
-
}
|
|
267
|
-
}
|
|
257
|
+
return ` return {
|
|
258
|
+
CallExpression(node) {
|
|
259
|
+
if (
|
|
260
|
+
node.callee.type === 'Identifier' &&
|
|
261
|
+
node.callee.name === 'useEffect' &&
|
|
262
|
+
node.arguments[0] &&
|
|
263
|
+
node.arguments[0].async
|
|
264
|
+
) {
|
|
265
|
+
context.report({ node, messageId: 'violation' });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
268
|
};`;
|
|
269
269
|
case 'charter/no-raw-sql':
|
|
270
|
-
return ` return {
|
|
271
|
-
CallExpression(node) {
|
|
272
|
-
if (
|
|
273
|
-
node.callee.type === 'MemberExpression' &&
|
|
274
|
-
node.callee.property.name === 'execute' &&
|
|
275
|
-
node.arguments[0]?.type === 'TemplateLiteral'
|
|
276
|
-
) {
|
|
277
|
-
context.report({ node, messageId: 'violation' });
|
|
278
|
-
}
|
|
279
|
-
}
|
|
270
|
+
return ` return {
|
|
271
|
+
CallExpression(node) {
|
|
272
|
+
if (
|
|
273
|
+
node.callee.type === 'MemberExpression' &&
|
|
274
|
+
node.callee.property.name === 'execute' &&
|
|
275
|
+
node.arguments[0]?.type === 'TemplateLiteral'
|
|
276
|
+
) {
|
|
277
|
+
context.report({ node, messageId: 'violation' });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
280
|
};`;
|
|
281
281
|
case 'charter/finance-ledger-sync':
|
|
282
|
-
return ` let hasFinanceInsert = false;
|
|
283
|
-
let hasLedgerCall = false;
|
|
284
|
-
return {
|
|
285
|
-
CallExpression(node) {
|
|
286
|
-
const callee = node.callee;
|
|
287
|
-
if (callee.property?.name === 'insert') hasFinanceInsert = true;
|
|
288
|
-
if (callee.object?.name === 'LedgerService') hasLedgerCall = true;
|
|
289
|
-
},
|
|
290
|
-
'Program:exit'(node) {
|
|
291
|
-
if (hasFinanceInsert && !hasLedgerCall) {
|
|
292
|
-
context.report({ node, messageId: 'violation' });
|
|
293
|
-
}
|
|
294
|
-
}
|
|
282
|
+
return ` let hasFinanceInsert = false;
|
|
283
|
+
let hasLedgerCall = false;
|
|
284
|
+
return {
|
|
285
|
+
CallExpression(node) {
|
|
286
|
+
const callee = node.callee;
|
|
287
|
+
if (callee.property?.name === 'insert') hasFinanceInsert = true;
|
|
288
|
+
if (callee.object?.name === 'LedgerService') hasLedgerCall = true;
|
|
289
|
+
},
|
|
290
|
+
'Program:exit'(node) {
|
|
291
|
+
if (hasFinanceInsert && !hasLedgerCall) {
|
|
292
|
+
context.report({ node, messageId: 'violation' });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
295
|
};`;
|
|
296
296
|
case 'charter/use-semantic-tokens':
|
|
297
|
-
return ` return {
|
|
298
|
-
Literal(node) {
|
|
299
|
-
if (typeof node.value === 'string' && /#[0-9a-fA-F]{3,8}/.test(node.value)) {
|
|
300
|
-
context.report({ node, messageId: 'violation' });
|
|
301
|
-
}
|
|
302
|
-
}
|
|
297
|
+
return ` return {
|
|
298
|
+
Literal(node) {
|
|
299
|
+
if (typeof node.value === 'string' && /#[0-9a-fA-F]{3,8}/.test(node.value)) {
|
|
300
|
+
context.report({ node, messageId: 'violation' });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
303
|
};`;
|
|
304
304
|
default:
|
|
305
|
-
return ` // Auto-generated rule - implement based on pattern
|
|
306
|
-
return {
|
|
307
|
-
Program(node) {
|
|
308
|
-
// Pattern detection logic here
|
|
309
|
-
}
|
|
305
|
+
return ` // Auto-generated rule - implement based on pattern
|
|
306
|
+
return {
|
|
307
|
+
Program(node) {
|
|
308
|
+
// Pattern detection logic here
|
|
309
|
+
}
|
|
310
310
|
};`;
|
|
311
311
|
}
|
|
312
312
|
}
|
|
@@ -371,9 +371,9 @@ ${ruleBody}
|
|
|
371
371
|
try {
|
|
372
372
|
const db = turso.getClient();
|
|
373
373
|
const result = await db.execute({
|
|
374
|
-
sql: `SELECT id, content FROM items
|
|
375
|
-
WHERE system = ? AND type = 'pattern'
|
|
376
|
-
AND json_extract(content, '$.patternId') = ?
|
|
374
|
+
sql: `SELECT id, content FROM items
|
|
375
|
+
WHERE system = ? AND type = 'pattern'
|
|
376
|
+
AND json_extract(content, '$.patternId') = ?
|
|
377
377
|
LIMIT 1`,
|
|
378
378
|
args: [system, patternId]
|
|
379
379
|
});
|
|
@@ -393,7 +393,7 @@ ${ruleBody}
|
|
|
393
393
|
const db = turso.getClient();
|
|
394
394
|
const now = new Date().toISOString();
|
|
395
395
|
await db.execute({
|
|
396
|
-
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
396
|
+
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
397
397
|
VALUES (?, ?, 'pattern', 'active', ?, ?, ?)`,
|
|
398
398
|
args: [pattern.id, system, JSON.stringify(pattern), now, now]
|
|
399
399
|
});
|
|
@@ -401,7 +401,7 @@ ${ruleBody}
|
|
|
401
401
|
async savePattern(pattern, _system) {
|
|
402
402
|
const db = turso.getClient();
|
|
403
403
|
await db.execute({
|
|
404
|
-
sql: `UPDATE items SET content = ?, updated_at = datetime('now')
|
|
404
|
+
sql: `UPDATE items SET content = ?, updated_at = datetime('now')
|
|
405
405
|
WHERE id = ?`,
|
|
406
406
|
args: [JSON.stringify(pattern), pattern.id]
|
|
407
407
|
});
|
|
@@ -411,7 +411,7 @@ ${ruleBody}
|
|
|
411
411
|
const id = `ai_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
412
412
|
const now = new Date().toISOString();
|
|
413
413
|
await db.execute({
|
|
414
|
-
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
414
|
+
sql: `INSERT INTO items (id, system, type, status, content, created_at, updated_at)
|
|
415
415
|
VALUES (?, ?, 'auto_improvement', 'pending', ?, ?, ?)`,
|
|
416
416
|
args: [id, system, JSON.stringify(improvement), now, now]
|
|
417
417
|
});
|
|
@@ -427,8 +427,8 @@ class PatternEvolutionService {
|
|
|
427
427
|
const generatedAt = now.toISOString();
|
|
428
428
|
// Get all patterns for this system
|
|
429
429
|
const patternsResult = await db.execute({
|
|
430
|
-
sql: `SELECT id, content, created_at FROM items
|
|
431
|
-
WHERE system = ? AND type = 'pattern'
|
|
430
|
+
sql: `SELECT id, content, created_at FROM items
|
|
431
|
+
WHERE system = ? AND type = 'pattern'
|
|
432
432
|
ORDER BY created_at DESC`,
|
|
433
433
|
args: [system]
|
|
434
434
|
});
|
|
@@ -507,9 +507,9 @@ class PatternEvolutionService {
|
|
|
507
507
|
weekEnd.setDate(weekEnd.getDate() - i * 7);
|
|
508
508
|
try {
|
|
509
509
|
const result = await db.execute({
|
|
510
|
-
sql: `SELECT content FROM items
|
|
511
|
-
WHERE system = ? AND type = 'pattern'
|
|
512
|
-
AND json_extract(content, '$.patternId') = ?
|
|
510
|
+
sql: `SELECT content FROM items
|
|
511
|
+
WHERE system = ? AND type = 'pattern'
|
|
512
|
+
AND json_extract(content, '$.patternId') = ?
|
|
513
513
|
AND updated_at BETWEEN ? AND ?`,
|
|
514
514
|
args: [system, patternId, weekStart.toISOString(), weekEnd.toISOString()]
|
|
515
515
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMhE;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,GAAE,MAA0D;CAIhF;AA4BD,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;;;;OAIG;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;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GACA,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA+DlC;;OAEG;YACW,YAAY;
|
|
1
|
+
{"version":3,"file":"semantic-search.d.ts","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMhE;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,GAAE,MAA0D;CAIhF;AA4BD,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;;;;OAIG;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;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GACA,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA+DlC;;OAEG;YACW,YAAY;IA6C1B;;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;;;OAGG;YACW,YAAY;IAmB1B;;OAEG;YACW,kBAAkB;IAuBhC;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACzE,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAwFF;;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"}
|
|
@@ -123,16 +123,20 @@ export class SemanticSearchService {
|
|
|
123
123
|
topK: options.limit,
|
|
124
124
|
includeMetadata: true,
|
|
125
125
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Fetch full item from DB to ensure schema consistency
|
|
126
|
+
// Filter by threshold first, then batch fetch from DB
|
|
127
|
+
const validResults = results.filter(res => res.score >= options.threshold);
|
|
128
|
+
// Batch fetch all items in parallel to avoid N+1 queries
|
|
129
|
+
const itemsWithScores = await Promise.all(validResults.map(async (res) => {
|
|
131
130
|
const item = await this.client.get(res.id);
|
|
131
|
+
return { item, score: res.score };
|
|
132
|
+
}));
|
|
133
|
+
// Build results from fetched items
|
|
134
|
+
const matchedResults = [];
|
|
135
|
+
for (const { item, score } of itemsWithScores) {
|
|
132
136
|
if (item) {
|
|
133
137
|
matchedResults.push({
|
|
134
138
|
item,
|
|
135
|
-
score
|
|
139
|
+
score,
|
|
136
140
|
content: item.content,
|
|
137
141
|
source: "vector",
|
|
138
142
|
});
|
|
@@ -149,7 +153,7 @@ export class SemanticSearchService {
|
|
|
149
153
|
* Create memory with embedding and sync to Vector DB
|
|
150
154
|
*/
|
|
151
155
|
async createMemoryWithEmbedding(title, body, options) {
|
|
152
|
-
const text = `${title}
|
|
156
|
+
const text = `${title}
|
|
153
157
|
${body}`;
|
|
154
158
|
let embedding;
|
|
155
159
|
let embeddingModel;
|
|
@@ -208,7 +212,7 @@ ${body}`;
|
|
|
208
212
|
const content = memory.content;
|
|
209
213
|
if (!content)
|
|
210
214
|
return [];
|
|
211
|
-
const text = `${content.title}
|
|
215
|
+
const text = `${content.title}
|
|
212
216
|
${content.body}`;
|
|
213
217
|
return this.search(text, { limit: limit + 1 }).then((results) => results.filter((r) => r.item.id !== memoryId).slice(0, limit));
|
|
214
218
|
}
|