@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 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.5.1",
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
- // Check if binary file
398
- if (isBinaryPath(filePath)) {
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
- if (fileStats.size > maxFileSize) {
425
- stats.oversizedFiles++;
426
- trackSkippedFile(normalizedPath, `File too large (${formatSize(fileStats.size)} > ${formatSize(maxFileSize)})`);
427
- return null;
428
- }
428
+ let content;
429
429
 
430
- let content = await readFileWithSizeCheck(fullPath, maxFileSize);
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) {