@volter/supercode-terminal 0.2.51 → 0.2.53
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/index.mjs +11 -6
- package/package.json +1 -1
- package/substrate/tmux.js +2 -1
package/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFile, spawn, spawnSync } from 'node:child_process';
|
|
2
2
|
import { randomBytes, randomUUID } from 'node:crypto';
|
|
3
|
-
import { appendFileSync, cpSync, existsSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { appendFileSync, cpSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { dirname, join } from 'node:path';
|
|
6
6
|
import { connect as netConnect } from 'node:net';
|
|
@@ -514,11 +514,15 @@ for (const event of ['end', 'close', 'error']) process.stdin.on(event, sweep);
|
|
|
514
514
|
* signal=…` when it failed), under SUPERCODE_HOME or ~/.config/supercode: the machine daemon tells a clean finish from
|
|
515
515
|
* a failure by it, and a ConPTY pane that ended cleanly is otherwise gone without a trace.
|
|
516
516
|
*/
|
|
517
|
-
function recordPaneExit(contextKey, exitCode, signal) {
|
|
517
|
+
function recordPaneExit(contextKey, exitCode, signal, screen = null) {
|
|
518
518
|
if (!contextKey) return;
|
|
519
519
|
const at = new Date().toISOString().slice(0, 19);
|
|
520
520
|
const line = exitCode === 0 && !signal ? `${at} ${contextKey} closed\n` : `${at} ${contextKey} died status=${exitCode ?? ''} signal=${signal || ''}\n`;
|
|
521
521
|
try { appendFileSync(join(process.env.SUPERCODE_HOME || join(homedir(), '.config', 'supercode'), 'pane-exits.log'), line); } catch { /* no log is no worse than before */ }
|
|
522
|
+
if ((exitCode !== 0 || signal) && typeof screen === 'string' && /^p_[A-Za-z0-9_-]+$/.test(contextKey)) {
|
|
523
|
+
try { const dir=join(process.env.SUPERCODE_HOME || join(homedir(), '.config', 'supercode'),'pane-exits');mkdirSync(dir,{recursive:true,mode:0o700});writeFileSync(join(dir,`${contextKey}.screen`),Buffer.from(screen).subarray(-32768),{mode:0o600}); }
|
|
524
|
+
catch { /* The receipt explicitly reports unavailable output. */ }
|
|
525
|
+
}
|
|
522
526
|
}
|
|
523
527
|
|
|
524
528
|
export class PtyTerminalHost {
|
|
@@ -597,7 +601,7 @@ export class PtyTerminalHost {
|
|
|
597
601
|
// server) outlives it, as it outlives a tmux pane. What stayed in the pane's console ends with the console.
|
|
598
602
|
// Only closing a pane, or its daemon dying, ends a whole tree.
|
|
599
603
|
releasePane(child);
|
|
600
|
-
recordPaneExit(entry.contextKey, exitCode, signal);
|
|
604
|
+
recordPaneExit(entry.contextKey, exitCode, signal, entry.serializer.serialize({scrollback:200}));
|
|
601
605
|
this.#tellExit(entry);
|
|
602
606
|
this.#writeWatchList();
|
|
603
607
|
if (exitCode === 0) this.#forget(entry);
|
|
@@ -1739,7 +1743,7 @@ export function composerText(kind, screen) {
|
|
|
1739
1743
|
const lines = String(screen ?? '').split('\n').map(styledCells);
|
|
1740
1744
|
const plain = lines.map((cells) => cells.map((cell) => cell.char).join(''));
|
|
1741
1745
|
const rule = /^\s*[─━]{4,}\s*$/u;
|
|
1742
|
-
const footer = /^\s*(?:\? for shortcuts\b
|
|
1746
|
+
const footer = /^\s*(?:\? for shortcuts\b|⚠\s+\d+\s+warnings?\s+·\s+f2 to view\s*$|[^\n]+ · (?:~(?:[\\/]|(?=\s|$))|[\\/]|[A-Z]:[\\/])[^\n]*$|.*← for agents\s*$|.*\bcontext(?:\s+\d+%)?\s+left\b)/iu;
|
|
1743
1747
|
const caret = kind === 'codex' ? /^\s*›(?:\s|$)/u : /^\s*[❯>](?:\s|$)/u;
|
|
1744
1748
|
for (let row = plain.length - 1; row >= 0; row -= 1) {
|
|
1745
1749
|
if (!caret.test(plain[row])) continue;
|
|
@@ -1748,8 +1752,9 @@ export function composerText(kind, screen) {
|
|
|
1748
1752
|
// Claude encloses the editor in rules; Codex ends it at its shortcut/context footer.
|
|
1749
1753
|
if (end === plain.length) return null;
|
|
1750
1754
|
// Startup can draw a caret before loading finishes or a modal opens. A rule
|
|
1751
|
-
// alone is not Codex's ready editor; require
|
|
1752
|
-
|
|
1755
|
+
// alone is not Codex's ready editor; require only recognized footer rows at
|
|
1756
|
+
// the live bottom (model/cwd and shortcuts can occupy separate rows).
|
|
1757
|
+
if (kind === 'codex' && (plain.slice(end + 1).some((line) => line.trim() && !footer.test(line)) ||
|
|
1753
1758
|
/\bmodel:\s+loading\b/iu.test(plain.findLast((line) => /\bmodel:/iu.test(line)) ?? ''))) return null;
|
|
1754
1759
|
if (kind === 'claude-code' && (row === 0 || !rule.test(plain[row - 1]))) return null;
|
|
1755
1760
|
const first = plain[row].match(caret)[0].length;
|
package/package.json
CHANGED
package/substrate/tmux.js
CHANGED
|
@@ -343,7 +343,8 @@ async function declareSessionColorEnvironmentAsync(socket) {
|
|
|
343
343
|
// Targets are not expanded as formats, so the shell that run-shell starts resolves
|
|
344
344
|
// the pane and does nothing when it no longer belongs to a p_* session.
|
|
345
345
|
const PANE_EXIT_LOG = '"${SUPERCODE_HOME:-$HOME/.config/supercode}/pane-exits.log"';
|
|
346
|
-
const
|
|
346
|
+
const PANE_EXIT_CAPTURE = 'case "$s" in *[!a-zA-Z0-9_-]*) exit 0 ;; esac; d="${SUPERCODE_HOME:-$HOME/.config/supercode}/pane-exits"; umask 077; mkdir -p "$d"; t capture-pane -p -e -S -200 -t "$p" 2>/dev/null | tail -c 32768 > "$d/$s.screen"';
|
|
347
|
+
const PANE_DIED_HOOK = "run-shell 'p=\"#{hook_pane}\"; t() { tmux -S \"#{socket_path}\" \"$@\"; }; s=$(t display -p -t \"$p\" \"##{session_name}\" 2>/dev/null) || exit 0; case \"$s\" in p_*) ;; *) exit 0 ;; esac; printf \"%s %s died status=%s signal=%s\\n\" \"$(date +%FT%T)\" \"$s\" \"$(t display -p -t \"$p\" \"##{pane_dead_status}\")\" \"$(t display -p -t \"$p\" \"##{pane_dead_signal}\")\" >> " + PANE_EXIT_LOG + "; " + PANE_EXIT_CAPTURE + "; t kill-pane -t \"$p\"'";
|
|
347
348
|
const SESSION_CLOSED_HOOK = "if-shell -F '#{m:p_*,#{hook_session_name}}' { run-shell 'printf \"%s %s closed\\n\" \"$(date +%FT%T)\" \"#{hook_session_name}\" >> " + PANE_EXIT_LOG + "' }";
|
|
348
349
|
function sessionServerOptionArgs() {
|
|
349
350
|
return [
|