@harness-mix/cli 0.1.8 → 0.1.10

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 (156) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/NOTICE +12 -0
  3. package/README.md +74 -71
  4. package/docs/harness-management.md +1 -1
  5. package/docs/native-acp.md +7 -2
  6. package/docs/task-handoff-design.md +65 -0
  7. package/licenses/codex-styler-Apache-2.0.txt +193 -0
  8. package/licenses/heige-codex-skin-studio-MIT.txt +22 -0
  9. package/output/native-build/desktop-controller.mjs +3 -2
  10. package/output/native-build/renderer-extension.js +1350 -46
  11. package/package.json +189 -188
  12. package/scripts/acp-capabilities-probe.cjs +1 -0
  13. package/scripts/build-native.cjs +1 -1
  14. package/scripts/codex-adapter-test.cjs +44 -0
  15. package/scripts/collaboration-recovery-test.cjs +3 -0
  16. package/scripts/e2e-codex.cjs +3 -1
  17. package/scripts/e2e-native-acp.cjs +1 -1
  18. package/scripts/error-kind-test.cjs +107 -0
  19. package/scripts/handoff-checkpoint-test.cjs +38 -0
  20. package/scripts/integrations-test.cjs +5 -2
  21. package/scripts/kiro-cursor-adapters-test.cjs +18 -0
  22. package/scripts/native-acp-depth-test.cjs +1 -1
  23. package/scripts/native-config-test.cjs +32 -2
  24. package/scripts/native-protocol-test.cjs +60 -4
  25. package/scripts/native-ui-smoke.cjs +127 -2
  26. package/scripts/pets-test.cjs +146 -0
  27. package/scripts/switch-harness-test.cjs +79 -12
  28. package/scripts/tool-concurrency-regression-test.cjs +8 -6
  29. package/src/assets/icons/cline-color.svg +1 -0
  30. package/src/assets/skins/codex-styler/ASSET_LICENSES.md +36 -0
  31. package/src/assets/skins/codex-styler/NOTICE +11 -0
  32. package/src/assets/skins/codex-styler/themes/gilded-grandeur/hero.webp +0 -0
  33. package/src/assets/skins/codex-styler/themes/merry-big-top/hero.webp +0 -0
  34. package/src/assets/skins/codex-styler/themes/nocturne-studio/hero.webp +0 -0
  35. package/src/assets/skins/codex-styler/themes/quiet-garden/hero.webp +0 -0
  36. package/src/assets/skins/heige/ASSET_PROVENANCE.md +56 -0
  37. package/src/assets/skins/heige/NOTICE.md +13 -0
  38. package/src/assets/skins/heige/themes/dalao-dianyan/hero.webp +0 -0
  39. package/src/assets/skins/heige/themes/dalao-dianyan/theme.json +14 -0
  40. package/src/assets/skins/heige/themes/deepspace-dawn/hero.webp +0 -0
  41. package/src/assets/skins/heige/themes/deepspace-dawn/theme.json +14 -0
  42. package/src/assets/skins/heige/themes/deepspace-star/hero.webp +0 -0
  43. package/src/assets/skins/heige/themes/deepspace-star/theme.json +14 -0
  44. package/src/assets/skins/heige/themes/dragonball-nimbus/hero.webp +0 -0
  45. package/src/assets/skins/heige/themes/dragonball-nimbus/theme.json +16 -0
  46. package/src/assets/skins/heige/themes/dragonball-super-saiyan/hero.webp +0 -0
  47. package/src/assets/skins/heige/themes/dragonball-super-saiyan/theme.json +16 -0
  48. package/src/assets/skins/heige/themes/genshin-dawn/hero.webp +0 -0
  49. package/src/assets/skins/heige/themes/genshin-dawn/theme.json +14 -0
  50. package/src/assets/skins/heige/themes/genshin-night/hero.webp +0 -0
  51. package/src/assets/skins/heige/themes/genshin-night/theme.json +14 -0
  52. package/src/assets/skins/heige/themes/miku-488137/hero.webp +0 -0
  53. package/src/assets/skins/heige/themes/miku-488137/logo.webp +0 -0
  54. package/src/assets/skins/heige/themes/miku-488137/polaroid.webp +0 -0
  55. package/src/assets/skins/heige/themes/miku-488137/theme.json +16 -0
  56. package/src/assets/skins/heige/themes/naruto-hokage/hero.webp +0 -0
  57. package/src/assets/skins/heige/themes/naruto-hokage/theme.json +14 -0
  58. package/src/assets/skins/heige/themes/naruto-sasuke/hero.webp +0 -0
  59. package/src/assets/skins/heige/themes/naruto-sasuke/theme.json +14 -0
  60. package/src/assets/skins/heige/themes/wuthering-echo/hero.webp +0 -0
  61. package/src/assets/skins/heige/themes/wuthering-echo/theme.json +14 -0
  62. package/src/assets/skins/heige/themes/wuthering-tide/hero.webp +0 -0
  63. package/src/assets/skins/heige/themes/wuthering-tide/theme.json +14 -0
  64. package/src/main/adapters/cline.js +22 -0
  65. package/src/main/adapters/codex.js +78 -8
  66. package/src/main/adapters/index.js +2 -1
  67. package/src/main/adapters/native-acp-command.js +1 -0
  68. package/src/main/harness-adapter/error-kind.js +82 -0
  69. package/src/main/harness-adapter/event-normalizer.js +7 -1
  70. package/src/main/host/core-session.js +1 -1
  71. package/src/main/host/handoff-access.js +23 -4
  72. package/src/main/host/handoff-checkpoints.js +9 -2
  73. package/src/main/host/handoff-tools.js +3 -0
  74. package/src/main/host/handoff.js +11 -2
  75. package/src/main/host/runtime.js +272 -163
  76. package/src/main/host/session-history.js +54 -15
  77. package/src/main/native/icons.js +3 -2
  78. package/src/main/native/launcher.js +49 -2
  79. package/src/main/native/pets.js +395 -0
  80. package/src/main/native/protocol.js +197 -55
  81. package/src/main/protocol-core/projector.js +44 -41
  82. package/src/native-ui/desktop-control/dist/production-controller.d.ts.map +1 -1
  83. package/src/native-ui/desktop-control/dist/production-controller.js +1 -0
  84. package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -1
  85. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +4 -4
  86. package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -1
  87. package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -1
  88. package/src/native-ui/desktop-control/src/production-controller.ts +1 -0
  89. package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +4 -4
  90. package/src/native-ui/desktop-control/test/production-controller.test.ts +1 -0
  91. package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +7 -0
  92. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +5 -2
  93. package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -1
  94. package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts.map +1 -1
  95. package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -1
  96. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +1 -0
  97. package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -1
  98. package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -1
  99. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +2 -0
  100. package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -1
  101. package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts +2 -1
  102. package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts.map +1 -1
  103. package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -1
  104. package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -1
  105. package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts +1 -1
  106. package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts.map +1 -1
  107. package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts.map +1 -1
  108. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +5 -3
  109. package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -1
  110. package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts +5 -0
  111. package/src/native-ui/renderer-extension/dist/types/settings/pet-market.d.ts.map +1 -0
  112. package/src/native-ui/renderer-extension/dist/types/settings/pets-client.d.ts +57 -0
  113. package/src/native-ui/renderer-extension/dist/types/settings/pets-client.d.ts.map +1 -0
  114. package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -1
  115. package/src/native-ui/renderer-extension/dist/types/settings/skin-market.d.ts +4 -0
  116. package/src/native-ui/renderer-extension/dist/types/settings/skin-market.d.ts.map +1 -0
  117. package/src/native-ui/renderer-extension/dist/types/settings/skin-runtime.d.ts +31 -0
  118. package/src/native-ui/renderer-extension/dist/types/settings/skin-runtime.d.ts.map +1 -0
  119. package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -1
  120. package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -1
  121. package/src/native-ui/renderer-extension/package.json +1 -1
  122. package/src/native-ui/renderer-extension/src/agent-selection-state.ts +61 -14
  123. package/src/native-ui/renderer-extension/src/assets.d.ts +5 -0
  124. package/src/native-ui/renderer-extension/src/renderer-agent-icon.ts +5 -4
  125. package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +1 -0
  126. package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +78 -33
  127. package/src/native-ui/renderer-extension/src/renderer-harness-handoff.ts +2 -2
  128. package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +2 -0
  129. package/src/native-ui/renderer-extension/src/renderer-model-client.ts +6 -0
  130. package/src/native-ui/renderer-extension/src/renderer-settings-lifecycle.ts +5 -0
  131. package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +1 -0
  132. package/src/native-ui/renderer-extension/src/settings/connections-page.ts +2 -0
  133. package/src/native-ui/renderer-extension/src/settings/icons.ts +15 -6
  134. package/src/native-ui/renderer-extension/src/settings/localization.ts +6 -2
  135. package/src/native-ui/renderer-extension/src/settings/pages.ts +72 -61
  136. package/src/native-ui/renderer-extension/src/settings/pet-market.css +310 -0
  137. package/src/native-ui/renderer-extension/src/settings/pet-market.ts +447 -0
  138. package/src/native-ui/renderer-extension/src/settings/pets-client.ts +74 -0
  139. package/src/native-ui/renderer-extension/src/settings/shell.css +27 -8
  140. package/src/native-ui/renderer-extension/src/settings/shell.ts +3 -1
  141. package/src/native-ui/renderer-extension/src/settings/skin-market.css +213 -0
  142. package/src/native-ui/renderer-extension/src/settings/skin-market.ts +174 -0
  143. package/src/native-ui/renderer-extension/src/settings/skin-runtime.ts +630 -0
  144. package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +2 -1
  145. package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +58 -0
  146. package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +12 -0
  147. package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +1 -0
  148. package/src/native-ui/renderer-extension/test/settings/localization.test.ts +12 -1
  149. package/src/native-ui/renderer-extension/test/settings/shell.test.ts +6 -0
  150. package/src/native-ui/renderer-extension/test/settings/skin-runtime.test.ts +162 -0
  151. package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts +7 -0
  152. package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts.map +1 -1
  153. package/src/native-ui/shared-contracts/dist/thread-harness-switch.js +3 -0
  154. package/src/native-ui/shared-contracts/dist/thread-harness-switch.js.map +1 -1
  155. package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -1
  156. package/src/native-ui/shared-contracts/src/thread-harness-switch.ts +3 -0
@@ -0,0 +1,630 @@
1
+ import dalaoDianyanHero from "../../../../assets/skins/heige/themes/dalao-dianyan/hero.webp";
2
+ import deepspaceDawnHero from "../../../../assets/skins/heige/themes/deepspace-dawn/hero.webp";
3
+ import deepspaceStarHero from "../../../../assets/skins/heige/themes/deepspace-star/hero.webp";
4
+ import dragonballNimbusHero from "../../../../assets/skins/heige/themes/dragonball-nimbus/hero.webp";
5
+ import dragonballSuperSaiyanHero from "../../../../assets/skins/heige/themes/dragonball-super-saiyan/hero.webp";
6
+ import genshinDawnHero from "../../../../assets/skins/heige/themes/genshin-dawn/hero.webp";
7
+ import genshinNightHero from "../../../../assets/skins/heige/themes/genshin-night/hero.webp";
8
+ import mikuHero from "../../../../assets/skins/heige/themes/miku-488137/hero.webp";
9
+ import mikuLogo from "../../../../assets/skins/heige/themes/miku-488137/logo.webp";
10
+ import mikuPolaroid from "../../../../assets/skins/heige/themes/miku-488137/polaroid.webp";
11
+ import narutoHokageHero from "../../../../assets/skins/heige/themes/naruto-hokage/hero.webp";
12
+ import narutoSasukeHero from "../../../../assets/skins/heige/themes/naruto-sasuke/hero.webp";
13
+ import wutheringEchoHero from "../../../../assets/skins/heige/themes/wuthering-echo/hero.webp";
14
+ import wutheringTideHero from "../../../../assets/skins/heige/themes/wuthering-tide/hero.webp";
15
+ import gildedGrandeurHero from "../../../../assets/skins/codex-styler/themes/gilded-grandeur/hero.webp";
16
+ import merryBigTopHero from "../../../../assets/skins/codex-styler/themes/merry-big-top/hero.webp";
17
+ import nocturneStudioHero from "../../../../assets/skins/codex-styler/themes/nocturne-studio/hero.webp";
18
+ import quietGardenHero from "../../../../assets/skins/codex-styler/themes/quiet-garden/hero.webp";
19
+
20
+ export const RENDERER_SKIN_STORAGE_KEY = "harness-mix.renderer-skin.v1";
21
+ export const RENDERER_SKIN_STYLE_ID = "harness-mix-renderer-skin";
22
+ export const RENDERER_SKIN_ATTRIBUTE = "data-harness-mix-skin";
23
+
24
+ export const RENDERER_SKIN_IDS = [
25
+ "native", "miku-488137", "genshin-dawn", "genshin-night", "wuthering-echo",
26
+ "wuthering-tide", "naruto-hokage", "naruto-sasuke", "deepspace-dawn",
27
+ "deepspace-star", "dragonball-nimbus", "dragonball-super-saiyan", "dalao-dianyan",
28
+ "styler-gilded-grandeur", "styler-merry-big-top", "styler-nocturne-studio",
29
+ "styler-quiet-garden",
30
+ ] as const;
31
+
32
+ export type RendererSkinId = (typeof RENDERER_SKIN_IDS)[number];
33
+
34
+ export interface RendererSkinDefinition {
35
+ readonly id: RendererSkinId;
36
+ readonly name: string;
37
+ readonly sourceName: string;
38
+ readonly sourceUrl: string | null;
39
+ readonly heroUrl: string | null;
40
+ readonly logoUrl: string | null;
41
+ readonly polaroidUrl: string | null;
42
+ readonly palette: readonly [surface: string, secondary: string, accent: string, text: string];
43
+ readonly preview: string;
44
+ readonly focus: string;
45
+ readonly dark: boolean;
46
+ }
47
+
48
+ const HEIGE_SOURCE_URL = "https://github.com/HeiGeAi/heige-codex-skin-studio";
49
+ const CODEX_STYLER_SOURCE_URL = "https://github.com/xuhuanstudio/codex-styler";
50
+
51
+ function heigeSkin(
52
+ id: Exclude<RendererSkinId, "native">,
53
+ name: string,
54
+ heroUrl: string,
55
+ palette: RendererSkinDefinition["palette"],
56
+ focus: string,
57
+ dark: boolean,
58
+ decorations: Pick<RendererSkinDefinition, "logoUrl" | "polaroidUrl"> = {
59
+ logoUrl: null,
60
+ polaroidUrl: null,
61
+ },
62
+ ): RendererSkinDefinition {
63
+ return Object.freeze({
64
+ id, name, heroUrl, palette, focus, dark, ...decorations,
65
+ sourceName: "HeiGe Codex Skin Studio",
66
+ sourceUrl: HEIGE_SOURCE_URL,
67
+ preview: `linear-gradient(${dark ? "rgb(3 7 12 / 16%)" : "rgb(255 255 255 / 8%)"}, transparent)`,
68
+ });
69
+ }
70
+
71
+ function codexStylerSkin(
72
+ id: Exclude<RendererSkinId, "native">,
73
+ name: string,
74
+ heroUrl: string,
75
+ palette: RendererSkinDefinition["palette"],
76
+ focus: string,
77
+ ): RendererSkinDefinition {
78
+ return Object.freeze({
79
+ id, name, heroUrl, logoUrl: null, polaroidUrl: null, palette, focus, dark: true,
80
+ sourceName: "Codex Styler · CC BY 4.0",
81
+ sourceUrl: CODEX_STYLER_SOURCE_URL,
82
+ preview: "linear-gradient(rgb(3 7 12 / 16%), transparent)",
83
+ });
84
+ }
85
+
86
+ export const RENDERER_SKINS: readonly RendererSkinDefinition[] = Object.freeze([
87
+ Object.freeze({
88
+ id: "native", name: "Native Codex", sourceName: "OpenAI Codex", sourceUrl: null,
89
+ heroUrl: null, logoUrl: null, polaroidUrl: null,
90
+ palette: ["#f7f7f7", "#d7d7d7", "#171717", "#171717"] as const,
91
+ preview: "linear-gradient(145deg, #f8f8f8 0 58%, #ececec 58% 100%)",
92
+ focus: "50% 50%", dark: false,
93
+ }),
94
+ heigeSkin(
95
+ "miku-488137",
96
+ "Miku 488137",
97
+ mikuHero,
98
+ ["#f5f6fc", "#ed6ec1", "#19c9e5", "#122c60"],
99
+ "50% 33%",
100
+ false,
101
+ { logoUrl: mikuLogo, polaroidUrl: mikuPolaroid },
102
+ ),
103
+ heigeSkin("genshin-dawn", "原神 · 晨曦", genshinDawnHero, ["#f2f1fb", "#e0aa3e", "#5b7fd6", "#2c3a6b"], "50% 24%", false),
104
+ heigeSkin("genshin-night", "原神 · 星夜", genshinNightHero, ["#171a2e", "#7a86d8", "#e0b458", "#f0e6c8"], "50% 17%", true),
105
+ heigeSkin("wuthering-echo", "鸣潮 · 共鸣", wutheringEchoHero, ["#16121f", "#a98fe8", "#56e0d8", "#e4def2"], "50% 27%", true),
106
+ heigeSkin("wuthering-tide", "鸣潮 · 声骸", wutheringTideHero, ["#0d1418", "#9aa8b0", "#3fd6d0", "#d8eef0"], "50% 30%", true),
107
+ heigeSkin("naruto-hokage", "火影 · 鸣人", narutoHokageHero, ["#17110b", "#ffd166", "#f2801e", "#ffe3c2"], "50% 27%", true),
108
+ heigeSkin("naruto-sasuke", "火影 · 佐助", narutoSasukeHero, ["#171019", "#7fb3ff", "#d8443c", "#ffd9d2"], "50% 24%", true),
109
+ heigeSkin("deepspace-dawn", "恋与深空 · 晨曦", deepspaceDawnHero, ["#f6f2fb", "#f097c8", "#8f7fe8", "#4a4668"], "50% 8%", false),
110
+ heigeSkin("deepspace-star", "恋与深空 · 星辰", deepspaceStarHero, ["#201a40", "#f097c8", "#9d8bff", "#e8e2ff"], "50% 8%", true),
111
+ heigeSkin("dragonball-nimbus", "龙珠 · 筋斗云", dragonballNimbusHero, ["#f3f7ff", "#f6c445", "#4fc3f7", "#14213d"], "72% 24%", false),
112
+ heigeSkin("dragonball-super-saiyan", "龙珠 · 超级赛亚人", dragonballSuperSaiyanHero, ["#fff8e8", "#52c7f2", "#f5c451", "#282033"], "67% 3%", false),
113
+ heigeSkin("dalao-dianyan", "大佬 · 点烟", dalaoDianyanHero, ["#111111", "#9aa3b0", "#e09a52", "#f2e8da"], "50% 8%", true),
114
+ codexStylerSkin("styler-gilded-grandeur", "金辉盛境", gildedGrandeurHero, ["#090704", "#5b4721", "#e8bd55", "#fff2cd"], "54% 48%"),
115
+ codexStylerSkin("styler-merry-big-top", "欢乐大帐篷", merryBigTopHero, ["#100b14", "#5a3d4b", "#ff755e", "#fff2dc"], "55% 48%"),
116
+ codexStylerSkin("styler-nocturne-studio", "夜曲工作室", nocturneStudioHero, ["#090b0d", "#34383a", "#e9a066", "#f5efe6"], "58% 46%"),
117
+ codexStylerSkin("styler-quiet-garden", "静谧花园", quietGardenHero, ["#101612", "#364339", "#9fc29a", "#edf2e8"], "52% 50%"),
118
+ ]);
119
+
120
+ interface RendererSkinStorage {
121
+ getItem(key: string): string | null;
122
+ setItem(key: string, value: string): void;
123
+ removeItem(key: string): void;
124
+ }
125
+
126
+ function documentSkinStorage(ownerDocument: Document): RendererSkinStorage | null {
127
+ try { return ownerDocument.defaultView?.localStorage ?? null; } catch { return null; }
128
+ }
129
+
130
+ function isRendererSkinId(value: string | null): value is RendererSkinId {
131
+ return (RENDERER_SKIN_IDS as readonly string[]).includes(value ?? "");
132
+ }
133
+
134
+ export function rendererSkinDefinition(id: RendererSkinId): RendererSkinDefinition {
135
+ return RENDERER_SKINS.find((skin) => skin.id === id) ?? RENDERER_SKINS[0]!;
136
+ }
137
+
138
+ export function readRendererSkin(storage?: RendererSkinStorage | null): RendererSkinId {
139
+ try {
140
+ const stored = storage?.getItem(RENDERER_SKIN_STORAGE_KEY) ?? null;
141
+ return isRendererSkinId(stored) ? stored : "native";
142
+ } catch { return "native"; }
143
+ }
144
+
145
+ export function readActiveRendererSkin(ownerDocument: Document = document): RendererSkinId {
146
+ const active = ownerDocument.documentElement.getAttribute(RENDERER_SKIN_ATTRIBUTE);
147
+ return isRendererSkinId(active) ? active : readRendererSkin(documentSkinStorage(ownerDocument));
148
+ }
149
+
150
+ function skinCss(skin: RendererSkinDefinition): string {
151
+ const [surface, secondary, accent, text] = skin.palette;
152
+ const image = skin.heroUrl ? `url("${skin.heroUrl}")` : skin.preview;
153
+ const sidebarVeil = skin.dark
154
+ ? `color-mix(in srgb, ${surface} 91%, transparent)`
155
+ : `color-mix(in srgb, ${surface} 88%, transparent)`;
156
+ const lowerVeil = skin.dark
157
+ ? `color-mix(in srgb, ${surface} 68%, transparent)`
158
+ : `color-mix(in srgb, ${surface} 72%, transparent)`;
159
+ const panelOpacity = skin.dark ? "84%" : "82%";
160
+ const secondaryText = `color-mix(in srgb, ${text} 72%, transparent)`;
161
+ const tertiaryText = `color-mix(in srgb, ${text} 54%, transparent)`;
162
+ const logoCss = skin.logoUrl ? `
163
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] .app-shell-left-panel button[aria-haspopup="menu"][aria-label*="ChatGPT"],
164
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] .app-shell-left-panel button[aria-haspopup="menu"][aria-label*="Codex"] {
165
+ width: min(214px, calc(100% - 12px)); height: 72px !important; margin: 4px 6px 0;
166
+ background: url("${skin.logoUrl}") left center / contain no-repeat !important;
167
+ }
168
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] .app-shell-left-panel button[aria-haspopup="menu"][aria-label*="ChatGPT"] > :where(span, svg),
169
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] .app-shell-left-panel button[aria-haspopup="menu"][aria-label*="Codex"] > :where(span, svg) { visibility: hidden !important; }
170
+ ` : "";
171
+ const polaroidCss = skin.polaroidUrl ? `
172
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] body::after {
173
+ content: ""; position: fixed; right: clamp(12px, 2vw, 24px); bottom: clamp(72px, 11vh, 108px);
174
+ width: clamp(108px, 11.5vw, 168px); aspect-ratio: 2 / 3;
175
+ background: url("${skin.polaroidUrl}") center / contain no-repeat;
176
+ filter: drop-shadow(0 12px 26px color-mix(in srgb, ${text} 24%, transparent));
177
+ pointer-events: none; z-index: 15;
178
+ }
179
+ @media (max-width: 760px) {
180
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] body::after { display: none; }
181
+ }
182
+ ` : "";
183
+ return `
184
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] {
185
+ color-scheme: ${skin.dark ? "dark" : "light"};
186
+ --codex-titlebar-tint: transparent !important;
187
+ --header-tint: transparent !important;
188
+ --color-text: ${text}; --color-text-primary: ${text}; --color-token-text-primary: ${text};
189
+ --color-token-foreground: ${text}; --color-text-prose: ${text}; --color-text-emphasis: ${text};
190
+ --color-text-primary-surface: ${text}; --color-text-primary-soft: ${text};
191
+ --color-text-primary-soft-alt: ${text}; --color-text-primary-ghost: ${text};
192
+ --color-text-primary-ghost-hover: ${text}; --color-text-primary-outline: ${text};
193
+ --color-text-primary-outline-hover: ${text};
194
+ --color-text-secondary: ${secondaryText}; --color-token-text-secondary: ${secondaryText};
195
+ --color-text-secondary-soft: ${secondaryText}; --color-text-secondary-soft-alt: ${secondaryText};
196
+ --color-text-secondary-ghost: ${secondaryText}; --color-text-secondary-ghost-hover: ${text};
197
+ --color-text-secondary-outline: ${secondaryText}; --color-text-secondary-outline-hover: ${text};
198
+ --color-text-secondary-solid: ${secondaryText};
199
+ --color-text-tertiary: ${tertiaryText}; --color-token-text-tertiary: ${tertiaryText};
200
+ --color-token-description-foreground: ${tertiaryText};
201
+ --color-token-dropdown-foreground: ${text};
202
+ --app-color-text-foreground: ${text}; --app-color-text-foreground-secondary: ${secondaryText};
203
+ --app-color-text-foreground-tertiary: ${tertiaryText};
204
+ --app-color-foreground-application-menu: ${text};
205
+ --app-color-text-button-secondary: ${text}; --app-color-text-button-tertiary: ${tertiaryText};
206
+ --wb-text-primary: ${text}; --wb-text-secondary: ${secondaryText}; --wb-text-tertiary: ${tertiaryText};
207
+ --color-control-thumb-foreground: ${text};
208
+ --color-text-mode-toggle-inactive: ${secondaryText};
209
+ --color-text-user-message: ${text} !important;
210
+ --color-surface: color-mix(in srgb, ${surface} 92%, transparent);
211
+ --color-surface-secondary: color-mix(in srgb, ${surface} 88%, transparent);
212
+ --color-surface-tertiary: color-mix(in srgb, ${surface} 94%, transparent);
213
+ --color-surface-elevated: color-mix(in srgb, ${surface} 96%, transparent);
214
+ --color-surface-elevated-secondary: color-mix(in srgb, ${surface} 96%, transparent);
215
+ --color-background-surface: color-mix(in srgb, ${surface} 90%, transparent);
216
+ --color-background-panel: color-mix(in srgb, ${surface} 94%, transparent);
217
+ --color-background-callout-surface: color-mix(in srgb, ${surface} 94%, transparent);
218
+ --color-background-control-opaque: ${surface};
219
+ --color-background-page-search: color-mix(in srgb, ${surface} 92%, transparent);
220
+ --color-background-composer-action-bar: color-mix(in srgb, ${surface} 88%, transparent);
221
+ --color-background-execution-output: color-mix(in srgb, ${surface} 88%, transparent);
222
+ --color-background-primary-soft: color-mix(in srgb, ${surface} 92%, transparent);
223
+ --color-background-primary-soft-alpha: color-mix(in srgb, ${surface} 88%, transparent);
224
+ --color-background-primary-soft-hover: color-mix(in srgb, ${surface} 80%, ${accent});
225
+ --color-background-primary-soft-active: color-mix(in srgb, ${surface} 72%, ${accent});
226
+ --color-background-primary-ghost-hover: color-mix(in srgb, ${text} 8%, transparent);
227
+ --color-background-secondary-soft: color-mix(in srgb, ${text} 7%, transparent);
228
+ --color-background-secondary-soft-alpha: color-mix(in srgb, ${text} 7%, transparent);
229
+ --color-background-secondary-soft-hover: color-mix(in srgb, ${text} 11%, transparent);
230
+ --color-background-other-user-message: color-mix(in srgb, ${surface} 76%, transparent);
231
+ --color-background-user-message: color-mix(in srgb, ${surface} 92%, transparent) !important;
232
+ --color-background-user-message-compact: color-mix(in srgb, ${surface} 88%, transparent);
233
+ --color-border: color-mix(in srgb, ${text} 16%, transparent);
234
+ --color-border-subtle: color-mix(in srgb, ${text} 8%, transparent);
235
+ --color-border-strong: color-mix(in srgb, ${text} 20%, transparent);
236
+ --color-token-main-surface-primary: color-mix(in srgb, ${surface} 92%, transparent);
237
+ --color-token-dropdown-background: color-mix(in srgb, ${surface} 96%, transparent);
238
+ --color-token-list-hover-background: color-mix(in srgb, ${text} 8%, transparent);
239
+ --color-token-border: color-mix(in srgb, ${text} 16%, transparent);
240
+ --color-token-border-default: color-mix(in srgb, ${text} 16%, transparent);
241
+ --color-token-border-light: color-mix(in srgb, ${text} 9%, transparent);
242
+ --color-token-border-heavy: color-mix(in srgb, ${text} 22%, transparent);
243
+ --color-token-input-border: color-mix(in srgb, ${text} 20%, transparent);
244
+ --color-codex-diff-surface: color-mix(in srgb, ${surface} 94%, ${text});
245
+ --color-token-diff-surface: color-mix(in srgb, ${surface} 94%, ${text});
246
+ --color-codex-editor-inline-code-background: color-mix(in srgb, ${surface} 92%, transparent);
247
+ --color-codex-terminal-background: ${surface};
248
+ --codex-base-surface: ${surface};
249
+ --app-color-background-surface: color-mix(in srgb, ${surface} 92%, transparent);
250
+ --app-color-background-surface-under: color-mix(in srgb, ${surface} 88%, transparent);
251
+ --app-color-background-control: color-mix(in srgb, ${surface} 96%, transparent);
252
+ --app-color-background-elevated-primary: color-mix(in srgb, ${surface} 96%, transparent);
253
+ --app-color-background-elevated-primary-opaque: ${surface};
254
+ --app-color-background-elevated-secondary: color-mix(in srgb, ${surface} 96%, transparent);
255
+ --app-color-background-elevated-secondary-opaque: ${surface};
256
+ --app-color-background-editor-opaque: ${surface};
257
+ --app-color-background-application-menu: color-mix(in srgb, ${surface} 96%, transparent);
258
+ --app-color-background-button-secondary: color-mix(in srgb, ${text} 7%, transparent);
259
+ --app-color-background-button-secondary-hover: color-mix(in srgb, ${text} 11%, transparent);
260
+ --app-color-border: color-mix(in srgb, ${text} 16%, transparent);
261
+ --app-color-border-light: color-mix(in srgb, ${text} 9%, transparent);
262
+ --app-color-border-heavy: color-mix(in srgb, ${text} 22%, transparent);
263
+ --wb-surface-primary: color-mix(in srgb, ${surface} 92%, transparent);
264
+ --wb-surface-secondary: color-mix(in srgb, ${surface} 88%, transparent);
265
+ --wb-border: color-mix(in srgb, ${text} 16%, transparent);
266
+ --wb-border-hover: color-mix(in srgb, ${text} 22%, transparent);
267
+ --vscode-foreground: ${text}; --vscode-descriptionForeground: ${secondaryText};
268
+ --vscode-editor-foreground: ${text}; --vscode-input-foreground: ${text};
269
+ --vscode-editor-background: ${surface}; --vscode-editorPane-background: ${surface};
270
+ --vscode-input-background: color-mix(in srgb, ${surface} 96%, transparent);
271
+ --vscode-dropdown-background: color-mix(in srgb, ${surface} 96%, transparent);
272
+ --vscode-menu-background: color-mix(in srgb, ${surface} 96%, transparent);
273
+ --vscode-panel-background: color-mix(in srgb, ${surface} 96%, transparent);
274
+ --vscode-terminal-background: ${surface};
275
+ --vscode-list-hoverBackground: color-mix(in srgb, ${text} 8%, transparent);
276
+ --vscode-list-activeSelectionBackground: color-mix(in srgb, ${accent} 24%, transparent);
277
+ --vscode-list-activeSelectionForeground: ${text};
278
+ --vscode-list-inactiveSelectionBackground: color-mix(in srgb, ${accent} 16%, transparent);
279
+ --vscode-list-inactiveSelectionForeground: ${text};
280
+ --background: color-mix(in srgb, ${surface} ${panelOpacity}, transparent);
281
+ --foreground: ${text}; --card: color-mix(in srgb, ${surface} 88%, transparent);
282
+ --card-foreground: ${text}; --popover: color-mix(in srgb, ${surface} 94%, transparent);
283
+ --popover-foreground: ${text}; --primary: ${accent}; --primary-foreground: ${surface};
284
+ --secondary: color-mix(in srgb, ${surface} 82%, ${secondary}); --secondary-foreground: ${text};
285
+ --muted: color-mix(in srgb, ${surface} 88%, ${secondary});
286
+ --muted-foreground: color-mix(in srgb, ${text} 68%, ${surface});
287
+ --accent: color-mix(in srgb, ${surface} 74%, ${accent}); --accent-foreground: ${text};
288
+ --border: color-mix(in srgb, ${text} 16%, transparent); --input: color-mix(in srgb, ${text} 18%, transparent); --ring: ${accent};
289
+ --sidebar: color-mix(in srgb, ${surface} 88%, transparent); --sidebar-background: color-mix(in srgb, ${surface} 88%, transparent);
290
+ --sidebar-foreground: ${text}; --sidebar-primary: ${accent}; --sidebar-primary-foreground: ${surface};
291
+ --sidebar-accent: color-mix(in srgb, ${surface} 74%, ${accent}); --sidebar-accent-foreground: ${text};
292
+ --sidebar-border: color-mix(in srgb, ${text} 14%, transparent); --sidebar-ring: ${accent};
293
+ --main-surface-primary: color-mix(in srgb, ${surface} 84%, transparent);
294
+ --main-surface-secondary: color-mix(in srgb, ${surface} 72%, transparent);
295
+ --sidebar-surface-primary: color-mix(in srgb, ${surface} 88%, transparent);
296
+ --sidebar-surface-secondary: color-mix(in srgb, ${surface} 76%, transparent);
297
+ --message-surface: color-mix(in srgb, ${surface} 82%, transparent);
298
+ --composer-surface: color-mix(in srgb, ${surface} 88%, transparent);
299
+ }
300
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] body {
301
+ color: ${text}; background: ${surface} !important;
302
+ }
303
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] body > #root {
304
+ min-height: 100vh; color: ${text} !important;
305
+ background-color: transparent !important;
306
+ background-image:
307
+ linear-gradient(90deg, ${sidebarVeil} 0 22%, transparent 46%),
308
+ linear-gradient(180deg, transparent 0 43%, ${lowerVeil} 100%),
309
+ ${image} !important;
310
+ background-position: left top, left top, ${skin.focus} !important;
311
+ background-repeat: no-repeat !important;
312
+ background-size: 100% 100%, 100% 100%, cover !important;
313
+ }
314
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
315
+ .main-surface,
316
+ .browser-main-surface,
317
+ [data-app-shell-main-surface="default"],
318
+ main[class*="_MainContentSurface_"]
319
+ ) {
320
+ background: linear-gradient(180deg, transparent 0 40%, color-mix(in srgb, ${surface} 70%, transparent) 100%) !important;
321
+ }
322
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] .app-shell-left-panel {
323
+ background: color-mix(in srgb, ${surface} 88%, transparent) !important;
324
+ border-right-color: color-mix(in srgb, ${accent} 32%, transparent) !important;
325
+ backdrop-filter: none !important;
326
+ }
327
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(.bg-background, .bg-sidebar, .bg-card, .bg-token-main-surface-primary, .bg-token-sidebar-surface-primary) {
328
+ background: color-mix(in srgb, ${surface} ${panelOpacity}, transparent) !important;
329
+ }
330
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
331
+ [data-response-annotation-conversation],
332
+ [data-local-conversation-final-assistant]:not(:has([data-response-annotation-conversation]))
333
+ ) {
334
+ box-sizing: border-box;
335
+ color: ${text} !important;
336
+ background: color-mix(in srgb, ${surface} 96%, transparent) !important;
337
+ border: 1px solid color-mix(in srgb, ${accent} 16%, transparent) !important;
338
+ border-radius: 18px;
339
+ padding: 14px 16px 12px;
340
+ box-shadow: 0 8px 24px color-mix(in srgb, ${text} 8%, transparent) !important;
341
+ backdrop-filter: blur(16px) saturate(120%) !important;
342
+ }
343
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
344
+ table,
345
+ [data-markdown-table],
346
+ [data-markdown-table] > div,
347
+ .main-surface table,
348
+ main table,
349
+ article table,
350
+ [data-response-annotation-conversation] table
351
+ ) {
352
+ background-color: color-mix(in srgb, ${surface} 95%, transparent) !important;
353
+ backdrop-filter: blur(16px) saturate(120%) !important;
354
+ }
355
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
356
+ [data-markdown-table],
357
+ .main-surface table,
358
+ main table,
359
+ article table,
360
+ table
361
+ ) {
362
+ border: 1px solid color-mix(in srgb, ${accent} 24%, transparent) !important;
363
+ border-radius: 12px !important;
364
+ box-shadow: 0 4px 20px color-mix(in srgb, ${text} 8%, transparent) !important;
365
+ overflow: hidden !important;
366
+ }
367
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
368
+ table th,
369
+ [data-markdown-table] th,
370
+ [data-response-annotation-conversation] th
371
+ ) {
372
+ background-color: color-mix(in srgb, ${surface} 98%, transparent) !important;
373
+ border-bottom: 2px solid color-mix(in srgb, ${accent} 28%, transparent) !important;
374
+ color: ${text} !important;
375
+ font-weight: 600 !important;
376
+ padding: 8px 14px !important;
377
+ }
378
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
379
+ table td,
380
+ [data-markdown-table] td,
381
+ [data-response-annotation-conversation] td,
382
+ [data-response-annotation-conversation] :where(th, td)
383
+ ) {
384
+ border-bottom: 1px solid color-mix(in srgb, ${text} 12%, transparent) !important;
385
+ border-right: 1px solid color-mix(in srgb, ${text} 6%, transparent) !important;
386
+ color: ${text} !important;
387
+ padding: 8px 14px !important;
388
+ }
389
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
390
+ table tr:last-child td,
391
+ [data-markdown-table] tr:last-child td
392
+ ) {
393
+ border-bottom: none !important;
394
+ }
395
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
396
+ table tr:hover td,
397
+ [data-markdown-table] tr:hover td
398
+ ) {
399
+ background-color: color-mix(in srgb, ${accent} 10%, transparent) !important;
400
+ }
401
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(.composer-surface-chrome, [data-user-message-bubble], [data-codex-approval-surface]) {
402
+ color: ${text} !important;
403
+ background: color-mix(in srgb, ${surface} 92%, transparent) !important;
404
+ border-color: color-mix(in srgb, ${accent} 24%, transparent) !important;
405
+ box-shadow: 0 8px 24px color-mix(in srgb, ${accent} 12%, transparent) !important;
406
+ backdrop-filter: blur(16px) saturate(120%) !important;
407
+ }
408
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-user-message-bubble],
409
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-user-message-bubble] :where(
410
+ [data-markdown-text-tone="user-message"],
411
+ [data-markdown-han-text],
412
+ p,
413
+ span,
414
+ a,
415
+ code
416
+ ) {
417
+ color: ${text} !important;
418
+ }
419
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
420
+ header,
421
+ header > div,
422
+ [data-pip-obstacle="app-shell-header"],
423
+ [data-pip-obstacle="app-shell-header"] > div,
424
+ [class*="_ApplicationMenuTopBar_"],
425
+ [class*="_FloatingHeader_"],
426
+ [class*="_TitleBar_"],
427
+ [data-testid="app-shell-header-context-menu-surface"],
428
+ [data-app-shell-header-toolbar],
429
+ [data-app-shell-tab-row],
430
+ [data-app-shell-application-menu-bar]
431
+ ) {
432
+ background: transparent !important;
433
+ background-color: transparent !important;
434
+ border-color: transparent !important;
435
+ box-shadow: none !important;
436
+ }
437
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] header :where(.bg-surface, .bg-surface-secondary, .bg-surface-elevated):not([data-tab-id], [data-tab-id] *),
438
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-pip-obstacle="app-shell-header"] :where(.bg-surface, .bg-surface-secondary, .bg-surface-elevated):not([data-tab-id], [data-tab-id] *) {
439
+ background: transparent !important;
440
+ background-color: transparent !important;
441
+ }
442
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-main-content-top-fade] {
443
+ background: none !important;
444
+ background-image: none !important;
445
+ opacity: 0 !important;
446
+ }
447
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > div:first-child {
448
+ background: transparent !important;
449
+ background-color: transparent !important;
450
+ border: 0 !important;
451
+ border-radius: 0 !important;
452
+ box-shadow: none !important;
453
+ backdrop-filter: none !important;
454
+ color: color-mix(in srgb, ${text} 82%, ${accent}) !important;
455
+ font-size: 13px !important;
456
+ font-weight: 500 !important;
457
+ text-shadow: 0 1px 2px color-mix(in srgb, ${surface} 72%, transparent) !important;
458
+ }
459
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > div:first-child > div {
460
+ background: transparent !important;
461
+ background-color: transparent !important;
462
+ }
463
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > div:first-child button {
464
+ background: transparent !important;
465
+ background-color: transparent !important;
466
+ border-color: transparent !important;
467
+ box-shadow: none !important;
468
+ color: inherit !important;
469
+ font-size: inherit !important;
470
+ font-weight: inherit !important;
471
+ }
472
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] header button:not([data-codexhost-settings-trigger] *),
473
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-pip-obstacle="app-shell-header"] button:not([data-codexhost-settings-trigger] *),
474
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-obstacle] button:not([data-codexhost-settings-trigger] *),
475
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-testid="app-shell-header-context-menu-surface"] button:not([data-codexhost-settings-trigger] *),
476
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-toolbar] button:not([data-codexhost-settings-trigger] *),
477
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] header [role="button"]:not([data-codexhost-settings-trigger] *) {
478
+ background: transparent !important;
479
+ background-color: transparent !important;
480
+ border-color: transparent !important;
481
+ box-shadow: none !important;
482
+ }
483
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > button[aria-haspopup="menu"] {
484
+ color: color-mix(in srgb, ${text} 62%, transparent) !important;
485
+ background: transparent !important;
486
+ background-color: transparent !important;
487
+ border-color: transparent !important;
488
+ box-shadow: none !important;
489
+ filter: none !important;
490
+ outline: none !important;
491
+ }
492
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] header button:not([data-codexhost-settings-trigger] *):hover,
493
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-pip-obstacle="app-shell-header"] button:not([data-codexhost-settings-trigger] *):hover,
494
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-obstacle] button:not([data-codexhost-settings-trigger] *):hover,
495
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-testid="app-shell-header-context-menu-surface"] button:not([data-codexhost-settings-trigger] *):hover,
496
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-toolbar] button:not([data-codexhost-settings-trigger] *):hover {
497
+ background: color-mix(in srgb, ${text} 12%, transparent) !important;
498
+ background-color: color-mix(in srgb, ${text} 12%, transparent) !important;
499
+ }
500
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > button[aria-haspopup="menu"]:hover,
501
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > button[aria-haspopup="menu"]:focus-visible {
502
+ color: ${text} !important;
503
+ background: transparent !important;
504
+ background-color: transparent !important;
505
+ border-color: transparent !important;
506
+ box-shadow: none !important;
507
+ filter: none !important;
508
+ outline: none !important;
509
+ }
510
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] header button:not([data-codexhost-settings-trigger] *):active,
511
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-pip-obstacle="app-shell-header"] button:not([data-codexhost-settings-trigger] *):active,
512
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-obstacle] button:not([data-codexhost-settings-trigger] *):active,
513
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-testid="app-shell-header-context-menu-surface"] button:not([data-codexhost-settings-trigger] *):active,
514
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-header-toolbar] button:not([data-codexhost-settings-trigger] *):active {
515
+ background: color-mix(in srgb, ${text} 18%, transparent) !important;
516
+ background-color: color-mix(in srgb, ${text} 18%, transparent) !important;
517
+ }
518
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > button[aria-haspopup="menu"]:active,
519
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-shell-page-header] > [data-app-shell-header-toolbar] > button[aria-haspopup="menu"][data-state="open"] {
520
+ color: ${text} !important;
521
+ background: transparent !important;
522
+ background-color: transparent !important;
523
+ border-color: transparent !important;
524
+ box-shadow: none !important;
525
+ filter: none !important;
526
+ outline: none !important;
527
+ }
528
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(
529
+ [data-app-shell-tab-controller],
530
+ [data-app-shell-tab-controller] [data-tab-id],
531
+ .\@container\/app-shell-tab,
532
+ [data-tab-id].group\/tab,
533
+ .group\/tab[data-tab-id],
534
+ [data-tab-id],
535
+ [data-app-shell-tab-capture]
536
+ ) {
537
+ max-width: min(680px, 55vw) !important;
538
+ }
539
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-tab-id] :where([class*="max-w-"], [class*="min-w-0"]) {
540
+ max-width: none !important;
541
+ }
542
+ @media (min-width: 100rem) {
543
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] {
544
+ --thread-content-max-width: min(72rem, calc(100vw - 22rem));
545
+ }
546
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [class*="thread-content-max-width"] {
547
+ --thread-content-max-width: min(72rem, calc(100vw - 22rem)) !important;
548
+ }
549
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-local-conversation-final-assistant] {
550
+ max-width: min(72rem, calc(100vw - 22rem)) !important;
551
+ }
552
+ }
553
+ @container home-main-content (inline-size <= 52rem) {
554
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] div[role="main"]:has([data-composer-placement="home"]) [class*="_Hero_"] {
555
+ min-block-size: clamp(8.5rem, 28cqh, 12.5rem) !important;
556
+ flex-basis: auto !important;
557
+ padding-block: 0.75rem 1rem !important;
558
+ }
559
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] div[role="main"]:has([data-composer-placement="home"]) [data-feature="game-source"] {
560
+ padding-inline: 1rem;
561
+ font-size: clamp(1.35rem, 4cqw, 1.75rem) !important;
562
+ line-height: 1.22 !important;
563
+ }
564
+ }
565
+ @media (max-width: 68.75rem), (max-height: 47.5rem) {
566
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] div[role="main"]:has([data-composer-placement="home"]) [class*="_Hero_"] {
567
+ min-block-size: clamp(8.5rem, 28vh, 12.5rem) !important;
568
+ flex-basis: auto !important;
569
+ padding-block: 0.75rem 1rem !important;
570
+ }
571
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] div[role="main"]:has([data-composer-placement="home"]) [data-feature="game-source"] {
572
+ padding-inline: 1rem;
573
+ font-size: clamp(1.35rem, 3.2vw, 1.75rem) !important;
574
+ line-height: 1.22 !important;
575
+ }
576
+ }
577
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-app-action-sidebar-thread-active="true"] {
578
+ background: linear-gradient(90deg, color-mix(in srgb, ${accent} 22%, transparent), color-mix(in srgb, ${secondary} 16%, transparent)) !important;
579
+ }
580
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(.border-border, .border-sidebar-border) { border-color: color-mix(in srgb, ${text} 14%, transparent) !important; }
581
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] [data-codexhost-settings-shell] {
582
+ --settings-bg: color-mix(in srgb, ${surface} 90%, transparent);
583
+ --settings-sidebar: color-mix(in srgb, ${surface} 86%, ${secondary});
584
+ --settings-panel: color-mix(in srgb, ${surface} 90%, transparent);
585
+ --settings-surface: color-mix(in srgb, ${surface} 82%, ${secondary});
586
+ --settings-surface-hover: color-mix(in srgb, ${surface} 72%, ${accent});
587
+ --settings-inset: color-mix(in srgb, ${surface} 92%, ${secondary});
588
+ --settings-text: ${text}; --settings-muted: color-mix(in srgb, ${text} 68%, ${surface});
589
+ --settings-subtle: color-mix(in srgb, ${text} 52%, ${surface});
590
+ --settings-border: color-mix(in srgb, ${text} 14%, transparent); --settings-focus: ${accent};
591
+ --settings-primary: ${accent}; --settings-primary-hover: color-mix(in srgb, ${accent} 82%, white);
592
+ --settings-primary-text: ${surface};
593
+ }
594
+ ${logoCss}${polaroidCss}
595
+ @media (prefers-reduced-transparency: reduce) {
596
+ html[${RENDERER_SKIN_ATTRIBUTE}="${skin.id}"] :where(.app-shell-left-panel, [data-response-annotation-conversation], .composer-surface-chrome, [data-user-message-bubble], [data-codex-approval-surface]) {
597
+ background-color: ${surface} !important;
598
+ }
599
+ }`;
600
+ }
601
+
602
+ export function applyRendererSkin(
603
+ id: RendererSkinId,
604
+ ownerDocument: Document = document,
605
+ storage?: RendererSkinStorage | null,
606
+ ): RendererSkinId {
607
+ const resolvedStorage = storage === undefined ? documentSkinStorage(ownerDocument) : storage;
608
+ const currentStyle = ownerDocument.getElementById(RENDERER_SKIN_STYLE_ID);
609
+ if (id === "native") {
610
+ currentStyle?.remove();
611
+ ownerDocument.documentElement.removeAttribute(RENDERER_SKIN_ATTRIBUTE);
612
+ try { resolvedStorage?.removeItem(RENDERER_SKIN_STORAGE_KEY); } catch { /* visual reset succeeded */ }
613
+ return id;
614
+ }
615
+ const skin = rendererSkinDefinition(id);
616
+ const style = currentStyle ?? ownerDocument.createElement("style");
617
+ style.id = RENDERER_SKIN_STYLE_ID;
618
+ style.textContent = skinCss(skin);
619
+ if (!currentStyle) ownerDocument.head.append(style);
620
+ ownerDocument.documentElement.setAttribute(RENDERER_SKIN_ATTRIBUTE, id);
621
+ try { resolvedStorage?.setItem(RENDERER_SKIN_STORAGE_KEY, id); } catch { /* session-only fallback */ }
622
+ return id;
623
+ }
624
+
625
+ export function restoreRendererSkin(ownerWindow: Window = window): RendererSkinId {
626
+ const storage = documentSkinStorage(ownerWindow.document);
627
+ const id = readRendererSkin(storage);
628
+ if (id === "native") return id;
629
+ return applyRendererSkin(id, ownerWindow.document, storage);
630
+ }
@@ -156,6 +156,7 @@ function transportModelIdForAgent(agent: RendererAgent): string | null {
156
156
  if (agent === "zcode") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("zcode") });
157
157
  if (agent === "trae") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("trae") });
158
158
  if (agent === "cursor-cli") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("cursor-cli") });
159
+ if (agent === "cline") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("cline") });
159
160
  if (agent === 'codex-harness') return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse(agent) });
160
161
  return null;
161
162
  }
@@ -955,7 +956,7 @@ export function modelSelectionForAgent(
955
956
  ...(thinkingOptionId ? { thinkingOptionId } : {}),
956
957
  ...(permissionModeId ? { permissionModeId } : {}),
957
958
  })
958
- : agent === "openclaw" || agent === "hermes" || agent === 'codex-harness' || agent === 'qoder' || agent === 'codebuddy' || agent === 'zcode' || agent === 'trae' || agent === 'cursor-cli'
959
+ : agent === "openclaw" || agent === "hermes" || agent === 'codex-harness' || agent === 'qoder' || agent === 'codebuddy' || agent === 'zcode' || agent === 'trae' || agent === 'cursor-cli' || agent === 'cline'
959
960
  ? encodeHarnessPluginRoute({
960
961
  harnessId: harnessIdSchema.parse(agent),
961
962
  ...(model ? { model } : {}),