@xcanwin/manyoyo 4.0.2 → 4.0.6

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
@@ -483,29 +483,14 @@ function collectClaudeInitData(homeDir) {
483
483
 
484
484
  const claudeDir = path.join(homeDir, '.claude');
485
485
  const claudeSettingsPath = path.join(claudeDir, 'settings.json');
486
- const claudeJsonPath = path.join(homeDir, '.claude.json');
487
486
  const settingsJson = readJsonFileSafely(claudeSettingsPath, 'Claude settings');
488
- const claudeJson = readJsonFileSafely(claudeJsonPath, 'Claude config');
489
487
 
490
488
  keys.forEach(key => setInitValue(values, key, process.env[key]));
491
489
 
492
- if (claudeJson && claudeJson.env && typeof claudeJson.env === 'object') {
493
- keys.forEach(key => setInitValue(values, key, claudeJson.env[key]));
494
- }
495
490
  if (settingsJson && settingsJson.env && typeof settingsJson.env === 'object') {
496
491
  keys.forEach(key => setInitValue(values, key, settingsJson.env[key]));
497
492
  }
498
493
 
499
- if (fs.existsSync(claudeDir)) {
500
- volumes.push(`${claudeDir}:/root/.claude`);
501
- }
502
- if (fs.existsSync(claudeJsonPath)) {
503
- volumes.push(`${claudeJsonPath}:/root/.claude.json`);
504
- }
505
- if (!fs.existsSync(claudeDir) && !fs.existsSync(claudeJsonPath)) {
506
- notes.push('未检测到 Claude 本地配置(~/.claude 或 ~/.claude.json),已生成占位模板。');
507
- }
508
-
509
494
  return { keys, values, notes, volumes: dedupeList(volumes) };
510
495
  }
511
496
 
@@ -63,7 +63,7 @@ body::before {
63
63
  left: -120px;
64
64
  top: -150px;
65
65
  background: radial-gradient(circle at 30% 30%, rgba(96, 190, 143, 0.28) 0%, rgba(96, 190, 143, 0) 72%);
66
- animation: orbA 14s ease-in-out infinite;
66
+ animation: none;
67
67
  }
68
68
 
69
69
  body::after {
@@ -72,7 +72,7 @@ body::after {
72
72
  right: -80px;
73
73
  bottom: -120px;
74
74
  background: radial-gradient(circle at 55% 45%, rgba(33, 130, 86, 0.22) 0%, rgba(33, 130, 86, 0) 70%);
75
- animation: orbB 16s ease-in-out infinite;
75
+ animation: none;
76
76
  }
77
77
 
78
78
  .app {
@@ -90,7 +90,6 @@ body::after {
90
90
  border-radius: 12px;
91
91
  border: 1px solid var(--line);
92
92
  background: var(--panel);
93
- backdrop-filter: blur(9px);
94
93
  box-shadow: var(--shadow-soft);
95
94
  }
96
95
 
@@ -362,7 +361,7 @@ button.danger:hover {
362
361
  min-height: 0;
363
362
  padding: 12px 14px 10px;
364
363
  display: grid;
365
- grid-template-rows: auto minmax(0, 1fr) auto;
364
+ grid-template-rows: auto auto minmax(0, 1fr) auto;
366
365
  gap: 0;
367
366
  animation: panelIn 380ms ease 80ms both;
368
367
  }
@@ -416,6 +415,53 @@ button.danger:hover {
416
415
  flex-wrap: wrap;
417
416
  }
418
417
 
418
+ .mode-switch {
419
+ display: flex;
420
+ justify-content: space-between;
421
+ align-items: center;
422
+ gap: 10px;
423
+ margin: 8px 8px 2px;
424
+ min-height: 34px;
425
+ }
426
+
427
+ .mode-switch-left {
428
+ display: inline-flex;
429
+ align-items: center;
430
+ gap: 8px;
431
+ min-width: 0;
432
+ }
433
+
434
+ .mode-switch button {
435
+ min-width: 98px;
436
+ color: var(--text);
437
+ background: #eef4f0;
438
+ border-color: var(--line);
439
+ }
440
+
441
+ .mode-switch button.is-active {
442
+ color: #ffffff;
443
+ background: var(--accent);
444
+ border-color: var(--accent-strong);
445
+ }
446
+
447
+ body.command-mode #modeCommandBtn,
448
+ body.terminal-mode #modeTerminalBtn {
449
+ color: #ffffff;
450
+ background: var(--accent);
451
+ border-color: var(--accent-strong);
452
+ }
453
+
454
+ .mode-terminal-controls {
455
+ display: none;
456
+ align-items: center;
457
+ gap: 8px;
458
+ min-width: 0;
459
+ }
460
+
461
+ body.terminal-mode .mode-terminal-controls {
462
+ display: inline-flex;
463
+ }
464
+
419
465
  #messages {
420
466
  min-height: 0;
421
467
  overflow-y: auto;
@@ -426,6 +472,71 @@ button.danger:hover {
426
472
  scroll-behavior: smooth;
427
473
  }
428
474
 
475
+ #terminalPanel {
476
+ min-height: 0;
477
+ display: none;
478
+ flex-direction: column;
479
+ gap: 8px;
480
+ padding: 6px 8px 8px;
481
+ }
482
+
483
+ .terminal-status {
484
+ display: inline-block;
485
+ color: var(--muted);
486
+ font-size: 12px;
487
+ white-space: nowrap;
488
+ }
489
+
490
+ #terminalScreen {
491
+ flex: 1;
492
+ min-height: 0;
493
+ height: 100%;
494
+ border-radius: 10px;
495
+ border: 1px solid #2a3d34;
496
+ box-shadow: inset 0 0 0 1px rgba(123, 161, 146, 0.12);
497
+ overflow: hidden;
498
+ background: radial-gradient(circle at 10% 8%, #1a2832 0%, #0c131a 64%);
499
+ }
500
+
501
+ #terminalScreen .xterm {
502
+ width: 100%;
503
+ height: 100%;
504
+ padding: 8px 6px;
505
+ }
506
+
507
+ #terminalScreen .xterm-screen {
508
+ width: 100%;
509
+ }
510
+
511
+ .terminal-foot {
512
+ color: #556961;
513
+ font-size: 12px;
514
+ }
515
+
516
+ body.command-mode #messages {
517
+ display: flex;
518
+ }
519
+
520
+ body.command-mode #terminalPanel {
521
+ display: none;
522
+ }
523
+
524
+ body.command-mode .composer {
525
+ display: block;
526
+ }
527
+
528
+ body.terminal-mode #messages {
529
+ display: none;
530
+ }
531
+
532
+ body.terminal-mode #terminalPanel {
533
+ display: flex;
534
+ }
535
+
536
+ body.terminal-mode .composer {
537
+ display: none;
538
+ }
539
+
429
540
  .msg {
430
541
  max-width: min(900px, 92%);
431
542
  width: fit-content;
@@ -652,6 +763,10 @@ button.danger:hover {
652
763
  max-height: none;
653
764
  }
654
765
 
766
+ #terminalPanel {
767
+ min-height: 0;
768
+ }
769
+
655
770
  .composer {
656
771
  position: sticky;
657
772
  bottom: 0;
@@ -740,6 +855,33 @@ button.danger:hover {
740
855
  grid-template-columns: 1fr auto;
741
856
  }
742
857
 
858
+ .mode-switch {
859
+ margin: 8px 10px 2px;
860
+ overflow-x: auto;
861
+ padding-bottom: 2px;
862
+ gap: 8px;
863
+ }
864
+
865
+ .mode-switch-left {
866
+ flex: 0 0 auto;
867
+ }
868
+
869
+ .mode-switch button {
870
+ min-width: 90px;
871
+ flex: 0 0 auto;
872
+ }
873
+
874
+ .mode-terminal-controls {
875
+ flex: 0 0 auto;
876
+ gap: 6px;
877
+ }
878
+
879
+ .terminal-status {
880
+ max-width: 5.2em;
881
+ overflow: hidden;
882
+ text-overflow: ellipsis;
883
+ }
884
+
743
885
  #commandInput {
744
886
  min-height: 68px;
745
887
  max-height: 160px;
@@ -8,6 +8,7 @@
8
8
  />
9
9
  <title>MANYOYO Web</title>
10
10
  <link rel="stylesheet" href="/app/frontend/app.css" />
11
+ <link rel="stylesheet" href="/app/vendor/xterm.css" />
11
12
  </head>
12
13
  <body>
13
14
  <div class="app">
@@ -62,7 +63,22 @@
62
63
  <button type="button" id="removeAllBtn" class="danger">删除对话</button>
63
64
  </div>
64
65
  </header>
66
+ <section class="mode-switch" id="modeSwitch">
67
+ <div class="mode-switch-left">
68
+ <button type="button" id="modeCommandBtn" class="secondary is-active">命令模式</button>
69
+ <button type="button" id="modeTerminalBtn" class="secondary">交互终端</button>
70
+ </div>
71
+ <div class="mode-terminal-controls">
72
+ <button type="button" id="terminalConnectBtn">连接终端</button>
73
+ <button type="button" id="terminalDisconnectBtn" class="secondary">断开终端</button>
74
+ <span id="terminalStatus" class="terminal-status">未连接</span>
75
+ </div>
76
+ </section>
65
77
  <section id="messages"></section>
78
+ <section id="terminalPanel" hidden>
79
+ <div id="terminalScreen" aria-label="终端输出区域"></div>
80
+ <div class="terminal-foot">点击终端后可直接输入;适用于 codex / claude 等交互式 agent。</div>
81
+ </section>
66
82
  <form class="composer" id="composer">
67
83
  <div class="composer-inner">
68
84
  <textarea id="commandInput" placeholder="输入容器命令,例如: ls -la"></textarea>
@@ -77,6 +93,8 @@
77
93
  <div id="sidebarBackdrop" class="sidebar-backdrop" hidden></div>
78
94
  </div>
79
95
 
96
+ <script src="/app/vendor/xterm.js"></script>
97
+ <script src="/app/vendor/xterm-addon-fit.js"></script>
80
98
  <script src="/app/frontend/app.js"></script>
81
99
  </body>
82
100
  </html>