codexmate 0.1.27 → 0.1.29

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.
Files changed (48) hide show
  1. package/README.md +53 -44
  2. package/README.vi.md +45 -36
  3. package/README.zh.md +51 -42
  4. package/cli/config-bootstrap.js +2 -9
  5. package/cli/session-usage.js +2 -2
  6. package/cli.js +407 -40
  7. package/package.json +1 -1
  8. package/web-ui/app.js +7 -0
  9. package/web-ui/index.html +12 -0
  10. package/web-ui/logic.sessions.mjs +6 -4
  11. package/web-ui/modules/app.computed.session.mjs +52 -33
  12. package/web-ui/modules/app.methods.agents.mjs +36 -0
  13. package/web-ui/modules/app.methods.codex-config.mjs +3 -1
  14. package/web-ui/modules/app.methods.index.mjs +2 -0
  15. package/web-ui/modules/app.methods.providers.mjs +12 -4
  16. package/web-ui/modules/app.methods.session-actions.mjs +10 -8
  17. package/web-ui/modules/app.methods.session-browser.mjs +3 -1
  18. package/web-ui/modules/app.methods.session-trash.mjs +16 -16
  19. package/web-ui/modules/app.methods.theme.mjs +39 -0
  20. package/web-ui/modules/app.methods.web-ui-preferences.mjs +9 -0
  21. package/web-ui/modules/i18n/locales/en.mjs +80 -2
  22. package/web-ui/modules/i18n/locales/ja.mjs +80 -2
  23. package/web-ui/modules/i18n/locales/vi.mjs +80 -2
  24. package/web-ui/modules/i18n/locales/zh-tw.mjs +80 -2
  25. package/web-ui/modules/i18n/locales/zh.mjs +80 -2
  26. package/web-ui/modules/i18n.mjs +7 -0
  27. package/web-ui/partials/index/modal-config-template-agents.html +1 -1
  28. package/web-ui/partials/index/modal-health-check.html +1 -1
  29. package/web-ui/partials/index/modal-openclaw-config.html +50 -50
  30. package/web-ui/partials/index/panel-dashboard.html +1 -1
  31. package/web-ui/partials/index/panel-prompts.html +2 -2
  32. package/web-ui/partials/index/panel-sessions.html +47 -30
  33. package/web-ui/partials/index/panel-settings.html +30 -0
  34. package/web-ui/res/web-ui-render.precompiled.js +244 -157
  35. package/web-ui/session-helpers.mjs +3 -0
  36. package/web-ui/styles/base-theme.css +3 -2
  37. package/web-ui/styles/bridge-pool.css +1 -1
  38. package/web-ui/styles/controls-forms.css +1 -1
  39. package/web-ui/styles/layout-shell.css +0 -1
  40. package/web-ui/styles/sessions-preview.css +77 -0
  41. package/web-ui/styles/sessions-toolbar-trash.css +1 -1
  42. package/web-ui/styles/sessions-usage.css +1 -1
  43. package/web-ui/styles/settings-panel.css +2 -2
  44. package/web-ui/styles/theme-dark-tokens.css +83 -0
  45. package/web-ui/styles/theme-dark.css +1355 -0
  46. package/web-ui/styles/theme-ocean-tokens.css +88 -0
  47. package/web-ui/styles/theme-ocean.css +920 -0
  48. package/web-ui/styles.css +2 -0
@@ -222,6 +222,7 @@ export async function loadSessions(api, options = {}) {
222
222
  const normalizedOptions = normalizeSessionLoadOptions(options);
223
223
  const includeActiveDetail = shouldIncludeActiveSessionDetail(this, normalizedOptions);
224
224
  this.sessionsLoading = true;
225
+ this.sessionSearchInfo = null;
225
226
  this.activeSessionDetailError = '';
226
227
  let loadSucceeded = false;
227
228
  const params = buildSessionListParams({
@@ -257,6 +258,7 @@ export async function loadSessions(api, options = {}) {
257
258
  clearSessionTimelineRefs(this);
258
259
  } else {
259
260
  loadSucceeded = true;
261
+ this.sessionSearchInfo = res.searchInfo || null;
260
262
  const rawSessions = Array.isArray(res.sessions) ? res.sessions : [];
261
263
  this.sessionsList = rawSessions.filter(s => s && typeof s === 'object');
262
264
  if (typeof this.clearSessionBatchSelection === 'function') {
@@ -313,6 +315,7 @@ export async function loadSessions(api, options = {}) {
313
315
  }
314
316
  }
315
317
  } catch (e) {
318
+ this.sessionSearchInfo = null;
316
319
  emitSessionLoadDebug(this, 'loadSessions:exception', e && e.message ? e.message : String(e));
317
320
  this.sessionsList = [];
318
321
  if (typeof this.primeSessionListRender === 'function') {
@@ -15,10 +15,11 @@
15
15
  --color-surface-alt: #F7EFE8;
16
16
  --color-surface-elevated: #FFFFFF;
17
17
  --color-surface-tint: rgba(255, 253, 250, 0.86);
18
+ --color-surface-chip: rgba(255, 255, 255, 0.76);
18
19
  --color-text-primary: #241F1C;
19
20
  --color-text-secondary: #5A504A;
20
- --color-text-tertiary: #82746A;
21
- --color-text-muted: #A99B91;
21
+ --color-text-tertiary: #74655B;
22
+ --color-text-muted: #77675C;
22
23
  --color-border: rgba(137, 111, 94, 0.18);
23
24
  --color-border-soft: rgba(137, 111, 94, 0.13);
24
25
  --color-border-strong: rgba(137, 111, 94, 0.34);
@@ -32,7 +32,7 @@
32
32
 
33
33
  /* ---- 轮询池触发按钮 ---- */
34
34
  .bridge-pool-trigger {
35
- color: var(--color-brand);
35
+ color: var(--color-brand-dark);
36
36
  background: rgba(200, 121, 99, 0.08);
37
37
  }
38
38
 
@@ -157,7 +157,7 @@
157
157
  line-height: 1 !important;
158
158
  border-radius: var(--radius-sm) !important;
159
159
  border: 1px solid var(--color-border-soft) !important;
160
- background: rgba(255, 255, 255, 0.76) !important;
160
+ background: var(--color-surface-chip) !important;
161
161
  font-size: 12px !important;
162
162
  font-weight: var(--font-weight-secondary) !important;
163
163
  color: var(--color-text-secondary) !important;
@@ -377,7 +377,6 @@ body::after {
377
377
  text-transform: uppercase;
378
378
  padding: 0 8px;
379
379
  margin-bottom: 6px;
380
- opacity: 0.72;
381
380
  }
382
381
 
383
382
  .side-item {
@@ -758,3 +758,80 @@
758
758
  width: 14px;
759
759
  height: 14px;
760
760
  }
761
+
762
+ /* Refined session workspace: preserve the list/detail structure and action contracts. */
763
+ #panel-sessions.session-browser-refined .session-preview-header {
764
+ padding: 12px 16px 8px; gap: 8px 16px;
765
+ display: grid; grid-template-columns: minmax(0, 1fr) auto;
766
+ grid-template-areas: "title export" "actions actions";
767
+ background: var(--color-surface); backdrop-filter: none;
768
+ }
769
+ #panel-sessions.session-browser-refined .session-preview-title {
770
+ font-size: 17px; line-height: 1.5; letter-spacing: -.015em;
771
+ }
772
+ #panel-sessions.session-browser-refined .session-preview-header > div:first-child { grid-area: title; min-width: 0; }
773
+ #panel-sessions .session-preview-actions { grid-area: actions; gap: 10px; justify-content: flex-start; margin-top: 0; }
774
+ #panel-sessions .session-export-control {
775
+ grid-area: export; justify-self: end; align-self: start;
776
+ display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
777
+ padding: 2px; border: 1px solid var(--color-border-soft); border-radius: var(--radius-md);
778
+ background: var(--color-surface-alt); max-width: 100%;
779
+ }
780
+ #panel-sessions .session-export-label { font-size: 12px; line-height: 1; color: var(--color-text-secondary); padding-inline: 6px 0; margin-block: 0; }
781
+ #panel-sessions #session-export-range {
782
+ min-height: 44px; min-width: 0; max-width: 100%; padding: 8px 28px 8px 10px;
783
+ border: 0; border-radius: var(--radius-sm); background: var(--color-surface);
784
+ color: var(--color-text-primary); font: inherit; font-size: 14px; cursor: pointer;
785
+ }
786
+ #panel-sessions .session-preview-actions button {
787
+ min-width: 44px; min-height: 44px; height: auto; width: auto; padding: 9px 12px;
788
+ border-radius: var(--radius-sm); box-shadow: none;
789
+ transition: background-color 120ms ease-out, transform 100ms ease-out, color 120ms ease-out;
790
+ touch-action: manipulation;
791
+ }
792
+ #panel-sessions .session-export-control .btn-session-export {
793
+ background: var(--color-text-primary); color: var(--color-surface);
794
+ border-color: transparent; font-weight: 600;
795
+ }
796
+ #panel-sessions .session-secondary-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
797
+ #panel-sessions .session-secondary-actions button { background: transparent; border-color: transparent; color: var(--color-text-secondary); }
798
+ #panel-sessions .session-secondary-actions .session-link-group { display: inline-flex; gap: 2px; }
799
+ #panel-sessions .session-danger-action { margin-inline-start: auto; padding-inline-start: 12px; border-inline-start: 1px solid var(--color-border-soft); }
800
+ #panel-sessions .session-danger-action button { background: transparent; border-color: transparent; }
801
+ #panel-sessions .session-preview-actions button:hover:not(:disabled) { transform: none; background: var(--color-surface-alt); }
802
+ #panel-sessions .session-export-control .btn-session-export:hover:not(:disabled) { background: var(--color-text-secondary); }
803
+ #panel-sessions .session-preview-actions button:active:not(:disabled) { transform: scale(.97); }
804
+ #panel-sessions .session-preview-actions :is(button, select):focus-visible,
805
+ #panel-sessions .session-empty-refined button:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 3px; }
806
+ #panel-sessions .session-preview-actions :disabled { opacity: .5; cursor: not-allowed; }
807
+ #panel-sessions .session-export-feedback { padding: 0 16px 16px; color: var(--color-text-secondary); line-height: 1.6; }
808
+ #panel-sessions .session-export-feedback small { display: block; font-size: 12px; }
809
+ #panel-sessions .session-export-notice {
810
+ margin: 10px 0 0; padding: 10px 12px; border: 1px solid var(--color-border-soft);
811
+ border-radius: var(--radius-sm); background: var(--color-surface-alt); font-size: 13px;
812
+ }
813
+ #panel-sessions .session-search-status {
814
+ display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px;
815
+ padding: 10px 2px 14px; font-size: 12px; line-height: 1.6; color: var(--color-text-secondary);
816
+ }
817
+ #panel-sessions .session-search-count { font-weight: 600; color: var(--color-text-primary); font-variant-numeric: tabular-nums; }
818
+ #panel-sessions .session-search-partial { color: var(--color-text-secondary); }
819
+ #panel-sessions .session-search-scope { font-size: inherit; margin-inline-start: auto; }
820
+ #panel-sessions .session-empty-refined { padding: 40px 20px; border: 1px dashed var(--color-border-soft); background: transparent; }
821
+ #panel-sessions .session-empty-refined::before { display: none; }
822
+ #panel-sessions .session-empty-refined p { margin: 0 0 16px; line-height: 1.65; }
823
+ #panel-sessions .session-empty-refined button { min-height: 44px; padding-inline: 16px; }
824
+ @media (max-width: 640px) {
825
+ #panel-sessions .session-preview-actions { flex-direction: row; align-items: center; gap: 10px; }
826
+ #panel-sessions .session-export-control { justify-self: stretch; }
827
+ #panel-sessions #session-export-range { flex: 1 1 120px; }
828
+ #panel-sessions .session-secondary-actions { flex: 1 1 180px; }
829
+ #panel-sessions .session-preview-actions button { width: auto; }
830
+ #panel-sessions .session-search-scope { flex-basis: 100%; margin-inline-start: 0; }
831
+ #panel-sessions.session-browser-refined .session-preview-header { padding: 12px 12px 8px; gap: 8px; grid-template-columns: 1fr; grid-template-areas: "title" "export" "actions"; }
832
+ #panel-sessions .session-export-feedback { padding-inline: 12px; }
833
+ }
834
+ @media (prefers-reduced-motion: reduce) {
835
+ #panel-sessions .session-preview-actions button { transition: none; }
836
+ #panel-sessions .session-preview-actions button:active:not(:disabled) { transform: none; }
837
+ }
@@ -179,7 +179,7 @@
179
179
  -webkit-tap-highlight-color: transparent;
180
180
  }
181
181
 
182
- .session-source-pill:hover:not(:disabled) {
182
+ .session-source-pill:hover:not(:disabled):not(.active) {
183
183
  color: var(--color-text-secondary);
184
184
  background: var(--color-surface);
185
185
  }
@@ -46,7 +46,7 @@
46
46
  -webkit-tap-highlight-color: transparent;
47
47
  }
48
48
 
49
- .usage-range-btn:hover:not(:disabled) {
49
+ .usage-range-btn:hover:not(:disabled):not(.active) {
50
50
  color: var(--color-text-secondary);
51
51
  background: rgba(200, 121, 99, 0.08);
52
52
  }
@@ -171,7 +171,7 @@
171
171
  left: 3px;
172
172
  width: 20px;
173
173
  height: 20px;
174
- background: white;
174
+ background: #fff;
175
175
  border-radius: 50%;
176
176
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
177
177
  transition: all 0.25s cubic-bezier(0.25, 1, 0.5, 1);
@@ -229,7 +229,7 @@
229
229
  flex: 1;
230
230
  }
231
231
 
232
- .settings-toggle-group .toggle-btn:hover:not(:disabled) {
232
+ .settings-toggle-group .toggle-btn:hover:not(:disabled):not(.active) {
233
233
  color: var(--color-text-secondary);
234
234
  background: var(--color-surface);
235
235
  }
@@ -0,0 +1,83 @@
1
+ /* ============================================
2
+ Codex Mate Web UI - 暗色主题令牌覆盖
3
+ 作用于 <html data-theme="dark">;浅色默认值见 base-theme.css
4
+ ============================================ */
5
+ :root[data-theme="dark"] {
6
+ color-scheme: dark;
7
+
8
+ /* 品牌色:保留暖橙 accent,提亮适配暗底 */
9
+ --color-brand: #D68F79;
10
+ --color-brand-dark: #C07A63;
11
+ --color-brand-light: rgba(214, 143, 121, 0.16);
12
+ --color-brand-subtle: rgba(214, 143, 121, 0.24);
13
+
14
+ /* 中性灰层级底色 */
15
+ --color-bg: #17181A;
16
+ --color-surface: #1E1F22;
17
+ --color-surface-alt: #232427;
18
+ --color-surface-elevated: #26272B;
19
+ --color-surface-tint: rgba(30, 31, 34, 0.86);
20
+ --color-surface-chip: rgba(30, 31, 34, 0.76);
21
+ --color-text-primary: #ECE8E4;
22
+ --color-text-secondary: #B5ABA4;
23
+ --color-text-tertiary: #A59A91;
24
+ --color-text-muted: #9A8D83;
25
+ --color-border: rgba(255, 255, 255, 0.09);
26
+ --color-border-soft: rgba(255, 255, 255, 0.06);
27
+ --color-border-strong: rgba(255, 255, 255, 0.2);
28
+
29
+ --color-success: #6DB08E;
30
+ --color-error: #D6766B;
31
+
32
+ /* Delta 指示色 */
33
+ --color-delta-up: #6FBE7C;
34
+ --color-delta-down: #EE7B6E;
35
+
36
+ /* 热力图色阶:品牌橙 alpha 阶梯 */
37
+ --color-heatmap-1: rgba(214, 143, 121, 0.18);
38
+ --color-heatmap-2: rgba(214, 143, 121, 0.38);
39
+ --color-heatmap-3: rgba(214, 143, 121, 0.58);
40
+ --color-heatmap-4: rgba(214, 143, 121, 0.85);
41
+
42
+ --bg-warm-gradient:
43
+ radial-gradient(circle at 14% 8%, rgba(214, 143, 121, 0.05) 0%, rgba(214, 143, 121, 0) 32%),
44
+ radial-gradient(circle at 88% 0%, rgba(120, 132, 158, 0.05) 0%, rgba(120, 132, 158, 0) 30%),
45
+ linear-gradient(135deg, #1A1B1E 0%, #17181A 46%, #141517 100%);
46
+
47
+ --color-bg-topbar-strong: rgba(23, 24, 26, 0.96);
48
+ --color-bg-topbar-soft: rgba(23, 24, 26, 0.86);
49
+ --color-bg-topbar-clear: rgba(23, 24, 26, 0);
50
+
51
+ /* 阴影:黑色系浮层 */
52
+ --shadow-subtle: 0 1px 2px rgba(0, 0, 0, 0.3);
53
+ --shadow-card: 0 12px 30px rgba(0, 0, 0, 0.35);
54
+ --shadow-card-hover: 0 18px 44px rgba(0, 0, 0, 0.45);
55
+ --shadow-float: 0 22px 56px rgba(0, 0, 0, 0.5);
56
+ --shadow-raised: 0 14px 30px rgba(0, 0, 0, 0.4);
57
+ --shadow-modal:
58
+ 0 16px 42px rgba(0, 0, 0, 0.45),
59
+ 0 34px 84px rgba(0, 0, 0, 0.45);
60
+ --shadow-input-focus:
61
+ 0 0 0 3px var(--color-brand-light),
62
+ 0 1px 2px rgba(0, 0, 0, 0.4);
63
+ }
64
+
65
+ /* 全局背景光斑:暗色下收敛为微弱冷光 */
66
+ :root[data-theme="dark"] body::before {
67
+ background:
68
+ radial-gradient(circle at 18% 16%, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0) 26%),
69
+ radial-gradient(circle at 86% 18%, rgba(214, 143, 121, 0.04), rgba(214, 143, 121, 0) 30%);
70
+ }
71
+
72
+ /* 滚动条 */
73
+ :root[data-theme="dark"] * {
74
+ scrollbar-color: rgba(255, 255, 255, 0.22) transparent;
75
+ }
76
+
77
+ :root[data-theme="dark"] ::-webkit-scrollbar-thumb {
78
+ background: rgba(255, 255, 255, 0.22);
79
+ }
80
+
81
+ :root[data-theme="dark"] ::-webkit-scrollbar-thumb:hover {
82
+ background: rgba(255, 255, 255, 0.34);
83
+ }