claude-coder 1.5.4 → 1.5.6

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/README.md CHANGED
@@ -97,7 +97,8 @@ your-project/
97
97
  progress.json # 会话历史 + 成本
98
98
  tests.json # 验证记录
99
99
  test.env # 测试凭证(API Key 等,可选)
100
- playwright-auth.json # Playwright 登录状态(可选,auth 命令生成)
100
+ playwright-auth.json # 登录状态快照(备份参考,auth 命令生成)
101
+ browser-profile/ # 持久化浏览器 Profile(MCP 实际使用)
101
102
  .runtime/ # 临时文件
102
103
  logs/ # 每 session 独立日志(含工具调用记录)
103
104
  requirements.md # 需求文档(可选)
@@ -31,7 +31,7 @@ Agent 在单次 session 中应最大化推进任务进度。**任何非致命问
31
31
 
32
32
  `git reset --hard` 是全量回滚,不做部分文件保护。
33
33
 
34
- - 凭证文件(`test.env`、`playwright-auth.json`)应通过 `.gitignore` 排除在 git 之外
34
+ - 凭证文件(`test.env`、`playwright-auth.json`、`browser-profile/`)应通过 `.gitignore` 排除在 git 之外
35
35
  - 如果回滚发生,说明 session 确实失败,代码应全部还原
36
36
  - 不需要 backup/restore 机制 — 这是过度设计
37
37
 
@@ -51,7 +51,8 @@ Agent 在单次 session 中应最大化推进任务进度。**任何非致命问
51
51
  | 文件 | git 状态 | 说明 |
52
52
  |------|---------|------|
53
53
  | `test.env` | .gitignore | Agent 可写入发现的 API Key、测试账号 |
54
- | `playwright-auth.json` | .gitignore | 用户通过 `claude-coder auth` 生成 |
54
+ | `playwright-auth.json` | .gitignore | 登录状态快照备份(`claude-coder auth` 生成) |
55
+ | `browser-profile/` | .gitignore | 持久化浏览器 Profile(MCP 实际使用) |
55
56
  | `session_result.json` | git-tracked | Agent 每次 session 覆盖写入 |
56
57
  | `tasks.json` | git-tracked | Agent 修改 status 字段 |
57
58
 
@@ -207,7 +208,8 @@ templates/
207
208
  | `tasks.json` | 首次扫描 | 任务列表 + 状态跟踪 |
208
209
  | `progress.json` | 每次 session 结束 | 结构化会话日志 + 成本记录 |
209
210
  | `session_result.json` | 每次 session 结束 | 当前 session 结果(扁平格式,向后兼容旧 `current` 包装) |
210
- | `playwright-auth.json` | `claude-coder auth` | Playwright 登录状态(cookies + localStorage) |
211
+ | `playwright-auth.json` | `claude-coder auth` | 登录状态快照(备份参考) |
212
+ | `browser-profile/` | `claude-coder auth` | 持久化浏览器 Profile(MCP 通过 `--user-data-dir` 使用) |
211
213
  | `tests.json` | 首次测试时 | 验证记录(防止反复测试) |
212
214
  | `.runtime/` | 运行时 | 临时文件(phase、step、logs/);工具调用记录合并到 session log |
213
215
 
@@ -265,7 +267,7 @@ flowchart TB
265
267
  | 5 | `docsHint` | profile.existing_docs 非空或 profile 有缺陷 | Step 4:读文档后再编码;profile 缺陷时提示 Agent 在 Step 6 补全 services/docs |
266
268
  | 6 | `taskHint` | tasks.json 存在且有待办任务 | Step 1:跳过读取 tasks.json,harness 已注入当前任务上下文 + 项目绝对路径 |
267
269
  | 6b | `testEnvHint` | 始终注入(内容因 test.env 是否存在而不同) | Step 5:存在时提示加载;不存在时告知可创建 |
268
- | 6c | `playwrightAuthHint` | .claude-coder/playwright-auth.json 存在 | Step 5:提示 Agent 前端测试可使用已认证的浏览器状态 |
270
+ | 6c | `playwrightAuthHint` | .claude-coder/browser-profile/ 存在 | Step 5:提示 Agent MCP 使用持久化浏览器 Profile,首次需手动登录 |
269
271
  | 7 | `memoryHint` | session_result.json 存在(扁平格式) | Step 1:跳过读取 session_result.json,harness 已注入上次会话摘要 |
270
272
  | 8 | `serviceHint` | 始终注入 | Step 6:单次模式停止服务,连续模式保持服务运行 |
271
273
  | 9 | `toolGuidance` | 始终注入 | 全局:工具使用规范(Grep/Glob/Read/LS/MultiEdit/Task 替代 bash 命令),非 Claude 模型必需 |
@@ -406,7 +408,8 @@ Harness 在 `buildCodingPrompt()` 中预读 `session_result.json`,将上次会
406
408
  | `tasks.json` | Agent(仅 `status` 字段) | 修改 `status` | tracked |
407
409
  | `project_profile.json` | Agent(仅扫描阶段) | 扫描时写入 | tracked |
408
410
  | `test.env` | Agent + 用户 | 可追加写入 | .gitignore |
409
- | `playwright-auth.json` | 用户(`claude-coder auth`) | 只读 | .gitignore |
411
+ | `playwright-auth.json` | 用户(`claude-coder auth`) | 快照备份 | .gitignore |
412
+ | `browser-profile/` | 用户(`claude-coder auth`) | MCP 自动维护 | .gitignore |
410
413
 
411
414
  ---
412
415
 
@@ -13,7 +13,7 @@ claude-coder 的核心目标是让 Agent **完全自主测试**,不因凭证
13
13
  **核心原则**:
14
14
  1. **Agent 可自行发现并持久化凭证** — 测试中发现需要的 API Key 或账号,直接写入 `test.env`
15
15
  2. **凭证不受回滚影响** — `git reset --hard` 不会摧毁已保存的凭证
16
- 3. **零手动干预** — 除首次浏览器登录态外,其余由 Agent 自动处理
16
+ 3. **零手动干预** — 首次浏览器登录后,后续由持久化 profile 自动处理
17
17
 
18
18
  ---
19
19
 
@@ -23,7 +23,8 @@ claude-coder 的核心目标是让 Agent **完全自主测试**,不因凭证
23
23
  .claude-coder/
24
24
  .env ← 模型配置(ANTHROPIC_API_KEY 等) [用户配置]
25
25
  test.env ← 测试凭证(API Key、测试账号等) [Agent 可写]
26
- playwright-auth.json ← 浏览器状态(cookies + localStorage) [auth 命令生成]
26
+ playwright-auth.json ← 登录状态快照(备份参考) [auth 命令生成]
27
+ browser-profile/ ← 持久化浏览器 Profile(MCP 实际使用) [auth 命令创建]
27
28
  ```
28
29
 
29
30
  ### 文件生命周期
@@ -32,17 +33,25 @@ claude-coder 的核心目标是让 Agent **完全自主测试**,不因凭证
32
33
  |------|--------|--------|----------|----------|
33
34
  | `.env` | `claude-coder setup` | 用户 | 是 | 长期 |
34
35
  | `test.env` | Agent 或用户 | Agent + 用户 | 是 | 长期,按需更新 |
35
- | `playwright-auth.json` | `claude-coder auth` | auth 命令 | 是 | 中期,cookies 过期后需刷新 |
36
-
37
- ### 回滚保护机制
38
-
39
- Harness 在 `git reset --hard` 前备份、后恢复以下文件:
40
- - `session_result.json` 会话结果
41
- - `progress.json` — 历史记录
42
- - `test.env` 测试凭证
43
- - `playwright-auth.json` 浏览器状态
44
-
45
- 这确保无论回滚多少次,凭证始终保留。
36
+ | `playwright-auth.json` | `claude-coder auth` | auth 命令 | 是 | 快照备份,不被 MCP 直接使用 |
37
+ | `browser-profile/` | `claude-coder auth` | MCP 自动维护 | 是 | 长期,自动续期 |
38
+
39
+ ### 技术实现:为什么用 `--user-data-dir` 而不是 `--storage-state`
40
+
41
+ | 维度 | `--storage-state`(旧方案) | `--user-data-dir`(当前方案) |
42
+ |------|-------------------------|--------------------------|
43
+ | 上下文类型 | 隔离上下文(isolated) | 持久化上下文(persistent) |
44
+ | 状态保持 | 每次从 JSON 文件加载,会话结束丢弃 | Profile 自动保存,跨会话保持 |
45
+ | Cookies 续期 | 不支持(JSON 文件静态) | 支持(浏览器自动刷新的 cookies 被保留) |
46
+ | localStorage | 从 JSON 注入(可靠) | 持久保存在 Profile 中 |
47
+ | Google OAuth | 每次创建新上下文 → Google 检测到自动化 | 持久 Profile → Google 视为常规浏览器 |
48
+ | 长期运行 | 差(cookies 过期后必须重新 auth) | 优(Profile 随浏览器使用自动演进) |
49
+
50
+ > **源码依据**:Playwright MCP `contextFactory()` 在 `isolated=false` 时使用 `PersistentContextFactory`,
51
+ > 调用 `launchPersistentContext(userDataDir, options)` 创建持久化浏览器上下文。
52
+ > `--storage-state` 虽然不强制 `isolated=true`,但官方文档明确描述其为 "load into an isolated browser context",
53
+ > 且 `launchPersistentContext` 的 `storageState` 参数存在已知缺陷(Issue #14949):localStorage 不注入,
54
+ > 旧 cookies 可能覆盖 Profile 中已刷新的 cookies。
46
55
 
47
56
  ---
48
57
 
@@ -54,56 +63,47 @@ Harness 在 `git reset --hard` 前备份、后恢复以下文件:
54
63
  Agent 测试 → 发现需要 API Key → 写入 test.env → 下次 session 自动加载
55
64
  ```
56
65
 
57
- Agent 在 CLAUDE.md Step 5 中被指导:测试中发现的凭证追加到 `.claude-coder/test.env`。Harness 在每次 session 的 prompt 中注入 hint,告知 Agent `test.env` 的存在和用法。
58
-
59
66
  ### 流程 2:用户预配置浏览器登录态
60
67
 
61
68
  ```
62
- 用户运行 claude-coder auth → 手动登录 → 状态自动保存 → Agent 测试时使用
69
+ 用户运行 claude-coder auth url
70
+ → playwright codegen 打开浏览器 → 手动登录 → 关闭浏览器
71
+ → cookies + localStorage 保存为快照备份(playwright-auth.json)
72
+ → 创建 browser-profile/ 目录
73
+ → 更新 .mcp.json(--user-data-dir 指向 browser-profile/)
74
+ → 首次 MCP 会话时在浏览器窗口中登录一次
75
+ → 之后 MCP 自动使用持久化 Profile,无需再次登录
63
76
  ```
64
77
 
65
- 适用于需要已登录状态才能测试的前端页面(如后台管理、需要 cookie 的 SPA)。
66
-
67
78
  ### 流程 3:用户预配置 API Key
68
79
 
69
80
  ```
70
81
  用户编辑 test.env → 填入 API Key → Agent 测试前 source 加载
71
82
  ```
72
83
 
73
- 适用于后端功能依赖真实 API 调用的场景。
74
-
75
84
  ---
76
85
 
77
86
  ## CLI 命令
78
87
 
79
88
  ### `claude-coder auth [url]`
80
89
 
81
- 一键导出浏览器登录态:
90
+ 配置持久化浏览器认证:
82
91
 
83
92
  ```bash
84
93
  # 默认打开 http://localhost:3000
85
94
  claude-coder auth
86
95
 
87
- # 指定 URL
88
- claude-coder auth http://localhost:8080/admin
96
+ # 指定 URL(如内部 API 文档平台)
97
+ claude-coder auth http://testyapi.example.com/group/2245
89
98
  ```
90
99
 
91
100
  **自动完成**:
92
- 1. 启动 Playwright 浏览器,用户手动登录后关闭
93
- 2. 保存 cookies + localStorage 到 `.claude-coder/playwright-auth.json`
94
- 3. 创建/更新 `.mcp.json`,配置 `--storage-state`
95
- 4. 添加 `.gitignore` 条目
101
+ 1. 创建 `.claude-coder/browser-profile/` 持久化 Profile 目录
102
+ 2. 启动 `playwright codegen`,用户手动登录后关闭浏览器(保存快照备份)
103
+ 3. 创建/更新 `.mcp.json`,配置 `--user-data-dir=.claude-coder/browser-profile`
104
+ 4. 添加 `.gitignore` 条目(`playwright-auth.json` + `browser-profile/`)
96
105
  5. 启用 `.claude-coder/.env` 中 `MCP_PLAYWRIGHT=true`
97
106
 
98
- ### `claude-coder setup`(相关)
99
-
100
- 配置模型时可启用 Playwright MCP:
101
-
102
- ```bash
103
- claude-coder setup
104
- # 选择启用 MCP_PLAYWRIGHT=true
105
- ```
106
-
107
107
  ---
108
108
 
109
109
  ## 场景示例
@@ -111,51 +111,42 @@ claude-coder setup
111
111
  ### 场景 1:全栈项目首次测试
112
112
 
113
113
  ```bash
114
- # 1. 配置模型
115
114
  claude-coder setup
116
-
117
- # 2. 填入后端测试需要的 API Key
118
115
  cat >> .claude-coder/test.env << 'EOF'
119
116
  OPENAI_API_KEY=sk-xxx
120
- ZHIPU_API_KEY=xxx.xxx
121
117
  EOF
122
-
123
- # 3. 导出前端登录态(可选,Agent 也能用 Playwright MCP 自动登录)
124
118
  claude-coder auth http://localhost:3000
125
-
126
- # 4. 开始自动编码和测试
127
119
  claude-coder run
120
+ # 首次 MCP 访问需登录的页面时,在浏览器窗口登录一次
121
+ # 之后所有 session 自动保持登录状态
128
122
  ```
129
123
 
130
- ### 场景 2:Agent 自主发现并处理凭证缺失
131
-
132
- Agent 在测试 feat-005(AI 内容生成)时发现需要 `OPENAI_API_KEY`:
133
-
134
- 1. Agent 尝试调用 API → 报错 "API key required"
135
- 2. Agent **不中断任务**,改用替代验证方式(如 mock 响应、检查代码逻辑是否正确、验证接口可达性)
136
- 3. Agent 将凭证需求写入 `test.env`:`echo 'OPENAI_API_KEY=需要配置' >> .claude-coder/test.env`
137
- 4. Agent 在 `session_result.json` 的 notes 中记录:"AI 内容生成功能已实现,但需要真实 OPENAI_API_KEY 才能完整测试,已记录到 test.env"
138
- 5. Agent 完成其他可验证的步骤后标记任务为 `done`(功能已实现)或 `testing`(等待凭证后完整验证)
124
+ ### 场景 2:内部系统(Google OAuth / SSO)
139
125
 
140
- **核心原则**:缺少凭证不等于任务失败。Agent 应最大化推进,将凭证问题记录为后续补充项,而非阻塞整个 session。
126
+ ```bash
127
+ claude-coder auth http://testyapi.example.com/group/2245
128
+ # 在弹出的浏览器中完成 Google 登录(快照备份)
129
+ # 首次 MCP 会话时在浏览器窗口中再次登录
130
+ # 之后持久化 Profile 自动保持 Google 登录状态
131
+ ```
141
132
 
142
- ### 场景 3:前端 localStorage 配置持久化
133
+ > **关于 Google OAuth 检测**:使用 `--user-data-dir` 持久化 Profile 后,Google 将浏览器视为
134
+ > "回访用户"而非"新自动化会话",大幅降低重复登录要求。如果仍被检测,可在 `.mcp.json` 中
135
+ > 添加 `--browser chrome` 使用真实 Chrome 进一步降低检测率。
143
136
 
144
- 项目的前端将 LLM 服务商配置存储在 localStorage 中:
137
+ ### 场景 3:长期运行(核心优势)
145
138
 
146
139
  ```bash
147
- # 启动前后端服务
148
- # 运行 auth,手动在页面中配置 LLM 设置
149
- claude-coder auth http://localhost:3000
150
-
151
- # playwright-auth.json 中已包含 localStorage 数据
152
- # 后续 Agent 使用 Playwright MCP 测试时自动加载这些配置
140
+ claude-coder run --max-sessions 50
141
+ # 浏览器 Profile 自动保持:
142
+ # - cookies 被网站刷新时,新 cookies 自动写入 Profile
143
+ # - 不依赖静态 JSON 文件,状态持续演进
144
+ # - 即使中途重启 claude-coder,Profile 中的登录状态仍然有效
153
145
  ```
154
146
 
155
- ### 场景 4:cookies 过期后刷新
147
+ ### 场景 4:清除登录状态
156
148
 
157
149
  ```bash
158
- # 重新运行 auth 即可
159
- claude-coder auth http://localhost:3000
160
- # 新的 cookies 覆盖旧文件,立即生效
150
+ rm -rf .claude-coder/browser-profile/
151
+ # 下次 MCP 会话时将创建全新 Profile,需重新登录
161
152
  ```
package/docs/README.en.md CHANGED
@@ -85,7 +85,8 @@ your-project/
85
85
  progress.json # Session history + costs
86
86
  tests.json # Verification records
87
87
  test.env # Test credentials (API keys, optional)
88
- playwright-auth.json # Playwright login state (optional, via auth command)
88
+ playwright-auth.json # Login state snapshot (backup, via auth command)
89
+ browser-profile/ # Persistent browser profile (used by MCP)
89
90
  .runtime/ # Temp files
90
91
  logs/ # Per-session logs (with tool call traces)
91
92
  requirements.md # Requirements (optional)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-coder",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "Claude Coder — Autonomous coding agent harness powered by Claude Code SDK. Scan, plan, code, validate, git-commit in a loop.",
5
5
  "bin": {
6
6
  "claude-coder": "bin/cli.js"
package/src/auth.js CHANGED
@@ -18,7 +18,7 @@ function updateGitignore(entry) {
18
18
  log('ok', `.gitignore 已添加: ${entry}`);
19
19
  }
20
20
 
21
- function updateMcpConfig(authFilePath) {
21
+ function updateMcpConfig(browserProfileDir) {
22
22
  const p = paths();
23
23
  let mcpConfig = {};
24
24
  if (fs.existsSync(p.mcpConfig)) {
@@ -31,17 +31,17 @@ function updateMcpConfig(authFilePath) {
31
31
 
32
32
  if (!mcpConfig.mcpServers) mcpConfig.mcpServers = {};
33
33
 
34
- const relAuthPath = path.relative(getProjectRoot(), authFilePath);
34
+ const relProfileDir = path.relative(getProjectRoot(), browserProfileDir);
35
35
  mcpConfig.mcpServers.playwright = {
36
36
  command: 'npx',
37
37
  args: [
38
38
  '@playwright/mcp@latest',
39
- `--storage-state=${relAuthPath}`,
39
+ `--user-data-dir=${relProfileDir}`,
40
40
  ],
41
41
  };
42
42
 
43
43
  fs.writeFileSync(p.mcpConfig, JSON.stringify(mcpConfig, null, 2) + '\n', 'utf8');
44
- log('ok', `.mcp.json 已配置 Playwright MCP (storage-state: ${relAuthPath})`);
44
+ log('ok', `.mcp.json 已配置 Playwright MCP (user-data-dir: ${relProfileDir})`);
45
45
  }
46
46
 
47
47
  function enableMcpPlaywrightEnv() {
@@ -64,14 +64,17 @@ async function auth(url) {
64
64
  const p = paths();
65
65
  const targetUrl = url || 'http://localhost:3000';
66
66
 
67
+ if (!fs.existsSync(p.browserProfile))
68
+ fs.mkdirSync(p.browserProfile, { recursive: true });
69
+
67
70
  log('info', '启动 Playwright 浏览器,请手动登录...');
68
71
  log('info', `目标 URL: ${targetUrl}`);
69
- log('info', `登录状态将保存到: ${p.playwrightAuth}`);
72
+ log('info', `浏览器配置将持久化到: ${p.browserProfile}`);
70
73
  console.log('');
71
74
  console.log('操作步骤:');
72
75
  console.log(' 1. 浏览器将自动打开,请手动完成登录');
73
76
  console.log(' 2. 登录成功后关闭浏览器窗口');
74
- console.log(' 3. 登录状态(cookies + localStorage)将自动保存');
77
+ console.log(' 3. 登录状态(cookies + localStorage)将保存为快照备份');
75
78
  console.log('');
76
79
 
77
80
  try {
@@ -92,16 +95,18 @@ async function auth(url) {
92
95
  return;
93
96
  }
94
97
 
95
- log('ok', '登录状态已保存');
98
+ log('ok', '登录状态快照已保存(备份参考)');
96
99
 
97
- updateMcpConfig(p.playwrightAuth);
100
+ updateMcpConfig(p.browserProfile);
98
101
  updateGitignore('.claude-coder/playwright-auth.json');
102
+ updateGitignore('.claude-coder/browser-profile/');
99
103
  enableMcpPlaywrightEnv();
100
104
 
101
105
  console.log('');
102
- log('ok', 'Playwright 凭证配置完成!');
103
- log('info', '后续运行 claude-coder run 时,Agent 的前端测试将自动使用已认证状态');
104
- log('info', '注意: cookies 有过期时间,需要定期重新运行 claude-coder auth 更新');
106
+ log('ok', '持久化浏览器配置完成!');
107
+ log('info', 'MCP 使用 --user-data-dir 持久化模式,登录状态跨会话保持');
108
+ log('info', '首次 MCP 会话时需在浏览器窗口中登录一次,之后永久保持');
109
+ log('info', 'cookies 自动续期,无需手动重新运行 claude-coder auth');
105
110
  }
106
111
 
107
112
  module.exports = { auth };
package/src/config.js CHANGED
@@ -57,6 +57,7 @@ function paths() {
57
57
  testsFile: path.join(loopDir, 'tests.json'),
58
58
  testEnvFile: path.join(loopDir, 'test.env'),
59
59
  playwrightAuth: path.join(loopDir, 'playwright-auth.json'),
60
+ browserProfile: path.join(loopDir, 'browser-profile'),
60
61
  mcpConfig: path.join(getProjectRoot(), '.mcp.json'),
61
62
  claudeMd: getTemplatePath('CLAUDE.md'),
62
63
  scanProtocol: getTemplatePath('SCAN_PROTOCOL.md'),
package/src/indicator.js CHANGED
@@ -17,11 +17,13 @@ class Indicator {
17
17
  this.sessionNum = 0;
18
18
  this.startTime = Date.now();
19
19
  this._lastContentKey = '';
20
+ this._lastRenderTime = 0;
20
21
  }
21
22
 
22
23
  start(sessionNum) {
23
24
  this.sessionNum = sessionNum;
24
25
  this.startTime = Date.now();
26
+ this._lastRenderTime = Date.now();
25
27
  this.timer = setInterval(() => this._render(), 500);
26
28
  }
27
29
 
@@ -87,6 +89,16 @@ class Indicator {
87
89
 
88
90
  _render() {
89
91
  this.spinnerIndex++;
92
+ const contentKey = `${this.phase}|${this.step}|${this.toolTarget}`;
93
+ const now = Date.now();
94
+ const contentChanged = contentKey !== this._lastContentKey;
95
+
96
+ if (!contentChanged && now - this._lastRenderTime < 3000) {
97
+ return;
98
+ }
99
+ this._lastContentKey = contentKey;
100
+ this._lastRenderTime = now;
101
+
90
102
  const line = this.getStatusLine();
91
103
  const maxWidth = process.stderr.columns || 80;
92
104
  const truncated = line.length > maxWidth + 20 ? line.slice(0, maxWidth + 20) : line;
package/src/prompts.js CHANGED
@@ -97,10 +97,12 @@ function buildCodingPrompt(sessionNum, opts = {}) {
97
97
  testEnvHint = `如需持久化测试凭证(API Key、测试账号密码等),写入 ${projectRoot}/.claude-coder/test.env(KEY=value 格式,每行一个)。后续 session 会自动感知。`;
98
98
  }
99
99
 
100
- // Hint 6c: Playwright authenticated state
100
+ // Hint 6c: Playwright persistent browser profile
101
101
  let playwrightAuthHint = '';
102
- if (p.playwrightAuth && fs.existsSync(p.playwrightAuth)) {
103
- playwrightAuthHint = `已检测到 Playwright 登录状态(${projectRoot}/.claude-coder/playwright-auth.json),前端/全栈测试将使用已认证的浏览器会话(含 cookies localStorage)。`;
102
+ if (fs.existsSync(p.browserProfile)) {
103
+ playwrightAuthHint = `已检测到持久化浏览器配置(${projectRoot}/.claude-coder/browser-profile/),MCP 使用 --user-data-dir 模式,登录状态跨会话自动保持。首次访问需登录的页面时,用户需在浏览器窗口中手动完成登录。`;
104
+ } else if (fs.existsSync(p.playwrightAuth)) {
105
+ playwrightAuthHint = `已检测到 Playwright 登录状态快照(${projectRoot}/.claude-coder/playwright-auth.json),建议运行 claude-coder auth 升级到持久化浏览器模式以获得更好的登录保持效果。`;
104
106
  }
105
107
 
106
108
  // Hint 7: Session memory (read flat session_result.json)
@@ -51,7 +51,8 @@
51
51
  | `.claude-coder/session_result.json` | 本次会话的结构化输出 | 每次会话结束时覆盖写入 |
52
52
  | `.claude-coder/tests.json` | 功能验证记录(轻量) | 可新增和更新;仅当功能涉及 API 或核心逻辑时记录 |
53
53
  | `.claude-coder/test.env` | 测试凭证(API Key、测试账号等) | **可追加写入**;发现测试需要的凭证时持久化到此文件 |
54
- | `.claude-coder/playwright-auth.json` | 浏览器登录状态(cookies + localStorage) | 只读;由用户通过 `claude-coder auth` 预配置 |
54
+ | `.claude-coder/playwright-auth.json` | 登录状态快照(备份参考) | 只读;由 `claude-coder auth` 生成 |
55
+ | `.claude-coder/browser-profile/` | 持久化浏览器 Profile | MCP 自动维护;首次需手动登录,之后永久保持 |
55
56
 
56
57
  ### requirements.md 处理原则
57
58