@trygocode/notify 0.6.6 → 0.6.7
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/README.md +14 -0
- package/dist/src/claude.js +3 -4
- package/dist/src/on_stop.js +43 -27
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -530,6 +530,20 @@ npm publish, real-device E2E), see
|
|
|
530
530
|
|
|
531
531
|
## Changelog
|
|
532
532
|
|
|
533
|
+
### 0.6.7
|
|
534
|
+
|
|
535
|
+
- **Notification project name now matches your IDE.** The per-turn completion
|
|
536
|
+
ping labels the notification with your **workspace folder name** (e.g.
|
|
537
|
+
`Cursor · OpenHandApp — Agent finished`) instead of the git `owner/repo`.
|
|
538
|
+
- **Fixed the `.cursor` project label.** When a stop hook ran without a piped
|
|
539
|
+
workspace path, the label derived from the hook's cwd (`~/.cursor`) and
|
|
540
|
+
rendered as “Cursor · .cursor” (the IDE name twice). `projectLabel` now walks
|
|
541
|
+
up past any leading-dot tooling dir (`.cursor`, `.git`, `.vscode`, …) and
|
|
542
|
+
stops at the home dir, so it never surfaces a tooling/home folder as the
|
|
543
|
+
project. When no real workspace folder is derivable it falls back to the git
|
|
544
|
+
repo name, and if even that is absent it shows the runtime alone
|
|
545
|
+
(`Cursor — Agent finished`) with no confusing suffix.
|
|
546
|
+
|
|
533
547
|
### 0.6.6
|
|
534
548
|
|
|
535
549
|
- **Claude questions are now classified by notification type.** Setup installs
|
package/dist/src/claude.js
CHANGED
|
@@ -67,10 +67,9 @@ export const CLAUDE_HOOK_COMMANDS = {
|
|
|
67
67
|
Notification: 'npx -y @trygocode/notify@latest on-notification --source claude_code --dedupe-key "$CLAUDE_SESSION_ID-notify" --quiet || true',
|
|
68
68
|
};
|
|
69
69
|
/**
|
|
70
|
-
* Claude `Notification` types that genuinely require the user's attention.
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* installs whose matcher is still empty until setup is rerun.
|
|
70
|
+
* Claude `Notification` types that genuinely require the user's attention. The
|
|
71
|
+
* dispatcher independently applies the same values as a defensive payload check
|
|
72
|
+
* for existing 0.6.5 installs whose matcher stays empty until setup reruns.
|
|
74
73
|
*
|
|
75
74
|
* Deliberately excluded: `auth_success`, `elicitation_complete`,
|
|
76
75
|
* `elicitation_response`, and `agent_completed`.
|
package/dist/src/on_stop.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
//
|
|
27
27
|
// Zero runtime deps — Node built-ins only, matching the package's zero-dep rule.
|
|
28
28
|
import path from "node:path";
|
|
29
|
+
import os from "node:os";
|
|
29
30
|
import { promises as fs } from "node:fs";
|
|
30
31
|
import { createHash } from "node:crypto";
|
|
31
32
|
import { resolveNotifySettings } from "./config.js";
|
|
@@ -223,42 +224,57 @@ function toPushSettings(settings) {
|
|
|
223
224
|
};
|
|
224
225
|
}
|
|
225
226
|
/**
|
|
226
|
-
* Resolve the `project` label for a per-turn ping (T-N4 / PRD §3.4).
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
227
|
+
* Resolve the `project` label for a per-turn ping (T-N4 / PRD §3.4).
|
|
228
|
+
*
|
|
229
|
+
* Preference order (user decision 2026-07-27):
|
|
230
|
+
* 1. The WORKSPACE FOLDER NAME — the cwd basename (e.g. "OpenHandApp"), which
|
|
231
|
+
* matches what the user sees in the IDE title bar / file explorer. We walk
|
|
232
|
+
* up past any leading-dot tooling dir (`.cursor`, `.git`, `.vscode`, …) so a
|
|
233
|
+
* hook that runs inside a config dir still names the real project folder,
|
|
234
|
+
* never "Cursor · .cursor". We also reject the user's HOME dir as a label
|
|
235
|
+
* (it is never a meaningful project name).
|
|
236
|
+
* 2. The git REPO NAME — the last segment of `repo_label` (`owner/repo` →
|
|
237
|
+
* `repo`), used only when the folder walk yields nothing usable. Also
|
|
238
|
+
* dot-guarded (a `.cursor` repo label must never surface).
|
|
239
|
+
* 3. `undefined` — no project word at all, so the caller renders the runtime
|
|
240
|
+
* alone ("Cursor — Agent finished"). This is the intentional fallback when
|
|
241
|
+
* there is genuinely no workspace/repo signal (a rare IDE edge case); it is
|
|
242
|
+
* strictly better than showing a confusing dir name.
|
|
232
243
|
*/
|
|
233
244
|
export function projectLabel(repo, cwd) {
|
|
234
|
-
const
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
// Fall back to the cwd basename — but SKIP tool/config dot-dirs. The stop hook
|
|
246
|
-
// can run with a cwd inside `.cursor` (or `.git`, `.vscode`, …), whose basename
|
|
247
|
-
// would otherwise become the project name and render as "Cursor · .cursor"
|
|
248
|
-
// (the IDE name shown twice). Walk up past any leading-dot segment to the first
|
|
249
|
-
// real project folder so the label is the actual repo dir, not its tooling dir.
|
|
245
|
+
const home = path.resolve(os.homedir());
|
|
246
|
+
// Directories that are never a meaningful project name, even if we land on
|
|
247
|
+
// them while walking up: the home dir itself and its parent chain (`/Users`,
|
|
248
|
+
// `/home`, filesystem root). Reaching any of these means "no project folder".
|
|
249
|
+
const isNonProjectDir = (d) => d === home || home === d + path.sep || home.startsWith(d + path.sep) || path.dirname(d) === d;
|
|
250
|
+
// (1) Prefer the workspace FOLDER name — walk up past leading-dot tooling dirs
|
|
251
|
+
// (`.cursor`, `.git`, `.vscode`, …) to the first REAL project folder. We STOP
|
|
252
|
+
// if we reach the home dir or any ancestor of it (so a hook run with cwd =
|
|
253
|
+
// `~/.cursor` and no workspace path bails to runtime-only rather than climbing
|
|
254
|
+
// into "Users"/"home"/root).
|
|
250
255
|
let dir = path.resolve(cwd);
|
|
251
|
-
for (let i = 0; i <
|
|
256
|
+
for (let i = 0; i < 8; i++) {
|
|
257
|
+
if (isNonProjectDir(dir))
|
|
258
|
+
break; // home / its ancestors / root → no folder label
|
|
252
259
|
const base = path.basename(dir).trim();
|
|
253
|
-
if (!base)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return base; // first non-dot folder wins
|
|
260
|
+
if (base && !base.startsWith(".")) {
|
|
261
|
+
return base; // first real (non-dot) project folder wins
|
|
262
|
+
}
|
|
257
263
|
const parent = path.dirname(dir);
|
|
258
264
|
if (parent === dir)
|
|
259
265
|
break; // no more parents
|
|
260
266
|
dir = parent;
|
|
261
267
|
}
|
|
268
|
+
// (2) Fall back to the git REPO name (last segment of `owner/repo`), dot-guarded.
|
|
269
|
+
const label = repo?.repo_label?.trim();
|
|
270
|
+
if (label) {
|
|
271
|
+
const lastSeg = label.replace(/\/+$/, "").split("/").pop()?.trim();
|
|
272
|
+
if (lastSeg && !lastSeg.startsWith("."))
|
|
273
|
+
return lastSeg;
|
|
274
|
+
if (!lastSeg && !label.startsWith("."))
|
|
275
|
+
return label;
|
|
276
|
+
}
|
|
277
|
+
// (3) No usable signal → runtime-only (undefined omits the project word).
|
|
262
278
|
return undefined;
|
|
263
279
|
}
|
|
264
280
|
/**
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Single source of truth for the CLI version. Keep in sync with package.json.
|
|
2
|
-
export const VERSION = "0.6.
|
|
2
|
+
export const VERSION = "0.6.7";
|
package/package.json
CHANGED