Command line interface for working with Aha!.
Currently supported commands are for creating and managing extensions and to-dos.
$ npm install -g aha-cli
$ aha auth:login
Authentication to Aha!...
$ aha extension:create
Create a new extension...
$ aha extension:install
Install the extension into your Aha! account...aha auth:checkaha auth:loginaha extension:add-contributionaha extension:buildaha extension:createaha extension:installaha extension:tailaha extension:uninstallaha extension:watchaha help [COMMANDS]
Check if the stored credentials work
USAGE
$ aha auth:check [-s <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
DESCRIPTION
Check if the stored credentials work
See code: src/commands/auth/check.ts
Login to Aha! and save credentials for other commands
USAGE
$ aha auth:login [-s <value>] [--authServer <value>] [--browser <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
--authServer=<value> [default: https://secure.aha.io] server to use for authentication
--browser=<value> browser to use for login, e.g. 'safari' or 'firefox'
DESCRIPTION
Login to Aha! and save credentials for other commands
Credentials are saved in ~/.netrc
See code: src/commands/auth/login.ts
Add a contribution to an extension
USAGE
$ aha extension:add-contribution [-s <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
DESCRIPTION
Add a contribution to an extension
See code: src/commands/extension/add-contribution.ts
Build an extension into a zip file for ease of distribution
USAGE
$ aha extension:build [-s <value>] [--noCache]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
--noCache skip cached http imports
DESCRIPTION
Build an extension into a zip file for ease of distribution
See code: src/commands/extension/build.ts
Create an example extension
USAGE
$ aha extension:create [-s <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
DESCRIPTION
Create an example extension
See code: src/commands/extension/create.ts
Install the extension from the current directory
USAGE
$ aha extension:install [-s <value>] [--dumpCode] [--noCache]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
--dumpCode dump all code as it is uploaded
--noCache skip cached http imports
DESCRIPTION
Install the extension from the current directory
See code: src/commands/extension/install.ts
Live tail extension logs
USAGE
$ aha extension:tail [-s <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
DESCRIPTION
Live tail extension logs
See code: src/commands/extension/tail.ts
Uninstall the extension in the current directory
USAGE
$ aha extension:uninstall [-s <value>]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
DESCRIPTION
Uninstall the extension in the current directory
See code: src/commands/extension/uninstall.ts
Watch the current directory for changes and install the extension each time a file changes
USAGE
$ aha extension:watch [-s <value>] [--noCache]
FLAGS
-s, --subdomain=<value> Aha! subdomain to use for authentication
--noCache skip cached http imports
DESCRIPTION
Watch the current directory for changes and install the extension each time a file changes
See code: src/commands/extension/watch.ts
Display help for aha.
USAGE
$ aha help [COMMANDS] [-n]
ARGUMENTS
COMMANDS Command to show help for.
FLAGS
-n, --nested-commands Include all nested commands in the output.
DESCRIPTION
Display help for aha.
See code: @oclif/plugin-help
Commands for working with records in an Aha! instance use space-separated syntax.
Authenticate with aha auth login, or use an API key from standard input:
$ aha auth login --with-token --url https://your-account.aha.io < /path/to/api-keyCredentials are saved in ~/.netrc. Use -s <subdomain> to select a saved account.
For API-key login, use --subdomain <alias> to give another instance a distinct
saved name (for example, acme-local). Login refuses to replace an alias belonging
to a different instance.
Create a to-do in My work, automatically assigned to yourself:
$ aha todo create --title "Review the release notes"
$ aha todo create -t "Review the release notes" -b "Check the examples" --due 2026-11-01The title is prompted for when running interactively; scripts and --json mode must
provide --title. The optional --body is plain text, and --due uses YYYY-MM-DD.
The command prints the created to-do's URL.
List, view, edit, complete, reopen, or delete a to-do:
$ aha todo list
$ aha todo list --state completed --search "release notes"
$ aha todo list --state all --json
$ aha todo view PERSONAL-TODO-1
$ aha todo edit PERSONAL-TODO-1 --title "Review updated notes" --due 2026-11-02
$ aha todo complete PERSONAL-TODO-1
$ aha todo reopen PERSONAL-TODO-1
$ aha todo delete PERSONAL-TODO-1 --yesThe list includes all pages of to-dos assigned to you. --state accepts pending
(the default), completed, or all, based on your assignment's status. --search
matches text in the title. Individual commands accept a numeric ID or reference.
view shows the description, due date, overall status, assignees, parent, and link.
edit changes only the supplied fields. Use --body "", --clear-due, or
--clear-record to clear the description, due date, or parent link. complete and
reopen update only your assignment; repeating either action reports when it is
already in the requested state. delete removes the entire shared to-do and asks
for confirmation unless --yes is supplied. Scripts must use --yes.
Assign users or link a to-do to a parent record when creating or editing it:
$ aha todo create -t "Review implementation" --assignee @me,123456789 --record DEMO-123 --record-type feature
$ aha todo edit PERSONAL-TODO-1 --add-assignee 123456789 --remove-assignee @me
$ aha todo edit PERSONAL-TODO-1 --record DEMO-123-1 --record-type requirementAssignment options accept comma-separated numeric user IDs or @me. Create defaults
to yourself; an explicit --assignee selects those users, and --unassigned creates
without assignees. Edit adds or removes only the specified users, preserving other
assignments and their states. Parent links require both --record (ID or reference)
and --record-type (a v3 record type such as feature, requirement, release, or page).
All to-do commands accept --json: list returns an array of v3 records, record
commands return one v3 record, and delete returns { "id": "…", "deleted": true }.
JSON preserves v3 fields, including overall status and individual assignment states.
Use -s <subdomain> to select an account when multiple accounts are saved; JSON mode
does not prompt. JSON deletion requires --yes.
Colon-separated commands also work, for example aha todo:view and aha todo:edit.
Build the CLI package into a .tgz file:
$ npm packThis runs the prepack script automatically, which cleans the lib/ directory, compiles TypeScript, and generates the oclif manifest. The output is a file like aha-cli-v1.17.0.tgz.
You can test the packaged CLI locally without installing it globally using npx:
$ npx --yes --package aha-cli-v1.17.0.tgz aha extension:watchReplace aha-cli-v1.17.0.tgz with the actual filename produced by npm pack. Any aha command can be used this way, for example:
$ npx --yes --package aha-cli-v1.17.0.tgz aha extension:build
$ npx --yes --package aha-cli-v1.17.0.tgz aha extension:installYou can compile the CLI into a standalone executable for your current platform using Bun.
Install Bun: https://bun.com/docs/installation
Install dependencies:
bun installBuild the executable:
bun run build:bunThis produces a binary at:
dist/ahaYou can test it directly:
./dist/aha --versionIf you want to install it locally on your PATH:
sudo mv dist/aha /usr/local/bin/
aha --version