api_url and api_key. Profiles give you machine-local isolation without mixing data, sessions, or credentials between setups.
Where profiles live
Profile roles
Every profile has arole, set by the wizard mode you choose:
| Role | Created by | What this machine does |
|---|---|---|
server | hirotaskmanager --setup-server | Runs the API server and acts as its own local client. The CLI on the same machine uses http://127.0.0.1:<port> automatically. |
client | hirotaskmanager --setup-client | Talks to a remote server only. Contains api_url and api_key; runs nothing locally. |
role by hand — the setup mode picks it. To convert a profile from one role to the other, delete it and re-run the appropriate wizard.
Configuration schema
Field matrix
| Field | Server profile | Client profile |
|---|---|---|
role | required ("server") | required ("client") |
port | required | — (must not be set) |
data_dir | required | — |
open_browser | optional (default true) | — |
bind_address | optional (default "127.0.0.1") | — |
require_cli_api_key | optional (default derived from bind_address) | — |
api_url | — (auto-derived as http://127.0.0.1:<port> for the local client) | required (absolute URL) |
api_key | optional (used by the local client when require_cli_api_key: true) | required |
Auth directory is fixed. The web passphrase hash and CLI API key hashes always live at<profileRoot>/auth/(i.e.~/.taskmanager/profiles/<name>/auth/). There is noauth_dirfield — the wizard does not prompt for it, and adding one toconfig.jsonby hand has no effect.
Validation rules (enforced when the config is loaded)
rolemust be"server"or"client".- Server profile:
portanddata_dirare required;api_urlmust not be present (it is auto-derived fromport). - Client profile:
api_url(absolute URL) andapi_keyare required;port,data_dir,open_browser,bind_address,require_cli_api_keymust not be present. - Public exposure requires a key. If
bind_addressis non-loopback (anything other than127.0.0.1,localhost,::1),require_cli_api_key: falseis rejected. - Bootstrap warning (not an error): if
require_cli_api_key === trueon a server profile and noapi_keyis set, the loader warns that the local CLI will fail withauth_cli_key_requireduntil you set one (or pass--api-keyper command). External callers may still authenticate viacli-api-keys.json.
CliError(invalid_config) (exit code 9). The error names the offending field and the profile path.
Example — same-machine server profile (no key)
Example — hardened single-host (loopback + forced key)
Example — public bind on the LAN (advanced, hand-edited)
Example — client profile (talks to a remote server)
Default-profile pointer
~/.taskmanager/config.json:
--setup-server and --setup-client offer to write this pointer at the end of the wizard. Change it later with:
profile use errors if <name> doesn’t exist on disk.
How the CLI picks a profile
Resolution order, per command:--profile <name>on the command line (highest priority).default_profilein~/.taskmanager/config.json.- If neither is set and exactly one profile exists on disk, use it implicitly.
- Otherwise the CLI errors with the list of available profiles and a hint to run
hirotaskmanager profile use <name>(or pass--profile).
How a profile is created
Use the wizards inhirotaskmanager. Each one writes the profile’s config.json, optionally mints a CLI API key, and optionally sets the default-profile pointer.
| Mode | Use it when | Wizard flag |
|---|---|---|
| Server | This machine runs the server (works for both same-machine and VPS installs). | hirotaskmanager --setup-server |
| Client | This machine only talks to a remote server. | hirotaskmanager --setup-client |
hirotaskmanager with no configured profile asks “server or client?” once, then routes to the right flow.
To re-run setup for an existing profile (change port, paths, etc.), use:
Updating a profile
- Interactive:
hirotaskmanager --setup --profile <name>. - Manual: edit
~/.taskmanager/profiles/<name>/config.jsoncarefully (keep valid JSON). Back up the file first. Validation errors will surface on the next CLI invocation.
Advanced: exposing the API on a network interface
bind_address is treated as an advanced, config-file-only setting. The setup wizard never asks for it: new profiles always default to 127.0.0.1 (loopback), and re-running the wizard preserves whatever value is already in config.json.
When loopback is the right answer:
- Same machine. The CLI on this machine talks to
http://127.0.0.1:<port>automatically. - Remote access via reverse proxy. Put Caddy, nginx, or similar in front of the loopback API and terminate TLS there. The API stays unreachable from the network directly.
config.json by hand and set both fields together:
bind_address (anything other than 127.0.0.1, localhost, ::1) must also have require_cli_api_key: true, set explicitly. Setting bind_address to 0.0.0.0 without require_cli_api_key, or with require_cli_api_key: false, is rejected with invalid_config (exit code 9) on the next CLI invocation.
Mint a CLI API key for any caller that will reach the public socket:
Related
- Quickstart — same-machine setup.
- Advanced setup — VPS / split / hardened / dev workflows.
- Concepts — concepts and how the CLI fits the app.
- Server operations —
server start/stop/statusandserver api-key …. - Errors & exit codes —
invalid_config,auth_cli_key_required, and friends.
Hiro developers only
For Hiro developers working on Task Manager itself,--dev and --profile are independent:
--devchanges runtime behavior, including the default port (3002) and dev CORS.--profileselects the profile directory for config, auth, and data.- The
devprofile is not magic. It is just a profile name. - All profiles, including
dev, store data under~/.taskmanager/profiles/<name>/data/unless you override the path.
