@xcanwin/manyoyo 5.6.0 → 5.6.2

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
@@ -0,0 +1,132 @@
1
+ function parseReleaseVersion(version) {
2
+ const match = String(version || '').trim().match(/^(\d+)\.(\d+)\.(\d+)$/);
3
+ if (!match) {
4
+ return null;
5
+ }
6
+ return {
7
+ major: Number(match[1]),
8
+ minor: Number(match[2]),
9
+ patch: Number(match[3])
10
+ };
11
+ }
12
+
13
+ function formatReleaseVersion(parts) {
14
+ return `${parts.major}.${parts.minor}.${parts.patch}`;
15
+ }
16
+
17
+ function compareReleaseVersions(left, right) {
18
+ const a = typeof left === 'string' ? parseReleaseVersion(left) : left;
19
+ const b = typeof right === 'string' ? parseReleaseVersion(right) : right;
20
+ if (!a || !b) {
21
+ return 0;
22
+ }
23
+ if (a.major !== b.major) return a.major - b.major;
24
+ if (a.minor !== b.minor) return a.minor - b.minor;
25
+ return a.patch - b.patch;
26
+ }
27
+
28
+ function buildVersionSuggestions(version) {
29
+ const parsed = parseReleaseVersion(version);
30
+ if (!parsed) {
31
+ return [];
32
+ }
33
+ return [
34
+ {
35
+ key: 'patch',
36
+ label: '第3段 +1 (patch)',
37
+ version: formatReleaseVersion({
38
+ major: parsed.major,
39
+ minor: parsed.minor,
40
+ patch: parsed.patch + 1
41
+ }),
42
+ recommended: true
43
+ },
44
+ {
45
+ key: 'minor',
46
+ label: '第2段 +1 (minor)',
47
+ version: formatReleaseVersion({
48
+ major: parsed.major,
49
+ minor: parsed.minor + 1,
50
+ patch: 0
51
+ }),
52
+ recommended: false
53
+ },
54
+ {
55
+ key: 'major',
56
+ label: '第1段 +1 (major)',
57
+ version: formatReleaseVersion({
58
+ major: parsed.major + 1,
59
+ minor: 0,
60
+ patch: 0
61
+ }),
62
+ recommended: false
63
+ }
64
+ ];
65
+ }
66
+
67
+ function pickLatestVersionTag(tags) {
68
+ let latest = null;
69
+ for (const rawTag of (tags || [])) {
70
+ const tag = String(rawTag || '').trim();
71
+ if (!tag) {
72
+ continue;
73
+ }
74
+ const normalized = tag.startsWith('v') ? tag.slice(1) : tag;
75
+ const parsed = parseReleaseVersion(normalized);
76
+ if (!parsed) {
77
+ continue;
78
+ }
79
+ if (!latest || compareReleaseVersions(parsed, latest.parsed) > 0) {
80
+ latest = {
81
+ tag,
82
+ version: normalized,
83
+ parsed
84
+ };
85
+ }
86
+ }
87
+ return latest ? { tag: latest.tag, version: latest.version } : null;
88
+ }
89
+
90
+ function normalizeCommitMessage(text) {
91
+ const lines = String(text || '').replace(/\r/g, '').split('\n');
92
+ if (!lines.length) {
93
+ return '';
94
+ }
95
+
96
+ let start = 0;
97
+ let end = lines.length;
98
+
99
+ while (start < end && lines[start].trim() === '') {
100
+ start += 1;
101
+ }
102
+ while (end > start && lines[end - 1].trim() === '') {
103
+ end -= 1;
104
+ }
105
+
106
+ if (start < end && lines[start].trim().startsWith('```')) {
107
+ start += 1;
108
+ while (start < end && lines[start].trim() === '') {
109
+ start += 1;
110
+ }
111
+ if (end > start && lines[end - 1].trim() === '```') {
112
+ end -= 1;
113
+ }
114
+ }
115
+
116
+ while (start < end && lines[start].trim() === '') {
117
+ start += 1;
118
+ }
119
+ while (end > start && lines[end - 1].trim() === '') {
120
+ end -= 1;
121
+ }
122
+
123
+ return lines.slice(start, end).join('\n').trim();
124
+ }
125
+
126
+ module.exports = {
127
+ parseReleaseVersion,
128
+ compareReleaseVersions,
129
+ buildVersionSuggestions,
130
+ pickLatestVersionTag,
131
+ normalizeCommitMessage
132
+ };
@@ -651,21 +651,24 @@ body.mobile-actions-open .header-actions {
651
651
 
652
652
  .workspace-shell {
653
653
  min-height: 0;
654
- margin-top: 10px;
655
- display: grid;
656
- grid-template-columns: minmax(0, 1fr) 320px;
657
- gap: 14px;
654
+ height: 100%;
655
+ padding-top: 10px;
656
+ display: block;
657
+ overflow: hidden;
658
658
  }
659
659
 
660
660
  .workspace-main {
661
+ height: 100%;
661
662
  min-height: 0;
662
663
  display: grid;
663
664
  grid-template-rows: minmax(0, 1fr) auto;
664
665
  gap: 0;
666
+ overflow: hidden;
665
667
  }
666
668
 
667
669
  .workspace-pane {
668
670
  min-height: 0;
671
+ height: 100%;
669
672
  }
670
673
 
671
674
  .workspace-pane[hidden],
@@ -707,16 +710,6 @@ body.mobile-actions-open .header-actions {
707
710
  linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(252, 246, 236, 0.88) 100%);
708
711
  }
709
712
 
710
- .context-panel {
711
- min-height: 0;
712
- overflow-y: auto;
713
- border: 1px solid var(--line);
714
- border-radius: 16px;
715
- background:
716
- linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(251, 244, 232, 0.96) 100%);
717
- box-shadow: 0 10px 24px rgba(46, 31, 13, 0.08);
718
- }
719
-
720
713
  .inspector-stack {
721
714
  display: flex;
722
715
  flex-direction: column;
@@ -1219,15 +1212,6 @@ body.command-mode .msg.origin-agent .bubble {
1219
1212
  grid-template-columns: minmax(0, 1fr);
1220
1213
  }
1221
1214
 
1222
- .workspace-shell {
1223
- grid-template-columns: minmax(0, 1fr);
1224
- gap: 10px;
1225
- }
1226
-
1227
- .context-panel {
1228
- display: none;
1229
- }
1230
-
1231
1215
  #messages,
1232
1216
  #terminalPanel,
1233
1217
  .inspector-pane {
@@ -1284,7 +1268,7 @@ body.command-mode .msg.origin-agent .bubble {
1284
1268
 
1285
1269
  .workbench-tabs {
1286
1270
  display: grid;
1287
- grid-template-columns: repeat(4, minmax(0, 1fr));
1271
+ grid-template-columns: repeat(5, minmax(0, 1fr));
1288
1272
  gap: 6px;
1289
1273
  }
1290
1274
 
@@ -67,6 +67,7 @@
67
67
  <div class="workbench-tabs" id="workbenchTabs" aria-label="工作台视图">
68
68
  <button type="button" id="viewActivityBtn" class="secondary is-active">活动</button>
69
69
  <button type="button" id="viewTerminalBtn" class="secondary">终端</button>
70
+ <button type="button" id="viewDetailBtn" class="secondary">详情</button>
70
71
  <button type="button" id="viewConfigBtn" class="secondary">配置</button>
71
72
  <button type="button" id="viewCheckBtn" class="secondary">检查</button>
72
73
  </div>
@@ -88,6 +89,9 @@
88
89
  </div>
89
90
  <div id="terminalScreen" aria-label="终端输出区域"></div>
90
91
  </section>
92
+ <section id="detailPanel" class="workspace-pane inspector-pane" hidden>
93
+ <div id="detailSummary" class="inspector-stack"></div>
94
+ </section>
91
95
  <section id="configPanel" class="workspace-pane inspector-pane" hidden>
92
96
  <div id="configSummary" class="inspector-stack"></div>
93
97
  </section>
@@ -112,9 +116,6 @@
112
116
  </div>
113
117
  </form>
114
118
  </div>
115
- <aside class="context-panel" id="contextPanel">
116
- <div id="contextSummary" class="inspector-stack"></div>
117
- </aside>
118
119
  </section>
119
120
  </main>
120
121
  <div id="sidebarBackdrop" class="sidebar-backdrop" hidden></div>
@@ -89,6 +89,7 @@
89
89
  const headerActions = document.getElementById('headerActions');
90
90
  const viewActivityBtn = document.getElementById('viewActivityBtn');
91
91
  const viewTerminalBtn = document.getElementById('viewTerminalBtn');
92
+ const viewDetailBtn = document.getElementById('viewDetailBtn');
92
93
  const viewConfigBtn = document.getElementById('viewConfigBtn');
93
94
  const viewCheckBtn = document.getElementById('viewCheckBtn');
94
95
  const mobileSidebarClose = document.getElementById('mobileSidebarClose');
@@ -129,11 +130,12 @@
129
130
  const activityAgentBtn = document.getElementById('activityAgentBtn');
130
131
  const messagesNode = document.getElementById('messages');
131
132
  const terminalPanel = document.getElementById('terminalPanel');
133
+ const detailPanel = document.getElementById('detailPanel');
132
134
  const configPanel = document.getElementById('configPanel');
133
135
  const checkPanel = document.getElementById('checkPanel');
136
+ const detailSummary = document.getElementById('detailSummary');
134
137
  const configSummary = document.getElementById('configSummary');
135
138
  const checkSummary = document.getElementById('checkSummary');
136
- const contextSummary = document.getElementById('contextSummary');
137
139
  const terminalScreen = document.getElementById('terminalScreen');
138
140
  const composer = document.getElementById('composer');
139
141
  const commandInput = document.getElementById('commandInput');
@@ -186,7 +188,7 @@
186
188
  if (message && message.mode === 'agent') {
187
189
  return 'AGENT 回复';
188
190
  }
189
- return '容器输出';
191
+ return '命令执行结果';
190
192
  }
191
193
  return '系统';
192
194
  }
@@ -912,6 +914,7 @@
912
914
  const VIEW_LABELS = {
913
915
  activity: '活动',
914
916
  terminal: '终端',
917
+ detail: '详情',
915
918
  config: '配置',
916
919
  check: '检查'
917
920
  };
@@ -1003,20 +1006,20 @@
1003
1006
  function renderSessionDetailPanels() {
1004
1007
  const detail = state.sessionDetail;
1005
1008
  if (!state.active) {
1006
- renderEmptyInspector(contextSummary, '当前上下文', '选择左侧会话后,这里会显示容器状态、配置摘要与 Agent 信息。');
1009
+ renderEmptyInspector(detailSummary, '详情视图', '选择左侧会话后,这里会显示会话概览、Agent 状态与运行参数。');
1007
1010
  renderEmptyInspector(configSummary, '配置视图', '选择会话后可查看当前容器会话的运行参数摘要。');
1008
1011
  renderEmptyInspector(checkSummary, '检查视图', '选择会话后可查看当前会话的基础健康检查。');
1009
1012
  return;
1010
1013
  }
1011
1014
  if (state.loadingSessionDetail) {
1012
- renderEmptyInspector(contextSummary, '当前上下文', '正在加载会话详情...');
1015
+ renderEmptyInspector(detailSummary, '详情视图', '正在加载会话详情...');
1013
1016
  renderEmptyInspector(configSummary, '配置视图', '正在加载会话详情...');
1014
1017
  renderEmptyInspector(checkSummary, '检查视图', '正在加载会话详情...');
1015
1018
  return;
1016
1019
  }
1017
1020
  if (!detail) {
1018
1021
  const message = state.sessionDetailError || '当前会话详情暂时不可用。';
1019
- renderEmptyInspector(contextSummary, '当前上下文', message);
1022
+ renderEmptyInspector(detailSummary, '详情视图', message);
1020
1023
  renderEmptyInspector(configSummary, '配置视图', message);
1021
1024
  renderEmptyInspector(checkSummary, '检查视图', message);
1022
1025
  return;
@@ -1026,23 +1029,23 @@
1026
1029
  const status = sessionStatusInfo(detail.status);
1027
1030
  const updatedText = formatDateTime(detail.updatedAt) || '暂无更新';
1028
1031
 
1029
- if (contextSummary) {
1030
- contextSummary.innerHTML = '';
1031
- renderKeyValueCard(contextSummary, '会话概览', [
1032
+ if (detailSummary) {
1033
+ detailSummary.innerHTML = '';
1034
+ renderKeyValueCard(detailSummary, '会话概览', [
1032
1035
  { label: '会话', value: detail.name || state.active },
1033
1036
  { label: '状态', value: status.label, tone: status.tone },
1034
1037
  { label: '镜像', value: detail.image || applied.imageName || '—' },
1035
1038
  { label: '最近更新', value: updatedText },
1036
1039
  { label: '消息数', value: String(safeMessageCount(detail.messageCount)) }
1037
1040
  ]);
1038
- renderKeyValueCard(contextSummary, 'Agent 上下文', [
1041
+ renderKeyValueCard(detailSummary, 'Agent 上下文', [
1039
1042
  { label: '已启用', value: detail.agentEnabled ? '是' : '否', tone: detail.agentEnabled ? 'ok' : 'warn' },
1040
1043
  { label: '程序', value: detail.agentProgram || '—' },
1041
1044
  { label: '支持 resume', value: detail.resumeSupported ? '是' : '否', tone: detail.resumeSupported ? 'ok' : 'warn' },
1042
1045
  { label: '最近 resume', value: detail.lastResumeAt ? formatDateTime(detail.lastResumeAt) : '暂无' },
1043
1046
  { label: '最近结果', value: detail.lastResumeOk == null ? '暂无' : (detail.lastResumeOk ? '成功' : '失败'), tone: detail.lastResumeOk == null ? 'info' : (detail.lastResumeOk ? 'ok' : 'danger') }
1044
1047
  ]);
1045
- renderKeyValueCard(contextSummary, '运行参数', [
1048
+ renderKeyValueCard(detailSummary, '运行参数', [
1046
1049
  { label: 'hostPath', value: applied.hostPath || '—' },
1047
1050
  { label: 'containerPath', value: applied.containerPath || '—' },
1048
1051
  { label: 'imageVersion', value: applied.imageVersion || '—' },
@@ -1139,6 +1142,7 @@
1139
1142
 
1140
1143
  const activityTab = state.activeTab === 'activity';
1141
1144
  const terminalTab = state.activeTab === 'terminal';
1145
+ const detailTab = state.activeTab === 'detail';
1142
1146
  const configTab = state.activeTab === 'config';
1143
1147
  const checkTab = state.activeTab === 'check';
1144
1148
  const commandMode = state.mode === 'command';
@@ -1148,6 +1152,7 @@
1148
1152
  document.body.classList.toggle('command-mode', commandMode);
1149
1153
  document.body.classList.toggle('agent-mode', agentMode);
1150
1154
  document.body.classList.toggle('terminal-mode', terminalTab);
1155
+ document.body.classList.toggle('detail-tab', detailTab);
1151
1156
  document.body.classList.toggle('config-tab', configTab);
1152
1157
  document.body.classList.toggle('check-tab', checkTab);
1153
1158
  if (activityCommandBtn) {
@@ -1160,6 +1165,7 @@
1160
1165
  }
1161
1166
  if (viewActivityBtn) viewActivityBtn.classList.toggle('is-active', activityTab);
1162
1167
  if (viewTerminalBtn) viewTerminalBtn.classList.toggle('is-active', terminalTab);
1168
+ if (viewDetailBtn) viewDetailBtn.classList.toggle('is-active', detailTab);
1163
1169
  if (viewConfigBtn) viewConfigBtn.classList.toggle('is-active', configTab);
1164
1170
  if (viewCheckBtn) viewCheckBtn.classList.toggle('is-active', checkTab);
1165
1171
  if (messagesNode) {
@@ -1168,6 +1174,9 @@
1168
1174
  if (terminalPanel) {
1169
1175
  terminalPanel.hidden = !terminalTab;
1170
1176
  }
1177
+ if (detailPanel) {
1178
+ detailPanel.hidden = !detailTab;
1179
+ }
1171
1180
  if (configPanel) {
1172
1181
  configPanel.hidden = !configTab;
1173
1182
  }
@@ -1654,12 +1663,6 @@
1654
1663
 
1655
1664
  row.appendChild(meta);
1656
1665
  row.appendChild(bubble);
1657
- if ((msg.role || '') === 'assistant' && typeof msg.exitCode === 'number') {
1658
- const exitNode = document.createElement('div');
1659
- exitNode.className = 'msg-exit';
1660
- exitNode.textContent = `exit ${msg.exitCode}`;
1661
- row.appendChild(exitNode);
1662
- }
1663
1666
  return row;
1664
1667
  }
1665
1668
 
@@ -2179,6 +2182,12 @@
2179
2182
  });
2180
2183
  }
2181
2184
 
2185
+ if (viewDetailBtn) {
2186
+ viewDetailBtn.addEventListener('click', function () {
2187
+ setActiveTab('detail');
2188
+ });
2189
+ }
2190
+
2182
2191
  if (viewConfigBtn) {
2183
2192
  viewConfigBtn.addEventListener('click', function () {
2184
2193
  setActiveTab('config');
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.2",
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",
@@ -30,6 +30,7 @@
30
30
  "my": "bin/manyoyo.js"
31
31
  },
32
32
  "scripts": {
33
+ "dev:release": "node scripts/dev-release.js",
33
34
  "install-link": "npm link",
34
35
  "test": "jest --coverage",
35
36
  "test:unit": "jest test/",
@@ -58,20 +59,22 @@
58
59
  "@playwright/mcp": "0.0.68",
59
60
  "@xterm/addon-fit": "^0.11.0",
60
61
  "@xterm/xterm": "^6.0.0",
61
- "commander": "^12.0.0",
62
+ "commander": "^14.0.3",
62
63
  "json5": "^2.2.3",
63
- "marked": "^12.0.2",
64
+ "marked": "^17.0.5",
64
65
  "playwright": "1.58.2",
65
- "ws": "^8.19.0"
66
+ "ws": "^8.20.0"
66
67
  },
67
68
  "devDependencies": {
68
- "jest": "^30.2.0",
69
- "vitepress": "^2.0.0-alpha.16"
69
+ "jest": "^30.3.0",
70
+ "vitepress": "^1.6.4"
70
71
  },
71
72
  "overrides": {
73
+ "esbuild": "^0.25.12",
72
74
  "glob": "^13.0.6",
73
75
  "minimatch": "^10.2.2",
74
- "test-exclude": "^8.0.0"
76
+ "test-exclude": "^8.0.0",
77
+ "vite": "^6.4.1"
75
78
  },
76
79
  "jest": {
77
80
  "testMatch": [