agentman

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 6, 2026 License: MIT

README

agentman (am)

Go Single binary

A tiny, self-hosted ticketing board designed for AI agents — a dead-simple "GitHub Projects." Agents pick up tasks, claim them, comment, and change status through a terse, token-cheap CLI; you watch progress live in a web dashboard. One Go binary, one SQLite file, localhost-only, no dependencies to install.

agents ──(am claim 13)──┐
                        ├──► HTTP+JSON API (127.0.0.1:8787) ──► SQLite (WAL)
you (browser) ◄──SSE────┘        sole writer · broadcasts every change live

Why

  • Built for agents, not humans first. Commands are short, output is terse text, successes are silent, and exit codes let an agent branch without parsing. A full pick-up→done cycle is ~65–75 tokens.
  • Real-time. Every change streams to the dashboard over SSE — no refresh.
  • Zero ops. A single static binary (pure-Go SQLite, no cgo), localhost, no auth, no database server. Back up = copy one file (or am db export for a consistent snapshot).
  • Multi-project & multi-agent. Group tasks into projects; atomic task claims so two agents never grab the same ticket.
  • Polished dashboard. A responsive kanban board with drag-and-drop status changes, a collapsible/resizable live activity feed, and keyboard shortcuts.

Install

With Go 1.25+ installed (older Go works too — the toolchain auto-upgrades):

go install github.com/RamiAltai/agentman/cmd/am@latest

This installs the am command to $(go env GOPATH)/bin (usually ~/go/bin). Make sure that's on your PATH:

export PATH="$PATH:$(go env GOPATH)/bin"   # add to your shell profile
am version
Build from source
git clone https://github.com/RamiAltai/agentman
cd agentman
go build -o am ./cmd/am
./am version

Quickstart

am serve            # starts the dashboard at http://127.0.0.1:8787 (db: ~/.agentman/agentman.db)

Open http://127.0.0.1:8787, click to create a project, then drive it from another terminal (or let your agents do it):

am init bugfix              # set this session's identity → e.g. bugfix_060626_4821
am project new web "Web"    # create a project
id=$(am new "fix login" -p web)   # create a task, get its id
am claim "$id"             # take it (atomic; exit 4 if already taken)
am note "$id" "on it"      # comment
am status "$id" done       # todo | doing | blocked | done

Everything you do on the dashboard flows through the same API the agents use, so human and agent actions both show up live.

Dashboard

The embedded web UI (no build step, no npm) is a live kanban board:

  • Columns — Todo / In Progress / Blocked / Done, with per-project tabs and counts. Click multiple project tabs to filter across several at once; All clears the filter.
  • Drag a card between columns to change its status; click a card to open a wide, resizable ticket with description, comments, and full history.
  • Activity feed you can collapse or drag-resize (it becomes an overlay drawer on small screens); task #refs in the feed are clickable.
  • Responsive from desktop down to mobile — columns stack and the panel overlays.
  • Keyboard: n new task · a toggle the activity panel · Enter/Space open a focused card · [ / ] move a focused card between statuses · Esc close a dialog.

Using it from agents (Claude Code & others)

Any agent that can run shell commands can use am. For Claude Code, the one-time setup (global memory file + permission allowlist) is in docs/agent-integration.md. The short version — drop this into your ~/.claude/CLAUDE.md (or a project CLAUDE.md):

## Task board (am) — run `am init <tasktype>` once, then:
am ls --status todo   # work to pick up        am ls --mine    # my tasks
am claim <id>         # take it (exit 4 = already claimed)
am show <id> -c       # detail + comments       am note <id> "msg"
am status <id> done   # todo|doing|blocked|done  am new "title" -p <proj>
am projects --all     # list projects (incl. archived)
am project archive <slug>   # hide a project    am project unarchive <slug>
Output is terse text (add --json to parse). Silence = success.

Other frameworks: call the HTTP API directly, or shell out to am.

Identity

Agents need an identity to claim/own tasks. Because agent runtimes spawn a fresh shell per command (so export doesn't persist), am init writes a per-directory identity that the CLI reads automatically:

am init refactor     # → refactor_060626_3391, remembered for this working directory
am whoami            # show current identity

Format: {tasktype}_{DDMMYY}_{4 digits} — human-readable and unique. Setting the AGENTMAN_AGENT env var overrides it (useful for several agents in one directory).

CLI reference

Command What it does
am ls [--mine] [--status S] [-p P] [--all] list tasks (current project, hides done)
am show <id> [-c] task detail; comments with -c
am new "title" [--body B] [-p P] [--priority N] create a task; prints the new id
am claim <id> atomic: assign me + → doing
am status <id> <todo|doing|blocked|done> change status
am assign <id> <agent|me|-> reassign (- = unassign)
am note <id> "text" add a comment (alias: comment)
am edit <id> [--title T] [--body B] [--priority N] edit fields
am drop <id> release: unassign + → todo
am projects [--all] · am project new <slug> [name] list (--all includes archived) / create projects
am project archive <slug> · am project unarchive <slug> soft-archive (hide) / restore a project
am init <tasktype> · am whoami identity
am serve [--port 8787] [--db PATH] run the dashboard + API
am db export [path] [--db PATH] write a consistent DB snapshot (prints the path)
am db import <path> [--db PATH] [--yes] restore a snapshot (stop am serve first; backs up current DB)
am version · am update [version] print version · reinstall the latest (or a given) version

<id> accepts a global id (13) or a project ref (web-3). --status accepts a comma list. Priority is 0 urgent … 3 low (default 2). Add --json to any read to parse. Exit codes: 0 ok · 3 not found · 4 already claimed · 5 invalid · 6 server down.

HTTP API

The CLI is a thin client over this (also what the dashboard uses). X-Agent header sets the actor.

GET   /api/projects                          GET   /api/tasks/{id}
POST  /api/projects {slug,name}              PATCH /api/tasks/{id} {status?,assignee?,title?,body?,priority?}
GET   /api/tasks?project=&status=&assignee=  POST  /api/tasks/{id}/claim
POST  /api/tasks {project,title,...}         POST  /api/tasks/{id}/comments {body}
GET   /api/events?since=  (poll)             GET   /api/stream  (SSE)
curl -s 127.0.0.1:8787/api/tasks?project=web
curl -s -H 'X-Agent: claude-1' -X POST 127.0.0.1:8787/api/tasks/13/claim

Configuration

AGENTMAN_URL server the CLI talks to (default http://127.0.0.1:8787)
AGENTMAN_PROJECT default project for am ls / am new
AGENTMAN_AGENT identity override (else am init file)
AGENTMAN_PORT / --port server port (default 8787)
AGENTMAN_DB / --db database path (default ~/.agentman/agentman.db)
AGENTMAN_NO_UPDATE_CHECK set to 1 to disable the startup "update available" check

Backups

The whole board is one SQLite file, so backing up is copying it. For a guaranteed-consistent snapshot (even while am serve is running), use am db export:

am db export                     # writes a timestamped snapshot in the cwd, prints the path
am db export /backups/board.db   # or pick the path
am db import /backups/board.db   # restore — stop `am serve` first; backs up the current DB

am db import validates the snapshot, refuses to run while a server is up, and backs up your existing DB before swapping it in. Both commands operate directly on the SQLite file.

Updating

On any machine where am is installed:

am update            # reinstalls the latest release (runs `go install …@latest` for you)
# or directly:  go install github.com/RamiAltai/agentman/cmd/am@latest

Then restart any running am serve — the dashboard is embedded in the binary, so a running server keeps serving the old UI until you restart it (hard-refresh the browser tab too). am serve also checks on startup and logs update available — vX.Y.Z when you're behind; disable that with AGENTMAN_NO_UPDATE_CHECK=1.

Maintainers: …@latest resolves to the highest git tag, so publish each release as a semver tag — git tag v0.3.0 && git push origin v0.3.0 — or @latest won't advance past it.

How it works

  • Single writer. am serve is the only process that touches the DB (SetMaxOpenConns(1), WAL mode). Claims are atomic via one conditional UPDATE … WHERE assignee IS NULL AND status!='done' RETURNING …; the loser of a race gets 409 already_claimed.
  • Live updates. Every mutation appends to an append-only events table in the same transaction, then broadcasts over SSE after commit. That table is also the durable cursor used to replay missed events on reconnect.
  • Embedded dashboard. Plain HTML/CSS/vanilla JS, embedded in the binary via go:embed — no build step, no npm. Agent-supplied text is rendered with textContent (never innerHTML), so a malicious task title can't inject markup.

Security

am serve binds to 127.0.0.1 with no authentication — it's a personal, local board. Don't expose the port to untrusted networks. If you need remote/multi-user access, put it behind a reverse proxy with auth, or open an issue.

Development

go build -o am ./cmd/am                       # build
go vet ./... && go test ./...                 # lint + tests
am serve --db /tmp/dev.db                     # run against a throwaway db
go build -ldflags "-X main.injectedVersion=v0.3.0" -o am ./cmd/am   # version-stamped build

Layout: cmd/am/ holds the single main package — server.go (API + SSE), hub.go (broadcast), store.go + schema.sql (SQLite), client.go + cli.go (CLI), db.go (am db export/import), identity.go, version.go, update.go, and web/ (dashboard).

Contributions welcome — open an issue or PR.

License

MIT

Directories

Path Synopsis
cmd
am command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL