myrlin-workbook 0.9.23 → 0.9.24
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/package.json +1 -1
- package/src/web/public/app.js +19 -62
package/package.json
CHANGED
package/src/web/public/app.js
CHANGED
|
@@ -9063,30 +9063,9 @@ class CWMApp {
|
|
|
9063
9063
|
* Preserves session info in terminalPanes[] for layout saves.
|
|
9064
9064
|
* Click reconnects via openTerminalInPane().
|
|
9065
9065
|
*/
|
|
9066
|
-
_showDisconnectedPlaceholder
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
const paneEl = document.getElementById(`term-pane-${slotIdx}`);
|
|
9070
|
-
if (!paneEl) return;
|
|
9071
|
-
paneEl.hidden = false;
|
|
9072
|
-
paneEl.classList.remove('terminal-pane-empty');
|
|
9073
|
-
const titleEl = paneEl.querySelector('.terminal-pane-title');
|
|
9074
|
-
if (titleEl) titleEl.textContent = sessionName || sessionId;
|
|
9075
|
-
const closeBtn = paneEl.querySelector('.terminal-pane-close');
|
|
9076
|
-
if (closeBtn) closeBtn.hidden = false;
|
|
9077
|
-
const container = document.getElementById(`term-container-${slotIdx}`);
|
|
9078
|
-
if (container) {
|
|
9079
|
-
container.innerHTML = `<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:var(--overlay0);font-size:13px;cursor:pointer;" class="reconnect-prompt">
|
|
9080
|
-
<span style="font-size:20px;">🔌</span>
|
|
9081
|
-
<span>${this.escapeHtml(sessionName || sessionId)}</span>
|
|
9082
|
-
<span style="font-size:11px;opacity:0.7;">Click to connect</span>
|
|
9083
|
-
</div>`;
|
|
9084
|
-
container.querySelector('.reconnect-prompt').addEventListener('click', () => {
|
|
9085
|
-
this.openTerminalInPane(slotIdx, sessionId, sessionName, spawnOpts);
|
|
9086
|
-
});
|
|
9087
|
-
}
|
|
9088
|
-
this.updateTerminalGridLayout();
|
|
9089
|
-
}
|
|
9066
|
+
// _showDisconnectedPlaceholder removed in v0.9.23 - caused more issues than it solved
|
|
9067
|
+
// (wrong pane on reconnect, unclosable panes, broken layout). Panes now connect
|
|
9068
|
+
// directly on restore and close cleanly on fatal error.
|
|
9090
9069
|
|
|
9091
9070
|
openTerminalInPane(slotIdx, sessionId, sessionName, spawnOpts) {
|
|
9092
9071
|
// Check localStorage for a previously saved name for this session
|
|
@@ -9095,12 +9074,6 @@ class CWMApp {
|
|
|
9095
9074
|
sessionName = savedTitle;
|
|
9096
9075
|
}
|
|
9097
9076
|
console.log('[DnD] openTerminalInPane slot:', slotIdx, 'session:', sessionId, 'name:', sessionName);
|
|
9098
|
-
// If the target slot has a disconnected placeholder, clear it so we reuse the slot.
|
|
9099
|
-
// Without this, "Click to connect" opens in a different pane instead of replacing.
|
|
9100
|
-
if (this.terminalPanes[slotIdx] && this.terminalPanes[slotIdx]._disconnected) {
|
|
9101
|
-
this.terminalPanes[slotIdx] = null;
|
|
9102
|
-
}
|
|
9103
|
-
|
|
9104
9077
|
// If the target slot already has an active terminal, find the next empty slot
|
|
9105
9078
|
if (this.terminalPanes[slotIdx]) {
|
|
9106
9079
|
const emptySlot = this.terminalPanes.findIndex(p => p === null);
|
|
@@ -9146,33 +9119,21 @@ class CWMApp {
|
|
|
9146
9119
|
});
|
|
9147
9120
|
};
|
|
9148
9121
|
|
|
9149
|
-
// On fatal connection error,
|
|
9150
|
-
// The session ID, name, and spawnOpts stay in the layout so the user can
|
|
9151
|
-
// reconnect by clicking, and layout saves don't lose the session mapping.
|
|
9122
|
+
// On fatal connection error, close the pane cleanly.
|
|
9152
9123
|
tp.onFatalError = (failedSessionId) => {
|
|
9153
9124
|
const idx = this.terminalPanes.indexOf(tp);
|
|
9154
9125
|
if (idx === -1) return;
|
|
9155
|
-
// Stash session info before disposing so we can offer reconnect
|
|
9156
|
-
const sid = tp.sessionId;
|
|
9157
|
-
const sName = tp.sessionName;
|
|
9158
|
-
const opts = { ...(tp.spawnOpts || {}) };
|
|
9159
9126
|
tp.dispose();
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
<span style="font-size:20px;">⚠</span>
|
|
9169
|
-
<span>${this.escapeHtml(sName || sid)}</span>
|
|
9170
|
-
<span style="font-size:11px;opacity:0.7;">Disconnected. Click to reconnect.</span>
|
|
9171
|
-
</div>`;
|
|
9172
|
-
container.querySelector('.reconnect-prompt').addEventListener('click', () => {
|
|
9173
|
-
this.openTerminalInPane(idx, sid, sName, opts);
|
|
9174
|
-
});
|
|
9127
|
+
this.terminalPanes[idx] = null;
|
|
9128
|
+
const deadPane = document.getElementById(`term-pane-${idx}`);
|
|
9129
|
+
if (deadPane) {
|
|
9130
|
+
deadPane.classList.add('terminal-pane-empty');
|
|
9131
|
+
const header = deadPane.querySelector('.terminal-pane-title');
|
|
9132
|
+
if (header) header.textContent = 'Drop a session here';
|
|
9133
|
+
const closeBtn2 = deadPane.querySelector('.terminal-pane-close');
|
|
9134
|
+
if (closeBtn2) closeBtn2.hidden = true;
|
|
9175
9135
|
}
|
|
9136
|
+
this.updateTerminalGridLayout();
|
|
9176
9137
|
};
|
|
9177
9138
|
|
|
9178
9139
|
// Enable auto-trust if the setting is on
|
|
@@ -12088,8 +12049,9 @@ class CWMApp {
|
|
|
12088
12049
|
if (cached.domFragments[i]) {
|
|
12089
12050
|
const termContainer = document.getElementById(`term-container-${i}`);
|
|
12090
12051
|
if (termContainer) termContainer.appendChild(cached.domFragments[i]);
|
|
12091
|
-
} else if (cached.panes[i].
|
|
12092
|
-
|
|
12052
|
+
} else if (cached.panes[i].sessionId) {
|
|
12053
|
+
// Cached pane had no DOM fragment (was disconnected), reconnect directly
|
|
12054
|
+
this.openTerminalInPane(i, cached.panes[i].sessionId, cached.panes[i].sessionName, cached.panes[i].spawnOpts);
|
|
12093
12055
|
}
|
|
12094
12056
|
}
|
|
12095
12057
|
}
|
|
@@ -12109,15 +12071,12 @@ class CWMApp {
|
|
|
12109
12071
|
}
|
|
12110
12072
|
});
|
|
12111
12073
|
} else {
|
|
12112
|
-
// No cache
|
|
12113
|
-
// Each PTY spawns a Claude process (~150MB), so eagerly connecting all
|
|
12114
|
-
// panes across all tab groups would consume gigabytes of system memory.
|
|
12115
|
-
// Users click a pane to connect on demand.
|
|
12074
|
+
// No cache, create fresh connections (first time opening this group)
|
|
12116
12075
|
const group = this._tabGroups.find(g => g.id === groupId);
|
|
12117
12076
|
if (group && group.panes) {
|
|
12118
12077
|
group.panes.forEach(p => {
|
|
12119
12078
|
if (p.sessionId && !this.terminalPanes[p.slot]) {
|
|
12120
|
-
this.
|
|
12079
|
+
this.openTerminalInPane(p.slot, p.sessionId, p.sessionName || 'Terminal', p.spawnOpts || {});
|
|
12121
12080
|
}
|
|
12122
12081
|
});
|
|
12123
12082
|
}
|
|
@@ -12147,9 +12106,7 @@ class CWMApp {
|
|
|
12147
12106
|
group.panes = [];
|
|
12148
12107
|
for (let i = 0; i < CWMApp.MAX_PANES; i++) {
|
|
12149
12108
|
const tp = this.terminalPanes[i];
|
|
12150
|
-
// Save
|
|
12151
|
-
// Disconnected placeholders have { sessionId, sessionName, spawnOpts, _disconnected: true }
|
|
12152
|
-
// and MUST be preserved so layout restores don't lose session mappings.
|
|
12109
|
+
// Save live TerminalPanes for layout restore.
|
|
12153
12110
|
if (tp && tp.sessionId) {
|
|
12154
12111
|
group.panes.push({
|
|
12155
12112
|
slot: i,
|