ccsini 0.1.47 → 0.1.49

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 (2) hide show
  1. package/dist/index.js +34 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28020,7 +28020,7 @@ var {
28020
28020
  } = import__.default;
28021
28021
 
28022
28022
  // src/version.ts
28023
- var VERSION = "0.1.47";
28023
+ var VERSION = "0.1.49";
28024
28024
 
28025
28025
  // src/commands/init.ts
28026
28026
  init_source();
@@ -29163,13 +29163,29 @@ function filterSessionFiles(files, options) {
29163
29163
  }
29164
29164
  return [...nonSessions, ...kept];
29165
29165
  }
29166
- async function hashFile(filePath) {
29166
+ var cacheHits = 0;
29167
+ var cacheMisses = 0;
29168
+ async function hashFileIfNeeded(filePath, relativePath, currentMtime, cachedManifest) {
29169
+ if (cachedManifest) {
29170
+ const cached = cachedManifest.files[relativePath];
29171
+ if (cached && Math.abs(cached.modified - currentMtime) < 1) {
29172
+ cacheHits++;
29173
+ return cached.hash;
29174
+ }
29175
+ if (cached) {
29176
+ const diff = Math.abs(cached.modified - currentMtime);
29177
+ if (diff < 1000) {
29178
+ console.log(`[DEBUG] mtime diff for ${relativePath}: ${diff}ms (cached: ${cached.modified}, current: ${currentMtime})`);
29179
+ }
29180
+ }
29181
+ }
29182
+ cacheMisses++;
29167
29183
  const content = await readFile4(filePath);
29168
29184
  return createHash("sha256").update(content).digest("hex");
29169
29185
  }
29170
29186
  var EXCLUDED_DIRS = NEVER_SYNC_PATTERNS.filter((p) => p.endsWith("/**") && !p.startsWith("**/")).map((p) => p.replace("/**", ""));
29171
29187
  var EXCLUDED_DIR_NAMES = new Set(NEVER_SYNC_PATTERNS.filter((p) => p.startsWith("**/") && p.endsWith("/**")).map((p) => p.replace("**/", "").replace("/**", "")));
29172
- async function scanDir(baseDir, currentDir, results, onProgress) {
29188
+ async function scanDir(baseDir, currentDir, results, onProgress, cachedManifest) {
29173
29189
  const entries = await readdir(currentDir, { withFileTypes: true });
29174
29190
  for (const entry of entries) {
29175
29191
  const fullPath = join4(currentDir, entry.name);
@@ -29179,12 +29195,12 @@ async function scanDir(baseDir, currentDir, results, onProgress) {
29179
29195
  continue;
29180
29196
  if (EXCLUDED_DIRS.includes(relativePath))
29181
29197
  continue;
29182
- await scanDir(baseDir, fullPath, results, onProgress);
29198
+ await scanDir(baseDir, fullPath, results, onProgress, cachedManifest);
29183
29199
  } else if (entry.isFile()) {
29184
29200
  if (isExcluded(relativePath))
29185
29201
  continue;
29186
29202
  const fileStat = await stat(fullPath);
29187
- const hash = await hashFile(fullPath);
29203
+ const hash = await hashFileIfNeeded(fullPath, relativePath, fileStat.mtimeMs, cachedManifest);
29188
29204
  results.push({
29189
29205
  relativePath,
29190
29206
  absolutePath: fullPath,
@@ -29197,12 +29213,19 @@ async function scanDir(baseDir, currentDir, results, onProgress) {
29197
29213
  }
29198
29214
  }
29199
29215
  }
29200
- async function scanClaudeDir(claudeDir, onProgress, sessionOptions) {
29216
+ async function scanClaudeDir(claudeDir, onProgress, sessionOptions, cachedManifest) {
29201
29217
  const progress = onProgress ?? (() => {});
29202
29218
  const results = [];
29219
+ cacheHits = 0;
29220
+ cacheMisses = 0;
29203
29221
  progress("Scanning local files...");
29204
- await scanDir(claudeDir, claudeDir, results, progress);
29222
+ await scanDir(claudeDir, claudeDir, results, progress, cachedManifest);
29205
29223
  progress(`Scan complete: ${results.length} files found`);
29224
+ if (cachedManifest && cacheHits + cacheMisses > 0) {
29225
+ const total = cacheHits + cacheMisses;
29226
+ const hitRate = (cacheHits / total * 100).toFixed(1);
29227
+ progress(`Cache: ${cacheHits} hits, ${cacheMisses} misses (${hitRate}% hit rate)`);
29228
+ }
29206
29229
  const sessionOpts = sessionOptions ?? {
29207
29230
  enabled: SESSION_SYNC_DEFAULTS.enabled,
29208
29231
  maxPerProject: SESSION_SYNC_DEFAULTS.maxPerProject,
@@ -29218,7 +29241,9 @@ async function scanClaudeDir(claudeDir, onProgress, sessionOptions) {
29218
29241
 
29219
29242
  // src/core/manifest.ts
29220
29243
  async function generateManifest(claudeDir, deviceName, onProgress, sessionOptions) {
29221
- const files = await scanClaudeDir(claudeDir, onProgress, sessionOptions);
29244
+ const configDir = getConfigDir();
29245
+ const cachedManifest = await loadManifest(configDir);
29246
+ const files = await scanClaudeDir(claudeDir, onProgress, sessionOptions, cachedManifest ?? undefined);
29222
29247
  const entries = {};
29223
29248
  for (const file of files) {
29224
29249
  entries[file.relativePath] = {
@@ -30714,6 +30739,7 @@ async function showInteractiveMenu(program2) {
30714
30739
  { label: "Sync Pull", desc: "Pull changes from cloud", args: ["sync", "pull"] },
30715
30740
  { label: "Sync Status", desc: "Show sync status", args: ["sync", "status"] },
30716
30741
  { label: "Sessions", desc: "Configure session sync", args: ["sessions", "status"] },
30742
+ { label: "Conflicts", desc: "Resolve sync conflicts", args: ["conflicts"] },
30717
30743
  { label: "Doctor", desc: "Check system health", args: ["doctor"] },
30718
30744
  { label: "Hooks Fix", desc: "Repair broken hooks", args: ["hooks", "fix"] },
30719
30745
  { label: "Help", desc: "Show all commands", args: ["--help"] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsini",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "description": "Claude Code seamless sync across devices",
5
5
  "type": "module",
6
6
  "bin": {