npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aiwcli

v0.15.5

Published

AI Workflow CLI - Command-line interface for AI-powered workflows

Readme

AIW CLI - AI Workflow CLI

Command-line interface for launching and managing Claude Code with AI Workflow (AIW) configuration. Provides seamless integration with AIW hooks, automatic sandbox permissions, and scriptable automation support.

oclif Version Downloads/week

Installation

Install from npm (Recommended)

# Install globally from npm
npm install -g aiwcli

# Verify installation
aiw --version
aiw --help

What's Included

aiwcli v0.9.0 includes:

  • CLI Commands: launch, init, branch, clean, clear
  • Templates:
    • cc-native - Event-sourced context management with plan review, 25+ specialized agents
    • _shared - Common utilities (context manager, event logging, task sync)
  • IDE Support: Claude Code, Windsurf, Codex

After installation, run aiw init --method cc-native to set up the template in your project.

Commands

AIW CLI provides the following commands:

aiw launch

Launch Claude Code with AIW configuration (sandbox disabled, tmux-first by default when outside tmux).

aiw launch
aiw launch --debug  # Enable verbose logging
aiw launch --quiet  # Suppress informational output
aiw launch --no-tmux  # Bypass tmux auto-launch and run directly
aiw launch --tmux-session aiw-main  # Reuse/attach a specific tmux session name

aiw launch now creates a fresh tmux session by default when auto-launching tmux.

If you prefer typing codex, route it through AIW launch behavior with an alias:

alias codex='aiw launch --codex'

aiw init

Initialize AIW tools and integrations with specified template method.

aiw init --interactive             # Run interactive setup wizard
aiw init --method cc-native        # Initialize CC-Native template
aiw init --method cc-native --ide windsurf        # Install for Windsurf
aiw init --method cc-native --ide claude --ide windsurf  # Install for both IDEs

aiw branch <branchName>

Create git worktree in sibling folder and auto-launch Claude Code.

Reduces friction in branch-based development workflows by:

  1. Creating a new git worktree with the specified branch name
  2. Creating a sibling folder with suffix pattern (e.g., aiwcliaiwcli-feature-name)
  3. Opening a new terminal window at the worktree path
  4. Automatically running aiw launch in that terminal
aiw branch feature-name     # Creates ../aiwcli-feature-name worktree
aiw branch fix-bug-123      # Creates ../aiwcli-fix-bug-123 worktree
aiw branch experiment       # Creates ../aiwcli-experiment worktree

Requirements:

  • Must be run from a git repository root
  • Target folder must not already exist
  • Branch name must not already exist

Exit codes:

  • 0 - Success: Worktree created and terminal launched
  • 1 - General error: Unexpected failure
  • 2 - Invalid usage: Invalid branch name, folder exists, or not in git repo
  • 3 - Environment error: Git not available

Requirements

Minimum Claude Code Version: 0.1.0 or later

AIW CLI automatically detects your Claude Code version and warns if incompatibilities are detected. The CLI will continue to launch even with version warnings (graceful degradation).

Known Incompatible Versions

  • 0.0.9 - Has known issues with AIW CLI integration

If you encounter version compatibility warnings, upgrade Claude Code to the latest version:

# Upgrade Claude Code to latest version
npm install -g @anthropic-ai/claude-code@latest

Troubleshooting

Windows Setup: Symlink Permission Denied

Symptom: aiw init fails with "Permission denied creating symlink" or "EPERM: operation not permitted"

Solution (choose one):

Option 1: Enable Developer Mode (Recommended)

  1. Open Windows Settings
  2. Go to "Privacy & Security" → "For developers"
  3. Enable "Developer Mode"
  4. Run aiw init again

Option 2: Run as Administrator

  1. Open PowerShell or Command Prompt as Administrator
  2. Run aiw init

Developer Mode is recommended as it allows symlink creation without elevated privileges for all future operations.

Version Compatibility Issues

Symptom: Warning message about Claude Code version incompatibility

Solution:

  1. Check your current Claude Code version: claude --version
  2. Upgrade to version 0.1.0 or later (see above)
  3. If version cannot be detected, ensure Claude Code is installed and in your PATH

Debug Mode:

Use --debug flag to see detailed version information:

aiw launch --debug

Debug output includes:

  • Resolved AIW_DIR path
  • Claude Code version detection
  • Compatibility check results
  • Spawn arguments and configuration

Version Check Failed

If claude --version fails or hangs:

  • Verify Claude Code is installed: which claude (Unix) or where claude (Windows)
  • Check PATH includes Claude Code installation directory
  • Reinstall Claude Code if necessary

AIW CLI assumes compatibility if version cannot be determined and will proceed with launch.

Environment Variables

AIW CLI respects standard environment variables for controlling output behavior:

NO_COLOR

Disables colored output. Useful for scripts or when colors interfere with output processing.

# Disable all colors
NO_COLOR=1 aiw launch

FORCE_COLOR

Forces colored output even when not in a TTY (terminal). Useful for CI environments that support colors.

# Force colors (level 1 = basic 16 colors)
FORCE_COLOR=1 aiw launch | less -R

# Force 256 colors
FORCE_COLOR=2 aiw launch

# Force truecolor (16 million colors)
FORCE_COLOR=3 aiw launch

AIW_DIR

Customize the AIW configuration directory (default: ~/.aiw):

AIW_DIR=/custom/path aiw launch

Output Behavior

AIW CLI automatically adapts its output based on the execution context:

Interactive Terminal (TTY)

  • Colors enabled
  • Progress spinners shown
  • Rich formatting

Piped or Redirected Output

  • Colors automatically disabled
  • Spinners suppressed
  • Clean, parseable text output
# Example: Piping to other commands
aiw launch --help | grep "OPTIONS"

# Example: Redirecting to file
aiw launch --help > help.txt

# Example: Processing with tools
aiw launch 2>&1 | tee output.log

This automatic behavior ensures AIW CLI works seamlessly in both interactive use and automation scripts without requiring manual configuration.

Quiet Mode

For scripting and automation where you want minimal output, use the --quiet (or -q) flag to suppress informational messages while preserving errors:

# Suppress informational output
aiw launch --quiet

# Short form
aiw launch -q

What Gets Suppressed:

  • Informational messages (logInfo)
  • Success messages (logSuccess)
  • Warning messages (logWarning)
  • Progress spinners

What's Always Shown:

  • Error messages (stderr) - critical for debugging failures
  • Essential data output (stdout) - for parsing in scripts

Example Usage:

# Silent execution in scripts
aiw launch --quiet
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
  echo "Launch failed with code $EXIT_CODE"
fi

# Combine with piping
aiw launch --quiet 2>&1 | tee log.txt

# CI/CD pipelines
aiw launch --quiet || exit 1

Quiet Mode vs. Piping:

  • Piping: Automatically disables colors and spinners
  • Quiet Mode: Explicitly suppresses informational text
  • Combined: Minimal clean output for scripting

Command Chaining

AIW CLI is designed for seamless integration into command chains and pipelines, enabling complex automation workflows.

Chaining with && (Success Chains)

Commands can be chained using && to execute multiple operations sequentially, stopping at the first failure:

# Execute multiple commands - stops if any fails
aiw launch --help && aiw init --help

# Chain with other tools
aiw launch --help && echo "Launch command is available"

# Complex chains
aiw init && aiw launch --quiet && echo "Setup and launch complete"

How It Works:

  • Exit code 0 (success) → chain continues to next command
  • Exit code 1/2/3 (error) → chain stops, subsequent commands don't run
  • Errors always output to stderr for visibility

Piping Output

AIW CLI produces clean stdout that works seamlessly with standard Unix tools:

# Pipe to grep, awk, jq, etc.
aiw launch --help | grep "Launch"

# Combine quiet mode for cleanest output
aiw launch --help --quiet | wc -l

# Multi-stage pipelines
aiw launch --help | grep "flags" | sort

Output Separation:

  • stdout: Data only (help text, command output)
  • stderr: Errors and warnings only
  • Status messages: Automatically suppressed when piped

Cross-Platform Compatibility

Windows PowerShell:

# && chains work in PowerShell 7+
aiw launch --help && echo "Success"

# Pipes work universally
aiw launch --help | Select-String "Launch"

# Legacy CMD/PowerShell 5.1 uses semicolon for sequential execution
aiw launch --help; echo "Runs regardless of success"

Unix/macOS (Bash/Zsh):

# Standard && chaining
aiw launch --help && echo "Success"

# Standard piping
aiw launch --help | grep "Launch"

# Complex pipelines
aiw launch --help | grep "flags" | awk '{print $1}'

Practical Examples

CI/CD Pipelines:

# Stop pipeline on first failure
aiw init && aiw launch --quiet && other-command || exit 1

Scripting with Error Handling:

#!/bin/bash
if aiw launch --quiet; then
  echo "Launch succeeded"
else
  echo "Launch failed with code $?" >&2
  exit 1
fi

Data Processing:

# Extract and process help text
aiw launch --help --quiet | grep -E "^  -" | sort

Exit Codes

AIW CLI uses standardized exit codes to enable reliable error handling in scripts and automation pipelines.

Exit Code Reference

| Code | Meaning | When It Occurs | |------|---------|----------------| | 0 | Success | Command completed successfully without errors | | 1 | General Error | Unexpected runtime failures, system errors, unhandled exceptions | | 2 | Invalid Usage | Invalid arguments, unknown flags, missing required parameters | | 3 | Environment Error | Missing prerequisites (Claude Code not installed, AIW_DIR not found, permission denied) |

Checking Exit Codes

Bash / Zsh (Unix, macOS, Linux, Git Bash, WSL):

# Check last command's exit code
aiw launch
echo $?  # 0 = success, non-zero = error

# Conditional execution with &&
aiw launch && echo "Success!"

# Fallback with ||
aiw launch || echo "Failed with code $?"

# Store and check exit code
aiw launch
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
  echo "Launch succeeded"
elif [ $EXIT_CODE -eq 3 ]; then
  echo "Environment error - run 'aiw init' or install Claude Code"
else
  echo "Command failed with exit code $EXIT_CODE"
fi

# Chain commands (stops on first failure)
aiw init && aiw launch && echo "All commands succeeded"

PowerShell (Windows):

# Check last command's exit code
aiw launch
echo $LASTEXITCODE  # 0 = success, non-zero = error

# Conditional execution
aiw launch
if ($LASTEXITCODE -eq 0) {
    Write-Host "Success!"
} elseif ($LASTEXITCODE -eq 3) {
    Write-Host "Environment error - run 'aiw init' or install Claude Code"
} else {
    Write-Host "Failed with exit code $LASTEXITCODE"
}

# Throw on error
$ErrorActionPreference = "Stop"
aiw launch  # Will throw exception if exit code is non-zero

# Continue on error but check result
$ErrorActionPreference = "Continue"
aiw launch
if ($LASTEXITCODE -ne 0) {
    Write-Error "Launch failed"
    exit $LASTEXITCODE
}

CMD (Windows):

REM Check exit code with %ERRORLEVEL%
aiw launch
echo %ERRORLEVEL%

REM Conditional execution with &&
aiw init && aiw launch && echo Success!

REM Check exit code in batch script
aiw launch
if %ERRORLEVEL% EQU 0 (
    echo Success
) else if %ERRORLEVEL% EQU 3 (
    echo Environment error
) else (
    echo Failed with code %ERRORLEVEL%
)

Common Exit Code Scenarios

Success (0):

  • Help displayed: aiwlaunch --help
  • Setup completed successfully: aiw init
  • Claude Code launched and exited normally: aiwlaunch

General Error (1):

  • Unexpected runtime failures
  • Network errors during operation
  • File system errors (other than missing prerequisites)
  • Unknown/unhandled exceptions

Invalid Usage (2):

  • Unknown flag: aiwlaunch --invalid-flag
  • Unknown command: aiwinvalid-command
  • Missing required argument: aiw init (without --method arg)
  • Conflicting options

Environment Error (3):

  • Claude Code not installed: aiwlaunch (when claude not in PATH)
  • AIW_DIR not found: aiw init (when ~/.aiw doesn't exist and AIW_DIR not set)
  • Permission denied: aiw init (on Windows without Developer Mode or admin rights)
  • Version incompatibility blocking operation

Exit Codes in CI/CD

Exit codes enable reliable automation in continuous integration and deployment pipelines:

# GitHub Actions example
- name: Launch AIW
  run: aiw launch
  # Automatically fails workflow on non-zero exit

# With custom error handling
- name: Launch AIW with fallback
  run: |
    aiw launch || {
      EXIT_CODE=$?
      if [ $EXIT_CODE -eq 3 ]; then
        echo "Environment setup needed"
        exit 1
      fi
      exit $EXIT_CODE
    }

Getting Help on Exit Codes

Every command documents its exit codes in help text:

aiw launch --help  # See EXIT CODES section
aiw init --help   # See EXIT CODES section

Shell Completion

AIW CLI supports tab completion for commands, subcommands, and flags in Bash, Zsh, and PowerShell.

Installation

Bash

Add to your ~/.bashrc:

eval "$(aiw autocomplete:script bash)"

Or run this one-liner:

printf "eval \"\$(aiw autocomplete:script bash)\"" >> ~/.bashrc && source ~/.bashrc

Note: If your terminal starts as a login shell, modify ~/.bash_profile or ~/.profile instead:

printf "eval \"\$(aiw autocomplete:script bash)\"" >> ~/.bash_profile && source ~/.bash_profile

Zsh

Add to your ~/.zshrc:

eval "$(aiw autocomplete:script zsh)"

Or run this one-liner:

printf "eval \"\$(aiw autocomplete:script zsh)\"" >> ~/.zshrc && source ~/.zshrc

PowerShell

Run the autocomplete command and follow the instructions:

aiw autocomplete powershell

The command will provide platform-specific setup instructions. Typically:

# Create profile directory if it doesn't exist
New-Item -Type Directory -Path (Split-Path -Parent $PROFILE) -ErrorAction SilentlyContinue

# Add autocomplete to profile and reload
Add-Content -Path $PROFILE -Value (Invoke-Expression -Command "aiw autocomplete script powershell"); .$PROFILE

Optional: Enable menu-style completion in PowerShell:

Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete

Usage

After installation, you can use tab completion:

# Command completion
aiw la<TAB>        # Completes to "aiw launch"

# Subcommand completion (when available)
aiw init <TAB>     # Shows available subcommands

# Flag completion
aiw launch --<TAB> # Shows available flags

# Command listing
aiw <TAB>          # Shows all available commands

Troubleshooting

Bash

If completion doesn't work:

  • Check if ~/.bashrc is sourced (may need ~/.bash_profile for login shells)
  • Verify completion script loaded: type _aiw_completion
  • Restart your shell: exec bash

Zsh

If completion doesn't work:

  • Check permissions: compaudit -D
  • Rebuild completion cache: rm ~/.zcompdump* && compinit
  • Restart your shell: exec zsh

PowerShell

If completion doesn't work:

  • Check execution policy: Get-ExecutionPolicy
  • May need: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
  • Restart PowerShell

Refresh Completion Cache

If commands or flags change after updates:

aiw autocomplete --refresh-cache

Or use the short form:

aiw autocomplete -r

Scripting Examples

AIW CLI is designed for seamless integration into automation scripts, shell pipelines, and CI/CD workflows. All examples work on Windows (PowerShell/CMD/Git Bash), macOS, and Linux.

Basic Piping

Pipe AIW CLI output to standard Unix tools for filtering and processing:

# Search help for specific command
aiw --help | grep "launch"

# Find all available flags
aiw launch --help | grep -E "^  -"

# Extract version number
aiw --version | cut -d' ' -f2

# Count lines of output
aiw --help | wc -l

PowerShell equivalent:

# Search help
aiw --help | Select-String "launch"

# Find flags
aiw launch --help | Select-String "^  -"

Command Chaining

Chain multiple commands together with proper error handling:

Bash/Zsh (Unix, macOS, Linux, Git Bash):

# Sequential execution - stops on first failure
aiw init && aiw launch

# Multiple commands
aiw --version && aiw init && aiw launch

# Continue on error
aiw init || echo "Setup failed"

# Error handling with exit codes
if aiw launch; then
  echo "Launch succeeded"
else
  EXIT_CODE=$?
  echo "Launch failed with exit code $EXIT_CODE"
fi

PowerShell (Windows):

# Sequential execution (PowerShell 7+)
aiw init && aiw launch

# Error handling
aiw launch
if ($LASTEXITCODE -eq 0) {
    Write-Host "Success"
} else {
    Write-Host "Failed with exit code $LASTEXITCODE"
}

CMD (Windows):

REM Sequential execution
aiw init && aiw launch && echo Success

REM Error handling
aiw launch
if %ERRORLEVEL% EQU 0 (
    echo Success
) else (
    echo Failed with code %ERRORLEVEL%
)

Quiet Mode for Scripts

Suppress informational output while preserving errors:

# Silent execution in automation
aiw launch --quiet

# Short form
aiw launch -q

# Capture exit code
aiw launch --quiet
EXIT_CODE=$?

# Only errors shown (goes to stderr)
aiw launch --quiet 2>errors.log

# Combine with piping for cleanest output
aiw launch --help --quiet | wc -l

Use cases for --quiet:

  • CI/CD pipelines where minimal output is desired
  • Automated scripts that parse command output
  • Reducing noise in log files
  • Background processes

Exit Code Handling

AIW CLI uses standardized exit codes for reliable automation:

| Code | Meaning | Example Scenarios | |------|---------|-------------------| | 0 | Success | Command completed, help displayed, setup successful | | 1 | General Error | Runtime failures, unexpected errors | | 2 | Invalid Usage | Unknown flags, invalid arguments | | 3 | Environment Error | Claude Code not installed, permissions denied |

Bash/Zsh examples:

# Basic exit code check
aiw launch
if [ $? -eq 0 ]; then
  echo "Success"
fi

# Handle specific exit codes
aiw launch
EXIT_CODE=$?
case $EXIT_CODE in
  0)
    echo "Launch successful"
    ;;
  2)
    echo "Invalid usage - check arguments"
    ;;
  3)
    echo "Environment issue - is Claude Code installed?"
    aiw init  # Try setup
    ;;
  *)
    echo "Unexpected error: $EXIT_CODE"
    ;;
esac

# Use exit codes in pipelines
aiw init && aiw launch || {
  echo "Failed at exit code $?"
  exit 1
}

PowerShell examples:

# Check last exit code
aiw launch
if ($LASTEXITCODE -eq 0) {
    Write-Host "Success"
}

# Handle specific codes
aiw launch
switch ($LASTEXITCODE) {
    0 { Write-Host "Success" }
    2 { Write-Host "Invalid usage" }
    3 { Write-Host "Environment issue"; aiw init }
    default { Write-Host "Error: $LASTEXITCODE" }
}

# Fail on error
$ErrorActionPreference = "Stop"
aiw launch  # Will throw if non-zero exit code

Shell Completion Usage

After installing shell completion (see Shell Completion section):

# Command completion
aiw la<TAB>        # Completes to "aiw launch"

# Show all commands
aiw <TAB>          # Lists: autocomplete, help, init, launch

# Flag completion
aiw launch --<TAB> # Shows: --debug, --help, --quiet

# Short flag completion
aiw launch -<TAB>  # Shows: -d, -h, -q

Benefits:

  • Faster command entry
  • Discover available commands without --help
  • Reduce typos
  • Learn flag names interactively

CI/CD Pipeline Examples

GitHub Actions:

name: Deploy with AIW

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Setup AIW
        run: |
          npm install -g aiwcli
          aiw init

      - name: Launch Claude Code
        run: aiw launch --quiet || exit $?

      - name: Check exit code
        if: failure()
        run: |
          echo "AIW launch failed"
          echo "Exit code: $?"

GitLab CI:

deploy:
  script:
    - aiw init
    - aiw launch --quiet
  only:
    - main

Jenkins:

pipeline {
    agent any
    stages {
        stage('Setup') {
            steps {
                sh 'aiw init'
            }
        }
        stage('Launch') {
            steps {
                sh 'aiw launch --quiet || exit $?'
            }
        }
    }
}

Automation Script Examples

Deployment script (Bash):

#!/bin/bash
set -e  # Exit on error

echo "Starting deployment..."

# Setup AIW if not configured
if ! aiw --version > /dev/null 2>&1; then
  echo "AIW CLI not found"
  exit 3
fi

# Run setup
aiw init || {
  echo "Setup failed with code $?"
  exit 1
}

# Launch with quiet mode
aiw launch --quiet

echo "Deployment complete"

Monitoring script (Bash):

#!/bin/bash

# Check AIW status every 5 minutes
while true; do
  if aiw --version --quiet; then
    echo "[$(date)] AIW CLI operational"
  else
    echo "[$(date)] AIW CLI check failed: exit code $?"
  fi
  sleep 300
done

Batch processing (PowerShell):

# Process multiple operations with AIW
$operations = @("setup", "launch")

foreach ($op in $operations) {
    Write-Host "Running: aiw $op"

    & aiw $op --quiet

    if ($LASTEXITCODE -ne 0) {
        Write-Error "Operation $op failed with code $LASTEXITCODE"
        exit $LASTEXITCODE
    }
}

Write-Host "All operations completed successfully"

Tips for Scripting

1. Always use --quiet in scripts:

# Good: Clean output
aiw launch --quiet

# Avoid: Verbose output pollutes logs
aiw launch

2. Check exit codes explicitly:

# Good: Explicit error handling
aiw launch
if [ $? -ne 0 ]; then
  handle_error
fi

# Risky: Assumes success
aiw launch
continue_anyway

3. Pipe stderr to log files:

# Capture errors for debugging
aiw launch 2>errors.log

# Capture both stdout and stderr
aiw launch >output.log 2>&1

4. Use timeout for long operations:

# Bash: timeout after 60 seconds
timeout 60 aiw launch || echo "Timeout or error"

# PowerShell: timeout after 60 seconds
Start-Process -Wait -Timeout 60 -NoNewWindow aiw -ArgumentList "launch"

5. Combine with other CLI tools:

# Log with timestamp
aiw launch --quiet 2>&1 | while read line; do
  echo "$(date -Is) $line"
done

# Notify on completion (Linux/macOS)
aiw launch --quiet && notify-send "AIW launch complete"

# Email on failure (with sendmail)
aiw launch --quiet || echo "AIW launch failed" | mail -s "Alert" [email protected]

Command Development Guide

This section explains how to add new commands to AIW CLI following Oclif best practices and our established patterns.

Command Architecture

AIW CLI uses Oclif which provides automatic command registration based on file structure:

  • File path = Command name: src/commands/launch.tsaiw launch
  • Subdirectories = Topics: src/commands/init/index.tsaiw init
  • Class names: PascalCase version of command name (Launch, Init)

Adding a New Top-Level Command

  1. Create the command file in src/commands/:

    # Example: Adding a "status" command
    touch src/commands/status.ts
  2. Implement the command:

    import {Flags} from '@oclif/core'
    
    import BaseCommand from '../lib/base-command.js'
    
    export default class Status extends BaseCommand {
      static override description = 'Show AIW status'
    
      static override examples = [
        '<%= config.bin %> <%= command.id %>',
        '<%= config.bin %> <%= command.id %> --debug',
      ]
    
      static override flags = {
        ...BaseCommand.baseFlags,  // Inherit global flags
        // Add command-specific flags here
      }
    
      async run(): Promise<void> {
        const {flags} = await this.parse(Status)
        // Implementation here
        this.log('Status output')
      }
    }
  3. Add tests in test/commands/:

    // test/commands/status.test.ts
    import {expect, test} from '@oclif/test'
    
    describe('status', () => {
      test
        .stdout()
        .command(['status'])
        .it('shows status', ctx => {
          expect(ctx.stdout).to.contain('Status output')
        })
    })

Adding a Topic (Command Group)

Topics organize related commands under a common namespace:

  1. Create directory in src/commands/:

    mkdir src/commands/config
  2. Add topic commands:

    // src/commands/config/show.ts → aiw config show
    // src/commands/config/edit.ts → aiw config edit

Standard Flag Patterns

All commands should inherit base flags from BaseCommand:

| Flag | Long Form | Short Form | Purpose | |------|-----------|------------|---------| | Debug | --debug | -d | Enable verbose logging | | Help | --help | -h | Show command help | | Quiet | --quiet | -q | Suppress informational output (errors still shown) |

Pattern:

static override flags = {
  ...BaseCommand.baseFlags,  // Always inherit base flags
  myFlag: Flags.string({
    char: 'm',  // Short form
    description: 'My flag description',
    required: false,
  }),
}

Naming Conventions

| Element | Convention | Example | |---------|------------|---------| | Command files | kebab-case | launch.ts, init/index.ts | | Command classes | PascalCase | Launch, Init | | Flags | camelCase | debug, aiwDir, quiet | | Constants | UPPER_SNAKE_CASE | EXIT_CODES.SUCCESS |

Import Organization

Follow strict import order (enforced by ESLint):

// 1. Node builtins (with node: prefix)
import {spawn} from 'node:child_process'

// 2. External packages
import {Flags} from '@oclif/core'

// 3. Internal imports
import BaseCommand from '../lib/base-command.js'
import {getAiwDir} from '../lib/config.js'

// 4. Type imports
import type {LaunchOptions} from '../types/index.js'

Error Handling

Use categorized exit codes and actionable error messages:

import {EXIT_CODES} from '../types/index.js'

// Actionable error format: {what_wrong}. {how_to_fix}
this.error(
  'Configuration file not found. Run `aiw init` to initialize.',
  {exit: EXIT_CODES.ENVIRONMENT_ERROR}
)

Exit codes:

  • EXIT_CODES.SUCCESS (0) - Successful execution
  • EXIT_CODES.GENERAL_ERROR (1) - General error
  • EXIT_CODES.INVALID_USAGE (2) - Invalid arguments
  • EXIT_CODES.ENVIRONMENT_ERROR (3) - Environment/prerequisite error

Help System

Oclif provides built-in help:

  • aiw <command> --help - Show command help
  • aiw help <command> - Alternative help format (same output)
  • aiw help - List all commands

Help is automatically generated from command metadata (description, examples, flags).

Testing Commands

  1. Unit tests (test/commands/<command>.test.ts):

    • Test command logic in isolation
    • Mock external dependencies
  2. Integration tests (test/integration/<feature>.test.ts):

    • Test actual CLI invocation
    • Use execSync() to run commands
    • Cross-platform compatibility

Example:

import {execSync} from 'node:child_process'
import {platform} from 'node:os'

const bin = platform() === 'win32' ? String.raw`.\bin\dev.cmd` : './bin/dev.js'

it('executes command', () => {
  const result = execSync(`${bin} status`, {encoding: 'utf8'})
  expect(result).to.include('expected output')
})

Project Structure

aiwcli/
├── src/
│   ├── commands/
│   │   ├── branch.ts         # aiw branch <branchName>
│   │   ├── launch.ts         # aiw launch
│   │   └── init/             # Topic: aiw init
│   │       └── index.ts      # aiw init --method <template>
│   ├── lib/                  # Internal libraries
│   │   ├── base-command.ts   # BaseCommand (extend this)
│   │   ├── config.ts
│   │   ├── debug.ts
│   │   ├── errors.ts
│   │   └── spawn.ts
│   └── types/                # Type definitions
│       └── index.ts
├── test/
│   ├── commands/             # Unit tests
│   ├── lib/                  # Library tests
│   └── integration/          # Integration tests
└── README.md

Critical Rules

MUST:

  • Extend BaseCommand for all commands
  • Inherit BaseCommand.baseFlags in flag definitions
  • Use .js extension in all imports (ESM requirement)
  • Add node: prefix for Node builtins
  • Use this.error() instead of process.exit()
  • Provide both short (-f) and long (--flag) flag forms
  • Follow kebab-case for command file names

MUST NOT:

  • Call process.exit() directly
  • Create utilities in src/utils/ or src/helpers/ (use src/lib/)
  • Use I prefix on interfaces (Config not IConfig)
  • Skip the .js extension in imports
  • Use Promise chains (use async/await)

Resources