cc-haha/AGENTS.md
程序员阿江(Relakkes) 7ae885a114 fix: add safe Doctor rescue path for desktop upgrades
Online upgrades can strand users on stale desktop UI state or malformed local persistence. This adds a deny-by-default Doctor path that resets only regenerable desktop UI state, reports protected local files with redacted metadata, and keeps protected repair as a dry-run no-op until a reviewed backup-first flow exists.

Constraint: Chat transcripts, model/provider config, Skills, MCP, IM bindings, adapter sessions, OAuth tokens, plugins, and team/session records are user-owned protected state.
Rejected: Automatically rewrite malformed protected JSON | unsafe without schema-specific migrations and backups.
Rejected: Continue relying only on startup migrations | users need an explicit recovery action after a white screen.
Confidence: high
Scope-risk: moderate
Directive: Keep Doctor repair deny-by-default; do not mutate protected state without an explicit reviewed backup-first manual repair flow.
Tested: bun test src/server/__tests__/doctor-service.test.ts
Tested: cd desktop && bun run test src/components/ErrorBoundary.test.tsx src/lib/doctorRepair.test.ts src/__tests__/diagnosticsSettings.test.tsx src/components/layout/StartupErrorView.test.tsx
Tested: cd desktop && bun run lint
Tested: bun run check:server
Tested: bun run verify (failed only existing agent-utils coverage baseline; changed-lines coverage 97.62%)
Not-tested: Packaged desktop manual Doctor click path.
2026-05-07 00:04:06 +08:00

13 KiB

Repository Guidelines

Project Structure & Module Organization

The root package is the Bun-based CLI and local server. Main code lives in src/: entrypoints/ for startup paths, screens/ and components/ for the Ink TUI, commands/ for slash commands, services/ for API/MCP/OAuth logic, and tools/ for agent tool implementations. bin/claude-haha is the executable entrypoint. The desktop app is isolated in desktop/ with React UI code in desktop/src/ and Tauri glue in desktop/src-tauri/. Documentation is in docs/ and builds with VitePress. Treat root screenshots and docs/images/ as reference assets, not source code.

Build, Test, and Development Commands

Install root dependencies with bun install, then install desktop dependencies in desktop/ if you are touching the app UI.

  • ./bin/claude-haha or bun run start: run the CLI locally.
  • SERVER_PORT=3456 bun run src/server/index.ts: start the local API/WebSocket server used by desktop/.
  • bun run docs:dev / bun run docs:build: preview or build the VitePress docs.
  • cd desktop && bun run dev: run the desktop frontend in Vite.
  • cd desktop && bun run build: type-check and produce a production web build.
  • cd desktop && bun run test: run Vitest suites.
  • cd desktop && bun run lint: run TypeScript no-emit checks.
  • bun run verify: one-command local PR verification entrypoint for contributors and AI coding agents; equivalent to bun run quality:pr.
  • bun run quality:providers: list configured provider/model selectors for live agent baselines.
  • bun run quality:pr: run the local PR quality gate and write markdown, JSON, JUnit, and per-lane logs under artifacts/quality-runs/, plus coverage reports under artifacts/coverage/.
  • bun run check:quarantine: validate quarantined tests still have owners, exit criteria, and active review windows.
  • bun run check:coverage: run root, desktop, and adapter coverage suites with ratchet enforcement.
  • bun run quality:smoke --provider-model <provider:model[:label]>: run only provider live/proxy smoke and desktop agent-browser smoke.
  • bun run quality:gate --mode baseline --allow-live --provider-model <provider:model[:label]>: run live Coding Agent baseline cases, provider smoke, and desktop agent-browser smoke.
  • bun run quality:gate --mode release --allow-live --provider-model <provider:model[:label]>: run the release gate with live baseline, provider smoke, desktop smoke, and coverage.

Desktop Release Workflow

  • Desktop releases are built remotely by GitHub Actions, not by uploading local build artifacts.
  • The release workflow is .github/workflows/release-desktop.yml; it triggers automatically on push of tags matching v*.*.*.
  • Release workflow builds wait on a non-live quality:gate --mode pr preflight and upload release-quality-gate; run the live release gate locally or in a maintainer-controlled environment when provider credentials are available.
  • GitHub Release body is sourced from release-notes/vX.Y.Z.md in the tagged commit. Keep the filename aligned with the version/tag exactly.
  • Use bun run scripts/release.ts <version> to cut a desktop release. The script updates version files, refreshes desktop/src-tauri/Cargo.lock, requires the matching release-notes/vX.Y.Z.md, commits it, and creates the annotated tag.
  • The normal release push is git push origin main --tags. If the tag, app version, or release-notes filename do not match, the workflow is designed to fail fast instead of publishing the wrong release.
  • For local macOS test packaging, desktop/scripts/build-macos-arm64.sh is the canonical Apple Silicon build entrypoint, and outputs land under desktop/build-artifacts/macos-arm64/.

Docs Workflow Notes

  • The docs workflow is .github/workflows/deploy-docs.yml and uses npm ci, not Bun. When root package.json dependencies change, keep package-lock.json in the same commit or the docs build will fail.
  • The docs workflow currently runs on Node 22; avoid reintroducing older Node assumptions there without checking dependency engine requirements.

Coding Style & Naming Conventions

Use TypeScript with 2-space indentation, ESM imports, and no semicolons to match the existing code. Prefer PascalCase for React components, camelCase for functions, hooks, and stores, and descriptive file names like teamWatcher.ts or AgentTranscript.tsx. Keep shared UI in desktop/src/components/, API clients in desktop/src/api/, and avoid adding new dependencies unless the existing utilities cannot cover the change.

Testing Guidelines

Desktop tests use Vitest with Testing Library in a jsdom environment. Name tests *.test.ts or *.test.tsx; colocate focused tests near the file or place broader coverage in desktop/src/__tests__/. Add regression tests for behavior changes and keep the coverage ratchet from dropping.

Persistent Storage Compatibility

  • Any change to local JSON, localStorage, or app config persistence formats must ship with a forward migration, an old-fixture regression test, and a persistence upgrade gate.
  • ~/.claude/settings.json is user-owned shared state: preserve unknown fields on read/write, merge additively, and never write a repo-owned global schemaVersion into it.
  • Desktop Doctor and any automatic repair path must be deny-by-default. One-click repair may only mutate allowlisted, regenerable desktop UI state such as cc-haha-* localStorage keys or native window state. It must never mutate chat transcripts, model/provider config, Skills, MCP config, plugin state, IM bindings, adapter sessions, OAuth tokens, or team/session records.
  • Protected files include ~/.claude/projects/**/*.jsonl, ~/.claude/settings.json, project .claude/settings.json, ~/.claude/cc-haha/providers.json, ~/.claude/cc-haha/settings.json, ~/.claude/adapters.json, ~/.claude/adapter-sessions.json, ~/.claude/skills, project .claude/skills, .mcp.json, managed MCP config, ~/.claude/plugins/**, ~/.claude/teams/**, and ~/.claude/cc-haha/*oauth*.json. Doctor may diagnose these paths only with redaction unless a future task explicitly adds a reviewed, backup-first manual repair flow.
  • If a persistence shape cannot be upgraded in place, the change is blocked until the upgrade path is explicit and tested.

Feature Quality Contract

Every feature, bugfix, and behavior change must ship with proof that matches the changed surface. Treat this as the implementation contract for both human authors and AI coding agents.

  • Start by naming the behavior surface: desktop, server, adapter, native, docs, provider/runtime, agent-loop, or release.
  • Production code changes under desktop/src, src/server, src/tools, src/utils, or adapters must include a same-area test file in the same PR unless a maintainer explicitly approves allow-missing-tests.
  • Pure logic requires unit tests. Server/API/provider/runtime changes require server or request-shape tests. Desktop UI/store/API changes require Vitest or Testing Library coverage. User-facing desktop flows require browser/agent-browser smoke when the flow cannot be trusted through unit tests alone.
  • Agent loop, tool execution, provider routing, model selection, file editing, permissions, session resume, and desktop chat changes require mock/fixture tests in PR plus live smoke or baseline evidence from a maintainer machine when provider access exists.
  • Coverage is part of the feature, not an afterthought. The project standard is modeled on Google/Microsoft-style coverage practice: generated/build output is excluded, maintained product areas should move toward 75-80%+, and every changed executable production line must meet the changed-line coverage gate in scripts/quality-gate/coverage-thresholds.json before push/PR readiness.
  • Do not lower scripts/quality-gate/coverage-baseline.json or coverage-thresholds.json unless the PR carries maintainer approval via allow-coverage-baseline-change and explains why. Legacy areas below target are debt; new work must leave the touched area higher than it found it.
  • E2E is required when the feature crosses process boundaries, browser UI, WebSocket/session state, provider proxying, native sidecars, or release packaging. Use the narrowest meaningful E2E lane first, then quality:baseline/quality:release for core Coding Agent paths.
  • A PR is not ready until the author records changed files, tests added, coverage report path, E2E/live evidence or explicit blocker, and remaining risk. AI agents must include this evidence before saying "complete", "ready", or "mergeable".

Quality Gate Automation

Future Coding Agents should run the right local gate themselves before claiming a change is ready. Do not ask the user to manually run the commands unless credentials, local model access, or machine resources are missing.

  • Unified local entrypoint: bun run verify. This is the command AI coding agents should run before final handoff; it is equivalent to bun run quality:pr, does not call real models, and writes artifacts/quality-runs/<timestamp>/report.md plus artifacts/coverage/<timestamp>/coverage-report.md.
  • If bun run verify fails, do not stop at reporting the failure. Read the latest quality report, identify the failed lane in the Result Matrix, open that lane log under artifacts/quality-runs/<timestamp>/logs/<lane>.log, fix the concrete missing tests, coverage failures, lint/type/build errors, docs errors, or native errors, then rerun the narrow check and finally rerun bun run verify.
  • For coverage failures, read both coverage-report.md and coverage-report.json. Fix changedLines.failures and failures first; treat targetGaps as debt signals and make touched areas better. Do not lower coverage-baseline.json or coverage-thresholds.json unless a maintainer explicitly requested and approved that policy change.
  • For Path-aware PR checks failures, add same-area tests for changed production files instead of bypassing the gate. Maintainer overrides such as allow-missing-tests, allow-cli-core-change, and allow-coverage-baseline-change are not valid for ordinary feature work.
  • For normal code changes, run the narrow relevant check first, then bun run verify before a PR-ready or merge-ready claim.
  • Use bun run check:server for src/server, src/tools, provider/runtime, MCP, OAuth, WebSocket, or API behavior changes.
  • Use bun run check:desktop for desktop/src UI, stores, API clients, and desktop web behavior changes.
  • Use bun run check:native for desktop/src-tauri, sidecars, native packaging, release, or platform startup behavior changes.
  • Use bun run check:adapters for adapters/; on a fresh checkout run cd adapters && bun install first if dependencies are missing.
  • Use bun run check:docs for docs, VitePress, README, or docs workflow changes.
  • Use bun run check:quarantine and bun run check:coverage for code changes; production changes under desktop/src, src/server, src/tools, src/utils, or adapters must include same-area tests unless a maintainer explicitly approves allow-missing-tests. Coverage baseline or threshold changes require allow-coverage-baseline-change.
  • For chat, agent loop, tool execution, provider routing, desktop chat UI, CLI task execution, or other core Coding Agent paths, also run a live baseline when local providers are available: first bun run quality:providers, then choose one or more copyable selectors and run bun run quality:gate --mode baseline --allow-live --provider-model <provider:model[:label]>.
  • For release readiness, run bun run quality:gate --mode release --allow-live --provider-model <provider:model[:label]> with at least one real provider/model selector. Prefer multiple providers when quota is available. Release-mode live lanes must not be skipped silently.
  • If no live provider is configured, or a provider quota/key is unavailable, run the non-live gate anyway and report the live-baseline blocker explicitly instead of claiming full release confidence.
  • bun run check:docs executes npm ci, which can rebuild root node_modules. Run docs checks sequentially, not in parallel with verify, quality:pr, check:native, or other commands that depend on the same installed packages.
  • Quality reports are written to artifacts/quality-runs/<timestamp>/ as report.md, report.json, junit.xml, and logs/*.log; coverage reports are written to artifacts/coverage/<timestamp>/. Summarize the final report paths and the pass/fail/skip counts in handoffs and PR descriptions.
  • Do not commit generated artifacts/quality-runs/, local .omx/ state, node_modules/, desktop/node_modules/, or adapter dependency folders.
  • Do not claim "complete", "ready to merge", or "ready to release" without either running the matching gate or naming the exact blocker that prevented it.

Commit & Pull Request Guidelines

Recent history follows Conventional Commit prefixes such as feat:, fix:, and docs:. Keep subjects imperative and scoped to one change. PRs should explain the user-visible impact, list verification steps, link related issues, and include screenshots for desktop or docs UI changes. Keep diffs reviewable and call out any follow-up work or known gaps. Branch names should use normal product prefixes such as fix/xxx, feat/xxx, or docs/xxx; do not create codex/-prefixed branches in this repository.