tabminal 3.0.13 → 3.0.14

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.
@@ -80,6 +80,20 @@ function uniqueStringList(values) {
80
80
  function normalizeWorkspaceState(input = {}, fallback = {}) {
81
81
  const source = input && typeof input === 'object' ? input : {};
82
82
  const base = fallback && typeof fallback === 'object' ? fallback : {};
83
+ const activeWorkspaceTabKey = typeof source.activeWorkspaceTabKey === 'string'
84
+ ? source.activeWorkspaceTabKey
85
+ : (
86
+ typeof base.activeWorkspaceTabKey === 'string'
87
+ ? base.activeWorkspaceTabKey
88
+ : ''
89
+ );
90
+ const markdownSplitPath = typeof source.markdownSplitPath === 'string'
91
+ ? source.markdownSplitPath
92
+ : (
93
+ typeof base.markdownSplitPath === 'string'
94
+ ? base.markdownSplitPath
95
+ : ''
96
+ );
83
97
  return {
84
98
  updatedAt: Number.isFinite(source.updatedAt)
85
99
  ? source.updatedAt
@@ -100,7 +114,9 @@ function normalizeWorkspaceState(input = {}, fallback = {}) {
100
114
  terminalDisplayMode: source.terminalDisplayMode === 'tab'
101
115
  ? 'tab'
102
116
  : 'auto',
103
- expandedPaths: uniqueStringList(source.expandedPaths)
117
+ expandedPaths: uniqueStringList(source.expandedPaths),
118
+ markdownSplitPath,
119
+ activeWorkspaceTabKey
104
120
  };
105
121
  }
106
122
 
@@ -131,6 +147,70 @@ export class TerminalManager {
131
147
  this.disposing = false;
132
148
  }
133
149
 
150
+ getLatestWorkspaceSession() {
151
+ let bestSession = null;
152
+ let bestWorkspaceUpdatedAt = -1;
153
+ let bestTerminalUpdatedAt = -1;
154
+ let bestCreatedAt = -1;
155
+
156
+ for (const session of this.sessions.values()) {
157
+ const cwd = typeof session?.cwd === 'string'
158
+ ? session.cwd.trim()
159
+ : '';
160
+ if (!cwd) continue;
161
+
162
+ const workspaceUpdatedAt = Number.isFinite(
163
+ session?.editorState?.updatedAt
164
+ )
165
+ ? session.editorState.updatedAt
166
+ : 0;
167
+ const terminalUpdatedAt = session?.updatedAt instanceof Date
168
+ ? session.updatedAt.getTime()
169
+ : Date.parse(session?.updatedAt || '') || 0;
170
+ const createdAt = session?.createdAt instanceof Date
171
+ ? session.createdAt.getTime()
172
+ : Date.parse(session?.createdAt || '') || 0;
173
+
174
+ const isBetterWorkspace = (
175
+ workspaceUpdatedAt > bestWorkspaceUpdatedAt
176
+ );
177
+ const isSameWorkspace = (
178
+ workspaceUpdatedAt === bestWorkspaceUpdatedAt
179
+ );
180
+ const isBetterTerminal = (
181
+ isSameWorkspace
182
+ && terminalUpdatedAt > bestTerminalUpdatedAt
183
+ );
184
+ const isSameTerminal = (
185
+ isSameWorkspace
186
+ && terminalUpdatedAt === bestTerminalUpdatedAt
187
+ );
188
+ const isBetterCreated = (
189
+ isSameTerminal
190
+ && createdAt > bestCreatedAt
191
+ );
192
+
193
+ if (
194
+ isBetterWorkspace
195
+ || isBetterTerminal
196
+ || isBetterCreated
197
+ ) {
198
+ bestSession = session;
199
+ bestWorkspaceUpdatedAt = workspaceUpdatedAt;
200
+ bestTerminalUpdatedAt = terminalUpdatedAt;
201
+ bestCreatedAt = createdAt;
202
+ }
203
+ }
204
+
205
+ return bestSession;
206
+ }
207
+
208
+ getDefaultSessionCwd() {
209
+ return this.getLatestWorkspaceSession()?.cwd
210
+ || process.env.TABMINAL_CWD
211
+ || os.homedir();
212
+ }
213
+
134
214
  queueSessionPersistence(id, operation) {
135
215
  const previous = this.sessionPersistenceChains.get(id)
136
216
  || Promise.resolve();
@@ -316,10 +396,25 @@ precmd_functions+=(_tabminal_zsh_apply_prompt_marker)
316
396
  }
317
397
 
318
398
  createSession(restoredData = null) {
399
+ const isRestoredSession = !!(
400
+ restoredData
401
+ && typeof restoredData === 'object'
402
+ && (
403
+ restoredData.id
404
+ || restoredData.createdAt
405
+ || restoredData.executions
406
+ || restoredData.editorState
407
+ || restoredData.workspaceState
408
+ )
409
+ );
319
410
  return this._createPtySession({
320
411
  id: restoredData?.id,
321
412
  shell: resolveShell(),
322
- cwd: restoredData?.cwd,
413
+ cwd: restoredData?.cwd || (
414
+ isRestoredSession
415
+ ? undefined
416
+ : this.getDefaultSessionCwd()
417
+ ),
323
418
  cols: restoredData?.cols,
324
419
  rows: restoredData?.rows,
325
420
  createdAt: restoredData?.createdAt,
@@ -167,6 +167,22 @@ function selectFallbackQueryResponder(clients, pendingClients) {
167
167
  return null;
168
168
  }
169
169
 
170
+ function isIgnorablePtyResizeError(error) {
171
+ if (!error) {
172
+ return false;
173
+ }
174
+
175
+ if (error.code === 'EBADF') {
176
+ return true;
177
+ }
178
+
179
+ const message = String(error.message || '');
180
+ return (
181
+ /ioctl\(2\) failed/i.test(message)
182
+ || /bad file descriptor/i.test(message)
183
+ );
184
+ }
185
+
170
186
  export class TerminalSession {
171
187
  constructor(pty, options = {}) {
172
188
  this.pty = pty;
@@ -488,7 +504,14 @@ export class TerminalSession {
488
504
 
489
505
  resize(cols, rows) {
490
506
  if (this.closed) return;
491
- this.pty.resize(cols, rows);
507
+ try {
508
+ this.pty.resize(cols, rows);
509
+ } catch (error) {
510
+ if (isIgnorablePtyResizeError(error)) {
511
+ return;
512
+ }
513
+ throw error;
514
+ }
492
515
  this._queueSnapshotMutation(() => {
493
516
  this.snapshotTerminal.resize(cols, rows);
494
517
  });