codedash-app 3.0.1 → 3.0.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codedash-app",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "Termius-style browser dashboard for Claude Code sessions. View, search, resume, and delete sessions with a dark-themed UI.",
5
5
  "bin": {
6
6
  "codedash": "./bin/cli.js"
@@ -1626,22 +1626,15 @@ function focusSession(sessionId) {
1626
1626
  var a = activeSessions[sessionId];
1627
1627
  if (!a) { showToast('Session not active'); return; }
1628
1628
 
1629
- // Use osascript via the launch API to focus the terminal window
1630
- var terminal = localStorage.getItem('codedash-terminal') || '';
1631
- fetch('/api/launch', {
1629
+ fetch('/api/focus', {
1632
1630
  method: 'POST',
1633
1631
  headers: { 'Content-Type': 'application/json' },
1634
- body: JSON.stringify({
1635
- sessionId: sessionId,
1636
- tool: a.kind === 'codex' ? 'codex' : 'claude',
1637
- flags: ['focus'],
1638
- project: a.cwd || '',
1639
- terminal: terminal,
1640
- })
1641
- }).then(function() {
1642
- showToast('Focused terminal');
1632
+ body: JSON.stringify({ pid: a.pid })
1633
+ }).then(function(r) { return r.json(); }).then(function(data) {
1634
+ if (data.ok) showToast('Switched to terminal (PID ' + a.pid + ')');
1635
+ else showToast('Could not focus — try clicking the terminal manually');
1643
1636
  }).catch(function() {
1644
- showToast('Could not focus terminal');
1637
+ showToast('Focus failed');
1645
1638
  });
1646
1639
  }
1647
1640
 
package/src/server.js CHANGED
@@ -4,7 +4,7 @@ const https = require('https');
4
4
  const { URL } = require('url');
5
5
  const { exec } = require('child_process');
6
6
  const { loadSessions, loadSessionDetail, deleteSession, getGitCommits, exportSessionMarkdown, getSessionPreview, searchFullText, getActiveSessions, getSessionReplay, getCostAnalytics } = require('./data');
7
- const { detectTerminals, openInTerminal } = require('./terminals');
7
+ const { detectTerminals, openInTerminal, focusTerminalByPid } = require('./terminals');
8
8
  const { getHTML } = require('./html');
9
9
 
10
10
  function startServer(port, openBrowser = true) {
@@ -110,6 +110,19 @@ function startServer(port, openBrowser = true) {
110
110
  json(res, active);
111
111
  }
112
112
 
113
+ // ── Focus terminal ──────────────────────
114
+ else if (req.method === 'POST' && pathname === '/api/focus') {
115
+ readBody(req, body => {
116
+ try {
117
+ const { pid } = JSON.parse(body);
118
+ const ok = focusTerminalByPid(pid);
119
+ json(res, { ok });
120
+ } catch (e) {
121
+ json(res, { ok: false, error: e.message }, 400);
122
+ }
123
+ });
124
+ }
125
+
113
126
  // ── Session preview ─────────────────────
114
127
  else if (req.method === 'GET' && pathname.startsWith('/api/preview/')) {
115
128
  const sessionId = pathname.split('/').pop();
package/src/terminals.js CHANGED
@@ -157,4 +157,53 @@ function openInTerminal(sessionId, tool, flags, projectDir, terminalId) {
157
157
  }
158
158
  }
159
159
 
160
- module.exports = { detectTerminals, openInTerminal };
160
+ // ── Focus existing terminal by PID ──────────────────────────
161
+
162
+ function focusTerminalByPid(pid) {
163
+ const platform = process.platform;
164
+
165
+ if (platform === 'darwin') {
166
+ // Find which terminal app owns this PID's TTY, then activate it
167
+ try {
168
+ // Get TTY of the process
169
+ const ttyOut = execSync(`ps -p ${pid} -o tty= 2>/dev/null`, { encoding: 'utf8' }).trim();
170
+ if (!ttyOut) throw new Error('no tty');
171
+
172
+ // Try iTerm2 first — activate and select session by tty
173
+ try {
174
+ const script = `
175
+ tell application "iTerm"
176
+ activate
177
+ repeat with w in windows
178
+ repeat with t in tabs of w
179
+ repeat with s in sessions of t
180
+ if tty of s contains "${ttyOut}" then
181
+ select t
182
+ return
183
+ end if
184
+ end repeat
185
+ end repeat
186
+ end repeat
187
+ end tell
188
+ `;
189
+ execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, { stdio: 'pipe', timeout: 3000 });
190
+ return true;
191
+ } catch {}
192
+
193
+ // Fallback: just activate iTerm2 or Terminal.app
194
+ try {
195
+ execSync(`osascript -e 'tell application "iTerm" to activate'`, { stdio: 'pipe' });
196
+ return true;
197
+ } catch {}
198
+ try {
199
+ execSync(`osascript -e 'tell application "Terminal" to activate'`, { stdio: 'pipe' });
200
+ return true;
201
+ } catch {}
202
+ } catch {}
203
+ }
204
+
205
+ // Linux/other: not much we can do without window manager integration
206
+ return false;
207
+ }
208
+
209
+ module.exports = { detectTerminals, openInTerminal, focusTerminalByPid };