minecodex 2.0.4 → 2.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.
Files changed (100) hide show
  1. package/DESIGN.md +40 -1
  2. package/README.md +9 -3
  3. package/apps/dashboard/DESIGN.md +53 -31
  4. package/apps/dashboard/app.js +55 -39
  5. package/apps/dashboard/assets/OFL.txt +93 -0
  6. package/apps/dashboard/assets/info.svg +15 -0
  7. package/apps/dashboard/assets/moon.svg +13 -0
  8. package/apps/dashboard/assets/refresh-cw.svg +16 -0
  9. package/apps/dashboard/assets/silkscreen.ttf +0 -0
  10. package/apps/dashboard/assets/sun.svg +21 -0
  11. package/apps/dashboard/assets/terrain.js +89 -0
  12. package/apps/dashboard/assets/triangle-alert.svg +15 -0
  13. package/apps/dashboard/favicon.svg +12 -17
  14. package/apps/dashboard/index.html +24 -18
  15. package/apps/dashboard/styles.css +147 -181
  16. package/assets/brand/README.md +19 -0
  17. package/assets/brand/minecodex-icon-dark.svg +9 -0
  18. package/assets/brand/minecodex-icon-light.svg +9 -0
  19. package/assets/brand/minecodex-icon.svg +8 -0
  20. package/assets/brand/references/lucide-LICENSE.txt +43 -0
  21. package/assets/readme/hero.svg +93 -0
  22. package/features/hide-upsell-banner/README.md +7 -5
  23. package/features/hide-upsell-banner/codex-feature.json +2 -2
  24. package/features/hide-upsell-banner/src/hide-upsell-banner.mjs +30 -12
  25. package/features/images/DESIGN.md +117 -41
  26. package/features/images/README.md +26 -16
  27. package/features/images/codex-feature.json +6 -3
  28. package/features/images/src/adapters/codex/image-prompt.mjs +24 -2
  29. package/features/images/src/adapters/codex/image-sources.mjs +19 -0
  30. package/features/images/src/adapters/codex/library-api.mjs +2 -0
  31. package/features/images/src/adapters/codex/library-viewer.mjs +26 -2
  32. package/features/images/src/adapters/codex/native-image-modules.mjs +211 -0
  33. package/features/images/src/adapters/codex/native-image-source.mjs +449 -0
  34. package/features/images/src/backend/local-image-source.mjs +138 -0
  35. package/features/images/src/frontend/cloud-image-actions.mjs +41 -0
  36. package/features/images/src/frontend/local-image-source.mjs +195 -0
  37. package/features/images/src/library-prompt-page.mjs +163 -53
  38. package/features/images/src/library-prompt-source.mjs +9 -3
  39. package/features/images/src/prompt-index.mjs +14 -2
  40. package/features/model-slider/DESIGN.md +2 -0
  41. package/features/model-slider/codex-feature.json +2 -2
  42. package/features/model-slider/src/frontend/install.mjs +78 -11
  43. package/features/notes/DESIGN.md +7 -3
  44. package/features/notes/codex-feature.json +2 -2
  45. package/features/notes/src/frontend/entry.mjs +26 -9
  46. package/features/session-status/DESIGN.md +4 -2
  47. package/features/session-status/codex-feature.json +2 -2
  48. package/features/session-status/src/adapters/codex/session-log.mjs +2 -1
  49. package/features/session-status/src/domain/session-stats.mjs +17 -9
  50. package/features/session-status/src/session-status.mjs +47 -11
  51. package/features/sidebar-focus/DESIGN.md +4 -4
  52. package/features/sidebar-focus/codex-feature.json +3 -2
  53. package/features/sidebar-focus/src/adapters/codex/renderer.mjs +1 -1
  54. package/features/sidebar-focus/src/sidebar-focus.mjs +9 -7
  55. package/features/sites/DESIGN.md +25 -3
  56. package/features/sites/README.md +6 -2
  57. package/features/sites/codex-feature.json +3 -2
  58. package/features/sites/src/adapters/codex/renderer.mjs +25 -4
  59. package/features/sites/src/backend/project-sites.mjs +18 -6
  60. package/features/sites/src/backend/sites-service.mjs +22 -10
  61. package/features/sites/src/domain/discovery-candidates.mjs +53 -0
  62. package/features/sites/src/frontend/entry.mjs +76 -38
  63. package/features/sites/src/frontend/styles.css +3 -3
  64. package/features/unread-inbox/DESIGN.md +24 -25
  65. package/features/unread-inbox/codex-feature.json +3 -2
  66. package/features/unread-inbox/src/adapters/codex/modules.mjs +52 -0
  67. package/features/unread-inbox/src/adapters/codex/renderer.mjs +90 -0
  68. package/features/unread-inbox/src/domain/notifications.mjs +21 -0
  69. package/features/unread-inbox/src/injection-source.mjs +5 -2
  70. package/features/unread-inbox/src/unread-inbox.mjs +212 -297
  71. package/features/usage-meter/codex-feature.json +2 -2
  72. package/package.json +11 -3
  73. package/packages/cli/native/MineCodex.app/Contents/Info.plist +4 -2
  74. package/packages/cli/native/MineCodex.app/Contents/MacOS/MineCodexServiceManager +0 -0
  75. package/packages/cli/native/MineCodex.app/Contents/Resources/MineCodex.icns +0 -0
  76. package/packages/cli/native/MineCodex.app/Contents/_CodeSignature/CodeResources +11 -0
  77. package/packages/cli/native/README.md +31 -0
  78. package/packages/cli/src/browser-control-panel.mjs +48 -0
  79. package/packages/cli/src/commands.mjs +3 -1
  80. package/packages/cli/src/control-server.mjs +6 -3
  81. package/packages/cli/src/platform.mjs +5 -0
  82. package/packages/codex-adapter/README.md +2 -1
  83. package/packages/codex-adapter/src/renderer/environment.mjs +24 -6
  84. package/packages/runtime-host/README.md +10 -5
  85. package/packages/runtime-host/src/codex-injection.mjs +13 -9
  86. package/packages/runtime-host/src/codex-runtime.mjs +26 -5
  87. package/packages/runtime-host/src/feature-registry.mjs +1 -0
  88. package/packages/ui/DESIGN.md +9 -2
  89. package/packages/ui/assets/arrow-up-right.svg +14 -0
  90. package/packages/ui/assets/lucide-LICENSE.txt +43 -0
  91. package/packages/ui/src/components/account-menu.mjs +74 -0
  92. package/packages/ui/src/components/button.mjs +2 -0
  93. package/packages/ui/src/components/navigation-rail.mjs +18 -10
  94. package/packages/ui/src/components/page.mjs +9 -2
  95. package/packages/ui/src/foundation/layers.mjs +1 -0
  96. package/packages/ui/src/install.mjs +6 -1
  97. package/packages/ui/src/native/account-menu.mjs +21 -0
  98. package/packages/ui/src/native/navigation-rail.mjs +6 -1
  99. package/packages/ui/src/native/page.mjs +38 -0
  100. package/packages/ui/src/native/tokens.mjs +4 -0
@@ -1,57 +1,81 @@
1
+ @font-face {
2
+ font-family: "Silkscreen";
3
+ src: url("/assets/silkscreen.ttf?v=bold") format("truetype");
4
+ font-weight: 700;
5
+ font-display: swap;
6
+ }
7
+
1
8
  :root {
2
9
  color-scheme: light;
3
- --canvas: oklch(0.982 0.002 260);
10
+ --canvas: #edf1f7;
4
11
  --surface: oklch(1 0 0);
5
12
  --surface-muted: oklch(0.962 0.004 260);
6
13
  --ink: oklch(0.235 0.012 260);
7
14
  --ink-secondary: oklch(0.43 0.012 260);
8
15
  --ink-tertiary: oklch(0.52 0.012 260);
9
- --border: oklch(0.89 0.006 260);
16
+ --border: #d7dfe9;
10
17
  --border-heavy: oklch(0.8 0.008 260);
11
- --accent: oklch(0.58 0.19 255);
12
- --accent-hover: oklch(0.53 0.2 255);
13
- --accent-soft: oklch(0.95 0.03 255);
14
- --success: oklch(0.56 0.15 150);
18
+ --accent: #3478d4;
19
+ --accent-hover: #2463b8;
20
+ --accent-soft: #e8f0fc;
21
+ --success: #3478d4;
15
22
  --warning: oklch(0.61 0.14 70);
16
23
  --danger: oklch(0.56 0.2 27);
17
24
  --shadow: 0 1px 2px color-mix(in oklch, var(--ink) 7%, transparent), 0 8px 28px color-mix(in oklch, var(--ink) 5%, transparent);
18
25
  --focus: 0 0 0 3px color-mix(in oklch, var(--accent) 28%, transparent);
26
+ --card-radius: 8px;
27
+ --grid-gap: 16px;
28
+ --card-padding: 24px;
29
+ --grid-line: #44668d08;
30
+ --block-shadow: #cbd5e3;
31
+ --word-face: #e8effa;
32
+ --word-edge: #263b57;
33
+ --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
19
34
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
20
35
  }
21
36
 
22
- @media (prefers-color-scheme: dark) {
23
- :root {
37
+ :root[data-theme="dark"] {
24
38
  color-scheme: dark;
25
- --canvas: oklch(0.17 0.008 260);
26
- --surface: oklch(0.215 0.009 260);
27
- --surface-muted: oklch(0.25 0.01 260);
39
+ --canvas: #101722;
40
+ --surface: #1b2533;
41
+ --surface-muted: #253246;
28
42
  --ink: oklch(0.94 0.006 260);
29
43
  --ink-secondary: oklch(0.76 0.008 260);
30
44
  --ink-tertiary: oklch(0.67 0.008 260);
31
- --border: oklch(0.32 0.01 260);
45
+ --border: #334359;
32
46
  --border-heavy: oklch(0.41 0.012 260);
33
- --accent: oklch(0.7 0.16 255);
34
- --accent-hover: oklch(0.75 0.14 255);
35
- --accent-soft: oklch(0.27 0.04 255);
36
- --success: oklch(0.7 0.14 150);
47
+ --accent: #71a8f3;
48
+ --accent-hover: #8dbaff;
49
+ --accent-soft: #203653;
50
+ --success: #71a8f3;
37
51
  --warning: oklch(0.74 0.13 75);
38
52
  --danger: oklch(0.72 0.16 27);
53
+ --grid-line: #b9d4ff06;
54
+ --block-shadow: #080e17;
55
+ --word-face: #d3e3f8;
56
+ --word-edge: #060d18;
39
57
  --shadow: 0 1px 2px oklch(0 0 0 / 0.3), 0 12px 34px oklch(0 0 0 / 0.24);
40
- }
41
- .plugin-icon img { filter: invert(1); }
42
58
  }
43
59
 
60
+ :root[data-theme="dark"] .plugin-icon img { filter: invert(1); }
61
+
44
62
  * { box-sizing: border-box; }
45
63
 
46
64
  body {
47
65
  min-width: 320px;
66
+ min-height: 100vh;
48
67
  margin: 0;
49
- background: var(--canvas);
68
+ background-color: var(--canvas);
69
+ background-image: radial-gradient(ellipse at 50% 0%, var(--accent-soft), transparent 75%);
70
+ background-repeat: no-repeat;
71
+ background-attachment: fixed;
50
72
  color: var(--ink);
51
- font-size: 13px;
73
+ font-size: 14px;
52
74
  -webkit-font-smoothing: antialiased;
53
75
  }
54
76
 
77
+ #agent-world { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
78
+
55
79
  button, input { font: inherit; }
56
80
 
57
81
  button:focus-visible, input:focus-visible + .switch-track {
@@ -60,12 +84,14 @@ button:focus-visible, input:focus-visible + .switch-track {
60
84
  }
61
85
 
62
86
  .shell {
63
- width: min(100% - 40px, 880px);
87
+ position: relative;
88
+ z-index: 1;
89
+ width: min(100% - 40px, 1064px);
64
90
  margin: 0 auto;
65
- padding: 42px 0 32px;
91
+ padding: 48px 0 32px;
66
92
  }
67
93
 
68
- .page-header, .section-heading, .restart-notice, .diagnostics, .plugin-card {
94
+ .page-header, .restart-notice, .diagnostics, .plugin-card {
69
95
  display: flex;
70
96
  align-items: center;
71
97
  }
@@ -73,20 +99,53 @@ button:focus-visible, input:focus-visible + .switch-track {
73
99
  .page-header {
74
100
  justify-content: space-between;
75
101
  gap: 24px;
76
- margin-bottom: 28px;
102
+ margin-bottom: 32px;
103
+ padding-bottom: 28px;
104
+ border-bottom: 2px solid var(--border);
105
+ }
106
+
107
+ h1, h2, h3, p { margin: 0; }
108
+ h1 { display: flex; align-items: center; gap: 22px; font-size: clamp(36px, 5.3vw, 64px); line-height: 1.2; font-weight: 400; }
109
+ .brand-name {
110
+ font-family: "Silkscreen", monospace;
111
+ font-weight: 700;
112
+ letter-spacing: -0.07em;
113
+ color: var(--word-face);
114
+ -webkit-text-stroke: 1px var(--word-edge);
115
+ text-shadow: 1px 1px 0 var(--word-edge), 2px 2px 0 var(--word-edge), 3px 3px 0 var(--word-edge), 4px 4px 0 var(--word-edge), 5px 5px 0 var(--block-shadow);
116
+ }
117
+ .brand-icon {
118
+ display: inline-block;
119
+ width: 76px;
120
+ height: 76px;
121
+ flex: 0 0 76px;
122
+ background: var(--ink);
123
+ mask: url("/favicon.svg?v=minecodex-1") center / contain no-repeat;
124
+ -webkit-mask: url("/favicon.svg?v=minecodex-1") center / contain no-repeat;
77
125
  }
78
126
 
79
- h1, h2, p { margin: 0; }
80
- h1 { font-size: 20px; font-weight: 650; letter-spacing: -0.015em; }
127
+ .ui-icon { display: inline-block; width: 18px; height: 18px; flex: 0 0 18px; background: currentColor; mask: var(--icon) center / contain no-repeat; }
128
+ .sun-icon { --icon: url("/assets/sun.svg"); }
129
+ .moon-icon { --icon: url("/assets/moon.svg"); }
130
+ .refresh-icon { --icon: url("/assets/refresh-cw.svg"); }
131
+ .info-icon { --icon: url("/assets/info.svg"); }
132
+ .alert-icon { --icon: url("/assets/triangle-alert.svg"); }
133
+ .theme-toggle { position: relative; display: flex; gap: 4px; padding: 4px; border-radius: 999px; background: var(--surface-muted); box-shadow: inset 0 0 0 1px var(--border); }
134
+ .theme-toggle button { position: relative; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--ink-secondary); cursor: pointer; }
135
+ .theme-toggle button[aria-pressed="true"] { color: var(--ink); }
136
+ .theme-selection { position: absolute; inset: 4px auto auto 4px; width: 32px; height: 32px; border-radius: 50%; background: var(--surface); box-shadow: 0 1px 3px #0002; transition: transform 180ms var(--ease-out); }
137
+ :root[data-theme="dark"] .theme-selection { transform: translateX(36px); }
138
+
81
139
  h2 { font-size: 14px; font-weight: 620; }
82
140
 
83
- .subtitle, #plugins-copy, .restart-notice p, .plugin-description, .error-state p {
141
+ .restart-notice p, .plugin-description, .error-state p {
84
142
  color: var(--ink-secondary);
85
143
  line-height: 1.5;
86
144
  text-wrap: pretty;
87
145
  }
88
146
 
89
- .subtitle { margin-top: 4px; }
147
+ .overview { margin: 0 0 32px; }
148
+ .header-actions { flex-shrink: 0; }
90
149
 
91
150
  .runtime-state, .plugin-state {
92
151
  display: inline-flex;
@@ -94,12 +153,13 @@ h2 { font-size: 14px; font-weight: 620; }
94
153
  gap: 7px;
95
154
  color: var(--ink-secondary);
96
155
  font-size: 12px;
97
- white-space: nowrap;
156
+ line-height: 1.5;
98
157
  }
99
158
 
100
159
  .status-dot {
101
- width: 7px;
102
- height: 7px;
160
+ width: 6px;
161
+ height: 6px;
162
+ flex: 0 0 6px;
103
163
  border-radius: 50%;
104
164
  background: var(--ink-tertiary);
105
165
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--ink-tertiary) 12%, transparent);
@@ -110,152 +170,55 @@ h2 { font-size: 14px; font-weight: 620; }
110
170
  .status-dot.is-failed { background: var(--danger); box-shadow: 0 0 0 3px color-mix(in oklch, var(--danger) 14%, transparent); }
111
171
  .status-dot.is-stopped { background: var(--ink-tertiary); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ink-tertiary) 12%, transparent); }
112
172
 
113
- .restart-notice {
114
- justify-content: space-between;
115
- gap: 24px;
116
- margin-bottom: 28px;
117
- padding: 14px 16px;
118
- border: 1px solid color-mix(in oklch, var(--accent) 22%, var(--border));
119
- border-radius: 12px;
120
- background: var(--accent-soft);
121
- animation: notice-in 180ms cubic-bezier(0.22, 1, 0.36, 1);
122
- }
123
-
124
- .restart-notice p { margin-top: 3px; }
125
-
126
- .section-heading {
127
- justify-content: space-between;
128
- gap: 20px;
129
- margin-bottom: 12px;
130
- }
131
-
132
- .section-heading h2 { margin-bottom: 3px; }
133
- .save-state { min-height: 18px; color: var(--ink-tertiary); font-size: 12px; }
134
-
135
- .plugin-list {
136
- overflow: hidden;
137
- border: 1px solid var(--border);
138
- border-radius: 14px;
139
- background: var(--surface);
140
- box-shadow: var(--shadow);
141
- }
142
-
143
- .plugin-card {
144
- min-height: 106px;
145
- gap: 14px;
146
- padding: 18px;
147
- }
148
-
149
- .plugin-card + .plugin-card { border-top: 1px solid var(--border); }
150
-
151
- .plugin-icon {
152
- display: grid;
153
- width: 34px;
154
- height: 34px;
155
- flex: 0 0 34px;
156
- place-items: center;
157
- border-radius: 9px;
158
- background: var(--surface-muted);
159
- color: var(--ink-secondary);
160
- }
161
-
162
- .plugin-icon img { width: 18px; height: 18px; opacity: 0.78; }
163
- .plugin-copy { min-width: 0; flex: 1; }
164
- .plugin-title-line { display: flex; align-items: baseline; gap: 8px; }
165
- .plugin-name { font-size: 14px; font-weight: 620; }
166
- .plugin-version { color: var(--ink-tertiary); font-size: 11px; }
167
- .plugin-description { max-width: 66ch; margin-top: 5px; }
168
-
169
- .plugin-control {
170
- display: flex;
171
- min-width: 138px;
172
- flex: 0 0 138px;
173
- flex-direction: column;
174
- align-items: flex-end;
175
- gap: 9px;
176
- }
177
-
178
- .switch { position: relative; display: inline-flex; cursor: pointer; }
179
- .switch input {
180
- position: absolute;
181
- z-index: 1;
182
- inset: 0;
183
- width: 36px;
184
- height: 21px;
185
- margin: 0;
186
- cursor: pointer;
187
- opacity: 0;
188
- }
189
- .switch-track {
190
- position: relative;
191
- pointer-events: none;
192
- width: 36px;
193
- height: 21px;
194
- border: 1px solid var(--border-heavy);
195
- border-radius: 999px;
196
- background: var(--surface-muted);
197
- transition: background 170ms ease-out, border-color 170ms ease-out;
198
- }
199
- .switch-track::after {
200
- content: "";
201
- position: absolute;
202
- top: 2px;
203
- left: 2px;
204
- width: 15px;
205
- height: 15px;
206
- border-radius: 50%;
207
- background: var(--surface);
208
- box-shadow: 0 1px 3px oklch(0 0 0 / 0.25);
209
- transition: transform 180ms cubic-bezier(0.22, 1, 0.36, 1);
210
- }
173
+ .restart-notice, .error-state { display: flex; align-items: center; gap: 16px; padding: 20px; border: 1px solid var(--border); border-radius: var(--card-radius); background: var(--surface); box-shadow: 0 3px 0 var(--block-shadow); }
174
+ .restart-notice { margin-bottom: 24px; border-left: 4px solid var(--accent); }
175
+ .notice-copy { flex: 1; min-width: 0; }
176
+ .notice-copy h2, .notice-copy strong { font-size: 14px; font-weight: 600; }
177
+ .notice-copy p { margin-top: 5px; font-size: 13px; line-height: 1.6; }
178
+ .notice-icon { width: 22px; height: 22px; flex-basis: 22px; color: var(--accent); }
179
+ .error-state { border-left: 4px solid var(--danger); }
180
+ .error-state .notice-icon { color: var(--danger); }
181
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
182
+ .plugin-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); }
183
+ .plugin-card { display: flex; flex-direction: column; align-items: stretch; min-width: 0; min-height: 216px; padding: var(--card-padding); border: 1px solid var(--border); border-radius: var(--card-radius); background: var(--surface); box-shadow: 0 3px 0 var(--block-shadow); }
184
+ .plugin-topline { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
185
+ .plugin-icon { display: grid; place-items: center; width: 28px; height: 28px; }
186
+ .plugin-icon img { width: 24px; height: 24px; opacity: 0.75; }
187
+ .plugin-copy { flex: 1; }
188
+ .plugin-name { font-size: 16px; font-weight: 600; line-height: 1.5; letter-spacing: -0.01em; }
189
+ .plugin-description { margin-top: 8px; font-size: 14px; line-height: 1.65; }
190
+ .plugin-state { margin-top: 16px; font-size: 13px; }
191
+ .plugin-card:has(input:focus-visible) { border-color: var(--accent); }
192
+ .switch { position: relative; display: inline-flex; align-items: center; min-height: 32px; cursor: pointer; }
193
+ .switch input { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; opacity: 0; }
194
+ .switch-track { position: relative; pointer-events: none; width: 36px; height: 21px; border: 1px solid var(--border-heavy); border-radius: 999px; background: var(--surface-muted); transition: opacity 160ms var(--ease-out); }
195
+ .switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: white; box-shadow: 0 1px 3px #0004; transition: transform 180ms var(--ease-out); }
211
196
  .switch input:checked + .switch-track { border-color: var(--accent); background: var(--accent); }
212
197
  .switch input:checked + .switch-track::after { transform: translateX(15px); }
213
198
  .switch input:disabled + .switch-track { cursor: wait; opacity: 0.58; }
214
-
215
- .button {
216
- min-height: 32px;
217
- border: 1px solid transparent;
218
- border-radius: 8px;
219
- padding: 6px 12px;
220
- cursor: pointer;
221
- font-weight: 560;
222
- transition: background 160ms ease-out, border-color 160ms ease-out, transform 80ms ease-out;
223
- }
224
- .button:active { transform: translateY(1px); }
199
+ .button { min-height: 32px; border: 1px solid transparent; border-radius: 6px; padding: 6px 12px; cursor: pointer; font-weight: 400; transition: transform 140ms var(--ease-out); }
200
+ .button:active:not(:disabled) { transform: scale(0.97); }
225
201
  .button:disabled { cursor: wait; opacity: 0.62; }
226
- .button.primary { background: var(--accent); color: white; }
227
- .button.primary:hover:not(:disabled) { background: var(--accent-hover); }
202
+ .button.primary { background: var(--ink); color: var(--surface); box-shadow: 0 2px 0 var(--block-shadow); }
228
203
  .button.secondary { border-color: var(--border-heavy); background: var(--surface); color: var(--ink); }
229
- .button.secondary:hover:not(:disabled), .button.quiet:hover:not(:disabled) { background: var(--surface-muted); }
230
204
  .button.quiet { border-color: transparent; background: transparent; color: var(--ink-secondary); }
231
-
232
- .plugin-skeleton {
233
- height: 106px;
234
- background: linear-gradient(90deg, transparent, color-mix(in oklch, var(--ink) 5%, transparent), transparent);
235
- background-size: 220% 100%;
236
- animation: skeleton 1.2s linear infinite;
205
+ .plugin-skeleton { height: 216px; border: 1px solid var(--border); border-radius: var(--card-radius); background: var(--surface); }
206
+ @media (hover: hover) and (pointer: fine) {
207
+ .button.primary:hover:not(:disabled) { opacity: 0.88; }
208
+ .button.secondary:hover:not(:disabled), .button.quiet:hover:not(:disabled) { background: var(--surface-muted); }
209
+ .switch:hover .switch-track { opacity: 0.85; }
237
210
  }
238
- .plugin-skeleton + .plugin-skeleton { border-top: 1px solid var(--border); }
239
-
240
- .error-state {
241
- display: flex;
242
- align-items: center;
243
- justify-content: space-between;
244
- gap: 20px;
245
- padding: 18px;
246
- border: 1px solid color-mix(in oklch, var(--danger) 30%, var(--border));
247
- border-radius: 12px;
248
- background: color-mix(in oklch, var(--danger) 7%, var(--surface));
249
- }
250
- .error-state p { margin-top: 4px; }
251
211
 
252
212
  .diagnostics {
253
- justify-content: space-between;
254
- gap: 24px;
213
+ justify-content: flex-start;
214
+ flex-wrap: wrap;
215
+ gap: 16px;
255
216
  margin-top: 26px;
256
217
  padding-top: 18px;
257
218
  border-top: 1px solid var(--border);
258
219
  }
220
+ .diagnostics .button { display: inline-flex; align-items: center; gap: 7px; font-weight: 400; }
221
+ .diagnostics .ui-icon { width: 15px; height: 15px; flex-basis: 15px; }
259
222
  .diagnostics dl { display: flex; flex-wrap: wrap; gap: 10px 24px; margin: 0; }
260
223
  .diagnostics dl div { display: flex; gap: 6px; }
261
224
  .diagnostics dt { color: var(--ink-tertiary); }
@@ -263,33 +226,36 @@ h2 { font-size: 14px; font-weight: 620; }
263
226
 
264
227
  .toast {
265
228
  position: fixed;
229
+ z-index: 2;
266
230
  right: 20px;
267
231
  bottom: 20px;
268
232
  max-width: min(360px, calc(100vw - 40px));
269
233
  border: 1px solid var(--border-heavy);
270
- border-radius: 10px;
271
- padding: 10px 12px;
234
+ border-radius: var(--card-radius);
235
+ border-left: 4px solid var(--danger);
236
+ padding: 16px 20px;
237
+ line-height: 1.6;
272
238
  background: var(--surface);
273
239
  box-shadow: var(--shadow);
274
240
  }
275
241
 
276
242
  [hidden] { display: none !important; }
277
243
 
278
- @keyframes notice-in { from { opacity: 0; transform: translateY(-4px); } }
279
- @keyframes skeleton { to { background-position: -220% 0; } }
280
-
281
- @media (max-width: 640px) {
282
- .shell { width: min(100% - 24px, 880px); padding-top: 26px; }
283
- .page-header { align-items: flex-start; }
284
- .restart-notice, .diagnostics { align-items: stretch; flex-direction: column; }
285
- .restart-notice .button { width: 100%; }
286
- .plugin-card { align-items: flex-start; flex-wrap: wrap; }
287
- .plugin-copy { flex-basis: calc(100% - 48px); }
288
- .plugin-control { width: 100%; min-width: 0; flex: 1 0 100%; flex-direction: row-reverse; justify-content: space-between; align-items: flex-start; padding-left: 48px; }
289
- .plugin-control .switch { flex: 0 0 auto; }
290
- .plugin-control .plugin-state { min-width: 0; align-items: flex-start; white-space: normal; line-height: 1.4; }
291
- .plugin-control .plugin-state .status-dot { flex: 0 0 auto; margin-top: 5px; }
292
- .diagnostics .button { align-self: flex-start; }
244
+ .update-result { margin-top: 12px; color: var(--ink-secondary); font-size: 12px; line-height: 1.6; }
245
+ :root[data-input="keyboard"] *, :root[data-input="keyboard"] *::after { transition: none !important; }
246
+ @media (max-width: 960px) { .plugin-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
247
+ @media (max-width: 600px) {
248
+ .shell { width: calc(100% - 32px); padding-top: 28px; }
249
+ .page-header { align-items: flex-start; gap: 12px; }
250
+ h1 { font-size: clamp(24px, 6vw, 36px); gap: 12px; }
251
+ .brand-icon { width: 48px; height: 48px; flex-basis: 48px; }
252
+ .page-header { flex-wrap: wrap; align-items: center; padding-bottom: 24px; }
253
+ .header-actions .button { padding: 6px 9px; font-size: 12px; }
254
+ .plugin-list { grid-template-columns: 1fr; }
255
+ .plugin-card { min-height: 204px; }
256
+ .restart-notice, .error-state { flex-wrap: wrap; gap: 12px; }
257
+ .restart-notice .button, .error-state .button { margin-left: 34px; }
258
+ .diagnostics { gap: 12px; }
293
259
  }
294
260
 
295
261
  @media (prefers-reduced-motion: reduce) {
@@ -0,0 +1,19 @@
1
+ # MineCodex 图标
2
+
3
+ `minecodex-icon.svg` 是透明底、单色的可编辑矢量图标,使用 `viewBox="0 0 24 24"` 和 `currentColor`。外圈与镐子分别位于 `codex-outline`、`pickaxe`,可单独编辑。`minecodex-icon.png` 是 512×512 透明底预览;`minecodex-icon-preview.png` 展示已选实心版的明暗主题及 16/24/32/48px 尺寸。当前主文件为实心版;`minecodex-icon-filled.svg` 是实心版副本,`minecodex-icon-outline.svg` 保留上一版空心设计。
4
+
5
+ ## 设计与来源
6
+
7
+ - 外圈完整保留 Codex 原生六瓣 SVG 路径,移除原来的终端符号。
8
+ - 空心版镐子复用原生资源中的 Lucide pickaxe;实心版依据同一轮廓合并为单一闭合填充路径,无内部描边。Minecraft 灵感由镐子语义表达。
9
+ - 内部镐子以 `translate(6.24 6.24) scale(.48)` 居中。空心版描边宽度为 `2.65`,变换后为 `1.272`;实心版只使用 `fill`。原生外圈路径保持不变。
10
+ - 来源为本机 `/Applications/ChatGPT.app/Contents/Resources/app.asar`,版本 **26.930.21537**;原始文件为 `webview/assets/codex_new-f14177b03534.svg` 与 `webview/assets/pickaxe-b4cdf185b279.svg`。
11
+ - 原始 SVG 保留在 `references/`,Lucide 许可保留在 `references/lucide-LICENSE.txt`。Codex 外圈属于 OpenAI 原生品牌素材,Lucide 许可仅覆盖镐子。
12
+
13
+ 推荐展示尺寸为 24px 及以上;16px 可保持整体轮廓,但镐子的内部细节会减少。颜色继承使用环境的 `color`;独立打开时默认黑色,白色版本可设置根 SVG 的 `color="#fff"`。
14
+
15
+ ## 应用与维护
16
+
17
+ `minecodex-icon.svg` 是唯一可编辑的生产源;运行 `npm run build:icons` 生成明暗 SVG、Dashboard favicon 和 README 顶部标识。`minecodex-icon-light.svg` 用于浅色背景,`minecodex-icon-dark.svg` 用于深色背景。Dashboard 标题通过 favicon 的 CSS mask 消费同一几何,颜色继承页面文字色。主题 SVG 与生产源、Lucide 许可、README 展示图均进入 npm 发布名单。
18
+
19
+ 历史空心版和 PNG 对比图仅用于设计参考,不进入 npm 发布包。macOS 后台服务 1.0.1 已接入 ICNS 图标;`minecodex-service-icon.svg` 为同一几何配浅色圆角底板的原生图标源,更新遵循原生服务文档的注销、替换和重新注册流程。
@@ -0,0 +1,9 @@
1
+ <!-- Generated by scripts/build-brand-icons.mjs from assets/brand/minecodex-icon.svg. -->
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" color="#fafafa" fill="none" role="img" aria-labelledby="minecodex-title">
3
+ <title id="minecodex-title">MineCodex</title>
4
+ <desc>Codex 原生六瓣外圈与实心镐子,象征受 Minecraft 启发的 Codex 工具项目。</desc>
5
+ <path id="codex-outline" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.3316 2.03768C11.1644 1.54688 13.0268 2.04668 14.356 3.20174C16.0859 2.86512 17.9511 3.36418 19.2935 4.70663C20.6356 6.04882 21.1326 7.91288 20.7964 9.64217C21.9527 10.9716 22.4534 12.8349 21.9625 14.6685C21.4711 16.5025 20.1051 17.8657 18.439 18.439C17.8658 20.1047 16.503 21.47 14.6695 21.9615C12.8356 22.4528 10.9727 21.9519 9.64312 20.7955C7.91371 21.1319 6.04993 20.635 4.70757 19.2926C3.36558 17.9505 2.86659 16.0866 3.20269 14.357C2.04693 13.0273 1.54757 11.1638 2.03863 9.33065C2.52997 7.49759 3.89436 6.13282 5.56011 5.55917C6.13382 3.8935 7.49837 2.52891 9.3316 2.03768ZM13.2623 4.63534C12.3606 3.80149 11.067 3.4361 9.79742 3.77596C8.52745 4.11626 7.58924 5.0796 7.22515 6.25253C7.08145 6.71575 6.71753 7.07928 6.25445 7.22323C5.08133 7.58702 4.11844 8.52622 3.77789 9.79647C3.43759 11.0667 3.80148 12.3606 4.63531 13.2623C4.96467 13.6184 5.09776 14.1154 4.99078 14.5885C4.71939 15.7864 5.05109 17.0891 5.98101 18.0191C6.91085 18.949 8.21345 19.2801 9.41168 19.0084L9.58941 18.9791C9.94695 18.9432 10.3065 19.0397 10.5982 19.2496L10.7378 19.3639L10.9117 19.5142C11.8015 20.2407 13.0127 20.5413 14.2037 20.2223C15.4733 19.8818 16.4111 18.9191 16.775 17.7457C16.9189 17.2824 17.2832 16.9186 17.7466 16.775L17.9634 16.6998C19.0376 16.2923 19.9051 15.3936 20.2242 14.2027C20.5641 12.9328 20.1989 11.6385 19.3648 10.7369C19.0353 10.3806 18.9021 9.88399 19.0093 9.41073L19.0533 9.18514C19.2372 8.0514 18.8917 6.85176 18.0201 5.98006C17.0901 5.05003 15.7865 4.71826 14.5884 4.98983C14.1153 5.09712 13.6186 4.96467 13.2623 4.63534Z"/>
6
+ <g id="pickaxe" transform="translate(6.24 6.24) scale(.48)" fill="currentColor">
7
+ <path d="M15.686 4.314 16.3 3.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-.614.614a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319l-.198.199a1 1 0 0 1-1.4 0l-.219.169L6.619 20.38a1 1 0 1 1-3-3l7.912-7.912.169.232a1 1 0 0 1 0-1.4l.198-.197A22 22 0 0 0 5.58 4.71a1 1 0 0 1-.119-1.752 12.5 12.5 0 0 1 10.225 1.356Z"/>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <!-- Generated by scripts/build-brand-icons.mjs from assets/brand/minecodex-icon.svg. -->
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" color="#0d0d0d" fill="none" role="img" aria-labelledby="minecodex-title">
3
+ <title id="minecodex-title">MineCodex</title>
4
+ <desc>Codex 原生六瓣外圈与实心镐子,象征受 Minecraft 启发的 Codex 工具项目。</desc>
5
+ <path id="codex-outline" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.3316 2.03768C11.1644 1.54688 13.0268 2.04668 14.356 3.20174C16.0859 2.86512 17.9511 3.36418 19.2935 4.70663C20.6356 6.04882 21.1326 7.91288 20.7964 9.64217C21.9527 10.9716 22.4534 12.8349 21.9625 14.6685C21.4711 16.5025 20.1051 17.8657 18.439 18.439C17.8658 20.1047 16.503 21.47 14.6695 21.9615C12.8356 22.4528 10.9727 21.9519 9.64312 20.7955C7.91371 21.1319 6.04993 20.635 4.70757 19.2926C3.36558 17.9505 2.86659 16.0866 3.20269 14.357C2.04693 13.0273 1.54757 11.1638 2.03863 9.33065C2.52997 7.49759 3.89436 6.13282 5.56011 5.55917C6.13382 3.8935 7.49837 2.52891 9.3316 2.03768ZM13.2623 4.63534C12.3606 3.80149 11.067 3.4361 9.79742 3.77596C8.52745 4.11626 7.58924 5.0796 7.22515 6.25253C7.08145 6.71575 6.71753 7.07928 6.25445 7.22323C5.08133 7.58702 4.11844 8.52622 3.77789 9.79647C3.43759 11.0667 3.80148 12.3606 4.63531 13.2623C4.96467 13.6184 5.09776 14.1154 4.99078 14.5885C4.71939 15.7864 5.05109 17.0891 5.98101 18.0191C6.91085 18.949 8.21345 19.2801 9.41168 19.0084L9.58941 18.9791C9.94695 18.9432 10.3065 19.0397 10.5982 19.2496L10.7378 19.3639L10.9117 19.5142C11.8015 20.2407 13.0127 20.5413 14.2037 20.2223C15.4733 19.8818 16.4111 18.9191 16.775 17.7457C16.9189 17.2824 17.2832 16.9186 17.7466 16.775L17.9634 16.6998C19.0376 16.2923 19.9051 15.3936 20.2242 14.2027C20.5641 12.9328 20.1989 11.6385 19.3648 10.7369C19.0353 10.3806 18.9021 9.88399 19.0093 9.41073L19.0533 9.18514C19.2372 8.0514 18.8917 6.85176 18.0201 5.98006C17.0901 5.05003 15.7865 4.71826 14.5884 4.98983C14.1153 5.09712 13.6186 4.96467 13.2623 4.63534Z"/>
6
+ <g id="pickaxe" transform="translate(6.24 6.24) scale(.48)" fill="currentColor">
7
+ <path d="M15.686 4.314 16.3 3.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-.614.614a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319l-.198.199a1 1 0 0 1-1.4 0l-.219.169L6.619 20.38a1 1 0 1 1-3-3l7.912-7.912.169.232a1 1 0 0 1 0-1.4l.198-.197A22 22 0 0 0 5.58 4.71a1 1 0 0 1-.119-1.752 12.5 12.5 0 0 1 10.225 1.356Z"/>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" role="img" aria-labelledby="minecodex-title">
2
+ <title id="minecodex-title">MineCodex</title>
3
+ <desc>Codex 原生六瓣外圈与实心镐子,象征受 Minecraft 启发的 Codex 工具项目。</desc>
4
+ <path id="codex-outline" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.3316 2.03768C11.1644 1.54688 13.0268 2.04668 14.356 3.20174C16.0859 2.86512 17.9511 3.36418 19.2935 4.70663C20.6356 6.04882 21.1326 7.91288 20.7964 9.64217C21.9527 10.9716 22.4534 12.8349 21.9625 14.6685C21.4711 16.5025 20.1051 17.8657 18.439 18.439C17.8658 20.1047 16.503 21.47 14.6695 21.9615C12.8356 22.4528 10.9727 21.9519 9.64312 20.7955C7.91371 21.1319 6.04993 20.635 4.70757 19.2926C3.36558 17.9505 2.86659 16.0866 3.20269 14.357C2.04693 13.0273 1.54757 11.1638 2.03863 9.33065C2.52997 7.49759 3.89436 6.13282 5.56011 5.55917C6.13382 3.8935 7.49837 2.52891 9.3316 2.03768ZM13.2623 4.63534C12.3606 3.80149 11.067 3.4361 9.79742 3.77596C8.52745 4.11626 7.58924 5.0796 7.22515 6.25253C7.08145 6.71575 6.71753 7.07928 6.25445 7.22323C5.08133 7.58702 4.11844 8.52622 3.77789 9.79647C3.43759 11.0667 3.80148 12.3606 4.63531 13.2623C4.96467 13.6184 5.09776 14.1154 4.99078 14.5885C4.71939 15.7864 5.05109 17.0891 5.98101 18.0191C6.91085 18.949 8.21345 19.2801 9.41168 19.0084L9.58941 18.9791C9.94695 18.9432 10.3065 19.0397 10.5982 19.2496L10.7378 19.3639L10.9117 19.5142C11.8015 20.2407 13.0127 20.5413 14.2037 20.2223C15.4733 19.8818 16.4111 18.9191 16.775 17.7457C16.9189 17.2824 17.2832 16.9186 17.7466 16.775L17.9634 16.6998C19.0376 16.2923 19.9051 15.3936 20.2242 14.2027C20.5641 12.9328 20.1989 11.6385 19.3648 10.7369C19.0353 10.3806 18.9021 9.88399 19.0093 9.41073L19.0533 9.18514C19.2372 8.0514 18.8917 6.85176 18.0201 5.98006C17.0901 5.05003 15.7865 4.71826 14.5884 4.98983C14.1153 5.09712 13.6186 4.96467 13.2623 4.63534Z"/>
5
+ <g id="pickaxe" transform="translate(6.24 6.24) scale(.48)" fill="currentColor">
6
+ <path d="M15.686 4.314 16.3 3.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-.614.614a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319l-.198.199a1 1 0 0 1-1.4 0l-.219.169L6.619 20.38a1 1 0 1 1-3-3l7.912-7.912.169.232a1 1 0 0 1 0-1.4l.198-.197A22 22 0 0 0 5.58 4.71a1 1 0 0 1-.119-1.752 12.5 12.5 0 0 1 10.225 1.356Z"/>
7
+ </g>
8
+ </svg>
@@ -0,0 +1,43 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Lucide Icons and Contributors
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+
17
+ ---
18
+
19
+ The following Lucide icons are derived from the Feather project:
20
+
21
+ airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
22
+
23
+ The MIT License (MIT) (for the icons listed above)
24
+
25
+ Copyright (c) 2013-present Cole Bemis
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ of this software and associated documentation files (the "Software"), to deal
29
+ in the Software without restriction, including without limitation the rights
30
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ copies of the Software, and to permit persons to whom the Software is
32
+ furnished to do so, subject to the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be included in all
35
+ copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ SOFTWARE.
@@ -0,0 +1,93 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg"
2
+ width="1200" height="400" viewBox="0 0 1200 400"
3
+ role="img" aria-labelledby="hero-title hero-desc">
4
+ <title id="hero-title">MineCodex</title>
5
+ <desc id="hero-desc">MineCodex 给 Codex Desktop 增加轻量、本地优先的插件:模型滑条、笔记与图片库。</desc>
6
+
7
+ <defs>
8
+ <style>
9
+ .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
10
+ .sans { font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Segoe UI", "PingFang SC", "Hiragino Sans GB", sans-serif; }
11
+ </style>
12
+ <filter id="card-shadow" x="-8%" y="-8%" width="116%" height="120%">
13
+ <feDropShadow dx="0" dy="6" stdDeviation="12" flood-color="#000000" flood-opacity="0.04"/>
14
+ <feDropShadow dx="0" dy="1" stdDeviation="2" flood-color="#000000" flood-opacity="0.03"/>
15
+ </filter>
16
+ <filter id="terminal-shadow" x="-4%" y="-8%" width="108%" height="124%">
17
+ <feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="#000000" flood-opacity="0.03"/>
18
+ </filter>
19
+ </defs>
20
+
21
+ <!-- Page background: Codex light theme surface -->
22
+ <rect width="1200" height="400" rx="24" fill="#f7f7f7"/>
23
+
24
+ <!-- Left: Title block -->
25
+ <g transform="translate(64 84)">
26
+ <text class="mono" x="0" y="14" font-size="13" font-weight="600" letter-spacing="2.5" fill="#0169cc">CODEX DESKTOP PLUGINS · macOS</text>
27
+ <!-- MineCodex brand start -->
28
+ <g transform="translate(0 23) scale(2.333333)" color="#0d0d0d" fill="none">
29
+ <path id="codex-outline" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.3316 2.03768C11.1644 1.54688 13.0268 2.04668 14.356 3.20174C16.0859 2.86512 17.9511 3.36418 19.2935 4.70663C20.6356 6.04882 21.1326 7.91288 20.7964 9.64217C21.9527 10.9716 22.4534 12.8349 21.9625 14.6685C21.4711 16.5025 20.1051 17.8657 18.439 18.439C17.8658 20.1047 16.503 21.47 14.6695 21.9615C12.8356 22.4528 10.9727 21.9519 9.64312 20.7955C7.91371 21.1319 6.04993 20.635 4.70757 19.2926C3.36558 17.9505 2.86659 16.0866 3.20269 14.357C2.04693 13.0273 1.54757 11.1638 2.03863 9.33065C2.52997 7.49759 3.89436 6.13282 5.56011 5.55917C6.13382 3.8935 7.49837 2.52891 9.3316 2.03768ZM13.2623 4.63534C12.3606 3.80149 11.067 3.4361 9.79742 3.77596C8.52745 4.11626 7.58924 5.0796 7.22515 6.25253C7.08145 6.71575 6.71753 7.07928 6.25445 7.22323C5.08133 7.58702 4.11844 8.52622 3.77789 9.79647C3.43759 11.0667 3.80148 12.3606 4.63531 13.2623C4.96467 13.6184 5.09776 14.1154 4.99078 14.5885C4.71939 15.7864 5.05109 17.0891 5.98101 18.0191C6.91085 18.949 8.21345 19.2801 9.41168 19.0084L9.58941 18.9791C9.94695 18.9432 10.3065 19.0397 10.5982 19.2496L10.7378 19.3639L10.9117 19.5142C11.8015 20.2407 13.0127 20.5413 14.2037 20.2223C15.4733 19.8818 16.4111 18.9191 16.775 17.7457C16.9189 17.2824 17.2832 16.9186 17.7466 16.775L17.9634 16.6998C19.0376 16.2923 19.9051 15.3936 20.2242 14.2027C20.5641 12.9328 20.1989 11.6385 19.3648 10.7369C19.0353 10.3806 18.9021 9.88399 19.0093 9.41073L19.0533 9.18514C19.2372 8.0514 18.8917 6.85176 18.0201 5.98006C17.0901 5.05003 15.7865 4.71826 14.5884 4.98983C14.1153 5.09712 13.6186 4.96467 13.2623 4.63534Z"/>
30
+ <g id="pickaxe" transform="translate(6.24 6.24) scale(.48)" fill="currentColor">
31
+ <path d="M15.686 4.314 16.3 3.7a1 1 0 0 1 1.4 0l2.6 2.6a1 1 0 0 1 0 1.4l-.614.614a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319l-.198.199a1 1 0 0 1-1.4 0l-.219.169L6.619 20.38a1 1 0 1 1-3-3l7.912-7.912.169.232a1 1 0 0 1 0-1.4l.198-.197A22 22 0 0 0 5.58 4.71a1 1 0 0 1-.119-1.752 12.5 12.5 0 0 1 10.225 1.356Z"/>
32
+ </g>
33
+ </g>
34
+ <!-- MineCodex brand end -->
35
+ <text class="sans" x="72" y="68" font-size="56" font-weight="700" letter-spacing="-0.5" fill="#0d0d0d">MineCodex</text>
36
+ <text class="sans" x="0" y="112" font-size="21" font-weight="400" fill="rgba(13,13,13,0.68)">给 Codex Desktop 增加轻量、本地优先的插件</text>
37
+
38
+ <!-- Install command pill -->
39
+ <g transform="translate(0 148)" filter="url(#terminal-shadow)">
40
+ <rect x="0" y="0" width="432" height="52" rx="14" fill="#ffffff" stroke="rgba(13,13,13,0.1)"/>
41
+ <circle cx="24" cy="26" r="4.5" fill="rgba(13,13,13,0.28)"/>
42
+ <text class="mono" x="42" y="32" font-size="17" font-weight="500" fill="#0d0d0d">npm install -g minecodex</text>
43
+ </g>
44
+
45
+ <text class="mono" x="0" y="234" font-size="14" fill="rgba(13,13,13,0.45)">Node 22.5+ · npm 包 · MIT License</text>
46
+ </g>
47
+
48
+ <!-- Right: Three capability cards -->
49
+ <g transform="translate(572 74)" filter="url(#card-shadow)">
50
+ <!-- Card 1: Model Slider -->
51
+ <g transform="translate(0 0)">
52
+ <rect x="0" y="0" width="172" height="252" rx="20" fill="#ffffff" stroke="rgba(13,13,13,0.09)"/>
53
+ <!-- Icon well -->
54
+ <rect x="50" y="28" width="72" height="72" rx="20" fill="#0d0d0d"/>
55
+ <g transform="translate(69.2 47.2) scale(1.4)" fill="none" stroke="#ffffff" stroke-width="1.43" stroke-linecap="round" stroke-linejoin="round">
56
+ <path d="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z"/>
57
+ <path d="M20 2v4"/>
58
+ <path d="M22 4h-4"/>
59
+ <circle cx="4" cy="20" r="2"/>
60
+ </g>
61
+ <text class="sans" x="86" y="146" font-size="19" font-weight="600" text-anchor="middle" fill="#0d0d0d">Model Slider</text>
62
+ <text class="sans" x="86" y="176" font-size="14" text-anchor="middle" fill="rgba(13,13,13,0.68)">更清晰顺滑的模型选择</text>
63
+ <text class="mono" x="86" y="212" font-size="12" letter-spacing="1.5" text-anchor="middle" fill="rgba(13,13,13,0.45)">MODEL PICKER</text>
64
+ </g>
65
+
66
+ <!-- Card 2: Notes -->
67
+ <g transform="translate(196 0)">
68
+ <rect x="0" y="0" width="172" height="252" rx="20" fill="#ffffff" stroke="rgba(13,13,13,0.09)"/>
69
+ <rect x="50" y="28" width="72" height="72" rx="20" fill="#0d0d0d"/>
70
+ <g transform="translate(68 46) scale(1.5)" fill="none" stroke="#ffffff" stroke-width="1.333" stroke-linecap="round" stroke-linejoin="round">
71
+ <path d="M21 9a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 15 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z"/>
72
+ <path d="M15 3v5a1 1 0 0 0 1 1h5"/>
73
+ </g>
74
+ <text class="sans" x="86" y="146" font-size="19" font-weight="600" text-anchor="middle" fill="#0d0d0d">Notes</text>
75
+ <text class="sans" x="86" y="176" font-size="14" text-anchor="middle" fill="rgba(13,13,13,0.68)">跨会话管理待办与提示词</text>
76
+ <text class="mono" x="86" y="212" font-size="12" letter-spacing="1.5" text-anchor="middle" fill="rgba(13,13,13,0.45)">TOOLBAR</text>
77
+ </g>
78
+
79
+ <!-- Card 3: Images -->
80
+ <g transform="translate(392 0)">
81
+ <rect x="0" y="0" width="172" height="252" rx="20" fill="#ffffff" stroke="rgba(13,13,13,0.09)"/>
82
+ <rect x="50" y="28" width="72" height="72" rx="20" fill="#0d0d0d"/>
83
+ <g transform="translate(68 46) scale(1.5)" fill="none" stroke="#ffffff" stroke-width="1.333" stroke-linecap="round" stroke-linejoin="round">
84
+ <rect x="3" y="3" width="18" height="18" rx="2"/>
85
+ <circle cx="9" cy="9" r="2"/>
86
+ <path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>
87
+ </g>
88
+ <text class="sans" x="86" y="146" font-size="19" font-weight="600" text-anchor="middle" fill="#0d0d0d">Images</text>
89
+ <text class="sans" x="86" y="176" font-size="14" text-anchor="middle" fill="rgba(13,13,13,0.68)">集中浏览生成图片与来源</text>
90
+ <text class="mono" x="86" y="212" font-size="12" letter-spacing="1.5" text-anchor="middle" fill="rgba(13,13,13,0.45)">LIBRARY</text>
91
+ </g>
92
+ </g>
93
+ </svg>