Command coding agents on your terms.

View on desktop to download

Free and open source. No account, no sign-in, no telemetry.

HO
horizon~/Code/horizon
To Do3
Wire payment retries to dunning queue
Add CSV export to invoices table
Bump deps for security advisory
In Progress4
Polish invitation email
└─Tightened subject and brand tokens
Rework onboarding flow
├─Editing onboarding stepper...
└─live dev server
Refine CTA button hover states
Audit accessibility on settings dialog
└─Investigating contrast at SettingsD…
In Review2
Speed up search index build
#486
Refactor billing webhook router
#482
Done2
Restore login redirect after timeout
#479
Add per-row selection to invoices

Plan at scale

Agent assisted

Agents know how to use Ouijit out of the box.

claudeouijit task create
>break the API hardening work into tasks on the board
Rate limiting first — it blocks the other two. Creating it.
Bash(ouijit task create "Add rate-limit headers to the public API" --prompt "429 + Retry-After on every public route")
{"success": true, "task": {"taskNumber": 119}}

Pull from GitHub

Turn any open issue into a task on the board with one click.

Issues
Open
Support SSO re-auth prompt2 days agojkataja#491Create taskT-121To Do
Export audit log as CSV4 days agomara-oduya#488

On the fly

⌘N opens the composer from anywhere in the app.

New taskTo Do
Fix flaky signup e2eTask name
The signup e2e fails about one run in five. Find out why.Describe the task, or write the prompt to start from…
escDraft is keptDiscardCreate task⌘↵
To Do1
Bump deps for security advisory
Add rate-limit headers to the public API
Support SSO re-auth prompt
Fix flaky signup e2e

Build in parallel

In Progress4
Bump deps for security advisory
└─Setting up workspace
Add rate-limit headers to the public API
└─Setting up workspace
Support SSO re-auth prompt
└─Setting up workspace
Fix flaky signup e2e
└─Setting up workspace

Keep work isolated

Starting a task cuts it a git worktree and a branch, keeping work safe and moving forward.

Reuse workflows with hooks

Run custom scripts and agent prompts automatically as a task changes status.

Run agents full auto

Use a sandbox to skip permission checks with peace of mind.

Review in depth

Analysis850 commits · 318 files · last 12 months
Rising · 259 of 850 commits in the last 3 months
Sep 2025Aug 2026

Rising · 20 of 68 commits in the last 3 months

612
lines
3,410
lines changed

Ownership

prentice61%mara-oduya24%jkataja10%others
Change frequencytop 2%

68 commits in 12 months

Nestingtop 6%

nests 7 deep, 2.4 on average

Moves with dunningQueue.ts 78% of the time
  • Large and still changing · worth splitting
  • Nests deeply · worth flattening the worst path
  • Usually changes with dunningQueue.ts · worth checking the seam
Open in editor
Analysis850 commits · 318 files
Rework onboarding flowdone · in review
rework-onboarding
Done — stepper shell, saved progress, and WelcomeIntro retired.
Bash(ouijit task set-status 101 in_review)
#101 in_progress → in_review
Type a follow-up…
⏵⏵ auto mode on· Opus 5 · ⏎ to send · ↓ to manage
main3 files +130 -78
src/onboarding/Stepper.tsxmodifiedhotspot+92 -14
@@ -1,8 +1,12 @@Stepper container
3+import { useOnboardingProgress } from './useOnboardingProgress';
4-export function Stepper() {
5+export function Stepper({ accountId }: { accountId: string }) {
5- const [step, setStep] = useState(0);
6+ const { step, setStep } = useOnboardingProgress(accountId);
67 const total = 3;
78
89 return (
src/onboarding/useOnboardingProgress.tsadded+38
1+import { useEffect, useState } from 'react';
2+import { readPreference, writePreference } from '../account/preferences';
3+
4+export function useOnboardingProgress(accountId: string) {
5+ const key = `onboarding:${accountId}`;
6+ const stored = readPreference(key);
7+ const [step, setStep] = useState(stored.step);
8+
9+ useEffect(() => writePreference(key, { step }), [key, step]);
10+ return { step, setStep };
Needs your review
Speed up search index build2 hours agomara-oduyaspeed-search-index3 unsentT-99+182 -54
Authored
Refactor billing webhook router5 hours agoprenticebilling-webhook-routerT-98+214 -96
Everything else
Add rate limiting to the public API30 minutes agojkatajaapi-rate-limits+96 -8
Speed up search index build
3 unsentReviewMerge
All files0/3
src/search
indexBuilder.ts+120 -30
legacyIndex.ts-18
tokenizer.ts+62 -6
src/search/indexBuilder.tsmodified+120 -30
@@ -18,9 +18,14 @@buildIndex
4+import { tokenize } from './tokenizer';
18-export function buildIndex(files: string[]) {
19+export async function buildIndex(files: string[], signal: AbortSignal) {
19- const index = new Map<string, number[]>();
20+ const index = new SearchIndex();
21+ for (const batch of chunk(files, 250)) {
22+ await idle(signal);
2023
src/search/legacyIndex.tsdeleted-18
@@ -1,18 +0,0 @@buildOnOpen
1-import { readFileSync } from 'node:fs';
2-
3-export function buildOnOpen(paths: string[]) {
4- return paths.map((path) => readFileSync(path, "utf8"));
5-}
src/search/tokenizer.tsmodified+62 -6
@@ -4,4 +4,8 @@tokenize
6+export function tokenize(text: string): string[] {
7+ return text.split(WORD).filter(Boolean);
8+}
69

Power tools included

Find anything with ⌘K

Terminals, projects, tasks, and pull requests, ranked by how often you come back to them.

Agents, sandboxed

A Lima VM mounts only the task's worktree — or sandbox in place with Seatbelt and Landlock, via nono.

Jump anywhere from the keyboard
The commands you always run

Saved with the project, run in any task's worktree.

Start, continue, review, done

Each runs the command you give it, task context included.

Drive the app with the CLI

The ouijit CLI is on the PATH in every terminal the app opens, sandboxed ones included. Tasks, tags, hooks, scripts, drafts, themes: everything on this page, as commands with JSON out.

Every color, down to the ANSI palette
Tag a terminal, filter the stack
Reopen where you left off

Terminals come back in their worktrees, panels included.

Supported harnesses

To request support for another harness, open an issue.

Start commanding.

View on desktop to download
Read the docs