sticky-note-cli 3.1.11 → 3.1.12

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
@@ -95,9 +95,8 @@ function resolveHookPaths(_obj, _rootDir) {
95
95
  return;
96
96
  }
97
97
 
98
- // Detects hook commands in an existing settings.json that point at an absolute
99
- // path (likely written by an older sticky-note-cli on another developer's
100
- // machine). Returns the list of stale command strings, or [] if all clean.
98
+ // Detects hook commands in an existing settings.json that are broken or stale.
99
+ // Returns the list of stale command strings, or [] if all clean.
101
100
  function findStaleHookPaths(settings) {
102
101
  const stale = [];
103
102
  const hooks = (settings && settings.hooks) || {};
@@ -107,9 +106,6 @@ function findStaleHookPaths(settings) {
107
106
  const cmd = h && h.command;
108
107
  if (typeof cmd !== "string") continue;
109
108
  // Absolute paths (Unix /Users, /home, /root or Windows C:/, D:/ etc.)
110
- // inside the hook command are the smoking gun. Match anywhere in the
111
- // string — the path may be preceded by other tokens (env vars, shell
112
- // prefixes) and may contain spaces.
113
109
  if (
114
110
  /["'][A-Za-z]:[\\/]/.test(cmd) ||
115
111
  /["']\/(?:Users|home|root|tmp)\//.test(cmd) ||
@@ -117,12 +113,9 @@ function findStaleHookPaths(settings) {
117
113
  ) {
118
114
  stale.push(cmd);
119
115
  }
120
- // Old relative-path format: node ".claude/hooks/foo.js"
121
- // This fails when Claude Code launches from a subdirectory of the
122
- // project root, because the path resolves relative to the launch cwd,
123
- // not relative to where .claude/settings.json lives. The fix is to
124
- // use `npx sticky-note run-hook foo` which walks up to find the hooks.
125
- if (/node\s+["']\.claude[\\/]hooks[\\/][^"']+\.js["']/.test(cmd)) {
116
+ // Broken `npx sticky-note run-hook X` — npm has no package named "sticky-note"
117
+ // (the package is "sticky-note-cli"). Written by earlier 3.x releases.
118
+ if (/^npx\s+sticky-note\s+run-hook\s+\S+/.test(cmd)) {
126
119
  stale.push(cmd);
127
120
  }
128
121
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sticky-note-cli",
3
- "version": "3.1.11",
3
+ "version": "3.1.12",
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": {
@@ -157,13 +157,13 @@ function selfHealHookPaths(settingsPath) {
157
157
  try { settings = JSON.parse(raw); } catch (_) { return result; }
158
158
  if (!settings || !settings.hooks) return result;
159
159
 
160
- // Two stale patterns:
160
+ // Stale patterns that need rewriting to the canonical template format:
161
161
  // 1. Absolute paths (written by older sticky-note-cli or copied from another machine)
162
- // 2. Old relative form `node ".claude/hooks/foo.js"` — fails when Claude Code
163
- // launches from a subdirectory, because the path resolves relative to the
164
- // launch cwd, not the directory containing .claude/settings.json.
162
+ // 2. `npx sticky-note run-hook X` — broken: npm has no package named "sticky-note"
163
+ // (the package is "sticky-note-cli"). Written by earlier 3.x releases via the
164
+ // now-removed selfHeal rewrite. Canonical form is `node ".claude/hooks/X.js"`.
165
165
  const STALE_ABSOLUTE = /["'][A-Za-z]:[\\/]|["']\/(?:Users|home|root|tmp)\/|\$\(git rev-parse/;
166
- const STALE_RELATIVE = /^node\s+["']\.claude[\\/]hooks[\\/][^"']+\.js["']\s*$/;
166
+ const STALE_NPX = /^npx\s+sticky-note\s+run-hook\s+(\S+)/;
167
167
  // Match the script basename in either quoted or bare form.
168
168
  const BASENAME = /([A-Za-z0-9_.-]+)\.(?:js|sh|cjs|mjs)(?:["'`\s]|$)/;
169
169
 
@@ -174,12 +174,17 @@ function selfHealHookPaths(settingsPath) {
174
174
  for (const h of (entry && entry.hooks) || []) {
175
175
  const cmd = h && h.command;
176
176
  if (typeof cmd !== "string") continue;
177
- const isStale = STALE_ABSOLUTE.test(cmd) || STALE_RELATIVE.test(cmd);
178
- if (!isStale) continue;
179
- const m = cmd.match(BASENAME);
180
- if (!m) continue;
181
- const basename = m[1];
182
- const newCmd = `npx sticky-note run-hook ${basename}`;
177
+ let basename = null;
178
+ // Check for broken `npx sticky-note run-hook X` pattern first
179
+ const npxMatch = cmd.match(STALE_NPX);
180
+ if (npxMatch) {
181
+ basename = npxMatch[1];
182
+ } else if (STALE_ABSOLUTE.test(cmd)) {
183
+ const m = cmd.match(BASENAME);
184
+ if (m) basename = m[1];
185
+ }
186
+ if (!basename) continue;
187
+ const newCmd = `node ".claude/hooks/${basename}.js"`;
183
188
  result.push({ event, oldCommand: cmd, newCommand: newCmd });
184
189
  h.command = newCmd;
185
190
  changed = true;
@@ -192,9 +197,9 @@ function selfHealHookPaths(settingsPath) {
192
197
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
193
198
  try {
194
199
  const summary =
195
- `[STICKY-NOTE] ⚠️ Detected ${result.length} stale hook path(s) in ` +
200
+ `[STICKY-NOTE] ⚠️ Detected ${result.length} stale hook command(s) in ` +
196
201
  `${path.relative(process.cwd(), settingsPath) || settingsPath} — rewrote to ` +
197
- `"npx sticky-note run-hook <name>" so hooks work from any subdirectory. ` +
202
+ `"node \\".claude/hooks/<name>.js\\"" (canonical form). ` +
198
203
  `Commit the change to share the fix with your team.`;
199
204
  process.stderr.write(summary + "\n");
200
205
  for (const { event, oldCommand, newCommand } of result.slice(0, 5)) {