From b6c8a158af6cc4348fd0ee76c5ccb9e3b69658e2 Mon Sep 17 00:00:00 2001 From: Elias Kohout Date: Thu, 2 Apr 2026 13:38:38 +0200 Subject: [PATCH] docs: simplify README and extract full reference to USAGE.md - Condensed README to quick overview (~40 lines) with key features - Added install instructions for Alpine, Arch, source, and Docker - Created USAGE.md with full command reference, server mode, OIDC, and permission model docs - New features documented: server mode, OIDC authentication, per-node permissions, multiplatform auto-builds Co-Authored-By: Claude Haiku 4.5 --- README.md | 280 +++++++----------------------------------------------- USAGE.md | 194 +++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 247 deletions(-) create mode 100644 USAGE.md diff --git a/README.md b/README.md index 2ae224c..1035fbb 100644 --- a/README.md +++ b/README.md @@ -1,266 +1,52 @@ # Axolotl -CLI-native lightweight issue tracker for you and your agents. A SQLite-based -single portable binary, built from ~1300 lines of Go code. +CLI-native issue tracker for you and your agents. Single binary, SQLite-backed, ~1300 lines of Go. -## Features +## Install -- **Issues with dependencies** - blocks, subtask, related relations -- **Tagging system** - flexible tags with `_key::value` property pattern -- **Namespacing** - organize issues by project or team -- **Due dates** - track deadlines -- **Thread-safe** - WAL mode for concurrent access -- **Multiuser support** - @mentions and assignments, inbox per user -- **JSON output** - all commands support `--json` for agent integration -- **Alias system** - define custom command shortcuts with argument expansion -- **Single binary** - no dependencies, portable `.ax.db` file +**Alpine Linux** (apk): +Download from the Gitea package registry. Have a look +[here](https://g.eliaskohout.de/eliaskohout/-/packages/alpine/axolotl/). -## Installation +**Arch Linux** (pacman): +Download from the Gitea package registry. Have a look +[here](https://g.eliaskohout.de/eliaskohout/-/packages/arch/axolotl/). +**From source:** ```bash -go build -o ax . +go build -o ax ./src ``` +**Docker (server mode):** +```bash +docker run -v ./data:/data g.eliaskohout.de/eliaskohout/axolotl-server:latest +``` + +Packages are built automatically on every version tag for `linux/amd64` and `linux/arm64`. + ## Quick Start ```bash -# Initialize a new database -ax init . - -# Create an issue -ax add "Implement feature X" --tag backend --prio high - -# Create with relations -ax add "Fix bug in auth" --rel blocks:abc12 - -# List open issues -ax list --status open - -# Show issue details -ax show abc12 - -# Update an issue -ax update abc12 --status done - -# View your inbox -ax inbox - -# Define an alias -ax alias mywork "list --namespace myproject --status open" --desc "My project tasks" +ax init . # create .ax.db in current dir +ax add "Fix login bug" --prio high # create an issue +ax list --status open # list open issues +ax show abc12 # show issue details +ax update abc12 --status done # close issue +ax inbox # your @mention inbox ``` -## Commands +## Key Features -### `ax init [path]` +- **Graph relations** — `blocks`, `subtask`, `related`, `assignee` +- **Namespaces** — organize issues by project or team +- **Permissions** — per-node access control (`can_read`, `can_write`, `has_ownership`) +- **Aliases** — custom shortcuts with `$me`, `$1`, `$@` expansion +- **JSON output** — `--json` flag on all commands for agent integration +- **Multiuser** — `@mention` auto-creates inbox entries; `AX_USER` to switch users +- **Server mode** — HTTP JSON API with optional OIDC authentication (`ax serve` / `ax login`) +- **Portable** — single `.ax.db` file, no server required -Create a new `.ax.db` database in the specified directory (default: current). - -### `ax add [flags]` - -Create a new node. - -| Flag | Description | -|------|-------------| -| `--type` | Node type: `issue` (default), `note`, `user`, `namespace` | -| `--status` | Status: `open` (default), `done` | -| `--prio` | Priority: `high`, `medium`, `low` | -| `--namespace` | Namespace (default: current user) | -| `--tag` | Add tag (repeatable) | -| `--due` | Due date | -| `--content` | Content/body text | -| `--rel` | Add relation `type:id` (repeatable) | - -### `ax update <id> [flags]` - -Update a node. - -| Flag | Description | -|------|-------------| -| `--title` | New title | -| `--status` | New status | -| `--prio` | New priority | -| `--type` | New type | -| `--namespace` | New namespace | -| `--assignee` | New assignee | -| `--due` | New due date | -| `--clear-due` | Clear due date | -| `--content` | New content | -| `--tag` | Add tag (repeatable) | -| `--tag-remove` | Remove tag (repeatable) | -| `--rel` | Add relation `type:id` (repeatable) | -| `--rel-remove` | Remove relation `type:id` (repeatable) | - -### `ax show <id>` - -Display node details. - -### `ax list [flags]` - -Query and list nodes. - -| Flag | Description | -|------|-------------| -| `--type` | Filter by type | -| `--status` | Filter by status | -| `--prio` | Filter by priority | -| `--namespace` | Filter by namespace | -| `--tag` | Filter by tag (repeatable) | -| `--assignee` | Filter by assignee | -| `--mention` | Filter by mention | - -### `ax edit <id>` - -Open node content in `$EDITOR`. - -### `ax del <id> [-f|--force]` - -Delete a node. Prompts for confirmation unless `--force`. - -### `ax alias [name] [command] [flags]` - -Manage aliases. - -```bash -ax alias # list all aliases -ax alias mywork "list --tag work" # create alias -ax alias mywork # show alias command -ax alias mywork "list --tag work2" # update alias -ax alias del mywork # delete alias -``` - -**Default aliases:** - -| Alias | Command | Description | -|-------|---------|-------------| -| `mine` | `list --assignee $me --type issue --status open` | Show open issues assigned to you | -| `due` | `list --type issue --status open` | Show open issues | -| `inbox` | `list --mention $me` | Show your inbox | - -**Alias argument expansion:** - -| Variable | Expands to | -|----------|------------| -| `$me` | Current username | -| `$@` | All arguments | -| `$1`, `$2`, ... | Positional arguments | - -```bash -# Create alias with argument expansion -ax alias find "list --tag $1 --status $2" -ax find backend open # expands to: list --tag backend --status open -``` - -## Relations - -Relations connect nodes together: - -| Type | Meaning | Behavior | -|------|---------|----------| -| `blocks` | A blocks B — B can't close until A is done | Enforced on status=done | -| `subtask` | A is a subtask of B | | -| `related` | A is related to B | | -| `assignee` | A is assigned to user | Single-value; set via `--assignee` flag | -| `in_namespace` | A belongs to namespace | Single-value; set via `--namespace` flag | - -```bash -# Block an issue (B can't close until A is done) -ax update A --rel blocks:B - -# Assign to user -ax update abc12 --assignee alice - -# Create subtask -ax update abc12 --rel subtask:parent12 -``` - -## Tags and Properties - -Tags are flexible labels. Tags with pattern `_key::value` are properties: - -```bash -# Regular tag -ax add "Task" --tag backend - -# Property tags (set via flags) -ax add "Task" --type issue --status open --prio high -# Equivalent to: --tag _type::issue --tag _status::open --tag _prio::high -``` - -**Built-in properties:** - -| Property | Values | Required | -|----------|--------|----------| -| `_type` | `issue`, `note`, `user`, `namespace` | Yes (default: `issue`) | -| `_status` | `open`, `done` | No | -| `_prio` | `high`, `medium`, `low` | No | - -## Mentions and Inbox - -Use `@username` in title or content to automatically add to user's inbox: - -```bash -ax add "Review PR @alice" --content "@bob please check" -# Both alice and bob get this in their inbox -``` - -View inbox: -```bash -ax inbox # your inbox -AX_USER=alice ax inbox # alice's inbox -``` - -## JSON Output - -All commands support `--json` for machine-readable output: - -```bash -ax list --status open --json -ax show abc12 --json -``` - -Example output: -```json -{ - "id": "abc12", - "title": "Implement feature", - "content": "Description here", - "created_at": "2026-03-25T10:00:00Z", - "updated_at": "2026-03-25T10:00:00Z", - "tags": ["_type::issue", "_status::open", "backend"], - "relations": { - "blocks": ["def34"] - } -} -``` - -## Configuration - -`ax` stores user configuration in a JSON file. It searches for `.axconfig` in the -current directory and parent directories (like git finds `.git`), falling back to -`~/.config/ax/config.json`. - -**Config file format:** -```json -{ - "user": "alice", - "aliases": [ - {"name": "mywork", "command": "list --namespace myproject", "description": "My tasks"} - ] -} -``` - -## Database Location - -`ax` searches for `.ax.db` in the current directory and parent directories, -similar to how git finds `.git`. This allows you to run commands from any -subdirectory. - -## Environment Variables - -| Variable | Description | -|----------|-------------| -| `AX_USER` | Override current username | -| `EDITOR` | Editor for `ax edit` (default: `vi`) | +For full command reference and examples, see [USAGE.md](USAGE.md). ## License diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..b1ad238 --- /dev/null +++ b/USAGE.md @@ -0,0 +1,194 @@ +# Axolotl Usage Reference + +## Commands + +### `ax init [path]` +Create a new `.ax.db` in the specified directory (default: current). + +### `ax add <title> [flags]` +| Flag | Description | +|------|-------------| +| `--type` | `issue` (default), `note`, `user`, `namespace` | +| `--status` | `open` (default), `done` | +| `--prio` | `high`, `medium`, `low` | +| `--namespace` | Namespace (default: current user) | +| `--tag` | Add tag (repeatable) | +| `--due` | Due date | +| `--content` | Body text | +| `--rel` | Relation `type:id` (repeatable) | + +### `ax update <id> [flags]` +| Flag | Description | +|------|-------------| +| `--title` | New title | +| `--status` | New status | +| `--prio` | New priority | +| `--type` | New type | +| `--namespace` | Transfer to namespace | +| `--assignee` | Assign to user | +| `--due` / `--clear-due` | Set or clear due date | +| `--content` | New body text | +| `--tag` / `--tag-remove` | Add or remove tag | +| `--rel` / `--rel-remove` | Add or remove relation `type:id` | + +### `ax show <id>` +Display node details. + +### `ax list [flags]` +| Flag | Description | +|------|-------------| +| `--type` | Filter by type | +| `--status` | Filter by status | +| `--prio` | Filter by priority | +| `--namespace` | Filter by namespace | +| `--tag` | Filter by tag (repeatable) | +| `--assignee` | Filter by assignee | +| `--mention` | Filter by mention | + +### `ax edit <id>` +Open node content in `$EDITOR`. + +### `ax del <id> [-f]` +Delete a node. Prompts for confirmation unless `--force`. + +### `ax alias [name] [command]` +```bash +ax alias # list all aliases +ax alias mywork "list --tag work" # create/update alias +ax alias del mywork # delete alias +``` + +**Built-in aliases:** `mine`, `due`, `inbox` + +**Argument expansion:** `$me` → current user, `$@` → all args, `$1`/`$2`/… → positional + +## Relations + +| Type | Description | +|------|-------------| +| `blocks` | Prevents target from closing until this is done | +| `subtask` | Marks as subtask of target | +| `related` | General association | +| `assignee` | Assigns to a user (single-value) | + +```bash +ax update A --rel blocks:B # A blocks B +ax update abc12 --assignee alice # assign to alice +``` + +## Tags and Properties + +Tags follow the `_key::value` pattern for properties: + +| Property | Values | +|----------|--------| +| `_type` | `issue`, `note`, `user`, `namespace` | +| `_status` | `open`, `done` | +| `_prio` | `high`, `medium`, `low` | + +## Mentions and Inbox + +Use `@username` in title or content to add to a user's inbox: +```bash +ax add "Review PR @alice" # alice gets an inbox entry +ax inbox # your inbox +AX_USER=alice ax inbox # alice's inbox +``` + +## JSON Output + +All commands support `--json`: +```bash +ax list --status open --json +ax show abc12 --json +``` + +## Configuration + +`ax` searches upward from CWD for `.axconfig`, falling back to `~/.config/ax/config.json`. + +```json +{ + "user": "alice", + "aliases": [ + {"name": "mywork", "command": "list --namespace myproject", "description": "My tasks"} + ] +} +``` + +## Server Mode + +`ax` can run as a shared HTTP JSON API server: + +```bash +ax serve # starts server on configured host:port (default: 0.0.0.0:7000) +``` + +The server exposes the same operations (add, list, show, update, delete) over HTTP. Clients connect by setting `remote.host` / `remote.port` in their config — the CLI then transparently routes calls to the server instead of a local database. + +### OIDC Authentication + +The server supports OIDC for authentication. Configure in `.axconfig`: + +```json +{ + "serve": { "host": "0.0.0.0", "port": 7000 }, + "oidc": { + "issuer": "https://your-idp.example.com", + "client_id": "axolotl", + "client_secret": "secret", + "public_url": "https://ax.example.com", + "user_claim": "preferred_username" + } +} +``` + +Client login: +```bash +ax login # opens browser for OIDC flow, saves session token +``` + +Without OIDC configured, the server accepts an `X-Ax-User` header for the username (development/trusted networks only). + +### Docker + +```bash +docker run -v ./data:/data g.eliaskohout.de/eliaskohout/axolotl-server:latest +``` + +The image runs `ax serve` and exposes port 7000. Mount a volume at `/data` to persist the database. + +## Permission Model + +Every node has per-node access control. Permissions are transitive via BFS from the requesting user's own node. + +| Level | Relation | Grants | +|-------|----------|--------| +| 1 | `can_read` | Read / show / list | +| 2 | `can_create_rel` | Create relations pointing to this node | +| 3 | `can_write` | Update title, content, tags | +| 4 | `has_ownership` | Full control including delete and granting access | + +- Creators automatically get `has_ownership` on nodes they create. +- Namespace nodes own regular nodes within them; users own their namespaces. +- Deleting an owner cascades to all nodes it owns. +- User nodes and namespace nodes are globally readable. + +```bash +# Grant bob read access to a node +ax update <bob-user-id> --rel can_read:<node-id> + +# Grant bob write access +ax update <bob-user-id> --rel can_write:<node-id> +``` + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `AX_USER` | Override current username | +| `EDITOR` | Editor for `ax edit` (default: `vi`) | + +## Database Location + +`ax` searches for `.ax.db` upward from CWD (like git finds `.git`), so commands work from any subdirectory.