claude-pager 0.3.7 → 0.3.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAY9D,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB;AA+BD,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,oUAyZlD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAa9D,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB;AA+BD,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,oUAgalD"}
@@ -10,6 +10,7 @@ const tracker_js_1 = require("../sessions/tracker.js");
10
10
  const helpers_js_1 = require("../sessions/helpers.js");
11
11
  const store_js_1 = require("../notes/store.js");
12
12
  const validation_js_1 = require("../utils/validation.js");
13
+ const log_js_1 = require("../utils/log.js");
13
14
  const node_crypto_1 = require("node:crypto");
14
15
  const routes_js_1 = require("../dashboard/routes.js");
15
16
  const sse_js_1 = require("../dashboard/sse.js");
@@ -55,9 +56,11 @@ async function createServer(deps) {
55
56
  const type = body.notification_type || body.type;
56
57
  const message = body.message;
57
58
  if (!(0, validation_js_1.isValidSessionId)(sessionId)) {
59
+ (0, log_js_1.logDaemon)('rejected', sessionId || '-', 'invalid-session-id');
58
60
  return reply.status(400).send({ error: 'Invalid session_id format' });
59
61
  }
60
62
  if (!(0, validation_js_1.isValidEventType)(type)) {
63
+ (0, log_js_1.logDaemon)('rejected', sessionId, `invalid-event-type=${type}`);
61
64
  return reply.status(400).send({ error: `Invalid event type: ${type}` });
62
65
  }
63
66
  const session = (0, tracker_js_1.getSession)(sessionId);
@@ -74,6 +77,7 @@ async function createServer(deps) {
74
77
  timestamp: Date.now(),
75
78
  };
76
79
  const shortId = (0, events_js_1.addPending)(event);
80
+ (0, log_js_1.logDaemon)('received', type, sessionId, event.id, `short=${shortId}`);
77
81
  (0, sse_js_1.broadcastSSE)('refresh');
78
82
  // Send to channel in background — don't block the hook response
79
83
  channel.send(event, shortId).then(result => {
@@ -107,9 +111,11 @@ async function createServer(deps) {
107
111
  }
108
112
  const ok = await injector.sendResponse(session, response, question.event.type);
109
113
  if (!ok) {
114
+ (0, log_js_1.logDaemon)('inject-failed', question.event.sessionId, question.event.id);
110
115
  return reply.status(500).send({ error: 'Failed to inject response' });
111
116
  }
112
117
  (0, events_js_1.removePending)(question.event.id);
118
+ (0, log_js_1.logDaemon)('resolved', question.event.sessionId, question.event.id, `via=respond`);
113
119
  return { ok: true, matched: question.shortId, injected: true };
114
120
  });
115
121
  // List pending questions
@@ -147,9 +153,11 @@ async function createServer(deps) {
147
153
  }
148
154
  const ok = await injector.sendResponse(session, response, question.event.type);
149
155
  if (!ok) {
156
+ (0, log_js_1.logDaemon)('inject-failed', question.event.sessionId, eventId);
150
157
  return reply.status(500).send({ error: 'Failed to inject response' });
151
158
  }
152
159
  (0, events_js_1.removePending)(eventId);
160
+ (0, log_js_1.logDaemon)('resolved', question.event.sessionId, eventId, `via=respond-to`);
153
161
  return { ok: true, eventId, injected: true };
154
162
  });
155
163
  // Send text directly to a session (used by dashboard for idle sessions)
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const DASHBOARD_HTML = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>claude-pager dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&display=swap\" rel=\"stylesheet\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n background: #0d1117;\n color: #c9d1d9;\n font-family: 'JetBrains Mono', monospace;\n min-height: 100vh;\n padding: 24px;\n }\n\n header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 32px;\n padding-bottom: 16px;\n border-bottom: 1px solid #21262d;\n }\n\n .logo {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .logo h1 {\n font-size: 22px;\n font-weight: 700;\n color: #f0f6fc;\n }\n\n .cursor {\n display: inline-block;\n width: 10px;\n height: 20px;\n background: #58a6ff;\n animation: blink 1s step-end infinite;\n vertical-align: middle;\n margin-left: 4px;\n }\n\n @keyframes blink {\n 50% { opacity: 0; }\n }\n\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .status-dot.connected { background: #3fb950; box-shadow: 0 0 6px #3fb950; }\n .status-dot.disconnected { background: #f85149; box-shadow: 0 0 6px #f85149; }\n\n .meta {\n font-size: 12px;\n color: #484f58;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .project {\n margin-bottom: 28px;\n }\n\n .project-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 12px;\n }\n\n .project-header h2 {\n font-size: 16px;\n font-weight: 600;\n color: #58a6ff;\n }\n\n .project-count {\n background: #21262d;\n color: #8b949e;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n .project-path {\n font-size: 11px;\n color: #484f58;\n margin-left: auto;\n }\n\n .pin-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 14px;\n opacity: 0.3;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .pin-btn:hover { opacity: 0.7; }\n .pin-btn.pinned { opacity: 1; }\n\n .dismiss-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n opacity: 0.25;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .dismiss-btn:hover { opacity: 0.8; color: #f85149; }\n\n .ci-row {\n display: flex;\n gap: 12px;\n margin-bottom: 12px;\n font-size: 11px;\n }\n\n .ci-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n border-radius: 12px;\n font-weight: 600;\n text-decoration: none;\n transition: opacity 0.2s;\n }\n\n .ci-badge:hover { opacity: 0.8; }\n\n .ci-badge.success { background: #0d2818; color: #3fb950; }\n .ci-badge.failed { background: #490202; color: #f85149; }\n .ci-badge.running { background: #0d419d; color: #58a6ff; animation: pulse 2s ease-in-out infinite; }\n .ci-badge.pending { background: #3d2e00; color: #d29922; }\n .ci-badge.canceled { background: #21262d; color: #8b949e; }\n .ci-badge.unknown { background: #21262d; color: #484f58; }\n\n .ci-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .ci-dot.success { background: #3fb950; }\n .ci-dot.failed { background: #f85149; }\n .ci-dot.running { background: #58a6ff; }\n .ci-dot.pending { background: #d29922; }\n .ci-dot.canceled { background: #8b949e; }\n .ci-dot.unknown { background: #484f58; }\n\n .sessions {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 12px;\n }\n\n .card {\n background: #161b22;\n border: 1px solid #21262d;\n border-radius: 8px;\n padding: 16px;\n transition: border-color 0.2s, box-shadow 0.2s, opacity 0.3s;\n }\n\n .card:hover {\n border-color: #388bfd44;\n box-shadow: 0 0 12px #388bfd22;\n }\n\n .card.stale {\n opacity: 0.45;\n border-style: dashed;\n }\n\n .card.stale:hover {\n opacity: 0.8;\n }\n\n .card.active {\n border-color: #388bfd44;\n border-left: 3px solid #58a6ff;\n }\n\n .card.alert {\n border-color: #f0883e44;\n border-left: 3px solid #f0883e;\n }\n\n .card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n\n .card-title {\n font-size: 14px;\n font-weight: 600;\n color: #f0f6fc;\n line-height: 1.3;\n flex: 1;\n margin-right: 8px;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n\n .card-title.expanded {\n -webkit-line-clamp: unset;\n overflow: visible;\n white-space: pre-wrap;\n }\n\n .expand-btn {\n background: none;\n border: none;\n color: #58a6ff;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n cursor: pointer;\n padding: 2px 0;\n opacity: 0.8;\n }\n\n .expand-btn:hover { opacity: 1; }\n\n .badge {\n font-size: 10px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 12px;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .badge.working {\n background: #0d419d;\n color: #58a6ff;\n animation: pulse 2s ease-in-out infinite;\n }\n\n .badge.waiting_permission {\n background: #5a1e02;\n color: #f0883e;\n }\n\n .badge.waiting_input {\n background: #3d2e00;\n color: #d29922;\n }\n\n .badge.idle {\n background: #21262d;\n color: #8b949e;\n }\n\n .badge.unknown {\n background: #21262d;\n color: #484f58;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n\n .pending-box {\n background: #1c1208;\n border: 1px solid #3d2e00;\n border-radius: 6px;\n padding: 8px 10px;\n margin-bottom: 10px;\n font-size: 12px;\n color: #d29922;\n }\n\n .pending-box .tool {\n color: #f0883e;\n font-weight: 600;\n }\n\n .pending-box .ago {\n color: #8b949e;\n float: right;\n }\n\n .action-row {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n }\n\n .action-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n font-weight: 600;\n padding: 4px 14px;\n border-radius: 6px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s, transform 0.1s;\n }\n\n .action-btn:hover { opacity: 0.85; }\n .action-btn:active { transform: scale(0.96); }\n\n .action-btn.allow {\n background: #238636;\n color: #ffffff;\n }\n\n .action-btn.deny {\n background: #da3633;\n color: #ffffff;\n }\n\n .action-btn.allow-all {\n background: #1f6feb;\n color: #ffffff;\n margin-left: auto;\n }\n\n .action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .reply-input {\n flex: 1;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid #30363d;\n background: #0d1117;\n color: #c9d1d9;\n outline: none;\n }\n\n .reply-input:focus {\n border-color: #58a6ff;\n }\n\n .git-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n margin-bottom: 6px;\n }\n\n .git-branch {\n color: #8b949e;\n }\n\n .git-branch::before {\n content: '\u2387 ';\n }\n\n .git-modified {\n color: #f85149;\n }\n\n .git-unpushed {\n color: #d29922;\n }\n\n .git-clean {\n color: #3fb950;\n }\n\n .needs-testing {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: #490202;\n color: #f85149;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .flag {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n letter-spacing: 0.3px;\n }\n\n .flag.ok {\n background: #0d2818;\n color: #3fb950;\n }\n\n .flag.pending {\n background: #3d2e00;\n color: #d29922;\n }\n\n .card-footer {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 8px;\n font-size: 10px;\n color: #484f58;\n }\n\n .card-footer .spacer {\n margin-left: auto;\n }\n\n .notes-panel {\n background: #1a1e2e;\n border: 1px solid #2d333b;\n border-radius: 8px;\n padding: 12px;\n min-width: 0;\n }\n\n .notes-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 600;\n color: #8b949e;\n }\n\n .notes-header .count {\n background: #2d333b;\n color: #c9d1d9;\n font-size: 10px;\n padding: 1px 7px;\n border-radius: 8px;\n }\n\n .note-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 4px;\n font-size: 12px;\n color: #c9d1d9;\n transition: background 0.15s;\n }\n\n .note-item:hover {\n background: #21262d;\n }\n\n .note-item .note-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: text;\n }\n\n .note-clock {\n font-size: 11px;\n cursor: default;\n flex-shrink: 0;\n }\n\n .note-thumb {\n width: 32px;\n height: 32px;\n object-fit: cover;\n border-radius: 4px;\n cursor: pointer;\n flex-shrink: 0;\n border: 1px solid #30363d;\n transition: transform 0.15s;\n }\n\n .note-thumb:hover {\n transform: scale(1.1);\n border-color: #58a6ff;\n }\n\n .note-lightbox {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n cursor: pointer;\n }\n\n .note-lightbox img {\n max-width: 90vw;\n max-height: 90vh;\n border-radius: 8px;\n box-shadow: 0 0 40px rgba(0,0,0,0.5);\n }\n\n .note-grip {\n cursor: grab;\n color: #484f58;\n font-size: 10px;\n user-select: none;\n }\n .note-item.dragging {\n opacity: 0.4;\n }\n .note-item.drag-over {\n border-top: 2px solid #58a6ff;\n margin-top: -2px;\n }\n .note-btn.move {\n background: none;\n color: #484f58;\n padding: 0 2px;\n font-size: 8px;\n min-width: 16px;\n }\n .note-btn.move:hover {\n color: #58a6ff;\n }\n .note-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s;\n }\n\n .note-btn:hover { opacity: 0.85; }\n\n .note-btn.send {\n background: #238636;\n color: #fff;\n }\n\n .note-btn.delete {\n background: #21262d;\n color: #8b949e;\n }\n\n .note-btn.delete:hover {\n background: #da3633;\n color: #fff;\n }\n\n .note-add-row {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n }\n\n .empty {\n text-align: center;\n padding: 60px 20px;\n color: #484f58;\n }\n\n .empty h2 {\n font-size: 18px;\n color: #8b949e;\n margin-bottom: 8px;\n }\n\n .empty p {\n font-size: 13px;\n }\n\n @media (max-width: 768px) {\n body { padding: 12px; }\n\n header { flex-direction: column; align-items: flex-start; gap: 8px; }\n\n .logo h1 { font-size: 18px; }\n\n .sessions {\n grid-template-columns: 1fr;\n gap: 10px;\n }\n\n .project-header {\n flex-wrap: wrap;\n }\n\n .project-path { display: none; }\n\n .card { padding: 12px; }\n\n .card-title { font-size: 13px; }\n\n .action-btn {\n padding: 8px 18px;\n font-size: 13px;\n }\n\n .reply-input {\n font-size: 13px;\n padding: 8px 10px;\n }\n\n .ci-row { flex-wrap: wrap; gap: 6px; }\n\n .pending-box { font-size: 11px; }\n\n .pending-box code { font-size: 9px; }\n }\n\n @media (max-width: 480px) {\n body { padding: 8px; }\n\n .logo h1 { font-size: 16px; }\n\n .badge { font-size: 9px; padding: 2px 6px; }\n\n .git-row { flex-wrap: wrap; gap: 6px; }\n\n .action-btn {\n padding: 10px 20px;\n font-size: 14px;\n }\n\n .action-btn.allow-all {\n width: 100%;\n text-align: center;\n }\n }\n\n .scanline {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: repeating-linear-gradient(\n 0deg,\n transparent,\n transparent 2px,\n rgba(0, 0, 0, 0.03) 2px,\n rgba(0, 0, 0, 0.03) 4px\n );\n z-index: 999;\n }\n </style>\n</head>\n<body>\n <div class=\"scanline\"></div>\n <header>\n <div class=\"logo\">\n <h1>claude-pager<span class=\"cursor\"></span></h1>\n </div>\n <div class=\"meta\">\n <button class=\"action-btn allow-all\" id=\"allowAllBtn\" style=\"display:none\" onclick=\"allowAll()\">Allow All</button>\n <span class=\"status-dot connected\" id=\"statusDot\"></span>\n <span id=\"lastUpdate\">connecting...</span>\n </div>\n </header>\n <main id=\"projects\"></main>\n\n <script>\n let data = null;\n const sentMessages = new Map(); // sessionId \u2192 { icon, text, at }\n\n function getPinnedOrder() {\n try { return JSON.parse(localStorage.getItem('dashboard-pin-order') || '[]'); }\n catch { return []; }\n }\n\n function savePinnedOrder(order) {\n localStorage.setItem('dashboard-pin-order', JSON.stringify(order));\n }\n\n function togglePin(name) {\n const order = getPinnedOrder();\n const idx = order.indexOf(name);\n if (idx >= 0) {\n order.splice(idx, 1);\n } else {\n order.push(name);\n }\n savePinnedOrder(order);\n if (data) render(data);\n }\n\n function sortProjects(projects) {\n const pinned = getPinnedOrder();\n return [...projects].sort((a, b) => {\n const aPin = pinned.indexOf(a.name);\n const bPin = pinned.indexOf(b.name);\n const aIsPinned = aPin >= 0;\n const bIsPinned = bPin >= 0;\n // Pinned projects first, in their pinned order\n if (aIsPinned && bIsPinned) return aPin - bPin;\n if (aIsPinned) return -1;\n if (bIsPinned) return 1;\n // Unpinned: keep the original sort (by state)\n return 0;\n });\n }\n\n function escapeHtml(s) {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function timeAgo(epochMs) {\n if (!epochMs) return 'unknown';\n const s = Math.floor((Date.now() - epochMs) / 1000);\n if (s < 10) return 'just now';\n if (s < 60) return s + 's ago';\n if (s < 3600) return Math.floor(s / 60) + 'm ago';\n if (s < 86400) return Math.floor(s / 3600) + 'h ago';\n return Math.floor(s / 86400) + 'd ago';\n }\n\n function noteAgeColor(epochMs) {\n const m = (Date.now() - epochMs) / 60000;\n if (m < 10) return '#3fb950'; // green \u2014 fresh\n if (m < 60) return '#d29922'; // yellow \u2014 aging\n if (m < 360) return '#f0883e'; // orange \u2014 old\n return '#f85149'; // red \u2014 stale\n }\n\n function formatToolInput(input) {\n if (!input) return '';\n const hasDiff = input.includes('--- old') && input.includes('+++ new');\n if (hasDiff) {\n const lines = input.slice(0, 800).split('\\n');\n const html = lines.map(line => {\n const escaped = escapeHtml(line);\n if (line.startsWith('+++ new')) return '<span style=\"color:#3fb950;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('--- old')) return '<span style=\"color:#f85149;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('+')) return '<span style=\"color:#3fb950\">' + escaped + '</span>';\n if (line.startsWith('-')) return '<span style=\"color:#f85149\">' + escaped + '</span>';\n return escaped;\n }).join('\\n');\n return '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + html + '</pre>';\n }\n return '<code style=\"font-size:10px;color:#8b949e;word-break:break-all\">' + escapeHtml(input.slice(0, 400)) + '</code>';\n }\n\n function stateLabel(state) {\n const labels = {\n working: 'Working',\n waiting_permission: 'Permission',\n waiting_input: 'Waiting',\n idle: 'Idle',\n unknown: '?',\n };\n return labels[state] || state;\n }\n\n function renderSession(s) {\n const ageMs = Date.now() - s.lastActivity;\n const isStale = (s.state === 'idle' || s.state === 'unknown') && ageMs > 2 * 3600_000;\n const isAlert = s.state === 'waiting_permission' || s.state === 'waiting_input';\n const isActive = s.state === 'working';\n const cardClass = isStale ? 'stale' : isAlert ? 'alert' : isActive ? 'active' : '';\n\n let pending = '';\n if (s.pendingQuestion) {\n const q = s.pendingQuestion;\n const isPermission = q.type === 'permission_prompt';\n const contextInfo = q.context\n ? '<div style=\"font-size:11px;color:#c9d1d9;margin-bottom:6px;white-space:pre-wrap\">' + escapeHtml(q.context.slice(-300)) + '</div>'\n : '';\n const toolInfo = q.toolName\n ? contextInfo + '<span class=\"tool\">' + escapeHtml(q.toolName) + '</span>' +\n (q.toolInput ? '<br>' + formatToolInput(q.toolInput) : '')\n : '<div style=\"font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto\">' + escapeHtml(q.message) + '</div>';\n\n const actions = isPermission\n ? `<div class=\"action-row\">\n <button class=\"action-btn allow\" onclick=\"respondTo('${q.eventId}', 'allow', this)\">\u2713 Allow</button>\n <button class=\"action-btn deny\" onclick=\"respondTo('${q.eventId}', 'deny', this)\">\u2717 Deny</button>\n </div>`\n : `<div class=\"action-row\" style=\"align-items:center\">\n <input type=\"text\" class=\"reply-input\" id=\"reply-${q.eventId}\" placeholder=\"Type a reply...\" onkeydown=\"if(event.key==='Enter')respondTo('${q.eventId}',this.value,this)\">\n <button class=\"action-btn allow\" onclick=\"respondTo('${q.eventId}',document.getElementById('reply-${q.eventId}').value,this)\">Send</button>\n </div>`;\n\n pending = `\n <div class=\"pending-box\">\n <span class=\"ago\">${timeAgo(Date.now() - q.agoSeconds * 1000)}</span>\n ${toolInfo}\n ${actions}\n </div>\n `;\n }\n\n const hasGit = s.git.branch !== 'unknown';\n\n const gitParts = [];\n if (hasGit) {\n gitParts.push('<span class=\"git-branch\">' + escapeHtml(s.git.branch) + '</span>');\n gitParts.push(s.git.modifiedFiles > 0\n ? '<span class=\"git-modified\">' + s.git.modifiedFiles + ' mod</span>'\n : '<span class=\"git-clean\">clean</span>');\n if (s.git.unpushedCommits > 0) gitParts.push('<span class=\"git-unpushed\">' + s.git.unpushedCommits + ' unpush</span>');\n gitParts.push(s.committed\n ? '<span class=\"flag ok\">\u2713 commit</span>'\n : '<span class=\"flag pending\">\u25CB uncommit</span>');\n gitParts.push(s.pushed\n ? '<span class=\"flag ok\">\u2713 push</span>'\n : '<span class=\"flag pending\">\u25CB unpush</span>');\n }\n\n // Show reply input for idle/waiting sessions without a pending question\n const idleInput = (!s.pendingQuestion && (s.state === 'idle' || s.state === 'waiting_input' || s.state === 'unknown'))\n ? `<div class=\"action-row\" style=\"margin-top:6px\">\n <input type=\"text\" class=\"reply-input\" id=\"idle-${s.sessionId}\" placeholder=\"Send a message...\" onkeydown=\"if(event.key==='Enter')sendToSession('${s.sessionId}',this.value,this)\">\n <button class=\"action-btn allow\" onclick=\"sendToSession('${s.sessionId}',document.getElementById('idle-${s.sessionId}').value,this)\">Send</button>\n </div>`\n : '';\n\n const titleId = 'title-' + s.sessionId.slice(0, 8);\n const longTitle = s.title.length > 80;\n const expandBtn = longTitle ? `<button class=\"expand-btn\" onclick=\"document.getElementById('${titleId}').classList.toggle('expanded');this.textContent=this.textContent==='...'?'\u25B2':'...'\">...</button>` : '';\n\n return `\n <div class=\"card ${cardClass}\">\n <div class=\"card-header\">\n <span class=\"card-title\" id=\"${titleId}\">${escapeHtml(s.title)}</span>\n <span class=\"badge ${s.state}\">${stateLabel(s.state)}</span>\n <button class=\"dismiss-btn\" onclick=\"dismissSession('${s.sessionId}')\" title=\"Dismiss session\">\uD83D\uDDD1</button>\n </div>\n ${expandBtn}\n ${(() => {\n const sent = sentMessages.get(s.sessionId);\n if (sent && Date.now() - sent.at < 300_000) {\n const label = sent.icon === '\u25B6' ? 'Working on' : 'Replied';\n return '<div style=\"background:#0d2818;border:1px solid #238636;border-radius:6px;padding:6px 10px;margin:8px 0;font-size:12px;color:#c9d1d9;white-space:pre-wrap\">'\n + '<span style=\"color:#3fb950;font-weight:600\">' + label + ' :</span> '\n + escapeHtml(sent.text.length > 150 ? sent.text.slice(0, 150) + '...' : sent.text) + '</div>';\n }\n return '';\n })()}\n ${pending}\n ${idleInput}\n <div class=\"card-footer\">\n ${gitParts.join(' ')}\n <span class=\"spacer\"></span>\n <span>pane ${escapeHtml(s.tmuxPane)}</span>\n <span>${timeAgo(s.lastActivity)}</span>\n </div>\n </div>\n `;\n }\n\n function renderPipeline(label, pipeline) {\n if (!pipeline) return '';\n const s = pipeline.status;\n const dot = '<span class=\"ci-dot ' + s + '\"></span>';\n const text = label + ': ' + s;\n if (pipeline.url) {\n return '<a class=\"ci-badge ' + s + '\" href=\"' + escapeHtml(pipeline.url) + '\" target=\"_blank\">' + dot + ' ' + text + '</a>';\n }\n return '<span class=\"ci-badge ' + s + '\">' + dot + ' ' + text + '</span>';\n }\n\n function renderCI(ci) {\n if (!ci) return '';\n const main = renderPipeline('main', ci.main);\n const staging = renderPipeline('staging', ci.staging);\n return main + staging;\n }\n\n function renderNotes(project, notes) {\n if (!notes || notes.length === 0) {\n return `\n <div class=\"notes-panel\">\n <div class=\"notes-header\">Notes</div>\n <div class=\"note-add-row\">\n <input type=\"text\" class=\"reply-input\" id=\"note-add-${escapeHtml(project)}\" placeholder=\"Add a note...\" onkeydown=\"if(event.key==='Enter')addNote('${escapeHtml(project)}',this.value,this)\" onpaste=\"handleNotePaste(event,'${escapeHtml(project)}')\">\n <button class=\"note-btn send\" onclick=\"var i=document.getElementById('note-add-${escapeHtml(project)}');addNote('${escapeHtml(project)}',i.value,i)\">+</button>\n </div>\n </div>\n `;\n }\n\n const items = notes.map((n, idx) => {\n const thumb = n.image\n ? '<img src=\"/api/v1/notes/images/' + escapeHtml(n.image) + '\" class=\"note-thumb\" onclick=\"openNoteImage(this.src)\" title=\"Click to enlarge\">'\n : '';\n return `\n <div class=\"note-item\" draggable=\"true\" data-note-id=\"${n.id}\" data-project=\"${escapeHtml(project)}\"\n ondragstart=\"onNoteDragStart(event)\" ondragover=\"onNoteDragOver(event)\" ondrop=\"onNoteDrop(event)\" ondragend=\"onNoteDragEnd(event)\">\n <span class=\"note-grip\" title=\"Drag to reorder\">\u283F</span>\n ${thumb}\n <span class=\"note-text\" title=\"${escapeHtml(n.text)}\" onclick=\"editNote(this,'${n.id}')\">${escapeHtml(n.text)}</span>\n <span class=\"note-clock\" title=\"${timeAgo(n.createdAt)}\" style=\"color:${noteAgeColor(n.createdAt)}\">\u23F1</span>\n ${idx > 0 ? '<button class=\"note-btn move\" onclick=\"moveNote(\\'' + escapeHtml(project) + '\\',' + idx + ',-1)\" title=\"Move up\">\u25B2</button>' : '<span class=\"note-btn move\" style=\"visibility:hidden\">\u25B2</span>'}\n ${idx < notes.length - 1 ? '<button class=\"note-btn move\" onclick=\"moveNote(\\'' + escapeHtml(project) + '\\',' + idx + ',1)\" title=\"Move down\">\u25BC</button>' : '<span class=\"note-btn move\" style=\"visibility:hidden\">\u25BC</span>'}\n <button class=\"note-btn send\" onclick=\"sendNote('${n.id}',this)\" title=\"Send to session\">\u25B6</button>\n <button class=\"note-btn delete\" onclick=\"deleteNote('${n.id}')\" title=\"Delete\">\u2715</button>\n </div>\n `}).join('');\n\n return `\n <div class=\"notes-panel\">\n <div class=\"notes-header\">\n <span>Notes</span>\n <span class=\"count\">${notes.length}</span>\n </div>\n ${items}\n <div class=\"note-add-row\">\n <input type=\"text\" class=\"reply-input\" id=\"note-add-${escapeHtml(project)}\" placeholder=\"Add a note...\" onkeydown=\"if(event.key==='Enter')addNote('${escapeHtml(project)}',this.value,this)\" onpaste=\"handleNotePaste(event,'${escapeHtml(project)}')\">\n <button class=\"note-btn send\" onclick=\"var i=document.getElementById('note-add-${escapeHtml(project)}');addNote('${escapeHtml(project)}',i.value,i)\">+</button>\n </div>\n </div>\n `;\n }\n\n function renderProject(p) {\n const isPinned = getPinnedOrder().includes(p.name);\n const anyNeedsTesting = p.sessions.some(s => s.needsTesting);\n const testBadge = anyNeedsTesting ? '<span class=\"needs-testing\">needs testing</span>' : '';\n const ciBadges = renderCI(p.ci);\n const infoRow = (ciBadges || testBadge) ? '<div class=\"ci-row\">' + ciBadges + testBadge + '</div>' : '';\n\n return `\n <div class=\"project\">\n <div class=\"project-header\">\n <button class=\"pin-btn ${isPinned ? 'pinned' : ''}\" onclick=\"togglePin('${escapeHtml(p.name)}')\" title=\"${isPinned ? 'Unpin' : 'Pin'}\">${isPinned ? '\uD83D\uDCCC' : '\uD83D\uDCCC'}</button>\n <h2>${escapeHtml(p.name)}</h2>\n <span class=\"project-count\">${p.sessions.length} session${p.sessions.length > 1 ? 's' : ''}</span>\n <span class=\"project-path\">${escapeHtml(p.path)}</span>\n </div>\n ${infoRow}\n <div class=\"sessions\">\n ${p.sessions.map(renderSession).join('')}\n ${renderNotes(p.name, p.notes)}\n </div>\n </div>\n `;\n }\n\n function countPending(data) {\n let count = 0;\n for (const p of data.projects) {\n for (const s of p.sessions) {\n if (s.pendingQuestion && s.pendingQuestion.type === 'permission_prompt') count++;\n }\n }\n return count;\n }\n\n function render(data) {\n const container = document.getElementById('projects');\n if (!data.projects || data.projects.length === 0) {\n container.innerHTML = `\n <div class=\"empty\">\n <h2>No active sessions</h2>\n <p>Start Claude Code in tmux and sessions will appear here.</p>\n </div>\n `;\n document.getElementById('allowAllBtn').style.display = 'none';\n return;\n }\n\n const pendingCount = countPending(data);\n const allowAllBtn = document.getElementById('allowAllBtn');\n if (pendingCount > 1) {\n allowAllBtn.style.display = 'inline-block';\n allowAllBtn.textContent = 'Allow All (' + pendingCount + ')';\n } else {\n allowAllBtn.style.display = 'none';\n }\n\n // Skip DOM update if user is focused on an input field\n const focused = document.activeElement;\n if (focused && focused.tagName === 'INPUT' && focused.classList.contains('reply-input')) return;\n\n // Preserve input values and cursor position across re-renders\n const savedInputs = new Map();\n const focusedId = focused?.id;\n const cursorPos = focused?.selectionStart;\n document.querySelectorAll('.reply-input').forEach(inp => {\n if (inp.id && inp.value.trim()) savedInputs.set(inp.id, inp.value);\n });\n const expandedTitles = new Set();\n document.querySelectorAll('.card-title.expanded').forEach(el => expandedTitles.add(el.id));\n\n container.innerHTML = sortProjects(data.projects).map(renderProject).join('');\n\n // Restore expanded titles\n expandedTitles.forEach(id => {\n const el = document.getElementById(id);\n if (el) {\n el.classList.add('expanded');\n const btn = el.parentElement?.querySelector('.expand-btn');\n if (btn) btn.textContent = '\u25B2';\n }\n });\n\n // Restore input values and focus\n savedInputs.forEach((val, id) => {\n const inp = document.getElementById(id);\n if (inp) inp.value = val;\n });\n if (focusedId) {\n const el = document.getElementById(focusedId);\n if (el) { el.focus(); if (cursorPos != null) el.selectionStart = el.selectionEnd = cursorPos; }\n }\n }\n\n function showSentBanner(card, icon, text, sessionId) {\n if (!card) return;\n // Track for persistent rendering across re-renders\n const sid = sessionId || card.querySelector('.card-title')?.id?.replace('title-', '');\n if (sid) {\n // Find full sessionId from data\n const fullId = data?.projects?.flatMap(p => p.sessions).find(s => s.sessionId.startsWith(sid))?.sessionId || sid;\n sentMessages.set(fullId, { icon, text, at: Date.now() });\n }\n }\n\n async function respondTo(eventId, response, btn) {\n if (btn) btn.disabled = true;\n const card = btn?.closest('.card');\n try {\n const res = await fetch('/api/v1/respond-to', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ eventId, response }),\n });\n if (res.ok) {\n const label = response === 'allow' ? '\u2713 Allowed' : response === 'deny' ? '\u2717 Denied' : response;\n showSentBanner(card, '\u21A9', label);\n fetchDashboard();\n } else {\n const err = await res.json();\n console.error('respond-to failed:', err);\n }\n } catch (e) {\n console.error('respond-to error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n async function dismissSession(sessionId) {\n try {\n await fetch('/api/v1/dismiss-session', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId }),\n });\n fetchDashboard();\n } catch (e) {\n console.error('dismiss error:', e);\n }\n }\n\n async function sendToSession(sessionId, text, btn) {\n if (!text || !text.trim()) return;\n if (btn) btn.disabled = true;\n const card = btn?.closest('.card');\n const input = card?.querySelector('input');\n if (input) { input.value = ''; input.blur(); }\n try {\n const res = await fetch('/api/v1/send-to', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, text: text.trim() }),\n });\n if (res.ok) {\n showSentBanner(card, '\u25B6', text.trim());\n fetchDashboard();\n } else {\n const err = await res.json();\n console.error('send-to failed:', err);\n }\n } catch (e) {\n console.error('send-to error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n let addingNote = false;\n async function addNote(project, text, input) {\n if (!text || !text.trim() || addingNote) return;\n addingNote = true;\n if (input) { input.value = ''; input.blur(); }\n try {\n await fetch('/api/v1/notes', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, text: text.trim(), source: 'dashboard' }),\n });\n fetchDashboard();\n } catch (e) {\n console.error('add-note error:', e);\n }\n addingNote = false;\n }\n\n async function handleNotePaste(event, project) {\n const items = event.clipboardData?.items;\n if (!items) return;\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const blob = item.getAsFile();\n if (!blob) return;\n const reader = new FileReader();\n reader.onload = async () => {\n const base64 = reader.result.split(',')[1];\n const text = event.target.value?.trim() || '';\n try {\n await fetch('/api/v1/notes/with-image', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, text: text || '(image)', imageBase64: base64, source: 'dashboard' }),\n });\n event.target.value = '';\n fetchDashboard();\n } catch (e) {\n console.error('paste-image error:', e);\n }\n };\n reader.readAsDataURL(blob);\n return;\n }\n }\n }\n\n function openNoteImage(src) {\n const lb = document.createElement('div');\n lb.className = 'note-lightbox';\n const img = document.createElement('img');\n img.src = src;\n lb.appendChild(img);\n lb.onclick = () => lb.remove();\n document.body.appendChild(lb);\n }\n\n function editNote(span, noteId) {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'reply-input';\n input.value = span.textContent;\n input.style.cssText = 'flex:1;font-size:12px;';\n span.replaceWith(input);\n input.focus();\n input.select();\n async function save() {\n const text = input.value.trim();\n if (text && text !== span.textContent) {\n await fetch('/api/v1/notes/' + noteId, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text }),\n });\n span.textContent = text;\n span.title = text;\n }\n input.replaceWith(span);\n }\n input.onblur = save;\n input.onkeydown = (e) => { if (e.key === 'Enter') { e.preventDefault(); save(); } if (e.key === 'Escape') input.replaceWith(span); };\n }\n\n async function deleteNote(noteId) {\n try {\n await fetch('/api/v1/notes/' + noteId, { method: 'DELETE' });\n fetchDashboard();\n } catch (e) {\n console.error('delete-note error:', e);\n }\n }\n\n async function sendNote(noteId, btn) {\n if (btn) btn.disabled = true;\n const noteText = btn?.closest('.note-item')?.querySelector('.note-text')?.textContent || '';\n try {\n const res = await fetch('/api/v1/notes/' + noteId + '/send', { method: 'POST' });\n const result = await res.json();\n if (!res.ok) {\n showToast(btn, result.error || 'Failed to send', true);\n } else {\n if (result.sessionId) {\n const card = document.querySelector('#title-' + result.sessionId.slice(0, 8))?.closest('.card');\n showSentBanner(card, '\u25B6', noteText);\n }\n showToast(btn, 'Sent', false);\n }\n fetchDashboard();\n } catch (e) {\n console.error('send-note error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n function getProjectNoteIds(project) {\n return Array.from(document.querySelectorAll('.note-item[data-project=\"' + project + '\"]'))\n .map(el => el.dataset.noteId);\n }\n\n async function saveNoteOrder(project) {\n const orderedIds = getProjectNoteIds(project);\n try {\n await fetch('/api/v1/notes/reorder', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, orderedIds }),\n });\n } catch (e) {\n console.error('reorder error:', e);\n }\n }\n\n function moveNote(project, idx, direction) {\n const items = document.querySelectorAll('.note-item[data-project=\"' + project + '\"]');\n const target = idx + direction;\n if (target < 0 || target >= items.length) return;\n const parent = items[0].parentNode;\n if (direction === -1) parent.insertBefore(items[idx], items[target]);\n else parent.insertBefore(items[target], items[idx]);\n saveNoteOrder(project);\n }\n\n let draggedNote = null;\n function onNoteDragStart(e) {\n draggedNote = e.currentTarget;\n draggedNote.classList.add('dragging');\n e.dataTransfer.effectAllowed = 'move';\n }\n function onNoteDragOver(e) {\n e.preventDefault();\n const item = e.currentTarget;\n if (item !== draggedNote) item.classList.add('drag-over');\n }\n function onNoteDrop(e) {\n e.preventDefault();\n const target = e.currentTarget;\n target.classList.remove('drag-over');\n if (!draggedNote || target === draggedNote) return;\n const parent = target.parentNode;\n const items = Array.from(parent.querySelectorAll('.note-item'));\n const fromIdx = items.indexOf(draggedNote);\n const toIdx = items.indexOf(target);\n if (fromIdx < toIdx) parent.insertBefore(draggedNote, target.nextSibling);\n else parent.insertBefore(draggedNote, target);\n saveNoteOrder(draggedNote.dataset.project);\n }\n function onNoteDragEnd(e) {\n document.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));\n if (draggedNote) draggedNote.classList.remove('dragging');\n draggedNote = null;\n }\n\n function showToast(anchor, text, isError) {\n const toast = document.createElement('span');\n toast.textContent = (isError ? '\u2717 ' : '\u2713 ') + text;\n toast.style.cssText = 'position:absolute;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:600;z-index:10;pointer-events:none;'\n + (isError ? 'background:#490202;color:#f85149;' : 'background:#0d2818;color:#3fb950;');\n if (anchor) {\n const rect = anchor.getBoundingClientRect();\n toast.style.left = rect.left + 'px';\n toast.style.top = (rect.top - 24) + 'px';\n } else {\n toast.style.right = '24px';\n toast.style.top = '70px';\n }\n document.body.appendChild(toast);\n setTimeout(() => toast.remove(), 2000);\n }\n\n async function allowAll() {\n if (!data) return;\n const pending = [];\n for (const p of data.projects) {\n for (const s of p.sessions) {\n if (s.pendingQuestion && s.pendingQuestion.type === 'permission_prompt') {\n pending.push(s.pendingQuestion);\n }\n }\n }\n for (const q of pending) {\n await respondTo(q.eventId, 'allow', null);\n }\n fetchDashboard();\n }\n\n async function fetchDashboard() {\n try {\n const res = await fetch('/api/v1/dashboard');\n data = await res.json();\n render(data);\n document.getElementById('statusDot').className = 'status-dot connected';\n document.getElementById('lastUpdate').textContent = 'updated ' + timeAgo(data.updatedAt);\n } catch {\n document.getElementById('statusDot').className = 'status-dot disconnected';\n document.getElementById('lastUpdate').textContent = 'disconnected';\n }\n }\n\n fetchDashboard();\n\n // SSE for instant push \u2014 polling as fallback\n let fallbackTimer = setInterval(fetchDashboard, 10000);\n function connectSSE() {\n const es = new EventSource('/api/v1/sse');\n es.addEventListener('refresh', () => fetchDashboard());\n es.onopen = () => {\n clearInterval(fallbackTimer);\n fallbackTimer = setInterval(fetchDashboard, 10000);\n };\n es.onerror = () => {\n es.close();\n clearInterval(fallbackTimer);\n fallbackTimer = setInterval(fetchDashboard, 2000);\n setTimeout(connectSSE, 3000);\n };\n }\n connectSSE();\n </script>\n</body>\n</html>";
1
+ export declare const DASHBOARD_HTML = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>claude-pager dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&display=swap\" rel=\"stylesheet\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n background: #0d1117;\n color: #c9d1d9;\n font-family: 'JetBrains Mono', monospace;\n min-height: 100vh;\n padding: 24px;\n }\n\n header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 32px;\n padding-bottom: 16px;\n border-bottom: 1px solid #21262d;\n }\n\n .logo {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .logo h1 {\n font-size: 22px;\n font-weight: 700;\n color: #f0f6fc;\n }\n\n .cursor {\n display: inline-block;\n width: 10px;\n height: 20px;\n background: #58a6ff;\n animation: blink 1s step-end infinite;\n vertical-align: middle;\n margin-left: 4px;\n }\n\n @keyframes blink {\n 50% { opacity: 0; }\n }\n\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .status-dot.connected { background: #3fb950; box-shadow: 0 0 6px #3fb950; }\n .status-dot.disconnected { background: #f85149; box-shadow: 0 0 6px #f85149; }\n\n .meta {\n font-size: 12px;\n color: #484f58;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .project {\n margin-bottom: 28px;\n }\n\n .project-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 12px;\n }\n\n .project-header h2 {\n font-size: 16px;\n font-weight: 600;\n color: #58a6ff;\n }\n\n .project-count {\n background: #21262d;\n color: #8b949e;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n .project-path {\n font-size: 11px;\n color: #484f58;\n margin-left: auto;\n }\n\n .pin-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 14px;\n opacity: 0.3;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .pin-btn:hover { opacity: 0.7; }\n .pin-btn.pinned { opacity: 1; }\n\n .dismiss-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n opacity: 0.25;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .dismiss-btn:hover { opacity: 0.8; color: #f85149; }\n\n .ci-row {\n display: flex;\n gap: 12px;\n margin-bottom: 12px;\n font-size: 11px;\n }\n\n .ci-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n border-radius: 12px;\n font-weight: 600;\n text-decoration: none;\n transition: opacity 0.2s;\n }\n\n .ci-badge:hover { opacity: 0.8; }\n\n .ci-badge.success { background: #0d2818; color: #3fb950; }\n .ci-badge.failed { background: #490202; color: #f85149; }\n .ci-badge.running { background: #0d419d; color: #58a6ff; animation: pulse 2s ease-in-out infinite; }\n .ci-badge.pending { background: #3d2e00; color: #d29922; }\n .ci-badge.canceled { background: #21262d; color: #8b949e; }\n .ci-badge.unknown { background: #21262d; color: #484f58; }\n\n .ci-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .ci-dot.success { background: #3fb950; }\n .ci-dot.failed { background: #f85149; }\n .ci-dot.running { background: #58a6ff; }\n .ci-dot.pending { background: #d29922; }\n .ci-dot.canceled { background: #8b949e; }\n .ci-dot.unknown { background: #484f58; }\n\n .sessions {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 12px;\n }\n\n .card {\n background: #161b22;\n border: 1px solid #21262d;\n border-radius: 8px;\n padding: 16px;\n transition: border-color 0.2s, box-shadow 0.2s, opacity 0.3s;\n }\n\n .card:hover {\n border-color: #388bfd44;\n box-shadow: 0 0 12px #388bfd22;\n }\n\n .card.stale {\n opacity: 0.45;\n border-style: dashed;\n }\n\n .card.stale:hover {\n opacity: 0.8;\n }\n\n .card.active {\n border-color: #388bfd44;\n border-left: 3px solid #58a6ff;\n }\n\n .card.alert {\n border-color: #f0883e44;\n border-left: 3px solid #f0883e;\n }\n\n .card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n\n .card-title {\n font-size: 14px;\n font-weight: 600;\n color: #f0f6fc;\n line-height: 1.3;\n flex: 1;\n margin-right: 8px;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n\n .card-title.expanded {\n -webkit-line-clamp: unset;\n overflow: visible;\n white-space: pre-wrap;\n }\n\n .expand-btn {\n background: none;\n border: none;\n color: #58a6ff;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n cursor: pointer;\n padding: 2px 0;\n opacity: 0.8;\n }\n\n .expand-btn:hover { opacity: 1; }\n\n .badge {\n font-size: 10px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 12px;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .badge.working {\n background: #0d419d;\n color: #58a6ff;\n animation: pulse 2s ease-in-out infinite;\n }\n\n .badge.waiting_permission {\n background: #5a1e02;\n color: #f0883e;\n }\n\n .badge.waiting_input {\n background: #3d2e00;\n color: #d29922;\n }\n\n .badge.idle {\n background: #21262d;\n color: #8b949e;\n }\n\n .badge.unknown {\n background: #21262d;\n color: #484f58;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n\n .pending-box {\n background: #1c1208;\n border: 1px solid #3d2e00;\n border-radius: 6px;\n padding: 8px 10px;\n margin-bottom: 10px;\n font-size: 12px;\n color: #d29922;\n }\n\n .pending-box .tool {\n color: #f0883e;\n font-weight: 600;\n }\n\n .pending-box .ago {\n color: #8b949e;\n float: right;\n }\n\n .action-row {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n }\n\n .action-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n font-weight: 600;\n padding: 4px 14px;\n border-radius: 6px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s, transform 0.1s;\n }\n\n .action-btn:hover { opacity: 0.85; }\n .action-btn:active { transform: scale(0.96); }\n\n .action-btn.allow {\n background: #238636;\n color: #ffffff;\n }\n\n .action-btn.deny {\n background: #da3633;\n color: #ffffff;\n }\n\n .action-btn.allow-all {\n background: #1f6feb;\n color: #ffffff;\n margin-left: auto;\n }\n\n .action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .reply-input {\n flex: 1;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid #30363d;\n background: #0d1117;\n color: #c9d1d9;\n outline: none;\n }\n\n .reply-input:focus {\n border-color: #58a6ff;\n }\n\n .git-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n margin-bottom: 6px;\n }\n\n .git-branch {\n color: #8b949e;\n }\n\n .git-branch::before {\n content: '\u2387 ';\n }\n\n .git-modified {\n color: #f85149;\n }\n\n .git-unpushed {\n color: #d29922;\n }\n\n .git-clean {\n color: #3fb950;\n }\n\n .needs-testing {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: #490202;\n color: #f85149;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .flag {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n letter-spacing: 0.3px;\n }\n\n .flag.ok {\n background: #0d2818;\n color: #3fb950;\n }\n\n .flag.pending {\n background: #3d2e00;\n color: #d29922;\n }\n\n .card-footer {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 8px;\n font-size: 10px;\n color: #484f58;\n }\n\n .card-footer .spacer {\n margin-left: auto;\n }\n\n .notes-panel {\n background: #1a1e2e;\n border: 1px solid #2d333b;\n border-radius: 8px;\n padding: 12px;\n min-width: 0;\n }\n\n .notes-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 600;\n color: #8b949e;\n }\n\n .notes-header .count {\n background: #2d333b;\n color: #c9d1d9;\n font-size: 10px;\n padding: 1px 7px;\n border-radius: 8px;\n }\n\n .note-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 4px;\n font-size: 12px;\n color: #c9d1d9;\n transition: background 0.15s;\n }\n\n .note-item:hover {\n background: #21262d;\n }\n\n .note-item .note-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: text;\n }\n\n .note-clock {\n font-size: 11px;\n cursor: default;\n flex-shrink: 0;\n }\n\n .note-thumb {\n width: 32px;\n height: 32px;\n object-fit: cover;\n border-radius: 4px;\n cursor: pointer;\n flex-shrink: 0;\n border: 1px solid #30363d;\n transition: transform 0.15s;\n }\n\n .note-thumb:hover {\n transform: scale(1.1);\n border-color: #58a6ff;\n }\n\n .note-lightbox {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n cursor: pointer;\n }\n\n .note-lightbox img {\n max-width: 90vw;\n max-height: 90vh;\n border-radius: 8px;\n box-shadow: 0 0 40px rgba(0,0,0,0.5);\n }\n\n .note-grip {\n cursor: grab;\n color: #484f58;\n font-size: 10px;\n user-select: none;\n }\n .note-item.dragging {\n opacity: 0.4;\n }\n .note-item.drag-over {\n border-top: 2px solid #58a6ff;\n margin-top: -2px;\n }\n .note-btn.move {\n background: none;\n color: #484f58;\n padding: 0 2px;\n font-size: 8px;\n min-width: 16px;\n }\n .note-btn.move:hover {\n color: #58a6ff;\n }\n .note-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s;\n }\n\n .note-btn:hover { opacity: 0.85; }\n\n .note-btn.send {\n background: #238636;\n color: #fff;\n }\n\n .note-btn.delete {\n background: #21262d;\n color: #8b949e;\n }\n\n .note-btn.delete:hover {\n background: #da3633;\n color: #fff;\n }\n\n .note-add-row {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n }\n\n .empty {\n text-align: center;\n padding: 60px 20px;\n color: #484f58;\n }\n\n .empty h2 {\n font-size: 18px;\n color: #8b949e;\n margin-bottom: 8px;\n }\n\n .empty p {\n font-size: 13px;\n }\n\n @media (max-width: 768px) {\n body { padding: 12px; }\n\n header { flex-direction: column; align-items: flex-start; gap: 8px; }\n\n .logo h1 { font-size: 18px; }\n\n .sessions {\n grid-template-columns: 1fr;\n gap: 10px;\n }\n\n .project-header {\n flex-wrap: wrap;\n }\n\n .project-path { display: none; }\n\n .card { padding: 12px; }\n\n .card-title { font-size: 13px; }\n\n .action-btn {\n padding: 8px 18px;\n font-size: 13px;\n }\n\n .reply-input {\n font-size: 13px;\n padding: 8px 10px;\n }\n\n .ci-row { flex-wrap: wrap; gap: 6px; }\n\n .pending-box { font-size: 11px; }\n\n .pending-box code { font-size: 9px; }\n }\n\n @media (max-width: 480px) {\n body { padding: 8px; }\n\n .logo h1 { font-size: 16px; }\n\n .badge { font-size: 9px; padding: 2px 6px; }\n\n .git-row { flex-wrap: wrap; gap: 6px; }\n\n .action-btn {\n padding: 10px 20px;\n font-size: 14px;\n }\n\n .action-btn.allow-all {\n width: 100%;\n text-align: center;\n }\n }\n\n .scanline {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: repeating-linear-gradient(\n 0deg,\n transparent,\n transparent 2px,\n rgba(0, 0, 0, 0.03) 2px,\n rgba(0, 0, 0, 0.03) 4px\n );\n z-index: 999;\n }\n </style>\n</head>\n<body>\n <div class=\"scanline\"></div>\n <header>\n <div class=\"logo\">\n <h1>claude-pager<span class=\"cursor\"></span></h1>\n </div>\n <div class=\"meta\">\n <button class=\"action-btn allow-all\" id=\"allowAllBtn\" style=\"display:none\" onclick=\"allowAll()\">Allow All</button>\n <span class=\"status-dot connected\" id=\"statusDot\"></span>\n <span id=\"lastUpdate\">connecting...</span>\n </div>\n </header>\n <main id=\"projects\"></main>\n\n <script>\n let data = null;\n const sentMessages = new Map(); // sessionId \u2192 { icon, text, at }\n\n function getPinnedOrder() {\n try { return JSON.parse(localStorage.getItem('dashboard-pin-order') || '[]'); }\n catch { return []; }\n }\n\n function savePinnedOrder(order) {\n localStorage.setItem('dashboard-pin-order', JSON.stringify(order));\n }\n\n function togglePin(name) {\n const order = getPinnedOrder();\n const idx = order.indexOf(name);\n if (idx >= 0) {\n order.splice(idx, 1);\n } else {\n order.push(name);\n }\n savePinnedOrder(order);\n if (data) render(data);\n }\n\n function sortProjects(projects) {\n const pinned = getPinnedOrder();\n return [...projects].sort((a, b) => {\n const aPin = pinned.indexOf(a.name);\n const bPin = pinned.indexOf(b.name);\n const aIsPinned = aPin >= 0;\n const bIsPinned = bPin >= 0;\n // Pinned projects first, in their pinned order\n if (aIsPinned && bIsPinned) return aPin - bPin;\n if (aIsPinned) return -1;\n if (bIsPinned) return 1;\n // Unpinned: keep the original sort (by state)\n return 0;\n });\n }\n\n function escapeHtml(s) {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function timeAgo(epochMs) {\n if (!epochMs) return 'unknown';\n const s = Math.floor((Date.now() - epochMs) / 1000);\n if (s < 10) return 'just now';\n if (s < 60) return s + 's ago';\n if (s < 3600) return Math.floor(s / 60) + 'm ago';\n if (s < 86400) return Math.floor(s / 3600) + 'h ago';\n return Math.floor(s / 86400) + 'd ago';\n }\n\n function noteAgeColor(epochMs) {\n const m = (Date.now() - epochMs) / 60000;\n if (m < 10) return '#3fb950'; // green \u2014 fresh\n if (m < 60) return '#d29922'; // yellow \u2014 aging\n if (m < 360) return '#f0883e'; // orange \u2014 old\n return '#f85149'; // red \u2014 stale\n }\n\n function formatToolInput(input) {\n if (!input) return '';\n const hasDiff = input.includes('--- old') && input.includes('+++ new');\n if (hasDiff) {\n const lines = input.slice(0, 800).split('\\n');\n const html = lines.map(line => {\n const escaped = escapeHtml(line);\n if (line.startsWith('+++ new')) return '<span style=\"color:#3fb950;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('--- old')) return '<span style=\"color:#f85149;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('+')) return '<span style=\"color:#3fb950\">' + escaped + '</span>';\n if (line.startsWith('-')) return '<span style=\"color:#f85149\">' + escaped + '</span>';\n return escaped;\n }).join('\\n');\n return '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + html + '</pre>';\n }\n return '<code style=\"font-size:10px;color:#8b949e;word-break:break-all\">' + escapeHtml(input.slice(0, 400)) + '</code>';\n }\n\n function stateLabel(state) {\n const labels = {\n working: 'Working',\n waiting_permission: 'Permission',\n waiting_input: 'Waiting',\n idle: 'Idle',\n unknown: '?',\n };\n return labels[state] || state;\n }\n\n function renderSession(s) {\n const ageMs = Date.now() - s.lastActivity;\n const isStale = (s.state === 'idle' || s.state === 'unknown') && ageMs > 2 * 3600_000;\n const isAlert = s.state === 'waiting_permission' || s.state === 'waiting_input';\n const isActive = s.state === 'working';\n const cardClass = isStale ? 'stale' : isAlert ? 'alert' : isActive ? 'active' : '';\n\n let pending = '';\n if (s.pendingQuestion) {\n const q = s.pendingQuestion;\n const isPermission = q.type === 'permission_prompt';\n const contextInfo = q.context\n ? '<div style=\"font-size:11px;color:#c9d1d9;margin-bottom:6px;white-space:pre-wrap\">' + escapeHtml(q.context.slice(-300)) + '</div>'\n : '';\n const toolInfo = q.toolName\n ? contextInfo + '<span class=\"tool\">' + escapeHtml(q.toolName) + '</span>' +\n (q.toolInput ? '<br>' + formatToolInput(q.toolInput) : '')\n : '<div class=\"prompt-msg\" style=\"font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto\">' + escapeHtml(q.message) + '</div>';\n\n const actions = isPermission\n ? `<div class=\"action-row\">\n <button class=\"action-btn allow\" onclick=\"respondTo('${q.eventId}', 'allow', this)\">\u2713 Allow</button>\n <button class=\"action-btn deny\" onclick=\"respondTo('${q.eventId}', 'deny', this)\">\u2717 Deny</button>\n </div>`\n : `<div class=\"action-row\" style=\"align-items:center\">\n <input type=\"text\" class=\"reply-input\" id=\"reply-${q.eventId}\" placeholder=\"Type a reply...\" onkeydown=\"if(event.key==='Enter')respondTo('${q.eventId}',this.value,this)\">\n <button class=\"action-btn allow\" onclick=\"respondTo('${q.eventId}',document.getElementById('reply-${q.eventId}').value,this)\">Send</button>\n </div>`;\n\n pending = `\n <div class=\"pending-box\">\n <span class=\"ago\">${timeAgo(Date.now() - q.agoSeconds * 1000)}</span>\n ${toolInfo}\n ${actions}\n </div>\n `;\n }\n\n const hasGit = s.git.branch !== 'unknown';\n\n const gitParts = [];\n if (hasGit) {\n gitParts.push('<span class=\"git-branch\">' + escapeHtml(s.git.branch) + '</span>');\n gitParts.push(s.git.modifiedFiles > 0\n ? '<span class=\"git-modified\">' + s.git.modifiedFiles + ' mod</span>'\n : '<span class=\"git-clean\">clean</span>');\n if (s.git.unpushedCommits > 0) gitParts.push('<span class=\"git-unpushed\">' + s.git.unpushedCommits + ' unpush</span>');\n gitParts.push(s.committed\n ? '<span class=\"flag ok\">\u2713 commit</span>'\n : '<span class=\"flag pending\">\u25CB uncommit</span>');\n gitParts.push(s.pushed\n ? '<span class=\"flag ok\">\u2713 push</span>'\n : '<span class=\"flag pending\">\u25CB unpush</span>');\n }\n\n // Show reply input for idle/waiting sessions without a pending question\n const idleInput = (!s.pendingQuestion && (s.state === 'idle' || s.state === 'waiting_input' || s.state === 'unknown'))\n ? `<div class=\"action-row\" style=\"margin-top:6px\">\n <input type=\"text\" class=\"reply-input\" id=\"idle-${s.sessionId}\" placeholder=\"Send a message...\" onkeydown=\"if(event.key==='Enter')sendToSession('${s.sessionId}',this.value,this)\">\n <button class=\"action-btn allow\" onclick=\"sendToSession('${s.sessionId}',document.getElementById('idle-${s.sessionId}').value,this)\">Send</button>\n </div>`\n : '';\n\n const titleId = 'title-' + s.sessionId.slice(0, 8);\n const longTitle = s.title.length > 80;\n const expandBtn = longTitle ? `<button class=\"expand-btn\" onclick=\"document.getElementById('${titleId}').classList.toggle('expanded');this.textContent=this.textContent==='...'?'\u25B2':'...'\">...</button>` : '';\n\n return `\n <div class=\"card ${cardClass}\">\n <div class=\"card-header\">\n <span class=\"card-title\" id=\"${titleId}\">${escapeHtml(s.title)}</span>\n <span class=\"badge ${s.state}\">${stateLabel(s.state)}</span>\n <button class=\"dismiss-btn\" onclick=\"dismissSession('${s.sessionId}')\" title=\"Dismiss session\">\uD83D\uDDD1</button>\n </div>\n ${expandBtn}\n ${(() => {\n const sent = sentMessages.get(s.sessionId);\n if (sent && Date.now() - sent.at < 300_000) {\n const label = sent.icon === '\u25B6' ? 'Working on' : 'Replied';\n return '<div style=\"background:#0d2818;border:1px solid #238636;border-radius:6px;padding:6px 10px;margin:8px 0;font-size:12px;color:#c9d1d9;white-space:pre-wrap\">'\n + '<span style=\"color:#3fb950;font-weight:600\">' + label + ' :</span> '\n + escapeHtml(sent.text.length > 150 ? sent.text.slice(0, 150) + '...' : sent.text) + '</div>';\n }\n return '';\n })()}\n ${pending}\n ${idleInput}\n <div class=\"card-footer\">\n ${gitParts.join(' ')}\n <span class=\"spacer\"></span>\n <span>pane ${escapeHtml(s.tmuxPane)}</span>\n <span>${timeAgo(s.lastActivity)}</span>\n </div>\n </div>\n `;\n }\n\n function renderPipeline(label, pipeline) {\n if (!pipeline) return '';\n const s = pipeline.status;\n const dot = '<span class=\"ci-dot ' + s + '\"></span>';\n const text = label + ': ' + s;\n if (pipeline.url) {\n return '<a class=\"ci-badge ' + s + '\" href=\"' + escapeHtml(pipeline.url) + '\" target=\"_blank\">' + dot + ' ' + text + '</a>';\n }\n return '<span class=\"ci-badge ' + s + '\">' + dot + ' ' + text + '</span>';\n }\n\n function renderCI(ci) {\n if (!ci) return '';\n const main = renderPipeline('main', ci.main);\n const staging = renderPipeline('staging', ci.staging);\n return main + staging;\n }\n\n function renderNotes(project, notes) {\n if (!notes || notes.length === 0) {\n return `\n <div class=\"notes-panel\">\n <div class=\"notes-header\">Notes</div>\n <div class=\"note-add-row\">\n <input type=\"text\" class=\"reply-input\" id=\"note-add-${escapeHtml(project)}\" placeholder=\"Add a note...\" onkeydown=\"if(event.key==='Enter')addNote('${escapeHtml(project)}',this.value,this)\" onpaste=\"handleNotePaste(event,'${escapeHtml(project)}')\">\n <button class=\"note-btn send\" onclick=\"var i=document.getElementById('note-add-${escapeHtml(project)}');addNote('${escapeHtml(project)}',i.value,i)\">+</button>\n </div>\n </div>\n `;\n }\n\n const items = notes.map((n, idx) => {\n const thumb = n.image\n ? '<img src=\"/api/v1/notes/images/' + escapeHtml(n.image) + '\" class=\"note-thumb\" onclick=\"openNoteImage(this.src)\" title=\"Click to enlarge\">'\n : '';\n return `\n <div class=\"note-item\" draggable=\"true\" data-note-id=\"${n.id}\" data-project=\"${escapeHtml(project)}\"\n ondragstart=\"onNoteDragStart(event)\" ondragover=\"onNoteDragOver(event)\" ondrop=\"onNoteDrop(event)\" ondragend=\"onNoteDragEnd(event)\">\n <span class=\"note-grip\" title=\"Drag to reorder\">\u283F</span>\n ${thumb}\n <span class=\"note-text\" title=\"${escapeHtml(n.text)}\" onclick=\"editNote(this,'${n.id}')\">${escapeHtml(n.text)}</span>\n <span class=\"note-clock\" title=\"${timeAgo(n.createdAt)}\" style=\"color:${noteAgeColor(n.createdAt)}\">\u23F1</span>\n ${idx > 0 ? '<button class=\"note-btn move\" onclick=\"moveNote(\\'' + escapeHtml(project) + '\\',' + idx + ',-1)\" title=\"Move up\">\u25B2</button>' : '<span class=\"note-btn move\" style=\"visibility:hidden\">\u25B2</span>'}\n ${idx < notes.length - 1 ? '<button class=\"note-btn move\" onclick=\"moveNote(\\'' + escapeHtml(project) + '\\',' + idx + ',1)\" title=\"Move down\">\u25BC</button>' : '<span class=\"note-btn move\" style=\"visibility:hidden\">\u25BC</span>'}\n <button class=\"note-btn send\" onclick=\"sendNote('${n.id}',this)\" title=\"Send to session\">\u25B6</button>\n <button class=\"note-btn delete\" onclick=\"deleteNote('${n.id}')\" title=\"Delete\">\u2715</button>\n </div>\n `}).join('');\n\n return `\n <div class=\"notes-panel\">\n <div class=\"notes-header\">\n <span>Notes</span>\n <span class=\"count\">${notes.length}</span>\n </div>\n ${items}\n <div class=\"note-add-row\">\n <input type=\"text\" class=\"reply-input\" id=\"note-add-${escapeHtml(project)}\" placeholder=\"Add a note...\" onkeydown=\"if(event.key==='Enter')addNote('${escapeHtml(project)}',this.value,this)\" onpaste=\"handleNotePaste(event,'${escapeHtml(project)}')\">\n <button class=\"note-btn send\" onclick=\"var i=document.getElementById('note-add-${escapeHtml(project)}');addNote('${escapeHtml(project)}',i.value,i)\">+</button>\n </div>\n </div>\n `;\n }\n\n function renderProject(p) {\n const isPinned = getPinnedOrder().includes(p.name);\n const anyNeedsTesting = p.sessions.some(s => s.needsTesting);\n const testBadge = anyNeedsTesting ? '<span class=\"needs-testing\">needs testing</span>' : '';\n const ciBadges = renderCI(p.ci);\n const infoRow = (ciBadges || testBadge) ? '<div class=\"ci-row\">' + ciBadges + testBadge + '</div>' : '';\n\n return `\n <div class=\"project\">\n <div class=\"project-header\">\n <button class=\"pin-btn ${isPinned ? 'pinned' : ''}\" onclick=\"togglePin('${escapeHtml(p.name)}')\" title=\"${isPinned ? 'Unpin' : 'Pin'}\">${isPinned ? '\uD83D\uDCCC' : '\uD83D\uDCCC'}</button>\n <h2>${escapeHtml(p.name)}</h2>\n <span class=\"project-count\">${p.sessions.length} session${p.sessions.length > 1 ? 's' : ''}</span>\n <span class=\"project-path\">${escapeHtml(p.path)}</span>\n </div>\n ${infoRow}\n <div class=\"sessions\">\n ${p.sessions.map(renderSession).join('')}\n ${renderNotes(p.name, p.notes)}\n </div>\n </div>\n `;\n }\n\n function countPending(data) {\n let count = 0;\n for (const p of data.projects) {\n for (const s of p.sessions) {\n if (s.pendingQuestion && s.pendingQuestion.type === 'permission_prompt') count++;\n }\n }\n return count;\n }\n\n function render(data) {\n const container = document.getElementById('projects');\n if (!data.projects || data.projects.length === 0) {\n container.innerHTML = `\n <div class=\"empty\">\n <h2>No active sessions</h2>\n <p>Start Claude Code in tmux and sessions will appear here.</p>\n </div>\n `;\n document.getElementById('allowAllBtn').style.display = 'none';\n return;\n }\n\n const pendingCount = countPending(data);\n const allowAllBtn = document.getElementById('allowAllBtn');\n if (pendingCount > 1) {\n allowAllBtn.style.display = 'inline-block';\n allowAllBtn.textContent = 'Allow All (' + pendingCount + ')';\n } else {\n allowAllBtn.style.display = 'none';\n }\n\n // Skip DOM update if user is focused on an input field\n const focused = document.activeElement;\n if (focused && focused.tagName === 'INPUT' && focused.classList.contains('reply-input')) return;\n\n // Preserve input values and cursor position across re-renders\n const savedInputs = new Map();\n const focusedId = focused?.id;\n const cursorPos = focused?.selectionStart;\n document.querySelectorAll('.reply-input').forEach(inp => {\n if (inp.id && inp.value.trim()) savedInputs.set(inp.id, inp.value);\n });\n const expandedTitles = new Set();\n document.querySelectorAll('.card-title.expanded').forEach(el => expandedTitles.add(el.id));\n\n container.innerHTML = sortProjects(data.projects).map(renderProject).join('');\n\n // Autoscroll prompt messages to bottom \u2014 Claude puts the actual question\n // at the end of an idle_prompt, so reveal that part on render.\n document.querySelectorAll('.prompt-msg').forEach(el => { el.scrollTop = el.scrollHeight; });\n\n // Restore expanded titles\n expandedTitles.forEach(id => {\n const el = document.getElementById(id);\n if (el) {\n el.classList.add('expanded');\n const btn = el.parentElement?.querySelector('.expand-btn');\n if (btn) btn.textContent = '\u25B2';\n }\n });\n\n // Restore input values and focus\n savedInputs.forEach((val, id) => {\n const inp = document.getElementById(id);\n if (inp) inp.value = val;\n });\n if (focusedId) {\n const el = document.getElementById(focusedId);\n if (el) { el.focus(); if (cursorPos != null) el.selectionStart = el.selectionEnd = cursorPos; }\n }\n }\n\n function showSentBanner(card, icon, text, sessionId) {\n if (!card) return;\n // Track for persistent rendering across re-renders\n const sid = sessionId || card.querySelector('.card-title')?.id?.replace('title-', '');\n if (sid) {\n // Find full sessionId from data\n const fullId = data?.projects?.flatMap(p => p.sessions).find(s => s.sessionId.startsWith(sid))?.sessionId || sid;\n sentMessages.set(fullId, { icon, text, at: Date.now() });\n }\n }\n\n async function respondTo(eventId, response, btn) {\n if (btn) btn.disabled = true;\n const card = btn?.closest('.card');\n try {\n const res = await fetch('/api/v1/respond-to', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ eventId, response }),\n });\n if (res.ok) {\n const label = response === 'allow' ? '\u2713 Allowed' : response === 'deny' ? '\u2717 Denied' : response;\n showSentBanner(card, '\u21A9', label);\n fetchDashboard();\n } else {\n const err = await res.json();\n console.error('respond-to failed:', err);\n }\n } catch (e) {\n console.error('respond-to error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n async function dismissSession(sessionId) {\n try {\n await fetch('/api/v1/dismiss-session', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId }),\n });\n fetchDashboard();\n } catch (e) {\n console.error('dismiss error:', e);\n }\n }\n\n async function sendToSession(sessionId, text, btn) {\n if (!text || !text.trim()) return;\n if (btn) btn.disabled = true;\n const card = btn?.closest('.card');\n const input = card?.querySelector('input');\n if (input) { input.value = ''; input.blur(); }\n try {\n const res = await fetch('/api/v1/send-to', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, text: text.trim() }),\n });\n if (res.ok) {\n showSentBanner(card, '\u25B6', text.trim());\n fetchDashboard();\n } else {\n const err = await res.json();\n console.error('send-to failed:', err);\n }\n } catch (e) {\n console.error('send-to error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n let addingNote = false;\n async function addNote(project, text, input) {\n if (!text || !text.trim() || addingNote) return;\n addingNote = true;\n if (input) { input.value = ''; input.blur(); }\n try {\n await fetch('/api/v1/notes', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, text: text.trim(), source: 'dashboard' }),\n });\n fetchDashboard();\n } catch (e) {\n console.error('add-note error:', e);\n }\n addingNote = false;\n }\n\n async function handleNotePaste(event, project) {\n const items = event.clipboardData?.items;\n if (!items) return;\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const blob = item.getAsFile();\n if (!blob) return;\n const reader = new FileReader();\n reader.onload = async () => {\n const base64 = reader.result.split(',')[1];\n const text = event.target.value?.trim() || '';\n try {\n await fetch('/api/v1/notes/with-image', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, text: text || '(image)', imageBase64: base64, source: 'dashboard' }),\n });\n event.target.value = '';\n fetchDashboard();\n } catch (e) {\n console.error('paste-image error:', e);\n }\n };\n reader.readAsDataURL(blob);\n return;\n }\n }\n }\n\n function openNoteImage(src) {\n const lb = document.createElement('div');\n lb.className = 'note-lightbox';\n const img = document.createElement('img');\n img.src = src;\n lb.appendChild(img);\n lb.onclick = () => lb.remove();\n document.body.appendChild(lb);\n }\n\n function editNote(span, noteId) {\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'reply-input';\n input.value = span.textContent;\n input.style.cssText = 'flex:1;font-size:12px;';\n span.replaceWith(input);\n input.focus();\n input.select();\n async function save() {\n const text = input.value.trim();\n if (text && text !== span.textContent) {\n await fetch('/api/v1/notes/' + noteId, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ text }),\n });\n span.textContent = text;\n span.title = text;\n }\n input.replaceWith(span);\n }\n input.onblur = save;\n input.onkeydown = (e) => { if (e.key === 'Enter') { e.preventDefault(); save(); } if (e.key === 'Escape') input.replaceWith(span); };\n }\n\n async function deleteNote(noteId) {\n try {\n await fetch('/api/v1/notes/' + noteId, { method: 'DELETE' });\n fetchDashboard();\n } catch (e) {\n console.error('delete-note error:', e);\n }\n }\n\n async function sendNote(noteId, btn) {\n if (btn) btn.disabled = true;\n const noteText = btn?.closest('.note-item')?.querySelector('.note-text')?.textContent || '';\n try {\n const res = await fetch('/api/v1/notes/' + noteId + '/send', { method: 'POST' });\n const result = await res.json();\n if (!res.ok) {\n showToast(btn, result.error || 'Failed to send', true);\n } else {\n if (result.sessionId) {\n const card = document.querySelector('#title-' + result.sessionId.slice(0, 8))?.closest('.card');\n showSentBanner(card, '\u25B6', noteText);\n }\n showToast(btn, 'Sent', false);\n }\n fetchDashboard();\n } catch (e) {\n console.error('send-note error:', e);\n }\n if (btn) btn.disabled = false;\n }\n\n function getProjectNoteIds(project) {\n return Array.from(document.querySelectorAll('.note-item[data-project=\"' + project + '\"]'))\n .map(el => el.dataset.noteId);\n }\n\n async function saveNoteOrder(project) {\n const orderedIds = getProjectNoteIds(project);\n try {\n await fetch('/api/v1/notes/reorder', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ project, orderedIds }),\n });\n } catch (e) {\n console.error('reorder error:', e);\n }\n }\n\n function moveNote(project, idx, direction) {\n const items = document.querySelectorAll('.note-item[data-project=\"' + project + '\"]');\n const target = idx + direction;\n if (target < 0 || target >= items.length) return;\n const parent = items[0].parentNode;\n if (direction === -1) parent.insertBefore(items[idx], items[target]);\n else parent.insertBefore(items[target], items[idx]);\n saveNoteOrder(project);\n }\n\n let draggedNote = null;\n function onNoteDragStart(e) {\n draggedNote = e.currentTarget;\n draggedNote.classList.add('dragging');\n e.dataTransfer.effectAllowed = 'move';\n }\n function onNoteDragOver(e) {\n e.preventDefault();\n const item = e.currentTarget;\n if (item !== draggedNote) item.classList.add('drag-over');\n }\n function onNoteDrop(e) {\n e.preventDefault();\n const target = e.currentTarget;\n target.classList.remove('drag-over');\n if (!draggedNote || target === draggedNote) return;\n const parent = target.parentNode;\n const items = Array.from(parent.querySelectorAll('.note-item'));\n const fromIdx = items.indexOf(draggedNote);\n const toIdx = items.indexOf(target);\n if (fromIdx < toIdx) parent.insertBefore(draggedNote, target.nextSibling);\n else parent.insertBefore(draggedNote, target);\n saveNoteOrder(draggedNote.dataset.project);\n }\n function onNoteDragEnd(e) {\n document.querySelectorAll('.drag-over').forEach(el => el.classList.remove('drag-over'));\n if (draggedNote) draggedNote.classList.remove('dragging');\n draggedNote = null;\n }\n\n function showToast(anchor, text, isError) {\n const toast = document.createElement('span');\n toast.textContent = (isError ? '\u2717 ' : '\u2713 ') + text;\n toast.style.cssText = 'position:absolute;padding:3px 8px;border-radius:4px;font-size:10px;font-weight:600;z-index:10;pointer-events:none;'\n + (isError ? 'background:#490202;color:#f85149;' : 'background:#0d2818;color:#3fb950;');\n if (anchor) {\n const rect = anchor.getBoundingClientRect();\n toast.style.left = rect.left + 'px';\n toast.style.top = (rect.top - 24) + 'px';\n } else {\n toast.style.right = '24px';\n toast.style.top = '70px';\n }\n document.body.appendChild(toast);\n setTimeout(() => toast.remove(), 2000);\n }\n\n async function allowAll() {\n if (!data) return;\n const pending = [];\n for (const p of data.projects) {\n for (const s of p.sessions) {\n if (s.pendingQuestion && s.pendingQuestion.type === 'permission_prompt') {\n pending.push(s.pendingQuestion);\n }\n }\n }\n for (const q of pending) {\n await respondTo(q.eventId, 'allow', null);\n }\n fetchDashboard();\n }\n\n async function fetchDashboard() {\n try {\n const res = await fetch('/api/v1/dashboard');\n data = await res.json();\n render(data);\n document.getElementById('statusDot').className = 'status-dot connected';\n document.getElementById('lastUpdate').textContent = 'updated ' + timeAgo(data.updatedAt);\n } catch {\n document.getElementById('statusDot').className = 'status-dot disconnected';\n document.getElementById('lastUpdate').textContent = 'disconnected';\n }\n }\n\n fetchDashboard();\n\n // SSE for instant push \u2014 polling as fallback\n let fallbackTimer = setInterval(fetchDashboard, 10000);\n function connectSSE() {\n const es = new EventSource('/api/v1/sse');\n es.addEventListener('refresh', () => fetchDashboard());\n es.onopen = () => {\n clearInterval(fallbackTimer);\n fallbackTimer = setInterval(fetchDashboard, 10000);\n };\n es.onerror = () => {\n es.close();\n clearInterval(fallbackTimer);\n fallbackTimer = setInterval(fetchDashboard, 2000);\n setTimeout(connectSSE, 3000);\n };\n }\n connectSSE();\n </script>\n</body>\n</html>";
2
2
  //# sourceMappingURL=html.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,u9yCAo0CnB,CAAC"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,+uzCAw0CnB,CAAC"}
@@ -800,7 +800,7 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
800
800
  const toolInfo = q.toolName
801
801
  ? contextInfo + '<span class="tool">' + escapeHtml(q.toolName) + '</span>' +
802
802
  (q.toolInput ? '<br>' + formatToolInput(q.toolInput) : '')
803
- : '<div style="font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto">' + escapeHtml(q.message) + '</div>';
803
+ : '<div class="prompt-msg" style="font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto">' + escapeHtml(q.message) + '</div>';
804
804
 
805
805
  const actions = isPermission
806
806
  ? \`<div class="action-row">
@@ -1016,6 +1016,10 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
1016
1016
 
1017
1017
  container.innerHTML = sortProjects(data.projects).map(renderProject).join('');
1018
1018
 
1019
+ // Autoscroll prompt messages to bottom — Claude puts the actual question
1020
+ // at the end of an idle_prompt, so reveal that part on render.
1021
+ document.querySelectorAll('.prompt-msg').forEach(el => { el.scrollTop = el.scrollHeight; });
1022
+
1019
1023
  // Restore expanded titles
1020
1024
  expandedTitles.forEach(id => {
1021
1025
  const el = document.getElementById(id);
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAo0CtB,CAAC"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAw0CtB,CAAC"}
@@ -6,6 +6,7 @@ const node_fs_1 = require("node:fs");
6
6
  const node_path_1 = require("node:path");
7
7
  const tracker_js_1 = require("../sessions/tracker.js");
8
8
  const index_js_1 = require("../config/index.js");
9
+ const log_js_1 = require("../utils/log.js");
9
10
  // Skip if relay is explicitly disabled (e.g. when working on claude-pager itself)
10
11
  if (process.env.CLAUDE_PAGER_DISABLED) {
11
12
  process.exit(0);
@@ -152,6 +153,7 @@ async function handleSessionStart() {
152
153
  };
153
154
  (0, index_js_1.ensureDataDir)();
154
155
  (0, tracker_js_1.registerSession)(info);
156
+ (0, log_js_1.logHook)('session-start', info.sessionId, 'registered');
155
157
  // Register with VS Code extension for terminal mapping
156
158
  if (vscodePort) {
157
159
  try {
@@ -172,7 +174,9 @@ async function handleNotification() {
172
174
  const data = JSON.parse(input);
173
175
  // Only forward permission_prompt and idle_prompt
174
176
  const type = data.notification_type;
177
+ const sid = data.session_id || '-';
175
178
  if (type !== 'permission_prompt' && type !== 'idle_prompt') {
179
+ (0, log_js_1.logHook)('notification', sid, `skipped:type=${type}`);
176
180
  return;
177
181
  }
178
182
  let enriched = data;
@@ -203,10 +207,16 @@ async function handleNotification() {
203
207
  });
204
208
  if (!res.ok) {
205
209
  console.error(`[hook] daemon responded ${res.status}`);
210
+ (0, log_js_1.logHook)('notification', sid, `error:status=${res.status}`);
211
+ }
212
+ else {
213
+ (0, log_js_1.logHook)('notification', sid, `sent:${type}`);
206
214
  }
207
215
  }
208
216
  catch (err) {
209
217
  console.error('[hook] daemon unreachable:', err);
218
+ const msg = err.message || 'fetch-failed';
219
+ (0, log_js_1.logHook)('notification', sid, `error:${msg.replace(/\s+/g, '_').slice(0, 80)}`);
210
220
  }
211
221
  }
212
222
  const command = process.argv[2];
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function logHook(...parts: string[]): void;
2
+ export declare function logDaemon(...parts: string[]): void;
3
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":"AAeA,wBAAgB,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAEhD;AAED,wBAAgB,SAAS,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAElD"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logHook = logHook;
4
+ exports.logDaemon = logDaemon;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const node_os_1 = require("node:os");
8
+ const DATA_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.claude-pager');
9
+ function appendLine(file, parts) {
10
+ try {
11
+ (0, node_fs_1.mkdirSync)(DATA_DIR, { recursive: true });
12
+ (0, node_fs_1.appendFileSync)((0, node_path_1.join)(DATA_DIR, file), `${new Date().toISOString()} ${parts.join(' ')}\n`);
13
+ }
14
+ catch {
15
+ // never let logging break operation
16
+ }
17
+ }
18
+ function logHook(...parts) {
19
+ appendLine('hook.log', parts);
20
+ }
21
+ function logDaemon(...parts) {
22
+ appendLine('daemon.log', parts);
23
+ }
24
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":";;AAeA,0BAEC;AAED,8BAEC;AArBD,qCAAoD;AACpD,yCAAiC;AACjC,qCAAkC;AAElC,MAAM,QAAQ,GAAG,IAAA,gBAAI,EAAC,IAAA,iBAAO,GAAE,EAAE,eAAe,CAAC,CAAC;AAElD,SAAS,UAAU,CAAC,IAAY,EAAE,KAAe;IAC/C,IAAI,CAAC;QACH,IAAA,mBAAS,EAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,IAAA,wBAAc,EAAC,IAAA,gBAAI,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3F,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;IACtC,CAAC;AACH,CAAC;AAED,SAAgB,OAAO,CAAC,GAAG,KAAe;IACxC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,SAAgB,SAAS,CAAC,GAAG,KAAe;IAC1C,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-pager",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Remote notification and response relay for Claude Code CLI sessions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",