nterminal 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/.env.example +12 -0
- package/LICENSE +674 -0
- package/README.md +181 -0
- package/assets/brand/app-icon-1024.png +0 -0
- package/assets/brand/app-icon-384.png +0 -0
- package/assets/brand/apple-touch-icon-360.png +0 -0
- package/assets/brand/favicon-32.png +0 -0
- package/assets/brand/favicon-64.png +0 -0
- package/assets/brand/favicon-96.png +0 -0
- package/assets/brand/favicon.svg +4 -0
- package/assets/brand/nterminal-mark-64.png +0 -0
- package/assets/brand/nterminal-mark.svg +4 -0
- package/assets/brand/nterminal-wordmark-486x68.png +0 -0
- package/assets/brand/nterminal-wordmark.svg +3 -0
- package/assets/screenshot/scr.png +0 -0
- package/bin/nterminal.js +114 -0
- package/dist/client/apple-touch-icon.png +0 -0
- package/dist/client/assets/MarkdownPreview-BeDi-V7k.js +29 -0
- package/dist/client/assets/MesloLGS-NF-Bold-Italic-DwFsXcwX.ttf +0 -0
- package/dist/client/assets/MesloLGS-NF-Bold-kN-HYz-g.ttf +0 -0
- package/dist/client/assets/MesloLGS-NF-Italic-CMg1T6-G.ttf +0 -0
- package/dist/client/assets/MesloLGS-NF-Regular-Cxr8pvCI.ttf +0 -0
- package/dist/client/assets/index-BQkKYjXb.js +33 -0
- package/dist/client/assets/index-WqeS39wU.css +1 -0
- package/dist/client/assets/notifications/character-2258.mp4 +0 -0
- package/dist/client/assets/notifications/character-2260.mp4 +0 -0
- package/dist/client/assets/notifications/character-2272.mp4 +0 -0
- package/dist/client/brand/nterminal-mark-64.png +0 -0
- package/dist/client/brand/nterminal-mark.svg +4 -0
- package/dist/client/brand/nterminal-wordmark-486x68.png +0 -0
- package/dist/client/brand/nterminal-wordmark.svg +3 -0
- package/dist/client/icons/app-icon-1024.png +0 -0
- package/dist/client/icons/app-icon-384.png +0 -0
- package/dist/client/icons/favicon-32.png +0 -0
- package/dist/client/icons/favicon-64.png +0 -0
- package/dist/client/icons/favicon-96.png +0 -0
- package/dist/client/icons/favicon.svg +4 -0
- package/dist/client/index.html +21 -0
- package/dist/client/manifest.webmanifest +24 -0
- package/dist/scripts/generate-secrets.js +3 -0
- package/dist/scripts/generate-secrets.js.map +1 -0
- package/dist/scripts/onboarding.js +814 -0
- package/dist/scripts/onboarding.js.map +1 -0
- package/dist/scripts/proxySetup.js +1007 -0
- package/dist/scripts/proxySetup.js.map +1 -0
- package/dist/server/agent/agentAuth.d.ts +6 -0
- package/dist/server/agent/agentAuth.js +35 -0
- package/dist/server/agent/agentAuth.js.map +1 -0
- package/dist/server/agent/agentProxy.d.ts +5 -0
- package/dist/server/agent/agentProxy.js +63 -0
- package/dist/server/agent/agentProxy.js.map +1 -0
- package/dist/server/agent/agentRoutes.d.ts +9 -0
- package/dist/server/agent/agentRoutes.js +327 -0
- package/dist/server/agent/agentRoutes.js.map +1 -0
- package/dist/server/agent/agentWebSocketProxy.d.ts +3 -0
- package/dist/server/agent/agentWebSocketProxy.js +65 -0
- package/dist/server/agent/agentWebSocketProxy.js.map +1 -0
- package/dist/server/auth/authService.d.ts +100 -0
- package/dist/server/auth/authService.js +415 -0
- package/dist/server/auth/authService.js.map +1 -0
- package/dist/server/auth/cookies.d.ts +11 -0
- package/dist/server/auth/cookies.js +39 -0
- package/dist/server/auth/cookies.js.map +1 -0
- package/dist/server/auth/ipMatch.d.ts +14 -0
- package/dist/server/auth/ipMatch.js +103 -0
- package/dist/server/auth/ipMatch.js.map +1 -0
- package/dist/server/auth/rateLimit.d.ts +17 -0
- package/dist/server/auth/rateLimit.js +25 -0
- package/dist/server/auth/rateLimit.js.map +1 -0
- package/dist/server/auth/totpService.d.ts +10 -0
- package/dist/server/auth/totpService.js +37 -0
- package/dist/server/auth/totpService.js.map +1 -0
- package/dist/server/config.d.ts +27 -0
- package/dist/server/config.js +138 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/files/fileExplorerService.d.ts +38 -0
- package/dist/server/files/fileExplorerService.js +551 -0
- package/dist/server/files/fileExplorerService.js.map +1 -0
- package/dist/server/files/rootToken.d.ts +51 -0
- package/dist/server/files/rootToken.js +139 -0
- package/dist/server/files/rootToken.js.map +1 -0
- package/dist/server/http.d.ts +13 -0
- package/dist/server/http.js +69 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +45 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/agentManagementRoutes.d.ts +9 -0
- package/dist/server/routes/agentManagementRoutes.js +304 -0
- package/dist/server/routes/agentManagementRoutes.js.map +1 -0
- package/dist/server/routes/authRoutes.d.ts +10 -0
- package/dist/server/routes/authRoutes.js +95 -0
- package/dist/server/routes/authRoutes.js.map +1 -0
- package/dist/server/routes/fileRoutes.d.ts +11 -0
- package/dist/server/routes/fileRoutes.js +185 -0
- package/dist/server/routes/fileRoutes.js.map +1 -0
- package/dist/server/routes/notificationAssetRoutes.d.ts +9 -0
- package/dist/server/routes/notificationAssetRoutes.js +280 -0
- package/dist/server/routes/notificationAssetRoutes.js.map +1 -0
- package/dist/server/routes/securityRoutes.d.ts +7 -0
- package/dist/server/routes/securityRoutes.js +53 -0
- package/dist/server/routes/securityRoutes.js.map +1 -0
- package/dist/server/routes/socketBackpressure.d.ts +26 -0
- package/dist/server/routes/socketBackpressure.js +63 -0
- package/dist/server/routes/socketBackpressure.js.map +1 -0
- package/dist/server/routes/terminalLayoutRoutes.d.ts +9 -0
- package/dist/server/routes/terminalLayoutRoutes.js +108 -0
- package/dist/server/routes/terminalLayoutRoutes.js.map +1 -0
- package/dist/server/routes/terminalRoutes.d.ts +14 -0
- package/dist/server/routes/terminalRoutes.js +177 -0
- package/dist/server/routes/terminalRoutes.js.map +1 -0
- package/dist/server/routes/terminalWebSocket.d.ts +9 -0
- package/dist/server/routes/terminalWebSocket.js +129 -0
- package/dist/server/routes/terminalWebSocket.js.map +1 -0
- package/dist/server/routes/totpRoutes.d.ts +7 -0
- package/dist/server/routes/totpRoutes.js +46 -0
- package/dist/server/routes/totpRoutes.js.map +1 -0
- package/dist/server/routes/updateRoutes.d.ts +7 -0
- package/dist/server/routes/updateRoutes.js +24 -0
- package/dist/server/routes/updateRoutes.js.map +1 -0
- package/dist/server/routes/uploadRoutes.d.ts +9 -0
- package/dist/server/routes/uploadRoutes.js +95 -0
- package/dist/server/routes/uploadRoutes.js.map +1 -0
- package/dist/server/storage/fileStore.d.ts +90 -0
- package/dist/server/storage/fileStore.js +275 -0
- package/dist/server/storage/fileStore.js.map +1 -0
- package/dist/server/system/stats.d.ts +2 -0
- package/dist/server/system/stats.js +37 -0
- package/dist/server/system/stats.js.map +1 -0
- package/dist/server/terminal/NodePtyAdapter.d.ts +4 -0
- package/dist/server/terminal/NodePtyAdapter.js +14 -0
- package/dist/server/terminal/NodePtyAdapter.js.map +1 -0
- package/dist/server/terminal/PtyAdapter.d.ts +57 -0
- package/dist/server/terminal/PtyAdapter.js +2 -0
- package/dist/server/terminal/PtyAdapter.js.map +1 -0
- package/dist/server/terminal/TerminalManager.d.ts +74 -0
- package/dist/server/terminal/TerminalManager.js +561 -0
- package/dist/server/terminal/TerminalManager.js.map +1 -0
- package/dist/server/terminal/TmuxPtyAdapter.d.ts +25 -0
- package/dist/server/terminal/TmuxPtyAdapter.js +543 -0
- package/dist/server/terminal/TmuxPtyAdapter.js.map +1 -0
- package/dist/server/terminal/codexTranscriptSource.d.ts +9 -0
- package/dist/server/terminal/codexTranscriptSource.js +144 -0
- package/dist/server/terminal/codexTranscriptSource.js.map +1 -0
- package/dist/server/terminal/cwdResolver.d.ts +8 -0
- package/dist/server/terminal/cwdResolver.js +37 -0
- package/dist/server/terminal/cwdResolver.js.map +1 -0
- package/dist/server/terminal/outputBuffer.d.ts +7 -0
- package/dist/server/terminal/outputBuffer.js +17 -0
- package/dist/server/terminal/outputBuffer.js.map +1 -0
- package/dist/server/terminal/transcriptHistory.d.ts +7 -0
- package/dist/server/terminal/transcriptHistory.js +315 -0
- package/dist/server/terminal/transcriptHistory.js.map +1 -0
- package/dist/server/update/gitUpdate.d.ts +27 -0
- package/dist/server/update/gitUpdate.js +241 -0
- package/dist/server/update/gitUpdate.js.map +1 -0
- package/dist/server/uploads/uploadPaths.d.ts +18 -0
- package/dist/server/uploads/uploadPaths.js +116 -0
- package/dist/server/uploads/uploadPaths.js.map +1 -0
- package/dist/server/uploads/uploadService.d.ts +21 -0
- package/dist/server/uploads/uploadService.js +230 -0
- package/dist/server/uploads/uploadService.js.map +1 -0
- package/dist/shared/layoutState.d.ts +6 -0
- package/dist/shared/layoutState.js +115 -0
- package/dist/shared/layoutState.js.map +1 -0
- package/dist/shared/notificationAssets.d.ts +9 -0
- package/dist/shared/notificationAssets.js +27 -0
- package/dist/shared/notificationAssets.js.map +1 -0
- package/dist/shared/protocol.d.ts +308 -0
- package/dist/shared/protocol.js +29 -0
- package/dist/shared/protocol.js.map +1 -0
- package/dist/shared/types.d.ts +56 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/docs/assets/nterminal-workspace.png +0 -0
- package/docs/configuration.md +97 -0
- package/docs/features.md +126 -0
- package/docs/onboarding.md +122 -0
- package/docs/operations.md +112 -0
- package/docs/terminal-history.md +54 -0
- package/package.json +85 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/notifications/character-2258.mp4 +0 -0
- package/public/assets/notifications/character-2260.mp4 +0 -0
- package/public/assets/notifications/character-2272.mp4 +0 -0
- package/public/brand/nterminal-mark-64.png +0 -0
- package/public/brand/nterminal-mark.svg +4 -0
- package/public/brand/nterminal-wordmark-486x68.png +0 -0
- package/public/brand/nterminal-wordmark.svg +3 -0
- package/public/icons/app-icon-1024.png +0 -0
- package/public/icons/app-icon-384.png +0 -0
- package/public/icons/favicon-32.png +0 -0
- package/public/icons/favicon-64.png +0 -0
- package/public/icons/favicon-96.png +0 -0
- package/public/icons/favicon.svg +4 -0
- package/public/manifest.webmanifest +24 -0
- package/scripts/nterminalctl +588 -0
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import * as nodePty from 'node-pty';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { resolveCodexTranscriptFromProcessLogs } from './codexTranscriptSource.js';
|
|
8
|
+
// Dedicated socket name so NTerminal's tmux server is completely isolated from
|
|
9
|
+
// any tmux the operator runs themselves (different `-L` = different daemon).
|
|
10
|
+
// Their `tmux ls` won't show our sessions, and our sessions don't pick up
|
|
11
|
+
// their ~/.tmux.conf either.
|
|
12
|
+
const TMUX_SOCKET = 'nterminal';
|
|
13
|
+
const TRANSCRIPT_FILE_CACHE_TTL_MS = 30_000;
|
|
14
|
+
const TRANSCRIPT_FILE_NEGATIVE_CACHE_TTL_MS = 5_000;
|
|
15
|
+
const transcriptFileCache = new Map();
|
|
16
|
+
// Wraps each PTY in a tmux session so shells survive `nterminalctl restart`
|
|
17
|
+
// and NTerminal version updates without losing state. The operator never
|
|
18
|
+
// interacts with tmux directly — the bundled `nterminal-tmux.conf` strips the
|
|
19
|
+
// status line, disables mouse capture, and unbinds every key so the
|
|
20
|
+
// experience matches a raw shell.
|
|
21
|
+
export class TmuxPtyAdapter {
|
|
22
|
+
configPath;
|
|
23
|
+
socket;
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.configPath = options.configPath ?? defaultConfigPath();
|
|
26
|
+
this.socket = options.socket ?? TMUX_SOCKET;
|
|
27
|
+
}
|
|
28
|
+
// Returns an instance only when `tmux` is on PATH and the bundled config
|
|
29
|
+
// file actually exists. The config-existence check prevents a confusing
|
|
30
|
+
// mid-flight failure mode where detect() returned an adapter but every
|
|
31
|
+
// `spawn` then errored with "no such file" on `tmux -f <conf>`. The
|
|
32
|
+
// caller wires up `NodePtyAdapter` as the fallback so a host without
|
|
33
|
+
// tmux (or with the config missing) still works — it just loses the
|
|
34
|
+
// across-restart persistence.
|
|
35
|
+
static detect(options = {}) {
|
|
36
|
+
const probe = spawnSync('sh', ['-c', 'command -v tmux'], { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
37
|
+
if (probe.status !== 0) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const configPath = options.configPath ?? defaultConfigPath();
|
|
41
|
+
if (!existsSync(configPath)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return new TmuxPtyAdapter({ ...options, configPath });
|
|
45
|
+
}
|
|
46
|
+
spawn(options) {
|
|
47
|
+
if (!options.sessionId) {
|
|
48
|
+
throw new Error('TmuxPtyAdapter.spawn requires a sessionId');
|
|
49
|
+
}
|
|
50
|
+
// `new-session -A` = attach to the named session if it already exists,
|
|
51
|
+
// otherwise create it. On the create path tmux runs `shell` inside the
|
|
52
|
+
// session in `-c cwd`; on the attach path both are ignored, which is
|
|
53
|
+
// exactly the behavior we want for the "NTerminal restarted, reattach to
|
|
54
|
+
// live shells" flow.
|
|
55
|
+
//
|
|
56
|
+
// -n <title> sets the window name only on the create path. On attach it
|
|
57
|
+
// is ignored — we don't want a re-attach to overwrite a name the
|
|
58
|
+
// operator already chose via the rename UI in a previous session.
|
|
59
|
+
const args = [
|
|
60
|
+
'-L',
|
|
61
|
+
this.socket,
|
|
62
|
+
'-f',
|
|
63
|
+
this.configPath,
|
|
64
|
+
'new-session',
|
|
65
|
+
'-A',
|
|
66
|
+
'-s',
|
|
67
|
+
options.sessionId,
|
|
68
|
+
'-c',
|
|
69
|
+
options.cwd
|
|
70
|
+
];
|
|
71
|
+
if (options.title) {
|
|
72
|
+
args.push('-n', sanitizeWindowName(options.title));
|
|
73
|
+
}
|
|
74
|
+
args.push(options.shell);
|
|
75
|
+
const pty = nodePty.spawn('tmux', args, {
|
|
76
|
+
name: 'xterm-256color',
|
|
77
|
+
cols: options.cols,
|
|
78
|
+
rows: options.rows,
|
|
79
|
+
cwd: options.cwd,
|
|
80
|
+
env: options.env
|
|
81
|
+
});
|
|
82
|
+
return wrapTmuxPty(pty, this.socket, this.configPath, options.sessionId);
|
|
83
|
+
}
|
|
84
|
+
listExisting() {
|
|
85
|
+
// Pull both session name and the (single) window's name in one call so
|
|
86
|
+
// restoreSessions in TerminalManager can repopulate the title without a
|
|
87
|
+
// per-session round-trip. The custom delimiter `\t` avoids ambiguity if a
|
|
88
|
+
// window name happens to contain spaces or pipes.
|
|
89
|
+
const result = spawnSync('tmux', [
|
|
90
|
+
'-L',
|
|
91
|
+
this.socket,
|
|
92
|
+
'-f',
|
|
93
|
+
this.configPath,
|
|
94
|
+
'list-sessions',
|
|
95
|
+
'-F',
|
|
96
|
+
'#{session_name}\t#{=128:window_name}'
|
|
97
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
98
|
+
if (result.status !== 0) {
|
|
99
|
+
// Common when no server is running yet (no sessions exist). tmux exits
|
|
100
|
+
// non-zero with stderr "no server running"; treat as empty list.
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
return result.stdout
|
|
104
|
+
.toString()
|
|
105
|
+
.split('\n')
|
|
106
|
+
.map((line) => line.trim())
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.map((line) => {
|
|
109
|
+
const tab = line.indexOf('\t');
|
|
110
|
+
if (tab === -1) {
|
|
111
|
+
return { sessionId: line };
|
|
112
|
+
}
|
|
113
|
+
const sessionId = line.slice(0, tab);
|
|
114
|
+
const title = line.slice(tab + 1);
|
|
115
|
+
return title ? { sessionId, title } : { sessionId };
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async pollSessions() {
|
|
119
|
+
// list-panes -a returns every pane across every session in one call.
|
|
120
|
+
// We use one pane per session, so the result is one row per terminal.
|
|
121
|
+
// `pane_current_command` is whichever process tmux sees as the
|
|
122
|
+
// foreground in that pane (the shell when at a prompt, otherwise vim
|
|
123
|
+
// / node / etc.). `pane_pid` is the root of that pane's process
|
|
124
|
+
// subtree — we walk its descendants below to decide busy vs idle.
|
|
125
|
+
const result = spawnSync('tmux', [
|
|
126
|
+
'-L',
|
|
127
|
+
this.socket,
|
|
128
|
+
'-f',
|
|
129
|
+
this.configPath,
|
|
130
|
+
'list-panes',
|
|
131
|
+
'-a',
|
|
132
|
+
'-F',
|
|
133
|
+
'#{session_name}\t#{pane_pid}\t#{pane_current_command}'
|
|
134
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
135
|
+
const out = new Map();
|
|
136
|
+
if (result.status !== 0)
|
|
137
|
+
return out;
|
|
138
|
+
const tree = readProcessTree();
|
|
139
|
+
for (const line of result.stdout.toString().split('\n')) {
|
|
140
|
+
const trimmed = line.trim();
|
|
141
|
+
if (!trimmed)
|
|
142
|
+
continue;
|
|
143
|
+
const parts = trimmed.split('\t');
|
|
144
|
+
if (parts.length < 3)
|
|
145
|
+
continue;
|
|
146
|
+
const sessionId = parts[0];
|
|
147
|
+
const panePid = Number(parts[1]);
|
|
148
|
+
const currentCommand = parts[2].trim();
|
|
149
|
+
if (!sessionId || !currentCommand || !Number.isFinite(panePid))
|
|
150
|
+
continue;
|
|
151
|
+
const busy = tree ? hasRunningDescendant(tree, panePid) : false;
|
|
152
|
+
out.set(sessionId, { currentCommand, busy });
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
setSessionTitle(sessionId, title) {
|
|
157
|
+
// Single-window-per-session in our setup, so renaming the window is the
|
|
158
|
+
// visible "session title" the operator perceives via the tab/pill label.
|
|
159
|
+
// tmux's rename-session is also possible but session names are how we
|
|
160
|
+
// address sessions in spawn/kill — those must stay stable, so we change
|
|
161
|
+
// window name instead.
|
|
162
|
+
spawnSync('tmux', [
|
|
163
|
+
'-L',
|
|
164
|
+
this.socket,
|
|
165
|
+
'-f',
|
|
166
|
+
this.configPath,
|
|
167
|
+
'rename-window',
|
|
168
|
+
'-t',
|
|
169
|
+
`${sessionId}:0`,
|
|
170
|
+
sanitizeWindowName(title)
|
|
171
|
+
], { stdio: 'ignore' });
|
|
172
|
+
}
|
|
173
|
+
captureHistory(sessionId, options) {
|
|
174
|
+
const limit = normalizeHistoryLimit(options.limit);
|
|
175
|
+
const metrics = this.readPaneMetrics(sessionId);
|
|
176
|
+
if (!metrics) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const oldestLine = -metrics.historySize;
|
|
180
|
+
const newestLine = Math.max(0, metrics.paneHeight - 1);
|
|
181
|
+
const requestedEnd = options.beforeLine === undefined ? newestLine : options.beforeLine - 1;
|
|
182
|
+
const endLine = Math.min(newestLine, requestedEnd);
|
|
183
|
+
if (endLine < oldestLine) {
|
|
184
|
+
return { startLine: oldestLine, endLine: oldestLine - 1, hasMore: false, output: [] };
|
|
185
|
+
}
|
|
186
|
+
const startLine = Math.max(oldestLine, endLine - limit + 1);
|
|
187
|
+
const result = spawnSync('tmux', [
|
|
188
|
+
'-L',
|
|
189
|
+
this.socket,
|
|
190
|
+
'-f',
|
|
191
|
+
this.configPath,
|
|
192
|
+
'capture-pane',
|
|
193
|
+
'-p',
|
|
194
|
+
'-e',
|
|
195
|
+
'-J',
|
|
196
|
+
'-S',
|
|
197
|
+
String(startLine),
|
|
198
|
+
'-E',
|
|
199
|
+
String(endLine),
|
|
200
|
+
'-t',
|
|
201
|
+
sessionId
|
|
202
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
203
|
+
if (result.status !== 0) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const text = normalizeCapturedPane(result.stdout.toString());
|
|
207
|
+
return {
|
|
208
|
+
startLine,
|
|
209
|
+
endLine,
|
|
210
|
+
hasMore: startLine > oldestLine,
|
|
211
|
+
output: text ? [text] : []
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
resolveTranscriptSource(sessionId) {
|
|
215
|
+
const panePid = this.readPanePid(sessionId);
|
|
216
|
+
if (panePid === null) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
const tree = readProcessTree();
|
|
220
|
+
if (!tree) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
const candidates = new Map();
|
|
224
|
+
for (const pid of listDescendantPids(tree, panePid)) {
|
|
225
|
+
const args = readProcessArgs(pid);
|
|
226
|
+
if (args.length === 0) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const candidate = extractTranscriptCandidate(args) ?? resolveTranscriptCandidateFromProcessLogs(pid, args);
|
|
230
|
+
if (candidate) {
|
|
231
|
+
candidates.set(`${candidate.provider}:${candidate.sessionId}`, candidate);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (candidates.size !== 1) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
const [candidate] = candidates.values();
|
|
238
|
+
if (!candidate) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
const matches = candidate.filePath ? [candidate.filePath] : findTranscriptFiles(candidate.provider, candidate.sessionId);
|
|
242
|
+
if (matches.length !== 1) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return { provider: candidate.provider, sessionId: candidate.sessionId, filePath: matches[0] };
|
|
246
|
+
}
|
|
247
|
+
readPaneMetrics(sessionId) {
|
|
248
|
+
const result = spawnSync('tmux', [
|
|
249
|
+
'-L',
|
|
250
|
+
this.socket,
|
|
251
|
+
'-f',
|
|
252
|
+
this.configPath,
|
|
253
|
+
'display-message',
|
|
254
|
+
'-p',
|
|
255
|
+
'-t',
|
|
256
|
+
sessionId,
|
|
257
|
+
'#{history_size}\t#{pane_height}'
|
|
258
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
259
|
+
if (result.status !== 0) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
const [historyRaw, heightRaw] = result.stdout.toString().trim().split('\t');
|
|
263
|
+
const historySize = Number(historyRaw);
|
|
264
|
+
const paneHeight = Number(heightRaw);
|
|
265
|
+
if (!Number.isInteger(historySize) || historySize < 0 || !Number.isInteger(paneHeight) || paneHeight <= 0) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
return { historySize, paneHeight };
|
|
269
|
+
}
|
|
270
|
+
readPanePid(sessionId) {
|
|
271
|
+
const result = spawnSync('tmux', [
|
|
272
|
+
'-L',
|
|
273
|
+
this.socket,
|
|
274
|
+
'-f',
|
|
275
|
+
this.configPath,
|
|
276
|
+
'display-message',
|
|
277
|
+
'-p',
|
|
278
|
+
'-t',
|
|
279
|
+
sessionId,
|
|
280
|
+
'#{pane_pid}'
|
|
281
|
+
], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
282
|
+
if (result.status !== 0) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
const panePid = Number(result.stdout.toString().trim());
|
|
286
|
+
return Number.isInteger(panePid) && panePid > 0 ? panePid : null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// tmux window names are a single line of text without ESC sequences. Cap the
|
|
290
|
+
// length and strip anything that could break terminal output if a future read
|
|
291
|
+
// path embedded the name in a status line. 80 chars is plenty for a tab
|
|
292
|
+
// label and matches the length we ask for in list-sessions's =128 cap.
|
|
293
|
+
function sanitizeWindowName(raw) {
|
|
294
|
+
const collapsed = raw.replace(/[\u0000-\u001f\u007f]+/g, ' ').trim();
|
|
295
|
+
return collapsed.slice(0, 80) || 'Terminal';
|
|
296
|
+
}
|
|
297
|
+
function normalizeHistoryLimit(value) {
|
|
298
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
299
|
+
return 1000;
|
|
300
|
+
}
|
|
301
|
+
return Math.min(value, 5000);
|
|
302
|
+
}
|
|
303
|
+
function normalizeCapturedPane(text) {
|
|
304
|
+
const stripped = text.replace(/\r?\n$/, '');
|
|
305
|
+
return stripped ? `${stripped.replace(/\r?\n/g, '\r\n')}\r\n` : '';
|
|
306
|
+
}
|
|
307
|
+
// Wrap node-pty's IPty so PtyProcess.kill() destroys the tmux SESSION (the
|
|
308
|
+
// goal of TerminalManager.closeTerminal — actually free the shell), not just
|
|
309
|
+
// the local tmux client. Without this, "close pane" would leave a zombie
|
|
310
|
+
// session behind and the operator's `tmux ls -L nterminal` would slowly grow.
|
|
311
|
+
function wrapTmuxPty(pty, socket, configPath, sessionId) {
|
|
312
|
+
return {
|
|
313
|
+
pid: pty.pid,
|
|
314
|
+
write(data) {
|
|
315
|
+
pty.write(data);
|
|
316
|
+
},
|
|
317
|
+
resize(cols, rows) {
|
|
318
|
+
pty.resize(cols, rows);
|
|
319
|
+
},
|
|
320
|
+
pause() {
|
|
321
|
+
pty.pause();
|
|
322
|
+
},
|
|
323
|
+
resume() {
|
|
324
|
+
pty.resume();
|
|
325
|
+
},
|
|
326
|
+
kill() {
|
|
327
|
+
// kill-session tears down the tmux session for this PTY. The local
|
|
328
|
+
// tmux client process (this pty) exits as a side effect once the
|
|
329
|
+
// server reports the session is gone. Done synchronously so the
|
|
330
|
+
// caller's "the shell is gone now" assumption holds.
|
|
331
|
+
spawnSync('tmux', ['-L', socket, '-f', configPath, 'kill-session', '-t', sessionId], { stdio: 'ignore' });
|
|
332
|
+
// Belt-and-suspenders: if kill-session failed (e.g., session already
|
|
333
|
+
// exited), make sure the client process is gone too.
|
|
334
|
+
try {
|
|
335
|
+
pty.kill();
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// tmux client may have already exited
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
onData(listener) {
|
|
342
|
+
const disposable = pty.onData(listener);
|
|
343
|
+
return { dispose: () => disposable.dispose() };
|
|
344
|
+
},
|
|
345
|
+
onExit(listener) {
|
|
346
|
+
const disposable = pty.onExit((event) => {
|
|
347
|
+
listener({ exitCode: event.exitCode ?? null });
|
|
348
|
+
});
|
|
349
|
+
return { dispose: () => disposable.dispose() };
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function defaultConfigPath() {
|
|
354
|
+
// import.meta.url points to the compiled file under dist/server; from
|
|
355
|
+
// there `../../../scripts/nterminal-tmux.conf` resolves back to the source
|
|
356
|
+
// tree's config. Same layout in dev (running directly under src/).
|
|
357
|
+
return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../scripts/nterminal-tmux.conf');
|
|
358
|
+
}
|
|
359
|
+
const SESSION_ID_PATTERN = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
360
|
+
// One `ps` dump covers every pane in the poll cycle — much cheaper than
|
|
361
|
+
// per-pane shell-outs. The output is `pid ppid state` with leading
|
|
362
|
+
// whitespace trimmed; state is the kernel-reported run state where
|
|
363
|
+
// 'R' = runnable / on-cpu, 'D' = uninterruptible I/O wait, anything
|
|
364
|
+
// else (S, T, t, Z, I) we treat as "not actively working right now".
|
|
365
|
+
function readProcessTree() {
|
|
366
|
+
const result = spawnSync('ps', ['-eo', 'pid=,ppid=,state='], {
|
|
367
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
368
|
+
});
|
|
369
|
+
if (result.status !== 0)
|
|
370
|
+
return null;
|
|
371
|
+
const childrenByPpid = new Map();
|
|
372
|
+
for (const line of result.stdout.toString().split('\n')) {
|
|
373
|
+
const parts = line.trim().split(/\s+/);
|
|
374
|
+
if (parts.length < 3)
|
|
375
|
+
continue;
|
|
376
|
+
const pid = Number(parts[0]);
|
|
377
|
+
const ppid = Number(parts[1]);
|
|
378
|
+
const state = parts[2].charAt(0);
|
|
379
|
+
if (!Number.isFinite(pid) || !Number.isFinite(ppid) || !state)
|
|
380
|
+
continue;
|
|
381
|
+
const bucket = childrenByPpid.get(ppid);
|
|
382
|
+
if (bucket)
|
|
383
|
+
bucket.push({ pid, state });
|
|
384
|
+
else
|
|
385
|
+
childrenByPpid.set(ppid, [{ pid, state }]);
|
|
386
|
+
}
|
|
387
|
+
return { childrenByPpid };
|
|
388
|
+
}
|
|
389
|
+
function hasRunningDescendant(tree, root) {
|
|
390
|
+
// BFS from the shell PID (root). Only descendants count — the shell
|
|
391
|
+
// itself is virtually always sleeping in read(), so including it
|
|
392
|
+
// would never flip the result anyway, but skipping it documents the
|
|
393
|
+
// intent: "is something the operator launched currently doing work".
|
|
394
|
+
const stack = [root];
|
|
395
|
+
const seen = new Set([root]);
|
|
396
|
+
while (stack.length > 0) {
|
|
397
|
+
const pid = stack.pop();
|
|
398
|
+
const kids = tree.childrenByPpid.get(pid);
|
|
399
|
+
if (!kids)
|
|
400
|
+
continue;
|
|
401
|
+
for (const child of kids) {
|
|
402
|
+
if (child.state === 'R' || child.state === 'D')
|
|
403
|
+
return true;
|
|
404
|
+
if (seen.has(child.pid))
|
|
405
|
+
continue;
|
|
406
|
+
seen.add(child.pid);
|
|
407
|
+
stack.push(child.pid);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
function listDescendantPids(tree, root) {
|
|
413
|
+
const out = [];
|
|
414
|
+
const stack = [root];
|
|
415
|
+
const seen = new Set([root]);
|
|
416
|
+
while (stack.length > 0) {
|
|
417
|
+
const pid = stack.pop();
|
|
418
|
+
const kids = tree.childrenByPpid.get(pid);
|
|
419
|
+
if (!kids)
|
|
420
|
+
continue;
|
|
421
|
+
for (const child of kids) {
|
|
422
|
+
if (seen.has(child.pid))
|
|
423
|
+
continue;
|
|
424
|
+
seen.add(child.pid);
|
|
425
|
+
out.push(child.pid);
|
|
426
|
+
stack.push(child.pid);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return out;
|
|
430
|
+
}
|
|
431
|
+
function readProcessArgs(pid) {
|
|
432
|
+
try {
|
|
433
|
+
const raw = readFileSync(`/proc/${pid}/cmdline`, 'utf8');
|
|
434
|
+
return raw.split('\0').filter(Boolean);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
return [];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function extractTranscriptCandidate(args) {
|
|
441
|
+
const codexIndex = findCommandArg(args, 'codex');
|
|
442
|
+
if (codexIndex !== -1) {
|
|
443
|
+
const sessionId = findCodexSessionId(args, codexIndex);
|
|
444
|
+
return sessionId ? { provider: 'codex', sessionId } : null;
|
|
445
|
+
}
|
|
446
|
+
const claudeIndex = findCommandArg(args, 'claude');
|
|
447
|
+
if (claudeIndex !== -1) {
|
|
448
|
+
const sessionId = findClaudeSessionId(args, claudeIndex);
|
|
449
|
+
return sessionId ? { provider: 'claude', sessionId } : null;
|
|
450
|
+
}
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
function resolveTranscriptCandidateFromProcessLogs(pid, args) {
|
|
454
|
+
if (findCommandArg(args, 'codex') === -1) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
return resolveCodexTranscriptFromProcessLogs(pid);
|
|
458
|
+
}
|
|
459
|
+
function findCommandArg(args, command) {
|
|
460
|
+
return args.findIndex((arg) => {
|
|
461
|
+
const base = path.basename(arg);
|
|
462
|
+
return base === command || base === `${command}.js` || base.startsWith(`${command}-`);
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
function findCodexSessionId(args, commandIndex) {
|
|
466
|
+
for (let index = commandIndex + 1; index < args.length - 1; index += 1) {
|
|
467
|
+
if (args[index] === 'resume' && isSessionId(args[index + 1])) {
|
|
468
|
+
return args[index + 1];
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
function findClaudeSessionId(args, commandIndex) {
|
|
474
|
+
for (let index = commandIndex + 1; index < args.length; index += 1) {
|
|
475
|
+
const arg = args[index];
|
|
476
|
+
if ((arg === '--session-id' || arg === '--resume' || arg === '-r') && isSessionId(args[index + 1])) {
|
|
477
|
+
return args[index + 1];
|
|
478
|
+
}
|
|
479
|
+
const sessionId = readLongOptionValue(arg, '--session-id') ?? readLongOptionValue(arg, '--resume');
|
|
480
|
+
if (sessionId && isSessionId(sessionId)) {
|
|
481
|
+
return sessionId;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
function readLongOptionValue(arg, option) {
|
|
487
|
+
const prefix = `${option}=`;
|
|
488
|
+
return arg.startsWith(prefix) ? arg.slice(prefix.length) : null;
|
|
489
|
+
}
|
|
490
|
+
function isSessionId(value) {
|
|
491
|
+
return typeof value === 'string' && SESSION_ID_PATTERN.test(value);
|
|
492
|
+
}
|
|
493
|
+
function findTranscriptFiles(provider, sessionId) {
|
|
494
|
+
const cacheKey = `${provider}:${sessionId}`;
|
|
495
|
+
const cached = transcriptFileCache.get(cacheKey);
|
|
496
|
+
const now = Date.now();
|
|
497
|
+
if (cached && cached.expiresAt > now) {
|
|
498
|
+
return cached.matches.slice();
|
|
499
|
+
}
|
|
500
|
+
const root = provider === 'codex'
|
|
501
|
+
? path.join(os.homedir(), '.codex', 'sessions')
|
|
502
|
+
: path.join(os.homedir(), '.claude', 'projects');
|
|
503
|
+
const matches = [];
|
|
504
|
+
findTranscriptFilesUnder(root, provider, sessionId, matches);
|
|
505
|
+
transcriptFileCache.set(cacheKey, {
|
|
506
|
+
expiresAt: now + (matches.length === 1 ? TRANSCRIPT_FILE_CACHE_TTL_MS : TRANSCRIPT_FILE_NEGATIVE_CACHE_TTL_MS),
|
|
507
|
+
matches: matches.slice()
|
|
508
|
+
});
|
|
509
|
+
return matches;
|
|
510
|
+
}
|
|
511
|
+
function findTranscriptFilesUnder(root, provider, sessionId, matches) {
|
|
512
|
+
if (matches.length > 1) {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
let entries;
|
|
516
|
+
try {
|
|
517
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
518
|
+
}
|
|
519
|
+
catch {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
for (const entry of entries) {
|
|
523
|
+
if (matches.length > 1) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const fullPath = path.join(root, entry.name);
|
|
527
|
+
if (entry.isDirectory()) {
|
|
528
|
+
findTranscriptFilesUnder(fullPath, provider, sessionId, matches);
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
if (!entry.isFile()) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
if (provider === 'codex' && entry.name.startsWith('rollout-') && entry.name.endsWith(`${sessionId}.jsonl`)) {
|
|
535
|
+
matches.push(fullPath);
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (provider === 'claude' && entry.name === `${sessionId}.jsonl`) {
|
|
539
|
+
matches.push(fullPath);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
//# sourceMappingURL=TmuxPtyAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TmuxPtyAdapter.js","sourceRoot":"","sources":["../../../src/server/terminal/TmuxPtyAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PtyTranscriptSource } from './PtyAdapter.js';
|
|
2
|
+
type RunSqlite = (databasePath: string, sql: string) => string | null;
|
|
3
|
+
export interface CodexTranscriptLogLookupOptions {
|
|
4
|
+
homeDir?: string;
|
|
5
|
+
processStartedAtSeconds?: number | null;
|
|
6
|
+
runSqlite?: RunSqlite;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveCodexTranscriptFromProcessLogs(pid: number, options?: CodexTranscriptLogLookupOptions): PtyTranscriptSource | null;
|
|
9
|
+
export {};
|