Commit 57d1b7b
authored
feat(prompt): add system prompt builder with context injection (#7)
## Summary
Add a section-based system prompt builder with runtime environment
detection, hierarchical instruction file discovery (CLAUDE.md /
AGENTS.md), and static guidance sections. The prompt is rebuilt each
turn so git status and branch info stay fresh.
The API client now sends the system prompt as an array of text blocks
with the identity prefix in its own block, which is required for OAuth
validation on non-Haiku models.
- Section-based prompt assembly: identity, task guidance, caution, tool
usage, tone / style, environment, user instructions.
- CLAUDE.md / AGENTS.md discovery with root-to-CWD walk and `.claude/`
subdirectory support.
- Runtime environment detection: working directory, platform, shell, git
branch + clean / dirty status, local date, model name.
- Per-turn prompt rebuild for fresh git state on every user message.
- System prompt sent as array of `TextBlock` with identity prefix in its
own block (OAuth requirement).
- Research docs on system prompt architecture and API authentication
(block format, attribution header, third-party restrictions).
- User-facing guide: quickstart, configuration, instruction files.
## Changes
| File | Description |
| ---- | ----------- |
| `crates/oxide-code/src/prompt.rs` | Module root: static guidance
constants, `build_system_prompt` entry, `assemble` (testable core),
`find_git_root` |
| `crates/oxide-code/src/prompt/environment.rs` | `Environment` struct
with `detect` / `render`, parallel git info via `tokio::join!`,
`current_date` via `time` crate with local-offset fallback |
| `crates/oxide-code/src/prompt/instructions.rs` | `Slot`-based
instruction discovery: `load` → `candidate_slots` → `walk_root_to_cwd` →
`load_files` → `render` |
| `crates/oxide-code/src/client/anthropic.rs` | `SystemBlock` type,
`system` field changed from `&str` to `Vec<SystemBlock>`, prefix sent as
separate block, `SYSTEM_PROMPT_PREFIX` moved here |
| `crates/oxide-code/src/main.rs` | Per-turn `build_system_prompt` call,
pass `Some(&system_prompt)` to client |
| `crates/oxide-code/src/config/oauth.rs` | `_ =` style consistency |
| `Cargo.toml` | Add `time` with `local-offset` feature |
| `CLAUDE.md` | Add `prompt.rs`, `prompt/environment.rs`,
`prompt/instructions.rs` to crate structure |
| `docs/research/system-prompt.md` | Research: Claude Code and opencode
prompt architecture, section caching, walk behavior |
| `docs/research/anthropic-api.md` | Research: system block format,
attribution header / fingerprint, third-party restrictions |
| `docs/guide/quickstart.md` | User guide: install, credentials, first
session, tools table |
| `docs/guide/configuration.md` | User guide: API key, OAuth,
environment variables |
| `docs/guide/instructions.md` | User guide: CLAUDE.md / AGENTS.md
discovery hierarchy, walk example |
| `docs/guide/README.md` | Guide index |
| `docs/README.md` | Add User Guide section |
| `docs/roadmap.md` | Move system prompt to Working, update focus |
| `README.md` | Slim down, add Documentation table linking to guide |
## Test plan
- [x] `cargo build` compiles cleanly
- [x] `cargo clippy --all-targets -- -D warnings` — zero warnings
- [x] `cargo test` — 195 tests pass
- [x] `cargo llvm-cov --ignore-filename-regex 'main\.rs'` — 89% line
coverage (prompt modules 98–99%)
- [x] Live test: `ox` responds correctly with full system prompt
(CLAUDE.md injected, environment detected)
- [x] Live test: `main` branch works, `feat/system-prompt` works after
block-format fix1 parent 687d557 commit 57d1b7b
20 files changed
Lines changed: 1466 additions & 52 deletions
File tree
- .cspell
- crates/oxide-code
- src
- client
- config
- prompt
- docs
- guide
- research
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
34 | 38 | | |
35 | 39 | | |
36 | 40 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | | - | |
| 25 | + | |
25 | 26 | | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
38 | 32 | | |
39 | 33 | | |
40 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
22 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
40 | 50 | | |
41 | 51 | | |
42 | 52 | | |
| |||
230 | 240 | | |
231 | 241 | | |
232 | 242 | | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
237 | 253 | | |
238 | 254 | | |
239 | 255 | | |
240 | 256 | | |
241 | 257 | | |
242 | 258 | | |
243 | | - | |
| 259 | + | |
244 | 260 | | |
245 | 261 | | |
246 | 262 | | |
| |||
253 | 269 | | |
254 | 270 | | |
255 | 271 | | |
256 | | - | |
| 272 | + | |
257 | 273 | | |
258 | 274 | | |
259 | 275 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
302 | 302 | | |
303 | 303 | | |
304 | 304 | | |
305 | | - | |
| 305 | + | |
306 | 306 | | |
307 | 307 | | |
308 | 308 | | |
| |||
318 | 318 | | |
319 | 319 | | |
320 | 320 | | |
321 | | - | |
| 321 | + | |
322 | 322 | | |
323 | 323 | | |
324 | 324 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
| 38 | + | |
37 | 39 | | |
38 | 40 | | |
39 | 41 | | |
| |||
44 | 46 | | |
45 | 47 | | |
46 | 48 | | |
47 | | - | |
| 49 | + | |
48 | 50 | | |
49 | 51 | | |
50 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
51 | 58 | | |
52 | 59 | | |
53 | 60 | | |
| |||
66 | 73 | | |
67 | 74 | | |
68 | 75 | | |
69 | | - | |
| 76 | + | |
| 77 | + | |
70 | 78 | | |
71 | 79 | | |
72 | 80 | | |
| |||
76 | 84 | | |
77 | 85 | | |
78 | 86 | | |
| 87 | + | |
79 | 88 | | |
80 | 89 | | |
81 | 90 | | |
82 | 91 | | |
83 | 92 | | |
84 | 93 | | |
85 | | - | |
| 94 | + | |
| 95 | + | |
86 | 96 | | |
87 | 97 | | |
88 | 98 | | |
| |||
205 | 215 | | |
206 | 216 | | |
207 | 217 | | |
| 218 | + | |
208 | 219 | | |
209 | 220 | | |
210 | | - | |
| 221 | + | |
211 | 222 | | |
212 | 223 | | |
213 | 224 | | |
| |||
0 commit comments