ccsini 0.1.31 → 0.1.33

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 +39 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -27913,7 +27913,14 @@ var init_constants = __esm(() => {
27913
27913
  "projects/**/*.jsonl",
27914
27914
  "plugins/**",
27915
27915
  "plans/**",
27916
- "todos/**"
27916
+ "todos/**",
27917
+ "tasks/**",
27918
+ "transcripts/**",
27919
+ "**/*.lock",
27920
+ "**/dist/**",
27921
+ "**/.git/**",
27922
+ "**/*.bak",
27923
+ "settings.*.json"
27917
27924
  ];
27918
27925
  });
27919
27926
 
@@ -27996,7 +28003,7 @@ var {
27996
28003
  } = import__.default;
27997
28004
 
27998
28005
  // src/version.ts
27999
- var VERSION = "0.1.31";
28006
+ var VERSION = "0.1.33";
28000
28007
 
28001
28008
  // src/commands/init.ts
28002
28009
  init_source();
@@ -29032,6 +29039,7 @@ class CcsiniClient {
29032
29039
  import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir2 } from "fs/promises";
29033
29040
  import { join as join6, dirname } from "path";
29034
29041
  import { homedir as homedir2 } from "os";
29042
+ import { createHash as createHash2 } from "crypto";
29035
29043
 
29036
29044
  // src/core/manifest.ts
29037
29045
  import { readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
@@ -29208,6 +29216,9 @@ function mergeLastWriteWins(localContent, remoteContent, localModified, remoteMo
29208
29216
 
29209
29217
  // src/core/sync.ts
29210
29218
  init_src();
29219
+ function blobKey(filePath, contentHash) {
29220
+ return createHash2("sha256").update(`${filePath}:${contentHash}`).digest("hex");
29221
+ }
29211
29222
  function getClaudeDir() {
29212
29223
  return join6(homedir2(), ".claude");
29213
29224
  }
@@ -29236,23 +29247,38 @@ async function pushSync(client, masterKey, deviceName, configDir, onProgress) {
29236
29247
  const toPush = diffs.filter((d) => d.action === "push" || d.action === "merge");
29237
29248
  progress(`${toPush.length} files to push`);
29238
29249
  let uploaded = 0;
29250
+ const failedPaths = new Set;
29239
29251
  const chunks = chunkArray(toPush, MAX_CONCURRENT_TRANSFERS);
29240
29252
  for (const chunk of chunks) {
29241
29253
  await Promise.all(chunk.map(async (diff) => {
29242
- try {
29243
- const filePath = join6(claudeDir, diff.path);
29244
- const content = await readFile6(filePath);
29245
- const encrypted = encryptFile(masterKey, diff.path, content);
29246
- await client.uploadBlob(diff.localHash, encrypted);
29247
- bytesTransferred += encrypted.length;
29248
- uploaded++;
29249
- progress(`Uploading ${uploaded}/${toPush.length}: ${diff.path}`);
29250
- } catch (e) {
29251
- errors2.push(`Push ${diff.path}: ${e.message}`);
29254
+ const MAX_RETRIES = 3;
29255
+ for (let attempt = 1;attempt <= MAX_RETRIES; attempt++) {
29256
+ try {
29257
+ const filePath = join6(claudeDir, diff.path);
29258
+ const content = await readFile6(filePath);
29259
+ const encrypted = encryptFile(masterKey, diff.path, content);
29260
+ await client.uploadBlob(blobKey(diff.path, diff.localHash), encrypted);
29261
+ bytesTransferred += encrypted.length;
29262
+ uploaded++;
29263
+ progress(`Uploading ${uploaded}/${toPush.length}: ${diff.path}`);
29264
+ return;
29265
+ } catch (e) {
29266
+ if (attempt < MAX_RETRIES) {
29267
+ await new Promise((r) => setTimeout(r, 500 * attempt));
29268
+ } else {
29269
+ failedPaths.add(diff.path);
29270
+ errors2.push(`Push ${diff.path}: ${e.message}`);
29271
+ }
29272
+ }
29252
29273
  }
29253
29274
  }));
29254
29275
  }
29255
29276
  progress("Saving manifest...");
29277
+ if (failedPaths.size > 0) {
29278
+ for (const path2 of failedPaths) {
29279
+ delete localManifest.files[path2];
29280
+ }
29281
+ }
29256
29282
  const manifestJson = JSON.stringify(localManifest);
29257
29283
  const manifestEnc = encryptFile(masterKey, "__manifest__", new TextEncoder().encode(manifestJson));
29258
29284
  await client.putManifest(manifestEnc);
@@ -29316,7 +29342,7 @@ async function pullSync(client, masterKey, deviceName, configDir, onProgress) {
29316
29342
  for (const chunk of chunks) {
29317
29343
  await Promise.all(chunk.map(async (diff) => {
29318
29344
  try {
29319
- const encrypted = await client.downloadBlob(diff.remoteHash);
29345
+ const encrypted = await client.downloadBlob(blobKey(diff.path, diff.remoteHash));
29320
29346
  bytesTransferred += encrypted.length;
29321
29347
  const decrypted = decryptFile(masterKey, diff.path, encrypted);
29322
29348
  if (diff.action === "merge" && diff.localHash) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsini",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Claude Code seamless sync across devices",
5
5
  "type": "module",
6
6
  "bin": {