Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
41e4f6a
feat: launch tasks
nocksock Dec 14, 2025
276eaa9
feat(launchers): configure defaults if none present
nocksock Dec 14, 2025
13b4c1f
feat(launchers): make `l` work in the list view
nocksock Dec 14, 2025
fa0c72b
feat(launch): use ! to launch.
nocksock Dec 14, 2025
b149029
feat(launch): use exec instead of command + multiline support
nocksock Dec 14, 2025
1f4600c
docs(launch): update readme multiline examples
nocksock Dec 14, 2025
3b239e0
docs: simplify tmux/kitty example
nocksock Dec 15, 2025
bcb8685
feat(launch): add support for multi launchers
nocksock Dec 15, 2025
08e678e
Merge remote-tracking branch 'upstream/main' into feat/multi-launchers
nocksock Dec 15, 2025
9353fe7
fix(launcher): use stdin instead of temp files and capture stderr
nocksock Dec 15, 2025
f85ceef
docs: update environment variables documentation
nocksock Dec 15, 2025
6626d08
chore: add example launchers configuration
nocksock Dec 15, 2025
7aadf04
fix!: consolidate command creation and add BEANS_DIR to single-bean l…
nocksock Dec 15, 2025
eaa3418
test: add regression tests for launch progress view (beans-b1u8)
nocksock Dec 15, 2025
f1d47fe
fix: remove misplaced key handler that was dismissing launch progress…
nocksock Dec 15, 2025
b02771c
refactor: remove unused launcher discovery functions
nocksock Dec 15, 2025
14186ef
refactor: replace custom stripAnsi with stdlib ansi.Strip
nocksock Dec 15, 2025
c8f84e7
test: add comprehensive launcher config validation tests
nocksock Dec 15, 2025
9be0161
feat!: unify single and multi-bean launch paths
nocksock Dec 15, 2025
960e719
docs: add design for simplified LaunchManager query API
nocksock Dec 15, 2025
c376135
feat: simplify LaunchManager query API with GetSummary()
nocksock Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .beans.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,41 @@ beans:
id_length: 4
default_status: todo
default_type: task

launchers:
- name: opencode
exec: opencode -p "Work on task $BEANS_ID"
description: "Open task in OpenCode"
- name: claude
exec: claude "Work on task $BEANS_ID"
description: "Open task in Claude Code"
- name: crush
exec: crush run "Work on task $BEANS_ID"
description: "Open task in Crush"
- name: worktree-kitty
multiple: true
description: "Create git worktree and open in new kitty window"
exec: |
#!/usr/bin/env bash
set -euo pipefail

WORKTREE_DIR=".worktrees/$BEANS_ID"

# Create worktree if it doesn't exist
if [ ! -d "$WORKTREE_DIR" ]; then
# Clean up any stale worktree registrations
git worktree prune

# Check if branch already exists
if git show-ref --verify --quiet "refs/heads/task/$BEANS_ID"; then
# Branch exists, check it out in the worktree
git worktree add "$WORKTREE_DIR" "task/$BEANS_ID"
else
# Create new branch
git worktree add "$WORKTREE_DIR" -b "task/$BEANS_ID"
fi
fi

# Open in new kitty window
kitty @ launch --type=window --cwd="$BEANS_ROOT/$WORKTREE_DIR" \
opencode -p "Work on task $BEANS_ID"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
# Added by goreleaser init:
dist/
/.docs.local
.beans/.worktrees
1 change: 1 addition & 0 deletions AGENTS.md
204 changes: 204 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,210 @@ You can also specifically ask it to start working on a particular bean:

> "It's time to tackle myproj-123."

## Launchers

You can configure external tools to launch from the TUI. Press `!` when viewing or selecting a bean to open the launcher picker.

**First-time setup:** If no launchers are configured, you'll be prompted to select from default options (opencode, claude, crush). Only installed tools will be pre-selected. This provides a quick start with sensible defaults.

Configure launchers in `.beans.yml`:

```yaml
launchers:
# Simple single-line launcher
- name: opencode
exec: opencode -p "Work on task $BEANS_ID"
description: "Open task in OpenCode"

# Git worktree + tmux launcher
- name: worktree-tmux
description: "Create git worktree and open in new tmux pane"
exec: |
#!/bin/bash
set -euo pipefail

WORKTREE_DIR=".worktrees/$BEANS_ID"

# Create worktree if it doesn't exist
if [ ! -d "$WORKTREE_DIR" ]; then
git worktree add "$WORKTREE_DIR" -b "task/$BEANS_ID"
fi

# Open in new tmux pane
tmux split-window -h -c "$BEANS_ROOT/$WORKTREE_DIR"
tmux send-keys "opencode -p 'Work on task $BEANS_ID'" Enter

# Kitty terminal window launcher
- name: worktree-kitty
description: "Create git worktree and open in new kitty window"
exec: |
#!/bin/bash
set -euo pipefail

WORKTREE_DIR=".worktrees/$BEANS_ID"

# Create worktree if it doesn't exist
if [ ! -d "$WORKTREE_DIR" ]; then
git worktree add "$WORKTREE_DIR" -b "task/$BEANS_ID"
fi

# Open in new kitty window
kitty @ launch --type=window --cwd="$BEANS_ROOT/$WORKTREE_DIR" \
opencode -p "Work on task $BEANS_ID"
```

### Multi-Bean Launchers

Some launchers can handle multiple beans in parallel, while others can only work with one bean at a time. Mark launchers that support parallel execution with `multiple: true`:

```yaml
launchers:
# Single-bean only (default)
- name: opencode
exec: opencode -p "Work on task $BEANS_ID"
description: "Open task in OpenCode"
# multiple: false (default)

# Can handle multiple beans in parallel
- name: worktree-tmux
multiple: true # ← Supports multi-bean launching
description: "Create git worktree and open in new tmux pane"
exec: |
#!/bin/bash
set -euo pipefail

WORKTREE_DIR=".worktrees/$BEANS_ID"

if [ ! -d "$WORKTREE_DIR" ]; then
git worktree add "$WORKTREE_DIR" -b "task/$BEANS_ID"
fi

tmux split-window -h -c "$BEANS_ROOT/$WORKTREE_DIR"
tmux send-keys "opencode -p 'Work on task $BEANS_ID'" Enter
```

**When to use `multiple: true`:**
- Launchers that create separate workspaces (worktrees, tmux panes, kitty windows)
- Scripts that can safely run in parallel without conflicts
- Tools that operate on isolated resources per bean

**When to keep default `multiple: false`:**
- Interactive tools that can only open one file/project at a time (editors, IDEs)
- Tools that modify shared state
- Single-instance applications

**Behavior:**
- **Single bean selected** → All launchers shown
- **Multiple beans selected** → Only `multiple: true` launchers shown
- **No `multiple: true` launchers available** → Error message displayed

### How It Works

- **Single-line exec**: Runs via `sh -c`, just like a shell command. Use for simple commands.
- **Multi-line exec**: Passed to the interpreter via stdin. **Must start with a shebang** (`#!/bin/bash`, `#!/usr/bin/env python3`, etc.). The shebang determines which interpreter executes your script.
- **Environment variables**: All launchers receive `$BEANS_ROOT`, `$BEANS_DIR`, `$BEANS_ID`, `$BEANS_TASK`
- **Working directory**: Set to project root (`$BEANS_ROOT`)
- **Unix/Linux/macOS only**: Shebang mechanism is Unix-specific

### Multi-Select Launching

In the TUI, you can launch for multiple beans simultaneously using launchers marked with `multiple: true`:

1. **Select multiple beans** using `x` (mark/unmark) or `X` (mark all visible)
2. **Press `!`** to open the launcher picker (only shows `multiple: true` launchers)
3. **Choose a launcher** - it will run in parallel for all selected beans

**Features:**
- **Parallel execution**: All launchers start simultaneously (perfect for creating multiple tmux panes or worktrees)
- **Real-time progress**: See status for each bean as it runs
- **Stop on failure**: If any bean fails, all others are immediately stopped
- **Confirmation prompt**: For 5+ beans, you'll be asked to confirm (can be disabled in config)
- **Selection management**: Selection is cleared on success, kept on failure (so you can retry)

**Use cases:**
- Create git worktrees for multiple tasks at once
- Open multiple beans in separate tmux panes/kitty windows
- Batch process related beans

### TUI Configuration

You can customize TUI behavior in `.beans.yml`:

```yaml
tui:
# Disable confirmation prompt when launching for 5+ beans
disable_launcher_warning: false
```

### Examples

```yaml
# Simple tool invocation
- name: cursor
exec: cursor "$BEANS_TASK"

# Shell command with pipes
- name: show-bean
exec: cat "$BEANS_TASK" | less

# Multi-step bash script
- name: test-and-open
exec: |
#!/bin/bash
set -e
cd "$BEANS_ROOT"
npm test -- "$BEANS_ID" || true
code "$BEANS_TASK"

# Ruby script
- name: ruby-tool
exec: |
#!/usr/bin/env ruby
bean_id = ENV['BEANS_ID']
puts "Processing #{bean_id}"
```

### Environment Variables

Launchers receive these environment variables:

- `BEANS_ROOT`: Project root directory (parent of `.beans/`, your working directory)
- `BEANS_DIR`: Beans directory (e.g., `/path/to/project/.beans`)
- `BEANS_ID`: Bean ID (e.g., `beans-abc123`)
- `BEANS_TASK`: Full path to bean file (e.g., `/path/to/project/.beans/beans-abc123.md`)

### CLI Usage

Launch beans from the command line:

```bash
# List all configured launchers with availability status
beans launch -l

# Example output:
# NAME AVAILABLE DESCRIPTION
# opencode ✓ Open task in OpenCode
# worktree-tmux ✓ Create git worktree and open in new tmux pane
# test-echo ✓ Simple test launcher

# Launch a specific launcher for a bean
beans launch opencode beans-abc123 # Full ID
beans launch opencode beans-abc # Partial ID (if unique)

# Launch worktree launchers
beans launch worktree-tmux beans-def456
beans launch worktree-kitty beans-ghi789

# JSON output for scripting
beans launch -l --json
```

**CLI launcher features:**
- Supports partial bean ID matching (like other commands)
- Executes launchers interactively (you see output in your terminal)
- Shows availability status with `-l` (✓ if command/interpreter found, ✗ if not)
- Returns non-zero exit code on failure

## Contributing

This project currently does not accept contributions -- it's just way too early for that!
Expand Down
Loading