dsh-ssh-tui 0.5.7 → 0.5.9
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.en.md +25 -0
- package/README.md +45 -0
- package/lib/display-sock.js +234 -62
- package/lib/display-sock.js.map +1 -1
- package/lib/dsh-compat.js +138 -5
- package/lib/dsh-compat.js.map +1 -1
- package/lib/footer.js +27 -2
- package/lib/footer.js.map +1 -1
- package/lib/i18n/en.js +1 -0
- package/lib/i18n/en.js.map +1 -1
- package/lib/i18n/zh.js +1 -0
- package/lib/i18n/zh.js.map +1 -1
- package/lib/index.js +59 -10
- package/lib/index.js.map +1 -1
- package/lib/paint.js +21 -2
- package/lib/paint.js.map +1 -1
- package/lib/picker.js +59 -28
- package/lib/picker.js.map +1 -1
- package/lib/session-index.js +2 -2
- package/lib/session-index.js.map +1 -1
- package/lib/session-lock.js +181 -25
- package/lib/session-lock.js.map +1 -1
- package/lib/tui.js +103 -24
- package/lib/tui.js.map +1 -1
- package/lib/types/display-sock.d.ts +62 -5
- package/lib/types/dsh-compat.d.ts +60 -2
- package/lib/types/footer.d.ts +11 -1
- package/lib/types/index.d.ts +4 -0
- package/lib/types/paint.d.ts +13 -0
- package/lib/types/picker.d.ts +8 -2
- package/lib/types/session-lock.d.ts +42 -3
- package/lib/types/tui.d.ts +17 -5
- package/package.json +3 -3
package/lib/session-lock.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Stale locks (dead pid) are stolen. A live lock with a reachable display
|
|
4
4
|
* socket is an attach target, not a hard failure.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { readdir } from 'node:fs/promises';
|
|
7
7
|
import { mkdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { execFile } from 'node:child_process';
|
|
10
10
|
import { dirname, join } from 'node:path';
|
|
11
11
|
import { t } from './i18n/index.js';
|
|
12
|
-
import { sessionSockPath } from './display-sock.js';
|
|
12
|
+
import { displaySockExists, isPipePath, resolveDshHome, sessionSockPath } from './display-sock.js';
|
|
13
13
|
export class SessionLockHeldError extends Error {
|
|
14
14
|
lock;
|
|
15
15
|
path;
|
|
@@ -20,7 +20,7 @@ export class SessionLockHeldError extends Error {
|
|
|
20
20
|
this.path = path;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
export function sessionLockPath(sessionId, dshHome =
|
|
23
|
+
export function sessionLockPath(sessionId, dshHome = resolveDshHome()) {
|
|
24
24
|
const safe = sessionId.replaceAll(/[^A-Za-z0-9._-]/g, '_');
|
|
25
25
|
return join(dshHome, 'tui-locks', `${safe}.json`);
|
|
26
26
|
}
|
|
@@ -99,6 +99,152 @@ function readProcCmdline(pid) {
|
|
|
99
99
|
return undefined;
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
+
/** Clock/resolution slack when comparing a creation time with the lock write. */
|
|
103
|
+
export const PID_REUSE_SLACK_MS = 5_000;
|
|
104
|
+
/**
|
|
105
|
+
* Cache of Windows identities so one lock costs at most one probe per window.
|
|
106
|
+
*
|
|
107
|
+
* Keyed by pid *and* the lock instance that was inspected: scoping it to the
|
|
108
|
+
* lock (not just the pid) is what keeps a recycled pid from being judged by an
|
|
109
|
+
* identity it no longer has — a foreign cached identity applied to a fresh
|
|
110
|
+
* lock would declare a live Host stale and let a second Host write the same
|
|
111
|
+
* session. The short TTL bounds the same hazard for repeated inspections of
|
|
112
|
+
* one lock.
|
|
113
|
+
*/
|
|
114
|
+
const WINDOWS_IDENTITY_TTL_MS = 10_000;
|
|
115
|
+
const windowsIdentityCache = new Map();
|
|
116
|
+
function lockInstanceKey(lock) {
|
|
117
|
+
return `${lock.pid}:${lock.startedAt}`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Parse the probe's stdout. Everything after the last non-empty line is
|
|
121
|
+
* ignored (a stray warning banner must not masquerade as the image name), and
|
|
122
|
+
* an unexpected shape is reported as "unverifiable" rather than as a
|
|
123
|
+
* mismatch: mistaking noise for a foreign process would steal a live lock.
|
|
124
|
+
*/
|
|
125
|
+
export function parseWindowsProcessIdentity(stdout) {
|
|
126
|
+
// Keep the raw line: the tab between name and timestamp is the shape being
|
|
127
|
+
// validated, and trimming whitespace off the end would delete it (a trailing
|
|
128
|
+
// tab means "name known, creation time unreadable", which is still useful).
|
|
129
|
+
const line = stdout.split('\n')
|
|
130
|
+
.map(entry => entry.replace(/\r$/u, ''))
|
|
131
|
+
.reverse()
|
|
132
|
+
.find(entry => entry.trim() !== '');
|
|
133
|
+
if (line === undefined || line.trim() === 'gone')
|
|
134
|
+
return undefined;
|
|
135
|
+
const trimmed = line.trimStart();
|
|
136
|
+
const tab = trimmed.indexOf('\t');
|
|
137
|
+
if (tab <= 0)
|
|
138
|
+
return undefined;
|
|
139
|
+
const name = trimmed.slice(0, tab).trim().toLowerCase();
|
|
140
|
+
if (!/^[a-z0-9_.-]+$/u.test(name))
|
|
141
|
+
return undefined;
|
|
142
|
+
const startedAt = Date.parse(trimmed.slice(tab + 1).trim());
|
|
143
|
+
return { name, ...Number.isFinite(startedAt) ? { startedAt } : {} };
|
|
144
|
+
}
|
|
145
|
+
/** Absolute Windows PowerShell, for hosts where the bare name is not on PATH. */
|
|
146
|
+
function systemPowerShell() {
|
|
147
|
+
const root = process.env.SystemRoot ?? process.env.windir ?? 'C:\\Windows';
|
|
148
|
+
return `${root}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* `Get-Process` beats WMI here: it is a single .NET call that reports both the
|
|
152
|
+
* image name (works across users) and the creation time. The script avoids
|
|
153
|
+
* double quotes so Node's CreateProcess quoting stays trivial, and formats the
|
|
154
|
+
* timestamp with the invariant culture so native-digit locales cannot turn it
|
|
155
|
+
* into NaN.
|
|
156
|
+
*/
|
|
157
|
+
async function queryWindowsProcess(pid) {
|
|
158
|
+
const script = `$p = Get-Process -Id ${pid} -ErrorAction SilentlyContinue; `
|
|
159
|
+
+ `if ($null -eq $p) { 'gone' } else { `
|
|
160
|
+
+ `$st = ''; try { $st = $p.StartTime.ToUniversalTime().ToString('yyyy-MM-dd\\THH\\:mm\\:ss.fff\\Z', [System.Globalization.CultureInfo]::InvariantCulture) } catch {}; `
|
|
161
|
+
+ `$p.ProcessName.ToLower() + [char]9 + $st }`;
|
|
162
|
+
for (const exe of ['powershell.exe', systemPowerShell()]) {
|
|
163
|
+
const stdout = await runPowerShell(exe, script);
|
|
164
|
+
// `undefined` means the interpreter could not run at all (missing,
|
|
165
|
+
// blocked, timed out); a readable answer — including `gone` — is final.
|
|
166
|
+
if (stdout === undefined)
|
|
167
|
+
continue;
|
|
168
|
+
return parseWindowsProcessIdentity(stdout);
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Async on purpose: this runs on the TUI's render path (`/resume` lists every
|
|
174
|
+
* lock), where a synchronous spawn would freeze painting and keystrokes for
|
|
175
|
+
* the whole probe.
|
|
176
|
+
*/
|
|
177
|
+
function runPowerShell(exe, script) {
|
|
178
|
+
return new Promise(resolve => {
|
|
179
|
+
execFile(exe, ['-NoProfile', '-NonInteractive', '-Command', script], {
|
|
180
|
+
encoding: 'utf8',
|
|
181
|
+
timeout: 5_000,
|
|
182
|
+
windowsHide: true,
|
|
183
|
+
maxBuffer: 64 * 1024,
|
|
184
|
+
}, (error, stdout) => {
|
|
185
|
+
if (error !== null) {
|
|
186
|
+
resolve(undefined);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
resolve(typeof stdout === 'string' ? stdout : '');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async function windowsProcessIdentity(lock) {
|
|
194
|
+
const key = lockInstanceKey(lock);
|
|
195
|
+
const cached = windowsIdentityCache.get(lock.pid);
|
|
196
|
+
if (cached !== undefined && cached.lockKey === key && Date.now() - cached.at < WINDOWS_IDENTITY_TTL_MS) {
|
|
197
|
+
return cached.identity;
|
|
198
|
+
}
|
|
199
|
+
const identity = await queryWindowsProcess(lock.pid);
|
|
200
|
+
// Only successful probes are cached: a transient failure must not make the
|
|
201
|
+
// pid look permanently dead for the rest of this process's life.
|
|
202
|
+
if (identity === undefined) {
|
|
203
|
+
windowsIdentityCache.delete(lock.pid);
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
if (windowsIdentityCache.size > 64)
|
|
207
|
+
windowsIdentityCache.clear();
|
|
208
|
+
windowsIdentityCache.set(lock.pid, { identity, at: Date.now(), lockKey: key });
|
|
209
|
+
return identity;
|
|
210
|
+
}
|
|
211
|
+
/** Image name this Host runs as (`node` / `dsh`), without `.exe`. */
|
|
212
|
+
export function hostImageName(execPath = process.execPath) {
|
|
213
|
+
// Split on both separators: the Windows probe's answer is compared on any
|
|
214
|
+
// platform, and tests may feed a Windows-style path from POSIX.
|
|
215
|
+
const file = execPath.split(/[\\/]/u).pop() ?? execPath;
|
|
216
|
+
return file.replace(/\.exe$/iu, '').toLowerCase();
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Decide whether a live Windows pid can still be the lock's Host.
|
|
220
|
+
*
|
|
221
|
+
* Windows recycles pids aggressively, and without procfs an unrelated process
|
|
222
|
+
* inheriting the recorded pid used to look like a permanent live-but-silent
|
|
223
|
+
* Host ("zombie"), which blocked `--resume` until the lock was deleted by
|
|
224
|
+
* hand. Two facts rule reuse out:
|
|
225
|
+
* - the Host always runs this same executable, so a different image name is
|
|
226
|
+
* someone else's process;
|
|
227
|
+
* - the Host existed before it wrote the lock, so a process created after the
|
|
228
|
+
* lock was written cannot be its owner.
|
|
229
|
+
* An unverifiable process keeps the legacy best-effort answer (alive).
|
|
230
|
+
*/
|
|
231
|
+
export function windowsProcessMatchesLock(lock, identity, expectedName = hostImageName(), slackMs = PID_REUSE_SLACK_MS) {
|
|
232
|
+
if (identity === undefined)
|
|
233
|
+
return true;
|
|
234
|
+
const lockStarted = Date.parse(lock.startedAt);
|
|
235
|
+
if (identity.startedAt !== undefined && Number.isFinite(lockStarted)) {
|
|
236
|
+
// The Host existed before it wrote the lock, so a process created after
|
|
237
|
+
// that cannot be its owner. The timeline answers on its own, which also
|
|
238
|
+
// covers a Host launched by a different runtime (bun vs node) or a renamed
|
|
239
|
+
// executable: only a pid the OS recycled can post-date the lock.
|
|
240
|
+
return identity.startedAt <= lockStarted + slackMs;
|
|
241
|
+
}
|
|
242
|
+
// No comparable timeline: the image name is the only signal left, and a
|
|
243
|
+
// mismatch there is weak enough that "unverifiable" is the safer answer.
|
|
244
|
+
if (identity.name !== '' && expectedName !== '' && identity.name !== expectedName)
|
|
245
|
+
return false;
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
102
248
|
/**
|
|
103
249
|
* True when `pid` is genuinely the Host process that wrote `lock`.
|
|
104
250
|
*
|
|
@@ -113,21 +259,31 @@ function readProcCmdline(pid) {
|
|
|
113
259
|
* boot, so a recycled or cross-namespace pid fails the check;
|
|
114
260
|
* - older locks fall back to `/proc/<pid>/cmdline`: the detached Host is
|
|
115
261
|
* always launched with `--resume=<sessionId>` in argv, so any other
|
|
116
|
-
* process (kernel threads have an empty cmdline) is proven stale
|
|
117
|
-
*
|
|
262
|
+
* process (kernel threads have an empty cmdline) is proven stale;
|
|
263
|
+
* - Windows has neither: a `Get-Process` probe supplies the image name and
|
|
264
|
+
* creation time instead (see {@link windowsProcessMatchesLock}).
|
|
265
|
+
* On platforms where none of this is available the legacy kill(pid, 0)
|
|
266
|
+
* behavior is kept.
|
|
267
|
+
*
|
|
268
|
+
* Async because the Windows probe spawns PowerShell, and this runs on the
|
|
269
|
+
* render path (`/resume` inspects every lock); a synchronous spawn would
|
|
270
|
+
* freeze painting and keystrokes for the duration of the probe.
|
|
118
271
|
*/
|
|
119
|
-
export function lockOwnerIsAlive(lock) {
|
|
272
|
+
export async function lockOwnerIsAlive(lock) {
|
|
120
273
|
const pid = lock.pid;
|
|
121
274
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
122
275
|
return false;
|
|
123
276
|
if (!processIsAlive(pid))
|
|
124
277
|
return false;
|
|
278
|
+
if (process.platform === 'win32') {
|
|
279
|
+
return windowsProcessMatchesLock(lock, await windowsProcessIdentity(lock));
|
|
280
|
+
}
|
|
125
281
|
if (lock.bootId !== undefined && lock.pidStart !== undefined) {
|
|
126
282
|
return readBootId() === lock.bootId && readProcStarttime(pid) === lock.pidStart;
|
|
127
283
|
}
|
|
128
284
|
const cmdline = readProcCmdline(pid);
|
|
129
285
|
if (cmdline === undefined)
|
|
130
|
-
return true; // no /proc (
|
|
286
|
+
return true; // no /proc (darwin): legacy best-effort
|
|
131
287
|
return cmdline.includes(`--resume=${lock.sessionId}`);
|
|
132
288
|
}
|
|
133
289
|
export function formatLockHeldMessage(lock) {
|
|
@@ -137,7 +293,7 @@ export function formatLockHeldMessage(lock) {
|
|
|
137
293
|
export function sessionLockDisabled(env = process.env) {
|
|
138
294
|
return env.DSH_TUI_NO_SESSION_LOCK === '1' || env.DSH_TUI_NO_SESSION_LOCK === 'true';
|
|
139
295
|
}
|
|
140
|
-
export async function readSessionLock(sessionId, dshHome =
|
|
296
|
+
export async function readSessionLock(sessionId, dshHome = resolveDshHome()) {
|
|
141
297
|
const path = sessionLockPath(sessionId, dshHome);
|
|
142
298
|
try {
|
|
143
299
|
const info = parseSessionLock(await readFile(path, 'utf8'));
|
|
@@ -154,7 +310,7 @@ export async function writeSessionLock(path, info) {
|
|
|
154
310
|
await writeFile(path, `${JSON.stringify(info, null, 2)}\n`, { mode: 0o600 });
|
|
155
311
|
}
|
|
156
312
|
export async function acquireSessionLock(sessionId, options = {}) {
|
|
157
|
-
const dshHome = options.dshHome ??
|
|
313
|
+
const dshHome = options.dshHome ?? resolveDshHome();
|
|
158
314
|
const path = sessionLockPath(sessionId, dshHome);
|
|
159
315
|
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
160
316
|
const pid = options.pid ?? process.pid;
|
|
@@ -189,7 +345,7 @@ export async function acquireSessionLock(sessionId, options = {}) {
|
|
|
189
345
|
existing = undefined;
|
|
190
346
|
}
|
|
191
347
|
const ours = options.pid ?? process.pid;
|
|
192
|
-
if (existing !== undefined && existing.pid !== ours && lockOwnerIsAlive(existing)) {
|
|
348
|
+
if (existing !== undefined && existing.pid !== ours && await lockOwnerIsAlive(existing)) {
|
|
193
349
|
throw new SessionLockHeldError(existing, path);
|
|
194
350
|
}
|
|
195
351
|
try {
|
|
@@ -213,7 +369,7 @@ export async function releaseSessionLock(path, pid = process.pid) {
|
|
|
213
369
|
// Missing lock is fine.
|
|
214
370
|
}
|
|
215
371
|
}
|
|
216
|
-
export async function inspectLiveHost(sessionId, dshHome =
|
|
372
|
+
export async function inspectLiveHost(sessionId, dshHome = resolveDshHome()) {
|
|
217
373
|
const held = await readSessionLock(sessionId, dshHome);
|
|
218
374
|
if (held === undefined)
|
|
219
375
|
return undefined;
|
|
@@ -221,19 +377,19 @@ export async function inspectLiveHost(sessionId, dshHome = process.env.DSH_HOME
|
|
|
221
377
|
}
|
|
222
378
|
async function inspectHeldLock(path, info, dshHome) {
|
|
223
379
|
const sock = info.sock ?? sessionSockPath(info.sessionId, dshHome);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
catch {
|
|
231
|
-
sockExists = false;
|
|
232
|
-
}
|
|
380
|
+
// A Windows named pipe is not a filesystem entry: fs.access() can never see
|
|
381
|
+
// it, so liveness must be probed with a connect (and it needs no unlink —
|
|
382
|
+
// Windows removes the pipe when the owning process exits). A reachable pipe
|
|
383
|
+
// also proves the owner is alive, so the pid identity probe can be skipped.
|
|
384
|
+
const sockExists = await displaySockExists(sock);
|
|
385
|
+
const alive = (isPipePath(sock) && sockExists) || await lockOwnerIsAlive(info);
|
|
233
386
|
if (!alive) {
|
|
234
387
|
// Host is gone. A leftover unix socket is not attachable — steal the
|
|
235
|
-
// lock so --resume can reopen from the session log
|
|
236
|
-
|
|
388
|
+
// lock so --resume can reopen from the session log, and remove the dead
|
|
389
|
+
// directory entry: the reachability probe cannot report it as ready, so
|
|
390
|
+
// it is cleaned by path (a Windows pipe is not a file entry and is
|
|
391
|
+
// already reclaimed by the OS).
|
|
392
|
+
if (!isPipePath(sock)) {
|
|
237
393
|
try {
|
|
238
394
|
await unlink(sock);
|
|
239
395
|
}
|
|
@@ -254,7 +410,7 @@ async function inspectHeldLock(path, info, dshHome) {
|
|
|
254
410
|
return { kind: 'attachable', lock: info, path, sock };
|
|
255
411
|
}
|
|
256
412
|
/** Every lock file under `$DSH_HOME/tui-locks` whose Host pid is still alive. */
|
|
257
|
-
export async function listAttachableHosts(dshHome =
|
|
413
|
+
export async function listAttachableHosts(dshHome = resolveDshHome()) {
|
|
258
414
|
let names = [];
|
|
259
415
|
try {
|
|
260
416
|
names = await readdir(join(dshHome, 'tui-locks'));
|
package/lib/session-lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-lock.js","sourceRoot":"","sources":["../src/session-lock.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-lock.js","sourceRoot":"","sources":["../src/session-lock.ts"],"names":[],"mappings":"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"}
|
package/lib/tui.js
CHANGED
|
@@ -25,12 +25,12 @@ import { StringDecoder } from 'node:string_decoder';
|
|
|
25
25
|
import { credentialRef } from '@deepseek-ai/dsh-credentials';
|
|
26
26
|
import { createUserMessage, errorChain, ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
27
27
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
28
|
-
import { commandAcceptsAttachments,
|
|
28
|
+
import { commandAcceptsAttachments, forEachSessionEventAsync, isAssistantStreamEvent, isTokenDeltaChunk, listenHostEvent, REPLAY_YIELD_EVERY, sessionEventType, sessionEvents, settingsNamespace, streamChunkOf, streamFirstTokenTime, streamFrameAttemptId, streamFrameOwner, } from './dsh-compat.js';
|
|
29
29
|
import { classifyApprovalDetailed, commandForApprovalRequest, isApprovalStatusArg, parseAutoApprovalMode } from './auto-approval.js';
|
|
30
30
|
import { buildReviewUserMessage, parseReviewOutput, reviewSystemPrompt } from './approval-reviewer.js';
|
|
31
31
|
import { loadProviderCatalog, mergeProviderEntries } from './provider-catalog.js';
|
|
32
32
|
import { formatFooterCwd, formatSessionTime, listResumableSessions } from './session-list.js';
|
|
33
|
-
import { detachFromSshSession, DisplayHost, sessionSockPath } from './display-sock.js';
|
|
33
|
+
import { detachFromSshSession, DisplayHost, resolveDshHome, sessionSockPath } from './display-sock.js';
|
|
34
34
|
import { applySavedLocale, getLocale, localeDisplayName, localeFromTag, setLocale, t, UI_LOCALE_NAMESPACE, } from './i18n/index.js';
|
|
35
35
|
import { defaultReasoningEffort } from './reasoning.js';
|
|
36
36
|
import { checkForPluginUpdate, installPluginLatest } from './update-check.js';
|
|
@@ -47,10 +47,10 @@ import { crossedQuotaThresholds, DEEPSEEK_PUBLIC_BASE_URL, formatAccountBalance,
|
|
|
47
47
|
import { appendSubagentLog, applyTurnEndToPlan, cardCategoryLabel, cardCategoryOf, compactionHeaderText, formatCompactCommandError, isPromptInjectionMessage, matchTranscriptRows, parseFindQuery, parsePlanTodos, planCloseNudgeText, planMarkdownFromArgs, planDockNote, planIsLive, planTitleFromMarkdown, promptInjectionSources, promptInjectionTitle, subagentHeaderText, todoItemKind, todoProgressLabel, TODO_STATUS_MARK, } from './plan.js';
|
|
48
48
|
import { buildToolHeader, canMergeToolCall, compactEditPath, compactToolBursts, countDiffAddDel, countDiffLines, countOutputLines, diffMetaDiffs, diffStatToken, formatModelList, HIDDEN_TOOL_NAMES, parseExitStatus, planReviewOf, presentToolCall, READ_TOOL_NAMES, SHELL_TOOL_NAMES, toolBodyFitsWorkspace, toolBodyLines, toolTitle, TOOL_FLIP_MS, wrappedToolBodyLineCount, } from './tool-present.js';
|
|
49
49
|
export { clipAnsiToWidth, cursorVisualPosition, displayWidth, foldInputView, hrefAtColumn, osc52Clipboard, osc8Enabled, paintedLinkHits, fmtElapsedCompact, padAnsiToWidth, padToWidth, renderMarkdownLines, repeatToWidth, shimmerText, truncateToWidth, visibleWidth, waitCardCopy, waitSummaryFromReasoning, wrapWaitDetails, } from './term-text.js';
|
|
50
|
-
export { captureHangupSignals, composePaintOutput, detectSshSession, formatLinkQualityChip, ignoreFurtherHangupSignals, isEscapePrefix, isHangupErrno, linkQualityOf, linkSignalPips, paintIntervalForRtt, paintLinkLabel, parseCursorPositionReply, pickerWindowStart, probeTerminalRttMs, releaseHangupSignals, resolvePaintIntervalMs, waitUntilIdleOrTimeout, writeBootSplash, } from './paint.js';
|
|
51
|
-
export { CONTEXT_IDLE_COMPACT_RATIO, CONTEXT_PRESSURE_DANGER_RATIO, CONTEXT_PRESSURE_WARN_RATIO, CONTEXT_RING_EMPTY, CONTEXT_RING_SEGMENTS, contextPressureAlertText, contextPressureRingColor, contextPressureUsedTokens, contextPressureView, describeProviderRoute, dropFooterQuotaPlanName, fitFooterStatsLine, fitFooterStatusLine, footerActivity, footerIdentityParts, footerStatsGroups, formatContextPressureChip, formatContextPressureRing, formatContextPressureStatusLine, formatDuration, formatFooterQuota, formatQuotaBar, formatStatusReport, formatTokens, formatTokensPerSecond, parseContextPressure, promptPressureTokens, providerShortCode, providerUsesLocalOAuth, shouldIdleAutoCompact, } from './footer.js';
|
|
50
|
+
export { captureHangupSignals, composePaintOutput, detectSshSession, formatLinkQualityChip, ignoreFurtherHangupSignals, isEscapePrefix, findCursorPositionReply, isHangupErrno, linkQualityOf, linkSignalPips, paintIntervalForRtt, paintLinkLabel, parseCursorPositionReply, pickerWindowStart, probeTerminalRttMs, releaseHangupSignals, resolvePaintIntervalMs, waitUntilIdleOrTimeout, writeBootSplash, } from './paint.js';
|
|
51
|
+
export { CONTEXT_IDLE_COMPACT_RATIO, CONTEXT_PRESSURE_DANGER_RATIO, CONTEXT_PRESSURE_WARN_RATIO, CONTEXT_RING_EMPTY, CONTEXT_RING_SEGMENTS, contextPressureAlertText, contextPressureRingColor, contextPressureUsedTokens, contextPressureView, describeProviderRoute, dropFooterQuotaPlanName, fitFooterStatsLine, fitFooterStatusLine, footerActivity, footerIdentityParts, footerStatsGroups, formatContextPressureChip, formatContextPressureRing, formatContextPressureStatusLine, formatDuration, formatFooterQuota, formatQuotaBar, formatStatusReport, formatTokens, formatTokensPerSecond, parseContextPressure, promptPressureTokens, providerShortCode, providerUsesLocalOAuth, shouldIdleAutoCompact, subagentRouteLabel, } from './footer.js';
|
|
52
52
|
export { crossedQuotaThresholds, formatAccountBalance, formatFooterBalance, formatOpenCodeGoUsage, formatQuotaSnapshot, formatQuotaStatusLine, joinUrl, openCodeSourceFor, parseDeepSeekBalance, parseOpenAiCompatibleBalance, parseOpenCodeGoQuota, parseSuperGrokBilling, quotaAlertText, quotaRefreshEverySteps, quotaRefreshEveryTurns, remainingPercentFromUsed, tightestQuotaWindow, } from './quota.js';
|
|
53
|
-
export { commandAcceptsAttachments, forEachSessionEvent, isAssistantStreamEvent, listPersistenceHeaders, inspectPersistenceSession, sessionEventType, sessionEvents, settingsNamespace, streamChunkOf, } from './dsh-compat.js';
|
|
53
|
+
export { commandAcceptsAttachments, forEachSessionEvent, isAssistantStreamEvent, isTokenDeltaChunk, listPersistenceHeaders, inspectPersistenceSession, sessionEventType, sessionEvents, settingsNamespace, streamChunkOf, streamFirstTokenTime, streamFrameAttemptId, streamFrameOwner, } from './dsh-compat.js';
|
|
54
54
|
export { applyTurnEndToPlan, askSummary, cardCategoryOf, compactionHeaderText, formatCompactCommandError, isPromptInjectionMessage, matchTranscriptRows, parseFindQuery, parsePlanTodos, planCloseNudgeText, planDockNote, planIsLive, planTitleFromMarkdown, planTurnLeftOpen, promptInjectionSources, promptInjectionTitle, subagentHeaderText, todoProgressLabel, todoSummary, } from './plan.js';
|
|
55
55
|
export { buildToolHeader, canMergeToolCall, compactEditPath, compactToolBursts, compactToolGroups, countDiffAddDel, countDiffLines, countOutputLines, diffMetaDiffs, diffStatToken, friendlyJsonLines, parseExitStatus, presentToolCall, READ_TOOL_NAMES, renderToolDiff, toolBodyFitsWorkspace, toolBodyLines, toolStateColor, toolStateLabel, wrappedToolBodyLineCount, } from './tool-present.js';
|
|
56
56
|
function discoverProviderModels(llm, request, signal) {
|
|
@@ -146,7 +146,7 @@ const RESERVED_BOTTOM_LINES = 3; // input line + stats line + status line
|
|
|
146
146
|
const MAX_TRANSCRIPT_ROWS = 5000;
|
|
147
147
|
const IS_WINDOWS = process.platform === 'win32';
|
|
148
148
|
function dshHomeDir() {
|
|
149
|
-
return
|
|
149
|
+
return resolveDshHome();
|
|
150
150
|
}
|
|
151
151
|
function displayDshPath(file) {
|
|
152
152
|
const home = dshHomeDir();
|
|
@@ -446,6 +446,12 @@ export class SshTui {
|
|
|
446
446
|
usage: { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 },
|
|
447
447
|
};
|
|
448
448
|
openStepStats;
|
|
449
|
+
/** Attempt whose live `start` frame opened the current token stream. */
|
|
450
|
+
liveStreamOwner;
|
|
451
|
+
/** Live events parked while the (yielding) history replay holds the floor. */
|
|
452
|
+
replayQueue;
|
|
453
|
+
/** A relay claimed the display while a hangup was still cancelling/flushing. */
|
|
454
|
+
reattachedDuringHangup = false;
|
|
449
455
|
pendingToolTimes = new Map();
|
|
450
456
|
usageByStep = new Map();
|
|
451
457
|
lastStatsTurn = null;
|
|
@@ -871,16 +877,29 @@ export class SshTui {
|
|
|
871
877
|
this.paintIntervalMs = resolvePaintIntervalMs(undefined, {}, { ssh: true, rttMs: rtt });
|
|
872
878
|
this.markDirty();
|
|
873
879
|
}
|
|
874
|
-
/**
|
|
875
|
-
|
|
880
|
+
/**
|
|
881
|
+
* Replay the durable session log so a resumed session renders its history.
|
|
882
|
+
* Chunked on purpose: a synchronous walk of a long log froze the TUI on the
|
|
883
|
+
* pre-replay frame, so the relay's RTT frame could not be applied and the
|
|
884
|
+
* footer sat on `SSH ○○○○` for the whole load.
|
|
885
|
+
*/
|
|
886
|
+
async replayHistory() {
|
|
887
|
+
const parked = [];
|
|
888
|
+
this.replayQueue = parked;
|
|
876
889
|
this.replaying = true;
|
|
877
890
|
try {
|
|
878
|
-
|
|
879
|
-
this.
|
|
880
|
-
});
|
|
891
|
+
await forEachSessionEventAsync(this.agent.session, (event) => {
|
|
892
|
+
this.applySessionEvent(this.agent.session, event);
|
|
893
|
+
}, REPLAY_YIELD_EVERY, () => this.disposed);
|
|
881
894
|
}
|
|
882
895
|
finally {
|
|
883
896
|
this.replaying = false;
|
|
897
|
+
this.replayQueue = undefined;
|
|
898
|
+
}
|
|
899
|
+
for (const item of parked) {
|
|
900
|
+
if (this.disposed)
|
|
901
|
+
return;
|
|
902
|
+
this.applySessionEvent(item.session, item.event);
|
|
884
903
|
}
|
|
885
904
|
this.streaming = undefined;
|
|
886
905
|
this.streamingReasoning = undefined;
|
|
@@ -1151,6 +1170,7 @@ export class SshTui {
|
|
|
1151
1170
|
if (this.hangingUp || this.disposed)
|
|
1152
1171
|
return;
|
|
1153
1172
|
this.hangingUp = true;
|
|
1173
|
+
this.reattachedDuringHangup = false;
|
|
1154
1174
|
ignoreFurtherHangupSignals();
|
|
1155
1175
|
this.detachDisplay();
|
|
1156
1176
|
const busy = this.isBusyForHangupKeepalive();
|
|
@@ -1165,6 +1185,17 @@ export class SshTui {
|
|
|
1165
1185
|
await waitUntilIdleOrTimeout(() => this.agent.status !== 'running', HANGUP_CANCEL_TIMEOUT_MS);
|
|
1166
1186
|
}
|
|
1167
1187
|
await this.flushSession();
|
|
1188
|
+
// A relay can reattach while the cancel/flush above was in flight — the
|
|
1189
|
+
// common case is a user reconnecting the moment the link drops. Deciding
|
|
1190
|
+
// from the snapshot taken at the start would dispose (or exit) the Host
|
|
1191
|
+
// under the display the user just got back, and the launcher would report
|
|
1192
|
+
// `write EPIPE` for an attach that had already succeeded.
|
|
1193
|
+
if (this.reattachedDuringHangup) {
|
|
1194
|
+
this.reattachedDuringHangup = false;
|
|
1195
|
+
this.hangingUp = false;
|
|
1196
|
+
this.clearDetachedIdleTimer();
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1168
1199
|
const keepHost = this.displayHost !== undefined && busy;
|
|
1169
1200
|
if (keepHost) {
|
|
1170
1201
|
this.hangingUp = false;
|
|
@@ -1327,6 +1358,12 @@ export class SshTui {
|
|
|
1327
1358
|
}
|
|
1328
1359
|
/** Re-open DECSET and start painting to an attached Display relay. */
|
|
1329
1360
|
attachRelayDisplay() {
|
|
1361
|
+
// A relay that HELLOs while a hangup is still unwinding must be honored by
|
|
1362
|
+
// that hangup: the snapshot taken at the drop would otherwise dispose (or
|
|
1363
|
+
// exit) the Host under the display the user just got back, and the
|
|
1364
|
+
// launcher reports `write EPIPE` for an attach that had already succeeded.
|
|
1365
|
+
if (this.hangingUp)
|
|
1366
|
+
this.reattachedDuringHangup = true;
|
|
1330
1367
|
this.displayDetached = false;
|
|
1331
1368
|
this.hangingUp = false;
|
|
1332
1369
|
this.clearDetachedIdleTimer();
|
|
@@ -2589,7 +2626,8 @@ export class SshTui {
|
|
|
2589
2626
|
provider,
|
|
2590
2627
|
parentModel,
|
|
2591
2628
|
subModel: sub.model,
|
|
2592
|
-
|
|
2629
|
+
...(sub.provider === undefined ? {} : { subProvider: sub.provider }),
|
|
2630
|
+
...(sub.reasoningEffort === undefined ? {} : { subEffort: String(sub.reasoningEffort) }),
|
|
2593
2631
|
...(quotaWindow === undefined || this.quotaSnapshot === undefined || this.quotaSnapshot.provider !== provider
|
|
2594
2632
|
? {}
|
|
2595
2633
|
: { quotaCode: this.quotaSnapshot.plan, quotaPercent: quotaWindow.remainingPercent }),
|
|
@@ -2879,20 +2917,20 @@ export class SshTui {
|
|
|
2879
2917
|
* row. 0.1.2 hosts append `assistant/chunk`; 0.1.5 emits the same chunk
|
|
2880
2918
|
* on `agent/assistant-stream` and never writes it to the log.
|
|
2881
2919
|
*/
|
|
2882
|
-
applyStreamChunk(streamed) {
|
|
2920
|
+
applyStreamChunk(streamed, statsOnly = false) {
|
|
2883
2921
|
const { chunk } = streamed;
|
|
2884
2922
|
const open = this.openStepStats;
|
|
2885
2923
|
if (open !== null && open !== undefined
|
|
2886
2924
|
&& open.turn === streamed.turn && open.step === streamed.step) {
|
|
2887
|
-
if (open.firstTokenTime === null
|
|
2888
|
-
&& chunk.type === 'text-delta'
|
|
2889
|
-
&& chunk.text !== '') {
|
|
2925
|
+
if (open.firstTokenTime === null && isTokenDeltaChunk(chunk)) {
|
|
2890
2926
|
this.openStepStats = { ...open, firstTokenTime: streamed.time };
|
|
2891
2927
|
}
|
|
2892
2928
|
}
|
|
2893
|
-
if (chunk.type === 'usage' && chunk.usage !== undefined) {
|
|
2929
|
+
if (chunk.type === 'usage' && chunk.usage !== undefined && streamed.stepKnown) {
|
|
2894
2930
|
this.recordUsage(streamed.turn, streamed.step, chunk.usage);
|
|
2895
2931
|
}
|
|
2932
|
+
if (statsOnly)
|
|
2933
|
+
return;
|
|
2896
2934
|
if (chunk.type === 'text-delta') {
|
|
2897
2935
|
this.streaming ??= { text: '', reasoning: '' };
|
|
2898
2936
|
this.streaming.text += chunk.text ?? '';
|
|
@@ -2924,7 +2962,23 @@ export class SshTui {
|
|
|
2924
2962
|
return;
|
|
2925
2963
|
this.lastActivity = Date.now();
|
|
2926
2964
|
this.refreshContextPressure();
|
|
2927
|
-
const
|
|
2965
|
+
const owner = streamFrameOwner(payload.frame);
|
|
2966
|
+
if (owner !== undefined) {
|
|
2967
|
+
// Live chunk frames carry no turn/step: remember the attempt's step here
|
|
2968
|
+
// or every chunk is attributed to step 0 and the stats never match.
|
|
2969
|
+
this.liveStreamOwner = owner;
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2972
|
+
if (payload.frame?.type === 'end') {
|
|
2973
|
+
this.liveStreamOwner = undefined;
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
const attemptId = streamFrameAttemptId(payload.frame);
|
|
2977
|
+
const current = this.liveStreamOwner;
|
|
2978
|
+
const fallback = current !== undefined && (attemptId === undefined || attemptId === current.attemptId)
|
|
2979
|
+
? current
|
|
2980
|
+
: this.openStepStats;
|
|
2981
|
+
const streamed = streamChunkOf(payload.frame, fallback);
|
|
2928
2982
|
if (streamed !== undefined)
|
|
2929
2983
|
this.applyStreamChunk(streamed);
|
|
2930
2984
|
};
|
|
@@ -2953,14 +3007,30 @@ export class SshTui {
|
|
|
2953
3007
|
};
|
|
2954
3008
|
};
|
|
2955
3009
|
handleSessionEvent = (session, event) => {
|
|
3010
|
+
if (this.replayQueue !== undefined) {
|
|
3011
|
+
// The replay yields between chunks, so live events can arrive mid-load.
|
|
3012
|
+
// Folding them now would interleave newer events under older history;
|
|
3013
|
+
// park them and drain in arrival order once the walk is done.
|
|
3014
|
+
this.replayQueue.push({ session, event });
|
|
3015
|
+
return;
|
|
3016
|
+
}
|
|
3017
|
+
this.applySessionEvent(session, event);
|
|
3018
|
+
};
|
|
3019
|
+
applySessionEvent(session, event) {
|
|
2956
3020
|
if (session.id !== this.agent.id) {
|
|
2957
3021
|
if (this.subagentSessions.has(session.id))
|
|
2958
3022
|
this.handleSubagentSessionEvent(session.id, event);
|
|
2959
3023
|
return;
|
|
2960
3024
|
}
|
|
2961
3025
|
this.lastActivity = Date.now();
|
|
2962
|
-
if (this.replaying && isAssistantStreamEvent(event))
|
|
3026
|
+
if (this.replaying && isAssistantStreamEvent(event)) {
|
|
3027
|
+
// Replay skips the in-progress row, but durable chunks still carry the
|
|
3028
|
+
// timing the footer needs: a resumed session must keep TTFT and tok/s.
|
|
3029
|
+
const streamed = streamChunkOf(event);
|
|
3030
|
+
if (streamed !== undefined)
|
|
3031
|
+
this.applyStreamChunk(streamed, true);
|
|
2963
3032
|
return;
|
|
3033
|
+
}
|
|
2964
3034
|
if (!this.replaying)
|
|
2965
3035
|
this.refreshContextPressure();
|
|
2966
3036
|
const eventType = sessionEventType(event);
|
|
@@ -3021,12 +3091,19 @@ export class SshTui {
|
|
|
3021
3091
|
const open = this.openStepStats;
|
|
3022
3092
|
if (open !== undefined && open.turn === event.data.turn && open.step === event.data.step) {
|
|
3023
3093
|
this.stats.llmMs += Math.max(0, event.time - open.startTime);
|
|
3024
|
-
|
|
3025
|
-
|
|
3094
|
+
// The settlement's own packed stream is authoritative: a retried
|
|
3095
|
+
// step keeps the failed attempt's first token in the live latch, and
|
|
3096
|
+
// spanning both attempts reported a rate ~20x off. 0.1.2 has no
|
|
3097
|
+
// `stream` and still relies on the replayed `assistant/chunk` events
|
|
3098
|
+
// (or the live latch) instead.
|
|
3099
|
+
const firstTokenTime = streamFirstTokenTime(event.data.stream)
|
|
3100
|
+
?? open.firstTokenTime;
|
|
3101
|
+
if (firstTokenTime !== null && firstTokenTime !== undefined && Number.isFinite(firstTokenTime)) {
|
|
3102
|
+
this.stats.ttftMs += Math.max(0, firstTokenTime - open.startTime);
|
|
3026
3103
|
this.stats.ttftSteps += 1;
|
|
3027
3104
|
const outputTokens = event.data.usage?.outputTokens;
|
|
3028
3105
|
if (typeof outputTokens === 'number' && Number.isFinite(outputTokens) && outputTokens >= 0) {
|
|
3029
|
-
this.stats.decodeMs += Math.max(0, event.time -
|
|
3106
|
+
this.stats.decodeMs += Math.max(0, event.time - firstTokenTime);
|
|
3030
3107
|
this.stats.decodeTokens += outputTokens;
|
|
3031
3108
|
}
|
|
3032
3109
|
}
|
|
@@ -3256,7 +3333,7 @@ export class SshTui {
|
|
|
3256
3333
|
this.handleExtensionEvent(event);
|
|
3257
3334
|
break;
|
|
3258
3335
|
}
|
|
3259
|
-
}
|
|
3336
|
+
}
|
|
3260
3337
|
handleStatus = ({ agent, status }) => {
|
|
3261
3338
|
if (agent !== this.agent)
|
|
3262
3339
|
return;
|
|
@@ -7150,7 +7227,9 @@ export function mountTui(ctx, config) {
|
|
|
7150
7227
|
stopWaiting();
|
|
7151
7228
|
controller = new SshTui(ctx, agent, config);
|
|
7152
7229
|
controller.start();
|
|
7153
|
-
|
|
7230
|
+
// Not awaited: the first frames paint while the (chunked) replay fills the
|
|
7231
|
+
// transcript, and relay RTT/resize frames keep flowing during the load.
|
|
7232
|
+
void controller.replayHistory();
|
|
7154
7233
|
};
|
|
7155
7234
|
const fail = (failedSessionId, error) => {
|
|
7156
7235
|
if (settled || failedSessionId !== sessionId)
|