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.
Files changed (129) hide show
  1. package/README.md +399 -633
  2. package/dist/analytics/CrossProjectAnalytics.js +65 -65
  3. package/dist/cli/index.js +255 -12
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/dashboard/tokens.js +173 -173
  6. package/dist/db/client.d.ts.map +1 -1
  7. package/dist/db/client.js +2 -0
  8. package/dist/db/client.js.map +1 -1
  9. package/dist/db/cloud.d.ts +1 -0
  10. package/dist/db/cloud.d.ts.map +1 -1
  11. package/dist/db/drizzle-client.d.ts +2 -2
  12. package/dist/db/drizzle-client.d.ts.map +1 -1
  13. package/dist/db/drizzle-client.js +0 -1
  14. package/dist/db/drizzle-client.js.map +1 -1
  15. package/dist/db/migrations.js +256 -256
  16. package/dist/db/turso-client.js +2 -2
  17. package/dist/db/upstash-client.d.ts +9 -0
  18. package/dist/db/upstash-client.d.ts.map +1 -1
  19. package/dist/db/upstash-client.js +11 -0
  20. package/dist/db/upstash-client.js.map +1 -1
  21. package/dist/eslint/rules/no-async-useeffect.js +6 -6
  22. package/dist/experts/ExpertVotePersistence.js +9 -9
  23. package/dist/feedback/collector.d.ts.map +1 -1
  24. package/dist/feedback/collector.js +6 -2
  25. package/dist/feedback/collector.js.map +1 -1
  26. package/dist/hooks/cloud-post-tool-use.d.ts.map +1 -1
  27. package/dist/hooks/cloud-post-tool-use.js +72 -10
  28. package/dist/hooks/cloud-post-tool-use.js.map +1 -1
  29. package/dist/hooks/cloud-pre-tool-use.d.ts +12 -9
  30. package/dist/hooks/cloud-pre-tool-use.d.ts.map +1 -1
  31. package/dist/hooks/cloud-pre-tool-use.js +227 -99
  32. package/dist/hooks/cloud-pre-tool-use.js.map +1 -1
  33. package/dist/hooks/cloud-session-start.d.ts.map +1 -1
  34. package/dist/hooks/cloud-session-start.js +19 -16
  35. package/dist/hooks/cloud-session-start.js.map +1 -1
  36. package/dist/hooks/resilient-hook-runner.d.ts +78 -0
  37. package/dist/hooks/resilient-hook-runner.d.ts.map +1 -0
  38. package/dist/hooks/resilient-hook-runner.js +201 -0
  39. package/dist/hooks/resilient-hook-runner.js.map +1 -0
  40. package/dist/hooks/session-end.js +14 -14
  41. package/dist/patterns/registry.js +90 -90
  42. package/dist/registry/generator.d.ts.map +1 -1
  43. package/dist/registry/generator.js +31 -21
  44. package/dist/registry/generator.js.map +1 -1
  45. package/dist/schema/codewiki-types.d.ts +10 -10
  46. package/dist/schema/docs-types.d.ts +8 -8
  47. package/dist/schema/ecosystem-types.d.ts +12 -12
  48. package/dist/schema/expert-types.d.ts +2 -2
  49. package/dist/schema/opportunity-types.d.ts +6 -6
  50. package/dist/schema/tracking.d.ts +2 -2
  51. package/dist/services/BootstrapService.d.ts +123 -0
  52. package/dist/services/BootstrapService.d.ts.map +1 -0
  53. package/dist/services/BootstrapService.js +309 -0
  54. package/dist/services/BootstrapService.js.map +1 -0
  55. package/dist/services/CodeWikiIndexer.js +3 -3
  56. package/dist/services/ContextGenerator.js +7 -7
  57. package/dist/services/FeedbackCollector.js +11 -11
  58. package/dist/services/GitIntegration.d.ts.map +1 -1
  59. package/dist/services/GitIntegration.js +27 -23
  60. package/dist/services/GitIntegration.js.map +1 -1
  61. package/dist/services/HookVerifier.js +70 -70
  62. package/dist/services/KnowledgeGapDetector.d.ts +122 -0
  63. package/dist/services/KnowledgeGapDetector.d.ts.map +1 -0
  64. package/dist/services/KnowledgeGapDetector.js +530 -0
  65. package/dist/services/KnowledgeGapDetector.js.map +1 -0
  66. package/dist/services/ProjectScaffold.d.ts.map +1 -1
  67. package/dist/services/ProjectScaffold.js +79 -78
  68. package/dist/services/ProjectScaffold.js.map +1 -1
  69. package/dist/services/index.d.ts +4 -0
  70. package/dist/services/index.d.ts.map +1 -1
  71. package/dist/services/index.js +6 -0
  72. package/dist/services/index.js.map +1 -1
  73. package/dist/services/knowledge-graph.d.ts +121 -0
  74. package/dist/services/knowledge-graph.d.ts.map +1 -0
  75. package/dist/services/knowledge-graph.js +446 -0
  76. package/dist/services/knowledge-graph.js.map +1 -0
  77. package/dist/services/memory-router.d.ts +25 -0
  78. package/dist/services/memory-router.d.ts.map +1 -1
  79. package/dist/services/memory-router.js +236 -98
  80. package/dist/services/memory-router.js.map +1 -1
  81. package/dist/services/pattern-learning.d.ts +79 -0
  82. package/dist/services/pattern-learning.d.ts.map +1 -0
  83. package/dist/services/pattern-learning.js +312 -0
  84. package/dist/services/pattern-learning.js.map +1 -0
  85. package/dist/services/pattern-tracker.js +95 -95
  86. package/dist/services/semantic-search.d.ts.map +1 -1
  87. package/dist/services/semantic-search.js +12 -8
  88. package/dist/services/semantic-search.js.map +1 -1
  89. package/package.json +124 -116
  90. package/standards/README.md +94 -50
  91. package/standards/experts/expert-routing.md +215 -215
  92. package/standards/general/code-quality.md +86 -86
  93. package/standards/general/ecosystem.md +243 -0
  94. package/standards/general/learning-loop.md +192 -0
  95. package/standards/general/memory-usage.md +205 -205
  96. package/standards/general/project-onboarding.md +339 -0
  97. package/standards/general/sync-workflow.md +235 -235
  98. package/standards/general/workflow.md +82 -82
  99. package/standards/hooks/mandatory-tracking.md +446 -446
  100. package/standards/infrastructure/cloud-database.md +287 -287
  101. package/standards/mcp/server-design.md +243 -243
  102. package/standards/mcp/tool-patterns.md +354 -354
  103. package/standards/skills/skill-structure.md +286 -286
  104. package/standards/skills/workflow-design.md +323 -323
  105. package/standards/tools/tool-design.md +297 -297
  106. package/templates/agents/architecture-expert.md +61 -61
  107. package/templates/agents/database-expert.md +62 -62
  108. package/templates/agents/documentation-expert.md +57 -57
  109. package/templates/agents/ecosystem-expert.md +104 -0
  110. package/templates/agents/memory-expert.md +88 -88
  111. package/templates/agents/performance-expert.md +61 -61
  112. package/templates/agents/security-expert.md +59 -59
  113. package/templates/agents/ux-expert.md +63 -63
  114. package/templates/agents/worker.md +75 -75
  115. package/templates/ai-skills/SKILL_TEMPLATE.md +55 -55
  116. package/templates/claude-settings.json +72 -72
  117. package/templates/commands/experts.md +138 -138
  118. package/templates/hooks/README.md +158 -158
  119. package/templates/hooks/project.config.json.template +77 -77
  120. package/templates/hooks/settings.local.json.template +57 -57
  121. package/templates/hooks.config.json +21 -0
  122. package/templates/memory-config.json +56 -56
  123. package/templates/memory-config.schema.json +212 -212
  124. package/templates/settings.json +58 -58
  125. package/templates/skills/continue.md +205 -205
  126. package/templates/workflows/business-improvement.md +264 -264
  127. package/templates/workflows/expert-review.md +153 -153
  128. package/templates/workflows/internal-app.md +245 -245
  129. package/templates/workflows/sync-docs.md +187 -187
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient-hook-runner.d.ts","sourceRoot":"","sources":["../../src/hooks/resilient-hook-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE;QACR,eAAe,EAAE,OAAO,CAAA;QACxB,YAAY,EAAE,OAAO,CAAA;QACrB,YAAY,EAAE,OAAO,CAAA;QACrB,kBAAkB,EAAE,OAAO,CAAA;KAC5B,CAAA;CACF;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,YAAY,CAAA;AAsBnF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAiC9D;AAMD;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,CAAC,GACV,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAoB3C;AAMD,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;CACZ;AAID,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,IAAI,CAUtD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAQrE;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAMD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,WAAW,CAAQ;gBAEf,WAAW,EAAE,MAAM;IAK/B;;OAEG;IACG,OAAO,CACX,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,EACjC,QAAQ,GAAE,UAAuD,GAChE,OAAO,CAAC,UAAU,CAAC;IAyBtB;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,UAAU,CAAC,UAAU,CAAC,GAAG,OAAO;IAIhE;;OAEG;IACH,SAAS,IAAI,UAAU;CAGxB;AAMD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,SAAS,OAAO,EAAE,EAC9C,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,UAAU,CAAC,EAC/C,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB,GACA,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,UAAU,CAAC,CAiCzC;AAiBD,eAAe,mBAAmB,CAAA"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @file Resilient Hook Runner
3
+ * @description A fault-tolerant hook execution system that:
4
+ * - Fails silently (never blocks tool execution)
5
+ * - Uses timeouts to prevent hanging
6
+ * - Caches state to avoid repeated network calls
7
+ * - Supports per-project enable/disable
8
+ * - Provides graceful degradation
9
+ */
10
+ import { existsSync, readFileSync } from 'fs';
11
+ import { join } from 'path';
12
+ // =============================================================================
13
+ // Default Configuration
14
+ // =============================================================================
15
+ const DEFAULT_CONFIG = {
16
+ enabled: true,
17
+ timeout: 2000, // 2 second max
18
+ silentFail: true, // Never block on errors
19
+ features: {
20
+ sessionTracking: false, // Disable by default - causes network calls
21
+ taskTracking: false, // Disable by default - causes network calls
22
+ fileTracking: true, // Local only - fast
23
+ knowledgeInjection: true // Local + optional network
24
+ }
25
+ };
26
+ // =============================================================================
27
+ // Configuration Loading
28
+ // =============================================================================
29
+ /**
30
+ * Load hook configuration from project
31
+ * Checks: .claude/hooks.config.json > .claude/memory-config.json > defaults
32
+ */
33
+ export function loadHookConfig(projectRoot) {
34
+ // Priority 1: Dedicated hook config
35
+ const hookConfigPath = join(projectRoot, '.claude', 'hooks.config.json');
36
+ if (existsSync(hookConfigPath)) {
37
+ try {
38
+ const content = readFileSync(hookConfigPath, 'utf-8');
39
+ const parsed = JSON.parse(content);
40
+ return { ...DEFAULT_CONFIG, ...parsed };
41
+ }
42
+ catch {
43
+ // Invalid JSON, use defaults
44
+ }
45
+ }
46
+ // Priority 2: Memory config with hooks section
47
+ const memoryConfigPath = join(projectRoot, '.claude', 'memory-config.json');
48
+ if (existsSync(memoryConfigPath)) {
49
+ try {
50
+ const content = readFileSync(memoryConfigPath, 'utf-8');
51
+ const parsed = JSON.parse(content);
52
+ if (parsed.hooks) {
53
+ return { ...DEFAULT_CONFIG, ...parsed.hooks };
54
+ }
55
+ }
56
+ catch {
57
+ // Invalid JSON, use defaults
58
+ }
59
+ }
60
+ // Priority 3: Environment variable override
61
+ if (process.env.CMP_HOOKS_DISABLED === 'true') {
62
+ return { ...DEFAULT_CONFIG, enabled: false };
63
+ }
64
+ return DEFAULT_CONFIG;
65
+ }
66
+ // =============================================================================
67
+ // Timeout Wrapper
68
+ // =============================================================================
69
+ /**
70
+ * Execute a function with timeout protection
71
+ */
72
+ export async function withTimeout(fn, timeoutMs, fallback) {
73
+ let timeoutId;
74
+ const timeoutPromise = new Promise((resolve) => {
75
+ timeoutId = setTimeout(() => {
76
+ resolve({ result: fallback, timedOut: true });
77
+ }, timeoutMs);
78
+ });
79
+ const executionPromise = fn()
80
+ .then(result => {
81
+ clearTimeout(timeoutId);
82
+ return { result, timedOut: false };
83
+ })
84
+ .catch(() => {
85
+ clearTimeout(timeoutId);
86
+ return { result: fallback, timedOut: false };
87
+ });
88
+ return Promise.race([executionPromise, timeoutPromise]);
89
+ }
90
+ let sessionCache = null;
91
+ export function getCachedSession() {
92
+ if (!sessionCache)
93
+ return null;
94
+ // Check if expired
95
+ if (Date.now() - sessionCache.lastUpdated > sessionCache.ttl) {
96
+ sessionCache = null;
97
+ return null;
98
+ }
99
+ return sessionCache;
100
+ }
101
+ export function setCachedSession(session) {
102
+ sessionCache = {
103
+ sessionId: session.sessionId || `session_${Date.now()}`,
104
+ system: session.system || 'UNKNOWN',
105
+ activeTaskId: session.activeTaskId,
106
+ lastUpdated: Date.now(),
107
+ ttl: session.ttl || 30 * 60 * 1000 // 30 minutes default
108
+ };
109
+ }
110
+ export function clearSessionCache() {
111
+ sessionCache = null;
112
+ }
113
+ // =============================================================================
114
+ // Resilient Hook Executor
115
+ // =============================================================================
116
+ export class ResilientHookRunner {
117
+ config;
118
+ projectRoot;
119
+ constructor(projectRoot) {
120
+ this.projectRoot = projectRoot;
121
+ this.config = loadHookConfig(projectRoot);
122
+ }
123
+ /**
124
+ * Execute a hook with full protection
125
+ */
126
+ async execute(hookType, hookFn, fallback = { success: false, proceed: true, took: 0 }) {
127
+ const start = Date.now();
128
+ // Check if hooks are enabled
129
+ if (!this.config.enabled) {
130
+ return { ...fallback, success: true, took: Date.now() - start };
131
+ }
132
+ // Execute with timeout protection
133
+ const { result, timedOut } = await withTimeout(hookFn, this.config.timeout, fallback);
134
+ if (timedOut) {
135
+ console.warn(`[Hook:${hookType}] Timed out after ${this.config.timeout}ms`);
136
+ }
137
+ return {
138
+ ...result,
139
+ took: Date.now() - start
140
+ };
141
+ }
142
+ /**
143
+ * Check if a specific feature is enabled
144
+ */
145
+ isFeatureEnabled(feature) {
146
+ return this.config.enabled && this.config.features[feature];
147
+ }
148
+ /**
149
+ * Get current configuration
150
+ */
151
+ getConfig() {
152
+ return { ...this.config };
153
+ }
154
+ }
155
+ // =============================================================================
156
+ // Safe Hook Wrapper
157
+ // =============================================================================
158
+ /**
159
+ * Wrap any hook function to make it resilient
160
+ */
161
+ export function safeHook(hookFn, options) {
162
+ const timeout = options?.timeout || DEFAULT_CONFIG.timeout;
163
+ return async (...args) => {
164
+ const start = Date.now();
165
+ try {
166
+ const { result, timedOut } = await withTimeout(() => hookFn(...args), timeout, { success: false, proceed: true, took: 0 });
167
+ if (timedOut) {
168
+ return {
169
+ success: false,
170
+ proceed: true,
171
+ warning: `Hook timed out after ${timeout}ms`,
172
+ took: Date.now() - start
173
+ };
174
+ }
175
+ return { ...result, took: Date.now() - start };
176
+ }
177
+ catch (error) {
178
+ // Never throw - always return proceed: true
179
+ return {
180
+ success: false,
181
+ proceed: true,
182
+ error: error instanceof Error ? error.message : 'Unknown error',
183
+ took: Date.now() - start
184
+ };
185
+ }
186
+ };
187
+ }
188
+ // =============================================================================
189
+ // CLI Entry Point
190
+ // =============================================================================
191
+ if (process.argv[1]?.includes('resilient-hook-runner')) {
192
+ const projectRoot = process.cwd();
193
+ const config = loadHookConfig(projectRoot);
194
+ console.log(JSON.stringify({
195
+ projectRoot,
196
+ config,
197
+ cacheStatus: getCachedSession() ? 'active' : 'empty'
198
+ }, null, 2));
199
+ }
200
+ export default ResilientHookRunner;
201
+ //# sourceMappingURL=resilient-hook-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient-hook-runner.js","sourceRoot":"","sources":["../../src/hooks/resilient-hook-runner.ts"],"names":[],"mappings":"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"}
@@ -63,34 +63,34 @@ export async function onSessionEnd(event) {
63
63
  const duration = new Date(endedAt).getTime() - new Date(startedAt).getTime();
64
64
  // 2. Get task counts for this session
65
65
  const taskCounts = await db.execute({
66
- sql: `SELECT
67
- SUM(CASE WHEN json_extract(content, '$.sessionId') = ? AND status = 'active' THEN 1 ELSE 0 END) as started,
68
- SUM(CASE WHEN json_extract(content, '$.sessionId') = ? AND status = 'done' THEN 1 ELSE 0 END) as completed
69
- FROM items
66
+ sql: `SELECT
67
+ SUM(CASE WHEN json_extract(content, '$.sessionId') = ? AND status = 'active' THEN 1 ELSE 0 END) as started,
68
+ SUM(CASE WHEN json_extract(content, '$.sessionId') = ? AND status = 'done' THEN 1 ELSE 0 END) as completed
69
+ FROM items
70
70
  WHERE system = ? AND type = 'task'`,
71
71
  args: [event.sessionId, event.sessionId, system]
72
72
  });
73
73
  const taskRow = taskCounts.rows[0] || { started: 0, completed: 0 };
74
74
  // 3. Get memory counts for this session
75
75
  const memoryCounts = await db.execute({
76
- sql: `SELECT COUNT(*) as created FROM items
77
- WHERE system = ? AND type = 'memory'
76
+ sql: `SELECT COUNT(*) as created FROM items
77
+ WHERE system = ? AND type = 'memory'
78
78
  AND json_extract(content, '$.sessionId') = ?`,
79
79
  args: [system, event.sessionId]
80
80
  });
81
81
  const memoryRow = memoryCounts.rows[0] || { created: 0 };
82
82
  // 4. Get pattern counts for this session
83
83
  const patternCounts = await db.execute({
84
- sql: `SELECT COUNT(*) as detected FROM items
85
- WHERE system = ? AND type = 'pattern'
84
+ sql: `SELECT COUNT(*) as detected FROM items
85
+ WHERE system = ? AND type = 'pattern'
86
86
  AND date(created_at) = date('now')`,
87
87
  args: [system]
88
88
  });
89
89
  const patternRow = patternCounts.rows[0] || { detected: 0 };
90
90
  // 5. Get improvement counts
91
91
  const improvementCounts = await db.execute({
92
- sql: `SELECT COUNT(*) as generated FROM items
93
- WHERE system = ? AND type = 'auto_improvement'
92
+ sql: `SELECT COUNT(*) as generated FROM items
93
+ WHERE system = ? AND type = 'auto_improvement'
94
94
  AND date(created_at) = date('now')`,
95
95
  args: [system]
96
96
  });
@@ -127,7 +127,7 @@ export async function onSessionEnd(event) {
127
127
  };
128
128
  // 9. Persist summary
129
129
  await db.execute({
130
- sql: `INSERT INTO items (id, type, system, status, content, created_at, updated_at)
130
+ sql: `INSERT INTO items (id, type, system, status, content, created_at, updated_at)
131
131
  VALUES (?, 'session_summary', ?, 'active', ?, ?, ?)`,
132
132
  args: [
133
133
  summary.id,
@@ -175,9 +175,9 @@ export async function getSessionSummaries(system, limit = 20) {
175
175
  try {
176
176
  const db = turso.getClient();
177
177
  const result = await db.execute({
178
- sql: `SELECT content FROM items
179
- WHERE system = ? AND type = 'session_summary' AND status = 'active'
180
- ORDER BY created_at DESC
178
+ sql: `SELECT content FROM items
179
+ WHERE system = ? AND type = 'session_summary' AND status = 'active'
180
+ ORDER BY created_at DESC
181
181
  LIMIT ?`,
182
182
  args: [system, limit]
183
183
  });
@@ -54,10 +54,10 @@ export const BUILTIN_PATTERNS = [
54
54
  filePatterns: ['*.ts', '*.tsx'],
55
55
  excludePatterns: ['*.test.ts', '*.spec.ts'],
56
56
  eslintRuleName: 'charter/no-any-type',
57
- astVisitorTemplate: `return {
58
- TSAnyKeyword(node) {
59
- context.report({ node, messageId: 'violation' });
60
- }
57
+ astVisitorTemplate: `return {
58
+ TSAnyKeyword(node) {
59
+ context.report({ node, messageId: 'violation' });
60
+ }
61
61
  };`,
62
62
  status: 'active',
63
63
  threshold: 3,
@@ -73,14 +73,14 @@ export const BUILTIN_PATTERNS = [
73
73
  filePatterns: ['*.ts', '*.tsx', '*.js', '*.jsx'],
74
74
  excludePatterns: ['*.test.ts', '*.spec.ts', '*.test.js'],
75
75
  eslintRuleName: 'no-console',
76
- astVisitorTemplate: `return {
77
- CallExpression(node) {
78
- if (node.callee.type === 'MemberExpression' &&
79
- node.callee.object.name === 'console' &&
80
- node.callee.property.name === 'log') {
81
- context.report({ node, messageId: 'violation' });
82
- }
83
- }
76
+ astVisitorTemplate: `return {
77
+ CallExpression(node) {
78
+ if (node.callee.type === 'MemberExpression' &&
79
+ node.callee.object.name === 'console' &&
80
+ node.callee.property.name === 'log') {
81
+ context.report({ node, messageId: 'violation' });
82
+ }
83
+ }
84
84
  };`,
85
85
  status: 'active',
86
86
  threshold: 3,
@@ -95,16 +95,16 @@ export const BUILTIN_PATTERNS = [
95
95
  regex: 'eslint-disable',
96
96
  filePatterns: ['*.ts', '*.tsx', '*.js', '*.jsx'],
97
97
  eslintRuleName: 'charter/no-eslint-disable',
98
- astVisitorTemplate: `const sourceCode = context.getSourceCode();
99
- return {
100
- Program() {
101
- const comments = sourceCode.getAllComments();
102
- for (const comment of comments) {
103
- if (comment.value.includes('eslint-disable')) {
104
- context.report({ loc: comment.loc, messageId: 'violation' });
105
- }
106
- }
107
- }
98
+ astVisitorTemplate: `const sourceCode = context.getSourceCode();
99
+ return {
100
+ Program() {
101
+ const comments = sourceCode.getAllComments();
102
+ for (const comment of comments) {
103
+ if (comment.value.includes('eslint-disable')) {
104
+ context.report({ loc: comment.loc, messageId: 'violation' });
105
+ }
106
+ }
107
+ }
108
108
  };`,
109
109
  status: 'active',
110
110
  threshold: 3,
@@ -120,14 +120,14 @@ export const BUILTIN_PATTERNS = [
120
120
  filePatterns: ['*.ts'],
121
121
  excludePatterns: ['**/migrations/**', '**/db/**'],
122
122
  eslintRuleName: 'charter/no-raw-sql',
123
- astVisitorTemplate: `return {
124
- CallExpression(node) {
125
- if (node.callee.type === 'MemberExpression' &&
126
- node.callee.property.name === 'execute' &&
127
- node.arguments[0]?.type === 'TemplateLiteral') {
128
- context.report({ node, messageId: 'violation' });
129
- }
130
- }
123
+ astVisitorTemplate: `return {
124
+ CallExpression(node) {
125
+ if (node.callee.type === 'MemberExpression' &&
126
+ node.callee.property.name === 'execute' &&
127
+ node.arguments[0]?.type === 'TemplateLiteral') {
128
+ context.report({ node, messageId: 'violation' });
129
+ }
130
+ }
131
131
  };`,
132
132
  status: 'active',
133
133
  threshold: 2,
@@ -143,15 +143,15 @@ export const BUILTIN_PATTERNS = [
143
143
  filePatterns: ['*.ts'],
144
144
  excludePatterns: [],
145
145
  eslintRuleName: 'charter/require-zod-validation',
146
- astVisitorTemplate: `return {
147
- CallExpression(node) {
148
- // Check for publicProcedure.mutation without .input()
149
- if (node.callee.type === 'MemberExpression' &&
150
- node.callee.property.name === 'mutation') {
151
- // Implementation details
152
- context.report({ node, messageId: 'violation' });
153
- }
154
- }
146
+ astVisitorTemplate: `return {
147
+ CallExpression(node) {
148
+ // Check for publicProcedure.mutation without .input()
149
+ if (node.callee.type === 'MemberExpression' &&
150
+ node.callee.property.name === 'mutation') {
151
+ // Implementation details
152
+ context.report({ node, messageId: 'violation' });
153
+ }
154
+ }
155
155
  };`,
156
156
  status: 'active',
157
157
  threshold: 3,
@@ -166,14 +166,14 @@ export const BUILTIN_PATTERNS = [
166
166
  regex: 'useEffect\\(async',
167
167
  filePatterns: ['*.tsx', '*.jsx'],
168
168
  eslintRuleName: 'charter/no-async-useeffect',
169
- astVisitorTemplate: `return {
170
- CallExpression(node) {
171
- if (node.callee.type === 'Identifier' &&
172
- node.callee.name === 'useEffect' &&
173
- node.arguments[0]?.async) {
174
- context.report({ node, messageId: 'violation' });
175
- }
176
- }
169
+ astVisitorTemplate: `return {
170
+ CallExpression(node) {
171
+ if (node.callee.type === 'Identifier' &&
172
+ node.callee.name === 'useEffect' &&
173
+ node.arguments[0]?.async) {
174
+ context.report({ node, messageId: 'violation' });
175
+ }
176
+ }
177
177
  };`,
178
178
  status: 'active',
179
179
  threshold: 3,
@@ -189,12 +189,12 @@ export const BUILTIN_PATTERNS = [
189
189
  filePatterns: ['*.tsx', '*.jsx', '*.css'],
190
190
  excludePatterns: ['**/tailwind.config.*'],
191
191
  eslintRuleName: 'charter/use-semantic-tokens',
192
- astVisitorTemplate: `return {
193
- Literal(node) {
194
- if (typeof node.value === 'string' && /#[0-9a-fA-F]{3,8}/.test(node.value)) {
195
- context.report({ node, messageId: 'violation' });
196
- }
197
- }
192
+ astVisitorTemplate: `return {
193
+ Literal(node) {
194
+ if (typeof node.value === 'string' && /#[0-9a-fA-F]{3,8}/.test(node.value)) {
195
+ context.report({ node, messageId: 'violation' });
196
+ }
197
+ }
198
198
  };`,
199
199
  status: 'active',
200
200
  threshold: 5,
@@ -209,19 +209,19 @@ export const BUILTIN_PATTERNS = [
209
209
  regex: 'insert\\(finance\\)(?!.*LedgerService)',
210
210
  filePatterns: ['*.ts'],
211
211
  eslintRuleName: 'charter/finance-ledger-sync',
212
- astVisitorTemplate: `let hasFinanceInsert = false;
213
- let hasLedgerCall = false;
214
- return {
215
- CallExpression(node) {
216
- const callee = node.callee;
217
- if (callee.property?.name === 'insert') hasFinanceInsert = true;
218
- if (callee.object?.name === 'LedgerService') hasLedgerCall = true;
219
- },
220
- 'Program:exit'(node) {
221
- if (hasFinanceInsert && !hasLedgerCall) {
222
- context.report({ node, messageId: 'violation' });
223
- }
224
- }
212
+ astVisitorTemplate: `let hasFinanceInsert = false;
213
+ let hasLedgerCall = false;
214
+ return {
215
+ CallExpression(node) {
216
+ const callee = node.callee;
217
+ if (callee.property?.name === 'insert') hasFinanceInsert = true;
218
+ if (callee.object?.name === 'LedgerService') hasLedgerCall = true;
219
+ },
220
+ 'Program:exit'(node) {
221
+ if (hasFinanceInsert && !hasLedgerCall) {
222
+ context.report({ node, messageId: 'violation' });
223
+ }
224
+ }
225
225
  };`,
226
226
  status: 'active',
227
227
  threshold: 1,
@@ -379,30 +379,30 @@ export class PatternRegistry {
379
379
  if (!pattern || !pattern.eslintRuleName || !pattern.astVisitorTemplate) {
380
380
  return null;
381
381
  }
382
- return `/**
383
- * @file ${pattern.eslintRuleName}
384
- * @description ${pattern.description}
385
- * Auto-generated by cmp-standards pattern detection
386
- * @version 1.0.0
387
- */
388
-
389
- module.exports = {
390
- meta: {
391
- type: 'problem',
392
- docs: {
393
- description: '${pattern.description}',
394
- category: 'Best Practices',
395
- recommended: true
396
- },
397
- schema: [],
398
- messages: {
399
- violation: '${pattern.description}'
400
- }
401
- },
402
- create(context) {
403
- ${pattern.astVisitorTemplate}
404
- }
405
- }
382
+ return `/**
383
+ * @file ${pattern.eslintRuleName}
384
+ * @description ${pattern.description}
385
+ * Auto-generated by cmp-standards pattern detection
386
+ * @version 1.0.0
387
+ */
388
+
389
+ module.exports = {
390
+ meta: {
391
+ type: 'problem',
392
+ docs: {
393
+ description: '${pattern.description}',
394
+ category: 'Best Practices',
395
+ recommended: true
396
+ },
397
+ schema: [],
398
+ messages: {
399
+ violation: '${pattern.description}'
400
+ }
401
+ },
402
+ create(context) {
403
+ ${pattern.astVisitorTemplate}
404
+ }
405
+ }
406
406
  `;
407
407
  }
408
408
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/registry/generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQ5E,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAA;IACxB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAoMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,WAAW,CAAsB;gBAE7B,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC;IAKrD;;OAEG;IACG,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAmF5C;;OAEG;YACW,eAAe;IAgB7B;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA4DjE;AAMD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1D"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/registry/generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQ5E,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAA;IACxB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAoMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,WAAW,CAAsB;gBAE7B,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC;IAKrD;;OAEG;IACG,IAAI,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAmG5C;;OAEG;YACW,eAAe;IAgB7B;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA4DjE;AAMD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1D"}
@@ -182,45 +182,55 @@ export class RegistryGenerator {
182
182
  // 1. Find all source files
183
183
  const files = await this.findSourceFiles(projectRoot);
184
184
  console.log(` Found ${files.length} source files`);
185
- // 2. Parse sections from all files
185
+ // 2. Parse sections from all files (parallel)
186
+ const parseResults = await Promise.allSettled(files.map(async (file) => {
187
+ const sections = await parseMarkdownFile(file, this.config);
188
+ console.log(` Parsed ${sections.length} sections from ${path.basename(file)}`);
189
+ return sections;
190
+ }));
186
191
  const allSections = [];
187
- for (const file of files) {
188
- try {
189
- const sections = await parseMarkdownFile(file, this.config);
190
- allSections.push(...sections);
191
- console.log(` Parsed ${sections.length} sections from ${path.basename(file)}`);
192
+ for (const result of parseResults) {
193
+ if (result.status === 'fulfilled') {
194
+ allSections.push(...result.value);
192
195
  }
193
- catch (error) {
194
- console.warn(` Warning: Could not parse ${file}:`, error);
196
+ else {
197
+ console.warn(` Warning: Could not parse file:`, result.reason);
195
198
  }
196
199
  }
197
200
  console.log(` Total sections: ${allSections.length}`);
198
- // 3. Generate embeddings
201
+ // 3. Generate embeddings (batched parallel for rate limiting)
199
202
  console.log(' Generating embeddings...');
200
203
  const providerInfo = this.embeddingService.getProviderInfo();
201
204
  const embeddingSections = [];
202
- for (let i = 0; i < allSections.length; i++) {
203
- const section = allSections[i];
204
- // Combine title, description, and content for embedding
205
- const textToEmbed = `${section.title}\n\n${section.description}\n\n${section.content}`;
206
- try {
205
+ const batchSize = 10; // Process 10 at a time to avoid rate limits
206
+ for (let i = 0; i < allSections.length; i += batchSize) {
207
+ const batch = allSections.slice(i, i + batchSize);
208
+ const batchResults = await Promise.allSettled(batch.map(async (section) => {
209
+ const textToEmbed = `${section.title}\n\n${section.description}\n\n${section.content}`;
207
210
  const embedding = await this.embeddingService.embed(textToEmbed);
208
- embeddingSections.push({
211
+ return {
209
212
  id: section.id,
210
213
  title: section.title,
211
214
  description: section.description,
212
215
  keywords: section.keywords,
213
216
  embedding,
214
217
  path: section.path,
215
- tokens: Math.ceil(textToEmbed.length / 4), // Rough estimate
218
+ tokens: Math.ceil(textToEmbed.length / 4),
216
219
  criticality: section.criticality,
217
- });
218
- if ((i + 1) % 10 === 0) {
219
- console.log(` Embedded ${i + 1}/${allSections.length} sections`);
220
+ };
221
+ }));
222
+ for (const result of batchResults) {
223
+ if (result.status === 'fulfilled') {
224
+ embeddingSections.push(result.value);
225
+ }
226
+ else {
227
+ console.warn(` Warning: Could not embed section:`, result.reason);
220
228
  }
221
229
  }
222
- catch (error) {
223
- console.warn(` Warning: Could not embed section "${section.title}":`, error);
230
+ console.log(` Embedded ${Math.min(i + batchSize, allSections.length)}/${allSections.length} sections`);
231
+ // Small delay between batches to respect rate limits
232
+ if (i + batchSize < allSections.length) {
233
+ await new Promise(r => setTimeout(r, 100));
224
234
  }
225
235
  }
226
236
  // 4. Create registry