diff --git a/Agent.md b/Agent.md index 0a02ef0..5e2dfbf 100644 --- a/Agent.md +++ b/Agent.md @@ -66,7 +66,7 @@ EMRG is a self-evolving AI agent architecture experiment. Python implementation, - Streaming chat with delta rendering (16ms batching), markdown on done (marked + DOMPurify + local highlight.js subset), tool call status cards (2000-char truncation + expand) - Session list/switch/new/delete + right-click rename (context menu, #423) synced with daemon; own-stream busy lock (G65); broadcast streams from other clients tagged "来自其他客户端" - Disconnect/reconnect: red status dot, auto daemon respawn (stale-port detection), session resume, input bar restored on disconnect (no 30s fake-timeout) - - Unit tests `npm test` (167: 43 daemon_client + 17 conn-manager + 22 app-commands + 50 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state); RESPONSE_TYPES mirror daemon protocol verified against `daemon.py` + - Unit tests `npm test` (169: 43 daemon_client + 17 conn-manager + 22 app-commands + 52 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state); RESPONSE_TYPES mirror daemon protocol verified against `daemon.py` - **Auto project tracking** — Automatically detects and records working directories; project-scoped sessions - **Rant-driven evolution** — User feedback via `/rant` drives automatic self-improvement cycles - **Headless GitHub auth** — Non-interactive evolution auto-extracts `GH_TOKEN` from git credential store (osxkeychain / credential helper); PR comment/LGTM queries fall back to REST API (GraphQL needs `read:org` scope) @@ -94,7 +94,7 @@ pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.port; python -m emrg ``` Python: `uv run pytest tests/ -v` (680) — import check: `uv run python -c "from emrg.client.app import run_client"` -GUI: `cd emrg/gui && npm test` (167: 43 daemon_client + 17 conn-manager + 22 app-commands + 50 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js` +GUI: `cd emrg/gui && npm test` (169: 43 daemon_client + 17 conn-manager + 22 app-commands + 52 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state) — syntax: `node --check main.js preload.js daemon_client.js renderer/js/*.js` CI: `uv run pytest` + 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 路径不受影响) diff --git a/README.cn.md b/README.cn.md index e979c55..ee14d6f 100644 --- a/README.cn.md +++ b/README.cn.md @@ -282,7 +282,7 @@ uv run python -m emrg # 启动 TUI cd emrg/gui npm ci # 安装依赖(生产模式可 --omit=dev) npm start # 启动 GUI(自动拉起 daemon) -npm test # 运行 Node 测试(167 项:43 daemon_client + 17 conn-manager + 22 app-commands + 50 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state;集成测试在 CI 跑,本地可 npm run test:integration) +npm test # 运行 Node 测试(169 项:43 daemon_client + 17 conn-manager + 22 app-commands + 52 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state;集成测试在 CI 跑,本地可 npm run test:integration) ``` CI 通过 GitHub Actions 自动运行测试并检查冲突标记(`.github/workflows/test.yml`)。 diff --git a/README.md b/README.md index e8b09ce..af1c210 100644 --- a/README.md +++ b/README.md @@ -281,7 +281,7 @@ uv run python -m emrg # launch TUI cd emrg/gui npm ci # install deps (production: --omit=dev) npm start # launch GUI (auto-starts daemon) -npm test # run Node tests (167: 43 daemon_client + 17 conn-manager + 22 app-commands + 50 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state; integration runs in CI, local: npm run test:integration) +npm test # run Node tests (169: 43 daemon_client + 17 conn-manager + 22 app-commands + 52 renderer smoke + 15 i18n + 7 integration + 3 commands + 3 build-config + 7 gui-state; integration runs in CI, local: npm run test:integration) ``` CI runs tests and checks for conflict markers automatically via GitHub Actions (`.github/workflows/test.yml`). diff --git a/emrg/gui/main.js b/emrg/gui/main.js index edd0036..362a388 100644 --- a/emrg/gui/main.js +++ b/emrg/gui/main.js @@ -456,6 +456,25 @@ vision = false return frame.projects || []; }); + // P5(rant 15:07:19):某项目的会话列表(list_sessions(cwd=projectPath)) + ipcMain.handle("emrg:listProjectSessions", async (_e, { projectPath }) => { + if (typeof projectPath !== "string" || !projectPath) throw new Error("invalid project path"); + const frame = await requireConn().sendCommandAndWait("list_sessions", { cwd: projectPath }, 5000); + return { sessions: frame.sessions || [] }; + }); + + // P5:新建项目 = 轻量命令带 cwd → daemon 隐式 _touch_project 注册(零改动) + ipcMain.handle("emrg:registerProject", async (_e, { path: p }) => { + if (typeof p !== "string" || !p) throw new Error("invalid project path"); + try { + fs.accessSync(p, fs.constants.W_OK); // 目录可写校验(G121) + } catch { + throw new Error("project directory not writable"); + } + await requireConn().sendCommandAndWait("list_sessions", { cwd: p }, 5000); // 隐式注册 + return { ok: true, path: p }; + }); + ipcMain.handle("emrg:listTasks", async () => { // GUI / 指令 P4:/trigger — daemon list_tasks → tasks_list const frame = await requireConn().sendCommandAndWait("list_tasks", {}, 5000); diff --git a/emrg/gui/preload.js b/emrg/gui/preload.js index 14cafe1..636abcf 100644 --- a/emrg/gui/preload.js +++ b/emrg/gui/preload.js @@ -25,6 +25,8 @@ const api = { readMemory: (payload) => ipcRenderer.invoke("emrg:readMemory", payload), listSkills: () => ipcRenderer.invoke("emrg:listSkills"), listProjects: () => ipcRenderer.invoke("emrg:listProjects"), + listProjectSessions: (payload) => ipcRenderer.invoke("emrg:listProjectSessions", payload), + registerProject: (payload) => ipcRenderer.invoke("emrg:registerProject", payload), listTasks: () => ipcRenderer.invoke("emrg:listTasks"), triggerTask: (payload) => ipcRenderer.invoke("emrg:triggerTask", payload), sendRant: (payload) => ipcRenderer.invoke("emrg:sendRant", payload), diff --git a/emrg/gui/renderer/index.html b/emrg/gui/renderer/index.html index 2284e9f..2f7128c 100644 --- a/emrg/gui/renderer/index.html +++ b/emrg/gui/renderer/index.html @@ -268,6 +268,19 @@