@andypai/orb 0.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 +349 -0
- package/assets/orb-logo.svg +75 -0
- package/assets/orb-terminal-session.svg +72 -0
- package/assets/orb-wordmark.svg +77 -0
- package/package.json +76 -0
- package/prompts/anthropic.md +2 -0
- package/prompts/base.md +1 -0
- package/prompts/openai.md +7 -0
- package/prompts/voice.md +12 -0
- package/src/cli.ts +9 -0
- package/src/config.ts +270 -0
- package/src/index.ts +82 -0
- package/src/pipeline/adapters/anthropic.ts +111 -0
- package/src/pipeline/adapters/openai.ts +202 -0
- package/src/pipeline/adapters/types.ts +16 -0
- package/src/pipeline/adapters/utils.ts +131 -0
- package/src/pipeline/frames.ts +113 -0
- package/src/pipeline/observer.ts +36 -0
- package/src/pipeline/observers/metrics.ts +95 -0
- package/src/pipeline/pipeline.ts +43 -0
- package/src/pipeline/processor.ts +57 -0
- package/src/pipeline/processors/agent.ts +38 -0
- package/src/pipeline/processors/tts.ts +120 -0
- package/src/pipeline/task.ts +239 -0
- package/src/pipeline/transports/terminal-text.ts +24 -0
- package/src/pipeline/transports/types.ts +33 -0
- package/src/services/auth-utils.ts +149 -0
- package/src/services/global-config.ts +363 -0
- package/src/services/openai-auth.ts +18 -0
- package/src/services/prompts.ts +76 -0
- package/src/services/provider-defaults.ts +97 -0
- package/src/services/session.ts +204 -0
- package/src/services/streaming-tts.ts +483 -0
- package/src/services/tts.ts +309 -0
- package/src/setup.ts +234 -0
- package/src/types/index.ts +108 -0
- package/src/ui/App.tsx +142 -0
- package/src/ui/components/ActivityTimeline.tsx +60 -0
- package/src/ui/components/AsciiOrb.tsx +92 -0
- package/src/ui/components/ConversationRail.tsx +44 -0
- package/src/ui/components/Footer.tsx +61 -0
- package/src/ui/components/InputPrompt.tsx +88 -0
- package/src/ui/components/MicroOrb.tsx +25 -0
- package/src/ui/components/TTSErrorBanner.tsx +36 -0
- package/src/ui/components/TurnRow.tsx +71 -0
- package/src/ui/components/WelcomeSplash.tsx +78 -0
- package/src/ui/hooks/useAnimationFrame.ts +33 -0
- package/src/ui/hooks/useConversation.ts +195 -0
- package/src/ui/hooks/useKeyboardShortcuts.ts +57 -0
- package/src/ui/hooks/usePipeline.ts +83 -0
- package/src/ui/hooks/useTerminalSize.ts +37 -0
- package/src/ui/utils/markdown.ts +89 -0
- package/src/ui/utils/model-label.ts +20 -0
- package/src/ui/utils/text.ts +18 -0
- package/src/ui/utils/tool-format.ts +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andy Pai
|
|
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,349 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./assets/orb-wordmark.svg" alt="orb" width="920" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
Voice-driven code explorer for your terminal. Ask questions about your codebase, watch tool calls live, and optionally hear answers spoken aloud while they stream.
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img src="./assets/orb-terminal-session.svg" alt="Orb running in the terminal with live tool activity and an architecture summary." width="1100" />
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
## Why Orb
|
|
14
|
+
|
|
15
|
+
Orb is a Bun-native terminal app for exploring real codebases with Anthropic or OpenAI models. It keeps the interface focused, shows tool activity as it happens, remembers project conversations, and can read answers aloud through `tts-gateway` or macOS `say`.
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **Natural language queries** - Ask questions about your code in plain English
|
|
20
|
+
- **Live tool activity** - See file reads, shell commands, and exploration steps as they happen
|
|
21
|
+
- **Voice input friendly** - Paste transcriptions from MacWhisper for hands-free interaction
|
|
22
|
+
- **Streaming TTS (serve mode)** - Hear answers while they are still being generated
|
|
23
|
+
- **Provider selection** - Choose Anthropic (Claude) or OpenAI via CLI flags
|
|
24
|
+
- **Model switching (Claude)** - Cycle Anthropic models during a conversation with Shift+Tab
|
|
25
|
+
- **Session persistence** - Automatically resume the last session per project
|
|
26
|
+
- **Focused terminal UI** - Ink-based interface with conversation history, tool activity, and the Orb intro
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### Global install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# With Bun
|
|
34
|
+
bun install -g @andypai/orb
|
|
35
|
+
|
|
36
|
+
# With npm (Bun is still required at runtime)
|
|
37
|
+
npm install -g @andypai/orb
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Local / one-off use
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Run without installing globally
|
|
44
|
+
bunx @andypai/orb
|
|
45
|
+
|
|
46
|
+
# Add to a Bun project
|
|
47
|
+
bun add @andypai/orb
|
|
48
|
+
|
|
49
|
+
# npm also works, but Bun is still required at runtime
|
|
50
|
+
npm install @andypai/orb
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 60-Second Quick Start
|
|
54
|
+
|
|
55
|
+
### 1. Set up an LLM provider
|
|
56
|
+
|
|
57
|
+
- Anthropic: sign in with Claude Code / Max, or set `ANTHROPIC_API_KEY`
|
|
58
|
+
- OpenAI: set `OPENAI_API_KEY`
|
|
59
|
+
|
|
60
|
+
If you do not pass `--provider` or `--model`, Orb auto-selects a provider in this order:
|
|
61
|
+
|
|
62
|
+
1. Claude Agent SDK (Claude Code / Max or API key)
|
|
63
|
+
2. `OPENAI_API_KEY`
|
|
64
|
+
3. `ANTHROPIC_API_KEY`
|
|
65
|
+
|
|
66
|
+
### 2. Pick your speech path
|
|
67
|
+
|
|
68
|
+
#### Fastest path with no speech
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
orb --no-tts
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Fastest path on macOS (batch speech)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
orb --tts-mode=generate
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Generate mode uses macOS built-ins (`say` and `afplay`) and does not require `tts-gateway`.
|
|
81
|
+
|
|
82
|
+
#### Recommended path for streaming speech
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv tool install tts-gateway[kokoro]
|
|
86
|
+
~/.local/share/uv/tools/tts-gateway/bin/python -m spacy download en_core_web_sm
|
|
87
|
+
tts serve --provider kokoro --port 8000
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
That spaCy install is important: Kokoro’s first request will crash in a plain `uv tool` install unless `en_core_web_sm` is installed into the `tts-gateway` tool environment.
|
|
91
|
+
|
|
92
|
+
Orb expects `tts-gateway` at `http://localhost:8000` by default and automatically targets `POST /tts`.
|
|
93
|
+
|
|
94
|
+
### 3. Run Orb
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Explore the current directory
|
|
98
|
+
orb
|
|
99
|
+
|
|
100
|
+
# Guided setup for persistent defaults
|
|
101
|
+
orb setup
|
|
102
|
+
|
|
103
|
+
# Explore a specific project
|
|
104
|
+
orb /path/to/project
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Anthropic with options
|
|
111
|
+
orb --model=sonnet --voice=marius
|
|
112
|
+
orb --provider=anthropic --model=opus
|
|
113
|
+
|
|
114
|
+
# OpenAI provider
|
|
115
|
+
orb --provider=openai --model=gpt-5.4
|
|
116
|
+
orb --model=openai:gpt-5.4
|
|
117
|
+
|
|
118
|
+
# Fresh conversation
|
|
119
|
+
orb --new
|
|
120
|
+
|
|
121
|
+
# Skip the intro animation
|
|
122
|
+
orb --skip-intro
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Options
|
|
126
|
+
|
|
127
|
+
| Option | Description | Default |
|
|
128
|
+
| ------------------------ | ------------------------------------------------------------------------------ | --------------------------------------- |
|
|
129
|
+
| `--provider=<provider>` | LLM provider: `anthropic`\|`claude`, `openai`\|`gpt` (alias: `--llm-provider`) | `auto` |
|
|
130
|
+
| `--model=<model>` | Model ID or alias (`haiku`, `sonnet`, `opus`) or `provider:model` | `haiku` (anthropic), `gpt-5.4` (openai) |
|
|
131
|
+
| `--voice=<voice>` | TTS voice: `alba`, `marius`, `jean` | `alba` |
|
|
132
|
+
| `--tts-mode=<mode>` | `serve` for `tts-gateway`, `generate` for local macOS `say` | `serve` |
|
|
133
|
+
| `--tts-server-url=<url>` | Serve-mode gateway URL | `http://localhost:8000` |
|
|
134
|
+
| `--tts-speed=<rate>` | TTS speed multiplier | `1.5` |
|
|
135
|
+
| `--new` | Start fresh (ignore saved session) | - |
|
|
136
|
+
| `--skip-intro` | Skip the welcome animation | - |
|
|
137
|
+
| `--no-tts` | Disable text-to-speech | - |
|
|
138
|
+
| `--no-streaming-tts` | Disable streaming (batch mode) | - |
|
|
139
|
+
| `--help` | Show help message | - |
|
|
140
|
+
|
|
141
|
+
### Controls
|
|
142
|
+
|
|
143
|
+
- Type your question and press **Enter** to submit
|
|
144
|
+
- Paste MacWhisper transcription with **Cmd+V**
|
|
145
|
+
- Press **Esc** or **Ctrl+S** to stop speech
|
|
146
|
+
- Press **Shift+Tab** to cycle Claude models (Anthropic only)
|
|
147
|
+
- Press **Ctrl+O** to toggle live tool-call details
|
|
148
|
+
- Press **Ctrl+C** to exit
|
|
149
|
+
|
|
150
|
+
## TTS Setup
|
|
151
|
+
|
|
152
|
+
Orb supports two TTS paths:
|
|
153
|
+
|
|
154
|
+
- **Serve mode** (default): send speech requests to a local `tts-gateway` server
|
|
155
|
+
- **Generate mode**: use macOS built-in `say` for local fallback speech
|
|
156
|
+
|
|
157
|
+
### Serve mode
|
|
158
|
+
|
|
159
|
+
Serve mode gives Orb the best experience for low-latency streaming speech.
|
|
160
|
+
|
|
161
|
+
#### Install and start `tts-gateway`
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
uv tool install tts-gateway[kokoro]
|
|
165
|
+
~/.local/share/uv/tools/tts-gateway/bin/python -m spacy download en_core_web_sm
|
|
166
|
+
tts serve --provider kokoro --port 8000
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Verify the server
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
curl http://localhost:8000/health
|
|
173
|
+
curl -X POST http://localhost:8000/tts -F 'text=hello from orb' -o /tmp/orb-check.wav
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Then run Orb with defaults:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
orb
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
If you use a different host or port:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
orb --tts-server-url=http://localhost:9000
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
You can also save that value permanently with `orb setup` or `tts.server_url` in `~/.orb/config.toml`.
|
|
189
|
+
|
|
190
|
+
#### Voice notes
|
|
191
|
+
|
|
192
|
+
Orb exposes three portable voice presets: `alba`, `marius`, and `jean`.
|
|
193
|
+
|
|
194
|
+
Some `tts-gateway` providers use different internal voice names. Orb already retries once without an explicit voice if the gateway rejects a preset, so a working server default will still speak.
|
|
195
|
+
|
|
196
|
+
### Generate mode
|
|
197
|
+
|
|
198
|
+
On macOS, generate mode works out of the box with the built-in `say` command:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
orb --tts-mode=generate
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
If you want advanced voices, non-macOS support, or streaming playback while the model is still responding, use serve mode with `tts-gateway` instead.
|
|
205
|
+
|
|
206
|
+
### Disable TTS
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
orb --no-tts
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Provider Setup
|
|
213
|
+
|
|
214
|
+
Orb supports two LLM providers: **Anthropic (Claude)** and **OpenAI**.
|
|
215
|
+
|
|
216
|
+
### Anthropic (default)
|
|
217
|
+
|
|
218
|
+
Anthropic uses the Claude Agent SDK. Orb can reuse a local Claude Code / Max-authenticated session when available, or fall back to `ANTHROPIC_API_KEY` / `CLAUDE_API_KEY`.
|
|
219
|
+
|
|
220
|
+
#### Quick start
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Uses Anthropic by default when available
|
|
224
|
+
orb
|
|
225
|
+
|
|
226
|
+
# Explicitly specify Anthropic
|
|
227
|
+
orb --provider=anthropic
|
|
228
|
+
|
|
229
|
+
# Use model aliases
|
|
230
|
+
orb --model=haiku
|
|
231
|
+
orb --model=sonnet
|
|
232
|
+
orb --model=opus
|
|
233
|
+
|
|
234
|
+
# Or use a full model ID
|
|
235
|
+
orb --model=claude-haiku-4-5-20251001
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Available models
|
|
239
|
+
|
|
240
|
+
- `claude-haiku-4-5-20251001` (default, alias: `haiku`)
|
|
241
|
+
- `claude-sonnet-4-6` (alias: `sonnet`)
|
|
242
|
+
- `claude-opus-4-6` (alias: `opus`)
|
|
243
|
+
|
|
244
|
+
If you are not already signed in through Claude Code / Max, set `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` before starting Orb.
|
|
245
|
+
|
|
246
|
+
For setup details, see the [Claude Agent SDK quickstart](https://platform.claude.com/docs/en/agent-sdk/quickstart) and the [Claude models overview](https://platform.claude.com/docs/en/about-claude/models/overview).
|
|
247
|
+
|
|
248
|
+
### OpenAI
|
|
249
|
+
|
|
250
|
+
OpenAI support uses the official OpenAI Responses API and requires `OPENAI_API_KEY`.
|
|
251
|
+
|
|
252
|
+
#### Quick start
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
export OPENAI_API_KEY=sk-...
|
|
256
|
+
|
|
257
|
+
orb --provider=openai
|
|
258
|
+
orb --provider=openai --model=gpt-5.4
|
|
259
|
+
orb --model=openai:gpt-5.4
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Common models
|
|
263
|
+
|
|
264
|
+
- `gpt-5.4` (default for OpenAI)
|
|
265
|
+
- `gpt-5`
|
|
266
|
+
- `gpt-4o`
|
|
267
|
+
- `gpt-5.4-mini`
|
|
268
|
+
|
|
269
|
+
> Note: OpenAI runs in a sandboxed environment via `bash-tool`. File edits happen in a sandbox overlay and are not applied directly to your working tree. Orb will describe changes it made so you can apply them yourself.
|
|
270
|
+
|
|
271
|
+
## Global Config
|
|
272
|
+
|
|
273
|
+
Persistent defaults live in `~/.orb/config.toml`. CLI flags override config values for one-off runs.
|
|
274
|
+
|
|
275
|
+
The easiest way to create the file is:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
orb setup
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
A typical config looks like:
|
|
282
|
+
|
|
283
|
+
```toml
|
|
284
|
+
provider = "anthropic"
|
|
285
|
+
model = "claude-haiku-4-5-20251001"
|
|
286
|
+
skip_intro = false
|
|
287
|
+
|
|
288
|
+
[tts]
|
|
289
|
+
enabled = true
|
|
290
|
+
streaming = true
|
|
291
|
+
mode = "serve"
|
|
292
|
+
server_url = "http://localhost:8000"
|
|
293
|
+
voice = "alba"
|
|
294
|
+
speed = 1.5
|
|
295
|
+
buffer_sentences = 1
|
|
296
|
+
clause_boundaries = false
|
|
297
|
+
min_chunk_length = 15
|
|
298
|
+
max_wait_ms = 150
|
|
299
|
+
grace_window_ms = 50
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Config-only advanced tuning keys live under `[tts]`:
|
|
303
|
+
|
|
304
|
+
- `buffer_sentences`
|
|
305
|
+
- `clause_boundaries`
|
|
306
|
+
- `min_chunk_length`
|
|
307
|
+
- `max_wait_ms`
|
|
308
|
+
- `grace_window_ms`
|
|
309
|
+
|
|
310
|
+
Sessions are stored under `~/.orb/sessions/` (one per project).
|
|
311
|
+
|
|
312
|
+
## Customizing Prompts
|
|
313
|
+
|
|
314
|
+
Orb’s built-in instructions live in the root-level `prompts/` directory:
|
|
315
|
+
|
|
316
|
+
- `prompts/base.md` for shared behavior
|
|
317
|
+
- `prompts/anthropic.md` for Anthropic-specific system instructions
|
|
318
|
+
- `prompts/openai.md` for OpenAI-specific tool and sandbox instructions
|
|
319
|
+
- `prompts/voice.md` for voice-mode guidance added when TTS is enabled
|
|
320
|
+
|
|
321
|
+
Prompt files are read fresh for each run, so edits apply to the next question without rebuilding the app.
|
|
322
|
+
|
|
323
|
+
## Requirements
|
|
324
|
+
|
|
325
|
+
- **Runtime**: Bun >= 1.1
|
|
326
|
+
- **LLM provider**: Anthropic or OpenAI authentication
|
|
327
|
+
- **TTS** (optional): `tts-gateway` for serve mode, or macOS `say` and `afplay` for generate mode
|
|
328
|
+
|
|
329
|
+
## Development
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
git clone https://github.com/andypai/orb.git
|
|
333
|
+
cd orb
|
|
334
|
+
bun install
|
|
335
|
+
|
|
336
|
+
# Run in development
|
|
337
|
+
bun run dev
|
|
338
|
+
|
|
339
|
+
# Run with OpenAI
|
|
340
|
+
bun run dev --provider=openai --model=gpt-5.4
|
|
341
|
+
|
|
342
|
+
# Checks
|
|
343
|
+
bun run check
|
|
344
|
+
bun run test
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
MIT
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="512" height="512" rx="120" fill="#111827"/>
|
|
3
|
+
<rect x="48" y="48" width="416" height="416" rx="96" fill="url(#bgGlow)"/>
|
|
4
|
+
<g opacity="0.28" filter="url(#blur)">
|
|
5
|
+
<circle cx="256" cy="256" r="130" fill="#67E8F9"/>
|
|
6
|
+
</g>
|
|
7
|
+
<g stroke="#67E8F9" stroke-width="10" stroke-linecap="round">
|
|
8
|
+
<path d="M126 158H180"/>
|
|
9
|
+
<path d="M332 158H386"/>
|
|
10
|
+
<path d="M104 194H162"/>
|
|
11
|
+
<path d="M350 194H408"/>
|
|
12
|
+
<path d="M92 230H150"/>
|
|
13
|
+
<path d="M362 230H420"/>
|
|
14
|
+
<path d="M86 266H144"/>
|
|
15
|
+
<path d="M368 266H426"/>
|
|
16
|
+
<path d="M92 302H150"/>
|
|
17
|
+
<path d="M362 302H420"/>
|
|
18
|
+
<path d="M104 338H162"/>
|
|
19
|
+
<path d="M350 338H408"/>
|
|
20
|
+
<path d="M126 374H180"/>
|
|
21
|
+
<path d="M332 374H386"/>
|
|
22
|
+
</g>
|
|
23
|
+
<g stroke="#67E8F9" stroke-width="8" stroke-linecap="round">
|
|
24
|
+
<path d="M164 144H348"/>
|
|
25
|
+
<path d="M142 180H370"/>
|
|
26
|
+
<path d="M126 216H386"/>
|
|
27
|
+
<path d="M118 252H394"/>
|
|
28
|
+
<path d="M126 288H386"/>
|
|
29
|
+
<path d="M142 324H370"/>
|
|
30
|
+
<path d="M164 360H348"/>
|
|
31
|
+
</g>
|
|
32
|
+
<g fill="#67E8F9">
|
|
33
|
+
<rect x="214" y="139" width="12" height="26" rx="6"/>
|
|
34
|
+
<rect x="286" y="139" width="12" height="26" rx="6"/>
|
|
35
|
+
<rect x="192" y="175" width="12" height="26" rx="6"/>
|
|
36
|
+
<rect x="214" y="175" width="12" height="26" rx="6"/>
|
|
37
|
+
<rect x="236" y="175" width="12" height="26" rx="6"/>
|
|
38
|
+
<rect x="264" y="175" width="12" height="26" rx="6"/>
|
|
39
|
+
<rect x="286" y="175" width="12" height="26" rx="6"/>
|
|
40
|
+
<rect x="308" y="175" width="12" height="26" rx="6"/>
|
|
41
|
+
<rect x="176" y="211" width="12" height="26" rx="6"/>
|
|
42
|
+
<rect x="200" y="211" width="12" height="26" rx="6"/>
|
|
43
|
+
<rect x="224" y="211" width="12" height="26" rx="6"/>
|
|
44
|
+
<rect x="248" y="211" width="12" height="26" rx="6"/>
|
|
45
|
+
<rect x="272" y="211" width="12" height="26" rx="6"/>
|
|
46
|
+
<rect x="296" y="211" width="12" height="26" rx="6"/>
|
|
47
|
+
<rect x="320" y="211" width="12" height="26" rx="6"/>
|
|
48
|
+
<rect x="188" y="247" width="12" height="26" rx="6"/>
|
|
49
|
+
<rect x="212" y="247" width="12" height="26" rx="6"/>
|
|
50
|
+
<rect x="300" y="247" width="12" height="26" rx="6"/>
|
|
51
|
+
<rect x="324" y="247" width="12" height="26" rx="6"/>
|
|
52
|
+
<rect x="202" y="283" width="12" height="26" rx="6"/>
|
|
53
|
+
<rect x="226" y="283" width="12" height="26" rx="6"/>
|
|
54
|
+
<rect x="250" y="283" width="12" height="26" rx="6"/>
|
|
55
|
+
<rect x="274" y="283" width="12" height="26" rx="6"/>
|
|
56
|
+
<rect x="298" y="283" width="12" height="26" rx="6"/>
|
|
57
|
+
<rect x="214" y="319" width="12" height="26" rx="6"/>
|
|
58
|
+
<rect x="286" y="319" width="12" height="26" rx="6"/>
|
|
59
|
+
</g>
|
|
60
|
+
<g fill="#9CA3AF" opacity="0.9">
|
|
61
|
+
<circle cx="248" cy="256" r="8"/>
|
|
62
|
+
<circle cx="264" cy="256" r="8"/>
|
|
63
|
+
</g>
|
|
64
|
+
<defs>
|
|
65
|
+
<filter id="blur" x="62" y="62" width="388" height="388" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
66
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
67
|
+
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
68
|
+
<feGaussianBlur stdDeviation="32" result="effect1_foregroundBlur"/>
|
|
69
|
+
</filter>
|
|
70
|
+
<radialGradient id="bgGlow" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(256 256) rotate(90) scale(208)">
|
|
71
|
+
<stop stop-color="#172554"/>
|
|
72
|
+
<stop offset="1" stop-color="#111827"/>
|
|
73
|
+
</radialGradient>
|
|
74
|
+
</defs>
|
|
75
|
+
</svg>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<svg width="1440" height="940" viewBox="0 0 1440 940" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="1440" height="940" fill="#0B1220"/>
|
|
3
|
+
<g filter="url(#shadow)">
|
|
4
|
+
<rect x="70" y="64" width="1300" height="812" rx="26" fill="#111827"/>
|
|
5
|
+
<rect x="70.5" y="64.5" width="1299" height="811" rx="25.5" stroke="#1F2937"/>
|
|
6
|
+
</g>
|
|
7
|
+
<rect x="70" y="64" width="1300" height="54" rx="26" fill="#162033"/>
|
|
8
|
+
<rect x="70" y="92" width="1300" height="26" fill="#162033"/>
|
|
9
|
+
<circle cx="112" cy="92" r="8" fill="#F87171"/>
|
|
10
|
+
<circle cx="140" cy="92" r="8" fill="#FBBF24"/>
|
|
11
|
+
<circle cx="168" cy="92" r="8" fill="#34D399"/>
|
|
12
|
+
<text x="214" y="100" fill="#E5E7EB" font-size="22" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace">orb main → orb --new</text>
|
|
13
|
+
|
|
14
|
+
<g font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" font-size="18">
|
|
15
|
+
<text x="94" y="156" fill="#60A5FA">you:</text>
|
|
16
|
+
<text x="150" y="156" fill="#E5E7EB">what project are we working on?</text>
|
|
17
|
+
|
|
18
|
+
<text x="94" y="192" fill="#A3E635">claude:</text>
|
|
19
|
+
<text x="184" y="192" fill="#9CA3AF">We're working on the "orb" project, located at /Users/andypai/Projects/orb.</text>
|
|
20
|
+
<text x="184" y="220" fill="#9CA3AF">Would you like me to explore the codebase and give you a better overview?</text>
|
|
21
|
+
|
|
22
|
+
<text x="94" y="286" fill="#60A5FA">you:</text>
|
|
23
|
+
<text x="150" y="286" fill="#E5E7EB">yes, explore and give a summary of the architecture</text>
|
|
24
|
+
|
|
25
|
+
<text x="140" y="332" fill="#22D3EE">✓ Agent</text>
|
|
26
|
+
<text x="224" y="332" fill="#9CA3AF">Explore orb project architecture</text>
|
|
27
|
+
|
|
28
|
+
<text x="140" y="360" fill="#34D399">✓ Read</text>
|
|
29
|
+
<text x="214" y="360" fill="#9CA3AF">/Users/andypai/Projects/orb/package.json</text>
|
|
30
|
+
|
|
31
|
+
<text x="140" y="388" fill="#34D399">✓ Read</text>
|
|
32
|
+
<text x="214" y="388" fill="#9CA3AF">/Users/andypai/Projects/orb/README.md</text>
|
|
33
|
+
|
|
34
|
+
<text x="140" y="416" fill="#34D399">✓ Bash</text>
|
|
35
|
+
<text x="214" y="416" fill="#9CA3AF">find /Users/andypai/Projects/orb/src ...</text>
|
|
36
|
+
|
|
37
|
+
<text x="140" y="444" fill="#34D399">✓ Bash</text>
|
|
38
|
+
<text x="214" y="444" fill="#9CA3AF">ls -la /Users/andypai/Projects/orb/src</text>
|
|
39
|
+
|
|
40
|
+
<text x="140" y="472" fill="#34D399">✓ Read</text>
|
|
41
|
+
<text x="214" y="472" fill="#9CA3AF">/Users/andypai/Projects/orb/src/index.ts</text>
|
|
42
|
+
|
|
43
|
+
<text x="94" y="538" fill="#A3E635">claude:</text>
|
|
44
|
+
<text x="184" y="538" fill="#D1D5DB">Orb is a voice-driven AI terminal assistant for your codebase. It uses Bun,</text>
|
|
45
|
+
<text x="184" y="566" fill="#D1D5DB">Ink, and a frame-based pipeline that routes prompts through Anthropic or</text>
|
|
46
|
+
<text x="184" y="594" fill="#D1D5DB">OpenAI, then optionally through streaming text-to-speech.</text>
|
|
47
|
+
|
|
48
|
+
<text x="184" y="638" fill="#9CA3AF">The main runtime path is:</text>
|
|
49
|
+
<text x="184" y="674" fill="#67E8F9">src/index.ts → src/ui/App.tsx → src/pipeline/** → adapters/transports</text>
|
|
50
|
+
|
|
51
|
+
<text x="184" y="724" fill="#D1D5DB">Results stream back into the terminal UI in real time, with tool activity,</text>
|
|
52
|
+
<text x="184" y="752" fill="#D1D5DB">session persistence, and optional spoken playback as the answer arrives.</text>
|
|
53
|
+
</g>
|
|
54
|
+
|
|
55
|
+
<rect x="94" y="800" width="382" height="34" rx="17" fill="#162033"/>
|
|
56
|
+
<circle cx="116" cy="817" r="6" fill="#67E8F9"/>
|
|
57
|
+
<text x="134" y="824" fill="#E5E7EB" font-size="18" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace">ask a question about your codebase…</text>
|
|
58
|
+
|
|
59
|
+
<text x="1330" y="824" text-anchor="end" fill="#9CA3AF" font-size="18" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace">sonnet 4.6 • alba • x1.5</text>
|
|
60
|
+
|
|
61
|
+
<defs>
|
|
62
|
+
<filter id="shadow" x="22" y="30" width="1396" height="908" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
63
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
64
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
65
|
+
<feOffset dy="14"/>
|
|
66
|
+
<feGaussianBlur stdDeviation="24"/>
|
|
67
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0.0156863 0 0 0 0 0.0235294 0 0 0 0 0.0588235 0 0 0 0.45 0"/>
|
|
68
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
|
69
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
|
70
|
+
</filter>
|
|
71
|
+
</defs>
|
|
72
|
+
</svg>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<svg width="1328" height="392" viewBox="0 0 1328 392" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="24" y="16" width="1280" height="360" rx="48" fill="#111827"/>
|
|
3
|
+
<rect x="52" y="44" width="1224" height="304" rx="36" fill="#131D2B" stroke="#1F2937" stroke-width="2"/>
|
|
4
|
+
<g transform="translate(118 64)">
|
|
5
|
+
<rect width="264" height="264" rx="64" fill="url(#logoBg)"/>
|
|
6
|
+
<g opacity="0.32" filter="url(#logoBlur)">
|
|
7
|
+
<circle cx="132" cy="132" r="78" fill="#67E8F9"/>
|
|
8
|
+
</g>
|
|
9
|
+
<g stroke="#67E8F9" stroke-width="6" stroke-linecap="round">
|
|
10
|
+
<path d="M42 64H78"/>
|
|
11
|
+
<path d="M186 64H222"/>
|
|
12
|
+
<path d="M28 92H68"/>
|
|
13
|
+
<path d="M196 92H236"/>
|
|
14
|
+
<path d="M20 120H60"/>
|
|
15
|
+
<path d="M204 120H244"/>
|
|
16
|
+
<path d="M18 148H58"/>
|
|
17
|
+
<path d="M206 148H246"/>
|
|
18
|
+
<path d="M20 176H60"/>
|
|
19
|
+
<path d="M204 176H244"/>
|
|
20
|
+
<path d="M28 204H68"/>
|
|
21
|
+
<path d="M196 204H236"/>
|
|
22
|
+
<path d="M42 232H78"/>
|
|
23
|
+
<path d="M186 232H222"/>
|
|
24
|
+
</g>
|
|
25
|
+
<g stroke="#67E8F9" stroke-width="5" stroke-linecap="round">
|
|
26
|
+
<path d="M70 54H194"/>
|
|
27
|
+
<path d="M54 82H210"/>
|
|
28
|
+
<path d="M42 110H222"/>
|
|
29
|
+
<path d="M36 138H228"/>
|
|
30
|
+
<path d="M42 166H222"/>
|
|
31
|
+
<path d="M54 194H210"/>
|
|
32
|
+
<path d="M70 222H194"/>
|
|
33
|
+
</g>
|
|
34
|
+
<g fill="#67E8F9">
|
|
35
|
+
<rect x="100" y="51" width="8" height="18" rx="4"/>
|
|
36
|
+
<rect x="156" y="51" width="8" height="18" rx="4"/>
|
|
37
|
+
<rect x="84" y="79" width="8" height="18" rx="4"/>
|
|
38
|
+
<rect x="100" y="79" width="8" height="18" rx="4"/>
|
|
39
|
+
<rect x="116" y="79" width="8" height="18" rx="4"/>
|
|
40
|
+
<rect x="140" y="79" width="8" height="18" rx="4"/>
|
|
41
|
+
<rect x="156" y="79" width="8" height="18" rx="4"/>
|
|
42
|
+
<rect x="172" y="79" width="8" height="18" rx="4"/>
|
|
43
|
+
<rect x="72" y="107" width="8" height="18" rx="4"/>
|
|
44
|
+
<rect x="88" y="107" width="8" height="18" rx="4"/>
|
|
45
|
+
<rect x="104" y="107" width="8" height="18" rx="4"/>
|
|
46
|
+
<rect x="120" y="107" width="8" height="18" rx="4"/>
|
|
47
|
+
<rect x="136" y="107" width="8" height="18" rx="4"/>
|
|
48
|
+
<rect x="152" y="107" width="8" height="18" rx="4"/>
|
|
49
|
+
<rect x="168" y="107" width="8" height="18" rx="4"/>
|
|
50
|
+
<rect x="82" y="135" width="8" height="18" rx="4"/>
|
|
51
|
+
<rect x="98" y="135" width="8" height="18" rx="4"/>
|
|
52
|
+
<rect x="158" y="135" width="8" height="18" rx="4"/>
|
|
53
|
+
<rect x="174" y="135" width="8" height="18" rx="4"/>
|
|
54
|
+
<rect x="92" y="163" width="8" height="18" rx="4"/>
|
|
55
|
+
<rect x="108" y="163" width="8" height="18" rx="4"/>
|
|
56
|
+
<rect x="124" y="163" width="8" height="18" rx="4"/>
|
|
57
|
+
<rect x="140" y="163" width="8" height="18" rx="4"/>
|
|
58
|
+
<rect x="156" y="163" width="8" height="18" rx="4"/>
|
|
59
|
+
<rect x="100" y="191" width="8" height="18" rx="4"/>
|
|
60
|
+
<rect x="156" y="191" width="8" height="18" rx="4"/>
|
|
61
|
+
</g>
|
|
62
|
+
</g>
|
|
63
|
+
<text x="462" y="170" fill="#E5E7EB" font-size="120" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" letter-spacing="20">orb</text>
|
|
64
|
+
<text x="468" y="222" fill="#67E8F9" opacity="0.9" font-size="28" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace" letter-spacing="6">VOICE-DRIVEN CODE EXPLORER</text>
|
|
65
|
+
<text x="468" y="268" fill="#9CA3AF" font-size="24" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace">Anthropic or OpenAI • live tools • streaming speech</text>
|
|
66
|
+
<defs>
|
|
67
|
+
<filter id="logoBlur" x="22" y="22" width="220" height="220" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
68
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
69
|
+
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
70
|
+
<feGaussianBlur stdDeviation="18" result="effect1_foregroundBlur"/>
|
|
71
|
+
</filter>
|
|
72
|
+
<radialGradient id="logoBg" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(132 132) rotate(90) scale(132)">
|
|
73
|
+
<stop stop-color="#172554"/>
|
|
74
|
+
<stop offset="1" stop-color="#111827"/>
|
|
75
|
+
</radialGradient>
|
|
76
|
+
</defs>
|
|
77
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@andypai/orb",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Voice-driven code explorer for your terminal",
|
|
5
|
+
"homepage": "https://github.com/andypai/orb#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/andypai/orb/issues"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"bin": {
|
|
11
|
+
"orb": "./src/cli.ts"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"assets/**/*",
|
|
15
|
+
"prompts/**/*.md",
|
|
16
|
+
"src/**/*.ts",
|
|
17
|
+
"src/**/*.tsx",
|
|
18
|
+
"!src/**/*.test.ts",
|
|
19
|
+
"!src/**/*.test.tsx",
|
|
20
|
+
"!src/**/*.spec.ts",
|
|
21
|
+
"!src/**/*.spec.tsx",
|
|
22
|
+
"!src/**/__tests__/**",
|
|
23
|
+
"!src/**/__snapshots__/**"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"bun": ">=1.1.0"
|
|
27
|
+
},
|
|
28
|
+
"packageManager": "bun@1.3.3",
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/andypai/orb.git"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"ai",
|
|
38
|
+
"voice",
|
|
39
|
+
"tts",
|
|
40
|
+
"code-explorer",
|
|
41
|
+
"cli",
|
|
42
|
+
"terminal",
|
|
43
|
+
"openai",
|
|
44
|
+
"anthropic"
|
|
45
|
+
],
|
|
46
|
+
"author": "Andy Pai",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"scripts": {
|
|
49
|
+
"dev": "bun --watch src/cli.ts",
|
|
50
|
+
"start": "bun src/cli.ts",
|
|
51
|
+
"format": "bunx prettier --write .",
|
|
52
|
+
"check": "bunx prettier --check . && bun run test",
|
|
53
|
+
"test": "bun test"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@clack/prompts": "^1.0.1",
|
|
57
|
+
"@ai-sdk/openai": "3.0.47",
|
|
58
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.80",
|
|
59
|
+
"@inkjs/ui": "2.0.0",
|
|
60
|
+
"@iarna/toml": "^2.2.5",
|
|
61
|
+
"ai": "6.0.134",
|
|
62
|
+
"bash-tool": "^1.3.9",
|
|
63
|
+
"commander": "^14.0.3",
|
|
64
|
+
"ink": "6.6.0",
|
|
65
|
+
"just-bash": "^2.7.0",
|
|
66
|
+
"react": "19.2.3",
|
|
67
|
+
"zod": "4.1.8"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/bun": "^1.1.22",
|
|
71
|
+
"@types/react": "19.2.9",
|
|
72
|
+
"ink-testing-library": "4.0.0",
|
|
73
|
+
"prettier": "^3.7.4",
|
|
74
|
+
"typescript": "^5.7.2"
|
|
75
|
+
}
|
|
76
|
+
}
|