@xelth/eck-snapshot 6.5.1 โ 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/package.json +1 -1
- package/src/cli/cli.js +4 -0
- package/src/cli/commands/createSnapshot.js +18 -9
- package/src/cli/commands/recon.js +308 -283
- package/src/cli/commands/setupMcp.js +2 -0
- package/src/cli/commands/updateSnapshot.js +126 -114
- package/src/utils/fileUtils.js +1084 -1081
package/README.md
CHANGED
|
@@ -200,6 +200,7 @@ By analyzing Claude Code's internal architecture, eckSnapshot replaces the old m
|
|
|
200
200
|
* **๐ The `.eck/` Manifest:** Automatically maintains project context files (`CONTEXT.md`, `ROADMAP.md`, `TECH_DEBT.md`). Dynamic scanning โ any `.md` file you add to `.eck/` is automatically included in snapshots.
|
|
201
201
|
* **โ ๏ธ Skeleton Mode:** Uses Tree-sitter and Babel to strip function bodies, drastically reducing token count for huge codebases.
|
|
202
202
|
* **๐ NotebookLM Export:** Semantic chunking for Google's NotebookLM with "Brain + Body" architecture (see below).
|
|
203
|
+
* **๐งช ML Model Compatibility:** Smart metadata extraction for `.safetensors`, `.onnx`, `.pt`, `.pth`, `.h5`, `.pb`, `.bin`, `.ckpt`, `.gguf` โ reads the first 4KB header instead of loading multi-GB weights into memory.
|
|
203
204
|
* **๐ง Multi-Agent Protocol:** Junior Architect delegation system for multi-agent coding workflows (see below).
|
|
204
205
|
|
|
205
206
|
### ๐ค Autonomous AI Protocols
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xelth/eck-snapshot",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "A powerful CLI tool to create and restore single-file text snapshots of Git repositories. Optimized for AI context, LLM workflows, and multi-agent Swarm coordination.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
package/src/cli/cli.js
CHANGED
|
@@ -6,6 +6,7 @@ import chalk from 'chalk';
|
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import os from 'os';
|
|
8
8
|
import crypto from 'crypto';
|
|
9
|
+
import { ensureSnapshotsInGitignore } from '../utils/fileUtils.js';
|
|
9
10
|
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
@@ -163,6 +164,7 @@ Ranked by frequency of use:
|
|
|
163
164
|
queue.feedback.push({ type, message: msg, date: new Date().toISOString() });
|
|
164
165
|
|
|
165
166
|
await fs.mkdir(path.dirname(queuePath), { recursive: true }).catch(() => {});
|
|
167
|
+
await ensureSnapshotsInGitignore(process.cwd()).catch(() => {});
|
|
166
168
|
await fs.writeFile(queuePath, JSON.stringify(queue, null, 2));
|
|
167
169
|
|
|
168
170
|
console.log(chalk.green('Feedback saved locally. It will be sent to developers during the next telemetry sync.'));
|
|
@@ -218,6 +220,7 @@ Ranked by frequency of use:
|
|
|
218
220
|
} catch(e) { /* no existing queue */ }
|
|
219
221
|
queue.usage[toolName] = (queue.usage[toolName] || 0) + 1;
|
|
220
222
|
await fs.mkdir(path.dirname(queuePath), { recursive: true }).catch(() => {});
|
|
223
|
+
await ensureSnapshotsInGitignore(cwd).catch(() => {});
|
|
221
224
|
await fs.writeFile(queuePath, JSON.stringify(queue, null, 2));
|
|
222
225
|
} catch(e) { /* ignore tracking errors */ }
|
|
223
226
|
}
|
|
@@ -265,6 +268,7 @@ Ranked by frequency of use:
|
|
|
265
268
|
} catch(e) { /* no existing queue */ }
|
|
266
269
|
queue.errors.push({ tool: toolName, error: err.message, date: new Date().toISOString() });
|
|
267
270
|
await fs.mkdir(path.dirname(queuePath), { recursive: true }).catch(() => {});
|
|
271
|
+
await ensureSnapshotsInGitignore(cwd).catch(() => {});
|
|
268
272
|
await fs.writeFile(queuePath, JSON.stringify(queue, null, 2));
|
|
269
273
|
} catch(e) { /* ignore tracking errors */ }
|
|
270
274
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
scanDirectoryRecursively, loadGitignore, readFileWithSizeCheck,
|
|
16
16
|
generateDirectoryTree, loadConfig, displayProjectInfo, loadProjectEckManifest,
|
|
17
17
|
ensureSnapshotsInGitignore, initializeEckManifest, generateTimestamp,
|
|
18
|
-
getShortRepoName, SecretScanner, getProjectFiles
|
|
18
|
+
getShortRepoName, SecretScanner, getProjectFiles, readMlModelMetadata
|
|
19
19
|
} from '../../utils/fileUtils.js';
|
|
20
20
|
import { detectProjectType, getProjectSpecificFiltering, getAllDetectedTypes } from '../../utils/projectDetector.js';
|
|
21
21
|
import { estimateTokensWithPolynomial, generateTrainingCommand } from '../../utils/tokenEstimator.js';
|
|
@@ -394,8 +394,12 @@ async function processProjectFiles(repoPath, options, config, projectTypes = nul
|
|
|
394
394
|
return null;
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
|
|
398
|
-
|
|
397
|
+
const mlExt = path.extname(filePath).toLowerCase();
|
|
398
|
+
const ML_EXTENSIONS = ['.safetensors', '.onnx', '.pt', '.pth', '.h5', '.pb', '.bin', '.ckpt', '.gguf'];
|
|
399
|
+
const isMlModel = ML_EXTENSIONS.includes(mlExt);
|
|
400
|
+
|
|
401
|
+
// Check if binary file (bypass if it's an ML model we want to peek into)
|
|
402
|
+
if (isBinaryPath(filePath) && !isMlModel) {
|
|
399
403
|
stats.binaryFiles++;
|
|
400
404
|
trackSkippedFile(normalizedPath, 'Binary files');
|
|
401
405
|
return null;
|
|
@@ -421,13 +425,18 @@ async function processProjectFiles(repoPath, options, config, projectTypes = nul
|
|
|
421
425
|
stats.totalSize += fileStats.size;
|
|
422
426
|
|
|
423
427
|
const maxFileSize = parseSize(config.maxFileSize);
|
|
424
|
-
|
|
425
|
-
stats.oversizedFiles++;
|
|
426
|
-
trackSkippedFile(normalizedPath, `File too large (${formatSize(fileStats.size)} > ${formatSize(maxFileSize)})`);
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
428
|
+
let content;
|
|
429
429
|
|
|
430
|
-
|
|
430
|
+
if (isMlModel) {
|
|
431
|
+
content = await readMlModelMetadata(fullPath);
|
|
432
|
+
} else {
|
|
433
|
+
if (fileStats.size > maxFileSize) {
|
|
434
|
+
stats.oversizedFiles++;
|
|
435
|
+
trackSkippedFile(normalizedPath, `File too large (${formatSize(fileStats.size)} > ${formatSize(maxFileSize)})`);
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
content = await readFileWithSizeCheck(fullPath, maxFileSize);
|
|
439
|
+
}
|
|
431
440
|
|
|
432
441
|
// Security scan for secrets
|
|
433
442
|
if (config.security?.scanForSecrets !== false) {
|