agent-dag 3.7.0 → 3.7.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.
@@ -40,7 +40,7 @@
40
40
  document.documentElement.setAttribute("data-theme", stored === "light" ? "light" : "dark");
41
41
  })();
42
42
  </script>
43
- <script type="module" crossorigin src="/assets/index-Bvo5gtk3.js"></script>
43
+ <script type="module" crossorigin src="/assets/index-Cc7GEg4Y.js"></script>
44
44
  <link rel="stylesheet" crossorigin href="/assets/index-ByAgTqB8.css">
45
45
  </head>
46
46
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-dag",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "Live deck of Claude Code and Codex agents — watch tool calls, token spend and every Claude Code subagent on one calm canvas. Run it with npx ccdeck.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,6 +31,12 @@
31
31
  "about a defect in the type, and the suite refuses both it and no space at",
32
32
  "all."
33
33
  ],
34
+ "3.7.1": [
35
+ {
36
+ "title": "\ud83d\udd14 The notifications now fire on the thing that actually stops your agent",
37
+ "body": "3.7.0 could tell you a session was waiting \u2014 but only when Claude Code asked permission to run a tool. If you work with permissions bypassed, that never happens, and the whole feature was silent for you. Measured on one real log: 1683 events, every one of them in bypassPermissions, and a single permission prompt in the entire history.\n\nWhat fires constantly on that setup is the other kind: the agent asking you a question and stopping for the answer. The deck was throwing those away \u2014 no amber chip, no row in the sidebar, no notification, and no \"notify me\" button, because the button only appears while something is actually blocked.\n\nNow they count. The card carries the question itself rather than a generic \"Your turn\" \u2014 \"paycore needs your input: merge both branches to main, or just one?\" \u2014 and so does the notification, on the desktop, whether the tab is behind something or not open at all.\n\nAn idle prompt still stays quiet: a turn that ended is not a session that is stuck, and a channel that cries wolf is one you switch off."
38
+ }
39
+ ],
34
40
  "3.7.0": [
35
41
  {
36
42
  "title": "\ud83d\udd14 The deck can reach you when you are not looking at it",
@@ -54,16 +54,31 @@ export const OFF_ENV = "AGENTS_DECK_NO_NOTIFY";
54
54
  */
55
55
  export const QUIET_MS = 2 * 60 * 1000;
56
56
 
57
- /** The one event that means a session has stopped and cannot start again
58
- * without a human. `idle_prompt` is the other kind CC emits and is deliberately
59
- * not here #348 measured 16 idle to 5 permission, and an idle prompt is a
60
- * turn that ended, not a session that is stuck. Three quarters noise is how a
61
- * notification channel gets muted, and a muted channel is worse than none
62
- * because the deck goes on believing it told somebody. */
63
- export function isPermissionPrompt(raw) {
57
+ /**
58
+ * The events that mean a session has stopped and cannot start again without a
59
+ * human. Two of the three kinds CC emits.
60
+ *
61
+ * `permission_prompt` it wants to run something and is waiting to be allowed.
62
+ *
63
+ * `agent_needs_input` — it asked a question and is waiting for the answer, with
64
+ * the question itself in `message`. This was missing, and its absence was not a
65
+ * small gap: on a machine running `bypassPermissions` Claude Code never asks to
66
+ * run anything, so `permission_prompt` essentially never fires and the desktop
67
+ * notification could not happen at all. Measured on one real log — 1683 events,
68
+ * every one of them bypassPermissions — a single permission prompt in the whole
69
+ * history against five of these.
70
+ *
71
+ * `idle_prompt` is deliberately still out: #348 measured 16 idle to 5
72
+ * permission, and an idle prompt is a turn that ended, not a session that is
73
+ * stuck. Three quarters noise is how a notification channel gets muted, and a
74
+ * muted channel is worse than none because the deck goes on believing it told
75
+ * somebody.
76
+ */
77
+ export function isBlockingPrompt(raw) {
64
78
  return !!raw
65
79
  && raw.hook_event_name === "Notification"
66
- && raw.notification_type === "permission_prompt";
80
+ && (raw.notification_type === "permission_prompt"
81
+ || raw.notification_type === "agent_needs_input");
67
82
  }
68
83
 
69
84
  /**
@@ -96,7 +111,7 @@ export function blockNotice(raw, product) {
96
111
  * notification — a channel that fires twelve times in a second is one the user
97
112
  * turns off within the minute:
98
113
  *
99
- * - a permission prompt, per `isPermissionPrompt`
114
+ * - a blocking prompt, per `isBlockingPrompt`
100
115
  * - NOTHING LISTENING. A page is a better surface than this in every way, so
101
116
  * wherever there is one, this stays out of the way.
102
117
  * - NOT A REPLAY. The server replays events.jsonl into itself at boot to
@@ -106,7 +121,7 @@ export function blockNotice(raw, product) {
106
121
  * - the session has not just been announced, per `QUIET_MS`.
107
122
  */
108
123
  export function shouldNotify(raw, { clients, replay, lastAt, now }) {
109
- if (!isPermissionPrompt(raw)) return false;
124
+ if (!isBlockingPrompt(raw)) return false;
110
125
  if (clients > 0) return false;
111
126
  if (replay) return false;
112
127
  if (lastAt != null && now - lastAt < QUIET_MS) return false;