Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
83e1476
perf(weapp-tailwindcss): 优化多构建器热路径缓存复用
sonofmagic Mar 10, 2026
0f76168
perf(weapp-tailwindcss): 继续压缩 JS 与 gulp 热路径开销
sonofmagic Mar 10, 2026
16e257a
chore(deps): upgrade
sonofmagic Mar 10, 2026
03252ec
perf(postcss): 优化 resolver 与 process options 缓存
sonofmagic Mar 10, 2026
d2cc7c9
perf(postcss): 扩展简单样式选项缓存命中
sonofmagic Mar 10, 2026
f1ae3bb
perf(postcss): 复用选择器热路径预计算结果
sonofmagic Mar 10, 2026
6ed1d5a
perf(postcss): 减少 spacing 归一化重复扫描
sonofmagic Mar 10, 2026
1b7a0f3
perf(postcss): 预计算 post 插件 host 追加条件
sonofmagic Mar 10, 2026
2ffc3db
perf(postcss): 复用默认 rem 与 px 转换配置
sonofmagic Mar 10, 2026
3115161
perf(postcss): 复用 calc 默认插件配置
sonofmagic Mar 10, 2026
24f1d1b
perf(postcss): 收紧自定义属性清理解析条件
sonofmagic Mar 10, 2026
359bef9
perf(postcss): 精简样式流水线节点构建
sonofmagic Mar 10, 2026
8d5a587
perf(weapp-tailwindcss): 复用模板替换参数对象
sonofmagic Mar 10, 2026
03320ce
perf(weapp-tailwindcss): 精简模板处理热路径
sonofmagic Mar 10, 2026
8767581
perf(weapp-tailwindcss): 复用 js 与模板处理默认分支
sonofmagic Mar 10, 2026
c9acce7
perf(weapp-tailwindcss): 减少候选解析与 legacy 回退开销
sonofmagic Mar 10, 2026
411e993
perf(weapp-tailwindcss): 复用类名判定与 js 后处理结果
sonofmagic Mar 10, 2026
313eb1f
perf(weapp-tailwindcss): 复用 eval 选项并收紧替换扫描
sonofmagic Mar 10, 2026
9711fd0
perf(weapp-tailwindcss): 精简调用表达式遍历默认分支
sonofmagic Mar 10, 2026
be9f9db
perf(weapp-tailwindcss): 精简名称匹配默认路径
sonofmagic Mar 10, 2026
c2e0c9c
perf(weapp-tailwindcss): 复用标签忽略判定上下文
sonofmagic Mar 10, 2026
88f605d
perf(weapp-tailwindcss): 精简标签忽略名称匹配
sonofmagic Mar 10, 2026
2003973
perf(weapp-tailwindcss): 延迟构建标签忽略匹配器
sonofmagic Mar 10, 2026
a55a1ee
perf(weapp-tailwindcss): 复用默认忽略路径集合
sonofmagic Mar 10, 2026
ad29e30
perf(weapp-tailwindcss): 修正模块替换空输入快路径
sonofmagic Mar 10, 2026
1c2bb22
perf(weapp-tailwindcss): 延迟分配导入标记集合
sonofmagic Mar 10, 2026
af6e76b
perf(weapp-tailwindcss): 延迟分配遍历去重集合
sonofmagic Mar 10, 2026
c633662
perf(weapp-tailwindcss): 精简模块图空结果分支
sonofmagic Mar 10, 2026
8c7baaa
perf(weapp-tailwindcss): 精简模块替换判空分支
sonofmagic Mar 10, 2026
f89ba78
perf(weapp-tailwindcss): 提前返回空路径更新分支
sonofmagic Mar 10, 2026
d942193
perf(weapp-tailwindcss): 按需收集模块元数据
sonofmagic Mar 10, 2026
6b57190
perf(weapp-tailwindcss): 精简标签模板默认分支
sonofmagic Mar 10, 2026
23834fc
perf(weapp-tailwindcss): 精简 js 遍历默认分支
sonofmagic Mar 10, 2026
eea00e0
perf(weapp-tailwindcss): 延迟分配调试样本列表
sonofmagic Mar 10, 2026
da67265
perf(weapp-tailwindcss): 精简 class 语义关键字归一化
sonofmagic Mar 10, 2026
997ffbd
perf(weapp-tailwindcss): 后移 class context 判定
sonofmagic Mar 10, 2026
1d9e105
perf(weapp-tailwindcss): 提前过滤非 class helper 调用
sonofmagic Mar 10, 2026
2df4fd7
perf(weapp-tailwindcss): 延迟分配候选计划缓存
sonofmagic Mar 10, 2026
d32db8a
perf(weapp-tailwindcss): 精简忽略注释扫描分支
sonofmagic Mar 10, 2026
f1b1be8
perf(weapp-tailwindcss): 精简字面量值读取分支
sonofmagic Mar 10, 2026
7d0e2d1
perf(weapp-tailwindcss): 精简任意值候选判定分支
sonofmagic Mar 10, 2026
0f215f6
perf(weapp-tailwindcss): 内联 fallback 启用态判定
sonofmagic Mar 10, 2026
8bd82b1
perf(weapp-tailwindcss): 按需收集调试采样信息
sonofmagic Mar 10, 2026
ff02666
perf(weapp-tailwindcss): 复用字面量级 replacement cache
sonofmagic Mar 10, 2026
0685799
perf(weapp-tailwindcss): 提前短路 fallback 候选扫描
sonofmagic Mar 11, 2026
229cf34
perf(weapp-tailwindcss): 复用最近 escaped candidate cache
sonofmagic Mar 11, 2026
135d5e9
fix(weapp-tailwindcss): harden hot-update comment carrier coverage
sonofmagic Mar 11, 2026
77a432b
fix(packages): 修复 packages 目录下所有 ESLint error
sonofmagic Mar 11, 2026
83a3bb0
fix(packages-runtime): 修复 packages-runtime 目录下所有 ESLint error
sonofmagic Mar 11, 2026
63c8e3c
fix(e2e,scripts,apps): 修复 e2e/scripts/apps 目录下可修复的 ESLint error
sonofmagic Mar 11, 2026
85c354f
fix(weapp-tailwindcss): 回退 Object.hasOwn 为 hasOwnProperty.call,兼容 ES2…
sonofmagic Mar 11, 2026
65ae636
chore(weapp-tailwindcss): 升级 tsconfig lib 至 ES2022,恢复 Object.hasOwn 用法
sonofmagic Mar 11, 2026
6c08eb8
fix(e2e): 修复 mpx same-class-literal escaped classes 断言不兼容 minRequired…
sonofmagic Mar 11, 2026
fc8ba46
fix(website): 修复 website 及周边文件的 ESLint e18e error
sonofmagic Mar 11, 2026
3d67397
fix: 修复全局剩余 ESLint error 并优化 eslint 配置
sonofmagic Mar 11, 2026
7aa5928
fix: 修复 CI 剩余 15 个 ESLint error
sonofmagic Mar 11, 2026
531cbaa
fix: vitest.config.ts 使用展开语法替代 Array.from
sonofmagic Mar 11, 2026
2da9508
fix: .gitattributes 为源码文件添加 eol=lf 修复 Windows CI CRLF 问题
sonofmagic Mar 11, 2026
d6dc007
fix: .gitattributes 全局默认 eol=lf 彻底修复 Windows CI CRLF 问题
sonofmagic Mar 11, 2026
35b3dd7
fix(demo): 修复 native-mina Windows spawn EINVAL 和 mpx-v4 序列化器重复注册
sonofmagic Mar 11, 2026
3a26873
feat(weapp-tailwindcss): 为所有编译插件入口新增 weappTailwindcss 别名导出
sonofmagic Mar 11, 2026
5b09267
fix(demo): 修复 mpx-tailwindcss-v4 webpack 序列化器重复注册问题
sonofmagic Mar 11, 2026
a9cdd49
test(weapp-tailwindcss): 修复 Windows 路径分隔符导致的 21 个测试失败
sonofmagic Mar 11, 2026
674e240
test(weapp-tailwindcss): 修复 normalizeCssEntries 测试在 Windows 下路径 drive…
sonofmagic Mar 11, 2026
a00c666
chore: 进入 changeset alpha 预发布模式
sonofmagic Mar 11, 2026
bd235e0
chore(deps): upgrade
sonofmagic Mar 11, 2026
5550c61
chore(deps): upgrade
sonofmagic Mar 11, 2026
3cbc7bd
fix(eslint): 忽略 apps 中生成的 result.json
sonofmagic Mar 11, 2026
e502eec
Version Packages (alpha)
github-actions[bot] Mar 11, 2026
6b0a062
perf(weapp-tailwindcss): 优化 vite 构建与热更新路径
sonofmagic Mar 11, 2026
76000c6
chore: update
sonofmagic Mar 11, 2026
17fe2f8
fix: 修复 vite basedir 对齐与快照回归
sonofmagic Mar 12, 2026
26fde22
fix: 修复 vite 增量 runtime set 对 rpx upx 的回退
sonofmagic Mar 12, 2026
2641d48
perf: 优化 vite css 增量缓存命中
sonofmagic Mar 12, 2026
6aa16ee
perf: 复用 vite 同轮重复 css 转换结果
sonofmagic Mar 12, 2026
f315fdf
test: 完善 e2e watch 分组入口
sonofmagic Mar 12, 2026
b3f570b
chore: 添加 e2e watch changeset
sonofmagic Mar 12, 2026
1fbcefc
chore: upgrade to pnpm@10.32.1
sonofmagic Mar 12, 2026
1f0742f
Version Packages (alpha)
github-actions[bot] Mar 12, 2026
f6f5699
chore(deps): upgrade
sonofmagic Mar 13, 2026
2184518
feat(e2e): 增强 watch 任意值回归
sonofmagic Mar 13, 2026
7554ae5
fix: reduce generated file git noise
sonofmagic Mar 13, 2026
fe4981b
test: 调整 watch hmr 脚本 coverage 统计
sonofmagic Mar 13, 2026
155331d
ci: 避免矩阵重复上传 coverage
sonofmagic Mar 13, 2026
cbead4c
chore(deps): upgrade tailwindcss-patch to 8.7.4-alpha.0
sonofmagic Mar 14, 2026
3f0c6eb
fix(vite): fallback dynamic wxml arbitrary classes
sonofmagic Mar 14, 2026
47e67c8
fix: migrate weapp-tailwindcss to tailwindcss-patch v9 runtime
sonofmagic Mar 14, 2026
f36af43
fix: finish tailwindcss-patch v9 alpha.2 migration
sonofmagic Mar 14, 2026
82cf33e
fix: restore monorepo build after patch v9 migration
sonofmagic Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 9 additions & 0 deletions .changeset/e2e-watch-group-entry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"weapp-tailwindcss": patch
---

完善 `e2e:watch` 热更新回归流程:

- 新增 `demo` 与 `apps` 分组测试入口,避免分组执行时重复跑单 case 文件
- 将 `test:watch-hmr` 切换为 `node --import tsx` 启动,修复部分环境下 `tsx` IPC `EPERM` 导致的回归无法启动问题
- 调整 `apps/taro-webpack-tailwindcss-v4` 的 watch 回归命令,确保 Taro webpack 场景下模板、脚本、样式热更新都能稳定校验
7 changes: 7 additions & 0 deletions .changeset/honest-hounds-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"weapp-tailwindcss": patch
---

增强多平台热更新回归覆盖,补齐 `uni-app`、`uni-app-vue3-vite`、`mpx` 的 comment-carrier 场景,并新增汇总断言校验 same-class 稳定性、comment-carrier 命中数量与热更新时间指标。

修复 `uni-app-vue3-vite` 在 comment-carrier 场景下 marker 无法进入运行时输出导致 watch-hmr 卡住的问题,同时将关键 HMR 用例接入 `E2E Watch` 工作流,确保 PR 与夜间任务都能持续校验多平台热更新链路。
79 changes: 79 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"mode": "pre",
"tag": "alpha",
"initialVersions": {
"react-app": "0.0.0",
"rsmax-app-ts": "1.0.0",
"tailwindcss-weapp": "0.0.1",
"taro-webpack-tailwindcss-v4": "1.0.0",
"uni-app-x-hbuilderx-tailwindcss3": "0.0.0",
"uni-app-x-hbuilderx-tailwindcss4": "0.0.0",
"vite-native": "1.0.19",
"vite-native-skyline": "1.0.1",
"vite-native-ts": "1.0.12",
"vite-native-ts-skyline": "1.0.1",
"vue-app": "0.0.0",
"weapp-wechat-zhihu": "1.0.0",
"@native-app/postcss7-compat": "1.0.1",
"benchmark": "0.0.1",
"benchmark-tailwindcss3": "0.0.8",
"benchmark-tailwindcss4": "0.0.6",
"@weapp-tailwindcss-demo/gulp-app": "0.0.5",
"@weapp-tailwindcss-demo/mpx-app": "0.1.0",
"@weapp-tailwindcss-demo/mpx-tailwindcss-v4": "0.1.0",
"@weapp-tailwindcss-demo/native": "1.0.0",
"@weapp-tailwindcss-demo/native-mina": "1.0.0",
"@weapp-tailwindcss-demo/native-ts": "1.0.0",
"@weapp-tailwindcss-demo/rax-app": "0.1.0",
"@weapp-tailwindcss-demo/taro-app": "1.0.1",
"@weapp-tailwindcss-demo/taro-app-vite": "1.0.0",
"@weapp-tailwindcss-demo/taro-vite-tailwindcss-v4": "1.0.0",
"@weapp-tailwindcss-demo/taro-vue3-app": "1.0.0",
"@weapp-tailwindcss-demo/taro-webpack-tailwindcss-v4": "1.0.0",
"@weapp-tailwindcss-demo/uni-app": "0.1.0",
"@weapp-tailwindcss-demo/uni-app-tailwindcss-v4": "0.0.0",
"@weapp-tailwindcss-demo/uni-app-vue3-vite": "0.0.1",
"@weapp-tailwindcss-demo/uni-app-webpack-tailwindcss-v4": "0.1.0",
"@weapp-tailwindcss-demo/uni-app-webpack5": "0.1.0",
"@weapp-tailwindcss-demo/uni-app-x-hbuilderx-tailwindcss3": "0.0.0",
"@weapp-tailwindcss-demo/uni-app-x-hbuilderx-tailwindcss4": "0.0.0",
"@weapp-tailwindcss-demo/web": "1.0.0",
"@weapp-tailwindcss/e2e": "0.0.0",
"@weapp-tailwindcss/cva": "0.1.6",
"@weapp-tailwindcss/merge": "2.1.6",
"@weapp-tailwindcss/merge-v3": "0.1.6",
"@weapp-tailwindcss/runtime": "0.1.5",
"tailwind-variant-v3": "0.2.1",
"theme-transition": "2.0.1",
"@weapp-tailwindcss/typography": "0.2.6",
"@weapp-tailwindcss/ui": "0.0.6",
"@weapp-tailwindcss/variants": "0.2.1",
"@weapp-tailwindcss/variants-v3": "0.1.1",
"@weapp-tailwindcss/babel": "0.0.3",
"@weapp-tailwindcss/build-all": "0.0.21",
"@weapp-tailwindcss/debug-uni-app-x": "0.0.3",
"@weapp-tailwindcss/experimental": "0.0.1",
"@weapp-tailwindcss/init": "1.0.10",
"@weapp-tailwindcss/logger": "1.1.0",
"@weapp-tailwindcss/minify-preserve": "0.0.0",
"@weapp-tailwindcss/postcss": "2.1.5",
"@weapp-tailwindcss/shared": "1.1.2",
"tailwindcss-config": "1.1.4",
"tailwindcss-core-plugins-extractor": "0.2.0",
"tailwindcss-injector": "1.0.10",
"@weapp-tailwindcss/test-helper": "0.0.1",
"weapp-style-injector": "0.0.1",
"weapp-tailwindcss": "4.10.3",
"weapp-tw": "0.0.0",
"weapptw": "0.0.0",
"wetw": "0.1.1",
"@weapp-tailwindcss/website": "1.0.17"
},
"changesets": [
"bright-horses-clean",
"e2e-watch-group-entry",
"honest-hounds-hug",
"perf-hot-path-caching",
"weapp-tailwindcss-alias"
]
}
13 changes: 13 additions & 0 deletions .changeset/tailwindcss-patch-874-alpha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'weapp-tailwindcss': patch
'weapp-tw': patch
'tailwindcss-injector': patch
'@weapp-tailwindcss/postcss': patch
'@weapp-tailwindcss/ui': patch
'@weapp-tailwindcss/shared': patch
'@weapp-tailwindcss/init': patch
'@weapp-tailwindcss/typography': patch
'wetw': patch
---

升级 `tailwindcss-patch` 到 `8.7.4-alpha.0`,同步消费最新的 alpha 版本依赖。
10 changes: 10 additions & 0 deletions .changeset/weapp-tailwindcss-alias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'weapp-tailwindcss': minor
---

为所有编译插件入口新增 `weappTailwindcss` 别名导出,方便用户统一简写引用:

- `weapp-tailwindcss/webpack` → `UnifiedWebpackPluginV5` 的别名
- `weapp-tailwindcss/webpack4` → `UnifiedWebpackPluginV4` 的别名
- `weapp-tailwindcss/vite` → `UnifiedViteWeappTailwindcssPlugin` 的别名
- `weapp-tailwindcss/gulp` → `createPlugins` 的别名
4 changes: 2 additions & 2 deletions .claude/skills/playwright-cli/references/test-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ test('login flow', async ({ page }) => {
await page.getByRole('textbox', { name: 'Password' }).fill('password123')
await page.getByRole('button', { name: 'Sign In' }).click()

// Add assertions
await expect(page).toHaveURL(/.*dashboard/)
// 验证跳转到 dashboard
await expect(page).toHaveURL('https://example.com/dashboard')
})
```

Expand Down
4 changes: 2 additions & 2 deletions .codex/skills/playwright-cli/references/test-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ test('login flow', async ({ page }) => {
await page.getByRole('textbox', { name: 'Password' }).fill('password123')
await page.getByRole('button', { name: 'Sign In' }).click()

// Add assertions
await expect(page).toHaveURL(/.*dashboard/)
// 验证跳转到 dashboard
await expect(page).toHaveURL('https://example.com/dashboard')
})
```

Expand Down
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
## Handle line endings automatically for files detected as
## text and leave all files detected as binary untouched.
## This will handle all files NOT defined below.
* text=auto
## 强制所有文本文件使用 LF,避免 Windows CI 上 CRLF 导致 prettier 报错
* text=auto eol=lf

# Source code
*.bash text eol=lf
Expand Down
71 changes: 50 additions & 21 deletions .github/scripts/e2e-watch-report.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,37 @@ const fs = require('node:fs')
const path = require('node:path')
const process = require('node:process')

/** 匹配换行符(兼容 CRLF) */
const CRLF_RE = /\r?\n/
/** 替换换行为转义表示 */
const NEWLINE_REPLACE_RE = /\n/g
/** 匹配 rollback 阶段(不区分大小写) */
const ROLLBACK_RE = /rollback/i
/** 按管道符分隔 token */
const TOKEN_SEPARATOR_RE = /\s+\|\s+/
/** 匹配截断的 bg hex / 未闭合 bg / 未闭合 px token(多行) */
const BG_PX_FALLBACK_RE = /\bbg-\s+\[#?[0-9a-fA-F]{3,8}\]?|\bbg-\[[^\]]*$|\bpx-\[[^\]]*$/m
/** 截断的 bg hex token */
const TRUNCATED_BG_HEX_RE = /\bbg-\s+\[#?[0-9a-fA-F]{3,8}\]?/g
/** 未闭合 bg token */
const UNTERMINATED_BG_RE = /\bbg-\[[^\]]*$/gm
/** 未闭合 px token */
const UNTERMINATED_PX_RE = /\bpx-\[[^\]]*$/gm
/** bg token 内含空白 */
const BG_WHITESPACE_INSIDE_RE = /\bbg-\[[^\]\s]*\s[^\]\s]*\]/g
/** px token 内含空白 */
const PX_WHITESPACE_INSIDE_RE = /\bpx-\[[^\]\s]*\s[^\]\s]*\]/g
/** 缓存失效相关关键词 */
const CACHE_INVALIDATION_RE = /invalidation|context-not-found|cache/
/** 文件系统竞态相关关键词 */
const FS_RACE_RE = /enoent|eperm|ebusy|eacces|crlf|lf|rename|path/
/** 进程/超时相关关键词 */
const PROCESS_TIMEOUT_RE = /timeout|exceeded|watch process exited|sigkill|fatal|killed/
/** 匹配 mutation kind */
const MUTATION_KIND_RE = /mutation=(template|script|style)/g
/** 匹配 round 名称 */
const ROUND_NAME_RE = /round=([a-z0-9-]+)/g

const ROOT_DIR = path.resolve(process.cwd(), 'e2e/benchmark/e2e-watch-hmr')
const SNAPSHOTS_DIR = path.join(ROOT_DIR, 'snapshots')
const FAILURES_DIR = path.join(ROOT_DIR, 'failures')
Expand Down Expand Up @@ -35,7 +66,7 @@ function listFilesSafe(dir, filter) {

function parseKvContent(content) {
const out = {}
for (const line of content.split(/\r?\n/)) {
for (const line of content.split(CRLF_RE)) {
const index = line.indexOf('=')
if (index <= 0) {
continue
Expand All @@ -61,10 +92,10 @@ function summarizeDiff(before, after) {
}
const beforeContext = before
.slice(Math.max(0, index - 40), Math.min(before.length, index + 120))
.replace(/\n/g, '\\n')
.replace(NEWLINE_REPLACE_RE, '\\n')
const afterContext = after
.slice(Math.max(0, index - 40), Math.min(after.length, index + 120))
.replace(/\n/g, '\\n')
.replace(NEWLINE_REPLACE_RE, '\\n')
return `firstDiff=${index}, len=${before.length}->${after.length}\n before=${beforeContext}\n after=${afterContext}`
}

Expand Down Expand Up @@ -99,7 +130,7 @@ function resolvePhase(rawPhase, errorText) {
if (rawPhase === 'add' || rawPhase === 'modify') {
return 'hot-update'
}
if (/rollback/i.test(errorText)) {
if (ROLLBACK_RE.test(errorText)) {
return 'rollback'
}
return 'hot-update'
Expand All @@ -118,13 +149,13 @@ function pickPrimaryFailure(failureLogs, failureSnapshots) {
phase: resolvePhase(kv.phase || '', kv.error || ''),
project: kv.project || 'unknown',
sourceFile: kv.source || 'unknown',
tokens: (kv.tokens || '').split(/\s+\|\s+/).filter(Boolean),
tokens: (kv.tokens || '').split(TOKEN_SEPARATOR_RE).filter(Boolean),
error: kv.error || '',
}
}

if (failureSnapshots.length > 0) {
const item = failureSnapshots[failureSnapshots.length - 1]
const item = failureSnapshots.at(-1)
return {
source: 'snapshot',
file: item.dir,
Expand Down Expand Up @@ -164,7 +195,7 @@ function pickFailureSnapshot(primary, snapshots) {
&& item.meta.roundName === primary.round
&& item.meta.phase === primary.phaseRaw,
)
return exact || candidates[candidates.length - 1]
return exact || candidates.at(-1)
}

function pickMetricFromReport(report, primary) {
Expand Down Expand Up @@ -218,9 +249,7 @@ function pickSnippet(source, probes) {
}

if (hitIndex < 0) {
const fallback = source.match(
/\bbg-\s+\[#?[0-9a-fA-F]{3,8}\]?|\bbg-\[[^\]]*$|\bpx-\[[^\]]*$/m,
)
const fallback = source.match(BG_PX_FALLBACK_RE)
if (fallback?.index != null) {
hitIndex = fallback.index
}
Expand All @@ -237,11 +266,11 @@ function pickSnippet(source, probes) {

function detectTokenAnomalies(source) {
const patterns = [
{ name: 'truncated-bg-hex', re: /\bbg-\s+\[#?[0-9a-fA-F]{3,8}\]?/g },
{ name: 'unterminated-bg-token', re: /\bbg-\[[^\]]*$/gm },
{ name: 'unterminated-px-token', re: /\bpx-\[[^\]]*$/gm },
{ name: 'bg-whitespace-inside-token', re: /\bbg-\[[^\]\s]*\s[^\]\s]*\]/g },
{ name: 'px-whitespace-inside-token', re: /\bpx-\[[^\]\s]*\s[^\]\s]*\]/g },
{ name: 'truncated-bg-hex', re: TRUNCATED_BG_HEX_RE },
{ name: 'unterminated-bg-token', re: UNTERMINATED_BG_RE },
{ name: 'unterminated-px-token', re: UNTERMINATED_PX_RE },
{ name: 'bg-whitespace-inside-token', re: BG_WHITESPACE_INSIDE_RE },
{ name: 'px-whitespace-inside-token', re: PX_WHITESPACE_INSIDE_RE },
]

const findings = []
Expand All @@ -267,7 +296,7 @@ function scoreAttribution(primary, evidence) {
['进程/超时问题', 0],
])

if (/invalidation|context-not-found|cache/.test(text)) {
if (CACHE_INVALIDATION_RE.test(text)) {
scores.set(
'cache key/invalidation',
scores.get('cache key/invalidation') + 2,
Expand All @@ -286,13 +315,13 @@ function scoreAttribution(primary, evidence) {
scores.get('transform emit mismatch') + 3,
)
}
if (/enoent|eperm|ebusy|eacces|crlf|lf|rename|path/.test(text)) {
if (FS_RACE_RE.test(text)) {
scores.set(
'文件系统竞态/路径换行差异',
scores.get('文件系统竞态/路径换行差异') + 3,
)
}
if (/timeout|exceeded|watch process exited|sigkill|fatal|killed/.test(text)) {
if (PROCESS_TIMEOUT_RE.test(text)) {
scores.set('进程/超时问题', scores.get('进程/超时问题') + 3)
}
if (primary.phase === 'rollback') {
Expand Down Expand Up @@ -393,7 +422,7 @@ function generateDiffSummary() {
lines.push(`- ${path.basename(file)}`)
const content = readUtf8(file).trim()
if (content) {
for (const line of content.split(/\r?\n/)) {
for (const line of content.split(CRLF_RE)) {
lines.push(` ${line}`)
}
}
Expand Down Expand Up @@ -619,8 +648,8 @@ function publishJobSummary() {
for (const log of logs) {
const content = fs.readFileSync(path.join(FAILURES_DIR, log), 'utf8')
const kindMatches
= content.match(/mutation=(template|script|style)/g) || []
const roundMatches = content.match(/round=([a-z0-9-]+)/g) || []
= content.match(MUTATION_KIND_RE) || []
const roundMatches = content.match(ROUND_NAME_RE) || []
for (const matched of kindMatches) {
failedKinds.add(matched.replace('mutation=', ''))
}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload coverage reports to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.node-version == 22
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Loading
Loading