Asana Auto-ID
Automatic human-readable ID assignment for Asana tasks and subtasks.
What is this?
aa-cli automatically adds short, readable IDs to your Asana tasks - like PRJ-5 or PRJ-5-1. This makes tasks easier to reference in discussions, documentation, and team communication.
Key Features:
- 🔢 Automatic hierarchical ID assignment
- 🔄 Preserves existing IDs and detects conflicts
- 🌳 Supports unlimited nesting depth
- 🚀 Fast async processing
- 🔍 Dry-run mode to preview changes
Installation
Prerequisites
Install UV if you don't have it:
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Usage
No installation needed! Just use uvx:
uvx aa-cli@latest --help
Quick Start
1. Initialize
Create your configuration file:
uvx aa-cli@latest init
This will:
- Prompt for your Asana Personal Access Token
- Fetch all your projects automatically
- Detect existing project codes from your tasks
- Create
.aa.ymlwith everything configured
Note: For workspaces with 100+ projects, automatic code detection is skipped to avoid API rate limits. In this case, only the first project is added as an example - you can manually add your projects to the config.
Get your token: Asana Developer Console → "Create new token"
2. Scan
Build the ID cache from your existing tasks:
uvx aa-cli@latest scan
3. Update
Preview changes:
uvx aa-cli@latest update --dry-run
Apply IDs to tasks:
uvx aa-cli@latest update
Done! Your tasks now have IDs like PRJ-1, PRJ-2, etc.
ID Format
IDs follow a hierarchical pattern:
PRJ-1: Implement authentication
├── PRJ-1-1: Design login flow
├── PRJ-1-2: Create user model
│ ├── PRJ-1-2-1: Add validation
│ └── PRJ-1-2-2: Write tests
└── PRJ-1-3: Build API endpoints
PRJ-2: Setup CI/CD
└── PRJ-2-1: Configure GitHub Actions
- Root tasks:
CODE-N(e.g.,PRJ-5) - Subtasks:
CODE-N-M(e.g.,PRJ-5-1) - Nested:
CODE-N-M-K(e.g.,PRJ-5-1-2) - Unlimited depth supported
Commands
init
Initialize configuration:
# Interactive mode (recommended)
uvx aa-cli@latest init
# Create template only
uvx aa-cli@latest init --force
scan
Scan projects and update cache:
# Scan all projects
uvx aa-cli@latest scan
# Scan specific project
uvx aa-cli@latest scan --project PRJ
# Ignore conflicts
uvx aa-cli@latest scan --ignore-conflicts
Safety Check: scan will fail if it detects "foreign" IDs (IDs from other projects) to prevent accidental duplication.
reset
Remove IDs from all tasks in a project (useful for cleaning up messy projects):
# Reset specific project (requires Asana Project GID)
uvx aa-cli@latest reset --project-id 123456789
# Preview changes without applying
uvx aa-cli@latest reset --project-id 123456789 --dry-run
update
Assign IDs to tasks:
# Preview changes
uvx aa-cli@latest update --dry-run
# Apply changes
uvx aa-cli@latest update
# Update specific project
uvx aa-cli@latest update --project PRJ
Options
All commands support:
--config PATH- Custom config file location-v- Verbose output (INFO level)-vv- Debug output (DEBUG level, shows API requests)--help- Show help
Configuration
.aa.yml
asana_token: "your-personal-access-token"
projects:
- code: PRJ # 2-5 uppercase letters
asana_id: "1234567890"
- code: TSK
asana_id: "9876543210"
Finding project IDs:
There are two ways to get a project ID:
-
From task URL (new format):
- Open any task in the project
- Copy the task link
- Find the number after
/project/:https://app.asana.com/.../project/123123123/task/... 123123123is your project ID
-
From project URL:
- Open the project in Asana
- Look at the URL:
https://app.asana.com/0/123123123/... - The number after
/0/is your project ID
Or just use uvx aa-cli@latest init - it fetches everything automatically!
.aa.cache.yaml
Automatically managed by scan and update. Tracks the last assigned ID for each project:
projects:
PRJ:
last_root: 42
subtasks:
"5": 3 # PRJ-5-3 is last subtask of PRJ-5
Workflow
Regular Usage
# Add new tasks in Asana, then:
uvx aa-cli@latest update
Adding New Projects
- Edit
.aa.ymlto add the project - Run
uvx aa-cli@latest scan --project NEW - Run
uvx aa-cli@latest update --project NEW
Handling Conflicts
If someone manually added IDs or cache is out of sync:
# Review the conflict
uvx aa-cli@latest scan
# If safe, update cache to match Asana
uvx aa-cli@latest scan --ignore-conflicts
Troubleshooting
"Config file not found"
- Run
uvx aa-cli@latest initfirst
"Invalid token" or 401 errors
- Generate new token at Asana Developer Console
- Update
.aa.yml
"Conflict detected"
- Someone may have manually added IDs
- Review tasks in Asana
- Use
--ignore-conflictsif safe
Tasks not getting IDs
- Check if tasks already have IDs (they're skipped)
- Make sure you're running
update, not justscan - Remove
--dry-runflag
Development
For contributors and developers:
Setup
git clone https://github.com/umaxfun/asana-tools
cd asana-tools
uv sync
Run Locally
uv run aa-cli --help
Project Structure
aa/
├── cli.py # Main CLI entry point
├── commands/ # Command implementations
├── core/ # Business logic
├── models/ # Data models
└── utils/ # Utilities
Testing
uv run pytest
Adding Dependencies
uv add <package-name>
Version Management
To bump the version and release a new tag:
# Bump version (updates pyproject.toml and aa/__init__.py)
python scripts/bump_version.py [major|minor|patch]
# Push commits and create a git tag
python scripts/push_tag.py
The push_tag.py script will:
- Show git status to help you catch uncommitted changes
- Ask for confirmation before proceeding
- Push all commits to origin
- Create and push a version tag (e.g.,
v0.4.3)
License
MIT
Support
- Open an issue
- Check existing issues for solutions
Metadata
Release files for aa-cli 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aa_cli-0.6.0.tar.gz | 70.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aa_cli-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 103.8 kB
Release files / aa_cli-0.6.0.tar.gz
| Download URL | aa_cli-0.6.0.tar.gz |
|---|---|
| Size | 70.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
99b7ee930cb54c1499b501bd36b5bc8a3a824436d4ad7c16fca0d67eceb26e86
|
|
BLAKE2b-256 checksum How to use checksums |
9893029402d094bea88b57b4f896f92825d797b2711123f5cb5744c9bcff642c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / aa_cli-0.6.0-py3-none-any.whl
| Download URL | aa_cli-0.6.0-py3-none-any.whl |
|---|---|
| Size | 33.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
013115346dd797e11139b9c0b915743f38fe9d69e0ed4018949a76536351f3dc
|
|
BLAKE2b-256 checksum How to use checksums |
77c800086e760a0cf3a5af82e000e85c692590fb7ecd67d980d6f0ea1a3a9993
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|