cmp-standards 2.7.0 → 2.8.0-alpha
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 -633
- package/dist/cache/EmbeddingCache.d.ts +109 -0
- package/dist/cache/EmbeddingCache.d.ts.map +1 -0
- package/dist/cache/EmbeddingCache.js +239 -0
- package/dist/cache/EmbeddingCache.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cli/index.js +0 -0
- package/dist/db/turso-client.js +11 -11
- package/dist/eslint/rules/no-async-useeffect.js +6 -6
- package/dist/events/EventBus.d.ts +87 -0
- package/dist/events/EventBus.d.ts.map +1 -0
- package/dist/events/EventBus.js +200 -0
- package/dist/events/EventBus.js.map +1 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +9 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +989 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +136 -0
- package/dist/events/types.js.map +1 -0
- package/dist/experts/ConsensusEngine.d.ts +57 -0
- package/dist/experts/ConsensusEngine.d.ts.map +1 -0
- package/dist/experts/ConsensusEngine.js +146 -0
- package/dist/experts/ConsensusEngine.js.map +1 -0
- package/dist/experts/ExpertPanelService.d.ts +84 -0
- package/dist/experts/ExpertPanelService.d.ts.map +1 -0
- package/dist/experts/ExpertPanelService.js +204 -0
- package/dist/experts/ExpertPanelService.js.map +1 -0
- package/dist/experts/ExpertRouter.d.ts +68 -0
- package/dist/experts/ExpertRouter.d.ts.map +1 -0
- package/dist/experts/ExpertRouter.js +374 -0
- package/dist/experts/ExpertRouter.js.map +1 -0
- package/dist/experts/VoteCollector.d.ts +58 -0
- package/dist/experts/VoteCollector.d.ts.map +1 -0
- package/dist/experts/VoteCollector.js +146 -0
- package/dist/experts/VoteCollector.js.map +1 -0
- package/dist/experts/index.d.ts +9 -0
- package/dist/experts/index.d.ts.map +1 -0
- package/dist/experts/index.js +13 -0
- package/dist/experts/index.js.map +1 -0
- package/dist/hooks/cloud-pre-tool-use.js +20 -20
- package/dist/hooks/expert-review.d.ts +74 -0
- package/dist/hooks/expert-review.d.ts.map +1 -0
- package/dist/hooks/expert-review.js +220 -0
- package/dist/hooks/expert-review.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/performance/Debouncer.d.ts +91 -0
- package/dist/performance/Debouncer.d.ts.map +1 -0
- package/dist/performance/Debouncer.js +198 -0
- package/dist/performance/Debouncer.js.map +1 -0
- package/dist/performance/MemoryDecay.d.ts +82 -0
- package/dist/performance/MemoryDecay.d.ts.map +1 -0
- package/dist/performance/MemoryDecay.js +153 -0
- package/dist/performance/MemoryDecay.js.map +1 -0
- package/dist/performance/index.d.ts +7 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +9 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/schema/expert-types.d.ts +395 -0
- package/dist/schema/expert-types.d.ts.map +1 -0
- package/dist/schema/expert-types.js +250 -0
- package/dist/schema/expert-types.js.map +1 -0
- package/dist/services/ContextGenerator.js +7 -7
- package/dist/services/ProjectScaffold.js +76 -76
- package/dist/services/memory-router.js +35 -35
- package/dist/services/pattern-tracker.js +90 -90
- package/dist/services/semantic-search.js +2 -2
- package/package.json +105 -104
- package/standards/README.md +50 -50
- package/standards/experts/expert-routing.md +215 -215
- package/standards/general/code-quality.md +86 -86
- package/standards/general/memory-usage.md +205 -205
- 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/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/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
|
@@ -42,13 +42,13 @@ export class ContextGenerator {
|
|
|
42
42
|
if (content.includes(splitMarker)) {
|
|
43
43
|
content = content.split(splitMarker)[0];
|
|
44
44
|
}
|
|
45
|
-
const freshContext = `
|
|
46
|
-
${splitMarker}
|
|
47
|
-
### Active Tasks
|
|
48
|
-
${tasksMd || "- No active tasks."}
|
|
49
|
-
|
|
50
|
-
### Recent Memories
|
|
51
|
-
${memoriesMd || "- No recent memories."}
|
|
45
|
+
const freshContext = `
|
|
46
|
+
${splitMarker}
|
|
47
|
+
### Active Tasks
|
|
48
|
+
${tasksMd || "- No active tasks."}
|
|
49
|
+
|
|
50
|
+
### Recent Memories
|
|
51
|
+
${memoriesMd || "- No recent memories."}
|
|
52
52
|
`;
|
|
53
53
|
await fs.writeFile(filePath, content + freshContext, "utf-8");
|
|
54
54
|
return true;
|
|
@@ -248,19 +248,19 @@ export class ProjectScaffold {
|
|
|
248
248
|
generateClaudeMd(scan, options) {
|
|
249
249
|
const system = options.system.toUpperCase();
|
|
250
250
|
const projectName = options.projectName || scan.name;
|
|
251
|
-
let content = `# CLAUDE.md - ${projectName}
|
|
252
|
-
|
|
253
|
-
> **System**: ${system}
|
|
254
|
-
> **Generated**: ${new Date().toISOString().split('T')[0]}
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
|
-
## Project Overview
|
|
259
|
-
|
|
260
|
-
${projectName} is part of the **MetaNautical Group** ecosystem.
|
|
261
|
-
|
|
262
|
-
### Tech Stack
|
|
263
|
-
|
|
251
|
+
let content = `# CLAUDE.md - ${projectName}
|
|
252
|
+
|
|
253
|
+
> **System**: ${system}
|
|
254
|
+
> **Generated**: ${new Date().toISOString().split('T')[0]}
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Project Overview
|
|
259
|
+
|
|
260
|
+
${projectName} is part of the **MetaNautical Group** ecosystem.
|
|
261
|
+
|
|
262
|
+
### Tech Stack
|
|
263
|
+
|
|
264
264
|
`;
|
|
265
265
|
// Framework
|
|
266
266
|
if (scan.framework.name !== 'unknown') {
|
|
@@ -294,33 +294,33 @@ ${projectName} is part of the **MetaNautical Group** ecosystem.
|
|
|
294
294
|
if (scan.api.type !== 'none') {
|
|
295
295
|
content += `- **API**: ${scan.api.type.toUpperCase()}\n`;
|
|
296
296
|
}
|
|
297
|
-
content += `
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
## Core Rules (Non-Negotiable)
|
|
301
|
-
|
|
302
|
-
### Code Quality
|
|
303
|
-
- NO \`any\`/\`unknown\` types - use proper typing
|
|
304
|
-
- NO ESLint disable comments without justification
|
|
305
|
-
- **Never Assume**: Verify files/constants exist before using
|
|
306
|
-
|
|
307
|
-
### Security
|
|
308
|
-
- All inputs must be validated with Zod
|
|
309
|
-
- Use \`protectedProcedure\` for authenticated routes
|
|
310
|
-
- Never expose sensitive data in responses
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
## Structure
|
|
315
|
-
|
|
316
|
-
\`\`\`
|
|
317
|
-
${scan.name}/
|
|
318
|
-
├── .claude/ # Claude Code configuration
|
|
319
|
-
│ ├── agents/ # AI expert agents
|
|
320
|
-
│ ├── commands/ # Slash commands (/experts, etc.)
|
|
321
|
-
│ ├── hooks/ # Session hooks
|
|
322
|
-
│ └── project.config.json
|
|
323
|
-
├── .ai-skills/ # Project-specific knowledge
|
|
297
|
+
content += `
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Core Rules (Non-Negotiable)
|
|
301
|
+
|
|
302
|
+
### Code Quality
|
|
303
|
+
- NO \`any\`/\`unknown\` types - use proper typing
|
|
304
|
+
- NO ESLint disable comments without justification
|
|
305
|
+
- **Never Assume**: Verify files/constants exist before using
|
|
306
|
+
|
|
307
|
+
### Security
|
|
308
|
+
- All inputs must be validated with Zod
|
|
309
|
+
- Use \`protectedProcedure\` for authenticated routes
|
|
310
|
+
- Never expose sensitive data in responses
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Structure
|
|
315
|
+
|
|
316
|
+
\`\`\`
|
|
317
|
+
${scan.name}/
|
|
318
|
+
├── .claude/ # Claude Code configuration
|
|
319
|
+
│ ├── agents/ # AI expert agents
|
|
320
|
+
│ ├── commands/ # Slash commands (/experts, etc.)
|
|
321
|
+
│ ├── hooks/ # Session hooks
|
|
322
|
+
│ └── project.config.json
|
|
323
|
+
├── .ai-skills/ # Project-specific knowledge
|
|
324
324
|
`;
|
|
325
325
|
if (scan.structure.srcDir) {
|
|
326
326
|
content += `├── src/\n`;
|
|
@@ -331,42 +331,42 @@ ${scan.name}/
|
|
|
331
331
|
content += `│ ├── server/\n`;
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
|
-
content += `└── CLAUDE.md # This file
|
|
335
|
-
\`\`\`
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
## Commands
|
|
340
|
-
|
|
341
|
-
### Development
|
|
342
|
-
\`\`\`bash
|
|
343
|
-
npm run dev # Start dev server
|
|
344
|
-
npm run build # Production build
|
|
345
|
-
npm run lint # ESLint check
|
|
346
|
-
npm run typecheck # TypeScript check
|
|
347
|
-
\`\`\`
|
|
348
|
-
|
|
349
|
-
### Memory System
|
|
350
|
-
\`\`\`bash
|
|
351
|
-
cmp-memory status # Check memory system health
|
|
352
|
-
cmp-memory validate # Validate project structure
|
|
353
|
-
cmp-memory sync # Sync experts/hooks from npm
|
|
354
|
-
\`\`\`
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## Expert Review
|
|
359
|
-
|
|
360
|
-
Use \`/experts\` for code review:
|
|
361
|
-
|
|
362
|
-
\`\`\`bash
|
|
363
|
-
/experts src/path/to/file.ts # Review specific file
|
|
364
|
-
/experts src/server/api/ # Review directory
|
|
365
|
-
\`\`\`
|
|
366
|
-
|
|
367
|
-
---
|
|
368
|
-
|
|
369
|
-
*Part of MetaNautical Group ecosystem*
|
|
334
|
+
content += `└── CLAUDE.md # This file
|
|
335
|
+
\`\`\`
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Commands
|
|
340
|
+
|
|
341
|
+
### Development
|
|
342
|
+
\`\`\`bash
|
|
343
|
+
npm run dev # Start dev server
|
|
344
|
+
npm run build # Production build
|
|
345
|
+
npm run lint # ESLint check
|
|
346
|
+
npm run typecheck # TypeScript check
|
|
347
|
+
\`\`\`
|
|
348
|
+
|
|
349
|
+
### Memory System
|
|
350
|
+
\`\`\`bash
|
|
351
|
+
cmp-memory status # Check memory system health
|
|
352
|
+
cmp-memory validate # Validate project structure
|
|
353
|
+
cmp-memory sync # Sync experts/hooks from npm
|
|
354
|
+
\`\`\`
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
## Expert Review
|
|
359
|
+
|
|
360
|
+
Use \`/experts\` for code review:
|
|
361
|
+
|
|
362
|
+
\`\`\`bash
|
|
363
|
+
/experts src/path/to/file.ts # Review specific file
|
|
364
|
+
/experts src/server/api/ # Review directory
|
|
365
|
+
\`\`\`
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
*Part of MetaNautical Group ecosystem*
|
|
370
370
|
`;
|
|
371
371
|
return content;
|
|
372
372
|
}
|
|
@@ -116,11 +116,11 @@ class MemoryRouterService {
|
|
|
116
116
|
try {
|
|
117
117
|
const db = turso.getClient();
|
|
118
118
|
const result = await db.execute({
|
|
119
|
-
sql: `SELECT * FROM items
|
|
120
|
-
WHERE system = ? AND type = 'memory'
|
|
121
|
-
AND json_extract(content, '$.domain') = ?
|
|
122
|
-
AND status != 'archived'
|
|
123
|
-
ORDER BY updated_at DESC
|
|
119
|
+
sql: `SELECT * FROM items
|
|
120
|
+
WHERE system = ? AND type = 'memory'
|
|
121
|
+
AND json_extract(content, '$.domain') = ?
|
|
122
|
+
AND status != 'archived'
|
|
123
|
+
ORDER BY updated_at DESC
|
|
124
124
|
LIMIT ?`,
|
|
125
125
|
args: [system, domain, limit]
|
|
126
126
|
});
|
|
@@ -138,16 +138,16 @@ class MemoryRouterService {
|
|
|
138
138
|
await this.init();
|
|
139
139
|
try {
|
|
140
140
|
const db = turso.getClient();
|
|
141
|
-
let sql = `
|
|
142
|
-
SELECT * FROM items
|
|
143
|
-
WHERE system = ? AND type = 'memory'
|
|
144
|
-
AND status = 'active'
|
|
145
|
-
AND (
|
|
146
|
-
json_extract(content, '$.title') LIKE '%gotcha%'
|
|
147
|
-
OR json_extract(content, '$.title') LIKE '%bug%'
|
|
148
|
-
OR json_extract(content, '$.title') LIKE '%issue%'
|
|
149
|
-
OR json_extract(content, '$.title') LIKE '%warning%'
|
|
150
|
-
)
|
|
141
|
+
let sql = `
|
|
142
|
+
SELECT * FROM items
|
|
143
|
+
WHERE system = ? AND type = 'memory'
|
|
144
|
+
AND status = 'active'
|
|
145
|
+
AND (
|
|
146
|
+
json_extract(content, '$.title') LIKE '%gotcha%'
|
|
147
|
+
OR json_extract(content, '$.title') LIKE '%bug%'
|
|
148
|
+
OR json_extract(content, '$.title') LIKE '%issue%'
|
|
149
|
+
OR json_extract(content, '$.title') LIKE '%warning%'
|
|
150
|
+
)
|
|
151
151
|
`;
|
|
152
152
|
const args = [system];
|
|
153
153
|
if (domain) {
|
|
@@ -171,10 +171,10 @@ class MemoryRouterService {
|
|
|
171
171
|
try {
|
|
172
172
|
const db = turso.getClient();
|
|
173
173
|
const result = await db.execute({
|
|
174
|
-
sql: `SELECT * FROM items
|
|
175
|
-
WHERE system = ? AND type = 'memory'
|
|
176
|
-
AND status != 'archived'
|
|
177
|
-
ORDER BY updated_at DESC
|
|
174
|
+
sql: `SELECT * FROM items
|
|
175
|
+
WHERE system = ? AND type = 'memory'
|
|
176
|
+
AND status != 'archived'
|
|
177
|
+
ORDER BY updated_at DESC
|
|
178
178
|
LIMIT ?`,
|
|
179
179
|
args: [system, limit]
|
|
180
180
|
});
|
|
@@ -193,9 +193,9 @@ class MemoryRouterService {
|
|
|
193
193
|
try {
|
|
194
194
|
const db = turso.getClient();
|
|
195
195
|
const result = await db.execute({
|
|
196
|
-
sql: `SELECT * FROM items
|
|
197
|
-
WHERE system = ? AND type = 'pattern'
|
|
198
|
-
AND status = 'triggered'
|
|
196
|
+
sql: `SELECT * FROM items
|
|
197
|
+
WHERE system = ? AND type = 'pattern'
|
|
198
|
+
AND status = 'triggered'
|
|
199
199
|
ORDER BY updated_at DESC`,
|
|
200
200
|
args: [system]
|
|
201
201
|
});
|
|
@@ -245,12 +245,12 @@ class MemoryRouterService {
|
|
|
245
245
|
// Build query
|
|
246
246
|
const sinceEpoch = options?.sinceEpoch || (Date.now() - 7 * 24 * 60 * 60 * 1000); // Default: last 7 days
|
|
247
247
|
const limit = options?.limit || 100;
|
|
248
|
-
let sql = `
|
|
249
|
-
SELECT id, sdk_session_id, project, type, title, subtitle,
|
|
250
|
-
narrative, facts, concepts, files_read, files_modified,
|
|
251
|
-
created_at, created_at_epoch
|
|
252
|
-
FROM observations
|
|
253
|
-
WHERE created_at_epoch > ?
|
|
248
|
+
let sql = `
|
|
249
|
+
SELECT id, sdk_session_id, project, type, title, subtitle,
|
|
250
|
+
narrative, facts, concepts, files_read, files_modified,
|
|
251
|
+
created_at, created_at_epoch
|
|
252
|
+
FROM observations
|
|
253
|
+
WHERE created_at_epoch > ?
|
|
254
254
|
`;
|
|
255
255
|
const args = [sinceEpoch];
|
|
256
256
|
if (options?.project) {
|
|
@@ -329,8 +329,8 @@ class MemoryRouterService {
|
|
|
329
329
|
try {
|
|
330
330
|
const db = turso.getClient();
|
|
331
331
|
const result = await db.execute({
|
|
332
|
-
sql: `SELECT id FROM items
|
|
333
|
-
WHERE system = ? AND type = 'memory'
|
|
332
|
+
sql: `SELECT id FROM items
|
|
333
|
+
WHERE system = ? AND type = 'memory'
|
|
334
334
|
AND id LIKE 'claudemem_%'`,
|
|
335
335
|
args: [system]
|
|
336
336
|
});
|
|
@@ -383,11 +383,11 @@ class MemoryRouterService {
|
|
|
383
383
|
for (const term of searchTerms) {
|
|
384
384
|
args.push(`%${term}%`, `%${term}%`);
|
|
385
385
|
}
|
|
386
|
-
let sql = `
|
|
387
|
-
SELECT * FROM items
|
|
388
|
-
WHERE system = ? AND type = 'memory'
|
|
389
|
-
AND status != 'archived'
|
|
390
|
-
AND (${likeConditions})
|
|
386
|
+
let sql = `
|
|
387
|
+
SELECT * FROM items
|
|
388
|
+
WHERE system = ? AND type = 'memory'
|
|
389
|
+
AND status != 'archived'
|
|
390
|
+
AND (${likeConditions})
|
|
391
391
|
`;
|
|
392
392
|
if (domain) {
|
|
393
393
|
sql += ` AND json_extract(content, '$.domain') = ?`;
|
|
@@ -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
|
});
|
|
@@ -94,7 +94,7 @@ export class SemanticSearchService {
|
|
|
94
94
|
* Create memory with embedding and sync to Vector DB
|
|
95
95
|
*/
|
|
96
96
|
async createMemoryWithEmbedding(title, body, options) {
|
|
97
|
-
const text = `${title}
|
|
97
|
+
const text = `${title}
|
|
98
98
|
${body}`;
|
|
99
99
|
let embedding;
|
|
100
100
|
let embeddingModel;
|
|
@@ -153,7 +153,7 @@ ${body}`;
|
|
|
153
153
|
const content = memory.content;
|
|
154
154
|
if (!content)
|
|
155
155
|
return [];
|
|
156
|
-
const text = `${content.title}
|
|
156
|
+
const text = `${content.title}
|
|
157
157
|
${content.body}`;
|
|
158
158
|
return this.search(text, { limit: limit + 1 }).then((results) => results.filter((r) => r.item.id !== memoryId).slice(0, limit));
|
|
159
159
|
}
|