sticky-note-cli 2.7.3 → 2.8.1

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/bin/cli.js CHANGED
@@ -716,6 +716,18 @@ async function cmdInit() {
716
716
  print(" ⏭️ Could not set git alias (non-fatal)");
717
717
  }
718
718
 
719
+ // Add git alias for safe pull with auto-sync
720
+ try {
721
+ const spullAlias = '!f() { npx sticky-note pull "$@"; }; f';
722
+ execFileSync("git", ["config", "alias.spull", spullAlias], {
723
+ cwd: process.cwd(),
724
+ stdio: ["pipe", "pipe", "pipe"],
725
+ });
726
+ print(" [OK] git alias: git spull (auto-sync + pull)");
727
+ } catch (_) {
728
+ print(" ⏭️ Could not set git spull alias (non-fatal)");
729
+ }
730
+
719
731
  // Deploy AI instruction files (CLAUDE.md + .github/copilot-instructions.md)
720
732
  const claudeMdDest = path.join(process.cwd(), "CLAUDE.md");
721
733
  if (!fs.existsSync(claudeMdDest)) {
@@ -2477,6 +2489,50 @@ function cmdSync() {
2477
2489
  print("");
2478
2490
  }
2479
2491
 
2492
+ // ──────────────────────────────────────────────
2493
+ // PULL command — auto-sync + git pull
2494
+ // ──────────────────────────────────────────────
2495
+
2496
+ function cmdPull() {
2497
+ const args = process.argv.slice(3);
2498
+ const stickyDir = path.join(process.cwd(), ".sticky-note");
2499
+
2500
+ // Step 1: Sync .sticky-note/ changes if any
2501
+ if (fs.existsSync(stickyDir)) {
2502
+ try {
2503
+ const status = execSync(
2504
+ 'git status --porcelain -- ".sticky-note/sticky-note.json" ".sticky-note/audit/" ".sticky-note/presence/"',
2505
+ { encoding: "utf-8", cwd: process.cwd() }
2506
+ ).trim();
2507
+ if (status) {
2508
+ const guardPath = path.join(stickyDir, ".sticky-syncing");
2509
+ fs.writeFileSync(guardPath, process.pid.toString(), "utf-8");
2510
+ try {
2511
+ execFileSync("git", [
2512
+ "add", "--", ".sticky-note/sticky-note.json",
2513
+ ".sticky-note/audit/", ".sticky-note/presence/"
2514
+ ], { cwd: process.cwd(), timeout: 10000, stdio: ["pipe", "pipe", "pipe"] });
2515
+ execFileSync("git", [
2516
+ "commit", "--no-verify", "-m", "chore(sticky-note): sync thread data"
2517
+ ], { cwd: process.cwd(), timeout: 15000, stdio: ["pipe", "pipe", "pipe"] });
2518
+ print(" ✅ Auto-synced .sticky-note/ before pull");
2519
+ } finally {
2520
+ try { fs.unlinkSync(guardPath); } catch (_) {}
2521
+ }
2522
+ }
2523
+ } catch (_) {
2524
+ // Non-fatal — proceed with pull even if sync fails
2525
+ }
2526
+ }
2527
+
2528
+ // Step 2: Run git pull with any extra args
2529
+ try {
2530
+ execFileSync("git", ["pull", ...args], { stdio: "inherit", cwd: process.cwd() });
2531
+ } catch (err) {
2532
+ process.exit(err.status || 1);
2533
+ }
2534
+ }
2535
+
2480
2536
  // MCP-SERVER command — launch the stdio MCP server
2481
2537
  function cmdMcpServer() {
2482
2538
  const mcpServerPath = path.join(__dirname, "mcp-server.js");
@@ -3064,6 +3120,9 @@ async function main() {
3064
3120
  case "sync":
3065
3121
  cmdSync();
3066
3122
  break;
3123
+ case "pull":
3124
+ cmdPull();
3125
+ break;
3067
3126
  case "bootstrap":
3068
3127
  await cmdBootstrap();
3069
3128
  break;
@@ -3099,6 +3158,7 @@ async function main() {
3099
3158
  print(" overlap Detect file overlaps with open/stuck threads");
3100
3159
  print(" claim Claim ownership of files you're working on (--list, --clear)");
3101
3160
  print(" sync Commit .sticky-note/ changes to git (--push to also push)");
3161
+ print(" pull Auto-sync .sticky-note/ then git pull (alias: git spull)");
3102
3162
  print(" bootstrap Provision MCP servers with secrets from manifest");
3103
3163
  print(" env Environment management (status, add-server, add-plugin)");
3104
3164
  print(" mcp-server Launch the sticky-note MCP server (stdio JSON-RPC)");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sticky-note-cli",
3
- "version": "2.7.3",
3
+ "version": "2.8.1",
4
4
  "description": "Human-to-human handoff for AI coding assistants. Git-backed shared memory for Claude Code and Copilot CLI.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -186,6 +186,18 @@ after. A raw `git checkout` or `git switch` will fail if sticky-note
186
186
  files have uncommitted changes. The alias `git sw <branch>` also works
187
187
  if set up by `npx sticky-note init`.
188
188
 
189
+ ### Pulling changes
190
+
191
+ **IMPORTANT:** Before pulling remote changes, always use:
192
+ ```bash
193
+ npx sticky-note pull
194
+ ```
195
+ This auto-commits `.sticky-note/` tracking data before pulling, preventing
196
+ "local changes would be overwritten" errors. The alias `git spull` also
197
+ works if set up by `npx sticky-note init`. The PreToolUse hook handles
198
+ this automatically for AI tool calls, but prefer `git spull` when running
199
+ git commands directly.
200
+
189
201
  ### ⚠️ Overlap warnings
190
202
 
191
203
  Sticky-note detects when your files overlap with other teammates'
@@ -189,6 +189,18 @@ after. A raw `git checkout` or `git switch` will fail if sticky-note
189
189
  files have uncommitted changes. The alias `git sw <branch>` also works
190
190
  if set up by `npx sticky-note init`.
191
191
 
192
+ ### Pulling changes
193
+
194
+ **IMPORTANT:** Before pulling remote changes, always use:
195
+ ```bash
196
+ npx sticky-note pull
197
+ ```
198
+ This auto-commits `.sticky-note/` tracking data before pulling, preventing
199
+ "local changes would be overwritten" errors. The alias `git spull` also
200
+ works if set up by `npx sticky-note init`. The PreToolUse hook handles
201
+ this automatically for AI tool calls, but prefer `git spull` when running
202
+ git commands directly.
203
+
192
204
  ### ⚠️ Overlap warnings
193
205
 
194
206
  Sticky-note detects when your files overlap with other teammates'
@@ -66,6 +66,7 @@ const {
66
66
  getMemoryPath,
67
67
  loadJson,
68
68
  normalizeSep,
69
+ syncStickyNote,
69
70
  } = utils;
70
71
 
71
72
  // ── File path extraction from tool input ──────────────────
@@ -189,6 +190,17 @@ function main() {
189
190
 
190
191
  const sessionId = getSessionId(hookInput);
191
192
 
193
+ // ── Auto-sync before git pull/merge/rebase ──
194
+ // Prevents "local changes would be overwritten" errors for .sticky-note/ files
195
+ const toolName = (hookInput.tool_name || hookInput.toolName || "").toLowerCase();
196
+ if (toolName === "bash" || toolName === "shell" || toolName === "command") {
197
+ const toolInput = hookInput.tool_input || hookInput.input || hookInput.toolArgs || {};
198
+ const cmd = typeof toolInput === "string" ? toolInput : (toolInput.command || "");
199
+ if (/\bgit\s+(pull|merge|rebase|fetch)\b/.test(cmd)) {
200
+ try { syncStickyNote({}); } catch (_) {}
201
+ }
202
+ }
203
+
192
204
  // ── Overlap deny gate (Copilot CLI only) ──
193
205
  // Detect overlaps and deny on first tool call, keyed by COPILOT_LOADER_PID.
194
206
  const denyResult = _checkOverlapsAndDeny();