nterminal 1.2.80 → 1.2.81
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/dist/client/assets/MarkdownPreview-Dq1fT9EP.js +1 -0
- package/dist/client/assets/{TranscriptMarkdownBody-BFu2FzgT.js → TranscriptMarkdownBody-DDFnUWuE.js} +1 -1
- package/dist/client/assets/{index-BFs4imuQ.js → index-D7w92nCI.js} +1 -1
- package/dist/client/assets/index-Di6LPXrS.js +57 -0
- package/dist/client/assets/{index-rROkcwjD.css → index-hoeidjW4.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/agent/agentRoutes.js +41 -1
- package/dist/server/agent/agentRoutes.js.map +1 -1
- package/dist/server/routes/agentManagementRoutes.js +29 -0
- package/dist/server/routes/agentManagementRoutes.js.map +1 -1
- package/dist/server/routes/terminalRoutes.js +51 -0
- package/dist/server/routes/terminalRoutes.js.map +1 -1
- package/dist/server/routes/terminalWebSocket.js +1 -1
- package/dist/server/routes/terminalWebSocket.js.map +1 -1
- package/dist/server/terminal/TerminalManager.d.ts +17 -2
- package/dist/server/terminal/TerminalManager.js +151 -62
- package/dist/server/terminal/TerminalManager.js.map +1 -1
- package/dist/server/terminal/TmuxPtyAdapter.d.ts +6 -0
- package/dist/server/terminal/TmuxPtyAdapter.js +29 -2
- package/dist/server/terminal/TmuxPtyAdapter.js.map +1 -1
- package/dist/server/terminal/codexTranscriptSource.d.ts +2 -2
- package/dist/server/terminal/codexTranscriptSource.js +1 -1
- package/dist/server/terminal/codexTranscriptSource.js.map +1 -1
- package/dist/server/terminal/subagentSources.d.ts +15 -0
- package/dist/server/terminal/subagentSources.js +801 -0
- package/dist/server/terminal/subagentSources.js.map +1 -0
- package/dist/server/terminal/transcriptHistory.d.ts +1 -0
- package/dist/server/terminal/transcriptHistory.js +24 -15
- package/dist/server/terminal/transcriptHistory.js.map +1 -1
- package/dist/shared/protocol.d.ts +18 -0
- package/dist/shared/protocol.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/MarkdownPreview-D2UZ6wJU.js +0 -1
- package/dist/client/assets/index-4MeJRcb6.js +0 -57
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminalWebSocket.js","sourceRoot":"","sources":["../../../src/server/routes/terminalWebSocket.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"terminalWebSocket.js","sourceRoot":"","sources":["../../../src/server/routes/terminalWebSocket.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AppConfig } from '../config.js';
|
|
2
|
-
import type { ServerTerminalMessage, TerminalHistoryCursor, TerminalHistoryResponse, TerminalTranscriptHistoryResponse, TerminalTranscriptSourceResponse } from '../../shared/protocol.js';
|
|
2
|
+
import type { ServerTerminalMessage, TerminalHistoryCursor, TerminalHistoryResponse, TerminalSubagentsResponse, TerminalTranscriptHistoryResponse, TerminalTranscriptSourceResponse } from '../../shared/protocol.js';
|
|
3
3
|
import type { TerminalCompletionOutcome, TerminalId, TerminalSummary } from '../../shared/types.js';
|
|
4
4
|
import { type PtyAdapter } from './PtyAdapter.js';
|
|
5
5
|
export interface CreateTerminalOptions {
|
|
@@ -40,7 +40,7 @@ export interface TerminalManagerCompletionEvent {
|
|
|
40
40
|
occurredAt: string;
|
|
41
41
|
}
|
|
42
42
|
export interface TerminalManagerDiagnostic {
|
|
43
|
-
event: 'terminal.status_poll_failed' | 'terminal.process_snapshot_failed' | 'terminal.restore_failed' | 'terminal.transcript_poll_failed' | 'terminal.transcript_poll_slow' | 'terminal.destroy_failed' | 'terminal.close_failed';
|
|
43
|
+
event: 'terminal.status_poll_failed' | 'terminal.process_snapshot_failed' | 'terminal.restore_failed' | 'terminal.transcript_poll_failed' | 'terminal.transcript_poll_slow' | 'terminal.reattach_failed' | 'terminal.destroy_failed' | 'terminal.close_failed';
|
|
44
44
|
terminalId?: TerminalId;
|
|
45
45
|
queueDepth?: number;
|
|
46
46
|
elapsedMs?: number;
|
|
@@ -78,6 +78,7 @@ export declare class TerminalManager {
|
|
|
78
78
|
private statusPollInflight;
|
|
79
79
|
private activeTranscriptWorkers;
|
|
80
80
|
private readonly pendingInitializations;
|
|
81
|
+
private readonly reattachInflight;
|
|
81
82
|
private terminalResetBlockers;
|
|
82
83
|
private terminalMutationGeneration;
|
|
83
84
|
private shutdownRequested;
|
|
@@ -115,6 +116,8 @@ export declare class TerminalManager {
|
|
|
115
116
|
snapshotPaneWidth?: number;
|
|
116
117
|
limit?: number;
|
|
117
118
|
}): Promise<TerminalHistoryResponse | null>;
|
|
119
|
+
private resolveLiveTranscriptSource;
|
|
120
|
+
private transcriptRequestStillLive;
|
|
118
121
|
getTerminalTranscriptHistory(id: TerminalId, options?: {
|
|
119
122
|
cursor?: string;
|
|
120
123
|
limit?: number;
|
|
@@ -122,10 +125,19 @@ export declare class TerminalManager {
|
|
|
122
125
|
includeTools?: boolean;
|
|
123
126
|
}): Promise<TerminalTranscriptHistoryResponse | null>;
|
|
124
127
|
getTerminalTranscriptSource(id: TerminalId): Promise<TerminalTranscriptSourceResponse | null>;
|
|
128
|
+
getTerminalSubagents(id: TerminalId): Promise<TerminalSubagentsResponse | null>;
|
|
129
|
+
getTerminalSubagentTranscript(id: TerminalId, subagentId: string, options?: {
|
|
130
|
+
cursor?: string;
|
|
131
|
+
limit?: number;
|
|
132
|
+
maxLines?: number;
|
|
133
|
+
includeTools?: boolean;
|
|
134
|
+
}): Promise<TerminalTranscriptHistoryResponse | null>;
|
|
125
135
|
resolveTerminalCwd(id: TerminalId): Promise<string | null>;
|
|
126
136
|
renameTerminal(id: TerminalId, title: string): Promise<RenameTerminalResult>;
|
|
127
137
|
refreshTerminalCwd(id: TerminalId): Promise<TerminalSummary | null>;
|
|
128
138
|
attachTerminal(id: TerminalId, subscriber: TerminalSubscriber, options?: AttachTerminalOptions): TerminalAttachment | null;
|
|
139
|
+
attachTerminalAsync(id: TerminalId, subscriber: TerminalSubscriber, options?: AttachTerminalOptions): Promise<TerminalAttachment | null>;
|
|
140
|
+
private createAttachment;
|
|
129
141
|
writeToTerminal(id: TerminalId, data: string, options?: WriteTerminalOptions): Promise<boolean>;
|
|
130
142
|
scrollTerminalScrollback(id: TerminalId, lines: number, options?: TerminalControlOptions): Promise<boolean>;
|
|
131
143
|
cancelTerminalScrollbackMode(id: TerminalId, options?: TerminalControlOptions): Promise<boolean>;
|
|
@@ -138,6 +150,9 @@ export declare class TerminalManager {
|
|
|
138
150
|
destroyAllTerminals(): Promise<DestroyAllTerminalsResult>;
|
|
139
151
|
private awaitPendingInitializations;
|
|
140
152
|
private ensureAttached;
|
|
153
|
+
private ensureAttachedAsync;
|
|
154
|
+
private attachOrRefresh;
|
|
155
|
+
private refreshAndAttach;
|
|
141
156
|
private resolveInitialCwd;
|
|
142
157
|
private safeResolveCwd;
|
|
143
158
|
private refreshCwd;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { normalizeTerminalTitle
|
|
3
|
+
import { normalizeTerminalTitle } from './PtyAdapter.js';
|
|
4
4
|
import { resolveProcessCwd } from './cwdResolver.js';
|
|
5
5
|
import { OutputBuffer } from './outputBuffer.js';
|
|
6
6
|
import { readTranscriptHistoryPage } from './transcriptHistory.js';
|
|
7
7
|
import { AgentTranscriptTracker } from './agentTranscriptStatus.js';
|
|
8
|
+
import { listTerminalSubagents, resolveSubagentTranscriptSource, subagentSummary } from './subagentSources.js';
|
|
8
9
|
import { mapWithConcurrency } from './asyncCommand.js';
|
|
9
10
|
// Window for the output-rate component of busy detection. Slightly larger
|
|
10
11
|
// than the poll interval so a tab that just stopped emitting output
|
|
@@ -51,6 +52,10 @@ export class TerminalManager {
|
|
|
51
52
|
statusPollInflight = false;
|
|
52
53
|
activeTranscriptWorkers = 0;
|
|
53
54
|
pendingInitializations = new Set();
|
|
55
|
+
// Restored tmux sessions start without a local PTY client. Keep a single
|
|
56
|
+
// reattach/catalog refresh in flight per terminal so an input burst cannot
|
|
57
|
+
// spawn competing tmux clients or repeatedly query the catalog.
|
|
58
|
+
reattachInflight = new Map();
|
|
54
59
|
terminalResetBlockers = 0;
|
|
55
60
|
terminalMutationGeneration = 0;
|
|
56
61
|
shutdownRequested = false;
|
|
@@ -110,14 +115,6 @@ export class TerminalManager {
|
|
|
110
115
|
this.reportDiagnostic({ event: 'terminal.process_snapshot_failed', terminalId, error });
|
|
111
116
|
}
|
|
112
117
|
}
|
|
113
|
-
for (const record of this.terminals.values()) {
|
|
114
|
-
if (record.summary.status === 'running' &&
|
|
115
|
-
!record.closing &&
|
|
116
|
-
record.pty === null &&
|
|
117
|
-
!result.has(record.summary.id)) {
|
|
118
|
-
this.markSessionUnavailable(record, null);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
118
|
}
|
|
122
119
|
applyProcessSnapshot(terminalId, snapshot, now) {
|
|
123
120
|
const record = this.terminals.get(terminalId);
|
|
@@ -550,17 +547,9 @@ export class TerminalManager {
|
|
|
550
547
|
record.summary.status = 'running';
|
|
551
548
|
record.summary.exitCode = null;
|
|
552
549
|
if (record.subscribers.size > 0) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
catch (error) {
|
|
557
|
-
if (error instanceof PtySessionUnavailableError) {
|
|
558
|
-
this.markSessionUnavailable(record, exitCode);
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
// Keep the live backing session lazily reattachable. A later
|
|
562
|
-
// browser reconnect can retry after a transient adapter failure.
|
|
563
|
-
}
|
|
550
|
+
// A local tmux client can exit while the backing session remains
|
|
551
|
+
// alive. Refresh the catalog before deciding it disappeared.
|
|
552
|
+
void this.ensureAttachedAsync(record);
|
|
564
553
|
}
|
|
565
554
|
record.summary.updatedAt = this.timestamp();
|
|
566
555
|
this.publish(record, { type: 'terminal_updated', terminal: cloneSummary(record.summary) });
|
|
@@ -642,7 +631,7 @@ export class TerminalManager {
|
|
|
642
631
|
if (!record || record.summary.status !== 'running' || record.closing) {
|
|
643
632
|
return null;
|
|
644
633
|
}
|
|
645
|
-
if (!record.pty && !this.
|
|
634
|
+
if (!record.pty && !await this.ensureAttachedAsync(record)) {
|
|
646
635
|
return null;
|
|
647
636
|
}
|
|
648
637
|
const limit = normalizeHistoryLimit(options.limit);
|
|
@@ -682,7 +671,10 @@ export class TerminalManager {
|
|
|
682
671
|
output: capture.output
|
|
683
672
|
};
|
|
684
673
|
}
|
|
685
|
-
|
|
674
|
+
// Shared liveness guard for the transcript endpoints: resolve the pane's
|
|
675
|
+
// source, re-validating the record after the await so a pane that closed
|
|
676
|
+
// or switched sessions mid-request never serves another session's data.
|
|
677
|
+
async resolveLiveTranscriptSource(id) {
|
|
686
678
|
const record = this.terminals.get(id);
|
|
687
679
|
if (!record || record.summary.status !== 'running' || record.closing) {
|
|
688
680
|
return null;
|
|
@@ -691,44 +683,74 @@ export class TerminalManager {
|
|
|
691
683
|
const source = await this.ptyAdapter.resolveTranscriptSource?.(id);
|
|
692
684
|
if (!source ||
|
|
693
685
|
!transcriptSourceMatchesForeground(record.summary, source.provider) ||
|
|
694
|
-
this.
|
|
695
|
-
record.summary.status !== 'running' ||
|
|
696
|
-
record.closing ||
|
|
697
|
-
record.transcriptGeneration !== generation) {
|
|
686
|
+
!this.transcriptRequestStillLive(id, record, generation)) {
|
|
698
687
|
return null;
|
|
699
688
|
}
|
|
700
|
-
|
|
701
|
-
|
|
689
|
+
return { record, generation, source };
|
|
690
|
+
}
|
|
691
|
+
transcriptRequestStillLive(id, record, generation) {
|
|
692
|
+
return this.terminals.get(id) === record &&
|
|
702
693
|
record.summary.status === 'running' &&
|
|
703
694
|
!record.closing &&
|
|
704
|
-
record.transcriptGeneration === generation
|
|
695
|
+
record.transcriptGeneration === generation;
|
|
696
|
+
}
|
|
697
|
+
async getTerminalTranscriptHistory(id, options = {}) {
|
|
698
|
+
const live = await this.resolveLiveTranscriptSource(id);
|
|
699
|
+
if (!live) {
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
const page = await readTranscriptHistoryPage(id, live.source, options);
|
|
703
|
+
return this.transcriptRequestStillLive(id, live.record, live.generation) ? page : null;
|
|
705
704
|
}
|
|
706
705
|
async getTerminalTranscriptSource(id) {
|
|
707
|
-
const
|
|
708
|
-
if (!
|
|
706
|
+
const live = await this.resolveLiveTranscriptSource(id);
|
|
707
|
+
if (!live) {
|
|
709
708
|
return null;
|
|
710
709
|
}
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
710
|
+
return {
|
|
711
|
+
terminalId: id,
|
|
712
|
+
source: { provider: live.source.provider, sessionId: live.source.sessionId }
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
async getTerminalSubagents(id) {
|
|
716
|
+
const live = await this.resolveLiveTranscriptSource(id);
|
|
717
|
+
if (!live) {
|
|
718
|
+
return null;
|
|
719
|
+
}
|
|
720
|
+
const subagents = await listTerminalSubagents(live.source);
|
|
721
|
+
if (!this.transcriptRequestStillLive(id, live.record, live.generation)) {
|
|
719
722
|
return null;
|
|
720
723
|
}
|
|
721
724
|
return {
|
|
722
725
|
terminalId: id,
|
|
723
|
-
source: { provider: source.provider, sessionId: source.sessionId }
|
|
726
|
+
source: { provider: live.source.provider, sessionId: live.source.sessionId },
|
|
727
|
+
subagents: subagents.map(subagentSummary)
|
|
724
728
|
};
|
|
725
729
|
}
|
|
730
|
+
async getTerminalSubagentTranscript(id, subagentId, options = {}) {
|
|
731
|
+
const live = await this.resolveLiveTranscriptSource(id);
|
|
732
|
+
if (!live) {
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
// Resolve the child through the server-side listing rather than trusting
|
|
736
|
+
// the client id as a path component: the transcript path is always
|
|
737
|
+
// server-derived.
|
|
738
|
+
const childSource = await resolveSubagentTranscriptSource(live.source, subagentId);
|
|
739
|
+
if (!childSource || !this.transcriptRequestStillLive(id, live.record, live.generation)) {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
const page = await readTranscriptHistoryPage(id, childSource, { ...options, archiveTrailer: false });
|
|
743
|
+
return this.transcriptRequestStillLive(id, live.record, live.generation) ? page : null;
|
|
744
|
+
}
|
|
726
745
|
async resolveTerminalCwd(id) {
|
|
727
746
|
const record = this.terminals.get(id);
|
|
728
|
-
if (!record || !this.
|
|
747
|
+
if (!record || !await this.ensureAttachedAsync(record)) {
|
|
729
748
|
return null;
|
|
730
749
|
}
|
|
731
750
|
const pty = record.pty;
|
|
751
|
+
if (!pty) {
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
732
754
|
const cwd = await this.safeResolveCwd(pty.pid);
|
|
733
755
|
return (cwd &&
|
|
734
756
|
this.terminals.get(id) === record &&
|
|
@@ -783,7 +805,7 @@ export class TerminalManager {
|
|
|
783
805
|
}
|
|
784
806
|
async refreshTerminalCwd(id) {
|
|
785
807
|
const record = this.terminals.get(id);
|
|
786
|
-
if (!record || !this.
|
|
808
|
+
if (!record || !await this.ensureAttachedAsync(record)) {
|
|
787
809
|
return null;
|
|
788
810
|
}
|
|
789
811
|
await this.refreshCwd(record);
|
|
@@ -804,6 +826,23 @@ export class TerminalManager {
|
|
|
804
826
|
if (record.summary.status === 'running' && !this.ensureAttached(record)) {
|
|
805
827
|
return null;
|
|
806
828
|
}
|
|
829
|
+
return this.createAttachment(record, subscriber, options);
|
|
830
|
+
}
|
|
831
|
+
async attachTerminalAsync(id, subscriber, options = {}) {
|
|
832
|
+
const record = this.terminals.get(id);
|
|
833
|
+
if (!record || record.closing) {
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
if (record.summary.status === 'running' && !await this.ensureAttachedAsync(record)) {
|
|
837
|
+
return null;
|
|
838
|
+
}
|
|
839
|
+
if (this.terminals.get(id) !== record || record.closing) {
|
|
840
|
+
return null;
|
|
841
|
+
}
|
|
842
|
+
return this.createAttachment(record, subscriber, options);
|
|
843
|
+
}
|
|
844
|
+
createAttachment(record, subscriber, options) {
|
|
845
|
+
const id = record.summary.id;
|
|
807
846
|
if (record.summary.status === 'running') {
|
|
808
847
|
record.history = typeof this.ptyAdapter.captureHistory === 'function'
|
|
809
848
|
? { startLine: 0, endLine: 0, hasMore: true }
|
|
@@ -854,7 +893,7 @@ export class TerminalManager {
|
|
|
854
893
|
return false;
|
|
855
894
|
}
|
|
856
895
|
if (record && !record.pty && record.summary.status === 'running' && !record.closing) {
|
|
857
|
-
this.
|
|
896
|
+
await this.ensureAttachedAsync(record);
|
|
858
897
|
}
|
|
859
898
|
if (!record?.pty ||
|
|
860
899
|
record.summary.status !== 'running' ||
|
|
@@ -888,25 +927,27 @@ export class TerminalManager {
|
|
|
888
927
|
return true;
|
|
889
928
|
}, inputBytes);
|
|
890
929
|
}
|
|
891
|
-
scrollTerminalScrollback(id, lines, options = {}) {
|
|
930
|
+
async scrollTerminalScrollback(id, lines, options = {}) {
|
|
892
931
|
const record = this.terminals.get(id);
|
|
893
932
|
const scroll = this.ptyAdapter.scrollbackScroll;
|
|
894
933
|
if (!controlOperationAllowed(options) ||
|
|
895
934
|
!record ||
|
|
896
935
|
record.summary.status !== 'running' ||
|
|
897
936
|
record.closing ||
|
|
898
|
-
!this.ensureAttached(record) ||
|
|
899
937
|
!scroll) {
|
|
900
|
-
return
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
if (!record.pty && !await this.ensureAttachedAsync(record)) {
|
|
941
|
+
return false;
|
|
901
942
|
}
|
|
902
943
|
const normalizedLines = clampScrollLines(lines);
|
|
903
944
|
const pending = record.pendingScroll;
|
|
904
945
|
if (pending) {
|
|
905
946
|
addPendingScrollDelta(pending.groups, options.canExecute, normalizedLines);
|
|
906
|
-
return pending.promise;
|
|
947
|
+
return await pending.promise;
|
|
907
948
|
}
|
|
908
949
|
if (!this.canEnqueueControl(record)) {
|
|
909
|
-
return
|
|
950
|
+
return false;
|
|
910
951
|
}
|
|
911
952
|
const groups = new Map();
|
|
912
953
|
addPendingScrollDelta(groups, options.canExecute, normalizedLines);
|
|
@@ -941,10 +982,12 @@ export class TerminalManager {
|
|
|
941
982
|
!record ||
|
|
942
983
|
record.summary.status !== 'running' ||
|
|
943
984
|
record.closing ||
|
|
944
|
-
!this.ensureAttached(record) ||
|
|
945
985
|
!this.canEnqueueControl(record)) {
|
|
946
986
|
return false;
|
|
947
987
|
}
|
|
988
|
+
if (!record.pty && !await this.ensureAttachedAsync(record)) {
|
|
989
|
+
return false;
|
|
990
|
+
}
|
|
948
991
|
this.sealPendingScroll(record);
|
|
949
992
|
return await this.enqueueControl(record, async () => {
|
|
950
993
|
if (!controlOperationAllowed(options) ||
|
|
@@ -1049,16 +1092,7 @@ export class TerminalManager {
|
|
|
1049
1092
|
record.summary.exitCode = null;
|
|
1050
1093
|
record.summary.updatedAt = this.timestamp();
|
|
1051
1094
|
if (record.subscribers.size > 0) {
|
|
1052
|
-
|
|
1053
|
-
this.reattachToSession(record);
|
|
1054
|
-
}
|
|
1055
|
-
catch (error) {
|
|
1056
|
-
if (error instanceof PtySessionUnavailableError) {
|
|
1057
|
-
this.markSessionUnavailable(record, null);
|
|
1058
|
-
return false;
|
|
1059
|
-
}
|
|
1060
|
-
// A later browser attach can retry after the transient failure.
|
|
1061
|
-
}
|
|
1095
|
+
void this.ensureAttachedAsync(record);
|
|
1062
1096
|
}
|
|
1063
1097
|
this.publish(record, {
|
|
1064
1098
|
type: 'terminal_updated',
|
|
@@ -1122,7 +1156,7 @@ export class TerminalManager {
|
|
|
1122
1156
|
await Promise.allSettled([...this.pendingInitializations]);
|
|
1123
1157
|
}
|
|
1124
1158
|
}
|
|
1125
|
-
ensureAttached(record) {
|
|
1159
|
+
ensureAttached(record, onAttachFailure) {
|
|
1126
1160
|
if (record.closing) {
|
|
1127
1161
|
return false;
|
|
1128
1162
|
}
|
|
@@ -1136,12 +1170,67 @@ export class TerminalManager {
|
|
|
1136
1170
|
this.reattachToSession(record);
|
|
1137
1171
|
}
|
|
1138
1172
|
catch (error) {
|
|
1139
|
-
|
|
1173
|
+
onAttachFailure?.(error);
|
|
1174
|
+
return false;
|
|
1175
|
+
}
|
|
1176
|
+
return record.pty !== null;
|
|
1177
|
+
}
|
|
1178
|
+
async ensureAttachedAsync(record) {
|
|
1179
|
+
if (this.terminals.get(record.summary.id) !== record ||
|
|
1180
|
+
record.closing ||
|
|
1181
|
+
record.summary.status !== 'running') {
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
if (record.pty)
|
|
1185
|
+
return true;
|
|
1186
|
+
if (!this.ptyAdapter.listExisting || !this.ptyAdapter.attachExisting) {
|
|
1187
|
+
return false;
|
|
1188
|
+
}
|
|
1189
|
+
const existing = this.reattachInflight.get(record.summary.id);
|
|
1190
|
+
if (existing) {
|
|
1191
|
+
return await existing;
|
|
1192
|
+
}
|
|
1193
|
+
const recovery = this.attachOrRefresh(record);
|
|
1194
|
+
this.reattachInflight.set(record.summary.id, recovery);
|
|
1195
|
+
try {
|
|
1196
|
+
return await recovery;
|
|
1197
|
+
}
|
|
1198
|
+
finally {
|
|
1199
|
+
if (this.reattachInflight.get(record.summary.id) === recovery) {
|
|
1200
|
+
this.reattachInflight.delete(record.summary.id);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
async attachOrRefresh(record) {
|
|
1205
|
+
if (this.ensureAttached(record)) {
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
return await this.refreshAndAttach(record);
|
|
1209
|
+
}
|
|
1210
|
+
async refreshAndAttach(record) {
|
|
1211
|
+
const id = record.summary.id;
|
|
1212
|
+
try {
|
|
1213
|
+
const existing = await this.ptyAdapter.listExisting?.();
|
|
1214
|
+
if (this.terminals.get(id) !== record ||
|
|
1215
|
+
record.closing ||
|
|
1216
|
+
record.summary.status !== 'running') {
|
|
1217
|
+
return false;
|
|
1218
|
+
}
|
|
1219
|
+
if (!existing?.some((session) => session.sessionId === id)) {
|
|
1140
1220
|
this.markSessionUnavailable(record, null);
|
|
1221
|
+
return false;
|
|
1141
1222
|
}
|
|
1223
|
+
// listExisting() refreshes the tmux adapter's pane-PID catalog. This
|
|
1224
|
+
// second attach is the only retry; terminal input itself is never
|
|
1225
|
+
// replayed by the manager.
|
|
1226
|
+
return this.ensureAttached(record, (attachError) => {
|
|
1227
|
+
this.reportDiagnostic({ event: 'terminal.reattach_failed', terminalId: id, error: attachError });
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
catch (error) {
|
|
1231
|
+
this.reportDiagnostic({ event: 'terminal.reattach_failed', terminalId: id, error });
|
|
1142
1232
|
return false;
|
|
1143
1233
|
}
|
|
1144
|
-
return record.pty !== null;
|
|
1145
1234
|
}
|
|
1146
1235
|
async resolveInitialCwd(options) {
|
|
1147
1236
|
if (options.cwd?.trim()) {
|