@cloudcli-ai/cloudcli 1.33.2 → 1.33.3

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.
@@ -5,6 +5,38 @@ import { scanPlugins, getPluginsConfig, getPluginDir } from './plugin-loader.js'
5
5
  const runningPlugins = new Map();
6
6
  // Map<pluginName, Promise<port>> — in-flight start operations
7
7
  const startingPlugins = new Map();
8
+ /**
9
+ * Build the environment handed to a plugin server subprocess.
10
+ *
11
+ * Intentionally minimal: only non-secret essentials, never the host's full
12
+ * environment. On Windows a handful of system variables are required for any
13
+ * child to bootstrap (Node itself, and any Python or CLI a plugin shells out
14
+ * to). Without APPDATA a `pip install --user` tool cannot locate its
15
+ * site-packages and fails to import; SystemRoot, PATHEXT and TEMP are needed to
16
+ * resolve system DLLs, executable extensions and a temp directory. None of
17
+ * these carry secrets, so the ones that are set get passed straight through.
18
+ */
19
+ function buildPluginEnv(name) {
20
+ const env = {
21
+ PATH: process.env.PATH,
22
+ HOME: process.env.HOME,
23
+ NODE_ENV: process.env.NODE_ENV || 'production',
24
+ PLUGIN_NAME: name,
25
+ };
26
+ if (process.platform === 'win32') {
27
+ const WINDOWS_ESSENTIALS = [
28
+ 'SystemRoot', 'windir', 'SystemDrive',
29
+ 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA',
30
+ 'TEMP', 'TMP', 'PATHEXT',
31
+ ];
32
+ for (const key of WINDOWS_ESSENTIALS) {
33
+ if (process.env[key] !== undefined) {
34
+ env[key] = process.env[key];
35
+ }
36
+ }
37
+ }
38
+ return env;
39
+ }
8
40
  /**
9
41
  * Start a plugin's server subprocess.
10
42
  * The plugin's server entry must print a JSON line with { ready: true, port: <number> }
@@ -20,15 +52,9 @@ export function startPluginServer(name, pluginDir, serverEntry) {
20
52
  }
21
53
  const startPromise = new Promise((resolve, reject) => {
22
54
  const serverPath = path.join(pluginDir, serverEntry);
23
- // Restricted env — only essentials, no host secrets
24
55
  const pluginProcess = spawn('node', [serverPath], {
25
56
  cwd: pluginDir,
26
- env: {
27
- PATH: process.env.PATH,
28
- HOME: process.env.HOME,
29
- NODE_ENV: process.env.NODE_ENV || 'production',
30
- PLUGIN_NAME: name,
31
- },
57
+ env: buildPluginEnv(name),
32
58
  stdio: ['ignore', 'pipe', 'pipe'],
33
59
  });
34
60
  let resolved = false;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-process-manager.js","sourceRoot":"","sources":["../../../server/utils/plugin-process-manager.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-process-manager.js","sourceRoot":"","sources":["../../../server/utils/plugin-process-manager.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjF,qCAAqC;AACrC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAE,CAAC;AACjC,8DAA8D;AAC9D,MAAM,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;AAElC;;;;;;;;;;GAUG;AACH,SAAS,cAAc,CAAC,IAAI;IAC1B,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI;QACtB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI;QACtB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,YAAY;QAC9C,WAAW,EAAE,IAAI;KAClB,CAAC;IAEF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,kBAAkB,GAAG;YACzB,YAAY,EAAE,QAAQ,EAAE,aAAa;YACrC,aAAa,EAAE,SAAS,EAAE,cAAc;YACxC,MAAM,EAAE,KAAK,EAAE,SAAS;SACzB,CAAC;QACF,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBACnC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW;IAC5D,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,iDAAiD;IACjD,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAEnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAErD,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE;YAChD,GAAG,EAAE,SAAS;YACd,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC;YACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,aAAa,CAAC,IAAI,EAAE,CAAC;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvC,IAAI,QAAQ;gBAAE,OAAO;YACrB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAE1B,+BAA+B;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACpC,IAAI,GAAG,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC9C,YAAY,CAAC,OAAO,CAAC,CAAC;wBACtB,QAAQ,GAAG,IAAI,CAAC;wBAChB,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;wBAErE,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;4BAC5B,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC9B,CAAC,CAAC,CAAC;wBAEH,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,aAAa,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;wBAC1E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,+BAA+B;gBACjC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvC,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAChC,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,kCAAkC,IAAI,yBAAyB,CAAC,CAAC,CAAC;YACrF,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QACd,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACxC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAI;IACnC,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAErC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,YAAY,CAAC,cAAc,CAAC,CAAC;YAC7B,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEpC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE9B,8CAA8C;QAC9C,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACrC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAI;IAChC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAI;IAClC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,SAAS;QAC7B,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,KAAK,KAAK;YAAE,SAAS;QAErD,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,IAAI,CAAC;YACH,MAAM,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yCAAyC,MAAM,CAAC,IAAI,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcli-ai/cloudcli",
3
- "version": "1.33.2",
3
+ "version": "1.33.3",
4
4
  "description": "A web-based UI for Claude Code CLI",
5
5
  "type": "module",
6
6
  "main": "dist-server/server/index.js",
package/server/cli.js CHANGED
@@ -455,7 +455,7 @@ async function sandboxCommand(args) {
455
455
  await new Promise(resolve => setTimeout(resolve, 5000));
456
456
 
457
457
  console.log(`${c.info('▶')} Launching CloudCLI web server...`);
458
- sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
458
+ sbx(['exec', opts.name, 'bash', '-c', 'nohup cloudcli start --port 3001 > /tmp/cloudcli-ui.log 2>&1 & disown']);
459
459
 
460
460
  console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
461
461
  try {
@@ -554,7 +554,7 @@ async function sandboxCommand(args) {
554
554
 
555
555
  // Step 3: Start CloudCLI inside the sandbox
556
556
  console.log(`${c.info('▶')} Launching CloudCLI web server...`);
557
- sbx(['exec', opts.name, 'bash', '-c', 'cloudcli start --port 3001 &']);
557
+ sbx(['exec', opts.name, 'bash', '-c', 'nohup cloudcli start --port 3001 > /tmp/cloudcli-ui.log 2>&1 & disown']);
558
558
 
559
559
  // Step 4: Forward port
560
560
  console.log(`${c.info('▶')} Forwarding port ${opts.port} → 3001...`);
package/server/index.js CHANGED
@@ -84,6 +84,9 @@ const __dirname = getModuleDir(import.meta.url);
84
84
  // Resolving the app root once keeps every repo-level lookup below aligned across both layouts.
85
85
  const APP_ROOT = findAppRoot(__dirname);
86
86
  const installMode = fs.existsSync(path.join(APP_ROOT, '.git')) ? 'git' : 'npm';
87
+ const MAX_FILE_UPLOAD_SIZE_MB = 200;
88
+ const MAX_FILE_UPLOAD_SIZE_BYTES = MAX_FILE_UPLOAD_SIZE_MB * 1024 * 1024;
89
+ const MAX_FILE_UPLOAD_COUNT = 20;
87
90
 
88
91
  console.log('SERVER_PORT from env:', process.env.SERVER_PORT);
89
92
 
@@ -897,27 +900,27 @@ const uploadFilesHandler = async (req, res) => {
897
900
  }
898
901
  }),
899
902
  limits: {
900
- fileSize: 50 * 1024 * 1024, // 50MB limit
901
- files: 20 // Max 20 files at once
903
+ fileSize: MAX_FILE_UPLOAD_SIZE_BYTES,
904
+ files: MAX_FILE_UPLOAD_COUNT
902
905
  }
903
906
  });
904
907
 
905
908
  // Use multer middleware
906
- uploadMiddleware.array('files', 20)(req, res, async (err) => {
909
+ uploadMiddleware.array('files', MAX_FILE_UPLOAD_COUNT)(req, res, async (err) => {
907
910
  if (err) {
908
911
  console.error('Multer error:', err);
909
912
  if (err.code === 'LIMIT_FILE_SIZE') {
910
- return res.status(400).json({ error: 'File too large. Maximum size is 50MB.' });
913
+ return res.status(400).json({ error: `File too large. Maximum size is ${MAX_FILE_UPLOAD_SIZE_MB}MB.` });
911
914
  }
912
915
  if (err.code === 'LIMIT_FILE_COUNT') {
913
- return res.status(400).json({ error: 'Too many files. Maximum is 20 files.' });
916
+ return res.status(400).json({ error: `Too many files. Maximum is ${MAX_FILE_UPLOAD_COUNT} files.` });
914
917
  }
915
918
  return res.status(500).json({ error: err.message });
916
919
  }
917
920
 
918
921
  try {
919
922
  const { projectId } = req.params;
920
- const { targetPath, relativePaths } = req.body;
923
+ const { targetPath, relativePaths, requestedFileCount: requestedFileCountRaw } = req.body;
921
924
 
922
925
  // Parse relative paths if provided (for folder uploads)
923
926
  let filePaths = [];
@@ -941,6 +944,11 @@ const uploadFilesHandler = async (req, res) => {
941
944
  return res.status(400).json({ error: 'No files provided' });
942
945
  }
943
946
 
947
+ const parsedRequestedFileCount = Number.parseInt(requestedFileCountRaw, 10);
948
+ const requestedFileCount = Number.isFinite(parsedRequestedFileCount) && parsedRequestedFileCount > 0
949
+ ? parsedRequestedFileCount
950
+ : req.files.length;
951
+
944
952
  // Resolve the project directory through the DB using the new projectId.
945
953
  const projectRoot = await projectsDb.getProjectPathById(projectId);
946
954
  if (!projectRoot) {
@@ -1019,8 +1027,10 @@ const uploadFilesHandler = async (req, res) => {
1019
1027
  res.json({
1020
1028
  success: true,
1021
1029
  files: uploadedFiles,
1030
+ uploadedCount: uploadedFiles.length,
1031
+ requestedFileCount,
1022
1032
  targetPath: resolvedTargetDir,
1023
- message: `Uploaded ${uploadedFiles.length} file(s) successfully`
1033
+ message: `Uploaded ${uploadedFiles.length} ${uploadedFiles.length === 1 ? 'file' : 'files'} successfully`
1024
1034
  });
1025
1035
  } catch (error) {
1026
1036
  console.error('Error uploading files:', error);
@@ -10,6 +10,7 @@ type NotificationPreferences = {
10
10
  channels: {
11
11
  inApp: boolean;
12
12
  webPush: boolean;
13
+ sound: boolean;
13
14
  };
14
15
  events: {
15
16
  actionRequired: boolean;
@@ -22,6 +23,7 @@ const DEFAULT_NOTIFICATION_PREFERENCES: NotificationPreferences = {
22
23
  channels: {
23
24
  inApp: false,
24
25
  webPush: false,
26
+ sound: true,
25
27
  },
26
28
  events: {
27
29
  actionRequired: true,
@@ -37,6 +39,7 @@ function normalizeNotificationPreferences(value: unknown): NotificationPreferenc
37
39
  channels: {
38
40
  inApp: source.channels?.inApp === true,
39
41
  webPush: source.channels?.webPush === true,
42
+ sound: source.channels?.sound !== false,
40
43
  },
41
44
  events: {
42
45
  actionRequired: source.events?.actionRequired !== false,
@@ -1,7 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
- import { spawn } from 'child_process';
4
+
5
+ import { spawn } from 'cross-spawn';
5
6
 
6
7
  const PLUGINS_DIR = path.join(os.homedir(), '.claude-code-ui', 'plugins');
7
8
  const PLUGINS_CONFIG_PATH = path.join(os.homedir(), '.claude-code-ui', 'plugins.json');
@@ -7,6 +7,41 @@ const runningPlugins = new Map();
7
7
  // Map<pluginName, Promise<port>> — in-flight start operations
8
8
  const startingPlugins = new Map();
9
9
 
10
+ /**
11
+ * Build the environment handed to a plugin server subprocess.
12
+ *
13
+ * Intentionally minimal: only non-secret essentials, never the host's full
14
+ * environment. On Windows a handful of system variables are required for any
15
+ * child to bootstrap (Node itself, and any Python or CLI a plugin shells out
16
+ * to). Without APPDATA a `pip install --user` tool cannot locate its
17
+ * site-packages and fails to import; SystemRoot, PATHEXT and TEMP are needed to
18
+ * resolve system DLLs, executable extensions and a temp directory. None of
19
+ * these carry secrets, so the ones that are set get passed straight through.
20
+ */
21
+ function buildPluginEnv(name) {
22
+ const env = {
23
+ PATH: process.env.PATH,
24
+ HOME: process.env.HOME,
25
+ NODE_ENV: process.env.NODE_ENV || 'production',
26
+ PLUGIN_NAME: name,
27
+ };
28
+
29
+ if (process.platform === 'win32') {
30
+ const WINDOWS_ESSENTIALS = [
31
+ 'SystemRoot', 'windir', 'SystemDrive',
32
+ 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA',
33
+ 'TEMP', 'TMP', 'PATHEXT',
34
+ ];
35
+ for (const key of WINDOWS_ESSENTIALS) {
36
+ if (process.env[key] !== undefined) {
37
+ env[key] = process.env[key];
38
+ }
39
+ }
40
+ }
41
+
42
+ return env;
43
+ }
44
+
10
45
  /**
11
46
  * Start a plugin's server subprocess.
12
47
  * The plugin's server entry must print a JSON line with { ready: true, port: <number> }
@@ -26,15 +61,9 @@ export function startPluginServer(name, pluginDir, serverEntry) {
26
61
 
27
62
  const serverPath = path.join(pluginDir, serverEntry);
28
63
 
29
- // Restricted env — only essentials, no host secrets
30
64
  const pluginProcess = spawn('node', [serverPath], {
31
65
  cwd: pluginDir,
32
- env: {
33
- PATH: process.env.PATH,
34
- HOME: process.env.HOME,
35
- NODE_ENV: process.env.NODE_ENV || 'production',
36
- PLUGIN_NAME: name,
37
- },
66
+ env: buildPluginEnv(name),
38
67
  stdio: ['ignore', 'pipe', 'pipe'],
39
68
  });
40
69