paris-immersion 0.1.3 → 0.1.4
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/index.js +1 -1
- package/dist/lib/relay-agent.js +35 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { serveCommand } from './commands/serve.js';
|
|
|
12
12
|
const program = new Command()
|
|
13
13
|
.name('paris')
|
|
14
14
|
.description('Paris Immersion — CLI do aluno (login, workspace, tarefas)')
|
|
15
|
-
.version('0.1.
|
|
15
|
+
.version('0.1.4');
|
|
16
16
|
program
|
|
17
17
|
.command('login')
|
|
18
18
|
.description('Autenticar com sua conta Paris (device-code OR --token direto)')
|
package/dist/lib/relay-agent.js
CHANGED
|
@@ -68,11 +68,15 @@ export async function startRelayAgent(opts) {
|
|
|
68
68
|
let closed = false;
|
|
69
69
|
let reconnect;
|
|
70
70
|
let killTimer;
|
|
71
|
+
// Tamanho atual do pty (spawnCoachPty começa 80x24). Usado pra detectar resize
|
|
72
|
+
// "no-op" (reconexão com mesma dimensão) e forçar o Claude a repintar.
|
|
73
|
+
let ptyCols = 80;
|
|
74
|
+
let ptyRows = 24;
|
|
71
75
|
// Mantém o Claude vivo por uma janela após o viewer sair, pra que uma
|
|
72
76
|
// reconexão (ex.: Safari derruba o ws periodicamente) REATACHE na MESMA sessão
|
|
73
77
|
// em vez de reiniciar o curso. O resize que o viewer manda ao reconectar faz a
|
|
74
78
|
// TUI do Claude repintar a tela atual.
|
|
75
|
-
const PTY_GRACE_MS =
|
|
79
|
+
const PTY_GRACE_MS = 600_000; // 10min — aluno que sai no meio e volta reatacha na MESMA sessão
|
|
76
80
|
const killPty = () => {
|
|
77
81
|
if (pty) {
|
|
78
82
|
try {
|
|
@@ -106,6 +110,28 @@ export async function startRelayAgent(opts) {
|
|
|
106
110
|
});
|
|
107
111
|
pty.onExit?.(() => killPty());
|
|
108
112
|
};
|
|
113
|
+
// Força o Claude a repintar a tela INTEIRA (não só os diffs). Necessário quando
|
|
114
|
+
// um viewer reconecta com um xterm em branco e manda o MESMO tamanho — sem
|
|
115
|
+
// mudança de tamanho não há SIGWINCH, então o Claude não redesenha e a tela
|
|
116
|
+
// fica vazia/quebrada. Um "nudge" (uma linha a menos e volta) gera o SIGWINCH.
|
|
117
|
+
const forceRepaint = () => {
|
|
118
|
+
if (!pty || ptyCols < 1 || ptyRows < 2)
|
|
119
|
+
return;
|
|
120
|
+
try {
|
|
121
|
+
pty.resize(ptyCols, ptyRows - 1);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
/* noop */
|
|
125
|
+
}
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
try {
|
|
128
|
+
pty?.resize(ptyCols, ptyRows);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* noop */
|
|
132
|
+
}
|
|
133
|
+
}, 80);
|
|
134
|
+
};
|
|
109
135
|
const connect = () => {
|
|
110
136
|
if (closed)
|
|
111
137
|
return;
|
|
@@ -148,13 +174,20 @@ export async function startRelayAgent(opts) {
|
|
|
148
174
|
}
|
|
149
175
|
else if (msg.type === TYPE_RESIZE) {
|
|
150
176
|
const [cols, rows] = msg.body.toString('utf8').split(',').map(Number);
|
|
151
|
-
if (Number.isFinite(cols) && Number.isFinite(rows)) {
|
|
177
|
+
if (Number.isFinite(cols) && Number.isFinite(rows) && cols > 0 && rows > 0) {
|
|
178
|
+
const same = cols === ptyCols && rows === ptyRows;
|
|
179
|
+
ptyCols = cols;
|
|
180
|
+
ptyRows = rows;
|
|
152
181
|
try {
|
|
153
182
|
pty.resize(cols, rows);
|
|
154
183
|
}
|
|
155
184
|
catch {
|
|
156
185
|
/* race de resize */
|
|
157
186
|
}
|
|
187
|
+
// Mesma dimensão (reconexão) não dispara SIGWINCH → o Claude não
|
|
188
|
+
// repinta e a tela fica em branco/quebrada. Força o repaint.
|
|
189
|
+
if (same)
|
|
190
|
+
forceRepaint();
|
|
158
191
|
}
|
|
159
192
|
}
|
|
160
193
|
});
|
package/package.json
CHANGED