cortex-sync 0.4.13 → 0.4.16

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/cli.js +35 -4
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -928,6 +928,7 @@ async function pullCommand(opts = {}) {
928
928
  if (mappingsDirty) await saveMappings(mappings);
929
929
  }
930
930
  async function* gen() {
931
+ let downloaded = 0;
931
932
  for (const path of toPull) {
932
933
  const blob = await backend.read("files/" + path);
933
934
  const content = decrypt(blob, derived);
@@ -951,11 +952,16 @@ async function pullCommand(opts = {}) {
951
952
  if (newEncodedDir !== oldEncodedDir) {
952
953
  relativePath = `projects/${newEncodedDir}/${m[3]}`;
953
954
  }
955
+ downloaded++;
956
+ process.stdout.write(`\r Downloading\u2026 ${downloaded}/${toPull.length} files`);
954
957
  yield { relativePath, content: remappedContent };
955
958
  } else {
959
+ downloaded++;
960
+ process.stdout.write(`\r Downloading\u2026 ${downloaded}/${toPull.length} files`);
956
961
  yield { relativePath: path, content };
957
962
  }
958
963
  }
964
+ if (toPull.length > 0) process.stdout.write("\n");
959
965
  }
960
966
  await adapter.putFiles(gen());
961
967
  await saveManifest(MANIFEST_PATH, remote);
@@ -1065,6 +1071,11 @@ function identifyProject(dir) {
1065
1071
  }
1066
1072
 
1067
1073
  // src/commands/sync.ts
1074
+ function isSafeGitHubPath(path) {
1075
+ return path.split("/").every(
1076
+ (c) => c.length > 0 && c !== "." && c !== ".." && c !== ".git" && !/[\x00-\x1f\x7f]/.test(c)
1077
+ );
1078
+ }
1068
1079
  async function syncCommand(opts = {}) {
1069
1080
  const config = await loadConfig();
1070
1081
  const passphrase = await readPassphrase();
@@ -1073,7 +1084,7 @@ async function syncCommand(opts = {}) {
1073
1084
  const backend = resolveBackend(config, { target: opts.target });
1074
1085
  console.log(`Sync target: ${backend.name}${opts.target ? ` (${opts.target})` : ""}
1075
1086
  `);
1076
- console.log("Reading local files\u2026");
1087
+ process.stdout.write("Reading local files\u2026");
1077
1088
  const local = emptyManifest("claude-code");
1078
1089
  const contents = /* @__PURE__ */ new Map();
1079
1090
  for await (const f of adapter.getFiles()) {
@@ -1083,8 +1094,10 @@ async function syncCommand(opts = {}) {
1083
1094
  size: f.content.length,
1084
1095
  encryptedSize: 0
1085
1096
  };
1097
+ process.stdout.write(`\r Reading\u2026 ${contents.size} files`);
1086
1098
  }
1087
- console.log(` ${contents.size} files`);
1099
+ process.stdout.write(`\r ${contents.size} files read${" ".repeat(20)}
1100
+ `);
1088
1101
  local.projects = {};
1089
1102
  const seenDirs = /* @__PURE__ */ new Set();
1090
1103
  for (const [path, content] of contents) {
@@ -1123,11 +1136,29 @@ async function syncCommand(opts = {}) {
1123
1136
  console.log(
1124
1137
  `Diff \u2014 added: ${diff.added.length}, modified: ${diff.modified.length}, removed: ${diff.removed.length}, unchanged: ${diff.unchanged.length}`
1125
1138
  );
1126
- for (const path of [...diff.added, ...diff.modified]) {
1139
+ const toUpload = [...diff.added, ...diff.modified];
1140
+ let uploaded = 0;
1141
+ let skipped = 0;
1142
+ for (const path of toUpload) {
1143
+ if (!isSafeGitHubPath(path)) {
1144
+ skipped++;
1145
+ continue;
1146
+ }
1127
1147
  const content = contents.get(path);
1128
1148
  const enc = encrypt(content, derived);
1129
1149
  local.files[path].encryptedSize = enc.length;
1130
- await backend.write("files/" + path, enc);
1150
+ try {
1151
+ await backend.write("files/" + path, enc);
1152
+ } catch (e) {
1153
+ process.stdout.write("\n");
1154
+ throw new Error(`Upload failed for "${path}": ${e.message}`);
1155
+ }
1156
+ uploaded++;
1157
+ process.stdout.write(`\r Uploading\u2026 ${uploaded}/${toUpload.length - skipped} files`);
1158
+ }
1159
+ if (toUpload.length > 0) process.stdout.write("\n");
1160
+ if (skipped > 0) {
1161
+ console.warn(` \u26A0 Skipped ${skipped} file(s) with paths incompatible with GitHub (control chars, .git, etc.)`);
1131
1162
  }
1132
1163
  for (const path of diff.removed) {
1133
1164
  await backend.remove("files/" + path);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortex-sync",
3
- "version": "0.4.13",
3
+ "version": "0.4.16",
4
4
  "description": "Sync Claude Code sessions between machines with automatic path remapping and skill conversion",
5
5
  "license": "AGPL-3.0",
6
6
  "type": "module",