ccsini 0.1.5 → 0.1.6

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 +35 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26950,7 +26950,7 @@ var {
26950
26950
  } = import__.default;
26951
26951
 
26952
26952
  // src/version.ts
26953
- var VERSION = "0.1.5";
26953
+ var VERSION = "0.1.6";
26954
26954
 
26955
26955
  // src/commands/init.ts
26956
26956
  init_source();
@@ -28498,12 +28498,17 @@ function mergeLastWriteWins(localContent, remoteContent, localModified, remoteMo
28498
28498
  function getClaudeDir() {
28499
28499
  return join6(homedir2(), ".claude");
28500
28500
  }
28501
- async function pushSync(client, masterKey, deviceName, configDir) {
28501
+ async function pushSync(client, masterKey, deviceName, configDir, onProgress) {
28502
28502
  const start = Date.now();
28503
28503
  const claudeDir = getClaudeDir();
28504
28504
  const errors2 = [];
28505
28505
  let bytesTransferred = 0;
28506
+ const progress = onProgress ?? (() => {});
28507
+ progress("Scanning local files...");
28506
28508
  const localManifest = await generateManifest(claudeDir, deviceName);
28509
+ const fileCount = Object.keys(localManifest.files).length;
28510
+ progress(`Scanned ${fileCount} files`);
28511
+ progress("Fetching remote manifest...");
28507
28512
  const remoteManifestEnc = await client.getManifest();
28508
28513
  let remoteManifest = null;
28509
28514
  if (remoteManifestEnc) {
@@ -28514,8 +28519,11 @@ async function pushSync(client, masterKey, deviceName, configDir) {
28514
28519
  remoteManifest = null;
28515
28520
  }
28516
28521
  }
28522
+ progress("Comparing manifests...");
28517
28523
  const diffs = diffManifests(localManifest, remoteManifest);
28518
28524
  const toPush = diffs.filter((d) => d.action === "push" || d.action === "merge");
28525
+ progress(`${toPush.length} files to push`);
28526
+ let uploaded = 0;
28519
28527
  const chunks = chunkArray(toPush, MAX_CONCURRENT_TRANSFERS);
28520
28528
  for (const chunk of chunks) {
28521
28529
  await Promise.all(chunk.map(async (diff) => {
@@ -28525,16 +28533,20 @@ async function pushSync(client, masterKey, deviceName, configDir) {
28525
28533
  const encrypted = encryptFile(masterKey, diff.path, content);
28526
28534
  await client.uploadBlob(diff.localHash, encrypted);
28527
28535
  bytesTransferred += encrypted.length;
28536
+ uploaded++;
28537
+ progress(`Uploading ${uploaded}/${toPush.length}: ${diff.path}`);
28528
28538
  } catch (e) {
28529
28539
  errors2.push(`Push ${diff.path}: ${e.message}`);
28530
28540
  }
28531
28541
  }));
28532
28542
  }
28543
+ progress("Saving manifest...");
28533
28544
  const manifestJson = JSON.stringify(localManifest);
28534
28545
  const manifestEnc = encryptFile(masterKey, "__manifest__", new TextEncoder().encode(manifestJson));
28535
28546
  await client.putManifest(manifestEnc);
28536
28547
  await saveManifest(configDir, localManifest);
28537
28548
  const durationMs = Date.now() - start;
28549
+ progress("Logging sync event...");
28538
28550
  await client.logSyncEvent({
28539
28551
  action: "push",
28540
28552
  filesChanged: toPush.length,
@@ -28549,11 +28561,13 @@ async function pushSync(client, masterKey, deviceName, configDir) {
28549
28561
  errors: errors2
28550
28562
  };
28551
28563
  }
28552
- async function pullSync(client, masterKey, deviceName, configDir) {
28564
+ async function pullSync(client, masterKey, deviceName, configDir, onProgress) {
28553
28565
  const start = Date.now();
28554
28566
  const claudeDir = getClaudeDir();
28555
28567
  const errors2 = [];
28556
28568
  let bytesTransferred = 0;
28569
+ const progress = onProgress ?? (() => {});
28570
+ progress("Fetching remote manifest...");
28557
28571
  const remoteManifestEnc = await client.getManifest();
28558
28572
  if (!remoteManifestEnc) {
28559
28573
  return {
@@ -28579,9 +28593,13 @@ async function pullSync(client, masterKey, deviceName, configDir) {
28579
28593
  ]
28580
28594
  };
28581
28595
  }
28596
+ progress("Loading local manifest...");
28582
28597
  const localManifest = await loadManifest(configDir);
28598
+ progress("Comparing manifests...");
28583
28599
  const diffs = diffManifests(localManifest, remoteManifest);
28584
28600
  const toPull = diffs.filter((d) => d.action === "pull" || d.action === "merge");
28601
+ progress(`${toPull.length} files to pull`);
28602
+ let downloaded = 0;
28585
28603
  const chunks = chunkArray(toPull, MAX_CONCURRENT_TRANSFERS);
28586
28604
  for (const chunk of chunks) {
28587
28605
  await Promise.all(chunk.map(async (diff) => {
@@ -28596,6 +28614,8 @@ async function pullSync(client, masterKey, deviceName, configDir) {
28596
28614
  if (diff.category === "session") {
28597
28615
  const merged = mergeSessionFiles(localContent, remoteContent);
28598
28616
  await writeFile5(localPath2, merged);
28617
+ downloaded++;
28618
+ progress(`Downloading ${downloaded}/${toPull.length}: ${diff.path}`);
28599
28619
  return;
28600
28620
  }
28601
28621
  const entry = remoteManifest.files[diff.path];
@@ -28604,19 +28624,25 @@ async function pullSync(client, masterKey, deviceName, configDir) {
28604
28624
  const result = mergeLastWriteWins(localContent, remoteContent, localEntry.modified, entry.modified);
28605
28625
  await writeFile5(localPath2, result.content);
28606
28626
  await writeFile5(`${localPath2}.bak`, result.backupContent);
28627
+ downloaded++;
28628
+ progress(`Downloading ${downloaded}/${toPull.length}: ${diff.path}`);
28607
28629
  return;
28608
28630
  }
28609
28631
  }
28610
28632
  const localPath = join6(claudeDir, diff.path);
28611
28633
  await mkdir2(dirname(localPath), { recursive: true });
28612
28634
  await writeFile5(localPath, decrypted);
28635
+ downloaded++;
28636
+ progress(`Downloading ${downloaded}/${toPull.length}: ${diff.path}`);
28613
28637
  } catch (e) {
28614
28638
  errors2.push(`Pull ${diff.path}: ${e.message}`);
28615
28639
  }
28616
28640
  }));
28617
28641
  }
28642
+ progress("Saving manifest...");
28618
28643
  await saveManifest(configDir, remoteManifest);
28619
28644
  const durationMs = Date.now() - start;
28645
+ progress("Logging sync event...");
28620
28646
  await client.logSyncEvent({
28621
28647
  action: "pull",
28622
28648
  filesChanged: toPull.length,
@@ -29004,7 +29030,9 @@ function registerSyncCommands(program2) {
29004
29030
  const client = await getAuthenticatedClient2(configDir);
29005
29031
  const config = await loadKeys(configDir);
29006
29032
  const spinner = ora2("Scanning files...").start();
29007
- const result = await pushSync(client, masterKey, config.deviceName, configDir);
29033
+ const result = await pushSync(client, masterKey, config.deviceName, configDir, (msg) => {
29034
+ spinner.text = msg;
29035
+ });
29008
29036
  if (result.errors.length > 0) {
29009
29037
  spinner.warn("Push completed with errors");
29010
29038
  for (const err of result.errors) {
@@ -29032,7 +29060,9 @@ function registerSyncCommands(program2) {
29032
29060
  const client = await getAuthenticatedClient2(configDir);
29033
29061
  const config = await loadKeys(configDir);
29034
29062
  const spinner = ora2("Pulling from cloud...").start();
29035
- const result = await pullSync(client, masterKey, config.deviceName, configDir);
29063
+ const result = await pullSync(client, masterKey, config.deviceName, configDir, (msg) => {
29064
+ spinner.text = msg;
29065
+ });
29036
29066
  if (result.errors.length > 0) {
29037
29067
  spinner.warn("Pull completed with errors");
29038
29068
  for (const err of result.errors) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsini",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Claude Code seamless sync across devices",
5
5
  "type": "module",
6
6
  "bin": {