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.
- package/DESIGN.md +40 -1
- package/README.md +9 -3
- package/apps/dashboard/DESIGN.md +53 -31
- package/apps/dashboard/app.js +55 -39
- package/apps/dashboard/assets/OFL.txt +93 -0
- package/apps/dashboard/assets/info.svg +15 -0
- package/apps/dashboard/assets/moon.svg +13 -0
- package/apps/dashboard/assets/refresh-cw.svg +16 -0
- package/apps/dashboard/assets/silkscreen.ttf +0 -0
- package/apps/dashboard/assets/sun.svg +21 -0
- package/apps/dashboard/assets/terrain.js +89 -0
- package/apps/dashboard/assets/triangle-alert.svg +15 -0
- package/apps/dashboard/favicon.svg +12 -17
- package/apps/dashboard/index.html +24 -18
- package/apps/dashboard/styles.css +147 -181
- package/assets/brand/README.md +19 -0
- package/assets/brand/minecodex-icon-dark.svg +9 -0
- package/assets/brand/minecodex-icon-light.svg +9 -0
- package/assets/brand/minecodex-icon.svg +8 -0
- package/assets/brand/references/lucide-LICENSE.txt +43 -0
- package/assets/readme/hero.svg +93 -0
- package/features/hide-upsell-banner/README.md +7 -5
- package/features/hide-upsell-banner/codex-feature.json +2 -2
- package/features/hide-upsell-banner/src/hide-upsell-banner.mjs +30 -12
- package/features/images/DESIGN.md +117 -41
- package/features/images/README.md +26 -16
- package/features/images/codex-feature.json +6 -3
- package/features/images/src/adapters/codex/image-prompt.mjs +24 -2
- package/features/images/src/adapters/codex/image-sources.mjs +19 -0
- package/features/images/src/adapters/codex/library-api.mjs +2 -0
- package/features/images/src/adapters/codex/library-viewer.mjs +26 -2
- package/features/images/src/adapters/codex/native-image-modules.mjs +211 -0
- package/features/images/src/adapters/codex/native-image-source.mjs +449 -0
- package/features/images/src/backend/local-image-source.mjs +138 -0
- package/features/images/src/frontend/cloud-image-actions.mjs +41 -0
- package/features/images/src/frontend/local-image-source.mjs +195 -0
- package/features/images/src/library-prompt-page.mjs +163 -53
- package/features/images/src/library-prompt-source.mjs +9 -3
- package/features/images/src/prompt-index.mjs +14 -2
- package/features/model-slider/DESIGN.md +2 -0
- package/features/model-slider/codex-feature.json +2 -2
- package/features/model-slider/src/frontend/install.mjs +78 -11
- package/features/notes/DESIGN.md +7 -3
- package/features/notes/codex-feature.json +2 -2
- package/features/notes/src/frontend/entry.mjs +26 -9
- package/features/session-status/DESIGN.md +4 -2
- package/features/session-status/codex-feature.json +2 -2
- package/features/session-status/src/adapters/codex/session-log.mjs +2 -1
- package/features/session-status/src/domain/session-stats.mjs +17 -9
- package/features/session-status/src/session-status.mjs +47 -11
- package/features/sidebar-focus/DESIGN.md +4 -4
- package/features/sidebar-focus/codex-feature.json +3 -2
- package/features/sidebar-focus/src/adapters/codex/renderer.mjs +1 -1
- package/features/sidebar-focus/src/sidebar-focus.mjs +9 -7
- package/features/sites/DESIGN.md +25 -3
- package/features/sites/README.md +6 -2
- package/features/sites/codex-feature.json +3 -2
- package/features/sites/src/adapters/codex/renderer.mjs +25 -4
- package/features/sites/src/backend/project-sites.mjs +18 -6
- package/features/sites/src/backend/sites-service.mjs +22 -10
- package/features/sites/src/domain/discovery-candidates.mjs +53 -0
- package/features/sites/src/frontend/entry.mjs +76 -38
- package/features/sites/src/frontend/styles.css +3 -3
- package/features/unread-inbox/DESIGN.md +24 -25
- package/features/unread-inbox/codex-feature.json +3 -2
- package/features/unread-inbox/src/adapters/codex/modules.mjs +52 -0
- package/features/unread-inbox/src/adapters/codex/renderer.mjs +90 -0
- package/features/unread-inbox/src/domain/notifications.mjs +21 -0
- package/features/unread-inbox/src/injection-source.mjs +5 -2
- package/features/unread-inbox/src/unread-inbox.mjs +212 -297
- package/features/usage-meter/codex-feature.json +2 -2
- package/package.json +11 -3
- package/packages/cli/native/MineCodex.app/Contents/Info.plist +4 -2
- package/packages/cli/native/MineCodex.app/Contents/MacOS/MineCodexServiceManager +0 -0
- package/packages/cli/native/MineCodex.app/Contents/Resources/MineCodex.icns +0 -0
- package/packages/cli/native/MineCodex.app/Contents/_CodeSignature/CodeResources +11 -0
- package/packages/cli/native/README.md +31 -0
- package/packages/cli/src/browser-control-panel.mjs +48 -0
- package/packages/cli/src/commands.mjs +3 -1
- package/packages/cli/src/control-server.mjs +6 -3
- package/packages/cli/src/platform.mjs +5 -0
- package/packages/codex-adapter/README.md +2 -1
- package/packages/codex-adapter/src/renderer/environment.mjs +24 -6
- package/packages/runtime-host/README.md +10 -5
- package/packages/runtime-host/src/codex-injection.mjs +13 -9
- package/packages/runtime-host/src/codex-runtime.mjs +26 -5
- package/packages/runtime-host/src/feature-registry.mjs +1 -0
- package/packages/ui/DESIGN.md +9 -2
- package/packages/ui/assets/arrow-up-right.svg +14 -0
- package/packages/ui/assets/lucide-LICENSE.txt +43 -0
- package/packages/ui/src/components/account-menu.mjs +74 -0
- package/packages/ui/src/components/button.mjs +2 -0
- package/packages/ui/src/components/navigation-rail.mjs +18 -10
- package/packages/ui/src/components/page.mjs +9 -2
- package/packages/ui/src/foundation/layers.mjs +1 -0
- package/packages/ui/src/install.mjs +6 -1
- package/packages/ui/src/native/account-menu.mjs +21 -0
- package/packages/ui/src/native/navigation-rail.mjs +6 -1
- package/packages/ui/src/native/page.mjs +38 -0
- package/packages/ui/src/native/tokens.mjs +4 -0
package/DESIGN.md
CHANGED
|
@@ -44,7 +44,8 @@ Token 名称是实现依据;括号内数值是本版本观测值。读取实
|
|
|
44
44
|
| Cancel 等取消操作(`ghost`) | 透明、无描边;hover 才出现底色 | `--color-text-secondary`、`--color-background-primary-ghost-hover` |
|
|
45
45
|
| 有实际功能的次级操作(outline,现有API tone为`secondary`) | 透明底、内描边 | `--color-text-primary`、`--color-border-primary-outline`、`--color-background-primary-outline-hover` |
|
|
46
46
|
| 主操作(solid,现有API tone为`primary`) | 实色底与配对文字色 | `--color-background-primary-solid`、`--color-text-primary-solid`、`--color-background-primary-solid-hover` |
|
|
47
|
-
|
|
|
47
|
+
| 轻量警戒操作(现有`danger`) | 警戒色,独立于主操作;插件负责确认业务 | `--color-background-danger-soft-alpha`、`--color-background-danger-soft-alpha-hover`、`--color-text-danger` |
|
|
48
|
+
| 实色警戒操作(`danger-solid`;原生 React 为 `dangerSolid`) | 用于明确的删除/移除动作,实色警戒底与配对文字;操作范围和二次确认由业务决定 | `--color-background-danger-solid`、`--color-text-danger-solid`;Library 动作条 hover 为 solid 90% alpha |
|
|
48
49
|
|
|
49
50
|
尺寸:`--control-size-lg`(36px)、`--control-font-size-md`(13px)、`--font-weight-normal`(原生按钮400)、`--radius-full`。水平 gutter 为 `--control-gutter-md × --control-gutter-pill-scaling`(15.96px),图文 gap 为 `--button-gap-lg`。焦点使用 `--color-ring`;禁用保留语义并阻止 hover 反馈。
|
|
50
51
|
|
|
@@ -65,6 +66,12 @@ Dropdown 的 `--shadow-dropdown-overlay` 当前指向 `--shadow-xl-spread`,该
|
|
|
65
66
|
|
|
66
67
|
Composer菜单的锚点是实际输入框主体(当前语义标记 `data-composer-body`),不是包含diff和请求队列的外层Root。挂载位置、可用高度、zoom与碰撞行为沿用对应原生组件,不为修复坐标问题盲目提高z-index。
|
|
67
68
|
|
|
69
|
+
## Viewer 附属信息面板
|
|
70
|
+
|
|
71
|
+
Codex 26.930.21537(2026-10-02 原生 File info DOM 与计算样式实测):viewer 右侧附属信息面板使用不透明 `bg-surface-elevated-secondary`、`rounded-2xl`(20px)和 Electron `elevation-prominent`;没有容器模糊,也不额外叠加 CSS border 或 `shadow-lg`。该 elevation 自带 0.5px 边缘及两层柔和投影,应直接沿用原生 utility。此分支不同于 Dialog、Dropdown 和页面内容面。
|
|
72
|
+
|
|
73
|
+
标题栏使用固定高度、原生 text-base/semibold 标题及圆形 `button-toolbar` 的 `bg-text/5` 按钮分支,hover 为 `bg-text/10`。面板宽度、viewer 工具栏避让及正文间距由所选原生信息面板的业务布局确定,在功能 DESIGN.md 记录。Images Prompt 采用当前 File info 分支。
|
|
74
|
+
|
|
68
75
|
## Page 与 sidebar
|
|
69
76
|
|
|
70
77
|
页面内容面使用 `--color-surface`,当前不透明、无模糊,`--radius-xl-base`(12px);外部PageSurface使用 `--app-shell-page-surface-shadow`,当前由 `--elevation-stroke-subtle` 与 `--shadow-card` 组成。区分内容面和窗口外壳,不重复施加阴影。
|
|
@@ -76,6 +83,18 @@ sidebar规则分状态:
|
|
|
76
83
|
| 非peeking sidebar-navigation | `--color-surface` 65%(oklab混合),无CSS模糊、无浮窗阴影;可见桌面程度还取决于窗口材质 |
|
|
77
84
|
| `data-slate-sidebar-peeking=true` | `--app-shell-sidebar-popover-background`强制alpha=1;`--app-shell-sidebar-popover-radius`当前为radius-xl-base减spacing(8px);`--hairline`、`--app-shell-sidebar-popover-border`内边缘与`--shadow-card` |
|
|
78
85
|
|
|
86
|
+
### 全页面功能的页面壳选择
|
|
87
|
+
|
|
88
|
+
后续功能开发独立全页面时,先按页面自身的导航需求选择页面壳。没有专属二级导航的页面默认使用无二级侧栏的 Page 分支,以原生 Projects 为行为参照;只有任务确实需要常驻二级导航时才选择带侧栏的布局。不能因入口来自 Home、Space、Scheduled 就继承它们的常驻二级侧栏。
|
|
89
|
+
|
|
90
|
+
页面是否带常驻二级侧栏,与用户的侧栏展开/收起偏好是两个独立语义。无二级侧栏页面只保留 Navbar,内容从 Navbar 右侧开始,不调用侧栏收起动作,也不修改用户的展开偏好。悬浮 Home、Space、Scheduled 等入口时,原生二级侧栏仍叠加在页面上,页面内容不移位;鼠标可进入操作,离开后沿用原生退出行为。
|
|
91
|
+
|
|
92
|
+
页面壳、原生导航适配与恢复由共享 UI 维护,功能只声明所需分支并负责自己的内容。新功能不得复制侧栏状态机、直接切换原生侧栏按钮,或另写隐藏侧栏的 CSS。退出页面时区分返回原页面与用户主动选择原生导航;卸载/禁用时释放页面壳并恢复所属状态。
|
|
93
|
+
|
|
94
|
+
验收至少覆盖:从 Home、Space、Scheduled 进入时无常驻二级侧栏;原有展开偏好不变;三个入口的悬浮侧栏覆盖页面且可操作,内容不移位;退出、原生导航与卸载恢复正确。
|
|
95
|
+
|
|
96
|
+
原生依据与当前实现:Codex 26.930.21537 的源码与隔离窗口确认该布局由路由决定。当前注入 Page 借用 `/projects` 作为原生页面壳,关闭时恢复原位置,用户主动选择原生导航时交还路由;这是版本相关的适配实现,不是功能的业务路由规范。后续原生接口变化只更新共享 Adapter,不改变上述页面语义。
|
|
97
|
+
|
|
79
98
|
保留原生的固定展开、收起与hover状态。hover sidebar应能覆盖注入页面,鼠标能进入操作,移回页面后可正常收起;不要通过页面层级、pointer-events或额外遮罩挡住它。原生overflow和contain切换负责浮出与裁切,插件不复制一套侧栏状态机。
|
|
80
99
|
|
|
81
100
|
## 左侧 Navbar
|
|
@@ -97,6 +116,7 @@ sidebar规则分状态:
|
|
|
97
116
|
层级数字是本版本实现值,不是原生CSS设计token;共同约束应集中维护语义角色与挂载点。
|
|
98
117
|
|
|
99
118
|
- 内容页面位于原生sidebar悬浮层下方;MineCodex当前Page使用20,原生左侧栏40。
|
|
119
|
+
- 通知使用共享 `notification` 挂载角色(当前30),位于内容页面之上、原生sidebar与模态浮层之下;通知业务负责在原生侧栏 peeking 时暂停呈现,不抢占原生导航。
|
|
100
120
|
- 原生Dialog、Dropdown、Popover和Composer Floating父容器通常为50;同数值不保证相同层级,仍受挂载顺序与stacking context影响。
|
|
101
121
|
- 模态层挂在窗口根容器/原生Portal,遮罩覆盖整个窗口;不要嵌在Page的低层级容器内。原生`dialog.showModal()`使用top layer,不能仅用z-index推断。
|
|
102
122
|
- Tooltip使用专用角色与层级;现有MineCodex实现值不是原生标准,不传播为通用token。
|
|
@@ -147,3 +167,22 @@ Navbar 在入口右侧居中,使用 `data-minecodex-tooltip-side="right"`;
|
|
|
147
167
|
这里的规范名称是稳定的项目映射键。Codex 更新名称时补充原生别名,不能跟着重命名插件消费的项目 token。新增实际使用的语义才增加映射;不预建完整的第三方 token 系统。`native/theme.mjs` 为直接注入容器写入同一快照,Runtime Host 将它传给 iframe;卸载恢复原值。主题变化丢失某个 token 时清除旧项目值,继续使用该组件既有的明确默认值或不可用状态,不复用上一主题颜色。
|
|
148
168
|
|
|
149
169
|
这些映射不改变原生组件分类、材质分支和 hover sidebar 层级,也不重写原生 Tailwind utility class。插件复用 native Adapter 返回的原生模板;特殊样式使用项目 token,Dialog、Button、Tooltip 等通用表现继续由组件库维护。
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
### Library 多选动作条的实色警戒按钮
|
|
173
|
+
|
|
174
|
+
Codex 26.930.21537(2026-10-02 原生源码与隔离窗口):Library 选中动作条的 Delete 使用 `dangerSolid`、full radius、toolbar size,图标 16px,警戒底与白色配对文字;hover 使用 danger solid 90% alpha,禁用保留原生 40% opacity 与禁止交互。确认弹窗也使用实色警戒提交按钮。共享 DOM 入口为 `ui.action(button, "danger-solid")`,和既有 soft `danger` 分支并存,不迁移原有功能的语义。通用组件只提供视觉和交互状态,删除确认、隐藏/回收站/永久删除的范围由所属功能明确告知。
|
|
175
|
+
|
|
176
|
+
## MineCodex 项目品牌图标
|
|
177
|
+
|
|
178
|
+
项目标识采用实心镐子与 Codex 原生六瓣外圈,唯一可编辑源为 `assets/brand/minecodex-icon.svg`。内部镐子使用 `translate(6.24 6.24) scale(.48)`,纯填充、无描边;保留已确认的留白比例。此标识代表 MineCodex,不替换插件功能图标、模型厂商图标或 Codex 原生应用图标。
|
|
179
|
+
|
|
180
|
+
内联使用 `currentColor` 跟随所在表面的语义文字色;外链明暗版本分别使用 `#0d0d0d` / `#fafafa`,透明背景。favicon 在 SVG 内通过 `prefers-color-scheme` 适配系统主题,Dashboard 标题通过 CSS mask 跟随页面 `--ink`。明暗版本、favicon 和 README 标识由 `npm run build:icons` 从同一源文件生成,修改几何后运行该命令。
|
|
181
|
+
|
|
182
|
+
macOS 后台服务 App 在明确的原生资源修订 1.0.1 中接入实心图标,采用浅色圆角底板,保证在明暗系统表面均可辨认。ICNS 来自同一项目几何。安装器先注销旧后台项,再验证并替换 bundle,最后重新注册;不能直接修改已安装的签名资源。后续普通 JavaScript 发布保留此原生 bundle 的签名身份,升级流程与验收边界见 `packages/cli/native/README.md`。
|
|
183
|
+
|
|
184
|
+
### 账号菜单中的 MineCodex 入口
|
|
185
|
+
|
|
186
|
+
Codex 26.930.21537(2026-10-03 安装包源码):`profile-dropdown-items` 的 Settings 使用原生菜单行,紧接 Help 前的 Separator;`onOpenSettings` / `settingsShortcut` 标识其行为,外层 `onClose` 关闭账号面板。MineCodex 行插在 Settings 与 Separator 之间,复制脱离 React 的原生行,保留原始 Settings 及其所属层级。左侧使用实心项目标识,右侧使用 Lucide ArrowUpRight,复用 Settings 快捷键区域的 class、间距与 `text-codex-description` 颜色。
|
|
187
|
+
|
|
188
|
+
入口随账号菜单重建恢复且只出现一次;补齐 Settings → MineCodex → Help 的上下键导航与 Enter/Space,保留原生 Escape 关闭行为。点击经已认证 Host bridge 调用 `mcx gui`;成功后关闭菜单,失败时显示实际错误。原生 UI 手动验收本次因 Computer Use 拒绝操作应用而未完成;隔离 DOM 契约页验证了位置、明暗颜色、点击、键盘、重建去重与清理。
|
package/README.md
CHANGED
|
@@ -13,10 +13,10 @@ MineCodex 给 Codex Desktop 增加一组轻量、本地优先的扩展功能。
|
|
|
13
13
|
| **Model Slider** | 更清晰、更顺滑的模型切换面板:具备品牌标识、常用收藏与流畅交互 |
|
|
14
14
|
| **Prompts** | 专页分类管理提示词与调用统计,输入框 Quick Prompts 快速调用 |
|
|
15
15
|
| **Usage Meter** | 在 Help 与 Account 之间显示剩余额度环,悬浮查看周 / 五小时额度,点击进入 Usage 设置 |
|
|
16
|
-
| **Images** | 在原生
|
|
16
|
+
| **Images** | 在原生 Images 中浏览本地 Image Gen 图片,查看并复制提示词 |
|
|
17
17
|
| **Hide Upsell Banner** | 隐藏输入框上方的用量提示横幅,仅优化界面展示,不影响正常的用量统计 |
|
|
18
18
|
| **Session Status** | 在输入框下方查看当前任务的步骤、观测速度、Token 用量与上下文明细 |
|
|
19
|
-
| **Task Switcher** |
|
|
19
|
+
| **Task Switcher** | 会话侧栏不可见时显示通知条,点击跳转到已完成未读或需要处理的会话 |
|
|
20
20
|
|
|
21
21
|
## 安装
|
|
22
22
|
|
|
@@ -56,7 +56,7 @@ mcx open
|
|
|
56
56
|
|
|
57
57
|
## 工作原理
|
|
58
58
|
|
|
59
|
-
MineCodex 统一管理 Codex 内的菜单入口、主题风格与界面适配。Model Slider、Prompts 各自管理操作界面,Images
|
|
59
|
+
MineCodex 统一管理 Codex 内的菜单入口、主题风格与界面适配。Model Slider、Prompts 各自管理操作界面,Images 在原生 Images 中接入本地生成图片和提示词查看;Session Status 只读汇总本机 Codex 会话事件,Hide Upsell Banner 优化界面展示。所有功能按需开启,关闭后即停止运行。
|
|
60
60
|
|
|
61
61
|
## 开发
|
|
62
62
|
|
|
@@ -68,6 +68,8 @@ npm run pack:check
|
|
|
68
68
|
npm run pack:audit
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
维护者发布流程见 [GitHub Actions 发布说明](docs/npm-publishing.md)。发布工作流仅允许维护者本人触发,使用 npm 可信发布,无需长期访问令牌。
|
|
72
|
+
|
|
71
73
|
## 许可
|
|
72
74
|
|
|
73
75
|
MineCodex 是非官方独立扩展项目,与 OpenAI 无关联。项目自有代码以 MIT License 授权;第三方图标、品牌和兼容资产遵循各自的权利说明,见 [`features/model-slider/THIRD_PARTY_NOTICES.md`](features/model-slider/THIRD_PARTY_NOTICES.md) 与 [`features/session-status/vendor/lucide-LICENSE`](features/session-status/vendor/lucide-LICENSE)。
|
|
@@ -75,3 +77,7 @@ MineCodex 是非官方独立扩展项目,与 OpenAI 无关联。项目自有
|
|
|
75
77
|
### Sidebar Focus / 侧栏聚焦
|
|
76
78
|
|
|
77
79
|
展开侧栏时,点击铃铛与搜索之间的聚焦按钮,保留当前任务路径并收起其他分支。再次点击恢复原先布局;切换任务时跟随路径,手动调整分支时退出聚焦。
|
|
80
|
+
|
|
81
|
+
### 从账号菜单打开控制台
|
|
82
|
+
|
|
83
|
+
在 Codex Navbar 底部打开账号菜单,点击 Settings 下方的 **MineCodex ↗**,即可在外部默认浏览器打开本地控制台,等同于 `mcx gui`。macOS 默认 Safari、Chrome/Chromium、Edge、Brave 和 Vivaldi 会定位已有控制台标签页,没有时才新建;首次定位可能需要系统自动化权限。其他浏览器与 Windows 仍由系统打开 URL。
|
package/apps/dashboard/DESIGN.md
CHANGED
|
@@ -1,45 +1,67 @@
|
|
|
1
1
|
# MineCodex Dashboard Design System
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The standalone control panel follows the root DESIGN.md semantic color and interaction
|
|
4
|
+
contract. It uses local light/dark tokens because no Codex renderer theme bridge exists here.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
appearance, uses one system sans family, and reserves accent color for enabled switches, focus,
|
|
7
|
-
and the primary restart action.
|
|
6
|
+
## Layout and reference
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
Reference: VPN Dashboard settings source, inspected 2026-10-03. Its card grid uses a 16px
|
|
9
|
+
radius/gap, top icon and trailing arrow, followed by a title and description. The live URL
|
|
10
|
+
required login; this reference is source-based, not a live visual match.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
MineCodex uses one centered 1064px column without a sidebar or category groups. The header
|
|
13
|
+
holds the shared brand and appearance control; a runtime notice appears below only when the service needs attention.
|
|
14
|
+
There is no tagline or visible section introduction. Save feedback remains available to screen readers.
|
|
15
|
+
Nine independent cards form a three-column grid, two columns at 960px and one at 600px.
|
|
16
|
+
Each card has an icon and switch at the top, name and purpose below, and a readable actual-state line
|
|
17
|
+
at the bottom of every card. Enabled switches and runtime state remain distinct information. A card is not itself clickable. The footer shows only the MineCodex version
|
|
18
|
+
and adjacent update check (16px gap, regular weight, refresh icon), with persistent update feedback below it. No install path or plugin versions.
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
- Surface: one subtle elevation step from the canvas.
|
|
15
|
-
- Ink: high-contrast neutral foreground.
|
|
16
|
-
- Secondary and tertiary ink: still meet AA for their text size.
|
|
17
|
-
- Border: quiet neutral separator.
|
|
18
|
-
- Accent: Codex-like blue used only for action and active state.
|
|
19
|
-
- Success and warning: paired with labels or icons, never color alone.
|
|
20
|
+
## Tokens and components
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
- Canvas: cool #edf1f7 / deep blue #101722, with a decorative ASCII voxel world.
|
|
23
|
+
- Surface: white / #1b2533, with a hard 3px lower edge for a block-like silhouette; no blur.
|
|
24
|
+
- Border: #d7dfe9 / #334359; blue #3478d4 / #71a8f3 switches and active state accents.
|
|
25
|
+
- Ink, secondary ink, accent, success, warning and danger use the local semantic CSS tokens.
|
|
26
|
+
- `--card-radius`: 8px; `--grid-gap`: 16px; `--card-padding`: 24px.
|
|
27
|
+
- Card minimum height: 216px desktop, 204px mobile; content can grow without clipping.
|
|
28
|
+
- System sans family; pixel brand title 36–64px/700, feature name 16px/600, description 14px/1.65,
|
|
29
|
+
state metadata 13px/1.5. Each description is one short statement of purpose; remove promotional filler while preserving each feature’s actual state.
|
|
30
|
+
- Feature icons: 24px display size, uniform 2.1-unit stroke in a 24×24 viewBox, matching Prompts. The control-server normalizes only dashboard output; original injected assets stay unchanged.
|
|
31
|
+
- Icons: existing manifest assets, with official Lucide bell, panel-left and globe for
|
|
32
|
+
Task Switcher, Sidebar Focus and Sites. Lucide ISC license is retained in
|
|
33
|
+
`packages/ui/assets/lucide-LICENSE.txt`.
|
|
34
|
+
- Checkbox switches expose switch semantics, feature labels, descriptions and state text.
|
|
35
|
+
Track is 36×21px with a 32px-high label hit area. Pending requests disable only their switch;
|
|
36
|
+
failures restore the previous value and focus. Enabled and active remain distinct facts.
|
|
37
|
+
- Appearance uses the VPN reference’s two-segment sun/moon capsule (32px segments, 4px gap and padding). A sliding selected circle and aria-pressed expose selection. It initially follows the system; manual choices persist locally.
|
|
38
|
+
- Restart and error notices use a neutral card, colored left edge, status icon, compact copy and trailing action; toast errors share that material. Restart notice appears only for a pending restart. No automatic restart.
|
|
39
|
+
- Update checks retain loading, result and retryable failure states; installation stays with
|
|
40
|
+
the existing `mcx update` flow.
|
|
22
41
|
|
|
23
|
-
|
|
24
|
-
plugin names 15px/600, body text 13px/1.5, and compact metadata 12px. No display type,
|
|
25
|
-
uppercase tracking, or fluid heading sizes.
|
|
42
|
+
## Motion
|
|
26
43
|
|
|
27
|
-
|
|
44
|
+
`--ease-out: cubic-bezier(0.23, 1, 0.32, 1)`. Switch thumb: 180ms transform;
|
|
45
|
+
button press: 140ms transform to scale(0.97). No stagger, card lift, layout motion or continuous
|
|
46
|
+
loading shimmer. Hover is limited to fine pointers. Keyboard actions disable transitions;
|
|
47
|
+
reduced-motion preferences disable movement. Focus rings remain visible in both themes.
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
needed, a vertical plugin settings group, and a low-emphasis diagnostics footer. At narrow widths
|
|
31
|
-
the rows wrap their status and switch controls beneath the copy without horizontal scrolling.
|
|
49
|
+
## Project identity
|
|
32
50
|
|
|
33
|
-
|
|
51
|
+
The masthead uses self-hosted Silkscreen Bold (SIL OFL, bundled license in assets/OFL.txt),
|
|
52
|
+
with a stone-colored face, dark outline and stepped text shadow inspired by Minecraft lettering.
|
|
53
|
+
The shared pickaxe mark is 76px desktop / 48px mobile. Body and state text retain the legible
|
|
54
|
+
project sans-serif contract. This is a dashboard-specific visual treatment; the brand geometry
|
|
55
|
+
and other injected plugin UI remain governed by root DESIGN.md.
|
|
34
56
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- Restart notice: inline surface between header and plugin group, not a modal.
|
|
38
|
-
- Buttons: one primary restart button and quiet secondary actions with full hover, focus,
|
|
39
|
-
active, disabled, and loading states.
|
|
40
|
-
- Loading: skeleton rows preserve layout; errors use an inline retry surface.
|
|
57
|
+
Dashboard icons are official Lucide SVGs, covered by packages/ui/assets/lucide-LICENSE.txt.
|
|
58
|
+
All font and icon assets are served locally and included in the npm package.
|
|
41
59
|
|
|
42
|
-
##
|
|
60
|
+
## ASCII agent world
|
|
43
61
|
|
|
44
|
-
|
|
45
|
-
|
|
62
|
+
A fixed, pointer-transparent and aria-hidden canvas renders deterministic terraced terrain,
|
|
63
|
+
ASCII water, paths and coding nodes (>_, {}, git, </>, [AI], $). It rotates around its vertical
|
|
64
|
+
axis once every 240 seconds, rendered at at most 20 fps and device pixel ratio capped at 2.
|
|
65
|
+
The world stays behind opaque cards; text and controls never rotate. Reduced motion freezes
|
|
66
|
+
the view, hidden tabs pause the animation. The terrain module has no external dependency
|
|
67
|
+
or network request and does not consume user or session data.
|
package/apps/dashboard/app.js
CHANGED
|
@@ -3,13 +3,11 @@ document.documentElement.lang = locale;
|
|
|
3
3
|
|
|
4
4
|
const copy = {
|
|
5
5
|
en: {
|
|
6
|
-
subtitle: "Personal plugins for Codex",
|
|
7
6
|
connecting: "Connecting…",
|
|
8
7
|
runtimeActive: "Active in Codex",
|
|
9
8
|
runtimeStopped: "Runtime unavailable",
|
|
10
9
|
runtimeNotInjected: "Runtime running — restart Codex to apply plugins",
|
|
11
|
-
plugins: "
|
|
12
|
-
pluginsCopy: "Choose which enhancements appear in Codex.",
|
|
10
|
+
plugins: "Your extensions",
|
|
13
11
|
restartTitle: "Restart Codex to apply changes",
|
|
14
12
|
restartCopy: "Your plugin choices are saved. Restart when you are ready.",
|
|
15
13
|
restart: "Restart Codex",
|
|
@@ -30,10 +28,9 @@ const copy = {
|
|
|
30
28
|
loadErrorCopy: "Check that the background service is running.",
|
|
31
29
|
retry: "Try again",
|
|
32
30
|
version: "Version",
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
stopped: "Stopped",
|
|
31
|
+
darkAppearance: "Dark appearance",
|
|
32
|
+
lightAppearance: "Light appearance",
|
|
33
|
+
updateFailed: "Couldn’t check for updates. Please try again.",
|
|
37
34
|
checkUpdates: "Check for updates",
|
|
38
35
|
checkingUpdates: "Checking…",
|
|
39
36
|
current: "You’re up to date.",
|
|
@@ -43,13 +40,11 @@ const copy = {
|
|
|
43
40
|
failureDetail: "Health or renderer status could not be confirmed.",
|
|
44
41
|
},
|
|
45
42
|
"zh-CN": {
|
|
46
|
-
subtitle: "为 Codex 准备的个人插件",
|
|
47
43
|
connecting: "正在连接…",
|
|
48
44
|
runtimeActive: "已在 Codex 中生效",
|
|
49
45
|
runtimeStopped: "运行服务不可用",
|
|
50
46
|
runtimeNotInjected: "运行服务已启动——重启 Codex 以应用插件",
|
|
51
|
-
plugins: "
|
|
52
|
-
pluginsCopy: "选择要在 Codex 中启用的增强功能。",
|
|
47
|
+
plugins: "功能扩展",
|
|
53
48
|
restartTitle: "重启 Codex 以应用更改",
|
|
54
49
|
restartCopy: "插件选择已经保存,可以在准备好后统一重启。",
|
|
55
50
|
restart: "重启 Codex",
|
|
@@ -70,10 +65,9 @@ const copy = {
|
|
|
70
65
|
loadErrorCopy: "请检查后台服务是否正在运行。",
|
|
71
66
|
retry: "重试",
|
|
72
67
|
version: "版本",
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
stopped: "已停止",
|
|
68
|
+
darkAppearance: "深色外观",
|
|
69
|
+
lightAppearance: "浅色外观",
|
|
70
|
+
updateFailed: "暂时无法检查更新,请稍后重试。",
|
|
77
71
|
checkUpdates: "检查更新",
|
|
78
72
|
checkingUpdates: "正在检查…",
|
|
79
73
|
current: "当前已是最新版本。",
|
|
@@ -85,7 +79,6 @@ const copy = {
|
|
|
85
79
|
}[locale];
|
|
86
80
|
|
|
87
81
|
const elements = {
|
|
88
|
-
subtitle: document.querySelector("#subtitle"),
|
|
89
82
|
runtimeDot: document.querySelector("#runtime-dot"),
|
|
90
83
|
runtimeLabel: document.querySelector("#runtime-label"),
|
|
91
84
|
restartNotice: document.querySelector("#restart-notice"),
|
|
@@ -93,7 +86,6 @@ const elements = {
|
|
|
93
86
|
restartCopy: document.querySelector("#restart-copy"),
|
|
94
87
|
restartButton: document.querySelector("#restart-button"),
|
|
95
88
|
pluginsHeading: document.querySelector("#plugins-heading"),
|
|
96
|
-
pluginsCopy: document.querySelector("#plugins-copy"),
|
|
97
89
|
saveState: document.querySelector("#save-state"),
|
|
98
90
|
pluginList: document.querySelector("#plugin-list"),
|
|
99
91
|
loadError: document.querySelector("#load-error"),
|
|
@@ -102,9 +94,9 @@ const elements = {
|
|
|
102
94
|
retryButton: document.querySelector("#retry-button"),
|
|
103
95
|
versionLabel: document.querySelector("#version-label"),
|
|
104
96
|
versionValue: document.querySelector("#version-value"),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
97
|
+
themeToggle: document.querySelector(".theme-toggle"),
|
|
98
|
+
themeButtons: [...document.querySelectorAll("[data-theme-choice]")],
|
|
99
|
+
updateResult: document.querySelector("#update-result"),
|
|
108
100
|
updateButton: document.querySelector("#update-button"),
|
|
109
101
|
toast: document.querySelector("#toast"),
|
|
110
102
|
};
|
|
@@ -114,20 +106,16 @@ let toastTimer = null;
|
|
|
114
106
|
const pendingFeatureIds = new Set();
|
|
115
107
|
|
|
116
108
|
function applyStaticCopy() {
|
|
117
|
-
elements.subtitle.textContent = copy.subtitle;
|
|
118
109
|
elements.runtimeLabel.textContent = copy.connecting;
|
|
119
110
|
elements.restartTitle.textContent = copy.restartTitle;
|
|
120
111
|
elements.restartCopy.textContent = copy.restartCopy;
|
|
121
112
|
elements.restartButton.querySelector(".button-label").textContent = copy.restart;
|
|
122
113
|
elements.pluginsHeading.textContent = copy.plugins;
|
|
123
|
-
elements.pluginsCopy.textContent = copy.pluginsCopy;
|
|
124
114
|
elements.errorTitle.textContent = copy.loadError;
|
|
125
115
|
elements.errorCopy.textContent = copy.loadErrorCopy;
|
|
126
116
|
elements.retryButton.textContent = copy.retry;
|
|
127
117
|
elements.versionLabel.textContent = copy.version;
|
|
128
|
-
elements.
|
|
129
|
-
elements.hostLabel.textContent = copy.runtimeHost;
|
|
130
|
-
elements.updateButton.textContent = copy.checkUpdates;
|
|
118
|
+
elements.updateButton.querySelector(".button-label").textContent = copy.checkUpdates;
|
|
131
119
|
}
|
|
132
120
|
|
|
133
121
|
function featureState(feature) {
|
|
@@ -164,23 +152,25 @@ function createPluginCard(feature) {
|
|
|
164
152
|
icon.setAttribute("aria-hidden", "true");
|
|
165
153
|
const image = element("img");
|
|
166
154
|
image.alt = "";
|
|
167
|
-
image.width =
|
|
168
|
-
image.height =
|
|
155
|
+
image.width = 24;
|
|
156
|
+
image.height = 24;
|
|
169
157
|
icon.append(image);
|
|
170
158
|
|
|
171
159
|
const pluginCopy = element("div", "plugin-copy");
|
|
172
160
|
const titleLine = element("div", "plugin-title-line");
|
|
173
161
|
const name = element("h3", "plugin-name");
|
|
174
|
-
|
|
175
|
-
titleLine.append(name, version);
|
|
162
|
+
titleLine.append(name);
|
|
176
163
|
const description = element("p", "plugin-description");
|
|
177
164
|
pluginCopy.append(titleLine, description);
|
|
178
165
|
|
|
179
|
-
const
|
|
166
|
+
const heading = element("div", "plugin-topline");
|
|
180
167
|
const label = element("label", "switch");
|
|
181
168
|
const input = element("input");
|
|
182
169
|
input.type = "checkbox";
|
|
183
170
|
input.name = `feature-${feature.id}`;
|
|
171
|
+
input.setAttribute("role", "switch");
|
|
172
|
+
input.setAttribute("aria-describedby", `description-${feature.id} state-${feature.id}`);
|
|
173
|
+
description.id = `description-${feature.id}`;
|
|
184
174
|
const track = element("span", "switch-track");
|
|
185
175
|
track.setAttribute("aria-hidden", "true");
|
|
186
176
|
label.append(input, track);
|
|
@@ -188,9 +178,10 @@ function createPluginCard(feature) {
|
|
|
188
178
|
const dot = element("span", "status-dot");
|
|
189
179
|
dot.setAttribute("aria-hidden", "true");
|
|
190
180
|
const stateLabel = element("span", "plugin-state-label");
|
|
181
|
+
stateLabel.id = `state-${feature.id}`;
|
|
191
182
|
pluginState.append(dot, stateLabel);
|
|
192
|
-
|
|
193
|
-
card.append(
|
|
183
|
+
heading.append(icon, label);
|
|
184
|
+
card.append(heading, pluginCopy, pluginState);
|
|
194
185
|
return card;
|
|
195
186
|
}
|
|
196
187
|
|
|
@@ -199,14 +190,12 @@ function updatePluginCard(card, feature) {
|
|
|
199
190
|
const input = card.querySelector('input[type="checkbox"]');
|
|
200
191
|
const image = card.querySelector(".plugin-icon img");
|
|
201
192
|
const name = card.querySelector(".plugin-name");
|
|
202
|
-
const version = card.querySelector(".plugin-version");
|
|
203
193
|
const description = card.querySelector(".plugin-description");
|
|
204
194
|
const dot = card.querySelector(".plugin-state .status-dot");
|
|
205
195
|
const stateLabel = card.querySelector(".plugin-state-label");
|
|
206
196
|
card.dataset.featureId = feature.id;
|
|
207
|
-
image.src = feature.iconUrl
|
|
197
|
+
image.src = `${feature.iconUrl}?v=stroke-2.1`;
|
|
208
198
|
name.textContent = feature.label;
|
|
209
|
-
version.textContent = feature.version;
|
|
210
199
|
description.textContent = feature.description;
|
|
211
200
|
input.checked = Boolean(feature.enabled);
|
|
212
201
|
input.disabled = pendingFeatureIds.has(feature.id);
|
|
@@ -249,13 +238,13 @@ function renderRuntime() {
|
|
|
249
238
|
&& Number(renderer.injectedTargets) > 0,
|
|
250
239
|
);
|
|
251
240
|
const active = runtimeRunning && rendererCurrent;
|
|
241
|
+
elements.runtimeLabel.closest(".overview").hidden = active;
|
|
252
242
|
elements.runtimeDot.className = `status-dot ${active ? "is-active" : "is-warning"}`;
|
|
253
243
|
elements.runtimeLabel.textContent = active
|
|
254
244
|
? copy.runtimeActive
|
|
255
245
|
: runtimeRunning
|
|
256
246
|
? copy.runtimeNotInjected
|
|
257
247
|
: copy.runtimeStopped;
|
|
258
|
-
elements.hostValue.textContent = runtimeRunning ? copy.running : copy.stopped;
|
|
259
248
|
elements.versionValue.textContent = state?.version ?? "—";
|
|
260
249
|
elements.restartNotice.hidden = !state?.pendingRestart;
|
|
261
250
|
}
|
|
@@ -302,6 +291,7 @@ async function load() {
|
|
|
302
291
|
elements.loadError.hidden = false;
|
|
303
292
|
elements.runtimeDot.className = "status-dot is-warning";
|
|
304
293
|
elements.runtimeLabel.textContent = copy.runtimeStopped;
|
|
294
|
+
elements.runtimeLabel.closest(".overview").hidden = true;
|
|
305
295
|
}
|
|
306
296
|
}
|
|
307
297
|
|
|
@@ -369,19 +359,45 @@ elements.retryButton.addEventListener("click", () => {
|
|
|
369
359
|
|
|
370
360
|
elements.updateButton.addEventListener("click", async () => {
|
|
371
361
|
elements.updateButton.disabled = true;
|
|
372
|
-
elements.updateButton.textContent = copy.checkingUpdates;
|
|
362
|
+
elements.updateButton.querySelector(".button-label").textContent = copy.checkingUpdates;
|
|
363
|
+
elements.updateResult.hidden = true;
|
|
373
364
|
try {
|
|
374
365
|
const response = await fetch("/api/update");
|
|
375
366
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
376
367
|
const update = await response.json();
|
|
377
|
-
|
|
368
|
+
elements.updateResult.textContent = update.available ? copy.updateAvailable(update.latest) : copy.current;
|
|
369
|
+
elements.updateResult.hidden = false;
|
|
378
370
|
} catch {
|
|
379
|
-
|
|
371
|
+
elements.updateResult.textContent = copy.updateFailed;
|
|
372
|
+
elements.updateResult.hidden = false;
|
|
380
373
|
} finally {
|
|
381
374
|
elements.updateButton.disabled = false;
|
|
382
|
-
elements.updateButton.textContent = copy.checkUpdates;
|
|
375
|
+
elements.updateButton.querySelector(".button-label").textContent = copy.checkUpdates;
|
|
383
376
|
}
|
|
384
377
|
});
|
|
385
378
|
|
|
379
|
+
const systemTheme = matchMedia("(prefers-color-scheme: dark)");
|
|
380
|
+
let selectedTheme = null;
|
|
381
|
+
try { selectedTheme = localStorage.getItem("minecodex-appearance"); } catch { /* 存储不可用时仍允许本次切换。 */ }
|
|
382
|
+
function applyTheme() {
|
|
383
|
+
const dark = selectedTheme === "dark" || (selectedTheme !== "light" && systemTheme.matches);
|
|
384
|
+
document.documentElement.dataset.theme = dark ? "dark" : "light";
|
|
385
|
+
elements.themeToggle.setAttribute("aria-label", locale === "zh-CN" ? "外观" : "Appearance");
|
|
386
|
+
for (const button of elements.themeButtons) {
|
|
387
|
+
button.setAttribute("aria-label", button.dataset.themeChoice === "light" ? copy.lightAppearance : copy.darkAppearance);
|
|
388
|
+
button.setAttribute("aria-pressed", String(button.dataset.themeChoice === (dark ? "dark" : "light")));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
elements.themeToggle.addEventListener("click", (event) => {
|
|
392
|
+
const button = event.target.closest("[data-theme-choice]");
|
|
393
|
+
if (!button) return;
|
|
394
|
+
selectedTheme = button.dataset.themeChoice;
|
|
395
|
+
try { localStorage.setItem("minecodex-appearance", selectedTheme); } catch { /* 保留内存中的选择。 */ }
|
|
396
|
+
applyTheme();
|
|
397
|
+
});
|
|
398
|
+
systemTheme.addEventListener("change", applyTheme);
|
|
399
|
+
document.addEventListener("keydown", () => { document.documentElement.dataset.input = "keyboard"; });
|
|
400
|
+
document.addEventListener("pointerdown", () => { document.documentElement.dataset.input = "pointer"; });
|
|
386
401
|
applyStaticCopy();
|
|
402
|
+
applyTheme();
|
|
387
403
|
void load();
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2001 The Silkscreen Project Authors (https://github.com/googlefonts/silkscreen)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
width="24"
|
|
4
|
+
height="24"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
fill="none"
|
|
7
|
+
stroke="currentColor"
|
|
8
|
+
stroke-width="2"
|
|
9
|
+
stroke-linecap="round"
|
|
10
|
+
stroke-linejoin="round"
|
|
11
|
+
>
|
|
12
|
+
<circle cx="12" cy="12" r="10" />
|
|
13
|
+
<path d="M12 16v-4" />
|
|
14
|
+
<path d="M12 8h.01" />
|
|
15
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
width="24"
|
|
4
|
+
height="24"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
fill="none"
|
|
7
|
+
stroke="currentColor"
|
|
8
|
+
stroke-width="2"
|
|
9
|
+
stroke-linecap="round"
|
|
10
|
+
stroke-linejoin="round"
|
|
11
|
+
>
|
|
12
|
+
<path d="M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" />
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
width="24"
|
|
4
|
+
height="24"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
fill="none"
|
|
7
|
+
stroke="currentColor"
|
|
8
|
+
stroke-width="2"
|
|
9
|
+
stroke-linecap="round"
|
|
10
|
+
stroke-linejoin="round"
|
|
11
|
+
>
|
|
12
|
+
<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" />
|
|
13
|
+
<path d="M21 3v5h-5" />
|
|
14
|
+
<path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" />
|
|
15
|
+
<path d="M8 16H3v5" />
|
|
16
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
width="24"
|
|
4
|
+
height="24"
|
|
5
|
+
viewBox="0 0 24 24"
|
|
6
|
+
fill="none"
|
|
7
|
+
stroke="currentColor"
|
|
8
|
+
stroke-width="2"
|
|
9
|
+
stroke-linecap="round"
|
|
10
|
+
stroke-linejoin="round"
|
|
11
|
+
>
|
|
12
|
+
<circle cx="12" cy="12" r="4" />
|
|
13
|
+
<path d="M12 2v2" />
|
|
14
|
+
<path d="M12 20v2" />
|
|
15
|
+
<path d="m4.93 4.93 1.41 1.41" />
|
|
16
|
+
<path d="m17.66 17.66 1.41 1.41" />
|
|
17
|
+
<path d="M2 12h2" />
|
|
18
|
+
<path d="M20 12h2" />
|
|
19
|
+
<path d="m6.34 17.66-1.41 1.41" />
|
|
20
|
+
<path d="m19.07 4.93-1.41 1.41" />
|
|
21
|
+
</svg>
|