Skip to content

Automation and Scripting

aisw is designed to be used safely in CI pipelines, shell scripts, and non-interactive environments.

Terminal window
aisw --non-interactive --quiet <command>
FlagEffect
--non-interactiveFail instead of prompting. Safe for CI - commands that require user input will exit non-zero with a clear error.
--quietSuppress human-readable presentation output (tables, status lines). Does not suppress errors, JSON output, --emit-env, or shell-hook output.
--yesSkip confirmation prompts on commands that ask before proceeding (remove, restore, uninstall).
Terminal window
# Add an API key profile without any prompts
aisw --non-interactive add claude ci --api-key "$ANTHROPIC_API_KEY"
# Add from an already-exported environment variable
aisw --non-interactive add codex ci --from-env
# Remove a profile with no confirmation
aisw --non-interactive remove codex ci --yes
# Restore a backup with no confirmation
aisw --non-interactive backup restore 20260325T114502Z-claude-ci --yes

Interactive OAuth flows (aisw add claude personal without flags) are not available in --non-interactive mode. Use --api-key or --from-env for CI.

All inventory and status commands support --json:

Terminal window
aisw status --json
aisw list --json
aisw list claude --json
aisw backup list --json
aisw doctor --json

JSON output goes to stdout. Errors always go to stderr with a non-zero exit code.

Terminal window
# Get the active Claude profile name
aisw status --json | jq -r '.tools.claude.active_profile'
# Check whether the live credentials match the active profile
aisw status --json | jq '.tools.claude.live_match'
# List all stored Codex profile names
aisw list codex --json | jq -r '.[].name'
# Find profiles with expired tokens
aisw status --json | jq '.tools[] | select(.token_warning != null) | {tool, warning: .token_warning}'
# Get the most recent backup for a specific profile
aisw backup list --json | jq '[.[] | select(.profile == "claude/work")] | sort_by(.created_at) | last'
OutputDestinationNotes
Human-readable tables and statusstdoutSuppressed by --quiet
Errorsstderr + non-zero exitAlways present, never suppressed
Promptsstderr or ttyOnly shown without --non-interactive and without --yes
aisw use --emit-envstdoutShell variable exports; not affected by --quiet
aisw shell-hookstdoutShell hook code; not affected by --quiet
JSON output (--json)stdoutNot affected by --quiet

Exit code 0 means success. Any non-zero exit code means failure; the error message is on stderr.

If the shell hook is not installed, aisw use still writes live credential files and updates the active profile in config. For commands that need the env vars emitted by aisw use:

Terminal window
# Apply profile and capture env exports into the current shell
eval "$(aisw use codex work --emit-env)"
# Or in a subshell
(eval "$(aisw use claude work --emit-env)"; claude ...)

--emit-env prints export VAR=value lines for any environment variables the profile activation sets (e.g. CLAUDE_CONFIG_DIR, CODEX_HOME).

Commands that write ~/.aisw/config.json take an exclusive file lock. If two aisw commands run concurrently, the second will wait briefly then fail with a lock error. This prevents partial writes in parallel CI matrix jobs. Design your CI steps so profile setup runs before parallel job steps that invoke the tools.

Terminal window
# GitHub Actions or similar
- name: Configure Codex profile
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
aisw --non-interactive add codex ci --from-env
aisw use codex ci
Terminal window
aisw --non-interactive use claude work
claude --print "summarize this file" < input.txt
Terminal window
active=$(aisw status --json | jq -r '.tools.claude.active_profile')
if [ "$active" != "ci" ]; then
echo "Expected profile 'ci', got '${active}'" >&2
exit 1
fi
Terminal window
aisw --non-interactive remove codex ci --yes