feat(system): audit cleanup: drone — fix ANSI escape corruption, add --rebase to git sync (#169)
* 📝 docs(STATUS): update last sync timestamp - update last sync timestamp to reflect recent status synchronization * feat(trigger): audit cleanup — fix timestamp parsing, CLI formatting, bypass entries - Fix log_watcher timestamp parsing: log warning once after all formats fail, not on each format attempt (was generating hundreds of warnings per scan) - Standardize rich formatting in branch_log_events and log_events print_help() to match medic.py/errors.py Panel+rule style - Add bypass entries for intentional silent catches (timestamp loop, error display) - Remove unused Path imports Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(memory): audit cleanup — handler tests + rollover timeout handling - Add 32 handler-layer tests (extractor, line_counter, normalize) in test_handlers.py - Add rollover run timeout message + try/except for graceful error handling - Fix commons welcome_ops.py missing _get_unwelcomed_branches function 264 tests pass, 100% seedgo compliance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(system): audit cleanup: spawn Co-Authored-By: @devpulse <devpulse@aipass> * feat(system): audit cleanup: drone — fix ANSI escape corruption, add --rebase to git sync Co-Authored-By: @devpulse <devpulse@aipass> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: @devpulse <devpulse@aipass>
This commit is contained in:
co-authored by
Claude Opus 4.6
@devpulse
parent
6e705eeb8e
commit
c8ad266175
@@ -13,3 +13,34 @@ API is the **centralized external API gateway** for AIPass. Provides authenticat
|
||||
- **Thread-safe mode:** `get_drive_service(thread_safe=True)` loads fresh creds from disk per call for concurrent workers.
|
||||
- **Google libs are optional deps** — guarded by `GOOGLE_AUTH_AVAILABLE` flag, commands fail explicitly with install instructions.
|
||||
- **After building:** Run `drone @seedgo audit aipass @api` before reporting complete.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `get-key [provider]` | Retrieve API key (default: openrouter) |
|
||||
| `validate [provider]` | Validate API key (default: openrouter) |
|
||||
| `validate google` | Validate Google OAuth2 credentials |
|
||||
| `reauth google` | Re-authenticate Google OAuth2 |
|
||||
| `test` | Test OpenRouter connection |
|
||||
| `models [--all]` | List available models |
|
||||
| `status` | OpenRouter client status |
|
||||
| `call "prompt" --model MODEL` | Make API call |
|
||||
| `list-providers` | List available providers |
|
||||
| `init` | Create .env template |
|
||||
| `track <gen_id> [caller]` | Track generation usage |
|
||||
| `stats` | Usage statistics |
|
||||
| `session` | Session usage summary |
|
||||
| `caller-usage <caller>` | Usage by caller |
|
||||
| `cleanup [days]` | Clean old usage data (default: 30) |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
api.py (entry, routing)
|
||||
→ modules/ (orchestration, CLI)
|
||||
→ handlers/ (business logic)
|
||||
```
|
||||
|
||||
**Modules:** `api_key`, `openrouter_client`, `usage_tracker`, `google_client`
|
||||
**Handlers:** `auth/`, `config/`, `openrouter/`, `usage/`, `json/`, `google/`
|
||||
|
||||
@@ -20,10 +20,9 @@ Business logic for provisioning OpenRouter API configs:
|
||||
- Ensure caller has complete 3-file JSON structure
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
from aipass.prax import logger
|
||||
|
||||
@@ -18,6 +18,8 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from rich.text import Text
|
||||
|
||||
from aipass.prax import logger
|
||||
from aipass.cli.apps.modules import console, err_console
|
||||
from aipass.drone.apps.modules import BranchNotFoundError, CommandExecutionError, RegistryError
|
||||
@@ -176,7 +178,9 @@ def _handle_module(name: str, args: List[str]) -> int:
|
||||
if not args:
|
||||
intro_text = get_module_introspective(name)
|
||||
if intro_text:
|
||||
console.print(intro_text, end="")
|
||||
# Text.from_ansi handles both pre-formatted ANSI (external modules)
|
||||
# and plain text (internal modules) correctly
|
||||
console.print(Text.from_ansi(intro_text), end="")
|
||||
else:
|
||||
console.print(f"No information available for @{name}.")
|
||||
return 0
|
||||
@@ -184,7 +188,7 @@ def _handle_module(name: str, args: List[str]) -> int:
|
||||
if args == ["--help"]:
|
||||
help_text = get_module_help(name)
|
||||
if help_text:
|
||||
console.print(help_text, end="")
|
||||
console.print(Text.from_ansi(help_text), end="")
|
||||
else:
|
||||
console.print(f"No help available for @{name}.")
|
||||
return 0
|
||||
|
||||
@@ -41,7 +41,7 @@ def sync_main() -> dict:
|
||||
return {"success": False, "message": msg, "stdout": result.stdout}
|
||||
|
||||
result = subprocess.run(
|
||||
["git", "pull"],
|
||||
["git", "pull", "--rebase"],
|
||||
capture_output=True, text=True, cwd=str(repo_root),
|
||||
)
|
||||
if result.returncode != 0:
|
||||
|
||||
@@ -63,9 +63,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
return False
|
||||
|
||||
if command == "craft":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_craft(args)
|
||||
elif command == "artifacts":
|
||||
result = _handle_list(args)
|
||||
|
||||
@@ -59,9 +59,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
return False
|
||||
|
||||
if command == "capsule":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_seal(args)
|
||||
elif command == "capsules":
|
||||
result = _handle_list(args)
|
||||
|
||||
@@ -61,10 +61,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
if command != "push-central":
|
||||
return False
|
||||
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
|
||||
try:
|
||||
stats = update_central()
|
||||
branch_count = len(stats.get("branch_stats", {}))
|
||||
|
||||
@@ -62,9 +62,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
True if command handled, False otherwise.
|
||||
"""
|
||||
if command == "comment":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_comment(args)
|
||||
elif command == "vote":
|
||||
result = _handle_vote(args)
|
||||
|
||||
@@ -66,9 +66,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
True if command handled, False otherwise.
|
||||
"""
|
||||
if command == "post":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_create_post(args)
|
||||
elif command == "thread":
|
||||
result = _handle_view_thread(args)
|
||||
|
||||
@@ -62,9 +62,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
True if command handled, False otherwise
|
||||
"""
|
||||
if command == "profile":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_profile(args)
|
||||
elif command == "who":
|
||||
result = _handle_who(args)
|
||||
|
||||
@@ -65,9 +65,6 @@ def handle_command(command: str, args: List[str]) -> bool:
|
||||
return False
|
||||
|
||||
if command == "gift":
|
||||
if not args:
|
||||
print_introspection()
|
||||
return True
|
||||
result = _handle_gift(args)
|
||||
elif command == "trade":
|
||||
result = _handle_trade(args)
|
||||
|
||||
Reference in New Issue
Block a user