skillwiki 0.10.16 → 0.10.17

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
  err,
7
7
  getErrorMessage,
8
8
  ok
9
- } from "./chunk-C5OLZRRM.js";
9
+ } from "./chunk-Y6KRDGI2.js";
10
10
 
11
11
  // src/utils/index-projection.ts
12
12
  import { readFile as readFile4 } from "fs/promises";
@@ -19,7 +19,7 @@ import {
19
19
  splitFrontmatter,
20
20
  vaultIoConcurrency,
21
21
  writeRootIndexProjection
22
- } from "./chunk-NMUYMNNB.js";
22
+ } from "./chunk-IGCW3DR2.js";
23
23
  import {
24
24
  CONFIG_KEYS,
25
25
  git,
@@ -33,7 +33,7 @@ import {
33
33
  satelliteGateFromFleetLoad,
34
34
  snapshotterAliasForLocalHost,
35
35
  writeDotenv
36
- } from "./chunk-OWPQJOFG.js";
36
+ } from "./chunk-VOVXDN56.js";
37
37
  import {
38
38
  CompoundSchema,
39
39
  ExitCode,
@@ -44,8 +44,11 @@ import {
44
44
  detectSchema,
45
45
  err,
46
46
  getErrorMessage,
47
- ok
48
- } from "./chunk-C5OLZRRM.js";
47
+ isVaultSyncKey,
48
+ ok,
49
+ parseVaultSyncKeyValue,
50
+ systemdPropertyFor
51
+ } from "./chunk-Y6KRDGI2.js";
49
52
 
50
53
  // src/commands/log-append.ts
51
54
  import { readFile as readFile2, stat } from "fs/promises";
@@ -4774,7 +4777,7 @@ import { readFile as readFile15 } from "fs/promises";
4774
4777
  import { existsSync as existsSync7 } from "fs";
4775
4778
  import { join as join19 } from "path";
4776
4779
  function validateKey(key) {
4777
- return CONFIG_KEYS.includes(key) || isValidWikiProfileKey(key);
4780
+ return CONFIG_KEYS.includes(key) || isValidWikiProfileKey(key) || isVaultSyncKey(key);
4778
4781
  }
4779
4782
  function configPath(home) {
4780
4783
  return join19(home, ".skillwiki", ".env");
@@ -4791,6 +4794,12 @@ async function runConfigSet(input) {
4791
4794
  if (!validateKey(input.key)) {
4792
4795
  return { exitCode: ExitCode.INVALID_CONFIG_KEY, result: err("INVALID_CONFIG_KEY", { key: input.key }) };
4793
4796
  }
4797
+ if (isVaultSyncKey(input.key)) {
4798
+ const parsed = parseVaultSyncKeyValue(input.key, input.value);
4799
+ if (!parsed.ok) {
4800
+ return { exitCode: ExitCode.INVALID_CONFIG_VALUE, result: err("INVALID_CONFIG_VALUE", { key: input.key, value: input.value, message: parsed.message }) };
4801
+ }
4802
+ }
4794
4803
  const filePath = configPath(input.home);
4795
4804
  try {
4796
4805
  let originalContent;
@@ -6521,24 +6530,6 @@ function resolveSnapshotGitWorktree(config) {
6521
6530
  const defaultPath = "/root/wiki-git";
6522
6531
  return existsSync13(defaultPath) ? defaultPath : void 0;
6523
6532
  }
6524
- var SNAPSHOT_SEMANTIC_TO_SYSTEMD = {
6525
- load_state: "LoadState",
6526
- unit_file_state: "UnitFileState",
6527
- active_state: "ActiveState",
6528
- sub_state: "SubState",
6529
- next_elapse: "NextElapseUSecRealtime",
6530
- result: "Result",
6531
- exec_main_status: "ExecMainStatus",
6532
- exec_main_code: "ExecMainCode",
6533
- active_enter_timestamp: "ActiveEnterTimestamp",
6534
- inactive_enter_timestamp: "InactiveEnterTimestamp",
6535
- exec_main_start_timestamp: "ExecMainStartTimestamp",
6536
- exec_main_exit_timestamp: "ExecMainExitTimestamp",
6537
- invocation_id: "InvocationID"
6538
- };
6539
- function semanticToSystemdProp(semantic) {
6540
- return SNAPSHOT_SEMANTIC_TO_SYSTEMD[semantic];
6541
- }
6542
6533
  function normalizeSystemdValue(raw) {
6543
6534
  if (raw == null) return void 0;
6544
6535
  const v = raw.trim();
@@ -6577,7 +6568,7 @@ function snapshotProp(kind, prop, fixture, scope) {
6577
6568
  return v == null ? void 0 : String(v);
6578
6569
  }
6579
6570
  const unit = kind === "timer" ? "wiki-snapshot.timer" : "wiki-snapshot.service";
6580
- const liveProp = semanticToSystemdProp(prop);
6571
+ const liveProp = systemdPropertyFor(prop);
6581
6572
  if (!liveProp) return void 0;
6582
6573
  return systemctlShowProperty(scope, unit, liveProp);
6583
6574
  }
@@ -6594,7 +6585,8 @@ function snapshotterHealthChecks(scope, logDir, env) {
6594
6585
  const fixture = loadSnapshotFixture(env);
6595
6586
  const cadence = fixture ? fixture.cadence_minutes : parseInt(env.VS_SNAPSHOT_CADENCE_MINUTES ?? "30", 10) || 30;
6596
6587
  const timeout = fixture ? fixture.service_timeout_seconds : parseInt(env.VS_SNAPSHOT_SERVICE_TIMEOUT_SECONDS ?? "900", 10) || 900;
6597
- const nowMs = fixture ? Date.parse(fixture.now) : Date.now();
6588
+ const injectedNowMs = env.VS_SNAPSHOT_HEALTH_NOW ? Date.parse(env.VS_SNAPSHOT_HEALTH_NOW) : Number.NaN;
6589
+ const nowMs = fixture ? Date.parse(fixture.now) : Number.isFinite(injectedNowMs) ? injectedNowMs : Date.now();
6598
6590
  const warnAge = cadence * 2 + 15;
6599
6591
  const errorAge = cadence * 4 + 15;
6600
6592
  const tUnitfile = snapshotProp("timer", "unit_file_state", fixture, scope);
@@ -6781,7 +6773,7 @@ function vaultSyncChecks(input) {
6781
6773
  execSync2(`launchctl print gui/${uid}/com.karlchow.wiki-push`, {
6782
6774
  encoding: "utf8",
6783
6775
  timeout: 2e3,
6784
- stdio: ["pipe", "pipe", "pipe"]
6776
+ stdio: ["pipe", "ignore", "ignore"]
6785
6777
  });
6786
6778
  c2 = check(
6787
6779
  "pass",
@@ -8,12 +8,12 @@ import {
8
8
  loadFleetManifestAndHost,
9
9
  runVaultSyncPullHelper,
10
10
  supersedeStaleReviewRequiredJournals
11
- } from "./chunk-OWPQJOFG.js";
11
+ } from "./chunk-VOVXDN56.js";
12
12
  import {
13
13
  ExitCode,
14
14
  err,
15
15
  ok
16
- } from "./chunk-C5OLZRRM.js";
16
+ } from "./chunk-Y6KRDGI2.js";
17
17
 
18
18
  // src/utils/managed-write-preflight.ts
19
19
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
@@ -3,8 +3,9 @@ import {
3
3
  ExitCode,
4
4
  FleetManifestSchema,
5
5
  err,
6
+ isVaultSyncKey,
6
7
  ok
7
- } from "./chunk-C5OLZRRM.js";
8
+ } from "./chunk-Y6KRDGI2.js";
8
9
 
9
10
  // src/utils/dotenv.ts
10
11
  import { readFile, writeFile, mkdir } from "fs/promises";
@@ -40,7 +41,7 @@ function parseDotenvText(text) {
40
41
  if (eq <= 0) continue;
41
42
  const key = line.slice(0, eq).trim();
42
43
  const value = line.slice(eq + 1).trim();
43
- if (!_whitelist.has(key) && !isValidWikiProfileKey(key)) continue;
44
+ if (!_whitelist.has(key) && !isValidWikiProfileKey(key) && !isVaultSyncKey(key)) continue;
44
45
  if (value.length === 0) continue;
45
46
  out[key] = value;
46
47
  }
@@ -55,7 +55,8 @@ var ExitCode = {
55
55
  FLEET_MANIFEST_INVALID: 50,
56
56
  SENSITIVE_CONTENT_DETECTED: 51,
57
57
  FLEET_SATELLITE_HEALTH_FAILED: 52,
58
- PROTECTED_SNAPSHOTTER_WRITE_BLOCKED: 53
58
+ PROTECTED_SNAPSHOTTER_WRITE_BLOCKED: 53,
59
+ INVALID_CONFIG_VALUE: 54
59
60
  };
60
61
 
61
62
  // ../shared/src/json-output.ts
@@ -285,6 +286,47 @@ var FleetManifestSchema = z.object({
285
286
  }
286
287
  }
287
288
  });
289
+ var vaultSyncRole = z.enum(["leaf", "snapshotter", "none"]);
290
+ var vaultSyncScheduler = z.enum(["systemd", "launchd", "none"]);
291
+ var vaultSyncScope = z.enum(["user", "system", "none"]);
292
+ var vaultSyncBool = z.enum(["true", "false"]);
293
+ var vaultSyncDuration = z.union([
294
+ z.string().regex(/^[1-9][0-9]*[mhs]$/, "must be <positive-int>m|h|s (e.g. 15m, 300s) or none"),
295
+ z.literal("none")
296
+ ]);
297
+ var vaultSyncPathOrNone = z.union([
298
+ absolutePath,
299
+ z.literal("none")
300
+ ]);
301
+ var VaultSyncConfigSchema = z.object({
302
+ "vault_sync.installed": vaultSyncBool,
303
+ "vault_sync.role": vaultSyncRole,
304
+ "vault_sync.scheduler": vaultSyncScheduler,
305
+ "vault_sync.service_scope": vaultSyncScope,
306
+ "vault_sync.snapshot_profile": vaultSyncPathOrNone,
307
+ "vault_sync.snapshot_script": vaultSyncPathOrNone,
308
+ "vault_sync.snapshot_worktree": vaultSyncPathOrNone,
309
+ "vault_sync.fuse_refresh_enabled": vaultSyncBool,
310
+ "vault_sync.fuse_refresh_interval": vaultSyncDuration,
311
+ "vault_sync.fuse_max_dir_cache": vaultSyncDuration,
312
+ "vault_sync.fuse_service_scope": vaultSyncScope
313
+ }).strict();
314
+ var VAULT_SYNC_KEYS = Object.keys(VaultSyncConfigSchema.shape);
315
+ function isVaultSyncKey(key) {
316
+ return VAULT_SYNC_KEYS.includes(key);
317
+ }
318
+ function parseVaultSyncKeyValue(key, value) {
319
+ if (!isVaultSyncKey(key)) {
320
+ return { ok: false, message: `unknown vault_sync key: ${key}` };
321
+ }
322
+ const fieldSchema = VaultSyncConfigSchema.shape[key];
323
+ const parsed = fieldSchema.safeParse(value);
324
+ if (parsed.success) {
325
+ return { ok: true };
326
+ }
327
+ const first = parsed.error.issues[0];
328
+ return { ok: false, message: first?.message ?? "invalid value" };
329
+ }
288
330
  function detectSchema(fm) {
289
331
  const COMPOUND_TYPES = /* @__PURE__ */ new Set(["lesson", "pattern", "antipattern", "gotcha"]);
290
332
  if (typeof fm.type === "string" && COMPOUND_TYPES.has(fm.type) && "project" in fm) return { schema: "compound" };
@@ -341,6 +383,29 @@ function getErrorMessage(e) {
341
383
  return e instanceof Error ? e.message : String(e);
342
384
  }
343
385
 
386
+ // ../shared/src/systemd-property-catalog.json
387
+ var systemd_property_catalog_default = {
388
+ load_state: "LoadState",
389
+ unit_file_state: "UnitFileState",
390
+ active_state: "ActiveState",
391
+ sub_state: "SubState",
392
+ next_elapse: "NextElapseUSecRealtime",
393
+ result: "Result",
394
+ exec_main_status: "ExecMainStatus",
395
+ exec_main_code: "ExecMainCode",
396
+ active_enter_timestamp: "ActiveEnterTimestamp",
397
+ inactive_enter_timestamp: "InactiveEnterTimestamp",
398
+ exec_main_start_timestamp: "ExecMainStartTimestamp",
399
+ exec_main_exit_timestamp: "ExecMainExitTimestamp",
400
+ invocation_id: "InvocationID"
401
+ };
402
+
403
+ // ../shared/src/systemd-property-catalog.ts
404
+ var SYSTEMD_PROPERTY_CATALOG = Object.freeze({ ...systemd_property_catalog_default });
405
+ function systemdPropertyFor(semantic) {
406
+ return SYSTEMD_PROPERTY_CATALOG[semantic];
407
+ }
408
+
344
409
  export {
345
410
  ExitCode,
346
411
  ok,
@@ -351,7 +416,10 @@ export {
351
416
  CompoundSchema,
352
417
  MetaSchema,
353
418
  FleetManifestSchema,
419
+ isVaultSyncKey,
420
+ parseVaultSyncKeyValue,
354
421
  detectSchema,
355
422
  isBlockedHost,
356
- getErrorMessage
423
+ getErrorMessage,
424
+ systemdPropertyFor
357
425
  };
package/dist/cli.js CHANGED
@@ -83,7 +83,7 @@ import {
83
83
  upsertIndexEntry,
84
84
  validateLogEvent,
85
85
  writeLogEvent
86
- } from "./chunk-24MVNAFJ.js";
86
+ } from "./chunk-IVTI3BOH.js";
87
87
  import {
88
88
  normalizeDistTag,
89
89
  readCache,
@@ -105,13 +105,13 @@ import {
105
105
  scanVault,
106
106
  splitFrontmatter,
107
107
  writeRootIndexProjection
108
- } from "./chunk-NMUYMNNB.js";
108
+ } from "./chunk-IGCW3DR2.js";
109
109
  import {
110
110
  acquireManagedWriteLock,
111
111
  releaseManagedWriteLock,
112
112
  runManagedWritePreflight,
113
113
  runManagedWriteTransaction
114
- } from "./chunk-UJLSUJB6.js";
114
+ } from "./chunk-RNPDHSGX.js";
115
115
  import {
116
116
  FLEET_REL_PATH,
117
117
  canSupersedeJournal,
@@ -138,7 +138,7 @@ import {
138
138
  snapshotterAliasForLocalHost,
139
139
  supersedeStaleReviewRequiredJournals,
140
140
  writeDotenv
141
- } from "./chunk-OWPQJOFG.js";
141
+ } from "./chunk-VOVXDN56.js";
142
142
  import {
143
143
  ExitCode,
144
144
  MetaSchema,
@@ -146,7 +146,7 @@ import {
146
146
  err,
147
147
  isBlockedHost,
148
148
  ok
149
- } from "./chunk-C5OLZRRM.js";
149
+ } from "./chunk-Y6KRDGI2.js";
150
150
 
151
151
  // src/cli.ts
152
152
  import { join as join37 } from "path";
@@ -3234,7 +3234,7 @@ ${fmRewritten}
3234
3234
  await rename2(join19(input.vault, relPath), join19(input.vault, archivePath));
3235
3235
  let indexUpdated = false;
3236
3236
  if (!isRaw) {
3237
- const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-MHXG7QO2.js");
3237
+ const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-DENEYZTK.js");
3238
3238
  const before = await readFile7(join19(input.vault, "index.md"), "utf8").catch(() => "");
3239
3239
  const fullTarget = relPath.replace(/\.md$/, "");
3240
3240
  const bare = fullTarget.split("/").pop() ?? fullTarget;
@@ -3345,7 +3345,7 @@ async function runRemove(input) {
3345
3345
  if (relPath.endsWith(".md") && !relPath.startsWith("raw/")) {
3346
3346
  const { readFile: readFile17 } = await import("fs/promises");
3347
3347
  const { join: pathJoin } = await import("path");
3348
- const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-MHXG7QO2.js");
3348
+ const { renderRootIndex: renderRootIndex2, writeRootIndexProjection: writeRootIndexProjection2 } = await import("./index-projection-DENEYZTK.js");
3349
3349
  const before = await readFile17(pathJoin(input.vault, "index.md"), "utf8").catch(() => "");
3350
3350
  const fullTarget = relPath.replace(/\.md$/, "");
3351
3351
  const bare = fullTarget.split("/").pop() ?? fullTarget;
@@ -7893,7 +7893,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
7893
7893
  if (dirty) {
7894
7894
  return emit(dirty, void 0, { postCommit: false });
7895
7895
  }
7896
- const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-M2HL6DDY.js");
7896
+ const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-IDIQYSWI.js");
7897
7897
  const run = await runManagedWriteTransaction2({
7898
7898
  vault,
7899
7899
  command,
@@ -4,8 +4,8 @@ import {
4
4
  UNMANAGED_START,
5
5
  renderRootIndex,
6
6
  writeRootIndexProjection
7
- } from "./chunk-NMUYMNNB.js";
8
- import "./chunk-C5OLZRRM.js";
7
+ } from "./chunk-IGCW3DR2.js";
8
+ import "./chunk-Y6KRDGI2.js";
9
9
  export {
10
10
  UNMANAGED_END,
11
11
  UNMANAGED_START,
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  runManagedWritePreflight,
4
4
  runManagedWriteTransaction
5
- } from "./chunk-UJLSUJB6.js";
6
- import "./chunk-OWPQJOFG.js";
7
- import "./chunk-C5OLZRRM.js";
5
+ } from "./chunk-RNPDHSGX.js";
6
+ import "./chunk-VOVXDN56.js";
7
+ import "./chunk-Y6KRDGI2.js";
8
8
  export {
9
9
  runManagedWritePreflight,
10
10
  runManagedWriteTransaction
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-24MVNAFJ.js";
4
+ } from "./chunk-IVTI3BOH.js";
5
5
  import "./chunk-7I2TPIV5.js";
6
- import "./chunk-NMUYMNNB.js";
7
- import "./chunk-OWPQJOFG.js";
8
- import "./chunk-C5OLZRRM.js";
6
+ import "./chunk-IGCW3DR2.js";
7
+ import "./chunk-VOVXDN56.js";
8
+ import "./chunk-Y6KRDGI2.js";
9
9
 
10
10
  // src/mcp-entry.ts
11
11
  runSkillwikiMcpStdio().catch((error) => {
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync, writeFileSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
8
+ const repoRoot = join(scriptDir, "..", "..", "..");
9
+ const catalogPath = join(
10
+ repoRoot,
11
+ "packages",
12
+ "shared",
13
+ "src",
14
+ "systemd-property-catalog.json",
15
+ );
16
+ const outputPath = join(
17
+ repoRoot,
18
+ "packages",
19
+ "vault-sync",
20
+ "skills",
21
+ "vault-sync-status",
22
+ "systemd-property-catalog.sh",
23
+ );
24
+ const checkOnly = process.argv.includes("--check");
25
+
26
+ const catalog = JSON.parse(readFileSync(catalogPath, "utf8"));
27
+ const entries = Object.entries(catalog);
28
+ const invalid = entries.find(([semantic, property]) =>
29
+ !/^[a-z][a-z0-9_]*$/.test(semantic)
30
+ || typeof property !== "string"
31
+ || !/^[A-Z][A-Za-z0-9]*$/.test(property)
32
+ );
33
+ if (invalid) {
34
+ throw new Error(`invalid systemd property catalog entry: ${JSON.stringify(invalid)}`);
35
+ }
36
+
37
+ const lines = [
38
+ "#!/usr/bin/env bash",
39
+ "# AUTO-GENERATED by packages/vault-sync/scripts/generate-systemd-property-catalog.mjs.",
40
+ "# Source: packages/shared/src/systemd-property-catalog.json",
41
+ "# Do not edit this file directly.",
42
+ "",
43
+ "snapshot_semantic_to_systemd_prop() {",
44
+ ' case "$1" in',
45
+ ...entries.map(([semantic, property]) =>
46
+ ` ${semantic}) printf '${property}\\n' ;;`
47
+ ),
48
+ " # Closed map: never pass unknown/snake_case keys through to systemctl.",
49
+ " *) return 1 ;;",
50
+ " esac",
51
+ "}",
52
+ "",
53
+ ].join("\n");
54
+
55
+ if (checkOnly) {
56
+ let current = "";
57
+ try {
58
+ current = readFileSync(outputPath, "utf8");
59
+ } catch {
60
+ // Report the same actionable drift error for a missing generated file.
61
+ }
62
+ if (current !== lines) {
63
+ console.error(
64
+ "systemd property catalog shell adapter is stale; run "
65
+ + "node packages/vault-sync/scripts/generate-systemd-property-catalog.mjs",
66
+ );
67
+ process.exit(1);
68
+ }
69
+ console.log("systemd property catalog shell adapter is current");
70
+ } else {
71
+ writeFileSync(outputPath, lines);
72
+ console.log(`wrote ${outputPath}`);
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.16",
3
+ "version": "0.10.17",
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.16",
3
+ "version": "0.10.17",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 19 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
6
6
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.16",
3
+ "version": "0.10.17",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 19 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/skills",
3
- "version": "0.10.16",
3
+ "version": "0.10.17",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",