dsh-ssh-tui 0.7.2 → 0.7.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.
Files changed (112) hide show
  1. package/README.en.md +113 -27
  2. package/README.md +90 -27
  3. package/cordis.patch.yml +15 -0
  4. package/docs/remote-ops.md +27 -1
  5. package/docs/terminals.md +126 -0
  6. package/docs/windows.md +128 -0
  7. package/lib/attach.js +14 -1
  8. package/lib/attach.js.map +1 -1
  9. package/lib/commands.js +1 -0
  10. package/lib/commands.js.map +1 -1
  11. package/lib/copy-text.js +2 -0
  12. package/lib/copy-text.js.map +1 -1
  13. package/lib/diag.js +38 -0
  14. package/lib/diag.js.map +1 -1
  15. package/lib/dialogs.js.map +1 -1
  16. package/lib/display-sock.js +572 -44
  17. package/lib/display-sock.js.map +1 -1
  18. package/lib/doctor.js +71 -37
  19. package/lib/doctor.js.map +1 -1
  20. package/lib/dsh-compat.js +252 -88
  21. package/lib/dsh-compat.js.map +1 -1
  22. package/lib/footer.js +4 -2
  23. package/lib/footer.js.map +1 -1
  24. package/lib/i18n/en.js +54 -10
  25. package/lib/i18n/en.js.map +1 -1
  26. package/lib/i18n/index.js +18 -7
  27. package/lib/i18n/index.js.map +1 -1
  28. package/lib/i18n/zh.js +54 -10
  29. package/lib/i18n/zh.js.map +1 -1
  30. package/lib/index.js +111 -26
  31. package/lib/index.js.map +1 -1
  32. package/lib/line-mode.js +4 -0
  33. package/lib/line-mode.js.map +1 -1
  34. package/lib/paint.js +37 -3
  35. package/lib/paint.js.map +1 -1
  36. package/lib/picker.js +109 -18
  37. package/lib/picker.js.map +1 -1
  38. package/lib/plan.js +8 -0
  39. package/lib/plan.js.map +1 -1
  40. package/lib/platform.js +377 -11
  41. package/lib/platform.js.map +1 -1
  42. package/lib/preset-authoring.js +10 -14
  43. package/lib/preset-authoring.js.map +1 -1
  44. package/lib/preset-compat.js +100 -0
  45. package/lib/preset-compat.js.map +1 -0
  46. package/lib/preset-picker.js +5 -1
  47. package/lib/preset-picker.js.map +1 -1
  48. package/lib/preset-rows.js +119 -19
  49. package/lib/preset-rows.js.map +1 -1
  50. package/lib/provider-catalog.js +4 -4
  51. package/lib/question-wait.js +418 -0
  52. package/lib/question-wait.js.map +1 -0
  53. package/lib/route-memory.js +3 -3
  54. package/lib/route-memory.js.map +1 -1
  55. package/lib/selection.js +26 -8
  56. package/lib/selection.js.map +1 -1
  57. package/lib/session-index.js +5 -0
  58. package/lib/session-index.js.map +1 -1
  59. package/lib/session-lock.js +4 -1
  60. package/lib/session-lock.js.map +1 -1
  61. package/lib/session-route.js +3 -0
  62. package/lib/session-route.js.map +1 -1
  63. package/lib/settings-routes.js +10 -0
  64. package/lib/settings-routes.js.map +1 -0
  65. package/lib/settings-subagent.js +10 -0
  66. package/lib/settings-subagent.js.map +1 -0
  67. package/lib/subagent-model.js +5 -5
  68. package/lib/subagent-model.js.map +1 -1
  69. package/lib/supergrok-token.js +4 -0
  70. package/lib/supergrok-token.js.map +1 -1
  71. package/lib/term-text.js +79 -8
  72. package/lib/term-text.js.map +1 -1
  73. package/lib/terminal-caps.js +358 -0
  74. package/lib/terminal-caps.js.map +1 -0
  75. package/lib/terminal-input.js +13 -0
  76. package/lib/terminal-input.js.map +1 -1
  77. package/lib/tui.js +775 -165
  78. package/lib/tui.js.map +1 -1
  79. package/lib/types/attach.d.ts +8 -0
  80. package/lib/types/commands.d.ts +3 -0
  81. package/lib/types/diag.d.ts +20 -1
  82. package/lib/types/dialogs.d.ts +16 -0
  83. package/lib/types/display-sock.d.ts +141 -24
  84. package/lib/types/doctor.d.ts +8 -1
  85. package/lib/types/dsh-compat.d.ts +173 -44
  86. package/lib/types/footer.d.ts +3 -1
  87. package/lib/types/i18n/index.d.ts +31 -15
  88. package/lib/types/index.d.ts +45 -0
  89. package/lib/types/paint.d.ts +21 -0
  90. package/lib/types/picker.d.ts +25 -0
  91. package/lib/types/platform.d.ts +197 -10
  92. package/lib/types/preset-authoring.d.ts +8 -14
  93. package/lib/types/preset-compat.d.ts +58 -0
  94. package/lib/types/preset-picker.d.ts +1 -1
  95. package/lib/types/preset-rows.d.ts +63 -13
  96. package/lib/types/question-wait.d.ts +221 -0
  97. package/lib/types/selection.d.ts +12 -4
  98. package/lib/types/settings-routes.d.ts +16 -0
  99. package/lib/types/settings-subagent.d.ts +24 -0
  100. package/lib/types/subagent-model.d.ts +10 -10
  101. package/lib/types/term-text.d.ts +14 -0
  102. package/lib/types/terminal-caps.d.ts +105 -0
  103. package/lib/types/terminal-input.d.ts +10 -0
  104. package/lib/types/transcript-types.d.ts +22 -0
  105. package/lib/types/tui.d.ts +167 -10
  106. package/lib/types/update-check.d.ts +19 -4
  107. package/lib/types/workspace-changes.d.ts +135 -0
  108. package/lib/update-check.js +25 -8
  109. package/lib/update-check.js.map +1 -1
  110. package/lib/workspace-changes.js +120 -0
  111. package/lib/workspace-changes.js.map +1 -0
  112. package/package.json +124 -59
@@ -20,18 +20,19 @@ import type { Context } from '@deepseek-ai/cordis';
20
20
  import { type LlmCallConfig } from '@deepseek-ai/dsh-llm';
21
21
  import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session';
22
22
  import type { SubagentRunEndInfo, SubagentRunInfo } from '@deepseek-ai/dsh-subagent';
23
+ import { type TerminalCapabilities } from './terminal-caps.js';
23
24
  import { type SessionRoute } from './session-route.js';
24
25
  import { type SubagentSelectionRef } from './subagent-model.js';
25
26
  import { type AskUserQuestionAnswer, type AskUserQuestionRequest } from '@deepseek-ai/dsh-user-questions';
26
27
  import type { ApprovalOutcome, ApprovalRequest } from '@deepseek-ai/dsh-user-approval';
27
- import type { CollapsibleBlock, DisconnectPolicyName } from './transcript-types.js';
28
+ import type { CollapsibleBlock, DisconnectPolicyName, Row } from './transcript-types.js';
28
29
  import { paintedLinkHits } from './term-text.js';
29
30
  export type { CollapsibleBlock, DisplayKind, DisconnectPolicyName, PlanTodoItem, Row, SubagentLogEntry, ToolDiffHunk, } from './transcript-types.js';
30
31
  export { clipAnsiToWidth, cursorVisualPosition, displayWidth, foldInputView, hrefAtColumn, osc52Clipboard, osc8Enabled, paintedLinkHits, fmtElapsedCompact, padAnsiToWidth, padToWidth, renderMarkdownLines, repeatToWidth, shimmerText, truncateToWidth, visibleWidth, waitCardCopy, waitSummaryFromReasoning, wrapWaitDetails, } from './term-text.js';
31
32
  export { captureHangupSignals, composePaintOutput, detectSshSession, formatLinkQualityChip, ignoreFurtherHangupSignals, isEscapePrefix, findCursorPositionReply, isHangupErrno, linkQualityOf, linkSignalPips, paintIntervalForRtt, paintLinkLabel, parseCursorPositionReply, pickerWindowStart, probeTerminalRttMs, releaseHangupSignals, resolvePaintIntervalMs, waitUntilIdleOrTimeout, writeBootSplash, type LinkQuality, type PaintLinkKind, } from './paint.js';
32
33
  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, footerSubagentForeign, paintFooterSubagentChip, formatContextPressureChip, formatContextPressureRing, formatContextPressureStatusLine, formatDuration, formatFooterQuota, formatQuotaBar, formatQuotaUnknown, formatStatusReport, providerHasQuotaSurface, quotaWindowTag, shortModelName, shortQuotaPlanName, formatTokens, formatTokensPerSecond, parseContextPressure, promptPressureTokens, providerShortCode, providerUsesLocalOAuth, shouldIdleAutoCompact, subagentRouteLabel, type ContextPressureSample, type ContextPressureView, type FooterActivityKind, type FooterStatsInput, type FooterStatusInput, type StatusReportInput, } from './footer.js';
33
34
  export { commandCodePeriodStart, commandCodeSourceFor, crossedQuotaThresholds, formatAccountBalance, formatFooterBalance, formatOpenCodeGoUsage, formatQuotaSnapshot, formatQuotaStatusLine, joinUrl, openCodeSourceFor, parseCommandCodeQuota, parseDeepSeekBalance, parseOpenAiCompatibleBalance, parseOpenCodeGoQuota, parseSuperGrokBilling, preferredQuotaWindow, quotaAlertText, quotaRefreshEverySteps, quotaRefreshEveryTurns, remainingPercentFromUsed, tightestQuotaWindow, type AccountBalanceLine, type AccountBalanceSnapshot, type CommandCodeSource, type OpenCodeFlavor, type OpenCodeSource, type QuotaPeriod, type QuotaSnapshot, type QuotaWindow, } from './quota.js';
34
- export { commandAcceptsAttachments, forEachSessionEvent, isAssistantStreamEvent, isTokenDeltaChunk, listPersistenceHeaders, inspectPersistenceSession, sessionEventType, sessionEvents, settingsNamespace, streamChunkOf, streamFirstTokenTime, streamFrameAttemptId, streamFrameOwner, } from './dsh-compat.js';
35
+ export { commandAcceptsAttachments, forEachSessionEvent, isTokenDeltaChunk, listPersistenceHeaders, inspectPersistenceSession, sessionEvents, settingsNamespace, streamChunkOf, streamFirstTokenTime, streamFrameAttemptId, streamFrameOwner, } from './dsh-compat.js';
35
36
  export { applyTurnEndToPlan, askSummary, cardCategoryOf, compactionHeaderText, formatCompactCommandError, isPromptInjectionMessage, matchTranscriptRows, parseFindQuery, parsePlanTodos, planCloseNudgeText, planDockNote, planIsLive, planTitleFromMarkdown, planTurnLeftOpen, promptInjectionSources, promptInjectionTitle, buildSubagentHeader, clipSubagentActivity, describeSubagentFailure, subagentChipSummary, subagentDisplayName, subagentInspectLines, subagentRowFromSpawnTool, foldSubagentUserLog, todoProgressLabel, todoSummary, type CardCategory, } from './plan.js';
36
37
  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';
37
38
  /** Presentation configuration for the terminal channel. */
@@ -78,6 +79,12 @@ export interface TuiConfig {
78
79
  selectionRef?: ModelSelectionRef;
79
80
  /** Settings-backed model/effort selection applied to subagent requests. */
80
81
  subagentSelection?: SubagentSelectionRef;
82
+ /**
83
+ * The terminal capabilities to act on. Defaults to reading the environment;
84
+ * tests pass their own so a suite does not change meaning with the terminal
85
+ * it happens to run in (`TERM=linux node --test` used to fail three cases).
86
+ */
87
+ terminalCaps?: TerminalCapabilities;
81
88
  /** Active agent-preset id (standard/code/minimal/cordis/...). */
82
89
  presetId?: string;
83
90
  /** Display name of the active preset. */
@@ -100,6 +107,15 @@ export interface TuiConfig {
100
107
  onHangup?: () => void | Promise<void>;
101
108
  /** Called when a Display relay attaches after hangup. */
102
109
  onReattach?: () => void | Promise<void>;
110
+ /**
111
+ * The display just went away, before the Host has decided whether to stay.
112
+ *
113
+ * The lock stops saying `attached` from here: that field is what a resume (and
114
+ * the launch picker's list) reads to decide whether another window is on the
115
+ * session, and leaving it set for the whole cancel-and-flush below turned a
116
+ * reconnect in that window into "already attached to another window".
117
+ */
118
+ onDetach?: () => void | Promise<void>;
103
119
  /** Host process: no local TTY; paint only through the display socket. */
104
120
  headlessDisplay?: boolean;
105
121
  /** Append events as plain lines instead of painting (see `line-mode`). */
@@ -116,6 +132,16 @@ export interface TuiController {
116
132
  disconnectPolicy(): DisconnectPolicyName;
117
133
  }
118
134
  export type WorkspaceView = 'detailed' | 'compact';
135
+ /**
136
+ * One row the card cursor can land on.
137
+ *
138
+ * Every collapsible card, plus the model replies. A reply has nothing to expand,
139
+ * which is why it used to be left out of the ring — and that is exactly what
140
+ * made `/copy` unreachable for it: `/copy` takes the focused row, so as soon as
141
+ * the reader selected any card the reply stopped being a copy target, and the
142
+ * newest reply survived only as the no-focus fallback.
143
+ */
144
+ export type FocusTarget = Row | CollapsibleBlock;
119
145
  export declare function parseDisconnectPolicy(raw: string): DisconnectPolicyName | undefined;
120
146
  /**
121
147
  * The `reasoningEfforts` map `/setup` writes for a hand-declared
@@ -214,6 +240,7 @@ export declare class SshTui {
214
240
  private relayRows;
215
241
  private readonly onHangup;
216
242
  private readonly onReattach;
243
+ private readonly onDetach;
217
244
  private renderTimer;
218
245
  private readonly decoder;
219
246
  private readonly color;
@@ -234,6 +261,14 @@ export declare class SshTui {
234
261
  /** Last route reported to the launcher; a repaint must not report it again. */
235
262
  private lastSessionRoute;
236
263
  private readonly useAlternateScreen;
264
+ /**
265
+ * What the terminal in front of us can do. Read from the environment at
266
+ * construction (see `terminal-caps.ts`): the mouse, bracketed paste and the
267
+ * alternate screen are only claimed where the terminal has them.
268
+ */
269
+ private readonly terminalCaps;
270
+ /** The OSC 52 caveat is worth saying once, not after every copy. */
271
+ private osc52HintShown;
237
272
  private agentGone;
238
273
  private onboarding;
239
274
  private commandSuggestions;
@@ -302,6 +337,15 @@ export declare class SshTui {
302
337
  private readonly inputGuard;
303
338
  private thinkingStartedAt;
304
339
  private waitStartedAt;
340
+ /**
341
+ * Whether the running turn produced anything a person can read: reply text or
342
+ * a tool card. A turn that ends with thinking only is the upstream returning
343
+ * an empty stop, and painting 完成 for it reads as a finished answer — see
344
+ * the hint at `turn/end`.
345
+ */
346
+ private turnSawOutput;
347
+ /** Whether the turn produced thinking, which the empty-stop hint names. */
348
+ private turnSawReasoning;
305
349
  private completionSignaled;
306
350
  private replaying;
307
351
  /** Display-line budget for the first paint after resume; 0 = full transcript. */
@@ -355,10 +399,22 @@ export declare class SshTui {
355
399
  private detachedDeniedCount;
356
400
  /** Questions waiting for a display right now — their cards do not exist yet. */
357
401
  private queuedQuestions;
402
+ /** When the current detached wait began, so the reconnect can say how long. */
403
+ private questionWaitSince;
358
404
  private paintIntervalMs;
359
405
  private paintLink;
406
+ /**
407
+ * Whether this process runs inside an SSH session, from the sshd environment.
408
+ *
409
+ * Distinct from `paintLink`, which `applyProbedRtt` pins to `'ssh'` for any
410
+ * relayed frame — a local window included. Only this flag says the capability
411
+ * table described a remote tty rather than the terminal the bytes reach.
412
+ */
413
+ private sshSession;
360
414
  private paintProbed;
361
415
  private paintRttMs;
416
+ /** The last few measured round-trips; the chip and the budget use their median. */
417
+ private paintRttHistory;
362
418
  private sessionTitle;
363
419
  private llmRetry;
364
420
  private quotaSnapshot;
@@ -387,6 +443,15 @@ export declare class SshTui {
387
443
  constructor(ctx: Context, agent: Agent, config: TuiConfig);
388
444
  /** Enter raw mode, switch to the alternate screen, and start listening. */
389
445
  start(): void;
446
+ /**
447
+ * Take over the screen: alternate screen where it is safe, then the input
448
+ * modes the terminal actually supports, then hide the cursor.
449
+ *
450
+ * Joining the parts here (rather than at each call site) is what keeps
451
+ * `start`, a reattach and a teardown from drifting apart — the reattach path
452
+ * used to duplicate this string verbatim.
453
+ */
454
+ private enterScreenSequence;
390
455
  private bindAgentEvents;
391
456
  private bootBackgroundTasks;
392
457
  private notifyPluginUpdate;
@@ -538,6 +603,8 @@ export declare class SshTui {
538
603
  /** Re-open DECSET and start painting to an attached Display relay. */
539
604
  attachRelayDisplay(): void;
540
605
  currentDisconnectPolicy(): DisconnectPolicyName;
606
+ /** The paint cadence in force right now: the link tier the footer shows. */
607
+ currentPaintIntervalMs(): number;
541
608
  applyProbedRtt(rttMs: number | undefined): void;
542
609
  private markDirty;
543
610
  private toolCardSummary;
@@ -552,6 +619,19 @@ export declare class SshTui {
552
619
  private flushLineMode;
553
620
  /** The transcript rows that support per-row expand/collapse. */
554
621
  private collapsibleRows;
622
+ /**
623
+ * Everything the card cursor walks, in transcript order: the collapsible
624
+ * cards plus the model replies.
625
+ *
626
+ * Built from the two lists rather than from the rows alone, because one of the
627
+ * collapsible entries is synthetic: the live thinking block exists only while a
628
+ * turn streams and is never a member of `this.rows`. Filtering the rows (the
629
+ * first version of this) silently dropped it out of the cursor walk — ↑ on a
630
+ * turn that had only streamed thinking did nothing, and Enter could no longer
631
+ * expand the card being written. It belongs at the end, which is where it is
632
+ * painted, so anything not in the rows is appended.
633
+ */
634
+ private focusRing;
555
635
  private spinnerFrame;
556
636
  /**
557
637
  * Codex wait card: shown while the turn is running. The live thinking
@@ -606,6 +686,16 @@ export declare class SshTui {
606
686
  private markSearchRow;
607
687
  private openToolInspect;
608
688
  private openSubagentInspect;
689
+ /**
690
+ * Read one reply full-screen.
691
+ *
692
+ * What Enter does on a selected reply: a reply has no body to fold away, and
693
+ * the transcript wraps it to the window — which for a long answer with tables
694
+ * or code blocks is not how it reads. The overlay is the same surface the tool
695
+ * cards use, and the copy key works inside it, so "read it, then copy it"
696
+ * needs no trip back through the timeline.
697
+ */
698
+ private openReplyInspect;
609
699
  /**
610
700
  * Line mode has no framed scroller, so an inspect body goes into the log.
611
701
  *
@@ -616,8 +706,18 @@ export declare class SshTui {
616
706
  private echoInspectToLog;
617
707
  closeInspect(): void;
618
708
  private paintCollapsibleHeader;
619
- /** Move the expand/collapse focus among reasoning and tool rows. */
620
- private moveCollapsibleFocus;
709
+ /**
710
+ * Which file line of an expanded changes card the screen cursor is on.
711
+ *
712
+ * The card paints its header, then one row per file, and `selectableLines`
713
+ * holds exactly the viewport. The cursor sits on the input row unless the
714
+ * reader scrolled, so the file is how many painted rows above the cursor the
715
+ * card's header is. A cursor on the header, the remainder line, or the prompt
716
+ * falls back to the first file, which is the only defensible guess.
717
+ */
718
+ private changesFileIndex;
719
+ /** Move the card cursor among the cards and the replies. */
720
+ private moveFocus;
621
721
  /** Toggle the focused block; without focus, toggle the most recent one. */
622
722
  toggleCollapsible(): void;
623
723
  /**
@@ -748,15 +848,15 @@ export declare class SshTui {
748
848
  */
749
849
  private selectLine;
750
850
  /**
751
- * Fold one live or durable stream chunk into the in-progress assistant
752
- * row. 0.1.2 hosts append `assistant/chunk`; 0.1.5 emits the same chunk
753
- * on `agent/assistant-stream` and never writes it to the log.
851
+ * Fold one live stream chunk into the in-progress assistant row. Hosts from
852
+ * 0.1.5 on emit the chunk on `agent/assistant-stream` and never write it to
853
+ * the log.
754
854
  */
755
855
  private applyStreamChunk;
756
856
  /**
757
- * 0.1.5 live tokens arrive as process-local `agent/assistant-stream`
758
- * frames (start / chunk / end). Chunk frames carry the same
759
- * `StreamChunk` the 0.1.2 log used to store as `assistant/chunk`.
857
+ * 0.1.5 and 0.1.7 live tokens arrive as process-local
858
+ * `agent/assistant-stream` frames (start / chunk / end). Chunk frames carry
859
+ * the same `StreamChunk` the settled `assistant/message` embeds in `stream`.
760
860
  */
761
861
  readonly handleAssistantStream: (...args: unknown[]) => void;
762
862
  /**
@@ -783,6 +883,27 @@ export declare class SshTui {
783
883
  private readonly handleInboxClaimed;
784
884
  private readonly handleInboxDiscarded;
785
885
  private readonly handleDisposed;
886
+ /**
887
+ * One `workspace/changes` event: the files a turn changed.
888
+ *
889
+ * The event carries only the turn number; the summary stays on the Host and
890
+ * is served by `workspaceChanges` for this event's own sequence, and only
891
+ * while the Session lives. A missing service (every 0.1.5 Host) or a summary
892
+ * that can no longer be opened (a log replayed after a restart) shows
893
+ * nothing — upstream's rule, so a card that cannot be read is never drawn.
894
+ * A later event for the same turn replaces the earlier summary in place.
895
+ */
896
+ private noteWorkspaceChanges;
897
+ /** Copy one summary onto its card. Shared by the first event and its replacements. */
898
+ private fillChangesCard;
899
+ /**
900
+ * Full view of one file on a changes card: its comparison, as the service
901
+ * computed it. Binary and oversized files have no lines, so the overlay
902
+ * carries the one-line explanation instead of an empty body.
903
+ */
904
+ private openChangesInspect;
905
+ /** Open (or replace) the changes overlay, or echo it to the log in line mode. */
906
+ private openChangesInspectLines;
786
907
  /** Plan-mode / command / team events that plugins merge into SessionEventMap. */
787
908
  private handleExtensionEvent;
788
909
  private findCompactionRow;
@@ -827,6 +948,19 @@ export declare class SshTui {
827
948
  /** Keep an open inspect overlay in sync with the live child log. */
828
949
  private refreshOpenSubagentInspect;
829
950
  private hasLiveDisplay;
951
+ /**
952
+ * Tell the absent user that a question is waiting.
953
+ *
954
+ * The marker file is the part that needs no configuration: it sits next to the
955
+ * session's stderr log, so logging back into the jump host shows it before the
956
+ * TUI is open. The command is whatever the user pointed `ssh-tui.notify` at,
957
+ * run once; it never blocks the wait and never reports its own failure.
958
+ */
959
+ private announceWaitingQuestion;
960
+ /** The SMTP account `/notify smtp` saved, when the target is authenticated. */
961
+ private readNotifySmtp;
962
+ /** `DSH_TUI_NOTIFY`, else the saved `ssh-tui.notify`. Empty means off. */
963
+ private readNotifyCommand;
830
964
  private waitForLiveDisplay;
831
965
  /**
832
966
  * Auto mode rides the approval waterfall: when the host approval policy is
@@ -860,6 +994,10 @@ export declare class SshTui {
860
994
  * `the user rejected tool "bash"`. Steer a plugin notice with the real
861
995
  * classifier/reviewer reason. Summary matches the workspace decision row
862
996
  * so the handler does not paint the body twice.
997
+ *
998
+ * This notice is committed to the session, so it is exactly the injection a
999
+ * V4 log refuses when it wears the released `plugin` wrapper — see
1000
+ * {@link TUI_SOURCE_KIND}.
863
1001
  */
864
1002
  private tellModelApprovalDenied;
865
1003
  readonly handleApproval: (request: ApprovalRequest, _next: () => Promise<ApprovalOutcome>) => Promise<ApprovalOutcome>;
@@ -1068,6 +1206,15 @@ export declare class SshTui {
1068
1206
  private runLanguageCommand;
1069
1207
  /** /view: detailed (see the work) vs compact (Codex-like summary). */
1070
1208
  private runViewCommand;
1209
+ /**
1210
+ * /notify: where a question waiting on an absent user is announced.
1211
+ *
1212
+ * No argument shows what is configured. `off` clears it. `mail`, `smtp` and
1213
+ * `local` store the command that target needs; the SMTP password is kept
1214
+ * beside it and handed to the command through the environment, so it is never
1215
+ * part of the command string.
1216
+ */
1217
+ private runNotifyCommand;
1071
1218
  /** /disconnect: pause (default) or continue the turn after SSH drop. */
1072
1219
  private runDisconnectCommand;
1073
1220
  /** /mode: pick an agent preset (standard / minimal / ptc / cordis / routing-suite / ...). */
@@ -1081,6 +1228,16 @@ export declare class SshTui {
1081
1228
  */
1082
1229
  /** Re-read the roster fact this process was composed with (cheap, no IO). */
1083
1230
  private refreshRosterHealth;
1231
+ /** Which settings protocol this host speaks; decides what "missing" means. */
1232
+ private get settingsGeneration();
1233
+ /**
1234
+ * The two lines `/mode` and `/preset` print when the preset service is absent.
1235
+ *
1236
+ * The reason differs by host line: 0.1.5 lost a roster the profile can mount,
1237
+ * while 0.1.7 composes the agent process-wide and has no terminal presets at
1238
+ * all — the repair there is the agent-plane rows, not a roster.
1239
+ */
1240
+ private missingPresetService;
1084
1241
  private repairRoster;
1085
1242
  /** Current provider route selected for the running agent. */
1086
1243
  private currentProvider;
@@ -1,13 +1,28 @@
1
1
  /**
2
2
  * Best-effort npm latest check. Failures stay quiet. The TUI may offer to
3
- * run `dsh plugin --profile <name> add dsh-ssh-tui@latest` — pnpm otherwise
4
- * keeps the lockfile pin (e.g. 0.3.7) when the spec is a bare package name.
3
+ * install the version it just read, by number: `dsh plugin --profile <name>
4
+ * add dsh-ssh-tui@<version>`. A bare package name lets pnpm keep the lockfile
5
+ * pin (e.g. 0.3.7), and `@latest` is resolved a second time at install — under
6
+ * pnpm's `minimumReleaseAge` that second lookup can quietly land on yesterday's
7
+ * release while still exiting 0.
5
8
  */
6
9
  import { spawn } from 'node:child_process';
7
10
  export declare const PLUGIN_PACKAGE = "dsh-ssh-tui";
8
11
  export declare function compareSemver(a: string, b: string): number;
9
12
  export declare function resolvePluginProfileName(env?: NodeJS.ProcessEnv): string;
10
- export declare function pluginUpgradeCommand(profile?: string): string;
13
+ /**
14
+ * The install command for one already-resolved version.
15
+ *
16
+ * The version is the number `checkForPluginUpdate` read from the registry, not
17
+ * the `latest` dist-tag: handing pnpm the tag makes it resolve the release a
18
+ * second time, and a release younger than `minimumReleaseAge` is then skipped
19
+ * without an error. A caller with no resolved version passes `@latest`, which
20
+ * is still better than a bare name.
21
+ * @param profile - the profile the plugin is installed into.
22
+ * @param version - the exact version to install.
23
+ * @returns the command, safe to show the user and to run.
24
+ */
25
+ export declare function pluginUpgradeCommand(profile?: string, version?: string): string;
11
26
  export declare function formatUpdateNotice(current: string, latest: string, profile?: string): string;
12
27
  export declare function fetchLatestNpmVersion(fetchImpl?: typeof fetch): Promise<string | undefined>;
13
28
  export interface PluginUpdateInfo {
@@ -50,7 +65,7 @@ export declare function resolveDshInvocation(options?: {
50
65
  * hold the fallback together.
51
66
  */
52
67
  export declare function shellSafeProfile(profile: string): string;
53
- export declare function installPluginLatest(profile?: string, deps?: {
68
+ export declare function installPluginLatest(profile?: string, version?: string, deps?: {
54
69
  invocation?: DshInvocation;
55
70
  spawnFn?: typeof spawn;
56
71
  }): Promise<{
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Per-turn workspace change cards, read from the Host's `workspaceChanges`
3
+ * service (`@deepseek-ai/dsh-workspace-changes`, shipped with dsh 0.1.7).
4
+ *
5
+ * The service is not a dependency of this plugin: 0.1.5 has neither the
6
+ * package nor the `workspace/changes` event, so everything here is reached by
7
+ * feature detection and the local types below are copied from the service's
8
+ * contract rather than imported. Importing the package would fail to compile
9
+ * on the 0.1.5 tree, where the module does not exist.
10
+ *
11
+ * What the service serves lives only as long as the Session does, in this Host
12
+ * process. After a restart a replayed event resolves to `undefined`, and the
13
+ * upstream decision — which this module honours — is to show no card at all
14
+ * rather than a card whose contents can no longer be opened.
15
+ * @module dsh-ssh-tui/workspace-changes
16
+ */
17
+ import type { DiffDisplayLine } from './transcript-types.js';
18
+ /** One file changed during a turn. Mirrors the service's `WorkspaceChangedFile`. */
19
+ export interface ChangesFile {
20
+ /** Path relative to the Session working directory, or absolute outside it. */
21
+ path: string;
22
+ /** Sort key and label, always slash-separated. */
23
+ display: string;
24
+ /** Lines added; zero when the file is binary or oversized. */
25
+ added: number;
26
+ /** Lines deleted; zero when the file is binary or oversized. */
27
+ deleted: number;
28
+ /** Git called it binary, or a captured side holds a NUL byte. */
29
+ binary?: true;
30
+ /** A captured side exceeded the plugin's byte cap; listed without counts. */
31
+ oversized?: true;
32
+ }
33
+ /** Files changed during one top-level turn. Mirrors `WorkspaceChangesSummary`. */
34
+ export interface ChangesSummary {
35
+ /** The turn this summary describes. */
36
+ turn: number;
37
+ /** Working directory the `path` values are relative to. */
38
+ cwd: string;
39
+ /** Changed files in `display` order, capped by the plugin's `maxFiles`. */
40
+ files: ChangesFile[];
41
+ /** Complete changed-file count, including files the cap omitted. */
42
+ total: number;
43
+ /** Lines added over every changed file, including omitted ones. */
44
+ added: number;
45
+ /** Lines deleted over every changed file, including omitted ones. */
46
+ deleted: number;
47
+ }
48
+ /** One unified-diff hunk; every line keeps its `+`, `-`, or space prefix. */
49
+ export interface ChangesHunk {
50
+ /** First line in the turn-start content, 1-based. */
51
+ oldStart: number;
52
+ /** Lines taken from the turn-start content. */
53
+ oldLines: number;
54
+ /** First line in the turn-end content, 1-based. */
55
+ newStart: number;
56
+ /** Lines taken from the turn-end content. */
57
+ newLines: number;
58
+ /** Hunk body in order, each line prefixed with `+`, `-`, or a space. */
59
+ lines: string[];
60
+ }
61
+ /**
62
+ * One listed file's comparison, computed when asked for. Mirrors
63
+ * `WorkspaceFileDiff`: a line diff, or a file that has no lines to show.
64
+ */
65
+ export type ChangesFileDiff = {
66
+ kind: 'text';
67
+ path: string;
68
+ display: string;
69
+ before: boolean;
70
+ after: boolean;
71
+ hunks: ChangesHunk[];
72
+ /** The comparison timed out and every line is shown as replaced. */
73
+ coarse: boolean;
74
+ } | {
75
+ kind: 'binary';
76
+ path: string;
77
+ display: string;
78
+ } | {
79
+ kind: 'oversized';
80
+ path: string;
81
+ display: string;
82
+ };
83
+ /**
84
+ * The Host service, as far as this plugin reads it. `seq` is the
85
+ * `workspace/changes` event's own sequence number, not the turn number.
86
+ */
87
+ export interface WorkspaceChangesSource {
88
+ summary(sessionId: string, seq: number): ChangesSummary | undefined;
89
+ diff(sessionId: string, seq: number, index: number, signal: AbortSignal): Promise<ChangesFileDiff | undefined>;
90
+ }
91
+ /**
92
+ * The `workspaceChanges` service, when this Host actually has one.
93
+ *
94
+ * Both methods have to be functions: a present-but-incomplete object (a stub,
95
+ * a future shape) must read as "not available" so the event is ignored instead
96
+ * of throwing when the card is built.
97
+ * @param ctx - the Host context.
98
+ * @returns the service, or undefined on a Host that never registered one.
99
+ */
100
+ export declare function workspaceChangesOf(ctx: {
101
+ get?(name: string): unknown;
102
+ }): WorkspaceChangesSource | undefined;
103
+ /** Whether a summary is worth a card. A turn that changed nothing is not. */
104
+ export declare function changesSummaryVisible(summary: ChangesSummary): boolean;
105
+ /** Collapsed-card header: `本轮改动 · 3 个文件 +42 -7`. */
106
+ export declare function changesHeader(summary: ChangesSummary): string;
107
+ /**
108
+ * One expanded-card file line.
109
+ *
110
+ * Binary and oversized files carry no counts upstream, so naming the file and
111
+ * then printing `+0 -0` would report a change that was not measured. They get
112
+ * a label instead.
113
+ * @param file - one entry of the summary.
114
+ * @returns the line, without the card's indent.
115
+ */
116
+ export declare function changesFileLine(file: ChangesFile): string;
117
+ /**
118
+ * Files the cap left out, when there are any.
119
+ * @param summary - the turn's summary.
120
+ * @returns the trailing line, or undefined when every file is listed.
121
+ */
122
+ export declare function changesRemainderLine(summary: ChangesSummary): string | undefined;
123
+ /**
124
+ * Render one file's comparison as overlay lines.
125
+ *
126
+ * The service already compared the two sides, so this only maps what it
127
+ * returned: recomputing the diff would be slower and could disagree with the
128
+ * counts the card already showed. A `+` line is an addition, a `-` line a
129
+ * removal, and a space-prefixed line is the unchanged context. Anything else
130
+ * (a hunk line the service did not prefix) is shown as context too — dropping
131
+ * it would hide part of the file.
132
+ * @param diff - the comparison `workspaceChanges.diff` returned.
133
+ * @returns the lines, or an empty list when there is nothing to show.
134
+ */
135
+ export declare function renderChangesDiff(diff: ChangesFileDiff | undefined): DiffDisplayLine[];
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Best-effort npm latest check. Failures stay quiet. The TUI may offer to
3
- * run `dsh plugin --profile <name> add dsh-ssh-tui@latest` — pnpm otherwise
4
- * keeps the lockfile pin (e.g. 0.3.7) when the spec is a bare package name.
3
+ * install the version it just read, by number: `dsh plugin --profile <name>
4
+ * add dsh-ssh-tui@<version>`. A bare package name lets pnpm keep the lockfile
5
+ * pin (e.g. 0.3.7), and `@latest` is resolved a second time at install — under
6
+ * pnpm's `minimumReleaseAge` that second lookup can quietly land on yesterday's
7
+ * release while still exiting 0.
5
8
  */
6
9
  import { spawn } from 'node:child_process';
7
10
  import { existsSync } from 'node:fs';
@@ -32,11 +35,24 @@ export function resolvePluginProfileName(env = process.env) {
32
35
  return arg;
33
36
  return 'tui';
34
37
  }
35
- export function pluginUpgradeCommand(profile = resolvePluginProfileName()) {
36
- return `dsh plugin --profile ${profile} add ${PLUGIN_PACKAGE}@latest`;
38
+ /**
39
+ * The install command for one already-resolved version.
40
+ *
41
+ * The version is the number `checkForPluginUpdate` read from the registry, not
42
+ * the `latest` dist-tag: handing pnpm the tag makes it resolve the release a
43
+ * second time, and a release younger than `minimumReleaseAge` is then skipped
44
+ * without an error. A caller with no resolved version passes `@latest`, which
45
+ * is still better than a bare name.
46
+ * @param profile - the profile the plugin is installed into.
47
+ * @param version - the exact version to install.
48
+ * @returns the command, safe to show the user and to run.
49
+ */
50
+ export function pluginUpgradeCommand(profile = resolvePluginProfileName(), version = 'latest') {
51
+ const spec = version.trim() === '' ? 'latest' : version.trim();
52
+ return `dsh plugin --profile ${profile} add ${PLUGIN_PACKAGE}@${spec}`;
37
53
  }
38
54
  export function formatUpdateNotice(current, latest, profile = resolvePluginProfileName()) {
39
- return t('update.notice', { latest, current, command: pluginUpgradeCommand(profile) });
55
+ return t('update.notice', { latest, current, command: pluginUpgradeCommand(profile, latest) });
40
56
  }
41
57
  export async function fetchLatestNpmVersion(fetchImpl = fetch) {
42
58
  try {
@@ -67,7 +83,7 @@ export async function checkForPluginUpdate(current) {
67
83
  current,
68
84
  latest,
69
85
  profile,
70
- command: pluginUpgradeCommand(profile),
86
+ command: pluginUpgradeCommand(profile, latest),
71
87
  notice: formatUpdateNotice(current, latest, profile),
72
88
  };
73
89
  }
@@ -93,12 +109,13 @@ export function resolveDshInvocation(options = {}) {
93
109
  export function shellSafeProfile(profile) {
94
110
  return /\s/u.test(profile) ? `"${profile.replaceAll('"', '')}"` : profile;
95
111
  }
96
- export async function installPluginLatest(profile = resolvePluginProfileName(), deps = {}) {
112
+ export async function installPluginLatest(profile = resolvePluginProfileName(), version = 'latest', deps = {}) {
97
113
  const invocation = deps.invocation ?? resolveDshInvocation();
98
114
  const spawnFn = deps.spawnFn ?? spawn;
99
115
  const profileArg = invocation.shell ? shellSafeProfile(profile) : profile;
116
+ const spec = version.trim() === '' ? 'latest' : version.trim();
100
117
  return await new Promise(resolve => {
101
- const child = spawnFn(invocation.command, [...invocation.prefix, 'plugin', '--profile', profileArg, 'add', `${PLUGIN_PACKAGE}@latest`], {
118
+ const child = spawnFn(invocation.command, [...invocation.prefix, 'plugin', '--profile', profileArg, 'add', `${PLUGIN_PACKAGE}@${spec}`], {
102
119
  env: process.env,
103
120
  stdio: ['ignore', 'pipe', 'pipe'],
104
121
  shell: invocation.shell,
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}