@xcanwin/manyoyo 5.5.2 → 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
@@ -12,7 +12,7 @@ const AGENT_RESUME_ARG_MAP = {
12
12
  const AGENT_PROMPT_TEMPLATE_MAP = {
13
13
  claude: 'claude -p {prompt}',
14
14
  gemini: 'gemini -p {prompt}',
15
- codex: 'codex exec {prompt}',
15
+ codex: 'codex exec --skip-git-repo-check {prompt}',
16
16
  opencode: 'opencode run {prompt}'
17
17
  };
18
18
 
@@ -580,7 +580,7 @@ textarea:focus-visible {
580
580
  min-width: 0;
581
581
  display: flex;
582
582
  flex-direction: column;
583
- gap: 4px;
583
+ gap: 8px;
584
584
  }
585
585
 
586
586
  .header-main-top {
@@ -590,6 +590,11 @@ textarea:focus-visible {
590
590
  min-width: 0;
591
591
  }
592
592
 
593
+ .header-menu {
594
+ position: relative;
595
+ flex: none;
596
+ }
597
+
593
598
  #activeTitle {
594
599
  margin: 0;
595
600
  font-family: var(--font-display);
@@ -611,11 +616,24 @@ textarea:focus-visible {
611
616
  color: var(--muted);
612
617
  }
613
618
 
619
+ .workbench-tabs {
620
+ display: inline-flex;
621
+ flex-wrap: wrap;
622
+ gap: 8px;
623
+ }
624
+
625
+ .workbench-tabs button.is-active,
626
+ .composer-mode-switch button.is-active {
627
+ color: #ffffff;
628
+ background: var(--accent);
629
+ border-color: var(--accent-strong);
630
+ }
631
+
614
632
  .header-actions {
615
633
  display: none;
616
634
  position: absolute;
617
- top: calc(100% + 6px);
618
- right: 8px;
635
+ top: calc(100% + 8px);
636
+ right: 0;
619
637
  z-index: 8;
620
638
  width: min(240px, calc(100vw - 36px));
621
639
  padding: 8px;
@@ -631,40 +649,34 @@ body.mobile-actions-open .header-actions {
631
649
  display: grid;
632
650
  }
633
651
 
634
- #modeToggle {
635
- position: relative;
652
+ .workspace-shell {
653
+ min-height: 0;
654
+ margin-top: 10px;
655
+ display: grid;
656
+ grid-template-columns: minmax(0, 1fr) 320px;
657
+ gap: 14px;
636
658
  }
637
659
 
638
- .mode-menu {
639
- display: none;
640
- position: absolute;
641
- top: calc(100% + 6px);
642
- right: 8px;
643
- z-index: 8;
644
- width: min(200px, calc(100vw - 36px));
645
- padding: 8px;
646
- border: 1px solid var(--line);
647
- border-radius: 10px;
648
- background: #fffaf2;
649
- box-shadow: var(--shadow-strong);
650
- grid-template-columns: 1fr;
651
- gap: 8px;
660
+ .workspace-main {
661
+ min-height: 0;
662
+ display: grid;
663
+ grid-template-rows: minmax(0, 1fr) auto;
664
+ gap: 0;
652
665
  }
653
666
 
654
- body.mode-menu-open .mode-menu {
655
- display: grid;
667
+ .workspace-pane {
668
+ min-height: 0;
656
669
  }
657
670
 
658
- .mode-menu button.is-active {
659
- color: #ffffff;
660
- background: var(--accent);
661
- border-color: var(--accent-strong);
671
+ .workspace-pane[hidden],
672
+ .composer[hidden] {
673
+ display: none !important;
662
674
  }
663
675
 
664
676
  #messages {
665
677
  min-height: 0;
666
678
  overflow-y: auto;
667
- margin: 10px 8px 0;
679
+ margin: 0;
668
680
  padding: 14px;
669
681
  border: 1px solid var(--line);
670
682
  border-radius: 14px;
@@ -678,9 +690,163 @@ body.mode-menu-open .mode-menu {
678
690
 
679
691
  #terminalPanel {
680
692
  min-height: 0;
681
- display: none;
682
693
  flex-direction: column;
683
- margin: 4px 0 0;
694
+ margin: 0;
695
+ border: 1px solid var(--line);
696
+ border-radius: 14px;
697
+ overflow: hidden;
698
+ background: #131923;
699
+ }
700
+
701
+ .inspector-pane {
702
+ overflow-y: auto;
703
+ padding: 0;
704
+ border: 1px solid var(--line);
705
+ border-radius: 14px;
706
+ background:
707
+ linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(252, 246, 236, 0.88) 100%);
708
+ }
709
+
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
+ .inspector-stack {
721
+ display: flex;
722
+ flex-direction: column;
723
+ gap: 12px;
724
+ padding: 14px;
725
+ }
726
+
727
+ .info-card {
728
+ display: flex;
729
+ flex-direction: column;
730
+ gap: 10px;
731
+ padding: 14px;
732
+ border: 1px solid rgba(181, 146, 99, 0.4);
733
+ border-radius: 14px;
734
+ background: rgba(255, 253, 250, 0.9);
735
+ }
736
+
737
+ .empty-card {
738
+ min-height: 112px;
739
+ justify-content: center;
740
+ }
741
+
742
+ .card-head {
743
+ display: flex;
744
+ align-items: center;
745
+ justify-content: space-between;
746
+ gap: 10px;
747
+ }
748
+
749
+ .card-title {
750
+ font-family: var(--font-display);
751
+ font-size: 15px;
752
+ font-weight: 700;
753
+ letter-spacing: 0.3px;
754
+ }
755
+
756
+ .card-desc {
757
+ color: var(--muted);
758
+ font-size: 13px;
759
+ line-height: 1.55;
760
+ }
761
+
762
+ .inline-action {
763
+ padding: 6px 10px;
764
+ font-size: 12px;
765
+ }
766
+
767
+ .kv-list,
768
+ .check-list {
769
+ display: flex;
770
+ flex-direction: column;
771
+ gap: 8px;
772
+ }
773
+
774
+ .kv-row {
775
+ display: grid;
776
+ grid-template-columns: 108px minmax(0, 1fr);
777
+ gap: 10px;
778
+ align-items: start;
779
+ padding-top: 8px;
780
+ border-top: 1px dashed rgba(181, 146, 99, 0.34);
781
+ }
782
+
783
+ .kv-row:first-child {
784
+ padding-top: 0;
785
+ border-top: none;
786
+ }
787
+
788
+ .kv-label {
789
+ min-width: 0;
790
+ color: var(--muted);
791
+ font-size: 12px;
792
+ font-weight: 700;
793
+ text-transform: uppercase;
794
+ letter-spacing: 0.3px;
795
+ line-height: 1.45;
796
+ overflow-wrap: anywhere;
797
+ }
798
+
799
+ .kv-value {
800
+ min-width: 0;
801
+ color: var(--text);
802
+ font-family: var(--font-mono);
803
+ font-size: 12px;
804
+ line-height: 1.5;
805
+ word-break: break-word;
806
+ }
807
+
808
+ .check-item {
809
+ display: flex;
810
+ flex-direction: column;
811
+ gap: 4px;
812
+ padding: 10px 12px;
813
+ border-radius: 12px;
814
+ border: 1px solid rgba(181, 146, 99, 0.28);
815
+ background: rgba(255, 252, 246, 0.86);
816
+ }
817
+
818
+ .check-main {
819
+ display: flex;
820
+ align-items: center;
821
+ justify-content: space-between;
822
+ gap: 10px;
823
+ }
824
+
825
+ .check-label,
826
+ .check-value {
827
+ font-weight: 700;
828
+ font-size: 13px;
829
+ }
830
+
831
+ .check-detail {
832
+ color: var(--muted);
833
+ font-size: 12px;
834
+ line-height: 1.45;
835
+ }
836
+
837
+ .tone-ok .check-value,
838
+ .kv-row.tone-ok .kv-value {
839
+ color: var(--subaccent-strong);
840
+ }
841
+
842
+ .tone-warn .check-value,
843
+ .kv-row.tone-warn .kv-value {
844
+ color: #9a5a09;
845
+ }
846
+
847
+ .tone-danger .check-value,
848
+ .kv-row.tone-danger .kv-value {
849
+ color: var(--danger);
684
850
  }
685
851
 
686
852
  .term-keybar {
@@ -890,11 +1056,29 @@ body.command-mode .msg.origin-agent .bubble {
890
1056
 
891
1057
  .composer {
892
1058
  border-top: 1px solid rgba(181, 146, 99, 0.45);
893
- margin-top: 10px;
1059
+ margin-top: 12px;
894
1060
  padding: 12px 8px 4px;
895
1061
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.32) 0%, rgba(255, 249, 240, 0.78) 100%);
896
1062
  }
897
1063
 
1064
+ .composer-toolbar {
1065
+ display: flex;
1066
+ align-items: center;
1067
+ justify-content: space-between;
1068
+ gap: 10px;
1069
+ margin-bottom: 10px;
1070
+ }
1071
+
1072
+ .composer-mode-switch {
1073
+ display: inline-flex;
1074
+ gap: 8px;
1075
+ }
1076
+
1077
+ .composer-toolbar-tip {
1078
+ color: var(--muted);
1079
+ font-size: 12px;
1080
+ }
1081
+
898
1082
  .composer-inner {
899
1083
  display: grid;
900
1084
  grid-template-columns: 1fr auto;
@@ -1035,8 +1219,18 @@ body.command-mode .msg.origin-agent .bubble {
1035
1219
  grid-template-columns: minmax(0, 1fr);
1036
1220
  }
1037
1221
 
1222
+ .workspace-shell {
1223
+ grid-template-columns: minmax(0, 1fr);
1224
+ gap: 10px;
1225
+ }
1226
+
1227
+ .context-panel {
1228
+ display: none;
1229
+ }
1230
+
1038
1231
  #messages,
1039
- #terminalPanel {
1232
+ #terminalPanel,
1233
+ .inspector-pane {
1040
1234
  min-height: 0;
1041
1235
  }
1042
1236
 
@@ -1088,6 +1282,32 @@ body.command-mode .msg.origin-agent .bubble {
1088
1282
  display: none;
1089
1283
  }
1090
1284
 
1285
+ .workbench-tabs {
1286
+ display: grid;
1287
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1288
+ gap: 6px;
1289
+ }
1290
+
1291
+ .workbench-tabs button {
1292
+ padding: 8px 10px;
1293
+ font-size: 12px;
1294
+ }
1295
+
1296
+ .composer-toolbar {
1297
+ flex-direction: column;
1298
+ align-items: flex-start;
1299
+ }
1300
+
1301
+ .composer-toolbar-tip {
1302
+ display: none;
1303
+ }
1304
+
1305
+ .composer-mode-switch {
1306
+ width: 100%;
1307
+ display: grid;
1308
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1309
+ }
1310
+
1091
1311
  #commandInput {
1092
1312
  min-height: 68px;
1093
1313
  max-height: 160px;
@@ -48,59 +48,74 @@
48
48
  aria-controls="sessionList"
49
49
  >会话</button>
50
50
  <h1 id="activeTitle">未选择会话</h1>
51
- <button
52
- type="button"
53
- id="modeToggle"
54
- class="secondary"
55
- aria-expanded="false"
56
- aria-controls="modeMenu"
57
- >AGENT 模式</button>
58
- <button
59
- type="button"
60
- id="mobileActionsToggle"
61
- class="secondary mobile-actions-toggle"
62
- aria-expanded="false"
63
- aria-controls="headerActions"
64
- >更多</button>
51
+ <div class="header-menu">
52
+ <button
53
+ type="button"
54
+ id="mobileActionsToggle"
55
+ class="secondary mobile-actions-toggle"
56
+ aria-expanded="false"
57
+ aria-controls="headerActions"
58
+ >更多</button>
59
+ <div class="header-actions" id="headerActions">
60
+ <button type="button" id="refreshBtn" class="secondary">刷新</button>
61
+ <button type="button" id="removeBtn" class="danger-outline">删除容器</button>
62
+ <button type="button" id="removeAllBtn" class="danger">删除对话</button>
63
+ </div>
64
+ </div>
65
65
  </div>
66
66
  <div id="activeMeta">请选择左侧会话</div>
67
- </div>
68
- <div class="mode-menu" id="modeMenu">
69
- <button type="button" id="modeAgentBtn" class="secondary is-active" aria-pressed="true">AGENT 模式</button>
70
- <button type="button" id="modeCommandBtn" class="secondary" aria-pressed="false">命令模式</button>
71
- <button type="button" id="modeTerminalBtn" class="secondary" aria-pressed="false">终端模式</button>
72
- </div>
73
- <div class="header-actions" id="headerActions">
74
- <button type="button" id="refreshBtn" class="secondary">刷新</button>
75
- <button type="button" id="removeBtn" class="danger-outline">删除容器</button>
76
- <button type="button" id="removeAllBtn" class="danger">删除对话</button>
67
+ <div class="workbench-tabs" id="workbenchTabs" aria-label="工作台视图">
68
+ <button type="button" id="viewActivityBtn" class="secondary is-active">活动</button>
69
+ <button type="button" id="viewTerminalBtn" class="secondary">终端</button>
70
+ <button type="button" id="viewConfigBtn" class="secondary">配置</button>
71
+ <button type="button" id="viewCheckBtn" class="secondary">检查</button>
72
+ </div>
77
73
  </div>
78
74
  </header>
79
- <section id="messages"></section>
80
- <section id="terminalPanel" hidden>
81
- <div id="terminalKeybar" class="term-keybar" aria-label="终端快捷键">
82
- <button type="button" class="term-key-btn" data-key="esc">esc</button>
83
- <button type="button" class="term-key-btn" data-key="tab">tab</button>
84
- <button type="button" class="term-key-btn term-ctrl-btn" data-key="ctrl">ctrl</button>
85
- <button type="button" class="term-key-btn term-alt-btn" data-key="alt">alt</button>&nbsp;&nbsp;
86
- <button type="button" class="term-key-btn" data-key="left">&nbsp;◀&nbsp;</button>
87
- <button type="button" class="term-key-btn" data-key="up">&nbsp;▲&nbsp;</button>
88
- <button type="button" class="term-key-btn" data-key="down">&nbsp;▼&nbsp;</button>
89
- <button type="button" class="term-key-btn" data-key="right">&nbsp;▶&nbsp;</button>
75
+ <section class="workspace-shell">
76
+ <div class="workspace-main">
77
+ <section id="messages" class="workspace-pane"></section>
78
+ <section id="terminalPanel" class="workspace-pane" hidden>
79
+ <div id="terminalKeybar" class="term-keybar" aria-label="终端快捷键">
80
+ <button type="button" class="term-key-btn" data-key="esc">esc</button>
81
+ <button type="button" class="term-key-btn" data-key="tab">tab</button>
82
+ <button type="button" class="term-key-btn term-ctrl-btn" data-key="ctrl">ctrl</button>
83
+ <button type="button" class="term-key-btn term-alt-btn" data-key="alt">alt</button>&nbsp;&nbsp;
84
+ <button type="button" class="term-key-btn" data-key="left">&nbsp;◀&nbsp;</button>
85
+ <button type="button" class="term-key-btn" data-key="up">&nbsp;▲&nbsp;</button>
86
+ <button type="button" class="term-key-btn" data-key="down">&nbsp;▼&nbsp;</button>
87
+ <button type="button" class="term-key-btn" data-key="right">&nbsp;▶&nbsp;</button>
88
+ </div>
89
+ <div id="terminalScreen" aria-label="终端输出区域"></div>
90
+ </section>
91
+ <section id="configPanel" class="workspace-pane inspector-pane" hidden>
92
+ <div id="configSummary" class="inspector-stack"></div>
93
+ </section>
94
+ <section id="checkPanel" class="workspace-pane inspector-pane" hidden>
95
+ <div id="checkSummary" class="inspector-stack"></div>
96
+ </section>
97
+ <form class="composer" id="composer">
98
+ <div class="composer-toolbar">
99
+ <div class="composer-mode-switch" aria-label="活动输入模式">
100
+ <button type="button" id="activityAgentBtn" class="secondary is-active">Agent</button>
101
+ <button type="button" id="activityCommandBtn" class="secondary">命令</button>
102
+ </div>
103
+ <div class="composer-toolbar-tip">活动页支持 Agent 提示词和容器命令两种输入。</div>
104
+ </div>
105
+ <div class="composer-inner">
106
+ <textarea id="commandInput" placeholder="输入容器命令,例如: ls -la"></textarea>
107
+ <button type="submit" id="sendBtn">发送</button>
108
+ </div>
109
+ <div class="composer-foot">
110
+ <span id="composerHint">Enter 发送 · Shift/Alt + Enter 换行</span>
111
+ <span id="sendState" class="send-state">未选择会话</span>
112
+ </div>
113
+ </form>
90
114
  </div>
91
- <div id="terminalScreen" aria-label="终端输出区域"></div>
92
-
115
+ <aside class="context-panel" id="contextPanel">
116
+ <div id="contextSummary" class="inspector-stack"></div>
117
+ </aside>
93
118
  </section>
94
- <form class="composer" id="composer">
95
- <div class="composer-inner">
96
- <textarea id="commandInput" placeholder="输入容器命令,例如: ls -la"></textarea>
97
- <button type="submit" id="sendBtn">发送</button>
98
- </div>
99
- <div class="composer-foot">
100
- <span id="composerHint">Enter 发送 · Shift/Alt + Enter 换行</span>
101
- <span id="sendState" class="send-state">未选择会话</span>
102
- </div>
103
- </form>
104
119
  </main>
105
120
  <div id="sidebarBackdrop" class="sidebar-backdrop" hidden></div>
106
121