feat(drone): docs(drone): comprehensive README update

Co-Authored-By: @drone <drone@aipass>
This commit is contained in:
AIOSAI
2026-04-22 21:25:10 -07:00
co-authored by @drone
parent ffa466354d
commit 8a59c9a8ec
+176 -46
View File
@@ -2,8 +2,9 @@
# Drone
**Purpose:** Command router and symbolic addressing for AIPass. Resolves `@branch` names to paths at runtime via `AIPASS_REGISTRY.json`, routes commands to module entry points, and discovers available commands across the system.
**Purpose:** Command router and symbolic addressing for AIPass. Resolves `@branch` names to paths at runtime via `AIPASS_REGISTRY.json`, routes commands to module entry points, manages git workflows, and discovers available commands across the system.
**Module:** `aipass.drone`
**Version:** 1.1.0
**Created:** 2026-03-05
---
@@ -13,8 +14,12 @@
### What I Do
- Resolve `@branch` symbolic names to absolute paths via `AIPASS_REGISTRY.json`
- Route commands to registered branches and internal modules
- Discover available commands across the system
- Manage git workflows: PR creation, branch sync, lock management, merge
- Discover and scan available commands across the system
- Provide `drone systems` introspection of all registered components
- Support external AIPass projects via dual registry lookup and module fallback
---
## Commands / Usage
@@ -23,23 +28,34 @@ Drone provides a CLI for terminal use and a Python API for programmatic access.
### CLI
```bash
drone systems # List all registered modules and branches
# Core routing
drone @seedgo audit aipass # Route "audit aipass" to seedgo
drone @module --help # Show help for any module
drone systems # List all registered modules and branches
# Git workflow
drone @git pr "description" # Create a PR from current branch
drone @git status # Git status scoped to branch directory
drone @git sync # Pull latest main with --rebase
drone @git sync --autostash # Sync with autostash for dirty trees
drone @git lock / unlock # Atomic branch lockfile
drone @git system-pr "desc" # System-wide PR (devpulse only)
drone @git merge <PR#> # Squash-merge a PR
# Git workflow (devpulse-authorized only)
drone @git system-pr "desc" # System-wide PR across all tracked changes
drone @git merge <PR#> # Straight-merge a PR and sync local main
drone @git smart-sync # Fetch + detect divergence + rebase
drone @git fix # Auto-fix stuck rebase / detached HEAD
drone @git fix --dry-run # Detect issues without fixing
# Command discovery
drone scan @branch # Discover available commands in a branch
drone activate @branch # Scan + register all commands from a branch
drone activate @branch # Scan + register all commands as shortcuts
drone list # List registered custom command shortcuts
drone remove <name> # Remove a custom command shortcut
# Utilities
drone hook-sounds on|off # Toggle hook notification sounds
drone --version # Show version
drone --version # Show version (v1.1.0)
drone --help # Show usage information
```
@@ -93,48 +109,103 @@ except CommandExecutionError as e:
## Architecture
### 3-Layer Pattern
```
drone/
├── cli.py # pip entry point (drone command)
├── __init__.py # Public API exports
├── cli.py # pip entry point (drone command)
├── __init__.py # Public API exports (v1.1.0)
├── apps/
│ ├── drone.py # Core entry point
│ ├── modules/ # Business logic
│ │ ├── config.py # Registry path resolution
│ │ ├── resolver.py # Branch resolution (@name -> path)
│ │ ├── router.py # Command routing via subprocess
│ │ ├── discovery.py # Module and command discovery
│ │ ├── module_registry.py # Internal module routing
│ │ ├── commands.py # Custom command shortcut orchestrator
│ │ ├── git_module.py # Git workflow (PR, status, sync, lock)
│ │ └── scan.py # Branch command scanning
│ ├── handlers/ # Implementation
│ │ ├── executor.py # Safe subprocess execution
│ │ ├── exceptions.py # Exception hierarchy
│ │ ├── generic_adapter.py # Centralized capture for external modules
│ │ ├── routing_config.json # External module routing declarations
│ │ ├── json/ # Three-JSON Pattern handler
│ │ ├── scanning/ # Scan result formatting + discovery
│ │ ├── command_registry/ # Command shortcut CRUD + lookup
│ │ └── git/ # Git workflow handlers
│ ├── drone.py # Core entry + CLI routing
│ ├── modules/ # Orchestrators (business logic)
│ │ ├── config.py # Registry path resolution
│ │ ├── resolver.py # Branch resolution (@name → path)
│ │ ├── router.py # Command routing via subprocess
│ │ ├── discovery.py # Module and command discovery
│ │ ├── module_registry.py # Internal module routing
│ │ ├── registry.py # Registry query operations
│ │ ├── commands.py # Custom command shortcut orchestrator
│ │ ├── git_module.py # Git workflow (9 commands + plugin routing)
│ │ └── scan.py # Branch command scanning
│ ├── handlers/ # Implementation details
│ │ ├── executor.py # Safe subprocess execution (timeout, no shell)
│ │ ├── exceptions.py # Exception hierarchy (10 exception types)
│ │ ├── router_handler.py # Routing implementation + caller detection
│ │ ├── registry_handler.py # Registry file ops + dual registry lookup
│ │ ├── discovery_handler.py # Discovery implementation + help parsing
│ │ ├── module_registry_handler.py # Module loading (internal + external)
│ │ ├── generic_adapter.py # StringIO capture for external modules
│ │ ├── routing_config.json # External module declarations
│ │ ├── json/
│ │ │ └── json_handler.py # Structured operation logging
│ │ ├── scanning/
│ │ │ ├── scanner.py # Help parsing + modules/ file scanning
│ │ │ └── formatters.py # Rich output for scan results
│ │ ├── command_registry/
│ │ │ ├── ops.py # Command shortcut CRUD
│ │ │ ├── lookup.py # Greedy multi-word matching
│ │ │ └── formatters.py # Rich output for command lists
│ │ └── git/
│ │ ├── lock_handler.py # Atomic lockfile (O_CREAT|O_EXCL)
│ │ ├── pr_handler.py # 10-step PR workflow
│ │ ├── status_handler.py # Scoped git status (subprocess)
│ │ ├── status_handler_gitpython.py # [prototype] GitPython status — DPLAN-0140 Phase 1, not wired in
│ │ └── sync_handler.py # Safe main sync
│ └── plugins/ # Extensions beyond core routing
│ └── devpulse_ops/ # System-wide PR, merge, smart-sync, fix
├── docs/ # Documentation
└── tests/ # 529+ tests, 19 test files
│ │ ├── pr_handler.py # 10-step PR workflow with scoped staging
│ │ ├── status_handler.py # Scoped git status (subprocess)
│ │ ├── status_handler_gitpython.py # [prototype] DPLAN-0140 Phase 1, not wired in
│ │ └── sync_handler.py # Safe main sync (--autostash support)
│ └── plugins/
│ ├── devpulse_ops/ # Privileged git operations (auth-gated)
│ │ ├── auth.py # Passport-based identity gate (ALLOWED_CALLERS)
│ │ ├── pr_plugin.py # System-wide PR (git add -A, system/ branches)
│ │ ├── merge_plugin.py # PR merge (--merge) + local sync
│ │ ├── sync_plugin.py # Smart sync (fetch, divergence detect, rebase)
│ │ └── fix_plugin.py # Auto-fix stuck rebase / detached HEAD
│ └── hook_sounds/
│ └── hook_sounds_plugin.py # Toggle notification sounds on/off
├── docs/ # Public documentation
├── docs.local/ # Investigation reports and policies
└── tests/ # 530 tests across 20 test files
```
### Routing Flow
1. **CLI input** → `drone.py:main()`
2. **Built-in commands** checked first: `systems`, `scan`, `activate`, `list`, `remove`, `hook-sounds`
3. **`@target` routing** → branch resolution via `AIPASS_REGISTRY.json` → subprocess dispatch
4. **Module fallback** → if branch not found but is a registered module, routes internally
5. **Bare module names** → auto-discovered from `apps/modules/*.py`, routed via `importlib`
6. **Custom commands** → greedy multi-word matching against `drone_command_registry.json`
### Module System
Drone routes to two kinds of modules:
| Type | Modules | Routing |
|------|---------|---------|
| Internal | `git` | `importlib` import → `handle_command()` |
| External | `seedgo`, `cli`, `spawn` | `generic_adapter.capture_main()` via `routing_config.json` |
External modules are declared in `apps/handlers/routing_config.json` with entry points, descriptions, and versions.
### Git Main-Only Enforcement
All agents work on `main`. Branch creation is only allowed inside `drone @git system-pr`, which:
1. Commits changes on main
2. Moves branch pointer with `git branch -f` (HEAD stays on main)
3. Pushes branch with `--force-with-lease`
4. Opens PR via `gh`
5. Returns to main
Enforcement layers:
- `.claude/settings.json` deny rules block `git checkout -b`, `git switch -c`
- `_assert_on_main_or_pr_flow()` guard in `git_module.py`
- Persistent citizen branches: `citizen/{name}` reused across PRs
---
## Interactive Commands
By default, drone captures subprocess output (`capture_output=True`) with a 30s timeout. This is safe for AI-to-AI routing but strips Rich colors, buffers progress bars, and kills long-running commands.
Commands in the interactive tuple bypass capture and inherit the terminal directly — enabling live Rich output, colors, and no timeout. Only add commands here when the user needs full terminal experience.
Commands in the interactive tuple bypass capture and inherit the terminal directly — enabling live Rich output, colors, and no timeout.
**Per-command allowlist** (in `apps/drone.py`):
@@ -142,6 +213,7 @@ Commands in the interactive tuple bypass capture and inherit the terminal direct
|--------------|---------------------------------------------|
| `monitor` | Prax real-time monitoring (live TUI) |
| `audit` | Seedgo audit (Rich progress bars) |
| `watchdog` | Devpulse watchdog (live monitoring) |
**Per-branch allowlist** — all commands from these branches get interactive mode:
@@ -149,32 +221,90 @@ Commands in the interactive tuple bypass capture and inherit the terminal direct
|----------|-----------------------------------------------|
| `cli` | User-facing CLI with Rich formatted output |
To add: edit `interactive_commands` or `interactive_branches` in `_handle_target()` in `apps/drone.py`.
To add: edit `INTERACTIVE_COMMANDS` or `INTERACTIVE_BRANCHES` in `apps/drone.py`.
---
## Plugin System
Plugins live in `apps/plugins/{name}/` — outside the 3-layer structure by design.
### devpulse_ops
Auth-gated operations for system administration. `auth.py` walks CWD for `.trinity/passport.json` and checks `branch_name` against `ALLOWED_CALLERS` (devpulse, seedgo, spawn).
| Plugin | Command | Purpose |
|--------|---------|---------|
| `pr_plugin` | `system-pr` | System-wide PR across all tracked changes |
| `merge_plugin` | `merge` | Straight-merge a PR and sync local main |
| `sync_plugin` | `smart-sync` | Fetch + detect divergence + rebase |
| `fix_plugin` | `fix` | Auto-fix stuck rebase / detached HEAD |
### hook_sounds
Simple toggle for hook notification sounds. Creates/removes `/tmp/aipass-hooks-muted` flag file.
---
## External Project Support
Infrastructure modules (seedgo, cli, git, spawn) work from external AIPass projects without per-project registration.
**Dual registry lookup:** `registry_handler.py` merges local project registry with `AIPASS_HOME` registry. Local entries win on name collision.
**Module fallback:** When subprocess routing fails (branch not in local registry), drone falls back to module routing for registered modules. Graceful degradation: Rich output from AIPass, functional output from external projects.
**AIPASS_HOME hints:** When `AIPASS_HOME` is not set and the local registry lacks core branches, drone shows setup hints:
```
Tip: set AIPASS_HOME=/path/to/AIPass to access all branches
```
---
## Integration Points
### Depends On
- `AIPASS_REGISTRY.json` — Branch registry at repo root (read for resolution)
- Python stdlib (`pathlib`, `sys`, `subprocess`, `json`)
- `AIPASS_REGISTRY.json` — Branch registry (read for resolution)
- `gh` CLI — GitHub operations (PR creation, merge)
- Python stdlib (`pathlib`, `sys`, `subprocess`, `json`, `threading`)
### Provides To
- All modules — command routing via `drone @target command`
- All modules — branch/module discovery via `drone systems`
- All branches — command routing via `drone @target command`
- All branches — module/branch discovery via `drone systems`
- External modules — `generic_adapter.capture_main()` for subprocess-free routing
- `aipass.seedgo` — routed via `drone @seedgo`
- `aipass.cli` — routed via `drone @cli`
- `aipass.spawn` — routed via `drone @spawn`
---
## External Project Support
## Testing
Infrastructure modules (seedgo, cli, git) work from external AIPass projects without per-project registration. When subprocess routing fails (branch not in local registry), drone falls back to module routing automatically. Graceful degradation: Rich output from AIPass, functional output from external projects.
530 tests across 20 test files, covering all layers:
| Area | Files | Tests |
|------|-------|-------|
| Core routing | `test_resolver.py`, `test_router.py`, `test_activation.py` | ~128 |
| Git operations | `test_git_module.py`, `test_system_pr.py`, `test_devpulse_plugins.py` | ~95 |
| Handlers | `test_executor.py`, `test_registry_handler.py`, `test_discovery.py` | ~99 |
| Infrastructure | `test_generic_adapter.py`, `test_module_registry.py`, `test_config.py` | ~66 |
| Features | `test_commands.py`, `test_scan.py`, `test_hook_sounds.py`, `test_json_handler.py` | ~125 |
| Standards | `test_cli_routing.py`, `test_contracts.py`, `test_error_resilience.py`, `test_init_provisioning.py` | ~21 |
Run tests: `cd src/aipass/drone && python -m pytest tests/ -q`
---
**Last Updated:** 2026-04-21
## Known Issues
- `status_handler_gitpython.py` is an unreferenced prototype (DPLAN-0140 Phase 1) — awaiting Phase 2/3
- `update_command()` and `command_exists()` in `ops.py` are tested CRUD API but unused from production
- Pyright warns about `json` package name shadowing stdlib — works at runtime
- Recurring sync errors when working tree is dirty — operational, not code bugs
---
**Seedgo:** 100% (34/34) | **Tests:** 530 pass, 4 skip | **Last Updated:** 2026-04-22
---
[← Back to AIPass](../../../README.md)