From f512a0f3fd2b8a4f74f1ba530bde17e6c212205a Mon Sep 17 00:00:00 2001 From: "xiaohan.yuan" Date: Wed, 21 Oct 2026 13:07:49 +0800 Subject: [PATCH] docs: add executable steps for predictable dev startup --- AGENTS.md | 7 ++ docs/协作/Dev启动SOP.md | 161 ++++++++++++++++++++++++++++++++ docs/协作/开发与验收协作流程.md | 2 + 3 files changed, 170 insertions(+) create mode 100644 docs/协作/Dev启动SOP.md diff --git a/AGENTS.md b/AGENTS.md index 365b4ea..7360b3b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,12 @@ # YCode 项目约定 +## 启动 dev + +- 用户要求启动、重启、启动当前/最新代码或用子代理启动 dev 时,先读并执行 `docs/协作/Dev启动SOP.md`。 +- 首个执行动作是检查目标目录、Git 版本和已有 dev;不要先做业务调研、REA、全量测试或依赖升级。 +- 当前代码保留本地状态;最新代码显式同步 `gitea/master`。不猜目录、不覆盖脏工作区、不复用固定版本验收目录。 +- 设置 `YCODE_SKIP_KERNEL_DATA_RESET=1` 后在同一进程运行 dev,保留 exec session;以实际端口、对应 renderer 与可响应窗口作为成功依据。 + ## 当前目标(2026-10-15 用户确认) - 借助 REA,按 WorkBuddy 的视觉、交互和功能进行 1:1 复刻。 diff --git a/docs/协作/Dev启动SOP.md b/docs/协作/Dev启动SOP.md new file mode 100644 index 0000000..455ec33 --- /dev/null +++ b/docs/协作/Dev启动SOP.md @@ -0,0 +1,161 @@ +# YCode Dev 启动 SOP + +适用:用户说“启动 dev”“启动当前代码”“启动最新代码”“使用子代理启动”。这是执行任务,目标是让正确版本的真实窗口可用;不要先做业务调研、REA、方案设计、全量测试或依赖升级。 + +## 0. 先选目录和版本 + +按顺序选,不猜: + +1. 用户明确指定路径/版本时,使用指定目标。 +2. 用户说“当前/本地代码”时,使用已确认的用户预览目录,保留本地修改,不自动同步远端。 +3. 用户说“最新代码”或明确要求同步时,目标是 fetch 后的 **`gitea/master`**,在干净的用户预览检出同步。 +4. 用户只说“启动 dev”时,复用上次确认的用户预览目录,不擅自切分支或换目录。 + +**当前验收电脑的用户预览目录:** + +```text +C:\Users\Administrator\.codex\worktrees\workbuddy-alignment-audit\YCode +``` + +这不是跨机器通用路径。另一台电脑以用户明确指定的开发目录为准,不照搬该路径。下列命令中的 `$devRoot` 都须一致指向目标目录。 + +- `C:\Users\Administrator\code\YCode` 是当前对话原工作区,可能停留在旧 master 并有文档修改,不能仅因它是环境 cwd 就拿来启动最新版本。 +- `b01-accept-01` 等验收检出不用于用户预览;已有验收进程可能正在被另一任务使用,不顺手停止或更新。 +- `b01-review-records` 是协作文档检出,也不是默认 dev 目录。 +- 不记忆某个旧 SHA 作为“最新”;每次从实际 Git 状态取值。 + +如果预览目录不存在,用应用的 `list_artifacts` 查找可复用检出;没有适用检出时用 `create_worktree(ref="gitea/master")` 创建。等待工具返回最终路径后,再继续。不要覆盖用户原目录或重用固定版本验收目录。 + +## 1. 首次工具动作:检查 Git 和正在运行的 dev + +在选定目录执行下面命令。`exec_command` 的 `workdir` 也设为该目录。 + +```powershell +$devRoot = 'C:\Users\Administrator\.codex\worktrees\workbuddy-alignment-audit\YCode' +git -C $devRoot rev-parse --show-toplevel +git -C $devRoot rev-parse HEAD +git -C $devRoot status --short +Get-CimInstance Win32_Process | + Where-Object { $_.Name -eq 'node.exe' -and $_.CommandLine -match 'electron-vite' } | + Select-Object ProcessId, ParentProcessId, CommandLine | Format-List +Get-Process electron -ErrorAction SilentlyContinue | + Where-Object { $_.MainWindowHandle -ne 0 } | + Select-Object Id, MainWindowTitle, Responding | Format-Table +``` + +执行规则: + +- 当前目录、版本均正确且已正常运行:直接核验并复用,不再执行第二次 `npm run dev`。 +- “当前代码”允许保留脏工作区;报告 SHA 时同时说明有本地修改,不能把它称为纯提交版本。 +- “最新代码”遇到脏工作区:不要 stash、reset、清理或直接合并;换干净预览检出,保留原修改。 +- 需要停止旧 dev 时,先用命令行、进程树确认属于**目标预览目录**,再只停止对应的主 Electron 与 Vite 进程。不要使用 `Stop-Process -Name node,electron` 等批量操作,也不要复制本文中的历史 PID。 +- 不知道进程归属时先不停止。Vite 可使用其他端口;最后必须说明实际端口。 + +## 2. 仅“最新代码”执行同步 + +“当前/本地代码”跳过本节。干净的预览检出执行: + +```powershell +$devRoot = 'C:\Users\Administrator\.codex\worktrees\workbuddy-alignment-audit\YCode' +if (git -C $devRoot status --porcelain) { throw '目标有本地修改,改用干净预览检出' } +git -C $devRoot fetch gitea +if ($LASTEXITCODE -ne 0) { throw 'fetch 失败,尚未确认最新版本' } +git -C $devRoot merge --ff-only --quiet gitea/master +if ($LASTEXITCODE -ne 0) { throw '无法快进,不要强制覆盖;改用干净检出' } +git -C $devRoot rev-parse HEAD +git -C $devRoot rev-parse gitea/master +``` + +末尾两个完整 SHA 必须相同。不要使用 `origin`、强制推送或 `reset --hard`。fetch 失败可以报告失败并保留已有窗口,但不能把缓存中的版本称为“已同步最新”。 + +## 3. 启动,只运行 dev + +已有可用依赖就复用,用户预览不要求每次重装。正式独立验收另按[协作流程](开发与验收协作流程.md),不能用预览复用依赖替代验收。 + +使用 `exec_command`: + +- `workdir`:选定的 `$devRoot`。 +- `yield_time_ms`:`1000`。 +- `cmd`:下面整块命令。 + +```powershell +$devRoot = 'C:\Users\Administrator\.codex\worktrees\workbuddy-alignment-audit\YCode' +Set-Location -LiteralPath $devRoot +$env:YCODE_SKIP_KERNEL_DATA_RESET = '1' +npm run dev +``` + +**保留返回的 session ID,拿到启动日志即继续核验,不等待 dev 自己退出。** + +- 环境变量必须与 npm 在同一命令/进程设置;不要假定不同 exec 调用会保留变量。 +- `YCODE_SKIP_KERNEL_DATA_RESET=1` 防止启动迁移清理正常用户数据,不能漏。 +- 普通预览不新设 `YCODE_QA_OFFSCREEN`、`YCODE_QA_DIRECTORY`、临时 `YCODE_USER_DATA_DIR`。若已有这些变量,先核对其用途,不要意外启动隐藏窗口或测试数据。 +- 不用 `npm run build`/preview 替代 dev;electron-vite dev 会构建需要的 main/preload。 +- 不额外开启可见终端,不用 `Start-Job` 或另建复杂后台服务。现有 exec session 就能承载 dev。 +- 端口以日志中的 `Local: http://localhost:.../` 为准,不能硬写 5173。 + +缺依赖时才执行 `npm ci --legacy-peer-deps --no-audit --no-fund`,不得升级 package.json 或锁文件。如果当前 npm 明确跳过 Electron postinstall 且 Electron 无法启动,执行项目现有的 `node node_modules/electron/install.js`,不要全局放开所有未知安装脚本。 + +## 4. 必须核验窗口,不能见到 Local URL 就宣布成功 + +至少核对: + +1. 目标目录的 Git SHA;最新模式与此次 fetch 的 `gitea/master` 一致。 +2. Vite 日志中的实际端口和 node 命令行指向选定预览目录。 +3. 有对应的真实 YCode 窗口,`Responding=True`。 +4. 对应 renderer 的 `--app-path` 指向选定目录;HTTP 能返回该目录的组件。不是另一个旧窗口刚好叫 YCode。 + +下面是只读核验命令,`$devPort` 要填本次日志中的端口: + +```powershell +$devRoot = 'C:\Users\Administrator\.codex\worktrees\workbuddy-alignment-audit\YCode' +$devPort = 5174 # 示例值;必须按本次启动日志修改 +git -C $devRoot rev-parse HEAD +Get-NetTCPConnection -State Listen -LocalPort $devPort | + Select-Object LocalPort, OwningProcess +Get-CimInstance Win32_Process | + Where-Object { $_.Name -eq 'electron.exe' -and $_.CommandLine -match '--type=renderer' } | + Select-Object ProcessId, ParentProcessId, CommandLine | Format-List +Get-Process electron -ErrorAction SilentlyContinue | + Where-Object { $_.MainWindowHandle -ne 0 } | + Select-Object Id, MainWindowTitle, Responding | Format-Table +$response = Invoke-WebRequest -Uri "http://localhost:$devPort/src/components/ChatPane.tsx" -UseBasicParsing +Write-Output "RendererStatus=$($response.StatusCode)" +``` + +注意 node_modules 可能是 junction,Electron 可执行文件可能来自原仓库。判断应用目录要看 Vite 启动命令与 renderer 的 `--app-path`,不能只看 electron.exe 所在位置。 + +窗口还没出现时,读取该 exec session 输出,短暂等待后再检查;若明确报错,处理该错误。不要不断启动新实例。不要为确认界面而发送模型消息、操作用户会话或修改用户设置。 + +## 5. 用户要求子代理时 + +没有明确要求就无需为启动任务额外委派。要求子代理时: + +- 使用当前 AGENTS 约定的模型与推理配置,不在 SOP 中另设模型。 +- 只派“按本 SOP 启动”,不附带源码研究、原版取证、修复、测试矩阵等任务。 +- 子代理首个执行动作是第 1 节,不先写长计划。拿到启动 session、SHA 和 URL 就回报,主线程最终核验。 +- 主线程不要每 10 秒反复询问或追加整套指令。委派后约 30 秒检查一次结果;60 秒仍未进入执行工具时,不再启动相同配置的第二个子代理。 +- 如必须接手,先中断原子代理,再重新检查进程和端口;工具启动的进程可能仍活着,不能因代理已中断就认为没有启动。能复用则复用,确认未运行才接手启动。 +- 如实际由主线程启动,最终如实说明,不能声称子代理已完成。 + +推荐委派消息: + +```text +按 docs/协作/Dev启动SOP.md 启动用户指定的 dev。 +目标目录:填已确认绝对路径;版本策略:当前代码/最新 gitea/master。 +不改源码、不提交、不运行额外测试。先执行第1节。 +拿到 SHA、URL、exec session ID 后立即回报,主线程核验窗口。 +``` + +## 6. 完成回复 + +成功必须同时有“版本正确、进程存活、真实窗口响应、renderer 正常”证据。最终回复只需: + +```text +dev 已启动,窗口正常响应。 +版本:实际短 SHA(有本地修改则注明)。 +地址:本次实际 URL。 +如并存旧 dev,明确其端口;本次操作不代表功能已验收。 +``` + +失败则写清卡在 fetch、依赖、构建、端口还是窗口,并给实际错误;不以“我会启动”“已有 Local URL”或“子代理还在运行”代替完成结果。 diff --git a/docs/协作/开发与验收协作流程.md b/docs/协作/开发与验收协作流程.md index 1b8ad11..bc69ba9 100644 --- a/docs/协作/开发与验收协作流程.md +++ b/docs/协作/开发与验收协作流程.md @@ -2,6 +2,8 @@ 更新:2026-10-21(Asia/Shanghai)。本流程以 **Gitea 为唯一交接源**;以下角色按职责定义,不使用随电脑变化的“本机/另一台”指代。 +仅启动/重启开发窗口时,直接执行 [Dev 启动 SOP](Dev启动SOP.md),不把启动任务扩展成独立验收;正式验收仍遵循下文的固定 SHA 和数据隔离要求。 + ## 1. 两台电脑,一条主线 - **开发端(用户另一台电脑上的开发对话)**:负责业务源码、测试脚本、依赖与构建配置;实现需求、自测、构建并提交交付记录。开发端可以按根目录约定委派子 agent,由开发主对话集成和自测。