@wspc/cli 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.
package/dist/cli.js CHANGED
@@ -1469,9 +1469,9 @@ function createConsistencyFetch(opts) {
1469
1469
  }
1470
1470
 
1471
1471
  // src/version.ts
1472
- var VERSION = "0.1.5";
1472
+ var VERSION = "0.1.6";
1473
1473
  var SPEC_SHA = "706a2577";
1474
- var SPEC_FETCHED_AT = "2026-06-22T07:51:02.058Z";
1474
+ var SPEC_FETCHED_AT = "2026-06-24T08:28:50.392Z";
1475
1475
  var API_BASE = "https://api.wspc.ai";
1476
1476
 
1477
1477
  // src/index.ts
@@ -4579,7 +4579,7 @@ var attachmentCommand = new Command70("attachment").description("Download an inb
4579
4579
 
4580
4580
  // src/handwritten/commands/drive/bind.ts
4581
4581
  import { Command as Command71 } from "commander";
4582
- import { stat as stat2 } from "fs/promises";
4582
+ import { stat as stat3 } from "fs/promises";
4583
4583
  import { resolve } from "path";
4584
4584
 
4585
4585
  // src/handwritten/commands/drive/api.ts
@@ -4667,7 +4667,7 @@ async function createDriveApi(opts = {}) {
4667
4667
  }
4668
4668
 
4669
4669
  // src/handwritten/commands/drive/state.ts
4670
- import { mkdir, open, readFile as readFile2, rename, rm, writeFile } from "fs/promises";
4670
+ import { mkdir, open, readFile as readFile2, rename, rm, stat as stat2, writeFile } from "fs/promises";
4671
4671
  import { randomUUID as randomUUID2 } from "crypto";
4672
4672
  import { join as join2 } from "path";
4673
4673
  import { DateTime as DateTime4 } from "luxon";
@@ -4695,6 +4695,7 @@ function driveConflictTimestamp(clock = systemDriveClock) {
4695
4695
  // src/handwritten/commands/drive/state.ts
4696
4696
  var DRIVE_DIR = ".wspc-drive";
4697
4697
  var STATE_FILE = "state.json";
4698
+ var STALE_LOCK_MS = 10 * 60 * 1e3;
4698
4699
  function statePath(root) {
4699
4700
  return join2(root, DRIVE_DIR, STATE_FILE);
4700
4701
  }
@@ -4720,7 +4721,7 @@ async function writeDriveState(root, state, clock) {
4720
4721
  const fullPath = statePath(root);
4721
4722
  try {
4722
4723
  await writeFile(tmp, snapshot, { mode: 384 });
4723
- const fh = await open(tmp, "r");
4724
+ const fh = await open(tmp, "r+");
4724
4725
  try {
4725
4726
  await fh.sync();
4726
4727
  } finally {
@@ -4780,11 +4781,22 @@ async function writeDriveRealtimeState(root, realtime) {
4780
4781
  async function withDriveLock(root, fn) {
4781
4782
  await mkdir(join2(root, DRIVE_DIR), { recursive: true });
4782
4783
  const lockFile = join2(root, DRIVE_DIR, "sync.lock");
4783
- const fh = await open(lockFile, "wx").catch((error) => {
4784
- if (error.code === "EEXIST") {
4784
+ const fh = await open(lockFile, "wx").catch(async (error) => {
4785
+ if (error.code !== "EEXIST") throw error;
4786
+ const lockStat = await stat2(lockFile).catch((statError) => {
4787
+ if (statError.code === "ENOENT") return void 0;
4788
+ throw statError;
4789
+ });
4790
+ if (lockStat && Date.now() - lockStat.mtimeMs <= STALE_LOCK_MS) {
4785
4791
  throw new Error("sync lock already exists");
4786
4792
  }
4787
- throw error;
4793
+ await rm(lockFile, { force: true });
4794
+ return open(lockFile, "wx").catch((retryError) => {
4795
+ if (retryError.code === "EEXIST") {
4796
+ throw new Error("sync lock already exists");
4797
+ }
4798
+ throw retryError;
4799
+ });
4788
4800
  });
4789
4801
  try {
4790
4802
  return await fn();
@@ -4832,7 +4844,7 @@ function isValidDriveState(value) {
4832
4844
  async function assertExistingDirectory(path) {
4833
4845
  let stats;
4834
4846
  try {
4835
- stats = await stat2(path);
4847
+ stats = await stat3(path);
4836
4848
  } catch {
4837
4849
  throw new Error(`local folder does not exist: ${path}`);
4838
4850
  }
@@ -6243,9 +6255,20 @@ function redactedRealtimeError(error) {
6243
6255
  return "auth failed";
6244
6256
  }
6245
6257
  if (/\bnetwork|fetch|close\b/i.test(text)) {
6246
- return "network error";
6258
+ return withRealtimeCode("network error", error);
6259
+ }
6260
+ return withRealtimeCode("realtime error", error);
6261
+ }
6262
+ function withRealtimeCode(label, error) {
6263
+ if (typeof error !== "object" || error === null) return label;
6264
+ const code = error.code;
6265
+ if (typeof code === "string" && /^[A-Z][A-Z0-9_]{1,31}$/.test(code)) {
6266
+ return `${label} (${code})`;
6267
+ }
6268
+ if (typeof code === "number" && Number.isInteger(code)) {
6269
+ return `${label} (${code})`;
6247
6270
  }
6248
- return "realtime error";
6271
+ return label;
6249
6272
  }
6250
6273
  function isRecord3(value) {
6251
6274
  return typeof value === "object" && value !== null && !Array.isArray(value);