update 1 file, create 421 files and delete 4 files

This commit is contained in:
AIOSAI
2026-03-05 15:22:59 -08:00
parent 291331b3c3
commit 019a69141e
426 changed files with 57505 additions and 11 deletions
+13 -3
View File
@@ -1,8 +1,8 @@
{
"metadata": {
"version": "1.0.0",
"last_updated": "2026-02-27",
"total_branches": 30
"last_updated": "2026-03-05",
"total_branches": 31
},
"branches": [
{
@@ -246,6 +246,16 @@
"created": "2025-11-12",
"last_active": "2025-11-12"
},
{
"name": "SEEDGO",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/seedgo",
"profile": "library",
"description": "Enforce code standards through pluggable standard packs with 3-source discovery",
"email": "@seedgo",
"status": "active",
"created": "2026-03-05",
"last_active": "2026-03-05"
},
{
"name": "SPEAKEASY",
"alias": "Speakeasy",
@@ -338,4 +348,4 @@
"last_active": "2026-02-17"
}
]
}
}
@@ -0,0 +1,37 @@
{
"metadata": {
"version": "1.0.0",
"description": "Files and patterns to exclude when creating branch backups"
},
"ignore_directories": [
".backup",
".venv",
"venv",
"node_modules",
"__pycache__",
".git",
".cache",
".pytest_cache",
".mypy_cache",
"dist",
"build",
"*.egg-info",
"ai_mail.local",
"logs",
".aipass",
".archive",
".claude",
"htmlcov"
],
"ignore_patterns": [
"*.pyc",
"*.pyo",
".DS_Store",
"*.log",
"*.tmp",
"*.swp",
"*~",
"*.env",
"BRANCH_REGISTRY.json"
]
}
@@ -0,0 +1,49 @@
{
"metadata": {
"version": "1.0.0",
"description": "Template structural migrations for branch updates",
"last_updated": "2025-11-07",
"applies_to_versions": ["all"]
},
"migrations": [
{
"id": "m001",
"description": "Example: Migrate flat metadata to document_metadata structure",
"version_introduced": "1.0.0",
"applies_to_files": ["*.id.json"],
"operations": [
{
"type": "key_rename",
"from": "metadata",
"to": "document_metadata"
},
{
"type": "move_to_nested",
"source_keys": ["branch_name", "path", "profile"],
"target_parent": "branch_info"
},
{
"type": "add_missing_keys",
"parent": "document_metadata",
"keys": {
"document_type": "branch_identity",
"schema_version": "1.0.0"
}
}
]
}
],
"options": {
"skip_if_target_exists": true,
"preserve_unknown_keys": true,
"recursive_application": false
},
"notes": {
"usage": "This file defines structural transformation rules applied during branch updates",
"pattern_matching": "applies_to_files uses glob patterns (*.json, *.id.json, etc.)",
"operation_order": "Operations execute in order listed within each migration",
"skip_behavior": "Operations skip if already compliant (target exists = success)",
"supported_operations": ["key_rename", "move_to_nested", "add_missing_keys"],
"future_operations": ["split_key", "combine_keys", "delete_key", "transform_value"]
}
}
@@ -0,0 +1,43 @@
{
"metadata": {
"version": "1.1.0",
"description": "Files and patterns to exclude when updating branches from template",
"last_updated": "2025-11-09"
},
"ignore_files": [
".template_registry.json",
".registry_ignore.json"
],
"ignore_patterns": [
"__pycache__",
"*.pyc",
"#@comments.txt",
".backup_*"
],
"notes": {
"how_it_works": "Two types of exclusions during branch updates:",
"ignore_files": {
"description": "Exact filename matches (no wildcards)",
"purpose": "Template-internal management files that branches don't need",
"examples": [
".template_registry.json (template's file tracking list)",
".registry_ignore.json (this config file)"
]
},
"ignore_patterns": {
"description": "Glob patterns - matches filenames AND directory names",
"purpose": "Exclude generated files, caches, and user content markers",
"examples": [
"__pycache__ (Python cache directories)",
"*.pyc (Python compiled bytecode files)",
"#@comments.txt (user comment files)",
".backup_* (timestamped backup files like .backup_20251109, NOT .backup directory)"
],
"how_matching_works": [
"Step 1: Check if filename matches pattern (e.g., file.pyc matches *.pyc)",
"Step 2: Check if any parent directory matches (e.g., files inside __pycache__/ dir)"
]
},
"what_gets_ignored": "These files never copy to branches during updates - they stay template-only"
}
}
@@ -0,0 +1,184 @@
{
"metadata": {
"description": "Template registry for tracking files",
"generated": true
},
"files": {
"f001": {
"path": ".aipass/aipass_local_prompt.md",
"name": "aipass_local_prompt.md",
"content_hash": "2658c0af3146e5a3",
"has_branch_placeholder": false
},
"f002": {
"path": ".claude/settings.local.json",
"name": "settings.local.json",
"content_hash": "6379c5be3fb714ac",
"has_branch_placeholder": false
},
"f003": {
"path": ".gitignore",
"name": ".gitignore",
"content_hash": "841dedb922da7ddb",
"has_branch_placeholder": false
},
"f004": {
"path": ".trinity/local.json",
"name": "local.json",
"content_hash": "bf358f3ea5bb2102",
"has_branch_placeholder": false
},
"f005": {
"path": ".trinity/observations.json",
"name": "observations.json",
"content_hash": "f262954fadc0255c",
"has_branch_placeholder": false
},
"f006": {
"path": ".trinity/passport.json",
"name": "passport.json",
"content_hash": "5e27bfc842901e85",
"has_branch_placeholder": false
},
"f007": {
"path": "DASHBOARD.local.json",
"name": "DASHBOARD.local.json",
"content_hash": "a90284523ed31500",
"has_branch_placeholder": false
},
"f008": {
"path": "README.md",
"name": "README.md",
"content_hash": "cade5edfc7702afc",
"has_branch_placeholder": false
},
"f009": {
"path": "apps/__init__.py",
"name": "__init__.py",
"content_hash": "468c3775af1fba3f",
"has_branch_placeholder": false
},
"f010": {
"path": "apps/branch.py",
"name": "branch.py",
"content_hash": "7c2ba42faecb752a",
"has_branch_placeholder": false
},
"f011": {
"path": "apps/handlers/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f012": {
"path": "apps/modules/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f013": {
"path": "apps/plugins/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f014": {
"path": "artifacts/birth_certificate.json",
"name": "birth_certificate.json",
"content_hash": "6eb88a4189013801",
"has_branch_placeholder": false
},
"f015": {
"path": "flow.local.md",
"name": "flow.local.md",
"content_hash": "c54c27b66394a741",
"has_branch_placeholder": false
},
"f016": {
"path": "pytest.ini",
"name": "pytest.ini",
"content_hash": "7b39ba7bca4025c5",
"has_branch_placeholder": false
},
"f017": {
"path": "tests/__init__.py",
"name": "__init__.py",
"content_hash": "cbf001d73714f7cd",
"has_branch_placeholder": false
},
"f018": {
"path": "tests/conftest.py",
"name": "conftest.py",
"content_hash": "5e5f2399e0d70978",
"has_branch_placeholder": false
},
"f019": {
"path": "tools/verify_branch.py",
"name": "verify_branch.py",
"content_hash": "06803a84118e5453",
"has_branch_placeholder": false
}
},
"directories": {
"d001": {
"path": ".aipass",
"name": ".aipass"
},
"d002": {
"path": ".archive",
"name": ".archive"
},
"d003": {
"path": ".claude",
"name": ".claude"
},
"d004": {
"path": ".trinity",
"name": ".trinity"
},
"d005": {
"path": "ai_mail_json",
"name": "ai_mail_json"
},
"d006": {
"path": "apps",
"name": "apps"
},
"d007": {
"path": "apps/handlers",
"name": "handlers"
},
"d008": {
"path": "apps/modules",
"name": "modules"
},
"d009": {
"path": "apps/plugins",
"name": "plugins"
},
"d010": {
"path": "artifacts",
"name": "artifacts"
},
"d011": {
"path": "docs",
"name": "docs"
},
"d012": {
"path": "dropbox",
"name": "dropbox"
},
"d013": {
"path": "templates",
"name": "templates"
},
"d014": {
"path": "tests",
"name": "tests"
},
"d015": {
"path": "tools",
"name": "tools"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
__pycache__/
*.pyc
*.pyo
.env
*.egg-info/
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
dist/
build/
*.log
*.tmp
*.swp
+34
View File
@@ -0,0 +1,34 @@
{
"document_metadata": {
"document_type": "session_history",
"document_name": "AI_MAIL.LOCAL",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "AI_MAIL",
"tags": ["session_tracking", "work_log", "AI_MAIL"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"active_tasks": {
"today_focus": "2026-03-05",
"recently_completed": []
},
"key_learnings": {},
"sessions": [
{
"session_number": 1,
"date": "2026-03-05",
"summary": "Branch initialized - AI_MAIL created by aipass init",
"status": "completed"
}
]
}
@@ -0,0 +1,37 @@
{
"document_metadata": {
"document_type": "collaboration_patterns",
"document_name": "AI_MAIL.OBSERVATIONS",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "AI_MAIL",
"tags": ["collaboration", "patterns", "AI_MAIL"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"guidelines": {
"purpose": "Capture collaboration patterns and experiential insights over time",
"chronological_order": "Newest entries at TOP, oldest at BOTTOM - NEVER reorder"
},
"observations": [
{
"date": "2026-03-05",
"session": 1,
"entries": [
{
"title": "First Contact",
"detail": "Branch initialized. Ready to begin capturing collaboration patterns."
}
]
}
]
}
+36
View File
@@ -0,0 +1,36 @@
{
"document_metadata": {
"document_type": "branch_identity",
"document_name": "AI_MAIL.PASSPORT",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "AI_MAIL",
"tags": ["identity", "passport", "branch_profile"]
},
"branch_info": {
"branch_name": "AI_MAIL",
"alias": "",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/ai_mail",
"module": "ai_mail",
"created": "2026-03-05"
},
"identity": {
"role": "Agent Messaging",
"purpose": "",
"what_i_do": [],
"what_i_dont_do": []
},
"principles": [
"Code is truth - fail honestly",
"Memory persists - context survives",
"Simple solutions over complex architecture"
],
"citizenship": {
"registered": true,
"registry_path": ".aipass/registry.json",
"communications": true,
"memory": true
}
}
+62
View File
@@ -0,0 +1,62 @@
{
"_warning": "AUTO-GENERATED FILE - DO NOT MANUALLY EDIT. This file is 100% automated and will be overwritten. Services update their own sections.",
"branch": "AI_MAIL",
"last_updated": "2026-03-05",
"quick_status": {
"new_mail": 0,
"opened_mail": 0,
"active_plans": 0,
"commons_mentions": 0,
"action_required": false,
"summary": ""
},
"sections": {
"ai_mail": {
"managed_by": "ai_mail",
"new": 0,
"opened": 0,
"total": 0,
"oldest_unread_age": null,
"last_dispatch_received": null,
"last_updated": "2026-03-05"
},
"flow": {
"managed_by": "flow",
"active_plans": 0,
"recently_closed": [],
"last_updated": "2026-03-05"
},
"memory_bank": {
"managed_by": "memory_bank",
"vectors_stored": 0,
"notes": {},
"last_updated": "2026-03-05"
},
"devpulse": {
"managed_by": "devpulse",
"summary": {
"issues": 0,
"todos": 0
},
"dplan_counts": {},
"recent_activity": "",
"last_updated": "2026-03-05"
},
"commons_activity": {
"managed_by": "the_commons",
"new_posts_since_last_visit": 0,
"new_comments_since_last_visit": 0,
"mentions": 0,
"trending": "None",
"last_checked": null,
"last_updated": "2026-03-05"
},
"agent_status": {
"managed_by": "prax",
"active_agents": [],
"agent_count": 0,
"stale_agents": [],
"last_updated": "2026-03-05"
}
}
}
+51
View File
@@ -0,0 +1,51 @@
# AI_MAIL
**Purpose:** Inter-agent messaging, inbox management, dispatch delivery
**Module:** `aipass.ai_mail`
**Created:** 2026-03-05
---
## Overview
### What I Do
### How I Work
- **Entry Point:** `apps/ai_mail.py`
- **Pattern:** Auto-discovers and routes to modules
---
## Architecture
```
AI_MAIL/
├── apps/
│ ├── ai_mail.py # Entry point
│ ├── modules/ # Business logic
│ ├── handlers/ # Implementation
│ └── plugins/ # Extensions
├── docs/
├── tests/
├── passport.json # Identity
├── local.json # Session history
├── observations.json # Collaboration patterns
└── README.md
```
---
## Commands
*Configure after initialization*
---
## Integration Points
### Depends On
### Provides To
+1
View File
@@ -0,0 +1 @@
# AI_MAIL apps package
+86
View File
@@ -0,0 +1,86 @@
"""
AI_MAIL Branch - Main Orchestrator
Auto-discovery architecture:
- Scans modules/ directory for .py files with handle_command()
- Routes commands to discovered modules automatically
- No manual imports or routing needed
"""
import sys
import importlib
from pathlib import Path
from typing import List, Any
from aipass.prax import logger
# =============================================================================
# MODULE DISCOVERY
# =============================================================================
MODULES_DIR = Path(__file__).parent / "modules"
def discover_modules() -> List[Any]:
"""Auto-discover modules in modules/ directory."""
modules = []
if not MODULES_DIR.exists():
return modules
for file_path in MODULES_DIR.glob("*.py"):
if file_path.name.startswith("_"):
continue
module_name = f"apps.modules.{file_path.stem}"
try:
module = importlib.import_module(module_name)
if hasattr(module, "handle_command"):
modules.append(module)
except Exception as e:
logger.error(f"[AI_MAIL] Failed to load module {module_name}: {e}")
return modules
def route_command(command: str, args: List[str], modules: List[Any]) -> bool:
"""Route command to appropriate module."""
for module in modules:
try:
if module.handle_command(command, args):
return True
except Exception as e:
logger.error(f"[AI_MAIL] Module {module.__name__} error: {e}")
return False
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point - routes commands or shows help."""
modules = discover_modules()
args = sys.argv[1:]
if len(args) == 0 or args[0] in ["--help", "-h", "help"]:
print(f"AI_MAIL - {len(modules)} modules discovered")
for module in modules:
name = module.__name__.split(".")[-1]
desc = (module.__doc__ or "").strip().split("\n")[0] if module.__doc__ else "No description"
print(f" {name:20} {desc}")
return 0
command = args[0]
remaining = args[1:] if len(args) > 1 else []
if route_command(command, remaining, modules):
return 0
print(f"Unknown command: {command}")
return 1
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,15 @@
{
"id": "32",
"name": "AI_MAIL Birth Certificate",
"type": "birth_certificate",
"creator": "SYSTEM",
"owner": "AI_MAIL",
"rarity": "unique",
"description": "Official birth certificate for AI_MAIL. Citizen #32, registered using 'library' template. Purpose: Inter-agent messaging, inbox management, dispatch delivery",
"metadata": {
"citizen_number": "32",
"template": "library",
"purpose": "Inter-agent messaging, inbox management, dispatch delivery"
},
"created_at": "2026-03-05"
}
+15
View File
@@ -0,0 +1,15 @@
# flow.local.md - AI_MAIL
```
Branch: /home/aipass/aipass_business/AIPass/src/aipass/ai_mail
Created: 2026-03-05
```
## Issues
-
---
## Todos
-
+21
View File
@@ -0,0 +1,21 @@
[pytest]
# Test discovery paths
testpaths = tests
# Test file patterns
python_files = test_*.py
python_functions = test_*
python_classes = Test*
# Command-line options (always applied)
addopts =
-v # Verbose output
--tb=short # Short traceback format
--strict-markers # Raise error on unknown markers
-ra # Show summary of all test outcomes
# Test markers (for categorizing tests)
markers =
unit: Unit tests
integration: Integration tests
slow: Tests that take significant time
+1
View File
@@ -0,0 +1 @@
# Tests package for ai_mail
+43
View File
@@ -0,0 +1,43 @@
#!/home/aipass/.venv/bin/python3
# ===================AIPASS====================
# META DATA HEADER
# Name: tests/conftest.py
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/tests
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Shared pytest fixtures
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""Shared pytest fixtures for cortex tests"""
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
@pytest.fixture
def temp_test_dir() -> Generator[Path, None, None]:
"""Creates temporary directory for testing, cleans up after"""
test_dir = Path(tempfile.mkdtemp())
yield test_dir
if test_dir.exists():
shutil.rmtree(test_dir)
@pytest.fixture
def sample_test_data() -> dict:
"""Provides sample test data
Customize this fixture for your module's needs
"""
return {
"test_key": "test_value",
"sample_data": "example"
}
+159
View File
@@ -0,0 +1,159 @@
#!/home/aipass/.venv/bin/python3
# -*- coding: utf-8 -*-
# ===================AIPASS====================
# META DATA HEADER
# Name: verify_branch.py - Branch Template Verification
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/modules
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Compare template vs branch
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""
Branch Template Verification Tool
Compares template directory with created branch to identify:
- Files in template but missing in branch
- Files in branch but not in template
- Renamed files
"""
import sys
import json
from pathlib import Path
from typing import Set, List, Tuple
from fnmatch import fnmatch
# INFRASTRUCTURE IMPORT PATTERN
AIPASS_ROOT = Path.home() / "aipass_core"
sys.path.insert(0, str(AIPASS_ROOT))
# Get template directory
TEMPLATE_DIR = AIPASS_ROOT / "cortex" / "templates" / "branch_template"
def load_ignore_patterns() -> Tuple[List[str], List[str]]:
"""Load ignore patterns from .registry_ignore.json"""
ignore_file = TEMPLATE_DIR / ".registry_ignore.json"
if not ignore_file.exists():
return [], []
try:
with open(ignore_file, 'r', encoding='utf-8') as f:
data = json.load(f)
ignore_files = data.get("ignore_files", [])
ignore_patterns = data.get("ignore_patterns", [])
return ignore_files, ignore_patterns
except Exception as e:
print(f"Warning: Could not load .registry_ignore.json: {e}")
return [], []
def should_exclude(path: Path, base_dir: Path, ignore_files: List[str], ignore_patterns: List[str]) -> bool:
"""Check if path should be excluded based on ignore patterns"""
rel_path = path.relative_to(base_dir)
filename = path.name
path_str = str(rel_path)
# Check exact filename matches
if filename in ignore_files:
return True
# Check glob patterns
for pattern in ignore_patterns:
if fnmatch(filename, pattern):
return True
# Check if any parent directory matches
for part in rel_path.parts:
if fnmatch(part, pattern):
return True
return False
def get_file_set(directory: Path, ignore_files: List[str], ignore_patterns: List[str]) -> Set[str]:
"""Get set of all file paths in directory (relative)"""
files = set()
for item in directory.rglob("*"):
if item.is_file() and not should_exclude(item, directory, ignore_files, ignore_patterns):
rel_path = str(item.relative_to(directory))
files.add(rel_path)
return files
def verify_branch(branch_dir: Path) -> Tuple[List[str], List[str], List[str]]:
"""
Compare template with branch
Returns:
Tuple of (in_template_only, in_branch_only, in_both)
"""
# Load ignore patterns from .registry_ignore.json
ignore_files, ignore_patterns = load_ignore_patterns()
template_files = get_file_set(TEMPLATE_DIR, ignore_files, ignore_patterns)
branch_files = get_file_set(branch_dir, ignore_files, ignore_patterns)
in_template_only = sorted(template_files - branch_files)
in_branch_only = sorted(branch_files - template_files)
in_both = sorted(template_files & branch_files)
return in_template_only, in_branch_only, in_both
def main():
if len(sys.argv) < 2:
print("Usage: python3 verify_branch.py <branch_directory>")
print("Example: python3 verify_branch.py test_branch002")
sys.exit(1)
branch_path = Path(sys.argv[1])
if not branch_path.is_absolute():
# Assume it's relative to cortex directory
branch_path = Path.cwd() / branch_path
if not branch_path.exists():
print(f"❌ ERROR: Branch directory not found: {branch_path}")
sys.exit(1)
print(f"\n=== Branch Verification ===")
print(f"Template: {TEMPLATE_DIR}")
print(f"Branch: {branch_path}")
print()
in_template_only, in_branch_only, in_both = verify_branch(branch_path)
print(f"Files in both: {len(in_both)}")
print(f"Files in template only: {len(in_template_only)}")
print(f"Files in branch only: {len(in_branch_only)}")
print()
if in_template_only:
print("❌ Missing from branch (expected from template):")
for file in in_template_only:
print(f" - {file}")
print()
if in_branch_only:
print("✅ Additional files in branch (renamed or new):")
for file in in_branch_only:
print(f" + {file}")
print()
if not in_template_only and not in_branch_only:
print("✅ Branch matches template perfectly")
print("="*70)
if __name__ == "__main__":
main()
+37
View File
@@ -0,0 +1,37 @@
{
"metadata": {
"version": "1.0.0",
"description": "Files and patterns to exclude when creating branch backups"
},
"ignore_directories": [
".backup",
".venv",
"venv",
"node_modules",
"__pycache__",
".git",
".cache",
".pytest_cache",
".mypy_cache",
"dist",
"build",
"*.egg-info",
"ai_mail.local",
"logs",
".aipass",
".archive",
".claude",
"htmlcov"
],
"ignore_patterns": [
"*.pyc",
"*.pyo",
".DS_Store",
"*.log",
"*.tmp",
"*.swp",
"*~",
"*.env",
"BRANCH_REGISTRY.json"
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"metadata": {
"version": "1.0.0",
"description": "Template structural migrations for branch updates",
"last_updated": "2025-11-07",
"applies_to_versions": ["all"]
},
"migrations": [
{
"id": "m001",
"description": "Example: Migrate flat metadata to document_metadata structure",
"version_introduced": "1.0.0",
"applies_to_files": ["*.id.json"],
"operations": [
{
"type": "key_rename",
"from": "metadata",
"to": "document_metadata"
},
{
"type": "move_to_nested",
"source_keys": ["branch_name", "path", "profile"],
"target_parent": "branch_info"
},
{
"type": "add_missing_keys",
"parent": "document_metadata",
"keys": {
"document_type": "branch_identity",
"schema_version": "1.0.0"
}
}
]
}
],
"options": {
"skip_if_target_exists": true,
"preserve_unknown_keys": true,
"recursive_application": false
},
"notes": {
"usage": "This file defines structural transformation rules applied during branch updates",
"pattern_matching": "applies_to_files uses glob patterns (*.json, *.id.json, etc.)",
"operation_order": "Operations execute in order listed within each migration",
"skip_behavior": "Operations skip if already compliant (target exists = success)",
"supported_operations": ["key_rename", "move_to_nested", "add_missing_keys"],
"future_operations": ["split_key", "combine_keys", "delete_key", "transform_value"]
}
}
@@ -0,0 +1,43 @@
{
"metadata": {
"version": "1.1.0",
"description": "Files and patterns to exclude when updating branches from template",
"last_updated": "2025-11-09"
},
"ignore_files": [
".template_registry.json",
".registry_ignore.json"
],
"ignore_patterns": [
"__pycache__",
"*.pyc",
"#@comments.txt",
".backup_*"
],
"notes": {
"how_it_works": "Two types of exclusions during branch updates:",
"ignore_files": {
"description": "Exact filename matches (no wildcards)",
"purpose": "Template-internal management files that branches don't need",
"examples": [
".template_registry.json (template's file tracking list)",
".registry_ignore.json (this config file)"
]
},
"ignore_patterns": {
"description": "Glob patterns - matches filenames AND directory names",
"purpose": "Exclude generated files, caches, and user content markers",
"examples": [
"__pycache__ (Python cache directories)",
"*.pyc (Python compiled bytecode files)",
"#@comments.txt (user comment files)",
".backup_* (timestamped backup files like .backup_20251109, NOT .backup directory)"
],
"how_matching_works": [
"Step 1: Check if filename matches pattern (e.g., file.pyc matches *.pyc)",
"Step 2: Check if any parent directory matches (e.g., files inside __pycache__/ dir)"
]
},
"what_gets_ignored": "These files never copy to branches during updates - they stay template-only"
}
}
@@ -0,0 +1,184 @@
{
"metadata": {
"description": "Template registry for tracking files",
"generated": true
},
"files": {
"f001": {
"path": ".aipass/aipass_local_prompt.md",
"name": "aipass_local_prompt.md",
"content_hash": "c3820174d35b6196",
"has_branch_placeholder": false
},
"f002": {
"path": ".claude/settings.local.json",
"name": "settings.local.json",
"content_hash": "6379c5be3fb714ac",
"has_branch_placeholder": false
},
"f003": {
"path": ".gitignore",
"name": ".gitignore",
"content_hash": "841dedb922da7ddb",
"has_branch_placeholder": false
},
"f004": {
"path": ".trinity/local.json",
"name": "local.json",
"content_hash": "163f753b4ca6b91e",
"has_branch_placeholder": false
},
"f005": {
"path": ".trinity/observations.json",
"name": "observations.json",
"content_hash": "50b6b9667f536132",
"has_branch_placeholder": false
},
"f006": {
"path": ".trinity/passport.json",
"name": "passport.json",
"content_hash": "72fea4e37901fc92",
"has_branch_placeholder": false
},
"f007": {
"path": "DASHBOARD.local.json",
"name": "DASHBOARD.local.json",
"content_hash": "adf8583e2e9f9638",
"has_branch_placeholder": false
},
"f008": {
"path": "README.md",
"name": "README.md",
"content_hash": "742a7cf14d085a2f",
"has_branch_placeholder": false
},
"f009": {
"path": "apps/__init__.py",
"name": "__init__.py",
"content_hash": "436dab8c706a5c20",
"has_branch_placeholder": false
},
"f010": {
"path": "apps/branch.py",
"name": "branch.py",
"content_hash": "ec1b725be2b76957",
"has_branch_placeholder": false
},
"f011": {
"path": "apps/handlers/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f012": {
"path": "apps/modules/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f013": {
"path": "apps/plugins/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f014": {
"path": "artifacts/birth_certificate.json",
"name": "birth_certificate.json",
"content_hash": "6804a2f6aa7900df",
"has_branch_placeholder": false
},
"f015": {
"path": "flow.local.md",
"name": "flow.local.md",
"content_hash": "3eb19b2da09318ad",
"has_branch_placeholder": false
},
"f016": {
"path": "pytest.ini",
"name": "pytest.ini",
"content_hash": "7b39ba7bca4025c5",
"has_branch_placeholder": false
},
"f017": {
"path": "tests/__init__.py",
"name": "__init__.py",
"content_hash": "ae4d4d2b382cf7b2",
"has_branch_placeholder": false
},
"f018": {
"path": "tests/conftest.py",
"name": "conftest.py",
"content_hash": "5e5f2399e0d70978",
"has_branch_placeholder": false
},
"f019": {
"path": "tools/verify_branch.py",
"name": "verify_branch.py",
"content_hash": "06803a84118e5453",
"has_branch_placeholder": false
}
},
"directories": {
"d001": {
"path": ".aipass",
"name": ".aipass"
},
"d002": {
"path": ".archive",
"name": ".archive"
},
"d003": {
"path": ".claude",
"name": ".claude"
},
"d004": {
"path": ".trinity",
"name": ".trinity"
},
"d005": {
"path": "api_json",
"name": "api_json"
},
"d006": {
"path": "apps",
"name": "apps"
},
"d007": {
"path": "apps/handlers",
"name": "handlers"
},
"d008": {
"path": "apps/modules",
"name": "modules"
},
"d009": {
"path": "apps/plugins",
"name": "plugins"
},
"d010": {
"path": "artifacts",
"name": "artifacts"
},
"d011": {
"path": "docs",
"name": "docs"
},
"d012": {
"path": "dropbox",
"name": "dropbox"
},
"d013": {
"path": "templates",
"name": "templates"
},
"d014": {
"path": "tests",
"name": "tests"
},
"d015": {
"path": "tools",
"name": "tools"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
__pycache__/
*.pyc
*.pyo
.env
*.egg-info/
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
dist/
build/
*.log
*.tmp
*.swp
+34
View File
@@ -0,0 +1,34 @@
{
"document_metadata": {
"document_type": "session_history",
"document_name": "API.LOCAL",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "API",
"tags": ["session_tracking", "work_log", "API"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"active_tasks": {
"today_focus": "2026-03-05",
"recently_completed": []
},
"key_learnings": {},
"sessions": [
{
"session_number": 1,
"date": "2026-03-05",
"summary": "Branch initialized - API created by aipass init",
"status": "completed"
}
]
}
+37
View File
@@ -0,0 +1,37 @@
{
"document_metadata": {
"document_type": "collaboration_patterns",
"document_name": "API.OBSERVATIONS",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "API",
"tags": ["collaboration", "patterns", "API"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"guidelines": {
"purpose": "Capture collaboration patterns and experiential insights over time",
"chronological_order": "Newest entries at TOP, oldest at BOTTOM - NEVER reorder"
},
"observations": [
{
"date": "2026-03-05",
"session": 1,
"entries": [
{
"title": "First Contact",
"detail": "Branch initialized. Ready to begin capturing collaboration patterns."
}
]
}
]
}
+36
View File
@@ -0,0 +1,36 @@
{
"document_metadata": {
"document_type": "branch_identity",
"document_name": "API.PASSPORT",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "API",
"tags": ["identity", "passport", "branch_profile"]
},
"branch_info": {
"branch_name": "API",
"alias": "",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/api",
"module": "api",
"created": "2026-03-05"
},
"identity": {
"role": "LLM Access",
"purpose": "",
"what_i_do": [],
"what_i_dont_do": []
},
"principles": [
"Code is truth - fail honestly",
"Memory persists - context survives",
"Simple solutions over complex architecture"
],
"citizenship": {
"registered": true,
"registry_path": ".aipass/registry.json",
"communications": true,
"memory": true
}
}
+62
View File
@@ -0,0 +1,62 @@
{
"_warning": "AUTO-GENERATED FILE - DO NOT MANUALLY EDIT. This file is 100% automated and will be overwritten. Services update their own sections.",
"branch": "API",
"last_updated": "2026-03-05",
"quick_status": {
"new_mail": 0,
"opened_mail": 0,
"active_plans": 0,
"commons_mentions": 0,
"action_required": false,
"summary": ""
},
"sections": {
"ai_mail": {
"managed_by": "ai_mail",
"new": 0,
"opened": 0,
"total": 0,
"oldest_unread_age": null,
"last_dispatch_received": null,
"last_updated": "2026-03-05"
},
"flow": {
"managed_by": "flow",
"active_plans": 0,
"recently_closed": [],
"last_updated": "2026-03-05"
},
"memory_bank": {
"managed_by": "memory_bank",
"vectors_stored": 0,
"notes": {},
"last_updated": "2026-03-05"
},
"devpulse": {
"managed_by": "devpulse",
"summary": {
"issues": 0,
"todos": 0
},
"dplan_counts": {},
"recent_activity": "",
"last_updated": "2026-03-05"
},
"commons_activity": {
"managed_by": "the_commons",
"new_posts_since_last_visit": 0,
"new_comments_since_last_visit": 0,
"mentions": 0,
"trending": "None",
"last_checked": null,
"last_updated": "2026-03-05"
},
"agent_status": {
"managed_by": "prax",
"active_agents": [],
"agent_count": 0,
"stale_agents": [],
"last_updated": "2026-03-05"
}
}
}
+51
View File
@@ -0,0 +1,51 @@
# API
**Purpose:** Model routing, provider abstraction, LLM API access layer
**Module:** `aipass.api`
**Created:** 2026-03-05
---
## Overview
### What I Do
### How I Work
- **Entry Point:** `apps/api.py`
- **Pattern:** Auto-discovers and routes to modules
---
## Architecture
```
API/
├── apps/
│ ├── api.py # Entry point
│ ├── modules/ # Business logic
│ ├── handlers/ # Implementation
│ └── plugins/ # Extensions
├── docs/
├── tests/
├── passport.json # Identity
├── local.json # Session history
├── observations.json # Collaboration patterns
└── README.md
```
---
## Commands
*Configure after initialization*
---
## Integration Points
### Depends On
### Provides To
+1
View File
@@ -0,0 +1 @@
# API apps package
+86
View File
@@ -0,0 +1,86 @@
"""
API Branch - Main Orchestrator
Auto-discovery architecture:
- Scans modules/ directory for .py files with handle_command()
- Routes commands to discovered modules automatically
- No manual imports or routing needed
"""
import sys
import importlib
from pathlib import Path
from typing import List, Any
from aipass.prax import logger
# =============================================================================
# MODULE DISCOVERY
# =============================================================================
MODULES_DIR = Path(__file__).parent / "modules"
def discover_modules() -> List[Any]:
"""Auto-discover modules in modules/ directory."""
modules = []
if not MODULES_DIR.exists():
return modules
for file_path in MODULES_DIR.glob("*.py"):
if file_path.name.startswith("_"):
continue
module_name = f"apps.modules.{file_path.stem}"
try:
module = importlib.import_module(module_name)
if hasattr(module, "handle_command"):
modules.append(module)
except Exception as e:
logger.error(f"[API] Failed to load module {module_name}: {e}")
return modules
def route_command(command: str, args: List[str], modules: List[Any]) -> bool:
"""Route command to appropriate module."""
for module in modules:
try:
if module.handle_command(command, args):
return True
except Exception as e:
logger.error(f"[API] Module {module.__name__} error: {e}")
return False
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point - routes commands or shows help."""
modules = discover_modules()
args = sys.argv[1:]
if len(args) == 0 or args[0] in ["--help", "-h", "help"]:
print(f"API - {len(modules)} modules discovered")
for module in modules:
name = module.__name__.split(".")[-1]
desc = (module.__doc__ or "").strip().split("\n")[0] if module.__doc__ else "No description"
print(f" {name:20} {desc}")
return 0
command = args[0]
remaining = args[1:] if len(args) > 1 else []
if route_command(command, remaining, modules):
return 0
print(f"Unknown command: {command}")
return 1
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,15 @@
{
"id": "32",
"name": "API Birth Certificate",
"type": "birth_certificate",
"creator": "SYSTEM",
"owner": "API",
"rarity": "unique",
"description": "Official birth certificate for API. Citizen #32, registered using 'library' template. Purpose: Model routing, provider abstraction, LLM API access layer",
"metadata": {
"citizen_number": "32",
"template": "library",
"purpose": "Model routing, provider abstraction, LLM API access layer"
},
"created_at": "2026-03-05"
}
+15
View File
@@ -0,0 +1,15 @@
# flow.local.md - API
```
Branch: /home/aipass/aipass_business/AIPass/src/aipass/api
Created: 2026-03-05
```
## Issues
-
---
## Todos
-
+21
View File
@@ -0,0 +1,21 @@
[pytest]
# Test discovery paths
testpaths = tests
# Test file patterns
python_files = test_*.py
python_functions = test_*
python_classes = Test*
# Command-line options (always applied)
addopts =
-v # Verbose output
--tb=short # Short traceback format
--strict-markers # Raise error on unknown markers
-ra # Show summary of all test outcomes
# Test markers (for categorizing tests)
markers =
unit: Unit tests
integration: Integration tests
slow: Tests that take significant time
+1
View File
@@ -0,0 +1 @@
# Tests package for api
+43
View File
@@ -0,0 +1,43 @@
#!/home/aipass/.venv/bin/python3
# ===================AIPASS====================
# META DATA HEADER
# Name: tests/conftest.py
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/tests
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Shared pytest fixtures
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""Shared pytest fixtures for cortex tests"""
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
@pytest.fixture
def temp_test_dir() -> Generator[Path, None, None]:
"""Creates temporary directory for testing, cleans up after"""
test_dir = Path(tempfile.mkdtemp())
yield test_dir
if test_dir.exists():
shutil.rmtree(test_dir)
@pytest.fixture
def sample_test_data() -> dict:
"""Provides sample test data
Customize this fixture for your module's needs
"""
return {
"test_key": "test_value",
"sample_data": "example"
}
+159
View File
@@ -0,0 +1,159 @@
#!/home/aipass/.venv/bin/python3
# -*- coding: utf-8 -*-
# ===================AIPASS====================
# META DATA HEADER
# Name: verify_branch.py - Branch Template Verification
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/modules
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Compare template vs branch
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""
Branch Template Verification Tool
Compares template directory with created branch to identify:
- Files in template but missing in branch
- Files in branch but not in template
- Renamed files
"""
import sys
import json
from pathlib import Path
from typing import Set, List, Tuple
from fnmatch import fnmatch
# INFRASTRUCTURE IMPORT PATTERN
AIPASS_ROOT = Path.home() / "aipass_core"
sys.path.insert(0, str(AIPASS_ROOT))
# Get template directory
TEMPLATE_DIR = AIPASS_ROOT / "cortex" / "templates" / "branch_template"
def load_ignore_patterns() -> Tuple[List[str], List[str]]:
"""Load ignore patterns from .registry_ignore.json"""
ignore_file = TEMPLATE_DIR / ".registry_ignore.json"
if not ignore_file.exists():
return [], []
try:
with open(ignore_file, 'r', encoding='utf-8') as f:
data = json.load(f)
ignore_files = data.get("ignore_files", [])
ignore_patterns = data.get("ignore_patterns", [])
return ignore_files, ignore_patterns
except Exception as e:
print(f"Warning: Could not load .registry_ignore.json: {e}")
return [], []
def should_exclude(path: Path, base_dir: Path, ignore_files: List[str], ignore_patterns: List[str]) -> bool:
"""Check if path should be excluded based on ignore patterns"""
rel_path = path.relative_to(base_dir)
filename = path.name
path_str = str(rel_path)
# Check exact filename matches
if filename in ignore_files:
return True
# Check glob patterns
for pattern in ignore_patterns:
if fnmatch(filename, pattern):
return True
# Check if any parent directory matches
for part in rel_path.parts:
if fnmatch(part, pattern):
return True
return False
def get_file_set(directory: Path, ignore_files: List[str], ignore_patterns: List[str]) -> Set[str]:
"""Get set of all file paths in directory (relative)"""
files = set()
for item in directory.rglob("*"):
if item.is_file() and not should_exclude(item, directory, ignore_files, ignore_patterns):
rel_path = str(item.relative_to(directory))
files.add(rel_path)
return files
def verify_branch(branch_dir: Path) -> Tuple[List[str], List[str], List[str]]:
"""
Compare template with branch
Returns:
Tuple of (in_template_only, in_branch_only, in_both)
"""
# Load ignore patterns from .registry_ignore.json
ignore_files, ignore_patterns = load_ignore_patterns()
template_files = get_file_set(TEMPLATE_DIR, ignore_files, ignore_patterns)
branch_files = get_file_set(branch_dir, ignore_files, ignore_patterns)
in_template_only = sorted(template_files - branch_files)
in_branch_only = sorted(branch_files - template_files)
in_both = sorted(template_files & branch_files)
return in_template_only, in_branch_only, in_both
def main():
if len(sys.argv) < 2:
print("Usage: python3 verify_branch.py <branch_directory>")
print("Example: python3 verify_branch.py test_branch002")
sys.exit(1)
branch_path = Path(sys.argv[1])
if not branch_path.is_absolute():
# Assume it's relative to cortex directory
branch_path = Path.cwd() / branch_path
if not branch_path.exists():
print(f"❌ ERROR: Branch directory not found: {branch_path}")
sys.exit(1)
print(f"\n=== Branch Verification ===")
print(f"Template: {TEMPLATE_DIR}")
print(f"Branch: {branch_path}")
print()
in_template_only, in_branch_only, in_both = verify_branch(branch_path)
print(f"Files in both: {len(in_both)}")
print(f"Files in template only: {len(in_template_only)}")
print(f"Files in branch only: {len(in_branch_only)}")
print()
if in_template_only:
print("❌ Missing from branch (expected from template):")
for file in in_template_only:
print(f" - {file}")
print()
if in_branch_only:
print("✅ Additional files in branch (renamed or new):")
for file in in_branch_only:
print(f" + {file}")
print()
if not in_template_only and not in_branch_only:
print("✅ Branch matches template perfectly")
print("="*70)
if __name__ == "__main__":
main()
+37
View File
@@ -0,0 +1,37 @@
{
"metadata": {
"version": "1.0.0",
"description": "Files and patterns to exclude when creating branch backups"
},
"ignore_directories": [
".backup",
".venv",
"venv",
"node_modules",
"__pycache__",
".git",
".cache",
".pytest_cache",
".mypy_cache",
"dist",
"build",
"*.egg-info",
"ai_mail.local",
"logs",
".aipass",
".archive",
".claude",
"htmlcov"
],
"ignore_patterns": [
"*.pyc",
"*.pyo",
".DS_Store",
"*.log",
"*.tmp",
"*.swp",
"*~",
"*.env",
"BRANCH_REGISTRY.json"
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"metadata": {
"version": "1.0.0",
"description": "Template structural migrations for branch updates",
"last_updated": "2025-11-07",
"applies_to_versions": ["all"]
},
"migrations": [
{
"id": "m001",
"description": "Example: Migrate flat metadata to document_metadata structure",
"version_introduced": "1.0.0",
"applies_to_files": ["*.id.json"],
"operations": [
{
"type": "key_rename",
"from": "metadata",
"to": "document_metadata"
},
{
"type": "move_to_nested",
"source_keys": ["branch_name", "path", "profile"],
"target_parent": "branch_info"
},
{
"type": "add_missing_keys",
"parent": "document_metadata",
"keys": {
"document_type": "branch_identity",
"schema_version": "1.0.0"
}
}
]
}
],
"options": {
"skip_if_target_exists": true,
"preserve_unknown_keys": true,
"recursive_application": false
},
"notes": {
"usage": "This file defines structural transformation rules applied during branch updates",
"pattern_matching": "applies_to_files uses glob patterns (*.json, *.id.json, etc.)",
"operation_order": "Operations execute in order listed within each migration",
"skip_behavior": "Operations skip if already compliant (target exists = success)",
"supported_operations": ["key_rename", "move_to_nested", "add_missing_keys"],
"future_operations": ["split_key", "combine_keys", "delete_key", "transform_value"]
}
}
@@ -0,0 +1,43 @@
{
"metadata": {
"version": "1.1.0",
"description": "Files and patterns to exclude when updating branches from template",
"last_updated": "2025-11-09"
},
"ignore_files": [
".template_registry.json",
".registry_ignore.json"
],
"ignore_patterns": [
"__pycache__",
"*.pyc",
"#@comments.txt",
".backup_*"
],
"notes": {
"how_it_works": "Two types of exclusions during branch updates:",
"ignore_files": {
"description": "Exact filename matches (no wildcards)",
"purpose": "Template-internal management files that branches don't need",
"examples": [
".template_registry.json (template's file tracking list)",
".registry_ignore.json (this config file)"
]
},
"ignore_patterns": {
"description": "Glob patterns - matches filenames AND directory names",
"purpose": "Exclude generated files, caches, and user content markers",
"examples": [
"__pycache__ (Python cache directories)",
"*.pyc (Python compiled bytecode files)",
"#@comments.txt (user comment files)",
".backup_* (timestamped backup files like .backup_20251109, NOT .backup directory)"
],
"how_matching_works": [
"Step 1: Check if filename matches pattern (e.g., file.pyc matches *.pyc)",
"Step 2: Check if any parent directory matches (e.g., files inside __pycache__/ dir)"
]
},
"what_gets_ignored": "These files never copy to branches during updates - they stay template-only"
}
}
@@ -0,0 +1,184 @@
{
"metadata": {
"description": "Template registry for tracking files",
"generated": true
},
"files": {
"f001": {
"path": ".aipass/aipass_local_prompt.md",
"name": "aipass_local_prompt.md",
"content_hash": "3fafa4a0b2f17a91",
"has_branch_placeholder": false
},
"f002": {
"path": ".claude/settings.local.json",
"name": "settings.local.json",
"content_hash": "6379c5be3fb714ac",
"has_branch_placeholder": false
},
"f003": {
"path": ".gitignore",
"name": ".gitignore",
"content_hash": "841dedb922da7ddb",
"has_branch_placeholder": false
},
"f004": {
"path": ".trinity/local.json",
"name": "local.json",
"content_hash": "bfa9a120289a7236",
"has_branch_placeholder": false
},
"f005": {
"path": ".trinity/observations.json",
"name": "observations.json",
"content_hash": "a79a11aef223c463",
"has_branch_placeholder": false
},
"f006": {
"path": ".trinity/passport.json",
"name": "passport.json",
"content_hash": "89cfad8c5a2afd7b",
"has_branch_placeholder": false
},
"f007": {
"path": "DASHBOARD.local.json",
"name": "DASHBOARD.local.json",
"content_hash": "7c28e6d7882a1596",
"has_branch_placeholder": false
},
"f008": {
"path": "README.md",
"name": "README.md",
"content_hash": "a4ff66d38c173a77",
"has_branch_placeholder": false
},
"f009": {
"path": "apps/__init__.py",
"name": "__init__.py",
"content_hash": "8d538bbb15bc3a5c",
"has_branch_placeholder": false
},
"f010": {
"path": "apps/branch.py",
"name": "branch.py",
"content_hash": "934981946063d189",
"has_branch_placeholder": false
},
"f011": {
"path": "apps/handlers/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f012": {
"path": "apps/modules/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f013": {
"path": "apps/plugins/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f014": {
"path": "artifacts/birth_certificate.json",
"name": "birth_certificate.json",
"content_hash": "9b003e8b9280d29f",
"has_branch_placeholder": false
},
"f015": {
"path": "flow.local.md",
"name": "flow.local.md",
"content_hash": "8cc213d5a2618e84",
"has_branch_placeholder": false
},
"f016": {
"path": "pytest.ini",
"name": "pytest.ini",
"content_hash": "7b39ba7bca4025c5",
"has_branch_placeholder": false
},
"f017": {
"path": "tests/__init__.py",
"name": "__init__.py",
"content_hash": "f54fee90f1ed1d75",
"has_branch_placeholder": false
},
"f018": {
"path": "tests/conftest.py",
"name": "conftest.py",
"content_hash": "5e5f2399e0d70978",
"has_branch_placeholder": false
},
"f019": {
"path": "tools/verify_branch.py",
"name": "verify_branch.py",
"content_hash": "06803a84118e5453",
"has_branch_placeholder": false
}
},
"directories": {
"d001": {
"path": ".aipass",
"name": ".aipass"
},
"d002": {
"path": ".archive",
"name": ".archive"
},
"d003": {
"path": ".claude",
"name": ".claude"
},
"d004": {
"path": ".trinity",
"name": ".trinity"
},
"d005": {
"path": "apps",
"name": "apps"
},
"d006": {
"path": "apps/handlers",
"name": "handlers"
},
"d007": {
"path": "apps/modules",
"name": "modules"
},
"d008": {
"path": "apps/plugins",
"name": "plugins"
},
"d009": {
"path": "artifacts",
"name": "artifacts"
},
"d010": {
"path": "cli_json",
"name": "cli_json"
},
"d011": {
"path": "docs",
"name": "docs"
},
"d012": {
"path": "dropbox",
"name": "dropbox"
},
"d013": {
"path": "templates",
"name": "templates"
},
"d014": {
"path": "tests",
"name": "tests"
},
"d015": {
"path": "tools",
"name": "tools"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
__pycache__/
*.pyc
*.pyo
.env
*.egg-info/
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
dist/
build/
*.log
*.tmp
*.swp
+34
View File
@@ -0,0 +1,34 @@
{
"document_metadata": {
"document_type": "session_history",
"document_name": "CLI.LOCAL",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "CLI",
"tags": ["session_tracking", "work_log", "CLI"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"active_tasks": {
"today_focus": "2026-03-05",
"recently_completed": []
},
"key_learnings": {},
"sessions": [
{
"session_number": 1,
"date": "2026-03-05",
"summary": "Branch initialized - CLI created by aipass init",
"status": "completed"
}
]
}
+37
View File
@@ -0,0 +1,37 @@
{
"document_metadata": {
"document_type": "collaboration_patterns",
"document_name": "CLI.OBSERVATIONS",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "CLI",
"tags": ["collaboration", "patterns", "CLI"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"guidelines": {
"purpose": "Capture collaboration patterns and experiential insights over time",
"chronological_order": "Newest entries at TOP, oldest at BOTTOM - NEVER reorder"
},
"observations": [
{
"date": "2026-03-05",
"session": 1,
"entries": [
{
"title": "First Contact",
"detail": "Branch initialized. Ready to begin capturing collaboration patterns."
}
]
}
]
}
+36
View File
@@ -0,0 +1,36 @@
{
"document_metadata": {
"document_type": "branch_identity",
"document_name": "CLI.PASSPORT",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "CLI",
"tags": ["identity", "passport", "branch_profile"]
},
"branch_info": {
"branch_name": "CLI",
"alias": "",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/cli",
"module": "cli",
"created": "2026-03-05"
},
"identity": {
"role": "Display Formatting",
"purpose": "",
"what_i_do": [],
"what_i_dont_do": []
},
"principles": [
"Code is truth - fail honestly",
"Memory persists - context survives",
"Simple solutions over complex architecture"
],
"citizenship": {
"registered": true,
"registry_path": ".aipass/registry.json",
"communications": true,
"memory": true
}
}
+62
View File
@@ -0,0 +1,62 @@
{
"_warning": "AUTO-GENERATED FILE - DO NOT MANUALLY EDIT. This file is 100% automated and will be overwritten. Services update their own sections.",
"branch": "CLI",
"last_updated": "2026-03-05",
"quick_status": {
"new_mail": 0,
"opened_mail": 0,
"active_plans": 0,
"commons_mentions": 0,
"action_required": false,
"summary": ""
},
"sections": {
"ai_mail": {
"managed_by": "ai_mail",
"new": 0,
"opened": 0,
"total": 0,
"oldest_unread_age": null,
"last_dispatch_received": null,
"last_updated": "2026-03-05"
},
"flow": {
"managed_by": "flow",
"active_plans": 0,
"recently_closed": [],
"last_updated": "2026-03-05"
},
"memory_bank": {
"managed_by": "memory_bank",
"vectors_stored": 0,
"notes": {},
"last_updated": "2026-03-05"
},
"devpulse": {
"managed_by": "devpulse",
"summary": {
"issues": 0,
"todos": 0
},
"dplan_counts": {},
"recent_activity": "",
"last_updated": "2026-03-05"
},
"commons_activity": {
"managed_by": "the_commons",
"new_posts_since_last_visit": 0,
"new_comments_since_last_visit": 0,
"mentions": 0,
"trending": "None",
"last_checked": null,
"last_updated": "2026-03-05"
},
"agent_status": {
"managed_by": "prax",
"active_agents": [],
"agent_count": 0,
"stale_agents": [],
"last_updated": "2026-03-05"
}
}
}
+51
View File
@@ -0,0 +1,51 @@
# CLI
**Purpose:** Terminal display formatting - headers, success, error, warning helpers
**Module:** `aipass.cli`
**Created:** 2026-03-05
---
## Overview
### What I Do
### How I Work
- **Entry Point:** `apps/cli.py`
- **Pattern:** Auto-discovers and routes to modules
---
## Architecture
```
CLI/
├── apps/
│ ├── cli.py # Entry point
│ ├── modules/ # Business logic
│ ├── handlers/ # Implementation
│ └── plugins/ # Extensions
├── docs/
├── tests/
├── passport.json # Identity
├── local.json # Session history
├── observations.json # Collaboration patterns
└── README.md
```
---
## Commands
*Configure after initialization*
---
## Integration Points
### Depends On
### Provides To
+1
View File
@@ -0,0 +1 @@
# CLI apps package
+86
View File
@@ -0,0 +1,86 @@
"""
CLI Branch - Main Orchestrator
Auto-discovery architecture:
- Scans modules/ directory for .py files with handle_command()
- Routes commands to discovered modules automatically
- No manual imports or routing needed
"""
import sys
import importlib
from pathlib import Path
from typing import List, Any
from aipass.prax import logger
# =============================================================================
# MODULE DISCOVERY
# =============================================================================
MODULES_DIR = Path(__file__).parent / "modules"
def discover_modules() -> List[Any]:
"""Auto-discover modules in modules/ directory."""
modules = []
if not MODULES_DIR.exists():
return modules
for file_path in MODULES_DIR.glob("*.py"):
if file_path.name.startswith("_"):
continue
module_name = f"apps.modules.{file_path.stem}"
try:
module = importlib.import_module(module_name)
if hasattr(module, "handle_command"):
modules.append(module)
except Exception as e:
logger.error(f"[CLI] Failed to load module {module_name}: {e}")
return modules
def route_command(command: str, args: List[str], modules: List[Any]) -> bool:
"""Route command to appropriate module."""
for module in modules:
try:
if module.handle_command(command, args):
return True
except Exception as e:
logger.error(f"[CLI] Module {module.__name__} error: {e}")
return False
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point - routes commands or shows help."""
modules = discover_modules()
args = sys.argv[1:]
if len(args) == 0 or args[0] in ["--help", "-h", "help"]:
print(f"CLI - {len(modules)} modules discovered")
for module in modules:
name = module.__name__.split(".")[-1]
desc = (module.__doc__ or "").strip().split("\n")[0] if module.__doc__ else "No description"
print(f" {name:20} {desc}")
return 0
command = args[0]
remaining = args[1:] if len(args) > 1 else []
if route_command(command, remaining, modules):
return 0
print(f"Unknown command: {command}")
return 1
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,15 @@
{
"id": "32",
"name": "CLI Birth Certificate",
"type": "birth_certificate",
"creator": "SYSTEM",
"owner": "CLI",
"rarity": "unique",
"description": "Official birth certificate for CLI. Citizen #32, registered using 'library' template. Purpose: Terminal display formatting - headers, success, error, warning helpers",
"metadata": {
"citizen_number": "32",
"template": "library",
"purpose": "Terminal display formatting - headers, success, error, warning helpers"
},
"created_at": "2026-03-05"
}
+15
View File
@@ -0,0 +1,15 @@
# flow.local.md - CLI
```
Branch: /home/aipass/aipass_business/AIPass/src/aipass/cli
Created: 2026-03-05
```
## Issues
-
---
## Todos
-
+21
View File
@@ -0,0 +1,21 @@
[pytest]
# Test discovery paths
testpaths = tests
# Test file patterns
python_files = test_*.py
python_functions = test_*
python_classes = Test*
# Command-line options (always applied)
addopts =
-v # Verbose output
--tb=short # Short traceback format
--strict-markers # Raise error on unknown markers
-ra # Show summary of all test outcomes
# Test markers (for categorizing tests)
markers =
unit: Unit tests
integration: Integration tests
slow: Tests that take significant time
+1
View File
@@ -0,0 +1 @@
# Tests package for cli
+43
View File
@@ -0,0 +1,43 @@
#!/home/aipass/.venv/bin/python3
# ===================AIPASS====================
# META DATA HEADER
# Name: tests/conftest.py
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/tests
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Shared pytest fixtures
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""Shared pytest fixtures for cortex tests"""
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
@pytest.fixture
def temp_test_dir() -> Generator[Path, None, None]:
"""Creates temporary directory for testing, cleans up after"""
test_dir = Path(tempfile.mkdtemp())
yield test_dir
if test_dir.exists():
shutil.rmtree(test_dir)
@pytest.fixture
def sample_test_data() -> dict:
"""Provides sample test data
Customize this fixture for your module's needs
"""
return {
"test_key": "test_value",
"sample_data": "example"
}
+159
View File
@@ -0,0 +1,159 @@
#!/home/aipass/.venv/bin/python3
# -*- coding: utf-8 -*-
# ===================AIPASS====================
# META DATA HEADER
# Name: verify_branch.py - Branch Template Verification
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/modules
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Compare template vs branch
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""
Branch Template Verification Tool
Compares template directory with created branch to identify:
- Files in template but missing in branch
- Files in branch but not in template
- Renamed files
"""
import sys
import json
from pathlib import Path
from typing import Set, List, Tuple
from fnmatch import fnmatch
# INFRASTRUCTURE IMPORT PATTERN
AIPASS_ROOT = Path.home() / "aipass_core"
sys.path.insert(0, str(AIPASS_ROOT))
# Get template directory
TEMPLATE_DIR = AIPASS_ROOT / "cortex" / "templates" / "branch_template"
def load_ignore_patterns() -> Tuple[List[str], List[str]]:
"""Load ignore patterns from .registry_ignore.json"""
ignore_file = TEMPLATE_DIR / ".registry_ignore.json"
if not ignore_file.exists():
return [], []
try:
with open(ignore_file, 'r', encoding='utf-8') as f:
data = json.load(f)
ignore_files = data.get("ignore_files", [])
ignore_patterns = data.get("ignore_patterns", [])
return ignore_files, ignore_patterns
except Exception as e:
print(f"Warning: Could not load .registry_ignore.json: {e}")
return [], []
def should_exclude(path: Path, base_dir: Path, ignore_files: List[str], ignore_patterns: List[str]) -> bool:
"""Check if path should be excluded based on ignore patterns"""
rel_path = path.relative_to(base_dir)
filename = path.name
path_str = str(rel_path)
# Check exact filename matches
if filename in ignore_files:
return True
# Check glob patterns
for pattern in ignore_patterns:
if fnmatch(filename, pattern):
return True
# Check if any parent directory matches
for part in rel_path.parts:
if fnmatch(part, pattern):
return True
return False
def get_file_set(directory: Path, ignore_files: List[str], ignore_patterns: List[str]) -> Set[str]:
"""Get set of all file paths in directory (relative)"""
files = set()
for item in directory.rglob("*"):
if item.is_file() and not should_exclude(item, directory, ignore_files, ignore_patterns):
rel_path = str(item.relative_to(directory))
files.add(rel_path)
return files
def verify_branch(branch_dir: Path) -> Tuple[List[str], List[str], List[str]]:
"""
Compare template with branch
Returns:
Tuple of (in_template_only, in_branch_only, in_both)
"""
# Load ignore patterns from .registry_ignore.json
ignore_files, ignore_patterns = load_ignore_patterns()
template_files = get_file_set(TEMPLATE_DIR, ignore_files, ignore_patterns)
branch_files = get_file_set(branch_dir, ignore_files, ignore_patterns)
in_template_only = sorted(template_files - branch_files)
in_branch_only = sorted(branch_files - template_files)
in_both = sorted(template_files & branch_files)
return in_template_only, in_branch_only, in_both
def main():
if len(sys.argv) < 2:
print("Usage: python3 verify_branch.py <branch_directory>")
print("Example: python3 verify_branch.py test_branch002")
sys.exit(1)
branch_path = Path(sys.argv[1])
if not branch_path.is_absolute():
# Assume it's relative to cortex directory
branch_path = Path.cwd() / branch_path
if not branch_path.exists():
print(f"❌ ERROR: Branch directory not found: {branch_path}")
sys.exit(1)
print(f"\n=== Branch Verification ===")
print(f"Template: {TEMPLATE_DIR}")
print(f"Branch: {branch_path}")
print()
in_template_only, in_branch_only, in_both = verify_branch(branch_path)
print(f"Files in both: {len(in_both)}")
print(f"Files in template only: {len(in_template_only)}")
print(f"Files in branch only: {len(in_branch_only)}")
print()
if in_template_only:
print("❌ Missing from branch (expected from template):")
for file in in_template_only:
print(f" - {file}")
print()
if in_branch_only:
print("✅ Additional files in branch (renamed or new):")
for file in in_branch_only:
print(f" + {file}")
print()
if not in_template_only and not in_branch_only:
print("✅ Branch matches template perfectly")
print("="*70)
if __name__ == "__main__":
main()
@@ -0,0 +1,37 @@
{
"metadata": {
"version": "1.0.0",
"description": "Files and patterns to exclude when creating branch backups"
},
"ignore_directories": [
".backup",
".venv",
"venv",
"node_modules",
"__pycache__",
".git",
".cache",
".pytest_cache",
".mypy_cache",
"dist",
"build",
"*.egg-info",
"ai_mail.local",
"logs",
".aipass",
".archive",
".claude",
"htmlcov"
],
"ignore_patterns": [
"*.pyc",
"*.pyo",
".DS_Store",
"*.log",
"*.tmp",
"*.swp",
"*~",
"*.env",
"BRANCH_REGISTRY.json"
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"metadata": {
"version": "1.0.0",
"description": "Template structural migrations for branch updates",
"last_updated": "2025-11-07",
"applies_to_versions": ["all"]
},
"migrations": [
{
"id": "m001",
"description": "Example: Migrate flat metadata to document_metadata structure",
"version_introduced": "1.0.0",
"applies_to_files": ["*.id.json"],
"operations": [
{
"type": "key_rename",
"from": "metadata",
"to": "document_metadata"
},
{
"type": "move_to_nested",
"source_keys": ["branch_name", "path", "profile"],
"target_parent": "branch_info"
},
{
"type": "add_missing_keys",
"parent": "document_metadata",
"keys": {
"document_type": "branch_identity",
"schema_version": "1.0.0"
}
}
]
}
],
"options": {
"skip_if_target_exists": true,
"preserve_unknown_keys": true,
"recursive_application": false
},
"notes": {
"usage": "This file defines structural transformation rules applied during branch updates",
"pattern_matching": "applies_to_files uses glob patterns (*.json, *.id.json, etc.)",
"operation_order": "Operations execute in order listed within each migration",
"skip_behavior": "Operations skip if already compliant (target exists = success)",
"supported_operations": ["key_rename", "move_to_nested", "add_missing_keys"],
"future_operations": ["split_key", "combine_keys", "delete_key", "transform_value"]
}
}
@@ -0,0 +1,43 @@
{
"metadata": {
"version": "1.1.0",
"description": "Files and patterns to exclude when updating branches from template",
"last_updated": "2025-11-09"
},
"ignore_files": [
".template_registry.json",
".registry_ignore.json"
],
"ignore_patterns": [
"__pycache__",
"*.pyc",
"#@comments.txt",
".backup_*"
],
"notes": {
"how_it_works": "Two types of exclusions during branch updates:",
"ignore_files": {
"description": "Exact filename matches (no wildcards)",
"purpose": "Template-internal management files that branches don't need",
"examples": [
".template_registry.json (template's file tracking list)",
".registry_ignore.json (this config file)"
]
},
"ignore_patterns": {
"description": "Glob patterns - matches filenames AND directory names",
"purpose": "Exclude generated files, caches, and user content markers",
"examples": [
"__pycache__ (Python cache directories)",
"*.pyc (Python compiled bytecode files)",
"#@comments.txt (user comment files)",
".backup_* (timestamped backup files like .backup_20251109, NOT .backup directory)"
],
"how_matching_works": [
"Step 1: Check if filename matches pattern (e.g., file.pyc matches *.pyc)",
"Step 2: Check if any parent directory matches (e.g., files inside __pycache__/ dir)"
]
},
"what_gets_ignored": "These files never copy to branches during updates - they stay template-only"
}
}
@@ -0,0 +1,184 @@
{
"metadata": {
"description": "Template registry for tracking files",
"generated": true
},
"files": {
"f001": {
"path": ".aipass/aipass_local_prompt.md",
"name": "aipass_local_prompt.md",
"content_hash": "3355bfa2a158034a",
"has_branch_placeholder": false
},
"f002": {
"path": ".claude/settings.local.json",
"name": "settings.local.json",
"content_hash": "6379c5be3fb714ac",
"has_branch_placeholder": false
},
"f003": {
"path": ".gitignore",
"name": ".gitignore",
"content_hash": "841dedb922da7ddb",
"has_branch_placeholder": false
},
"f004": {
"path": ".trinity/local.json",
"name": "local.json",
"content_hash": "ea83c9972a157754",
"has_branch_placeholder": false
},
"f005": {
"path": ".trinity/observations.json",
"name": "observations.json",
"content_hash": "b11c5e097705281c",
"has_branch_placeholder": false
},
"f006": {
"path": ".trinity/passport.json",
"name": "passport.json",
"content_hash": "8644c91fe4a8246f",
"has_branch_placeholder": false
},
"f007": {
"path": "DASHBOARD.local.json",
"name": "DASHBOARD.local.json",
"content_hash": "8b8594e36158acd4",
"has_branch_placeholder": false
},
"f008": {
"path": "README.md",
"name": "README.md",
"content_hash": "c39108bde9346c58",
"has_branch_placeholder": false
},
"f009": {
"path": "apps/__init__.py",
"name": "__init__.py",
"content_hash": "093ad65fa80094da",
"has_branch_placeholder": false
},
"f010": {
"path": "apps/branch.py",
"name": "branch.py",
"content_hash": "ef22ee28aac325ac",
"has_branch_placeholder": false
},
"f011": {
"path": "apps/handlers/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f012": {
"path": "apps/modules/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f013": {
"path": "apps/plugins/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f014": {
"path": "artifacts/birth_certificate.json",
"name": "birth_certificate.json",
"content_hash": "40d1eece6992b3c6",
"has_branch_placeholder": false
},
"f015": {
"path": "flow.local.md",
"name": "flow.local.md",
"content_hash": "2969274f045ff065",
"has_branch_placeholder": false
},
"f016": {
"path": "pytest.ini",
"name": "pytest.ini",
"content_hash": "7b39ba7bca4025c5",
"has_branch_placeholder": false
},
"f017": {
"path": "tests/__init__.py",
"name": "__init__.py",
"content_hash": "c93579434ecce5bd",
"has_branch_placeholder": false
},
"f018": {
"path": "tests/conftest.py",
"name": "conftest.py",
"content_hash": "5e5f2399e0d70978",
"has_branch_placeholder": false
},
"f019": {
"path": "tools/verify_branch.py",
"name": "verify_branch.py",
"content_hash": "06803a84118e5453",
"has_branch_placeholder": false
}
},
"directories": {
"d001": {
"path": ".aipass",
"name": ".aipass"
},
"d002": {
"path": ".archive",
"name": ".archive"
},
"d003": {
"path": ".claude",
"name": ".claude"
},
"d004": {
"path": ".trinity",
"name": ".trinity"
},
"d005": {
"path": "apps",
"name": "apps"
},
"d006": {
"path": "apps/handlers",
"name": "handlers"
},
"d007": {
"path": "apps/modules",
"name": "modules"
},
"d008": {
"path": "apps/plugins",
"name": "plugins"
},
"d009": {
"path": "artifacts",
"name": "artifacts"
},
"d010": {
"path": "docs",
"name": "docs"
},
"d011": {
"path": "drone_json",
"name": "drone_json"
},
"d012": {
"path": "dropbox",
"name": "dropbox"
},
"d013": {
"path": "templates",
"name": "templates"
},
"d014": {
"path": "tests",
"name": "tests"
},
"d015": {
"path": "tools",
"name": "tools"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
__pycache__/
*.pyc
*.pyo
.env
*.egg-info/
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
dist/
build/
*.log
*.tmp
*.swp
+34
View File
@@ -0,0 +1,34 @@
{
"document_metadata": {
"document_type": "session_history",
"document_name": "DRONE.LOCAL",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "DRONE",
"tags": ["session_tracking", "work_log", "DRONE"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"active_tasks": {
"today_focus": "2026-03-05",
"recently_completed": []
},
"key_learnings": {},
"sessions": [
{
"session_number": 1,
"date": "2026-03-05",
"summary": "Branch initialized - DRONE created by aipass init",
"status": "completed"
}
]
}
@@ -0,0 +1,37 @@
{
"document_metadata": {
"document_type": "collaboration_patterns",
"document_name": "DRONE.OBSERVATIONS",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "DRONE",
"tags": ["collaboration", "patterns", "DRONE"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"guidelines": {
"purpose": "Capture collaboration patterns and experiential insights over time",
"chronological_order": "Newest entries at TOP, oldest at BOTTOM - NEVER reorder"
},
"observations": [
{
"date": "2026-03-05",
"session": 1,
"entries": [
{
"title": "First Contact",
"detail": "Branch initialized. Ready to begin capturing collaboration patterns."
}
]
}
]
}
+36
View File
@@ -0,0 +1,36 @@
{
"document_metadata": {
"document_type": "branch_identity",
"document_name": "DRONE.PASSPORT",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "DRONE",
"tags": ["identity", "passport", "branch_profile"]
},
"branch_info": {
"branch_name": "DRONE",
"alias": "",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/drone",
"module": "drone",
"created": "2026-03-05"
},
"identity": {
"role": "Command Router",
"purpose": "",
"what_i_do": [],
"what_i_dont_do": []
},
"principles": [
"Code is truth - fail honestly",
"Memory persists - context survives",
"Simple solutions over complex architecture"
],
"citizenship": {
"registered": true,
"registry_path": ".aipass/registry.json",
"communications": true,
"memory": true
}
}
+62
View File
@@ -0,0 +1,62 @@
{
"_warning": "AUTO-GENERATED FILE - DO NOT MANUALLY EDIT. This file is 100% automated and will be overwritten. Services update their own sections.",
"branch": "DRONE",
"last_updated": "2026-03-05",
"quick_status": {
"new_mail": 0,
"opened_mail": 0,
"active_plans": 0,
"commons_mentions": 0,
"action_required": false,
"summary": ""
},
"sections": {
"ai_mail": {
"managed_by": "ai_mail",
"new": 0,
"opened": 0,
"total": 0,
"oldest_unread_age": null,
"last_dispatch_received": null,
"last_updated": "2026-03-05"
},
"flow": {
"managed_by": "flow",
"active_plans": 0,
"recently_closed": [],
"last_updated": "2026-03-05"
},
"memory_bank": {
"managed_by": "memory_bank",
"vectors_stored": 0,
"notes": {},
"last_updated": "2026-03-05"
},
"devpulse": {
"managed_by": "devpulse",
"summary": {
"issues": 0,
"todos": 0
},
"dplan_counts": {},
"recent_activity": "",
"last_updated": "2026-03-05"
},
"commons_activity": {
"managed_by": "the_commons",
"new_posts_since_last_visit": 0,
"new_comments_since_last_visit": 0,
"mentions": 0,
"trending": "None",
"last_checked": null,
"last_updated": "2026-03-05"
},
"agent_status": {
"managed_by": "prax",
"active_agents": [],
"agent_count": 0,
"stale_agents": [],
"last_updated": "2026-03-05"
}
}
}
+51
View File
@@ -0,0 +1,51 @@
# DRONE
**Purpose:** Command routing, @ resolution, module discovery and dispatch
**Module:** `aipass.drone`
**Created:** 2026-03-05
---
## Overview
### What I Do
### How I Work
- **Entry Point:** `apps/drone.py`
- **Pattern:** Auto-discovers and routes to modules
---
## Architecture
```
DRONE/
├── apps/
│ ├── drone.py # Entry point
│ ├── modules/ # Business logic
│ ├── handlers/ # Implementation
│ └── plugins/ # Extensions
├── docs/
├── tests/
├── passport.json # Identity
├── local.json # Session history
├── observations.json # Collaboration patterns
└── README.md
```
---
## Commands
*Configure after initialization*
---
## Integration Points
### Depends On
### Provides To
+1
View File
@@ -0,0 +1 @@
# DRONE apps package
+86
View File
@@ -0,0 +1,86 @@
"""
DRONE Branch - Main Orchestrator
Auto-discovery architecture:
- Scans modules/ directory for .py files with handle_command()
- Routes commands to discovered modules automatically
- No manual imports or routing needed
"""
import sys
import importlib
from pathlib import Path
from typing import List, Any
from aipass.prax import logger
# =============================================================================
# MODULE DISCOVERY
# =============================================================================
MODULES_DIR = Path(__file__).parent / "modules"
def discover_modules() -> List[Any]:
"""Auto-discover modules in modules/ directory."""
modules = []
if not MODULES_DIR.exists():
return modules
for file_path in MODULES_DIR.glob("*.py"):
if file_path.name.startswith("_"):
continue
module_name = f"apps.modules.{file_path.stem}"
try:
module = importlib.import_module(module_name)
if hasattr(module, "handle_command"):
modules.append(module)
except Exception as e:
logger.error(f"[DRONE] Failed to load module {module_name}: {e}")
return modules
def route_command(command: str, args: List[str], modules: List[Any]) -> bool:
"""Route command to appropriate module."""
for module in modules:
try:
if module.handle_command(command, args):
return True
except Exception as e:
logger.error(f"[DRONE] Module {module.__name__} error: {e}")
return False
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point - routes commands or shows help."""
modules = discover_modules()
args = sys.argv[1:]
if len(args) == 0 or args[0] in ["--help", "-h", "help"]:
print(f"DRONE - {len(modules)} modules discovered")
for module in modules:
name = module.__name__.split(".")[-1]
desc = (module.__doc__ or "").strip().split("\n")[0] if module.__doc__ else "No description"
print(f" {name:20} {desc}")
return 0
command = args[0]
remaining = args[1:] if len(args) > 1 else []
if route_command(command, remaining, modules):
return 0
print(f"Unknown command: {command}")
return 1
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,15 @@
{
"id": "32",
"name": "DRONE Birth Certificate",
"type": "birth_certificate",
"creator": "SYSTEM",
"owner": "DRONE",
"rarity": "unique",
"description": "Official birth certificate for DRONE. Citizen #32, registered using 'library' template. Purpose: Command routing, @ resolution, module discovery and dispatch",
"metadata": {
"citizen_number": "32",
"template": "library",
"purpose": "Command routing, @ resolution, module discovery and dispatch"
},
"created_at": "2026-03-05"
}
+15
View File
@@ -0,0 +1,15 @@
# flow.local.md - DRONE
```
Branch: /home/aipass/aipass_business/AIPass/src/aipass/drone
Created: 2026-03-05
```
## Issues
-
---
## Todos
-
+21
View File
@@ -0,0 +1,21 @@
[pytest]
# Test discovery paths
testpaths = tests
# Test file patterns
python_files = test_*.py
python_functions = test_*
python_classes = Test*
# Command-line options (always applied)
addopts =
-v # Verbose output
--tb=short # Short traceback format
--strict-markers # Raise error on unknown markers
-ra # Show summary of all test outcomes
# Test markers (for categorizing tests)
markers =
unit: Unit tests
integration: Integration tests
slow: Tests that take significant time
+1
View File
@@ -0,0 +1 @@
# Tests package for drone
+43
View File
@@ -0,0 +1,43 @@
#!/home/aipass/.venv/bin/python3
# ===================AIPASS====================
# META DATA HEADER
# Name: tests/conftest.py
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/tests
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Shared pytest fixtures
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""Shared pytest fixtures for cortex tests"""
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
@pytest.fixture
def temp_test_dir() -> Generator[Path, None, None]:
"""Creates temporary directory for testing, cleans up after"""
test_dir = Path(tempfile.mkdtemp())
yield test_dir
if test_dir.exists():
shutil.rmtree(test_dir)
@pytest.fixture
def sample_test_data() -> dict:
"""Provides sample test data
Customize this fixture for your module's needs
"""
return {
"test_key": "test_value",
"sample_data": "example"
}
+159
View File
@@ -0,0 +1,159 @@
#!/home/aipass/.venv/bin/python3
# -*- coding: utf-8 -*-
# ===================AIPASS====================
# META DATA HEADER
# Name: verify_branch.py - Branch Template Verification
# Date: 2025-11-08
# Version: 1.0.0
# Category: cortex/modules
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2025-11-08): Initial implementation - Compare template vs branch
#
# CODE STANDARDS:
# - Error handling: Use error handler system (apps/handlers/error/)
# =============================================
"""
Branch Template Verification Tool
Compares template directory with created branch to identify:
- Files in template but missing in branch
- Files in branch but not in template
- Renamed files
"""
import sys
import json
from pathlib import Path
from typing import Set, List, Tuple
from fnmatch import fnmatch
# INFRASTRUCTURE IMPORT PATTERN
AIPASS_ROOT = Path.home() / "aipass_core"
sys.path.insert(0, str(AIPASS_ROOT))
# Get template directory
TEMPLATE_DIR = AIPASS_ROOT / "cortex" / "templates" / "branch_template"
def load_ignore_patterns() -> Tuple[List[str], List[str]]:
"""Load ignore patterns from .registry_ignore.json"""
ignore_file = TEMPLATE_DIR / ".registry_ignore.json"
if not ignore_file.exists():
return [], []
try:
with open(ignore_file, 'r', encoding='utf-8') as f:
data = json.load(f)
ignore_files = data.get("ignore_files", [])
ignore_patterns = data.get("ignore_patterns", [])
return ignore_files, ignore_patterns
except Exception as e:
print(f"Warning: Could not load .registry_ignore.json: {e}")
return [], []
def should_exclude(path: Path, base_dir: Path, ignore_files: List[str], ignore_patterns: List[str]) -> bool:
"""Check if path should be excluded based on ignore patterns"""
rel_path = path.relative_to(base_dir)
filename = path.name
path_str = str(rel_path)
# Check exact filename matches
if filename in ignore_files:
return True
# Check glob patterns
for pattern in ignore_patterns:
if fnmatch(filename, pattern):
return True
# Check if any parent directory matches
for part in rel_path.parts:
if fnmatch(part, pattern):
return True
return False
def get_file_set(directory: Path, ignore_files: List[str], ignore_patterns: List[str]) -> Set[str]:
"""Get set of all file paths in directory (relative)"""
files = set()
for item in directory.rglob("*"):
if item.is_file() and not should_exclude(item, directory, ignore_files, ignore_patterns):
rel_path = str(item.relative_to(directory))
files.add(rel_path)
return files
def verify_branch(branch_dir: Path) -> Tuple[List[str], List[str], List[str]]:
"""
Compare template with branch
Returns:
Tuple of (in_template_only, in_branch_only, in_both)
"""
# Load ignore patterns from .registry_ignore.json
ignore_files, ignore_patterns = load_ignore_patterns()
template_files = get_file_set(TEMPLATE_DIR, ignore_files, ignore_patterns)
branch_files = get_file_set(branch_dir, ignore_files, ignore_patterns)
in_template_only = sorted(template_files - branch_files)
in_branch_only = sorted(branch_files - template_files)
in_both = sorted(template_files & branch_files)
return in_template_only, in_branch_only, in_both
def main():
if len(sys.argv) < 2:
print("Usage: python3 verify_branch.py <branch_directory>")
print("Example: python3 verify_branch.py test_branch002")
sys.exit(1)
branch_path = Path(sys.argv[1])
if not branch_path.is_absolute():
# Assume it's relative to cortex directory
branch_path = Path.cwd() / branch_path
if not branch_path.exists():
print(f"❌ ERROR: Branch directory not found: {branch_path}")
sys.exit(1)
print(f"\n=== Branch Verification ===")
print(f"Template: {TEMPLATE_DIR}")
print(f"Branch: {branch_path}")
print()
in_template_only, in_branch_only, in_both = verify_branch(branch_path)
print(f"Files in both: {len(in_both)}")
print(f"Files in template only: {len(in_template_only)}")
print(f"Files in branch only: {len(in_branch_only)}")
print()
if in_template_only:
print("❌ Missing from branch (expected from template):")
for file in in_template_only:
print(f" - {file}")
print()
if in_branch_only:
print("✅ Additional files in branch (renamed or new):")
for file in in_branch_only:
print(f" + {file}")
print()
if not in_template_only and not in_branch_only:
print("✅ Branch matches template perfectly")
print("="*70)
if __name__ == "__main__":
main()
@@ -0,0 +1,37 @@
{
"metadata": {
"version": "1.0.0",
"description": "Files and patterns to exclude when creating branch backups"
},
"ignore_directories": [
".backup",
".venv",
"venv",
"node_modules",
"__pycache__",
".git",
".cache",
".pytest_cache",
".mypy_cache",
"dist",
"build",
"*.egg-info",
"ai_mail.local",
"logs",
".aipass",
".archive",
".claude",
"htmlcov"
],
"ignore_patterns": [
"*.pyc",
"*.pyo",
".DS_Store",
"*.log",
"*.tmp",
"*.swp",
"*~",
"*.env",
"BRANCH_REGISTRY.json"
]
}
+49
View File
@@ -0,0 +1,49 @@
{
"metadata": {
"version": "1.0.0",
"description": "Template structural migrations for branch updates",
"last_updated": "2025-11-07",
"applies_to_versions": ["all"]
},
"migrations": [
{
"id": "m001",
"description": "Example: Migrate flat metadata to document_metadata structure",
"version_introduced": "1.0.0",
"applies_to_files": ["*.id.json"],
"operations": [
{
"type": "key_rename",
"from": "metadata",
"to": "document_metadata"
},
{
"type": "move_to_nested",
"source_keys": ["branch_name", "path", "profile"],
"target_parent": "branch_info"
},
{
"type": "add_missing_keys",
"parent": "document_metadata",
"keys": {
"document_type": "branch_identity",
"schema_version": "1.0.0"
}
}
]
}
],
"options": {
"skip_if_target_exists": true,
"preserve_unknown_keys": true,
"recursive_application": false
},
"notes": {
"usage": "This file defines structural transformation rules applied during branch updates",
"pattern_matching": "applies_to_files uses glob patterns (*.json, *.id.json, etc.)",
"operation_order": "Operations execute in order listed within each migration",
"skip_behavior": "Operations skip if already compliant (target exists = success)",
"supported_operations": ["key_rename", "move_to_nested", "add_missing_keys"],
"future_operations": ["split_key", "combine_keys", "delete_key", "transform_value"]
}
}
@@ -0,0 +1,43 @@
{
"metadata": {
"version": "1.1.0",
"description": "Files and patterns to exclude when updating branches from template",
"last_updated": "2025-11-09"
},
"ignore_files": [
".template_registry.json",
".registry_ignore.json"
],
"ignore_patterns": [
"__pycache__",
"*.pyc",
"#@comments.txt",
".backup_*"
],
"notes": {
"how_it_works": "Two types of exclusions during branch updates:",
"ignore_files": {
"description": "Exact filename matches (no wildcards)",
"purpose": "Template-internal management files that branches don't need",
"examples": [
".template_registry.json (template's file tracking list)",
".registry_ignore.json (this config file)"
]
},
"ignore_patterns": {
"description": "Glob patterns - matches filenames AND directory names",
"purpose": "Exclude generated files, caches, and user content markers",
"examples": [
"__pycache__ (Python cache directories)",
"*.pyc (Python compiled bytecode files)",
"#@comments.txt (user comment files)",
".backup_* (timestamped backup files like .backup_20251109, NOT .backup directory)"
],
"how_matching_works": [
"Step 1: Check if filename matches pattern (e.g., file.pyc matches *.pyc)",
"Step 2: Check if any parent directory matches (e.g., files inside __pycache__/ dir)"
]
},
"what_gets_ignored": "These files never copy to branches during updates - they stay template-only"
}
}
@@ -0,0 +1,184 @@
{
"metadata": {
"description": "Template registry for tracking files",
"generated": true
},
"files": {
"f001": {
"path": ".aipass/aipass_local_prompt.md",
"name": "aipass_local_prompt.md",
"content_hash": "d9f30eec94323dce",
"has_branch_placeholder": false
},
"f002": {
"path": ".claude/settings.local.json",
"name": "settings.local.json",
"content_hash": "6379c5be3fb714ac",
"has_branch_placeholder": false
},
"f003": {
"path": ".gitignore",
"name": ".gitignore",
"content_hash": "841dedb922da7ddb",
"has_branch_placeholder": false
},
"f004": {
"path": ".trinity/local.json",
"name": "local.json",
"content_hash": "73802b130cf702c0",
"has_branch_placeholder": false
},
"f005": {
"path": ".trinity/observations.json",
"name": "observations.json",
"content_hash": "ca99db1e971f87b8",
"has_branch_placeholder": false
},
"f006": {
"path": ".trinity/passport.json",
"name": "passport.json",
"content_hash": "401de7ee8be708f2",
"has_branch_placeholder": false
},
"f007": {
"path": "DASHBOARD.local.json",
"name": "DASHBOARD.local.json",
"content_hash": "84bbf1dcba695ba9",
"has_branch_placeholder": false
},
"f008": {
"path": "README.md",
"name": "README.md",
"content_hash": "d6db2cf386aadb48",
"has_branch_placeholder": false
},
"f009": {
"path": "apps/__init__.py",
"name": "__init__.py",
"content_hash": "d21e6e1e683010c4",
"has_branch_placeholder": false
},
"f010": {
"path": "apps/branch.py",
"name": "branch.py",
"content_hash": "b57c3cacbc7ceed6",
"has_branch_placeholder": false
},
"f011": {
"path": "apps/handlers/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f012": {
"path": "apps/modules/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f013": {
"path": "apps/plugins/__init__.py",
"name": "__init__.py",
"content_hash": "e3b0c44298fc1c14",
"has_branch_placeholder": false
},
"f014": {
"path": "artifacts/birth_certificate.json",
"name": "birth_certificate.json",
"content_hash": "f67445a5ca0421e2",
"has_branch_placeholder": false
},
"f015": {
"path": "flow.local.md",
"name": "flow.local.md",
"content_hash": "aa99b6d661fcc117",
"has_branch_placeholder": false
},
"f016": {
"path": "pytest.ini",
"name": "pytest.ini",
"content_hash": "7b39ba7bca4025c5",
"has_branch_placeholder": false
},
"f017": {
"path": "tests/__init__.py",
"name": "__init__.py",
"content_hash": "8d879ba57a180e9b",
"has_branch_placeholder": false
},
"f018": {
"path": "tests/conftest.py",
"name": "conftest.py",
"content_hash": "5e5f2399e0d70978",
"has_branch_placeholder": false
},
"f019": {
"path": "tools/verify_branch.py",
"name": "verify_branch.py",
"content_hash": "06803a84118e5453",
"has_branch_placeholder": false
}
},
"directories": {
"d001": {
"path": ".aipass",
"name": ".aipass"
},
"d002": {
"path": ".archive",
"name": ".archive"
},
"d003": {
"path": ".claude",
"name": ".claude"
},
"d004": {
"path": ".trinity",
"name": ".trinity"
},
"d005": {
"path": "apps",
"name": "apps"
},
"d006": {
"path": "apps/handlers",
"name": "handlers"
},
"d007": {
"path": "apps/modules",
"name": "modules"
},
"d008": {
"path": "apps/plugins",
"name": "plugins"
},
"d009": {
"path": "artifacts",
"name": "artifacts"
},
"d010": {
"path": "docs",
"name": "docs"
},
"d011": {
"path": "dropbox",
"name": "dropbox"
},
"d012": {
"path": "flow_json",
"name": "flow_json"
},
"d013": {
"path": "templates",
"name": "templates"
},
"d014": {
"path": "tests",
"name": "tests"
},
"d015": {
"path": "tools",
"name": "tools"
}
}
}
+14
View File
@@ -0,0 +1,14 @@
__pycache__/
*.pyc
*.pyo
.env
*.egg-info/
.coverage
htmlcov/
.pytest_cache/
.mypy_cache/
dist/
build/
*.log
*.tmp
*.swp
+34
View File
@@ -0,0 +1,34 @@
{
"document_metadata": {
"document_type": "session_history",
"document_name": "FLOW.LOCAL",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "FLOW",
"tags": ["session_tracking", "work_log", "FLOW"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"active_tasks": {
"today_focus": "2026-03-05",
"recently_completed": []
},
"key_learnings": {},
"sessions": [
{
"session_number": 1,
"date": "2026-03-05",
"summary": "Branch initialized - FLOW created by aipass init",
"status": "completed"
}
]
}
@@ -0,0 +1,37 @@
{
"document_metadata": {
"document_type": "collaboration_patterns",
"document_name": "FLOW.OBSERVATIONS",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "FLOW",
"tags": ["collaboration", "patterns", "FLOW"],
"limits": {
"max_lines": 600,
"note": "Auto-rollover when max_lines exceeded"
},
"status": {
"health": "healthy",
"current_lines": 0,
"last_health_check": "2026-03-05"
}
},
"guidelines": {
"purpose": "Capture collaboration patterns and experiential insights over time",
"chronological_order": "Newest entries at TOP, oldest at BOTTOM - NEVER reorder"
},
"observations": [
{
"date": "2026-03-05",
"session": 1,
"entries": [
{
"title": "First Contact",
"detail": "Branch initialized. Ready to begin capturing collaboration patterns."
}
]
}
]
}
+36
View File
@@ -0,0 +1,36 @@
{
"document_metadata": {
"document_type": "branch_identity",
"document_name": "FLOW.PASSPORT",
"version": "1.0.0",
"schema_version": "1.0.0",
"created": "2026-03-05",
"last_updated": "2026-03-05",
"managed_by": "FLOW",
"tags": ["identity", "passport", "branch_profile"]
},
"branch_info": {
"branch_name": "FLOW",
"alias": "",
"path": "/home/aipass/aipass_business/AIPass/src/aipass/flow",
"module": "flow",
"created": "2026-03-05"
},
"identity": {
"role": "Planning & Workflow",
"purpose": "",
"what_i_do": [],
"what_i_dont_do": []
},
"principles": [
"Code is truth - fail honestly",
"Memory persists - context survives",
"Simple solutions over complex architecture"
],
"citizenship": {
"registered": true,
"registry_path": ".aipass/registry.json",
"communications": true,
"memory": true
}
}
+62
View File
@@ -0,0 +1,62 @@
{
"_warning": "AUTO-GENERATED FILE - DO NOT MANUALLY EDIT. This file is 100% automated and will be overwritten. Services update their own sections.",
"branch": "FLOW",
"last_updated": "2026-03-05",
"quick_status": {
"new_mail": 0,
"opened_mail": 0,
"active_plans": 0,
"commons_mentions": 0,
"action_required": false,
"summary": ""
},
"sections": {
"ai_mail": {
"managed_by": "ai_mail",
"new": 0,
"opened": 0,
"total": 0,
"oldest_unread_age": null,
"last_dispatch_received": null,
"last_updated": "2026-03-05"
},
"flow": {
"managed_by": "flow",
"active_plans": 0,
"recently_closed": [],
"last_updated": "2026-03-05"
},
"memory_bank": {
"managed_by": "memory_bank",
"vectors_stored": 0,
"notes": {},
"last_updated": "2026-03-05"
},
"devpulse": {
"managed_by": "devpulse",
"summary": {
"issues": 0,
"todos": 0
},
"dplan_counts": {},
"recent_activity": "",
"last_updated": "2026-03-05"
},
"commons_activity": {
"managed_by": "the_commons",
"new_posts_since_last_visit": 0,
"new_comments_since_last_visit": 0,
"mentions": 0,
"trending": "None",
"last_checked": null,
"last_updated": "2026-03-05"
},
"agent_status": {
"managed_by": "prax",
"active_agents": [],
"agent_count": 0,
"stale_agents": [],
"last_updated": "2026-03-05"
}
}
}
+51
View File
@@ -0,0 +1,51 @@
# FLOW
**Purpose:** Plan lifecycle management - DPLAN/FPLAN/MPLAN creation, tracking, closure
**Module:** `aipass.flow`
**Created:** 2026-03-05
---
## Overview
### What I Do
### How I Work
- **Entry Point:** `apps/flow.py`
- **Pattern:** Auto-discovers and routes to modules
---
## Architecture
```
FLOW/
├── apps/
│ ├── flow.py # Entry point
│ ├── modules/ # Business logic
│ ├── handlers/ # Implementation
│ └── plugins/ # Extensions
├── docs/
├── tests/
├── passport.json # Identity
├── local.json # Session history
├── observations.json # Collaboration patterns
└── README.md
```
---
## Commands
*Configure after initialization*
---
## Integration Points
### Depends On
### Provides To
+1
View File
@@ -0,0 +1 @@
# FLOW apps package
+86
View File
@@ -0,0 +1,86 @@
"""
FLOW Branch - Main Orchestrator
Auto-discovery architecture:
- Scans modules/ directory for .py files with handle_command()
- Routes commands to discovered modules automatically
- No manual imports or routing needed
"""
import sys
import importlib
from pathlib import Path
from typing import List, Any
from aipass.prax import logger
# =============================================================================
# MODULE DISCOVERY
# =============================================================================
MODULES_DIR = Path(__file__).parent / "modules"
def discover_modules() -> List[Any]:
"""Auto-discover modules in modules/ directory."""
modules = []
if not MODULES_DIR.exists():
return modules
for file_path in MODULES_DIR.glob("*.py"):
if file_path.name.startswith("_"):
continue
module_name = f"apps.modules.{file_path.stem}"
try:
module = importlib.import_module(module_name)
if hasattr(module, "handle_command"):
modules.append(module)
except Exception as e:
logger.error(f"[FLOW] Failed to load module {module_name}: {e}")
return modules
def route_command(command: str, args: List[str], modules: List[Any]) -> bool:
"""Route command to appropriate module."""
for module in modules:
try:
if module.handle_command(command, args):
return True
except Exception as e:
logger.error(f"[FLOW] Module {module.__name__} error: {e}")
return False
# =============================================================================
# MAIN ENTRY POINT
# =============================================================================
def main():
"""Main entry point - routes commands or shows help."""
modules = discover_modules()
args = sys.argv[1:]
if len(args) == 0 or args[0] in ["--help", "-h", "help"]:
print(f"FLOW - {len(modules)} modules discovered")
for module in modules:
name = module.__name__.split(".")[-1]
desc = (module.__doc__ or "").strip().split("\n")[0] if module.__doc__ else "No description"
print(f" {name:20} {desc}")
return 0
command = args[0]
remaining = args[1:] if len(args) > 1 else []
if route_command(command, remaining, modules):
return 0
print(f"Unknown command: {command}")
return 1
if __name__ == "__main__":
sys.exit(main())

Some files were not shown because too many files have changed in this diff Show More