Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1e4a4c4
chore(oxide-code): add dependencies for Anthropic client
hakula139 Apr 1, 2026
05f2eb4
feat(oxide-code): add config with API key and OAuth auth
hakula139 Apr 1, 2026
e0e4e96
feat(oxide-code): add conversation message types
hakula139 Apr 1, 2026
75d4063
feat(oxide-code): add Anthropic Messages API streaming client
hakula139 Apr 1, 2026
66d965a
feat(oxide-code): wire up async REPL with streaming responses
hakula139 Apr 1, 2026
cf31dc8
docs: update crate structure diagram and cspell dictionary
hakula139 Apr 1, 2026
213260f
refactor(oxide-code): rename binary from oxide-code to ox
hakula139 Apr 1, 2026
d4baad0
fix(oxide-code): change default model to claude-opus-4-6
hakula139 Apr 2, 2026
006ddce
fix(oxide-code): use correct auth headers for OAuth tokens
hakula139 Apr 2, 2026
fe48c1b
docs: standardize section dividers to box-drawing style (── xxx ──)
hakula139 Apr 2, 2026
f1eadac
chore: add missing words to cspell dictionary
hakula139 Apr 2, 2026
7433a07
feat(oxide-code): enable 1M context via anthropic-beta header
hakula139 Apr 2, 2026
25dade3
fix(oxide-code): treat empty env vars as unset in config loading
hakula139 Apr 2, 2026
1e9531c
fix(oxide-code): add required system prompt prefix and beta headers
hakula139 Apr 2, 2026
fe1e1c0
docs: add Anthropic API authentication research notes
hakula139 Apr 2, 2026
17d6736
docs: update roadmap with current working features
hakula139 Apr 2, 2026
3926ecf
docs: add documentation index
hakula139 Apr 2, 2026
1c64fce
chore: add markdownlint configuration
hakula139 Apr 2, 2026
d42ff04
chore: add Python environment (uv) for development scripts
hakula139 Apr 2, 2026
8736261
chore: add missing words to cspell dictionary
hakula139 Apr 2, 2026
f0e9804
style: fix table alignment in docs index
hakula139 Apr 2, 2026
e97a0a3
docs(CLAUDE): revise coding conventions for idiomaticness
hakula139 Apr 2, 2026
7608da0
refactor(oxide-code): address code review findings
hakula139 Apr 2, 2026
286347a
refactor(oxide-code): reorder helpers after their callers
hakula139 Apr 2, 2026
9b75352
style(oxide-code): reorder beta header constants by usage
hakula139 Apr 2, 2026
8cf339d
test(oxide-code): use indoc for multi-line test strings
hakula139 Apr 2, 2026
616c699
chore: update Cargo.lock for indoc dependency
hakula139 Apr 2, 2026
3de3984
docs(research): revise Anthropic API authentication notes
hakula139 Apr 2, 2026
6b19745
feat(oxide-code): add OAuth token refresh with proactive renewal
hakula139 Apr 2, 2026
0607730
style(research): sort source references alphabetically by path
hakula139 Apr 2, 2026
bd2d098
docs: add PR template with Changes table and refine git conventions
hakula139 Apr 2, 2026
15ab134
refactor(oauth): extract expires_at_ms() and reduce nesting in load_t…
hakula139 Apr 2, 2026
5e5c324
refactor(client): remove Client re-export, use consistent import path
hakula139 Apr 2, 2026
605549d
fix(oauth): add #[serde(default)] for missing refresh_token field
hakula139 Apr 2, 2026
cac7ea6
test(message): add tests for Message::user and Message::assistant
hakula139 Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .cspell/words.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
anthropic
anyhow
clippy
codex
creds
deserialize
dtolnay
hakula
impls
indoc
println
RAII
ratatui
reqwest
rustls
serde
strum
swatinem
thiserror
tokio
tracing
venv
13 changes: 9 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<!-- markdownlint-disable-next-line first-line-heading -->
## Summary

<!-- One bullet per logical change. Group by: features, refactors, tests, docs. -->
<!-- Prose intro: what this PR does and why, in 1-3 sentences. -->

<!-- Then one bullet per logical change. -->

-

## Follow-ups
## Changes

<!-- Items deferred from this PR. Remove section if none. -->
<!-- Per-file breakdown. Remove for trivial PRs. -->

-
| File | Description |
| ---- | ----------- |
| | |

## Test plan

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Build output
/target/

# Python
/.venv/

# OS files
.DS_Store

Expand Down
5 changes: 5 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"line-length": false,
"no-duplicate-heading": { "siblings_only": true },
"no-inline-html": false
}
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
64 changes: 50 additions & 14 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

## Project Overview

oxide-code is a terminal-based AI coding assistant written in Rust, inspired by [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It communicates with LLM APIs to help developers with software engineering tasks directly from the terminal.
oxide-code is a terminal-based AI coding assistant written in Rust, inspired by [Claude Code](http://code.claude.com/docs). It communicates with LLM APIs to help developers with software engineering tasks directly from the terminal.

### CLI

```bash
oxide-code # Start an interactive session
ox # Start an interactive session
```

### Project Layout
Expand All @@ -22,7 +22,14 @@ oxide-code # Start an interactive session

```text
.
└── main.rs # CLI entry point
├── client.rs # Client module root
├── client/
│ └── anthropic.rs # Anthropic Messages API streaming client
├── config.rs # Configuration loading (env vars, model, base URL)
├── config/
│ └── oauth.rs # Claude Code OAuth credentials, token refresh, file locking
├── main.rs # CLI entry point, async REPL
└── message.rs # Conversation message types
```

## Coding Conventions
Expand All @@ -31,18 +38,35 @@ oxide-code # Start an interactive session

- Application code: `anyhow::Result` with `.context()` for actionable messages.
- Library error types: `thiserror::Error` derive for errors that callers need to match on.
- Avoid `unwrap()` / `expect()` in production code. Reserve them for cases with a clear invariant comment.

### Lint Suppression

- Use `#[expect(lint)]` instead of `#[allow(lint)]`. `#[expect]` warns when the suppressed lint is no longer triggered, preventing stale suppressions from accumulating.
- `#[expect]` reason strings must describe the current state, not future plans.

### Section Dividers

- Use `// ── Section Name ──` for section dividers in code (box-drawing character `─`, U+2500).
- In tests, use `// ── function_name ──` as section headers grouping tests by the function they cover.

### Module Organization

- New-style module paths: `foo.rs` alongside `foo/` directory, not `foo/mod.rs`.
- Keep files focused: one primary type or concern per file.
- Place functions and types in the module that reflects their conceptual domain — import paths should not mislead about what the item does. Create new modules when needed for clean organization.
- Avoid deep `pub use` re-export chains that obscure where items are defined.
- Order helper functions by their caller.
- Avoid `pub use` re-exports that obscure where items are defined. Prefer consistent import paths — if some items are re-exported, re-export all related items so callers never mix paths.
- Order helper functions after their caller (top-down reading order).

### Visibility

- Default to the smallest visibility needed: private → `pub(crate)` → `pub`.
- `pub` items form the crate's API surface. Use `pub(crate)` for items shared across modules but not intended for external use.

### Imports

- Group `use` statements in three blocks separated by blank lines: std → external crates → internal modules.
- Within each block, sort alphabetically.

### String Literals

Expand All @@ -61,21 +85,33 @@ oxide-code # Start an interactive session

### Git Conventions

- Commit messages: `type(scope): description`
#### Commits

- Messages: `type(scope): description`
- Types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `style`, `perf`
- Scope: crate or module name (e.g., `oxide-code`, `cli`, `agent`)
- Feature branches: `feat/<feature-name>`
- Scope: the most specific area changed — module (e.g., `client`, `config`, `oauth`), doc target (e.g., `CLAUDE`, `research`), or crate name only for cross-module changes.
- Keep commits atomic — one logical change per commit.
- PRs: assign to `hakula139`, label `enhancement` for `feat`, `bug` for `fix`. Do not request review from the PR author (GitHub rejects it).

#### Branches

- Feature branches: `feat/<feature-name>`

#### Pull Requests

- Assign to `hakula139`. Label `enhancement` for `feat`, `bug` for `fix`.
- Do not request review from the PR author (GitHub rejects it).
- Descriptions follow `.github/pull_request_template.md`:
- Prose intro summarizing what and why.
- Per-file Changes table (for non-trivial PRs).
- Test plan checklist.

### Testing

- Unit tests in the same file as the code they test (`#[cfg(test)]` module).
- Integration tests in `tests/` directory for cross-module behavior.
- Group tests by function under `// -- function_name --` section headers. Section order must mirror the production function order in the same file. Within each section, order: happy path → variants → error cases.
- Test name prefixes should match the section's function name (or a clear shortening).
- Error-case test names use a return-type suffix: `_returns_error` (`Result`), `_returns_none` (`Option`), `_returns_false` (`bool`).
- Use `indoc!` for multi-line test inputs whenever possible.
- Group tests by function under `// ── function_name ──` section headers. Section order must mirror the production function order in the same file. Within each section, order: happy path → variants → edge / error cases.
- Name tests after the scenario they cover, not the return type. Prefix with the function name being tested (e.g., `parse_sse_frame_missing_data`, `load_oauth_expired_token`).
- Use `indoc!` for multi-line string literals in tests.

### Documentation Maintenance

Expand All @@ -96,7 +132,7 @@ cargo llvm-cov --ignore-filename-regex 'main\.rs' # check test coverage

## Code Review

After verification passes, run a dual review using both a reviewer subagent and a Codex MCP reviewer in parallel. Focus on:
After verification passes, review for:

- Correctness and edge cases
- Adherence to project conventions (this file)
Expand Down
Loading