@withone/cli 1.52.2 → 1.52.3
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.
|
@@ -216,6 +216,32 @@ function listSyncedPlatforms() {
|
|
|
216
216
|
if (!fs3.existsSync(DATA_DIR)) return [];
|
|
217
217
|
return fs3.readdirSync(DATA_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(/\.db$/, ""));
|
|
218
218
|
}
|
|
219
|
+
function isDriverFault(err) {
|
|
220
|
+
const code = err?.code;
|
|
221
|
+
if (code === "ERR_DLOPEN_FAILED") return true;
|
|
222
|
+
const msg = err instanceof Error ? err.message : String(err ?? "");
|
|
223
|
+
return /NODE_MODULE_VERSION|compiled against a different Node\.js version|Could not locate the bindings file|invalid ELF header|wrong ELF class|symbol not found|image not found|not a valid Win32 application/i.test(msg);
|
|
224
|
+
}
|
|
225
|
+
function passesIntegrityCheck(Ctor, dbPath) {
|
|
226
|
+
let probe;
|
|
227
|
+
try {
|
|
228
|
+
probe = new Ctor(dbPath, { readonly: true, fileMustExist: true });
|
|
229
|
+
const result = probe.pragma("quick_check");
|
|
230
|
+
const first = Array.isArray(result) ? result[0] : result;
|
|
231
|
+
const verdict = typeof first === "string" ? first : first?.quick_check;
|
|
232
|
+
return verdict === "ok";
|
|
233
|
+
} catch {
|
|
234
|
+
return false;
|
|
235
|
+
} finally {
|
|
236
|
+
try {
|
|
237
|
+
probe?.close();
|
|
238
|
+
} catch {
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function backupPathFor(dbPath, now = /* @__PURE__ */ new Date()) {
|
|
243
|
+
return `${dbPath}.bak.${now.toISOString().replace(/[:.]/g, "-")}`;
|
|
244
|
+
}
|
|
219
245
|
async function openDatabase(platform, opts = {}) {
|
|
220
246
|
const Database = await loadSqlite();
|
|
221
247
|
fs3.mkdirSync(DATA_DIR, { recursive: true });
|
|
@@ -226,13 +252,38 @@ async function openDatabase(platform, opts = {}) {
|
|
|
226
252
|
let db;
|
|
227
253
|
try {
|
|
228
254
|
db = new Database(dbPath);
|
|
229
|
-
} catch {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
255
|
+
} catch (err) {
|
|
256
|
+
if (isDriverFault(err)) {
|
|
257
|
+
const detail = err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
258
|
+
throw new Error(
|
|
259
|
+
`The local sync engine (better-sqlite3) could not load in this Node process.
|
|
260
|
+
Your database was NOT modified.
|
|
261
|
+
|
|
262
|
+
This usually means the CLI is running under a different Node than the one
|
|
263
|
+
better-sqlite3 was built for \u2014 currently node ${process.version} (NODE_MODULE_VERSION ${process.versions.modules}). \`one\` is a #!/usr/bin/env node shim, so a minimal PATH under cron, launchd,
|
|
264
|
+
or an agent runner can select a different interpreter than your shell does.
|
|
265
|
+
|
|
266
|
+
Rebuild it against this Node with:
|
|
267
|
+
one sync install
|
|
268
|
+
|
|
269
|
+
Underlying error: ${detail}`
|
|
270
|
+
);
|
|
235
271
|
}
|
|
272
|
+
if (!fs3.existsSync(dbPath)) throw err;
|
|
273
|
+
if (passesIntegrityCheck(Database, dbPath)) {
|
|
274
|
+
const detail = err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
275
|
+
throw new Error(
|
|
276
|
+
`Could not open ${dbPath}, but it passes SQLite's integrity check \u2014 so it is not corrupt and has been left untouched.
|
|
277
|
+
|
|
278
|
+
Underlying error: ${detail}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
const backupPath = backupPathFor(dbPath);
|
|
282
|
+
fs3.renameSync(dbPath, backupPath);
|
|
283
|
+
process.stderr.write(
|
|
284
|
+
`Database at ${dbPath} failed its integrity check. Backup saved at ${backupPath}, starting fresh.
|
|
285
|
+
`
|
|
286
|
+
);
|
|
236
287
|
db = new Database(dbPath);
|
|
237
288
|
}
|
|
238
289
|
db.pragma("journal_mode = WAL");
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
writeDraftProfile,
|
|
66
66
|
writePageToMemory,
|
|
67
67
|
writeProfile
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-IKYXS7EI.js";
|
|
69
69
|
import {
|
|
70
70
|
getByDotPath
|
|
71
71
|
} from "./chunk-44CV5IMX.js";
|
|
@@ -7731,6 +7731,7 @@ async function syncDoctorCommand() {
|
|
|
7731
7731
|
checks.push({ name: "better-sqlite3 loads", ok: false, detail: err instanceof Error ? err.message : String(err) });
|
|
7732
7732
|
}
|
|
7733
7733
|
const allOk = checks.every((c) => c.ok);
|
|
7734
|
+
if (!allOk) process.exitCode = 1;
|
|
7734
7735
|
if (isAgentMode()) {
|
|
7735
7736
|
json({ ok: allOk, checks });
|
|
7736
7737
|
return;
|
|
@@ -8286,7 +8287,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
8286
8287
|
` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
|
|
8287
8288
|
`
|
|
8288
8289
|
);
|
|
8289
|
-
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-
|
|
8290
|
+
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-U2MZVGU6.js");
|
|
8290
8291
|
await memMigrateCommand3({ platform, yes: true });
|
|
8291
8292
|
return;
|
|
8292
8293
|
}
|
|
@@ -8295,7 +8296,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
8295
8296
|
initialValue: true
|
|
8296
8297
|
});
|
|
8297
8298
|
if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
|
|
8298
|
-
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-
|
|
8299
|
+
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-U2MZVGU6.js");
|
|
8299
8300
|
await memMigrateCommand2({ platform, yes: true });
|
|
8300
8301
|
}
|
|
8301
8302
|
async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
@@ -10903,7 +10904,7 @@ Every \`sync X\` command is also exposed as \`mem sync X\` \u2014 same handlers,
|
|
|
10903
10904
|
| Command | What it does |
|
|
10904
10905
|
|---------|-------------|
|
|
10905
10906
|
| \`sync profiles [platform]\` | List built-in pre-validated profiles |
|
|
10906
|
-
| \`sync doctor\` | Verify sync engine health |
|
|
10907
|
+
| \`sync doctor\` | Verify sync engine health. **Exits non-zero when not ready**, so \`one sync doctor && one sync run <platform>\` is a safe gate \u2014 run it first from cron/launchd, where a bare PATH can select a Node the native driver wasn't built for |
|
|
10907
10908
|
| \`sync models <platform>\` | Discover available models |
|
|
10908
10909
|
| \`sync init <plat> <model>\` | Create/patch profile (seeds from built-in, auto-tests) |
|
|
10909
10910
|
| \`sync test <plat>/<model>\` | Validate profile. \`--show-searchable\` previews embedded text across 5 samples with per-path hit rates |
|