@yeaft/webchat-agent 0.0.173 → 0.0.175

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 (3) hide show
  1. package/crew.js +97 -33
  2. package/index.js +1 -1
  3. package/package.json +1 -1
package/crew.js CHANGED
@@ -313,7 +313,8 @@ async function saveSessionMeta(session) {
313
313
  status: session.status,
314
314
  roles: Array.from(session.roles.values()).map(r => ({
315
315
  name: r.name, displayName: r.displayName, icon: r.icon,
316
- description: r.description, isDecisionMaker: r.isDecisionMaker || false
316
+ description: r.description, isDecisionMaker: r.isDecisionMaker || false,
317
+ groupIndex: r.groupIndex, roleType: r.roleType, model: r.model
317
318
  })),
318
319
  decisionMaker: session.decisionMaker,
319
320
  maxRounds: session.maxRounds,
@@ -494,7 +495,8 @@ export async function resumeCrewSession(msg) {
494
495
  sharedKnowledge: session.sharedKnowledge || '',
495
496
  roles: roles.map(r => ({
496
497
  name: r.name, displayName: r.displayName, icon: r.icon,
497
- description: r.description, isDecisionMaker: r.isDecisionMaker || false
498
+ description: r.description, isDecisionMaker: r.isDecisionMaker || false,
499
+ groupIndex: r.groupIndex, roleType: r.roleType, model: r.model
498
500
  })),
499
501
  decisionMaker: session.decisionMaker,
500
502
  maxRounds: session.maxRounds,
@@ -567,7 +569,8 @@ export async function resumeCrewSession(msg) {
567
569
  sharedKnowledge: session.sharedKnowledge || '',
568
570
  roles: roles.map(r => ({
569
571
  name: r.name, displayName: r.displayName, icon: r.icon,
570
- description: r.description, isDecisionMaker: r.isDecisionMaker || false
572
+ description: r.description, isDecisionMaker: r.isDecisionMaker || false,
573
+ groupIndex: r.groupIndex, roleType: r.roleType, model: r.model
571
574
  })),
572
575
  decisionMaker,
573
576
  maxRounds: session.maxRounds,
@@ -666,20 +669,6 @@ export async function createCrewSession(msg) {
666
669
  }
667
670
  }
668
671
 
669
- // 生成组名
670
- const groupNames = {};
671
- const maxGroup = Math.max(0, ...roles.map(r => r.groupIndex || 0));
672
- for (let g = 1; g <= maxGroup; g++) {
673
- const members = roles.filter(r => r.groupIndex === g);
674
- const hasRev = members.some(r => r.roleType === 'reviewer');
675
- const hasTest = members.some(r => r.roleType === 'tester');
676
- if (hasRev && hasTest) {
677
- groupNames[g] = maxGroup > 1 ? `全栈开发组 ${g}` : '全栈开发组';
678
- } else {
679
- groupNames[g] = maxGroup > 1 ? `开发组 ${g}` : '开发组';
680
- }
681
- }
682
-
683
672
  // 找到决策者
684
673
  const decisionMaker = roles.find(r => r.isDecisionMaker)?.name || roles[0]?.name || null;
685
674
 
@@ -705,7 +694,6 @@ export async function createCrewSession(msg) {
705
694
  waitingHumanContext: null, // { fromRole, reason, message }
706
695
  pendingRoutes: [], // [{ fromRole, route }] — 暂停时未完成的路由
707
696
  features: new Map(), // taskId → { taskId, taskTitle, createdAt } — 持久化 feature 列表
708
- groupNames, // groupIndex → 组名
709
697
  userId,
710
698
  username,
711
699
  agentId: ctx.CONFIG?.agentName || null,
@@ -735,7 +723,6 @@ export async function createCrewSession(msg) {
735
723
  })),
736
724
  decisionMaker,
737
725
  maxRounds,
738
- groupNames,
739
726
  userId,
740
727
  username
741
728
  });
@@ -998,6 +985,50 @@ ${roles.length > 0 ? roles.map(r => `- ${roleLabel(r)}(${r.name}): ${r.descripti
998
985
  - PM 不做 cherry-pick,只负责打 tag
999
986
  - 每次新任务/新 feature 必须基于最新的 main 分支创建新的 worktree,确保在最新代码上开发
1000
987
 
988
+ # Feature 进度管理
989
+ 每个 Feature 使用独立的进度文件来跟踪状态,存放在 context/features/ 目录下。
990
+
991
+ ## 文件命名规范
992
+ - 文件名格式: \`context/features/{task-id}.md\`(如 \`context/features/task-1.md\`)
993
+ - 由 PM 在分配任务时指示 developer 创建初始文件
994
+
995
+ ## 文件格式
996
+ \`\`\`markdown
997
+ # Feature: {taskTitle}
998
+ - task-id: {task-id}
999
+ - 状态: 待开发 | 开发中 | 待审查 | 审查中 | 已完成 | 已阻塞
1000
+ - 负责人: {dev角色name}
1001
+ - 审查者: {reviewer角色name}
1002
+ - 测试者: {tester角色name}
1003
+ - 创建时间: {ISO时间}
1004
+
1005
+ ## 需求描述
1006
+ {PM写的需求}
1007
+
1008
+ ## 实现记录
1009
+ _由开发者填写_
1010
+
1011
+ ## 审查记录
1012
+ _由审查者填写_
1013
+
1014
+ ## 测试记录
1015
+ _由测试者填写_
1016
+ \`\`\`
1017
+
1018
+ ## 状态流转规则
1019
+ 1. PM 创建文件 → 状态「待开发」
1020
+ 2. dev 开始工作 → 更新为「开发中」,填写实现方案
1021
+ 3. dev 完成 → 更新为「待审查」,记录改动摘要(reviewer 和 tester 并行工作)
1022
+ 4. reviewer/tester 开始工作 → 更新为「审查中」,各自填写审查/测试记录
1023
+ 5. 发现问题需返工 → 更新回「开发中」
1024
+ 6. 全部通过 → PM 更新为「已完成」
1025
+
1026
+ ## 角色职责
1027
+ - **PM**: 规划 feature 文件(通过 ROUTE 让 dev 创建),填写需求描述,最终标记完成
1028
+ - **Developer**: 更新开发状态,填写「实现记录」(方案、改动文件、注意事项)
1029
+ - **Reviewer**: 填写「审查记录」(评分、问题列表、是否通过)
1030
+ - **Tester**: 填写「测试记录」(测试用例、结果、发现的 Bug)
1031
+
1001
1032
  ${sharedMemoryContent}`;
1002
1033
 
1003
1034
  await fs.writeFile(join(sharedDir, 'CLAUDE.md'), claudeMd);
@@ -1238,19 +1269,12 @@ ${routeTargets.map(r => `- ${r.name}: ${roleLabel(r)} — ${r.description}`).joi
1238
1269
  // 决策者额外 prompt
1239
1270
  if (role.isDecisionMaker) {
1240
1271
 
1241
- prompt += `\n\n# 工具使用限制(绝对禁令)
1242
- 你**绝对不能**使用以下工具修改任何文件:
1243
- - Edit 工具 — 禁止
1244
- - Write 工具 — 禁止
1245
- - NotebookEdit 工具 — 禁止
1272
+ prompt += `\n\n# 工具使用规则
1273
+ 你**不能**使用 Edit/Write/NotebookEdit 工具修改代码文件(.js/.ts/.jsx/.tsx/.css/.html/.vue/.py/.go/.rs/.java/.c/.cpp/.h/.rb/.php/.swift/.kt 等源代码文件)。
1274
+ 你**可以**使用这些工具修改文档和配置文件(.md/.json/.yaml/.yml/.toml/.txt/.env/.gitignore 等非代码文件)。
1275
+ 你**可以**使用:Read、Grep、Glob、Bash(git 命令和只读命令)。
1246
1276
 
1247
- 你**可以**使用的工具:
1248
- - Read — 读取文件内容
1249
- - Grep — 搜索代码
1250
- - Glob — 查找文件
1251
- - Bash — 仅限 git 命令(git status/add/commit/push/tag/log/diff)和只读命令
1252
-
1253
- 如果你需要修改任何文件(无论多小的改动),必须 ROUTE 给 developer 执行。`;
1277
+ 代码改动必须 ROUTE 给 developer 执行。文档和配置可以自己改。`;
1254
1278
 
1255
1279
  prompt += `\n\n# 决策者职责
1256
1280
  你是团队的决策者。其他角色遇到不确定的情况会请求你的决策。
@@ -1335,6 +1359,47 @@ summary: 请实现注册页面,包括邮箱验证
1335
1359
  - TASKS 块不需要在回复最末尾,可以放在任意位置`;
1336
1360
  }
1337
1361
 
1362
+ // Feature 进度记录要求(按角色类型注入)
1363
+ if (role.isDecisionMaker) {
1364
+ prompt += `\n\n# Feature 进度文件管理
1365
+ 当你分配任务时,需要确保对应的 feature 进度文件被创建:
1366
+ 1. 文件路径: \`context/features/{task-id}.md\`(如 \`context/features/task-1.md\`)
1367
+ 2. 使用共享 CLAUDE.md 中定义的文件格式,填写需求描述
1368
+ 3. 初始状态设为「待开发」
1369
+ 4. 所有子任务完成后,通过 ROUTE 让 dev 将状态更新为「已完成」
1370
+
1371
+ 因为你不能使用 Write/Edit 工具,feature 文件的创建和更新都通过 ROUTE 给 developer 执行。在 ROUTE 的 summary 中明确要求 dev 创建/更新 feature 文件,并提供需求描述内容。`;
1372
+ } else if (role.roleType === 'developer') {
1373
+ prompt += `\n\n# Feature 进度记录
1374
+ 收到任务后,你必须维护 feature 进度文件 \`context/features/{task-id}.md\`:
1375
+ 1. 如果 PM 要求创建 feature 文件,先创建它(确保 context/features/ 目录存在)
1376
+ 2. 开始开发时:将状态更新为「开发中」
1377
+ 3. 开发完成时:将状态更新为「待审查」,在「实现记录」中填写:
1378
+ - 实现方案概述
1379
+ - 修改的文件列表
1380
+ - 需要注意的事项
1381
+ 4. 收到审查/测试反馈需要修改时:将状态更新回「开发中」,追加修改记录`;
1382
+ } else if (role.roleType === 'reviewer') {
1383
+ prompt += `\n\n# Feature 进度记录
1384
+ 完成代码审查后,你必须更新 feature 进度文件 \`context/features/{task-id}.md\`:
1385
+ 1. 在「审查记录」中填写:
1386
+ - 代码质量评分(10分制)
1387
+ - 发现的问题列表(如有)
1388
+ - 审查结论(通过/需修改)
1389
+ 2. 如果审查通过:不修改状态(等测试也通过后由 PM 标记完成)
1390
+ 3. 如果需要修改:将状态更新为「开发中」`;
1391
+ } else if (role.roleType === 'tester') {
1392
+ prompt += `\n\n# Feature 进度记录
1393
+ 完成测试后,你必须更新 feature 进度文件 \`context/features/{task-id}.md\`:
1394
+ 1. 在「测试记录」中填写:
1395
+ - 测试用例列表及结果
1396
+ - 发现的 Bug(如有)
1397
+ - 测试结论(通过/不通过)
1398
+ 2. 如果测试通过:不修改状态(等审查也通过后由 PM 标记完成)
1399
+ 3. 如果发现 Bug:将状态更新为「开发中」`;
1400
+ }
1401
+ // designer 等其他角色不需要维护 feature 进度文件,无需注入额外 prompt
1402
+
1338
1403
  // 执行者角色的组绑定 prompt(count > 1 时)
1339
1404
  if (role.groupIndex > 0 && role.roleType === 'developer') {
1340
1405
  const gi = role.groupIndex;
@@ -2675,8 +2740,7 @@ function sendStatusUpdate(session) {
2675
2740
  .filter(([, s]) => s.turnActive && s.currentTool)
2676
2741
  .map(([name, s]) => [name, s.currentTool])
2677
2742
  ),
2678
- features: Array.from(session.features.values()),
2679
- groupNames: session.groupNames || {}
2743
+ features: Array.from(session.features.values())
2680
2744
  });
2681
2745
 
2682
2746
  // 异步更新持久化
package/index.js CHANGED
@@ -59,7 +59,7 @@ const fileConfig = loadConfig();
59
59
  const CONFIG = {
60
60
  serverUrl: process.env.SERVER_URL || fileConfig.serverUrl,
61
61
  agentName: process.env.AGENT_NAME || fileConfig.agentName,
62
- workDir: process.env.WORK_DIR || fileConfig.workDir,
62
+ workDir: process.env.WORK_DIR || fileConfig.workDir || process.cwd(),
63
63
  reconnectInterval: fileConfig.reconnectInterval,
64
64
  agentSecret: process.env.AGENT_SECRET || fileConfig.agentSecret,
65
65
  // MCP 白名单:只允许这些 MCP 服务器的工具,其余自动禁用
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.0.173",
3
+ "version": "0.0.175",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",