Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Agent.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -121,7 +121,7 @@ pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.token; python -m emrg

Python: `uv run pytest tests/ -v` (1123) — import check: `uv run python -c "from emrg.client.app import run_client"`
GUI: `cd emrg/gui && npm test` (89: 45 daemon_client + 20 conn-manager + 8 integration + 6 build-config + 7 gui-state + 3 preload-api) — syntax: `node --check main.js preload.js daemon_client.js`
Renderer: `cd emrg/gui/renderer && npm run typecheck && npm test` (441: 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 + 17 Sidebar + 9 fileTree + 9 FileTree + 16 resultPanel + 8 ResultPanel + 29 workspaceView + 8 WorkspaceView + 10 dialog + 6 Dialog + 9 ConfirmDialog + 9 RenameDialog + 10 dialogLists + 3 HelpDialog + 9 MemoryDialog + 6 SkillsDialog + 9 openSession + 6 WelcomeDialog + 8 OpenSessionDialog + 7 NewSessionDialog + 7 rewind + 8 RewindDialog + 7 GithubDeviceDialog + 12 daemonBridge + 6 DaemonBridgeProvider + 23 Shell + 15 DialogHost + 19 SettingsPanel + 6 TaskFormDialog + 5 RantDialog + 4 vendorMarkdown) + `npm run build` → `renderer/dist/`
Renderer: `cd emrg/gui/renderer && npm run typecheck && npm test` (442: 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 + 17 Sidebar + 9 fileTree + 9 FileTree + 16 resultPanel + 8 ResultPanel + 29 workspaceView + 8 WorkspaceView + 10 dialog + 6 Dialog + 9 ConfirmDialog + 9 RenameDialog + 10 dialogLists + 3 HelpDialog + 9 MemoryDialog + 6 SkillsDialog + 9 openSession + 6 WelcomeDialog + 8 OpenSessionDialog + 7 NewSessionDialog + 7 rewind + 8 RewindDialog + 7 GithubDeviceDialog + 12 daemonBridge + 6 DaemonBridgeProvider + 24 Shell + 15 DialogHost + 19 SettingsPanel + 6 TaskFormDialog + 5 RantDialog + 4 vendorMarkdown) + `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+ 周期实证的恢复路径)
Expand Down
25 changes: 24 additions & 1 deletion emrg/gui/renderer/src/components/Shell.test.tsx
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
import type { ReactNode } from "react";
import { Shell } from "./Shell";
import { DaemonBridgeProvider } from "./DaemonBridgeProvider";
Expand DownExpand Up@@ -322,6 +322,29 @@ describe("Shell (Batch 5 slice 3 chat wiring)", () => {

// ── Batch 5 slice 8:任务表单 + Rant 对话框接线 ──

it("任务面板激活时每 5s 轮询 listTasks(vanilla startTaskPoll 语义)", async () => {
vi.useFakeTimers();
try {
const m = mockEmrg();
render(wrapper(<Shell />));
await vi.waitFor(() => expect(screen.getByTestId("composer")).toBeInTheDocument());
fireEvent.click(screen.getByTestId("nav-tasks"));
await vi.waitFor(() => expect(screen.getByTestId("task-row")).toBeInTheDocument());
const callsAfterActivation = m.listTasks.mock.calls.length;
expect(callsAfterActivation).toBeGreaterThanOrEqual(1);
// 快进 5s → 再次轮询;再快进 10s → 至少再两次
await act(async () => {
vi.advanceTimersByTime(5000);
});
await act(async () => {
vi.advanceTimersByTime(10_000);
});
expect(m.listTasks.mock.calls.length).toBeGreaterThanOrEqual(callsAfterActivation + 2);
} finally {
vi.useRealTimers();
}
});

it("任务面板「+ 添加任务」→ 打开表单 → 保存 → taskCreate + 刷新列表", async () => {
const m = mockEmrg();
render(wrapper(<Shell />));
Expand Down
12 changes: 12 additions & 0 deletions emrg/gui/renderer/src/components/Shell.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,6 +145,18 @@ export function Shell() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeView]);

// 任务面板激活时每 5s 轮询任务状态(vanilla startTaskPoll,rant 2026-08-22T07:18:35 方案 B:
// 宿主确认轮询、可接受几秒滞后)——让"运行中→待运行"切换与下次倒计时 ≤5s 内自动更新,
// 不引入事件推送。幂等:重复启动先清旧定时器;离开任务视图清除防泄漏;轮询失败静默下轮重试。
useEffect(() => {
if (activeView !== "tasks") return;
const id = setInterval(() => {
void loadTasks();
}, 5000);
return () => clearInterval(id);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeView]);

// ── workspace 面板动作(vanilla dialogs.js 语义) ──
async function addProject() {
const b = wsBridge();
Expand Down
Loading