Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
714bdac
charm: clean slate with 016-kasmos-agent-orchestrator as sole feature
brkastner Feb 18, 2026
5fef887
Add plan for feature 016-kasmos-agent-orchestrator
brkastner Feb 18, 2026
4409783
plan(016): implementation plan for kasmos Go/bubbletea agent orchestr…
brkastner Feb 18, 2026
c45875c
tasks(016): generate 13 work packages across 3 waves
brkastner Feb 18, 2026
cb002ab
feat(016): WP01 project bootstrap + WP02 worker backend
brkastner Feb 18, 2026
2d4b1bf
feat(016): WP03 TUI foundation - layout, styles, keys, empty dashboard
brkastner Feb 18, 2026
2981d22
feat(016): WP04 worker-TUI integration - spawn, output, lifecycle
brkastner Feb 18, 2026
ef3491d
fix(016): View purity + dedup extractSessionID before WP05
brkastner Feb 18, 2026
7ddb864
feat(016): WP05 continue dialog + WP07 kill/restart + WP08 task sources
brkastner Feb 18, 2026
6c6babd
feat(016): WP06 fullscreen viewport + shutdown, WP10 setup command
brkastner Feb 18, 2026
5e5971d
feat(016): WP09 task panel + batch spawn, WP11 AI helpers
brkastner Feb 18, 2026
cc6d185
fix(016): remove View() mutations in renderFullScreen and renderTasks…
brkastner Feb 18, 2026
8ffa0dd
feat(016): WP12 daemon mode + WP13 session persistence
brkastner Feb 18, 2026
4651d64
fix(016): cleanup review items, add TUI tests, rewrite README for v2.0.0
brkastner Feb 18, 2026
8dc1e68
fix: update TUI header version to v2.0.0
brkastner Feb 18, 2026
52f925d
fix: complete help view keybindings (add HalfDown/HalfUp, trim ShortH…
brkastner Feb 18, 2026
fdcc7a5
tasks(016): WP14 new spec/plan dialog (n key) + WP15 history view (h …
brkastner Feb 18, 2026
21bcedf
fix(016): WP14 picker uses direct keys (n->s/g/r) instead of arrow nav
brkastner Feb 18, 2026
dbc9b89
tasks(016): WP16 release workflow (just release X.Y.Z)
brkastner Feb 18, 2026
bfc425c
tasks(016): WP16 updated to use goreleaser with homebrew tap
brkastner Feb 18, 2026
771a339
tasks(016): WP14 add task source autodiscovery on bare launch
brkastner Feb 18, 2026
2cc7322
feat(016): WP16 release workflow - goreleaser, ldflags version, Justf…
brkastner Feb 18, 2026
1fb6b74
release: v2.0.0
brkastner Feb 18, 2026
618af20
release: v2.0.1
brkastner Feb 18, 2026
a80f3f6
fix: pass GITHUB_TOKEN to goreleaser from GH_PAT
brkastner Feb 18, 2026
8d0a947
release: v2.0.0
brkastner Feb 18, 2026
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ HANDOFF.md
SPEC_REVIEW_PLAN.md
kasmos-collect.sh
kasmos-config.sh
/kasmos
/dist/
86 changes: 86 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
version: 2

env:
- CGO_ENABLED=0

before:
hooks:
- go mod tidy
- go test ./...

builds:
- id: kasmos
main: ./cmd/kasmos
binary: kasmos
flags:
- -trimpath
ldflags:
- -s -w
- -X main.version={{.Version}}
goos:
- linux
- darwin
goarch:
- amd64
- arm64
ignore:
- goos: linux
goarch: arm64

archives:
- id: default
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
formats:
- tar.gz
files:
- LICENSE*
- README.md

checksum:
name_template: "checksums.txt"
algorithm: sha256

changelog:
sort: asc
use: github
groups:
- title: Features
regexp: '^.*feat[\w)]*:.*$'
order: 0
- title: Bug Fixes
regexp: '^.*fix[\w)]*:.*$'
order: 1
- title: Tasks
regexp: '^.*tasks[\w)]*:.*$'
order: 2
- title: Others
order: 999
filters:
exclude:
- "^docs:"
- "^test:"
- "Merge pull request"

release:
github:
owner: kastheco
name: kasmos
draft: false
prerelease: auto
name_template: "kasmos v{{.Version}}"

homebrew_casks:
- repository:
owner: kastheco
name: homebrew-tap
token: "{{ .Env.GH_PAT }}"
directory: Casks
homepage: "https://github.com/kastheco/kasmos"
description: "TUI agent orchestrator for concurrent OpenCode sessions"
license: "MIT"
hooks:
post:
install: |
if OS.mac?
system_command "/usr/bin/xattr", args: ["-dr", "com.apple.quarantine", "#{staged_path}/kasmos"]
end
249 changes: 123 additions & 126 deletions .kittify/memory/architecture.md

Large diffs are not rendered by default.

47 changes: 29 additions & 18 deletions .kittify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,57 @@
# kasmos Constitution

> Auto-generated by spec-kitty constitution command
> Created: 2026-02-10
> Version: 1.0.0
> Updated: 2026-02-17
> Version: 2.0.0

## Purpose

This constitution captures the technical standards and governance rules for kasmos,
a Zellij-based agent orchestrator for managing concurrent AI coding sessions.
a TUI-based agent orchestrator for managing concurrent AI coding sessions.
All features and pull requests should align with these principles.

## Technical Standards

### Languages and Frameworks

- **Rust** (latest stable, 2024 edition)
- **tokio** for async runtime
- **ratatui** for terminal UI
- **Zellij** as the terminal multiplexer substrate
- **just** command runner for task automation
- **OpenCode** as the primary AI coding agent (optionally **Claude Code**)
- **Go** (1.23+)
- **bubbletea** v2 for TUI (Elm architecture: Model/Update/View)
- **lipgloss** v2 for terminal styling
- **bubbles** for TUI components (table, viewport, textinput, list, spinner, help)
- **huh** for form dialogs
- **cobra** for CLI command structure
- **OpenCode** as the sole AI agent harness (`opencode run` for headless workers)

### Testing Requirements

- Use `cargo test` for all testing
- Use `go test ./...` for all testing
- All features must have corresponding tests
- Standard library `testing` package; table-driven tests for parsers and state machines
- Mock `WorkerBackend` for TUI tests (no real subprocess spawning in unit tests)
- Integration tests gated behind `KASMOS_INTEGRATION=1` env var
- No hard coverage target, but untested features are not considered complete
- Unit tests for core logic, integration tests where feasible

### Performance and Scale

- TUI must remain responsive at all times — never block the render loop
- Support orchestrating many concurrent agent panes without degradation
- Async operations must not starve the event loop
- Minimize unnecessary allocations in hot paths
- TUI must remain responsive at all times - never block the Update loop
- Support orchestrating many concurrent workers without degradation
- Worker output reading must be async (goroutines + channels, surfaced as tea.Msg)
- Minimize unnecessary allocations in hot paths (output buffer ring, not unbounded slices)

### Architecture Principles

- **No manager AI agent** - the TUI is the orchestrator. Zero token cost for orchestration.
- **Workers are headless subprocesses** - spawned via `opencode run`, output captured via Go pipes.
- **Session continuation over interactivity** - `opencode run --continue -s <id>` preserves context without PTY allocation.
- **Pluggable WorkerBackend interface** - SubprocessBackend (MVP), TmuxBackend (future).
- **Three task source adapters** - spec-kitty (plan.md/WP frontmatter), GSD (checkbox markdown), ad-hoc (manual prompts).
- **Daemon mode** - same Model/Update loop, no View rendering (`WithoutRenderer()`).

### Deployment and Constraints

- **Linux**: Primary platform (full support)
- **macOS**: Secondary platform (best-effort support)
- **Runtime dependencies**: Zellij and OpenCode must be installed and in PATH
- Distributed as a single binary (standard `cargo install` workflow)
- **Runtime dependencies**: OpenCode and git must be installed and in PATH
- Distributed as a single binary (standard `go install` or goreleaser workflow)

## Governance

Expand Down
64 changes: 28 additions & 36 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,53 @@
- Read `README.md` for project overview.
- Read `.kittify/memory/` for project constitution, architecture knowledge, and workflow intelligence.
- Check `kitty-specs/` for feature specifications.
- This is a Rust workspace -- crates live in `crates/`.
- Primary binary: `crates/kasmos/` -- the Zellij orchestrator.
- This is a Go module. Source lives at the repository root.
- Primary binary: `cmd/kasmos/` - the TUI agent orchestrator.

## Repository layout
- `crates/kasmos/`: Main orchestrator binary
- `cmd/kasmos/`: Entry point (main.go)
- `internal/tui/`: bubbletea TUI (model, update, view, styles, keys)
- `internal/worker/`: Worker backend interface, subprocess backend, output buffer
- `internal/task/`: Task source adapters (spec-kitty, GSD, ad-hoc)
- `internal/persist/`: Session persistence (JSON)
- `internal/setup/`: `kasmos setup` subcommand (agent scaffolding, dep validation)
- `kitty-specs/`: Feature specifications (spec-kitty)
- `design-artifacts/`: TUI visual design (mockups, layout, styles, keybinds)
- `.kittify/memory/`: Persistent project memory (constitution, architecture, workflow learnings)
- `.kittify/`: spec-kitty project configuration, scripts, missions
- `docs/`: Documentation

## Build / run commands
- Build: `cargo build`
- Run: `cargo run -p kasmos`
- Test: `cargo test`

## Code style (Rust)
- Use Rust 2024 edition conventions
- Prefer explicit error handling with `thiserror` / `anyhow`
- Use `tokio` for async runtime
- Follow standard Rust naming: `snake_case` functions, `PascalCase` types
- Keep modules small and focused
- Build: `go build ./cmd/kasmos`
- Run: `go run ./cmd/kasmos`
- Test: `go test ./...`
- Test (integration): `KASMOS_INTEGRATION=1 go test ./...`
- Lint: `golangci-lint run`

## Code style (Go)
- Follow standard Go conventions (gofmt, go vet)
- Use `internal/` for non-exported packages
- Prefer explicit error handling with `fmt.Errorf` wrapping
- Use table-driven tests
- Follow standard Go naming: camelCase unexported, PascalCase exported
- Keep packages small and focused

## External tools
- `zellij`: Terminal multiplexer (must be in PATH)
- `opencode`: AI coding agent harness (workers spawned via `opencode run`)
- `spec-kitty`: Feature specification tool
- `opencode`: AI coding agent harness (launched in Zellij panes)
- `git`: Version control

## Agent harness: OpenCode only

kasmos uses **OpenCode** as the sole agent harness for spawning worker agents. This is a hard rule:

- Worker panes are launched via `opencode [-p <profile>] -- --agent <role> --prompt <prompt>`.
- The `opencode_binary` and `opencode_profile` are configured in `kasmos.toml` under `[agent]`.
- **Never invoke a model-specific CLI** (e.g., `claude`, `gemini`, `aider`) directly. OpenCode is the abstraction layer -- it handles model selection, permissions, and session management.
- kasmos is **model-agnostic**. The model running behind OpenCode is configured in OpenCode's own config, not in kasmos. Do not assume or hardcode any specific model provider.
- When spawning workers programmatically, always go through kasmos MCP tools (`spawn_worker`) or `opencode`. Never shell out to a bare model CLI.
- If you are the manager agent and need to delegate work to a new pane, use `kasmos serve`'s `spawn_worker` MCP tool, which handles the OpenCode invocation internally.

## Worktree awareness

kasmos uses git worktrees at `.worktrees/<feature_slug>-<wp_id>/` for WP isolation. When modifying code that deals with file paths -- especially task file watching, file scanning, or agent CWD setup -- always consider whether the path should point to the main repo or the worktree. See `.kittify/memory/architecture.md` for the full explanation and known issues.

Key rule: agents work in worktrees, so any file they modify is the worktree copy. Watchers/detectors that need to see agent changes must watch the worktree path, not the main repo path.

## Zellij constraints

- There is no `list-panes` or `focus-pane-by-name` CLI command (as of Zellij 0.41+).
- Inside a Zellij session, use `zellij action <cmd>` directly (no `--session` flag).
- Pane tracking is internal via `SessionManager` HashMap -- do not assume Zellij provides pane discovery.
- See `.kittify/memory/architecture.md` for session layout and pane naming conventions.
- Workers are spawned via `opencode run --agent <role> "prompt"`.
- **Never invoke a model-specific CLI** (e.g., `claude`, `gemini`, `aider`) directly. OpenCode is the abstraction layer.
- kasmos is **model-agnostic**. The model running behind OpenCode is configured in OpenCode's own config, not in kasmos.
- Session continuation uses `opencode run --continue -s <session_id> "follow-up"`.

## Persistent memory

When you discover something significant about the codebase architecture, runtime behavior, or integration quirks, record it in `.kittify/memory/`. This directory is symlinked into worktrees so all sessions share it.
When you discover something significant about the codebase architecture, runtime behavior, or integration quirks, record it in `.kittify/memory/`.

- `constitution.md`: Project technical standards and governance (do not modify without discussion).
- `architecture.md`: Codebase structure, type locations, subsystem interactions, known issues.
Expand Down
97 changes: 58 additions & 39 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,51 +1,70 @@
set shell := ["bash", "-cu"]
set dotenv-load := true

# Spec Kitty manual swarm lifecycle
# Usage: just swarm <prefix> [flags...]
# just swarm 001 # start next wave
# just swarm 003 --status # show board + waves
# just swarm 001 --cleanup # start with orphan cleanup
# just swarm 001 --review WP02
# just swarm 001 --done WP01
# just swarm 001 --reject WP02 --feedback /tmp/fb.md

# just swarm 001 --dry-run
swarm +ARGS:
@scripts/sk-start.sh {{ ARGS }}

# Install kasmos binary to ~/.cargo/bin
# Build kasmos binary
build:
go build ./cmd/kasmos

# Install to GOPATH/bin
install:
cargo install --path crates/kasmos
go install ./cmd/kasmos

# Build
build:
cargo build
# Run tests
test:
go test ./...

# Run (pass-through args)
run +ARGS:
cargo run -p kasmos -- {{ ARGS }}
# Run linter
lint:
go vet ./...

# Launch orchestration by feature path or prefix (e.g. 001)
launch feature mode="continuous":
cargo run -p kasmos -- launch {{ feature }} --mode {{ mode }}
# Run kasmos (pass-through args)
run *ARGS:
go run ./cmd/kasmos {{ARGS}}

# Show orchestration status (current dir if feature omitted)
status feature="":
if [ -n "{{ feature }}" ]; then cargo run -p kasmos -- status {{ feature }}; else cargo run -p kasmos -- status; fi
# Dry-run release (no publish)
release-dry v:
#!/usr/bin/env bash
set -euo pipefail
echo "==> Dry run for kasmos v{{v}}"
goreleaser release --snapshot --clean
echo "==> Artifacts in dist/"

# Attach to running orchestration by feature path or prefix (e.g. 001)
attach feature:
cargo run -p kasmos -- attach {{ feature }}
# Full release: just release 2.0.1
release v:
#!/usr/bin/env bash
set -euo pipefail

# Stop orchestration (current dir if feature omitted)
stop feature="":
if [ -n "{{ feature }}" ]; then cargo run -p kasmos -- stop {{ feature }}; else cargo run -p kasmos -- stop; fi
VERSION="{{v}}"
TAG="v${VERSION}"

# Test
test:
cargo test
echo "==> Releasing kasmos ${TAG}"

# Lint
lint:
cargo clippy --all-targets --all-features -- -D warnings
# 1. Ensure clean working tree
if [[ -n "$(git status --porcelain)" ]]; then
echo "ERROR: working tree is dirty, commit or stash first"
exit 1
fi

BRANCH=$(git branch --show-current)
echo " branch: ${BRANCH}"

# 2. Update version in source
sed -i "s/var version = \".*\"/var version = \"${VERSION}\"/" cmd/kasmos/main.go
if [[ -n "$(git status --porcelain)" ]]; then
git add cmd/kasmos/main.go
git commit -m "release: v${VERSION}"
echo " committed version bump"
fi

# 3. Tag
git tag -a "${TAG}" -m "kasmos ${TAG}"
echo " tagged ${TAG}"

# 4. Push commit + tag
git push origin "${BRANCH}"
git push origin "${TAG}"
echo " pushed to origin"

# 5. Goreleaser builds, creates GH release, pushes homebrew formula
GITHUB_TOKEN="${GH_PAT}" goreleaser release --clean
echo "==> Done: https://github.com/kastheco/kasmos/releases/tag/${TAG}"
Loading