@agentdeck/bridge 1.0.11 → 1.0.13

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.
Files changed (62) hide show
  1. package/assets/fm-helper/agentdeck-fm-helper +0 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +34 -19
  4. package/dist/cli.js.map +1 -1
  5. package/dist/d200h/hid-protocol.d.ts +62 -0
  6. package/dist/d200h/hid-protocol.d.ts.map +1 -0
  7. package/dist/d200h/hid-protocol.js +124 -0
  8. package/dist/d200h/hid-protocol.js.map +1 -0
  9. package/dist/d200h/image-renderer.d.ts +24 -0
  10. package/dist/d200h/image-renderer.d.ts.map +1 -0
  11. package/dist/d200h/image-renderer.js +321 -0
  12. package/dist/d200h/image-renderer.js.map +1 -0
  13. package/dist/daemon-server.d.ts.map +1 -1
  14. package/dist/daemon-server.js +47 -1
  15. package/dist/daemon-server.js.map +1 -1
  16. package/dist/daemon.js +1 -1
  17. package/dist/hook-migration.d.ts +2 -0
  18. package/dist/hook-migration.d.ts.map +1 -0
  19. package/dist/hook-migration.js +116 -0
  20. package/dist/hook-migration.js.map +1 -0
  21. package/dist/modules/d200h-module.d.ts +65 -0
  22. package/dist/modules/d200h-module.d.ts.map +1 -0
  23. package/dist/modules/d200h-module.js +495 -0
  24. package/dist/modules/d200h-module.js.map +1 -0
  25. package/dist/modules/d200h-renderer.d.ts +7 -0
  26. package/dist/modules/d200h-renderer.d.ts.map +1 -0
  27. package/dist/modules/d200h-renderer.js +321 -0
  28. package/dist/modules/d200h-renderer.js.map +1 -0
  29. package/dist/modules/trmnl-module.d.ts +38 -0
  30. package/dist/modules/trmnl-module.d.ts.map +1 -0
  31. package/dist/modules/trmnl-module.js +111 -0
  32. package/dist/modules/trmnl-module.js.map +1 -0
  33. package/dist/passive-observer.d.ts +14 -1
  34. package/dist/passive-observer.d.ts.map +1 -1
  35. package/dist/passive-observer.js +90 -15
  36. package/dist/passive-observer.js.map +1 -1
  37. package/dist/trmnl/byos-server.d.ts +39 -0
  38. package/dist/trmnl/byos-server.d.ts.map +1 -0
  39. package/dist/trmnl/byos-server.js +301 -0
  40. package/dist/trmnl/byos-server.js.map +1 -0
  41. package/dist/trmnl/frame-cache.d.ts +37 -0
  42. package/dist/trmnl/frame-cache.d.ts.map +1 -0
  43. package/dist/trmnl/frame-cache.js +157 -0
  44. package/dist/trmnl/frame-cache.js.map +1 -0
  45. package/dist/trmnl/image-renderer.d.ts +27 -0
  46. package/dist/trmnl/image-renderer.d.ts.map +1 -0
  47. package/dist/trmnl/image-renderer.js +235 -0
  48. package/dist/trmnl/image-renderer.js.map +1 -0
  49. package/dist/trmnl/trmnl-settings.d.ts +96 -0
  50. package/dist/trmnl/trmnl-settings.d.ts.map +1 -0
  51. package/dist/trmnl/trmnl-settings.js +177 -0
  52. package/dist/trmnl/trmnl-settings.js.map +1 -0
  53. package/dist/trmnl/trmnl-telemetry.d.ts +47 -0
  54. package/dist/trmnl/trmnl-telemetry.d.ts.map +1 -0
  55. package/dist/trmnl/trmnl-telemetry.js +56 -0
  56. package/dist/trmnl/trmnl-telemetry.js.map +1 -0
  57. package/dist/whisper-server-manager.d.ts +19 -0
  58. package/dist/whisper-server-manager.d.ts.map +1 -0
  59. package/dist/whisper-server-manager.js +171 -0
  60. package/dist/whisper-server-manager.js.map +1 -0
  61. package/fm-helper/AgentDeckFMHelper.swift +111 -10
  62. package/package.json +3 -3
@@ -0,0 +1,321 @@
1
+ /**
2
+ * D200H framebuffer renderer — renders AgentDeck 14-key dashboard
3
+ * Screen: 960×540 logical (landscape), fb0: 540×960 with 90° CW rotation
4
+ * Transform: screen(sx,sy) → fb(sy, 959-sx)
5
+ * Layout: 3 rows × 5 cols, row2 col3+4 merged = 14 keys
6
+ */
7
+ import { execSync } from 'child_process';
8
+ import { writeFileSync } from 'fs';
9
+ import { tmpdir } from 'os';
10
+ import { join } from 'path';
11
+ import { debug } from '../logger.js';
12
+ const TAG = 'd200h-render';
13
+ // Screen dimensions (logical, after rotation)
14
+ const SW = 960;
15
+ const SH = 540;
16
+ // Framebuffer dimensions (physical)
17
+ const FBW = 540;
18
+ const FBH = 960;
19
+ // Double buffer
20
+ const FB_SIZE = FBW * FBH * 2 * 4; // 2 pages, BGRA32
21
+ const PAGE_SIZE = FBW * FBH * 4;
22
+ // Key grid: 3 rows × 5 cols
23
+ const COLS = 5;
24
+ const ROWS = 3;
25
+ const COL_W = Math.floor(SW / COLS); // 192
26
+ const ROW_H = Math.floor(SH / ROWS); // 180
27
+ const GAP = 3;
28
+ const D200H_SERIAL = '0123456789ABCDEF';
29
+ // Colors (BGRA format)
30
+ const COLOR_BG = [20, 20, 25, 255]; // dark background
31
+ const COLOR_IDLE = [60, 50, 40, 255]; // slate
32
+ const COLOR_PROCESSING = [160, 80, 20, 255]; // blue (BGRA: high B)
33
+ const COLOR_AWAITING = [30, 140, 200, 255]; // amber
34
+ const COLOR_ERROR = [40, 40, 180, 255]; // red
35
+ const COLOR_TEXT = [220, 220, 220, 255]; // light gray
36
+ const COLOR_DIM = [120, 120, 120, 255]; // dim text
37
+ const COLOR_ACCENT = [200, 140, 40, 255]; // accent blue
38
+ const COLOR_GREEN = [60, 180, 60, 255]; // green
39
+ const COLOR_BAR_BG = [50, 50, 55, 255]; // gauge background
40
+ const COLOR_BAR_5H = [180, 160, 40, 255]; // 5h gauge color
41
+ const COLOR_BAR_7D = [160, 80, 40, 255]; // 7d gauge color
42
+ // 3×5 bitmap font — full alphanumeric (lowercase rendered, input lowercased)
43
+ const FONT_3X5 = {
44
+ '0': [0b111, 0b101, 0b101, 0b101, 0b111],
45
+ '1': [0b010, 0b110, 0b010, 0b010, 0b111],
46
+ '2': [0b111, 0b001, 0b111, 0b100, 0b111],
47
+ '3': [0b111, 0b001, 0b111, 0b001, 0b111],
48
+ '4': [0b101, 0b101, 0b111, 0b001, 0b001],
49
+ '5': [0b111, 0b100, 0b111, 0b001, 0b111],
50
+ '6': [0b111, 0b100, 0b111, 0b101, 0b111],
51
+ '7': [0b111, 0b001, 0b010, 0b010, 0b010],
52
+ '8': [0b111, 0b101, 0b111, 0b101, 0b111],
53
+ '9': [0b111, 0b101, 0b111, 0b001, 0b111],
54
+ 'a': [0b010, 0b101, 0b111, 0b101, 0b101],
55
+ 'b': [0b110, 0b101, 0b110, 0b101, 0b110],
56
+ 'c': [0b011, 0b100, 0b100, 0b100, 0b011],
57
+ 'd': [0b110, 0b101, 0b101, 0b101, 0b110],
58
+ 'e': [0b111, 0b100, 0b110, 0b100, 0b111],
59
+ 'f': [0b111, 0b100, 0b110, 0b100, 0b100],
60
+ 'g': [0b011, 0b100, 0b101, 0b101, 0b011],
61
+ 'h': [0b101, 0b101, 0b111, 0b101, 0b101],
62
+ 'i': [0b111, 0b010, 0b010, 0b010, 0b111],
63
+ 'j': [0b001, 0b001, 0b001, 0b101, 0b010],
64
+ 'k': [0b101, 0b110, 0b100, 0b110, 0b101],
65
+ 'l': [0b100, 0b100, 0b100, 0b100, 0b111],
66
+ 'm': [0b101, 0b111, 0b111, 0b101, 0b101],
67
+ 'n': [0b101, 0b111, 0b111, 0b111, 0b101],
68
+ 'o': [0b010, 0b101, 0b101, 0b101, 0b010],
69
+ 'p': [0b110, 0b101, 0b110, 0b100, 0b100],
70
+ 'q': [0b010, 0b101, 0b101, 0b110, 0b011],
71
+ 'r': [0b110, 0b101, 0b110, 0b101, 0b101],
72
+ 's': [0b011, 0b100, 0b010, 0b001, 0b110],
73
+ 't': [0b111, 0b010, 0b010, 0b010, 0b010],
74
+ 'u': [0b101, 0b101, 0b101, 0b101, 0b011],
75
+ 'v': [0b101, 0b101, 0b101, 0b101, 0b010],
76
+ 'w': [0b101, 0b101, 0b111, 0b111, 0b101],
77
+ 'x': [0b101, 0b101, 0b010, 0b101, 0b101],
78
+ 'y': [0b101, 0b101, 0b010, 0b010, 0b010],
79
+ 'z': [0b111, 0b001, 0b010, 0b100, 0b111],
80
+ '%': [0b101, 0b001, 0b010, 0b100, 0b101],
81
+ '.': [0b000, 0b000, 0b000, 0b000, 0b010],
82
+ ',': [0b000, 0b000, 0b000, 0b010, 0b100],
83
+ ':': [0b000, 0b010, 0b000, 0b010, 0b000],
84
+ '-': [0b000, 0b000, 0b111, 0b000, 0b000],
85
+ '_': [0b000, 0b000, 0b000, 0b000, 0b111],
86
+ '/': [0b001, 0b001, 0b010, 0b100, 0b100],
87
+ '$': [0b011, 0b110, 0b010, 0b011, 0b110],
88
+ ' ': [0b000, 0b000, 0b000, 0b000, 0b000],
89
+ };
90
+ const KEY_DEFS = [
91
+ // Row 0: Mode, Session, Usage, Quick1, Quick2
92
+ { id: 0, col: 0, row: 0, colSpan: 1, label: 'MODE', type: 'action' },
93
+ { id: 1, col: 1, row: 0, colSpan: 1, label: 'SESSION', type: 'info' },
94
+ { id: 2, col: 2, row: 0, colSpan: 1, label: 'USAGE', type: 'info' },
95
+ { id: 3, col: 3, row: 0, colSpan: 1, label: 'QA 1', type: 'action' },
96
+ { id: 4, col: 4, row: 0, colSpan: 1, label: 'QA 2', type: 'action' },
97
+ // Row 1: Quick3, Quick4, Model, 5h Rate, 7d Rate
98
+ { id: 5, col: 0, row: 1, colSpan: 1, label: 'QA 3', type: 'action' },
99
+ { id: 6, col: 1, row: 1, colSpan: 1, label: 'QA 4', type: 'action' },
100
+ { id: 7, col: 2, row: 1, colSpan: 1, label: 'MODEL', type: 'info' },
101
+ { id: 8, col: 3, row: 1, colSpan: 1, label: '5h', type: 'info' },
102
+ { id: 9, col: 4, row: 1, colSpan: 1, label: '7d', type: 'info' },
103
+ // Row 2: Stop, Tokens, Cost, Info (merged 2-wide)
104
+ { id: 10, col: 0, row: 2, colSpan: 1, label: 'STOP', type: 'action' },
105
+ { id: 11, col: 1, row: 2, colSpan: 1, label: 'TOKENS', type: 'info' },
106
+ { id: 12, col: 2, row: 2, colSpan: 1, label: 'COST', type: 'info' },
107
+ { id: 13, col: 3, row: 2, colSpan: 2, label: 'INFO', type: 'info' },
108
+ ];
109
+ /** Cached framebuffer */
110
+ let fbBuffer = null;
111
+ let lastRenderHash = '';
112
+ const tmpPath = join(tmpdir(), 'd200h_fb.raw');
113
+ function setPixel(fb, sx, sy, color) {
114
+ // Screen(sx,sy) → fb(sy, 959-sx)
115
+ const fx = sy;
116
+ const fy = 959 - sx;
117
+ if (fx < 0 || fx >= FBW || fy < 0 || fy >= FBH)
118
+ return;
119
+ const offset = (fy * FBW + fx) * 4;
120
+ fb[offset] = color[0]; // B
121
+ fb[offset + 1] = color[1]; // G
122
+ fb[offset + 2] = color[2]; // R
123
+ fb[offset + 3] = color[3]; // A
124
+ }
125
+ function fillRect(fb, x1, y1, x2, y2, color) {
126
+ for (let sy = Math.max(0, y1); sy < Math.min(SH, y2); sy++) {
127
+ for (let sx = Math.max(0, x1); sx < Math.min(SW, x2); sx++) {
128
+ setPixel(fb, sx, sy, color);
129
+ }
130
+ }
131
+ }
132
+ function drawText(fb, x, y, text, scale, color) {
133
+ let cx = x;
134
+ for (const ch of text.toLowerCase()) {
135
+ const glyph = FONT_3X5[ch];
136
+ if (!glyph) {
137
+ cx += 4 * scale;
138
+ continue;
139
+ }
140
+ for (let dy = 0; dy < 5; dy++) {
141
+ for (let dx = 0; dx < 3; dx++) {
142
+ if (glyph[dy] & (1 << (2 - dx))) {
143
+ for (let ssy = 0; ssy < scale; ssy++) {
144
+ for (let ssx = 0; ssx < scale; ssx++) {
145
+ setPixel(fb, cx + dx * scale + ssx, y + dy * scale + ssy, color);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ cx += 4 * scale;
152
+ }
153
+ }
154
+ function drawTextCentered(fb, cx, cy, text, scale, color) {
155
+ const textW = text.length * 4 * scale;
156
+ const textH = 5 * scale;
157
+ drawText(fb, cx - Math.floor(textW / 2), cy - Math.floor(textH / 2), text, scale, color);
158
+ }
159
+ function drawGauge(fb, x, y, w, h, percent, barColor) {
160
+ fillRect(fb, x, y, x + w, y + h, COLOR_BAR_BG);
161
+ const filled = Math.floor(w * Math.min(100, Math.max(0, percent)) / 100);
162
+ fillRect(fb, x, y, x + filled, y + h, barColor);
163
+ }
164
+ function parseState(evt) {
165
+ return {
166
+ state: evt?.state ?? 'DISCONNECTED',
167
+ projectName: evt?.projectName ?? '',
168
+ modelName: evt?.modelName ?? '',
169
+ agentType: evt?.agentType ?? 'claude-code',
170
+ mode: evt?.mode ?? 'default',
171
+ fiveHourPercent: typeof evt?.fiveHourPercent === 'number' ? evt.fiveHourPercent : undefined,
172
+ sevenDayPercent: typeof evt?.sevenDayPercent === 'number' ? evt.sevenDayPercent : undefined,
173
+ totalTokens: evt?.totalTokens ?? 0,
174
+ totalCost: evt?.totalCost ?? 0,
175
+ options: (evt?.options ?? []).map((o) => o?.label ?? o ?? ''),
176
+ currentTool: evt?.currentTool ?? '',
177
+ };
178
+ }
179
+ function stateColor(state) {
180
+ switch (state) {
181
+ case 'PROCESSING': return COLOR_PROCESSING;
182
+ case 'AWAITING_PERMISSION':
183
+ case 'AWAITING_INPUT':
184
+ case 'AWAITING_PROMPT': return COLOR_AWAITING;
185
+ case 'ERROR': return COLOR_ERROR;
186
+ default: return COLOR_IDLE;
187
+ }
188
+ }
189
+ /** Render a single key to the framebuffer */
190
+ function renderKey(fb, key, state) {
191
+ const x1 = key.col * COL_W + GAP;
192
+ const y1 = key.row * ROW_H + GAP;
193
+ const x2 = (key.col + key.colSpan) * COL_W - GAP;
194
+ const y2 = (key.row + 1) * ROW_H - GAP;
195
+ const cx = Math.floor((x1 + x2) / 2);
196
+ const cy = Math.floor((y1 + y2) / 2);
197
+ switch (key.id) {
198
+ case 0: // MODE
199
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
200
+ drawTextCentered(fb, cx, cy - 16, 'mode', 3, COLOR_DIM);
201
+ drawTextCentered(fb, cx, cy + 10, state.mode, 3, COLOR_TEXT);
202
+ break;
203
+ case 1: // SESSION
204
+ fillRect(fb, x1, y1, x2, y2, stateColor(state.state));
205
+ drawTextCentered(fb, cx, cy - 20, state.projectName.slice(0, 10), 3, COLOR_TEXT);
206
+ drawTextCentered(fb, cx, cy + 5, state.state.slice(0, 12).toLowerCase(), 2, COLOR_DIM);
207
+ break;
208
+ case 2: // USAGE
209
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
210
+ drawTextCentered(fb, cx, cy - 16, 'usage', 3, COLOR_DIM);
211
+ break;
212
+ case 3:
213
+ case 4:
214
+ case 5:
215
+ case 6: { // Quick Actions
216
+ const qaIdx = key.id <= 4 ? key.id - 3 : key.id - 3;
217
+ const label = state.options[qaIdx] ?? '';
218
+ if (label) {
219
+ fillRect(fb, x1, y1, x2, y2, COLOR_ACCENT);
220
+ drawTextCentered(fb, cx, cy, label.slice(0, 10), 3, COLOR_TEXT);
221
+ }
222
+ else {
223
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
224
+ drawTextCentered(fb, cx, cy, key.label, 2, COLOR_DIM);
225
+ }
226
+ break;
227
+ }
228
+ case 7: // MODEL
229
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
230
+ drawTextCentered(fb, cx, cy - 12, 'model', 2, COLOR_DIM);
231
+ drawTextCentered(fb, cx, cy + 8, state.modelName.slice(0, 10), 3, COLOR_TEXT);
232
+ break;
233
+ case 8: // 5h Rate
234
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
235
+ drawTextCentered(fb, cx, y1 + 20, '5h', 2, COLOR_DIM);
236
+ if (state.fiveHourPercent != null) {
237
+ drawGauge(fb, x1 + 10, cy - 4, x2 - x1 - 20, 12, state.fiveHourPercent, COLOR_BAR_5H);
238
+ drawTextCentered(fb, cx, y2 - 25, `${Math.round(state.fiveHourPercent)}%`, 3, COLOR_TEXT);
239
+ }
240
+ break;
241
+ case 9: // 7d Rate
242
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
243
+ drawTextCentered(fb, cx, y1 + 20, '7d', 2, COLOR_DIM);
244
+ if (state.sevenDayPercent != null) {
245
+ drawGauge(fb, x1 + 10, cy - 4, x2 - x1 - 20, 12, state.sevenDayPercent, COLOR_BAR_7D);
246
+ drawTextCentered(fb, cx, y2 - 25, `${Math.round(state.sevenDayPercent)}%`, 3, COLOR_TEXT);
247
+ }
248
+ break;
249
+ case 10: // STOP
250
+ fillRect(fb, x1, y1, x2, y2, state.state === 'PROCESSING' ? COLOR_ERROR : COLOR_IDLE);
251
+ drawTextCentered(fb, cx, cy, 'stop', 3, state.state === 'PROCESSING' ? COLOR_TEXT : COLOR_DIM);
252
+ break;
253
+ case 11: // TOKENS
254
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
255
+ drawTextCentered(fb, cx, cy - 12, 'tokens', 2, COLOR_DIM);
256
+ const tk = state.totalTokens > 1000 ? `${(state.totalTokens / 1000).toFixed(0)}k` : `${state.totalTokens}`;
257
+ drawTextCentered(fb, cx, cy + 10, tk, 3, COLOR_TEXT);
258
+ break;
259
+ case 12: // COST
260
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
261
+ drawTextCentered(fb, cx, cy - 12, 'cost', 2, COLOR_DIM);
262
+ drawTextCentered(fb, cx, cy + 10, `${state.totalCost.toFixed(2)}`, 3, COLOR_GREEN);
263
+ break;
264
+ case 13: // INFO (merged)
265
+ fillRect(fb, x1, y1, x2, y2, COLOR_IDLE);
266
+ if (state.currentTool) {
267
+ drawTextCentered(fb, cx, cy - 12, 'tool', 2, COLOR_DIM);
268
+ drawTextCentered(fb, cx, cy + 10, state.currentTool.slice(0, 18), 2, COLOR_TEXT);
269
+ }
270
+ else {
271
+ drawTextCentered(fb, cx, cy - 12, state.agentType, 2, COLOR_DIM);
272
+ drawTextCentered(fb, cx, cy + 10, 'agentdeck', 3, COLOR_ACCENT);
273
+ }
274
+ break;
275
+ }
276
+ }
277
+ /** Render full dashboard and return raw BGRA framebuffer */
278
+ export function renderDashboard(stateEvt) {
279
+ const fb = Buffer.alloc(FB_SIZE, 0);
280
+ const state = parseState(stateEvt);
281
+ // Fill background
282
+ for (let sy = 0; sy < SH; sy++) {
283
+ for (let sx = 0; sx < SW; sx++) {
284
+ setPixel(fb, sx, sy, COLOR_BG);
285
+ }
286
+ }
287
+ // Render all 14 keys
288
+ for (const key of KEY_DEFS) {
289
+ renderKey(fb, key, state);
290
+ }
291
+ return fb;
292
+ }
293
+ /** Push framebuffer to D200H via ADB */
294
+ export function pushToDevice(fb) {
295
+ try {
296
+ writeFileSync(tmpPath, fb);
297
+ execSync(`adb -s ${D200H_SERIAL} push ${tmpPath} /tmp/agentdeck.raw`, {
298
+ stdio: 'pipe',
299
+ timeout: 5000,
300
+ });
301
+ execSync(`adb -s ${D200H_SERIAL} shell "cat /tmp/agentdeck.raw > /dev/fb0"`, {
302
+ stdio: 'pipe',
303
+ timeout: 3000,
304
+ });
305
+ return true;
306
+ }
307
+ catch (err) {
308
+ debug(TAG, `push failed: ${err}`);
309
+ return false;
310
+ }
311
+ }
312
+ /** Render and push dashboard to D200H */
313
+ export function updateD200hDisplay(stateEvt) {
314
+ const hash = JSON.stringify(stateEvt?.state) + JSON.stringify(stateEvt?.fiveHourPercent);
315
+ if (hash === lastRenderHash)
316
+ return; // skip if unchanged
317
+ lastRenderHash = hash;
318
+ const fb = renderDashboard(stateEvt);
319
+ pushToDevice(fb);
320
+ }
321
+ //# sourceMappingURL=d200h-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"d200h-renderer.js","sourceRoot":"","sources":["../../src/modules/d200h-renderer.ts"],"names":[],"mappings":"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E,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxC,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * TRMNL device module — keeps the BYOS frame cache fresh.
3
+ *
4
+ * TRMNL is a WiFi e-ink display that PULLS rendered images from a server on its
5
+ * own schedule (the BYOS /api/display contract), so unlike Pixoo/D200H this
6
+ * module never pushes to hardware. It only subscribes to AgentDeck state
7
+ * broadcasts and re-renders the cached 800×480 1-bit frame when the visual state
8
+ * changes; the daemon's HTTP routes (bridge/src/trmnl/byos-server.ts) serve that
9
+ * frame when a device polls.
10
+ *
11
+ * Rendering is gated on a device being registered (or `trmnl.enabled`) so a
12
+ * machine with no TRMNL panel does no extra rasterization. The gate is refreshed
13
+ * from settings on a short interval and immediately when a device enrolls.
14
+ */
15
+ import type { DeviceModule, BridgeContext } from './types.js';
16
+ export declare class TrmnlModule implements DeviceModule {
17
+ readonly name = "trmnl";
18
+ private lastState;
19
+ private lastUsage;
20
+ private lastSessions;
21
+ private gateActive;
22
+ private gateTimer;
23
+ shouldActivate(config: 'auto' | boolean): Promise<boolean>;
24
+ start(ctx: BridgeContext): Promise<void>;
25
+ stop(): Promise<void>;
26
+ statusSnapshot(): Record<string, unknown>;
27
+ /** Re-read settings to decide whether rendering is worthwhile. */
28
+ private refreshGate;
29
+ private render;
30
+ /**
31
+ * Combine the latest state_update + usage_update + sessions into one render
32
+ * event. usage_update is spread last so its 5H/7D + reset fields win. No time
33
+ * component is added: the frame hash must change only on real visual change so
34
+ * a real TRMNL can skip the (battery + flaky-WiFi) re-download otherwise.
35
+ */
36
+ private buildRenderState;
37
+ }
38
+ //# sourceMappingURL=trmnl-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trmnl-module.d.ts","sourceRoot":"","sources":["../../src/modules/trmnl-module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgB9D,qBAAa,WAAY,YAAW,YAAY;IAC9C,QAAQ,CAAC,IAAI,WAAW;IAExB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAA+C;IAE1D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ1D,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAoBzC,kEAAkE;IAClE,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,MAAM;IAWd;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;CAYzB"}
@@ -0,0 +1,111 @@
1
+ import { initTrmnlRenderer, isTrmnlResvgLoaded } from '../trmnl/image-renderer.js';
2
+ import { refreshTrmnlFrame, setTrmnlState, getTrmnlFrameKeys, getTrmnlActivity } from '../trmnl/frame-cache.js';
3
+ import { loadTrmnlConfig, effectiveRefreshRate } from '../trmnl/trmnl-settings.js';
4
+ import { getTelemetryHealth } from '../trmnl/trmnl-telemetry.js';
5
+ import { debug } from '../logger.js';
6
+ const TAG = 'trmnl';
7
+ const GATE_REFRESH_MS = 30_000;
8
+ function isControllableOrObserved(session) {
9
+ // TRMNL is a read-only dashboard — show every live session (controllable or
10
+ // observed), unlike D200H which filters to controllable for its buttons.
11
+ return !!session && session.alive !== false;
12
+ }
13
+ export class TrmnlModule {
14
+ name = 'trmnl';
15
+ lastState = null;
16
+ lastUsage = null;
17
+ lastSessions = [];
18
+ gateActive = false;
19
+ gateTimer = null;
20
+ async shouldActivate(config) {
21
+ if (config === false)
22
+ return false;
23
+ if (config === true)
24
+ return true;
25
+ // auto: active if a device is registered or the user forced it on.
26
+ const cfg = loadTrmnlConfig();
27
+ return cfg.enabled || cfg.devices.length > 0;
28
+ }
29
+ async start(ctx) {
30
+ await initTrmnlRenderer();
31
+ this.refreshGate();
32
+ this.gateTimer = setInterval(() => this.refreshGate(), GATE_REFRESH_MS);
33
+ ctx.wsServer.onBroadcast((evt) => {
34
+ if (evt?.type === 'state_update') {
35
+ this.lastState = evt;
36
+ this.render();
37
+ }
38
+ else if (evt?.type === 'usage_update') {
39
+ // state_update never carries usage; the 5H/7D gauges + token/cost footer
40
+ // only exist on usage_update (same as Pixoo/ESP32). Without this the panel
41
+ // renders a confident 0% forever.
42
+ this.lastUsage = evt;
43
+ this.render();
44
+ }
45
+ else if (evt?.type === 'sessions_list') {
46
+ this.lastSessions = (evt.sessions ?? []).filter(isControllableOrObserved);
47
+ this.render();
48
+ }
49
+ });
50
+ debug(TAG, `started (resvg=${isTrmnlResvgLoaded()}, gate=${this.gateActive})`);
51
+ }
52
+ async stop() {
53
+ if (this.gateTimer) {
54
+ clearInterval(this.gateTimer);
55
+ this.gateTimer = null;
56
+ }
57
+ }
58
+ statusSnapshot() {
59
+ const cfg = loadTrmnlConfig();
60
+ const activeResolutions = getTrmnlFrameKeys();
61
+ const activity = getTrmnlActivity();
62
+ const currentRefreshRate = effectiveRefreshRate(cfg, activity);
63
+ return {
64
+ resvgLoaded: isTrmnlResvgLoaded(),
65
+ gateActive: this.gateActive,
66
+ enabled: cfg.enabled,
67
+ deviceCount: cfg.devices.length,
68
+ refreshRate: cfg.refreshRate,
69
+ refreshActive: cfg.refreshActive,
70
+ currentRefreshRate,
71
+ activeResolutions,
72
+ frameCount: activeResolutions.length,
73
+ // Health uses the current adaptive cadence so "stale" tracks real expectations.
74
+ telemetry: getTelemetryHealth(currentRefreshRate),
75
+ };
76
+ }
77
+ /** Re-read settings to decide whether rendering is worthwhile. */
78
+ refreshGate() {
79
+ const cfg = loadTrmnlConfig();
80
+ this.gateActive = cfg.enabled || cfg.devices.length > 0;
81
+ }
82
+ render() {
83
+ const evt = this.buildRenderState();
84
+ if (!this.gateActive) {
85
+ // No device yet — remember the state so the frame is correct the instant a
86
+ // device enrolls (byos-server forces a render then), but skip rasterizing.
87
+ setTrmnlState(evt);
88
+ return;
89
+ }
90
+ refreshTrmnlFrame(evt);
91
+ }
92
+ /**
93
+ * Combine the latest state_update + usage_update + sessions into one render
94
+ * event. usage_update is spread last so its 5H/7D + reset fields win. No time
95
+ * component is added: the frame hash must change only on real visual change so
96
+ * a real TRMNL can skip the (battery + flaky-WiFi) re-download otherwise.
97
+ */
98
+ buildRenderState() {
99
+ const u = this.lastUsage ?? {};
100
+ // Usage is "known" only when the hub actually has subscription quota (the
101
+ // gauges are meaningful); otherwise the layout renders "—" instead of 0%.
102
+ const usageKnown = u.fiveHourPercent != null || u.sevenDayPercent != null;
103
+ return {
104
+ ...(this.lastState ?? {}),
105
+ ...u,
106
+ usageKnown,
107
+ allSessions: this.lastSessions,
108
+ };
109
+ }
110
+ }
111
+ //# sourceMappingURL=trmnl-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trmnl-module.js","sourceRoot":"","sources":["../../src/modules/trmnl-module.ts"],"names":[],"mappings":"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"}
@@ -132,11 +132,24 @@ export declare function collectCodexSessionsFromRollouts(processes: ProcInfo[],
132
132
  * Admission is settled downstream instead, by whether the pid holds an open
133
133
  * rollout file: an app-server with no conversation holds none and is dropped in
134
134
  * `collectCodexSessions`. The Electron helpers ship a capital-`Codex` basename
135
- * (`Codex (Renderer)`), so `cmdHasBinary` already excludes them.
135
+ * (`Codex (Renderer)` on macOS, `Codex.exe` on Windows), which the exact-case
136
+ * stem compare in `cmdHasBinary` excludes; the `--type=` guard is the belt to
137
+ * that suspenders, since only the Windows helpers carry the app's own name.
136
138
  */
137
139
  export declare function isCodexSessionProcessCommand(command: string): boolean;
138
140
  export declare function isAntigravityProcessCommand(command: string): boolean;
139
141
  export declare function dedupeObservedSessions(observed: ObservedSession[], managedSessions: EnrichedSession[], processes: ProcInfo[]): ObservedSession[];
140
142
  export declare function parseLsofRollouts(output: string): Map<number, string[]>;
143
+ /**
144
+ * A process that can own a standalone Claude Code session.
145
+ *
146
+ * The native installer's `claude` / `claude.exe` is the direct case. The npm
147
+ * install is not: on Windows `claude` is a `.cmd` shim, so the process the scan
148
+ * sees is `node.exe "…\@anthropic-ai\claude-code\cli.js"` and the binary name
149
+ * never appears in argv[0]. Matching the package path is exact enough that it
150
+ * cannot collide with anything else, and it costs nothing on POSIX, where the
151
+ * same shape appears for npm installs behind a shebang.
152
+ */
153
+ export declare function isClaudeSessionProcessCommand(command: string): boolean;
141
154
  export {};
142
155
  //# sourceMappingURL=passive-observer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passive-observer.d.ts","sourceRoot":"","sources":["../src/passive-observer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passive-observer.d.ts","sourceRoot":"","sources":["../src/passive-observer.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAW/D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,UAAU,EAAE,OAAO,CAAC;CACrB;AAgBD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU7C;AASD,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;iDAC6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,UAAU,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;sEAIkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAQD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,sBAAuB,SAAQ,oBAAoB;IAC3D,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3E;AAUD;;;;GAIG;AACH,qBAAa,iBAAiB;IAGhB,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAA6C;gBAExC,IAAI,GAAE,6BAAoE;IAExF,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC;IAsBpE,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI;IAMxC,IAAI,IAAI,IAAI,MAAM,CAA8B;CACjD;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,iBAAiB,CAA2B;IAEpD;;0DAEsD;IACtD,WAAW,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAEtC;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe,EAAE,eAAe,EAAE,GAAG,eAAe,EAAE;YAYhD,IAAI;CAenB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAc5D;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAoFpE;AAgCD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAwHlE;AAsDD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CA2B7D;AAED;0EAC0E;AAC1E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED;;iEAEiE;AACjE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5B,QAAQ,SAAI,GACX,MAAM,GAAG,SAAS,CASpB;AAiDD,+EAA+E;AAC/E,wBAAsB,gCAAgC,CACpD,SAAS,EAAE,QAAQ,EAAE,EACrB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACpC,YAAY,EAAE,iBAAiB,GAC9B,OAAO,CAAC,eAAe,EAAE,CAAC,CAiD5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGrE;AAiFD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBpE;AA6BD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EAAE,EAC3B,eAAe,EAAE,eAAe,EAAE,EAClC,SAAS,EAAE,QAAQ,EAAE,GACpB,eAAe,EAAE,CAkBnB;AAkGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAgBvE;AAmOD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAItE"}