dsh-ssh-tui 0.3.2 → 0.3.4
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 +34 -17
- package/README.md +21 -13
- package/docs/screenshots/slow-link.gif +0 -0
- package/lib/tui.js +616 -74
- package/lib/tui.js.map +1 -1
- package/lib/types/tui.d.ts +93 -6
- package/package.json +4 -2
package/lib/types/tui.d.ts
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* The renderer uses plain ANSI and coalesces each frame into one stdout
|
|
9
9
|
* write of dirty rows only — jump-host / proxied SSH should see one packet
|
|
10
|
-
* per paint, not one per line. Cadence is DSH_TUI_PAINT_MS
|
|
10
|
+
* per paint, not one per line. Cadence is DSH_TUI_PAINT_MS, else local 80 ms
|
|
11
|
+
* or an SSH tier from a CSI 6n round-trip (default 160 ms).
|
|
11
12
|
*/
|
|
12
13
|
import type { Agent, ModelSelection, ModelSelectionRef } from '@deepseek-ai/dsh-agent';
|
|
13
14
|
import type { Context } from '@deepseek-ai/cordis';
|
|
@@ -142,6 +143,17 @@ type Row = {
|
|
|
142
143
|
phase: 'active' | 'paused' | 'blocked' | 'complete' | 'cleared';
|
|
143
144
|
blockedReason?: string;
|
|
144
145
|
expanded: boolean;
|
|
146
|
+
} | {
|
|
147
|
+
kind: 'compaction';
|
|
148
|
+
compactionId: string;
|
|
149
|
+
status: 'running' | 'ok' | 'error';
|
|
150
|
+
startedAt: number;
|
|
151
|
+
endedAt?: number;
|
|
152
|
+
pruneCount: number;
|
|
153
|
+
prunedTokens: number;
|
|
154
|
+
summary?: string;
|
|
155
|
+
error?: string;
|
|
156
|
+
expanded: boolean;
|
|
145
157
|
} | {
|
|
146
158
|
kind: 'system';
|
|
147
159
|
text: string;
|
|
@@ -160,11 +172,21 @@ interface ToolDiffHunk {
|
|
|
160
172
|
export interface TuiController {
|
|
161
173
|
dispose(): Promise<void>;
|
|
162
174
|
}
|
|
175
|
+
export type PaintLinkKind = 'local' | 'ssh';
|
|
163
176
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
177
|
+
* Explicit env/config always wins. Otherwise local TTYs stay snappy and SSH
|
|
178
|
+
* sessions pick a tier from a measured round-trip (CSI 6n), falling back to
|
|
179
|
+
* 160 ms when the probe is missing.
|
|
166
180
|
*/
|
|
167
|
-
export declare function resolvePaintIntervalMs(configured?: number, env?: NodeJS.ProcessEnv
|
|
181
|
+
export declare function resolvePaintIntervalMs(configured?: number, env?: NodeJS.ProcessEnv, options?: {
|
|
182
|
+
ssh?: boolean;
|
|
183
|
+
rttMs?: number;
|
|
184
|
+
}): number;
|
|
185
|
+
/** True when this process is attached to an SSH session (jump host / proxy). */
|
|
186
|
+
export declare function detectSshSession(env?: NodeJS.ProcessEnv): boolean;
|
|
187
|
+
/** Map a CSI-6n round-trip to a paint cadence. Unknown RTT uses the SSH default. */
|
|
188
|
+
export declare function paintIntervalForRtt(rttMs: number | undefined): number;
|
|
189
|
+
export declare function paintLinkLabel(kind: PaintLinkKind, intervalMs: number, probed: boolean): string;
|
|
168
190
|
/** One incremental paint as a single stdout write (one SSH packet when corked). */
|
|
169
191
|
export declare function composePaintOutput(options: {
|
|
170
192
|
width: number;
|
|
@@ -250,10 +272,50 @@ export interface OpenCodeSource {
|
|
|
250
272
|
* routes are recognized by their `opencode.ai` base URL.
|
|
251
273
|
*/
|
|
252
274
|
export declare function openCodeSourceFor(provider: string, llmPiAiSection: unknown): OpenCodeSource | null;
|
|
275
|
+
export type QuotaPeriod = 'hourly' | 'weekly' | 'monthly' | 'unknown';
|
|
276
|
+
export interface QuotaWindow {
|
|
277
|
+
label: string;
|
|
278
|
+
period: QuotaPeriod;
|
|
279
|
+
/** Remaining percent of the window (100 = unused). */
|
|
280
|
+
remainingPercent: number;
|
|
281
|
+
resetsAt?: string;
|
|
282
|
+
}
|
|
283
|
+
export interface QuotaSnapshot {
|
|
284
|
+
provider: string;
|
|
285
|
+
plan: string;
|
|
286
|
+
windows: QuotaWindow[];
|
|
287
|
+
}
|
|
288
|
+
export declare function remainingPercentFromUsed(usedPercent: number): number;
|
|
289
|
+
/** Cross a remaining-percent threshold from above (50 / 25 / 10 / 5). */
|
|
290
|
+
export declare function crossedQuotaThresholds(previousRemaining: number | undefined, remaining: number): number[];
|
|
291
|
+
export declare function quotaAlertText(snapshot: QuotaSnapshot, window: QuotaWindow): string;
|
|
292
|
+
/**
|
|
293
|
+
* How often to re-fetch quota, based on the tightest window.
|
|
294
|
+
* Hourly/5h: every 10 turns, every 4 when near a threshold.
|
|
295
|
+
* Weekly: every 50 turns, every 10 when near.
|
|
296
|
+
* Monthly: every 80 turns, every 20 when near.
|
|
297
|
+
*/
|
|
298
|
+
export declare function quotaRefreshEveryTurns(window: QuotaWindow | undefined): number;
|
|
299
|
+
export declare function parseSuperGrokBilling(payload: unknown): QuotaSnapshot;
|
|
300
|
+
export declare function parseOpenCodeGoQuota(payload: unknown, provider: string): QuotaSnapshot;
|
|
301
|
+
export declare function formatQuotaSnapshot(snapshot: QuotaSnapshot): string;
|
|
302
|
+
/** Tightest remaining window — used for threshold alerts. */
|
|
303
|
+
export declare function tightestQuotaWindow(snapshot: QuotaSnapshot): QuotaWindow | undefined;
|
|
253
304
|
/** Render the OpenCode Go quota payload as a transcript block. */
|
|
254
305
|
export declare function formatOpenCodeGoUsage(payload: unknown, source: OpenCodeSource): string;
|
|
255
306
|
/** Whether `text` could still grow into a recognized escape sequence. */
|
|
256
307
|
export declare function isEscapePrefix(text: string): boolean;
|
|
308
|
+
/** Parse a Device Status Report cursor reply (`CSI row;col R`). */
|
|
309
|
+
export declare function parseCursorPositionReply(text: string): {
|
|
310
|
+
row: number;
|
|
311
|
+
column: number;
|
|
312
|
+
} | undefined;
|
|
313
|
+
/**
|
|
314
|
+
* Round-trip to the attached terminal via CSI 6n. Returns undefined when the
|
|
315
|
+
* reply never arrives (dumb pipe, blocked DSR). Does not interpret the
|
|
316
|
+
* coordinates — only the elapsed milliseconds matter.
|
|
317
|
+
*/
|
|
318
|
+
export declare function probeTerminalRttMs(stdin?: NodeJS.ReadStream, stdout?: NodeJS.WriteStream, timeoutMs?: number): Promise<number | undefined>;
|
|
257
319
|
/** True while a plan still belongs in the dock (latest incomplete work). */
|
|
258
320
|
export declare function planIsLive(plan: {
|
|
259
321
|
active: boolean;
|
|
@@ -285,6 +347,12 @@ export declare function parseFindQuery(raw: string): {
|
|
|
285
347
|
category?: CardCategory;
|
|
286
348
|
query: string;
|
|
287
349
|
};
|
|
350
|
+
export declare function compactionHeaderText(row: {
|
|
351
|
+
status: 'running' | 'ok' | 'error';
|
|
352
|
+
pruneCount: number;
|
|
353
|
+
prunedTokens: number;
|
|
354
|
+
error?: string;
|
|
355
|
+
}): string;
|
|
288
356
|
/** Transcript rows matching a `/find` query, newest last. */
|
|
289
357
|
export declare function matchTranscriptRows(rows: readonly Row[], raw: string): Row[];
|
|
290
358
|
/** One-line note under an expanded plan strip. */
|
|
@@ -423,7 +491,15 @@ export declare class SshTui {
|
|
|
423
491
|
private lastChromeKey;
|
|
424
492
|
private lastPaintWidth;
|
|
425
493
|
private lastPaintHeight;
|
|
426
|
-
private
|
|
494
|
+
private paintIntervalMs;
|
|
495
|
+
private paintLink;
|
|
496
|
+
private paintProbed;
|
|
497
|
+
private sessionTitle;
|
|
498
|
+
private llmRetry;
|
|
499
|
+
private quotaSnapshot;
|
|
500
|
+
private quotaAlerted;
|
|
501
|
+
private quotaTurnsSinceRefresh;
|
|
502
|
+
private quotaRefreshInFlight;
|
|
427
503
|
private searchHits;
|
|
428
504
|
private searchIndex;
|
|
429
505
|
private searchQuery;
|
|
@@ -432,6 +508,8 @@ export declare class SshTui {
|
|
|
432
508
|
constructor(ctx: Context, agent: Agent, config: TuiConfig);
|
|
433
509
|
/** Enter raw mode, switch to the alternate screen, and start listening. */
|
|
434
510
|
start(): void;
|
|
511
|
+
private startRenderTimer;
|
|
512
|
+
private calibratePaintInterval;
|
|
435
513
|
/** Replay the durable session log so a resumed session renders its history. */
|
|
436
514
|
replayHistory(): void;
|
|
437
515
|
/** Show the first-launch provider/API-key onboarding when nothing is configured. */
|
|
@@ -512,6 +590,10 @@ export declare class SshTui {
|
|
|
512
590
|
private readonly handleDisposed;
|
|
513
591
|
/** Plan-mode / command / team events that plugins merge into SessionEventMap. */
|
|
514
592
|
private handleExtensionEvent;
|
|
593
|
+
private findCompactionRow;
|
|
594
|
+
private handleCompactionEvent;
|
|
595
|
+
private handleCommandRun;
|
|
596
|
+
private handleCommandDone;
|
|
515
597
|
private handleGoalChange;
|
|
516
598
|
private handleSubagentExtensionEvent;
|
|
517
599
|
/** Fold a live subagent's own session events into that child's card. */
|
|
@@ -590,8 +672,13 @@ export declare class SshTui {
|
|
|
590
672
|
private fetchOpenCodeGoUsage;
|
|
591
673
|
/** Explain Zen metered billing instead of pretending it has a quota. */
|
|
592
674
|
private zenUsageText;
|
|
593
|
-
/** /usage and /quota:
|
|
675
|
+
/** /usage and /quota: remaining quota for the current subscription provider. */
|
|
594
676
|
private runUsageCommand;
|
|
677
|
+
private applyQuotaSnapshot;
|
|
678
|
+
private refreshQuota;
|
|
679
|
+
private fetchQuotaSnapshot;
|
|
680
|
+
private resolveSuperGrokToken;
|
|
681
|
+
private fetchJson;
|
|
595
682
|
private readonly handleData;
|
|
596
683
|
/** Handle one data chunk that may contain bracketed-paste markers. */
|
|
597
684
|
private processPasteChunk;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ssh-tui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "SSH-friendly interactive terminal TUI plugin for DeepSeek Harness",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"docs/screenshots/compare.png",
|
|
46
46
|
"docs/screenshots/headless.png",
|
|
47
47
|
"docs/screenshots/workspace.png",
|
|
48
|
+
"docs/screenshots/slow-link.gif",
|
|
48
49
|
"LICENSE"
|
|
49
50
|
],
|
|
50
51
|
"license": "MIT",
|
|
@@ -65,7 +66,8 @@
|
|
|
65
66
|
"install:npm": "bash scripts/install-npm.sh",
|
|
66
67
|
"uninstall:dsh": "bash scripts/uninstall.sh",
|
|
67
68
|
"verify:dsh": "bash scripts/verify.sh",
|
|
68
|
-
"screenshots": "npm run build && node scripts/capture-readme-frames.mjs"
|
|
69
|
+
"screenshots": "npm run build && node scripts/capture-readme-frames.mjs",
|
|
70
|
+
"screenshots:slow": "npm run build && node scripts/capture-slow-link.mjs"
|
|
69
71
|
},
|
|
70
72
|
"engines": {
|
|
71
73
|
"node": ">=22.19"
|