@gaburieuru/claudio 0.24.0

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 ADDED
@@ -0,0 +1,29 @@
1
+ NOTICE
2
+
3
+ This repository contains code derived from Anthropic's Claude Code CLI.
4
+
5
+ The original Claude Code source is proprietary software:
6
+ Copyright (c) Anthropic PBC. All rights reserved.
7
+ Subject to Anthropic's Commercial Terms of Service.
8
+
9
+ Modifications and additions by OpenClaude contributors are offered under
10
+ the MIT License where legally permissible:
11
+
12
+ MIT License
13
+ Copyright (c) 2026 OpenClaude contributors (modifications only)
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining
16
+ a copy of the modifications made by OpenClaude contributors, to deal
17
+ in those modifications without restriction, including without limitation
18
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
19
+ and/or sell copies, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included
22
+ in all copies or substantial portions of the modifications.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
25
+
26
+ The underlying derived code remains subject to Anthropic's copyright.
27
+ This project does not have Anthropic's authorization to distribute
28
+ their proprietary source. Users and contributors should evaluate their
29
+ own legal position.
package/README.md ADDED
@@ -0,0 +1,424 @@
1
+ <div align="center">
2
+ <img src="docs/assets/openclaude-wordmark.svg" alt="Claudio — Open terminal for any LLM" width="830">
3
+
4
+ <p>
5
+ <a href="https://trendshift.io/repositories/25807?utm_source=trendshift-badge&amp;utm_medium=badge&amp;utm_campaign=badge-trendshift-25807" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/25807/daily?language=TypeScript" alt="Gitlawb%2Fopenclaude | Trendshift" width="250" height="55"/></a>
6
+ <a href="https://trendshift.io/repositories/25807?utm_source=trendshift-badge&amp;utm_medium=badge&amp;utm_campaign=badge-trendshift-25807" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/25807/monthly?language=TypeScript" alt="Gitlawb%2Fopenclaude | Trendshift" width="250" height="55"/></a>
7
+ <a href="https://trendshift.io/repositories/25807?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-25807" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/25807" alt="Gitlawb%2Fopenclaude | Trendshift" width="250" height="55"/></a>
8
+ </p>
9
+ </div>
10
+
11
+ Claudio is an open-source coding-agent CLI for cloud and local model providers.
12
+
13
+ Use OpenAI-compatible APIs, Gemini, GitHub Models, Codex OAuth, Codex, Ollama, Atomic Chat, and other supported backends while keeping one terminal-first workflow: prompts, tools, agents, MCP, slash commands, and streaming output.
14
+
15
+ [![PR Checks](https://github.com/Gitlawb/openclaude/actions/workflows/pr-checks.yml/badge.svg?branch=main)](https://github.com/Gitlawb/openclaude/actions/workflows/pr-checks.yml)
16
+ [![Release](https://img.shields.io/github/v/tag/Gitlawb/openclaude?label=release&color=0ea5e9)](https://github.com/Gitlawb/openclaude/tags)
17
+ [![Discussions](https://img.shields.io/badge/discussions-open-7c3aed)](https://github.com/Gitlawb/openclaude/discussions)
18
+ [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/k68zFR6AcB)
19
+ [![X](https://img.shields.io/badge/X-@gitlawb-000000?logo=x&logoColor=white)](https://x.com/gitlawb)
20
+ [![Security Policy](https://img.shields.io/badge/security-policy-0f766e)](SECURITY.md)
21
+ [![License](https://img.shields.io/badge/license-MIT-2563eb)](LICENSE)
22
+
23
+ Claudio is also mirrored to GitLawb:
24
+ [gitlawb.com/node/repos/z6MkqDnb/openclaude](https://gitlawb.com/node/repos/z6MkqDnb/openclaude)
25
+
26
+ [Quick Start](#quick-start) | [Setup Guides](#setup-guides) | [Providers](#supported-providers) | [Development](#development) | [VS Code Extension](#vs-code-extension) | [Sponsors](#sponsors) | [Community](#community)
27
+
28
+ ## Sponsors
29
+
30
+ <table align="center">
31
+ <tr>
32
+ <td align="center" width="150" height="80">
33
+ <a href="https://gitlawb.com">
34
+ <img src="https://gitlawb.com/logo.png" alt="GitLawb logo" width="72">
35
+ </a>
36
+ </td>
37
+ <td align="center" width="150" height="80">
38
+ <a href="https://bankr.bot">
39
+ <img src="https://bankr.bot/favicon.svg" alt="Bankr.bot logo" width="72">
40
+ </a>
41
+ </td>
42
+ <td align="center" width="150" height="80">
43
+ <a href="https://atomic.chat/">
44
+ <img src="docs/assets/atomic-chat-logo.png" alt="Atomic Chat logo" width="72">
45
+ </a>
46
+ </td>
47
+ <td align="center" width="150" height="80">
48
+ <a href="https://mimo.mi.com">
49
+ <img src="https://mimo.xiaomi.com/mimo-v2-pro/assets/logo.svg" alt="Xiaomi MiMo logo" width="136">
50
+ </a>
51
+ </td>
52
+ <td align="center" width="150" height="80">
53
+ <a href="https://www.atlascloud.ai/">
54
+ <img src="docs/assets/atlas-cloud-banner.png" alt="Atlas Cloud logo" width="136">
55
+ </a>
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <td align="center"><a href="https://gitlawb.com"><strong>GitLawb</strong></a></td>
60
+ <td align="center"><a href="https://bankr.bot"><strong>Bankr.bot</strong></a></td>
61
+ <td align="center"><a href="https://atomic.chat/"><strong>Atomic Chat</strong></a></td>
62
+ <td align="center"><a href="https://mimo.mi.com"><strong>Xiaomi MiMo</strong></a></td>
63
+ <td align="center"><a href="https://www.atlascloud.ai/"><strong>Atlas Cloud</strong></a></td>
64
+ </tr>
65
+ </table>
66
+
67
+ ## Why Claudio
68
+
69
+ - One CLI across cloud APIs and local model backends — no per-provider tooling
70
+ - Guided provider setup and saved profiles with `/provider`
71
+ - Coding-agent workflows in one place: bash, file tools, grep, glob, agents, tasks, MCP, and web tools
72
+ - A bundled VS Code extension for launch integration and theme support
73
+ - A pixel-art hero companion who fires an arrow every time you press Enter (really — see [Meet your buddy](#meet-your-buddy))
74
+
75
+ ## Quick Start
76
+
77
+ ### Install
78
+
79
+ Claudio requires Node.js `>=22.0.0` for npm installs and runtime. Bun is
80
+ only needed for source builds and local development.
81
+
82
+ ```bash
83
+ npm install -g @gaburieuru/claudio@latest
84
+ # or
85
+ bun install -g @gaburieuru/claudio@latest
86
+ ```
87
+
88
+ If the install later reports `ripgrep not found`, install ripgrep system-wide and confirm `rg --version` works in the same terminal before starting Claudio.
89
+
90
+ **Verify / troubleshoot installed version:**
91
+
92
+ ```bash
93
+ claudio --version
94
+ npm view @gaburieuru/claudio dist-tags
95
+ npm install -g @gaburieuru/claudio@latest
96
+ ```
97
+
98
+ ### Start
99
+
100
+ ```bash
101
+ claudio
102
+ ```
103
+
104
+ Inside Claudio:
105
+
106
+ - run `/provider` for guided provider setup and saved profiles
107
+ - run `/onboard-github` for GitHub Models onboarding
108
+
109
+ > **Note:** Claudio does not automatically load project `.env` files. We recommend using the `/provider` command for setup, which saves provider profiles and credentials in `.openclaude-profile.json`. If you prefer environment variables, export them explicitly or run `claudio --provider-env-file .env` for provider/setup variables. Export runtime/debug knobs from your shell or launcher.
110
+
111
+ ### Resume or fork a conversation
112
+
113
+ Resume an existing conversation by session ID, or continue the most recent
114
+ conversation in the current directory:
115
+
116
+ ```bash
117
+ claudio --resume <session-id>
118
+ claudio --continue
119
+ ```
120
+
121
+ Add `--fork-session` to branch the conversation history into a new session ID
122
+ instead of reusing the original transcript:
123
+
124
+ ```bash
125
+ claudio --resume <session-id> --fork-session
126
+ claudio --continue --fork-session
127
+ ```
128
+
129
+ Forking is conversation branching only. It does not create filesystem isolation,
130
+ copy your working tree, or create a git worktree branch.
131
+
132
+ ### Background sessions
133
+
134
+ Run long non-interactive prompts detached from the current terminal:
135
+
136
+ ```bash
137
+ claudio --bg "fix failing tests"
138
+ claudio --bg --name auth-refactor "refactor auth middleware"
139
+ claudio ps
140
+ claudio logs auth-refactor
141
+ claudio logs auth-refactor -f
142
+ claudio kill auth-refactor
143
+ ```
144
+
145
+ Background sessions are local child processes. Claudio does not start a daemon
146
+ or network service, and permission/provider/model/settings flags are passed to
147
+ the child process the same way they are for a foreground `--print` run. Session
148
+ metadata and logs are stored under the resolved Claudio config directory,
149
+ usually `~/.openclaude/bg-sessions/`; `OPENCLAUDE_CONFIG_DIR` can point
150
+ Claudio somewhere else. `CLAUDE_CONFIG_DIR` is ignored for Claudio
151
+ background-session storage. Session names can be reused after older sessions
152
+ reach a terminal state; use the session ID to inspect older logs with the same
153
+ name.
154
+
155
+ `claudio attach <id-or-name>` currently reports the matching session and
156
+ points to `claudio logs <id> -f`; full terminal reattach is not implemented
157
+ for local background sessions yet.
158
+
159
+ ### Claudio config cutover
160
+
161
+ Claudio stores its own config under `~/.openclaude` and `~/.openclaude.json`
162
+ by default. It does not read `~/.claude`, project `.claude/` directories, or
163
+ `CLAUDE_CONFIG_DIR`; new users can start with an empty Claudio config and do
164
+ not need Claude Code installed.
165
+
166
+ If you previously used Claudio with `.claude` paths, migrate intentionally:
167
+ copy only the settings, commands, agents, skills, scheduled tasks, or other files
168
+ you personally created for Claudio into the matching `.openclaude` location.
169
+ Do not blanket-copy `.claude`, and do not copy Claude Code credentials or auth
170
+ files. For provider authentication, prefer running Claudio's provider setup
171
+ again or exporting provider-specific environment variables.
172
+
173
+ ### Fastest OpenAI setup
174
+
175
+ macOS / Linux:
176
+
177
+ ```bash
178
+ export CLAUDE_CODE_USE_OPENAI=1
179
+ export OPENAI_API_KEY=sk-your-key-here
180
+ export OPENAI_MODEL=gpt-4o
181
+
182
+ claudio
183
+ ```
184
+
185
+ Windows PowerShell:
186
+
187
+ ```powershell
188
+ $env:CLAUDE_CODE_USE_OPENAI="1"
189
+ $env:OPENAI_API_KEY="sk-your-key-here"
190
+ $env:OPENAI_MODEL="gpt-4o"
191
+
192
+ claudio
193
+ ```
194
+
195
+ ### Fastest local Ollama setup
196
+
197
+ macOS / Linux:
198
+
199
+ ```bash
200
+ export CLAUDE_CODE_USE_OPENAI=1
201
+ export OPENAI_BASE_URL=http://localhost:11434/v1
202
+ export OPENAI_MODEL=qwen2.5-coder:7b
203
+
204
+ claudio
205
+ ```
206
+
207
+ Windows PowerShell:
208
+
209
+ ```powershell
210
+ $env:CLAUDE_CODE_USE_OPENAI="1"
211
+ $env:OPENAI_BASE_URL="http://localhost:11434/v1"
212
+ $env:OPENAI_MODEL="qwen2.5-coder:7b"
213
+
214
+ claudio
215
+ ```
216
+
217
+ For Ollama, Claudio uses Ollama's native chat API and requests a 32768-token
218
+ context window on each chat request so same-session history is not silently
219
+ truncated by Ollama's OpenAI-compatible shim. Set `OPENCLAUDE_OLLAMA_NUM_CTX`
220
+ or `OLLAMA_CONTEXT_LENGTH` if you need a different request-level context size.
221
+ See [Advanced Setup](docs/advanced-setup.md#ollama-context-length) for
222
+ verification with `ollama ps`.
223
+
224
+ ## Setup Guides
225
+
226
+ Beginner-friendly guides:
227
+
228
+ - [Non-Technical Setup](docs/non-technical-setup.md)
229
+ - [Windows Quick Start](docs/quick-start-windows.md)
230
+ - [macOS / Linux Quick Start](docs/quick-start-mac-linux.md)
231
+
232
+ Advanced and source-build guides:
233
+
234
+ - [Advanced Setup](docs/advanced-setup.md)
235
+ - [Smart Auto-Routing](docs/smart-routing.md)
236
+ - [Agent Routing and Step Limits](docs/agent-routing.md)
237
+ - [Headless gRPC Server](docs/grpc-server.md)
238
+ - [Repo Map (codebase intelligence)](docs/repo-map.md)
239
+ - [Android Install](ANDROID_INSTALL.md)
240
+
241
+ ## Supported Providers
242
+
243
+ | Provider | Setup Path | Notes |
244
+ | --- | --- | --- |
245
+ | OpenAI-compatible | `/provider` or env vars | Works with OpenAI, OpenRouter, DeepSeek, Groq, Mistral, LM Studio, and other compatible `/v1` servers |
246
+ | Z.AI GLM Coding Plan | `/provider` or OpenAI-compatible env vars | Uses `OPENAI_API_KEY` at `https://api.z.ai/api/coding/paas/v4` and defaults to `glm-5.2` |
247
+ | AI/ML API | `/provider` or `AIMLAPI_API_KEY` ([setup guide](docs/aimlapi-setup.md)) | Uses `https://api.aimlapi.com/v1`, auto-detects the OpenAI-compatible route from `AIMLAPI_API_KEY`, sends Claudio attribution headers, and discovers chat-capable models from the public `/models` catalog |
248
+ | Hicap | `/provider` or OpenAI-compatible env vars | Uses `api-key` auth, discovers models from unauthenticated `/models`, and supports Responses mode for `gpt-` models |
249
+ | Fireworks AI | `/provider` or env vars | First-class provider with 276 curated models (DeepSeek, Qwen, Llama, Gemma, and more); uses `FIREWORKS_API_KEY` |
250
+ | ClinePass | `/provider` or env vars | AI model gateway with usage limits (5hr, weekly, monthly); uses `CLINE_API_KEY` at `https://api.cline.bot/api/v1` |
251
+ | Gemini | `/provider` or env vars | Supports API key only |
252
+ | GitHub Models | `/onboard-github` | Interactive onboarding with saved credentials |
253
+ | Codex OAuth | `/provider` | Opens ChatGPT sign-in in your browser and stores Codex credentials securely |
254
+ | Codex | `/provider` | Uses existing Codex CLI auth, Claudio secure storage, or env credentials |
255
+ | Gitlawb Opengateway | Startup default, `/provider`, or env vars | Smart gateway at `https://opengateway.gitlawb.com/v1`; requires an API key from https://gitlawb.com/opengateway/keys and routes Xiaomi MiMo and GMI Cloud partner models by `OPENAI_MODEL` |
256
+ | OpenCode Zen | `/provider` or env vars | Pay-as-you-go AI gateway (48 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/v1`; shared key with OpenCode Go |
257
+ | OpenCode Go | `/provider` or env vars | $10/mo subscription for open models (13 models); uses `OPENCODE_API_KEY` via `https://opencode.ai/zen/go/v1`; shared key with OpenCode Zen |
258
+ | Xiaomi MiMo | `/provider` or env vars | OpenAI-compatible API at `https://mimo.mi.com`; uses `MIMO_API_KEY` and defaults to `mimo-v2.5-pro` |
259
+ | NEAR AI | `/provider` or env vars | Unified gateway (Claude, GPT, Gemini + TEE open models); uses `NEARAI_API_KEY` at `https://cloud-api.near.ai/v1` |
260
+ | Cloudflare Workers AI | `/provider` or env vars | OpenAI-compatible API at `https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1`; uses `CLOUDFLARE_API_TOKEN`. Replace `<ACCOUNT_ID>` with your Cloudflare account id. |
261
+ | Ollama | `/provider` or env vars | Local inference with no API key |
262
+ | Atomic Chat | `/provider`, env vars, or `bun run dev:atomic-chat` | Local Model Provider; auto-detects loaded models |
263
+ | Bedrock / Vertex / Foundry | env vars | Anthropic-family cloud routes; Vertex is for Claude on Vertex AI, not arbitrary Model Garden models |
264
+
265
+ ## What Works
266
+
267
+ - **Tool-driven coding workflows**: Bash, file read/write/edit, grep, glob, agents, tasks, MCP, and slash commands
268
+ - **Streaming responses**: Real-time token output and tool progress
269
+ - **Tool calling**: Multi-step tool loops with model calls, tool execution, and follow-up responses
270
+ - **Images**: URL and base64 image inputs for providers that support vision
271
+ - **Provider profiles**: Guided setup plus saved user-level provider profile support
272
+ - **Local and remote model backends**: Cloud APIs, local servers, and Apple Silicon local inference
273
+ - **Codebase intelligence (repo map)**: Structural map of the repository ranked by PageRank importance, auto-injected into context when the `REPO_MAP` flag is enabled or the `REPO_MAP` environment variable is set. Inspect with `/repomap` (2048-token default). See [docs/repo-map.md](docs/repo-map.md) for details.
274
+ - **A companion with signature moves**: A truecolor pixel-art hero who lives beside your prompt and reacts when you work. See below.
275
+
276
+ ## Meet Your Buddy
277
+
278
+ Run `/buddy` to hatch a companion — a truecolor pixel-art hero who stands
279
+ beside your prompt, idles, blinks, and fires their signature move every time
280
+ you submit a message:
281
+
282
+ ```
283
+ /buddy hatch (first run) or pet your companion
284
+ /buddy set robinhood the green archer — arrow shot on every Enter
285
+ /buddy set kaio gold-haired warrior — charges a full-width energy wave
286
+ /buddy set strawhat stretchy punch that snaps back
287
+ /buddy set merlin twinkling sparkle stream
288
+ /buddy set kage spinning shuriken
289
+ /buddy set ember dragon fire with a real heat gradient
290
+ /buddy set corsair cannonball with smoke trail
291
+ /buddy name Robin rename your companion
292
+ /buddy set random back to your rolled hero
293
+ ```
294
+
295
+ Companions respect `prefersReducedMotion`, degrade gracefully to line art in
296
+ low-color terminals, and can be silenced with `/buddy mute`. Requires a
297
+ terminal at least 100 columns wide for the full sprite.
298
+
299
+ ## Provider Notes
300
+
301
+ Claudio supports multiple providers, but behavior is not identical across all of them.
302
+
303
+ - Anthropic-specific features may not exist on other providers
304
+ - Tool quality depends heavily on the selected model
305
+ - Smaller local models can struggle with long multi-step tool flows
306
+ - Some providers impose lower output caps than the CLI defaults, and Claudio adapts where possible
307
+ - AI/ML API uses the OpenAI-compatible route, defaults to `gpt-4o`, and only surfaces chat-capable models from its public catalog
308
+ - Gitlawb Opengateway is the fresh-install startup default and requires an API key from https://gitlawb.com/opengateway/keys. It uses one OpenAI-compatible base URL; switch between `mimo-*` and `google/gemini-3.1-flash-lite-preview` with `/model`, and do not pin the base URL to `/v1/xiaomi-mimo`.
309
+ - Z.AI GLM Coding Plan uses `https://api.z.ai/api/coding/paas/v4` with `glm-5.2` by default. Use `glm-5.2?reasoning=high` for enhanced reasoning, `glm-5.2?reasoning=xhigh` to request Z.AI `reasoning_effort=max`, or `glm-5.2?thinking=disabled` for faster direct answers.
310
+ - Xiaomi MiMo uses `api-key` header auth on the direct OpenAI-compatible route and currently does not support `/usage` reporting in Claudio
311
+ - GitHub Copilot serializes sub-agent execution by default to reduce Premium Request consumption — see [Agent Routing and Step Limits](docs/agent-routing.md#github-copilot-sub-agent-optimization) for tuning
312
+
313
+ For best results, use models with strong tool/function calling support.
314
+
315
+ ## Agents
316
+
317
+ Route different agents to different models (cost optimization, splitting work
318
+ by model strength), cap sub-agent tool steps with `maxSteps`, and tune GitHub
319
+ Copilot sub-agent behavior. All settings-driven:
320
+
321
+ - per-agent provider/model overrides via `agentModels` + `agentRouting` in `~/.openclaude.json`
322
+ - model-only routes that reuse your current provider's credentials
323
+ - built-in agents (`Explore`, `Plan`, `verification`) routable by type name
324
+
325
+ See [Agent Routing and Step Limits](docs/agent-routing.md) for the full guide.
326
+
327
+ ## Web Search and Fetch
328
+
329
+ By default, `WebSearch` works on non-Anthropic models using DuckDuckGo. This gives GPT-4o, DeepSeek, Gemini, Ollama, and other OpenAI-compatible providers a free web search path out of the box.
330
+
331
+ > **Note:** DuckDuckGo fallback works by scraping search results and may be rate-limited, blocked, or subject to DuckDuckGo's Terms of Service. If you want a more reliable supported option, configure Firecrawl.
332
+
333
+ For Anthropic-native backends and Codex responses, Claudio keeps the native provider web search behavior.
334
+
335
+ `WebFetch` works, but its basic HTTP plus HTML-to-markdown path can still fail on JavaScript-rendered sites or sites that block plain HTTP requests.
336
+
337
+ Set a [Firecrawl](https://firecrawl.dev) API key if you want Firecrawl-powered search/fetch behavior:
338
+
339
+ ```bash
340
+ export FIRECRAWL_API_KEY=your-key-here
341
+ ```
342
+
343
+ With Firecrawl enabled:
344
+
345
+ - `WebSearch` can use Firecrawl's search API while DuckDuckGo remains the default free path for non-Claude models
346
+ - `WebFetch` uses Firecrawl's scrape endpoint instead of raw HTTP, handling JS-rendered pages correctly
347
+
348
+ Free tier at [firecrawl.dev](https://firecrawl.dev) includes 500 credits. The key is optional.
349
+
350
+ ## Headless gRPC Server
351
+
352
+ Claudio can run as a headless gRPC service with bidirectional streaming —
353
+ integrate its agentic capabilities into other applications, CI/CD pipelines,
354
+ or custom UIs. Start it with `npm run dev:grpc`; a test CLI client ships with
355
+ the repo. See [Headless gRPC Server](docs/grpc-server.md) for configuration
356
+ and client generation from `src/proto/openclaude.proto`.
357
+
358
+ ## Development
359
+
360
+ Use Node.js `>=22.0.0` and Bun `1.3.13` or newer for source builds.
361
+
362
+ ```bash
363
+ bun install
364
+ bun run build
365
+ node dist/cli.mjs
366
+ ```
367
+
368
+ Day-to-day commands:
369
+
370
+ - `bun run dev` — build and launch from source
371
+ - `bun test` — full unit suite (Bun's built-in runner)
372
+ - `bun test path/to/file.test.ts` — focused runs for the areas you touch
373
+ - `bun run test:coverage` — coverage to `coverage/lcov.info` plus a visual report at `coverage/index.html` (`bun run test:coverage:ui` rebuilds just the UI)
374
+ - `bun run smoke` — smoke checks
375
+ - `bun run doctor:runtime`, `bun run verify:privacy`, `bun run security:pr-scan -- --base origin/main`
376
+
377
+ Focused suites: `bun run test:provider`, `bun run test:provider-recommendation`.
378
+
379
+ Recommended validation before opening a PR:
380
+
381
+ - `bun run build`
382
+ - `bun run smoke`
383
+ - `bun run test:coverage` when your change affects shared runtime or provider logic
384
+ - focused `bun test ...` runs for the files and flows you changed
385
+
386
+ ## Repository Structure
387
+
388
+ - `src/` - core CLI/runtime
389
+ - `scripts/` - build, verification, and maintenance scripts
390
+ - `docs/` - setup, contributor, and project documentation
391
+ - `vscode-extension/openclaude-vscode/` - VS Code extension
392
+ - `.github/` - repo automation, templates, and CI configuration
393
+ - `bin/` - CLI launcher entrypoints
394
+
395
+ ## VS Code Extension
396
+
397
+ The repo includes a VS Code extension in [`vscode-extension/openclaude-vscode`](vscode-extension/openclaude-vscode) for Claudio launch integration, provider-aware Control Center, in-editor chat, theme support, and optional **Microsoft Foundry / Azure OpenAI** configuration (endpoint, API version, deployment, API key via Secret Storage) injected into launched terminals. See that folder's [README](vscode-extension/openclaude-vscode/README.md).
398
+
399
+ ## Security
400
+
401
+ If you believe you found a security issue, see [SECURITY.md](SECURITY.md).
402
+
403
+ ## Community
404
+
405
+ - Use [GitHub Discussions](https://github.com/Gitlawb/openclaude/discussions) for Q&A, ideas, and community conversation
406
+ - Use [GitHub Issues](https://github.com/Gitlawb/openclaude/issues) for confirmed bugs and actionable feature work
407
+ - Join the [Discord](https://discord.gg/k68zFR6AcB) to chat with the community in real time
408
+ - Follow [@gitlawb on X](https://x.com/gitlawb) for updates and announcements
409
+
410
+ ## Contributing
411
+
412
+ Contributions are welcome. For larger changes, open an issue first so the
413
+ scope is clear before implementation. See [Development](#development) for the
414
+ build, test, and pre-PR validation commands.
415
+
416
+ ## Disclaimer
417
+
418
+ Claudio is an independent community project and is not affiliated with, endorsed by, or sponsored by Anthropic.
419
+
420
+ Claudio originated from the Claude Code codebase and has since been substantially modified to support multiple providers and open use. "Claude" and "Claude Code" are trademarks of Anthropic PBC. See [LICENSE](LICENSE) for details.
421
+
422
+ ## License
423
+
424
+ MIT for Claudio contributors' modifications; the derived Claude Code remains Anthropic's. [See more](LICENSE).
package/bin/claudio ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claudio — Claude Code with any LLM
5
+ *
6
+ * If dist/cli.mjs exists (built), run that.
7
+ * Otherwise, tell the user to build first or use `bun run dev`.
8
+ */
9
+
10
+ import { existsSync } from 'fs'
11
+ import { join, dirname } from 'path'
12
+ import { fileURLToPath, pathToFileURL } from 'url'
13
+ import { spawnSync } from 'child_process'
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url))
16
+ const distPath = join(__dirname, '..', 'dist', 'cli.mjs')
17
+
18
+ const HEAP_RELAUNCHED_ENV = 'OPENCLAUDE_HEAP_RELAUNCHED'
19
+ const DISABLE_HEAP_RELAUNCH_ENV = 'OPENCLAUDE_DISABLE_HEAP_RELAUNCH'
20
+ const HEAP_SIZE_ENV = 'OPENCLAUDE_NODE_MAX_OLD_SPACE_SIZE_MB'
21
+ const DEFAULT_HEAP_SIZE_MB = 8192
22
+
23
+ function hasNodeFlag(args, flag) {
24
+ return args.some(arg => arg === flag || arg.startsWith(`${flag}=`))
25
+ }
26
+
27
+ function hasNodeOptionFlag(flag) {
28
+ return hasNodeFlag([
29
+ ...process.execArgv,
30
+ ...(process.env.NODE_OPTIONS || '').split(/\s+/).filter(Boolean),
31
+ ], flag)
32
+ }
33
+
34
+ function getHeapSizeMb() {
35
+ // --max-memory flag overrides env var
36
+ const maxMemArg = process.argv.find(a => a.startsWith('--max-memory='))
37
+ if (maxMemArg) {
38
+ const mb = Number.parseInt(maxMemArg.split('=')[1] || '0', 10)
39
+ if (Number.isSafeInteger(mb) && mb > 0) {
40
+ process.env[HEAP_SIZE_ENV] = String(mb)
41
+ process.env.OPENCLAUDE_MAX_MEMORY_MB = String(mb)
42
+ return mb
43
+ }
44
+ }
45
+
46
+ const raw = process.env[HEAP_SIZE_ENV]
47
+ if (!raw) return DEFAULT_HEAP_SIZE_MB
48
+ const parsed = Number.parseInt(raw, 10)
49
+ return Number.isSafeInteger(parsed) && parsed > 0
50
+ ? parsed
51
+ : DEFAULT_HEAP_SIZE_MB
52
+ }
53
+
54
+ function relaunchWithLongSessionHeapIfNeeded() {
55
+ if (process.env[DISABLE_HEAP_RELAUNCH_ENV] === '1') return
56
+ if (process.env[HEAP_RELAUNCHED_ENV] === '1') return
57
+ const hasHeapLimit = hasNodeOptionFlag('--max-old-space-size')
58
+ const hasExplicitGc = hasNodeOptionFlag('--expose-gc')
59
+ if (hasHeapLimit && hasExplicitGc) return
60
+
61
+ const execArgv = [...process.execArgv]
62
+ if (!hasHeapLimit) {
63
+ execArgv.push(`--max-old-space-size=${getHeapSizeMb()}`)
64
+ }
65
+
66
+ // Expose explicit GC for long interactive sessions. NODE_OPTIONS cannot
67
+ // carry --expose-gc, so the executable wrapper must add it before startup.
68
+ if (!hasExplicitGc) {
69
+ execArgv.push('--expose-gc')
70
+ }
71
+
72
+ // Strip --max-memory flag before relaunching — it's a launcher-only arg
73
+ // that Commander in the built CLI would reject as unknown.
74
+ const childArgs = process.argv.slice(2).filter(
75
+ arg => !arg.startsWith('--max-memory=') && arg !== '--max-memory',
76
+ )
77
+
78
+ // Preserve the original argv[1] (which may be a symlink like
79
+ // /usr/local/bin/openclaude) instead of resolving it via import.meta.url.
80
+ // Resolving symlinks here defeats install-type detection downstream: a real
81
+ // npm global install (symlink → node_modules/@gitlawb/openclaude/bin) would
82
+ // resolve to the package's real path inside node_modules, which is fine, but
83
+ // a `npm install -g .` dev symlink resolves back to the repo and looks like
84
+ // a source-tree dev run. Using argv[1] keeps the invocation path stable so
85
+ // doctorDiagnostic's npm-global path markers can match correctly.
86
+ const launcherPath = process.argv[1] || fileURLToPath(import.meta.url)
87
+
88
+ const result = spawnSync(process.execPath, [
89
+ ...execArgv,
90
+ launcherPath,
91
+ ...childArgs,
92
+ ], {
93
+ stdio: 'inherit',
94
+ env: {
95
+ ...process.env,
96
+ [HEAP_RELAUNCHED_ENV]: '1',
97
+ },
98
+ })
99
+
100
+ if (result.error) {
101
+ console.error(`openclaude: failed to restart with long-session heap: ${result.error.message}`)
102
+ process.exit(1)
103
+ }
104
+
105
+ process.exit(result.status ?? 1)
106
+ }
107
+
108
+ if (existsSync(distPath)) {
109
+ relaunchWithLongSessionHeapIfNeeded()
110
+ await import(pathToFileURL(distPath).href)
111
+ } else {
112
+ console.error(`
113
+ openclaude: dist/cli.mjs not found.
114
+
115
+ Build first:
116
+ bun run build
117
+
118
+ Or run directly with Bun:
119
+ bun run dev
120
+
121
+ See README.md for setup instructions.
122
+ `)
123
+ process.exit(1)
124
+ }
@@ -0,0 +1,13 @@
1
+ import { join, win32 } from 'path'
2
+ import { pathToFileURL } from 'url'
3
+
4
+ export function getDistImportSpecifier(baseDir) {
5
+ if (/^[A-Za-z]:\\/.test(baseDir)) {
6
+ const distPath = win32.join(baseDir, '..', 'dist', 'cli.mjs')
7
+ return `file:///${distPath.replace(/\\/g, '/')}`
8
+ }
9
+
10
+ const joinImpl = join
11
+ const distPath = joinImpl(baseDir, '..', 'dist', 'cli.mjs')
12
+ return pathToFileURL(distPath).href
13
+ }
@@ -0,0 +1,13 @@
1
+ import assert from 'node:assert/strict'
2
+ import test from 'node:test'
3
+
4
+ import { getDistImportSpecifier } from './import-specifier.mjs'
5
+
6
+ test('builds a file URL import specifier for dist/cli.mjs', () => {
7
+ const specifier = getDistImportSpecifier('C:\\repo\\bin')
8
+
9
+ assert.equal(
10
+ specifier,
11
+ 'file:///C:/repo/dist/cli.mjs',
12
+ )
13
+ })