diff --git a/Agent.md b/Agent.md index 1260d8d1..842f48bd 100644 --- a/Agent.md +++ b/Agent.md @@ -120,7 +120,7 @@ pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.token; python -m emrg ``` Python: `uv run pytest tests/ -v` (1106) — import check: `uv run python -c "from emrg.client.app import run_client"` -GUI: `cd emrg/gui && npm test` (265: 45 daemon_client + 20 conn-manager + 22 app-commands + 132 renderer smoke + 15 i18n + 8 integration + 3 commands + 8 build-config + 7 gui-state + 2 tool-group + 3 preload-api) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js`; renderer React suite: `cd emrg/gui/renderer && npm run typecheck && npm test` (168 vitest: 5 snapshot-store + 9 utils + 3 ErrorBoundary + 2 App smoke + 11 commands + 4 copywriting + 11 i18n + 11 markdown + 15 transcript + 7 TranscriptView + 15 history + 22 composer + 14 Composer + 12 sidebar + 10 Sidebar + 9 fileTree + 8 FileTree) + `npm run build` → `renderer/dist/` +GUI: `cd emrg/gui && npm test` (265: 45 daemon_client + 20 conn-manager + 22 app-commands + 132 renderer smoke + 15 i18n + 8 integration + 3 commands + 8 build-config + 7 gui-state + 2 tool-group + 3 preload-api) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js`; renderer React suite: `cd emrg/gui/renderer && npm run typecheck && npm test` (169 vitest: 5 snapshot-store + 9 utils + 3 ErrorBoundary + 2 App smoke + 11 commands + 4 copywriting + 11 i18n + 11 markdown + 15 transcript + 7 TranscriptView + 15 history + 22 composer + 14 Composer + 12 sidebar + 10 Sidebar + 9 fileTree + 9 FileTree) + `npm run build` → `renderer/dist/` CI: `uv run pytest` (ubuntu + **windows-2025 matrix** — Windows pytest 回归在 PR CI 即失败,v0.2.29 教训 #725) + GUI tests + **actionlint workflow lint** (`rhysd/actionlint@v1.7.12` gate, #444 — workflow 解析错误在 PR CI 即失败,如 `if:` secrets 上下文) Re-trigger: `scripts/re-trigger-ci.sh [branch]` (workflow_dispatch, #527 — 替代空 commit 重触发:Actions outage 会整段丢弃 push 事件,dispatch 走 API 路径不受影响) Git-over-https 兜底: `python scripts/sync-master-from-api.py [--repo owner/name] [--ref master]` — 受限网络下 github.com:443 不可达而 api.github.com 可达时,用 Git Data API 的 verification payload + signature 字节级重建上游 commit(含 web-flow GPG 签名 squash merge,reconstruct_commit 经 hermetic 测试验证 sha 一致)并推进本地 refs;内容对象缺失时 fail-loud 提示改用 git fetch(10+ 周期实证的恢复路径) diff --git a/emrg/gui/renderer/src/components/FileTree.test.tsx b/emrg/gui/renderer/src/components/FileTree.test.tsx index 142323c6..1b1a4292 100644 --- a/emrg/gui/renderer/src/components/FileTree.test.tsx +++ b/emrg/gui/renderer/src/components/FileTree.test.tsx @@ -92,6 +92,19 @@ describe("FileTree", () => { await waitFor(() => expect(screen.getByText("LOAD_FAILED")).toBeInTheDocument()); }); + it("嵌套目录加载失败 → 子目录行内显示失败提示(根成功,回归 #999 审查发现)", async () => { + const listFiles = vi.fn(async (path: string) => { + if (path === "/proj/src") throw new Error("boom"); + return { entries: [dir("src", "/proj/src")] }; + }); + setup({ listFiles, t: (k) => (k === "result.treeLoadFailed" ? "LOAD_FAILED" : k) }); + await waitFor(() => expect(screen.getByText("src")).toBeInTheDocument()); + await userEvent.click(screen.getByText("src").closest(".ft-row")!); + // 修复前:子目录 catch 置 loaded:true + error:true,但提示条件要求 + // !st.loaded(永假)→ 失败静默;修复后与根错误路径一致(st.loaded && st.error) + await waitFor(() => expect(screen.getByText("LOAD_FAILED")).toBeInTheDocument()); + }); + it("root 为空 → 显示 empty 提示(result.filesEmpty)", () => { setup({ root: "" }); expect(screen.getByTestId("filetree-empty")).toHaveTextContent("No workspace"); diff --git a/emrg/gui/renderer/src/components/FileTree.tsx b/emrg/gui/renderer/src/components/FileTree.tsx index 4cf75f1a..7636eb62 100644 --- a/emrg/gui/renderer/src/components/FileTree.tsx +++ b/emrg/gui/renderer/src/components/FileTree.tsx @@ -96,7 +96,7 @@ function FileTreeNode({ {isDir && (
- {expanded && st && !st.loaded && !st.loading && st.error && ( + {expanded && st && st.loaded && st.error && (
{t("result.treeLoadFailed")}
)} {expanded && st && st.loading && !st.loaded && (