skillwiki 0.9.35 → 0.9.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -3303,6 +3303,7 @@ ${body}`;
3303
3303
  // src/commands/sync.ts
3304
3304
  import { existsSync as existsSync7 } from "fs";
3305
3305
  import { join as join18 } from "path";
3306
+ import { execFileSync as execFileSync2 } from "child_process";
3306
3307
 
3307
3308
  // src/utils/git.ts
3308
3309
  import { execFileSync } from "child_process";
@@ -3453,6 +3454,33 @@ function stageVaultContentChanges(vault) {
3453
3454
  }
3454
3455
 
3455
3456
  // src/commands/sync.ts
3457
+ function parseDirtyPaths(porcelain) {
3458
+ if (!porcelain) return [];
3459
+ return porcelain.split("\n").map((line) => line.trimEnd()).filter((line) => line.length >= 4).map((line) => {
3460
+ const payload = line.length >= 3 && line[2] === " " ? line.slice(3) : line.length >= 2 && line[1] === " " ? line.slice(2) : line;
3461
+ const arrow = payload.lastIndexOf(" -> ");
3462
+ return arrow >= 0 ? payload.slice(arrow + 4) : payload;
3463
+ }).filter((path) => path.length > 0);
3464
+ }
3465
+ function splitNonEmptyLines(text) {
3466
+ if (!text) return [];
3467
+ return text.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
3468
+ }
3469
+ function isTrackedNotePath(path) {
3470
+ if (!path.endsWith(".md")) return false;
3471
+ return !/^\.(skillwiki|claude|obsidian|antigravitycli|playwright-cli)\//.test(path);
3472
+ }
3473
+ function refHasPath(vault, ref, path) {
3474
+ try {
3475
+ execFileSync2("git", ["cat-file", "-e", `${ref}:${path}`], {
3476
+ cwd: vault,
3477
+ stdio: ["pipe", "pipe", "pipe"]
3478
+ });
3479
+ return true;
3480
+ } catch {
3481
+ return false;
3482
+ }
3483
+ }
3456
3484
  function runSyncStatus(input) {
3457
3485
  const vault = input.vault;
3458
3486
  const includeStashes = input.includeStashes ?? false;
@@ -3464,6 +3492,8 @@ function runSyncStatus(input) {
3464
3492
  dirty: 0,
3465
3493
  ahead: 0,
3466
3494
  behind: 0,
3495
+ unpromoted_note_paths: 0,
3496
+ unpromoted_note_examples: [],
3467
3497
  last_commit: "never",
3468
3498
  status: "not_a_repo",
3469
3499
  humanHint: "not a git repository"
@@ -3473,6 +3503,8 @@ function runSyncStatus(input) {
3473
3503
  enableGitLongPathsOnWindows(vault);
3474
3504
  const porcelain = git(vault, ["status", "--porcelain"]);
3475
3505
  const dirty = porcelain ? porcelain.split("\n").filter((l) => l.trim().length > 0).length : 0;
3506
+ const dirtyPaths = parseDirtyPaths(porcelain);
3507
+ const untrackedPaths = splitNonEmptyLines(git(vault, ["ls-files", "--others", "--exclude-standard"]));
3476
3508
  const revOutput = git(vault, ["rev-list", "--left-right", "--count", "origin/HEAD...HEAD"]);
3477
3509
  let ahead = 0;
3478
3510
  let behind = 0;
@@ -3493,6 +3525,10 @@ function runSyncStatus(input) {
3493
3525
  } else {
3494
3526
  last_commit = "never";
3495
3527
  }
3528
+ const remoteRef = git(vault, ["rev-parse", "--verify", "origin/main"]) ? "origin/main" : git(vault, ["rev-parse", "--verify", "origin/HEAD"]) ? "origin/HEAD" : "HEAD";
3529
+ const unpromotedNoteAll = Array.from(/* @__PURE__ */ new Set([...dirtyPaths, ...untrackedPaths])).filter(isTrackedNotePath).filter((path) => !refHasPath(vault, remoteRef, path));
3530
+ const unpromotedNoteExamples = unpromotedNoteAll.slice(0, 5);
3531
+ const unpromotedNotePaths = unpromotedNoteAll.length;
3496
3532
  let status;
3497
3533
  if (dirty > 0) {
3498
3534
  status = "dirty";
@@ -3508,6 +3544,7 @@ function runSyncStatus(input) {
3508
3544
  `dirty: ${dirty}`,
3509
3545
  `ahead: ${ahead}`,
3510
3546
  `behind: ${behind}`,
3547
+ `unpromoted_note_paths: ${unpromotedNotePaths}`,
3511
3548
  `last_commit: ${last_commit}`
3512
3549
  ];
3513
3550
  const exitCode = status === "clean" ? ExitCode.OK : ExitCode.LINT_HAS_WARNINGS;
@@ -3520,6 +3557,8 @@ function runSyncStatus(input) {
3520
3557
  dirty,
3521
3558
  ahead,
3522
3559
  behind,
3560
+ unpromoted_note_paths: unpromotedNotePaths,
3561
+ unpromoted_note_examples: unpromotedNoteExamples,
3523
3562
  last_commit,
3524
3563
  status,
3525
3564
  humanHint: hintLines.join("\n")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.35",
3
+ "version": "0.9.37",
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.9.35",
3
+ "version": "0.9.37",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 18 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.9.35",
3
+ "version": "0.9.37",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 18 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.9.35",
3
+ "version": "0.9.37",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",
@@ -216,9 +216,10 @@ git fetch origin main
216
216
  git reset --hard origin/main
217
217
  bash ~/.hermes/scripts/wiki-snapshot.sh # Re-sync fresh
218
218
  ```
219
- **Prevention**: Avoid editing the GitHub repo directly via web interface or uncoordinated clones. The canonical flow is:
220
- - Server: rclone mount → rsync → git commit → git push
221
- - macOS/desktop: git pull edit git commit git push → server pulls on next cron
219
+ **Prevention**: Avoid editing the GitHub repo directly via web interface or uncoordinated clones. The canonical flow is **single-writer-git** (see `concepts/vault-write-authority-model.md`):
220
+ - Server (sg01): rclone mount → rsync → git commit "Snapshot ..." → git push — **sole git writer to `main`**
221
+ - macOS/desktop: edit`wiki-push` rclone copy to S3 (NO git push)consume sg01 snapshots via `wiki-fetch-notify` (opt-in `WIKI_FETCH_PULL_ON_DELTA=1`) or manual `skillwiki sync`
222
+ - `wiki-sync` skill push is for **explicit** agent/human edit commits only, not automated background pushes
222
223
  2. **Slow rsync on rclone mounts**: The rclone FUSE mount can be slow for large directory listings. Use `rsync -q` (quiet) to reduce output overhead, and consider `--delete-delay` instead of `--delete` if file churn is high. The rclone mount latency can cause `du` and `find` operations to timeout — this is normal, not an error.
223
224
  3. **Golden Rule violation**: Never mix sync methods on the same vault. If using rclone mount + git snapshotting, do NOT also enable Obsidian Sync, Syncthing, or iCloud on `~/wiki`. The rclone mount IS the sync mechanism.
224
225
  4. **Credential exposure**: The rclone mount and git remote use different credentials. Ensure git credentials are cached or use HTTPS with token, but never commit rclone config to git.
@@ -216,9 +216,10 @@ git fetch origin main
216
216
  git reset --hard origin/main
217
217
  bash ~/.hermes/scripts/wiki-snapshot.sh # Re-sync fresh
218
218
  ```
219
- **Prevention**: Avoid editing the GitHub repo directly via web interface or uncoordinated clones. The canonical flow is:
220
- - Server: rclone mount → rsync → git commit → git push
221
- - macOS/desktop: git pull edit git commit git push → server pulls on next cron
219
+ **Prevention**: Avoid editing the GitHub repo directly via web interface or uncoordinated clones. The canonical flow is **single-writer-git** (see `concepts/vault-write-authority-model.md`):
220
+ - Server (sg01): rclone mount → rsync → git commit "Snapshot ..." → git push — **sole git writer to `main`**
221
+ - macOS/desktop: edit`wiki-push` rclone copy to S3 (NO git push)consume sg01 snapshots via `wiki-fetch-notify` (opt-in `WIKI_FETCH_PULL_ON_DELTA=1`) or manual `skillwiki sync`
222
+ - `wiki-sync` skill push is for **explicit** agent/human edit commits only, not automated background pushes
222
223
  2. **Slow rsync on rclone mounts**: The rclone FUSE mount can be slow for large directory listings. Use `rsync -q` (quiet) to reduce output overhead, and consider `--delete-delay` instead of `--delete` if file churn is high. The rclone mount latency can cause `du` and `find` operations to timeout — this is normal, not an error.
223
224
  3. **Golden Rule violation**: Never mix sync methods on the same vault. If using rclone mount + git snapshotting, do NOT also enable Obsidian Sync, Syncthing, or iCloud on `~/wiki`. The rclone mount IS the sync mechanism.
224
225
  4. **Credential exposure**: The rclone mount and git remote use different credentials. Ensure git credentials are cached or use HTTPS with token, but never commit rclone config to git.