skillwiki 0.10.81 → 0.10.82

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.
@@ -6,7 +6,7 @@ import {
6
6
  readPage,
7
7
  scanSensitiveContent,
8
8
  splitFrontmatter
9
- } from "./chunk-HJ4ALQG6.js";
9
+ } from "./chunk-XJR3XXP5.js";
10
10
 
11
11
  // src/utils/vault-path-safety.ts
12
12
  import { lstatSync, realpathSync } from "fs";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  atomicWriteText,
4
4
  buildRootIndexUniverse
5
- } from "./chunk-BPJ5KWIT.js";
5
+ } from "./chunk-JHDN3FSF.js";
6
6
  import {
7
7
  authorizeRawOperation,
8
8
  buildSourceReferenceIndex,
@@ -22,7 +22,7 @@ import {
22
22
  resolveExistingRegularFileInsideVault,
23
23
  stripFencedBlocks,
24
24
  writeLogEvent
25
- } from "./chunk-OMO45AHI.js";
25
+ } from "./chunk-5BNCYHRN.js";
26
26
  import {
27
27
  ExitCode,
28
28
  FleetManifestSchema,
@@ -41,7 +41,7 @@ import {
41
41
  scanVault,
42
42
  splitFrontmatter,
43
43
  vaultIoConcurrency
44
- } from "./chunk-HJ4ALQG6.js";
44
+ } from "./chunk-XJR3XXP5.js";
45
45
 
46
46
  // src/utils/managed-write-preflight.ts
47
47
  import { existsSync as existsSync11 } from "fs";
@@ -8,7 +8,7 @@ import {
8
8
  readLogEvents,
9
9
  resolveExistingRegularFileInsideVault,
10
10
  writeLogEvent
11
- } from "./chunk-OMO45AHI.js";
11
+ } from "./chunk-5BNCYHRN.js";
12
12
  import {
13
13
  ExitCode,
14
14
  RawSourceSchema,
@@ -19,7 +19,7 @@ import {
19
19
  scanSensitiveContent,
20
20
  scanVault,
21
21
  splitFrontmatter
22
- } from "./chunk-HJ4ALQG6.js";
22
+ } from "./chunk-XJR3XXP5.js";
23
23
 
24
24
  // src/commands/sources.ts
25
25
  import { readFile as readFile4 } from "fs/promises";
@@ -8,7 +8,7 @@ import {
8
8
  ok,
9
9
  scanSensitiveContent,
10
10
  scanVault
11
- } from "./chunk-HJ4ALQG6.js";
11
+ } from "./chunk-XJR3XXP5.js";
12
12
 
13
13
  // src/utils/atomic-write.ts
14
14
  import { randomBytes } from "crypto";
@@ -389,6 +389,7 @@ var VaultSyncConfigSchema = z.object({
389
389
  "vault_sync.snapshot_profile": vaultSyncPathOrNone,
390
390
  "vault_sync.snapshot_script": vaultSyncPathOrNone,
391
391
  "vault_sync.snapshot_worktree": vaultSyncPathOrNone,
392
+ "vault_sync.push_enabled": vaultSyncBool,
392
393
  "vault_sync.fuse_refresh_enabled": vaultSyncBool,
393
394
  "vault_sync.fuse_refresh_interval": vaultSyncDuration,
394
395
  "vault_sync.fuse_max_dir_cache": vaultSyncDuration,
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  renderRootIndex,
8
8
  writeRootIndexProjection
9
- } from "./chunk-KFEOMMWK.js";
9
+ } from "./chunk-ZUHA2EXE.js";
10
10
  import {
11
11
  CONFIG_KEYS,
12
12
  VAULT_HYGIENE_GENERATED_COMMIT_PATHS,
@@ -40,11 +40,11 @@ import {
40
40
  snapshotterAliasForLocalHost,
41
41
  toUndirectedWeighted,
42
42
  writeDotenv
43
- } from "./chunk-GPUK2IAW.js";
43
+ } from "./chunk-BO7JIJIA.js";
44
44
  import {
45
45
  atomicWriteText,
46
46
  prepareTypedPage
47
- } from "./chunk-BPJ5KWIT.js";
47
+ } from "./chunk-JHDN3FSF.js";
48
48
  import {
49
49
  applySourceCompileClaim,
50
50
  applySourceCompilePublished,
@@ -57,11 +57,11 @@ import {
57
57
  planSourceCompileRelease,
58
58
  planSourceReview,
59
59
  runSourcesPending
60
- } from "./chunk-NPTIYO2S.js";
60
+ } from "./chunk-CGQQS7MO.js";
61
61
  import {
62
62
  eventPathFor,
63
63
  writeLogEvent
64
- } from "./chunk-OMO45AHI.js";
64
+ } from "./chunk-5BNCYHRN.js";
65
65
  import {
66
66
  CompoundSchema,
67
67
  ExitCode,
@@ -82,7 +82,7 @@ import {
82
82
  scanVault,
83
83
  splitFrontmatter,
84
84
  systemdPropertyFor
85
- } from "./chunk-HJ4ALQG6.js";
85
+ } from "./chunk-XJR3XXP5.js";
86
86
 
87
87
  // src/commands/log-append.ts
88
88
  import { readFile, stat } from "fs/promises";
@@ -2394,11 +2394,14 @@ function checkRcloneFlagAudit(resolvedPath) {
2394
2394
  }
2395
2395
  return check("pass", "rclone_flags", "rclone VFS flags", `PID ${pid}: all critical flags at safe values`);
2396
2396
  }
2397
- function checkRcloneVersion(resolvedPath, vaultSyncInstalled) {
2397
+ function checkRcloneVersion(resolvedPath, vaultSyncInstalled, pushEnabled = true) {
2398
+ const fuse = resolvedPath ? detectFuseMount(resolvedPath) : null;
2399
+ if (pushEnabled === false && !fuse) {
2400
+ return check("pass", "rclone_version", "rclone version", "push not required \u2014 check skipped");
2401
+ }
2398
2402
  if (!resolvedPath && !vaultSyncInstalled) {
2399
2403
  return check("pass", "rclone_version", "rclone version", "No vault path \u2014 check skipped");
2400
2404
  }
2401
- const fuse = resolvedPath ? detectFuseMount(resolvedPath) : null;
2402
2405
  if (!fuse && !vaultSyncInstalled) {
2403
2406
  return check("pass", "rclone_version", "rclone version", "local disk \u2014 check skipped");
2404
2407
  }
@@ -2518,7 +2521,7 @@ var s3MountHealthProbe = {
2518
2521
  checkS3MountPerf(ctx.resolvedPath),
2519
2522
  checkS3MountFreshness(ctx.resolvedPath),
2520
2523
  checkRcloneFlagAudit(ctx.resolvedPath),
2521
- checkRcloneVersion(ctx.resolvedPath, ctx.vsConfig.installed),
2524
+ checkRcloneVersion(ctx.resolvedPath, ctx.vsConfig.installed, ctx.vsConfig.pushEnabled !== false),
2522
2525
  checkWriteTest(ctx.resolvedPath),
2523
2526
  checkVfsCacheHealth(ctx.resolvedPath)
2524
2527
  ];
@@ -2802,6 +2805,7 @@ function readVaultSyncConfig(home) {
2802
2805
  let role;
2803
2806
  let serviceScope;
2804
2807
  let snapshotScript;
2808
+ let pushEnabled;
2805
2809
  for (const line of content.split(/\r?\n/)) {
2806
2810
  const trimmed = line.trim();
2807
2811
  if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
@@ -2814,8 +2818,9 @@ function readVaultSyncConfig(home) {
2814
2818
  if (k === "vault_sync.role") role = v;
2815
2819
  if (k === "vault_sync.service_scope") serviceScope = v;
2816
2820
  if (k === "vault_sync.snapshot_script") snapshotScript = v;
2821
+ if (k === "vault_sync.push_enabled" && v === "false") pushEnabled = false;
2817
2822
  }
2818
- return { installed, role, serviceScope, snapshotScript };
2823
+ return { installed, role, serviceScope, snapshotScript, pushEnabled };
2819
2824
  } catch {
2820
2825
  return { installed: false };
2821
2826
  }
@@ -3139,6 +3144,125 @@ function snapshotterHealthChecks(scope, logDir, env) {
3139
3144
  const consecutiveFailures = failureStreak.count >= 2 ? check("error", "vault_sync_snapshot_consecutive_failures", "Vault sync snapshot consecutive failures", consecutiveSnapshotFailureDetail(failureStreak)) : check("pass", "vault_sync_snapshot_consecutive_failures", "Vault sync snapshot consecutive failures", consecutiveSnapshotFailureDetail(failureStreak));
3140
3145
  return [jobs, serviceResult, freshness, consecutiveFailures];
3141
3146
  }
3147
+ var PUSH_NOT_IN_PROFILE = "push not part of host profile";
3148
+ function checkLastFetchStatus(fetchLogFile) {
3149
+ try {
3150
+ const logContent = readFileSync8(fetchLogFile, "utf8");
3151
+ const lines = logContent.trim().split("\n").filter(Boolean);
3152
+ if (lines.length === 0) {
3153
+ return check(
3154
+ "warn",
3155
+ "vault_sync_last_fetch_status",
3156
+ "Vault sync last fetch status",
3157
+ "Fetch log file is empty"
3158
+ );
3159
+ }
3160
+ const lastLine = lines[lines.length - 1];
3161
+ if (/fetch failed/i.test(lastLine)) {
3162
+ return check(
3163
+ "error",
3164
+ "vault_sync_last_fetch_status",
3165
+ "Vault sync last fetch status",
3166
+ `Last fetch failed: ${lastLine.slice(0, 100)}`
3167
+ );
3168
+ }
3169
+ if (/OK/.test(lastLine)) {
3170
+ return check(
3171
+ "pass",
3172
+ "vault_sync_last_fetch_status",
3173
+ "Vault sync last fetch status",
3174
+ lastLine.slice(0, 100)
3175
+ );
3176
+ }
3177
+ return check(
3178
+ "warn",
3179
+ "vault_sync_last_fetch_status",
3180
+ "Vault sync last fetch status",
3181
+ `Last fetch log entry: ${lastLine.slice(0, 80)}`
3182
+ );
3183
+ } catch {
3184
+ return check(
3185
+ "warn",
3186
+ "vault_sync_last_fetch_status",
3187
+ "Vault sync last fetch status",
3188
+ `Fetch log not found at ${fetchLogFile}`
3189
+ );
3190
+ }
3191
+ }
3192
+ function checkLeafFetchScheduler(isMac, env) {
3193
+ const fixture = env.VS_LEAF_SCHEDULER_FIXTURE;
3194
+ if (fixture === "enabled") {
3195
+ return check(
3196
+ "pass",
3197
+ "vault_sync_jobs_enabled",
3198
+ "Vault sync jobs enabled",
3199
+ isMac ? "launchd: com.karlchow.wiki-fetch loaded" : "systemd: wiki-fetch.timer enabled"
3200
+ );
3201
+ }
3202
+ if (fixture === "disabled") {
3203
+ return check(
3204
+ "error",
3205
+ "vault_sync_jobs_enabled",
3206
+ "Vault sync jobs enabled",
3207
+ isMac ? "launchd: com.karlchow.wiki-fetch not loaded \u2014 enable wiki-fetch" : "systemd: wiki-fetch.timer is disabled \u2014 enable wiki-fetch.timer"
3208
+ );
3209
+ }
3210
+ if (fixture === "missing") {
3211
+ return check(
3212
+ "error",
3213
+ "vault_sync_jobs_enabled",
3214
+ "Vault sync jobs enabled",
3215
+ "Scheduler check failed \u2014 enable wiki-fetch"
3216
+ );
3217
+ }
3218
+ try {
3219
+ if (isMac) {
3220
+ const uidStr = execSync5("id -u", {
3221
+ encoding: "utf8",
3222
+ timeout: 2e3,
3223
+ stdio: ["pipe", "pipe", "pipe"]
3224
+ }).trim();
3225
+ const uid = parseInt(uidStr, 10);
3226
+ execSync5(`launchctl print gui/${uid}/com.karlchow.wiki-fetch`, {
3227
+ encoding: "utf8",
3228
+ timeout: 2e3,
3229
+ stdio: ["pipe", "ignore", "ignore"]
3230
+ });
3231
+ return check(
3232
+ "pass",
3233
+ "vault_sync_jobs_enabled",
3234
+ "Vault sync jobs enabled",
3235
+ "launchd: com.karlchow.wiki-fetch loaded"
3236
+ );
3237
+ }
3238
+ const out = execSync5("systemctl --user is-enabled wiki-fetch.timer", {
3239
+ encoding: "utf8",
3240
+ timeout: 2e3,
3241
+ stdio: ["pipe", "pipe", "pipe"]
3242
+ }).trim();
3243
+ if (out === "enabled") {
3244
+ return check(
3245
+ "pass",
3246
+ "vault_sync_jobs_enabled",
3247
+ "Vault sync jobs enabled",
3248
+ "systemd: wiki-fetch.timer enabled"
3249
+ );
3250
+ }
3251
+ return check(
3252
+ "error",
3253
+ "vault_sync_jobs_enabled",
3254
+ "Vault sync jobs enabled",
3255
+ `systemd: wiki-fetch.timer is ${out} \u2014 enable wiki-fetch.timer`
3256
+ );
3257
+ } catch {
3258
+ return check(
3259
+ "error",
3260
+ "vault_sync_jobs_enabled",
3261
+ "Vault sync jobs enabled",
3262
+ "Scheduler check failed \u2014 enable wiki-fetch"
3263
+ );
3264
+ }
3265
+ }
3142
3266
  function vaultSyncChecks(input) {
3143
3267
  const os = input.os ?? platform3();
3144
3268
  const home = input.home;
@@ -3217,6 +3341,44 @@ function vaultSyncChecks(input) {
3217
3341
  }
3218
3342
  return [c12, ...healthChecks, cFetch2, c42, c52];
3219
3343
  }
3344
+ const env = input.env ?? process.env;
3345
+ const fetchLogFile = join15(logDir, "wiki-fetch.log");
3346
+ if (input.pushEnabled === false) {
3347
+ const fetchHelperPath = join15(shareDir, "wiki-fetch-notify.sh");
3348
+ const c12 = existsSync12(fetchHelperPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found: ${fetchHelperPath}`) : check(
3349
+ "error",
3350
+ "vault_sync_installed",
3351
+ "Vault sync installed",
3352
+ `Fetch helper not found at ${fetchHelperPath}`
3353
+ );
3354
+ const c22 = checkLeafFetchScheduler(isMac, env);
3355
+ const c32 = check(
3356
+ "pass",
3357
+ "vault_sync_last_push_age",
3358
+ "Vault sync last push recency",
3359
+ PUSH_NOT_IN_PROFILE
3360
+ );
3361
+ const cPushResult2 = check(
3362
+ "pass",
3363
+ "vault_sync_last_push_result",
3364
+ "Vault sync last push result",
3365
+ PUSH_NOT_IN_PROFILE
3366
+ );
3367
+ const cFetch2 = checkLastFetchStatus(fetchLogFile);
3368
+ const c42 = check(
3369
+ "pass",
3370
+ "vault_sync_filter_present",
3371
+ "Vault sync filter file present",
3372
+ PUSH_NOT_IN_PROFILE
3373
+ );
3374
+ const c52 = check(
3375
+ "pass",
3376
+ "vault_sync_snapshot_guard",
3377
+ "Snapshot script guard",
3378
+ "Not a snapshotter host \u2014 check skipped"
3379
+ );
3380
+ return [c12, c22, c32, cPushResult2, cFetch2, c42, c52];
3381
+ }
3220
3382
  const pushScriptPath = join15(shareDir, "wiki-push.sh");
3221
3383
  const c1 = existsSync12(pushScriptPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found: ${pushScriptPath}`) : check("error", "vault_sync_installed", "Vault sync installed", `Script not found at ${pushScriptPath} \u2014 run vault-sync-install`);
3222
3384
  let c2;
@@ -3321,51 +3483,7 @@ function vaultSyncChecks(input) {
3321
3483
  `result=refused reason=${pushState.reason ?? ""} timestamp=${pushState.timestamp ?? ""}`
3322
3484
  );
3323
3485
  }
3324
- const fetchLogFile = join15(logDir, "wiki-fetch.log");
3325
- let cFetch;
3326
- try {
3327
- const logContent = readFileSync8(fetchLogFile, "utf8");
3328
- const lines = logContent.trim().split("\n").filter(Boolean);
3329
- if (lines.length === 0) {
3330
- cFetch = check(
3331
- "warn",
3332
- "vault_sync_last_fetch_status",
3333
- "Vault sync last fetch status",
3334
- "Fetch log file is empty"
3335
- );
3336
- } else {
3337
- const lastLine = lines[lines.length - 1];
3338
- if (/fetch failed/i.test(lastLine)) {
3339
- cFetch = check(
3340
- "error",
3341
- "vault_sync_last_fetch_status",
3342
- "Vault sync last fetch status",
3343
- `Last fetch failed: ${lastLine.slice(0, 100)}`
3344
- );
3345
- } else if (/OK/.test(lastLine)) {
3346
- cFetch = check(
3347
- "pass",
3348
- "vault_sync_last_fetch_status",
3349
- "Vault sync last fetch status",
3350
- lastLine.slice(0, 100)
3351
- );
3352
- } else {
3353
- cFetch = check(
3354
- "warn",
3355
- "vault_sync_last_fetch_status",
3356
- "Vault sync last fetch status",
3357
- `Last fetch log entry: ${lastLine.slice(0, 80)}`
3358
- );
3359
- }
3360
- }
3361
- } catch {
3362
- cFetch = check(
3363
- "warn",
3364
- "vault_sync_last_fetch_status",
3365
- "Vault sync last fetch status",
3366
- `Fetch log not found at ${fetchLogFile}`
3367
- );
3368
- }
3486
+ const cFetch = checkLastFetchStatus(fetchLogFile);
3369
3487
  let c4;
3370
3488
  try {
3371
3489
  if (!existsSync12(filterPath)) {
@@ -3538,6 +3656,7 @@ var vaultSyncProbe = {
3538
3656
  vaultSyncInstalled: ctx.vsConfig.installed,
3539
3657
  vaultSyncRole: ctx.vsConfig.role,
3540
3658
  vaultSyncServiceScope: ctx.vsConfig.serviceScope,
3659
+ pushEnabled: ctx.vsConfig.pushEnabled,
3541
3660
  snapshotScriptPath: ctx.vsConfig.snapshotScript,
3542
3661
  env: ctx.input.env ?? process.env
3543
3662
  }));
@@ -6332,7 +6451,7 @@ async function runQuery(input) {
6332
6451
  }
6333
6452
  let pendingSources;
6334
6453
  if (input.includePending) {
6335
- const { runSourcesPending: runSourcesPending2 } = await import("./sources-C4LUWNET.js");
6454
+ const { runSourcesPending: runSourcesPending2 } = await import("./sources-TNX2VEMB.js");
6336
6455
  const pending = await runSourcesPending2({
6337
6456
  vault: input.vault,
6338
6457
  match: input.text,
@@ -7681,7 +7800,9 @@ export {
7681
7800
  runConfigList,
7682
7801
  runConfigPath,
7683
7802
  detectFuseMount,
7803
+ readVaultSyncConfig,
7684
7804
  snapshotterHealthChecks,
7805
+ PUSH_NOT_IN_PROFILE,
7685
7806
  SATELLITE_STALE_MS,
7686
7807
  satelliteLatestRunPath,
7687
7808
  isFailedRunStatus,
@@ -3,11 +3,11 @@ import {
3
3
  ROOT_INDEX_SECTION_ORDER,
4
4
  atomicWriteText,
5
5
  buildRootIndexUniverse
6
- } from "./chunk-BPJ5KWIT.js";
6
+ } from "./chunk-JHDN3FSF.js";
7
7
  import {
8
8
  err,
9
9
  ok
10
- } from "./chunk-HJ4ALQG6.js";
10
+ } from "./chunk-XJR3XXP5.js";
11
11
 
12
12
  // src/utils/index-projection.ts
13
13
  import { readFile } from "fs/promises";
package/dist/cli.js CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  DEFAULT_DIRTY_VOLUME_THRESHOLD,
6
6
  DEFAULT_NO_DECISION_STREAK,
7
7
  GateError,
8
+ PUSH_NOT_IN_PROFILE,
8
9
  SATELLITE_STALE_MS,
9
10
  buildVectorIndex,
10
11
  configPath,
@@ -18,6 +19,7 @@ import {
18
19
  pruneVectorIndex,
19
20
  readCliPackageJson,
20
21
  readSatelliteLatestRunFromText,
22
+ readVaultSyncConfig,
21
23
  reindexPageInVectorIndex,
22
24
  renderIndexUpsert,
23
25
  renderProjectIndex,
@@ -50,7 +52,7 @@ import {
50
52
  snapshotterHealthChecks,
51
53
  upsertIndexEntry,
52
54
  vectorIndexStatus
53
- } from "./chunk-G7I34RQW.js";
55
+ } from "./chunk-YEVR5XNN.js";
54
56
  import {
55
57
  normalizeDistTag,
56
58
  readCache,
@@ -63,7 +65,7 @@ import {
63
65
  UNMANAGED_START,
64
66
  renderRootIndex,
65
67
  writeRootIndexProjection
66
- } from "./chunk-KFEOMMWK.js";
68
+ } from "./chunk-ZUHA2EXE.js";
67
69
  import {
68
70
  FLEET_REL_PATH,
69
71
  REDACTED_MALFORMED_REFERENCE,
@@ -151,12 +153,12 @@ import {
151
153
  supersedeStaleReviewRequiredJournals,
152
154
  taxonomyCommentForPage,
153
155
  writeDotenv
154
- } from "./chunk-GPUK2IAW.js";
156
+ } from "./chunk-BO7JIJIA.js";
155
157
  import {
156
158
  assertTargetInsideVault,
157
159
  atomicWriteText,
158
160
  prepareTypedPage
159
- } from "./chunk-BPJ5KWIT.js";
161
+ } from "./chunk-JHDN3FSF.js";
160
162
  import {
161
163
  applySourceDisposition,
162
164
  decodeSourceActionApproval,
@@ -164,7 +166,7 @@ import {
164
166
  inventorySources,
165
167
  planSourceDisposition,
166
168
  runSourcesPending
167
- } from "./chunk-NPTIYO2S.js";
169
+ } from "./chunk-CGQQS7MO.js";
168
170
  import {
169
171
  authorizeRawOperation,
170
172
  buildSourceReferenceIndex,
@@ -181,7 +183,7 @@ import {
181
183
  resolveExistingRegularFileInsideVault,
182
184
  validateLogEvent,
183
185
  writeLogEvent
184
- } from "./chunk-OMO45AHI.js";
186
+ } from "./chunk-5BNCYHRN.js";
185
187
  import {
186
188
  ExitCode,
187
189
  MetaSchema,
@@ -202,7 +204,7 @@ import {
202
204
  scanVault,
203
205
  splitFrontmatter,
204
206
  vaultIoConcurrency
205
- } from "./chunk-HJ4ALQG6.js";
207
+ } from "./chunk-XJR3XXP5.js";
206
208
 
207
209
  // src/cli.ts
208
210
  import { join as join42 } from "path";
@@ -3136,29 +3138,6 @@ function classifyLog(path, id, label, okPattern) {
3136
3138
  if (okPattern.test(last)) return { id, label, status: "pass", detail: last.slice(0, 120) };
3137
3139
  return { id, label, status: "warn", detail: last.slice(0, 120) };
3138
3140
  }
3139
- function readVaultSyncRoleAndScope(home) {
3140
- try {
3141
- const content = readFileSync10(join17(home, ".skillwiki", ".env"), "utf8");
3142
- let role;
3143
- let serviceScope;
3144
- let snapshotScript;
3145
- for (const line of content.split(/\r?\n/)) {
3146
- const trimmed = line.trim();
3147
- if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
3148
- const eq = trimmed.indexOf("=");
3149
- if (eq <= 0) continue;
3150
- const k = trimmed.slice(0, eq).trim();
3151
- const v = trimmed.slice(eq + 1).trim();
3152
- if (v.length === 0) continue;
3153
- if (k === "vault_sync.role") role = v;
3154
- if (k === "vault_sync.service_scope") serviceScope = v;
3155
- if (k === "vault_sync.snapshot_script") snapshotScript = v;
3156
- }
3157
- return { role, serviceScope, snapshotScript };
3158
- } catch {
3159
- return {};
3160
- }
3161
- }
3162
3141
  function runVaultSyncHealth(home, syncMode, env = process.env) {
3163
3142
  if (syncMode === "off") {
3164
3143
  return {
@@ -3174,8 +3153,10 @@ function runVaultSyncHealth(home, syncMode, env = process.env) {
3174
3153
  const logDir = isMac ? join17(home, "Library", "Logs") : join17(home, ".local", "state", "vault-sync", "log");
3175
3154
  const filterPath = join17(home, ".config", "rclone", "wiki-push-filters.txt");
3176
3155
  const checks = [];
3177
- const pushScript = join17(shareDir, "wiki-push.sh");
3178
- if (syncMode === "optional" && !existsSync6(pushScript)) {
3156
+ const vsConfig = readVaultSyncConfig(home);
3157
+ const fetchOnly = vsConfig.pushEnabled === false;
3158
+ const installedScript = fetchOnly ? join17(shareDir, "wiki-fetch-notify.sh") : join17(shareDir, "wiki-push.sh");
3159
+ if (syncMode === "optional" && !existsSync6(installedScript)) {
3179
3160
  return {
3180
3161
  status: "pass",
3181
3162
  blocking: false,
@@ -3184,11 +3165,10 @@ function runVaultSyncHealth(home, syncMode, env = process.env) {
3184
3165
  checks: [{
3185
3166
  id: "vault_sync_installed",
3186
3167
  status: "pass",
3187
- detail: `vault-sync not installed at ${pushScript}; optional check skipped`
3168
+ detail: `vault-sync not installed at ${installedScript}; optional check skipped`
3188
3169
  }]
3189
3170
  };
3190
3171
  }
3191
- const vsConfig = readVaultSyncRoleAndScope(home);
3192
3172
  if (vsConfig.role === "snapshotter") {
3193
3173
  const snapshotScript = vsConfig.snapshotScript ?? join17(shareDir, "wiki-snapshot.sh");
3194
3174
  const installed = existsSync6(snapshotScript) ? { id: "vault_sync_installed", label: "Vault sync installed", status: "pass", detail: `Found snapshot script: ${snapshotScript}` } : { id: "vault_sync_installed", label: "Vault sync installed", status: "error", detail: `Snapshot script not found at ${snapshotScript}` };
@@ -3212,23 +3192,31 @@ function runVaultSyncHealth(home, syncMode, env = process.env) {
3212
3192
  checks: allChecks.map((c) => ({ id: c.id, status: c.status, detail: c.detail }))
3213
3193
  };
3214
3194
  }
3215
- checks.push(existsSync6(pushScript) ? { id: "vault_sync_installed", label: "Vault sync installed", status: "pass", detail: `Found: ${pushScript}` } : { id: "vault_sync_installed", label: "Vault sync installed", status: "error", detail: `Script missing: ${pushScript}` });
3195
+ checks.push(existsSync6(installedScript) ? { id: "vault_sync_installed", label: "Vault sync installed", status: "pass", detail: `Found: ${installedScript}` } : { id: "vault_sync_installed", label: "Vault sync installed", status: "error", detail: `Script missing: ${installedScript}` });
3216
3196
  if (isMac) {
3217
3197
  const pushPlist = join17(home, "Library", "LaunchAgents", "com.karlchow.wiki-push.plist");
3218
3198
  const fetchPlist = join17(home, "Library", "LaunchAgents", "com.karlchow.wiki-fetch.plist");
3219
- checks.push(existsSync6(pushPlist) && existsSync6(fetchPlist) ? { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "pass", detail: "launchd unit files present (read-only mode)" } : { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "warn", detail: "launchd unit files missing (read-only mode)" });
3199
+ const jobsOk = fetchOnly ? existsSync6(fetchPlist) : existsSync6(pushPlist) && existsSync6(fetchPlist);
3200
+ checks.push(jobsOk ? { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "pass", detail: fetchOnly ? "launchd: wiki-fetch unit file present (read-only mode)" : "launchd unit files present (read-only mode)" } : { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "warn", detail: fetchOnly ? "launchd wiki-fetch unit file missing (read-only mode)" : "launchd unit files missing (read-only mode)" });
3220
3201
  checks.push({ id: "vault_sync_fuse_refresh_job", label: "Vault sync fuse refresh job", status: "pass", detail: "macOS host \u2014 check skipped" });
3221
3202
  } else {
3222
3203
  const pushTimer = join17(home, ".config", "systemd", "user", "wiki-push.timer");
3223
3204
  const fetchTimer = join17(home, ".config", "systemd", "user", "wiki-fetch.timer");
3224
3205
  const fuseTimer = join17(home, ".config", "systemd", "user", "wiki-fuse-refresh.timer");
3225
3206
  const fuseService = join17(home, ".config", "systemd", "user", "wiki-fuse-refresh.service");
3226
- checks.push(existsSync6(pushTimer) && existsSync6(fetchTimer) ? { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "pass", detail: "systemd timer unit files present (read-only mode)" } : { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "warn", detail: "systemd timer unit files missing (read-only mode)" });
3207
+ const jobsOk = fetchOnly ? existsSync6(fetchTimer) : existsSync6(pushTimer) && existsSync6(fetchTimer);
3208
+ checks.push(jobsOk ? { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "pass", detail: fetchOnly ? "systemd: wiki-fetch.timer unit file present (read-only mode)" : "systemd timer unit files present (read-only mode)" } : { id: "vault_sync_jobs_enabled", label: "Vault sync jobs enabled", status: "warn", detail: fetchOnly ? "systemd wiki-fetch.timer unit file missing (read-only mode)" : "systemd timer unit files missing (read-only mode)" });
3227
3209
  checks.push(existsSync6(fuseTimer) && existsSync6(fuseService) ? { id: "vault_sync_fuse_refresh_job", label: "Vault sync fuse refresh job", status: "pass", detail: "wiki-fuse-refresh unit files present (read-only mode)" } : { id: "vault_sync_fuse_refresh_job", label: "Vault sync fuse refresh job", status: "warn", detail: "wiki-fuse-refresh unit files missing (read-only mode)" });
3228
3210
  }
3229
- checks.push(classifyLog(join17(logDir, "wiki-push.log"), "vault_sync_last_push_age", "Vault sync last push recency", /OK push/));
3211
+ if (fetchOnly) {
3212
+ checks.push({ id: "vault_sync_last_push_age", label: "Vault sync last push recency", status: "pass", detail: PUSH_NOT_IN_PROFILE });
3213
+ } else {
3214
+ checks.push(classifyLog(join17(logDir, "wiki-push.log"), "vault_sync_last_push_age", "Vault sync last push recency", /OK push/));
3215
+ }
3230
3216
  checks.push(classifyLog(join17(logDir, "wiki-fetch.log"), "vault_sync_last_fetch_status", "Vault sync last fetch status", /NOTIFY|OK behind|OK/));
3231
- if (!existsSync6(filterPath)) {
3217
+ if (fetchOnly) {
3218
+ checks.push({ id: "vault_sync_filter_present", label: "Vault sync filter file present", status: "pass", detail: PUSH_NOT_IN_PROFILE });
3219
+ } else if (!existsSync6(filterPath)) {
3232
3220
  checks.push({ id: "vault_sync_filter_present", label: "Vault sync filter file present", status: "error", detail: `Filter missing: ${filterPath}` });
3233
3221
  } else {
3234
3222
  const content = readFileSync10(filterPath, "utf8");
@@ -3784,7 +3772,7 @@ ${fmRewritten}
3784
3772
  }
3785
3773
  let indexUpdated = false;
3786
3774
  if (!isRaw) {
3787
- const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-J5IV7NH3.js");
3775
+ const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-YP4JIMIQ.js");
3788
3776
  const before = await readFile7(join19(input.vault, "index.md"), "utf8").catch(() => "");
3789
3777
  const fullTarget = relPath.replace(/\.md$/, "");
3790
3778
  const bare = fullTarget.split("/").pop() ?? fullTarget;
@@ -3907,7 +3895,7 @@ async function runRemove(input) {
3907
3895
  if (relPath.endsWith(".md") && !relPath.startsWith("raw/")) {
3908
3896
  const { readFile: readFile22 } = await import("fs/promises");
3909
3897
  const { join: pathJoin } = await import("path");
3910
- const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-J5IV7NH3.js");
3898
+ const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-YP4JIMIQ.js");
3911
3899
  const before = await readFile22(pathJoin(input.vault, "index.md"), "utf8").catch(() => "");
3912
3900
  const fullTarget = relPath.replace(/\.md$/, "");
3913
3901
  const bare = fullTarget.split("/").pop() ?? fullTarget;
@@ -10559,7 +10547,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
10559
10547
  if (dirty) {
10560
10548
  return emit(dirty, void 0, { postCommit: false });
10561
10549
  }
10562
- const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-DEPLZAA6.js");
10550
+ const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-BAIL5GMW.js");
10563
10551
  const run = await runManagedWriteTransaction2({
10564
10552
  vault,
10565
10553
  command,
@@ -4,9 +4,9 @@ import {
4
4
  UNMANAGED_START,
5
5
  renderRootIndex,
6
6
  writeRootIndexProjection
7
- } from "./chunk-KFEOMMWK.js";
8
- import "./chunk-BPJ5KWIT.js";
9
- import "./chunk-HJ4ALQG6.js";
7
+ } from "./chunk-ZUHA2EXE.js";
8
+ import "./chunk-JHDN3FSF.js";
9
+ import "./chunk-XJR3XXP5.js";
10
10
  export {
11
11
  UNMANAGED_END,
12
12
  UNMANAGED_START,
@@ -6,10 +6,10 @@ import {
6
6
  runManagedWritePeerGate,
7
7
  runManagedWritePreflight,
8
8
  runManagedWriteTransaction
9
- } from "./chunk-GPUK2IAW.js";
10
- import "./chunk-BPJ5KWIT.js";
11
- import "./chunk-OMO45AHI.js";
12
- import "./chunk-HJ4ALQG6.js";
9
+ } from "./chunk-BO7JIJIA.js";
10
+ import "./chunk-JHDN3FSF.js";
11
+ import "./chunk-5BNCYHRN.js";
12
+ import "./chunk-XJR3XXP5.js";
13
13
  export {
14
14
  DEFAULT_MANAGED_WRITE_WAIT_MS,
15
15
  MANAGED_WRITE_POLL_INTERVAL_MS,
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-G7I34RQW.js";
4
+ } from "./chunk-YEVR5XNN.js";
5
5
  import "./chunk-7I2TPIV5.js";
6
- import "./chunk-KFEOMMWK.js";
7
- import "./chunk-GPUK2IAW.js";
8
- import "./chunk-BPJ5KWIT.js";
9
- import "./chunk-NPTIYO2S.js";
10
- import "./chunk-OMO45AHI.js";
11
- import "./chunk-HJ4ALQG6.js";
6
+ import "./chunk-ZUHA2EXE.js";
7
+ import "./chunk-BO7JIJIA.js";
8
+ import "./chunk-JHDN3FSF.js";
9
+ import "./chunk-CGQQS7MO.js";
10
+ import "./chunk-5BNCYHRN.js";
11
+ import "./chunk-XJR3XXP5.js";
12
12
 
13
13
  // src/mcp-entry.ts
14
14
  runSkillwikiMcpStdio().catch((error) => {
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runSourcesPending
4
+ } from "./chunk-CGQQS7MO.js";
5
+ import "./chunk-5BNCYHRN.js";
6
+ import "./chunk-XJR3XXP5.js";
7
+ export {
8
+ runSourcesPending
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.81",
3
+ "version": "0.10.82",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "skillwiki": "dist/cli.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.81",
3
+ "version": "0.10.82",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by the deterministic `skillwiki` CLI.",
6
6
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.81",
3
+ "version": "0.10.82",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 21 prompt-only skills backed by the deterministic skillwiki CLI.",
5
5
  "author": {
6
6
  "name": "karlorz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.81",
3
+ "version": "0.10.82",
4
4
  "description": "Project-aware Karpathy-style knowledge base: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by HTTP MCP wiki_capture.",
5
5
  "author": {
6
6
  "name": "karlorz"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.10.81",
3
+ "version": "0.10.82",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",
@@ -247,7 +247,7 @@ Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang
247
247
  Optional read-only MCP (`skillwiki mcp`) exposes pending/compile/review list tools. Do not use MCP for compile claim, publish, or review writes.
248
248
  `skillwiki claim` binds a transcript to a work item only through an exact `raw/transcripts/...` path in `source:` / `sources:` / `closes:`. A `--project` that contradicts the capture's explicit project is rejected. `skillwiki stale --project` uses exact normalized slugs, not substring matching. `skillwiki claims audit` is the read-only integrity report for duplicate, malformed, dangling, cross-project, and unbacked claims; it never rewrites captures or work items.
249
249
 
250
- Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
250
+ Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. Fetch-only leaves set `vault_sync.push_enabled=false`; doctor must not tell them to run `vault-sync-install` to enable wiki-push. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
251
251
 
252
252
  ## Runtime Host Context and Fleet Freshness
253
253
  Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
@@ -247,7 +247,7 @@ Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang
247
247
  Optional read-only MCP (`skillwiki mcp`) exposes pending/compile/review list tools. Do not use MCP for compile claim, publish, or review writes.
248
248
  `skillwiki claim` binds a transcript to a work item only through an exact `raw/transcripts/...` path in `source:` / `sources:` / `closes:`. A `--project` that contradicts the capture's explicit project is rejected. `skillwiki stale --project` uses exact normalized slugs, not substring matching. `skillwiki claims audit` is the read-only integrity report for duplicate, malformed, dangling, cross-project, and unbacked claims; it never rewrites captures or work items.
249
249
 
250
- Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
250
+ Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes the nonblocking source-lifecycle backlog. Pending captures are informational and do not make health fail. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only, including HTTP MCP URL/auth presence and the frozen-leaf write path. Pass `--check-mcp` for a live initialize handshake and pin/tool-list lag; the default doctor path does not contact HTTP MCP. Fetch-only leaves set `vault_sync.push_enabled=false`; doctor must not tell them to run `vault-sync-install` to enable wiki-push. New hosts need an issued host-id bearer from metal `skillwiki mcp-auth issue-host` before handshake can pass. There is no second MCP admin skill. Run `skillwiki config list` to see current configuration.
251
251
 
252
252
  ## Runtime Host Context and Fleet Freshness
253
253
  Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- runSourcesPending
4
- } from "./chunk-NPTIYO2S.js";
5
- import "./chunk-OMO45AHI.js";
6
- import "./chunk-HJ4ALQG6.js";
7
- export {
8
- runSourcesPending
9
- };