Skip to content

Commit 7a4e8ee

Browse files
committed
docs: Add extension contracts and ADRs
- extensions/EXTENSIONS.md: Extension system definition - modules/CONTRACTS.md: Module interfaces - modules/ADRS: Architectural decisions
1 parent 0ea6abb commit 7a4e8ee

3 files changed

Lines changed: 286 additions & 0 deletions

File tree

extensions/EXTENSIONS.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Extension Points for heliosCLI System
2+
3+
## Overview
4+
5+
Extensions allow heliosCLI (and harbor framework) to be extended without modifying core code. This document defines the extension system.
6+
7+
## Extension Types
8+
9+
### 1. CLI Commands
10+
11+
```yaml
12+
# Extension point: codex_command
13+
# Location: clones/codex/cli/extensions/
14+
command:
15+
name: my-extension
16+
description: "My custom command"
17+
arguments:
18+
- name: input
19+
type: string
20+
required: true
21+
handler: extensions.commands.my_extension
22+
```
23+
24+
### 2. Harbor Adapters
25+
26+
```yaml
27+
# Extension point: harbor_adapter
28+
# Location: portage/harbor/adapters/
29+
adapter:
30+
name: custom-backend
31+
type: http
32+
config:
33+
base_url: https://api.example.com
34+
handlers:
35+
- on_request
36+
- on_response
37+
```
38+
39+
### 3. Portage Modules
40+
41+
```python
42+
# Extension point: portage_module
43+
# Location: portage/portage_modules/
44+
class MyModule(PortageModule):
45+
name = "my_module"
46+
version = "1.0.0"
47+
48+
def process(self, context):
49+
pass
50+
```
51+
52+
### 4. Template Renderers
53+
54+
```python
55+
# Extension point: template_renderer
56+
class CustomRenderer(TemplateRenderer):
57+
extensions = [".custom"]
58+
59+
def render(self, template, context):
60+
pass
61+
```
62+
63+
## Extension Discovery
64+
65+
Extensions are discovered via:
66+
1. `pyproject.toml` entry points
67+
2. Extension directories (configurable)
68+
3. External plugin registries
69+
70+
## Loading Order
71+
72+
1. Core extensions (built-in)
73+
2. System extensions (`~/.helios/extensions/`)
74+
3. Project extensions (`./helios_extensions/`)
75+
4. Dynamic (runtime loaded)
76+
77+
## Example Extension Structure
78+
79+
```
80+
extensions/
81+
├── pyproject.toml
82+
├── src/
83+
│ └── my_extension/
84+
│ ├── __init__.py
85+
│ ├── plugin.yaml
86+
│ ├── handlers.py
87+
│ └── tests/
88+
└── README.md
89+
```
90+
91+
## plugin.yaml Schema
92+
93+
```yaml
94+
name: my-extension
95+
version: 1.0.0
96+
helios_version: ">=2.0.0"
97+
entry_points:
98+
commands:
99+
- my-command
100+
adapters:
101+
- my-adapter
102+
dependencies:
103+
- package>=1.0
104+
- another-package
105+
```
106+
107+
## Publishing Extensions
108+
109+
```bash
110+
# Publish to PyPI
111+
helios extension publish
112+
113+
# Install from PyPI
114+
helios extension install my-extension
115+
```

modules/ADRS.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Architectural Decision Records
2+
3+
## ADR-001: Plugin-Based Extension System
4+
5+
**Status:** Proposed
6+
7+
**Context:** heliosCLI needs to support extensions without core changes
8+
9+
**Decision:** Use plugin architecture with entry points
10+
11+
**Consequences:**
12+
- Extensions load at runtime
13+
- Clear contracts for extensions
14+
- Version compatibility checking
15+
16+
---
17+
18+
## ADR-002: Async-First Handlers
19+
20+
**Status:** Proposed
21+
22+
**Context:** I/O-bound operations require async support
23+
24+
**Decision:** All handlers must support async execution
25+
26+
**Consequences:**
27+
- Use asyncio throughout
28+
- Provide sync wrappers for compatibility
29+
30+
---
31+
32+
## ADR-003: Configuration-Driven Modules
33+
34+
**Status:** Proposed
35+
36+
**Context:** Modules need flexible configuration
37+
38+
**Decision:** YAML/JSON config with validation
39+
40+
**Consequences:**
41+
- Schema validation on load
42+
- Hot reload support
43+
- Environment variable interpolation

modules/CONTRACTS.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Module Contracts
2+
3+
## Base Module Interface
4+
5+
All modules must implement this interface:
6+
7+
```python
8+
from abc import ABC, abstractmethod
9+
from typing import Any, Dict, Optional
10+
11+
class Module(ABC):
12+
"""Base module interface."""
13+
14+
@property
15+
@abstractmethod
16+
def name(self) -> str:
17+
"""Module name."""
18+
pass
19+
20+
@property
21+
@abstractmethod
22+
def version(self) -> str:
23+
"""Module version."""
24+
pass
25+
26+
@property
27+
def dependencies(self) -> list[str]:
28+
"""Module dependencies."""
29+
return []
30+
31+
@abstractmethod
32+
def initialize(self, config: Dict[str, Any]) -> None:
33+
"""Initialize module with configuration."""
34+
pass
35+
36+
@abstractmethod
37+
def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
38+
"""Execute module logic."""
39+
pass
40+
41+
@abstractmethod
42+
def shutdown(self) -> None:
43+
"""Cleanup resources."""
44+
pass
45+
46+
def validate(self) -> bool:
47+
"""Validate module configuration."""
48+
return True
49+
```
50+
51+
## Handler Contract
52+
53+
```python
54+
class Handler(ABC):
55+
"""Handler interface for processing requests."""
56+
57+
@property
58+
def event_types(self) -> list[str]:
59+
"""Events this handler subscribes to."""
60+
return []
61+
62+
async def handle(self, event: Event) -> Response:
63+
"""Process event and return response."""
64+
pass
65+
66+
def cleanup(self) -> None:
67+
"""Release resources."""
68+
pass
69+
```
70+
71+
## Adapter Contract
72+
73+
```python
74+
class Adapter(ABC):
75+
"""Adapter for external systems."""
76+
77+
@property
78+
def name(self) -> str:
79+
pass
80+
81+
async def connect(self) -> None:
82+
pass
83+
84+
async def disconnect(self) -> None:
85+
pass
86+
87+
async def send(self, message: Message) -> Response:
88+
pass
89+
90+
def health_check(self) -> HealthStatus:
91+
pass
92+
```
93+
94+
## Validator Contract
95+
96+
```python
97+
class Validator(ABC):
98+
"""Input/output validation."""
99+
100+
@property
101+
def schema(self) -> dict:
102+
pass
103+
104+
def validate(self, data: Any) -> ValidationResult:
105+
pass
106+
107+
def validate_response(self, response: Any) -> bool:
108+
pass
109+
```
110+
111+
## Registry Pattern
112+
113+
```python
114+
class ModuleRegistry:
115+
"""Central module registration."""
116+
117+
def register(self, module: Module) -> None:
118+
...
119+
120+
def get(self, name: str) -> Module:
121+
...
122+
123+
def list_modules(self) -> list[str]:
124+
...
125+
126+
def unregister(self, name: str) -> None:
127+
...
128+
```

0 commit comments

Comments
 (0)