claude-pager 0.3.13 → 0.3.15
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/dist/channels/ntfy/__tests__/provider.test.js +30 -0
- package/dist/channels/ntfy/__tests__/provider.test.js.map +1 -1
- package/dist/channels/ntfy/provider.d.ts +1 -0
- package/dist/channels/ntfy/provider.d.ts.map +1 -1
- package/dist/channels/ntfy/provider.js +27 -0
- package/dist/channels/ntfy/provider.js.map +1 -1
- package/dist/channels/telegram/provider.d.ts.map +1 -1
- package/dist/channels/telegram/provider.js +10 -0
- package/dist/channels/telegram/provider.js.map +1 -1
- package/dist/dashboard/enricher.d.ts +1 -0
- package/dist/dashboard/enricher.d.ts.map +1 -1
- package/dist/dashboard/enricher.js +7 -0
- package/dist/dashboard/enricher.js.map +1 -1
- package/dist/dashboard/html.d.ts +1 -1
- package/dist/dashboard/html.d.ts.map +1 -1
- package/dist/dashboard/html.js +3 -0
- package/dist/dashboard/html.js.map +1 -1
- package/dist/dashboard/transcript.d.ts.map +1 -1
- package/dist/dashboard/transcript.js +2 -1
- package/dist/dashboard/transcript.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -25,5 +25,35 @@ const provider_js_1 = require("../provider.js");
|
|
|
25
25
|
strict_1.default.ok(result.error);
|
|
26
26
|
});
|
|
27
27
|
});
|
|
28
|
+
(0, node_test_1.describe)('insecure ntfy.sh guard', () => {
|
|
29
|
+
(0, node_test_1.it)('refuses default ntfy.sh topic without auth', () => {
|
|
30
|
+
strict_1.default.throws(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.sh', topic: 'claude-pager' }), /Refusing to start/);
|
|
31
|
+
});
|
|
32
|
+
(0, node_test_1.it)('accepts ntfy.sh with a token', () => {
|
|
33
|
+
strict_1.default.doesNotThrow(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.sh', topic: 't', token: 'tk_x' }));
|
|
34
|
+
});
|
|
35
|
+
(0, node_test_1.it)('accepts ntfy.sh with basic auth', () => {
|
|
36
|
+
strict_1.default.doesNotThrow(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.sh', topic: 't', user: 'u', password: 'p' }));
|
|
37
|
+
});
|
|
38
|
+
(0, node_test_1.it)('accepts self-hosted server without auth', () => {
|
|
39
|
+
strict_1.default.doesNotThrow(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.example.com', topic: 't' }));
|
|
40
|
+
});
|
|
41
|
+
(0, node_test_1.it)('honors allowInsecure escape hatch', () => {
|
|
42
|
+
strict_1.default.doesNotThrow(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.sh', topic: 't', allowInsecure: true }));
|
|
43
|
+
});
|
|
44
|
+
(0, node_test_1.it)('honors CLAUDE_PAGER_ALLOW_INSECURE_NTFY env var', () => {
|
|
45
|
+
const prev = process.env.CLAUDE_PAGER_ALLOW_INSECURE_NTFY;
|
|
46
|
+
process.env.CLAUDE_PAGER_ALLOW_INSECURE_NTFY = '1';
|
|
47
|
+
try {
|
|
48
|
+
strict_1.default.doesNotThrow(() => new provider_js_1.NtfyProvider({ server: 'https://ntfy.sh', topic: 't' }));
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
if (prev === undefined)
|
|
52
|
+
delete process.env.CLAUDE_PAGER_ALLOW_INSECURE_NTFY;
|
|
53
|
+
else
|
|
54
|
+
process.env.CLAUDE_PAGER_ALLOW_INSECURE_NTFY = prev;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
28
58
|
});
|
|
29
59
|
//# sourceMappingURL=provider.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../../../src/channels/ntfy/__tests__/provider.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAyC;AACzC,gEAAwC;AACxC,gDAA8C;AAE9C,IAAA,oBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,oBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;QACpB,IAAA,cAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,QAAQ,GAAG,IAAI,0BAAY,CAAC;gBAChC,MAAM,EAAE,wBAAwB;gBAChC,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC;gBACE,EAAE,EAAE,OAAO;gBACX,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,yBAAyB;gBAClC,OAAO,EAAE,0BAA0B;gBACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,EACD,GAAG,CACJ,CAAC;YAEF,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../../../src/channels/ntfy/__tests__/provider.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export declare class NtfyProvider implements ChannelProvider {
|
|
|
6
6
|
private readonly config;
|
|
7
7
|
private processedIds;
|
|
8
8
|
constructor(config: NtfyConfig);
|
|
9
|
+
private static assertSecure;
|
|
9
10
|
private get topicUrl();
|
|
10
11
|
private authHeaders;
|
|
11
12
|
send(event: RelayEvent, shortId: string): Promise<NotificationResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7D,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,MAAM,EAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7D,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,MAAM,EAAE,UAAU;IAS9B,OAAO,CAAC,MAAM,CAAC,YAAY;IAmB3B,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,WAAW;IAWb,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiD3E,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;YAMnC,IAAI;IAsDlB,OAAO,CAAC,MAAM;IAOd,aAAa,IAAI,IAAI;CAItB"}
|
|
@@ -8,6 +8,33 @@ class NtfyProvider {
|
|
|
8
8
|
processedIds = new Set();
|
|
9
9
|
constructor(config) {
|
|
10
10
|
this.config = config;
|
|
11
|
+
NtfyProvider.assertSecure(config);
|
|
12
|
+
}
|
|
13
|
+
// A public ntfy.sh topic with no auth lets anyone who guesses the topic
|
|
14
|
+
// publish messages that the daemon will treat as a response and inject into
|
|
15
|
+
// tmux. Refuse to start in that configuration unless the operator opts in
|
|
16
|
+
// explicitly (config.allowInsecure or env CLAUDE_PAGER_ALLOW_INSECURE_NTFY=1).
|
|
17
|
+
static assertSecure(config) {
|
|
18
|
+
if (config.allowInsecure || process.env.CLAUDE_PAGER_ALLOW_INSECURE_NTFY === '1')
|
|
19
|
+
return;
|
|
20
|
+
const hasAuth = !!config.token || !!(config.user && config.password);
|
|
21
|
+
if (hasAuth)
|
|
22
|
+
return;
|
|
23
|
+
let host;
|
|
24
|
+
try {
|
|
25
|
+
host = new URL(config.server).hostname;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
host = config.server;
|
|
29
|
+
}
|
|
30
|
+
if (host === 'ntfy.sh' || host.endsWith('.ntfy.sh')) {
|
|
31
|
+
throw new Error(`Refusing to start: ntfy.sh topic "${config.topic}" has no auth. ` +
|
|
32
|
+
`Anyone who guesses this topic can inject text into your terminal. ` +
|
|
33
|
+
`Either add a token (channel.ntfy.token) or HTTP basic auth ` +
|
|
34
|
+
`(channel.ntfy.user + .password), self-host ntfy, or — only if you ` +
|
|
35
|
+
`accept the risk — set channel.ntfy.allowInsecure: true (or env ` +
|
|
36
|
+
`CLAUDE_PAGER_ALLOW_INSECURE_NTFY=1).`);
|
|
37
|
+
}
|
|
11
38
|
}
|
|
12
39
|
get topicUrl() {
|
|
13
40
|
return `${this.config.server}/${this.config.topic}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":";;;AAGA,MAAa,YAAY;IACd,IAAI,GAAG,MAAM,CAAC;IACf,eAAe,GAA2B,IAAI,CAAC;IACtC,MAAM,CAAa;IAC5B,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEzC,YAAY,MAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/telegram/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAe,MAAM,eAAe,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/telegram/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAe,MAAM,eAAe,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA8BjE,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,MAAM,EAAE,cAAc;IAIlC,OAAO,CAAC,MAAM;IAIR,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8DrE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAapC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA0BlH,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;YAMnC,IAAI;YAwDJ,cAAc;YAwEd,WAAW;YAYX,iBAAiB;YAiCjB,WAAW;IA2CzB,OAAO,CAAC,MAAM;IAOd,aAAa,IAAI,IAAI;CAItB"}
|
|
@@ -139,6 +139,16 @@ class TelegramProvider {
|
|
|
139
139
|
continue;
|
|
140
140
|
for (const update of data.result) {
|
|
141
141
|
this.lastUpdateId = update.update_id + 1;
|
|
142
|
+
// Authorization: only the configured chat is allowed to send anything
|
|
143
|
+
// to the bot. Drops messages from any other Telegram user that
|
|
144
|
+
// happens to start a conversation with the bot — without this guard,
|
|
145
|
+
// they could pilot the agent (free messages → tmux send-keys), add
|
|
146
|
+
// notes, or trigger expensive voice transcription on the host.
|
|
147
|
+
const chatId = update.callback_query?.message?.chat.id ?? update.message?.chat.id;
|
|
148
|
+
if (chatId !== undefined && chatId !== this.config.chatId) {
|
|
149
|
+
console.warn(`[telegram] dropped update from unauthorized chat ${chatId}`);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
142
152
|
if (update.callback_query) {
|
|
143
153
|
await this.handleCallback(update.callback_query, listeners);
|
|
144
154
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/channels/telegram/provider.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/channels/telegram/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enricher.d.ts","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAkB9C,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/E,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"enricher.d.ts","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAkB9C,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,oBAAoB,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/E,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAMF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,EAAE,CAAC,EAAE,eAAe,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAgKnE"}
|
|
@@ -93,6 +93,13 @@ async function getDashboardData() {
|
|
|
93
93
|
agoSeconds: Math.floor((Date.now() - pendingQ.notifiedAt) / 1000),
|
|
94
94
|
};
|
|
95
95
|
})() : undefined,
|
|
96
|
+
// Surface the latest assistant text when the session is not
|
|
97
|
+
// actively working AND there is no pending event to render. This
|
|
98
|
+
// covers the gap between Claude finishing a turn and Claude Code
|
|
99
|
+
// firing its idle_prompt notification 60s later.
|
|
100
|
+
lastAssistantText: (!pendingQ
|
|
101
|
+
&& state !== 'working'
|
|
102
|
+
&& transcript.lastAssistantText) ? transcript.lastAssistantText.slice(-3000) : undefined,
|
|
96
103
|
git,
|
|
97
104
|
needsTesting: false, // computed at project level after CI fetch
|
|
98
105
|
committed: git.modifiedFiles === 0 || transcript.recentCommit,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enricher.js","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"enricher.js","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":"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"}
|
package/dist/dashboard/html.d.ts
CHANGED
|
@@ -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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\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 '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + escapeHtml(input.slice(0, 3000)) + '</pre>';\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>";
|
|
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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\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 '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + escapeHtml(input.slice(0, 3000)) + '</pre>';\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 ${s.lastAssistantText\n ? '<div class=\"prompt-msg\" style=\"font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto;background:#0d1117;border:1px solid #21262d;border-radius:6px;padding:8px 10px;margin:8px 0\">' + escapeHtml(s.lastAssistantText) + '</div>'\n : ''}\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,
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,un0CA20CnB,CAAC"}
|
package/dist/dashboard/html.js
CHANGED
|
@@ -869,6 +869,9 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
869
869
|
return '';
|
|
870
870
|
})()}
|
|
871
871
|
\${pending}
|
|
872
|
+
\${s.lastAssistantText
|
|
873
|
+
? '<div class="prompt-msg" style="font-size:12px;color:#c9d1d9;white-space:pre-wrap;max-height:240px;overflow-y:auto;background:#0d1117;border:1px solid #21262d;border-radius:6px;padding:8px 10px;margin:8px 0">' + escapeHtml(s.lastAssistantText) + '</div>'
|
|
874
|
+
: ''}
|
|
872
875
|
\${idleInput}
|
|
873
876
|
<div class="card-footer">
|
|
874
877
|
\${gitParts.join(' ')}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA20CtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/dashboard/transcript.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/dashboard/transcript.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA8OD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAoBjF"}
|
|
@@ -6,7 +6,8 @@ const node_path_1 = require("node:path");
|
|
|
6
6
|
const node_os_1 = require("node:os");
|
|
7
7
|
const cache = new Map();
|
|
8
8
|
function projectDir(cwd) {
|
|
9
|
-
//
|
|
9
|
+
// Claude Code encodes the cwd by replacing / with -, e.g.
|
|
10
|
+
// /home/user/dev/myproject → ~/.claude/projects/-home-user-dev-myproject/
|
|
10
11
|
const encoded = cwd.replace(/\//g, '-');
|
|
11
12
|
return (0, node_path_1.join)((0, node_os_1.homedir)(), '.claude', 'projects', encoded);
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/dashboard/transcript.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/dashboard/transcript.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IAIf,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,mBAAmB,GAAG,aAAa,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|