@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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -0
  3. package/assets/orb-logo.svg +75 -0
  4. package/assets/orb-terminal-session.svg +72 -0
  5. package/assets/orb-wordmark.svg +77 -0
  6. package/package.json +76 -0
  7. package/prompts/anthropic.md +2 -0
  8. package/prompts/base.md +1 -0
  9. package/prompts/openai.md +7 -0
  10. package/prompts/voice.md +12 -0
  11. package/src/cli.ts +9 -0
  12. package/src/config.ts +270 -0
  13. package/src/index.ts +82 -0
  14. package/src/pipeline/adapters/anthropic.ts +111 -0
  15. package/src/pipeline/adapters/openai.ts +202 -0
  16. package/src/pipeline/adapters/types.ts +16 -0
  17. package/src/pipeline/adapters/utils.ts +131 -0
  18. package/src/pipeline/frames.ts +113 -0
  19. package/src/pipeline/observer.ts +36 -0
  20. package/src/pipeline/observers/metrics.ts +95 -0
  21. package/src/pipeline/pipeline.ts +43 -0
  22. package/src/pipeline/processor.ts +57 -0
  23. package/src/pipeline/processors/agent.ts +38 -0
  24. package/src/pipeline/processors/tts.ts +120 -0
  25. package/src/pipeline/task.ts +239 -0
  26. package/src/pipeline/transports/terminal-text.ts +24 -0
  27. package/src/pipeline/transports/types.ts +33 -0
  28. package/src/services/auth-utils.ts +149 -0
  29. package/src/services/global-config.ts +363 -0
  30. package/src/services/openai-auth.ts +18 -0
  31. package/src/services/prompts.ts +76 -0
  32. package/src/services/provider-defaults.ts +97 -0
  33. package/src/services/session.ts +204 -0
  34. package/src/services/streaming-tts.ts +483 -0
  35. package/src/services/tts.ts +309 -0
  36. package/src/setup.ts +234 -0
  37. package/src/types/index.ts +108 -0
  38. package/src/ui/App.tsx +142 -0
  39. package/src/ui/components/ActivityTimeline.tsx +60 -0
  40. package/src/ui/components/AsciiOrb.tsx +92 -0
  41. package/src/ui/components/ConversationRail.tsx +44 -0
  42. package/src/ui/components/Footer.tsx +61 -0
  43. package/src/ui/components/InputPrompt.tsx +88 -0
  44. package/src/ui/components/MicroOrb.tsx +25 -0
  45. package/src/ui/components/TTSErrorBanner.tsx +36 -0
  46. package/src/ui/components/TurnRow.tsx +71 -0
  47. package/src/ui/components/WelcomeSplash.tsx +78 -0
  48. package/src/ui/hooks/useAnimationFrame.ts +33 -0
  49. package/src/ui/hooks/useConversation.ts +195 -0
  50. package/src/ui/hooks/useKeyboardShortcuts.ts +57 -0
  51. package/src/ui/hooks/usePipeline.ts +83 -0
  52. package/src/ui/hooks/useTerminalSize.ts +37 -0
  53. package/src/ui/utils/markdown.ts +89 -0
  54. package/src/ui/utils/model-label.ts +20 -0
  55. package/src/ui/utils/text.ts +18 -0
  56. 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
+ }