@openanalystinc/openanalyst-cli 1.0.106
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 +404 -0
- package/bin/cli.js +70 -0
- package/package.json +58 -0
- package/scripts/postinstall.js +115 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenAnalyst Inc
|
|
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
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# OpenAnalyst CLI
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>The Universal AI Agent for Your Terminal</strong><br>
|
|
5
|
+
<em>One CLI. Every LLM Provider. Persistent Conversations Across Models.</em>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## What Is OpenAnalyst CLI?
|
|
11
|
+
|
|
12
|
+
OpenAnalyst CLI is an **independent, open-source AI coding agent** that connects to every major LLM provider through a single, unified terminal interface. It is built from the ground up in Rust with its own multi-provider architecture, Ratatui-based TUI, multi-agent orchestrator, and a full tool execution framework.
|
|
13
|
+
|
|
14
|
+
**OpenAnalyst is not a fork or copy of any other product.** It is an original work by OpenAnalyst Inc that implements industry-standard agent patterns — agentic loops, tool calling, permission systems, and session management — which are common across every major AI CLI tool (Codex CLI, Gemini CLI, Aider, Goose, aichat, and many others). These are established software engineering patterns, not proprietary to any single company.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Why OpenAnalyst?
|
|
19
|
+
|
|
20
|
+
| Capability | OpenAnalyst CLI | Other CLI Tools |
|
|
21
|
+
|-----------|----------------|-----------------|
|
|
22
|
+
| **Providers** | 7 (OpenAnalyst, Anthropic, OpenAI, xAI, Gemini, OpenRouter, Bedrock) | Typically 1-2 |
|
|
23
|
+
| **OAuth login** | Browser login for Claude, Codex, Gemini — no API key needed | API key only |
|
|
24
|
+
| **Mid-conversation model switching** | Session persists across providers | Not supported |
|
|
25
|
+
| **TUI** | Full Ratatui-based terminal UI with blue-branded OA banner | Most use basic REPL |
|
|
26
|
+
| **Multi-agent orchestrator** | Built-in parallel agents, swarms, autonomous loops, MOE | Limited or none |
|
|
27
|
+
| **Multimedia** | /image, /voice, /speak, /vision, /diagram | Rarely supported |
|
|
28
|
+
| **51+ slash commands** | Git, AI planning, multimedia, web scraping, Playwright | 5-15 typical |
|
|
29
|
+
| **19 built-in tools** | Bash, file ops, search, web, agents, REPL, PowerShell | 5-10 typical |
|
|
30
|
+
| **MCP support** | Full Model Context Protocol — unlimited external tools | Partial or none |
|
|
31
|
+
| **Single binary** | Native Rust, no runtime dependencies (18 MB) | Often needs Node/Python |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### 1. Install
|
|
38
|
+
|
|
39
|
+
**macOS / Linux:**
|
|
40
|
+
```bash
|
|
41
|
+
curl -fsSL https://raw.githubusercontent.com/OpenAnalystInc/openanalyst-cli/main/install.sh | bash
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Windows PowerShell:**
|
|
45
|
+
```powershell
|
|
46
|
+
irm https://raw.githubusercontent.com/OpenAnalystInc/openanalyst-cli/main/install.ps1 | iex
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Build from source:**
|
|
50
|
+
```bash
|
|
51
|
+
cd rust && cargo build --release
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Login
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
openanalyst login
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Interactive provider picker — select your LLM provider, authenticate via browser OAuth or API key, credentials saved automatically.
|
|
61
|
+
|
|
62
|
+
**Direct provider login:** For **Claude** (Anthropic), **Codex** (OpenAI), and **Gemini** (Google) you can login directly with your provider account via browser OAuth — no API key needed. Credentials are stored securely with PKCE and auto-refresh.
|
|
63
|
+
|
|
64
|
+
Alternatively, edit `~/.openanalyst/.env` (created during install) and add your API keys directly.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
openanalyst whoami # See all logged-in providers
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3. Start
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
openanalyst # Launch TUI (default)
|
|
74
|
+
openanalyst --no-tui # Legacy REPL mode
|
|
75
|
+
openanalyst "explain this codebase" # One-shot prompt
|
|
76
|
+
openanalyst --model gpt-4o "summarize this" # Use specific model
|
|
77
|
+
openanalyst --model gemini-2.5-pro "review" # Google Gemini
|
|
78
|
+
openanalyst --model grok "fix the bug" # xAI Grok
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Supported Providers
|
|
84
|
+
|
|
85
|
+
All providers are first-class citizens with live model discovery, streaming, and full tool support.
|
|
86
|
+
|
|
87
|
+
| Provider | Auth | Models |
|
|
88
|
+
|----------|------|--------|
|
|
89
|
+
| **OpenAnalyst** (default) | `OPENANALYST_AUTH_TOKEN` | Fetched live from API |
|
|
90
|
+
| **Anthropic / Claude** | `openanalyst login` (OAuth) or `ANTHROPIC_API_KEY` | opus, sonnet, haiku |
|
|
91
|
+
| **OpenAI / Codex** | `openanalyst login` (OAuth) or `OPENAI_API_KEY` | gpt-4o, o3, codex-mini |
|
|
92
|
+
| **Google Gemini** | `openanalyst login` (OAuth) or `GEMINI_API_KEY` | gemini-2.5-pro, flash |
|
|
93
|
+
| **xAI / Grok** | `XAI_API_KEY` | grok-3, grok-mini |
|
|
94
|
+
| **OpenRouter** | `OPENROUTER_API_KEY` | 350+ models from any provider |
|
|
95
|
+
| **Amazon Bedrock** | `BEDROCK_API_KEY` | Fetched live from gateway |
|
|
96
|
+
|
|
97
|
+
**All credits and trademarks belong to their respective providers.** Claude is a trademark of Anthropic. GPT is a trademark of OpenAI. Gemini is a trademark of Google. Grok is a trademark of xAI. OpenAnalyst CLI is an independent tool that connects to these providers' public APIs.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Features
|
|
102
|
+
|
|
103
|
+
### Full Terminal UI (Ratatui-based)
|
|
104
|
+
- **Blue-branded OA banner** with version inline, rounded-corner box, account info, tips
|
|
105
|
+
- Scrollable chat with inline tool call cards and rich diff rendering
|
|
106
|
+
- **Type immediately** — no vim Normal mode gate, just start typing
|
|
107
|
+
- Up/Down arrow keys for prompt history navigation
|
|
108
|
+
- Status line with animated spinner, elapsed time, token count, and current model
|
|
109
|
+
- Blue thick borders on input box, sidebar, and autocomplete popup
|
|
110
|
+
- Permission dialogs as modal overlays
|
|
111
|
+
- Mouse scroll and keyboard navigation
|
|
112
|
+
- Vim mode available via `/vim` toggle
|
|
113
|
+
- Shift+Enter for multi-line input
|
|
114
|
+
- Double Ctrl+C to quit (first press cancels, second quits)
|
|
115
|
+
|
|
116
|
+
### Authentication
|
|
117
|
+
- **Browser OAuth** for Claude, Codex, and Gemini — sign in with your provider account
|
|
118
|
+
- **API key** support for all 7 providers
|
|
119
|
+
- **PKCE security** with automatic token refresh
|
|
120
|
+
- Credentials stored in `~/.openanalyst/credentials.json`
|
|
121
|
+
- Interactive provider picker with arrow-key navigation
|
|
122
|
+
|
|
123
|
+
### Multi-Agent Orchestrator
|
|
124
|
+
- Spawn sub-agents for parallel tasks (Explore, Plan, General)
|
|
125
|
+
- **Agent Swarm** — `/swarm <task>` decomposes work across parallel agents
|
|
126
|
+
- **Autonomous loops** — `/openanalyst <task>` runs think→act→observe→verify cycles
|
|
127
|
+
- **Mixture of Experts (MOE)** — routes to specialized models per task type
|
|
128
|
+
- **Smart model routing** — `/route` to view/edit per-category model assignments
|
|
129
|
+
- **Effort budgets** — `/effort` to control thinking depth (low/medium/high/max)
|
|
130
|
+
- Each agent has its own conversation runtime and tool permissions
|
|
131
|
+
- Agent lifecycle events displayed in real-time in TUI
|
|
132
|
+
- Channel-based async bridge (sync runtime ↔ async TUI)
|
|
133
|
+
|
|
134
|
+
### 51+ Slash Commands
|
|
135
|
+
|
|
136
|
+
**Session & Config:** /help, /status, /cost, /model, /clear, /compact, /session, /export, /resume, /version, /login, /logout, /context, /vim, /config, /memory, /init, /exit, /sidebar, /permissions
|
|
137
|
+
|
|
138
|
+
**Code & Git:** /diff, /commit, /commit-push-pr, /pr, /issue, /branch, /worktree, /teleport, /diff-review, /changelog
|
|
139
|
+
|
|
140
|
+
**Analysis & Planning:** /bughunter, /ultraplan, /debug-tool-call, /think, /doctor
|
|
141
|
+
|
|
142
|
+
**Multimedia:** /image, /voice, /speak, /vision, /diagram
|
|
143
|
+
|
|
144
|
+
**Web & Data:** /scrape, /json
|
|
145
|
+
|
|
146
|
+
**AI & Translation:** /translate, /tokens
|
|
147
|
+
|
|
148
|
+
**Agent Control:** /swarm, /openanalyst, /ask, /user-prompt, /effort, /route, /agents, /skills
|
|
149
|
+
|
|
150
|
+
**Dev Tools:** /dev (install, open, screenshot, snap, click, type, test, codegen, stop)
|
|
151
|
+
|
|
152
|
+
**Advanced:** /mcp, /knowledge, /explore, /plugins, /hooks, /add-dir
|
|
153
|
+
|
|
154
|
+
### 19 Built-in Tools
|
|
155
|
+
|
|
156
|
+
| Tool | Permission | Description |
|
|
157
|
+
|------|-----------|-------------|
|
|
158
|
+
| `bash` | Full Access | Execute shell commands with sandboxing |
|
|
159
|
+
| `read_file` | Read Only | Read file contents with line numbers |
|
|
160
|
+
| `write_file` | Workspace | Create or overwrite files |
|
|
161
|
+
| `edit_file` | Workspace | Modify files with exact string replacement |
|
|
162
|
+
| `glob_search` | Read Only | Find files by glob patterns |
|
|
163
|
+
| `grep_search` | Read Only | Search file contents with regex |
|
|
164
|
+
| `web_search` | Read Only | Search the internet |
|
|
165
|
+
| `web_fetch` | Read Only | Fetch and parse URL content |
|
|
166
|
+
| `agent` | Varies | Spawn sub-agents for parallel tasks |
|
|
167
|
+
| `todo_write` | Workspace | Create and manage task lists |
|
|
168
|
+
| `notebook_edit` | Workspace | Edit Jupyter notebook cells |
|
|
169
|
+
| `skill` | Varies | Invoke custom skills |
|
|
170
|
+
| `tool_search` | Read Only | Discover available tools |
|
|
171
|
+
| `config` | Read Only | Read configuration and settings |
|
|
172
|
+
| `repl` | Varies | Run code in Python or Node REPL |
|
|
173
|
+
| `structured_output` | Read Only | Validate output against JSON schema |
|
|
174
|
+
| `sleep` | Read Only | Pause execution |
|
|
175
|
+
| `send_user_message` | Read Only | Send notification to user |
|
|
176
|
+
| `powershell` | Varies | Execute PowerShell commands (Windows) |
|
|
177
|
+
|
|
178
|
+
Additional tools can be registered via **MCP servers** (unlimited).
|
|
179
|
+
|
|
180
|
+
### MCP (Model Context Protocol)
|
|
181
|
+
|
|
182
|
+
Full MCP client with 6 transport types:
|
|
183
|
+
- **stdio** — Local processes, npm packages
|
|
184
|
+
- **SSE** — Remote servers over HTTP
|
|
185
|
+
- **WebSocket** — Bidirectional real-time
|
|
186
|
+
- **HTTP** — REST API wrappers
|
|
187
|
+
- **SDK** — Direct in-process integration
|
|
188
|
+
- **Managed proxy** — Enterprise environments
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
/mcp # List connected servers
|
|
192
|
+
/mcp add my-server stdio npx -y @my/mcp-server
|
|
193
|
+
/mcp remove my-server
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Knowledge Base (`/knowledge`)
|
|
197
|
+
|
|
198
|
+
Agentic RAG powered by real BGE-M3 1024-dim embeddings, PostgreSQL pgvector, and Neo4j knowledge graph.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
/knowledge best Meta Ads strategy for scaling D2C brands
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Pipeline:**
|
|
205
|
+
1. **Local intent classification** — Rust-side MOE classifies query intent (strategic, procedural, factual, etc.)
|
|
206
|
+
2. **API call** to hosted AgenticRAG server with intent hint
|
|
207
|
+
3. **Hybrid search** — pgvector cosine + PostgreSQL FTS + Neo4j graph expansion
|
|
208
|
+
4. **RRF fusion** — Reciprocal Rank Fusion merges results from all sources
|
|
209
|
+
5. **KnowledgeCard** — Tabbed, collapsible results with abstracted category labels
|
|
210
|
+
6. **Feedback** — Inline 👍/👎 buttons + `/feedback` command for corrections
|
|
211
|
+
7. **Local cache** — Results cached in `.openanalyst/knowledge/` for instant replay
|
|
212
|
+
|
|
213
|
+
**MOE Intent Types:** factual, conceptual, procedural, comparative, strategic, example_seeking, diagnostic, general
|
|
214
|
+
|
|
215
|
+
**No raw course names exposed** — results show abstracted labels like "Ads Strategy", "AI & Machine Learning".
|
|
216
|
+
|
|
217
|
+
Set `OPENANALYST_API_KEY=oa_your_key` to access the knowledge base.
|
|
218
|
+
|
|
219
|
+
### Permission Mode Switching (`Ctrl+P`)
|
|
220
|
+
|
|
221
|
+
Cycle through permission modes directly from the input box:
|
|
222
|
+
|
|
223
|
+
| Mode | Icon | Border | Behavior |
|
|
224
|
+
|------|------|--------|----------|
|
|
225
|
+
| Default | ❯ | Blue | Ask before running tools |
|
|
226
|
+
| Plan | ◈ | Yellow | Read-only tools only |
|
|
227
|
+
| Accept Edits | ✎ | Green | Auto-approve file write/edit |
|
|
228
|
+
| Danger | ⚡ | Red | Everything auto-approved |
|
|
229
|
+
|
|
230
|
+
Right-aligned badges on input box show: `[mode] [model] [agent] [branch]`
|
|
231
|
+
|
|
232
|
+
### Agent Selection from Sidebar
|
|
233
|
+
|
|
234
|
+
- Load agents from `.openanalyst/agents/*.md` (project + user level)
|
|
235
|
+
- Select agent in sidebar → changes input box title + system prompt
|
|
236
|
+
- Purple badge shows active agent name
|
|
237
|
+
- Dynamic system prompt switching without leaving the conversation
|
|
238
|
+
|
|
239
|
+
### Permission System
|
|
240
|
+
|
|
241
|
+
| Mode | Bash | Write | Edit | Install | Delete |
|
|
242
|
+
|------|------|-------|------|---------|--------|
|
|
243
|
+
| `read-only` | ✗ | ✗ | ✗ | ✗ | ✗ |
|
|
244
|
+
| `workspace-write` | ✓ | ✓ | ✓ | ✗ | ✗ |
|
|
245
|
+
| `danger-full-access` | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
246
|
+
|
|
247
|
+
Modal permission dialogs appear when a tool requires elevated access. Cycle with `Ctrl+P`.
|
|
248
|
+
|
|
249
|
+
### Hooks System
|
|
250
|
+
|
|
251
|
+
| Event | Fires When |
|
|
252
|
+
|-------|-----------|
|
|
253
|
+
| `PreToolUse` | Before a tool is executed |
|
|
254
|
+
| `PostToolUse` | After a tool completes |
|
|
255
|
+
| `SessionStart` | When a new session begins |
|
|
256
|
+
| `SessionEnd` | When a session ends |
|
|
257
|
+
| `CwdChanged` | When the working directory changes |
|
|
258
|
+
| `FileChanged` | When a file is modified |
|
|
259
|
+
| `TaskCreated` | When a new task is created |
|
|
260
|
+
|
|
261
|
+
### Plugin System
|
|
262
|
+
- Install, enable, disable plugins from `~/.openanalyst/plugins/`
|
|
263
|
+
- Full lifecycle management with `/plugins` command
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Architecture
|
|
268
|
+
|
|
269
|
+
OpenAnalyst CLI is a **14-crate Rust workspace**:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
rust/crates/
|
|
273
|
+
├── api/ # Multi-provider API client (7 providers)
|
|
274
|
+
├── commands/ # 51+ slash commands
|
|
275
|
+
├── events/ # Shared TUI ↔ backend event types
|
|
276
|
+
├── orchestrator/ # Multi-agent lifecycle, MOE, model routing
|
|
277
|
+
├── tui/ # Ratatui full-screen TUI application
|
|
278
|
+
├── tui-widgets/ # Widgets (markdown, tool cards, input, spinner)
|
|
279
|
+
├── runtime/ # Conversation engine, session, permissions, MCP
|
|
280
|
+
├── tools/ # 19 built-in tool implementations
|
|
281
|
+
├── plugins/ # Plugin system (install, enable, hooks)
|
|
282
|
+
├── openanalyst-cli/ # Binary entry point
|
|
283
|
+
├── openanalyst-agent/ # Headless autonomous agent runner
|
|
284
|
+
├── server/ # HTTP/SSE server (axum)
|
|
285
|
+
├── lsp/ # Language Server Protocol integration
|
|
286
|
+
└── compat-harness/ # Upstream manifest extraction
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Key Technologies
|
|
290
|
+
- **Ratatui 0.30** — Terminal UI framework
|
|
291
|
+
- **Tokio 1.x** — Async runtime (multi-threaded)
|
|
292
|
+
- **Crossterm 0.29** — Terminal backend
|
|
293
|
+
- **Reqwest 0.12** — HTTP client
|
|
294
|
+
- **Syntect 5.x** — Syntax highlighting
|
|
295
|
+
- **Tiktoken-rs** — Token counting
|
|
296
|
+
- **edtui** — Text editor widget (vim mode optional)
|
|
297
|
+
- **tui-markdown** — Markdown rendering (Ratatui team)
|
|
298
|
+
- **Axum** — HTTP/SSE server
|
|
299
|
+
|
|
300
|
+
### Ecosystem Crates Used (not reinvented)
|
|
301
|
+
- **tui-markdown** — Markdown rendering (by Ratatui core team)
|
|
302
|
+
- **edtui** — Vim-mode text editor widget
|
|
303
|
+
- **tui-tree-widget** — File tree sidebar
|
|
304
|
+
- **throbber-widgets-tui** — Animated spinners
|
|
305
|
+
- **syntect-tui** — Syntax highlighting bridge
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Configuration
|
|
310
|
+
|
|
311
|
+
| File | Purpose |
|
|
312
|
+
|------|---------|
|
|
313
|
+
| `OPENANALYST.md` | Project-specific AI instructions (auto-detected) |
|
|
314
|
+
| `.openanalyst.json` | Shared project defaults |
|
|
315
|
+
| `.openanalyst/settings.json` | Project settings (hooks, plugins, MCP, model, permissions) |
|
|
316
|
+
| `.openanalyst/settings.local.json` | Machine-local overrides (gitignored) |
|
|
317
|
+
| `~/.openanalyst/.env` | API keys and base URLs |
|
|
318
|
+
| `~/.openanalyst/credentials.json` | Saved OAuth tokens (auto-managed) |
|
|
319
|
+
|
|
320
|
+
### Environment Variables
|
|
321
|
+
|
|
322
|
+
**Authentication:**
|
|
323
|
+
| Variable | Provider |
|
|
324
|
+
|----------|----------|
|
|
325
|
+
| `OPENANALYST_AUTH_TOKEN` | OpenAnalyst (default) |
|
|
326
|
+
| `ANTHROPIC_API_KEY` | Anthropic / Claude |
|
|
327
|
+
| `OPENAI_API_KEY` | OpenAI / Codex |
|
|
328
|
+
| `GEMINI_API_KEY` | Google Gemini |
|
|
329
|
+
| `XAI_API_KEY` | xAI / Grok |
|
|
330
|
+
| `OPENROUTER_API_KEY` | OpenRouter |
|
|
331
|
+
| `BEDROCK_API_KEY` | Amazon Bedrock |
|
|
332
|
+
|
|
333
|
+
**Runtime:**
|
|
334
|
+
| Variable | Description |
|
|
335
|
+
|----------|-------------|
|
|
336
|
+
| `OPENANALYST_CONFIG_HOME` | Override config directory |
|
|
337
|
+
| `OPENANALYST_MODEL` | Override default model |
|
|
338
|
+
| `OPENANALYST_PERMISSION_MODE` | Set permission mode |
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Documentation
|
|
343
|
+
|
|
344
|
+
Full Mintlify-style documentation is included at [`docs/Documentation/index.html`](docs/Documentation/index.html) — 12 pages covering:
|
|
345
|
+
|
|
346
|
+
- Installation & Quick Start
|
|
347
|
+
- Authentication (OAuth + API keys)
|
|
348
|
+
- LLM Providers & model switching
|
|
349
|
+
- Terminal UI layout & keybindings
|
|
350
|
+
- All 51+ slash commands
|
|
351
|
+
- 19 built-in tools with permissions
|
|
352
|
+
- Multi-agent system (swarms, autonomous, MOE)
|
|
353
|
+
- Configuration & hooks
|
|
354
|
+
- MCP integration
|
|
355
|
+
- Architecture & building
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Legal & Credits
|
|
360
|
+
|
|
361
|
+
### OpenAnalyst CLI Is an Independent Product
|
|
362
|
+
|
|
363
|
+
OpenAnalyst CLI is **original software** developed by OpenAnalyst Inc. It is:
|
|
364
|
+
|
|
365
|
+
- **Not** a fork, copy, or derivative of any other product
|
|
366
|
+
- **Not** affiliated with, endorsed by, or maintained by Anthropic, OpenAI, Google, xAI, or any other provider
|
|
367
|
+
- Built using **industry-standard patterns** (agentic loops, tool calling, MCP, session management) that are common across the entire AI CLI ecosystem
|
|
368
|
+
|
|
369
|
+
The architectural patterns used — streaming tool execution, permission hierarchies, session persistence, system prompts with project context — are **well-established, open engineering practices** implemented independently by dozens of projects including Codex CLI, Gemini CLI, Aider, Goose, aichat, rust-code, kai, and many others. No single company owns these patterns.
|
|
370
|
+
|
|
371
|
+
### Provider Credits & Trademarks
|
|
372
|
+
|
|
373
|
+
OpenAnalyst CLI connects to third-party APIs. All credits belong to the respective providers:
|
|
374
|
+
|
|
375
|
+
- **Anthropic** — Claude, the Anthropic API, and all related trademarks are property of Anthropic, PBC
|
|
376
|
+
- **OpenAI** — GPT, DALL-E, Whisper, Codex, and all related trademarks are property of OpenAI, Inc
|
|
377
|
+
- **Google** — Gemini, Imagen, and all related trademarks are property of Google LLC
|
|
378
|
+
- **xAI** — Grok and all related trademarks are property of xAI Corp
|
|
379
|
+
- **Amazon** — Bedrock and all related trademarks are property of Amazon Web Services, Inc
|
|
380
|
+
- **OpenRouter** — OpenRouter is property of OpenRouter, Inc
|
|
381
|
+
|
|
382
|
+
Use of these providers' APIs through OpenAnalyst CLI is subject to each provider's respective Terms of Service. OpenAnalyst CLI is a client application that facilitates access to these APIs — it does not claim any ownership of or rights to the providers' services, models, or intellectual property.
|
|
383
|
+
|
|
384
|
+
### License
|
|
385
|
+
|
|
386
|
+
The Rust workspace is licensed under the **MIT License**. See `rust/LICENSE` for details.
|
|
387
|
+
|
|
388
|
+
### Disclaimer
|
|
389
|
+
|
|
390
|
+
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. OpenAnalyst Inc makes no representations regarding the suitability of this software for any purpose. OpenAnalyst CLI is an independent product that connects to third-party APIs under their respective terms of service.
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Contact
|
|
395
|
+
|
|
396
|
+
- **Issues:** [github.com/OpenAnalystInc/openanalyst-cli/issues](https://github.com/OpenAnalystInc/openanalyst-cli/issues)
|
|
397
|
+
- **Email:** anit@openanalyst.com
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
<p align="center">
|
|
402
|
+
<strong>OpenAnalyst CLI v1.0.91</strong> — Built by OpenAnalyst Inc<br>
|
|
403
|
+
<em>An independent, open-source AI agent for the terminal.</em>
|
|
404
|
+
</p>
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execFileSync, spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
|
|
8
|
+
// Resolve the native binary path
|
|
9
|
+
function getBinaryPath() {
|
|
10
|
+
const platform = os.platform();
|
|
11
|
+
const ext = platform === "win32" ? ".exe" : "";
|
|
12
|
+
const binaryName = `openanalyst${ext}`;
|
|
13
|
+
|
|
14
|
+
// Check multiple locations in priority order
|
|
15
|
+
const candidates = [
|
|
16
|
+
// Installed via postinstall (prebuilt binary)
|
|
17
|
+
path.join(__dirname, "..", "native", binaryName),
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
for (const candidate of candidates) {
|
|
21
|
+
if (fs.existsSync(candidate)) {
|
|
22
|
+
return candidate;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Try system PATH
|
|
27
|
+
try {
|
|
28
|
+
const which = platform === "win32" ? "where" : "which";
|
|
29
|
+
const result = execFileSync(which, ["openanalyst"], {
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
32
|
+
}).trim();
|
|
33
|
+
if (result) return result.split("\n")[0].trim();
|
|
34
|
+
} catch {
|
|
35
|
+
// not in PATH
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const binary = getBinaryPath();
|
|
42
|
+
|
|
43
|
+
if (!binary) {
|
|
44
|
+
console.error(`
|
|
45
|
+
OpenAnalyst CLI binary not found.
|
|
46
|
+
|
|
47
|
+
Try reinstalling:
|
|
48
|
+
npm install -g @openanalyst/openanalyst-cli
|
|
49
|
+
|
|
50
|
+
Or download from: https://openanalyst.com
|
|
51
|
+
Support: support@openanalyst.com
|
|
52
|
+
`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Pass through all arguments to the native binary
|
|
57
|
+
const args = process.argv.slice(2);
|
|
58
|
+
const child = spawn(binary, args, {
|
|
59
|
+
stdio: "inherit",
|
|
60
|
+
env: process.env,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
child.on("error", (err) => {
|
|
64
|
+
console.error(`Failed to start OpenAnalyst CLI: ${err.message}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
child.on("exit", (code) => {
|
|
69
|
+
process.exit(code ?? 0);
|
|
70
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openanalystinc/openanalyst-cli",
|
|
3
|
+
"version": "1.0.106",
|
|
4
|
+
"description": "OpenAnalyst CLI — AI-powered code analysis agent with multi-provider LLM support",
|
|
5
|
+
"bin": {
|
|
6
|
+
"openanalyst": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/postinstall.js",
|
|
10
|
+
"build": "node scripts/build.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"scripts/postinstall.js",
|
|
15
|
+
"native/",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"cli",
|
|
21
|
+
"ai",
|
|
22
|
+
"openanalyst",
|
|
23
|
+
"code-analysis",
|
|
24
|
+
"llm",
|
|
25
|
+
"agent"
|
|
26
|
+
],
|
|
27
|
+
"author": "OpenAnalyst Inc",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/OpenAnalystInc/openanalyst-cli.git"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"registry": "https://registry.npmjs.org/"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"os": [
|
|
41
|
+
"darwin",
|
|
42
|
+
"linux",
|
|
43
|
+
"win32"
|
|
44
|
+
],
|
|
45
|
+
"main": "index.js",
|
|
46
|
+
"directories": {
|
|
47
|
+
"doc": "docs",
|
|
48
|
+
"test": "tests"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/OpenAnalystInc/openanalyst-cli/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/OpenAnalystInc/openanalyst-cli#readme",
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@playwright/test": "1.52",
|
|
56
|
+
"playwright": "1.52"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
const https = require("https");
|
|
8
|
+
|
|
9
|
+
const PACKAGE_VERSION = require("../package.json").version;
|
|
10
|
+
const REPO = "OpenAnalystInc/openanalyst-cli";
|
|
11
|
+
const NATIVE_DIR = path.join(__dirname, "..", "native");
|
|
12
|
+
|
|
13
|
+
const PLATFORM_MAP = {
|
|
14
|
+
"darwin-x64": "x86_64-apple-darwin",
|
|
15
|
+
"darwin-arm64": "aarch64-apple-darwin",
|
|
16
|
+
"linux-x64": "x86_64-unknown-linux-gnu",
|
|
17
|
+
"linux-arm64": "aarch64-unknown-linux-gnu",
|
|
18
|
+
"win32-x64": "x86_64-pc-windows-msvc",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function getPlatformKey() {
|
|
22
|
+
return `${os.platform()}-${os.arch()}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function log(msg) {
|
|
26
|
+
console.log(` [openanalyst] ${msg}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Try to download a prebuilt binary from GitHub releases
|
|
30
|
+
async function tryDownloadPrebuilt() {
|
|
31
|
+
const platformKey = getPlatformKey();
|
|
32
|
+
const target = PLATFORM_MAP[platformKey];
|
|
33
|
+
|
|
34
|
+
if (!target) {
|
|
35
|
+
log(`No prebuilt binary for ${platformKey}, will build from source`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const ext = os.platform() === "win32" ? ".exe" : "";
|
|
40
|
+
const assetName = `openanalyst-${target}${ext}`;
|
|
41
|
+
const releaseUrl = `https://github.com/${REPO}/releases/download/v${PACKAGE_VERSION}/${assetName}`;
|
|
42
|
+
|
|
43
|
+
log(`Checking for prebuilt binary: ${assetName}`);
|
|
44
|
+
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
const request = https.get(releaseUrl, { headers: { "User-Agent": "openanalyst-cli" } }, (res) => {
|
|
47
|
+
if (res.statusCode === 302 || res.statusCode === 301) {
|
|
48
|
+
// Follow redirect (GitHub releases redirect to S3)
|
|
49
|
+
https.get(res.headers.location, { headers: { "User-Agent": "openanalyst-cli" } }, (redirectRes) => {
|
|
50
|
+
if (redirectRes.statusCode !== 200) {
|
|
51
|
+
resolve(false);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
downloadStream(redirectRes, assetName, ext, resolve);
|
|
55
|
+
}).on("error", () => resolve(false));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (res.statusCode !== 200) {
|
|
59
|
+
resolve(false);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
downloadStream(res, assetName, ext, resolve);
|
|
63
|
+
});
|
|
64
|
+
request.on("error", () => resolve(false));
|
|
65
|
+
request.setTimeout(15000, () => { request.destroy(); resolve(false); });
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function downloadStream(stream, assetName, ext, resolve) {
|
|
70
|
+
const chunks = [];
|
|
71
|
+
stream.on("data", (chunk) => chunks.push(chunk));
|
|
72
|
+
stream.on("end", () => {
|
|
73
|
+
try {
|
|
74
|
+
fs.mkdirSync(NATIVE_DIR, { recursive: true });
|
|
75
|
+
const outPath = path.join(NATIVE_DIR, `openanalyst${ext}`);
|
|
76
|
+
fs.writeFileSync(outPath, Buffer.concat(chunks));
|
|
77
|
+
if (os.platform() !== "win32") {
|
|
78
|
+
fs.chmodSync(outPath, 0o755);
|
|
79
|
+
}
|
|
80
|
+
log(`Downloaded prebuilt binary to ${outPath}`);
|
|
81
|
+
resolve(true);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
log(`Failed to write binary: ${err.message}`);
|
|
84
|
+
resolve(false);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
stream.on("error", () => resolve(false));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async function main() {
|
|
92
|
+
console.log("");
|
|
93
|
+
log("Installing OpenAnalyst CLI v" + PACKAGE_VERSION);
|
|
94
|
+
console.log("");
|
|
95
|
+
|
|
96
|
+
// Strategy 1: Try prebuilt download
|
|
97
|
+
const downloaded = await tryDownloadPrebuilt();
|
|
98
|
+
if (downloaded) {
|
|
99
|
+
log("Installation complete (prebuilt binary)");
|
|
100
|
+
console.log("");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// No prebuilt available
|
|
105
|
+
console.log("");
|
|
106
|
+
log("Could not install the OpenAnalyst CLI binary.");
|
|
107
|
+
log("Download from: https://openanalyst.com");
|
|
108
|
+
log("Support: support@openanalyst.com");
|
|
109
|
+
console.log("");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
main().catch((err) => {
|
|
113
|
+
console.error(` [openanalyst] postinstall error: ${err.message}`);
|
|
114
|
+
// Don't fail the npm install — user can build manually
|
|
115
|
+
});
|