claude-pager 0.3.19 → 0.3.21

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.
@@ -114,5 +114,49 @@ const TEST_CONFIG = {
114
114
  strict_1.default.ok(res.statusCode !== 404, 'Should have found a matching pending question');
115
115
  });
116
116
  });
117
+ (0, node_test_1.describe)('terminal endpoints gating', () => {
118
+ (0, node_test_1.it)('returns 404 for capture when allowTerminal is off (default)', async () => {
119
+ const res = await app.inject({ method: 'GET', url: '/api/v1/session/sess-1/terminal' });
120
+ strict_1.default.equal(res.statusCode, 404);
121
+ strict_1.default.match(JSON.parse(res.payload).error, /disabled/);
122
+ });
123
+ (0, node_test_1.it)('returns 404 for keys when allowTerminal is off (default)', async () => {
124
+ const res = await app.inject({
125
+ method: 'POST',
126
+ url: '/api/v1/session/sess-1/keys',
127
+ payload: { keys: 'ls', enter: true },
128
+ });
129
+ strict_1.default.equal(res.statusCode, 404);
130
+ strict_1.default.match(JSON.parse(res.payload).error, /disabled/);
131
+ });
132
+ });
133
+ });
134
+ (0, node_test_1.describe)('HTTP server with allowTerminal enabled', () => {
135
+ let app;
136
+ (0, node_test_1.before)(async () => {
137
+ app = await (0, server_js_1.createServer)({
138
+ config: { ...TEST_CONFIG, dashboard: { allowTerminal: true } },
139
+ channel: mockChannel(),
140
+ injector: mockInjector(),
141
+ });
142
+ });
143
+ (0, node_test_1.after)(async () => { await app.close(); });
144
+ (0, node_test_1.it)('capture: rejects invalid session id', async () => {
145
+ const res = await app.inject({ method: 'GET', url: '/api/v1/session/bad%20id/terminal' });
146
+ strict_1.default.equal(res.statusCode, 400);
147
+ });
148
+ (0, node_test_1.it)('capture: 404 when the session is unknown (not "disabled")', async () => {
149
+ const res = await app.inject({ method: 'GET', url: '/api/v1/session/no-such-session/terminal' });
150
+ strict_1.default.equal(res.statusCode, 404);
151
+ strict_1.default.match(JSON.parse(res.payload).error, /not found|no tmux/);
152
+ });
153
+ (0, node_test_1.it)('keys: validates body (missing keys → 400)', async () => {
154
+ const res = await app.inject({
155
+ method: 'POST',
156
+ url: '/api/v1/session/sess-1/keys',
157
+ payload: { enter: true },
158
+ });
159
+ strict_1.default.equal(res.statusCode, 400);
160
+ });
117
161
  });
118
162
  //# sourceMappingURL=server.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../../src/daemon/__tests__/server.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../../src/daemon/__tests__/server.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=terminal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.test.d.ts","sourceRoot":"","sources":["../../../src/daemon/__tests__/terminal.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const terminal_js_1 = require("../terminal.js");
9
+ (0, node_test_1.describe)('terminal', () => {
10
+ (0, node_test_1.describe)('isValidPane', () => {
11
+ (0, node_test_1.it)('accepts %0, %5, %12', () => {
12
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%0'), true);
13
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%5'), true);
14
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%12'), true);
15
+ });
16
+ (0, node_test_1.it)('rejects values that could carry tmux options or shell metachars', () => {
17
+ strict_1.default.equal((0, terminal_js_1.isValidPane)(''), false);
18
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('5'), false);
19
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%'), false);
20
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%1; rm -rf /'), false);
21
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('-S'), false);
22
+ strict_1.default.equal((0, terminal_js_1.isValidPane)('%1 %2'), false);
23
+ });
24
+ });
25
+ });
26
+ //# sourceMappingURL=terminal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.test.js","sourceRoot":"","sources":["../../../src/daemon/__tests__/terminal.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAyC;AACzC,gEAAwC;AACxC,gDAA6C;AAE7C,IAAA,oBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAA,oBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,IAAA,cAAE,EAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YACtC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YACtC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAA,cAAE,EAAC,iEAAiE,EAAE,GAAG,EAAE;YACzE,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACrC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACtC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACtC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;YACjD,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YACvC,gBAAM,CAAC,KAAK,CAAC,IAAA,yBAAW,EAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,eAAe,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAYpE;AAED,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;AAoB9F,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAyBvE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuDjD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAWpC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAgBA,wBAAgB,eAAe,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAYpE;AAED,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;AAoB9F,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAyBvE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAwDjD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAWpC"}
@@ -14,6 +14,7 @@ const server_js_1 = require("./server.js");
14
14
  const handlers_js_1 = require("./handlers.js");
15
15
  const sse_js_1 = require("../dashboard/sse.js");
16
16
  const auth_js_1 = require("./auth.js");
17
+ const events_js_1 = require("../sessions/events.js");
17
18
  const SHUTDOWN_TIMEOUT_MS = 3000;
18
19
  const PID_FILE = () => (0, node_path_1.join)((0, index_js_1.getDataDir)(), 'daemon.pid');
19
20
  function isDaemonRunning() {
@@ -83,6 +84,8 @@ async function startDaemon() {
83
84
  (0, index_js_1.ensureDataDir)();
84
85
  const config = (0, index_js_1.loadConfig)();
85
86
  (0, auth_js_1.assertDashboardConfig)(config.dashboard);
87
+ if (config.pendingTtlSeconds)
88
+ (0, events_js_1.setPendingTtlMs)(config.pendingTtlSeconds * 1000);
86
89
  const channel = (0, factory_js_1.createChannel)(config.channel);
87
90
  const injector = (0, factory_js_2.createInjector)(config.injector);
88
91
  const app = await (0, server_js_1.createServer)({ config, channel, injector });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":";;AAeA,0CAYC;AAsBD,kDAyBC;AAED,kCAuDC;AAED,gCAWC;AAhJD,qCAAwF;AACxF,2DAA2C;AAC3C,yCAAiC;AACjC,iDAA2E;AAC3E,uDAAuD;AACvD,wDAAyD;AACzD,2CAA2C;AAC3C,+CAAsD;AACtD,gDAAyD;AACzD,uCAAkD;AAElD,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAA,gBAAI,EAAC,IAAA,qBAAU,GAAE,EAAE,YAAY,CAAC,CAAC;AAExD,SAAgB,eAAe;IAC7B,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;IAC3B,IAAI,CAAC,IAAA,oBAAU,EAAC,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAEpD,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAA,sBAAY,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,IAAA,oBAAU,EAAC,OAAO,CAAC,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAID,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,gBAAgB,EAAE;YAChE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC;SACjC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,oEAAoE;AACpE,0EAA0E;AAC1E,6EAA6E;AAC7E,6EAA6E;AAC7E,mEAAmE;AACnE,mBAAmB;AACZ,KAAK,UAAU,mBAAmB;IACvC,MAAM,IAAI,GAAG,IAAA,qBAAU,GAAE,CAAC,IAAI,CAAC;IAE/B,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,EAAE,CAAC;IACtC,IAAI,OAAO,IAAI,MAAM,SAAS,CAAC,IAAI,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAE/D,IAAI,CAAC;QACH,IAAA,wBAAa,GAAE,CAAC;QAChB,MAAM,GAAG,GAAG,IAAA,kBAAQ,EAAC,IAAA,gBAAI,EAAC,IAAA,qBAAU,GAAE,EAAE,mBAAmB,CAAC,EAAE,GAAG,CAAC,CAAC;QACnE,uEAAuE;QACvE,MAAM,KAAK,GAAG,IAAA,0BAAK,EAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE;YAChE,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC;SAC5B,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,+CAA+C;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,IAAI,MAAM,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;IAC9C,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAEM,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,eAAe,EAAE,CAAC;IAC3C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,GAAG,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAA,wBAAa,GAAE,CAAC;IAChB,MAAM,MAAM,GAAG,IAAA,qBAAU,GAAE,CAAC;IAC5B,IAAA,+BAAqB,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAA,0BAAa,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAA,2BAAc,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,GAAG,GAAG,MAAM,IAAA,wBAAY,EAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE9D,iBAAiB;IACjB,IAAA,uBAAa,EAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAE/C,+CAA+C;IAC/C,MAAM,QAAQ,GAAG,IAAA,mCAAqB,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC1D,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEjC,oBAAoB;IACpB,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,aAAa,EAAE,CAAC;QACxB,IAAA,2BAAkB,GAAE,CAAC;QACrB,4EAA4E;QAC5E,oEAAoE;QACpE,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,GAAG,CAAC,KAAK,EAAE;YACX,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;SACvE,CAAC,CAAC;QACH,IAAI,CAAC;YAAC,IAAA,oBAAU,EAAC,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,IAAI,IAAI,WAAW,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnE,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,yBAAyB,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,gDAAgD,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC;YAAC,IAAA,oBAAU,EAAC,QAAQ,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAgB,UAAU;IACxB,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,eAAe,EAAE,CAAC;IAC3C,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC7B,IAAI,CAAC;QAAC,IAAA,oBAAU,EAAC,QAAQ,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,GAAG,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAc9D,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB;AA+BD,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,oUAkalD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAe9D,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB;AA+BD,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,oUA0dlD"}
@@ -12,6 +12,7 @@ const store_js_1 = require("../notes/store.js");
12
12
  const validation_js_1 = require("../utils/validation.js");
13
13
  const log_js_1 = require("../utils/log.js");
14
14
  const auth_js_1 = require("./auth.js");
15
+ const terminal_js_1 = require("./terminal.js");
15
16
  const node_crypto_1 = require("node:crypto");
16
17
  const routes_js_1 = require("../dashboard/routes.js");
17
18
  const sse_js_1 = require("../dashboard/sse.js");
@@ -214,6 +215,60 @@ async function createServer(deps) {
214
215
  (0, tracker_js_1.cleanDeadSessions)();
215
216
  return { sessions: (0, tracker_js_1.listSessions)() };
216
217
  });
218
+ // --- Terminal (opt-in via config.dashboard.allowTerminal) ---
219
+ const terminalEnabled = config.dashboard?.allowTerminal === true;
220
+ // Capture a session's tmux pane content (with scrollback + ANSI colors).
221
+ app.get('/api/v1/session/:id/terminal', async (request, reply) => {
222
+ if (!terminalEnabled)
223
+ return reply.status(404).send({ error: 'Terminal view is disabled' });
224
+ const { id } = request.params;
225
+ if (!(0, validation_js_1.isValidSessionId)(id))
226
+ return reply.status(400).send({ error: 'Invalid session id' });
227
+ const session = (0, tracker_js_1.getSession)(id);
228
+ if (!session || !session.tmuxPane) {
229
+ return reply.status(404).send({ error: 'Session not found or has no tmux pane' });
230
+ }
231
+ try {
232
+ const content = await (0, terminal_js_1.capturePane)(session.tmuxPane);
233
+ return { content, tmuxPane: session.tmuxPane };
234
+ }
235
+ catch (err) {
236
+ (0, log_js_1.logDaemon)('terminal-capture-failed', id, String(err.message).slice(0, 60));
237
+ return reply.status(500).send({ error: 'Failed to capture pane' });
238
+ }
239
+ });
240
+ // Send keystrokes (literal text, optionally + Enter) to a session's pane.
241
+ app.post('/api/v1/session/:id/keys', {
242
+ schema: {
243
+ body: {
244
+ type: 'object',
245
+ required: ['keys'],
246
+ properties: {
247
+ keys: { type: 'string', maxLength: 10000 },
248
+ enter: { type: 'boolean' },
249
+ },
250
+ },
251
+ },
252
+ }, async (request, reply) => {
253
+ if (!terminalEnabled)
254
+ return reply.status(404).send({ error: 'Terminal view is disabled' });
255
+ const { id } = request.params;
256
+ if (!(0, validation_js_1.isValidSessionId)(id))
257
+ return reply.status(400).send({ error: 'Invalid session id' });
258
+ const session = (0, tracker_js_1.getSession)(id);
259
+ if (!session || !session.tmuxPane) {
260
+ return reply.status(404).send({ error: 'Session not found or has no tmux pane' });
261
+ }
262
+ try {
263
+ await (0, terminal_js_1.sendKeys)(session.tmuxPane, request.body.keys, request.body.enter !== false);
264
+ (0, log_js_1.logDaemon)('terminal-keys', id, session.tmuxPane);
265
+ return { ok: true };
266
+ }
267
+ catch (err) {
268
+ (0, log_js_1.logDaemon)('terminal-keys-failed', id, String(err.message).slice(0, 60));
269
+ return reply.status(500).send({ error: 'Failed to send keys' });
270
+ }
271
+ });
217
272
  // --- Notes ---
218
273
  // Add a note
219
274
  app.post('/api/v1/notes', {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function isValidPane(pane: string): boolean;
2
+ export declare function capturePane(pane: string, lines?: number): Promise<string>;
3
+ export declare function sendKeys(pane: string, keys: string, enter: boolean): Promise<void>;
4
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/daemon/terminal.ts"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAID,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ7E;AAKD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxF"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidPane = isValidPane;
4
+ exports.capturePane = capturePane;
5
+ exports.sendKeys = sendKeys;
6
+ const node_child_process_1 = require("node:child_process");
7
+ const node_util_1 = require("node:util");
8
+ const execFileP = (0, node_util_1.promisify)(node_child_process_1.execFile);
9
+ // tmux pane ids look like %0, %12. Validate before passing to tmux to avoid
10
+ // any argument/option injection even though execFile already prevents shell
11
+ // interpretation.
12
+ const PANE_RE = /^%\d+$/;
13
+ function isValidPane(pane) {
14
+ return PANE_RE.test(pane);
15
+ }
16
+ // Dump a pane's content including scrollback, with ANSI escape sequences (-e)
17
+ // so the dashboard can render colors. -S -<lines> sets the scrollback start.
18
+ async function capturePane(pane, lines = 3000) {
19
+ if (!isValidPane(pane))
20
+ throw new Error('invalid pane');
21
+ const { stdout } = await execFileP('tmux', ['capture-pane', '-t', pane, '-p', '-e', '-S', `-${lines}`], { timeout: 3000, maxBuffer: 16 * 1024 * 1024 });
22
+ return stdout;
23
+ }
24
+ // Send literal text to a pane (-l disables key-name interpretation, -- stops
25
+ // option parsing), optionally followed by Enter. Control keys are not sent
26
+ // literally: when `enter` is true we append a real Enter key event.
27
+ async function sendKeys(pane, keys, enter) {
28
+ if (!isValidPane(pane))
29
+ throw new Error('invalid pane');
30
+ if (keys.length > 0) {
31
+ await execFileP('tmux', ['send-keys', '-t', pane, '-l', '--', keys], { timeout: 2000 });
32
+ }
33
+ if (enter) {
34
+ await execFileP('tmux', ['send-keys', '-t', pane, 'Enter'], { timeout: 2000 });
35
+ }
36
+ }
37
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/daemon/terminal.ts"],"names":[],"mappings":";;AAUA,kCAEC;AAID,kCAQC;AAKD,4BAQC;AArCD,2DAA8C;AAC9C,yCAAsC;AAEtC,MAAM,SAAS,GAAG,IAAA,qBAAS,EAAC,6BAAQ,CAAC,CAAC;AAEtC,4EAA4E;AAC5E,4EAA4E;AAC5E,kBAAkB;AAClB,MAAM,OAAO,GAAG,QAAQ,CAAC;AAEzB,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,6EAA6E;AACtE,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,KAAK,GAAG,IAAI;IAC1D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,MAAM,EACN,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC,EAC3D,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAC/C,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,6EAA6E;AAC7E,2EAA2E;AAC3E,oEAAoE;AAC7D,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAY,EAAE,KAAc;IACvE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
@@ -33,6 +33,7 @@ export interface DashboardProject {
33
33
  export interface DashboardResponse {
34
34
  projects: DashboardProject[];
35
35
  updatedAt: number;
36
+ terminalEnabled: boolean;
36
37
  }
37
38
  export declare function getDashboardData(): Promise<DashboardResponse>;
38
39
  //# sourceMappingURL=enricher.d.ts.map
@@ -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;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"}
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;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAgKnE"}
@@ -165,6 +165,6 @@ async function getDashboardData() {
165
165
  const bMin = Math.min(...b.sessions.map(s => stateOrder[s.state] ?? 5));
166
166
  return aMin !== bMin ? aMin - bMin : a.name.localeCompare(b.name);
167
167
  });
168
- return { projects, updatedAt: Date.now() };
168
+ return { projects, updatedAt: Date.now(), terminalEnabled: config.dashboard?.allowTerminal === true };
169
169
  }
170
170
  //# sourceMappingURL=enricher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"enricher.js","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"enricher.js","sourceRoot":"","sources":["../../src/dashboard/enricher.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const DASHBOARD_HTML = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>claude-pager dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&display=swap\" rel=\"stylesheet\">\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n background: #0d1117;\n color: #c9d1d9;\n font-family: 'JetBrains Mono', monospace;\n min-height: 100vh;\n padding: 24px;\n }\n\n header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 32px;\n padding-bottom: 16px;\n border-bottom: 1px solid #21262d;\n }\n\n .logo {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .logo h1 {\n font-size: 22px;\n font-weight: 700;\n color: #f0f6fc;\n }\n\n .cursor {\n display: inline-block;\n width: 10px;\n height: 20px;\n background: #58a6ff;\n animation: blink 1s step-end infinite;\n vertical-align: middle;\n margin-left: 4px;\n }\n\n @keyframes blink {\n 50% { opacity: 0; }\n }\n\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .status-dot.connected { background: #3fb950; box-shadow: 0 0 6px #3fb950; }\n .status-dot.disconnected { background: #f85149; box-shadow: 0 0 6px #f85149; }\n\n .meta {\n font-size: 12px;\n color: #484f58;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .project {\n margin-bottom: 28px;\n }\n\n .project-header {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 12px;\n }\n\n .project-header h2 {\n font-size: 16px;\n font-weight: 600;\n color: #58a6ff;\n }\n\n .project-count {\n background: #21262d;\n color: #8b949e;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n }\n\n .project-path {\n font-size: 11px;\n color: #484f58;\n margin-left: auto;\n }\n\n .pin-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 14px;\n opacity: 0.3;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .pin-btn:hover { opacity: 0.7; }\n .pin-btn.pinned { opacity: 1; }\n\n .dismiss-btn {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 12px;\n opacity: 0.25;\n transition: opacity 0.2s;\n padding: 2px 4px;\n }\n\n .dismiss-btn:hover { opacity: 0.8; color: #f85149; }\n\n .ci-row {\n display: flex;\n gap: 12px;\n margin-bottom: 12px;\n font-size: 11px;\n }\n\n .ci-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 3px 10px;\n border-radius: 12px;\n font-weight: 600;\n text-decoration: none;\n transition: opacity 0.2s;\n }\n\n .ci-badge:hover { opacity: 0.8; }\n\n .ci-badge.success { background: #0d2818; color: #3fb950; }\n .ci-badge.failed { background: #490202; color: #f85149; }\n .ci-badge.running { background: #0d419d; color: #58a6ff; animation: pulse 2s ease-in-out infinite; }\n .ci-badge.pending { background: #3d2e00; color: #d29922; }\n .ci-badge.canceled { background: #21262d; color: #8b949e; }\n .ci-badge.unknown { background: #21262d; color: #484f58; }\n\n .ci-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n display: inline-block;\n }\n\n .ci-dot.success { background: #3fb950; }\n .ci-dot.failed { background: #f85149; }\n .ci-dot.running { background: #58a6ff; }\n .ci-dot.pending { background: #d29922; }\n .ci-dot.canceled { background: #8b949e; }\n .ci-dot.unknown { background: #484f58; }\n\n .sessions {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));\n gap: 12px;\n }\n\n .card {\n background: #161b22;\n border: 1px solid #21262d;\n border-radius: 8px;\n padding: 16px;\n transition: border-color 0.2s, box-shadow 0.2s, opacity 0.3s;\n }\n\n .card:hover {\n border-color: #388bfd44;\n box-shadow: 0 0 12px #388bfd22;\n }\n\n .card.stale {\n opacity: 0.45;\n border-style: dashed;\n }\n\n .card.stale:hover {\n opacity: 0.8;\n }\n\n .card.active {\n border-color: #388bfd44;\n border-left: 3px solid #58a6ff;\n }\n\n .card.alert {\n border-color: #f0883e44;\n border-left: 3px solid #f0883e;\n }\n\n .card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n margin-bottom: 10px;\n }\n\n .card-title {\n font-size: 14px;\n font-weight: 600;\n color: #f0f6fc;\n line-height: 1.3;\n flex: 1;\n margin-right: 8px;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n\n .card-title.expanded {\n -webkit-line-clamp: unset;\n overflow: visible;\n white-space: pre-wrap;\n }\n\n .expand-btn {\n background: none;\n border: none;\n color: #58a6ff;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n cursor: pointer;\n padding: 2px 0;\n opacity: 0.8;\n }\n\n .expand-btn:hover { opacity: 1; }\n\n .badge {\n font-size: 10px;\n font-weight: 600;\n padding: 3px 8px;\n border-radius: 12px;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .badge.working {\n background: #0d419d;\n color: #58a6ff;\n animation: pulse 2s ease-in-out infinite;\n }\n\n .badge.waiting_permission {\n background: #5a1e02;\n color: #f0883e;\n }\n\n .badge.waiting_input {\n background: #3d2e00;\n color: #d29922;\n }\n\n .badge.idle {\n background: #21262d;\n color: #8b949e;\n }\n\n .badge.unknown {\n background: #21262d;\n color: #484f58;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n\n .pending-box {\n background: #1c1208;\n border: 1px solid #3d2e00;\n border-radius: 6px;\n padding: 8px 10px;\n margin-bottom: 10px;\n font-size: 12px;\n color: #d29922;\n }\n\n .pending-box .tool {\n color: #f0883e;\n font-weight: 600;\n }\n\n .pending-box .ago {\n color: #8b949e;\n float: right;\n }\n\n .action-row {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n }\n\n .action-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n font-weight: 600;\n padding: 4px 14px;\n border-radius: 6px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s, transform 0.1s;\n }\n\n .action-btn:hover { opacity: 0.85; }\n .action-btn:active { transform: scale(0.96); }\n\n .action-btn.allow {\n background: #238636;\n color: #ffffff;\n }\n\n .action-btn.deny {\n background: #da3633;\n color: #ffffff;\n }\n\n .action-btn.allow-all {\n background: #1f6feb;\n color: #ffffff;\n margin-left: auto;\n }\n\n .action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .reply-input {\n flex: 1;\n font-family: 'JetBrains Mono', monospace;\n font-size: 11px;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid #30363d;\n background: #0d1117;\n color: #c9d1d9;\n outline: none;\n }\n\n .reply-input:focus {\n border-color: #58a6ff;\n }\n\n .git-row {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 11px;\n margin-bottom: 6px;\n }\n\n .git-branch {\n color: #8b949e;\n }\n\n .git-branch::before {\n content: '\u2387 ';\n }\n\n .git-modified {\n color: #f85149;\n }\n\n .git-unpushed {\n color: #d29922;\n }\n\n .git-clean {\n color: #3fb950;\n }\n\n .needs-testing {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n background: #490202;\n color: #f85149;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .flag {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n letter-spacing: 0.3px;\n }\n\n .flag.ok {\n background: #0d2818;\n color: #3fb950;\n }\n\n .flag.pending {\n background: #3d2e00;\n color: #d29922;\n }\n\n .card-footer {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n margin-top: 8px;\n font-size: 10px;\n color: #484f58;\n }\n\n .card-footer .spacer {\n margin-left: auto;\n }\n\n .notes-panel {\n background: #1a1e2e;\n border: 1px solid #2d333b;\n border-radius: 8px;\n padding: 12px;\n min-width: 0;\n }\n\n .notes-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 8px;\n font-size: 12px;\n font-weight: 600;\n color: #8b949e;\n }\n\n .notes-header .count {\n background: #2d333b;\n color: #c9d1d9;\n font-size: 10px;\n padding: 1px 7px;\n border-radius: 8px;\n }\n\n .note-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 4px;\n font-size: 12px;\n color: #c9d1d9;\n transition: background 0.15s;\n }\n\n .note-item:hover {\n background: #21262d;\n }\n\n .note-item .note-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: text;\n }\n\n .note-clock {\n font-size: 11px;\n cursor: default;\n flex-shrink: 0;\n }\n\n .note-thumb {\n width: 32px;\n height: 32px;\n object-fit: cover;\n border-radius: 4px;\n cursor: pointer;\n flex-shrink: 0;\n border: 1px solid #30363d;\n transition: transform 0.15s;\n }\n\n .note-thumb:hover {\n transform: scale(1.1);\n border-color: #58a6ff;\n }\n\n .note-lightbox {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.85);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n cursor: pointer;\n }\n\n .note-lightbox img {\n max-width: 90vw;\n max-height: 90vh;\n border-radius: 8px;\n box-shadow: 0 0 40px rgba(0,0,0,0.5);\n }\n\n .note-grip {\n cursor: grab;\n color: #484f58;\n font-size: 10px;\n user-select: none;\n }\n .note-item.dragging {\n opacity: 0.4;\n }\n .note-item.drag-over {\n border-top: 2px solid #58a6ff;\n margin-top: -2px;\n }\n .note-btn.move {\n background: none;\n color: #484f58;\n padding: 0 2px;\n font-size: 8px;\n min-width: 16px;\n }\n .note-btn.move:hover {\n color: #58a6ff;\n }\n .note-btn {\n font-family: 'JetBrains Mono', monospace;\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n transition: opacity 0.2s;\n }\n\n .note-btn:hover { opacity: 0.85; }\n\n .note-btn.send {\n background: #238636;\n color: #fff;\n }\n\n .note-btn.delete {\n background: #21262d;\n color: #8b949e;\n }\n\n .note-btn.delete:hover {\n background: #da3633;\n color: #fff;\n }\n\n .note-add-row {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n }\n\n .empty {\n text-align: center;\n padding: 60px 20px;\n color: #484f58;\n }\n\n .empty h2 {\n font-size: 18px;\n color: #8b949e;\n margin-bottom: 8px;\n }\n\n .empty p {\n font-size: 13px;\n }\n\n @media (max-width: 768px) {\n body { padding: 12px; }\n\n header { flex-direction: column; align-items: flex-start; gap: 8px; }\n\n .logo h1 { font-size: 18px; }\n\n .sessions {\n grid-template-columns: 1fr;\n gap: 10px;\n }\n\n .project-header {\n flex-wrap: wrap;\n }\n\n .project-path { display: none; }\n\n .card { padding: 12px; }\n\n .card-title { font-size: 13px; }\n\n .action-btn {\n padding: 8px 18px;\n font-size: 13px;\n }\n\n .reply-input {\n font-size: 13px;\n padding: 8px 10px;\n }\n\n .ci-row { flex-wrap: wrap; gap: 6px; }\n\n .pending-box { font-size: 11px; }\n\n .pending-box code { font-size: 9px; }\n }\n\n @media (max-width: 480px) {\n body { padding: 8px; }\n\n .logo h1 { font-size: 16px; }\n\n .badge { font-size: 9px; padding: 2px 6px; }\n\n .git-row { flex-wrap: wrap; gap: 6px; }\n\n .action-btn {\n padding: 10px 20px;\n font-size: 14px;\n }\n\n .action-btn.allow-all {\n width: 100%;\n text-align: center;\n }\n }\n\n .scanline {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: repeating-linear-gradient(\n 0deg,\n transparent,\n transparent 2px,\n rgba(0, 0, 0, 0.03) 2px,\n rgba(0, 0, 0, 0.03) 4px\n );\n z-index: 999;\n }\n </style>\n</head>\n<body>\n <div class=\"scanline\"></div>\n <header>\n <div class=\"logo\">\n <h1>claude-pager<span class=\"cursor\"></span></h1>\n </div>\n <div class=\"meta\">\n <button class=\"action-btn allow-all\" id=\"allowAllBtn\" style=\"display:none\" onclick=\"allowAll()\">Allow All</button>\n <span class=\"status-dot connected\" id=\"statusDot\"></span>\n <span id=\"lastUpdate\">connecting...</span>\n </div>\n </header>\n <main id=\"projects\"></main>\n\n <script>\n let data = null;\n const sentMessages = new Map(); // sessionId \u2192 { icon, text, at }\n\n function getPinnedOrder() {\n try { return JSON.parse(localStorage.getItem('dashboard-pin-order') || '[]'); }\n catch { return []; }\n }\n\n function savePinnedOrder(order) {\n localStorage.setItem('dashboard-pin-order', JSON.stringify(order));\n }\n\n function togglePin(name) {\n const order = getPinnedOrder();\n const idx = order.indexOf(name);\n if (idx >= 0) {\n order.splice(idx, 1);\n } else {\n order.push(name);\n }\n savePinnedOrder(order);\n if (data) render(data);\n }\n\n function sortProjects(projects) {\n const pinned = getPinnedOrder();\n const hasQuestion = (p) => p.sessions.some(s =>\n s.state === 'waiting_permission' || s.state === 'waiting_input'\n );\n return [...projects].sort((a, b) => {\n // Tier 1: projects with a session asking something float to the top.\n const aQ = hasQuestion(a);\n const bQ = hasQuestion(b);\n if (aQ !== bQ) return aQ ? -1 : 1;\n\n // Within the same tier, pinned projects keep their pinned order.\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 if (aIsPinned && bIsPinned) return aPin - bPin;\n if (aIsPinned) return -1;\n if (bIsPinned) return 1;\n\n // Otherwise preserve backend's state-based ordering.\n return 0;\n });\n }\n\n function escapeHtml(s) {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function timeAgo(epochMs) {\n if (!epochMs) return 'unknown';\n const s = Math.floor((Date.now() - epochMs) / 1000);\n if (s < 10) return 'just now';\n if (s < 60) return s + 's ago';\n if (s < 3600) return Math.floor(s / 60) + 'm ago';\n if (s < 86400) return Math.floor(s / 3600) + 'h ago';\n return Math.floor(s / 86400) + 'd ago';\n }\n\n function noteAgeColor(epochMs) {\n const m = (Date.now() - epochMs) / 60000;\n if (m < 10) return '#3fb950'; // green \u2014 fresh\n if (m < 60) return '#d29922'; // yellow \u2014 aging\n if (m < 360) return '#f0883e'; // orange \u2014 old\n return '#f85149'; // red \u2014 stale\n }\n\n function formatToolInput(input) {\n if (!input) return '';\n const hasDiff = input.includes('--- old') && input.includes('+++ new');\n if (hasDiff) {\n const lines = input.slice(0, 800).split('\\n');\n const html = lines.map(line => {\n const escaped = escapeHtml(line);\n if (line.startsWith('+++ new')) return '<span style=\"color:#3fb950;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('--- old')) return '<span style=\"color:#f85149;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('+')) return '<span style=\"color:#3fb950\">' + escaped + '</span>';\n if (line.startsWith('-')) return '<span style=\"color:#f85149\">' + escaped + '</span>';\n return escaped;\n }).join('\\n');\n return '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + html + '</pre>';\n }\n return '<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>";
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 <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.min.css\">\n <script src=\"https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js\"></script>\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 .term-overlay {\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 }\n\n .term-modal {\n width: min(1100px, 94vw);\n height: min(760px, 90vh);\n background: #0d1117;\n border: 1px solid #30363d;\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n box-shadow: 0 0 40px rgba(0,0,0,0.6);\n overflow: hidden;\n }\n\n .term-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid #21262d;\n font-size: 13px;\n color: #c9d1d9;\n }\n\n .term-head .term-title { font-weight: 600; color: #f0f6fc; }\n .term-head .term-pane { color: #8b949e; }\n .term-head .term-close {\n margin-left: auto;\n background: none; border: none; color: #8b949e;\n font-size: 18px; cursor: pointer; padding: 0 4px;\n }\n .term-head .term-close:hover { color: #f85149; }\n\n .term-body { flex: 1; min-height: 0; padding: 8px; }\n .term-body .xterm { height: 100%; }\n\n .term-input-row {\n display: flex;\n gap: 8px;\n padding: 10px 14px;\n border-top: 1px solid #21262d;\n }\n .term-input-row input {\n flex: 1;\n background: #161b22;\n border: 1px solid #30363d;\n border-radius: 6px;\n color: #c9d1d9;\n font-family: 'JetBrains Mono', monospace;\n font-size: 12px;\n padding: 6px 10px;\n }\n .term-input-row input:focus { outline: none; border-color: #58a6ff; }\n\n .term-btn {\n background: none; border: none; cursor: pointer;\n font-size: 13px; opacity: 0.35; transition: opacity 0.2s; padding: 2px 4px;\n }\n .term-btn:hover { opacity: 0.9; }\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 const hasQuestion = (p) => p.sessions.some(s =>\n s.state === 'waiting_permission' || s.state === 'waiting_input'\n );\n return [...projects].sort((a, b) => {\n // Tier 1: projects with a session asking something float to the top.\n const aQ = hasQuestion(a);\n const bQ = hasQuestion(b);\n if (aQ !== bQ) return aQ ? -1 : 1;\n\n // Within the same tier, pinned projects keep their pinned order.\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 if (aIsPinned && bIsPinned) return aPin - bPin;\n if (aIsPinned) return -1;\n if (bIsPinned) return 1;\n\n // Otherwise preserve backend's state-based ordering.\n return 0;\n });\n }\n\n function escapeHtml(s) {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function timeAgo(epochMs) {\n if (!epochMs) return 'unknown';\n const s = Math.floor((Date.now() - epochMs) / 1000);\n if (s < 10) return 'just now';\n if (s < 60) return s + 's ago';\n if (s < 3600) return Math.floor(s / 60) + 'm ago';\n if (s < 86400) return Math.floor(s / 3600) + 'h ago';\n return Math.floor(s / 86400) + 'd ago';\n }\n\n function noteAgeColor(epochMs) {\n const m = (Date.now() - epochMs) / 60000;\n if (m < 10) return '#3fb950'; // green \u2014 fresh\n if (m < 60) return '#d29922'; // yellow \u2014 aging\n if (m < 360) return '#f0883e'; // orange \u2014 old\n return '#f85149'; // red \u2014 stale\n }\n\n function formatToolInput(input) {\n if (!input) return '';\n const hasDiff = input.includes('--- old') && input.includes('+++ new');\n if (hasDiff) {\n const lines = input.slice(0, 800).split('\\n');\n const html = lines.map(line => {\n const escaped = escapeHtml(line);\n if (line.startsWith('+++ new')) return '<span style=\"color:#3fb950;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('--- old')) return '<span style=\"color:#f85149;font-weight:600\">' + escaped + '</span>';\n if (line.startsWith('+')) return '<span style=\"color:#3fb950\">' + escaped + '</span>';\n if (line.startsWith('-')) return '<span style=\"color:#f85149\">' + escaped + '</span>';\n return escaped;\n }).join('\\n');\n return '<pre style=\"font-size:10px;color:#8b949e;word-break:break-all;white-space:pre-wrap;margin:4px 0;max-height:200px;overflow-y:auto\">' + html + '</pre>';\n }\n return '<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 ${(data && data.terminalEnabled && s.tmuxPane)\n ? '<button class=\"term-btn\" onclick=\"openTerminal(\\'' + s.sessionId + '\\',\\'' + escapeHtml(s.tmuxPane) + '\\')\" title=\"Open terminal\">\uD83D\uDCDF</button>'\n : ''}\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 // --- Terminal view ---\n let termState = null; // { overlay, term, sessionId, pollTimer }\n\n async function openTerminal(sessionId, pane) {\n if (termState) closeTerminal();\n\n const overlay = document.createElement('div');\n overlay.className = 'term-overlay';\n overlay.innerHTML =\n '<div class=\"term-modal\">'\n + '<div class=\"term-head\">'\n + '<span class=\"term-title\">Terminal</span>'\n + '<span class=\"term-pane\">pane ' + pane + '</span>'\n + '<button class=\"term-close\" title=\"Close\">\u2715</button>'\n + '</div>'\n + '<div class=\"term-body\"><div class=\"term-xterm\"></div></div>'\n + '<div class=\"term-input-row\">'\n + '<input type=\"text\" class=\"term-send\" placeholder=\"Type and press Enter to send to the session...\">'\n + '</div>'\n + '</div>';\n document.body.appendChild(overlay);\n\n const term = new Terminal({\n fontFamily: 'JetBrains Mono, monospace',\n fontSize: 12,\n convertEol: true,\n disableStdin: true,\n theme: { background: '#0d1117', foreground: '#c9d1d9' },\n scrollback: 5000,\n });\n term.open(overlay.querySelector('.term-xterm'));\n\n termState = { overlay, term, sessionId, pollTimer: null };\n\n // Close on \u2715, on click outside the modal, or Escape.\n overlay.querySelector('.term-close').onclick = closeTerminal;\n overlay.onclick = (e) => { if (e.target === overlay) closeTerminal(); };\n document.addEventListener('keydown', onTermEsc);\n\n const sendInput = overlay.querySelector('.term-send');\n sendInput.onkeydown = (e) => {\n if (e.key === 'Enter') {\n sendTerminalKeys(sessionId, sendInput.value);\n sendInput.value = '';\n }\n };\n sendInput.focus();\n\n await refreshTerminal();\n termState.pollTimer = setInterval(refreshTerminal, 2000);\n }\n\n function onTermEsc(e) { if (e.key === 'Escape') closeTerminal(); }\n\n function closeTerminal() {\n if (!termState) return;\n clearInterval(termState.pollTimer);\n document.removeEventListener('keydown', onTermEsc);\n termState.term.dispose();\n termState.overlay.remove();\n termState = null;\n }\n\n async function refreshTerminal() {\n if (!termState) return;\n try {\n const res = await fetch('/api/v1/session/' + termState.sessionId + '/terminal');\n if (!res.ok) return;\n const data = await res.json();\n // Snapshot rendering: reset then write the captured buffer (with ANSI).\n termState.term.reset();\n termState.term.write(data.content || '');\n } catch (e) {\n console.error('terminal refresh error:', e);\n }\n }\n\n async function sendTerminalKeys(sessionId, keys) {\n if (!keys) return;\n try {\n await fetch('/api/v1/session/' + sessionId + '/keys', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ keys, enter: true }),\n });\n setTimeout(refreshTerminal, 150);\n } catch (e) {\n console.error('terminal send error:', e);\n }\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,i+0CAo1CnB,CAAC"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,+8/CAw/CnB,CAAC"}
@@ -9,6 +9,8 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
9
9
  <title>claude-pager dashboard</title>
10
10
  <link rel="preconnect" href="https://fonts.googleapis.com">
11
11
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet">
12
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.min.css">
13
+ <script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js"></script>
12
14
  <style>
13
15
  * { margin: 0; padding: 0; box-sizing: border-box; }
14
16
 
@@ -527,6 +529,74 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
527
529
  box-shadow: 0 0 40px rgba(0,0,0,0.5);
528
530
  }
529
531
 
532
+ .term-overlay {
533
+ position: fixed;
534
+ top: 0; left: 0; right: 0; bottom: 0;
535
+ background: rgba(0,0,0,0.85);
536
+ display: flex;
537
+ align-items: center;
538
+ justify-content: center;
539
+ z-index: 1000;
540
+ }
541
+
542
+ .term-modal {
543
+ width: min(1100px, 94vw);
544
+ height: min(760px, 90vh);
545
+ background: #0d1117;
546
+ border: 1px solid #30363d;
547
+ border-radius: 10px;
548
+ display: flex;
549
+ flex-direction: column;
550
+ box-shadow: 0 0 40px rgba(0,0,0,0.6);
551
+ overflow: hidden;
552
+ }
553
+
554
+ .term-head {
555
+ display: flex;
556
+ align-items: center;
557
+ gap: 10px;
558
+ padding: 10px 14px;
559
+ border-bottom: 1px solid #21262d;
560
+ font-size: 13px;
561
+ color: #c9d1d9;
562
+ }
563
+
564
+ .term-head .term-title { font-weight: 600; color: #f0f6fc; }
565
+ .term-head .term-pane { color: #8b949e; }
566
+ .term-head .term-close {
567
+ margin-left: auto;
568
+ background: none; border: none; color: #8b949e;
569
+ font-size: 18px; cursor: pointer; padding: 0 4px;
570
+ }
571
+ .term-head .term-close:hover { color: #f85149; }
572
+
573
+ .term-body { flex: 1; min-height: 0; padding: 8px; }
574
+ .term-body .xterm { height: 100%; }
575
+
576
+ .term-input-row {
577
+ display: flex;
578
+ gap: 8px;
579
+ padding: 10px 14px;
580
+ border-top: 1px solid #21262d;
581
+ }
582
+ .term-input-row input {
583
+ flex: 1;
584
+ background: #161b22;
585
+ border: 1px solid #30363d;
586
+ border-radius: 6px;
587
+ color: #c9d1d9;
588
+ font-family: 'JetBrains Mono', monospace;
589
+ font-size: 12px;
590
+ padding: 6px 10px;
591
+ }
592
+ .term-input-row input:focus { outline: none; border-color: #58a6ff; }
593
+
594
+ .term-btn {
595
+ background: none; border: none; cursor: pointer;
596
+ font-size: 13px; opacity: 0.35; transition: opacity 0.2s; padding: 2px 4px;
597
+ }
598
+ .term-btn:hover { opacity: 0.9; }
599
+
530
600
  .note-grip {
531
601
  cursor: grab;
532
602
  color: #484f58;
@@ -864,6 +934,9 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
864
934
  <div class="card-header">
865
935
  <span class="card-title" id="\${titleId}">\${escapeHtml(s.title)}</span>
866
936
  <span class="badge \${s.state}">\${stateLabel(s.state)}</span>
937
+ \${(data && data.terminalEnabled && s.tmuxPane)
938
+ ? '<button class="term-btn" onclick="openTerminal(\\'' + s.sessionId + '\\',\\'' + escapeHtml(s.tmuxPane) + '\\')" title="Open terminal">📟</button>'
939
+ : ''}
867
940
  <button class="dismiss-btn" onclick="dismissSession('\${s.sessionId}')" title="Dismiss session">🗑</button>
868
941
  </div>
869
942
  \${expandBtn}
@@ -1331,6 +1404,97 @@ exports.DASHBOARD_HTML = `<!DOCTYPE html>
1331
1404
  fetchDashboard();
1332
1405
  }
1333
1406
 
1407
+ // --- Terminal view ---
1408
+ let termState = null; // { overlay, term, sessionId, pollTimer }
1409
+
1410
+ async function openTerminal(sessionId, pane) {
1411
+ if (termState) closeTerminal();
1412
+
1413
+ const overlay = document.createElement('div');
1414
+ overlay.className = 'term-overlay';
1415
+ overlay.innerHTML =
1416
+ '<div class="term-modal">'
1417
+ + '<div class="term-head">'
1418
+ + '<span class="term-title">Terminal</span>'
1419
+ + '<span class="term-pane">pane ' + pane + '</span>'
1420
+ + '<button class="term-close" title="Close">✕</button>'
1421
+ + '</div>'
1422
+ + '<div class="term-body"><div class="term-xterm"></div></div>'
1423
+ + '<div class="term-input-row">'
1424
+ + '<input type="text" class="term-send" placeholder="Type and press Enter to send to the session...">'
1425
+ + '</div>'
1426
+ + '</div>';
1427
+ document.body.appendChild(overlay);
1428
+
1429
+ const term = new Terminal({
1430
+ fontFamily: 'JetBrains Mono, monospace',
1431
+ fontSize: 12,
1432
+ convertEol: true,
1433
+ disableStdin: true,
1434
+ theme: { background: '#0d1117', foreground: '#c9d1d9' },
1435
+ scrollback: 5000,
1436
+ });
1437
+ term.open(overlay.querySelector('.term-xterm'));
1438
+
1439
+ termState = { overlay, term, sessionId, pollTimer: null };
1440
+
1441
+ // Close on ✕, on click outside the modal, or Escape.
1442
+ overlay.querySelector('.term-close').onclick = closeTerminal;
1443
+ overlay.onclick = (e) => { if (e.target === overlay) closeTerminal(); };
1444
+ document.addEventListener('keydown', onTermEsc);
1445
+
1446
+ const sendInput = overlay.querySelector('.term-send');
1447
+ sendInput.onkeydown = (e) => {
1448
+ if (e.key === 'Enter') {
1449
+ sendTerminalKeys(sessionId, sendInput.value);
1450
+ sendInput.value = '';
1451
+ }
1452
+ };
1453
+ sendInput.focus();
1454
+
1455
+ await refreshTerminal();
1456
+ termState.pollTimer = setInterval(refreshTerminal, 2000);
1457
+ }
1458
+
1459
+ function onTermEsc(e) { if (e.key === 'Escape') closeTerminal(); }
1460
+
1461
+ function closeTerminal() {
1462
+ if (!termState) return;
1463
+ clearInterval(termState.pollTimer);
1464
+ document.removeEventListener('keydown', onTermEsc);
1465
+ termState.term.dispose();
1466
+ termState.overlay.remove();
1467
+ termState = null;
1468
+ }
1469
+
1470
+ async function refreshTerminal() {
1471
+ if (!termState) return;
1472
+ try {
1473
+ const res = await fetch('/api/v1/session/' + termState.sessionId + '/terminal');
1474
+ if (!res.ok) return;
1475
+ const data = await res.json();
1476
+ // Snapshot rendering: reset then write the captured buffer (with ANSI).
1477
+ termState.term.reset();
1478
+ termState.term.write(data.content || '');
1479
+ } catch (e) {
1480
+ console.error('terminal refresh error:', e);
1481
+ }
1482
+ }
1483
+
1484
+ async function sendTerminalKeys(sessionId, keys) {
1485
+ if (!keys) return;
1486
+ try {
1487
+ await fetch('/api/v1/session/' + sessionId + '/keys', {
1488
+ method: 'POST',
1489
+ headers: { 'Content-Type': 'application/json' },
1490
+ body: JSON.stringify({ keys, enter: true }),
1491
+ });
1492
+ setTimeout(refreshTerminal, 150);
1493
+ } catch (e) {
1494
+ console.error('terminal send error:', e);
1495
+ }
1496
+ }
1497
+
1334
1498
  async function fetchDashboard() {
1335
1499
  try {
1336
1500
  const res = await fetch('/api/v1/dashboard');
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAo1CtB,CAAC"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAw/CtB,CAAC"}
@@ -99,5 +99,29 @@ function makeEvent(id, overrides) {
99
99
  strict_1.default.equal(result.question.event.id, 'evt-2');
100
100
  });
101
101
  });
102
+ (0, node_test_1.describe)('pending TTL configuration', () => {
103
+ (0, node_test_1.it)('defaults to 12 hours', () => {
104
+ // Default is 12h, but a previous test may have overridden it. Reset
105
+ // and assert the documented default.
106
+ (0, events_js_1.setPendingTtlMs)(12 * 60 * 60 * 1000);
107
+ strict_1.default.equal((0, events_js_1.getPendingTtlMs)(), 12 * 60 * 60 * 1000);
108
+ });
109
+ (0, node_test_1.it)('expires pending entries after the configured TTL', async () => {
110
+ (0, events_js_1.setPendingTtlMs)(50);
111
+ (0, events_js_1.addPending)(makeEvent('evt-ttl'));
112
+ strict_1.default.equal((0, events_js_1.listPending)().length, 1);
113
+ await new Promise(r => setTimeout(r, 120));
114
+ strict_1.default.equal((0, events_js_1.listPending)().length, 0, 'entry should have expired');
115
+ // Restore default so it does not leak to other tests.
116
+ (0, events_js_1.setPendingTtlMs)(12 * 60 * 60 * 1000);
117
+ });
118
+ (0, node_test_1.it)('ignores non-positive values', () => {
119
+ (0, events_js_1.setPendingTtlMs)(5000);
120
+ (0, events_js_1.setPendingTtlMs)(0);
121
+ (0, events_js_1.setPendingTtlMs)(-1);
122
+ strict_1.default.equal((0, events_js_1.getPendingTtlMs)(), 5000, 'invalid values should not clobber the current TTL');
123
+ (0, events_js_1.setPendingTtlMs)(12 * 60 * 60 * 1000);
124
+ });
125
+ });
102
126
  });
103
127
  //# sourceMappingURL=events.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.test.js","sourceRoot":"","sources":["../../../src/sessions/__tests__/events.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.test.js","sourceRoot":"","sources":["../../../src/sessions/__tests__/events.test.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ export declare function addPending(event: RelayEvent, channelMessageId?: string)
3
3
  export declare function getPending(eventId: string): PendingQuestion | undefined;
4
4
  export declare function removePending(eventId: string): void;
5
5
  export declare function isResolved(eventId: string): boolean;
6
+ export declare function setPendingTtlMs(ms: number): void;
7
+ export declare function getPendingTtlMs(): number;
6
8
  export declare function listPending(): PendingQuestion[];
7
9
  export interface ResolvedResponse {
8
10
  question: PendingQuestion;
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sessions/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ/D,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAU/E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEvE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQnD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnD;AAKD,wBAAgB,WAAW,IAAI,eAAe,EAAE,CAS/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAsCxE"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sessions/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ/D,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAU/E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEvE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQnD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnD;AAQD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,WAAW,IAAI,eAAe,EAAE,CAS/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAsCxE"}
@@ -4,6 +4,8 @@ exports.addPending = addPending;
4
4
  exports.getPending = getPending;
5
5
  exports.removePending = removePending;
6
6
  exports.isResolved = isResolved;
7
+ exports.setPendingTtlMs = setPendingTtlMs;
8
+ exports.getPendingTtlMs = getPendingTtlMs;
7
9
  exports.listPending = listPending;
8
10
  exports.resolveResponse = resolveResponse;
9
11
  const pending = new Map();
@@ -38,12 +40,22 @@ function removePending(eventId) {
38
40
  function isResolved(eventId) {
39
41
  return resolved.has(eventId);
40
42
  }
41
- const PENDING_TTL_MS = 30 * 60 * 1000; // 30 minutes
43
+ // Default 12 hours so overnight prompts survive until morning. Configurable
44
+ // via RelayConfig.pendingTtlSeconds — the daemon calls setPendingTtlMs() at
45
+ // startup with the configured value.
46
+ let pendingTtlMs = 12 * 60 * 60 * 1000;
47
+ function setPendingTtlMs(ms) {
48
+ if (ms > 0)
49
+ pendingTtlMs = ms;
50
+ }
51
+ function getPendingTtlMs() {
52
+ return pendingTtlMs;
53
+ }
42
54
  function listPending() {
43
55
  // Expire old questions
44
56
  const now = Date.now();
45
57
  for (const [id, q] of pending) {
46
- if (now - q.notifiedAt > PENDING_TTL_MS) {
58
+ if (now - q.notifiedAt > pendingTtlMs) {
47
59
  pending.delete(id);
48
60
  }
49
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sessions/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sessions/events.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -15,6 +15,7 @@ export interface RelayConfig {
15
15
  dataDir: string;
16
16
  ci?: CIConfig;
17
17
  dashboard?: DashboardConfig;
18
+ pendingTtlSeconds?: number;
18
19
  }
19
20
  export interface DashboardConfig {
20
21
  bind?: string;
@@ -23,6 +24,7 @@ export interface DashboardConfig {
23
24
  password: string;
24
25
  };
25
26
  allowInsecure?: boolean;
27
+ allowTerminal?: boolean;
26
28
  }
27
29
  export interface ChannelConfig {
28
30
  type: 'ntfy' | 'telegram';
@@ -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;IACd,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAK9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAG/C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;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"}
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;IACd,SAAS,CAAC,EAAE,eAAe,CAAC;IAI5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAK9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAG/C,aAAa,CAAC,EAAE,OAAO,CAAC;IAIxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-pager",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "Remote notification and response relay for Claude Code CLI sessions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",