repo-dive 0.16.2 → 0.16.4

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.
package/dist/cli.js CHANGED
@@ -6,14 +6,12 @@ import * as NodeCrypto from "node:crypto";
6
6
  import { createHash } from "node:crypto";
7
7
  import * as NFS from "node:fs";
8
8
  import { existsSync, mkdirSync, statSync } from "node:fs";
9
- import * as OS from "node:os";
10
- import os from "node:os";
11
- import * as Path from "node:path";
12
- import path from "node:path";
9
+ import os, * as OS from "node:os";
10
+ import path, * as Path from "node:path";
13
11
  import { DatabaseSync } from "node:sqlite";
14
12
  import * as NodeUrl from "node:url";
15
13
  import { fileURLToPath, pathToFileURL } from "node:url";
16
- import { access, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises";
14
+ import { access, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
17
15
  import * as readline from "node:readline";
18
16
  import { registerHooks } from "node:module";
19
17
  //#region node_modules/.pnpm/effect@4.0.0/node_modules/effect/dist/Pipeable.js
@@ -8722,6 +8720,8 @@ var AsyncFiberError = class extends (/*#__PURE__*/ TaggedError$2("AsyncFiberErro
8722
8720
  /** @internal */
8723
8721
  var UnknownErrorTypeId = "~effect/Cause/UnknownError";
8724
8722
  /** @internal */
8723
+ var isUnknownError$1 = (u) => hasProperty(u, UnknownErrorTypeId);
8724
+ /** @internal */
8725
8725
  var UnknownError$2 = class extends (/*#__PURE__*/ TaggedError$2("UnknownError")) {
8726
8726
  [UnknownErrorTypeId] = UnknownErrorTypeId;
8727
8727
  constructor(cause, message) {
@@ -11190,6 +11190,22 @@ var IllegalArgumentError = IllegalArgumentError$1;
11190
11190
  */
11191
11191
  var ExceededCapacityError = ExceededCapacityError$1;
11192
11192
  /**
11193
+ * Checks whether an arbitrary value is an `UnknownError`.
11194
+ *
11195
+ * **Example** (Checking the runtime type)
11196
+ *
11197
+ * ```ts import.meta.vitest
11198
+ * import { Cause } from "effect"
11199
+ *
11200
+ * Cause.isUnknownError(new Cause.UnknownError("x")) // => true
11201
+ * Cause.isUnknownError("nope") // => false
11202
+ * ```
11203
+ *
11204
+ * @category guards
11205
+ * @since 4.0.0
11206
+ */
11207
+ var isUnknownError = isUnknownError$1;
11208
+ /**
11193
11209
  * Constructs an `UnknownError`. The first argument is the original
11194
11210
  * cause (stored in `Error.cause`); the second is an optional human-readable
11195
11211
  * message.
@@ -26043,7 +26059,7 @@ var concatTokens = (prevTokens, nextTokens, isSeparated) => isSeparated || prevT
26043
26059
  ...nextTokens.slice(1)
26044
26060
  ];
26045
26061
  //#endregion
26046
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js
26062
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js
26047
26063
  var buildSpawnOptions = (options, base, platform) => {
26048
26064
  const detached = options.detached ?? platform !== "win32";
26049
26065
  return {
@@ -26054,7 +26070,7 @@ var buildSpawnOptions = (options, base, platform) => {
26054
26070
  };
26055
26071
  };
26056
26072
  //#endregion
26057
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/internal/utils.js
26073
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/internal/utils.js
26058
26074
  /** @internal */
26059
26075
  var handleErrnoException = (module, method) => (err, [path]) => {
26060
26076
  let reason = "Unknown";
@@ -26089,12 +26105,13 @@ var handleErrnoException = (module, method) => (err, [path]) => {
26089
26105
  });
26090
26106
  };
26091
26107
  //#endregion
26092
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeSink.js
26108
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeSink.js
26093
26109
  /**
26094
26110
  * Creates a `Sink` that writes chunks to a Node writable stream, respecting
26095
26111
  * backpressure, mapping writable errors with `onError`, and ending the stream
26096
26112
  * on completion unless `endOnDone` is `false`.
26097
26113
  *
26114
+ * @stability unstable
26098
26115
  * @category constructors
26099
26116
  * @since 4.0.0
26100
26117
  */
@@ -26104,6 +26121,7 @@ var fromWritable = (options) => fromChannel$1(mapDone(fromWritableChannel(option
26104
26121
  * Node writable stream, respecting backpressure and optionally ending the
26105
26122
  * writable when upstream is done.
26106
26123
  *
26124
+ * @stability unstable
26107
26125
  * @category constructors
26108
26126
  * @since 4.0.0
26109
26127
  */
@@ -26128,6 +26146,7 @@ var fromWritableChannel = (options) => fromTransform$1((pull) => {
26128
26146
  * The loop waits for `drain` when needed, fails on writable errors, and ends
26129
26147
  * the writable on upstream completion unless `endOnDone` is `false`.
26130
26148
  *
26149
+ * @stability unstable
26131
26150
  * @category converting
26132
26151
  * @since 4.0.0
26133
26152
  */
@@ -26169,7 +26188,7 @@ var pullIntoWritable = (options) => options.pull.pipe(flatMap$1((chunk) => {
26169
26188
  });
26170
26189
  })));
26171
26190
  //#endregion
26172
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeStream.js
26191
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeStream.js
26173
26192
  /**
26174
26193
  * Adapters between Node streams and Effect streams, channels, and readables.
26175
26194
  *
@@ -26179,6 +26198,7 @@ var pullIntoWritable = (options) => options.pull.pipe(flatMap$1((chunk) => {
26179
26198
  * `Readable`, and collects readable payloads into strings, array buffers, or
26180
26199
  * `Uint8Array`s with optional byte limits.
26181
26200
  *
26201
+ * @stability unstable
26182
26202
  * @since 4.0.0
26183
26203
  */
26184
26204
  /**
@@ -26186,6 +26206,7 @@ var pullIntoWritable = (options) => options.pull.pipe(flatMap$1((chunk) => {
26186
26206
  * an optional chunk size, mapping stream errors with `onError`, and destroying
26187
26207
  * the readable on completion unless `closeOnDone` is `false`.
26188
26208
  *
26209
+ * @stability unstable
26189
26210
  * @category constructors
26190
26211
  * @since 4.0.0
26191
26212
  */
@@ -26195,6 +26216,7 @@ var fromReadable = (options) => fromChannel(fromReadableChannel(options));
26195
26216
  * errors with `onError` and destroying the readable on completion unless
26196
26217
  * `closeOnDone` is `false`.
26197
26218
  *
26219
+ * @stability unstable
26198
26220
  * @category constructors
26199
26221
  * @since 4.0.0
26200
26222
  */
@@ -26249,7 +26271,7 @@ var readableToPullUnsafe = (options) => {
26249
26271
  };
26250
26272
  var defaultOnError = (error) => new UnknownError$1(error);
26251
26273
  //#endregion
26252
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js
26274
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js
26253
26275
  var toError = (error) => error instanceof globalThis.Error ? error : new globalThis.Error(String(error));
26254
26276
  var toPlatformError = (method, error, command) => {
26255
26277
  const { commands } = flattenCommand(command);
@@ -26281,6 +26303,7 @@ var taskkill = (childProcess, onExit = () => {}) => NodeChildProcess.execFile("t
26281
26303
  /**
26282
26304
  * Layer that provides the `NodeChildProcessSpawner` implementation.
26283
26305
  *
26306
+ * @stability unstable
26284
26307
  * @category layers
26285
26308
  * @since 4.0.0
26286
26309
  */
@@ -26545,7 +26568,7 @@ var layer$12 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
26545
26568
  }, process.platform)), fnUntraced(function* ([childProcess, exitSignal]) {
26546
26569
  if (yield* isDone$1(exitSignal)) {
26547
26570
  const [code] = yield* _await(exitSignal);
26548
- if (code !== 0 && isNotNull(code)) yield* ignore$1(killProcessGroup(cmd, childProcess, cmd.options.killSignal ?? "SIGTERM"));
26571
+ if (code !== 0 && isNotNull(code)) yield* ignore$1(terminateProcessGroup(cmd, childProcess, exitSignal, cmd.options));
26549
26572
  else if (isReferenced && process.platform !== "win32" && cmd.options.detached !== false) yield* ignore$1(terminateProcessGroup(cmd, childProcess, exitSignal, cmd.options));
26550
26573
  return;
26551
26574
  }
@@ -26662,6 +26685,7 @@ var layer$12 = /*#__PURE__*/ effect(ChildProcessSpawner, /* @__PURE__ */ gen(fun
26662
26685
  * Flattens a `Command` into an array of `StandardCommand`s along with pipe
26663
26686
  * options for each connection.
26664
26687
  *
26688
+ * @stability unstable
26665
26689
  * @category transforming
26666
26690
  * @since 4.0.0
26667
26691
  */
@@ -34494,7 +34518,7 @@ var validateSize = (method, size) => Number.isSafeInteger(size) && size >= 0 ? s
34494
34518
  description: "size must be a non-negative safe integer"
34495
34519
  }));
34496
34520
  //#endregion
34497
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeCrypto.js
34521
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeCrypto.js
34498
34522
  /**
34499
34523
  * Node-compatible implementation of Effect's `Crypto` service.
34500
34524
  *
@@ -34503,6 +34527,7 @@ var validateSize = (method, size) => Number.isSafeInteger(size) && size >= 0 ? s
34503
34527
  * `make` as the concrete service value and `layer` for providing it through
34504
34528
  * Effect context.
34505
34529
  *
34530
+ * @stability unstable
34506
34531
  * @since 1.0.0
34507
34532
  */
34508
34533
  var toHashAlgorithm = (algorithm) => {
@@ -34549,7 +34574,7 @@ var layer$10 = /* @__PURE__ */ succeed$5(Crypto, /* @__PURE__ */ make$12({
34549
34574
  digest
34550
34575
  }));
34551
34576
  //#endregion
34552
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeFileSystem.js
34577
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodeFileSystem.js
34553
34578
  /**
34554
34579
  * Shared Node-compatible implementation of Effect's `FileSystem` service.
34555
34580
  *
@@ -34559,6 +34584,7 @@ var layer$10 = /* @__PURE__ */ succeed$5(Crypto, /* @__PURE__ */ make$12({
34559
34584
  * links, metadata, temporary files and directories, and file watching through
34560
34585
  * the shared `FileSystem` service.
34561
34586
  *
34587
+ * @stability unstable
34562
34588
  * @since 4.0.0
34563
34589
  */
34564
34590
  var handleBadArgument = (method) => (err) => badArgument({
@@ -34645,12 +34671,41 @@ var makeTempDirectoryScoped = /*#__PURE__*/ (() => {
34645
34671
  const removeDirectory = /*#__PURE__*/ removeFactory("makeTempDirectoryScoped");
34646
34672
  return (options) => acquireRelease(makeDirectory(options), (directory) => orDie(removeDirectory(directory, { recursive: true })));
34647
34673
  })();
34674
+ var openFlagBits = (flag) => {
34675
+ const { O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY } = NFS.constants;
34676
+ switch (flag) {
34677
+ case "r": return O_RDONLY;
34678
+ case "r+": return O_RDWR;
34679
+ case "w": return O_TRUNC | O_CREAT | O_WRONLY;
34680
+ case "wx": return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;
34681
+ case "w+": return O_TRUNC | O_CREAT | O_RDWR;
34682
+ case "wx+": return O_TRUNC | O_CREAT | O_RDWR | O_EXCL;
34683
+ case "a": return O_APPEND | O_CREAT | O_WRONLY;
34684
+ case "ax": return O_APPEND | O_CREAT | O_WRONLY | O_EXCL;
34685
+ case "a+": return O_APPEND | O_CREAT | O_RDWR;
34686
+ case "ax+": return O_APPEND | O_CREAT | O_RDWR | O_EXCL;
34687
+ }
34688
+ };
34689
+ var noFollowFlags = (method, flag) => suspend$2(() => {
34690
+ const { O_NOFOLLOW } = NFS.constants;
34691
+ if (process.platform === "win32" || typeof O_NOFOLLOW !== "number" || O_NOFOLLOW === 0) return fail$3(badArgument({
34692
+ module: "FileSystem",
34693
+ method,
34694
+ description: "noFollow is not supported on this platform"
34695
+ }));
34696
+ return succeed$4(openFlagBits(flag) | O_NOFOLLOW);
34697
+ });
34648
34698
  var openFactory = (method) => {
34649
34699
  const nodeOpen = effectify(NFS.open, handleErrnoException("FileSystem", method), handleBadArgument(method));
34650
34700
  const nodeClose = effectify(NFS.close, handleErrnoException("FileSystem", method), handleBadArgument(method));
34651
- return (path, options) => pipe(acquireRelease(nodeOpen(path, options?.flag ?? "r", options?.mode), (fd) => orDie(nodeClose(fd))), map$6((fd) => makeFile(fd, options?.flag?.startsWith("a") ?? false)));
34701
+ return (path, options) => pipe(acquireRelease(options?.noFollow === true ? flatMap$1(noFollowFlags(method, options.flag ?? "r"), (flags) => nodeOpen(path, flags, options.mode)) : nodeOpen(path, options?.flag ?? "r", options?.mode), (fd) => orDie(nodeClose(fd))), map$6((fd) => makeFile(fd, options?.flag?.startsWith("a") ?? false)));
34652
34702
  };
34653
34703
  var open = /*#__PURE__*/ openFactory("open");
34704
+ var negativePosition = (method) => badArgument({
34705
+ module: "FileSystem",
34706
+ method,
34707
+ description: "Cannot read before the start of the file"
34708
+ });
34654
34709
  var makeFile = /*#__PURE__*/ (() => {
34655
34710
  const nodeReadFactory = (method) => effectify(NFS.read, handleErrnoException("FileSystem", method), handleBadArgument(method));
34656
34711
  const nodeRead = /*#__PURE__*/ nodeReadFactory("read");
@@ -34689,8 +34744,13 @@ var makeFile = /*#__PURE__*/ (() => {
34689
34744
  return succeed$4(position);
34690
34745
  });
34691
34746
  }
34692
- read(buffer) {
34747
+ read(buffer, options) {
34693
34748
  return suspend$2(() => {
34749
+ const explicit = options?.position;
34750
+ if (explicit !== void 0) return explicit < BigInt(0) ? fail$3(negativePosition("read")) : nodeRead(this.fd, {
34751
+ buffer,
34752
+ position: explicit
34753
+ });
34694
34754
  const position = this.position;
34695
34755
  return map$6(nodeRead(this.fd, {
34696
34756
  buffer,
@@ -34701,18 +34761,20 @@ var makeFile = /*#__PURE__*/ (() => {
34701
34761
  });
34702
34762
  });
34703
34763
  }
34704
- readAlloc(size) {
34764
+ readAlloc(size, options) {
34705
34765
  return suspend$2(() => {
34706
34766
  try {
34707
34767
  if (!Number.isInteger(size) || size < 0) throw new RangeError("size must be a non-negative integer");
34768
+ const explicit = options?.position;
34769
+ if (explicit !== void 0 && explicit < BigInt(0)) return fail$3(negativePosition("readAlloc"));
34708
34770
  const buffer = Buffer.allocUnsafeSlow(size);
34709
- const position = this.position;
34771
+ const position = explicit ?? this.position;
34710
34772
  return map$6(nodeReadAlloc(this.fd, {
34711
34773
  buffer,
34712
34774
  position
34713
34775
  }), (bytesRead) => {
34714
34776
  if (bytesRead === 0) return none();
34715
- this.position = position + BigInt(bytesRead);
34777
+ if (explicit === void 0) this.position = position + BigInt(bytesRead);
34716
34778
  if (bytesRead === size) return some(buffer);
34717
34779
  const dst = Buffer.allocUnsafeSlow(bytesRead);
34718
34780
  buffer.copy(dst, 0, 0, bytesRead);
@@ -34800,7 +34862,7 @@ var realPath = /*#__PURE__*/ (() => {
34800
34862
  const nodeRealPath = /*#__PURE__*/ effectify(NFS.realpath, /*#__PURE__*/ handleErrnoException("FileSystem", "realPath"), /*#__PURE__*/ handleBadArgument("realPath"));
34801
34863
  return (path) => nodeRealPath(path);
34802
34864
  })();
34803
- var rename = /*#__PURE__*/ (() => {
34865
+ var rename$1 = /*#__PURE__*/ (() => {
34804
34866
  const nodeRename = /*#__PURE__*/ effectify(NFS.rename, /*#__PURE__*/ handleErrnoException("FileSystem", "rename"), /*#__PURE__*/ handleBadArgument("rename"));
34805
34867
  return (oldPath, newPath) => nodeRename(oldPath, newPath);
34806
34868
  })();
@@ -34912,7 +34974,7 @@ var makeFileSystem = /*#__PURE__*/ map$6(/*#__PURE__*/ serviceOption(WatchBacken
34912
34974
  readLink,
34913
34975
  realPath,
34914
34976
  remove,
34915
- rename,
34977
+ rename: rename$1,
34916
34978
  stat,
34917
34979
  symlink,
34918
34980
  truncate,
@@ -34942,7 +35004,7 @@ var makeFileSystem = /*#__PURE__*/ map$6(/*#__PURE__*/ serviceOption(WatchBacken
34942
35004
  */
34943
35005
  var layer$8 = /* @__PURE__ */ effect(FileSystem)(makeFileSystem);
34944
35006
  //#endregion
34945
- //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.0_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodePath.js
35007
+ //#region node_modules/.pnpm/@effect+platform-node-shared@4.0.3_effect@4.0.0/node_modules/@effect/platform-node-shared/dist/NodePath.js
34946
35008
  /**
34947
35009
  * Node-backed provider for Effect's `Path` service.
34948
35010
  *
@@ -34951,6 +35013,7 @@ var layer$8 = /* @__PURE__ */ effect(FileSystem)(makeFileSystem);
34951
35013
  * `layerWin32` provide fixed POSIX and Windows variants. All three layers also
34952
35014
  * include helpers for converting between file paths and file URLs.
34953
35015
  *
35016
+ * @stability unstable
34954
35017
  * @since 4.0.0
34955
35018
  */
34956
35019
  var fileUrlOps = (windows) => ({
@@ -35026,6 +35089,7 @@ var layer$4 = /* @__PURE__ */ succeed$5(Stdio, /*#__PURE__*/ make$15({
35026
35089
  args: /*#__PURE__*/ sync(() => process.argv.slice(2)),
35027
35090
  stdinIsTerminal: /*#__PURE__*/ sync(() => process.stdin.isTTY === true),
35028
35091
  stdoutIsTerminal: /*#__PURE__*/ sync(() => process.stdout.isTTY === true),
35092
+ stderrIsTerminal: /*#__PURE__*/ sync(() => process.stderr.isTTY === true),
35029
35093
  stdout: (options) => fromWritable({
35030
35094
  evaluate: () => process.stdout,
35031
35095
  onError: (cause) => systemError({
@@ -35138,8 +35202,9 @@ var make$10 = (impl) => Terminal.of({
35138
35202
  });
35139
35203
  /**
35140
35204
  * Provides the default process-backed `Terminal` service, ending key input on
35141
- * Ctrl+C or Ctrl+D.
35205
+ * bare Esc, Ctrl+C, or Ctrl+D.
35142
35206
  *
35207
+ * @stability unstable
35143
35208
  * @category layers
35144
35209
  * @since 4.0.0
35145
35210
  */
@@ -35242,7 +35307,8 @@ var layer$3 = /*#__PURE__*/ effect(Terminal, /*#__PURE__*/ (/* @__PURE__ */ fnUn
35242
35307
  });
35243
35308
  }))(defaultShouldQuit));
35244
35309
  function defaultShouldQuit(input) {
35245
- return input.key.ctrl && (input.key.name === "c" || input.key.name === "d");
35310
+ const key = input.key;
35311
+ return key.name === "escape" || key.ctrl && (key.name === "c" || key.name === "d");
35246
35312
  }
35247
35313
  //#endregion
35248
35314
  //#region node_modules/.pnpm/@effect+platform-node@4.0.0_effect@4.0.0_redis@6.3.0/node_modules/@effect/platform-node/dist/NodeServices.js
@@ -42739,7 +42805,7 @@ var runWith = (command, config) => {
42739
42805
  };
42740
42806
  var package_default = {
42741
42807
  name: "repo-dive",
42742
- version: "0.16.2",
42808
+ version: "0.16.4",
42743
42809
  description: "Dive into a git repo's history: per-commit snapshots, an indexed metrics catalog and an interactive dashboard",
42744
42810
  keywords: [
42745
42811
  "git",
@@ -42808,8 +42874,8 @@ var package_default = {
42808
42874
  "lint-staged": { "**": ["prettier --ignore-unknown --write"] },
42809
42875
  prettier: "@kachkaev/prettier-config",
42810
42876
  devDependencies: {
42811
- "@babel/core": "8.0.6",
42812
- "@base-ui/react": "1.8.0",
42877
+ "@babel/core": "8.0.7",
42878
+ "@base-ui/react": "1.9.0",
42813
42879
  "@changesets/changelog-github": "1.0.1",
42814
42880
  "@changesets/cli": "3.0.3",
42815
42881
  "@changesets/config": "4.0.1",
@@ -42823,7 +42889,7 @@ var package_default = {
42823
42889
  "@tsconfig/node-ts": "23.6.4",
42824
42890
  "@tsconfig/strictest": "2.0.8",
42825
42891
  "@types/babel__core": "7.20.5",
42826
- "@types/node": "26.6.4",
42892
+ "@types/node": "26.6.5",
42827
42893
  "@types/react": "19.3.0",
42828
42894
  "@types/react-dom": "19.3.0",
42829
42895
  "@typescript/native": "npm:typescript@7.0.2",
@@ -42833,7 +42899,7 @@ var package_default = {
42833
42899
  "@visx/group": "4.0.0",
42834
42900
  "@visx/scale": "4.0.0",
42835
42901
  "@visx/shape": "4.0.0",
42836
- "@vitejs/plugin-react": "6.1.1",
42902
+ "@vitejs/plugin-react": "6.1.2",
42837
42903
  "babel-plugin-react-compiler": "1.0.0",
42838
42904
  "class-variance-authority": "0.7.1",
42839
42905
  "cspell": "10.3.6",
@@ -42841,18 +42907,18 @@ var package_default = {
42841
42907
  "eslint": "10.12.0",
42842
42908
  "eslint-plugin-react-hooks": "7.1.1",
42843
42909
  "husky": "9.1.7",
42844
- "knip": "6.39.0",
42910
+ "knip": "6.41.0",
42845
42911
  "lint-staged": "17.6.0",
42846
42912
  "lucide-react": "1.52.0",
42847
42913
  "markdownlint-cli": "0.49.1",
42848
42914
  "npm-run-all2": "9.0.3",
42849
- "prettier": "3.9.9",
42915
+ "prettier": "3.9.10",
42850
42916
  "react": "19.3.0",
42851
42917
  "react-dom": "19.3.0",
42852
42918
  "tailwind-merge": "3.7.0",
42853
42919
  "tailwindcss": "4.3.3",
42854
42920
  "typescript": "npm:@typescript/typescript6@6.0.2",
42855
- "vite": "8.3.2",
42921
+ "vite": "8.3.4",
42856
42922
  "vitest": "5.0.3",
42857
42923
  "yaml": "2.9.1"
42858
42924
  },
@@ -50646,14 +50712,42 @@ var CatalogFormatError = class extends TaggedError$1("CatalogFormatError") {
50646
50712
  return `Catalog at ${this.rootPath} has format version ${String(this.formatVersion)}, but this version of repo-dive expects ${catalogFormatVersion}. Delete the folder to re-collect from scratch.`;
50647
50713
  }
50648
50714
  };
50649
- var writeJson = (filePath, value) => tryPromise(() => writeFile(filePath, `${JSON.stringify(value, void 0, 2)}\n`, "utf8"));
50650
- var readJsonIfExists = (filePath) => tryPromise(async () => {
50715
+ /**
50716
+ * Writes beside the target, then renames over it. A scan cut short (Ctrl+C, a
50717
+ * CI step timeout) or a copy of the catalog taken mid-scan (a CI cache save)
50718
+ * then sees either the previous file or the complete new one, never a
50719
+ * truncated one. A temporary file a cut-short write leaves behind is reused by
50720
+ * the next write of the same file.
50721
+ */
50722
+ var writeJson = (filePath, value) => tryPromise(async () => {
50723
+ const temporaryPath = `${filePath}.tmp`;
50724
+ await writeFile(temporaryPath, `${JSON.stringify(value, void 0, 2)}\n`, "utf8");
50725
+ await rename(temporaryPath, filePath);
50726
+ });
50727
+ var readTextIfExists = async (filePath) => {
50651
50728
  try {
50652
- return JSON.parse(await readFile(filePath, "utf8"));
50729
+ return await readFile(filePath, "utf8");
50653
50730
  } catch (error) {
50654
50731
  if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
50655
50732
  throw error;
50656
50733
  }
50734
+ };
50735
+ var readJsonIfExists = (filePath) => tryPromise(async () => {
50736
+ const raw = await readTextIfExists(filePath);
50737
+ return raw === void 0 ? void 0 : JSON.parse(raw);
50738
+ });
50739
+ /**
50740
+ * Like {@link readJsonIfExists}, but a file that does not parse reads as
50741
+ * missing too. Catalogs written before writes became atomic can hold
50742
+ * truncated files, and failing on one would fail every scan from then on.
50743
+ */
50744
+ var readJsonIfIntact = (filePath) => tryPromise(async () => {
50745
+ const raw = await readTextIfExists(filePath);
50746
+ try {
50747
+ return raw === void 0 ? void 0 : JSON.parse(raw);
50748
+ } catch {
50749
+ return;
50750
+ }
50657
50751
  });
50658
50752
  var cacheKeyOf = (sidecar) => typeof sidecar === "object" && sidecar !== null && "cacheKey" in sidecar ? sidecar.cacheKey : void 0;
50659
50753
  var formatVersionOf = (manifest) => typeof manifest === "object" && manifest !== null && "formatVersion" in manifest ? manifest.formatVersion : void 0;
@@ -50710,8 +50804,11 @@ var openCatalog = fn("openCatalog")(function* ({ repoRoot, catalogPath }) {
50710
50804
  };
50711
50805
  });
50712
50806
  var collectorDir = (catalog, sha, collectorName) => path.join(catalog.rootPath, "commits", sha, collectorName);
50713
- /** Reads the cache fingerprint recorded in a collector's sidecar, if any. */
50714
- var readCollectorCacheKey = (catalog, sha, collectorName) => readJsonIfExists(path.join(collectorDir(catalog, sha, collectorName), "collector.json")).pipe(map$6(cacheKeyOf));
50807
+ /**
50808
+ * Reads the cache fingerprint recorded in a collector's sidecar, if any. A
50809
+ * truncated sidecar has none, so the commit is collected afresh.
50810
+ */
50811
+ var readCollectorCacheKey = (catalog, sha, collectorName) => readJsonIfIntact(path.join(collectorDir(catalog, sha, collectorName), "collector.json")).pipe(map$6(cacheKeyOf));
50715
50812
  /**
50716
50813
  * A (commit, collector) pair is done when a sidecar recording the current cache
50717
50814
  * fingerprint exists. `cacheKey` folds in the collector version and any config
@@ -51312,6 +51409,11 @@ var summarizeCommits = (commits) => {
51312
51409
  lastCommitDate: dates.at(-1)
51313
51410
  };
51314
51411
  };
51412
+ /**
51413
+ * A scan's remaining time at the precision an estimate deserves: seconds only
51414
+ * while under a minute, whole minutes from then on (`~1m`, not `~1m 52s`).
51415
+ */
51416
+ var formatTimeLeft = (seconds) => seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m`;
51315
51417
  var runCollector = ({ catalog, sha, collector, cacheKey, worktreePath }) => collector.collect({
51316
51418
  repoRoot: catalog.repoRoot,
51317
51419
  catalogPath: catalog.rootPath,
@@ -51432,9 +51534,7 @@ var runScan = fn("runScan")(function* ({ repoPath, collectorNames, maxCommits, s
51432
51534
  const elapsedSeconds = (now - startedAt) / 1e3;
51433
51535
  const rate = processed / Math.max(1, elapsedSeconds);
51434
51536
  const remainingSeconds = Math.round((selected.length - processed) / Math.max(.01, rate));
51435
- const minutes = Math.floor(remainingSeconds / 60);
51436
- const seconds = remainingSeconds % 60;
51437
- return `${Math.round(rate)}/s, ~${minutes > 0 ? `${minutes}m ` : ""}${seconds}s left`;
51537
+ return `${Math.round(rate)}/s, ~${formatTimeLeft(remainingSeconds)} left`;
51438
51538
  };
51439
51539
  const processedRef = yield* make$31(0);
51440
51540
  const outcomes = yield* forEach$1(selected, (commit) => collectCommit({
@@ -52311,6 +52411,7 @@ var runIndex = fn("runIndex")(function* ({ repoPath }) {
52311
52411
  const factsByCollector = /* @__PURE__ */ new Map();
52312
52412
  let unknownCollectorDirs = 0;
52313
52413
  let offMainlineSnapshots = 0;
52414
+ let incompleteOutputs = 0;
52314
52415
  for (const collectorName of await readdir(commitDir)) {
52315
52416
  const collector = registry.get(collectorName);
52316
52417
  if (!collector) {
@@ -52321,7 +52422,16 @@ var runIndex = fn("runIndex")(function* ({ repoPath }) {
52321
52422
  offMainlineSnapshots += 1;
52322
52423
  continue;
52323
52424
  }
52324
- const raw = JSON.parse(await readFile(path.join(commitDir, collectorName, "output.json"), "utf8"));
52425
+ let raw;
52426
+ try {
52427
+ raw = JSON.parse(await readFile(path.join(commitDir, collectorName, "output.json"), "utf8"));
52428
+ } catch (error) {
52429
+ if (error instanceof SyntaxError || error instanceof Error && "code" in error && error.code === "ENOENT") {
52430
+ incompleteOutputs += 1;
52431
+ continue;
52432
+ }
52433
+ throw error;
52434
+ }
52325
52435
  factsByCollector.set(collectorName, collector.normalize(raw));
52326
52436
  }
52327
52437
  return {
@@ -52334,12 +52444,14 @@ var runIndex = fn("runIndex")(function* ({ repoPath }) {
52334
52444
  factsByCollector
52335
52445
  },
52336
52446
  unknownCollectorDirs,
52337
- offMainlineSnapshots
52447
+ offMainlineSnapshots,
52448
+ incompleteOutputs
52338
52449
  };
52339
52450
  }), { concurrency: 16 });
52340
52451
  const commitFacts = readOutcomes.map((outcome) => outcome.facts);
52341
52452
  const unknownCollectorDirs = readOutcomes.reduce((total, outcome) => total + outcome.unknownCollectorDirs, 0);
52342
52453
  const offMainlineSnapshots = readOutcomes.reduce((total, outcome) => total + outcome.offMainlineSnapshots, 0);
52454
+ const incompleteOutputs = readOutcomes.reduce((total, outcome) => total + outcome.incompleteOutputs, 0);
52343
52455
  const indexDir = path.join(catalogPath, "index");
52344
52456
  yield* tryPromise(() => mkdir(indexDir, { recursive: true }));
52345
52457
  const dbPath = path.join(indexDir, "metrics.sqlite");
@@ -52353,7 +52465,8 @@ var runIndex = fn("runIndex")(function* ({ repoPath }) {
52353
52465
  `Cube: ${dbPath}`,
52354
52466
  `Dashboard data: ${dashboardPath}`,
52355
52467
  ...unknownCollectorDirs > 0 ? [`Skipped ${unknownCollectorDirs} outputs from unknown collectors (see \`gc --stale\`).`] : [],
52356
- ...offMainlineSnapshots > 0 ? [`Skipped ${offMainlineSnapshots} tree snapshots taken off the lineages.`] : []
52468
+ ...offMainlineSnapshots > 0 ? [`Skipped ${offMainlineSnapshots} tree snapshots taken off the lineages.`] : [],
52469
+ ...incompleteOutputs > 0 ? [`Skipped ${incompleteOutputs} incomplete outputs left by an interrupted scan.`] : []
52357
52470
  ].join("\n"));
52358
52471
  yield* warnAboutIgnoreFiles({
52359
52472
  repoRoot,
@@ -59625,5 +59738,14 @@ var cli = make$8("repo-dive", {
59625
59738
  var ReportedCliFailure = class extends TaggedError$1("ReportedCliFailure") {
59626
59739
  [errorReported] = false;
59627
59740
  };
59628
- run(cli, { version: package_default.version }).pipe(catchIf((error) => !isCliError(error), (error$1) => error(error$1 instanceof Error ? error$1.message : String(error$1)).pipe(andThen(fail$3(new ReportedCliFailure())))), provide(layer$1), runMain);
59741
+ /**
59742
+ * The one line a domain failure prints as. `Effect.try` / `Effect.tryPromise`
59743
+ * failures only say "An error occurred in Effect.tryPromise", so the error
59744
+ * they wrap is what tells the user what went wrong.
59745
+ */
59746
+ var describeFailure = (error) => {
59747
+ if (!(error instanceof Error)) return String(error);
59748
+ return isUnknownError(error) && error.cause instanceof Error ? `${error.message}: ${error.cause.message}` : error.message;
59749
+ };
59750
+ run(cli, { version: package_default.version }).pipe(catchIf((error) => !isCliError(error), (error$1) => error(describeFailure(error$1)).pipe(andThen(fail$3(new ReportedCliFailure())))), provide(layer$1), runMain);
59629
59751
  //#endregion