diff --git a/Agent.md b/Agent.md
index 4ab533c..d82b002 100644
--- a/Agent.md
+++ b/Agent.md
@@ -93,7 +93,7 @@ Community needs voiced in HN agent-UI discussions map directly to EMRG's design:
pkill -f "emrg.server"; rm -f ~/.emrg/emrgd.port; python -m emrg
```
-Python: `uv run pytest tests/ -v` (534) — import check: `uv run python -c "from emrg.client.app import run_client"`
+Python: `uv run pytest tests/ -v` (542) — import check: `uv run python -c "from emrg.client.app import run_client"`
GUI: `cd emrg/gui && npm test` (91: 22 daemon_client + 22 app-commands + 22 renderer smoke + 15 i18n + 7 integration + 3 commands) — 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 9cdda4c..39828c6 100644
--- a/README.cn.md
+++ b/README.cn.md
@@ -274,7 +274,7 @@ EMRG 不只是追赶——它自己追上来。
git clone https://github.com/argszero/emrg.git
cd emrg
uv sync # 安装依赖
-uv run pytest tests/ -v # 跑测试(当前 534 项)
+uv run pytest tests/ -v # 跑测试(当前 542 项)
uv run python -m emrg # 启动 TUI
# CI 含 actionlint workflow 门禁(#444):workflow 解析错误在 PR 即失败
diff --git a/README.md b/README.md
index eefb54f..6d8fe2c 100644
--- a/README.md
+++ b/README.md
@@ -273,7 +273,7 @@ EMRG doesn't just keep up — it catches up on its own.
git clone https://github.com/argszero/emrg.git
cd emrg
uv sync # install deps
-uv run pytest tests/ -v # run tests (currently 534 items)
+uv run pytest tests/ -v # run tests (currently 542 items)
uv run python -m emrg # launch TUI
# CI includes actionlint workflow gate (#444): workflow parse errors fail PR CI
diff --git a/emrg/gui/daemon_client.js b/emrg/gui/daemon_client.js
index 76a4849..dd27983 100644
--- a/emrg/gui/daemon_client.js
+++ b/emrg/gui/daemon_client.js
@@ -45,6 +45,8 @@ const RESPONSE_TYPES = {
rewind_session: "rewind_result", // 补缺:daemon.py:955 rewind_result
read_memory: "memory_content", // 补缺:daemon.py:771/778 memory_content
evolution_summary: "evolution_summary", // WorkBuddy P3:自进化可见化
+ github_connect: "github_connect_result", // Windows GCM rant Stage 2:PAT 授权(daemon.py github_connect)
+ github_disconnect: "github_disconnect_result", // Windows GCM rant Stage 2:断开(daemon.py github_disconnect)
};
class DaemonClient {
diff --git a/emrg/gui/main.js b/emrg/gui/main.js
index 0b20c7e..06404e5 100644
--- a/emrg/gui/main.js
+++ b/emrg/gui/main.js
@@ -442,6 +442,24 @@ vision = false
return { count: frame.count ?? 0, recent: frame.recent || [] };
});
+ ipcMain.handle("emrg:githubStatus", async () => {
+ // Windows GCM rant Stage 2:设置页 GitHub 连接状态(daemon github_status)
+ const frame = await client.sendCommandAndWait("github_status", {}, 10000);
+ return { authenticated: Boolean(frame.authenticated), user: frame.user || null };
+ });
+
+ ipcMain.handle("emrg:githubConnect", async (_e, { token }) => {
+ // Windows GCM rant Stage 2:PAT 授权 + setup-git(daemon github_connect)
+ const frame = await client.sendCommandAndWait("github_connect", { token: String(token || "").trim() }, 40000);
+ return { ok: Boolean(frame.ok), user: frame.user || null, error: frame.error || null };
+ });
+
+ ipcMain.handle("emrg:githubDisconnect", async () => {
+ // Windows GCM rant Stage 2:断开 GitHub(daemon github_disconnect)
+ const frame = await client.sendCommandAndWait("github_disconnect", {}, 40000);
+ return { ok: Boolean(frame.ok), error: frame.error || null };
+ });
+
ipcMain.handle("emrg:setModel", async (_e, { model }) => {
await client.sendCommandAndWait("set_model", { model }, 5000);
return { ok: true };
diff --git a/emrg/gui/preload.js b/emrg/gui/preload.js
index 197b2be..945225e 100644
--- a/emrg/gui/preload.js
+++ b/emrg/gui/preload.js
@@ -27,6 +27,9 @@ const api = {
triggerTask: (payload) => ipcRenderer.invoke("emrg:triggerTask", payload),
sendRant: (payload) => ipcRenderer.invoke("emrg:sendRant", payload),
evolutionSummary: (payload) => ipcRenderer.invoke("emrg:evolutionSummary", payload),
+ githubStatus: () => ipcRenderer.invoke("emrg:githubStatus"),
+ githubConnect: (payload) => ipcRenderer.invoke("emrg:githubConnect", payload),
+ githubDisconnect: () => ipcRenderer.invoke("emrg:githubDisconnect"),
listModels: () => ipcRenderer.invoke("emrg:listModels"),
openFile: (payload) => ipcRenderer.invoke("emrg:openFile", payload),
saveSettings: (payload) => ipcRenderer.invoke("emrg:saveSettings", payload),
diff --git a/emrg/gui/renderer/index.html b/emrg/gui/renderer/index.html
index 9715252..166739e 100644
--- a/emrg/gui/renderer/index.html
+++ b/emrg/gui/renderer/index.html
@@ -123,6 +123,16 @@
设置
+
+
GitHub 连接
+
—
+
+
+
+
+
+
用于自进化推送 PR;授权后自动执行 gh auth setup-git,git 操作不再弹 GCM
+
外观