@0xmaxma/claude-gateway 1.3.24 → 1.3.31
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/README.md +172 -50
- package/config.template.json +6 -2
- package/dist/agent/incident-store.d.ts +89 -0
- package/dist/agent/incident-store.d.ts.map +1 -0
- package/dist/agent/incident-store.js +299 -0
- package/dist/agent/incident-store.js.map +1 -0
- package/dist/agent/incident.d.ts +156 -0
- package/dist/agent/incident.d.ts.map +1 -0
- package/dist/agent/incident.js +177 -0
- package/dist/agent/incident.js.map +1 -0
- package/dist/agent/recovery-executor.d.ts +117 -0
- package/dist/agent/recovery-executor.d.ts.map +1 -0
- package/dist/agent/recovery-executor.js +168 -0
- package/dist/agent/recovery-executor.js.map +1 -0
- package/dist/agent/recovery-policy.d.ts +97 -0
- package/dist/agent/recovery-policy.d.ts.map +1 -0
- package/dist/agent/recovery-policy.js +164 -0
- package/dist/agent/recovery-policy.js.map +1 -0
- package/dist/agent/runner.d.ts +44 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +272 -2
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/safe-mode.d.ts +61 -0
- package/dist/agent/safe-mode.d.ts.map +1 -0
- package/dist/agent/safe-mode.js +102 -0
- package/dist/agent/safe-mode.js.map +1 -0
- package/dist/agent/triage.d.ts +94 -0
- package/dist/agent/triage.d.ts.map +1 -0
- package/dist/agent/triage.js +209 -0
- package/dist/agent/triage.js.map +1 -0
- package/dist/agent/turn-trace.d.ts +120 -0
- package/dist/agent/turn-trace.d.ts.map +1 -0
- package/dist/agent/turn-trace.js +122 -0
- package/dist/agent/turn-trace.js.map +1 -0
- package/dist/api/gateway-router.d.ts +21 -0
- package/dist/api/gateway-router.d.ts.map +1 -1
- package/dist/api/gateway-router.js +58 -17
- package/dist/api/gateway-router.js.map +1 -1
- package/dist/api/line-pending-senders.d.ts +7 -2
- package/dist/api/line-pending-senders.d.ts.map +1 -1
- package/dist/api/line-pending-senders.js +7 -2
- package/dist/api/line-pending-senders.js.map +1 -1
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +563 -172
- package/dist/api/router.js.map +1 -1
- package/dist/api/wizard-state.d.ts +1 -4
- package/dist/api/wizard-state.d.ts.map +1 -1
- package/dist/api/wizard-state.js.map +1 -1
- package/dist/config/migrator.d.ts +4 -0
- package/dist/config/migrator.d.ts.map +1 -1
- package/dist/config/migrator.js +60 -3
- package/dist/config/migrator.js.map +1 -1
- package/dist/discord/receiver.d.ts +1 -0
- package/dist/discord/receiver.d.ts.map +1 -1
- package/dist/discord/receiver.js +24 -6
- package/dist/discord/receiver.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/session/process.d.ts +18 -0
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +61 -1
- package/dist/session/process.js.map +1 -1
- package/dist/shell/claude-pty-shell.js +59 -0
- package/dist/shell/claude-pty-shell.js.map +1 -1
- package/dist/shell/control-channel.d.ts +74 -0
- package/dist/shell/control-channel.d.ts.map +1 -0
- package/dist/shell/control-channel.js +114 -0
- package/dist/shell/control-channel.js.map +1 -0
- package/dist/telegram/receiver.d.ts +1 -0
- package/dist/telegram/receiver.d.ts.map +1 -1
- package/dist/telegram/receiver.js +18 -6
- package/dist/telegram/receiver.js.map +1 -1
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/web-ui.d.ts.map +1 -1
- package/dist/ui/web-ui.js +103 -2
- package/dist/ui/web-ui.js.map +1 -1
- package/mcp/tools/discord/access.ts +136 -20
- package/mcp/tools/discord/client.ts +3 -1
- package/mcp/tools/discord/module.ts +75 -4
- package/mcp/tools/discord/skills/access/SKILL.md +66 -8
- package/mcp/tools/discord/skills/configure/SKILL.md +11 -1
- package/mcp/tools/discord/types.ts +21 -2
- package/mcp/tools/skills/handlers.ts +4 -2
- package/mcp/tools/telegram/dedup.ts +4 -1
- package/mcp/tools/telegram/module.ts +5 -14
- package/mcp/tools/telegram/pure.ts +169 -31
- package/mcp/tools/telegram/receiver-server.ts +271 -78
- package/mcp/tools/telegram/skills/access/SKILL.md +93 -23
- package/mcp/tools/telegram/skills/configure/SKILL.md +31 -26
- package/mcp/tools/telegram/typing.ts +124 -0
- package/package.json +3 -1
|
@@ -39,6 +39,9 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
const logger_1 = require("../logger");
|
|
40
40
|
const AUTO_RESTART_DELAY_MS = 5000;
|
|
41
41
|
const MAX_RESTARTS = 3;
|
|
42
|
+
// After MAX_RESTARTS fast attempts, fall back to a slow indefinite retry
|
|
43
|
+
// instead of giving up permanently — mirrors discord/receiver.ts.
|
|
44
|
+
const SLOW_RESTART_DELAY_MS = 5 * 60000;
|
|
42
45
|
class TelegramReceiver {
|
|
43
46
|
constructor(agentConfig, callbackPort, logDir) {
|
|
44
47
|
this.agentConfig = agentConfig;
|
|
@@ -47,12 +50,14 @@ class TelegramReceiver {
|
|
|
47
50
|
this.process = null;
|
|
48
51
|
this.stopping = false;
|
|
49
52
|
this.restartCount = 0;
|
|
53
|
+
this.slowPhaseAnnounced = false;
|
|
50
54
|
this.restartTimer = null;
|
|
51
55
|
this.logger = (0, logger_1.createLogger)(`${agentConfig.id}:receiver`, logDir);
|
|
52
56
|
}
|
|
53
57
|
start() {
|
|
54
58
|
this.stopping = false;
|
|
55
59
|
this.restartCount = 0;
|
|
60
|
+
this.slowPhaseAnnounced = false;
|
|
56
61
|
this.spawnProcess();
|
|
57
62
|
}
|
|
58
63
|
spawnProcess() {
|
|
@@ -80,19 +85,26 @@ class TelegramReceiver {
|
|
|
80
85
|
this.logger.info('TelegramReceiver started');
|
|
81
86
|
}
|
|
82
87
|
scheduleRestart() {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
const slowPhase = this.restartCount >= MAX_RESTARTS;
|
|
89
|
+
const delay = slowPhase ? SLOW_RESTART_DELAY_MS : AUTO_RESTART_DELAY_MS;
|
|
90
|
+
if (!slowPhase)
|
|
91
|
+
this.restartCount++;
|
|
92
|
+
// Surface the transition into indefinite slow-retry once at error level so a
|
|
93
|
+
// permanently-broken config (bad/revoked token) is visible instead of hiding
|
|
94
|
+
// behind a steady stream of warn-level retry lines.
|
|
95
|
+
if (slowPhase && !this.slowPhaseAnnounced) {
|
|
96
|
+
this.slowPhaseAnnounced = true;
|
|
97
|
+
this.logger.error(`TelegramReceiver failed ${MAX_RESTARTS} fast restarts; switching to slow retry every ${SLOW_RESTART_DELAY_MS}ms — check the bot token`);
|
|
86
98
|
}
|
|
87
|
-
this.
|
|
88
|
-
this.logger.warn(`Restarting TelegramReceiver in ${AUTO_RESTART_DELAY_MS}ms`, {
|
|
99
|
+
this.logger.warn(`Restarting TelegramReceiver in ${delay}ms`, {
|
|
89
100
|
attempt: this.restartCount,
|
|
101
|
+
slowPhase,
|
|
90
102
|
});
|
|
91
103
|
this.restartTimer = setTimeout(() => {
|
|
92
104
|
this.restartTimer = null;
|
|
93
105
|
if (!this.stopping)
|
|
94
106
|
this.spawnProcess();
|
|
95
|
-
},
|
|
107
|
+
}, delay);
|
|
96
108
|
}
|
|
97
109
|
stop() {
|
|
98
110
|
this.stopping = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"receiver.js","sourceRoot":"","sources":["../../src/telegram/receiver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAoD;AACpD,2CAA6B;AAE7B,sCAAyC;AAEzC,MAAM,qBAAqB,GAAG,IAAK,CAAC;AACpC,MAAM,YAAY,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"receiver.js","sourceRoot":"","sources":["../../src/telegram/receiver.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -136,6 +136,14 @@ export interface GatewayConfig {
|
|
|
136
136
|
gateway: {
|
|
137
137
|
logDir: string;
|
|
138
138
|
timezone: string;
|
|
139
|
+
/**
|
|
140
|
+
* Network interface the HTTP/WebSocket server binds to. Defaults to
|
|
141
|
+
* "127.0.0.1" (localhost-only) so the dashboard and API are not exposed to
|
|
142
|
+
* the local network out of the box. Set to "0.0.0.0" to expose all
|
|
143
|
+
* interfaces (e.g. behind a trusted reverse proxy). The `GATEWAY_BIND` env
|
|
144
|
+
* var, when set, takes precedence over this field.
|
|
145
|
+
*/
|
|
146
|
+
bind?: string;
|
|
139
147
|
models?: ModelConfig[];
|
|
140
148
|
api?: {
|
|
141
149
|
keys: ApiKey[];
|
|
@@ -145,6 +153,19 @@ export interface GatewayConfig {
|
|
|
145
153
|
* false = interactive backend: claude TUI under the claude-pty-shell PTY wrapper.
|
|
146
154
|
*/
|
|
147
155
|
headless?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* Self-healing recovery (Epic #195, Phase 3). When `autoRecover` is true the
|
|
158
|
+
* turn-trace watchdog may auto-execute a whitelisted recovery action
|
|
159
|
+
* (keystroke, session/receiver restart, safe-mode fallback, guarded resend)
|
|
160
|
+
* for a stalled turn. Default false — detection, incident logging, and
|
|
161
|
+
* notification still run when disabled; only live action execution is gated,
|
|
162
|
+
* so the feature ships dark and the operator opts in when ready. Safe-mode
|
|
163
|
+
* auto-fallback on hard PTY failure is independent of this flag (it is always
|
|
164
|
+
* reversible and never presses keys).
|
|
165
|
+
*/
|
|
166
|
+
selfHealing?: {
|
|
167
|
+
autoRecover?: boolean;
|
|
168
|
+
};
|
|
148
169
|
/** Global history retention/cleanup defaults */
|
|
149
170
|
history?: HistoryConfig & {
|
|
150
171
|
cleanupHour?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/web-ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-ui.d.ts","sourceRoot":"","sources":["../../src/ui/web-ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,SAAK,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"web-ui.d.ts","sourceRoot":"","sources":["../../src/ui/web-ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,SAAK,GAAG,MAAM,CAu3B5D"}
|
package/dist/ui/web-ui.js
CHANGED
|
@@ -119,6 +119,22 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
119
119
|
}
|
|
120
120
|
.pty-close:hover { color: #fc8181; }
|
|
121
121
|
.pty-refresh:hover { color: #63b3ed; }
|
|
122
|
+
/* Keyboard-focus outline on the viewer (it is tabindex focusable so PageUp/
|
|
123
|
+
PageDown reach the terminal); keep it subtle rather than the default ring. */
|
|
124
|
+
#pty-terminal:focus, #pty-terminal:focus-visible { outline: 1px solid #2d3748; }
|
|
125
|
+
.pty-mode-toggle {
|
|
126
|
+
background: none;
|
|
127
|
+
border: 1px solid #2d3748;
|
|
128
|
+
border-radius: 4px;
|
|
129
|
+
color: #718096;
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
font-size: 0.72rem;
|
|
132
|
+
padding: 1px 7px;
|
|
133
|
+
margin-right: 6px;
|
|
134
|
+
}
|
|
135
|
+
.pty-mode-toggle:hover { color: #63b3ed; border-color: #3d4a5f; }
|
|
136
|
+
/* Active (input) mode — clearly signals the viewer now types into the PTY. */
|
|
137
|
+
.pty-mode-toggle.input-active { color: #0d1117; background: #63b3ed; border-color: #63b3ed; font-weight: 600; }
|
|
122
138
|
/* Fixed-size terminal viewport — the server PTY runs at 200x50, so the
|
|
123
139
|
viewer must NOT resize to the panel (that mismatch is what garbles the
|
|
124
140
|
output). We render at the native size and pan horizontally if the 200-col
|
|
@@ -233,13 +249,16 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
233
249
|
in view when streaming. -->
|
|
234
250
|
<div class="pty-viewer" id="pty-viewer">
|
|
235
251
|
<div class="pty-viewer-header">
|
|
236
|
-
<span>
|
|
252
|
+
<span><span id="pty-title-text">Terminal Viewer</span> — <span class="agent-label" id="pty-agent-label"></span><span class="session-label" id="pty-session-label"></span></span>
|
|
237
253
|
<span>
|
|
254
|
+
<button class="pty-mode-toggle" id="pty-mode-toggle-btn" title="Toggle input mode (type into the live terminal)">⌨ View</button>
|
|
238
255
|
<button class="pty-refresh" id="pty-refresh-btn" title="Refresh (reconnect & redraw)">↺</button>
|
|
239
256
|
<button class="pty-close" id="pty-close-btn" title="Close">✕</button>
|
|
240
257
|
</span>
|
|
241
258
|
</div>
|
|
242
|
-
|
|
259
|
+
<!-- tabindex makes the viewer keyboard-focusable so PageUp/PageDown reach it
|
|
260
|
+
even in read-only view mode (xterm stdin is disabled there). -->
|
|
261
|
+
<div id="pty-terminal" tabindex="0"></div>
|
|
243
262
|
</div>
|
|
244
263
|
|
|
245
264
|
<!-- Sessions — full width (session-centric, flat list) -->
|
|
@@ -350,6 +369,11 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
350
369
|
// multi-byte char into noise — decode as UTF-8 with {stream:true} so sequences
|
|
351
370
|
// split across WebSocket frames are reassembled instead of corrupted.
|
|
352
371
|
let utf8Decoder = null;
|
|
372
|
+
// Interactive input mode (Issue #201). When on, keystrokes typed into the
|
|
373
|
+
// terminal are streamed to the live PTY over the same WebSocket. Off by
|
|
374
|
+
// default (read-only mirror); the viewer flips it on via the mode toggle.
|
|
375
|
+
let ptyInputMode = false;
|
|
376
|
+
let ptyOnDataDisposable = null;
|
|
353
377
|
|
|
354
378
|
// The agent's TUI enables mouse tracking (DECSET 1000/1002/1003/1006...).
|
|
355
379
|
// While those modes are active, xterm.js forwards wheel/click events to the
|
|
@@ -373,6 +397,9 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
373
397
|
// Append the session id after the agent name, e.g. "claude-founder · 3c01897c…".
|
|
374
398
|
document.getElementById('pty-session-label').textContent = sessionId ? ' \\u00b7 ' + sessionId : '';
|
|
375
399
|
document.getElementById('pty-viewer').style.display = 'block';
|
|
400
|
+
// Always (re)open a fresh session in read-only view mode; the mode toggle
|
|
401
|
+
// lets the viewer switch into interactive input on demand.
|
|
402
|
+
setPtyInputMode(false);
|
|
376
403
|
|
|
377
404
|
if (!term) {
|
|
378
405
|
term = new Terminal({
|
|
@@ -488,12 +515,53 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
488
515
|
// are about to close intentionally, so it does not schedule a new one.
|
|
489
516
|
if (ptyReconnectTimer) { clearTimeout(ptyReconnectTimer); ptyReconnectTimer = null; }
|
|
490
517
|
ptyReconnectAttempts = 0;
|
|
518
|
+
setPtyInputMode(false); // always leave input mode when closing/switching
|
|
491
519
|
if (ptyWs) { ptyWs.onclose = null; ptyWs.onerror = null; ptyWs.close(); ptyWs = null; }
|
|
492
520
|
currentPtyAgent = null;
|
|
493
521
|
currentPtySession = null;
|
|
494
522
|
document.getElementById('pty-viewer').style.display = 'none';
|
|
495
523
|
}
|
|
496
524
|
|
|
525
|
+
// Switch the viewer between read-only mirror and interactive input. In input
|
|
526
|
+
// mode the terminal accepts stdin and every keystroke (printable chars,
|
|
527
|
+
// Enter, arrows, Ctrl-combos, Esc) is streamed to the live PTY over the WS,
|
|
528
|
+
// like a real terminal; the title and toggle reflect the active mode.
|
|
529
|
+
function setPtyInputMode(on) {
|
|
530
|
+
if (!term) on = false;
|
|
531
|
+
ptyInputMode = !!on;
|
|
532
|
+
const toggleBtn = document.getElementById('pty-mode-toggle-btn');
|
|
533
|
+
const titleEl = document.getElementById('pty-title-text');
|
|
534
|
+
if (term) term.options.disableStdin = !ptyInputMode;
|
|
535
|
+
// Detach any previous onData listener before (re)attaching, so toggling
|
|
536
|
+
// off — or toggling on twice — never leaves a duplicate keystroke stream.
|
|
537
|
+
if (ptyOnDataDisposable) { ptyOnDataDisposable.dispose(); ptyOnDataDisposable = null; }
|
|
538
|
+
if (ptyInputMode && term) {
|
|
539
|
+
ptyOnDataDisposable = term.onData(function(data) {
|
|
540
|
+
if (ptyWs && ptyWs.readyState === WebSocket.OPEN) ptyWs.send(data);
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
if (titleEl) titleEl.textContent = ptyInputMode ? 'Interactive Terminal' : 'Terminal Viewer';
|
|
544
|
+
if (toggleBtn) {
|
|
545
|
+
toggleBtn.innerHTML = ptyInputMode ? '\\u2328 Input' : '\\u2328 View';
|
|
546
|
+
toggleBtn.classList.toggle('input-active', ptyInputMode);
|
|
547
|
+
toggleBtn.title = ptyInputMode
|
|
548
|
+
? 'Input mode — keystrokes go to the live terminal (click for read-only)'
|
|
549
|
+
: 'Toggle input mode (type into the live terminal)';
|
|
550
|
+
}
|
|
551
|
+
if (ptyInputMode && term) {
|
|
552
|
+
term.focus(); // typing goes to xterm's textarea
|
|
553
|
+
} else {
|
|
554
|
+
// View mode: focus the container (tabindex) so PageUp/PageDown reach our
|
|
555
|
+
// key handler instead of scrolling the browser page.
|
|
556
|
+
const host = document.getElementById('pty-terminal');
|
|
557
|
+
if (host) host.focus();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function togglePtyInputMode() {
|
|
562
|
+
setPtyInputMode(!ptyInputMode);
|
|
563
|
+
}
|
|
564
|
+
|
|
497
565
|
// Refresh: force a clean reconnect of the CURRENT session. The server replays
|
|
498
566
|
// a freshly-serialized screen frame on subscribe, so this redraws from a clean
|
|
499
567
|
// xterm state — a manual escape hatch if the live stream ever drifts.
|
|
@@ -505,8 +573,41 @@ function generateDashboardHtml(dashToken = '') {
|
|
|
505
573
|
await openPtyViewer(agentId, sessionId);
|
|
506
574
|
}
|
|
507
575
|
|
|
576
|
+
// Page Up / Page Down keys (Issue #201): the alt-screen mirror keeps no
|
|
577
|
+
// scrollback of its own, so a physical PageUp/PageDown key is forwarded to the
|
|
578
|
+
// live TUI — which holds the history and scrolls itself. In read-only view mode
|
|
579
|
+
// xterm's stdin is disabled, so without this those keys would just scroll the
|
|
580
|
+
// browser page; here we intercept ONLY these two keys (never printable input)
|
|
581
|
+
// and send them to the PTY, so the user can page through earlier output without
|
|
582
|
+
// enabling the interactive keyboard. In input mode xterm already forwards them
|
|
583
|
+
// via onData, so we skip to avoid double-send.
|
|
584
|
+
//
|
|
585
|
+
// The listener is attached to the document, NOT the viewer container: xterm renders
|
|
586
|
+
// its own focusable helpers inside #pty-terminal, and with disableStdin the
|
|
587
|
+
// container rarely holds focus reliably (a reconnect or stray click drops it),
|
|
588
|
+
// so a container-scoped keydown silently missed the keys. Gating on the viewer
|
|
589
|
+
// being open + view mode keeps it from hijacking PageUp elsewhere on the page,
|
|
590
|
+
// and we bail when focus is in a real text field so form paging still works.
|
|
591
|
+
// \\x1b[5~ = PageUp, \\x1b[6~ = PageDown.
|
|
592
|
+
function forwardPageKey(e) {
|
|
593
|
+
if (e.key !== 'PageUp' && e.key !== 'PageDown') return;
|
|
594
|
+
if (ptyInputMode) return; // input mode: xterm.onData already sends it
|
|
595
|
+
// Only while THIS viewer is actually open with a live socket.
|
|
596
|
+
const viewer = document.getElementById('pty-viewer');
|
|
597
|
+
if (!viewer || viewer.style.display === 'none') return;
|
|
598
|
+
if (!ptyWs || ptyWs.readyState !== WebSocket.OPEN) return;
|
|
599
|
+
// Don't steal paging from a genuine editable field (none in view mode today,
|
|
600
|
+
// but keep the guard so the document-level listener stays well-behaved).
|
|
601
|
+
const t = e.target;
|
|
602
|
+
if (t && (t.tagName === 'INPUT' || (t.tagName === 'TEXTAREA' && !t.disabled) || t.isContentEditable)) return;
|
|
603
|
+
e.preventDefault();
|
|
604
|
+
ptyWs.send(e.key === 'PageUp' ? '\\x1b[5~' : '\\x1b[6~');
|
|
605
|
+
}
|
|
606
|
+
document.addEventListener('keydown', forwardPageKey);
|
|
607
|
+
|
|
508
608
|
document.getElementById('pty-close-btn').addEventListener('click', closePtyViewer);
|
|
509
609
|
document.getElementById('pty-refresh-btn').addEventListener('click', function() { void refreshPtyViewer(); });
|
|
610
|
+
document.getElementById('pty-mode-toggle-btn').addEventListener('click', togglePtyInputMode);
|
|
510
611
|
|
|
511
612
|
// Event delegation for Live buttons (avoids inline onclick + HTML injection)
|
|
512
613
|
document.getElementById('sessions-tbody').addEventListener('click', function(e) {
|
package/dist/ui/web-ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-ui.js","sourceRoot":"","sources":["../../src/ui/web-ui.ts"],"names":[],"mappings":";;AAIA,
|
|
1
|
+
{"version":3,"file":"web-ui.js","sourceRoot":"","sources":["../../src/ui/web-ui.ts"],"names":[],"mappings":";;AAIA,sDAu3BC;AA33BD;;;GAGG;AACH,SAAgB,qBAAqB,CAAC,SAAS,GAAG,EAAE;IAClD,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3E,OAAO;;;;;qCAK4B,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+2BtC,CAAC;AACT,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import { randomBytes } from 'crypto';
|
|
9
|
-
import type { DiscordAccessConfig, DiscordMessageContext, DiscordAccess, DiscordGateResult } from './types';
|
|
9
|
+
import type { DiscordAccessConfig, DiscordMessageContext, DiscordAccess, DiscordGateResult, DiscordPending } from './types';
|
|
10
10
|
export type { DiscordAccessConfig, DiscordAccess } from './types';
|
|
11
11
|
|
|
12
12
|
export type AccessResult = { allowed: boolean; reason?: string };
|
|
@@ -15,10 +15,17 @@ export type AccessResult = { allowed: boolean; reason?: string };
|
|
|
15
15
|
// File-based access (new — pairing flow)
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
|
+
// Default for a brand-new agent (no access.json yet): closed base + pairing on,
|
|
19
|
+
// so the owner can DM the bot and capture their own id via a code. This matches
|
|
20
|
+
// the pre-split behavior where a missing file defaulted to dmPolicy:'pairing'.
|
|
18
21
|
export function defaultAccess(): DiscordAccess {
|
|
19
22
|
return {
|
|
20
|
-
dmPolicy: '
|
|
23
|
+
dmPolicy: 'allowlist',
|
|
24
|
+
pairing: true,
|
|
21
25
|
allowFrom: [],
|
|
26
|
+
// Secure new-agent default: guilds closed + answer only when @mentioned.
|
|
27
|
+
groupPolicy: 'allowlist',
|
|
28
|
+
requireMention: true,
|
|
22
29
|
guildAllowlist: [],
|
|
23
30
|
channelAllowlist: [],
|
|
24
31
|
roleAllowlist: [],
|
|
@@ -26,24 +33,83 @@ export function defaultAccess(): DiscordAccess {
|
|
|
26
33
|
};
|
|
27
34
|
}
|
|
28
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Normalize a parsed access.json into the current split shape, migrating the
|
|
38
|
+
* legacy fused dmPolicy ('pairing' folded pairing in) to the split model.
|
|
39
|
+
* Mirrors telegram/pure.ts:migrateAccess.
|
|
40
|
+
*
|
|
41
|
+
* SECURITY: a legacy `allowlist` file was deliberately locked down — it must
|
|
42
|
+
* migrate to `pairing:false`, NOT true, or it would start minting codes for
|
|
43
|
+
* strangers. Here an absent `pairing` on an existing file means a pre-split
|
|
44
|
+
* file → pairing off. Only the brand-new/ENOENT path (defaultAccess) is on.
|
|
45
|
+
*/
|
|
46
|
+
export function migrateAccess(parsed: {
|
|
47
|
+
dmPolicy?: string;
|
|
48
|
+
pairing?: boolean;
|
|
49
|
+
allowFrom?: string[];
|
|
50
|
+
groupPolicy?: string;
|
|
51
|
+
requireMention?: boolean;
|
|
52
|
+
guildAllowlist?: string[];
|
|
53
|
+
channelAllowlist?: string[];
|
|
54
|
+
roleAllowlist?: string[];
|
|
55
|
+
pending?: Record<string, DiscordPending>;
|
|
56
|
+
}): DiscordAccess {
|
|
57
|
+
const legacy = parsed.dmPolicy;
|
|
58
|
+
let dmPolicy: DiscordAccess['dmPolicy'];
|
|
59
|
+
let pairing: boolean;
|
|
60
|
+
if (legacy === 'pairing') {
|
|
61
|
+
dmPolicy = 'allowlist';
|
|
62
|
+
pairing = true;
|
|
63
|
+
} else {
|
|
64
|
+
dmPolicy = (legacy as DiscordAccess['dmPolicy']) ?? 'allowlist';
|
|
65
|
+
pairing = parsed.pairing ?? false;
|
|
66
|
+
}
|
|
67
|
+
const guildAllowlist = parsed.guildAllowlist ?? [];
|
|
68
|
+
// Guild tier migration must be behavior-preserving on upgrade. Today an empty
|
|
69
|
+
// guildAllowlist means "deliver to all guilds" — so derive 'open' when empty,
|
|
70
|
+
// 'allowlist' when non-empty; and requireMention defaults to false for
|
|
71
|
+
// existing files (they had no mention gate). New agents get the secure
|
|
72
|
+
// 'allowlist'+requireMention:true from defaultAccess() instead.
|
|
73
|
+
const groupPolicy = (parsed.groupPolicy as DiscordAccess['groupPolicy'])
|
|
74
|
+
?? (guildAllowlist.length > 0 ? 'allowlist' : 'open');
|
|
75
|
+
const requireMention = parsed.requireMention ?? false;
|
|
76
|
+
return {
|
|
77
|
+
dmPolicy,
|
|
78
|
+
pairing,
|
|
79
|
+
allowFrom: parsed.allowFrom ?? [],
|
|
80
|
+
groupPolicy,
|
|
81
|
+
requireMention,
|
|
82
|
+
guildAllowlist,
|
|
83
|
+
channelAllowlist: parsed.channelAllowlist ?? [],
|
|
84
|
+
roleAllowlist: parsed.roleAllowlist ?? [],
|
|
85
|
+
pending: parsed.pending ?? {},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
29
89
|
export function loadAccess(stateDir: string): DiscordAccess {
|
|
30
90
|
const accessFile = path.join(stateDir, 'access.json');
|
|
31
91
|
try {
|
|
32
92
|
const raw = fs.readFileSync(accessFile, 'utf8');
|
|
33
|
-
const parsed = JSON.parse(raw) as Partial<DiscordAccess
|
|
34
|
-
return
|
|
35
|
-
dmPolicy: parsed.dmPolicy ?? 'pairing',
|
|
36
|
-
allowFrom: parsed.allowFrom ?? [],
|
|
37
|
-
guildAllowlist: parsed.guildAllowlist ?? [],
|
|
38
|
-
channelAllowlist: parsed.channelAllowlist ?? [],
|
|
39
|
-
roleAllowlist: parsed.roleAllowlist ?? [],
|
|
40
|
-
pending: parsed.pending ?? {},
|
|
41
|
-
};
|
|
93
|
+
const parsed = JSON.parse(raw) as Partial<DiscordAccess> & { dmPolicy?: string };
|
|
94
|
+
return migrateAccess(parsed);
|
|
42
95
|
} catch (err) {
|
|
43
96
|
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
97
|
+
// Brand-new agent (no access.json yet). If the deployment configured
|
|
98
|
+
// access via DISCORD_* env vars, honour that (legacy backward-compat,
|
|
99
|
+
// normalized through migrate). Otherwise fall back to defaultAccess() so
|
|
100
|
+
// the owner can DM the bot and self-pair — migrateAccess would yield
|
|
101
|
+
// pairing:false here (its "locked existing file" rule), which wrongly
|
|
102
|
+
// drops the owner's first DM on a fresh agent.
|
|
103
|
+
const hasEnvConfig = Boolean(
|
|
104
|
+
process.env.DISCORD_DM_POLICY ||
|
|
105
|
+
process.env.DISCORD_DM_ALLOWLIST ||
|
|
106
|
+
process.env.DISCORD_GUILD_ALLOWLIST ||
|
|
107
|
+
process.env.DISCORD_CHANNEL_ALLOWLIST ||
|
|
108
|
+
process.env.DISCORD_ROLE_ALLOWLIST,
|
|
109
|
+
);
|
|
110
|
+
if (!hasEnvConfig) return defaultAccess();
|
|
111
|
+
return migrateAccess({
|
|
112
|
+
dmPolicy: process.env.DISCORD_DM_POLICY,
|
|
47
113
|
allowFrom: process.env.DISCORD_DM_ALLOWLIST
|
|
48
114
|
? process.env.DISCORD_DM_ALLOWLIST.split(',').filter(Boolean)
|
|
49
115
|
: [],
|
|
@@ -57,7 +123,7 @@ export function loadAccess(stateDir: string): DiscordAccess {
|
|
|
57
123
|
? process.env.DISCORD_ROLE_ALLOWLIST.split(',').filter(Boolean)
|
|
58
124
|
: [],
|
|
59
125
|
pending: {},
|
|
60
|
-
};
|
|
126
|
+
});
|
|
61
127
|
}
|
|
62
128
|
try {
|
|
63
129
|
fs.renameSync(accessFile, `${accessFile}.corrupt-${Date.now()}`);
|
|
@@ -100,36 +166,77 @@ export function gate(
|
|
|
100
166
|
const { isDM, userId, guildId, channelId } = context;
|
|
101
167
|
|
|
102
168
|
if (!isDM) {
|
|
103
|
-
if (access.
|
|
104
|
-
|
|
169
|
+
if (access.groupPolicy === 'disabled') return { action: 'drop' };
|
|
170
|
+
|
|
171
|
+
if (access.groupPolicy === 'allowlist' && guildId && !access.guildAllowlist.includes(guildId)) {
|
|
172
|
+
// Unknown guild. Pairing off ⇒ silent drop. On ⇒ mint a code keyed on the
|
|
173
|
+
// guild id and post it here; a member relays it to the admin (mirrors LINE).
|
|
174
|
+
if (!access.pairing) return { action: 'drop' };
|
|
175
|
+
for (const [code, p] of Object.entries(access.pending)) {
|
|
176
|
+
if (p.kind === 'guild' && p.guildId === guildId) {
|
|
177
|
+
if (p.replies >= 2) return { action: 'drop' };
|
|
178
|
+
p.replies++;
|
|
179
|
+
saveAccessFn(access);
|
|
180
|
+
return { action: 'pair', code, isResend: true, isGuild: true };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (countPending(access, 'guild') >= 5) return { action: 'drop' };
|
|
184
|
+
const code = generateCode();
|
|
185
|
+
access.pending[code] = {
|
|
186
|
+
senderId: userId,
|
|
187
|
+
channelId,
|
|
188
|
+
guildId,
|
|
189
|
+
kind: 'guild',
|
|
190
|
+
createdAt: ts,
|
|
191
|
+
expiresAt: ts + 60 * 60 * 1000,
|
|
192
|
+
replies: 1,
|
|
193
|
+
};
|
|
194
|
+
saveAccessFn(access);
|
|
195
|
+
return { action: 'pair', code, isResend: false, isGuild: true };
|
|
105
196
|
}
|
|
197
|
+
|
|
198
|
+
// Allowlisted (or open policy) → keep the channel filter, then mention gate.
|
|
106
199
|
if (access.channelAllowlist.length > 0) {
|
|
107
200
|
if (!access.channelAllowlist.includes(channelId)) return { action: 'drop' };
|
|
108
201
|
}
|
|
202
|
+
if (access.requireMention !== false && !context.mentionsBot) return { action: 'drop' };
|
|
109
203
|
return { action: 'deliver' };
|
|
110
204
|
}
|
|
111
205
|
|
|
112
206
|
// DM message
|
|
113
207
|
if (access.dmPolicy === 'disabled') return { action: 'drop' };
|
|
114
208
|
|
|
209
|
+
if (access.dmPolicy === 'open') {
|
|
210
|
+
// Open base: anyone may DM; capture their id so future messages are known.
|
|
211
|
+
if (!access.allowFrom.includes(userId)) {
|
|
212
|
+
access.allowFrom.push(userId);
|
|
213
|
+
saveAccessFn(access);
|
|
214
|
+
}
|
|
215
|
+
return { action: 'deliver' };
|
|
216
|
+
}
|
|
217
|
+
|
|
115
218
|
if (access.allowFrom.includes(userId)) return { action: 'deliver' };
|
|
116
|
-
|
|
219
|
+
// Base policy is 'allowlist' ('disabled'/'open' handled above). Pairing is the
|
|
220
|
+
// orthogonal toggle: off ⇒ pure allowlist (drop strangers, no code).
|
|
221
|
+
if (!access.pairing) return { action: 'drop' };
|
|
117
222
|
|
|
118
223
|
// pairing mode
|
|
119
224
|
for (const [code, p] of Object.entries(access.pending)) {
|
|
120
|
-
if (p.senderId === userId) {
|
|
225
|
+
if ((p.kind ?? 'dm') === 'dm' && p.senderId === userId) {
|
|
121
226
|
if (p.replies >= 2) return { action: 'drop' };
|
|
122
227
|
p.replies++;
|
|
123
228
|
saveAccessFn(access);
|
|
124
229
|
return { action: 'pair', code, isResend: true };
|
|
125
230
|
}
|
|
126
231
|
}
|
|
127
|
-
|
|
232
|
+
// Cap pending per-kind so guild knocks and DM knocks don't starve each other.
|
|
233
|
+
if (countPending(access, 'dm') >= 5) return { action: 'drop' };
|
|
128
234
|
|
|
129
235
|
const code = generateCode();
|
|
130
236
|
access.pending[code] = {
|
|
131
237
|
senderId: userId,
|
|
132
238
|
channelId,
|
|
239
|
+
kind: 'dm',
|
|
133
240
|
createdAt: ts,
|
|
134
241
|
expiresAt: ts + 60 * 60 * 1000,
|
|
135
242
|
replies: 1,
|
|
@@ -138,6 +245,15 @@ export function gate(
|
|
|
138
245
|
return { action: 'pair', code, isResend: false };
|
|
139
246
|
}
|
|
140
247
|
|
|
248
|
+
/** Count pending entries of a given kind (absent kind ⇒ 'dm'). */
|
|
249
|
+
function countPending(access: DiscordAccess, kind: 'dm' | 'guild'): number {
|
|
250
|
+
let n = 0;
|
|
251
|
+
for (const p of Object.values(access.pending)) {
|
|
252
|
+
if ((p.kind ?? 'dm') === kind) n++;
|
|
253
|
+
}
|
|
254
|
+
return n;
|
|
255
|
+
}
|
|
256
|
+
|
|
141
257
|
// ---------------------------------------------------------------------------
|
|
142
258
|
// Env-var based access (backward compat)
|
|
143
259
|
// ---------------------------------------------------------------------------
|
|
@@ -22,7 +22,9 @@ export async function createDiscordClient(token: string): Promise<any> {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
await new Promise<void>((resolve, reject) => {
|
|
25
|
-
|
|
25
|
+
// 'clientReady' is the renamed 'ready' event (discord.js v14 emits both;
|
|
26
|
+
// 'ready' is deprecated and becomes clientReady-only in v15).
|
|
27
|
+
client.once('clientReady', () => resolve());
|
|
26
28
|
client.once('error', reject);
|
|
27
29
|
client.login(token).catch(reject);
|
|
28
30
|
});
|