@pixelbyte-software/pixcode 1.50.8 → 1.51.0

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-gecaamTl.js"></script>
38
+ <script type="module" crossorigin src="/assets/index-DJosGZ59.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';
@@ -518,6 +536,40 @@ function quoteShellArgForPlatform(value) {
518
536
  return os.platform() === 'win32' ? quotePowerShellArg(value) : quoteBashArg(value);
519
537
  }
520
538
  const HERMES_CLI_COMMAND_PATTERN = /^hermes(?:\s+[A-Za-z0-9._:/=@+-]+)*\s*$/;
539
+ const HERMES_AGENT_API_SCOPES = [
540
+ 'auth:read',
541
+ 'auth:write',
542
+ 'diagnostics:read',
543
+ 'files:read',
544
+ 'files:write',
545
+ 'git:read',
546
+ 'git:write',
547
+ 'hermes:mcp',
548
+ 'hermes:gateway',
549
+ 'notifications:read',
550
+ 'notifications:write',
551
+ 'orchestration:read',
552
+ 'orchestration:write',
553
+ 'plugins:read',
554
+ 'plugins:write',
555
+ 'projects:read',
556
+ 'projects:write',
557
+ 'providers:read',
558
+ 'providers:write',
559
+ 'remote:read',
560
+ 'remote:write',
561
+ 'sessions:read',
562
+ 'sessions:write',
563
+ 'settings:read',
564
+ 'settings:write',
565
+ 'telegram:read',
566
+ 'telegram:write',
567
+ 'terminal:launch',
568
+ 'updates:read',
569
+ 'updates:write',
570
+ 'webhooks:read',
571
+ 'webhooks:write',
572
+ ];
521
573
  function isHermesCliCommand(command) {
522
574
  return typeof command === 'string' && HERMES_CLI_COMMAND_PATTERN.test(command.trim());
523
575
  }
@@ -536,15 +588,14 @@ function getOrCreateHermesApiKey(userId) {
536
588
  .getApiKeys(userId)
537
589
  .find((key) => key.key_name === 'Hermes Agent MCP' && key.is_active);
538
590
  if (existing?.api_key) {
591
+ const existingScopes = Array.isArray(existing.scopes) ? existing.scopes : [];
592
+ const missingScopes = HERMES_AGENT_API_SCOPES.filter((scope) => !existingScopes.includes(scope));
593
+ if (missingScopes.length > 0 && existing.id) {
594
+ apiKeysDb.updateApiKeyScopes(userId, existing.id, [...existingScopes, ...missingScopes]);
595
+ }
539
596
  return existing.api_key;
540
597
  }
541
- return apiKeysDb.createApiKey(userId, 'Hermes Agent MCP', [
542
- 'hermes:mcp',
543
- 'hermes:gateway',
544
- 'projects:read',
545
- 'providers:read',
546
- 'terminal:launch',
547
- ]).apiKey;
598
+ return apiKeysDb.createApiKey(userId, 'Hermes Agent MCP', HERMES_AGENT_API_SCOPES).apiKey;
548
599
  }
549
600
  // Single WebSocket server that handles both paths
550
601
  const wss = new WebSocketServer({
@@ -664,6 +715,66 @@ app.get('/api/shell/sessions/provider-output', authenticateToken, (req, res) =>
664
715
  output,
665
716
  });
666
717
  });
718
+ app.post('/api/shell/sessions/provider-input', authenticateToken, (req, res) => {
719
+ const provider = String(req.body?.provider || 'claude');
720
+ const projectPath = typeof req.body?.projectPath === 'string' && req.body.projectPath.trim()
721
+ ? req.body.projectPath.trim()
722
+ : null;
723
+ const launchId = Number.parseInt(String(req.body?.launchId || ''), 10);
724
+ const requestedLaunchId = Number.isFinite(launchId) && launchId > 0 ? launchId : null;
725
+ const input = typeof req.body?.input === 'string' ? req.body.input : '';
726
+ const submit = req.body?.submit !== false;
727
+ if (!SHELL_CLI_PROVIDERS.has(provider)) {
728
+ return res.status(400).json({ error: 'Unsupported provider' });
729
+ }
730
+ const requestedProjectPath = projectPath ? path.resolve(projectPath) : null;
731
+ let matchedSession = null;
732
+ for (const session of ptySessionsMap.values()) {
733
+ if (session?.provider === provider &&
734
+ !session?.isPlainShell &&
735
+ session?.pty &&
736
+ session.lifecycleState === 'running' &&
737
+ (!requestedProjectPath || path.resolve(session.projectPath || os.homedir()) === requestedProjectPath) &&
738
+ (!requestedLaunchId || session.hermesLaunchId === requestedLaunchId)) {
739
+ if (!matchedSession || (session.updatedAt || 0) > (matchedSession.updatedAt || 0)) {
740
+ matchedSession = session;
741
+ }
742
+ }
743
+ }
744
+ if (!matchedSession?.pty) {
745
+ return res.status(404).json({
746
+ ok: false,
747
+ provider,
748
+ projectPath: requestedProjectPath,
749
+ launchId: requestedLaunchId,
750
+ wrote: false,
751
+ message: 'No running provider terminal session found for this project.',
752
+ });
753
+ }
754
+ const data = submit ? normalizeTerminalStartupInput(input) : input;
755
+ try {
756
+ matchedSession.pty.write(data);
757
+ matchedSession.updatedAt = Date.now();
758
+ res.json({
759
+ ok: true,
760
+ provider,
761
+ projectPath: path.resolve(matchedSession.projectPath || os.homedir()),
762
+ sessionId: matchedSession.sessionId || null,
763
+ launchId: matchedSession.hermesLaunchId || null,
764
+ wrote: true,
765
+ submitted: submit,
766
+ bytes: Buffer.byteLength(data),
767
+ });
768
+ }
769
+ catch (error) {
770
+ res.status(500).json({
771
+ ok: false,
772
+ provider,
773
+ wrote: false,
774
+ error: error instanceof Error ? error.message : String(error),
775
+ });
776
+ }
777
+ });
667
778
  // Authentication routes (public)
668
779
  app.use('/api/auth', authRoutes);
669
780
  // Projects API Routes (protected)
@@ -732,6 +843,18 @@ app.use('/api/agent', agentRoutes);
732
843
  // Static app files served after API routes. Keep dist before public so
733
844
  // / and /index.html always resolve to the Pixcode app, not the GitHub Pages
734
845
  // landing page that also lives in public/index.html.
846
+ const monacoAssetsPath = resolveMonacoAssetsPath();
847
+ if (monacoAssetsPath) {
848
+ app.use(MONACO_ASSETS_ROUTE, express.static(monacoAssetsPath, {
849
+ index: false,
850
+ setHeaders: (res) => {
851
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
852
+ },
853
+ }));
854
+ }
855
+ else {
856
+ console.warn('[monaco] Local Monaco assets not found; code editor loader may fail.');
857
+ }
735
858
  app.use(express.static(path.join(APP_ROOT, 'dist'), {
736
859
  setHeaders: (res, filePath) => {
737
860
  if (filePath.endsWith('.html')) {