Commit Graph
11 Commits
Author SHA1 Message Date
YHH 4fbbca6a99 refactor(go): adopt modern stdlib idioms and gate them (#7831)
* refactor(go): adopt modern stdlib idioms across kernel and desktop

Mechanical sweep with golangci-lint's modernize/intrange/copyloopvar/
usestdlibvars fixers plus hand-fixes for what they could not rewrite:
slices.Contains, min/max, slices.Backward, WaitGroup.Go, reflect.TypeFor,
maps.Copy, strings.Cut/CutPrefix/SplitSeq, strings.Builder, range-over-int.
Net -549 lines with no behavior change.

Three loops in session.go stay index-based: slices.Backward yields element
copies, so the fixer's rewrite silently dropped writes to DecisionReceipts
and ToolCalls (caught by TestDelivery* and TestDependentSameBatch*). All 49
slices.Backward sites were audited for that shape; only these three write
through the index, and they carry a nolint with the reason.

CaptureAfter's scan loop had an empty body and never ran any logic, so the
fixer could not express it. Drop it and the accessor it was the only caller
of. omitzero is deliberately untouched: turning omitempty into omitzero
changes the JSON written for nested structs, which is a wire-format change
to session files and the extension protocol.

* build(lint): gate the modern-idiom linters

Nothing stopped the codebase from drifting back to pre-1.22 idioms. Both
modules are now clean for modernize, intrange, copyloopvar, and
usestdlibvars, so enable them rather than leaving the sweep as a one-off.

omitzero stays disabled with the reason inline; usetesting, perfsprint, and
errorlint still have residue and land separately.
2026-08-07 15:30:33 +08:00
YHH c969509d66 style: strip section-banner decoration from comments (#7840)
312 banner separators across 63 files, the thing REASONIX.md bans outright and
nothing has ever checked. 64 were pure rules with no content and are gone; the
other 248 carried a label inside the dashes, so the decoration is stripped and
the label kept -- `// --- session/resume ---` becomes `// session/resume`, which
still orients a reader in a 1000-line test file without drawing a line across it.

The repolint ceiling for this rule drops 312 -> 0, so it is now zero-tolerance
rather than merely frozen.
2026-08-07 14:39:41 +08:00
SivanCola 7fe7d2b3f3 Simplify MCP authorization for installed servers / 简化已安装 MCP 授权 (#6767)
* fix(mcp): trust installed readers in subagents

Problem:
User-installed MCP tools that declared readOnlyHint could be exposed as readers but then fail before dispatch in planners and read-only subagents. Users were told to configure a second per-tool reader policy after already installing or authorizing the server.

Root cause:
Strict reader trust did not treat explicit install or an exact project launch grant as authority for non-destructive server metadata. Direct, lazy, and on-demand paths also duplicated cached-to-live safety reconciliation, while trusted_read_only_tools remained wired through configuration and Desktop contracts.

Fix:
Authorize non-destructive readOnlyHint tools for installed or launch-authorized servers, carry reader intent only for trusted readers, and share one cached-to-live safety reconciliation boundary across lazy and on-demand adapters. Remove trusted_read_only_tools from runtime, Desktop, examples, and docs while accepting and dropping legacy input on the next save.

Verification:
- env -u DEEPSEEK_API_KEY go test -count=1 ./...
- cd desktop && go test -count=1 ./...
- cd desktop/frontend && pnpm test:typecheck
- cd desktop/frontend && pnpm exec tsx src/__tests__/capabilities-panel-actions.test.ts
- ./scripts/cache-guard.sh
- ./scripts/check-cache-impact.sh
- git diff --check

* refactor(mcp): simplify installed server authorization

Problem:
User-installed MCP servers still depended on official-catalog and per-tool reader trust layers, so direct, lazy, and on-demand paths could disagree and strict child sessions could reject an already authorized reader.

Root cause:
Server authorization, signed package status, cached reader trust, and legacy plan-mode allowlists were modeled as separate overlapping decisions.

Fix:
Remove the official MCP catalog, signature/revocation plumbing, package verification, per-tool cached trust, and obsolete reader settings. Use one server-level authorization source for user installs, host-session installs, and exact project grants while retaining live read-only, destructive, and capability-fingerprint checks.

Verification:
- go test ./internal/plugin ./internal/agent ./internal/boot ./internal/config ./internal/installsource ./internal/pluginpkg ./internal/mcplaunch ./internal/planmode
- go test ./internal/acp ./internal/agent ./internal/plugin ./internal/boot
- cd desktop && go test ./...
- ./scripts/cache-guard.sh
- git diff --check

* refactor(mcp): make install authorization final

Problem:
Installed MCP servers could still encounter server, per-tool, writer, or destructive approval branches, and users had to understand settings that duplicated the install decision.

Root cause:
MCP authorization, cached reader trust, approval policy, and process sandboxing evolved as separate paths across direct, lazy, and on-demand execution.

Fix:
Treat install or exact project identity confirmation as the server authorization boundary, keep only explicit global deny plus Plan/read-only and sandbox safety checks, remove catalog and approval configuration, and unify the persistent MCP process sandbox.

Verification:
env -u DEEPSEEK_API_KEY go test ./...
go build ./...
cd desktop && go test ./...
cd desktop/frontend && pnpm typecheck
cd desktop/frontend && pnpm exec tsx src/__tests__/capabilities-panel-actions.test.ts
cd desktop/frontend && pnpm exec tsx src/__tests__/decision-surface.test.tsx

* chore(mcp): remove retired cache helper

Problem:
CI lint found writeBoolKV left unused after per-tool reader trust was removed.

Root cause:
The cached reader-map fingerprint was deleted, but its serialization helper remained.

Fix:
Remove the dead helper.

Verification:
go test ./internal/plugin
go vet ./internal/plugin
go build ./...

* refactor(mcp): stop blocking schema-only drift

Problem:
Authorized MCP calls could be rejected when a cached tool schema differed from the live server even though authorization and safety classification were unchanged.

Root cause:
A capability fingerprint mixed schema compatibility with read-only and destructive execution safety across direct, lazy, and on-demand paths.

Fix:
Remove the tool-level schema fingerprint chain, keep live server authorization and read-only/destructive reclassification checks, and refresh changed schemas for the next session without interrupting the current authorized call.

Verification:
- go test ./internal/plugin ./internal/agent ./internal/tool
- env -u DEEPSEEK_API_KEY go test ./...
- go vet ./...
- go build ./...
- ./scripts/cache-guard.sh
- pnpm --dir site test
- cd desktop && go test ./...

* fix(mcp): preserve short Windows temp paths

Problem:
Windows stdio MCP servers inherited a deeply nested Reasonix private TEMP path. Servers such as MATLAB create watchdog Unix sockets below TEMP and exit before initialization when the path exceeds the platform limit.

Root cause:
MCP private-state preparation redirected TMP, TEMP, and TMPDIR below the workspace-scoped mcp-state directory on every platform even though Reasonix does not currently provide an OS sandbox on Windows.

Fix:
Keep the host temporary-directory environment for Windows stdio MCP processes while retaining private cache and state directories. Preserve the existing private temporary directory behavior on other platforms and add focused regression coverage for both branches.

Verification:
- go test ./internal/plugin -count=1
- GOOS=windows GOARCH=amd64 go test -c ./internal/plugin
- go test ./...
- go vet ./internal/plugin
- git diff --check

* Simplify MCP runtime authorization state

Use Spec.Authorized as the sole resolved server authorization result so installed and host-session MCP servers no longer depend on launch-manager presence.

Keep exact identity grants for project sources, align planner and strict read-only registries with non-destructive readOnlyHint metadata, and document the cooperative trust boundary.

Add source and agent-surface matrix coverage while preserving the main provider-visible MCP tool surface.

* Limit MCP identity digests to project servers

Problem: User-installed and host-session MCP servers still resolved and hashed their executable identity during every startup even though installation was already the authorization decision.

Root cause: Project launch authorization and schema-cache ownership shared generic fingerprint terminology, and start() computed the project identity before checking whether launch approval was required.

Fix: Skip project identity resolution for installed servers, remove dead and non-participating identity state, and rename the remaining concepts to ProjectLaunchIdentityDigest and SchemaCacheKey while preserving existing JSON keys and digest bytes.

Verification: go test ./internal/mcplaunch ./internal/plugin ./internal/capability ./internal/boot ./internal/control ./internal/agent; go test ./...; cd desktop && go test .; go vet ./...; ./scripts/cache-guard.sh; git diff --check.

* Restore MCP 0.53 compatibility surfaces

Problem: MCP authorization was simplified, but the current client still lacked four compatibility surfaces present in the 0.53 line: legacy SSE, workspace roots, progress notifications, and registry browsing/install.

Root cause: the Go transport abstraction dropped inbound notifications and rejected legacy SSE; runtime specs did not carry a separate workspace root; the registry UI and CLI had no official MCP Registry client.

Fix: add inbound request/progress routing across transports, implement legacy SSE with same-origin endpoint protection, advertise roots/list, and add an explicit cached official Registry marketplace to CLI and desktop. Remove stale approval documentation and the dead helper that broke lint.

Verification: go test ./...; focused go test -race for plugin/registry/CLI/control; go vet in root and desktop; desktop go test ./...; frontend production build and marketplace UI test; Windows amd64 cross-build; official Registry browse smoke test.

* Avoid MCP progress capacity overflow

* Align MCP authorization documentation

Problem: CLI help and Chinese documentation still contained ambiguous or obsolete wording that implied installed MCP writer or destructive calls could require per-call approval.

Root cause: The server-level authorization simplification removed MCP approval modes, but not every user-facing explanation was updated consistently.

Fix: State explicitly that install or exact project identity confirmation authorizes the server, that writer and destructive hints do not prompt per call, and that deny, Plan, and strict read-only filtering remain separate boundaries.

Verification: go test ./internal/cli; go vet ./internal/cli; reasonix mcp help smoke test; stale-wording scan; git diff --check.

* Harden MCP registry installs and SSE replies

Problem:
Registry cache freshness was shared across queries, cached entries could flow into install paths, and legacy SSE server requests spawned an unbounded reply goroutine per request.

Root cause:
The cache stored one global timestamp, Resolve reused Search's offline fallback, the desktop installed browse payloads directly, and the SSE reader delegated every reply to a new goroutine.

Fix:
Track freshness per Registry query with legacy-cache compatibility, require live resolution before CLI and desktop installs, and serialize SSE replies through a bounded single-worker queue with finite deadlines.

Verification:
- env -u DEEPSEEK_API_KEY go test -count=1 ./...
- env -u DEEPSEEK_API_KEY go test -race -count=1 ./internal/mcpregistry ./internal/plugin
- env -u DEEPSEEK_API_KEY go test -count=1 ./... (desktop)
- env -u DEEPSEEK_API_KEY go vet ./... (root and desktop)
- pnpm run test:all
- pnpm run build
- env -u DEEPSEEK_API_KEY ./scripts/cache-guard.sh
- git diff --check

* Reject unavailable live registry installs

Problem:
A Registry entry could become non-installable between browsing and the desktop's live re-resolution, leaving the generic add flow with an invalid empty connection. The SSE concurrency regression also used a fixed delay after routing the client response.

Root cause:
The desktop resolver verified freshness but not the resolved entry's installability, and the test inferred worker startup from elapsed time.

Fix:
Validate the live entry through PluginEntry before returning it to the installer, and synchronize the SSE test on the first reply POST instead of sleeping.

Verification:
- env -u DEEPSEEK_API_KEY go test -count=5 ./internal/plugin
- env -u DEEPSEEK_API_KEY go test -race -count=3 ./internal/plugin
- env -u DEEPSEEK_API_KEY go test -count=1 ./...
- cd desktop && env -u DEEPSEEK_API_KEY go test -count=1 ./...
- git diff --check
2026-07-22 01:58:43 +08:00
MorningTZH 43cc7a315c fix(acp): accept official HTTPHeader[] shape for MCP server headers
ACP spec ships HTTP/SSE MCP `headers` as an array of {name,value} objects
(see https://agentclientprotocol.com). Reasonix's `MCPServerSpec.Headers`
declared the legacy `map[string]string` shape, so spec-compliant clients
like Paseo — which always emits `headers` as an array, even when empty —
got rejected at the very first `session/new`:

    json: cannot unmarshal array into Go struct field
    MCPServerSpec.mcpServers.headers of type map[string]string

The sibling `Env` field already solves this exact problem with a custom
`MCPEnv` type that tries the official array shape first and falls back to
the legacy map. Mirror that for headers via a new `MCPHeaders` type, and
extract the shared parse into `unmarshalNameValueMap` so both fields share
one implementation. Existing wire formats keep working unchanged.

Refs: #5553
2026-06-29 15:15:40 +08:00
SivanCola 77d58bcbfb Fix ACP Zed integration gaps 2026-06-16 23:07:26 +08:00
Sivan 655c72ad9b Remove bundled MCP servers and add code index fallback 2026-06-16 17:44:27 +08:00
SivanCola a9760911fc feat(tools): add workspace-confined move_file built-in (#4316)
Add a workspace-confined move_file(source_path, destination_path) built-in so
file moves/renames go through the Edit permission family instead of shell mv /
Move-Item, where prefix-scoped approvals would keep re-prompting. Both endpoints
are confined and permission-checked (deny > ask > allow across source and
destination); cross-device and case-only renames are handled.

Closes #4310
2026-06-14 20:08:28 +08:00
SivanCola e32d167842 feat(acp): complete v1 session lifecycle (#3383) 2026-06-06 19:21:08 -07:00
YHHandreasonix 1d5703af48 test: make path and codegraph tests Windows-portable (#2507)
Several tests hard-coded Unix paths (transcriptPath, NewSessionPath, Store.Path, resolveCustomPaths), failing on Windows where filepath joins with backslash and '/x' is not absolute. Switched to t.TempDir() + filepath.Join. The three boot.Build tests also left CodeGraph enabled (default true), which spawns an MCP child holding codegraph.db open, so t.TempDir cleanup fails on Windows (locked file); disabled it there since those tests cover memory/skill folding, not codegraph. Full suite now green on Windows; unchanged on Linux/macOS.

Co-authored-by: reasonix <[email protected]>
2026-05-31 19:28:41 -07:00
HUQIANTAOandHUQIANTAO 3dac4d2876 test(acp): add tests for newSessionID, mcpSpecs, transcriptPath, and acpSession (#2445)
Co-authored-by: HUQIANTAO <[email protected]>
2026-05-31 07:34:47 -07:00
esengine 5d40158aa6 feat(acp): add stdio JSON-RPC adapter layer (phase A)
Faithful Go port of main's src/acp/*.ts: NDJSON JSON-RPC 2.0 server,
ACP v1 wire types, event.Sink -> session/update dispatcher,
permission.Approver -> session/request_permission bridge, and a session
registry behind a Factory seam so the package stays independent of cli
wiring. Tested: lifecycle, permission round-trip, cancel, framing.
2026-05-29 20:29:39 -07:00