openspec-playwright 0.3.75 → 0.3.77

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.
@@ -158,24 +158,178 @@ const FRONTEND_FRAMEWORK_DEPS = [
158
158
  // Frontend dev-command keywords — substring match on scripts.dev (command
159
159
  // text is naturally matched by inclusion).
160
160
  const FRONTEND_DEV_COMMAND_KEYWORDS = ["vite", "next", "nuxt", "svelte-kit", "astro"];
161
+ // Framework config files — the strongest zero-ambiguity signal: presence at
162
+ // a project/npm root means "frontend" even when dependencies live elsewhere
163
+ // (monorepo roots commonly hold no frontend deps at all).
164
+ const FRONTEND_CONFIG_FILES = [
165
+ "vite.config.js", "vite.config.ts", "vite.config.mjs",
166
+ "next.config.js", "next.config.ts", "next.config.mjs",
167
+ "nuxt.config.js", "nuxt.config.ts", "nuxt.config.mjs",
168
+ "angular.json",
169
+ "svelte.config.js", "svelte.config.ts",
170
+ "astro.config.js", "astro.config.mjs", "astro.config.ts",
171
+ "vue.config.js", "vue.config.ts",
172
+ "remix.config.js", "remix.config.ts",
173
+ ];
174
+ // Workspace-scan bounds (spec: frontend-signal-detection): never walk deeper
175
+ // than 3 directory levels and never inspect more than 50 member package.jsons
176
+ // — guards against unbounded scans on huge repos.
177
+ const WORKSPACE_SCAN_MAX_DEPTH = 3;
178
+ const WORKSPACE_SCAN_MAX_MEMBERS = 50;
179
+ function hasFrontendConfigFile(dir) {
180
+ return FRONTEND_CONFIG_FILES.some((file) => existsSync(join(dir, file)));
181
+ }
182
+ function packageHasFrontendDeps(pkg) {
183
+ return FRONTEND_FRAMEWORK_DEPS.some((name) => dependencyExists(pkg, name));
184
+ }
161
185
  /**
162
- * Detect whether the project has frontend code: reads the package.json
163
- * located by findNpmRoot (same source as detectAppServer, so monorepo
164
- * conclusions match a nested app is treated consistently by both).
186
+ * Workspace member globs for a detected monorepo, or null when the project
187
+ * is not a detectable workspace. An empty array means "workspace but no
188
+ * member globs discoverable" (marker files only) the caller falls back to
189
+ * a bounded tree scan. Reads pnpm-workspace.yaml naively (list items only)
190
+ * and package.json workspaces (array or {packages} form); turbo/nx/lerna/
191
+ * rush markers carry no member list at all.
192
+ */
193
+ function workspaceGlobPatterns(root, pkg) {
194
+ const pnpmYaml = join(root, "pnpm-workspace.yaml");
195
+ let isWorkspace = false;
196
+ if (existsSync(pnpmYaml)) {
197
+ isWorkspace = true;
198
+ try {
199
+ const patterns = readFileSync(pnpmYaml, "utf-8")
200
+ .split(/\r?\n/)
201
+ .filter((line) => /^\s*-/.test(line))
202
+ .map((line) => line.replace(/^\s*-\s*/, "").trim().replace(/^['"]|['"]$/g, ""))
203
+ .filter((pattern) => pattern.length > 0);
204
+ if (patterns.length > 0)
205
+ return patterns;
206
+ }
207
+ catch {
208
+ // unreadable → fall through to the other markers
209
+ }
210
+ }
211
+ if (Array.isArray(pkg.workspaces))
212
+ return pkg.workspaces;
213
+ const wsPackages = pkg.workspaces?.packages;
214
+ if (Array.isArray(wsPackages))
215
+ return wsPackages;
216
+ for (const marker of ["turbo.json", "nx.json", "lerna.json", "rush.json"]) {
217
+ if (existsSync(join(root, marker)))
218
+ return [];
219
+ }
220
+ return isWorkspace ? [] : null;
221
+ }
222
+ /**
223
+ * Expand member globs ("apps/*", "packages/**", "apps/web") into candidate
224
+ * member directories. Supports only the simple forms — an exact path, or a
225
+ * star-wildcard in the last segment. Anything else (leading/middle wildcards)
226
+ * returns null so the caller falls back to a bounded tree scan.
227
+ */
228
+ function resolveMemberDirs(root, patterns) {
229
+ const dirs = [];
230
+ for (const raw of patterns) {
231
+ const pattern = raw.replace(/^\.\//, "").replace(/\/+$/, "");
232
+ if (pattern === "")
233
+ continue;
234
+ const segments = pattern.split("/");
235
+ const last = segments.length - 1;
236
+ if (segments.some((seg, i) => i !== last && seg.includes("*")))
237
+ return null;
238
+ if (segments[last].includes("*")) {
239
+ const baseDir = join(root, ...segments.slice(0, last));
240
+ if (!existsSync(baseDir))
241
+ continue;
242
+ try {
243
+ for (const entry of readdirSync(baseDir, { withFileTypes: true })) {
244
+ if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules")
245
+ continue;
246
+ dirs.push(join(baseDir, entry.name));
247
+ }
248
+ }
249
+ catch {
250
+ // unreadable base directory — skip this pattern
251
+ }
252
+ }
253
+ else {
254
+ dirs.push(join(root, ...segments)); // exact member path
255
+ }
256
+ }
257
+ return dirs;
258
+ }
259
+ /**
260
+ * Bounded scan of member candidate dirs for frontend deps or config files.
261
+ * Each seed gets `budget` directory levels below it; at most
262
+ * WORKSPACE_SCAN_MAX_MEMBERS member package.jsons are inspected. Skips
263
+ * node_modules and dot-directories (same convention as findNpmRoot).
264
+ */
265
+ function hasFrontendInDirs(seeds, budget) {
266
+ let checked = 0;
267
+ const visit = (dir, remaining) => {
268
+ if (remaining < 0 || checked >= WORKSPACE_SCAN_MAX_MEMBERS)
269
+ return false;
270
+ const pkg = readPackageJson(join(dir, "package.json"));
271
+ if (pkg)
272
+ checked++;
273
+ if ((pkg !== null && packageHasFrontendDeps(pkg)) || hasFrontendConfigFile(dir))
274
+ return true;
275
+ if (remaining === 0)
276
+ return false;
277
+ let entries;
278
+ try {
279
+ entries = readdirSync(dir, { withFileTypes: true });
280
+ }
281
+ catch {
282
+ return false;
283
+ }
284
+ for (const entry of entries) {
285
+ if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules")
286
+ continue;
287
+ if (visit(join(dir, entry.name), remaining - 1))
288
+ return true;
289
+ }
290
+ return false;
291
+ };
292
+ for (const seed of seeds) {
293
+ if (visit(seed, budget))
294
+ return true;
295
+ }
296
+ return false;
297
+ }
298
+ /**
299
+ * Detect whether the project has frontend code — layered signals, specific
300
+ * first, stop on first hit:
301
+ * 1. framework config files at the project/npm root (strongest);
302
+ * 2. framework dependencies in the package.json located by findNpmRoot
303
+ * (same source as detectAppServer, so monorepo conclusions match);
304
+ * 3. dev-script command keywords;
305
+ * 4. monorepo workspace members (bounded scan) — frontend code commonly
306
+ * lives in member packages (e.g. pnpm apps/*) whose root package.json
307
+ * carries no frontend deps at all.
165
308
  * Returns null when no readable package.json is found at the located root —
166
309
  * callers skip the hint in that case (detection skipped, not "no frontend").
310
+ * Deliberately biased toward "frontend": a false positive costs one extra
311
+ * MCP install (--no-mcp skips it); a false negative silently skips the MCP.
167
312
  */
168
313
  export function hasFrontendSignal(projectRoot) {
169
314
  const npmRoot = findNpmRoot(projectRoot);
170
315
  const pkg = readPackageJson(join(npmRoot, "package.json"));
171
316
  if (!pkg)
172
317
  return null;
173
- for (const name of FRONTEND_FRAMEWORK_DEPS) {
174
- if (dependencyExists(pkg, name))
175
- return true;
176
- }
318
+ if (hasFrontendConfigFile(projectRoot) || (npmRoot !== projectRoot && hasFrontendConfigFile(npmRoot)))
319
+ return true;
320
+ if (packageHasFrontendDeps(pkg))
321
+ return true;
177
322
  const dev = pkg.scripts?.dev ?? "";
178
- return FRONTEND_DEV_COMMAND_KEYWORDS.some((kw) => dev.includes(kw));
323
+ if (FRONTEND_DEV_COMMAND_KEYWORDS.some((kw) => dev.includes(kw)))
324
+ return true;
325
+ const patterns = workspaceGlobPatterns(projectRoot, pkg);
326
+ if (patterns === null)
327
+ return false;
328
+ const memberDirs = resolveMemberDirs(projectRoot, patterns);
329
+ if (memberDirs !== null && memberDirs.length > 0) {
330
+ return hasFrontendInDirs(memberDirs, WORKSPACE_SCAN_MAX_DEPTH - 1);
331
+ }
332
+ return hasFrontendInDirs([projectRoot], WORKSPACE_SCAN_MAX_DEPTH);
179
333
  }
180
334
  export function detectAppServer(projectRoot, env = process.env) {
181
335
  const npmRoot = findNpmRoot(projectRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"app-detect.js","sourceRoot":"","sources":["../../src/shared/app-detect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-detect.js","sourceRoot":"","sources":["../../src/shared/app-detect.ts"],"names":[],"mappings":"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"}
@@ -8,33 +8,26 @@
8
8
 
9
9
  **OpenSpec 命令**:跑 `npx openspec --help` 查看可用命令。
10
10
 
11
- **语言**:用中文回复用户。
12
-
13
11
  **优先级决策规则**:🔴 CRITICAL(违反→静默 bug / 安全漏洞,必须修正)→ **停下确认后再执行**|🟡 IMPORTANT(偏离需说明理由)→ **谨慎执行,偏离说明原因**|⚪ STANDARD(标准实践,可调整)→ 按标准执行
14
12
 
15
13
  ---
16
14
 
17
15
  ## 1. 代码质量
18
16
 
19
- > WHY:AI 默认倾向多写、快写、猜写。本节约束将这些倾向转化为可验证的生产代码。
17
+ > WHY:AI 默认倾向多写、快写、猜写——本节把倾向转化为可验证的生产代码。
20
18
 
21
19
  **DO**
22
- - 🔴 **lint + typecheck 每次编辑后自动执行,通过才算成功**。扫源码扩展名判断主语言:.ts/.tsx→ESLint+tsc、.py→ruff+mypy、.go→gofmt+vet 等。工具不存在时告知用户,不假装跑过
20
+ - 🔴 **lint + typecheck 每次编辑后自动执行,通过才算成功**。扫源码扩展名判断主语言:.ts/.tsx→ESLint+tsc、.py→ruff+mypy、.go→gofmt+vet 等;失败时先跑对应语言 auto-fix(如 `npm run lint:fix`)再重跑 gate。工具不存在时告知用户,不假装跑过
23
21
  - 🟡 不隐藏任何 gate 失败结果——lint / typecheck / test 任一失败时,完整输出错误日志并停止,不继续后续步骤
24
- - 未执行的检查步骤明确标注「未运行」,不暗示已通过
25
- - 🟡 需求理解不清或存在可见风险时,先停下来提问,不直接执行。偏离标准实践需说明理由
26
- - 🟡 动手前列假设 → 逐条验证。有不清→停下来,说出困惑,再提问
22
+ - 🟡 未执行的检查步骤明确标注「未运行」,不暗示已通过
23
+ - 🟡 需求理解不清或存在可见风险时,先停下来提问,不直接执行;动手前列假设 → 逐条验证,有不清再提问
27
24
  - 🟡 多解释则全列,更简单方案则提出并坚持
28
25
  - 🟡 多步任务先列计划(`1. [Step] → verify: [check]`),循环验证直到成功
29
- - 🟡 lint 失败时优先运行对应语言的 auto-fix(如 `npm run lint:fix` / `ruff format .` / `go fmt ./...`)
30
26
  - 🟡 只写被要求的:不加"灵活"、"可配置"、单次使用抽象、未要求功能。200行能50行则重写
31
27
  - 🔴 过时的直接删:删除/修改时不留兼容层、不写迁移、不留 fallback
32
- - 🟡 优先用成熟、有人维护的库,没有明确理由别自己重写
33
- - 🟡 选型前先翻项目已有依赖能做什么,再加新包或自己写
34
- - 🟡 同类问题先用成熟产品验证过的模式解决,不从零发明
35
- - 🟡 精准改动:只改必要的,改完清理自己造成的垃圾。匹配现有风格
28
+ - 🔴 方案选型按优先级链:项目已有依赖 → 成熟有人维护的库 → 自己实现(没有明确理由不从零发明);同类问题先用成熟产品验证过的模式解决
29
+ - 🟡 精准改动:只改必要的,改完清理自己造成的垃圾(未使用的 import/export/prop/console.log 等;清理与重构分开提交)。匹配现有风格
36
30
  - 🟡 代码文件行数上限 1500:超过即违例,必须按职责拆分,不得继续堆叠
37
- - ⚪ 重构前清理未使用的 import/export/prop/console.log 等,单独提交再做重构
38
31
 
39
32
  **DO NOT**
40
33
  - 不写只适配特定输入值的逻辑 → 上游格式变化即失效
@@ -55,24 +48,20 @@
55
48
 
56
49
  ## 2. 工具使用
57
50
 
58
- > WHY:工具使用方式直接影响搜索覆盖面和结果准确性。
59
-
60
51
  **工具调用纪律(防循环)🔴**
61
52
  - 🔴 一次只发一个工具调用,等结果再决定下一步;等待/轮询用单个调用内部的循环实现
62
53
  - 🔴 单条消息并行只用于真正独立的调用,禁止复制相同调用
63
54
  - 🔴 发现自己正在重复生成相同调用 → 立即停止,重新评估
64
- - 🟡 长会话接近上下文上限时,复杂任务前先压缩上下文(如 /compact)
55
+ - 🟡 长会话接近上下文上限时,复杂任务前先压缩上下文
65
56
 
66
57
  **DO**
67
58
  - 🟡 搜索分层:结构性问题(定义/调用/影响/流)优先用 CodeGraph;字面文本用全文搜索;文件名模式用文件名匹配。跳过依赖目录和缓存目录(调试依赖时除外),搜子目录时按需缩小
68
59
  - 🟡 重命名覆盖:调用、类型、字符串、import、barrel file、测试 mock,不得假设一次覆盖
69
- - 🟡 联网调研优先 agent-reach skill
70
- - 🟡 涉及前端 UI 设计时,按序使用:frontend-design skill 定方向 → ui-ux-pro-max skill 选风格 → web-design-guidelines skill 审查,三步组合避免"千篇一律 AI 风"
71
60
  - 🟡 编辑 → 重新读取确认 → 跑 §1 的 lint+typecheck → 任一失败则回退
72
61
  - 🟡 变更完成告知用户可能遗漏区域,提示人工复查
73
62
 
74
63
  **DO NOT**
75
- - 🔴 禁止用 sed/awk/node -e/python -c 等管道命令改源码文件(跳过编辑工具验证层)
64
+ - 🔴 禁止用 sed/awk/node -e/python -c 等管道命令改写项目内已有文件——源码/文档/测试/配置同算(跳过编辑工具验证层);确需批量改写,先征得用户同意
76
65
  - 不主动推送,除非用户明确要求
77
66
 
78
67
  **REQUIRE**
@@ -83,23 +72,12 @@
83
72
 
84
73
  ## 3. 大规模任务
85
74
 
86
- > WHY:200+ 行直接修改缺乏评审,OpenSpec 工作流强制提案→设计→评审→实现。
75
+ > WHY:200+ 行直接修改缺乏评审。
87
76
 
88
77
  - 🔴 200+ 行修改或架构变更(新增服务/API 契约/数据模型重构)必须走 OpenSpec(`/opsx:propose`),禁止直接修改
89
78
  - 🟡 新功能先跑通最小端到端路径,再增量扩展;不为未完成的复杂度拆掉能跑的代码
90
79
  - 🟡 架构决策往长了做:不接受"先这样以后再换"的临时方案
91
-
92
- ### 工作流参考
93
-
94
- | 阶段 | 命令 | 退出条件 |
95
- |------|------|---------|
96
- | 提案 | `/opsx:propose` | proposal + scenarios 生成 |
97
- | 实现 | `/opsx:apply` | lint + typecheck 通过 |
98
- | 自审 | `/opsx:verify` | 实现匹配 design,无遗漏 |
99
- | E2E | `/opsx:e2e` / `/opsx-e2e` | 测试生成 + Healer 验证通过 |
100
- | 归档 | `/opsx:archive` | specs 更新,归档完成 |
101
-
102
- 所有阶段由用户手动触发,**AI 不自动进入下一阶段**。
80
+ - 🔴 所有阶段由用户手动触发,**AI 不自动进入下一阶段**(提案 `/opsx:propose` → 实现 `/opsx:apply` → 自审 `/opsx:verify` → E2E `/opsx:e2e` → 归档 `/opsx:archive`)
103
81
 
104
82
  ---
105
83
 
@@ -124,30 +102,29 @@
124
102
 
125
103
  ## 5. 临时文件管理
126
104
 
127
- > WHY:临时文件散落在项目根目录而非集中存放,会在 commit 时被意外加入版本控制(导致仓库膨胀),或积累到难以清理(占用磁盘空间)。本节建立可自动化管理协议,避免这两类问题。
128
-
129
- **DO**
130
- - 🟡 非源码临时文件(截图、日志、heapdump 等)放项目根 `tmp/` 下
131
- - 🟡 文件名含时间戳(如 `screenshot-20260721T143000.png`)以避免冲突和重复
132
- - ⚪ 平铺存放,不分子目录,简化清理脚本
133
-
134
- **DO NOT**
135
- - 🔴 禁止将临时文件提交到版本控制(确保 `.gitignore` 包含 `tmp/`)
136
-
137
- **REQUIRE**
138
- - 🟡 超 24 小时的文件应在 commit 前删除
139
- - ⚪ 文件命名遵循项目所在语言/框架的约定(如 JS/Go 用 kebab-case,Python/Rust 用 snake_case,Java 用 PascalCase),避免空格和特殊字符
105
+ - 🟡 非源码临时文件(截图、日志、heapdump 等)放项目根 `tmp/` 下,文件名含时间戳(如 `screenshot-20260721T143000.png`)
106
+ - 🔴 禁止将临时文件提交到版本控制(确保 `.gitignore` 包含 `tmp/`);超 24 小时的临时文件在 commit 前删除
140
107
 
141
108
  ---
142
109
 
143
- ## 6. 浏览器验证证据链
110
+ ## 6. 测试与验证策略
144
111
 
145
- > WHY:截图证明像素,不证明行为。改用户可见可交互的东西,验证必须真的发生,不靠「代码看起来对」。
112
+ > WHY:测试的价值在验证行为,不在覆盖率数字;截图证明像素,不证明行为。AI 用琐碎单测堆数量冒充完成度——生成烧 token、套件拖慢反馈,验收结果才决定能否交付。
146
113
 
147
114
  **触发:改了用户可见可交互的东西,就必须在浏览器里证明**
148
- - 🔴 改 DOM/交互/跳转/异步渲染/样式/响应式,或守卫/权限/多角色可见性 → 浏览器验证(权限类必须真实登录态);纯逻辑 → unit,不开浏览器
115
+ - 🔴 改 DOM/交互/跳转/异步渲染/样式/响应式,或守卫/权限/多角色可见性 → 浏览器验证(权限类必须真实登录态);纯逻辑 → 按下方单测取舍,不开浏览器
116
+
117
+ **单测——命中才测,宁缺毋滥**
118
+ - 🟡 值得单测:业务核心计算/状态转换、含分支的纯函数、边界与错误处理路径、被多处复用的工具、修过 bug 的回归。不值得:纯透传、getter/装饰器/样板、类型系统已保证的行为、框架自带行为;模糊地带默认测(漏测代价 > 多测代价),一个行为一组断言,不拆场景凑数
119
+ - 🔴 验收标准点名的行为与业务核心逻辑必须被某层测试覆盖(单测或验收测试,一层即可,不重复堆);不以本条为由跳过/删除既有测试
120
+ - 🟡 分层反馈预期:单测改完随手跑(秒级量级);验收测试提交前实跑(见下方交付,分钟级可接受)
121
+
122
+ **验收——对照 spec 验收标准的真实行为验证,层级由被验对象决定**
123
+ - 🔴 后端/服务 → 对真实运行的服务发真实请求验证契约与端到端行为,不以全 mock 的单测链冒充验收;验收落成集成测试,提交前实跑
124
+ - 🔴 前端/用户可见 → 浏览器自检 + Playwright 交付测试(见下方 A/B)
125
+ - 🟡 集成测试用真实数据/依赖(seed/fixture,遵守 §4);期望锚定 spec 写「预期 X,实测 Y」(同下方自检 A),不自定期望
149
126
 
150
- **A. 自检(开发中 AI 验证,不留测试代码)**
127
+ **A. 自检(浏览器,开发中 AI 验证,不留测试代码)**
151
128
  - 🔴 截图 ≠ 行为验证:交互必须验证结果(点击后的状态/跳转/渲染),仅截图不算通过
152
129
  - 🟡 验证前核对加载的是本次产物(清缓存/停用 SW/核 hash)——跑旧包验证作废
153
130
  - 🟡 权限类禁止注入 token(守卫未执行,验证作废);多角色各角色单独登录验证
@@ -160,4 +137,4 @@
160
137
  - 🟡 提交前实跑测试,通过才算完成;未运行不视为完成
161
138
  - 🟡 无法覆盖的路径说明理由;skip/fixme 必附理由
162
139
  - 🟡 稳定选择器(data-testid/role);Healer 只消 flaky,不得掩盖断言失败
163
- - 🔴 含断言的临时脚本转正为 Playwright 测试或删除
140
+ - 🔴 含断言的临时脚本转正为对应层级的测试(浏览器→Playwright、服务→API 集成测试)或删除
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openspec-playwright",
3
- "version": "0.3.75",
3
+ "version": "0.3.77",
4
4
  "description": "OpenSpec + Playwright E2E verification setup tool for Claude Code, OpenCode, Cline, and Cursor",
5
5
  "type": "module",
6
6
  "bin": {