twskin 0.6.2 → 0.6.4
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/CHANGELOG.md +30 -0
- package/package.json +1 -1
- package/runtime/injector.mjs +8 -1
- package/runtime/manifest.json +9 -9
- package/runtime/skin.js +1 -0
- package/runtime/styles/base.css +17 -0
- package/runtime/token-map.mjs +13 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,36 @@ All notable changes to this package are documented here. This project follows
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.6.4] - 2026-07-29
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Mapped the legacy `text-text-default-reverse` alias to the foreground derived
|
|
13
|
+
from `surface.invert`. Older host primary buttons now retain readable text on
|
|
14
|
+
both light and dark inverse surfaces.
|
|
15
|
+
|
|
16
|
+
### For contributors
|
|
17
|
+
|
|
18
|
+
- Extended the official-theme action-contrast audit to cover this legacy
|
|
19
|
+
inverse-action foreground alias.
|
|
20
|
+
|
|
21
|
+
## [0.6.3] - 2026-07-29
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Corrected the semantic foreground for TRAE's inverted primary actions. Settings,
|
|
26
|
+
Automation, Marketplace and their dialogs now use a high-contrast foreground
|
|
27
|
+
independently from the brand-color foreground in every official theme.
|
|
28
|
+
- Removed the fixed pale strip behind the Templates tabs and the Automation Run
|
|
29
|
+
History filter bar, while preserving the hierarchy of their interactive controls.
|
|
30
|
+
- Made injected runtime payloads read their version from the packaged manifest,
|
|
31
|
+
preventing a current runtime from being mistaken for an older injection.
|
|
32
|
+
|
|
33
|
+
### For contributors
|
|
34
|
+
|
|
35
|
+
- Added full-catalog regression coverage for primary-action foreground contrast
|
|
36
|
+
across every official theme and all TRAE token namespaces.
|
|
37
|
+
|
|
8
38
|
## [0.6.2] - 2026-07-29
|
|
9
39
|
|
|
10
40
|
### Fixed
|
package/package.json
CHANGED
package/runtime/injector.mjs
CHANGED
|
@@ -16,7 +16,14 @@ import { spawnSync } from "node:child_process";
|
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
|
|
18
18
|
const ROOT = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
const VERSION =
|
|
19
|
+
const VERSION = (() => {
|
|
20
|
+
if (process.env.TWSKIN_RUNTIME_VERSION) return process.env.TWSKIN_RUNTIME_VERSION;
|
|
21
|
+
try {
|
|
22
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(ROOT, "manifest.json"), "utf8"));
|
|
23
|
+
if (typeof manifest.packageVersion === "string" && manifest.packageVersion) return manifest.packageVersion;
|
|
24
|
+
} catch {}
|
|
25
|
+
return "development";
|
|
26
|
+
})();
|
|
20
27
|
const DATA_DIR = process.env.TWSKIN_DATA_DIR || path.join(os.homedir(), ".trae-work-skin");
|
|
21
28
|
|
|
22
29
|
function parseArgs(argv) {
|
package/runtime/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"packageVersion": "0.6.
|
|
3
|
+
"packageVersion": "0.6.4",
|
|
4
4
|
"themesBundled": false,
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": "injector.mjs",
|
|
13
|
-
"size":
|
|
14
|
-
"sha256": "
|
|
13
|
+
"size": 31648,
|
|
14
|
+
"sha256": "7b0854c2b8b14323df1d5d469188ef3a0e290c7484aefd58bb3b29d19c0c056a"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"path": "restore.sh",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"path": "skin.js",
|
|
23
|
-
"size":
|
|
24
|
-
"sha256": "
|
|
23
|
+
"size": 62070,
|
|
24
|
+
"sha256": "c2c259652046286048ee0a298ab08210ae3dd8dd226e6410ee888610b41cd96c"
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"path": "start.sh",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"path": "styles/base.css",
|
|
33
|
-
"size":
|
|
34
|
-
"sha256": "
|
|
33
|
+
"size": 36601,
|
|
34
|
+
"sha256": "4fb182ba011d330b9ff668d12a25c10eec07ff1c20cb924dbb2598a44a1b8d49"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"path": "styles/manager.css",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"path": "token-map.mjs",
|
|
43
|
-
"size":
|
|
44
|
-
"sha256": "
|
|
43
|
+
"size": 25102,
|
|
44
|
+
"sha256": "5655ad4b3cfab19b569005a64b6a70972e86328129e4ac104323d81427e21559"
|
|
45
45
|
}
|
|
46
46
|
]
|
|
47
47
|
}
|
package/runtime/skin.js
CHANGED
|
@@ -416,6 +416,7 @@
|
|
|
416
416
|
setVar("--trae-skin-success", state.success);
|
|
417
417
|
setVar("--trae-skin-input", surface.input);
|
|
418
418
|
setVar("--trae-skin-menu", surface.menu);
|
|
419
|
+
setVar("--trae-skin-card", surface.card);
|
|
419
420
|
setVar("--trae-skin-card-hover", surface.cardHover);
|
|
420
421
|
setVar("--trae-skin-border-subtle", border.subtle);
|
|
421
422
|
setVar("--trae-skin-border-default", border.default);
|
package/runtime/styles/base.css
CHANGED
|
@@ -311,6 +311,23 @@ body.trae-skin-v2 [role="menuitem"][data-state="checked"] {
|
|
|
311
311
|
background: var(--trae-skin-popover-selected) !important;
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
+
/* Templates 的 CSS module 固定用纯白 tab strip;让容器回归透明,
|
|
315
|
+
仅由搜索框与选中态承担控件层级。只匹配含 tabRow 的栏目导航,
|
|
316
|
+
避免影响其他同前缀的内部 tab 容器。 */
|
|
317
|
+
body.trae-skin-v2 :is([class^="tabsBar-"], [class*=" tabsBar-"]):has(> :is([class^="tabRow-"], [class*=" tabRow-"])) {
|
|
318
|
+
background: transparent !important;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* Automation Run History 的筛选条在宿主中强制占用基础背景,形成一整块
|
|
322
|
+
不透明色带。条本身应融入页面,仅让可操作的筛选控件使用 input 表面。 */
|
|
323
|
+
body.trae-skin-v2 :is([class^="filterBar-"], [class*=" filterBar-"]):has(> :is([class^="statusSelect-"], [class*=" statusSelect-"])) {
|
|
324
|
+
background: transparent !important;
|
|
325
|
+
}
|
|
326
|
+
body.trae-skin-v2 :is([class^="filterBar-"], [class*=" filterBar-"]):has(> :is([class^="statusSelect-"], [class*=" statusSelect-"]))
|
|
327
|
+
:is([role="combobox"], [class^="trigger-"], [class*=" trigger-"]) {
|
|
328
|
+
background: var(--trae-skin-input) !important;
|
|
329
|
+
}
|
|
330
|
+
|
|
314
331
|
/* Account card:Trae Work 使用独立 CSS module,不走通用 popover。 */
|
|
315
332
|
body.trae-skin-v2 [class*="account-module__card___"],
|
|
316
333
|
body.trae-skin-v2 [class*="account-module__subMenuInner___"] {
|
package/runtime/token-map.mjs
CHANGED
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
|
|
79
79
|
// ---------- 命名空间普查清单(2026-07 实地盘点,见 docs/验证记录)----------
|
|
80
80
|
const NS_BG = ["base-default", "base-secondary", "base-tertiary", "brand", "brand-active", "brand-disabled", "brand-disabled-sub", "brand-hover", "brand-hover-sub", "brand-old", "brand-popup", "brand-popup-sub", "brand-sub", "card", "card-hover", "input", "invert", "invert-active", "invert-disabled", "invert-hover", "menu", "menu-old", "overlay-l0", "overlay-l1", "overlay-l2", "overlay-l3", "overlay-l4", "tooltip", "white"];
|
|
81
|
-
const NS_TEXT = ["brand", "brand-hover", "brand-hover-sub", "brand-sub", "default", "default-active", "default-hover", "disabled", "onaccent", "onbrand", "preformat-foreground", "secondary", "secondary-active", "secondary-hover", "tertiary"];
|
|
81
|
+
const NS_TEXT = ["brand", "brand-hover", "brand-hover-sub", "brand-sub", "default", "default-active", "default-hover", "default-reverse", "disabled", "onaccent", "onbrand", "preformat-foreground", "secondary", "secondary-active", "secondary-hover", "tertiary"];
|
|
82
82
|
const NS_ICON = ["brand", "brand-hover", "brand-hover-sub", "brand-sub", "default", "default-active", "default-hover", "disabled", "onaccent", "onbrand", "secondary", "secondary-active", "secondary-hover", "tertiary", "white"];
|
|
83
83
|
const NS_BORDER = ["brand", "brand-sub", "contrast", "neutral-l1", "neutral-l2", "neutral-l3"];
|
|
84
84
|
// --vscode-icube-- 别名层(组件真正消费的那层)
|
|
@@ -179,6 +179,11 @@
|
|
|
179
179
|
function buildVarMap(tokens, opts) {
|
|
180
180
|
const r = deriveRoles(tokens, opts);
|
|
181
181
|
const { accent, surface, text, icons, border, state } = r;
|
|
182
|
+
// TRAE 的原生语义并不对称:`*-onbrand` 配对 `bg-bg-brand`,
|
|
183
|
+
// 而 Marketplace / Automation / Settings 的主操作使用
|
|
184
|
+
// `bg-bg-invert` + `*-onaccent`。不能把二者都绑定到 accent,
|
|
185
|
+
// 否则浅色主题的深色 invert 表面会拿到同色文字。
|
|
186
|
+
const onInvert = pickOnColor(surface.invert);
|
|
182
187
|
const out = {};
|
|
183
188
|
|
|
184
189
|
// bg 语义(后缀共享:--bg-bg-* / --vscode-icube--bg-bg-* / --ras-bg-bg-*)
|
|
@@ -216,12 +221,16 @@
|
|
|
216
221
|
const textValue = (suffix) => {
|
|
217
222
|
switch (suffix) {
|
|
218
223
|
case "default": case "default-hover": case "default-active": return text.primary;
|
|
224
|
+
// 少数旧 CSS module 使用这个别名配对 bg-bg-invert;它不是“正文反色”,
|
|
225
|
+
// 仍须从实际 invert 表面推导,避免浅色 invert 按钮得到白字。
|
|
226
|
+
case "default-reverse": return onInvert;
|
|
219
227
|
case "secondary": case "secondary-hover": case "secondary-active": return text.secondary;
|
|
220
228
|
case "tertiary": return text.tertiary;
|
|
221
229
|
case "disabled": return text.disabled;
|
|
222
230
|
case "brand": case "brand-sub": case "brand-design": return accent.base;
|
|
223
231
|
case "brand-hover": case "brand-hover-sub": case "brand-hover-design": return accent.hover;
|
|
224
|
-
case "onaccent":
|
|
232
|
+
case "onaccent": return onInvert;
|
|
233
|
+
case "onbrand": return accent.onAccent;
|
|
225
234
|
case "preformat-foreground": return text.secondary;
|
|
226
235
|
default: return undefined;
|
|
227
236
|
}
|
|
@@ -234,7 +243,8 @@
|
|
|
234
243
|
case "disabled": return icons.disabled;
|
|
235
244
|
case "brand": case "brand-sub": case "brand-design": return accent.base;
|
|
236
245
|
case "brand-hover": case "brand-hover-sub": case "brand-hover-design": return accent.hover;
|
|
237
|
-
case "onaccent":
|
|
246
|
+
case "onaccent": return onInvert;
|
|
247
|
+
case "onbrand": return accent.onAccent;
|
|
238
248
|
case "white": return "#ffffff";
|
|
239
249
|
default: return undefined;
|
|
240
250
|
}
|