caveat-cli 0.16.3 → 0.17.0

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.
@@ -15434,11 +15434,17 @@ function errorMessage2(err) {
15434
15434
  }
15435
15435
 
15436
15436
  // ../../packages/core/dist/autoSync.js
15437
+ import { spawn as spawn2 } from "node:child_process";
15437
15438
  import { createHash as createHash4 } from "node:crypto";
15438
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "node:fs";
15439
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync3, statSync as statSync6, writeFileSync as writeFileSync5 } from "node:fs";
15439
15440
  import { dirname as dirname5, join as join9 } from "node:path";
15440
- var AUTO_SYNC_DEBOUNCE_MS = 24 * 60 * 60 * 1e3;
15441
+ var AUTO_SYNC_DEBOUNCE_MS = 15 * 60 * 1e3;
15442
+ var AUTO_SYNC_RECORD_DEBOUNCE_MS = 60 * 1e3;
15443
+ var AUTO_SYNC_SUSPEND_THRESHOLD = 3;
15444
+ var AUTO_SYNC_DEGRADED_RETRY_MS = 6 * 60 * 60 * 1e3;
15445
+ var AUTO_SYNC_NOTICE_REPEAT_MS = 24 * 60 * 60 * 1e3;
15441
15446
  var CAVEAT_AUTO_SYNC_ENV = "CAVEAT_AUTO_SYNC";
15447
+ var CAVEAT_AUTO_SYNC_DEBOUNCE_ENV = "CAVEAT_AUTO_SYNC_DEBOUNCE_MS";
15442
15448
  function syncDir(caveatHome) {
15443
15449
  return join9(caveatHome, "sync");
15444
15450
  }
@@ -15471,6 +15477,7 @@ function resetAutoSyncFailureState(caveatHome) {
15471
15477
  writeAutoSyncState(caveatHome, {
15472
15478
  finishedAt: current?.finishedAt ?? (/* @__PURE__ */ new Date(0)).toISOString(),
15473
15479
  signature: current?.signature ?? "",
15480
+ lastNotifiedAt: current?.lastNotifiedAt,
15474
15481
  ownSync: { consecutiveFailureSignature: null, consecutiveFailureCount: 0 }
15475
15482
  });
15476
15483
  } catch {
@@ -15479,7 +15486,15 @@ function resetAutoSyncFailureState(caveatHome) {
15479
15486
  function isAutoSyncState(value) {
15480
15487
  if (value === null || typeof value !== "object") return false;
15481
15488
  const candidate = value;
15482
- return typeof candidate.finishedAt === "string" && typeof candidate.signature === "string" && candidate.ownSync !== null && typeof candidate.ownSync === "object" && (candidate.ownSync.consecutiveFailureSignature === null || typeof candidate.ownSync.consecutiveFailureSignature === "string") && Number.isInteger(candidate.ownSync.consecutiveFailureCount) && candidate.ownSync.consecutiveFailureCount >= 0;
15489
+ return typeof candidate.finishedAt === "string" && typeof candidate.signature === "string" && isOptionalString(candidate.lastNotifiedAt) && candidate.ownSync !== null && typeof candidate.ownSync === "object" && (candidate.ownSync.consecutiveFailureSignature === null || typeof candidate.ownSync.consecutiveFailureSignature === "string") && Number.isInteger(candidate.ownSync.consecutiveFailureCount) && candidate.ownSync.consecutiveFailureCount >= 0 && isOptionalString(candidate.ownSync.lastAttemptAt);
15490
+ }
15491
+ function isOptionalString(value) {
15492
+ return value === void 0 || typeof value === "string";
15493
+ }
15494
+ function parseTimestamp(value) {
15495
+ if (value === void 0) return 0;
15496
+ const ms = Date.parse(value);
15497
+ return Number.isFinite(ms) ? ms : 0;
15483
15498
  }
15484
15499
  function classifyOwnSyncOutcome(err, lastProbe) {
15485
15500
  if (!(err instanceof SyncError)) return "fail";
@@ -15507,8 +15522,9 @@ function autoSyncNotification(outcome) {
15507
15522
  if (outcome.own.pulled === true) {
15508
15523
  lines.push("autosync: pulled updates from your private remote");
15509
15524
  }
15510
- if (outcome.own.escalated === true) {
15511
- lines.push("autosync: own sync failed 3x in a row and auto-retry is paused. run `caveat sync` manually to resolve and resume.");
15525
+ const backoffHours = Math.round(AUTO_SYNC_DEGRADED_RETRY_MS / (60 * 60 * 1e3));
15526
+ if (outcome.own.degraded === true) {
15527
+ lines.push(`autosync: own sync keeps failing; auto-retry is backed off to every ${backoffHours}h. run \`caveat sync\` to resolve now.`);
15512
15528
  } else if (outcome.own.disposition === "fail") {
15513
15529
  lines.push(`autosync: own sync failed (${outcome.own.code ?? "UNKNOWN"}). run \`caveat sync\` to resolve.`);
15514
15530
  }
@@ -15517,17 +15533,7 @@ function autoSyncNotification(outcome) {
15517
15533
  lines.push(`autosync: community pull failed: ${failedHandles.join(", ")}`);
15518
15534
  }
15519
15535
  const text = lines.length > 0 ? lines.join("\n") : null;
15520
- const signature = sha256(JSON.stringify({
15521
- lines,
15522
- own: {
15523
- disposition: outcome.own.disposition,
15524
- code: outcome.own.code ?? null,
15525
- pulled: outcome.own.pulled ?? null,
15526
- suspended: outcome.own.suspended ?? false,
15527
- escalated: outcome.own.escalated ?? false
15528
- },
15529
- communityFailed: failedHandles
15530
- }));
15536
+ const signature = sha256(JSON.stringify(lines));
15531
15537
  return { signature, text };
15532
15538
  }
15533
15539
  async function runAutoSync(opts) {
@@ -15538,6 +15544,9 @@ async function runAutoSync(opts) {
15538
15544
  try {
15539
15545
  reindexLock = acquireReindexLock(opts.caveatHome);
15540
15546
  if (!reindexLock) return { ran: false };
15547
+ const nowDate = (opts.now ?? (() => /* @__PURE__ */ new Date()))();
15548
+ const nowMs = nowDate.getTime();
15549
+ const nowIso = nowDate.toISOString();
15541
15550
  const previousState = readAutoSyncState(opts.caveatHome);
15542
15551
  let ownSyncState = previousState?.ownSync ?? {
15543
15552
  consecutiveFailureSignature: null,
@@ -15549,9 +15558,12 @@ async function runAutoSync(opts) {
15549
15558
  gitTimeoutMs: opts.gitTimeoutMs ?? BACKGROUND_GIT_TIMEOUT_MS
15550
15559
  });
15551
15560
  let own;
15552
- if (ownSyncState.consecutiveFailureCount >= 3) {
15561
+ const degraded = ownSyncState.consecutiveFailureCount >= AUTO_SYNC_SUSPEND_THRESHOLD;
15562
+ const retryDue = nowMs - parseTimestamp(ownSyncState.lastAttemptAt) >= AUTO_SYNC_DEGRADED_RETRY_MS;
15563
+ if (degraded && !retryDue) {
15553
15564
  own = { disposition: "skip", suspended: true };
15554
15565
  } else {
15566
+ ownSyncState = { ...ownSyncState, lastAttemptAt: nowIso };
15555
15567
  let lastProbe;
15556
15568
  try {
15557
15569
  const result = await syncOwn({
@@ -15582,23 +15594,27 @@ async function runAutoSync(opts) {
15582
15594
  const consecutiveFailureCount = ownSyncState.consecutiveFailureSignature === failureSignature ? ownSyncState.consecutiveFailureCount + 1 : 1;
15583
15595
  ownSyncState = {
15584
15596
  consecutiveFailureSignature: failureSignature,
15585
- consecutiveFailureCount
15597
+ consecutiveFailureCount,
15598
+ lastAttemptAt: nowIso
15586
15599
  };
15587
- if (consecutiveFailureCount === 3) own.escalated = true;
15600
+ if (consecutiveFailureCount === AUTO_SYNC_SUSPEND_THRESHOLD) own.escalated = true;
15588
15601
  }
15589
15602
  }
15590
15603
  }
15604
+ if (ownSyncState.consecutiveFailureCount >= AUTO_SYNC_SUSPEND_THRESHOLD) own.degraded = true;
15591
15605
  await reindexAndMark2(opts);
15592
15606
  const outcome = { community, own };
15593
15607
  const { signature, text } = autoSyncNotification(outcome);
15608
+ const repeatDue = own.degraded === true && nowMs - parseTimestamp(previousState?.lastNotifiedAt) >= AUTO_SYNC_NOTICE_REPEAT_MS;
15594
15609
  let notified = false;
15595
- if (text !== null && previousState?.signature !== signature) {
15610
+ if (text !== null && (previousState?.signature !== signature || repeatDue)) {
15596
15611
  appendGlobalPendingReminder(opts.caveatHome, text);
15597
15612
  notified = true;
15598
15613
  }
15599
15614
  writeAutoSyncState(opts.caveatHome, {
15600
- finishedAt: (opts.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
15615
+ finishedAt: nowIso,
15601
15616
  signature,
15617
+ lastNotifiedAt: notified ? nowIso : previousState?.lastNotifiedAt,
15602
15618
  ownSync: ownSyncState
15603
15619
  });
15604
15620
  return { ran: true, outcome, notified };
@@ -15620,6 +15636,35 @@ async function runAutoSync(opts) {
15620
15636
  }
15621
15637
  }
15622
15638
  }
15639
+ function triggerAutoSync(opts) {
15640
+ if (process.env[CAVEAT_AUTO_SYNC_ENV] === "off") return;
15641
+ const debounceMs = resolveTriggerDebounceMs(opts.debounceMs ?? AUTO_SYNC_DEBOUNCE_MS);
15642
+ const statePath = autoSyncStatePath(opts.caveatHome);
15643
+ try {
15644
+ if (existsSync9(statePath) && Date.now() - statSync6(statePath).mtimeMs < debounceMs) return;
15645
+ } catch {
15646
+ }
15647
+ if (!opts.cliScript) throw new Error("current Caveat CLI script path is unavailable");
15648
+ const child = spawn2(
15649
+ process.execPath,
15650
+ [...process.execArgv, "--disable-warning=ExperimentalWarning", opts.cliScript, "hook", "autosync"],
15651
+ { detached: true, stdio: "ignore", windowsHide: true }
15652
+ );
15653
+ child.unref();
15654
+ }
15655
+ function resolveTriggerDebounceMs(fallback) {
15656
+ const raw = process.env[CAVEAT_AUTO_SYNC_DEBOUNCE_ENV];
15657
+ if (raw === void 0) return fallback;
15658
+ const parsed = Number(raw);
15659
+ if (!Number.isFinite(parsed) || parsed < 0) {
15660
+ process.stderr.write(
15661
+ `[caveat] ${CAVEAT_AUTO_SYNC_DEBOUNCE_ENV}=${raw} is not a non-negative number; using ${fallback}ms
15662
+ `
15663
+ );
15664
+ return fallback;
15665
+ }
15666
+ return parsed;
15667
+ }
15623
15668
  async function reindexAndMark2(opts) {
15624
15669
  const keyProvider = createKeyserverKeyProvider({ caveatHome: opts.caveatHome });
15625
15670
  const failures = await prewarmSealedKeys({ paths: opts.paths, keyProvider });
@@ -15731,7 +15776,7 @@ function toSearchResult(row) {
15731
15776
  }
15732
15777
 
15733
15778
  // ../../packages/core/dist/paths.js
15734
- import { existsSync as existsSync9 } from "node:fs";
15779
+ import { existsSync as existsSync10 } from "node:fs";
15735
15780
  import { dirname as dirname6, isAbsolute, join as join10, resolve as resolve2 } from "node:path";
15736
15781
  import { fileURLToPath as fileURLToPath2 } from "node:url";
15737
15782
  function expandHome(p2, userHome) {
@@ -15763,7 +15808,7 @@ function resolvePaths(caveatHome, knowledgeRepo, userHome) {
15763
15808
  }
15764
15809
 
15765
15810
  // ../../packages/core/dist/config.js
15766
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "node:fs";
15811
+ import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "node:fs";
15767
15812
  var DEFAULT_CONFIG = {
15768
15813
  knowledgeRepo: "own",
15769
15814
  semverKeys: ["driver", "cuda", "node"],
@@ -15772,16 +15817,16 @@ var DEFAULT_CONFIG = {
15772
15817
  sealedKeyserverUrl: null
15773
15818
  };
15774
15819
  function loadConfig(userConfigPath) {
15775
- const userCfg = existsSync10(userConfigPath) ? JSON.parse(readFileSync8(userConfigPath, "utf-8")) : {};
15820
+ const userCfg = existsSync11(userConfigPath) ? JSON.parse(readFileSync8(userConfigPath, "utf-8")) : {};
15776
15821
  return deepMerge(DEFAULT_CONFIG, userCfg);
15777
15822
  }
15778
15823
  function ensureUserConfig(userConfigPath) {
15779
- if (!existsSync10(userConfigPath)) {
15824
+ if (!existsSync11(userConfigPath)) {
15780
15825
  writeFileSync6(userConfigPath, "{}\n", "utf-8");
15781
15826
  }
15782
15827
  }
15783
15828
  function writeUserConfigPatch(userConfigPath, patch) {
15784
- const existing = existsSync10(userConfigPath) ? JSON.parse(readFileSync8(userConfigPath, "utf-8")) : {};
15829
+ const existing = existsSync11(userConfigPath) ? JSON.parse(readFileSync8(userConfigPath, "utf-8")) : {};
15785
15830
  writeFileSync6(userConfigPath, `${JSON.stringify({ ...existing, ...patch }, null, 2)}
15786
15831
  `, "utf-8");
15787
15832
  }
@@ -16090,7 +16135,7 @@ function stopReminderText(signals, related) {
16090
16135
  }
16091
16136
 
16092
16137
  // ../../packages/core/dist/transcriptSignals.js
16093
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
16138
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
16094
16139
  var MAX_ERROR_SNIPPETS = 10;
16095
16140
  var MAX_ERROR_SNIPPET_LENGTH = 300;
16096
16141
  var MAX_SEARCH_QUERIES = 10;
@@ -16110,13 +16155,13 @@ function extractResultText(content) {
16110
16155
  }
16111
16156
  return "";
16112
16157
  }
16113
- function parseTimestamp(raw) {
16158
+ function parseTimestamp2(raw) {
16114
16159
  if (typeof raw !== "string") return void 0;
16115
16160
  const ms = Date.parse(raw);
16116
16161
  return Number.isNaN(ms) ? void 0 : ms;
16117
16162
  }
16118
16163
  function readSessionSignals(transcriptPath) {
16119
- if (!transcriptPath || !existsSync11(transcriptPath)) return null;
16164
+ if (!transcriptPath || !existsSync12(transcriptPath)) return null;
16120
16165
  let raw;
16121
16166
  try {
16122
16167
  raw = readFileSync9(transcriptPath, "utf-8");
@@ -16140,7 +16185,7 @@ function readSessionSignals(transcriptPath) {
16140
16185
  } catch {
16141
16186
  continue;
16142
16187
  }
16143
- const ts = parseTimestamp(parsed.timestamp);
16188
+ const ts = parseTimestamp2(parsed.timestamp);
16144
16189
  if (ts !== void 0) {
16145
16190
  if (firstTs === void 0 || ts < firstTs) firstTs = ts;
16146
16191
  if (lastTs === void 0 || ts > lastTs) lastTs = ts;
@@ -16200,7 +16245,7 @@ function struggleSearchText(s) {
16200
16245
  }
16201
16246
 
16202
16247
  // ../../packages/core/dist/codexTranscriptSignals.js
16203
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
16248
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "node:fs";
16204
16249
  var MAX_ERROR_SNIPPETS2 = 10;
16205
16250
  var MAX_ERROR_SNIPPET_LENGTH2 = 300;
16206
16251
  var MAX_SEARCH_QUERIES2 = 10;
@@ -16209,7 +16254,7 @@ var MAX_FILE_EDIT_ENTRIES2 = 20;
16209
16254
  function isRecord2(v) {
16210
16255
  return typeof v === "object" && v !== null && !Array.isArray(v);
16211
16256
  }
16212
- function parseTimestamp2(raw) {
16257
+ function parseTimestamp3(raw) {
16213
16258
  if (typeof raw !== "string") return void 0;
16214
16259
  const ms = Date.parse(raw);
16215
16260
  return Number.isNaN(ms) ? void 0 : ms;
@@ -16265,7 +16310,7 @@ function addQuery(searchQueries, query) {
16265
16310
  searchQueries.push(query.slice(0, MAX_SEARCH_QUERY_LENGTH2));
16266
16311
  }
16267
16312
  function readCodexSessionSignals(transcriptPath) {
16268
- if (!transcriptPath || !existsSync12(transcriptPath)) return null;
16313
+ if (!transcriptPath || !existsSync13(transcriptPath)) return null;
16269
16314
  let raw;
16270
16315
  try {
16271
16316
  raw = readFileSync10(transcriptPath, "utf-8");
@@ -16291,7 +16336,7 @@ function readCodexSessionSignals(transcriptPath) {
16291
16336
  } catch {
16292
16337
  continue;
16293
16338
  }
16294
- const ts = parseTimestamp2(parsed.timestamp);
16339
+ const ts = parseTimestamp3(parsed.timestamp);
16295
16340
  if (ts !== void 0) {
16296
16341
  if (firstTs === void 0 || ts < firstTs) firstTs = ts;
16297
16342
  if (lastTs === void 0 || ts > lastTs) lastTs = ts;
@@ -16383,7 +16428,7 @@ function markHit(db, keys, now2 = () => (/* @__PURE__ */ new Date()).toISOString
16383
16428
  }
16384
16429
 
16385
16430
  // ../../packages/core/dist/hookQueryLog.js
16386
- import { appendFileSync, chmodSync as chmodSync2, mkdirSync as mkdirSync7, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync3 } from "node:fs";
16431
+ import { appendFileSync, chmodSync as chmodSync2, mkdirSync as mkdirSync7, renameSync as renameSync4, statSync as statSync7, unlinkSync as unlinkSync3 } from "node:fs";
16387
16432
  import { join as join11, resolve as resolve3 } from "node:path";
16388
16433
  var CAVEAT_HOOK_QUERY_LOG_ENV = "CAVEAT_HOOK_QUERY_LOG";
16389
16434
  var HOOK_QUERY_LOG_MAX_BYTES = 1024 * 1024;
@@ -16393,7 +16438,7 @@ var fsDependencies = {
16393
16438
  chmodSync: chmodSync2,
16394
16439
  mkdirSync: mkdirSync7,
16395
16440
  renameSync: renameSync4,
16396
- statSync: statSync6,
16441
+ statSync: statSync7,
16397
16442
  unlinkSync: unlinkSync3
16398
16443
  };
16399
16444
  function isMissingPathError(err) {
@@ -16481,7 +16526,7 @@ function listStale(db, opts = {}) {
16481
16526
 
16482
16527
  // ../../packages/core/dist/publishScan.js
16483
16528
  import { createHash as createHash5 } from "node:crypto";
16484
- import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "node:fs";
16529
+ import { existsSync as existsSync14, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "node:fs";
16485
16530
  import { join as join12, basename as basename2 } from "node:path";
16486
16531
  import { homedir as homedir2, userInfo as userInfo2 } from "node:os";
16487
16532
  var ALLOW_FILE = ".caveat-publish-allow.json";
@@ -16712,7 +16757,7 @@ function publishSelfIdentityTokens() {
16712
16757
  }
16713
16758
  function loadPublishAllow(knowledgeRepo) {
16714
16759
  const path = join12(knowledgeRepo, ALLOW_FILE);
16715
- if (!existsSync13(path)) return /* @__PURE__ */ new Set();
16760
+ if (!existsSync14(path)) return /* @__PURE__ */ new Set();
16716
16761
  const parsed = JSON.parse(readFileSync11(path, "utf-8"));
16717
16762
  if (!Array.isArray(parsed.allow)) throw new Error(`${ALLOW_FILE} must contain an "allow" array`);
16718
16763
  return new Set(parsed.allow.filter((value) => typeof value === "string" && DIGEST_RE.test(value)));
@@ -16742,7 +16787,7 @@ var PublishScanError = class extends Error {
16742
16787
 
16743
16788
  // ../../packages/core/dist/publish.js
16744
16789
  import { createHash as createHash6 } from "node:crypto";
16745
- import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync12, readdirSync as readdirSync8, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
16790
+ import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync12, readdirSync as readdirSync8, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "node:fs";
16746
16791
  import { dirname as dirname7, join as join13, relative as relative3 } from "node:path";
16747
16792
 
16748
16793
  // ../../packages/core/dist/visibility.js
@@ -16758,7 +16803,7 @@ var TMP_BRANCH = "caveat-publish-tmp";
16758
16803
  function collectPublishSet(entriesDir) {
16759
16804
  const files = [];
16760
16805
  const invalid = [];
16761
- if (!existsSync14(entriesDir)) return { files, invalid };
16806
+ if (!existsSync15(entriesDir)) return { files, invalid };
16762
16807
  for (const path of walkMarkdown(entriesDir)) {
16763
16808
  const relPath = relative3(entriesDir, path).replace(/\\/g, "/");
16764
16809
  const content = readFileSync12(path);
@@ -16779,7 +16824,7 @@ function collectPublishSet(entriesDir) {
16779
16824
  }
16780
16825
  async function preparePublishMirror(opts) {
16781
16826
  const git = opts.git ?? createGit();
16782
- if (!existsSync14(opts.mirrorDir)) {
16827
+ if (!existsSync15(opts.mirrorDir)) {
16783
16828
  mkdirSync8(dirname7(opts.mirrorDir), { recursive: true });
16784
16829
  await git.clone(opts.target, opts.mirrorDir);
16785
16830
  } else {
@@ -16952,8 +16997,8 @@ function readExistingMirror(mirrorDir) {
16952
16997
  const readmePath = join13(mirrorDir, "README.md");
16953
16998
  const bundlePath = join13(mirrorDir, BUNDLE_RELPATH);
16954
16999
  return {
16955
- readme: existsSync14(readmePath) ? readFileSync12(readmePath, "utf-8") : null,
16956
- bundle: existsSync14(bundlePath) ? readFileSync12(bundlePath) : null
17000
+ readme: existsSync15(readmePath) ? readFileSync12(readmePath, "utf-8") : null,
17001
+ bundle: existsSync15(bundlePath) ? readFileSync12(bundlePath) : null
16957
17002
  };
16958
17003
  }
16959
17004
  async function publishOwn(opts) {
@@ -17244,7 +17289,7 @@ function boundedCount(value) {
17244
17289
  // ../../packages/core/dist/runtimeErrors.js
17245
17290
  import { spawnSync } from "node:child_process";
17246
17291
  import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
17247
- import { closeSync as closeSync2, constants, existsSync as existsSync15, fstatSync, lstatSync, mkdirSync as mkdirSync9, openSync as openSync2, readFileSync as readFileSync13, renameSync as renameSync5, rmSync as rmSync6, statSync as statSync7, writeFileSync as writeFileSync9 } from "node:fs";
17292
+ import { closeSync as closeSync2, constants, existsSync as existsSync16, fstatSync, lstatSync, mkdirSync as mkdirSync9, openSync as openSync2, readFileSync as readFileSync13, renameSync as renameSync5, rmSync as rmSync6, statSync as statSync8, writeFileSync as writeFileSync9 } from "node:fs";
17248
17293
  import { arch as hostArch, homedir as homedir3, platform as hostPlatform } from "node:os";
17249
17294
  import { dirname as dirname8, join as join14 } from "node:path";
17250
17295
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
@@ -17311,7 +17356,7 @@ function fingerprint(code) {
17311
17356
  return createHash7("sha256").update(`caveat\0${d.component}\0${code}\0${d.template}`).digest("hex");
17312
17357
  }
17313
17358
  function ensureSafeDir(dir, isWin, options2 = {}) {
17314
- const existed = existsSync15(dir);
17359
+ const existed = existsSync16(dir);
17315
17360
  mkdirSync9(dir, { recursive: true, mode: 448 });
17316
17361
  const s = lstatSync(dir);
17317
17362
  if (!s.isDirectory() || s.isSymbolicLink()) throw Error("store_unsafe");
@@ -17333,9 +17378,11 @@ function canonicalReporting(value) {
17333
17378
  }
17334
17379
  var WINDOWS_ACL_VERIFY = String.raw`$p=$env:CAVEAT_ACL_PATH;$isDir=$env:CAVEAT_ACL_DIRECTORY -eq '1';$sid=[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value;$acl=if($isDir){[System.IO.Directory]::GetAccessControl($p)}else{[System.IO.File]::GetAccessControl($p)};$owner=$acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value;if($owner -ne $sid){exit 41};$rules=@($acl.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]));if($rules.Count -ne 1){exit 42};$r=$rules[0];if($r.IdentityReference.Value -ne $sid -or $r.AccessControlType -ne 'Allow' -or $r.IsInherited -or ($r.FileSystemRights -band [System.Security.AccessControl.FileSystemRights]::FullControl) -ne [System.Security.AccessControl.FileSystemRights]::FullControl){exit 43}`;
17335
17380
  var WINDOWS_ACL_APPLY = String.raw`$p=$env:CAVEAT_ACL_PATH;$isDir=$env:CAVEAT_ACL_DIRECTORY -eq '1';$sid=[System.Security.Principal.WindowsIdentity]::GetCurrent().User;$acl=if($isDir){New-Object System.Security.AccessControl.DirectorySecurity}else{New-Object System.Security.AccessControl.FileSecurity};$acl.SetAccessRuleProtection($true,$false);$flags=if($isDir){[System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit'}else{[System.Security.AccessControl.InheritanceFlags]::None};$rule=New-Object System.Security.AccessControl.FileSystemAccessRule($sid,'FullControl',$flags,[System.Security.AccessControl.PropagationFlags]::None,[System.Security.AccessControl.AccessControlType]::Allow);$acl.SetOwner($sid);$acl.AddAccessRule($rule);if($isDir){[System.IO.Directory]::SetAccessControl($p,$acl)}else{[System.IO.File]::SetAccessControl($p,$acl)};` + WINDOWS_ACL_VERIFY;
17381
+ var WINDOWS_ACL_TIMEOUT_MS = 15e3;
17336
17382
  function runWindowsAcl(path, directory, apply) {
17337
- const result = spawnSync("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", apply ? WINDOWS_ACL_APPLY : WINDOWS_ACL_VERIFY], { env: { ...process.env, CAVEAT_ACL_PATH: path, CAVEAT_ACL_DIRECTORY: directory ? "1" : "0" }, stdio: "ignore", timeout: 3e3, windowsHide: true });
17338
- if (result.status !== 0) throw Error("store_unsafe");
17383
+ const result = spawnSync("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", apply ? WINDOWS_ACL_APPLY : WINDOWS_ACL_VERIFY], { env: { ...process.env, CAVEAT_ACL_PATH: path, CAVEAT_ACL_DIRECTORY: directory ? "1" : "0" }, encoding: "utf-8", timeout: WINDOWS_ACL_TIMEOUT_MS, windowsHide: true });
17384
+ if (result.error !== void 0) throw Error(`store_unsafe: powershell spawn ${result.error.code ?? result.error.message}`);
17385
+ if (result.status !== 0) throw Error(`store_unsafe: powershell exit=${result.status} signal=${result.signal ?? "none"} stderr=${(result.stderr ?? "").replace(/\s+/g, " ").trim().slice(0, 400) || "(empty)"}`);
17339
17386
  }
17340
17387
  function secureWindowsAcl(path, runner, directory = false, apply = false) {
17341
17388
  try {
@@ -17351,7 +17398,7 @@ function ensureSafeFile(path, isWin, options2 = {}) {
17351
17398
  const s = lstatSync(path);
17352
17399
  if (!s.isFile() || s.isSymbolicLink()) throw Error("store_unsafe");
17353
17400
  if (isWin) secureWindowsAcl(path, options2.aclRunner);
17354
- else assertPosix(statSync7(path), 384);
17401
+ else assertPosix(statSync8(path), 384);
17355
17402
  }
17356
17403
  function validate(store) {
17357
17404
  if (!plain(store) || !exact(store, ["schema", "next_sequence", "acknowledged_through", "records"])) throw Error("state_invalid");
@@ -17369,7 +17416,7 @@ function validate(store) {
17369
17416
  }
17370
17417
  }
17371
17418
  function readStore(path, isWin, options2 = {}) {
17372
- if (!existsSync15(path)) return empty();
17419
+ if (!existsSync16(path)) return empty();
17373
17420
  ensureSafeFile(path, isWin, options2);
17374
17421
  const value = JSON.parse(readFileSync13(path, "utf8"));
17375
17422
  validate(value);
@@ -17387,7 +17434,7 @@ function lock(path, isWin, fn, options2 = {}) {
17387
17434
  }
17388
17435
  if (created) {
17389
17436
  if (isWin) secureWindowsAcl(lockPath2, options2.aclRunner, false, true);
17390
- else assertPosix(statSync7(lockPath2), 384);
17437
+ else assertPosix(statSync8(lockPath2), 384);
17391
17438
  } else ensureSafeFile(lockPath2, isWin, options2);
17392
17439
  const db = new DatabaseSync3(lockPath2);
17393
17440
  let begun = false;
@@ -17415,7 +17462,7 @@ function writeStore(path, store, isWin, options2 = {}) {
17415
17462
  writeFileSync9(temporary, `${JSON.stringify(store)}
17416
17463
  `, { mode: 384, flag: "wx" });
17417
17464
  if (isWin) secureWindowsAcl(temporary, options2.aclRunner, false, true);
17418
- else assertPosix(statSync7(temporary), 384);
17465
+ else assertPosix(statSync8(temporary), 384);
17419
17466
  renameSync5(temporary, path);
17420
17467
  ensureSafeFile(path, isWin, options2);
17421
17468
  } finally {
@@ -17592,7 +17639,7 @@ function generateSourceSession(now2 = () => /* @__PURE__ */ new Date()) {
17592
17639
  }
17593
17640
 
17594
17641
  // ../../packages/core/dist/writer.js
17595
- import { existsSync as existsSync16, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
17642
+ import { existsSync as existsSync17, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "node:fs";
17596
17643
  import { dirname as dirname9 } from "node:path";
17597
17644
  function buildEntry(frontmatter, sections) {
17598
17645
  const bodyParts = [];
@@ -17612,12 +17659,12 @@ ${body}${body ? "\n" : ""}`;
17612
17659
  }
17613
17660
  function writeEntryFile(filePath, content) {
17614
17661
  const dir = dirname9(filePath);
17615
- if (!existsSync16(dir)) mkdirSync10(dir, { recursive: true });
17662
+ if (!existsSync17(dir)) mkdirSync10(dir, { recursive: true });
17616
17663
  writeFileSync10(filePath, content, "utf-8");
17617
17664
  }
17618
17665
 
17619
17666
  // ../../packages/core/dist/record.js
17620
- import { statSync as statSync8 } from "node:fs";
17667
+ import { statSync as statSync9 } from "node:fs";
17621
17668
  import { join as join15 } from "node:path";
17622
17669
  var DEFAULT_CATEGORY = "misc";
17623
17670
  function recordEntry(input, opts) {
@@ -17656,7 +17703,7 @@ function recordEntry(input, opts) {
17656
17703
  const relPath = `${category}/${id}.md`;
17657
17704
  const filePath = join15(opts.entriesRoot, relPath);
17658
17705
  writeEntryFile(filePath, built.content);
17659
- const stat = statSync8(filePath);
17706
+ const stat = statSync9(filePath);
17660
17707
  upsertEntry(opts.db, {
17661
17708
  id,
17662
17709
  source,
@@ -17684,7 +17731,7 @@ function formatYmd(d) {
17684
17731
  }
17685
17732
 
17686
17733
  // ../../packages/core/dist/update.js
17687
- import { readFileSync as readFileSync14, statSync as statSync9, writeFileSync as writeFileSync11 } from "node:fs";
17734
+ import { readFileSync as readFileSync14, statSync as statSync10, writeFileSync as writeFileSync11 } from "node:fs";
17688
17735
  import { join as join16 } from "node:path";
17689
17736
  var IMMUTABLE_KEYS = /* @__PURE__ */ new Set([
17690
17737
  "id",
@@ -17747,7 +17794,7 @@ function updateEntry(id, patch, opts) {
17747
17794
  }
17748
17795
  const built = buildEntry(mergedFrontmatter, mergedSections);
17749
17796
  writeFileSync11(filePath, built.content, "utf-8");
17750
- const stat = statSync9(filePath);
17797
+ const stat = statSync10(filePath);
17751
17798
  upsertEntry(opts.db, {
17752
17799
  id,
17753
17800
  source,
@@ -17810,9 +17857,11 @@ export {
17810
17857
  KNOWLEDGE_GITIGNORE,
17811
17858
  initOwnSync,
17812
17859
  AUTO_SYNC_DEBOUNCE_MS,
17860
+ AUTO_SYNC_RECORD_DEBOUNCE_MS,
17813
17861
  CAVEAT_AUTO_SYNC_ENV,
17814
17862
  resetAutoSyncFailureState,
17815
17863
  runAutoSync,
17864
+ triggerAutoSync,
17816
17865
  search,
17817
17866
  get,
17818
17867
  listRecent,
@@ -17872,4 +17921,4 @@ strip-bom-string/index.js:
17872
17921
  js-yaml/dist/js-yaml.mjs:
17873
17922
  (*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
17874
17923
  */
17875
- //# sourceMappingURL=chunk-PD5E6TFL.js.map
17924
+ //# sourceMappingURL=chunk-7FEOFAMA.js.map