# CLI: Command Reference

The production CLI command groups are:

```text
keito auth <command>
keito clients <command>
keito projects <command>
keito time <command>
keito skill <command>
```

Every command supports `--help`. Every command can output JSON with `--json`.

## Global Flags

| Flag | Description |
|---|---|
| `--json` | Force JSON output |
| `--workspace <id>` | Override the Company ID for one invocation |
| `--quiet` | Suppress non-essential output |
| `--verbose` | Enable debug logging |
| `--help` | Show help |
| `--version` | Show version |

When stdout is piped, JSON output is enabled automatically.

## Auth Commands

| Command | Description |
|---|---|
| `keito auth login` | Prompt for API key and Company ID, validate them, and save config |
| `keito auth logout` | Remove saved config credentials |
| `keito auth status` | Show whether credentials are configured and valid |
| `keito auth whoami` | Show the current user and company from the API |

### `keito auth login`

```bash
keito auth login
```

Prompts for a `kto_...` API key and Company ID. The key is saved in the config file, not in a system keychain.

### `keito auth status`

```bash
keito auth status --json
```

Configured credentials:

```json
{
  "authenticated": true,
  "api_key_source": "config file",
  "account_id": "company_id_here",
  "workspace_id": "company_id_here",
  "api_key_valid": true
}
```

No credentials:

```json
{"authenticated": false}
```

### `keito auth logout`

```bash
keito auth logout --json
```

```json
{
  "status": "logged_out",
  "config_credentials_removed": true
}
```

## Projects and Tasks

| Command | Description |
|---|---|
| `keito projects list` | List active projects |
| `keito projects show <project>` | Show project details by name, code, or ID |
| `keito projects tasks` | List workspace-global tasks |

## Clients

| Command | Description |
|---|---|
| `keito clients list` | List active clients |
| `keito clients create <name>` | Create a client if the authenticated user has permission |

### `keito projects list`

```bash
keito projects list
keito projects list --limit 20 --json
```

| Flag | Description |
|---|---|
| `--limit <number>` | Max results to return |

### `keito projects show <project>`

```bash
keito projects show "Acme Website"
keito projects show ACME --json
keito projects show project_id_here --json
```

The `<project>` argument accepts a project ID, name, or code. Resolution is case-insensitive.

### `keito projects tasks`

```bash
keito projects tasks
keito projects tasks --limit 20 --json
```

Tasks are workspace-global, not project-specific.

## Time Commands

| Command | Description |
|---|---|
| `keito time start` | Start a running timer |
| `keito time stop` | Stop or discard the running timer |
| `keito time log` | Log a completed time entry |
| `keito time list` | List time entries |
| `keito time running` | Show the currently running timer |
| `keito time session-record` | Create or update a completed agent session entry |

### `keito time start`

```bash
keito time start --project "Acme Website" --task "Development" \
  --notes "Working on auth" \
  --json
```

| Flag | Description | Required |
|---|---|---|
| `--project <value>` | Project name, code, or ID | Yes |
| `--task <value>` | Task name or ID | Yes |
| `--notes <text>` | Initial notes | No |
| `--billable <true|false>` | Override billable status | No |

Only one timer may be active. If a timer is already running, the command exits with code `3`.

### `keito time session-record`

```bash
keito time session-record \
  --project "Acme Website" \
  --task "Development" \
  --session-id "codex-123" \
  --duration-seconds 5400 \
  --source agent \
  --metadata '{"integration":"keito_skill","agent_type":"codex"}' \
  --json
```

| Flag | Description | Required |
|---|---|---|
| `--project <value>` | Project name, code, or ID | Yes |
| `--task <value>` | Task name or ID | Yes |
| `--session-id <value>` | Stable session ID for idempotent updates | Yes |
| `--duration-seconds <number>` | Duration in whole seconds | Yes |
| `--started-at <RFC3339>` | Session start timestamp | No |
| `--ended-at <RFC3339>` | Session end timestamp | No |
| `--source <web|cli|api|agent>` | Source stored on the time entry; default `agent` | No |
| `--metadata <json>` | Metadata object stored on the time entry | No |
| `--agent-id <value>` | Stores `metadata.agent_id` | No |
| `--agent-type <value>` | Stores `metadata.agent_type` | No |
| `--skill <value>` | Stores `metadata.skill` | No |

If a matching session entry already exists for the same date and source, the CLI updates it instead of creating a duplicate.

### `keito time running`

```bash
keito time running
keito time running --json
```

Returns `{"running": false}` when no timer is active, or an array of running timer objects when a timer exists.

### `keito time stop`

```bash
keito time stop --notes "Finished auth work" --json
keito time stop --discard --json
```

| Flag | Description |
|---|---|
| `--notes <text>` | Replace notes on the entry |
| `--discard` | Delete the running timer instead of saving it |

### `keito time log`

```bash
keito time log --project "Acme Website" --task "Development" \
  --duration 1:30 \
  --date 2026-05-06 \
  --notes "Implemented OAuth flow" \
  --json
```

| Flag | Description | Required |
|---|---|---|
| `--project <value>` | Project name, code, or ID | Yes |
| `--task <value>` | Task name or ID | Yes |
| `--duration <value>` | Decimal hours or `HH:MM` | Yes |
| `--date <YYYY-MM-DD>` | Work date; defaults to today | No |
| `--notes <text>` | Description of work | No |
| `--billable <true|false>` | Override billable status | No |

### `keito time list`

```bash
keito time list --from 2026-05-01 --to 2026-05-31 --json
keito time list --project "Acme Website" --limit 10 --page 2 --json
```

| Flag | Description |
|---|---|
| `--from <YYYY-MM-DD>` | Start date |
| `--to <YYYY-MM-DD>` | End date |
| `--project <value>` | Filter by project name, code, or ID |
| `--task <value>` | Filter by task name or ID |
| `--limit <number>` | Entries per page; default `50` |
| `--page <number>` | Page number; default `1` |

## Skill Commands

| Command | Description |
|---|---|
| `keito skill install` | Install the Keito Agent Skill and configure Codex and Claude Code hooks |
| `keito skill status` | Show CLI, auth, skill, and hook status |
| `keito skill doctor` | Show readiness checks and next actions |

```bash
keito skill install
keito skill install --agent codex
keito --json skill status
keito skill doctor
```

## Environment Variables

| Variable | Description |
|---|---|
| `KEITO_API_KEY` | API key; highest-priority credential source |
| `KEITO_ACCOUNT_ID` | Company ID sent as `Keito-Account-Id` |
| `KEITO_WORKSPACE_ID` | Legacy alias for `KEITO_ACCOUNT_ID` |

## Config File

| OS | Path |
|---|---|
| macOS | `~/Library/Application Support/keito/config.toml` |
| Linux | `~/.config/keito/config.toml` |
| Windows | `%APPDATA%\keito\config.toml` |

```toml
api_key = "kto_xxxxx"
account_id = "company_id_here"
workspace_id = "company_id_here" # legacy alias
api_url = "https://app.keito.ai"
```

## Exit Codes

| Code | Meaning |
|---|---|
| `0` | Success |
| `1` | Authentication error |
| `2` | Invalid input |
| `3` | Conflict, such as a timer already running |
| `4` | Not found |
| `5` | Rate limited |
| `6` | Server error |
| `7` | Network error |
| `8` | Configuration error |

`keito auth status` is a health-check command. When credentials are missing, JSON output is `{"authenticated": false}`.

## JSON Error Shape

In JSON mode, errors are written to stderr:

```json
{
  "error": true,
  "code": 4,
  "message": "Not found: Project 'demo' not found.",
  "suggestion": "keito projects list --json"
}
```

Agents should branch on the exit code and use `suggestion` as the recovery hint.