@pixelbyte-software/pixcode 1.50.7 → 1.50.9

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.
@@ -0,0 +1 @@
1
+ import{loader as r}from"./index-ak1p_4ew.js";import"./vendor-react-DB6V5Fl1.js";const e="/vendor/monaco-editor/min/vs";let o=!1;function i(){o||(r.config({paths:{vs:e}}),o=!0)}export{e as LOCAL_MONACO_BASE_PATH,i as ensureLocalMonaco};
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-CR4j4iu_.js"></script>
38
+ <script type="module" crossorigin src="/assets/index-CXTCtUku.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">
@@ -7,6 +7,7 @@ import path from 'path';
7
7
  import os from 'os';
8
8
  import http from 'http';
9
9
  import net from 'node:net';
10
+ import { createRequire } from 'node:module';
10
11
  import { spawn } from 'child_process';
11
12
  import express from 'express';
12
13
  import { WebSocketServer, WebSocket } from 'ws';
@@ -17,6 +18,8 @@ const __dirname = getModuleDir(import.meta.url);
17
18
  // The server source runs from /server, while the compiled output runs from /dist-server/server.
18
19
  // Resolving the app root once keeps every repo-level lookup below aligned across both layouts.
19
20
  const APP_ROOT = findAppRoot(__dirname);
21
+ const require = createRequire(import.meta.url);
22
+ const MONACO_ASSETS_ROUTE = '/vendor/monaco-editor/min/vs';
20
23
  const installMode = fs.existsSync(path.join(APP_ROOT, '.git')) ? 'git' : 'npm';
21
24
  const SERVER_VERSION = (() => {
22
25
  try {
@@ -32,6 +35,21 @@ const DAEMON_COMMAND_CONTEXT = {
32
35
  cliEntry: path.join(APP_ROOT, 'server', 'cli.js'),
33
36
  nodeExecPath: process.execPath,
34
37
  };
38
+ function resolveMonacoAssetsPath() {
39
+ const candidates = [
40
+ path.join(APP_ROOT, 'node_modules', 'monaco-editor', 'min', 'vs'),
41
+ ];
42
+ try {
43
+ const monacoPackagePath = require.resolve('monaco-editor/package.json', {
44
+ paths: [APP_ROOT, __dirname],
45
+ });
46
+ candidates.push(path.join(path.dirname(monacoPackagePath), 'min', 'vs'));
47
+ }
48
+ catch {
49
+ // The editor will show its normal load failure if the dependency is unavailable.
50
+ }
51
+ return candidates.find((candidate) => fs.existsSync(path.join(candidate, 'loader.js'))) || null;
52
+ }
35
53
  import { c } from './utils/colors.js';
36
54
  console.log('SERVER_PORT from env:', process.env.SERVER_PORT);
37
55
  import pty from 'node-pty';
@@ -118,6 +136,8 @@ let projectsWatchers = [];
118
136
  let projectsWatcherDebounceTimer = null;
119
137
  const connectedClients = new Set();
120
138
  let isGetProjectsRunning = false; // Flag to prevent reentrant calls
139
+ const STARTUP_INPUT_READY_TIMEOUT_MS = 10 * 60 * 1000;
140
+ const STARTUP_INPUT_POLL_MS = 750;
121
141
  // Broadcast progress to all connected WebSocket clients
122
142
  function broadcastProgress(progress) {
123
143
  const message = JSON.stringify({
@@ -244,6 +264,10 @@ function terminatePtySession(sessionKey, session, reason) {
244
264
  if (session.timeoutId) {
245
265
  clearTimeout(session.timeoutId);
246
266
  }
267
+ if (session.startupInputTimerId) {
268
+ clearTimeout(session.startupInputTimerId);
269
+ session.startupInputTimerId = null;
270
+ }
247
271
  try {
248
272
  if (session.pty && session.pty.kill) {
249
273
  session.pty.kill();
@@ -360,24 +384,86 @@ function appendPtySessionBuffer(session, data) {
360
384
  }
361
385
  }
362
386
  function normalizeTerminalStartupInput(input) {
363
- return `${String(input || '').replace(/(?:\r\n|\r|\n)+$/u, '')}\r`;
387
+ return `\x15${String(input || '').replace(/(?:\r\n|\r|\n)+$/u, '')}\r`;
364
388
  }
365
- function writeTerminalStartupInput(session, startupInput, reason, delayMs = 500) {
366
- if (!session?.pty || !startupInput)
389
+ function readSessionOutputForState(session, maxChars = 12000) {
390
+ return stripAnsiSequences((session?.buffer || []).join('').slice(-maxChars));
391
+ }
392
+ function shouldWaitForProviderIdle(provider) {
393
+ return provider === 'codex';
394
+ }
395
+ function isTerminalReadyForStartupInput(session) {
396
+ if (!session?.pty || session.lifecycleState !== 'running') {
397
+ return { ready: false, retry: false, terminalState: 'exited' };
398
+ }
399
+ const output = readSessionOutputForState(session);
400
+ const state = resolveProviderTerminalState(session, session.provider, output);
401
+ if (state.terminalState === 'busy') {
402
+ return { ready: false, retry: true, terminalState: state.terminalState };
403
+ }
404
+ if (state.terminalState === 'idle') {
405
+ return { ready: true, retry: false, terminalState: state.terminalState };
406
+ }
407
+ if (shouldWaitForProviderIdle(session.provider)) {
408
+ return { ready: false, retry: true, terminalState: state.terminalState };
409
+ }
410
+ return { ready: true, retry: false, terminalState: state.terminalState };
411
+ }
412
+ function processTerminalStartupInputQueue(session) {
413
+ if (!session?.pendingStartupInputs?.length) {
414
+ session.startupInputTimerId = null;
367
415
  return;
368
- const submittedInput = normalizeTerminalStartupInput(startupInput);
369
- setTimeout(() => {
370
- try {
371
- if (session.pty && session.lifecycleState === 'running') {
372
- session.pty.write(submittedInput);
373
- session.updatedAt = Date.now();
374
- console.log(`⌨️ Submitted startup input to visible PTY (${reason})`);
416
+ }
417
+ const item = session.pendingStartupInputs[0];
418
+ const readiness = isTerminalReadyForStartupInput(session);
419
+ if (!readiness.ready) {
420
+ if (!readiness.retry || Date.now() - item.queuedAt > STARTUP_INPUT_READY_TIMEOUT_MS) {
421
+ session.pendingStartupInputs.shift();
422
+ session.startupInputTimerId = null;
423
+ const message = `\r\n\x1b[33m[Pixcode] Startup input was not sent because ${session.provider} is still ${readiness.terminalState || 'unavailable'}.\x1b[0m\r\n`;
424
+ try {
425
+ session.ws?.send?.(JSON.stringify({ type: 'output', data: message }));
375
426
  }
427
+ catch { /* websocket gone */ }
428
+ if (session.pendingStartupInputs.length > 0) {
429
+ session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
430
+ }
431
+ return;
376
432
  }
377
- catch (error) {
378
- console.warn('Failed to submit startup input to visible PTY:', error?.message || error);
379
- }
380
- }, delayMs);
433
+ session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
434
+ return;
435
+ }
436
+ session.pendingStartupInputs.shift();
437
+ session.startupInputTimerId = null;
438
+ try {
439
+ session.pty.write(normalizeTerminalStartupInput(item.startupInput));
440
+ session.updatedAt = Date.now();
441
+ console.log(`⌨️ Submitted startup input to visible PTY (${item.reason})`);
442
+ }
443
+ catch (error) {
444
+ console.warn('Failed to submit startup input to visible PTY:', error?.message || error);
445
+ }
446
+ if (session.pendingStartupInputs.length > 0) {
447
+ session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), STARTUP_INPUT_POLL_MS);
448
+ }
449
+ }
450
+ function queueTerminalStartupInput(session, startupInput, reason, delayMs = 500) {
451
+ if (!session?.pty || !startupInput)
452
+ return;
453
+ if (!Array.isArray(session.pendingStartupInputs)) {
454
+ session.pendingStartupInputs = [];
455
+ }
456
+ session.pendingStartupInputs.push({
457
+ startupInput,
458
+ reason,
459
+ queuedAt: Date.now(),
460
+ });
461
+ if (session.startupInputTimerId)
462
+ return;
463
+ session.startupInputTimerId = setTimeout(() => processTerminalStartupInputQueue(session), delayMs);
464
+ }
465
+ function writeTerminalStartupInput(session, startupInput, reason, delayMs = 500) {
466
+ queueTerminalStartupInput(session, startupInput, reason, delayMs);
381
467
  }
382
468
  function normalizeShellPermissionMode(value) {
383
469
  return typeof value === 'string' ? value.trim() : '';
@@ -664,6 +750,18 @@ app.use('/api/agent', agentRoutes);
664
750
  // Static app files served after API routes. Keep dist before public so
665
751
  // / and /index.html always resolve to the Pixcode app, not the GitHub Pages
666
752
  // landing page that also lives in public/index.html.
753
+ const monacoAssetsPath = resolveMonacoAssetsPath();
754
+ if (monacoAssetsPath) {
755
+ app.use(MONACO_ASSETS_ROUTE, express.static(monacoAssetsPath, {
756
+ index: false,
757
+ setHeaders: (res) => {
758
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
759
+ },
760
+ }));
761
+ }
762
+ else {
763
+ console.warn('[monaco] Local Monaco assets not found; code editor loader may fail.');
764
+ }
667
765
  app.use(express.static(path.join(APP_ROOT, 'dist'), {
668
766
  setHeaders: (res, filePath) => {
669
767
  if (filePath.endsWith('.html')) {
@@ -2286,6 +2384,8 @@ function handleShellConnection(ws, request) {
2286
2384
  });
2287
2385
  }
2288
2386
  existingSession.ws = ws;
2387
+ existingSession.hermesLaunchId = hermesLaunchId || existingSession.hermesLaunchId;
2388
+ existingSession.updatedAt = Date.now();
2289
2389
  if (terminalStartupInput && !isPlainShell) {
2290
2390
  writeTerminalStartupInput(existingSession, terminalStartupInput, 'reused provider session', 350);
2291
2391
  }
@@ -2501,6 +2601,8 @@ function handleShellConnection(ws, request) {
2501
2601
  exitSignal: null,
2502
2602
  completedAt: null,
2503
2603
  keepAliveUntilExit: false,
2604
+ pendingStartupInputs: [],
2605
+ startupInputTimerId: null,
2504
2606
  updatedAt: Date.now(),
2505
2607
  });
2506
2608
  const createdSession = ptySessionsMap.get(ptySessionKey);
@@ -2565,6 +2667,11 @@ function handleShellConnection(ws, request) {
2565
2667
  session.exitSignal = exitCode.signal || null;
2566
2668
  session.completedAt = new Date().toISOString();
2567
2669
  session.updatedAt = Date.now();
2670
+ if (session.startupInputTimerId) {
2671
+ clearTimeout(session.startupInputTimerId);
2672
+ session.startupInputTimerId = null;
2673
+ }
2674
+ session.pendingStartupInputs = [];
2568
2675
  session.pty = null;
2569
2676
  appendPtySessionBuffer(session, exitMessage);
2570
2677
  }