@automagik/genie 0.260201.2240
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/.github/workflows/publish.yml +26 -0
- package/.worktrees/.metadata.json +3 -0
- package/README.md +532 -0
- package/bun.lock +101 -0
- package/dist/claudio.js +76 -0
- package/dist/genie.js +201 -0
- package/dist/term.js +136 -0
- package/install.sh +351 -0
- package/package.json +37 -0
- package/scripts/version.ts +48 -0
- package/src/claudio.ts +128 -0
- package/src/commands/launch.ts +245 -0
- package/src/commands/models.ts +43 -0
- package/src/commands/profiles.ts +95 -0
- package/src/commands/setup.ts +5 -0
- package/src/genie-commands/hooks.ts +317 -0
- package/src/genie-commands/install.ts +351 -0
- package/src/genie-commands/setup.ts +282 -0
- package/src/genie-commands/shortcuts.ts +62 -0
- package/src/genie-commands/update.ts +228 -0
- package/src/genie.ts +106 -0
- package/src/lib/api-client.ts +109 -0
- package/src/lib/claude-settings.ts +252 -0
- package/src/lib/config.ts +109 -0
- package/src/lib/genie-config.ts +164 -0
- package/src/lib/hook-manager.ts +130 -0
- package/src/lib/hook-script.ts +256 -0
- package/src/lib/hooks/compose.ts +72 -0
- package/src/lib/hooks/index.ts +163 -0
- package/src/lib/hooks/presets/audited.ts +191 -0
- package/src/lib/hooks/presets/collaborative.ts +143 -0
- package/src/lib/hooks/presets/sandboxed.ts +153 -0
- package/src/lib/hooks/presets/supervised.ts +66 -0
- package/src/lib/hooks/utils/escape.ts +46 -0
- package/src/lib/log-reader.ts +213 -0
- package/src/lib/picker.ts +62 -0
- package/src/lib/session-metadata.ts +58 -0
- package/src/lib/system-detect.ts +185 -0
- package/src/lib/tmux.ts +410 -0
- package/src/lib/version.ts +15 -0
- package/src/lib/wizard.ts +104 -0
- package/src/lib/worktree.ts +362 -0
- package/src/term-commands/attach.ts +23 -0
- package/src/term-commands/exec.ts +34 -0
- package/src/term-commands/hook.ts +42 -0
- package/src/term-commands/ls.ts +33 -0
- package/src/term-commands/new.ts +73 -0
- package/src/term-commands/pane.ts +81 -0
- package/src/term-commands/read.ts +70 -0
- package/src/term-commands/rm.ts +47 -0
- package/src/term-commands/send.ts +34 -0
- package/src/term-commands/shortcuts.ts +355 -0
- package/src/term-commands/split.ts +87 -0
- package/src/term-commands/status.ts +116 -0
- package/src/term-commands/window.ts +72 -0
- package/src/term.ts +192 -0
- package/src/types/config.ts +17 -0
- package/src/types/genie-config.ts +104 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
with:
|
|
15
|
+
node-version: '20'
|
|
16
|
+
registry-url: 'https://registry.npmjs.org'
|
|
17
|
+
|
|
18
|
+
- uses: oven-sh/setup-bun@v2
|
|
19
|
+
|
|
20
|
+
- run: bun install
|
|
21
|
+
|
|
22
|
+
- run: bun run build
|
|
23
|
+
|
|
24
|
+
- run: npm publish
|
|
25
|
+
env:
|
|
26
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
# Genie CLI
|
|
2
|
+
|
|
3
|
+
Collaborative terminal toolkit for human + AI workflows.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Genie CLI provides three tools for human/AI collaboration:
|
|
8
|
+
|
|
9
|
+
- **genie** - Setup wizard, prerequisites installer, and hook management
|
|
10
|
+
- **term** - tmux orchestration for managing terminal sessions
|
|
11
|
+
- **claudio** - Claude Code launcher with custom LLM routing profiles
|
|
12
|
+
|
|
13
|
+
The core idea: **tmux is the collaboration layer**. AI agents create and manage terminal sessions; humans can attach at any time to watch, assist, or take over. Both work in the same shared workspace.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Install prerequisites (tmux, bun)
|
|
21
|
+
genie install
|
|
22
|
+
|
|
23
|
+
# 2. Configure hook presets interactively
|
|
24
|
+
genie setup
|
|
25
|
+
|
|
26
|
+
# 3. Install hooks into Claude Code
|
|
27
|
+
genie hooks install
|
|
28
|
+
|
|
29
|
+
# 4. Launch Claude Code with your router profile
|
|
30
|
+
claudio
|
|
31
|
+
|
|
32
|
+
# 5. Watch the AI work (from another terminal)
|
|
33
|
+
tmux attach -t genie
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Configuration Files
|
|
39
|
+
|
|
40
|
+
Genie uses several configuration files:
|
|
41
|
+
|
|
42
|
+
| File | Purpose |
|
|
43
|
+
|------|---------|
|
|
44
|
+
| `~/.genie/config.json` | Hook presets and session settings |
|
|
45
|
+
| `~/.claudio/config.json` | LLM routing profiles (API URL, model mappings) |
|
|
46
|
+
| `~/.claude/settings.json` | Claude Code settings (hooks registered here) |
|
|
47
|
+
| `~/.claude/hooks/genie-bash-hook.sh` | Hook script that enforces configured behaviors |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## genie Reference
|
|
52
|
+
|
|
53
|
+
### Prerequisites Check & Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
genie install # Interactive prerequisite check & install
|
|
57
|
+
genie install --check # Only check, don't offer to install
|
|
58
|
+
genie install --yes # Auto-approve all installations
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### What It Checks
|
|
62
|
+
|
|
63
|
+
| Prerequisite | Required | Installation Method |
|
|
64
|
+
|--------------|----------|---------------------|
|
|
65
|
+
| tmux | Yes | brew > apt/dnf/pacman > manual |
|
|
66
|
+
| bun | Yes | Official installer (curl) |
|
|
67
|
+
| claude | No (recommended) | npm global install |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Hook Configuration (genie setup)
|
|
72
|
+
|
|
73
|
+
Interactive wizard for configuring which hooks to enable:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
genie setup # Interactive wizard
|
|
77
|
+
genie setup --quick # Use recommended defaults (collaborative + audited)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The wizard explains each hook preset and lets you choose which to enable. Configuration is saved to `~/.genie/config.json`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### Hook Management (genie hooks)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
genie hooks show # Show current hook configuration
|
|
88
|
+
genie hooks install # Install hooks into Claude Code
|
|
89
|
+
genie hooks install --force # Overwrite existing hooks
|
|
90
|
+
genie hooks uninstall # Remove hooks from Claude Code
|
|
91
|
+
genie hooks uninstall --keep-script # Remove but keep the script file
|
|
92
|
+
genie hooks test # Test the hook script
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### How Hooks Work
|
|
96
|
+
|
|
97
|
+
1. `genie setup` saves your preferences to `~/.genie/config.json`
|
|
98
|
+
2. `genie hooks install` creates `~/.claude/hooks/genie-bash-hook.sh` and registers it in `~/.claude/settings.json`
|
|
99
|
+
3. When Claude Code runs, it invokes the hook script for relevant tool calls
|
|
100
|
+
4. The hook script enforces your configured behaviors
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### Hook Presets
|
|
105
|
+
|
|
106
|
+
#### Collaborative (Recommended)
|
|
107
|
+
|
|
108
|
+
**What:** All terminal commands run through tmux
|
|
109
|
+
**Why:** You can watch AI work in real-time
|
|
110
|
+
**How:** Bash commands are rewritten to `term exec genie:shell '<command>'`
|
|
111
|
+
|
|
112
|
+
When enabled, any Bash tool call the AI makes gets automatically proxied through your tmux session. You can attach and watch:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
tmux attach -t genie
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Configuration options:
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"hooks": {
|
|
122
|
+
"enabled": ["collaborative"],
|
|
123
|
+
"collaborative": {
|
|
124
|
+
"sessionName": "genie",
|
|
125
|
+
"windowName": "shell"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Supervised
|
|
132
|
+
|
|
133
|
+
**What:** File changes require your approval
|
|
134
|
+
**Why:** Prevents accidental overwrites
|
|
135
|
+
**How:** Write/Edit tools always ask permission
|
|
136
|
+
|
|
137
|
+
When enabled, the AI must get your explicit approval before writing or editing files. The default tools that require approval are `Write` and `Edit`.
|
|
138
|
+
|
|
139
|
+
Configuration options:
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"hooks": {
|
|
143
|
+
"enabled": ["supervised"],
|
|
144
|
+
"supervised": {
|
|
145
|
+
"alwaysAsk": ["Write", "Edit"]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Sandboxed
|
|
152
|
+
|
|
153
|
+
**What:** Restrict file access to specific directories
|
|
154
|
+
**Why:** Protects sensitive areas of your system
|
|
155
|
+
**How:** Operations outside the sandbox are blocked
|
|
156
|
+
|
|
157
|
+
When enabled, the AI can only read, write, or search files within the allowed paths. Attempts to access files outside these directories are denied.
|
|
158
|
+
|
|
159
|
+
Configuration options:
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"hooks": {
|
|
163
|
+
"enabled": ["sandboxed"],
|
|
164
|
+
"sandboxed": {
|
|
165
|
+
"allowedPaths": ["~/projects", "/tmp"]
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### Audited
|
|
172
|
+
|
|
173
|
+
**What:** Log all AI tool usage to a file
|
|
174
|
+
**Why:** Review what the AI did after a session
|
|
175
|
+
**How:** Every tool call is logged to `~/.genie/audit.log`
|
|
176
|
+
|
|
177
|
+
When enabled, all tool executions are recorded in JSONL format with timestamps, inputs, outputs, and duration.
|
|
178
|
+
|
|
179
|
+
Configuration options:
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"hooks": {
|
|
183
|
+
"enabled": ["audited"],
|
|
184
|
+
"audited": {
|
|
185
|
+
"logPath": "~/.genie/audit.log"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
#### Combining Presets
|
|
192
|
+
|
|
193
|
+
You can enable multiple presets together:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"hooks": {
|
|
198
|
+
"enabled": ["collaborative", "audited"]
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
This gives you real-time observation (collaborative) plus a complete audit trail (audited).
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## term Reference
|
|
208
|
+
|
|
209
|
+
### Command Tree
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
term
|
|
213
|
+
βββ new <name> Create session (-d workspace, -w worktree)
|
|
214
|
+
βββ ls List sessions (--json)
|
|
215
|
+
βββ attach <name> Attach interactively
|
|
216
|
+
βββ rm <name> Remove session (--keep-worktree)
|
|
217
|
+
βββ read <session> Read output (-n, --grep, --json, -f)
|
|
218
|
+
βββ exec <session> <cmd> Run command (async)
|
|
219
|
+
βββ send <session> <keys> Send keystrokes
|
|
220
|
+
βββ split <session> <h|v> Split pane (-d, -w)
|
|
221
|
+
βββ status <session> Check state (--command <id>, --json)
|
|
222
|
+
βββ window
|
|
223
|
+
β βββ new <session> <name>
|
|
224
|
+
β βββ ls <session> (--json)
|
|
225
|
+
β βββ rm <window-id>
|
|
226
|
+
βββ pane
|
|
227
|
+
β βββ ls <session> (--json)
|
|
228
|
+
β βββ rm <pane-id>
|
|
229
|
+
βββ hook
|
|
230
|
+
βββ set <event> <cmd>
|
|
231
|
+
βββ list
|
|
232
|
+
βββ rm <event>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Common Options
|
|
236
|
+
|
|
237
|
+
| Option | Description |
|
|
238
|
+
|--------|-------------|
|
|
239
|
+
| `--json` | Output as JSON (essential for agents) |
|
|
240
|
+
| `-n <lines>` | Number of lines to read |
|
|
241
|
+
| `-f` | Follow mode (live tail) |
|
|
242
|
+
| `-d <path>` | Working directory |
|
|
243
|
+
| `-w` | Create git worktree |
|
|
244
|
+
| `--grep <pattern>` | Filter output by pattern |
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## claudio Reference
|
|
249
|
+
|
|
250
|
+
### What It Does
|
|
251
|
+
|
|
252
|
+
claudio launches Claude Code with custom LLM routing profiles. It configures Claude's model mappings so requests for "opus", "sonnet", or "haiku" route to specific models via your configured router.
|
|
253
|
+
|
|
254
|
+
**Key principle**: `claude` = vanilla Anthropic, `claudio` = your custom router setup.
|
|
255
|
+
|
|
256
|
+
### Command Reference
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
claudio Launch with default profile
|
|
260
|
+
claudio <profile> Launch with named profile
|
|
261
|
+
|
|
262
|
+
claudio setup First-time setup wizard
|
|
263
|
+
claudio profiles List all profiles (* = default)
|
|
264
|
+
claudio profiles add Add new profile (interactive picker)
|
|
265
|
+
claudio profiles rm <name> Delete profile
|
|
266
|
+
claudio profiles default <name> Set default profile
|
|
267
|
+
claudio profiles show <name> Show profile details
|
|
268
|
+
|
|
269
|
+
claudio models List available models from router
|
|
270
|
+
claudio config Show current config (URL, default profile)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Hook Override Flags
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
claudio --hooks collaborative,audited # Override with specific presets
|
|
277
|
+
claudio --no-hooks # Disable all hooks for this session
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
These flags let you temporarily override your `~/.genie/config.json` settings without changing the configuration file.
|
|
281
|
+
|
|
282
|
+
### Setup Wizard
|
|
283
|
+
|
|
284
|
+
Run `claudio setup` for first-time configuration:
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
$ claudio setup
|
|
288
|
+
|
|
289
|
+
π§ Claudio Setup
|
|
290
|
+
|
|
291
|
+
? API URL: http://localhost:8317
|
|
292
|
+
? API Key: ********
|
|
293
|
+
|
|
294
|
+
Testing connection... β Connected (47 models available)
|
|
295
|
+
|
|
296
|
+
Create your first profile:
|
|
297
|
+
|
|
298
|
+
? Profile name: main
|
|
299
|
+
? Select OPUS model: gemini-2.5-pro
|
|
300
|
+
? Select SONNET model: gemini-2.5-flash
|
|
301
|
+
? Select HAIKU model: gemini-2.5-flash
|
|
302
|
+
|
|
303
|
+
β Profile "main" created and set as default
|
|
304
|
+
|
|
305
|
+
Run `claudio` to launch, or `claudio profiles add` to create more.
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Profile Management
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
# List all profiles
|
|
312
|
+
claudio profiles
|
|
313
|
+
# main *
|
|
314
|
+
# opus: gemini-2.5-pro
|
|
315
|
+
# sonnet: gemini-2.5-flash
|
|
316
|
+
# haiku: gemini-2.5-flash
|
|
317
|
+
# (* = default)
|
|
318
|
+
|
|
319
|
+
# Add a new profile
|
|
320
|
+
claudio profiles add
|
|
321
|
+
|
|
322
|
+
# Set default profile
|
|
323
|
+
claudio profiles default main
|
|
324
|
+
|
|
325
|
+
# Show profile details
|
|
326
|
+
claudio profiles show main
|
|
327
|
+
|
|
328
|
+
# Delete a profile
|
|
329
|
+
claudio profiles rm old-profile
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Configuration
|
|
333
|
+
|
|
334
|
+
Config lives in `~/.claudio/config.json`:
|
|
335
|
+
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"apiUrl": "http://localhost:8317",
|
|
339
|
+
"apiKey": "sk-...",
|
|
340
|
+
"defaultProfile": "main",
|
|
341
|
+
"profiles": {
|
|
342
|
+
"main": {
|
|
343
|
+
"opus": "gemini-2.5-pro",
|
|
344
|
+
"sonnet": "gemini-2.5-flash",
|
|
345
|
+
"haiku": "gemini-2.5-flash"
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## For Humans
|
|
354
|
+
|
|
355
|
+
### Watching Agent Work
|
|
356
|
+
|
|
357
|
+
See what sessions exist:
|
|
358
|
+
```bash
|
|
359
|
+
term ls
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Attach to watch an agent's session:
|
|
363
|
+
```bash
|
|
364
|
+
term attach genie
|
|
365
|
+
# or directly with tmux
|
|
366
|
+
tmux attach -t genie
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Read recent output without attaching:
|
|
370
|
+
```bash
|
|
371
|
+
term read genie -n 200
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Taking Control
|
|
375
|
+
|
|
376
|
+
Once attached, you're in a normal tmux session:
|
|
377
|
+
- Type commands directly
|
|
378
|
+
- Use `Ctrl+B d` to detach
|
|
379
|
+
- The agent can continue working after you detach
|
|
380
|
+
|
|
381
|
+
### Quick Reference
|
|
382
|
+
|
|
383
|
+
| Task | Command |
|
|
384
|
+
|------|---------|
|
|
385
|
+
| List sessions | `term ls` |
|
|
386
|
+
| Attach to session | `term attach <name>` |
|
|
387
|
+
| Read output | `term read <name> -n 100` |
|
|
388
|
+
| Follow live | `term read <name> -f` |
|
|
389
|
+
| Kill session | `term rm <name>` |
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## For AI Agents
|
|
394
|
+
|
|
395
|
+
### Standard Workflow
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# 1. Create a session
|
|
399
|
+
term new khal-tests -d /path/to/project
|
|
400
|
+
|
|
401
|
+
# 2. Execute commands
|
|
402
|
+
term exec khal-tests "npm test"
|
|
403
|
+
|
|
404
|
+
# 3. Read output (always use --json for parsing)
|
|
405
|
+
term read khal-tests -n 100 --json
|
|
406
|
+
|
|
407
|
+
# 4. Clean up when done
|
|
408
|
+
term rm khal-tests
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### JSON Output
|
|
412
|
+
|
|
413
|
+
Always use `--json` for reliable parsing:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
# List sessions
|
|
417
|
+
term ls --json
|
|
418
|
+
# β [{"name":"khal-tests","windows":1,"created":"2025-01-30T10:00:00Z"}]
|
|
419
|
+
|
|
420
|
+
# Read output
|
|
421
|
+
term read khal-tests --json
|
|
422
|
+
# β {"session":"khal-tests","lines":["$ npm test","PASS src/app.test.ts"]}
|
|
423
|
+
|
|
424
|
+
# Check status
|
|
425
|
+
term status khal-tests --json
|
|
426
|
+
# β {"exists":true,"windows":1,"panes":1}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Session Naming Convention
|
|
430
|
+
|
|
431
|
+
Use descriptive names: `<project>-<task>`
|
|
432
|
+
- `khal-tests` - running Khal test suite
|
|
433
|
+
- `khal-deploy` - deployment process
|
|
434
|
+
- `api-build` - building API server
|
|
435
|
+
|
|
436
|
+
### Parallel Execution
|
|
437
|
+
|
|
438
|
+
Run multiple tasks in separate windows:
|
|
439
|
+
```bash
|
|
440
|
+
term new project-work -d /path/to/project
|
|
441
|
+
term window new project-work tests
|
|
442
|
+
term window new project-work build
|
|
443
|
+
|
|
444
|
+
term exec project-work:tests "npm test"
|
|
445
|
+
term exec project-work:build "npm run build"
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Or use panes within a window:
|
|
449
|
+
```bash
|
|
450
|
+
term split project-work h # horizontal split
|
|
451
|
+
term exec project-work "npm test" # runs in active pane
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Detecting Completion
|
|
455
|
+
|
|
456
|
+
Check if a command finished:
|
|
457
|
+
```bash
|
|
458
|
+
term status my-session --json
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Look for shell prompt in output to detect completion:
|
|
462
|
+
```bash
|
|
463
|
+
term read my-session -n 10 --json
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Installation
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# 1. Check prerequisites
|
|
472
|
+
genie install
|
|
473
|
+
|
|
474
|
+
# 2. Build
|
|
475
|
+
bun install
|
|
476
|
+
bun run build
|
|
477
|
+
|
|
478
|
+
# 3. Symlink to PATH
|
|
479
|
+
ln -s $(pwd)/dist/genie.js ~/.local/bin/genie
|
|
480
|
+
ln -s $(pwd)/dist/term.js ~/.local/bin/term
|
|
481
|
+
ln -s $(pwd)/dist/claudio.js ~/.local/bin/claudio
|
|
482
|
+
|
|
483
|
+
# 4. Configure hooks
|
|
484
|
+
genie setup
|
|
485
|
+
|
|
486
|
+
# 5. Install hooks into Claude Code
|
|
487
|
+
genie hooks install
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Requirements: Bun, tmux
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## Architecture
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
498
|
+
β Claude Code β
|
|
499
|
+
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
500
|
+
β β ~/.claude/settings.json ββ
|
|
501
|
+
β β hooks: [{ matcher: "Bash", command: "genie-bash-..." }]ββ
|
|
502
|
+
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
503
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
504
|
+
β
|
|
505
|
+
βΌ PreToolUse / PostToolUse
|
|
506
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
507
|
+
β ~/.claude/hooks/genie-bash-hook.sh β
|
|
508
|
+
β β
|
|
509
|
+
β Reads: ~/.genie/config.json β
|
|
510
|
+
β Applies: collaborative, supervised, sandboxed, audited β
|
|
511
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
512
|
+
β
|
|
513
|
+
βββββββββββββββββββββΌββββββββββββββββββββ
|
|
514
|
+
βΌ βΌ βΌ
|
|
515
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
516
|
+
β Collaborative β β Audited β β Sandboxed β
|
|
517
|
+
β β β β β β
|
|
518
|
+
β Bash β term β β Log to file β β Block paths β
|
|
519
|
+
β exec session β β β β outside list β
|
|
520
|
+
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Components:**
|
|
524
|
+
|
|
525
|
+
- **Bun** - TypeScript runtime and bundler
|
|
526
|
+
- **Commander.js** - CLI framework
|
|
527
|
+
- **tmux** - Session orchestration backend
|
|
528
|
+
- **Inquirer** - Interactive prompts for setup wizard
|
|
529
|
+
|
|
530
|
+
## License
|
|
531
|
+
|
|
532
|
+
MIT
|
package/bun.lock
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "@namastexlabs/claudio",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@inquirer/prompts": "^7.0.0",
|
|
9
|
+
"commander": "^12.1.0",
|
|
10
|
+
"uuid": "^11.1.0",
|
|
11
|
+
"zod": "^3.22.4",
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "^1.1.0",
|
|
15
|
+
"@types/node": "^20.10.5",
|
|
16
|
+
"typescript": "^5.3.3",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
"packages": {
|
|
21
|
+
"@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="],
|
|
22
|
+
|
|
23
|
+
"@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="],
|
|
24
|
+
|
|
25
|
+
"@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="],
|
|
26
|
+
|
|
27
|
+
"@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="],
|
|
28
|
+
|
|
29
|
+
"@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="],
|
|
30
|
+
|
|
31
|
+
"@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="],
|
|
32
|
+
|
|
33
|
+
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="],
|
|
34
|
+
|
|
35
|
+
"@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="],
|
|
36
|
+
|
|
37
|
+
"@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="],
|
|
38
|
+
|
|
39
|
+
"@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="],
|
|
40
|
+
|
|
41
|
+
"@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="],
|
|
42
|
+
|
|
43
|
+
"@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="],
|
|
44
|
+
|
|
45
|
+
"@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="],
|
|
46
|
+
|
|
47
|
+
"@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="],
|
|
48
|
+
|
|
49
|
+
"@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="],
|
|
50
|
+
|
|
51
|
+
"@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="],
|
|
52
|
+
|
|
53
|
+
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
|
|
54
|
+
|
|
55
|
+
"@types/node": ["@types/node@20.19.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g=="],
|
|
56
|
+
|
|
57
|
+
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
58
|
+
|
|
59
|
+
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
60
|
+
|
|
61
|
+
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
|
|
62
|
+
|
|
63
|
+
"chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="],
|
|
64
|
+
|
|
65
|
+
"cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="],
|
|
66
|
+
|
|
67
|
+
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
68
|
+
|
|
69
|
+
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
70
|
+
|
|
71
|
+
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
|
72
|
+
|
|
73
|
+
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
74
|
+
|
|
75
|
+
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
|
76
|
+
|
|
77
|
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
78
|
+
|
|
79
|
+
"mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="],
|
|
80
|
+
|
|
81
|
+
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
|
82
|
+
|
|
83
|
+
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
|
84
|
+
|
|
85
|
+
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
86
|
+
|
|
87
|
+
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
88
|
+
|
|
89
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
90
|
+
|
|
91
|
+
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
|
92
|
+
|
|
93
|
+
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
|
94
|
+
|
|
95
|
+
"wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="],
|
|
96
|
+
|
|
97
|
+
"yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="],
|
|
98
|
+
|
|
99
|
+
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
|
100
|
+
}
|
|
101
|
+
}
|