@pixelbyte-software/pixcode 1.50.7 → 1.50.8
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/assets/{index-CR4j4iu_.js → index-gecaamTl.js} +69 -69
- package/dist/index.html +1 -1
- package/dist-server/server/index.js +91 -14
- package/dist-server/server/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/hermes/pixcode-mcp-server.mjs +35 -14
- package/scripts/smoke/hermes-mcp-pixcode-roundtrip.mjs +22 -1
- package/scripts/smoke/hermes-settings-commands.mjs +45 -0
- package/server/index.js +102 -13
package/dist/index.html
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
<!-- Prevent zoom on iOS -->
|
|
37
37
|
<meta name="format-detection" content="telephone=no" />
|
|
38
|
-
<script type="module" crossorigin src="/assets/index-
|
|
38
|
+
<script type="module" crossorigin src="/assets/index-gecaamTl.js"></script>
|
|
39
39
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-DB6V5Fl1.js">
|
|
40
40
|
<link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-CIYNS698.js">
|
|
41
41
|
<link rel="modulepreload" crossorigin href="/assets/vendor-xterm-C7tpxJl7.js">
|
|
@@ -118,6 +118,8 @@ let projectsWatchers = [];
|
|
|
118
118
|
let projectsWatcherDebounceTimer = null;
|
|
119
119
|
const connectedClients = new Set();
|
|
120
120
|
let isGetProjectsRunning = false; // Flag to prevent reentrant calls
|
|
121
|
+
const STARTUP_INPUT_READY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
122
|
+
const STARTUP_INPUT_POLL_MS = 750;
|
|
121
123
|
// Broadcast progress to all connected WebSocket clients
|
|
122
124
|
function broadcastProgress(progress) {
|
|
123
125
|
const message = JSON.stringify({
|
|
@@ -244,6 +246,10 @@ function terminatePtySession(sessionKey, session, reason) {
|
|
|
244
246
|
if (session.timeoutId) {
|
|
245
247
|
clearTimeout(session.timeoutId);
|
|
246
248
|
}
|
|
249
|
+
if (session.startupInputTimerId) {
|
|
250
|
+
clearTimeout(session.startupInputTimerId);
|
|
251
|
+
session.startupInputTimerId = null;
|
|
252
|
+
}
|
|
247
253
|
try {
|
|
248
254
|
if (session.pty && session.pty.kill) {
|
|
249
255
|
session.pty.kill();
|
|
@@ -360,24 +366,86 @@ function appendPtySessionBuffer(session, data) {
|
|
|
360
366
|
}
|
|
361
367
|
}
|
|
362
368
|
function normalizeTerminalStartupInput(input) {
|
|
363
|
-
return
|
|
369
|
+
return `\x15${String(input || '').replace(/(?:\r\n|\r|\n)+$/u, '')}\r`;
|
|
364
370
|
}
|
|
365
|
-
function
|
|
366
|
-
|
|
371
|
+
function readSessionOutputForState(session, maxChars = 12000) {
|
|
372
|
+
return stripAnsiSequences((session?.buffer || []).join('').slice(-maxChars));
|
|
373
|
+
}
|
|
374
|
+
function shouldWaitForProviderIdle(provider) {
|
|
375
|
+
return provider === 'codex';
|
|
376
|
+
}
|
|
377
|
+
function isTerminalReadyForStartupInput(session) {
|
|
378
|
+
if (!session?.pty || session.lifecycleState !== 'running') {
|
|
379
|
+
return { ready: false, retry: false, terminalState: 'exited' };
|
|
380
|
+
}
|
|
381
|
+
const output = readSessionOutputForState(session);
|
|
382
|
+
const state = resolveProviderTerminalState(session, session.provider, output);
|
|
383
|
+
if (state.terminalState === 'busy') {
|
|
384
|
+
return { ready: false, retry: true, terminalState: state.terminalState };
|
|
385
|
+
}
|
|
386
|
+
if (state.terminalState === 'idle') {
|
|
387
|
+
return { ready: true, retry: false, terminalState: state.terminalState };
|
|
388
|
+
}
|
|
389
|
+
if (shouldWaitForProviderIdle(session.provider)) {
|
|
390
|
+
return { ready: false, retry: true, terminalState: state.terminalState };
|
|
391
|
+
}
|
|
392
|
+
return { ready: true, retry: false, terminalState: state.terminalState };
|
|
393
|
+
}
|
|
394
|
+
function processTerminalStartupInputQueue(session) {
|
|
395
|
+
if (!session?.pendingStartupInputs?.length) {
|
|
396
|
+
session.startupInputTimerId = null;
|
|
367
397
|
return;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
398
|
+
}
|
|
399
|
+
const item = session.pendingStartupInputs[0];
|
|
400
|
+
const readiness = isTerminalReadyForStartupInput(session);
|
|
401
|
+
if (!readiness.ready) {
|
|
402
|
+
if (!readiness.retry || Date.now() - item.queuedAt > STARTUP_INPUT_READY_TIMEOUT_MS) {
|
|
403
|
+
session.pendingStartupInputs.shift();
|
|
404
|
+
session.startupInputTimerId = null;
|
|
405
|
+
const message = `\r\n\x1b[33m[Pixcode] Startup input was not sent because ${session.provider} is still ${readiness.terminalState || 'unavailable'}.\x1b[0m\r\n`;
|
|
406
|
+
try {
|
|
407
|
+
session.ws?.send?.(JSON.stringify({ type: 'output', data: message }));
|
|
375
408
|
}
|
|
409
|
+
catch { /* websocket gone */ }
|
|
410
|
+
if (session.pendingStartupInputs.length > 0) {
|
|
411
|
+
session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
376
414
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
415
|
+
session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
session.pendingStartupInputs.shift();
|
|
419
|
+
session.startupInputTimerId = null;
|
|
420
|
+
try {
|
|
421
|
+
session.pty.write(normalizeTerminalStartupInput(item.startupInput));
|
|
422
|
+
session.updatedAt = Date.now();
|
|
423
|
+
console.log(`⌨️ Submitted startup input to visible PTY (${item.reason})`);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
console.warn('Failed to submit startup input to visible PTY:', error?.message || error);
|
|
427
|
+
}
|
|
428
|
+
if (session.pendingStartupInputs.length > 0) {
|
|
429
|
+
session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function queueTerminalStartupInput(session, startupInput, reason, delayMs = 500) {
|
|
433
|
+
if (!session?.pty || !startupInput)
|
|
434
|
+
return;
|
|
435
|
+
if (!Array.isArray(session.pendingStartupInputs)) {
|
|
436
|
+
session.pendingStartupInputs = [];
|
|
437
|
+
}
|
|
438
|
+
session.pendingStartupInputs.push({
|
|
439
|
+
startupInput,
|
|
440
|
+
reason,
|
|
441
|
+
queuedAt: Date.now(),
|
|
442
|
+
});
|
|
443
|
+
if (session.startupInputTimerId)
|
|
444
|
+
return;
|
|
445
|
+
session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), delayMs);
|
|
446
|
+
}
|
|
447
|
+
function writeTerminalStartupInput(session, startupInput, reason, delayMs = 500) {
|
|
448
|
+
queueTerminalStartupInput(session, startupInput, reason, delayMs);
|
|
381
449
|
}
|
|
382
450
|
function normalizeShellPermissionMode(value) {
|
|
383
451
|
return typeof value === 'string' ? value.trim() : '';
|
|
@@ -2286,6 +2354,8 @@ function handleShellConnection(ws, request) {
|
|
|
2286
2354
|
});
|
|
2287
2355
|
}
|
|
2288
2356
|
existingSession.ws = ws;
|
|
2357
|
+
existingSession.hermesLaunchId = hermesLaunchId || existingSession.hermesLaunchId;
|
|
2358
|
+
existingSession.updatedAt = Date.now();
|
|
2289
2359
|
if (terminalStartupInput && !isPlainShell) {
|
|
2290
2360
|
writeTerminalStartupInput(existingSession, terminalStartupInput, 'reused provider session', 350);
|
|
2291
2361
|
}
|
|
@@ -2501,6 +2571,8 @@ function handleShellConnection(ws, request) {
|
|
|
2501
2571
|
exitSignal: null,
|
|
2502
2572
|
completedAt: null,
|
|
2503
2573
|
keepAliveUntilExit: false,
|
|
2574
|
+
pendingStartupInputs: [],
|
|
2575
|
+
startupInputTimerId: null,
|
|
2504
2576
|
updatedAt: Date.now(),
|
|
2505
2577
|
});
|
|
2506
2578
|
const createdSession = ptySessionsMap.get(ptySessionKey);
|
|
@@ -2565,6 +2637,11 @@ function handleShellConnection(ws, request) {
|
|
|
2565
2637
|
session.exitSignal = exitCode.signal || null;
|
|
2566
2638
|
session.completedAt = new Date().toISOString();
|
|
2567
2639
|
session.updatedAt = Date.now();
|
|
2640
|
+
if (session.startupInputTimerId) {
|
|
2641
|
+
clearTimeout(session.startupInputTimerId);
|
|
2642
|
+
session.startupInputTimerId = null;
|
|
2643
|
+
}
|
|
2644
|
+
session.pendingStartupInputs = [];
|
|
2568
2645
|
session.pty = null;
|
|
2569
2646
|
appendPtySessionBuffer(session, exitMessage);
|
|
2570
2647
|
}
|