Skip to content

feat(maker-core): add optional Grok Build ACP harness - #3479

Open
yuchenlin wants to merge 7 commits into
makecindy:mainfrom
yuchenlin:feat/grok-build-harness
Open

feat(maker-core): add optional Grok Build ACP harness#3479
yuchenlin wants to merge 7 commits into
makecindy:mainfrom
yuchenlin:feat/grok-build-harness

Conversation

@yuchenlin

@yuchenlin yuchenlin commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

把 xAI Grok Build(本机 grok CLI)做成 Cindy 的第四个可选 runtimeAgentKind = 'grok-build'),装配方式对齐 Pi 的 buildXAgent() | null:PATH 上没有 grok 时不注册、选择器隐藏,Claude Code / Codex / Pi 不受影响。

协议是 ACP(grok agent stdio,JSON-RPC 2.0 带 jsonrpc: "2.0"),不是 Pi RPC,也不是把目录里的 xai/grok-* 模型当成本需求。权限档从严到宽为 [ask, auto, bypassPermissions]:ask 走 ACP 审批;auto 走 Cindy 共用 Auto-review(不用 grok 的 --always-approve / autoMode);bypass 才 grok agent --always-approve stdio_meta.yoloMode: true。探测只看 PATH,不读 ~/.grok/auth.json,不复用 SuperGrok OAuth,不钉 CDN 二进制。

后两个 commit 补的是「把 AgentKind 拓宽这件事做完」:首版把共享 AgentKind 联合类型加了第四个成员,但依赖它的调用点没跟上,pnpm --filter desktop typecheck 有 106 个错误——CI 没报出来是因为 verify-checks 在更早的 check:i18n 就失败退出了,压根没跑到 typecheck。修的过程中还翻出几处编译期不报、运行期串台的问题,见「范围」。

变更类型

  • feat 新功能

范围

  • 关联 Issue / 需求:Add Grok Build as a coding-agent backend with automatic detection #3328feat: add Grok Agent Harness for Desktop #3027
  • 本 PR 包含:
    • maker-core GrokBuildAgent + ACP stdio 客户端 / translator / PATH 探测 / Auto-review 映射;desktop buildGrokBuildAgent() 可选注册;AgentKind / SELECTABLE_VENDORS / 五语 i18n;探测与 ACP fixture 单测;docs/dev-rules/grok-build-harness.md
    • 落库口径agentKindConversion 此前把任何未知值映射成 'cc',grok-build 会话会被写进 sessions.agent_kind 变成 Claude Code、读回来也是 Claude Code。同一类还有自动起名目标、上下文重建卡片打标、任务摘要三处(都是编译期不报的静默串台)
    • 身份呈现:desktop 侧栏 VendorIcon 真正画上本 PR 新加却一直没接线的 GrokBuildMark;mobile MobileVendorIcon 不再把 grok-build 会话读成 Claude Code;右侧栏资源占用行新增 agent-grok-build
    • 能力边界 fail-closedGrokBuildAgent 声明 rewind/fork 不支持,rewind / fork 入口显式拒绝 grok-build 会话,而不是落进「非 codex/pi 即 Claude」的分支去回滚一个没有 checkpoint 的会话
    • 其余联合类型收口:desktop main / renderer / shared、maker-scheduler、lizi-mcps 里那些手抄的三档 'claude-code' | 'codex' | 'pi' 副本,凡属级联的一律接回共享类型;模型面(model plane)、参考价、目录默认种子这类 grok-build 确实不参与的子系统,保持三档并显式排除
  • 明确不包含:CDN 钉 grok;读取 ~/.grok/auth.json 或 SuperGrok OAuth 当本 harness 登录;把 grok-build 加进 VALID_AGENTS;嵌入 Grok TUI;one-shot grok -p;MCP send_to_session / create_workeragent_kind zod 枚举(能不能让模型把活派给 grok-build 是产品决定,本轮只对齐 ControlWorkerAgent 这个结果侧类型)
  • 用户可见变化:本机 PATH 有 grok 且已登录(或设置了 XAI_API_KEY)时,新建对话引擎选择器多出 Grok Build;该会话在侧栏 / 模型选择器 / 资源占用里显示自己的身份标识而不是 Claude 的
  • 是否存在 breaking change:无。未安装 grok 时行为与现在相同

UI 变化

新增的可见元素只有 Grok Build 的身份标识(图标 + 徽标底色 + 资源行文案),没有新布局、没有改任何既有组件的形状。下面是静态 HTML 复现,SVG path 与 GrokBuildMark.tsx 是同一份:

<!doctype html>
<meta charset="utf-8">
<title>PR 3479 — Grok Build identity surfaces</title>
<style>
  :root { --sidebar-muted: 0 0% 45%; --warning-accent: #d97706; --engine-badge-grok-build: #6b7280; }
  body { margin: 0; padding: 24px; background: #fff; color: #1a1a1a;
         font: 13px/1.45 -apple-system, "SF Pro Text", "PingFang SC", sans-serif; }
  h2 { font-size: 12px; font-weight: 600; color: #737373; margin: 22px 0 8px; }
  .row { display: flex; align-items: center; gap: 8px; min-height: 28px; padding: 4px 8px;
         border-radius: 8px; width: 420px; }
  .row.active { background: #f4f4f5; color: #111; }
  .muted { color: hsl(var(--sidebar-muted)); }
  .running { color: var(--warning-accent); }
  /* UnifiedModelRow badge: 底 14% / 描边 30%,由同一个 var color-mix 派生 */
  .badge { display: inline-flex; align-items: center; justify-content: center;
           width: 22px; height: 22px; border-radius: 6px;
           color: var(--engine-badge-grok-build);
           background: color-mix(in srgb, var(--engine-badge-grok-build) 14%, transparent);
           border: 1px solid color-mix(in srgb, var(--engine-badge-grok-build) 30%, transparent); }
  .model-row { display: flex; align-items: center; gap: 10px; width: 320px; padding: 6px 8px;
               border-radius: 8px; }
  .name { font-weight: 500; }
  .sub { color: #737373; font-size: 11px; }
  .usage { display: grid; grid-template-columns: 22px 120px 60px 70px; align-items: center;
           gap: 8px; width: 300px; padding: 4px 8px; }
</style>

<!-- GrokBuildMark:与 apps/desktop/src/renderer/components/icons/GrokBuildMark.tsx 同一份路径 -->
<svg style="display:none"><symbol id="grok-build-mark" viewBox="0 0 24 24">
  <g fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
    <path d="M7 7.2h10.4v9.6H7.6c-1.5 0-2.4-.9-2.4-2.4V9.6c0-1.5.9-2.4 2.4-2.4Z"/>
    <path d="M12.4 12h5"/>
  </g>
</symbol></svg>

<h2>0. GrokBuildMark 放大观察(同一份 path,48px)</h2>
<div style="display:flex;gap:24px;align-items:center">
  <svg class="muted" width="48" height="48"><use href="#grok-build-mark"/></svg>
  <svg class="running" width="48" height="48"><use href="#grok-build-mark"/></svg>
  <span class="sub">左:idle(Stone 灰) 右:running(Thinking Orange)</span>
</div>

<h2>1. 侧栏会话行的 Agent 身份位(VendorIcon,13px)</h2>
<div class="row"><svg class="muted" width="13" height="13"><use href="#grok-build-mark"/></svg>
  <span>fix ACP permission mapping</span></div>
<div class="row"><svg class="running" width="13" height="13"><use href="#grok-build-mark"/></svg>
  <span>running session(Thinking Orange,与 cc / codex / pi 同一套呼吸态)</span></div>
<div class="row active"><svg width="13" height="13"><use href="#grok-build-mark"/></svg>
  <span>selected row(前景与文字同色)</span></div>

<h2>2. 统一模型选择器的引擎徽标(engine-badge-grok-build = #6b7280)</h2>
<div class="model-row">
  <span class="badge"><svg width="13" height="13"><use href="#grok-build-mark"/></svg></span>
  <span><span class="name">Grok Build</span><br><span class="sub">local grok CLI · ACP</span></span>
</div>

<h2>3. 右侧栏资源占用行(ProcessUsageKind = agent-grok-build)</h2>
<div class="usage"><svg class="muted" width="14" height="14"><use href="#grok-build-mark"/></svg>
  <span>Grok Build</span><span class="sub">1.4%</span><span class="sub">128 MB</span></div>
  • 引用的设计规范:DESIGN.md §10「Semantic Exemption Colors (theme-invariant)」——新注册的 engine-badge-grok-build#6b7280)与既有 engine-badge-cc / codex / pi 同类,是表达「这一行挂在哪个引擎上」的身份色,light / dark 同值是有意决策,不表达界面明暗层次;themes/__tests__/tokenRegistry.test.ts 的守护测试已把第四个 token 纳入,组件只经 var(--engine-badge-grok-build) 消费,不留 hex 副本。DESIGN.md §4「Select & Dropdown」与 §14.4「容器形变」——沿用既有 PermissionSelector / AgentSelect,只补第四个 vendor 项,容器与交互零改动。DESIGN.md §11「Voice & Content」——权限档文案走 i18n 五语,品牌名 Grok Build 不翻译。图标取色沿用侧栏既有约定(idle Stone 灰 / running Thinking Orange / 选中态与文字同色),不引入新色。

怎么验证的

自动验证

cd apps/desktop && tsc --noEmit -p tsconfig.json
结果:0 error(改动前 106 error)

cd apps/mobile && tsc --noEmit
结果:0 error

node scripts/check-i18n.mjs
结果:✅ 五语共 8280 个 key 全部一致(改动前 zh-TW 缺 16 个 key,CI 就是挂在这一步)

node scripts/check-i18n-glossary.mjs / check-endpoint-literals.mjs / brand-terminology-guard.mjs
pnpm ci:scheduler-guard / pnpm --filter mobile test:scope
结果:全部 PASS

cd packages/maker-core && vitest run src/agents/grok-build     → 7 files / 30 tests passed
cd packages/maker-shared && vitest run                          → 63 files / 972 tests passed
cd packages/model-providers && vitest run                       → 20 files / 670 tests passed
cd packages/lizi-mcps && vitest run                             → 49 files / 671 tests passed
cd apps/mobile && vitest run                                    → 321 files / 3896 tests passed
cd apps/desktop && vitest run                                   → 2292 files passed / 9 failed(见下)

desktop 全量里有 10 个文件失败。逐个在不含本 PR 任何改动的分支(fix/mobile-work-group-tool-row-i18n,同样基于近期 main)上跑同一组文件,9 个以完全相同的报错失败(dbClient.tx is not a functionno such column: list_preview / codex_plan_json 的 DB harness 漂移,来自性能提交 51bed2719;以及 BillingPage 的日期格式化),第 10 个 codexExecFunctionAdapter.e2e 单独跑在本分支通过,是全量并发下的超时抖动。结论:与本 PR 无关。

grok-build-session.test.ts 这轮也修了跨平台问题:假 grok ACP server 原本靠 #!/usr/bin/env bun 的 shebang 启动,CI runner 上没有 bun,四个用例全挂在 exit 127。现在改成生成一个 sh wrapper 显式 exec 当前 node,Windows 按仓库既有约定(Pi 侧同款)跳过整组。实测把 bun 从 PATH 摘掉后四个用例照常通过。

手工验证

不涉及(本机没有 grok CLI,跑不了真实 ACP 联调)。建议审阅者:PATH 无 grok 时确认 CC / Codex / Pi 正常;安装并 grok login 后确认选择器出现 Grok Build、建出的会话在侧栏显示 Grok Build 图标、sessions.agent_kind 落的是 grok-build

未执行的验证

  • 真 grok CLI 的 ACP 端到端联调(本机无该二进制)
  • desktop Playwright / mobile e2e / 移动端真机
  • Windows 上的 grok-build 会话(grok-build-session.test.ts 在 Windows 跳过,理由同 Pi:spawn 不过 shell 起不了 .cmd wrapper)

风险

风险分类

  • 协议兼容
  • 权限 / 安全 / 用户数据
  • SQLite / migration

影响与回滚

  • 影响范围:仅在本机 PATH 存在 grok 时多注册一个可选 harness。共享联合类型拓宽后,desktop / mobile / scheduler / MCP 侧的对应字段多了一个合法取值。
  • SQLite:没有 migration。sessions.agent_kind 是无约束的 text,drizzle 侧几处 text 枚举是类型层的,不进 drizzle/meta/*_snapshot.jsondb:check 无漂移。数据形态上的唯一变化是:grok-build 会话会真的写入 'grok-build' 这个值(此前会被静默写成 'cc')。
  • 回滚 / 降级方式:revert 本 PR,或从 PATH 拿掉 grok。降级注意:已经建过 grok-build 会话的用户回退到旧版本后,那些行的 agent_kind='grok-build' 会被旧版 dbToMakerAgentKind 回落成 claude-code —— 会话仍可打开、按 Claude 解析,不会损坏数据,但引擎标识会显示成 Claude Code。这是「新值 + 旧读取端」的固有代价,不是本 PR 新引入的读取路径缺陷。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名
  • UI 改动已在「UI 变化」注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

Fixes #3328
Related #3027

@yuchenlin
yuchenlin requested a review from a team as a code owner August 26, 2026 18:54
@greptile-apps

greptile-apps Bot commented Aug 26, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 新增可选的 Grok Build ACP runtime,并将新的 agent kind 接入桌面端、移动端、持久化、进程监控和共享类型。此前报告的权限拒绝、初始化清理、强制终止和派发确认问题均已在当前 HEAD 修复并由针对性测试覆盖。

  • PATH 中存在 grok 时注册 Grok Build,并通过 ACP stdio 管理会话、事件、权限和认证状态
  • 扩展 agent kind 的存储、IPC、调度、跨端呈现及资源监控契约
  • 对 rewind、fork 和模型平面等不支持 Grok Build 的能力显式 fail-closed
  • 增加 ACP transport、权限策略、会话生命周期、PATH 探测和 UI 身份呈现测试

Confidence Score: 5/5

当前 HEAD 中此前的四项阻塞问题均已修复,PR 看起来可以安全合并。

当前没有仍然存在的阻塞性失败。

Important Files Changed

Filename Overview
packages/maker-core/src/agents/grok-build/index.ts 实现 Grok Build 会话初始化、ACP 事件转换、权限响应、首事件派发确认和失败清理;此前生命周期问题在当前实现中已修复。
packages/maker-core/src/agents/grok-build/auto-review-policy.ts 将 ACP 工具映射到共用 Auto-review,并在拒绝选项缺失时返回 null 以保持 fail-closed。
packages/maker-core/src/agents/grok-build/stdio-transport.ts 实现 Grok ACP 子进程 stdio transport,并在 SIGTERM 无效时定时升级为 SIGKILL。
apps/desktop/src/main/maker-host/grok-build-host.ts 根据 PATH 可选注册 Grok Build,接入 CLI 登录、API key 认证探测和本地进程监控。
apps/desktop/src/shared/agentKindConversion.ts 将 grok-build 纳入 Maker 与数据库 agent kind 的双向转换,避免会话静默归类为 Claude Code。
packages/maker-core/src/agents/grok-build/tests/grok-build-session.test.ts 覆盖初始化失败清理、首个更新确认派发以及 prompt 更新前后失败语义。
packages/maker-core/src/agents/grok-build/tests/grok-build-stdio-transport.test.ts 覆盖忽略 SIGTERM 时升级 SIGKILL,以及正常退出时不误发 SIGKILL。

Sequence Diagram

sequenceDiagram
  participant UI as Cindy UI
  participant Maker as Maker
  participant Grok as GrokBuildAgent
  participant ACP as grok agent stdio
  UI->>Maker: 创建 grok-build 会话
  Maker->>Grok: startSession()
  Grok->>ACP: initialize + session/new
  UI->>Maker: send(message)
  Maker->>Grok: send()
  Grok->>ACP: session/prompt
  ACP-->>Grok: 首个 session/update
  Grok-->>Maker: 确认 turn 已接收
  ACP-->>Grok: 后续事件或终态
  Grok-->>Maker: 标准化 AgentEvent
  Maker-->>UI: 状态、文本、工具及终态事件
Loading

Reviews (2): Last reviewed commit: "fix(grok-build): resolve the grok binary..." | Re-trigger Greptile

Comment thread packages/maker-core/src/agents/grok-build/auto-review-policy.ts Outdated
@yuchenlin

Copy link
Copy Markdown
Contributor Author

关于 #3027 上 bot 的判断:那段里「不要为了包一层 Grok 模型 再造第四套 loop」我同意,也不是本 PR 在做的事。

#3027 原文更像「Pi 上的 Grok 体验」(SuperGrok / xAI API 当模型来源)。那个路径 Cindy 已经有了:xai/grok-* 跑在 Pi / Claude Code / Codex 上。本 PR 不替代它,也不把 xai/grok-build-0.1 目录条目当成 harness。

本 PR 接的是独立 runtime:Grok Build(本机 grok CLI / TUI),产品诉求在 #3328。bot 自己也写了:如果目标是官方 Agent runtime,需要先有可核验的上游契约。现在契约是公开的:

  • 进程:本机 grok
  • 会话协议:ACP grok agent stdio(JSON-RPC 2.0:initialize / session/new / session/prompt / session/request_permission
  • 审批边界:ask 走 ACP 权限请求;auto 走 Cindy Auto-review;bypass 才 --always-approve / yoloMode
  • 认证:复用已有 grok loginXAI_API_KEY,不读 ~/.grok/auth.json,不把 SuperGrok OAuth 当本 harness 登录

Pi + xAI Responses 表达不了 Grok Build 自己的 plan / 并行 subagent / worktree,也复用不了本机已登录的 Grok Build 会话。没有 grok 时本 harness 不注册,CC / Codex / Pi 不变。

所以:#3027 的 Pi profile 建议可以继续单独做;本 PR 回答的是 bot 那句「先补契约再决定是否新增 agentKind」。

@MagicLizi

Copy link
Copy Markdown
Contributor

@yuchenlin 👋 这个 PR 还有 1 条 review conversation 没 resolve(packages/maker-core/src/agents/grok-build/auto-review-policy.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Aug 26, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

这个 PR 需要维护者确认后才能继续落地。

它新增了可选的 Grok Build ACP harness,并改到新建任务 / 设置 / 调度等用户可见入口,同时带规则文档和跨包契约,不属于存量 bugfix。

请维护者直接在本 PR 上 Approve;如果范围或交互需要改,请 Request Changes。确认方式见讨论 issue:#3480

@MagicLizi MagicLizi added the awaiting-discussion 等待维护者讨论(review-pr) label Aug 26, 2026
yuchenlin added a commit to yuchenlin/cindy that referenced this pull request Aug 26, 2026
Greptile on makecindy#3479 — deny without reject_* cancels instead of picking allow; startSession closes ACP on init failure; SIGKILL after SIGTERM uses exit, not child.killed; send returns on turn acceptance not prompt completion.

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/cindy-brain/GhostErrandPrefs.tsx / apps/desktop/src/renderer/components/icons/GrokBuildMark.tsx / apps/desktop/src/renderer/components/new-chat/PermissionSelector.tsx 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@yuchenlin

Copy link
Copy Markdown
Contributor Author

更新一轮,把 CI 全红的原因和一批编译期不报、运行期串台的问题一起收掉了。两个新 commit:

38c26fe 让 CI 能跑起来

  • zh-TW 少了 16 个 grok-build 相关 key,check:i18n 就挂在这里;verify-checks 在这一步失败退出,所以后面的 typecheck / 单测根本没跑到
  • grok-build-session.test.ts 的假 ACP server 用 #!/usr/bin/env bun 起,CI runner 上没有 bun → exit 127,四个用例全挂。改成生成 sh wrapper 显式 exec 当前 node,Windows 按 Pi 侧既有约定跳过。实测把 bun 从 PATH 摘掉后照常通过
  • mobile 新建入口:grok-build 不进 fail-open 名单(它只有被控端 PATH 上有 grok 才注册,拉取注册集合期间露出来就是个建了必报 not-registered 的入口)

80b80b6 把 AgentKind 拓宽这件事做完——tsc --noEmit 从 106 error 到 0。过程中翻出的不是类型噪音,是真问题:

  • 落库串台:agentKindConversion 把未知值一律映射成 'cc',grok-build 会话会被写进 sessions.agent_kind 变成 Claude Code、读回来也是 Claude Code。同一类还有自动起名目标(注释里自己写了「起名会发到错的供应商」)、上下文重建卡片打标、任务摘要
  • 身份没接线:本 PR 新加的 GrokBuildMark 从来没有被任何组件引用,侧栏会画 Claude 脸;mobile MobileVendorIcon 连无障碍标签都读成「Claude Code」
  • 能力边界:GrokBuildAgent 声明 rewind/fork 不支持,但两个入口都是「非 codex/pi 即 Claude」,grok-build 会静默走 Claude checkpoint / message-uuid 路径。现在显式拒绝
  • 其余是把各处手抄的三档联合类型接回共享类型;模型面 / 参考价 / 目录默认种子这些 grok-build 确实不参与的子系统保持三档并显式排除,不做「反正能过编译」的强行拓宽

验证(命令与结果在 description 里):desktop / mobile typecheck 0 error;五个 i18n 与守门脚本全 PASS;maker-core grok-build 30、maker-shared 972、model-providers 670、lizi-mcps 671、mobile 3896 全通过。desktop 全量有 10 个文件失败,逐个在不含本 PR 任何改动的分支上跑同一组,9 个以完全相同的报错失败(DB harness 漂移 + BillingPage 日期格式化),第 10 个单独跑通过,是并发超时抖动——与本 PR 无关。

description 已按模板重写,「UI 变化」附了新身份标识的 HTML 复现与引用的规范章节(§10 语义豁免色 / §4 / §11),风险段补了 SQLite 数据形态与降级口径(旧版本读到 agent_kind='grok-build' 会显示成 Claude Code,数据不损坏)。

还需要维护者拍板的两处,我没有替你们决定:

  1. 维护者确认:#3479 新增可选 Grok Build ACP harness #3480 那条产品门(新增用户可见 runtime)
  2. maker-orchestration/rewind.ts 的能力门:现在是入口 fail-closed 拒绝。如果产品上希望 grok-build 支持某种形式的回滚,需要另设计,不在本 PR

@MagicLizi

Copy link
Copy Markdown
Contributor

@yuchenlin 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi MagicLizi added touches:redline 改动碰到红线路径(updater / DB schema 等,review-pr 自动维护,仅展示) and removed touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) labels Aug 27, 2026
@yuchenlin

Copy link
Copy Markdown
Contributor Author

@MagicLizi 冲突已解决,origin/main(aa4f069)已 merge 进来并推送。

冲突本身只有一处、是 import 顺序:apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts 里 main 加了 redactSensitiveText、本分支加了 AgentKind 的 type import,两边落在同一行位置。两个都保留。

merge 之后又跑了一遍全套校验,发现 main 的新代码与本 PR 拓宽的 AgentKind 有两处语义冲突(git 不会报,tsc 才报),已在 861d537 一并修掉:

  • XdGatewayModelInfo.agents 写的是 AgentKind[],拓宽后跟 shared/modelAccess.ts 里的服务端协议类型 ModelAccessGatewayModel.agents(三档)对不上。网关目录只服务 cc / codex / pi 三个 tab,grok-build 是本机 CLI、自带唯一内置模型、不进网关目录,所以这里改回逐字对齐协议,而不是把协议类型也拓宽。
  • newMakerDefaultTuple 的产品默认种子表同理:这张表只覆盖走 provider 路由的三个 harness,新增 NewMakerDefaultAgent = Exclude<AgentKind, 'grok-build'> 收口。

merge 后复验:apps/desktop tsc 0 errorapps/mobile tsc 0 error、check:i18n 五语 8368 key 一致、check:i18n-glossary 无新增违规;model-access / active-catalog / catalogDerivedModels / newMakerDefaultTuple 相关 6 files / 102 tests 通过。

顺带记一个基线数据:把 upstream/main(aa4f069)单独 checkout 出来跑 desktop typecheck 是 0 error,所以上面这两处确实是「本 PR × main 新代码」的交叉,不是 main 自身的问题。

@yuchenlin

Copy link
Copy Markdown
Contributor Author

@greptile-apps 回一下那条 Confidence 1/5 的判断——四条阻塞项都是针对首个 commit 0820cd6 的,在 7212f12 之后已经逐条修掉,现在都有对应测试钉住。逐条对照:

1. deny 回退可能 fail open(auto-review-policy.ts)
pickPermissionOptionId 现在只在 allow 分支回退首项;非 allow 找不到匹配拒绝项时返回 null:

return behavior === 'allow' ? options[0]?.optionId ?? null : null;   // auto-review-policy.ts:94

调用方把 null 映射成 cancelled,而不是随便挑一个选项:

if (!optionId) return { outcome: { outcome: 'cancelled' as const } };  // index.ts:373

测试:grok-build-auto-review-policy.test.ts > fail-closes deny when only allow_* options exist

2. 初始化失败遗留子进程(index.ts)
startSession 的 catch 里先关掉 client / transport 再抛:

} catch (err) {
  ...
  await client.close('startSession failed');   // index.ts:258-260

测试:grok-build-session.test.ts > registers the child via onProcessSpawned once and closes ACP if initialize fails

3. 误用 child.killed 导致 SIGKILL 升级失效(stdio-transport.ts)
不再看 child.killed,SIGTERM 之后挂定时器强杀:

try { child.kill('SIGTERM'); } catch { /* already gone */ }   // :160
... try { child.kill('SIGKILL'); } catch { /* already gone */ }  // :152

测试:sends SIGKILL if the child ignores SIGTERM (does not use child.killed),以及反向用例 does not send SIGKILL when the child exits after SIGTERM

4. send 等完整 turn 才算 acceptance
acceptance 边界改成首个 session/update 到达即成立(onTurnAccepted?.(),index.ts:194),prompt 仍然在飞以便 abort;turn 完成后的失败不再被算成派发失败。测试:returns send() once the first session/update arrives, keeping prompt in-flight for abortthrows from send() when session/prompt errors before any updatedoes not throw from send() when session/prompt errors after a turn update

另外这一轮还修了四类你当时没看到的问题(CI 在更早的 check:i18n 就挂了,typecheck 与单测根本没跑到):落库把 grok-build 会话写成 'cc'GrokBuildMark 从未接线、rewind/fork 静默走 Claude 路径、PATH 解析在 Windows 上混用两个平台的分隔符与拼接。详见上面两条 commit 说明。

现在全流水线绿:verify / verify-checks / Linux 两分片 / Windows 两分片 / design-basis / DCO 全部 success。麻烦重跑一次 review;如果上面四条里有哪条你认为仍不成立,请指出具体代码行,我再看。

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks For the New Featrue ~ I think Can GoOn

@MagicLizi MagicLizi removed the awaiting-discussion 等待维护者讨论(review-pr) label Aug 28, 2026

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grok Build 作为可选 runtime 已经能创建/选择,但几条真实 IPC 入口仍按三家 harness 拒绝,用户走不通。请先补齐这些门,再 rebase 当前 main(账号切换 API 会被这版 preload 删掉)。

P1×4(均已对照 head f358156 复核):

  • apps/desktop/src/main/maker-ipc/register.ts:13680 — requireQueuedMessage 仍只认 claude-code|codex|pi。Composer 发送走 INPUT_ENQUEUE,grok-build 会话会 INVALID_PARAMS。请把 'grok-build' 纳入校验,并加 enqueue/send 测试。

  • apps/desktop/src/main/maker-ipc/register.ts:2084 — 本地 requireAgentKind 仍是三值,却被 GET_CAPABILITIES / LIST_AGENT_COMMANDS / LIST_AGENT_SKILLS / SCAN_AT_RESOURCES / LIST_CUSTOMIZATIONS 使用;renderer getCapabilities('grok-build') 已接线。权限模式、rewind/fork、模型、/ 命令、@ 资源都加载失败。请拆出「仅草稿三家」与完整 AgentKind 两套 helper。

  • apps/desktop/src/main/maker-ipc/authHandlers.ts:21 — AGENT_KINDS 仍是三家,但 useVendorAuthGatemaker.auth.triggerLogin('grok-build')。未认证弹窗无法启动 grok login。请把 'grok-build' 加进 IPC 枚举(device-code/ownerId 可继续只给 Codex)。

  • apps/desktop/src/preload/preload.ts:1868 — 相对当前 origin/main,本 PR 会删掉 authListAccounts / authSyncAccounts / authSwitchAccount / authBeginAddAccount / authCancelAddAccount#3505 已在 main)。与 Grok Build 无关,合进去会拆掉账号切换桥。请 rebase/merge 当前 main 并保留这些方法。

修完后不需要逐条回复本评论;push 新 commit 即可,下一轮会重审。

Register AgentKind 'grok-build' as a Pi-style optional runtime. Detect the local grok CLI on PATH, speak ACP over `grok agent stdio`, and leave Claude Code / Codex / Pi untouched when grok is missing.

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Greptile on makecindy#3479 — deny without reject_* cancels instead of picking allow; startSession closes ACP on init failure; SIGKILL after SIGTERM uses exit, not child.killed; send returns on turn acceptance not prompt completion.

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…ype gaps

- add the 16 missing zh-TW keys so the five common.json files match again
- run the fake grok ACP server through a generated sh wrapper on the current
  node instead of a bun shebang; skip the group on Windows like the Pi tests
- keep grok-build out of the mobile new-session fail-open list: it only exists
  when the controlled device has grok on PATH
- widen the mobile agent-kind unions, the vendor icon and the label helpers so
  a grok-build session is not rendered as Claude Code
- fix the grok-build type gaps tsc caught: thought block ctx key, ACP toolCall
  and content narrowing, turn-accept state across closures

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…implied

Widening AgentKind to a fourth runtime left ~106 desktop type errors that
CI never reported: verify-checks failed at check-i18n and stopped before
typecheck. Fixing them surfaced silent mislabels too.

- persist the real kind: agentKindConversion mapped anything unknown to
  'cc', so a Grok Build session was written to sessions.agent_kind as
  Claude Code and read back as Claude Code. Same class of bug in the
  auto-title target, the context-rebuild card stamp and the task summary.
- render the real identity: VendorIcon now draws the GrokBuildMark this
  PR added but never wired up, and MobileVendorIcon stops announcing a
  Grok Build session as Claude Code.
- fail closed where the runtime cannot follow: rewind and fork refuse a
  grok-build session instead of falling through to the Claude checkpoint
  and message-uuid paths; the model plane, reference prices and catalog
  seeds keep their three-agent shape and exclude it explicitly.
- widen the local duplicates of the agent unions everywhere else, so the
  desktop typecheck is clean again

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Merging main surfaced two places where the widened AgentKind leaked into
domains grok-build does not belong to: the XD gateway model projection
(a server protocol type that mirrors ModelAccessGatewayModel) and the
new-chat product default tuple seeds (provider-routed models only).

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…ath rules

resolveGrokBinaryFromPath took the delimiter from the injected platform but
joined with the host's path module, so a posix PATH fixture produced
backslash candidates on Windows and the lookup returned null. Pick both the
delimiter and the join from the same platform, and cover the Windows .cmd
shim that npm installs.

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Composer send, capabilities/commands/skills/@/customizations, and
auth login still rejected anything outside the original three
harnesses. Split the wire helpers: session-facing gates accept the
full AgentKind union (including grok-build); New Maker draft slots
stay three-vendor. Auth triggerLogin can now start `grok login`;
device-code and ownerId remain Codex-only.

Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
@yuchenlin
yuchenlin force-pushed the feat/grok-build-harness branch from f358156 to f22311e Compare August 28, 2026 07:05
@MagicLizi MagicLizi added the awaiting-discussion 等待维护者讨论(review-pr) label Aug 28, 2026
@MagicLizi
MagicLizi dismissed their stale review August 28, 2026 12:26

这些问题已在当前 head 的后续 commit 中修复(格式门/安全门已通过),自动 dismiss 旧的 CHANGES_REQUESTED 以解除合并阻塞。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:redline 改动碰到红线路径(updater / DB schema 等,review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Grok Build as a coding-agent backend with automatic detection

2 participants