@indianic/dialout 1.1.1 → 1.2.0
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 +429 -16
- package/bin/AGENTS.md +44 -0
- package/bin/devdash-agent.js +2 -0
- package/dist/ai-adapters/claude.d.ts +3 -0
- package/dist/ai-adapters/claude.d.ts.map +1 -0
- package/dist/ai-adapters/claude.js +98 -0
- package/dist/ai-adapters/claude.js.map +1 -0
- package/dist/ai-adapters/codex.d.ts +3 -0
- package/dist/ai-adapters/codex.d.ts.map +1 -0
- package/dist/ai-adapters/codex.js +147 -0
- package/dist/ai-adapters/codex.js.map +1 -0
- package/dist/ai-adapters/grok.d.ts +3 -0
- package/dist/ai-adapters/grok.d.ts.map +1 -0
- package/dist/ai-adapters/grok.js +164 -0
- package/dist/ai-adapters/grok.js.map +1 -0
- package/dist/ai-adapters/index.d.ts +5 -0
- package/dist/ai-adapters/index.d.ts.map +1 -0
- package/dist/ai-adapters/index.js +30 -0
- package/dist/ai-adapters/index.js.map +1 -0
- package/dist/ai-adapters/types.d.ts +3 -0
- package/dist/ai-adapters/types.d.ts.map +1 -0
- package/dist/ai-adapters/types.js +7 -0
- package/dist/ai-adapters/types.js.map +1 -0
- package/dist/ai-capabilities/claude.d.ts +4 -0
- package/dist/ai-capabilities/claude.d.ts.map +1 -0
- package/dist/ai-capabilities/claude.js +174 -0
- package/dist/ai-capabilities/claude.js.map +1 -0
- package/dist/ai-capabilities/describe.d.ts +2 -0
- package/dist/ai-capabilities/describe.d.ts.map +1 -0
- package/dist/ai-capabilities/describe.js +31 -0
- package/dist/ai-capabilities/describe.js.map +1 -0
- package/dist/ai-capabilities/fsdeps.d.ts +3 -0
- package/dist/ai-capabilities/fsdeps.d.ts.map +1 -0
- package/dist/ai-capabilities/fsdeps.js +71 -0
- package/dist/ai-capabilities/fsdeps.js.map +1 -0
- package/dist/ai-capabilities/grok.d.ts +5 -0
- package/dist/ai-capabilities/grok.d.ts.map +1 -0
- package/dist/ai-capabilities/grok.js +145 -0
- package/dist/ai-capabilities/grok.js.map +1 -0
- package/dist/ai-capabilities/index.d.ts +4 -0
- package/dist/ai-capabilities/index.d.ts.map +1 -0
- package/dist/ai-capabilities/index.js +94 -0
- package/dist/ai-capabilities/index.js.map +1 -0
- package/dist/ai-capabilities/redact.d.ts +2 -0
- package/dist/ai-capabilities/redact.d.ts.map +1 -0
- package/dist/ai-capabilities/redact.js +27 -0
- package/dist/ai-capabilities/redact.js.map +1 -0
- package/dist/ai-capabilities/types.d.ts +11 -0
- package/dist/ai-capabilities/types.d.ts.map +1 -0
- package/dist/ai-capabilities/types.js +3 -0
- package/dist/ai-capabilities/types.js.map +1 -0
- package/dist/ai-launch.d.ts +35 -0
- package/dist/ai-launch.d.ts.map +1 -0
- package/dist/ai-launch.js +211 -0
- package/dist/ai-launch.js.map +1 -0
- package/dist/ai-session-detector.d.ts +19 -0
- package/dist/ai-session-detector.d.ts.map +1 -0
- package/dist/ai-session-detector.js +79 -0
- package/dist/ai-session-detector.js.map +1 -0
- package/dist/ai-sessions.d.ts +36 -0
- package/dist/ai-sessions.d.ts.map +1 -0
- package/dist/ai-sessions.js +309 -0
- package/dist/ai-sessions.js.map +1 -0
- package/dist/ai-status.d.ts +6 -0
- package/dist/ai-status.d.ts.map +1 -0
- package/dist/ai-status.js +40 -0
- package/dist/ai-status.js.map +1 -0
- package/dist/ai-transcript-locator.d.ts +35 -0
- package/dist/ai-transcript-locator.d.ts.map +1 -0
- package/dist/ai-transcript-locator.js +268 -0
- package/dist/ai-transcript-locator.js.map +1 -0
- package/dist/ai-transcript-tail.d.ts +17 -0
- package/dist/ai-transcript-tail.d.ts.map +1 -0
- package/dist/ai-transcript-tail.js +120 -0
- package/dist/ai-transcript-tail.js.map +1 -0
- package/dist/checklist.d.ts +20 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +51 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1427 -0
- package/dist/cli.js.map +1 -0
- package/dist/command-runner.d.ts +15 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +84 -0
- package/dist/command-runner.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +152 -0
- package/dist/config.js.map +1 -0
- package/dist/cowork.d.ts +26 -0
- package/dist/cowork.d.ts.map +1 -0
- package/dist/cowork.js +370 -0
- package/dist/cowork.js.map +1 -0
- package/dist/fs-browser.d.ts +6 -0
- package/dist/fs-browser.d.ts.map +1 -0
- package/dist/fs-browser.js +61 -0
- package/dist/fs-browser.js.map +1 -0
- package/dist/has-command.d.ts +12 -0
- package/dist/has-command.d.ts.map +1 -0
- package/dist/has-command.js +24 -0
- package/dist/has-command.js.map +1 -0
- package/dist/heartbeat.d.ts +7 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +50 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/port-scanner.d.ts +4 -0
- package/dist/port-scanner.d.ts.map +1 -0
- package/dist/port-scanner.js +75 -0
- package/dist/port-scanner.js.map +1 -0
- package/dist/project-scanner.d.ts +15 -0
- package/dist/project-scanner.d.ts.map +1 -0
- package/dist/project-scanner.js +333 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/pty-manager.d.ts +28 -0
- package/dist/pty-manager.d.ts.map +1 -0
- package/dist/pty-manager.js +506 -0
- package/dist/pty-manager.js.map +1 -0
- package/dist/service-installer.d.ts +95 -0
- package/dist/service-installer.d.ts.map +1 -0
- package/dist/service-installer.js +911 -0
- package/dist/service-installer.js.map +1 -0
- package/dist/single-instance.d.ts +20 -0
- package/dist/single-instance.d.ts.map +1 -0
- package/dist/single-instance.js +151 -0
- package/dist/single-instance.js.map +1 -0
- package/dist/ssh-local-network.d.ts +26 -0
- package/dist/ssh-local-network.d.ts.map +1 -0
- package/dist/ssh-local-network.js +169 -0
- package/dist/ssh-local-network.js.map +1 -0
- package/dist/terminal-detect.d.ts +52 -0
- package/dist/terminal-detect.d.ts.map +1 -0
- package/dist/terminal-detect.js +147 -0
- package/dist/terminal-detect.js.map +1 -0
- package/dist/terminal-markers.d.ts +52 -0
- package/dist/terminal-markers.d.ts.map +1 -0
- package/dist/terminal-markers.js +174 -0
- package/dist/terminal-markers.js.map +1 -0
- package/dist/tmux-manager.d.ts +35 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +274 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/update-check.d.ts +3 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +202 -0
- package/dist/update-check.js.map +1 -0
- package/dist/websocket.d.ts +8 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +472 -0
- package/dist/websocket.js.map +1 -0
- package/node_modules/@dialout/shared/README.md +16 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts +8 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/ai-chat-prefs.js +41 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/capabilities.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/capabilities.js +2 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts +33 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/chat-blocks.js +61 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/command-filter.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/command-filter.js +49 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts +6 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/composer-behaviour.js +24 -0
- package/node_modules/@dialout/shared/dist/events.d.ts +37 -0
- package/node_modules/@dialout/shared/dist/events.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/events.js +13 -0
- package/node_modules/@dialout/shared/dist/index.d.ts +21 -0
- package/node_modules/@dialout/shared/dist/index.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/index.js +37 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts +2 -0
- package/node_modules/@dialout/shared/dist/kinds.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/kinds.js +2 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/notify.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/notify.js +31 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts +4 -0
- package/node_modules/@dialout/shared/dist/permission.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/permission.js +8 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts +3 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/scroll-pin.js +11 -0
- package/node_modules/@dialout/shared/dist/session.d.ts +19 -0
- package/node_modules/@dialout/shared/dist/session.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/session.js +6 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts +25 -0
- package/node_modules/@dialout/shared/dist/terminal-name.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/terminal-name.js +63 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts +9 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.d.ts.map +1 -0
- package/node_modules/@dialout/shared/dist/tool-appearance.js +30 -0
- package/node_modules/@dialout/shared/package.json +37 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.test.ts +40 -0
- package/node_modules/@dialout/shared/src/ai-chat-prefs.ts +39 -0
- package/node_modules/@dialout/shared/src/capabilities.ts +30 -0
- package/node_modules/@dialout/shared/src/chat-blocks.test.ts +65 -0
- package/node_modules/@dialout/shared/src/chat-blocks.ts +79 -0
- package/node_modules/@dialout/shared/src/command-filter.test.ts +76 -0
- package/node_modules/@dialout/shared/src/command-filter.ts +45 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.test.ts +31 -0
- package/node_modules/@dialout/shared/src/composer-behaviour.ts +22 -0
- package/node_modules/@dialout/shared/src/events.ts +27 -0
- package/node_modules/@dialout/shared/src/index.ts +32 -0
- package/node_modules/@dialout/shared/src/kinds.ts +5 -0
- package/node_modules/@dialout/shared/src/notify.test.ts +49 -0
- package/node_modules/@dialout/shared/src/notify.ts +30 -0
- package/node_modules/@dialout/shared/src/permission.ts +10 -0
- package/node_modules/@dialout/shared/src/scroll-pin.test.ts +23 -0
- package/node_modules/@dialout/shared/src/scroll-pin.ts +13 -0
- package/node_modules/@dialout/shared/src/session.ts +25 -0
- package/node_modules/@dialout/shared/src/terminal-name.ts +82 -0
- package/node_modules/@dialout/shared/src/tool-appearance.test.ts +41 -0
- package/node_modules/@dialout/shared/src/tool-appearance.ts +39 -0
- package/package.json +54 -14
- package/scripts/postinstall.js +79 -0
- package/scripts/prepack.js +45 -0
- package/bin/dialout.js +0 -13
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RECONNECT_MAX_MS = exports.RECONNECT_BASE_MS = void 0;
|
|
7
|
+
exports.reconnectDelay = reconnectDelay;
|
|
8
|
+
exports.connect = connect;
|
|
9
|
+
exports.disconnect = disconnect;
|
|
10
|
+
exports.isConnected = isConnected;
|
|
11
|
+
const ws_1 = __importDefault(require("ws"));
|
|
12
|
+
const heartbeat_1 = require("./heartbeat");
|
|
13
|
+
const port_scanner_1 = require("./port-scanner");
|
|
14
|
+
const fs_browser_1 = require("./fs-browser");
|
|
15
|
+
const project_scanner_1 = require("./project-scanner");
|
|
16
|
+
const command_runner_1 = require("./command-runner");
|
|
17
|
+
const pty_manager_1 = require("./pty-manager");
|
|
18
|
+
const tmux_manager_1 = require("./tmux-manager");
|
|
19
|
+
const ai_sessions_1 = require("./ai-sessions");
|
|
20
|
+
const ai_capabilities_1 = require("./ai-capabilities");
|
|
21
|
+
let ws = null;
|
|
22
|
+
let reconnectTimer = null;
|
|
23
|
+
let isShuttingDown = false;
|
|
24
|
+
let reconnectAttempt = 0;
|
|
25
|
+
exports.RECONNECT_BASE_MS = 1000;
|
|
26
|
+
exports.RECONNECT_MAX_MS = 60_000;
|
|
27
|
+
// Exponential backoff with +/-20% jitter. A flat delay made every agent in the
|
|
28
|
+
// fleet retry in lockstep and hammer the server the moment it went down; the
|
|
29
|
+
// jitter spreads the herd out across the window.
|
|
30
|
+
function reconnectDelay(attempt, rand = Math.random) {
|
|
31
|
+
const raw = Math.min(exports.RECONNECT_BASE_MS * 2 ** (attempt - 1), exports.RECONNECT_MAX_MS);
|
|
32
|
+
return Math.round(raw * (0.8 + rand() * 0.4));
|
|
33
|
+
}
|
|
34
|
+
let tmuxPollTimer = null;
|
|
35
|
+
let lastTmuxSnapshot = '';
|
|
36
|
+
const TMUX_POLL_MS = 5000;
|
|
37
|
+
const TMUX_RESYNC_MS = 60_000;
|
|
38
|
+
const PREVIEW_CAP = 5;
|
|
39
|
+
let lastTmuxSentAt = 0;
|
|
40
|
+
let reportedSinceConnect = false;
|
|
41
|
+
async function pollTmuxSessions() {
|
|
42
|
+
if (!ws || ws.readyState !== ws_1.default.OPEN)
|
|
43
|
+
return;
|
|
44
|
+
if (!(await (0, tmux_manager_1.tmuxAvailable)()))
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
const sessions = await (0, tmux_manager_1.listSessions)();
|
|
48
|
+
const enriched = await Promise.all(sessions.map(async (s) => ({
|
|
49
|
+
...s,
|
|
50
|
+
lastLines: await (0, tmux_manager_1.capturePane)(s.name, PREVIEW_CAP),
|
|
51
|
+
})));
|
|
52
|
+
// folderPath is part of the change key: it is now the LIVE pane path, so a
|
|
53
|
+
// bare `cd` changes nothing else and the update would otherwise be held
|
|
54
|
+
// back until the next 60s resync (or forever, if nothing else changes).
|
|
55
|
+
const snapshot = JSON.stringify(enriched.map((s) => [s.name, s.attached, s.width, s.height, s.folderPath, s.lastLines]));
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
if (snapshot !== lastTmuxSnapshot || now - lastTmuxSentAt > TMUX_RESYNC_MS) {
|
|
58
|
+
lastTmuxSnapshot = snapshot;
|
|
59
|
+
lastTmuxSentAt = now;
|
|
60
|
+
ws.send(JSON.stringify({ type: 'tmux_sessions', sessions: enriched }));
|
|
61
|
+
// Say what the FIRST report after a connect actually contained. An agent
|
|
62
|
+
// that cannot read the user's tmux sessions sends an empty list forever
|
|
63
|
+
// and looks online and healthy, while the dashboard shows no terminals
|
|
64
|
+
// and no AI sessions. Reporting "0 sessions" is the difference between
|
|
65
|
+
// that and "nothing is running", and it costs one line per connect.
|
|
66
|
+
//
|
|
67
|
+
// The message names uid AND locale because both have caused this, and the
|
|
68
|
+
// first version of this line named only the uid — which sent the next
|
|
69
|
+
// investigation straight down the wrong path on a machine whose uid was
|
|
70
|
+
// correct and whose locale was not. Print the facts, not a conclusion.
|
|
71
|
+
if (!reportedSinceConnect) {
|
|
72
|
+
reportedSinceConnect = true;
|
|
73
|
+
const uid = typeof process.getuid === 'function' ? process.getuid() : '?';
|
|
74
|
+
const locale = process.env.LC_ALL || process.env.LC_CTYPE || process.env.LANG || '(unset)';
|
|
75
|
+
console.log(`[dialout] reporting ${enriched.length} tmux session(s)`
|
|
76
|
+
+ (enriched.length === 0
|
|
77
|
+
? ` — none visible. uid=${uid}, locale=${locale}.`
|
|
78
|
+
+ ' If you do have tmux sessions, compare that uid with `id -u`'
|
|
79
|
+
+ ' (a daemon running as another user reads a different'
|
|
80
|
+
+ ' /tmp/tmux-<uid> socket).'
|
|
81
|
+
: `: ${enriched.map((s) => s.name).join(', ')}`));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
console.error('[dialout] tmux poll failed:', err.message);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function startTmuxPolling() {
|
|
90
|
+
stopTmuxPolling();
|
|
91
|
+
lastTmuxSnapshot = '';
|
|
92
|
+
reportedSinceConnect = false;
|
|
93
|
+
tmuxPollTimer = setInterval(() => { void pollTmuxSessions(); }, TMUX_POLL_MS);
|
|
94
|
+
void pollTmuxSessions(); // immediate sync on connect
|
|
95
|
+
}
|
|
96
|
+
function stopTmuxPolling() {
|
|
97
|
+
if (tmuxPollTimer) {
|
|
98
|
+
clearInterval(tmuxPollTimer);
|
|
99
|
+
tmuxPollTimer = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// AI sessions are discovered from the same tmux sessions the poll above
|
|
103
|
+
// reports, but resolving the process tree and the transcript for each one is
|
|
104
|
+
// far more work than a list-sessions, so it gets its own cadence and its own
|
|
105
|
+
// change-detection.
|
|
106
|
+
let aiPollTimer = null;
|
|
107
|
+
let lastAiSnapshot = '';
|
|
108
|
+
const AI_POLL_MS = 5000;
|
|
109
|
+
async function pollAiSessions() {
|
|
110
|
+
if (!ws || ws.readyState !== ws_1.default.OPEN)
|
|
111
|
+
return;
|
|
112
|
+
try {
|
|
113
|
+
const sessions = await (0, ai_sessions_1.discoverAiSessions)();
|
|
114
|
+
const snapshot = JSON.stringify(sessions);
|
|
115
|
+
if (snapshot === lastAiSnapshot)
|
|
116
|
+
return;
|
|
117
|
+
lastAiSnapshot = snapshot;
|
|
118
|
+
ws.send(JSON.stringify({ type: 'ai_session_list', sessions }));
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
console.error('[dialout] ai session poll failed:', err.message);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function startAiPolling() {
|
|
125
|
+
stopAiPolling();
|
|
126
|
+
lastAiSnapshot = '';
|
|
127
|
+
aiPollTimer = setInterval(() => { void pollAiSessions(); }, AI_POLL_MS);
|
|
128
|
+
void pollAiSessions();
|
|
129
|
+
}
|
|
130
|
+
function stopAiPolling() {
|
|
131
|
+
if (aiPollTimer) {
|
|
132
|
+
clearInterval(aiPollTimer);
|
|
133
|
+
aiPollTimer = null;
|
|
134
|
+
}
|
|
135
|
+
// Tails are per-connection state: a reconnect re-opens whatever the browser
|
|
136
|
+
// is still watching, and leaving them running would poll files nobody reads.
|
|
137
|
+
(0, ai_sessions_1.closeAllAiSessions)();
|
|
138
|
+
}
|
|
139
|
+
function connect(config, onConnected) {
|
|
140
|
+
isShuttingDown = false;
|
|
141
|
+
const url = config.serverUrl.replace(/\/$/, '') + '/daemon';
|
|
142
|
+
ws = new ws_1.default(url, {
|
|
143
|
+
headers: { 'X-API-Key': config.apiKey },
|
|
144
|
+
});
|
|
145
|
+
ws.on('open', () => {
|
|
146
|
+
console.log('[dialout] Connected to server');
|
|
147
|
+
reconnectAttempt = 0; // a good connection resets the backoff
|
|
148
|
+
(0, pty_manager_1.setActiveSocket)(ws);
|
|
149
|
+
// A dead socket may never emit 'close' on its own — terminate() forces it,
|
|
150
|
+
// which runs the 'close' handler and schedules the reconnect.
|
|
151
|
+
(0, heartbeat_1.startHeartbeat)(ws, config.heartbeatInterval, () => {
|
|
152
|
+
try {
|
|
153
|
+
ws?.terminate();
|
|
154
|
+
}
|
|
155
|
+
catch { /* already gone */ }
|
|
156
|
+
});
|
|
157
|
+
startTmuxPolling();
|
|
158
|
+
startAiPolling();
|
|
159
|
+
// Reaper handshake. Detach timers live only in the ws-server's memory, so
|
|
160
|
+
// a ws-server restart forgets every browser connection while our client
|
|
161
|
+
// PTYs keep running with nothing on the other end. Reporting what we hold
|
|
162
|
+
// lets the server answer pty_detach for the ones it no longer tracks. The
|
|
163
|
+
// tmux sessions behind them are untouched either way — this reclaims
|
|
164
|
+
// node-pty processes, it does not end anyone's work.
|
|
165
|
+
ws.send(JSON.stringify({ type: 'active_ptys', ids: (0, pty_manager_1.getActiveSessions)() }));
|
|
166
|
+
(0, pty_manager_1.applyNativeTmuxOptions)(); // native terminals (Hyper etc.) get mouse/scroll/no-status without a wrapper re-install
|
|
167
|
+
onConnected?.();
|
|
168
|
+
});
|
|
169
|
+
ws.on('message', (raw) => {
|
|
170
|
+
try {
|
|
171
|
+
const msg = JSON.parse(raw.toString());
|
|
172
|
+
handleMessage(msg, config);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
console.error('[dialout] Invalid message:', err);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
ws.on('close', (code) => {
|
|
179
|
+
console.log(`[dialout] Disconnected (code: ${code})`);
|
|
180
|
+
(0, heartbeat_1.stopHeartbeat)();
|
|
181
|
+
stopTmuxPolling();
|
|
182
|
+
stopAiPolling();
|
|
183
|
+
// Keep PTY sessions alive across reconnects — output resumes on the new
|
|
184
|
+
// socket once we're back (sessions are only killed by explicit pty_close
|
|
185
|
+
// or agent shutdown).
|
|
186
|
+
scheduleReconnect(config, onConnected);
|
|
187
|
+
});
|
|
188
|
+
ws.on('error', (err) => {
|
|
189
|
+
console.error('[dialout] WebSocket error:', err.message);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function disconnect() {
|
|
193
|
+
isShuttingDown = true;
|
|
194
|
+
if (reconnectTimer) {
|
|
195
|
+
clearTimeout(reconnectTimer);
|
|
196
|
+
reconnectTimer = null;
|
|
197
|
+
}
|
|
198
|
+
(0, heartbeat_1.stopHeartbeat)();
|
|
199
|
+
stopTmuxPolling();
|
|
200
|
+
stopAiPolling();
|
|
201
|
+
(0, pty_manager_1.closeAllSessions)();
|
|
202
|
+
if (ws) {
|
|
203
|
+
ws.close();
|
|
204
|
+
ws = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function isConnected() {
|
|
208
|
+
return ws !== null && ws.readyState === ws_1.default.OPEN;
|
|
209
|
+
}
|
|
210
|
+
function scheduleReconnect(config, onConnected) {
|
|
211
|
+
if (isShuttingDown)
|
|
212
|
+
return;
|
|
213
|
+
if (reconnectTimer)
|
|
214
|
+
return;
|
|
215
|
+
const delay = reconnectDelay(++reconnectAttempt);
|
|
216
|
+
console.log(`[dialout] Reconnecting in ${(delay / 1000).toFixed(1)}s (attempt ${reconnectAttempt})...`);
|
|
217
|
+
reconnectTimer = setTimeout(() => {
|
|
218
|
+
reconnectTimer = null;
|
|
219
|
+
connect(config, onConnected);
|
|
220
|
+
}, delay);
|
|
221
|
+
}
|
|
222
|
+
async function handleMessage(msg, config) {
|
|
223
|
+
if (!ws || ws.readyState !== ws_1.default.OPEN)
|
|
224
|
+
return;
|
|
225
|
+
switch (msg.type) {
|
|
226
|
+
case 'auth_ok':
|
|
227
|
+
console.log(`[dialout] Authenticated as machine ${msg.machineId}`);
|
|
228
|
+
break;
|
|
229
|
+
case 'pong':
|
|
230
|
+
// Server acknowledged heartbeat — proves the socket is still two-way.
|
|
231
|
+
(0, heartbeat_1.notePong)();
|
|
232
|
+
break;
|
|
233
|
+
case 'port_scan_request': {
|
|
234
|
+
const { ports, from, to } = msg;
|
|
235
|
+
let openPorts;
|
|
236
|
+
if (ports && Array.isArray(ports)) {
|
|
237
|
+
openPorts = await (0, port_scanner_1.scanPorts)(ports);
|
|
238
|
+
}
|
|
239
|
+
else if (from != null && to != null) {
|
|
240
|
+
openPorts = await (0, port_scanner_1.scanRange)(from, to);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
openPorts = await (0, port_scanner_1.scanPorts)(config.scanPorts);
|
|
244
|
+
}
|
|
245
|
+
ws.send(JSON.stringify({ type: 'port_scan_result', requestId: msg.requestId, openPorts }));
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case 'fs_browse': {
|
|
249
|
+
const entries = (0, fs_browser_1.listDirectory)(msg.path || '/');
|
|
250
|
+
ws.send(JSON.stringify({ type: 'fs_list', requestId: msg.requestId, path: msg.path, entries }));
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
case 'project_scan': {
|
|
254
|
+
try {
|
|
255
|
+
const projects = await (0, project_scanner_1.scanProjects)(msg.path || process.env.HOME || '/', msg.depth ?? 2);
|
|
256
|
+
ws.send(JSON.stringify({ type: 'project_scan_result', requestId: msg.requestId, projects }));
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
ws.send(JSON.stringify({
|
|
260
|
+
type: 'project_scan_result',
|
|
261
|
+
requestId: msg.requestId,
|
|
262
|
+
projects: [],
|
|
263
|
+
error: err?.message || 'Scan failed',
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
case 'run_command': {
|
|
269
|
+
const result = await (0, command_runner_1.runCommand)({
|
|
270
|
+
command: msg.command || '',
|
|
271
|
+
cwd: msg.cwd,
|
|
272
|
+
background: !!msg.background,
|
|
273
|
+
logName: msg.logName,
|
|
274
|
+
});
|
|
275
|
+
ws.send(JSON.stringify({ type: 'run_command_result', requestId: msg.requestId, ...result }));
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
case 'pty_open': {
|
|
279
|
+
if (!(0, pty_manager_1.isPtyAvailable)()) {
|
|
280
|
+
ws.send(JSON.stringify({ type: 'pty_error', id: msg.id, error: 'node-pty not available' }));
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
let opened;
|
|
284
|
+
if (msg.tmuxSession) {
|
|
285
|
+
opened = (0, pty_manager_1.openAttach)(msg.id, String(msg.tmuxSession), !!msg.readOnly, msg.cols || 80, msg.rows || 24);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
opened = (0, pty_manager_1.openSession)(msg.id, msg.command || '', msg.cwd || process.env.HOME || '/', msg.cols || 80, msg.rows || 24, { coworkWrap: !!config.cowork });
|
|
289
|
+
}
|
|
290
|
+
if (!opened) {
|
|
291
|
+
ws.send(JSON.stringify({ type: 'pty_error', id: msg.id, error: msg.tmuxSession ? 'Failed to attach to session' : 'Failed to open session' }));
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case 'pty_data': {
|
|
296
|
+
(0, pty_manager_1.writeToSession)(msg.id, msg.data);
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
case 'pty_resize': {
|
|
300
|
+
(0, pty_manager_1.resizeSession)(msg.id, msg.cols, msg.rows);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case 'pty_close': {
|
|
304
|
+
void (0, pty_manager_1.closeSession)(msg.id);
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case 'pty_detach': {
|
|
308
|
+
// Browser is gone for good, but the work is not: drop our tmux client
|
|
309
|
+
// and leave the session running. See detachPtySession().
|
|
310
|
+
(0, pty_manager_1.detachPtySession)(msg.id);
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
case 'ai_session_list_request': {
|
|
314
|
+
const sessions = await (0, ai_sessions_1.discoverAiSessions)();
|
|
315
|
+
ws.send(JSON.stringify({ type: 'ai_session_list', requestId: msg.requestId, sessions }));
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case 'ai_capabilities_request': {
|
|
319
|
+
// cwd comes from the server, which took it from the session registry —
|
|
320
|
+
// the agent does not re-derive it, so the answer matches the session the
|
|
321
|
+
// user is actually looking at.
|
|
322
|
+
const caps = (0, ai_capabilities_1.discoverCapabilities)(String(msg.kind || ''), String(msg.cwd || ''));
|
|
323
|
+
ws.send(JSON.stringify({ type: 'ai_capabilities', requestId: msg.requestId, caps }));
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
case 'ai_session_open': {
|
|
327
|
+
const name = String(msg.tmuxName || '');
|
|
328
|
+
if (!name)
|
|
329
|
+
break;
|
|
330
|
+
(0, ai_sessions_1.openAiSession)(name, (events, status) => {
|
|
331
|
+
if (ws && ws.readyState === ws_1.default.OPEN) {
|
|
332
|
+
ws.send(JSON.stringify({ type: 'ai_session_events', tmuxName: name, events, status }));
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
case 'ai_session_create': {
|
|
338
|
+
const id = (0, ai_sessions_1.createAiSession)({
|
|
339
|
+
kind: msg.kind,
|
|
340
|
+
cwd: msg.cwd,
|
|
341
|
+
prompt: msg.prompt,
|
|
342
|
+
permissionMode: msg.permissionMode,
|
|
343
|
+
configHome: msg.configHome,
|
|
344
|
+
});
|
|
345
|
+
ws.send(JSON.stringify({
|
|
346
|
+
type: 'ai_session_created', requestId: msg.requestId, id,
|
|
347
|
+
}));
|
|
348
|
+
// The new session should appear in the list immediately rather than on
|
|
349
|
+
// the next five-second poll.
|
|
350
|
+
lastAiSnapshot = '';
|
|
351
|
+
void pollAiSessions();
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
case 'ai_session_delete': {
|
|
355
|
+
const ok = (0, ai_sessions_1.deleteAiSession)(String(msg.id || ''));
|
|
356
|
+
ws.send(JSON.stringify({
|
|
357
|
+
type: 'ai_session_deleted', requestId: msg.requestId, ok,
|
|
358
|
+
}));
|
|
359
|
+
lastAiSnapshot = '';
|
|
360
|
+
void pollAiSessions();
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
case 'ai_session_close': {
|
|
364
|
+
(0, ai_sessions_1.closeAiSession)(String(msg.tmuxName || ''));
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
case 'ai_session_input': {
|
|
368
|
+
// Input is keystrokes into the pane: a natively-launched TUI cannot
|
|
369
|
+
// accept structured input. This is the ceiling of attach mode.
|
|
370
|
+
if (msg.tmuxName && typeof msg.text === 'string') {
|
|
371
|
+
(0, ai_sessions_1.sendAiInput)(String(msg.tmuxName), msg.text);
|
|
372
|
+
}
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
case 'kill_tmux': {
|
|
376
|
+
// Force-kill a tmux session by name (used by the Terminals "kill" action).
|
|
377
|
+
// Kills the session and every process in it; any attached client PTY exits.
|
|
378
|
+
// An already-gone session counts as success; a broken tmux reports the
|
|
379
|
+
// real error so the UI can tell "killed" from "failed".
|
|
380
|
+
const killed = await (0, tmux_manager_1.killTmuxSession)(msg.name);
|
|
381
|
+
if (!killed.ok) {
|
|
382
|
+
console.error(`[dialout] kill_tmux ${msg.name} failed: ${killed.error}`);
|
|
383
|
+
}
|
|
384
|
+
ws.send(JSON.stringify({
|
|
385
|
+
type: 'kill_tmux_result',
|
|
386
|
+
requestId: msg.requestId,
|
|
387
|
+
ok: killed.ok,
|
|
388
|
+
error: killed.error,
|
|
389
|
+
}));
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
case 'http_request': {
|
|
393
|
+
try {
|
|
394
|
+
const url = msg.baseUrl
|
|
395
|
+
? `${msg.baseUrl}${msg.path}`
|
|
396
|
+
: `http://localhost:${msg.port}${msg.path}`;
|
|
397
|
+
const fetchOpts = {
|
|
398
|
+
method: msg.method || 'GET',
|
|
399
|
+
headers: msg.headers || {},
|
|
400
|
+
};
|
|
401
|
+
// Only attach body for methods that support it
|
|
402
|
+
if (msg.body && !['GET', 'HEAD'].includes((msg.method || 'GET').toUpperCase())) {
|
|
403
|
+
fetchOpts.body = Buffer.from(msg.body, 'base64');
|
|
404
|
+
}
|
|
405
|
+
const resp = await fetch(url, fetchOpts);
|
|
406
|
+
const bodyBuf = Buffer.from(await resp.arrayBuffer());
|
|
407
|
+
const respHeaders = {};
|
|
408
|
+
resp.headers.forEach((val, key) => { respHeaders[key] = val; });
|
|
409
|
+
const b64 = bodyBuf.toString('base64');
|
|
410
|
+
// Split a large body across several frames.
|
|
411
|
+
//
|
|
412
|
+
// A single frame carrying ~10 MB of base64 — a 7.6 MB dev-server chunk,
|
|
413
|
+
// say — did not survive the hop to the server: the request never
|
|
414
|
+
// completed and eventually timed out, while every smaller asset on the
|
|
415
|
+
// same socket went through. That is why one big script could 404 on a
|
|
416
|
+
// page whose other chunks all loaded.
|
|
417
|
+
//
|
|
418
|
+
// The threshold comes from the server on each request. An older server
|
|
419
|
+
// does not send it, `chunkThreshold` is undefined, and this whole branch
|
|
420
|
+
// is skipped — so the agent keeps behaving exactly as it does today
|
|
421
|
+
// rather than sending frames the other end cannot reassemble.
|
|
422
|
+
const threshold = typeof msg.chunkThreshold === 'number' && msg.chunkThreshold > 0
|
|
423
|
+
? msg.chunkThreshold
|
|
424
|
+
: undefined;
|
|
425
|
+
if (threshold && b64.length > threshold) {
|
|
426
|
+
const total = Math.ceil(b64.length / threshold);
|
|
427
|
+
for (let i = 0; i < total; i++) {
|
|
428
|
+
ws.send(JSON.stringify({
|
|
429
|
+
type: 'http_response_chunk',
|
|
430
|
+
requestId: msg.requestId,
|
|
431
|
+
index: i,
|
|
432
|
+
data: b64.slice(i * threshold, (i + 1) * threshold),
|
|
433
|
+
}));
|
|
434
|
+
}
|
|
435
|
+
// The metadata frame goes last and carries no body: it is what tells
|
|
436
|
+
// the server the parts are all sent and how many to expect, so a
|
|
437
|
+
// short delivery is detected rather than silently truncating.
|
|
438
|
+
ws.send(JSON.stringify({
|
|
439
|
+
type: 'http_response',
|
|
440
|
+
requestId: msg.requestId,
|
|
441
|
+
status: resp.status,
|
|
442
|
+
headers: respHeaders,
|
|
443
|
+
chunked: true,
|
|
444
|
+
totalChunks: total,
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
ws.send(JSON.stringify({
|
|
449
|
+
type: 'http_response',
|
|
450
|
+
requestId: msg.requestId,
|
|
451
|
+
status: resp.status,
|
|
452
|
+
headers: respHeaders,
|
|
453
|
+
body: b64,
|
|
454
|
+
}));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
catch (err) {
|
|
458
|
+
ws.send(JSON.stringify({
|
|
459
|
+
type: 'http_response',
|
|
460
|
+
requestId: msg.requestId,
|
|
461
|
+
status: 502,
|
|
462
|
+
headers: { 'content-type': 'text/plain' },
|
|
463
|
+
body: Buffer.from(`Tunnel error: ${err.message}`).toString('base64'),
|
|
464
|
+
}));
|
|
465
|
+
}
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
default:
|
|
469
|
+
console.warn('[dialout] Unknown message type:', msg.type);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../src/websocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @dialout/shared
|
|
2
|
+
|
|
3
|
+
Domain types and pure functions used by the web app, the agent, and (next)
|
|
4
|
+
the React Native app. Nothing in here imports `fs`, `next/…`, or
|
|
5
|
+
`react-native` — the moment it does, it stops being shareable.
|
|
6
|
+
|
|
7
|
+
One home for `AiEvent`, `AiSessionSummary`, `AiCapabilities`,
|
|
8
|
+
`PERMISSION_MODES`, `shouldNotifyAi`, and the chat rules (`groupEvents`,
|
|
9
|
+
`shouldFollow`, `toolAppearance`, `commandQuery`, `shouldSubmitOnEnter`).
|
|
10
|
+
Adding a field here is a compile error in every consumer. That is the point:
|
|
11
|
+
the previous copies had already drifted (`origin` / `permissionMode` missing
|
|
12
|
+
from the web `AiSessionSummary`).
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { groupEvents, shouldNotifyAi, PERMISSION_MODES } from '@dialout/shared';
|
|
16
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const FUNCTION_KEYS_PREF = "devdash-ai-function-keys";
|
|
2
|
+
export interface PrefStore {
|
|
3
|
+
getItem(key: string): string | null;
|
|
4
|
+
setItem(key: string, value: string): void;
|
|
5
|
+
}
|
|
6
|
+
export declare function getFunctionKeysVisible(store?: PrefStore | null): boolean;
|
|
7
|
+
export declare function setFunctionKeysVisible(on: boolean, store?: PrefStore | null): void;
|
|
8
|
+
//# sourceMappingURL=ai-chat-prefs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-chat-prefs.d.ts","sourceRoot":"","sources":["../src/ai-chat-prefs.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAYD,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,SAAS,GAAG,IAAqB,GAAG,OAAO,CAOxF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,GAAG,IAAqB,GAAG,IAAI,CAKlG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Per-device AI chat preferences. Every read and write is guarded, because
|
|
3
|
+
// blocked storage must degrade to the default rather than break the composer.
|
|
4
|
+
//
|
|
5
|
+
// Storage is injected so this stays free of both `window` assumptions in the
|
|
6
|
+
// function signatures and of any React Native / Next import. The web default
|
|
7
|
+
// uses localStorage; a native client passes SecureStore.
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FUNCTION_KEYS_PREF = void 0;
|
|
10
|
+
exports.getFunctionKeysVisible = getFunctionKeysVisible;
|
|
11
|
+
exports.setFunctionKeysVisible = setFunctionKeysVisible;
|
|
12
|
+
exports.FUNCTION_KEYS_PREF = 'devdash-ai-function-keys';
|
|
13
|
+
function browserStore() {
|
|
14
|
+
const w = globalThis.window;
|
|
15
|
+
if (!w?.localStorage)
|
|
16
|
+
return null;
|
|
17
|
+
try {
|
|
18
|
+
return w.localStorage;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function getFunctionKeysVisible(store = browserStore()) {
|
|
25
|
+
if (!store)
|
|
26
|
+
return false;
|
|
27
|
+
try {
|
|
28
|
+
return store.getItem(exports.FUNCTION_KEYS_PREF) === '1';
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function setFunctionKeysVisible(on, store = browserStore()) {
|
|
35
|
+
if (!store)
|
|
36
|
+
return;
|
|
37
|
+
try {
|
|
38
|
+
store.setItem(exports.FUNCTION_KEYS_PREF, on ? '1' : '0');
|
|
39
|
+
}
|
|
40
|
+
catch { /* blocked storage: keep the in-memory default */ }
|
|
41
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AiKind } from './kinds';
|
|
2
|
+
export type CommandSource = 'user' | 'project' | 'plugin' | 'builtin';
|
|
3
|
+
export interface AiCommand {
|
|
4
|
+
name: string;
|
|
5
|
+
alias?: string;
|
|
6
|
+
description: string;
|
|
7
|
+
source: CommandSource;
|
|
8
|
+
}
|
|
9
|
+
export interface McpServerInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
scope: 'global' | 'project';
|
|
12
|
+
transport: 'stdio' | 'http';
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
origin: string;
|
|
15
|
+
command?: string;
|
|
16
|
+
args?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface AiCapabilities {
|
|
19
|
+
kind: AiKind | string;
|
|
20
|
+
commands: AiCommand[];
|
|
21
|
+
mcpServers: McpServerInfo[];
|
|
22
|
+
scannedAt: string;
|
|
23
|
+
unavailable?: boolean;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAGlB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AiEvent } from './events';
|
|
2
|
+
export interface ToolItem {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
ok: boolean | null;
|
|
7
|
+
resultPreview: string | null;
|
|
8
|
+
resultLines: number | null;
|
|
9
|
+
}
|
|
10
|
+
export type ChatBlock = {
|
|
11
|
+
kind: 'user';
|
|
12
|
+
key: string;
|
|
13
|
+
text: string;
|
|
14
|
+
pending?: boolean;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'assistant';
|
|
17
|
+
key: string;
|
|
18
|
+
text: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'tools';
|
|
21
|
+
key: string;
|
|
22
|
+
items: ToolItem[];
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'thinking';
|
|
25
|
+
key: string;
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'status';
|
|
29
|
+
key: string;
|
|
30
|
+
status: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function groupEvents(events: AiEvent[]): ChatBlock[];
|
|
33
|
+
//# sourceMappingURL=chat-blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-blocks.d.ts","sourceRoot":"","sources":["../src/chat-blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAM,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAK,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAI,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAIvD,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CA0D1D"}
|