Skip to main content
Guide · How-to

Install senkani

Clone the repo, build with Swift Package Manager, launch the SenkaniApp workspace, register project hooks. Three minutes end-to-end on Apple Silicon.

Prerequisites

Step 1 · Clone + build
git clone https://github.com/ckluis/senkani
cd senkani
swift build -c release

First build takes ~4 minutes. Subsequent builds are incremental.

Step 2 · Launch the workspace
.build/release/SenkaniApp

The SwiftUI workspace opens to a project-first Welcome surface. On first launch the app self-installs the hook wrapper at ~/.senkani/bin/senkani-hook and registers a single global MCP entry in ~/.claude/settings.json — gated on SENKANI_PANE_ID, so MCP only activates inside Senkani-managed terminals. Idempotent on every launch.

Step 3 · Register project hooks
cd /path/to/your/project
.build/release/senkani init

Run from each project root. Registers PreToolUse + PostToolUse hooks at <project>/.claude/settings.json so the filter pipeline runs on this project's Claude Code tool calls. Idempotent — safe to re-run. Reverse with senkani init --uninstall.

Step 4 · Verify
.build/release/senkani doctor

Should report all green: MCP server registered, hooks registered, binary path resolved, grammar versions within window. If anything is amber or red, run senkani doctor --fix.

Step 5 · Choose a project and start an agent

From the Welcome surface, click Choose project folder and pick the repo your agent will run in. The Claude / Ollama agent cards then unlock; clicking Start Claude in <project> opens a Terminal pane in that directory and launches claude. The pane shows a Senkani Active proof strip (PROJECT, MCP, HOOKS, TRACK, EVENTS) so you can confirm every component is wired up before the first command runs.

Notification permission

On first launch SenkaniApp asks macOS for permission to post local notifications (the standard system TCC prompt). Granting lets the app show a one-time banner when you cross a celebrate-moment — currently the first non-zero token-saving the optimizer reports. If you deny, every other surface still works; the in-process notification fan-out is installed regardless, the OS just silently drops the banner request. Per-sink and per-event subscriptions are configurable via ~/.senkani/notifications.json; missing file means every sink subscribes to every event (opt-out, not opt-in).

You don't need to hand-edit that JSON: the sidebar's Notifications tool view (TOOLS → Notifications) renders the same config as a per-sink × per-event matrix of checkboxes — rows for the stdout JSON-line sink and the macOS banner sink, columns for notify_done / notify_failure / schedule_end. Every flip is written to disk immediately and the live router reloads in place, so the next event honors the new matrix without restarting the app. The pane's Test buttons fire a synthetic event of each class through the live router — ticked sinks react (stdout logs a line; macOS posts a banner if authorized), unticked sinks stay silent. A ConfirmationGate deny always surfaces regardless of the matrix — that failure path is deliberately non-suppressible.

If you don't use Claude Code

senkani init is already hooks-only — it never touches MCP. The MCP entry is written by SenkaniApp on launch, but it's gated on SENKANI_PANE_ID and stays dormant unless a Claude Code session runs inside a Senkani-managed terminal. For Cursor, Copilot, or another non-MCP agent, run senkani init in each project to get the hook-driven filter pipeline + secret redaction; the MCP server entry sits idle. See Wire up Cursor / Copilot.

Next

Wire up Claude Code →