@agentdeck/bridge 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fm-helper/agentdeck-fm-helper +0 -0
- package/dist/adapters/claude-code.d.ts.map +1 -1
- package/dist/adapters/claude-code.js +3 -0
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adb-reverse.d.ts.map +1 -1
- package/dist/adb-reverse.js +4 -2
- package/dist/adb-reverse.js.map +1 -1
- package/dist/apme/collector.js +2 -2
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/outcome.js +2 -2
- package/dist/apme/outcome.js.map +1 -1
- package/dist/apme/runner.js +3 -3
- package/dist/apme/runner.js.map +1 -1
- package/dist/ble-sync-spawn.js +1 -1
- package/dist/ble-sync-spawn.js.map +1 -1
- package/dist/calendar.d.ts +82 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +324 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card-feed.d.ts +63 -5
- package/dist/card-feed.d.ts.map +1 -1
- package/dist/card-feed.js +218 -14
- package/dist/card-feed.js.map +1 -1
- package/dist/card-modules.d.ts +4 -0
- package/dist/card-modules.d.ts.map +1 -1
- package/dist/card-modules.js +5 -3
- package/dist/card-modules.js.map +1 -1
- package/dist/check-deps.js +4 -4
- package/dist/check-deps.js.map +1 -1
- package/dist/cli.d.ts +35 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +269 -9
- package/dist/cli.js.map +1 -1
- package/dist/codex-otel.d.ts +89 -0
- package/dist/codex-otel.d.ts.map +1 -0
- package/dist/codex-otel.js +487 -0
- package/dist/codex-otel.js.map +1 -0
- package/dist/codex-rate-limits.d.ts.map +1 -1
- package/dist/codex-rate-limits.js +15 -3
- package/dist/codex-rate-limits.js.map +1 -1
- package/dist/daemon-server.d.ts +4 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +797 -54
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon-ws-client.d.ts +108 -24
- package/dist/daemon-ws-client.d.ts.map +1 -1
- package/dist/daemon-ws-client.js +175 -39
- package/dist/daemon-ws-client.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/device-voice-reply.d.ts.map +1 -1
- package/dist/device-voice-reply.js +15 -3
- package/dist/device-voice-reply.js.map +1 -1
- package/dist/device-voice.d.ts +37 -0
- package/dist/device-voice.d.ts.map +1 -1
- package/dist/device-voice.js +130 -1
- package/dist/device-voice.js.map +1 -1
- package/dist/diag-analyzer.d.ts.map +1 -1
- package/dist/diag-analyzer.js +1 -0
- package/dist/diag-analyzer.js.map +1 -1
- package/dist/display-monitor.d.ts.map +1 -1
- package/dist/display-monitor.js +1 -0
- package/dist/display-monitor.js.map +1 -1
- package/dist/esp32-serial.d.ts +4 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +6 -3
- package/dist/esp32-serial.js.map +1 -1
- package/dist/foundation-models-helper.d.ts +23 -0
- package/dist/foundation-models-helper.d.ts.map +1 -1
- package/dist/foundation-models-helper.js +32 -0
- package/dist/foundation-models-helper.js.map +1 -1
- package/dist/gateway-probe.js +1 -1
- package/dist/gateway-probe.js.map +1 -1
- package/dist/glance-frame.d.ts +64 -0
- package/dist/glance-frame.d.ts.map +1 -0
- package/dist/glance-frame.js +364 -0
- package/dist/glance-frame.js.map +1 -0
- package/dist/hook-codex-sessions.d.ts +40 -0
- package/dist/hook-codex-sessions.d.ts.map +1 -0
- package/dist/hook-codex-sessions.js +174 -0
- package/dist/hook-codex-sessions.js.map +1 -0
- package/dist/idotmatrix/idotmatrix-discover.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-discover.js +7 -4
- package/dist/idotmatrix/idotmatrix-discover.js.map +1 -1
- package/dist/idotmatrix/idotmatrix-settings.d.ts +15 -0
- package/dist/idotmatrix/idotmatrix-settings.d.ts.map +1 -1
- package/dist/idotmatrix/idotmatrix-settings.js +21 -0
- package/dist/idotmatrix/idotmatrix-settings.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -7
- package/dist/index.js.map +1 -1
- package/dist/linux-service.d.ts +52 -0
- package/dist/linux-service.d.ts.map +1 -0
- package/dist/linux-service.js +206 -0
- package/dist/linux-service.js.map +1 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +15 -0
- package/dist/logger.js.map +1 -1
- package/dist/mdns-discover.d.ts +19 -0
- package/dist/mdns-discover.d.ts.map +1 -0
- package/dist/mdns-discover.js +109 -0
- package/dist/mdns-discover.js.map +1 -0
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +1 -0
- package/dist/model-catalog.js.map +1 -1
- package/dist/modules/adb-module.js +1 -1
- package/dist/modules/adb-module.js.map +1 -1
- package/dist/output-parser.d.ts +9 -0
- package/dist/output-parser.d.ts.map +1 -1
- package/dist/output-parser.js +67 -16
- package/dist/output-parser.js.map +1 -1
- package/dist/passive-observer.d.ts +57 -8
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +210 -74
- package/dist/passive-observer.js.map +1 -1
- package/dist/pixoo/pixoo-bridge.d.ts.map +1 -1
- package/dist/pixoo/pixoo-bridge.js +47 -6
- package/dist/pixoo/pixoo-bridge.js.map +1 -1
- package/dist/pixoo/pixoo-renderer.d.ts +2 -1
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
- package/dist/pixoo/pixoo-renderer.js +137 -8
- package/dist/pixoo/pixoo-renderer.js.map +1 -1
- package/dist/pocket-autonomy.d.ts +78 -0
- package/dist/pocket-autonomy.d.ts.map +1 -0
- package/dist/pocket-autonomy.js +529 -0
- package/dist/pocket-autonomy.js.map +1 -0
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +3 -2
- package/dist/pty-manager.js.map +1 -1
- package/dist/python-ble-runtime.d.ts +2 -0
- package/dist/python-ble-runtime.d.ts.map +1 -1
- package/dist/python-ble-runtime.js +2 -1
- package/dist/python-ble-runtime.js.map +1 -1
- package/dist/remote-sessions.d.ts +64 -0
- package/dist/remote-sessions.d.ts.map +1 -0
- package/dist/remote-sessions.js +81 -0
- package/dist/remote-sessions.js.map +1 -0
- package/dist/review-runner.js +2 -2
- package/dist/review-runner.js.map +1 -1
- package/dist/session-aggregator.d.ts +2 -0
- package/dist/session-aggregator.d.ts.map +1 -1
- package/dist/session-aggregator.js +6 -1
- package/dist/session-aggregator.js.map +1 -1
- package/dist/session-focus-relay.d.ts +47 -1
- package/dist/session-focus-relay.d.ts.map +1 -1
- package/dist/session-focus-relay.js +130 -15
- package/dist/session-focus-relay.js.map +1 -1
- package/dist/session-push-channel.d.ts +31 -0
- package/dist/session-push-channel.d.ts.map +1 -0
- package/dist/session-push-channel.js +94 -0
- package/dist/session-push-channel.js.map +1 -0
- package/dist/session-registry.d.ts +126 -0
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/session-registry.js +180 -3
- package/dist/session-registry.js.map +1 -1
- package/dist/subagent-timeline.d.ts +34 -0
- package/dist/subagent-timeline.d.ts.map +1 -0
- package/dist/subagent-timeline.js +156 -0
- package/dist/subagent-timeline.js.map +1 -0
- package/dist/timebox/timebox-discover.js +1 -1
- package/dist/timebox/timebox-discover.js.map +1 -1
- package/dist/tui/gauge.d.ts +4 -2
- package/dist/tui/gauge.d.ts.map +1 -1
- package/dist/tui/gauge.js +8 -4
- package/dist/tui/gauge.js.map +1 -1
- package/dist/tui/renderer.d.ts.map +1 -1
- package/dist/tui/renderer.js +28 -0
- package/dist/tui/renderer.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/usage-api.d.ts +43 -0
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +114 -9
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts +19 -0
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +35 -0
- package/dist/usage-event.js.map +1 -1
- package/dist/utils/project-name.d.ts.map +1 -1
- package/dist/utils/project-name.js +1 -0
- package/dist/utils/project-name.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +3 -2
- package/dist/version-check.js.map +1 -1
- package/dist/voice-assistant.d.ts.map +1 -1
- package/dist/voice-assistant.js +2 -1
- package/dist/voice-assistant.js.map +1 -1
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +1 -0
- package/dist/voice.js.map +1 -1
- package/dist/weather.d.ts +72 -0
- package/dist/weather.d.ts.map +1 -0
- package/dist/weather.js +206 -0
- package/dist/weather.js.map +1 -0
- package/dist/windows-service.js +5 -5
- package/dist/windows-service.js.map +1 -1
- package/fm-helper/AgentDeckFMHelper.swift +200 -0
- package/package.json +15 -13
- package/src/idotmatrix/identity_generated.py +50 -0
- package/src/idotmatrix/scan.py +33 -13
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Glance Frame — daemon-side pixel rendering of the sleep/ambient dashboard
|
|
3
|
+
* (M8). The device-side glance (fork `renderGlance`) is the offline fallback;
|
|
4
|
+
* this is the rich face: the daemon lays the glance out as SVG (real
|
|
5
|
+
* typography, vector weather icons, gauge bars), rasterizes it with sharp,
|
|
6
|
+
* ordered-dithers to 1-bit, and packs it in the e-ink framebuffer format
|
|
7
|
+
* (1bpp, MSB-first rows, 1 = white — matching `clearScreen(0xFF)` semantics).
|
|
8
|
+
*
|
|
9
|
+
* tesserae-inspired (concepts only — tesserae is AGPL): server renders pixels,
|
|
10
|
+
* the panel is a display driver, and the browser preview shows the *exact*
|
|
11
|
+
* frame the panel will hold (`?format=png` returns the dithered pixels, so
|
|
12
|
+
* "looked fine in the preview, broke on the panel" cannot happen).
|
|
13
|
+
*
|
|
14
|
+
* Ordered (Bayer) dithering, not error diffusion: deterministic output means
|
|
15
|
+
* the frame bytes — and therefore the frame sig — are stable for stable input.
|
|
16
|
+
*/
|
|
17
|
+
import sharp from 'sharp';
|
|
18
|
+
export const GLANCE_FRAME_BOARDS = {
|
|
19
|
+
// X3 panel: physical 792×528 (stride 99); layout stays portrait 528×792.
|
|
20
|
+
xteink_x3: { width: 528, height: 792, landscape: false, rotateToPhysical: true },
|
|
21
|
+
xteink_x4: { width: 800, height: 480, landscape: true },
|
|
22
|
+
inkdeck: { width: 800, height: 480, landscape: true },
|
|
23
|
+
};
|
|
24
|
+
// ===== Weather icons (vector, 1-bit friendly) =====
|
|
25
|
+
/** WMO code → icon key. Kept alongside `wmoSummary` in weather.ts semantics. */
|
|
26
|
+
export function wmoIconKey(code) {
|
|
27
|
+
if (code === undefined || !Number.isFinite(code))
|
|
28
|
+
return 'cloud';
|
|
29
|
+
if (code === 0)
|
|
30
|
+
return 'sun';
|
|
31
|
+
if (code <= 2)
|
|
32
|
+
return 'partly';
|
|
33
|
+
if (code === 3)
|
|
34
|
+
return 'cloud';
|
|
35
|
+
if (code === 45 || code === 48)
|
|
36
|
+
return 'fog';
|
|
37
|
+
if ((code >= 51 && code <= 67) || (code >= 80 && code <= 82))
|
|
38
|
+
return 'rain';
|
|
39
|
+
if ((code >= 71 && code <= 77) || code === 85 || code === 86)
|
|
40
|
+
return 'snow';
|
|
41
|
+
if (code >= 95)
|
|
42
|
+
return 'storm';
|
|
43
|
+
return 'cloud';
|
|
44
|
+
}
|
|
45
|
+
/** Icon drawn in a 100×100 viewbox, stroke-based so it reads at 1 bit. */
|
|
46
|
+
function iconSvg(key) {
|
|
47
|
+
const cloud = '<path d="M28 62 a16 16 0 0 1 4 -31 a22 22 0 0 1 42 -4 a15 15 0 0 1 2 30 z" fill="none" stroke="black" stroke-width="7" stroke-linejoin="round"/>';
|
|
48
|
+
switch (key) {
|
|
49
|
+
case 'sun': {
|
|
50
|
+
const rays = Array.from({ length: 8 }, (_, i) => {
|
|
51
|
+
const a = (i * Math.PI) / 4;
|
|
52
|
+
const x1 = 50 + Math.cos(a) * 34, y1 = 50 + Math.sin(a) * 34;
|
|
53
|
+
const x2 = 50 + Math.cos(a) * 46, y2 = 50 + Math.sin(a) * 46;
|
|
54
|
+
return `<line x1="${x1.toFixed(1)}" y1="${y1.toFixed(1)}" x2="${x2.toFixed(1)}" y2="${y2.toFixed(1)}" stroke="black" stroke-width="7" stroke-linecap="round"/>`;
|
|
55
|
+
}).join('');
|
|
56
|
+
return `<circle cx="50" cy="50" r="21" fill="none" stroke="black" stroke-width="7"/>${rays}`;
|
|
57
|
+
}
|
|
58
|
+
case 'partly':
|
|
59
|
+
return ('<circle cx="66" cy="34" r="16" fill="none" stroke="black" stroke-width="6"/>' +
|
|
60
|
+
'<path d="M20 74 a13 13 0 0 1 3 -25 a18 18 0 0 1 34 -3 a12 12 0 0 1 2 28 z" fill="white" stroke="black" stroke-width="6" stroke-linejoin="round"/>');
|
|
61
|
+
case 'fog':
|
|
62
|
+
return [30, 46, 62, 78]
|
|
63
|
+
.map((y) => `<line x1="18" y1="${y}" x2="82" y2="${y}" stroke="black" stroke-width="7" stroke-linecap="round"/>`)
|
|
64
|
+
.join('');
|
|
65
|
+
case 'rain':
|
|
66
|
+
return (cloud +
|
|
67
|
+
[34, 52, 70]
|
|
68
|
+
.map((x) => `<line x1="${x}" y1="72" x2="${x - 6}" y2="88" stroke="black" stroke-width="6" stroke-linecap="round"/>`)
|
|
69
|
+
.join(''));
|
|
70
|
+
case 'snow':
|
|
71
|
+
return (cloud +
|
|
72
|
+
[34, 52, 70]
|
|
73
|
+
.map((x) => `<circle cx="${x}" cy="80" r="4" fill="black"/>`)
|
|
74
|
+
.join(''));
|
|
75
|
+
case 'storm':
|
|
76
|
+
return cloud + '<path d="M52 64 L40 84 h10 L44 100 L62 76 h-10 L58 64 z" fill="black"/>';
|
|
77
|
+
case 'cloud':
|
|
78
|
+
default:
|
|
79
|
+
return cloud;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// ===== SVG layout =====
|
|
83
|
+
const SANS = 'IBM Plex Sans, Helvetica, Arial, sans-serif';
|
|
84
|
+
const MONO = 'JetBrains Mono, Menlo, monospace';
|
|
85
|
+
/** 50% gray — the Bayer pass turns it into a clean checker; used for
|
|
86
|
+
* secondary fills so the frame has depth without real grayscale. */
|
|
87
|
+
const GRAY = '#808080';
|
|
88
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
89
|
+
/** Conservative SVG text-width estimate used only to add an honest ellipsis
|
|
90
|
+
* before the hard clip. The production renderer cannot ask librsvg for text
|
|
91
|
+
* metrics before composing the SVG, and emitting the full string lets e-ink
|
|
92
|
+
* crop a word mid-letter. Count CJK/full-width glyphs as one em and bucket the
|
|
93
|
+
* common Latin widths; the clipPath remains the final safety boundary. */
|
|
94
|
+
function fitText(s, maxWidth, fontSize) {
|
|
95
|
+
const glyphEm = (ch) => {
|
|
96
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
97
|
+
if (cp >= 0x2e80)
|
|
98
|
+
return 1;
|
|
99
|
+
if (/\s/.test(ch))
|
|
100
|
+
return 0.33;
|
|
101
|
+
if (/[ilI1.,'`|!:;]/.test(ch))
|
|
102
|
+
return 0.28;
|
|
103
|
+
if (/[mwMW@#%&]/.test(ch))
|
|
104
|
+
return 0.82;
|
|
105
|
+
return 0.56;
|
|
106
|
+
};
|
|
107
|
+
const width = (value) => [...value].reduce((sum, ch) => sum + glyphEm(ch) * fontSize, 0);
|
|
108
|
+
if (width(s) <= maxWidth)
|
|
109
|
+
return s;
|
|
110
|
+
const suffix = '…';
|
|
111
|
+
const suffixWidth = width(suffix);
|
|
112
|
+
let used = 0;
|
|
113
|
+
let out = '';
|
|
114
|
+
for (const ch of s) {
|
|
115
|
+
const next = glyphEm(ch) * fontSize;
|
|
116
|
+
if (used + next + suffixWidth > maxWidth)
|
|
117
|
+
break;
|
|
118
|
+
out += ch;
|
|
119
|
+
used += next;
|
|
120
|
+
}
|
|
121
|
+
return `${out.trimEnd()}${suffix}`;
|
|
122
|
+
}
|
|
123
|
+
function text(c, x, y, size, s, opts = {}) {
|
|
124
|
+
if (!s)
|
|
125
|
+
return;
|
|
126
|
+
c.parts.push(`<text x="${x}" y="${y}" font-family="${opts.mono ? MONO : SANS}" font-size="${size}"` +
|
|
127
|
+
(opts.weight ? ` font-weight="${opts.weight}"` : '') +
|
|
128
|
+
(opts.anchor ? ` text-anchor="${opts.anchor}"` : '') +
|
|
129
|
+
(opts.spacing ? ` letter-spacing="${opts.spacing}"` : '') +
|
|
130
|
+
` fill="${opts.fill ?? 'black'}">${esc(s)}</text>`);
|
|
131
|
+
}
|
|
132
|
+
function rule(c, x1, y, x2, thick = 2) {
|
|
133
|
+
c.parts.push(`<line x1="${x1}" y1="${y}" x2="${x2}" y2="${y}" stroke="black" stroke-width="${thick}"/>`);
|
|
134
|
+
}
|
|
135
|
+
function sectionLabel(c, x, y, label) {
|
|
136
|
+
text(c, x, y, 17, label, { weight: 700, spacing: '3' });
|
|
137
|
+
rule(c, x, y + 10, c.w - 36, 2);
|
|
138
|
+
}
|
|
139
|
+
/** One provider quota row: name + 5H/7D bars with the reset time. Returns the
|
|
140
|
+
* y consumed. */
|
|
141
|
+
function quotaRow(c, x, y, width, row) {
|
|
142
|
+
text(c, x, y + 20, 22, row.label + (row.stale ? ' *' : ''), { weight: 600 });
|
|
143
|
+
const barX = x + 118;
|
|
144
|
+
const barW = width - 118;
|
|
145
|
+
const drawBar = (by, tag, pct, extra) => {
|
|
146
|
+
if (pct === undefined)
|
|
147
|
+
return;
|
|
148
|
+
const h = 18;
|
|
149
|
+
text(c, barX - 8, by + h - 3, 15, tag, { weight: 700, anchor: 'end', mono: true });
|
|
150
|
+
c.parts.push(`<rect x="${barX}" y="${by}" width="${barW}" height="${h}" fill="white" stroke="black" stroke-width="2"/>`);
|
|
151
|
+
const fw = Math.round(((barW - 4) * Math.min(100, Math.max(0, pct))) / 100);
|
|
152
|
+
if (fw > 0)
|
|
153
|
+
c.parts.push(`<rect x="${barX + 2}" y="${by + 2}" width="${fw}" height="${h - 4}" fill="black"/>`);
|
|
154
|
+
const label = `${Math.round(pct)}%${extra ? ` ${extra}` : ''}`;
|
|
155
|
+
// Percent label sits inside the empty end of the bar when it fits, else
|
|
156
|
+
// just past the fill — always readable at 1 bit.
|
|
157
|
+
text(c, barX + barW - 6, by + h - 4, 14, label, { anchor: 'end', mono: true, fill: fw > barW - 90 ? 'white' : 'black' });
|
|
158
|
+
};
|
|
159
|
+
drawBar(y + 4, '5H', row.primaryPercent, row.primaryResetHm ? `→${row.primaryResetHm}` : undefined);
|
|
160
|
+
drawBar(y + 30, '7D', row.secondaryPercent);
|
|
161
|
+
return 62;
|
|
162
|
+
}
|
|
163
|
+
function weatherBlock(c, x, y, width, w) {
|
|
164
|
+
const startY = y;
|
|
165
|
+
// Hero: icon + big temperature.
|
|
166
|
+
const iconSize = 96;
|
|
167
|
+
c.parts.push(`<g transform="translate(${x},${y}) scale(${iconSize / 100})">${iconSvg(wmoIconKey(w.code))}</g>`);
|
|
168
|
+
const tx = x + iconSize + 26;
|
|
169
|
+
if (w.tempC !== undefined)
|
|
170
|
+
text(c, tx, y + 78, 88, `${w.tempC}°`, { weight: 700 });
|
|
171
|
+
const rx = x + width;
|
|
172
|
+
if (w.summary)
|
|
173
|
+
text(c, rx, y + 34, 26, w.summary, { weight: 600, anchor: 'end' });
|
|
174
|
+
if (w.todayMinC !== undefined && w.todayMaxC !== undefined) {
|
|
175
|
+
text(c, rx, y + 66, 21, `${w.todayMinC}–${w.todayMaxC}°`, { anchor: 'end' });
|
|
176
|
+
}
|
|
177
|
+
y += 112;
|
|
178
|
+
if (w.rain) {
|
|
179
|
+
const range = w.rain.endHm ? `${w.rain.startHm}–${w.rain.endHm}` : `~${w.rain.startHm}`;
|
|
180
|
+
text(c, x, y + 8, 22, `☂ Rain ${range} · ${w.rain.probability}%`, { weight: 600 });
|
|
181
|
+
y += 34;
|
|
182
|
+
}
|
|
183
|
+
if (w.tomorrow && (w.tomorrow.summary || w.tomorrow.minC !== undefined)) {
|
|
184
|
+
const t = w.tomorrow;
|
|
185
|
+
const bits = ['Tomorrow'];
|
|
186
|
+
if (t.summary)
|
|
187
|
+
bits.push(t.summary);
|
|
188
|
+
if (t.minC !== undefined && t.maxC !== undefined)
|
|
189
|
+
bits.push(`${t.minC}–${t.maxC}°`);
|
|
190
|
+
if (t.rainProbability !== undefined && t.rainProbability > 0)
|
|
191
|
+
bits.push(`rain ${t.rainProbability}%`);
|
|
192
|
+
text(c, x, y + 6, 19, bits.join(' · '), { fill: 'black' });
|
|
193
|
+
// A quiet gray underline separates the outlook from the sections below.
|
|
194
|
+
c.parts.push(`<rect x="${x}" y="${y + 16}" width="${width}" height="4" fill="${GRAY}"/>`);
|
|
195
|
+
y += 34;
|
|
196
|
+
}
|
|
197
|
+
return y - startY;
|
|
198
|
+
}
|
|
199
|
+
export function renderGlanceFrameSvg(input) {
|
|
200
|
+
const { width: W, height: H, landscape } = input.geometry;
|
|
201
|
+
const g = input.glance ?? {};
|
|
202
|
+
const c = { parts: [], w: W };
|
|
203
|
+
const M = 36; // outer margin
|
|
204
|
+
c.parts.push(`<rect width="${W}" height="${H}" fill="white"/>`);
|
|
205
|
+
// ── Masthead ──
|
|
206
|
+
text(c, M, 46, 24, 'AgentDeck', { weight: 700, spacing: '1' });
|
|
207
|
+
const mastRight = [g.weather?.place, input.serverHm ? `Synced ${input.serverHm}` : ''].filter(Boolean).join(' · ');
|
|
208
|
+
text(c, W - M, 46, 19, mastRight, { anchor: 'end' });
|
|
209
|
+
rule(c, M, 62, W - M, 3);
|
|
210
|
+
const colX = M;
|
|
211
|
+
const colW = landscape ? Math.floor((W - M * 2 - 40) / 2) : W - M * 2;
|
|
212
|
+
const rightX = M + colW + 40;
|
|
213
|
+
let yL = 96;
|
|
214
|
+
let yR = 96;
|
|
215
|
+
// ── Weather (left column / top block) ──
|
|
216
|
+
if (g.weather && (g.weather.tempC !== undefined || g.weather.summary)) {
|
|
217
|
+
yL += weatherBlock(c, colX, yL, colW, g.weather) + 18;
|
|
218
|
+
}
|
|
219
|
+
// ── Today's schedule (left column, under weather) ──
|
|
220
|
+
const events = g.events ?? [];
|
|
221
|
+
if (events.length > 0) {
|
|
222
|
+
sectionLabel(c, colX, yL, 'TODAY');
|
|
223
|
+
yL += 34;
|
|
224
|
+
for (const e of events) {
|
|
225
|
+
const time = e.startHm ? (e.endHm ? `${e.startHm}–${e.endHm}` : e.startHm) : 'All day';
|
|
226
|
+
text(c, colX, yL, 20, fitText(`${time} · ${e.title}`, colW, 20));
|
|
227
|
+
yL += 32;
|
|
228
|
+
}
|
|
229
|
+
yL += 10;
|
|
230
|
+
}
|
|
231
|
+
// ── Quota ──
|
|
232
|
+
let qx = colX, qy = yL, qw = colW;
|
|
233
|
+
if (landscape) {
|
|
234
|
+
qx = rightX;
|
|
235
|
+
qy = yR;
|
|
236
|
+
qw = W - M - rightX;
|
|
237
|
+
}
|
|
238
|
+
if (g.usage && g.usage.length > 0) {
|
|
239
|
+
sectionLabel(c, qx, qy, 'AI BUDGET');
|
|
240
|
+
qy += 26;
|
|
241
|
+
for (const row of g.usage)
|
|
242
|
+
qy += quotaRow(c, qx, qy, qw, row) + 8;
|
|
243
|
+
qy += 10;
|
|
244
|
+
}
|
|
245
|
+
if (landscape)
|
|
246
|
+
yR = qy;
|
|
247
|
+
else
|
|
248
|
+
yL = qy;
|
|
249
|
+
// ── Work wrap-up ──
|
|
250
|
+
let wx = colX, wy = yL, ww = colW;
|
|
251
|
+
if (landscape) {
|
|
252
|
+
wx = rightX;
|
|
253
|
+
wy = yR;
|
|
254
|
+
ww = W - M - rightX;
|
|
255
|
+
}
|
|
256
|
+
const wrapup = g.wrapup ?? [];
|
|
257
|
+
sectionLabel(c, wx, wy, 'WORK');
|
|
258
|
+
wy += 34;
|
|
259
|
+
if (wrapup.length === 0) {
|
|
260
|
+
text(c, wx, wy, 20, 'No active sessions', { fill: GRAY });
|
|
261
|
+
wy += 30;
|
|
262
|
+
}
|
|
263
|
+
// Clip the work lines to their column — a long CJK line must never bleed
|
|
264
|
+
// into the margin or the other column.
|
|
265
|
+
c.parts.push(`<clipPath id="work"><rect x="${wx}" y="${wy - 30}" width="${ww}" height="${H - wy - 30}"/></clipPath>`);
|
|
266
|
+
c.parts.push(`<g clip-path="url(#work)">`);
|
|
267
|
+
for (const line of wrapup) {
|
|
268
|
+
if (wy > H - 60)
|
|
269
|
+
break;
|
|
270
|
+
c.parts.push(`<circle cx="${wx + 5}" cy="${wy - 6}" r="4" fill="black"/>`);
|
|
271
|
+
text(c, wx + 20, wy, 20, fitText(line, ww - 20, 20));
|
|
272
|
+
wy += 32;
|
|
273
|
+
}
|
|
274
|
+
c.parts.push('</g>');
|
|
275
|
+
// ── Footer status ──
|
|
276
|
+
rule(c, M, H - 44, W - M, 2);
|
|
277
|
+
text(c, M, H - 18, 17, 'AGENTDECK · GLANCE', { weight: 700, spacing: '2', fill: GRAY });
|
|
278
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">${c.parts.join('')}</svg>`;
|
|
279
|
+
}
|
|
280
|
+
// ===== Rasterize → dither → pack =====
|
|
281
|
+
/** 4×4 Bayer matrix, thresholds spread over 0..255. Ordered dithering is
|
|
282
|
+
* deterministic, so identical input yields identical bytes (stable sig). */
|
|
283
|
+
const BAYER4 = [
|
|
284
|
+
[0, 8, 2, 10],
|
|
285
|
+
[12, 4, 14, 6],
|
|
286
|
+
[3, 11, 1, 9],
|
|
287
|
+
[15, 7, 13, 5],
|
|
288
|
+
].map((row) => row.map((v) => Math.round(((v + 0.5) * 255) / 16)));
|
|
289
|
+
/** Rotate a logical-space grayscale raster (w×h) into physical panel space
|
|
290
|
+
* (h×w), using the device GfxRenderer Portrait mapping: phyX = y,
|
|
291
|
+
* phyY = physH − 1 − x (with physH = logical width). Kept exactly in sync
|
|
292
|
+
* with `rotateCoordinates` in the XTeink fork's GfxRenderer.cpp. */
|
|
293
|
+
export function rotateGrayToPhysical(gray, width, height) {
|
|
294
|
+
const physW = height;
|
|
295
|
+
const physH = width;
|
|
296
|
+
const out = Buffer.alloc(physW * physH);
|
|
297
|
+
for (let y = 0; y < height; y++) {
|
|
298
|
+
for (let x = 0; x < width; x++) {
|
|
299
|
+
out[(physH - 1 - x) * physW + y] = gray[y * width + x];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
/** Pack 8-bit grayscale into the e-ink framebuffer format: 1bpp, MSB-first
|
|
305
|
+
* within each byte, row-major, bit 1 = white (clearScreen(0xFF) = white). */
|
|
306
|
+
export function packMono(gray, width, height) {
|
|
307
|
+
const rowBytes = Math.ceil(width / 8);
|
|
308
|
+
const out = Buffer.alloc(rowBytes * height, 0x00);
|
|
309
|
+
for (let y = 0; y < height; y++) {
|
|
310
|
+
const bay = BAYER4[y & 3];
|
|
311
|
+
for (let x = 0; x < width; x++) {
|
|
312
|
+
if (gray[y * width + x] > bay[x & 3]) {
|
|
313
|
+
out[y * rowBytes + (x >> 3)] |= 0x80 >> (x & 7);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return out;
|
|
318
|
+
}
|
|
319
|
+
/** FNV-1a over a byte buffer (frame sig / content sig). */
|
|
320
|
+
export function frameSig(packed) {
|
|
321
|
+
let h = 0x811c9dc5;
|
|
322
|
+
for (let i = 0; i < packed.length; i++) {
|
|
323
|
+
h ^= packed[i];
|
|
324
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
325
|
+
}
|
|
326
|
+
return h.toString(16).padStart(8, '0');
|
|
327
|
+
}
|
|
328
|
+
export async function renderGlanceFrame(input) {
|
|
329
|
+
const svg = Buffer.from(renderGlanceFrameSvg(input));
|
|
330
|
+
let gray = await sharp(svg, { density: 72 }).flatten({ background: 'white' }).greyscale().raw().toBuffer();
|
|
331
|
+
let { width, height } = input.geometry;
|
|
332
|
+
if (input.geometry.rotateToPhysical) {
|
|
333
|
+
gray = rotateGrayToPhysical(gray, width, height);
|
|
334
|
+
[width, height] = [height, width];
|
|
335
|
+
}
|
|
336
|
+
const packed = packMono(gray, width, height);
|
|
337
|
+
// The sig hashes the frame's CONTENT, not its pixels: the masthead bakes the
|
|
338
|
+
// "Synced HH:MM" clock stamp into the raster, so a pixel hash would change
|
|
339
|
+
// every minute and silently void the ?sig= conditional (a device would
|
|
340
|
+
// re-download ~50KB on every poll past a minute boundary). Hashing the SVG
|
|
341
|
+
// with the clock stamp blanked keeps the sig stable across clock ticks while
|
|
342
|
+
// still covering everything else that moves pixels — glance data, geometry,
|
|
343
|
+
// and layout-code changes all flow through the SVG string.
|
|
344
|
+
const sig = frameSig(Buffer.from(renderGlanceFrameSvg({ ...input, serverHm: '' })));
|
|
345
|
+
return {
|
|
346
|
+
packed,
|
|
347
|
+
sig,
|
|
348
|
+
width,
|
|
349
|
+
height,
|
|
350
|
+
png: async () => {
|
|
351
|
+
// Re-expand the packed bits so the PNG shows the dithered result, not
|
|
352
|
+
// the smooth grayscale — what you preview is what the panel holds.
|
|
353
|
+
const rowBytes = Math.ceil(width / 8);
|
|
354
|
+
const px = Buffer.alloc(width * height);
|
|
355
|
+
for (let y = 0; y < height; y++) {
|
|
356
|
+
for (let x = 0; x < width; x++) {
|
|
357
|
+
px[y * width + x] = packed[y * rowBytes + (x >> 3)] & (0x80 >> (x & 7)) ? 255 : 0;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return sharp(px, { raw: { width, height, channels: 1 } }).png().toBuffer();
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=glance-frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glance-frame.js","sourceRoot":"","sources":["../src/glance-frame.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ObservedSession } from './passive-observer.js';
|
|
2
|
+
export interface HookCodexSession {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
projectName: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
state: 'idle' | 'processing';
|
|
7
|
+
currentTool?: string;
|
|
8
|
+
startedAt: number;
|
|
9
|
+
lastHookAt: number;
|
|
10
|
+
terminalAt?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface HookCodexPayload {
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
projectName?: string;
|
|
16
|
+
toolName?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class HookCodexSessions {
|
|
19
|
+
private readonly sessions;
|
|
20
|
+
/** sessionId → epoch ms of its last terminal hook, outliving the row. */
|
|
21
|
+
private readonly terminated;
|
|
22
|
+
/** Fired when a hook changed something worth broadcasting. */
|
|
23
|
+
onChanged: (() => void) | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Record a `codex_*` lifecycle hook. Returns true when the sessions list
|
|
26
|
+
* should be rebroadcast.
|
|
27
|
+
*/
|
|
28
|
+
note(event: string, payload: HookCodexPayload, now?: number): boolean;
|
|
29
|
+
/** Drop a session immediately (explicit end, not a timeout). */
|
|
30
|
+
forget(sessionId: string): void;
|
|
31
|
+
snapshot(): HookCodexSession[];
|
|
32
|
+
private reap;
|
|
33
|
+
/**
|
|
34
|
+
* Append a row for every hook-known Codex the process scan didn't produce.
|
|
35
|
+
* Sessions the observer already found are left entirely alone — its row is
|
|
36
|
+
* strictly richer.
|
|
37
|
+
*/
|
|
38
|
+
applyTo(observed: ObservedSession[], now?: number): ObservedSession[];
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=hook-codex-sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-codex-sessions.d.ts","sourceRoot":"","sources":["../src/hook-codex-sessions.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAuB7D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IAExD,8DAA8D;IAC9D,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAEpC;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,SAAa,GAAG,OAAO;IA0DzE,gEAAgE;IAChE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI/B,QAAQ,IAAI,gBAAgB,EAAE;IAI9B,OAAO,CAAC,IAAI;IAWZ;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,GAAG,SAAa,GAAG,eAAe,EAAE;CAgC1E"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// hook-codex-sessions.ts — Codex sessions derived from lifecycle hooks alone.
|
|
2
|
+
//
|
|
3
|
+
// The Node daemon has always let the ps/lsof passive observer own observed
|
|
4
|
+
// Codex session identity and state, with `codex_*` hooks feeding only the
|
|
5
|
+
// timeline (see the dispatch comment in daemon-server.ts). That works right up
|
|
6
|
+
// until the process scan can't answer: `lsof` is a 2 s-timeout subprocess, and
|
|
7
|
+
// when it times out — or a Codex holds no rollout open — the row disappears
|
|
8
|
+
// from every deck even though hooks are still arriving. The Swift daemon never
|
|
9
|
+
// had this failure mode because it has no process visibility at all and
|
|
10
|
+
// synthesizes a session from `codex_session_start` directly
|
|
11
|
+
// (`DaemonServer.handleHookEvent`). This is that path, ported.
|
|
12
|
+
//
|
|
13
|
+
// Ownership rules, so the two sources can't fight:
|
|
14
|
+
// • The observer wins whenever it sees the session. A hook row is emitted only
|
|
15
|
+
// for a session id no observed row carries — never a second row for one
|
|
16
|
+
// conversation.
|
|
17
|
+
// • Hook rows are deliberately thin (id, project, state, tool). Model, token
|
|
18
|
+
// counts, context %, and goal come from the rollout and stay the observer's
|
|
19
|
+
// job; a hook row that guessed them would flicker against the real values
|
|
20
|
+
// the moment the scan recovered.
|
|
21
|
+
import { resolveProjectNameFromCwdCached } from './utils/project-name.js';
|
|
22
|
+
/** Reaped this long after the turn-ending hook — Swift's `codexPostTerminalTTL`. */
|
|
23
|
+
const POST_TERMINAL_TTL_MS = 60_000;
|
|
24
|
+
/**
|
|
25
|
+
* Reaped this long after ANY hook when no terminal event arrived. A session
|
|
26
|
+
* killed mid-turn (SIGKILL, closed laptop) fires no `codex_stop`, and without
|
|
27
|
+
* this its creature would sit "processing" forever.
|
|
28
|
+
*/
|
|
29
|
+
const SILENT_TTL_MS = 30 * 60_000;
|
|
30
|
+
/** Hook events that may create a row. */
|
|
31
|
+
const OPENING_EVENTS = new Set(['codex_session_start', 'codex_user_prompt_submit']);
|
|
32
|
+
/** Hook events that end a turn. `codex_turn_complete` is the notify-only fallback. */
|
|
33
|
+
const TERMINAL_EVENTS = new Set(['codex_stop', 'codex_session_end', 'codex_turn_complete']);
|
|
34
|
+
/**
|
|
35
|
+
* A finished session stays un-resurrectable this long — longer than its row
|
|
36
|
+
* lives, so a trailing tool callback can't revive a creature 90 s after the turn
|
|
37
|
+
* ended. Only an explicit opening event clears it.
|
|
38
|
+
*/
|
|
39
|
+
const TOMBSTONE_TTL_MS = 30 * 60_000;
|
|
40
|
+
export class HookCodexSessions {
|
|
41
|
+
sessions = new Map();
|
|
42
|
+
/** sessionId → epoch ms of its last terminal hook, outliving the row. */
|
|
43
|
+
terminated = new Map();
|
|
44
|
+
/** Fired when a hook changed something worth broadcasting. */
|
|
45
|
+
onChanged;
|
|
46
|
+
/**
|
|
47
|
+
* Record a `codex_*` lifecycle hook. Returns true when the sessions list
|
|
48
|
+
* should be rebroadcast.
|
|
49
|
+
*/
|
|
50
|
+
note(event, payload, now = Date.now()) {
|
|
51
|
+
const sessionId = payload.sessionId?.trim();
|
|
52
|
+
if (!sessionId || !event.startsWith('codex_'))
|
|
53
|
+
return false;
|
|
54
|
+
if (OPENING_EVENTS.has(event))
|
|
55
|
+
this.terminated.delete(sessionId);
|
|
56
|
+
const existing = this.sessions.get(sessionId);
|
|
57
|
+
if (!existing) {
|
|
58
|
+
// A mid-turn event may open a row too — that's how a session whose start
|
|
59
|
+
// hook predates this daemon (restart, or hooks installed mid-session)
|
|
60
|
+
// becomes visible at all. But only when the session has no tombstone: a
|
|
61
|
+
// trailing tool callback from a finished companion task must not
|
|
62
|
+
// resurrect a creature. Swift layers the same tombstone-gated bypass over
|
|
63
|
+
// `shouldSynthesizeUnknownHookSession`.
|
|
64
|
+
if (!OPENING_EVENTS.has(event) && !isProgressEvent(event))
|
|
65
|
+
return false;
|
|
66
|
+
if (this.terminated.has(sessionId))
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const session = existing ?? {
|
|
70
|
+
sessionId,
|
|
71
|
+
projectName: '',
|
|
72
|
+
state: 'idle',
|
|
73
|
+
startedAt: now,
|
|
74
|
+
lastHookAt: now,
|
|
75
|
+
};
|
|
76
|
+
const before = JSON.stringify(session);
|
|
77
|
+
session.lastHookAt = now;
|
|
78
|
+
// cwd/project upgrade once, empty→set: later hooks on the same session can
|
|
79
|
+
// carry a subcommand's directory, and overwriting would relabel the row.
|
|
80
|
+
if (!session.cwd && payload.cwd) {
|
|
81
|
+
session.cwd = payload.cwd;
|
|
82
|
+
session.projectName = resolveProjectNameFromCwdCached(payload.cwd);
|
|
83
|
+
}
|
|
84
|
+
if (!session.projectName && payload.projectName)
|
|
85
|
+
session.projectName = payload.projectName;
|
|
86
|
+
if (TERMINAL_EVENTS.has(event)) {
|
|
87
|
+
session.state = 'idle';
|
|
88
|
+
session.currentTool = undefined;
|
|
89
|
+
session.terminalAt = now;
|
|
90
|
+
this.terminated.set(sessionId, now);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Any non-terminal hook means the turn is live again — including a
|
|
94
|
+
// follow-up prompt on a session whose previous turn ended.
|
|
95
|
+
session.terminalAt = undefined;
|
|
96
|
+
session.state = 'processing';
|
|
97
|
+
if (event === 'codex_tool_start')
|
|
98
|
+
session.currentTool = payload.toolName || undefined;
|
|
99
|
+
else if (event === 'codex_tool_end')
|
|
100
|
+
session.currentTool = undefined;
|
|
101
|
+
else if (event === 'codex_user_prompt_submit')
|
|
102
|
+
session.currentTool = undefined;
|
|
103
|
+
}
|
|
104
|
+
this.sessions.set(sessionId, session);
|
|
105
|
+
this.reap(now);
|
|
106
|
+
const changed = JSON.stringify(session) !== before || !existing;
|
|
107
|
+
if (changed)
|
|
108
|
+
this.onChanged?.();
|
|
109
|
+
return changed;
|
|
110
|
+
}
|
|
111
|
+
/** Drop a session immediately (explicit end, not a timeout). */
|
|
112
|
+
forget(sessionId) {
|
|
113
|
+
if (this.sessions.delete(sessionId))
|
|
114
|
+
this.onChanged?.();
|
|
115
|
+
}
|
|
116
|
+
snapshot() {
|
|
117
|
+
return [...this.sessions.values()];
|
|
118
|
+
}
|
|
119
|
+
reap(now) {
|
|
120
|
+
for (const [sessionId, session] of this.sessions) {
|
|
121
|
+
const finished = session.terminalAt !== undefined
|
|
122
|
+
&& now - session.terminalAt > POST_TERMINAL_TTL_MS;
|
|
123
|
+
if (finished || now - session.lastHookAt > SILENT_TTL_MS)
|
|
124
|
+
this.sessions.delete(sessionId);
|
|
125
|
+
}
|
|
126
|
+
for (const [sessionId, at] of this.terminated) {
|
|
127
|
+
if (now - at > TOMBSTONE_TTL_MS)
|
|
128
|
+
this.terminated.delete(sessionId);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Append a row for every hook-known Codex the process scan didn't produce.
|
|
133
|
+
* Sessions the observer already found are left entirely alone — its row is
|
|
134
|
+
* strictly richer.
|
|
135
|
+
*/
|
|
136
|
+
applyTo(observed, now = Date.now()) {
|
|
137
|
+
this.reap(now);
|
|
138
|
+
if (this.sessions.size === 0)
|
|
139
|
+
return observed;
|
|
140
|
+
const seen = new Set();
|
|
141
|
+
for (const session of observed) {
|
|
142
|
+
// `observed:codex:<uuid>` / `observed:codex-app:<uuid>` → the bare uuid
|
|
143
|
+
// hooks use. Both id forms name the same conversation.
|
|
144
|
+
const match = /^observed:codex(?:-app)?:(.+)$/.exec(session.id);
|
|
145
|
+
if (match?.[1])
|
|
146
|
+
seen.add(match[1]);
|
|
147
|
+
}
|
|
148
|
+
const extra = [];
|
|
149
|
+
for (const session of this.sessions.values()) {
|
|
150
|
+
if (seen.has(session.sessionId))
|
|
151
|
+
continue;
|
|
152
|
+
extra.push({
|
|
153
|
+
id: `observed:codex:${session.sessionId}`,
|
|
154
|
+
port: 0,
|
|
155
|
+
pid: 0,
|
|
156
|
+
projectName: session.projectName || 'Codex',
|
|
157
|
+
agentType: 'codex-cli',
|
|
158
|
+
alive: true,
|
|
159
|
+
state: session.state,
|
|
160
|
+
controlMode: 'observed',
|
|
161
|
+
cwd: session.cwd,
|
|
162
|
+
currentTask: session.currentTool,
|
|
163
|
+
startedAt: new Date(session.startedAt).toISOString(),
|
|
164
|
+
lastActivityAt: session.lastHookAt,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return extra.length > 0 ? [...observed, ...extra] : observed;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Mid-turn hooks: progress on a session that must already be known. */
|
|
171
|
+
function isProgressEvent(event) {
|
|
172
|
+
return event === 'codex_tool_start' || event === 'codex_tool_end';
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=hook-codex-sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-codex-sessions.js","sourceRoot":"","sources":["../src/hook-codex-sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idotmatrix-discover.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"idotmatrix-discover.d.ts","sourceRoot":"","sources":["../../src/idotmatrix/idotmatrix-discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8DH;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsB9D"}
|