cortico 0.1.0
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/LICENSE +21 -0
- package/README.md +47 -0
- package/package.json +43 -0
- package/src/boot.ts +46 -0
- package/src/bot.ts +1342 -0
- package/src/config-file.ts +41 -0
- package/src/core/README.md +92 -0
- package/src/core/billing.ts +26 -0
- package/src/core/blobs.ts +106 -0
- package/src/core/bus.ts +311 -0
- package/src/core/config-schema.ts +201 -0
- package/src/core/config.ts +262 -0
- package/src/core/core.ts +699 -0
- package/src/core/cost.ts +244 -0
- package/src/core/event-store.ts +304 -0
- package/src/core/fork.ts +113 -0
- package/src/core/generation.ts +118 -0
- package/src/core/instance-lock.ts +215 -0
- package/src/core/ipc-logger.ts +105 -0
- package/src/core/language.ts +62 -0
- package/src/core/log-context.ts +38 -0
- package/src/core/loop.ts +1858 -0
- package/src/core/markers.ts +48 -0
- package/src/core/prefix.ts +121 -0
- package/src/core/run.ts +95 -0
- package/src/core/secrets.ts +18 -0
- package/src/core/session.ts +56 -0
- package/src/core/sessions.ts +261 -0
- package/src/core/state.ts +104 -0
- package/src/core/template.ts +72 -0
- package/src/core/timers.ts +129 -0
- package/src/core/tool-log.ts +135 -0
- package/src/core/transcript.ts +92 -0
- package/src/core/truncate.ts +121 -0
- package/src/core/types.ts +1140 -0
- package/src/core/usage-log.ts +79 -0
- package/src/core/util.ts +386 -0
- package/src/deploy-listing.ts +160 -0
- package/src/deploy.ts +162 -0
- package/src/extensions/README.md +72 -0
- package/src/extensions/dry-mount.ts +390 -0
- package/src/extensions/manifest.ts +153 -0
- package/src/extensions/runtime.ts +42 -0
- package/src/extensions.ts +519 -0
- package/src/launcher.ts +285 -0
- package/src/paths.ts +155 -0
- package/src/protocol/open-responses/LICENSE +201 -0
- package/src/protocol/open-responses/README.md +14 -0
- package/src/protocol/open-responses/context-helpers.ts +27 -0
- package/src/protocol/open-responses/context-log.ts +59 -0
- package/src/protocol/open-responses/context.ts +89 -0
- package/src/protocol/open-responses/generated.ts +115 -0
- package/src/protocol/open-responses/index.ts +33 -0
- package/src/protocol/open-responses/openapi.json +4230 -0
- package/src/protocol/open-responses/stream.ts +146 -0
- package/src/protocol/open-responses/tokens.ts +31 -0
- package/src/providers/README.md +86 -0
- package/src/providers/base.ts +111 -0
- package/src/providers/configuration.ts +97 -0
- package/src/providers/console/config.ts +21 -0
- package/src/providers/console/settings.ts +443 -0
- package/src/providers/console/strings.ts +74 -0
- package/src/providers/console/types.ts +11 -0
- package/src/providers/llamacpp/archive.ts +148 -0
- package/src/providers/llamacpp/catalog.ts +247 -0
- package/src/providers/llamacpp/config.ts +36 -0
- package/src/providers/llamacpp/console/client.ts +6 -0
- package/src/providers/llamacpp/console/models-panel.ts +120 -0
- package/src/providers/llamacpp/console/runtime-panel.ts +173 -0
- package/src/providers/llamacpp/console/server.ts +153 -0
- package/src/providers/llamacpp/index.ts +95 -0
- package/src/providers/llamacpp/native.ts +51 -0
- package/src/providers/llamacpp/options.ts +117 -0
- package/src/providers/llamacpp/runtime-store.ts +139 -0
- package/src/providers/llamacpp/runtime.ts +214 -0
- package/src/providers/llamacpp/server.ts +286 -0
- package/src/providers/llamacpp/strings.ts +230 -0
- package/src/providers/openai-responses-compat/config.ts +20 -0
- package/src/providers/openai-responses-compat/index.ts +89 -0
- package/src/providers/openai-responses-compat/native.ts +127 -0
- package/src/providers/openai-responses-compat/strings.ts +19 -0
- package/src/providers/pricebook.ts +75 -0
- package/src/providers/registry.ts +137 -0
- package/src/providers/strings.ts +71 -0
- package/src/providers/transport/chat.ts +156 -0
- package/src/providers/transport/errors.ts +48 -0
- package/src/providers/transport/history.ts +68 -0
- package/src/providers/transport/native-input.ts +83 -0
- package/src/providers/transport/native-types.ts +13 -0
- package/src/providers/transport/response-assembly.ts +191 -0
- package/src/providers/transport/response-http.ts +196 -0
- package/src/providers/transport/response-meters.ts +27 -0
- package/src/providers/transport/responses-input.ts +56 -0
- package/src/web/README.md +84 -0
- package/src/web/client/console-pages/builtins/llm-settings/panel.ts +625 -0
- package/src/web/client/console-pages/builtins/llm-settings/pricing-panel.ts +168 -0
- package/src/web/client/console-pages/builtins/llm-settings/strings.ts +213 -0
- package/src/web/client/console-pages/builtins.ts +10 -0
- package/src/web/client/console-pages/context.ts +135 -0
- package/src/web/client/console-pages/host.ts +633 -0
- package/src/web/client/console-pages/loader.ts +132 -0
- package/src/web/client/console-pages/strings.ts +90 -0
- package/src/web/client/console-pages/tools/strings.ts +49 -0
- package/src/web/client/console-pages/tools/view.ts +215 -0
- package/src/web/client/core/api.ts +200 -0
- package/src/web/client/core/language.ts +56 -0
- package/src/web/client/core/lifecycle.ts +132 -0
- package/src/web/client/core/router.ts +199 -0
- package/src/web/client/core/stream.ts +157 -0
- package/src/web/client/core/websocket.ts +82 -0
- package/src/web/client/features/appearance/index.ts +333 -0
- package/src/web/client/features/appearance/strings.ts +87 -0
- package/src/web/client/features/config/index.ts +11 -0
- package/src/web/client/features/config/strings.ts +41 -0
- package/src/web/client/features/config/view.ts +428 -0
- package/src/web/client/features/core/events.ts +197 -0
- package/src/web/client/features/core/index.ts +254 -0
- package/src/web/client/features/core/run.ts +56 -0
- package/src/web/client/features/core/runlog.ts +214 -0
- package/src/web/client/features/core/sessions.ts +53 -0
- package/src/web/client/features/core/strings.ts +157 -0
- package/src/web/client/features/extensions/index.ts +422 -0
- package/src/web/client/features/extensions/strings.ts +164 -0
- package/src/web/client/features/feature.ts +93 -0
- package/src/web/client/features/live/context.ts +280 -0
- package/src/web/client/features/live/fork.ts +156 -0
- package/src/web/client/features/live/index.ts +392 -0
- package/src/web/client/features/live/onboarding.ts +113 -0
- package/src/web/client/features/live/protocol.ts +122 -0
- package/src/web/client/features/live/sessions.ts +71 -0
- package/src/web/client/features/live/status.ts +68 -0
- package/src/web/client/features/live/strings.ts +252 -0
- package/src/web/client/features/live/timeline.ts +590 -0
- package/src/web/client/features/prompts/editor.ts +292 -0
- package/src/web/client/features/prompts/index.ts +346 -0
- package/src/web/client/features/prompts/strings.ts +136 -0
- package/src/web/client/features/prompts/view.ts +256 -0
- package/src/web/client/features/providers/index.ts +100 -0
- package/src/web/client/features/providers/strings.ts +23 -0
- package/src/web/client/features/settings/general.ts +28 -0
- package/src/web/client/features/settings/index.ts +82 -0
- package/src/web/client/features/settings/strings.ts +33 -0
- package/src/web/client/features/storage/index.ts +1 -0
- package/src/web/client/features/storage/strings.ts +45 -0
- package/src/web/client/features/storage/view.ts +154 -0
- package/src/web/client/features/usage/chart.ts +486 -0
- package/src/web/client/features/usage/index.ts +407 -0
- package/src/web/client/features/usage/labels.ts +46 -0
- package/src/web/client/features/usage/range.ts +36 -0
- package/src/web/client/features/usage/state.ts +37 -0
- package/src/web/client/features/usage/strings.ts +191 -0
- package/src/web/client/features/usage/tooltip.ts +86 -0
- package/src/web/client/features/usage/types.ts +96 -0
- package/src/web/client/features/worlds/index.ts +424 -0
- package/src/web/client/features/worlds/strings.ts +121 -0
- package/src/web/client/main.ts +273 -0
- package/src/web/client/shell/avatar.ts +233 -0
- package/src/web/client/shell/index.ts +549 -0
- package/src/web/client/shell/strings.ts +89 -0
- package/src/web/client/theme/handoff.ts +43 -0
- package/src/web/client/theme/palette.ts +109 -0
- package/src/web/client/theme/registry.ts +130 -0
- package/src/web/client/theme/storage.ts +72 -0
- package/src/web/client/theme/strings.ts +123 -0
- package/src/web/client/theme/studio.ts +366 -0
- package/src/web/client/ui/actions.ts +109 -0
- package/src/web/client/ui/data.ts +185 -0
- package/src/web/client/ui/dom.ts +23 -0
- package/src/web/client/ui/fields.ts +191 -0
- package/src/web/client/ui/format.ts +75 -0
- package/src/web/client/ui/icons.ts +183 -0
- package/src/web/client/ui/images.ts +91 -0
- package/src/web/client/ui/index.ts +89 -0
- package/src/web/client/ui/lamp.ts +125 -0
- package/src/web/client/ui/log.ts +98 -0
- package/src/web/client/ui/overlay.ts +184 -0
- package/src/web/client/ui/page.ts +8 -0
- package/src/web/client/ui/prompt-input.tsx +311 -0
- package/src/web/client/ui/sheet.ts +131 -0
- package/src/web/client/ui/strings.ts +71 -0
- package/src/web/console-pages.ts +367 -0
- package/src/web/files.ts +107 -0
- package/src/web/path-picker.ts +296 -0
- package/src/web/public/index.html +17 -0
- package/src/web/public/styles.css +1715 -0
- package/src/web/server.ts +1883 -0
- package/src/web/shared/client-panel.ts +603 -0
- package/src/web/shared/console-protocol.ts +560 -0
- package/src/web/shared/css.d.ts +1 -0
- package/src/web/shared/path-picker.ts +23 -0
- package/src/web/shared/theme.ts +256 -0
- package/src/web/theme-store.ts +37 -0
- package/src/world.ts +449 -0
- package/src/worlds/bilibili/ENV_PROMPT.md +5 -0
- package/src/worlds/bilibili/README.md +176 -0
- package/src/worlds/bilibili/audience-admission.ts +995 -0
- package/src/worlds/bilibili/client.ts +528 -0
- package/src/worlds/bilibili/coalescing-buffer.ts +125 -0
- package/src/worlds/bilibili/config.ts +185 -0
- package/src/worlds/bilibili/console/client.ts +202 -0
- package/src/worlds/bilibili/definition.ts +35 -0
- package/src/worlds/bilibili/gift-frame.ts +131 -0
- package/src/worlds/bilibili/normalize.ts +452 -0
- package/src/worlds/bilibili/overlay/announcement.ts +76 -0
- package/src/worlds/bilibili/overlay/assets.ts +82 -0
- package/src/worlds/bilibili/overlay/model.ts +494 -0
- package/src/worlds/bilibili/overlay/project.ts +202 -0
- package/src/worlds/bilibili/overlay/server.ts +286 -0
- package/src/worlds/bilibili/overlay/types.ts +217 -0
- package/src/worlds/bilibili/overlay/web/app.js +690 -0
- package/src/worlds/bilibili/overlay/web/editor.css +297 -0
- package/src/worlds/bilibili/overlay/web/editor.html +102 -0
- package/src/worlds/bilibili/overlay/web/editor.js +2116 -0
- package/src/worlds/bilibili/overlay/web/overlay.html +13 -0
- package/src/worlds/bilibili/overlay/web/styles.css +258 -0
- package/src/worlds/bilibili/protobuf.ts +123 -0
- package/src/worlds/bilibili/wire.ts +94 -0
- package/src/worlds/bilibili/world.ts +1389 -0
- package/src/worlds/console-fixture/ENV_PROMPT.md +1 -0
- package/src/worlds/console-fixture/console/client.ts +72 -0
- package/src/worlds/console-fixture/world.ts +73 -0
- package/src/worlds/index.ts +15 -0
- package/src/worlds/minecraft/ENV_PROMPT.md +32 -0
- package/src/worlds/minecraft/ENV_PROMPT_CAMERA.md +2 -0
- package/src/worlds/minecraft/LICENSE-mineflayer-pathfinder.txt +21 -0
- package/src/worlds/minecraft/README.md +917 -0
- package/src/worlds/minecraft/blueprint-plan.ts +915 -0
- package/src/worlds/minecraft/blueprint-registry.ts +566 -0
- package/src/worlds/minecraft/blueprint-repair.ts +236 -0
- package/src/worlds/minecraft/blueprint-resource.ts +272 -0
- package/src/worlds/minecraft/blueprint.ts +492 -0
- package/src/worlds/minecraft/body-lease.ts +340 -0
- package/src/worlds/minecraft/bridge.ts +749 -0
- package/src/worlds/minecraft/check.ts +651 -0
- package/src/worlds/minecraft/chests.ts +292 -0
- package/src/worlds/minecraft/client-launch.ts +272 -0
- package/src/worlds/minecraft/client-options.ts +85 -0
- package/src/worlds/minecraft/client-skins.ts +164 -0
- package/src/worlds/minecraft/client-window.ps1 +91 -0
- package/src/worlds/minecraft/client.ts +423 -0
- package/src/worlds/minecraft/combat-context.ts +109 -0
- package/src/worlds/minecraft/combat.ts +1552 -0
- package/src/worlds/minecraft/config.ts +499 -0
- package/src/worlds/minecraft/console/access.ts +218 -0
- package/src/worlds/minecraft/console/client.ts +244 -0
- package/src/worlds/minecraft/console/log.ts +110 -0
- package/src/worlds/minecraft/console/mount.ts +420 -0
- package/src/worlds/minecraft/console/skin.ts +257 -0
- package/src/worlds/minecraft/console/style.css +154 -0
- package/src/worlds/minecraft/console/world.ts +449 -0
- package/src/worlds/minecraft/deaths.ts +135 -0
- package/src/worlds/minecraft/definition.ts +18 -0
- package/src/worlds/minecraft/engine-child.ts +274 -0
- package/src/worlds/minecraft/engine-ipc.ts +98 -0
- package/src/worlds/minecraft/entity-facts.ts +132 -0
- package/src/worlds/minecraft/escape.ts +407 -0
- package/src/worlds/minecraft/executor.ts +14494 -0
- package/src/worlds/minecraft/explored.ts +156 -0
- package/src/worlds/minecraft/geometry.ts +205 -0
- package/src/worlds/minecraft/goal-plan.ts +647 -0
- package/src/worlds/minecraft/item-break.ts +126 -0
- package/src/worlds/minecraft/item-facts.ts +146 -0
- package/src/worlds/minecraft/item-pick.ts +67 -0
- package/src/worlds/minecraft/level-dat.ts +176 -0
- package/src/worlds/minecraft/log.ts +132 -0
- package/src/worlds/minecraft/mineflayer-fixes.ts +1180 -0
- package/src/worlds/minecraft/names.ts +377 -0
- package/src/worlds/minecraft/pathfinder-lib.d.ts +13 -0
- package/src/worlds/minecraft/pathfinder-perf.ts +796 -0
- package/src/worlds/minecraft/piglin.ts +49 -0
- package/src/worlds/minecraft/policy.ts +547 -0
- package/src/worlds/minecraft/precheck.ts +655 -0
- package/src/worlds/minecraft/proxy.ts +445 -0
- package/src/worlds/minecraft/ranged.ts +635 -0
- package/src/worlds/minecraft/readouts.ts +102 -0
- package/src/worlds/minecraft/round.ts +26 -0
- package/src/worlds/minecraft/search-observation.ts +92 -0
- package/src/worlds/minecraft/server-config.ts +467 -0
- package/src/worlds/minecraft/server.ts +658 -0
- package/src/worlds/minecraft/show.ts +84 -0
- package/src/worlds/minecraft/skills.ts +1763 -0
- package/src/worlds/minecraft/terrain.ts +1735 -0
- package/src/worlds/minecraft/window.ts +96 -0
- package/src/worlds/minecraft/works.ts +179 -0
- package/src/worlds/minecraft/world.ts +6438 -0
- package/src/worlds/qq/ENV_PROMPT.md +5 -0
- package/src/worlds/qq/config.ts +108 -0
- package/src/worlds/qq/console/client.ts +126 -0
- package/src/worlds/qq/console/events.ts +155 -0
- package/src/worlds/qq/console/gate.ts +232 -0
- package/src/worlds/qq/console/roster.ts +203 -0
- package/src/worlds/qq/console/style.css +65 -0
- package/src/worlds/qq/conversation.ts +28 -0
- package/src/worlds/qq/definition.ts +62 -0
- package/src/worlds/qq/driver.ts +375 -0
- package/src/worlds/qq/history-tools.ts +209 -0
- package/src/worlds/qq/normalize.ts +323 -0
- package/src/worlds/qq/qface-map.ts +282 -0
- package/src/worlds/qq/vision-prompt.ts +27 -0
- package/src/worlds/qq/vision.ts +642 -0
- package/src/worlds/qq/vlm.ts +142 -0
- package/src/worlds/qq/world.ts +1503 -0
- package/src/worlds/terminal/ENV_PROMPT.md +11 -0
- package/src/worlds/terminal/config.ts +9 -0
- package/src/worlds/terminal/definition.ts +14 -0
- package/src/worlds/terminal/world.ts +700 -0
- package/src/worlds/websearch/ENV_PROMPT.md +1 -0
- package/src/worlds/websearch/brave-client.ts +261 -0
- package/src/worlds/websearch/config.ts +75 -0
- package/src/worlds/websearch/definition.ts +20 -0
- package/src/worlds/websearch/world.ts +171 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 主题的数据与纯函数:token 词表、内置调色板、部署主题记录的规范化。
|
|
3
|
+
* 浏览器、控制台服务端与启动器共用这一份;不依赖 DOM,token 的中文标签由浏览器侧贴。
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type ThemeMode = 'light' | 'dark' | 'system';
|
|
7
|
+
|
|
8
|
+
/** `system` 解析之后只剩两种。CSS 变量真正落地时看的是这个。 */
|
|
9
|
+
export type ThemeAppearance = 'light' | 'dark';
|
|
10
|
+
|
|
11
|
+
/** token key → `#rrggbb`。缺格由 `normalizePalette` 用回退表补齐。 */
|
|
12
|
+
export type ThemePalette = Record<string, string>;
|
|
13
|
+
|
|
14
|
+
export interface ThemeScheme {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
note: string;
|
|
18
|
+
/** 浅色与黑夜是**两份独立配色**,不是同一份的明暗算法推导。 */
|
|
19
|
+
palettes: Record<ThemeAppearance, ThemePalette>;
|
|
20
|
+
builtin?: boolean;
|
|
21
|
+
custom?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 一份部署的主题记录,存在 `<部署>/theme.json`。内置方案不进记录。 */
|
|
25
|
+
export interface StoredTheme {
|
|
26
|
+
/** 选中的方案 id(可能指向一个已被删掉的自定义方案,取用时再兜底)。 */
|
|
27
|
+
selectedId: string;
|
|
28
|
+
mode: ThemeMode;
|
|
29
|
+
custom: ThemeScheme[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const THEME_MODES: readonly ThemeMode[] = ['light', 'dark', 'system'];
|
|
33
|
+
|
|
34
|
+
/** 词表分组与顺序。组标题与逐个 token 的标签在浏览器侧按 id 取。 */
|
|
35
|
+
export const THEME_TOKEN_GROUPS = [
|
|
36
|
+
{ id: 'paper', keys: ['paper', 'paper-2', 'sheet', 'sheet-2', 'sheet-3'] },
|
|
37
|
+
{ id: 'ink', keys: ['ink', 'ink-soft', 'ink-dim', 'line', 'line-2', 'line-strong'] },
|
|
38
|
+
{ id: 'state', keys: ['accent', 'accent-2', 'on-accent', 'ok', 'warn', 'danger'] },
|
|
39
|
+
{
|
|
40
|
+
id: 'timeline',
|
|
41
|
+
keys: ['ink-blue', 'violet', 'agent-surface', 'world-bg', 'world-ink', 'bubble-bg', 'bubble-ink', 'tool-result'],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'chart',
|
|
45
|
+
keys: [
|
|
46
|
+
'chart-hit', 'chart-miss', 'chart-output',
|
|
47
|
+
'chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5', 'chart-6', 'chart-7', 'chart-8',
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
export const THEME_TOKEN_KEYS: readonly string[] = THEME_TOKEN_GROUPS.flatMap((g) => [...g.keys]);
|
|
53
|
+
|
|
54
|
+
/** 主强调取自明暗版 Logo;正文使用加深或调亮的同色系绿色。 */
|
|
55
|
+
const mintLight: ThemePalette = {
|
|
56
|
+
paper: '#f4f5f4', 'paper-2': '#ecedec', sheet: '#fbfbfb', 'sheet-2': '#f2f3f2', 'sheet-3': '#e8e9e8',
|
|
57
|
+
ink: '#1b1a1e', 'ink-soft': '#5c5c60', 'ink-dim': '#8b8b8f', line: '#e3e4e3', 'line-2': '#d0d2d0', 'line-strong': '#aeb0ae',
|
|
58
|
+
accent: '#00a870', 'accent-2': '#54b494', 'on-accent': '#082a1e', ok: '#19815e', warn: '#96743b', danger: '#b45950',
|
|
59
|
+
'ink-blue': '#238268', violet: '#25765e', 'agent-surface': '#f4f5f4', 'world-bg': '#f0f1f0', 'world-ink': '#4a4a4e',
|
|
60
|
+
'bubble-bg': '#e6e9e7', 'bubble-ink': '#1f2221', 'tool-result': '#087452',
|
|
61
|
+
'chart-hit': '#19815e', 'chart-miss': '#96743b', 'chart-output': '#00a870',
|
|
62
|
+
'chart-1': '#00a870', 'chart-2': '#54b494', 'chart-3': '#348f86', 'chart-4': '#72967f',
|
|
63
|
+
'chart-5': '#b59564', 'chart-6': '#9b8071', 'chart-7': '#4a8f9a', 'chart-8': '#889460',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const mintDark: ThemePalette = {
|
|
67
|
+
paper: '#121312', 'paper-2': '#181a19', sheet: '#1d1f1e', 'sheet-2': '#242726', 'sheet-3': '#2c302e',
|
|
68
|
+
ink: '#e9eae9', 'ink-soft': '#b0b2b1', 'ink-dim': '#828584', line: '#292c2b', 'line-2': '#383c3a', 'line-strong': '#535856',
|
|
69
|
+
accent: '#2fd59b', 'accent-2': '#78cbae', 'on-accent': '#082a1e', ok: '#76ca9f', warn: '#c4a372', danger: '#d18c83',
|
|
70
|
+
'ink-blue': '#53bda0', violet: '#91d8bb', 'agent-surface': '#181a19', 'world-bg': '#1e211f', 'world-ink': '#adb2b0',
|
|
71
|
+
'bubble-bg': '#2c3230', 'bubble-ink': '#e6eae8', 'tool-result': '#75cfa8',
|
|
72
|
+
'chart-hit': '#76ca9f', 'chart-miss': '#c4a372', 'chart-output': '#2fd59b',
|
|
73
|
+
'chart-1': '#2fd59b', 'chart-2': '#78cbae', 'chart-3': '#64b8ad', 'chart-4': '#91b99d',
|
|
74
|
+
'chart-5': '#c4a372', 'chart-6': '#b69b8c', 'chart-7': '#76afb9', 'chart-8': '#a8b17e',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const navigatorLight: ThemePalette = {
|
|
78
|
+
paper: '#f5f7fa', 'paper-2': '#e9eef4', sheet: '#ffffff', 'sheet-2': '#f1f4f8', 'sheet-3': '#e3eaf2',
|
|
79
|
+
ink: '#383d43', 'ink-soft': '#536174', 'ink-dim': '#7d8a9c', line: '#dce3eb', 'line-2': '#c6d1df', 'line-strong': '#9dacc0',
|
|
80
|
+
accent: '#6591c3', 'accent-2': '#383d43', 'on-accent': '#111820', ok: '#357389', warn: '#865963', danger: '#a34f63',
|
|
81
|
+
'ink-blue': '#426c99', violet: '#383d43', 'agent-surface': '#f5f7fa', 'world-bg': '#edf3f8', 'world-ink': '#485665',
|
|
82
|
+
'bubble-bg': '#e4eef8', 'bubble-ink': '#383d43', 'tool-result': '#355c84',
|
|
83
|
+
'chart-hit': '#529bbd', 'chart-miss': '#383d43', 'chart-output': '#6591c3',
|
|
84
|
+
'chart-1': '#6591c3', 'chart-2': '#383d43', 'chart-3': '#81c9ef', 'chart-4': '#a9bed6',
|
|
85
|
+
'chart-5': '#bc8f9a', 'chart-6': '#637489', 'chart-7': '#4f91ad', 'chart-8': '#c6d3e2',
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** 深色背景上的海军蓝边线与文字使用提亮的同色系蓝色。 */
|
|
89
|
+
const navigatorDark: ThemePalette = {
|
|
90
|
+
paper: '#12171d', 'paper-2': '#171d24', sheet: '#202730', 'sheet-2': '#28313c', 'sheet-3': '#323d4a',
|
|
91
|
+
ink: '#f2f5fa', 'ink-soft': '#b8c5d6', 'ink-dim': '#8594a7', line: '#2d3743', 'line-2': '#3c4959', 'line-strong': '#596b80',
|
|
92
|
+
accent: '#81c9ef', 'accent-2': '#6591c3', 'on-accent': '#162331', ok: '#85c8dc', warn: '#d6aeb8', danger: '#e99bae',
|
|
93
|
+
'ink-blue': '#81c9ef', violet: '#a9bed6', 'agent-surface': '#171d24', 'world-bg': '#202b38', 'world-ink': '#b8c5d6',
|
|
94
|
+
'bubble-bg': '#2e3d50', 'bubble-ink': '#f2f5fa', 'tool-result': '#9dbfe2',
|
|
95
|
+
'chart-hit': '#81c9ef', 'chart-miss': '#6591c3', 'chart-output': '#adc7e4',
|
|
96
|
+
'chart-1': '#81c9ef', 'chart-2': '#6591c3', 'chart-3': '#9dbfe2', 'chart-4': '#b8c5d6',
|
|
97
|
+
'chart-5': '#fae6e8', 'chart-6': '#8e9fb5', 'chart-7': '#73aec9', 'chart-8': '#cbd6e4',
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/** Claude 灰阶配赤陶与灰玫瑰强调色;浅色文字使用同色系的深色。 */
|
|
101
|
+
const crabDaisyLight: ThemePalette = {
|
|
102
|
+
paper: '#fcfcfb', 'paper-2': '#f9f9f7', sheet: '#ffffff', 'sheet-2': '#f3f3f0', 'sheet-3': '#f0efec',
|
|
103
|
+
ink: '#0b0b0b', 'ink-soft': '#52514e', 'ink-dim': '#7b7974', line: '#e1e0d9', 'line-2': '#d2d1c7', 'line-strong': '#b4b3a8',
|
|
104
|
+
accent: '#c87c5d', 'accent-2': '#cb7c78', 'on-accent': '#131313', ok: '#006300', warn: '#835100', danger: '#8e2626',
|
|
105
|
+
'ink-blue': '#cb7c78', violet: '#a15d59', 'agent-surface': '#fcfcfb', 'world-bg': '#f3f3f0', 'world-ink': '#52514e',
|
|
106
|
+
'bubble-bg': '#f0efec', 'bubble-ink': '#131313', 'tool-result': '#995b43',
|
|
107
|
+
'chart-hit': '#009300', 'chart-miss': '#a66a00', 'chart-output': '#c87c5d',
|
|
108
|
+
'chart-1': '#c87c5d', 'chart-2': '#cb7c78', 'chart-3': '#7161e0', 'chart-4': '#009300',
|
|
109
|
+
'chart-5': '#c6613f', 'chart-6': '#a66a00', 'chart-7': '#7b7974', 'chart-8': '#c04873',
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const crabDaisyDark: ThemePalette = {
|
|
113
|
+
paper: '#151515', 'paper-2': '#111111', sheet: '#20201f', 'sheet-2': '#1e1e1d', 'sheet-3': '#2c2c2a',
|
|
114
|
+
ink: '#f0efec', 'ink-soft': '#c3c2b7', 'ink-dim': '#97958d', line: '#383835', 'line-2': '#454442', 'line-strong': '#5f5e5a',
|
|
115
|
+
accent: '#c87c5d', 'accent-2': '#cb7c78', 'on-accent': '#131313', ok: '#91d68b', warn: '#db9300', danger: '#ec7e7e',
|
|
116
|
+
'ink-blue': '#cb7c78', violet: '#cb7c78', 'agent-surface': '#151515', 'world-bg': '#20201f', 'world-ink': '#c3c2b7',
|
|
117
|
+
'bubble-bg': '#2c2c2a', 'bubble-ink': '#f0efec', 'tool-result': '#c87c5d',
|
|
118
|
+
'chart-hit': '#91d68b', 'chart-miss': '#db9300', 'chart-output': '#c87c5d',
|
|
119
|
+
'chart-1': '#c87c5d', 'chart-2': '#cb7c78', 'chart-3': '#a096eb', 'chart-4': '#91d68b',
|
|
120
|
+
'chart-5': '#ec835a', 'chart-6': '#db9300', 'chart-7': '#97958d', 'chart-8': '#e87ba4',
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/** 内置方案的调色板,按 id。名称与说明是界面文案,由浏览器侧按 id 贴。 */
|
|
124
|
+
export const BUILTIN_PALETTES: Readonly<Record<string, Record<ThemeAppearance, ThemePalette>>> = {
|
|
125
|
+
mint: { light: mintLight, dark: mintDark },
|
|
126
|
+
navigator: { light: navigatorLight, dark: navigatorDark },
|
|
127
|
+
'crab-daisy': { light: crabDaisyLight, dark: crabDaisyDark },
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/** 内置方案 id,第一个是框架默认方案。 */
|
|
131
|
+
export const BUILTIN_SCHEME_IDS: readonly string[] = Object.keys(BUILTIN_PALETTES);
|
|
132
|
+
|
|
133
|
+
/** 记录里没有可用选择时落到哪一个。 */
|
|
134
|
+
export const DEFAULT_SCHEME_ID = BUILTIN_SCHEME_IDS[0];
|
|
135
|
+
|
|
136
|
+
/** `#rrggbb`(大小写不限)。三位简写**不算**——记录里只留规范形式。 */
|
|
137
|
+
export function isHexColor(value: unknown): boolean {
|
|
138
|
+
return /^#[0-9a-f]{6}$/i.test(String(value ?? ''));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 用户输入 → 规范 `#rrggbb`(小写);认不出给 `null`。
|
|
143
|
+
*
|
|
144
|
+
* 收 `#abc` 简写是因为手打十六进制的人真会那么写,而 `<input type="color">`
|
|
145
|
+
* 永远吐六位——两边喂进同一个函数,编辑器里就不必分两条路。
|
|
146
|
+
*/
|
|
147
|
+
export function normalizeHex(value: unknown): string | null {
|
|
148
|
+
const raw = String(value ?? '').trim();
|
|
149
|
+
const short = /^#([0-9a-f]{3})$/i.exec(raw);
|
|
150
|
+
const full = short ? '#' + short[1].split('').map((c) => c + c).join('') : raw;
|
|
151
|
+
return isHexColor(full) ? full.toLowerCase() : null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** 该明暗变体的兜底调色板(默认方案)。 */
|
|
155
|
+
export function fallbackPalette(appearance: ThemeAppearance): ThemePalette {
|
|
156
|
+
return BUILTIN_PALETTES[DEFAULT_SCHEME_ID][appearance];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 逐 token 校验 + 补齐。**只留词表里的键**:记录里混进来的野键不该被原样写回
|
|
161
|
+
* `documentElement`,那等于让一份主题记录往全站注入任意 CSS 变量。
|
|
162
|
+
*/
|
|
163
|
+
export function normalizePalette(palette: unknown, fallback: ThemePalette): ThemePalette {
|
|
164
|
+
const src = (palette ?? {}) as Record<string, unknown>;
|
|
165
|
+
const out: ThemePalette = {};
|
|
166
|
+
for (const key of THEME_TOKEN_KEYS) {
|
|
167
|
+
const value = src[key];
|
|
168
|
+
out[key] = isHexColor(value) ? String(value).toLowerCase() : fallback[key];
|
|
169
|
+
}
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function clonePalette(palette: ThemePalette): ThemePalette {
|
|
174
|
+
return { ...palette };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function cloneScheme(scheme: ThemeScheme): ThemeScheme {
|
|
178
|
+
return {
|
|
179
|
+
...scheme,
|
|
180
|
+
palettes: {
|
|
181
|
+
light: clonePalette(scheme.palettes.light),
|
|
182
|
+
dark: clonePalette(scheme.palettes.dark),
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** 方案卡上那条四格色带:底纸 / 主卡纸 / 主强调 / 一个图表系列色。 */
|
|
188
|
+
export function schemeSwatches(scheme: ThemeScheme, appearance: ThemeAppearance): string[] {
|
|
189
|
+
const p = scheme.palettes[appearance];
|
|
190
|
+
return [p.paper, p.sheet, p.accent, p['chart-2']];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function defaultStoredTheme(): StoredTheme {
|
|
194
|
+
return { selectedId: DEFAULT_SCHEME_ID, mode: 'system', custom: [] };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** 自定义方案的名称上限 40 字、说明上限 80 字;缺 id 的记录返回 null。 */
|
|
198
|
+
function normalizeCustomScheme(raw: unknown): ThemeScheme | null {
|
|
199
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
200
|
+
const scheme = raw as Partial<ThemeScheme>;
|
|
201
|
+
if (typeof scheme.id !== 'string' || scheme.id === '') return null;
|
|
202
|
+
const palettes = (scheme.palettes ?? {}) as Partial<ThemeScheme['palettes']>;
|
|
203
|
+
return {
|
|
204
|
+
id: scheme.id,
|
|
205
|
+
name: String(scheme.name ?? '').slice(0, 40),
|
|
206
|
+
note: String(scheme.note ?? '').slice(0, 80),
|
|
207
|
+
palettes: {
|
|
208
|
+
light: normalizePalette(palettes.light, fallbackPalette('light')),
|
|
209
|
+
dark: normalizePalette(palettes.dark, fallbackPalette('dark')),
|
|
210
|
+
},
|
|
211
|
+
custom: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** 任意值 → 一份可用的主题记录。字段类型不对的按缺省算,绝不抛。 */
|
|
216
|
+
export function normalizeStoredTheme(value: unknown): StoredTheme {
|
|
217
|
+
if (!value || typeof value !== 'object') return defaultStoredTheme();
|
|
218
|
+
const raw = value as Partial<StoredTheme>;
|
|
219
|
+
return {
|
|
220
|
+
selectedId: typeof raw.selectedId === 'string' ? raw.selectedId : DEFAULT_SCHEME_ID,
|
|
221
|
+
mode: THEME_MODES.includes(raw.mode as ThemeMode) ? (raw.mode as ThemeMode) : 'system',
|
|
222
|
+
custom: Array.isArray(raw.custom)
|
|
223
|
+
? raw.custom.map(normalizeCustomScheme).filter((s): s is ThemeScheme => s !== null)
|
|
224
|
+
: [],
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** JSON 文本 → 主题记录。解析不了或是空串给默认值。 */
|
|
229
|
+
export function parseStoredTheme(raw: string | null | undefined): StoredTheme {
|
|
230
|
+
if (raw == null || raw === '') return defaultStoredTheme();
|
|
231
|
+
try {
|
|
232
|
+
return normalizeStoredTheme(JSON.parse(raw));
|
|
233
|
+
} catch {
|
|
234
|
+
return defaultStoredTheme();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 记录里选中的那份调色板。选中的自定义方案被删掉、或 id 认不出时落到默认方案。
|
|
240
|
+
* `mode` 为 `system` 时由调用方决定明暗:浏览器问系统,终端按深色。
|
|
241
|
+
*/
|
|
242
|
+
export function resolvePalette(state: StoredTheme, appearance: ThemeAppearance): ThemePalette {
|
|
243
|
+
const custom = state.custom.find((s) => s.id === state.selectedId);
|
|
244
|
+
if (custom) return custom.palettes[appearance];
|
|
245
|
+
const builtin = BUILTIN_PALETTES[state.selectedId] ?? BUILTIN_PALETTES[DEFAULT_SCHEME_ID];
|
|
246
|
+
return builtin[appearance];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/** 服务端把部署的主题记录注入到这个 id 的 `<script type="application/json">`。 */
|
|
250
|
+
export const THEME_SCRIPT_ID = 'cortico-theme';
|
|
251
|
+
|
|
252
|
+
/** 随首页发出的主题:部署默认方案 id,以及这份部署已保存的记录(没保存过为 null)。 */
|
|
253
|
+
export interface InjectedTheme {
|
|
254
|
+
defaultScheme: string;
|
|
255
|
+
theme: StoredTheme | null;
|
|
256
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 部署的控制台配色记录:`<部署>/theme.json`。控制台读写,启动器只读。
|
|
3
|
+
* 文件内容就是浏览器侧的主题记录形状,写入前逐个 token 规范化。
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { normalizeStoredTheme, type StoredTheme } from './shared/theme.ts';
|
|
8
|
+
|
|
9
|
+
export const THEME_FILE = 'theme.json';
|
|
10
|
+
|
|
11
|
+
export interface DeploymentTheme {
|
|
12
|
+
/** 部署还没有记录时为 null;调用方落到框架默认方案。 */
|
|
13
|
+
state: StoredTheme | null;
|
|
14
|
+
/** 文件在但读不成 JSON 时的原因。此时 state 为 null,下一次保存会覆盖它。 */
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function readDeploymentTheme(botDir: string): DeploymentTheme {
|
|
19
|
+
const file = join(botDir, THEME_FILE);
|
|
20
|
+
if (!existsSync(file)) return { state: null };
|
|
21
|
+
try {
|
|
22
|
+
return { state: normalizeStoredTheme(JSON.parse(readFileSync(file, 'utf8')) as unknown) };
|
|
23
|
+
} catch (err) {
|
|
24
|
+
return { state: null, error: err instanceof Error ? err.message : String(err) };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** 规范化后整份替换,返回真正写进去的记录。 */
|
|
29
|
+
export function writeDeploymentTheme(botDir: string, value: unknown): StoredTheme {
|
|
30
|
+
const state = normalizeStoredTheme(value);
|
|
31
|
+
const file = join(botDir, THEME_FILE);
|
|
32
|
+
const temporary = join(botDir, `.${THEME_FILE}.${process.pid}.tmp`);
|
|
33
|
+
writeFileSync(temporary, JSON.stringify(state, null, 2) + '\n', 'utf8');
|
|
34
|
+
rmSync(file, { force: true });
|
|
35
|
+
renameSync(temporary, file);
|
|
36
|
+
return state;
|
|
37
|
+
}
|