@coderook/cli 0.31.1 → 0.31.2

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.
@@ -2,7 +2,7 @@
2
2
  "name": "coderook",
3
3
  "displayName": "CodeRook",
4
4
  "description": "Save, browse and restore whole-snapshot versions of a project on CodeRook, from Claude Code.",
5
- "version": "0.31.1",
5
+ "version": "0.31.2",
6
6
  "author": {
7
7
  "name": "ACCA Gaming Productions",
8
8
  "url": "https://coderook.com"
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  const promises_1 = require("node:readline/promises");
19
19
  const node_os_1 = __importDefault(require("node:os"));
20
20
  const promises_2 = require("node:fs/promises");
21
+ const node_fs_1 = require("node:fs");
21
22
  const node_path_1 = __importDefault(require("node:path"));
22
23
  const node_process_1 = __importDefault(require("node:process"));
23
24
  const api_js_1 = require("./api.js");
@@ -385,6 +386,22 @@ async function commandStatus(parsed) {
385
386
  `— run ${accent("cbx get")} to bring ${stale.length === 1 ? "it" : "them"} down.`));
386
387
  for (const [path] of stale.slice(0, 10))
387
388
  console.log(dim(` behind ${path}`));
389
+ /*
390
+ Behind, and not here at all. Usually somebody else's file that has not
391
+ been fetched — but it is also what a file deleted here looked like after
392
+ a save that did not send the deletion, because until 0.31.2 that save
393
+ dropped it from this folder's record. Told plainly, since the one advice
394
+ above would bring back a file the person meant to be rid of.
395
+ */
396
+ const absent = stale.filter(([file]) => !(0, node_fs_1.existsSync)(node_path_1.default.join(folder, ...file.split("/"))));
397
+ if (absent.length) {
398
+ const one = absent.length === 1;
399
+ const which = absent.length === stale.length
400
+ ? one ? "It is not" : "They are not"
401
+ : `${absent.length} of them ${one ? "is" : "are"} not`;
402
+ console.log(dim(`${which} in this folder at all. If you deleted ${one ? "it" : "them"} yourself, ` +
403
+ `run ${accent("cbx get")}, delete ${one ? "it" : "them"} again, and save with ${accent("--sync")}.`));
404
+ }
388
405
  }
389
406
  /** The deletions, and what a plain save will do about them. */
390
407
  /*
@@ -915,6 +915,53 @@ class Uploader {
915
915
  if (!completed.mergeTrack && !Object.keys(acceptedManifest).length) {
916
916
  acceptedManifest = Object.fromEntries([...(await this.versionFiles(repositoryId, completed.version.id))].map(([file, descriptor]) => [file, descriptor.sha256]));
917
917
  }
918
+ const manifest = Object.keys(acceptedManifest).length
919
+ ? acceptedManifest
920
+ : {
921
+ ...Object.fromEntries(reused.map((file) => [file.path, prior.get(file.path).sha256])),
922
+ ...Object.fromEntries(declarations.map((declaration) => [declaration.path, declaration.sha256])),
923
+ };
924
+ /*
925
+ What this folder holds after the save. A file that was sent holds
926
+ the bytes that were sent. Anything else keeps whatever digest was
927
+ recorded before: an unticked edit therefore stays pending rather
928
+ than looking saved, and a copy left stale by somebody else's merge
929
+ stays recognisably stale rather than looking like a new edit.
930
+
931
+ Looked up in a map rather than by searching the declarations for each
932
+ file, which on a 47,000-file project was over a billion comparisons at
933
+ the very end of a save.
934
+ */
935
+ const sentDigest = new Map(declarations.map((declaration) => [declaration.path, declaration.sha256]));
936
+ const onDisk = new Set(everything.map((file) => file.path));
937
+ const local = Object.fromEntries(everything.flatMap((file) => {
938
+ const sent = sentDigest.get(file.path);
939
+ if (sent)
940
+ return [[file.path, sent]];
941
+ const before = request.known?.[file.path] ?? prior.get(file.path)?.sha256;
942
+ return before ? [[file.path, before]] : [];
943
+ }));
944
+ /*
945
+ And a file deleted here that this save carried forward keeps its place.
946
+
947
+ A plain save adds and updates, so a file somebody deleted stays in the
948
+ version. It used to vanish from this record all the same, because the
949
+ record was built only from what is on disk — and the next status then
950
+ found the version holding a file this folder did not, called it
951
+ "behind", and offered to fetch it back. The person had deleted it; the
952
+ only thing that brought it back was being told to run `cbx get`.
953
+
954
+ Only where the record already had it. A file that was never here — one
955
+ somebody else's save merged into the version — has no entry to keep, so
956
+ it stays "behind", which is exactly what it is.
957
+ */
958
+ for (const path of Object.keys(manifest)) {
959
+ if (onDisk.has(path))
960
+ continue;
961
+ const held = request.known?.[path];
962
+ if (held)
963
+ local[path] = held;
964
+ }
918
965
  report({
919
966
  stage: "done",
920
967
  files: declarations.length,
@@ -940,29 +987,8 @@ class Uploader {
940
987
  /** Selected, but the service already held the content. */
941
988
  alreadyStoredFiles: progress.alreadyOnAccount,
942
989
  telemetry: this.telemetry.snapshot(),
943
- // A file that kept its old object records the digest of *that* copy,
944
- // not of the file on disk, so an unticked edit is still pending next
945
- // time rather than looking as though it had been saved.
946
- /*
947
- What this folder holds after the save. A file that was sent holds
948
- the bytes that were sent. Anything else keeps whatever digest was
949
- recorded before: an unticked edit therefore stays pending rather
950
- than looking saved, and a copy left stale by somebody else's merge
951
- stays recognisably stale rather than looking like a new edit.
952
- */
953
- local: Object.fromEntries(everything.flatMap((file) => {
954
- const sent = declarations.find((one) => one.path === file.path);
955
- if (sent)
956
- return [[file.path, sent.sha256]];
957
- const before = request.known?.[file.path] ?? prior.get(file.path)?.sha256;
958
- return before ? [[file.path, before]] : [];
959
- })),
960
- manifest: Object.keys(acceptedManifest).length
961
- ? acceptedManifest
962
- : {
963
- ...Object.fromEntries(reused.map((file) => [file.path, prior.get(file.path).sha256])),
964
- ...Object.fromEntries(declarations.map((declaration) => [declaration.path, declaration.sha256])),
965
- },
990
+ local,
991
+ manifest,
966
992
  };
967
993
  }
968
994
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coderook/cli",
3
- "version": "0.31.1",
3
+ "version": "0.31.2",
4
4
  "description": "CodeRook from the command line, on any operating system",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "homepage": "https://coderook.com",