@ruvnet/open-claude-code 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +376 -106
- package/package.json +11 -4
- package/src/auth/oauth.mjs +46 -6
- package/src/config/cli-args.mjs +20 -0
- package/src/config/env.mjs +2 -0
- package/src/config/settings.mjs +6 -0
- package/src/core/agent-loop.mjs +92 -28
- package/src/core/providers.mjs +19 -1
- package/src/core/session.mjs +30 -4
- package/src/hooks/engine.mjs +10 -2
- package/src/index.mjs +40 -2
- package/src/optimize/cascade.mjs +128 -0
- package/src/optimize/commands.mjs +139 -0
- package/src/optimize/router.mjs +212 -0
- package/src/optimize/store.mjs +170 -0
- package/src/permissions/injection-check.mjs +3 -2
- package/src/permissions/path-check.mjs +8 -0
- package/src/permissions/sandbox.mjs +8 -2
- package/src/permissions/ssrf-check.mjs +102 -0
- package/src/plugins/loader.mjs +14 -6
- package/src/skills/loader.mjs +16 -4
- package/src/tools/enter-worktree.mjs +5 -3
- package/src/tools/exit-worktree.mjs +4 -3
- package/src/tools/grep.mjs +26 -11
- package/src/tools/lsp.mjs +23 -9
- package/src/tools/read.mjs +20 -9
- package/src/tools/send-message.mjs +5 -1
- package/src/tools/web-fetch.mjs +15 -1
- package/src/tools/web-search.mjs +13 -1
- package/src/ui/commands.mjs +44 -7
- package/test/test.mjs +0 -1857
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 rUv
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,113 +1,383 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Open Claude Code</h1>
|
|
2
|
+
<h3 align="center">Open Source Claude Code CLI — Reverse Engineered & Rebuilt</h3>
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<em>An open source implementation of Anthropic's Claude Code CLI,<br/>
|
|
8
|
+
built from decompiled source intelligence using <a href="https://github.com/ruvnet/rudevolution">ruDevolution</a>.</em>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img alt="Tests" src="https://img.shields.io/badge/tests-1008_passing-brightgreen?style=flat-square" />
|
|
13
|
+
<img alt="Tools" src="https://img.shields.io/badge/tools-25-blue?style=flat-square" />
|
|
14
|
+
<img alt="Commands" src="https://img.shields.io/badge/commands-40-blue?style=flat-square" />
|
|
15
|
+
<img alt="npm" src="https://img.shields.io/npm/v/@ruvnet/open-claude-code?style=flat-square&label=npm" />
|
|
16
|
+
<img alt="License" src="https://img.shields.io/badge/License-MIT-blue?style=flat-square" />
|
|
17
|
+
<img alt="Nightly" src="https://img.shields.io/badge/nightly-verified_releases-brightgreen?style=flat-square" />
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
> **Verified nightly releases:** Detection, source validation, tests, AI analysis and npm publication run automatically. Capability proposals require review before implementation. See the release workflow and ADR-004.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ⚡ Quick Start
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Run instantly (no install)
|
|
28
|
+
npx @ruvnet/open-claude-code "explain this codebase"
|
|
29
|
+
|
|
30
|
+
# Or install globally
|
|
31
|
+
npm install -g @ruvnet/open-claude-code
|
|
32
|
+
occ "hello"
|
|
33
|
+
|
|
34
|
+
# Interactive mode
|
|
35
|
+
occ
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Requires:** `ANTHROPIC_API_KEY` environment variable set.
|
|
4
39
|
|
|
5
40
|
```bash
|
|
6
41
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
│ ├── edit.mjs # Edit (replace_all, uniqueness check)
|
|
32
|
-
│ ├── write.mjs # Write (mkdir, overwrite protection)
|
|
33
|
-
│ ├── glob.mjs # Glob (proper matching, mtime sort)
|
|
34
|
-
│ ├── grep.mjs # Grep (-i/-n/-A/-B/-C, ripgrep)
|
|
35
|
-
│ ├── agent.mjs # Subagent (worktree, background, model)
|
|
36
|
-
│ ├── web-fetch.mjs # URL fetch
|
|
37
|
-
│ ├── web-search.mjs # Web search
|
|
38
|
-
│ ├── todo-write.mjs # Task management
|
|
39
|
-
│ ├── notebook-edit.mjs # Jupyter notebooks
|
|
40
|
-
│ ├── multi-edit.mjs # Atomic multi-file edits
|
|
41
|
-
│ ├── ls.mjs # Directory listing
|
|
42
|
-
│ ├── tool-search.mjs # Deferred tool discovery
|
|
43
|
-
│ ├── ask-user.mjs # User prompts
|
|
44
|
-
│ ├── skill.mjs # Skill invocation
|
|
45
|
-
│ ├── send-message.mjs # Agent team messaging
|
|
46
|
-
│ ├── cron-create.mjs # Scheduled tasks
|
|
47
|
-
│ ├── cron-delete.mjs
|
|
48
|
-
│ ├── cron-list.mjs
|
|
49
|
-
│ ├── enter-worktree.mjs # Git worktree
|
|
50
|
-
│ ├── exit-worktree.mjs
|
|
51
|
-
│ ├── remote-trigger.mjs # Remote execution
|
|
52
|
-
│ ├── lsp.mjs # Language server
|
|
53
|
-
│ └── read-mcp-resource.mjs
|
|
54
|
-
├── mcp/ # MCP protocol
|
|
55
|
-
│ ├── client.mjs # JSON-RPC client
|
|
56
|
-
│ ├── transport-sse.mjs # SSE transport
|
|
57
|
-
│ ├── transport-shttp.mjs # Streamable HTTP
|
|
58
|
-
│ └── transport-ws.mjs # WebSocket
|
|
59
|
-
├── permissions/ # Security
|
|
60
|
-
│ ├── checker.mjs # 6 modes + interactive prompts
|
|
61
|
-
│ ├── sandbox.mjs # bubblewrap/seatbelt
|
|
62
|
-
│ ├── injection-check.mjs # Command injection detection
|
|
63
|
-
│ ├── path-check.mjs # File path validation
|
|
64
|
-
│ └── prompt.mjs # Permission prompting
|
|
65
|
-
├── hooks/
|
|
66
|
-
│ └── engine.mjs # PreToolUse/PostToolUse/Stop/Notification
|
|
67
|
-
├── agents/
|
|
68
|
-
│ ├── loader.mjs # Agent definition loader
|
|
69
|
-
│ ├── parser.mjs # JSON/MD frontmatter parser
|
|
70
|
-
│ └── teams.mjs # Multi-agent teams
|
|
71
|
-
├── skills/
|
|
72
|
-
│ ├── loader.mjs # Skill discovery
|
|
73
|
-
│ └── runner.mjs # Skill execution
|
|
74
|
-
├── plugins/
|
|
75
|
-
│ └── loader.mjs # Plugin discovery + git clone
|
|
76
|
-
├── auth/
|
|
77
|
-
│ └── oauth.mjs # PKCE OAuth flow
|
|
78
|
-
├── config/
|
|
79
|
-
│ ├── settings.mjs # 4-source deep merge
|
|
80
|
-
│ ├── cli-args.mjs # All CLI flags
|
|
81
|
-
│ └── env.mjs # 104 env vars
|
|
82
|
-
├── ui/
|
|
83
|
-
│ ├── repl.mjs # Interactive REPL
|
|
84
|
-
│ ├── ink-app.mjs # Rich terminal output
|
|
85
|
-
│ └── commands.mjs # 40 slash commands
|
|
86
|
-
├── telemetry/
|
|
87
|
-
│ └── index.mjs # Telemetry stub
|
|
88
|
-
└── index.mjs # Entry point
|
|
89
|
-
|
|
90
|
-
test/
|
|
91
|
-
└── test.mjs # 1,581 tests
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Stats
|
|
95
|
-
|
|
96
|
-
| Metric | Value |
|
|
97
|
-
|--------|:-----:|
|
|
98
|
-
| Source files | 61 |
|
|
99
|
-
| Lines of code | 8,314 |
|
|
100
|
-
| Tests | 1,581 (0 failures) |
|
|
101
|
-
| Tools | 25 |
|
|
102
|
-
| Slash commands | 40 |
|
|
103
|
-
| MCP transports | 4 |
|
|
104
|
-
| AI providers | 5 |
|
|
105
|
-
| Env vars | 104 |
|
|
106
|
-
| Permission modes | 6 |
|
|
107
|
-
|
|
108
|
-
## Tests
|
|
42
|
+
npx @ruvnet/open-claude-code "what files are in this directory?"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🧠 What Is This?
|
|
48
|
+
|
|
49
|
+
**Open Claude Code** is a ground-up open source rebuild of Anthropic's [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code), informed by [ruDevolution's](https://github.com/ruvnet/rudevolution) AI-powered decompilation of the published npm package.
|
|
50
|
+
|
|
51
|
+
It's not a copy — it's a clean-room implementation that mirrors the actual Claude Code architecture: async generator agent loop, 25 tools, 4 MCP transports, 6 permission modes, hooks, settings chain, sessions, and more.
|
|
52
|
+
|
|
53
|
+
**1,008 unit tests plus installed-package behavioral checks. Full upstream parity is not established.**
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 📦 Installation
|
|
58
|
+
|
|
59
|
+
### npx (no install needed)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx @ruvnet/open-claude-code "your prompt here"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Global install
|
|
109
66
|
|
|
110
67
|
```bash
|
|
111
|
-
|
|
112
|
-
|
|
68
|
+
npm install -g @ruvnet/open-claude-code
|
|
69
|
+
occ "your prompt here"
|
|
113
70
|
```
|
|
71
|
+
|
|
72
|
+
### From source
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git clone https://github.com/ruvnet/open-claude-code.git
|
|
76
|
+
cd open-claude-code/v2
|
|
77
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
78
|
+
node src/index.mjs "hello"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 🖥️ Usage
|
|
84
|
+
|
|
85
|
+
### One-shot mode
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
occ "explain the auth module"
|
|
89
|
+
occ "fix the bug in server.js"
|
|
90
|
+
occ "create a REST API for user management"
|
|
91
|
+
occ "find all TODO comments in this project"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Interactive REPL
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
occ
|
|
98
|
+
# > explain this codebase
|
|
99
|
+
# > /help
|
|
100
|
+
# > /tools
|
|
101
|
+
# > /model claude-opus-4-6
|
|
102
|
+
# > refactor the database layer
|
|
103
|
+
# > /cost
|
|
104
|
+
# > /exit
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### CLI Options
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
occ [options] [prompt]
|
|
111
|
+
|
|
112
|
+
Options:
|
|
113
|
+
-m, --model <model> Model to use (default: claude-sonnet-4-6)
|
|
114
|
+
-p, --print Print mode (non-interactive, output only)
|
|
115
|
+
--permission-mode <mode> Permission mode: default, auto, plan, acceptEdits,
|
|
116
|
+
bypassPermissions, dontAsk
|
|
117
|
+
--system-prompt <text> Override system prompt
|
|
118
|
+
--add-dir <path> Additional CLAUDE.md directory
|
|
119
|
+
--max-turns <n> Maximum conversation turns
|
|
120
|
+
--allowedTools <tools> Comma-separated allowed tools
|
|
121
|
+
--disallowedTools <tools> Comma-separated denied tools
|
|
122
|
+
--output-format <fmt> Output: text, json, stream-json
|
|
123
|
+
-v, --verbose Verbose output
|
|
124
|
+
-d, --debug Debug mode
|
|
125
|
+
--version Show version
|
|
126
|
+
-h, --help Show help
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Examples
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Use a different model
|
|
133
|
+
occ -m claude-opus-4-6 "design a database schema for a blog"
|
|
134
|
+
|
|
135
|
+
# Print mode (for piping)
|
|
136
|
+
occ -p "list all functions in src/" > functions.txt
|
|
137
|
+
|
|
138
|
+
# Plan mode (read-only, no edits)
|
|
139
|
+
occ --permission-mode plan "review the security of auth.js"
|
|
140
|
+
|
|
141
|
+
# Restrict tools
|
|
142
|
+
occ --allowedTools "Read,Glob,Grep" "find all API endpoints"
|
|
143
|
+
|
|
144
|
+
# With custom system prompt
|
|
145
|
+
occ --system-prompt "You are a senior Go developer" "review main.go"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🔧 Interactive Commands
|
|
151
|
+
|
|
152
|
+
40 slash commands available in REPL mode:
|
|
153
|
+
|
|
154
|
+
| Command | Description |
|
|
155
|
+
|---------|-------------|
|
|
156
|
+
| `/help` | Show all commands |
|
|
157
|
+
| `/model <name>` | Switch model mid-conversation |
|
|
158
|
+
| `/tools` | List available tools |
|
|
159
|
+
| `/tokens` | Show current token usage |
|
|
160
|
+
| `/cost` | Show session cost estimate |
|
|
161
|
+
| `/compact` | Compact context window |
|
|
162
|
+
| `/undo` | Undo last file edit |
|
|
163
|
+
| `/clear` | Clear conversation history |
|
|
164
|
+
| `/doctor` | Check API connectivity + health |
|
|
165
|
+
| `/fast` | Toggle fast mode (Haiku) |
|
|
166
|
+
| `/effort <level>` | Set effort: low, medium, high, max |
|
|
167
|
+
| `/resume [id]` | Resume a previous session |
|
|
168
|
+
| `/sessions` | List saved sessions |
|
|
169
|
+
| `/agents` | List custom agents |
|
|
170
|
+
| `/skills` | List available skills |
|
|
171
|
+
| `/hooks` | Show active hooks |
|
|
172
|
+
| `/config` | Show current settings |
|
|
173
|
+
| `/permissions` | Show permission mode |
|
|
174
|
+
| `/mcp` | Show MCP server status |
|
|
175
|
+
| `/memory` | Show memory usage |
|
|
176
|
+
| `/exit` | Exit |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 🔨 Tools
|
|
181
|
+
|
|
182
|
+
25 built-in tools matching Claude Code's tool system:
|
|
183
|
+
|
|
184
|
+
| Tool | Description |
|
|
185
|
+
|------|-------------|
|
|
186
|
+
| **Bash** | Execute shell commands (sandboxed) |
|
|
187
|
+
| **Read** | Read files with line numbers |
|
|
188
|
+
| **Edit** | Replace strings in files |
|
|
189
|
+
| **Write** | Create/overwrite files |
|
|
190
|
+
| **Glob** | Find files by pattern |
|
|
191
|
+
| **Grep** | Search file contents (regex) |
|
|
192
|
+
| **LS** | List directory contents |
|
|
193
|
+
| **Agent** | Spawn sub-agents |
|
|
194
|
+
| **WebFetch** | Fetch URL content |
|
|
195
|
+
| **WebSearch** | Web search |
|
|
196
|
+
| **TodoWrite** | Task management |
|
|
197
|
+
| **NotebookEdit** | Edit Jupyter notebooks |
|
|
198
|
+
| **MultiEdit** | Atomic multi-file edits |
|
|
199
|
+
| **ToolSearch** | Discover deferred tools |
|
|
200
|
+
| **AskUser** | Prompt user for input |
|
|
201
|
+
| **Skill** | Invoke a skill |
|
|
202
|
+
| **SendMessage** | Agent team messaging |
|
|
203
|
+
| **CronCreate/Delete/List** | Scheduled tasks |
|
|
204
|
+
| **EnterWorktree/ExitWorktree** | Git worktree isolation |
|
|
205
|
+
| **RemoteTrigger** | Remote execution |
|
|
206
|
+
| **LSP** | Language server protocol |
|
|
207
|
+
| **ReadMcpResource** | Read MCP resources |
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ⚙️ Configuration
|
|
212
|
+
|
|
213
|
+
### Settings
|
|
214
|
+
|
|
215
|
+
Create `.claude/settings.json` in your project or `~/.claude/settings.json` globally:
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"model": "claude-sonnet-4-6",
|
|
220
|
+
"permissions": {
|
|
221
|
+
"defaultMode": "auto"
|
|
222
|
+
},
|
|
223
|
+
"hooks": {
|
|
224
|
+
"PreToolUse": [{
|
|
225
|
+
"matcher": "Bash",
|
|
226
|
+
"hooks": [{ "type": "command", "command": "echo 'Running bash...'" }]
|
|
227
|
+
}]
|
|
228
|
+
},
|
|
229
|
+
"autoCompactEnabled": true,
|
|
230
|
+
"alwaysThinkingEnabled": true
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Settings are loaded from 4 sources (in priority order):
|
|
235
|
+
1. `.claude/settings.local.json` (local, gitignored)
|
|
236
|
+
2. `.claude/settings.json` (project, shared)
|
|
237
|
+
3. `~/.claude/settings.json` (user global)
|
|
238
|
+
4. Managed policy (enterprise)
|
|
239
|
+
|
|
240
|
+
### CLAUDE.md
|
|
241
|
+
|
|
242
|
+
Create a `CLAUDE.md` in your project root to customize behavior:
|
|
243
|
+
|
|
244
|
+
```markdown
|
|
245
|
+
# Project Rules
|
|
246
|
+
- Always use TypeScript
|
|
247
|
+
- Follow TDD
|
|
248
|
+
- Keep files under 500 lines
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
CLAUDE.md files are loaded from: `~/.claude/CLAUDE.md` → parent directories → project root → `.claude/CLAUDE.md`.
|
|
252
|
+
|
|
253
|
+
### Custom Agents
|
|
254
|
+
|
|
255
|
+
Create `.claude/agents/reviewer.md`:
|
|
256
|
+
|
|
257
|
+
```markdown
|
|
258
|
+
---
|
|
259
|
+
name: reviewer
|
|
260
|
+
description: Code review specialist
|
|
261
|
+
model: claude-sonnet-4-6
|
|
262
|
+
tools: [Read, Glob, Grep]
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
You are a thorough code reviewer. Check for bugs, security issues, and style.
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Skills
|
|
269
|
+
|
|
270
|
+
Create `.claude/skills/deploy/SKILL.md`:
|
|
271
|
+
|
|
272
|
+
```markdown
|
|
273
|
+
---
|
|
274
|
+
name: deploy
|
|
275
|
+
description: Deploy to production
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
1. Run tests: npm test
|
|
279
|
+
2. Build: npm run build
|
|
280
|
+
3. Deploy: ./scripts/deploy.sh
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Invoke with `/deploy` in the REPL.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 🔐 Multi-Provider Support
|
|
288
|
+
|
|
289
|
+
Adapters exist for Anthropic, OpenAI-compatible endpoints and Google. Installed-package E2E covers Anthropic and OpenAI-compatible tool roundtrips; Google is not covered by that gate. Bedrock and Vertex remain stubs.
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Anthropic (default)
|
|
293
|
+
ANTHROPIC_API_KEY=... occ "hello"
|
|
294
|
+
|
|
295
|
+
# OpenAI
|
|
296
|
+
OPENAI_API_KEY=... occ -m gpt-4o "hello"
|
|
297
|
+
|
|
298
|
+
# Google
|
|
299
|
+
GOOGLE_API_KEY=... occ -m gemini-2.5-flash "hello"
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 🔗 MCP Integration
|
|
307
|
+
|
|
308
|
+
Connect to MCP servers for additional tools:
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
// .mcp.json
|
|
312
|
+
{
|
|
313
|
+
"mcpServers": {
|
|
314
|
+
"my-server": {
|
|
315
|
+
"command": "npx",
|
|
316
|
+
"args": ["-y", "my-mcp-server"],
|
|
317
|
+
"env": { "API_KEY": "..." }
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Supports 4 transports: stdio, SSE, Streamable HTTP, WebSocket.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## 🔍 Background: The Claude Code Source Leak
|
|
328
|
+
|
|
329
|
+
On March 31, 2026, Anthropic accidentally shipped source maps in the Claude Code npm package, [exposing the full TypeScript source](https://www.sabrina.dev/p/claude-code-source-leak-analysis). This project takes a different approach — we use [ruDevolution](https://github.com/ruvnet/rudevolution) to analyze the **published npm package** legally and rebuild from that intelligence.
|
|
330
|
+
|
|
331
|
+
### What ruDevolution Found
|
|
332
|
+
|
|
333
|
+
| Discovery | Evidence |
|
|
334
|
+
|-----------|---------|
|
|
335
|
+
| 🤖 Agent Teams | `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` |
|
|
336
|
+
| 🌙 Auto Dream Mode | `tengu_auto_dream_completed` |
|
|
337
|
+
| 🔮 claude-opus-4-6 | Unreleased model ID |
|
|
338
|
+
| 🔐 6 "amber" codenames | Internal feature gates |
|
|
339
|
+
| ☁️ Cloud Code Runner | BYOC compute |
|
|
340
|
+
| 📡 MCP Streamable HTTP | New transport |
|
|
341
|
+
|
|
342
|
+
[Download decompiled releases →](https://github.com/ruvnet/rudevolution/releases)
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## ⚖️ Legal
|
|
347
|
+
|
|
348
|
+
This is a **clean-room implementation** — no leaked source used. Architecture informed by analysis of the published npm package, legal under US DMCA §1201(f), EU Software Directive Art. 6, UK CDPA §50B.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## 📚 Related
|
|
353
|
+
|
|
354
|
+
- [ruDevolution](https://github.com/ruvnet/rudevolution) — AI-Powered JavaScript Decompiler
|
|
355
|
+
- [Decompiled Releases](https://github.com/ruvnet/rudevolution/releases) — Every Claude Code version
|
|
356
|
+
- [v2 Architecture (ADR-001)](./docs/adr/ADR-001-v2-architecture.md)
|
|
357
|
+
- [Path to 100% (ADR-002)](./docs/adr/ADR-002-path-to-100-percent.md)
|
|
358
|
+
|
|
359
|
+
## Verified release automation
|
|
360
|
+
|
|
361
|
+

|
|
362
|
+
|
|
363
|
+
Runs daily at 03:00 UTC. Unchanged upstream versions are explicitly reported as no-op runs.
|
|
364
|
+
|
|
365
|
+
Publication requires unit and regression tests, a dependency audit, validated source recovery, successful AI analysis, clean package installation tests, and a live provider Read tool roundtrip against a fresh random fixture. The exact tested tarball is published to npm, its SHA-512 integrity verified, and the registry version installed and exercised again.
|
|
366
|
+
|
|
367
|
+
Only then does the upstream checkpoint advance. Failed gates stop publication and create an investigation issue. GitHub releases attach the package, source commit receipt and analysis. Nightly versions use the npm nightly tag. Stable releases require the manually selected latest channel.
|
|
368
|
+
|
|
369
|
+
Required repository secrets: AI_API_KEY (OpenRouter) and NPM_TOKEN with publishing permission. GITHUB_TOKEN is supplied by GitHub Actions. ruOS bindings provision credentials without printing their values.
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
gh workflow run nightly.yml -f force_release=true -f channel=nightly
|
|
373
|
+
npm install @ruvnet/open-claude-code@nightly
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Structural changes produce review proposals, not implemented features. Concrete behavioral specifications and new tests are required before implementing them. Full upstream parity is not established.
|
|
377
|
+
|
|
378
|
+
See [release integrity ADR](docs/adr/ADR-004-verified-npm-publication.md).
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
## 📄 License
|
|
382
|
+
|
|
383
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruvnet/open-claude-code",
|
|
3
|
-
"version": "2.1.
|
|
4
|
-
"description": "Open source
|
|
3
|
+
"version": "2.1.1",
|
|
4
|
+
"description": "Open source agentic coding CLI with verified nightly upstream analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"occ": "src/index.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"src/",
|
|
11
|
-
"
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"start": "node src/index.mjs",
|
|
@@ -31,7 +32,7 @@
|
|
|
31
32
|
"url": "https://github.com/ruvnet/open-claude-code/issues"
|
|
32
33
|
},
|
|
33
34
|
"homepage": "https://github.com/ruvnet/open-claude-code#readme",
|
|
34
|
-
"main": "index.
|
|
35
|
+
"main": "src/index.mjs",
|
|
35
36
|
"directories": {
|
|
36
37
|
"test": "test"
|
|
37
38
|
},
|
|
@@ -41,5 +42,11 @@
|
|
|
41
42
|
"ink-spinner": "^5.0.0",
|
|
42
43
|
"ink-text-input": "^6.0.0",
|
|
43
44
|
"react": "^18.3.1"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
44
51
|
}
|
|
45
52
|
}
|
package/src/auth/oauth.mjs
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - Authorization code + PKCE
|
|
7
7
|
* - Token refresh
|
|
8
8
|
* - Credential storage in ~/.claude/credentials
|
|
9
|
+
* - Codex (OpenAI) OAuth via CODEX_CLIENT_ID / OPENAI_CLIENT_ID env vars
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import crypto from 'crypto';
|
|
@@ -13,24 +14,63 @@ import fs from 'fs';
|
|
|
13
14
|
import path from 'path';
|
|
14
15
|
import os from 'os';
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Well-known provider presets.
|
|
19
|
+
* Consumers can pass `provider: 'codex'` (or `'openai'`) to switch endpoints.
|
|
20
|
+
*/
|
|
21
|
+
const PROVIDER_PRESETS = {
|
|
22
|
+
anthropic: {
|
|
23
|
+
authUrl: 'https://console.anthropic.com/oauth/authorize',
|
|
24
|
+
tokenUrl: 'https://console.anthropic.com/oauth/token',
|
|
25
|
+
deviceUrl: 'https://console.anthropic.com/oauth/device',
|
|
26
|
+
},
|
|
27
|
+
codex: {
|
|
28
|
+
authUrl: 'https://auth.openai.com/authorize',
|
|
29
|
+
tokenUrl: 'https://auth.openai.com/oauth/token',
|
|
30
|
+
deviceUrl: 'https://auth.openai.com/oauth/device/code',
|
|
31
|
+
},
|
|
32
|
+
openai: {
|
|
33
|
+
authUrl: 'https://auth.openai.com/authorize',
|
|
34
|
+
tokenUrl: 'https://auth.openai.com/oauth/token',
|
|
35
|
+
deviceUrl: 'https://auth.openai.com/oauth/device/code',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
16
39
|
export class OAuthClient {
|
|
17
40
|
/**
|
|
18
41
|
* @param {string} clientId - OAuth client ID
|
|
19
42
|
* @param {object} [options]
|
|
20
|
-
* @param {string} [options.
|
|
21
|
-
* @param {string} [options.
|
|
22
|
-
* @param {string} [options.
|
|
43
|
+
* @param {string} [options.provider] - 'anthropic' | 'codex' | 'openai' (default: 'anthropic')
|
|
44
|
+
* @param {string} [options.authUrl] - authorization endpoint (overrides provider preset)
|
|
45
|
+
* @param {string} [options.tokenUrl] - token endpoint (overrides provider preset)
|
|
46
|
+
* @param {string} [options.deviceUrl] - device authorization endpoint (overrides provider preset)
|
|
23
47
|
* @param {string} [options.credentialsPath] - path to store credentials
|
|
24
48
|
*/
|
|
25
49
|
constructor(clientId, options = {}) {
|
|
26
50
|
this.clientId = clientId;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
51
|
+
|
|
52
|
+
const preset = PROVIDER_PRESETS[options.provider] || PROVIDER_PRESETS.anthropic;
|
|
53
|
+
this.authUrl = options.authUrl || preset.authUrl;
|
|
54
|
+
this.tokenUrl = options.tokenUrl || preset.tokenUrl;
|
|
55
|
+
this.deviceUrl = options.deviceUrl || preset.deviceUrl;
|
|
30
56
|
this.credentialsPath = options.credentialsPath ||
|
|
31
57
|
path.join(os.homedir(), '.claude', 'credentials');
|
|
32
58
|
}
|
|
33
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Create a client pre-configured for Codex / OpenAI auth.
|
|
62
|
+
* Falls back to CODEX_CLIENT_ID → OPENAI_CLIENT_ID env vars.
|
|
63
|
+
* @param {object} [options]
|
|
64
|
+
* @returns {OAuthClient}
|
|
65
|
+
*/
|
|
66
|
+
static forCodex(options = {}) {
|
|
67
|
+
const clientId = options.clientId ||
|
|
68
|
+
process.env.CODEX_CLIENT_ID ||
|
|
69
|
+
process.env.OPENAI_CLIENT_ID ||
|
|
70
|
+
'codex-default';
|
|
71
|
+
return new OAuthClient(clientId, { ...options, provider: 'codex' });
|
|
72
|
+
}
|
|
73
|
+
|
|
34
74
|
/**
|
|
35
75
|
* Generate a PKCE code verifier and challenge.
|
|
36
76
|
* @returns {{ verifier: string, challenge: string }}
|
package/src/config/cli-args.mjs
CHANGED
|
@@ -32,6 +32,8 @@ export function parseArgs(args) {
|
|
|
32
32
|
debug: false,
|
|
33
33
|
showVersion: false,
|
|
34
34
|
showHelp: false,
|
|
35
|
+
// Opt-in metaharness self-optimization. null = unset (defer to env/setting).
|
|
36
|
+
selfOptimize: null,
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -86,6 +88,14 @@ export function parseArgs(args) {
|
|
|
86
88
|
result.debug = true;
|
|
87
89
|
break;
|
|
88
90
|
|
|
91
|
+
case '--self-optimize':
|
|
92
|
+
result.selfOptimize = true;
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case '--no-self-optimize':
|
|
96
|
+
result.selfOptimize = false;
|
|
97
|
+
break;
|
|
98
|
+
|
|
89
99
|
case '--version':
|
|
90
100
|
result.showVersion = true;
|
|
91
101
|
break;
|
|
@@ -127,13 +137,23 @@ Options:
|
|
|
127
137
|
--disallowedTools <tools> Comma-separated list of denied tools
|
|
128
138
|
--verbose, -v Verbose output
|
|
129
139
|
--debug, -d Debug mode
|
|
140
|
+
--self-optimize Route model calls through the metaharness cost-cascade
|
|
141
|
+
(cheap base -> escalate) and record real outcomes (opt-in)
|
|
142
|
+
--no-self-optimize Force self-optimization off (overrides env/setting)
|
|
130
143
|
--version Show version
|
|
131
144
|
--help, -h Show this help
|
|
132
145
|
|
|
146
|
+
Subcommands:
|
|
147
|
+
occ optimize <status|route|report|reset|help> Inspect/manage the self-optimization router (no model calls)
|
|
148
|
+
occ redblue [...] Delegate to @metaharness/redblue CLI (self red/blue-team testing, via npx)
|
|
149
|
+
occ darwin [...] Delegate to @metaharness/darwin CLI (config evolution, via npx)
|
|
150
|
+
|
|
133
151
|
Examples:
|
|
134
152
|
occ Start interactive REPL
|
|
135
153
|
occ -p "What is 2+2?" Run prompt and exit
|
|
136
154
|
occ -m claude-haiku-4-5 Use Haiku model
|
|
137
155
|
occ --debug -p "Fix bug" Debug mode with prompt
|
|
156
|
+
occ --self-optimize -p "..." Run with the cost-cascade router enabled
|
|
157
|
+
occ optimize status Show the router config and recorded outcomes
|
|
138
158
|
`.trim();
|
|
139
159
|
}
|
package/src/config/env.mjs
CHANGED
|
@@ -30,6 +30,8 @@ export const ENV_SCHEMA = {
|
|
|
30
30
|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: { type: 'boolean', default: false, description: 'Enable agent teams' },
|
|
31
31
|
CLAUDE_CODE_DEBUG: { type: 'boolean', default: false, description: 'Debug mode' },
|
|
32
32
|
CLAUDE_CODE_DISABLE_TELEMETRY: { type: 'boolean', default: false, description: 'Disable telemetry' },
|
|
33
|
+
CLAUDE_CODE_SELF_OPTIMIZE: { type: 'boolean', default: false, description: 'Enable metaharness cost-cascade self-optimization (opt-in)' },
|
|
34
|
+
CLAUDE_CODE_OPTIMIZE_DIR: { type: 'string', description: 'Directory for self-optimization outcome store' },
|
|
33
35
|
|
|
34
36
|
// Permission and Security
|
|
35
37
|
CLAUDE_CODE_PERMISSION_MODE: { type: 'string', default: 'default', description: 'Permission mode' },
|