@xelth/eck-snapshot 2.2.0 β†’ 4.0.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 (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -225
  3. package/index.js +14 -776
  4. package/package.json +25 -7
  5. package/setup.json +805 -0
  6. package/src/cli/cli.js +427 -0
  7. package/src/cli/commands/askGpt.js +29 -0
  8. package/src/cli/commands/autoDocs.js +150 -0
  9. package/src/cli/commands/consilium.js +86 -0
  10. package/src/cli/commands/createSnapshot.js +601 -0
  11. package/src/cli/commands/detectProfiles.js +98 -0
  12. package/src/cli/commands/detectProject.js +112 -0
  13. package/src/cli/commands/generateProfileGuide.js +91 -0
  14. package/src/cli/commands/pruneSnapshot.js +106 -0
  15. package/src/cli/commands/restoreSnapshot.js +173 -0
  16. package/src/cli/commands/setupGemini.js +149 -0
  17. package/src/cli/commands/setupGemini.test.js +115 -0
  18. package/src/cli/commands/trainTokens.js +38 -0
  19. package/src/config.js +81 -0
  20. package/src/services/authService.js +20 -0
  21. package/src/services/claudeCliService.js +621 -0
  22. package/src/services/claudeCliService.test.js +267 -0
  23. package/src/services/dispatcherService.js +33 -0
  24. package/src/services/gptService.js +302 -0
  25. package/src/services/gptService.test.js +120 -0
  26. package/src/templates/agent-prompt.template.md +29 -0
  27. package/src/templates/architect-prompt.template.md +50 -0
  28. package/src/templates/envScanRequest.md +4 -0
  29. package/src/templates/gitWorkflow.md +32 -0
  30. package/src/templates/multiAgent.md +164 -0
  31. package/src/templates/vectorMode.md +22 -0
  32. package/src/utils/aiHeader.js +303 -0
  33. package/src/utils/fileUtils.js +928 -0
  34. package/src/utils/projectDetector.js +704 -0
  35. package/src/utils/tokenEstimator.js +198 -0
  36. package/.ecksnapshot.config.js +0 -35
@@ -0,0 +1,198 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ /**
6
+ * Adaptive token estimation system with project-specific polynomials
7
+ */
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ const ESTIMATION_DATA_FILE = path.join(__dirname, '..', '..', '.eck-token-training.json');
12
+
13
+ /**
14
+ * Default coefficients for different project types (bytes to tokens ratio)
15
+ * Format: [constant, linear, quadratic, cubic] coefficients
16
+ */
17
+ const DEFAULT_COEFFICIENTS = {
18
+ 'android': [0, 0.25, 0, 0], // Start with simple 1/4 ratio
19
+ 'nodejs': [0, 0.20, 0, 0],
20
+ 'python': [0, 0.22, 0, 0],
21
+ 'rust': [0, 0.18, 0, 0],
22
+ 'go': [0, 0.19, 0, 0],
23
+ 'c': [0, 0.23, 0, 0],
24
+ 'unknown': [0, 0.25, 0, 0]
25
+ };
26
+
27
+ /**
28
+ * Load training data from file
29
+ */
30
+ async function loadTrainingData() {
31
+ try {
32
+ const data = await fs.readFile(ESTIMATION_DATA_FILE, 'utf-8');
33
+ const parsedData = JSON.parse(data);
34
+ // Ensure the structure is complete by merging with defaults
35
+ return {
36
+ coefficients: { ...DEFAULT_COEFFICIENTS, ...parsedData.coefficients },
37
+ trainingPoints: parsedData.trainingPoints || {}
38
+ };
39
+ } catch (error) {
40
+ // If file doesn't exist or is malformed, return default structure
41
+ return {
42
+ coefficients: { ...DEFAULT_COEFFICIENTS },
43
+ trainingPoints: {}
44
+ };
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Save training data to file
50
+ */
51
+ async function saveTrainingData(data) {
52
+ await fs.writeFile(ESTIMATION_DATA_FILE, JSON.stringify(data, null, 2));
53
+ }
54
+
55
+ /**
56
+ * Calculate polynomial value
57
+ */
58
+ function evaluatePolynomial(coefficients, x) {
59
+ let result = 0;
60
+ for (let i = 0; i < coefficients.length; i++) {
61
+ result += coefficients[i] * Math.pow(x, i);
62
+ }
63
+ return Math.max(0, result); // Ensure non-negative result
64
+ }
65
+
66
+ /**
67
+ * Estimate tokens using project-specific polynomial
68
+ */
69
+ export async function estimateTokensWithPolynomial(projectType, fileSizeInBytes) {
70
+ const data = await loadTrainingData();
71
+ const coefficients = data.coefficients[projectType] || data.coefficients['unknown'];
72
+
73
+ const estimatedTokens = evaluatePolynomial(coefficients, fileSizeInBytes);
74
+ return Math.round(estimatedTokens);
75
+ }
76
+
77
+ /**
78
+ * Generate training command string for data collection
79
+ */
80
+ export function generateTrainingCommand(projectType, estimatedTokens, fileSizeInBytes, projectPath) {
81
+ const projectName = path.basename(projectPath);
82
+
83
+ return `eck-snapshot train-tokens ${projectType} ${fileSizeInBytes} ${estimatedTokens} `;
84
+ }
85
+
86
+ /**
87
+ * Add training point and update polynomial coefficients
88
+ */
89
+ export async function addTrainingPoint(projectType, fileSizeInBytes, estimatedTokens, actualTokens) {
90
+ const data = await loadTrainingData();
91
+
92
+ // Initialize training points array for project type if it doesn't exist
93
+ if (!data.trainingPoints[projectType]) {
94
+ data.trainingPoints[projectType] = [];
95
+ }
96
+
97
+ // Add new training point
98
+ const trainingPoint = {
99
+ fileSizeInBytes,
100
+ estimatedTokens,
101
+ actualTokens,
102
+ timestamp: new Date().toISOString()
103
+ };
104
+
105
+ data.trainingPoints[projectType].push(trainingPoint);
106
+
107
+ // Recalculate coefficients using least squares fitting
108
+ updateCoefficients(data, projectType);
109
+
110
+ await saveTrainingData(data);
111
+
112
+ console.log(`βœ… Added training point for ${projectType}:`);
113
+ console.log(` File size: ${fileSizeInBytes} bytes`);
114
+ console.log(` Estimated: ${estimatedTokens} tokens`);
115
+ console.log(` Actual: ${actualTokens} tokens`);
116
+ console.log(` Error: ${Math.abs(actualTokens - estimatedTokens)} tokens (${Math.round(Math.abs(actualTokens - estimatedTokens) / actualTokens * 100)}%)`);
117
+ }
118
+
119
+ /**
120
+ * Update polynomial coefficients using least squares fitting
121
+ * For now, we'll use a simple adaptive approach
122
+ */
123
+ function updateCoefficients(data, projectType) {
124
+ const points = data.trainingPoints[projectType];
125
+
126
+ if (!points || points.length === 0) {
127
+ // No points, nothing to do.
128
+ return;
129
+ }
130
+
131
+ if (points.length === 1) {
132
+ // With one point, use a direct ratio for the linear coefficient.
133
+ const point = points[0];
134
+ if (point.fileSizeInBytes > 0) { // Avoid division by zero
135
+ const ratio = point.actualTokens / point.fileSizeInBytes;
136
+ data.coefficients[projectType] = [
137
+ 0, // intercept
138
+ Math.max(0, ratio), // linear term (slope)
139
+ 0, 0 // quadratic, cubic
140
+ ];
141
+ }
142
+ return;
143
+ }
144
+
145
+ // Use linear regression for 2 or more points.
146
+ let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
147
+ const n = points.length;
148
+
149
+ for (const point of points) {
150
+ const x = point.fileSizeInBytes;
151
+ const y = point.actualTokens;
152
+
153
+ sumX += x;
154
+ sumY += y;
155
+ sumXY += x * y;
156
+ sumX2 += x * x;
157
+ }
158
+
159
+ const denominator = (n * sumX2 - sumX * sumX);
160
+ if (denominator === 0) return; // Avoid division by zero, can't calculate slope
161
+
162
+ // Calculate linear coefficients: y = a + bx
163
+ const slope = (n * sumXY - sumX * sumY) / denominator;
164
+ const intercept = (sumY - slope * sumX) / n;
165
+
166
+ // Update coefficients [constant, linear, quadratic, cubic]
167
+ data.coefficients[projectType] = [
168
+ Math.max(0, intercept), // constant term (ensure non-negative)
169
+ Math.max(0, slope), // linear term (ensure non-negative)
170
+ 0, // quadratic (not used yet)
171
+ 0 // cubic (not used yet)
172
+ ];
173
+ }
174
+
175
+ /**
176
+ * Show current estimation statistics
177
+ */
178
+ export async function showEstimationStats() {
179
+ const data = await loadTrainingData();
180
+
181
+ console.log('\nπŸ“Š Token Estimation Statistics:');
182
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
183
+
184
+ for (const [projectType, coefficients] of Object.entries(data.coefficients)) {
185
+ const points = data.trainingPoints[projectType] || [];
186
+ console.log(`\nπŸ”Έ ${projectType}:`);
187
+ console.log(` Coefficients: [${coefficients.map(c => c.toFixed(6)).join(', ')}]`);
188
+ console.log(` Training points: ${points.length}`);
189
+
190
+ if (points.length > 0) {
191
+ const errors = points.map(p => Math.abs(p.actualTokens - p.estimatedTokens));
192
+ const avgError = errors.reduce((a, b) => a + b, 0) / errors.length;
193
+ console.log(` Average error: ${Math.round(avgError)} tokens`);
194
+ }
195
+ }
196
+
197
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
198
+ }
@@ -1,35 +0,0 @@
1
- // .ecksnapshot.config.js
2
-
3
- // Π― Π·Π°ΠΌΠ΅Π½ΠΈΠ» "module.exports =" Π½Π° "export default"
4
- export default {
5
- filesToIgnore: [
6
- 'package-lock.json',
7
- 'yarn.lock',
8
- 'pnpm-lock.yaml'
9
- ],
10
- extensionsToIgnore: [
11
- '.sqlite3',
12
- '.db',
13
- '.DS_Store',
14
- '.env',
15
- '.log',
16
- '.tmp',
17
- '.bak',
18
- '.swp',
19
- '.ico',
20
- '.png',
21
- '.jpg',
22
- '.jpeg',
23
- '.gif',
24
- '.svg'
25
- ],
26
- dirsToIgnore: [
27
- 'node_modules/',
28
- '.git/',
29
- '.idea/',
30
- 'snapshots/',
31
- 'dist/',
32
- 'build/',
33
- 'coverage/'
34
- ],
35
- };