@xcanwin/manyoyo 5.6.0 → 5.6.1

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/bin/manyoyo.js CHANGED
@@ -988,6 +988,22 @@ function appendArrayOption(command, flags, description) {
988
988
  );
989
989
  }
990
990
 
991
+ function enableShellSuffixPassThrough(command) {
992
+ return command.allowExcessArguments(true);
993
+ }
994
+
995
+ function validateShellSuffixPassThroughArgs(command) {
996
+ const extraArgs = Array.isArray(command && command.args) ? command.args : [];
997
+ if (!extraArgs.length) {
998
+ return;
999
+ }
1000
+
1001
+ if (!process.argv.includes('--')) {
1002
+ console.error(`${RED}⚠️ 错误: 存在多余位置参数: ${extraArgs.join(' ')}。如需透传命令后缀,请使用 -- <args...>${NC}`);
1003
+ process.exit(1);
1004
+ }
1005
+ }
1006
+
991
1007
  function applyRunStyleOptions(command, options = {}) {
992
1008
  const includeRmOnExit = options.includeRmOnExit !== false;
993
1009
  const includeServePreview = options.includeServePreview === true;
@@ -1169,7 +1185,11 @@ Notes:
1169
1185
  参数优先级与合并规则(标量覆盖、数组追加、env 按 key 合并)请用 ${MANYOYO_NAME} config show --help 或查看文档。
1170
1186
  `);
1171
1187
  applyRunStyleOptions(runCommand);
1172
- runCommand.action(options => selectAction('run', options));
1188
+ enableShellSuffixPassThrough(runCommand);
1189
+ runCommand.action((options, command) => {
1190
+ validateShellSuffixPassThroughArgs(command);
1191
+ selectAction('run', options);
1192
+ });
1173
1193
 
1174
1194
  const buildCommand = program.command('build').description('构建 manyoyo 沙箱镜像');
1175
1195
  buildCommand
@@ -1223,7 +1243,9 @@ Notes:
1223
1243
  const configCommand = program.command('config').description('查看解析后的配置或命令');
1224
1244
  const configShowCommand = configCommand.command('show').description('显示最终生效配置并退出');
1225
1245
  applyRunStyleOptions(configShowCommand, { includeRmOnExit: false, includeServePreview: true });
1226
- configShowCommand.action(options => {
1246
+ enableShellSuffixPassThrough(configShowCommand);
1247
+ configShowCommand.action((options, command) => {
1248
+ validateShellSuffixPassThroughArgs(command);
1227
1249
  const finalOptions = {
1228
1250
  ...options,
1229
1251
  showConfig: true
@@ -1238,7 +1260,11 @@ Notes:
1238
1260
 
1239
1261
  const configRunCommand = configCommand.command('command').description('显示将执行的 docker run 命令并退出');
1240
1262
  applyRunStyleOptions(configRunCommand, { includeRmOnExit: false });
1241
- configRunCommand.action(options => selectAction('config-command', options));
1263
+ enableShellSuffixPassThrough(configRunCommand);
1264
+ configRunCommand.action((options, command) => {
1265
+ validateShellSuffixPassThroughArgs(command);
1266
+ selectAction('config-command', options);
1267
+ });
1242
1268
 
1243
1269
  const initCommand = program.command('init [agents]').description('初始化 Agent 配置到 ~/.manyoyo');
1244
1270
  initCommand
package/lib/web/server.js CHANGED
@@ -86,7 +86,8 @@ try {
86
86
  XTERM_ADDON_FIT_JS_FILE = null;
87
87
  }
88
88
  try {
89
- MARKED_MIN_JS_FILE = require.resolve('marked/marked.min.js');
89
+ const markedPackageDir = path.dirname(require.resolve('marked/package.json'));
90
+ MARKED_MIN_JS_FILE = path.join(markedPackageDir, 'lib', 'marked.umd.js');
90
91
  } catch (e) {
91
92
  MARKED_MIN_JS_FILE = null;
92
93
  }
@@ -1146,34 +1147,48 @@ async function execCommandInWebContainer(ctx, containerName, command) {
1146
1147
  );
1147
1148
 
1148
1149
  const MAX_RAW_OUTPUT_CHARS = 32 * 1024 * 1024;
1149
- let rawOutput = '';
1150
- let outputTruncated = false;
1150
+ let stdoutOutput = '';
1151
+ let stderrOutput = '';
1152
+ let stdoutTruncated = false;
1153
+ let stderrTruncated = false;
1151
1154
 
1152
- function appendChunk(chunk) {
1155
+ function appendChunk(chunk, target) {
1153
1156
  if (!chunk) return;
1154
1157
  const text = chunk.toString('utf-8');
1155
1158
  if (!text) return;
1156
- if (rawOutput.length >= MAX_RAW_OUTPUT_CHARS) {
1157
- outputTruncated = true;
1159
+ if (target.value.length >= MAX_RAW_OUTPUT_CHARS) {
1160
+ target.truncated = true;
1158
1161
  return;
1159
1162
  }
1160
- const remain = MAX_RAW_OUTPUT_CHARS - rawOutput.length;
1163
+ const remain = MAX_RAW_OUTPUT_CHARS - target.value.length;
1161
1164
  if (text.length > remain) {
1162
- rawOutput += text.slice(0, remain);
1163
- outputTruncated = true;
1165
+ target.value += text.slice(0, remain);
1166
+ target.truncated = true;
1164
1167
  return;
1165
1168
  }
1166
- rawOutput += text;
1169
+ target.value += text;
1167
1170
  }
1168
1171
 
1169
- process.stdout.on('data', appendChunk);
1170
- process.stderr.on('data', appendChunk);
1172
+ process.stdout.on('data', chunk => appendChunk(chunk, {
1173
+ get value() { return stdoutOutput; },
1174
+ set value(nextValue) { stdoutOutput = nextValue; },
1175
+ get truncated() { return stdoutTruncated; },
1176
+ set truncated(nextValue) { stdoutTruncated = nextValue; }
1177
+ }));
1178
+ process.stderr.on('data', chunk => appendChunk(chunk, {
1179
+ get value() { return stderrOutput; },
1180
+ set value(nextValue) { stderrOutput = nextValue; },
1181
+ get truncated() { return stderrTruncated; },
1182
+ set truncated(nextValue) { stderrTruncated = nextValue; }
1183
+ }));
1171
1184
 
1172
1185
  process.on('error', reject);
1173
1186
  process.on('close', code => {
1174
1187
  const exitCode = typeof code === 'number' ? code : 1;
1175
- const clippedRaw = outputTruncated ? `${rawOutput}\n...[raw-truncated]` : rawOutput;
1176
- const extractedLastMessage = extractLastMessageOutput(clippedRaw);
1188
+ const clippedStdout = stdoutTruncated ? `${stdoutOutput}\n...[stdout-truncated]` : stdoutOutput;
1189
+ const clippedStderr = stderrTruncated ? `${stderrOutput}\n...[stderr-truncated]` : stderrOutput;
1190
+ const clippedRaw = `${clippedStdout}${clippedStdout && clippedStderr ? '\n' : ''}${clippedStderr}`;
1191
+ const extractedLastMessage = extractLastMessageOutput(clippedStdout);
1177
1192
  const cleanOutputSource = extractedLastMessage || clippedRaw;
1178
1193
  const output = clipText(stripAnsi(cleanOutputSource).trim() || '(无输出)');
1179
1194
  resolve({ exitCode, output });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcanwin/manyoyo",
3
- "version": "5.6.0",
3
+ "version": "5.6.1",
4
4
  "imageVersion": "1.9.0-common",
5
5
  "playwrightCliVersion": "0.1.1",
6
6
  "description": "AI Agent CLI Security Sandbox for Docker and Podman",
@@ -58,20 +58,22 @@
58
58
  "@playwright/mcp": "0.0.68",
59
59
  "@xterm/addon-fit": "^0.11.0",
60
60
  "@xterm/xterm": "^6.0.0",
61
- "commander": "^12.0.0",
61
+ "commander": "^14.0.3",
62
62
  "json5": "^2.2.3",
63
- "marked": "^12.0.2",
63
+ "marked": "^17.0.5",
64
64
  "playwright": "1.58.2",
65
- "ws": "^8.19.0"
65
+ "ws": "^8.20.0"
66
66
  },
67
67
  "devDependencies": {
68
- "jest": "^30.2.0",
69
- "vitepress": "^2.0.0-alpha.16"
68
+ "jest": "^30.3.0",
69
+ "vitepress": "^1.6.4"
70
70
  },
71
71
  "overrides": {
72
+ "esbuild": "^0.25.12",
72
73
  "glob": "^13.0.6",
73
74
  "minimatch": "^10.2.2",
74
- "test-exclude": "^8.0.0"
75
+ "test-exclude": "^8.0.0",
76
+ "vite": "^6.4.1"
75
77
  },
76
78
  "jest": {
77
79
  "testMatch": [