返回 DeepSeek-Reasonix
CONTRIBUTING.md
根目录 / CONTRIBUTING.md
1 # Contributing to Reasonix
2
3 Thank you for your interest in contributing to Reasonix! This guide covers
4 everything you need to get started.
5
6 ## Prerequisites
7
8 - **Go 1.25+** — the project targets the latest stable Go release
9 - **Git** — for version control
10 - **Node.js** (optional) — only if you work on the desktop app (`desktop/`)
11
12 ## Getting started
13
14 ```bash
15 git clone https://github.com/esengine/DeepSeek-Reasonix.git
16 cd DeepSeek-Reasonix
17 go build ./cmd/reasonix # builds the CLI binary
18 go test ./... # runs the full test suite
19 ```
20
21 ## Project structure
22
23 | Directory | Purpose |
24 |-----------|---------|
25 | `cmd/reasonix` | CLI entry point |
26 | `internal/agent` | Agent loop, session, coordinator |
27 | `internal/cli` | TUI, subcommands, setup wizard |
28 | `internal/control` | Transport-agnostic controller |
29 | `internal/config` | TOML configuration loading |
30 | `internal/tool/builtin` | Built-in tools (bash, read_file, …) |
31 | `internal/provider` | Model-backend abstraction |
32 | `internal/provider/openai` | OpenAI-compatible provider |
33 | `internal/plugin` | MCP client (stdio + HTTP) |
34 | `internal/event` | Typed event stream |
35 | `internal/hook` | Shell hooks (PreToolUse, …) |
36 | `internal/memory` | REASONIX.md hierarchy + auto-memory |
37 | `internal/skill` | Skill discovery from Markdown |
38 | `internal/sandbox` | OS-level sandboxing |
39 | `internal/serve` | HTTP/SSE server frontend |
40 | `internal/checkpoint` | Snapshot-based rewind |
41 | `desktop/` | Wails-based desktop app (separate Go module) |
42 | `docs/` | Engineering spec, migration guide |
43
44 ### Dependency direction
45
46 ```
47 cli → {agent, plugin, config} → {tool, provider}
48 ```
49
50 Built-in subpackages import their parent to self-register via `init()`.
51 Parents never import children.
52
53 ## Development workflow
54
55 ### Building
56
57 ```bash
58 make build # go build ./...
59 make test # go test ./...
60 make vet # go vet ./...
61 make fmt # gofmt -w .
62 make hooks # install git hooks (pre-push: go vet)
63 make cross # cross-compile for all 6 targets
64 ```
65
66 ### Isolated development environment
67
68 A source-built binary shares no on-disk state with a stable release when launched
69 with `REASONIX_HOME` set. This gives each build its own self-contained directory
70 tree — config, credentials, sessions, cache, skills, commands, hooks, and
71 desktop tab state — so the two builds never interfere:
72
73 **CLI**
74
75 ```bash
76 REASONIX_HOME=/tmp/reasonix-dev go run ./cmd/reasonix
77 # or after building:
78 # REASONIX_HOME=/tmp/reasonix-dev ./bin/reasonix
79 ```
80
81 **Desktop**
82
83 ```bash
84 cd desktop && wails build
85 REASONIX_HOME=/tmp/reasonix-dev-isolated build/bin/reasonix-desktop
86 ```
87
88 On Windows, use `$env:REASONIX_HOME` in PowerShell or `set REASONIX_HOME=` in
89 Command Prompt; the binary extension is `.exe`.
90
91 The directory is empty on first launch; the app behaves exactly like a fresh
92 install. Every subsequent write — config saves, credential storage, session
93 logs — stays under `REASONIX_HOME`. Legacy migration, OS-home convention
94 directory scanning, and all other fallback paths are skipped so no production
95 data leaks in or out.
96
97 ### Cache-first review gate
98
99 Reasonix treats high prompt-cache hit rate as product behavior. Changes that
100 touch provider-visible system prompt construction, memory prefix, output styles,
101 skill index behavior, default tool surfaces, tool schemas, provider request
102 serialization, compaction, or MCP/tool registration need explicit cache review.
103
104 For these changes:
105
106 - Keep system prompt changes low-frequency and require explicit review.
107 - Fill the PR body `Cache-impact:` line with `none`, `low`, `medium`, or `high`
108 plus the reason.
109 - Fill the PR body `Cache-guard:` line with the focused guard test/command added
110 or run, or explain why an existing guard covers the change.
111 - Fill `System-prompt-review:` when system prompt, memory prefix, output style,
112 or skill index behavior changes.
113 - Prefer focused guard tests near the changed surface; `scripts/cache-guard.sh`
114 remains the broader release-level cache-hit check.
115
116 CI enforces this metadata for cache-sensitive paths so prompt/tool prefix churn
117 is called out before review.
118
119 ### Running tests
120
121 ```bash
122 go test ./... # all tests
123 go test ./internal/agent/ -v # verbose, one package
124 go test ./internal/tool/builtin/ -run TestGrep # one test
125 ```
126
127 ### Code style
128
129 - `gofmt` is enforced by CI — format before committing
130 - Follow existing patterns: wrap errors with `fmt.Errorf("...: %w", err)`
131 - Library code never calls `os.Exit` or prints to stdout/stderr
132 - Only `cli/` and `main/` decide exit codes and user-facing messages
133 - Exported identifiers must have doc comments
134
135 ### Commit messages
136
137 Follow [Conventional Commits](https://www.conventionalcommits.org/):
138
139 ```
140 feat(glob): add ** recursive pattern support
141 fix: replace silent error discards with structured logging
142 test(event): add comprehensive unit tests for event package
143 docs: add CONTRIBUTING.md
144 ci: add golangci-lint and govulncheck
145 ```
146
147 ## Adding a new built-in tool
148
149 1. Create `internal/tool/builtin/mytool.go`
150 2. Implement the `tool.Tool` interface: `Name()`, `Description()`, `Schema()`, `ReadOnly()`, `Execute()`
151 3. Register via `func init() { tool.RegisterBuiltin(myTool{}) }`
152 4. Add tests in `internal/tool/builtin/builtin_test.go` or a separate `mytool_test.go`
153 5. The tool is automatically available — `main` blank-imports `builtin`
154
155 ## Adding a new model provider
156
157 (For MCP tool servers see `internal/plugin` instead — that's a different layer.)
158
159 1. Create `internal/provider/myprovider/`
160 2. Implement `provider.Provider`: `Name()`, `Stream()`
161 3. Register via `func init() { provider.Register("mykind", New) }`
162 4. The provider is available from config with `kind = "mykind"`
163
164 ## Adding i18n strings
165
166 1. Add the field to `internal/i18n/i18n.go` (`Messages` struct)
167 2. Add the value in `internal/i18n/messages_en.go` and `messages_zh.go`
168 3. The `TestCatalogsComplete` test will fail if you miss a locale
169
170 ## Submitting changes
171
172 1. Fork the repository
173 2. Create a feature branch from `main-v2`
174 3. Make your changes with tests
175 4. Ensure `go test ./...` passes
176 5. Ensure `gofmt -l .` shows no changes
177 6. Submit a pull request to `main-v2`
178
179 ## Reporting issues
180
181 Open an issue on GitHub with:
182 - Steps to reproduce
183 - Expected vs actual behavior
184 - Go version and OS
185 - Relevant logs or error messages
186
187 ## License
188
189 By contributing, you agree that your contributions will be licensed under the
190 same license as the project.
191
191 lines MARKDOWN