Skip to content

fix: restore green main, and add the CI that would have caught it - #16

Merged
yujiezhang-ops merged 3 commits into
mainfrom
fix/restore-green-main
Aug 4, 2026
Merged

fix: restore green main, and add the CI that would have caught it#16
yujiezhang-ops merged 3 commits into
mainfrom
fix/restore-green-main

Conversation

@yujiezhang-ops

Copy link
Copy Markdown
Collaborator

修复 #15main 当前在构建和测试上都是红的,本 PR 让它恢复绿色,并补上让这件事得以发生的缺口。

根因

4d63d75("chore: remove unused files")删了文件,但没有动引用它们的代码:

  • 删了 cursor.svg / hermes.png / openclaw.svg,但 icons/agents.tsx:25,26,28 的 import 还在 → 构建 UNRESOLVED_IMPORT,7 个前端测试文件无法加载
  • 删了 9 个 catalog 条目,但两个 Go 测试硬编码 openclaw,golden fixture 也没更新 → 3 个 Go 测试失败

go vet 全程是干净的,这就是它没被发现的原因:只有构建和测试才会走到这些路径。

二分确认过边界:30d01f5(父提交)全绿,4d63d75 三项全红。与 #4#14 无关,我单独验证过在 07cf902#4 合并之前)就已经是坏的。

恢复了什么,以及为什么不是全部

三个图标资源恢复,因为 agents.tsx 从未停止 import 它们,而 icons/agents.test.tsx:9 明确把 cursoropenclawhermes 定义为 PROMINENT_GUIDE_AGENTS——"和一键配置的 Agent 一起出现在第一屏,所以需要自己的图标"。这个契约不在那次清理的意图之内。

同样这三个 catalog 条目恢复,rank 用 6/7/8 而不是原来的 3/5/6——main 已把 auto 条目重排为 1–5,沿用旧值会撞号。

guide-only 不是死概念,所以不能顺着删:internal/app/install.go:340catalog/manifest.go:129 的校验、AgentRow.tsxReviewPage.tsx 都在分支判断它,provider_test.go:79cmd/oneagent/main_test.go:20 更是直接用 openclaw 来测这条路径。

另外 6 个条目保持删除kirogemini-cliclinecontinueqwen-codekilo-vscode——没有任何代码引用它们。这也意味着 #12 想提升的 qwen-code 仍然不在目录里,那个 PR 的决定权仍在你手上,本 PR 不替它做决定。

golden fixture 是重新生成的,不是手改的

写了个临时 generator 走同一个 GetStatus 调用产出 fixture(已在提交前删除),而不是从失败信息里抄。

需要提醒的是这个 diff 比实质改动大:Go 序列化 map 时按键排序,而原文件不是那个顺序,所以重新生成必然带来重排。实质只有「6 个 Agent 离开、3 个留下」。我试过保留原顺序做最小 diff,但 catalogsupportedAgentIds 是按 rank 排序的数组,顺序是语义而非格式,强行保留旧序反而会写进错误的排序——所以采用生成结果。

frontend/dist/.keep

这是 #15 里提到的第二个独立问题,一并修了。.gitignore:14!frontend/dist/.keep 否定规则是正确的,注释说它是让 go:embed all:frontend/dist 在全新克隆上工作的关键——但那个文件从未被跟踪,所以规则没有东西可匹配。

后果是全新克隆或新 worktree 上 go vet ./... 会先失败于 pattern all:frontend/dist: no matching files found,必须先跑一次前端构建才能编译 Go。

验证方式是真的做了一次全新克隆:.keep 存在,go vet 直接通过(此前不可能),go testpnpm run build 也都过。

CI

仓库此前没有任何 PR 检查gh pr checks 报 "no checks reported"),build-artifacts.ymlworkflow_dispatch 手动触发且只构建不测试。这就是断裂能畅通无阻进 main 的原因。

新增 ci.yml,两个 job 对应本地实际跑的命令:go vet + go test -race,以及前端 pnpm run test + pnpm run build前端 build 正是能拦住 4d63d75 的那一步——它会解析那个提交遗弃的 import;go vet 拦不住,事实也没拦住。

-race 而非普通运行,因为 internal/app 的写入协调锁在普通运行下不会被触发。

验证

在本分支:

结果
go vet ./... 无输出
go test -race ./... 全部通过
前端 pnpm run build 通过(含 tsc --noEmit
前端 pnpm run test 151/151(main 是 89 passed + 7 文件加载失败)
覆盖率 statements 91.66% / branches 87.05% / functions 90%,过 85% 门禁

外加全新克隆上从零验证:go vetgo testpnpm run buildpnpm run test 151/151、覆盖率同上,全部通过。

🤖 Generated with Claude Code

yujiezhang-ops and others added 3 commits August 4, 2026 17:37
`chore: remove unused files` deleted three icon assets and nine catalog
entries but did not touch the code reading them, so main could not build or
pass its tests. `go vet` stayed clean, which is why it went unnoticed: only
the build and the test run reach these paths.

The three assets are restored because agents.tsx never stopped importing
them, and icons/agents.test.tsx asserts a distinct mark for cursor, openclaw
and hermes -- it calls them PROMINENT_GUIDE_AGENTS, agents shown on the first
screen alongside the one-click ones. That contract was not part of the
cleanup.

Those same three catalog entries come back, at ranks 6-8 rather than their
old 3/5/6, since main renumbered the auto agents to 1-5 and the old values
would now collide. Guide-only is not a dead concept: internal/app/install.go,
catalog/manifest.go validation, AgentRow and ReviewPage all still branch on
it, and provider_test.go and cmd/oneagent/main_test.go both use openclaw to
exercise it. The six entries with no code referencing them -- kiro,
gemini-cli, cline, continue, qwen-code, kilo-vscode -- stay deleted.

The golden fixture is regenerated rather than hand-edited, so it comes from
the same GetStatus call the assertion reads. It reorders more lines than it
changes because Go marshals maps with sorted keys and the previous file was
not written that way; the substance is six agents leaving and three staying.

frontend/dist/.keep is added because it was never actually tracked. The
.gitignore comment describes it as the thing that makes `go:embed
all:frontend/dist` work on a fresh clone, and the negation on line 14 is
right, but with no committed file the pattern had nothing to match -- so
`go vet` on a clean checkout failed before any of the above could be seen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The repository had no PR checks at all -- `gh pr checks` reported none, and
build-artifacts.yml is workflow_dispatch-only and builds without testing. So
the break this branch repairs reached main unopposed.

Two jobs, matching what a developer runs locally: go vet plus go test -race,
and the frontend test run plus build. The frontend build is the step that
would have caught 4d63d75, since it resolves the imports that commit
orphaned; `go vet` would not have, and did not.

-race rather than a plain run because the write coordination lock in
internal/app is not exercised otherwise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The new CI run is the first time `go test` has run on Linux in this
repository, and it failed on a test nobody had touched:
TestTheRegionProbeRunsOnlyOnce, "region probe ran 5 times, want 1".

The production code was right. countingRunner delegated to a real
process.Runner, while the caller simulates darwin -- so the argv is
`defaults read -g AppleLocale`. On a developer's Mac that succeeds and the
answer is cached once, which is what the test asserts. On Linux `defaults`
does not exist, so the probe reports "unanswered", and detectChineseRegion
deliberately does not cache an unanswered probe: it retried five times,
exactly as designed.

countingRunner now answers the probe itself, so the test measures caching
rather than which machine it runs on. Verified it still detects the
regression it exists for: disabling the `if answered` cache in settings.go
brings back "ran 5 times, want 1".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@yujiezhang-ops
yujiezhang-ops merged commit 65ebfb6 into main Aug 4, 2026
2 checks passed
@yujiezhang-ops
yujiezhang-ops deleted the fix/restore-green-main branch August 4, 2026 09:52
@yujiezhang-ops

Copy link
Copy Markdown
Collaborator Author

追加第三个修复:新 CI 自己抓到了一个我在本机看不到的问题。

TestTheRegionProbeRunsOnlyOnce 在 Linux 上失败("region probe ran 5 times, want 1")。查下来这是本仓库历史上第一次在 Linux 上跑 go test(此前只有手动触发的 Build artifacts,且不跑测试),所以这个测试从写下就没被跨平台验证过。

生产代码是对的。countingRunner 委托给真实的 process.Runner,而调用方模拟的是 darwin——argv 因此是 defaults read -g AppleLocale。在 Mac 上它成功、答案被缓存一次,正是断言期望的;在 Linux 上 defaults 根本不存在,探测报告「未作答」,而 detectChineseRegion 刻意不缓存未作答的探测(注释写明了原因),于是如设计般重试 5 次。

改成让 countingRunner 自己回答探测,测的是缓存行为而不是宿主机。做了变异测试确认它仍然有效:把 settings.goif answered 缓存关掉,「ran 5 times, want 1」立刻回来。

CI 现在两个 job 全绿——补 CI 的第一次运行就付出了价值。

yujiezhang-ops added a commit that referenced this pull request Aug 4, 2026
…heir tools

The repository had no LICENSE at all, which in a public repository means
"all rights reserved": nobody could legally fork, modify or `go get` a
module whose path is already github.com/MaimoryLab/OneAgent. Apache-2.0 was
chosen for its explicit patent grant and trademark clause.

NOTICE is the other half. distribution-compliance-policy.md has always
required a third-party licence manifest as a release precondition, but the
tool that generated it (cmd/oneagent-release) was removed in 23805b0, so the
obligation had no implementation. Every entry is read from disk rather than
assumed: the five Go modules actually linked into the desktop binary via
`go list -deps`, the five npm packages in the bundle, and the two runtimes
from runtimes.lock.json. The trademark section covers the eight Agent marks
in frontend/src/components/icons/assets, which agents.tsx already documents
as nominative use.

Three documents are removed rather than edited. agent-installer-target-versions.md
was internal strategy -- four unpublished conversion targets, SSO and unified
billing plans, and a hosted model gateway that product-boundary-baseline.md
explicitly lists as out of scope, so publishing both would have promised and
denied the same thing. The two concept documents were generation logs: one
carried a private image-proxy endpoint, and between them seventeen image
links point into the gitignored output/ directory, so they would have
rendered as broken images to any reader.

Twelve documents cited cmd/oneagent-release, cmd/oneagent-rc or
cmd/oneagent-provider-smoke, none of which exist. Removing them was
deliberate -- 23805b0 replaced them with build-artifacts.yml -- so the docs
are corrected rather than the tools restored. README and CLAUDE.md now
describe the workflow that runs; historical documents keep their conclusions
and gain a note saying the commands are background. Their command blocks are
retagged from `bash` to `text`, because a header note does not stop someone
scrolling to a shell block and running it. README also loses `task
test:native`, a target no Taskfile defines.

Two ADRs both claimed number 006. The public-site one becomes ADR-009, since
ADR-008's Supersedes line refers to the multi-profile one; ADR-006 now says
on its first line that its credential half is superseded, which previously
appeared only sixty lines down.

frontend/dist/.keep is restored: de3ed69 deleted it again, which re-broke
`go vet` on a fresh clone in exactly the way #16 fixed.

The cc-switch notes keep their findings but drop two conclusions that read
as disparaging a named individual's project; both are rewritten as the
methodological point they were actually making.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant