speexor 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API-REFERENCE.md +96 -1
- package/ARCHITECTURE.md +84 -33
- package/BENCHMARKS.md +52 -0
- package/CHANGELOG.md +35 -4
- package/CODE-OF-CONDUCT.md +83 -83
- package/CONTRIBUTING.md +98 -98
- package/FAQ.md +105 -105
- package/GLOSSARY.md +33 -0
- package/LICENSE.md +21 -21
- package/PUBLISH.md +77 -77
- package/README.md +222 -8
- package/REFACTOR-LOG.md +40 -40
- package/ROADMAP.md +37 -15
- package/SECURITY-DEFAULTS.md +118 -0
- package/SECURITY.md +79 -79
- package/SUMMARY.md +31 -8
- package/TESTING.md +140 -140
- package/dist/{agent-5D3BVWNK.js → agent-D4BRWEOZ.js} +4 -4
- package/dist/agent-D4BRWEOZ.js.map +1 -0
- package/dist/{chunk-2F66BZYJ.js → chunk-2DX54KIM.js} +2 -2
- package/dist/chunk-2DX54KIM.js.map +1 -0
- package/dist/{chunk-B7WLHC4W.js → chunk-7VZHDGRQ.js} +2 -2
- package/dist/chunk-7VZHDGRQ.js.map +1 -0
- package/dist/{chunk-SXALZEOJ.js → chunk-AOFWQZWY.js} +2 -2
- package/dist/chunk-AOFWQZWY.js.map +1 -0
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.js +1 -1
- package/docs/SETUP.md +94 -94
- package/docs/TROUBLESHOOTING.md +113 -113
- package/docs/adr/0001-record-architecture-decisions.md +44 -0
- package/docs/adr/0002-plugin-architecture.md +53 -0
- package/docs/adr/0003-recursive-task-decomposition.md +57 -0
- package/docs/adr/0004-local-first-security.md +58 -0
- package/docs/adr/0005-data-directory-layout.md +69 -0
- package/examples/basic.yaml +61 -61
- package/package.json +103 -102
- package/schema/config.schema.json +119 -119
- package/speexor.config.yaml.example +30 -30
- package/dist/agent-5D3BVWNK.js.map +0 -1
- package/dist/chunk-2F66BZYJ.js.map +0 -1
- package/dist/chunk-B7WLHC4W.js.map +0 -1
- package/dist/chunk-SXALZEOJ.js.map +0 -1
package/docs/SETUP.md
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
# Speexor Setup Guide
|
|
2
|
-
|
|
3
|
-
## Prerequisites
|
|
4
|
-
|
|
5
|
-
- **Node.js** >= 18.0.0
|
|
6
|
-
- **pnpm** (recommended) or npm
|
|
7
|
-
- **Git** >= 2.30 (for `git worktree` support)
|
|
8
|
-
- **GitHub CLI** (`gh`) — for tracker & SCM plugins (optional for local-only mode)
|
|
9
|
-
- **tmux** >= 3.0 — for tmux runtime (macOS/Linux, optional with process fallback)
|
|
10
|
-
- One or more AI coding agent CLIs:
|
|
11
|
-
- [OpenCode CLI](https://github.com/superdevids/opencode)
|
|
12
|
-
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
13
|
-
- [Aider](https://aider.chat/)
|
|
14
|
-
- [Codex CLI](https://github.com/openai/codex)
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# Via npm
|
|
20
|
-
npm install -g
|
|
21
|
-
|
|
22
|
-
# Or via pnpm
|
|
23
|
-
pnpm add -g
|
|
24
|
-
|
|
25
|
-
# Or run from the monorepo
|
|
26
|
-
cd speexjs
|
|
27
|
-
pnpm install
|
|
28
|
-
pnpm --filter
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Quick Start
|
|
32
|
-
|
|
33
|
-
### 1. Initialize a project
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd /path/to/your/project
|
|
37
|
-
speexor start https://github.com/username/repo.git
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
This will:
|
|
41
|
-
- Create `speexor.config.yaml` with default configuration
|
|
42
|
-
- Create `.speexor/` directory for worktrees and logs
|
|
43
|
-
- Start the dashboard at `http://localhost:3000`
|
|
44
|
-
|
|
45
|
-
### 2. Spawn an agent for a task
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
# Using a GitHub issue ID
|
|
49
|
-
speexor agent spawn --task 42 --agent opencode
|
|
50
|
-
|
|
51
|
-
# Using a custom task ID
|
|
52
|
-
speexor agent spawn --task "feature-auth" --agent claude-code
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 3. Monitor progress
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Open dashboard in browser
|
|
59
|
-
open http://localhost:3000
|
|
60
|
-
|
|
61
|
-
# List active sessions
|
|
62
|
-
speexor list
|
|
63
|
-
|
|
64
|
-
# View agent logs
|
|
65
|
-
speexor logs <session-id>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### 4. Stop a session
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
speexor stop <session-id>
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Configuration
|
|
75
|
-
|
|
76
|
-
See `speexor config-help` for full schema reference, or refer to `examples/basic.yaml` in the package.
|
|
77
|
-
|
|
78
|
-
## Plugin Architecture
|
|
79
|
-
|
|
80
|
-
Speexor uses a 7-slot plugin architecture:
|
|
81
|
-
|
|
82
|
-
| Slot | Purpose | Default Plugin |
|
|
83
|
-
|------|---------|---------------|
|
|
84
|
-
| **Agent** | AI coding agent adapter | OpenCode, Claude Code, Aider, Codex |
|
|
85
|
-
| **Runtime** | Process execution environment | tmux (Unix), Process (Windows) |
|
|
86
|
-
| **Workspace** | Code isolation strategy | Git Worktree |
|
|
87
|
-
| **Tracker** | Task/issue source | GitHub Issues |
|
|
88
|
-
| **SCM** | Git/PR operations | GitHub (gh CLI) |
|
|
89
|
-
| **Notifier** | Alert channel | Desktop notifications |
|
|
90
|
-
| **Terminal** | Live session viewer | Web (dashboard) |
|
|
91
|
-
|
|
92
|
-
## Troubleshooting
|
|
93
|
-
|
|
94
|
-
See [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for common issues.
|
|
1
|
+
# Speexor Setup Guide
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- **Node.js** >= 18.0.0
|
|
6
|
+
- **pnpm** (recommended) or npm
|
|
7
|
+
- **Git** >= 2.30 (for `git worktree` support)
|
|
8
|
+
- **GitHub CLI** (`gh`) — for tracker & SCM plugins (optional for local-only mode)
|
|
9
|
+
- **tmux** >= 3.0 — for tmux runtime (macOS/Linux, optional with process fallback)
|
|
10
|
+
- One or more AI coding agent CLIs:
|
|
11
|
+
- [OpenCode CLI](https://github.com/superdevids/opencode)
|
|
12
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
13
|
+
- [Aider](https://aider.chat/)
|
|
14
|
+
- [Codex CLI](https://github.com/openai/codex)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Via npm
|
|
20
|
+
npm install -g speexor
|
|
21
|
+
|
|
22
|
+
# Or via pnpm
|
|
23
|
+
pnpm add -g speexor
|
|
24
|
+
|
|
25
|
+
# Or run from the monorepo
|
|
26
|
+
cd speexjs
|
|
27
|
+
pnpm install
|
|
28
|
+
pnpm --filter speexor build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### 1. Initialize a project
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd /path/to/your/project
|
|
37
|
+
speexor start https://github.com/username/repo.git
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This will:
|
|
41
|
+
- Create `speexor.config.yaml` with default configuration
|
|
42
|
+
- Create `.speexor/` directory for worktrees and logs
|
|
43
|
+
- Start the dashboard at `http://localhost:3000`
|
|
44
|
+
|
|
45
|
+
### 2. Spawn an agent for a task
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Using a GitHub issue ID
|
|
49
|
+
speexor agent spawn --task 42 --agent opencode
|
|
50
|
+
|
|
51
|
+
# Using a custom task ID
|
|
52
|
+
speexor agent spawn --task "feature-auth" --agent claude-code
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Monitor progress
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Open dashboard in browser
|
|
59
|
+
open http://localhost:3000
|
|
60
|
+
|
|
61
|
+
# List active sessions
|
|
62
|
+
speexor list
|
|
63
|
+
|
|
64
|
+
# View agent logs
|
|
65
|
+
speexor logs <session-id>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 4. Stop a session
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
speexor stop <session-id>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
See `speexor config-help` for full schema reference, or refer to `examples/basic.yaml` in the package.
|
|
77
|
+
|
|
78
|
+
## Plugin Architecture
|
|
79
|
+
|
|
80
|
+
Speexor uses a 7-slot plugin architecture:
|
|
81
|
+
|
|
82
|
+
| Slot | Purpose | Default Plugin |
|
|
83
|
+
|------|---------|---------------|
|
|
84
|
+
| **Agent** | AI coding agent adapter | OpenCode, Claude Code, Aider, Codex |
|
|
85
|
+
| **Runtime** | Process execution environment | tmux (Unix), Process (Windows) |
|
|
86
|
+
| **Workspace** | Code isolation strategy | Git Worktree |
|
|
87
|
+
| **Tracker** | Task/issue source | GitHub Issues |
|
|
88
|
+
| **SCM** | Git/PR operations | GitHub (gh CLI) |
|
|
89
|
+
| **Notifier** | Alert channel | Desktop notifications |
|
|
90
|
+
| **Terminal** | Live session viewer | Web (dashboard) |
|
|
91
|
+
|
|
92
|
+
## Troubleshooting
|
|
93
|
+
|
|
94
|
+
See [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for common issues.
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
# Speexor Troubleshooting Guide
|
|
2
|
-
|
|
3
|
-
## Common Issues
|
|
4
|
-
|
|
5
|
-
### "speexor.config.yaml not found"
|
|
6
|
-
|
|
7
|
-
**Cause:** You ran `speexor list` or `speexor agent spawn` without initializing a project first.
|
|
8
|
-
|
|
9
|
-
**Fix:** Run `speexor start <repo-url>` to create the config file, or manually create `speexor.config.yaml` in your project root.
|
|
10
|
-
|
|
11
|
-
### "Not a git repository"
|
|
12
|
-
|
|
13
|
-
**Cause:** You're running `speexor` outside a git repository.
|
|
14
|
-
|
|
15
|
-
**Fix:** Navigate to a git repository or run `git init` first.
|
|
16
|
-
|
|
17
|
-
### "tmux not available"
|
|
18
|
-
|
|
19
|
-
**Cause:** tmux is not installed on your system.
|
|
20
|
-
|
|
21
|
-
**Fix (macOS):**
|
|
22
|
-
```bash
|
|
23
|
-
brew install tmux
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**Fix (Linux):**
|
|
27
|
-
```bash
|
|
28
|
-
sudo apt install tmux # Debian/Ubuntu
|
|
29
|
-
sudo dnf install tmux # Fedora
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
**Fix (Windows):** Speexor will automatically fall back to the Process runtime on Windows.
|
|
33
|
-
|
|
34
|
-
### "GitHub CLI (gh) not found"
|
|
35
|
-
|
|
36
|
-
**Cause:** The `gh` CLI is not installed but required for GitHub tracker/SCM plugins.
|
|
37
|
-
|
|
38
|
-
**Fix:**
|
|
39
|
-
```bash
|
|
40
|
-
# macOS
|
|
41
|
-
brew install gh
|
|
42
|
-
|
|
43
|
-
# Linux (Debian/Ubuntu)
|
|
44
|
-
sudo apt install gh
|
|
45
|
-
|
|
46
|
-
# Windows (winget)
|
|
47
|
-
winget install GitHub.cli
|
|
48
|
-
|
|
49
|
-
# Or manual: https://cli.github.com/
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Agent spawn fails
|
|
53
|
-
|
|
54
|
-
**Cause:** The specified agent CLI is not installed or not in PATH.
|
|
55
|
-
|
|
56
|
-
**Fix:** Ensure the agent CLI is installed and accessible:
|
|
57
|
-
```bash
|
|
58
|
-
# Verify
|
|
59
|
-
opencode --version
|
|
60
|
-
claude --version
|
|
61
|
-
aider --version
|
|
62
|
-
codex --version
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### "Worktree already exists"
|
|
66
|
-
|
|
67
|
-
**Cause:** A worktree for the same branch already exists, possibly from a previous interrupted session.
|
|
68
|
-
|
|
69
|
-
**Fix:**
|
|
70
|
-
```bash
|
|
71
|
-
# List worktrees
|
|
72
|
-
git worktree list
|
|
73
|
-
|
|
74
|
-
# Remove stale worktree
|
|
75
|
-
speexor stop <session-id>
|
|
76
|
-
# Or manually:
|
|
77
|
-
git worktree remove --force .speexor/worktrees/<task-id>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Dashboard not showing
|
|
81
|
-
|
|
82
|
-
**Cause:** Port 3000 might be in use, or the dashboard was not started.
|
|
83
|
-
|
|
84
|
-
**Fix:**
|
|
85
|
-
```bash
|
|
86
|
-
# Specify a different port
|
|
87
|
-
speexor start --port 4000
|
|
88
|
-
|
|
89
|
-
# Or start dashboard only (if already initialized)
|
|
90
|
-
speexor start
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Windows-Specific Issues
|
|
94
|
-
|
|
95
|
-
### ConPTY Fallback
|
|
96
|
-
|
|
97
|
-
On Windows, tmux is not available. Speexor automatically uses the Process runtime instead. This works for most cases but lacks live terminal streaming.
|
|
98
|
-
|
|
99
|
-
### Shell Path
|
|
100
|
-
|
|
101
|
-
If you use PowerShell, the default shell path detection should work. To customize:
|
|
102
|
-
|
|
103
|
-
```yaml
|
|
104
|
-
# In speexor.config.yaml
|
|
105
|
-
plugins:
|
|
106
|
-
runtime: process
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Getting Help
|
|
110
|
-
|
|
111
|
-
- Open an issue: https://github.com/superdevids/speexjs/issues
|
|
112
|
-
- Check the PRD: [PRD01.md](./PRD01.md)
|
|
113
|
-
- Ask in the SpeexJS community
|
|
1
|
+
# Speexor Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## Common Issues
|
|
4
|
+
|
|
5
|
+
### "speexor.config.yaml not found"
|
|
6
|
+
|
|
7
|
+
**Cause:** You ran `speexor list` or `speexor agent spawn` without initializing a project first.
|
|
8
|
+
|
|
9
|
+
**Fix:** Run `speexor start <repo-url>` to create the config file, or manually create `speexor.config.yaml` in your project root.
|
|
10
|
+
|
|
11
|
+
### "Not a git repository"
|
|
12
|
+
|
|
13
|
+
**Cause:** You're running `speexor` outside a git repository.
|
|
14
|
+
|
|
15
|
+
**Fix:** Navigate to a git repository or run `git init` first.
|
|
16
|
+
|
|
17
|
+
### "tmux not available"
|
|
18
|
+
|
|
19
|
+
**Cause:** tmux is not installed on your system.
|
|
20
|
+
|
|
21
|
+
**Fix (macOS):**
|
|
22
|
+
```bash
|
|
23
|
+
brew install tmux
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Fix (Linux):**
|
|
27
|
+
```bash
|
|
28
|
+
sudo apt install tmux # Debian/Ubuntu
|
|
29
|
+
sudo dnf install tmux # Fedora
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Fix (Windows):** Speexor will automatically fall back to the Process runtime on Windows.
|
|
33
|
+
|
|
34
|
+
### "GitHub CLI (gh) not found"
|
|
35
|
+
|
|
36
|
+
**Cause:** The `gh` CLI is not installed but required for GitHub tracker/SCM plugins.
|
|
37
|
+
|
|
38
|
+
**Fix:**
|
|
39
|
+
```bash
|
|
40
|
+
# macOS
|
|
41
|
+
brew install gh
|
|
42
|
+
|
|
43
|
+
# Linux (Debian/Ubuntu)
|
|
44
|
+
sudo apt install gh
|
|
45
|
+
|
|
46
|
+
# Windows (winget)
|
|
47
|
+
winget install GitHub.cli
|
|
48
|
+
|
|
49
|
+
# Or manual: https://cli.github.com/
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Agent spawn fails
|
|
53
|
+
|
|
54
|
+
**Cause:** The specified agent CLI is not installed or not in PATH.
|
|
55
|
+
|
|
56
|
+
**Fix:** Ensure the agent CLI is installed and accessible:
|
|
57
|
+
```bash
|
|
58
|
+
# Verify
|
|
59
|
+
opencode --version
|
|
60
|
+
claude --version
|
|
61
|
+
aider --version
|
|
62
|
+
codex --version
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### "Worktree already exists"
|
|
66
|
+
|
|
67
|
+
**Cause:** A worktree for the same branch already exists, possibly from a previous interrupted session.
|
|
68
|
+
|
|
69
|
+
**Fix:**
|
|
70
|
+
```bash
|
|
71
|
+
# List worktrees
|
|
72
|
+
git worktree list
|
|
73
|
+
|
|
74
|
+
# Remove stale worktree
|
|
75
|
+
speexor stop <session-id>
|
|
76
|
+
# Or manually:
|
|
77
|
+
git worktree remove --force .speexor/worktrees/<task-id>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Dashboard not showing
|
|
81
|
+
|
|
82
|
+
**Cause:** Port 3000 might be in use, or the dashboard was not started.
|
|
83
|
+
|
|
84
|
+
**Fix:**
|
|
85
|
+
```bash
|
|
86
|
+
# Specify a different port
|
|
87
|
+
speexor start --port 4000
|
|
88
|
+
|
|
89
|
+
# Or start dashboard only (if already initialized)
|
|
90
|
+
speexor start
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Windows-Specific Issues
|
|
94
|
+
|
|
95
|
+
### ConPTY Fallback
|
|
96
|
+
|
|
97
|
+
On Windows, tmux is not available. Speexor automatically uses the Process runtime instead. This works for most cases but lacks live terminal streaming.
|
|
98
|
+
|
|
99
|
+
### Shell Path
|
|
100
|
+
|
|
101
|
+
If you use PowerShell, the default shell path detection should work. To customize:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
# In speexor.config.yaml
|
|
105
|
+
plugins:
|
|
106
|
+
runtime: process
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Getting Help
|
|
110
|
+
|
|
111
|
+
- Open an issue: https://github.com/superdevids/speexjs/issues
|
|
112
|
+
- Check the PRD: [PRD01.md](./PRD01.md)
|
|
113
|
+
- Ask in the SpeexJS community
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ADR-0001: Use Architecture Decision Records
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Speexor is a plugin-based, agent-agnostic orchestrator for multi-AI coding agents. As the project grows, contributors and maintainers need a clear historical record of why architectural choices were made. Without this, future developers may reverse decisions without understanding the original rationale, leading to inconsistent architecture.
|
|
10
|
+
|
|
11
|
+
## Decision
|
|
12
|
+
|
|
13
|
+
We will use Architecture Decision Records (ADRs) in `docs/adr/` to document all significant architectural decisions. Each ADR follows this template:
|
|
14
|
+
|
|
15
|
+
```markdown
|
|
16
|
+
# ADR-NNNN: Title
|
|
17
|
+
|
|
18
|
+
## Status
|
|
19
|
+
|
|
20
|
+
[Proposed | Accepted | Deprecated | Superseded by ADR-NNNN]
|
|
21
|
+
|
|
22
|
+
## Context
|
|
23
|
+
|
|
24
|
+
The background, constraints, and forces that led to this decision.
|
|
25
|
+
|
|
26
|
+
## Decision
|
|
27
|
+
|
|
28
|
+
The architectural choice we made and how it addresses the context.
|
|
29
|
+
|
|
30
|
+
## Consequences
|
|
31
|
+
|
|
32
|
+
The trade-offs, benefits, and costs of this decision.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- ADRs are numbered sequentially (0001, 0002, ...).
|
|
36
|
+
- ADRs are written in the present tense as of the decision date.
|
|
37
|
+
- ADRs are never deleted; deprecated ADRs link to their replacement.
|
|
38
|
+
- ADRs are committed alongside the code changes they describe.
|
|
39
|
+
|
|
40
|
+
## Consequences
|
|
41
|
+
|
|
42
|
+
- **Positive:** Clear rationale trail for future contributors; easier onboarding; architectural consistency enforced by explicit record-keeping.
|
|
43
|
+
- **Negative:** Overhead of writing and maintaining ADRs; risk of falling behind if decisions are not documented promptly.
|
|
44
|
+
- **Neutral:** ADRs become a permanent part of the codebase in `docs/adr/`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# ADR-0002: 7-Slot Plugin Architecture with EventBus
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Speexor must support diverse capabilities — agent adapters, runtime backends, workspace management, issue tracking, SCM operations, notifications, and terminal I/O — without coupling these concerns in the core lifecycle. The architecture must allow:
|
|
10
|
+
|
|
11
|
+
1. New plugins to be added without modifying core code.
|
|
12
|
+
2. Multiple implementations per slot (e.g., tmux and Process for runtime).
|
|
13
|
+
3. Loose communication between plugins and the dashboard.
|
|
14
|
+
4. Graceful degradation when a plugin dependency (e.g., `tmux`, `gh` CLI) is unavailable.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
### Seven Plugin Slots
|
|
19
|
+
|
|
20
|
+
We define exactly seven plugin slots, each with a dedicated TypeScript interface:
|
|
21
|
+
|
|
22
|
+
| Slot | Interface | Purpose |
|
|
23
|
+
|------------|---------------------|---------------------------------------|
|
|
24
|
+
| agent | `AgentPlugin` | Spawn, communicate with, kill agents |
|
|
25
|
+
| runtime | `RuntimePlugin` | Create/destroy terminal sessions |
|
|
26
|
+
| workspace | `WorkspacePlugin` | Manage isolated git worktrees |
|
|
27
|
+
| tracker | `TrackerPlugin` | Fetch issues, subscribe to events |
|
|
28
|
+
| scm | `SCMPlugin` | Branch, commit, PR, CI operations |
|
|
29
|
+
| notifier | `NotifierPlugin` | Desktop notifications |
|
|
30
|
+
| terminal | `TerminalPlugin` | Interactive terminal attach/detach |
|
|
31
|
+
|
|
32
|
+
### EventBus over Direct Calls
|
|
33
|
+
|
|
34
|
+
All inter-module communication flows through an EventBus (EventEmitter3 wrapper) rather than direct method calls. This means:
|
|
35
|
+
|
|
36
|
+
- The dashboard subscribes to lifecycle events without lifecycle knowing about the dashboard.
|
|
37
|
+
- Plugins emit events (e.g., `session:created`, `worktree:created`) without importing other modules.
|
|
38
|
+
- New observers (e.g., logging, metrics) can be added without modifying existing code.
|
|
39
|
+
|
|
40
|
+
### getFirstPlugin() Resolution
|
|
41
|
+
|
|
42
|
+
When the lifecycle needs a plugin for a slot, it calls `getFirstPlugin<T>(slot)` which returns the first registered implementation. This allows:
|
|
43
|
+
|
|
44
|
+
- Multiple implementations per slot (e.g., both TmuxRuntime and ProcessRuntime).
|
|
45
|
+
- Implicit priority ordering by registration order.
|
|
46
|
+
- Graceful fallback: if the primary plugin fails initialization, the next in the list serves.
|
|
47
|
+
|
|
48
|
+
## Consequences
|
|
49
|
+
|
|
50
|
+
- **Positive:** Loose coupling; plugins are independently testable; new capabilities slot in without core changes.
|
|
51
|
+
- **Positive:** The `getFirstPlugin()` pattern enables natural fallback (ProcessRuntime when tmux is absent).
|
|
52
|
+
- **Negative:** Event-based flow is harder to trace than direct calls during debugging.
|
|
53
|
+
- **Negative:** Seven slots are a fixed set — adding a new slot requires a core type change and a new interface definition.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# ADR-0003: DAG-Based Recursive Task Decomposition with LLM Planner
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Speexor must decompose complex tasks (e.g., "implement feature X across the full stack") into smaller, parallel-executable units that can be distributed across multiple agents. Two core design questions arise:
|
|
10
|
+
|
|
11
|
+
1. **Representation:** Should the task structure be a flat list, a tree, or a directed acyclic graph (DAG)?
|
|
12
|
+
2. **Planner:** Should the decomposition algorithm be rule-based (deterministic) or LLM-driven (probabilistic)?
|
|
13
|
+
|
|
14
|
+
The representation must handle dependency ordering (task B depends on task A, task C depends on both) and allow parallel execution of independent sub-tasks. The planner must adapt to arbitrary repo structures and technologies without hardcoded rules.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
### DAG-Based Task Graph
|
|
19
|
+
|
|
20
|
+
We represent decomposed tasks as a **directed acyclic graph (DAG)** where:
|
|
21
|
+
|
|
22
|
+
- Each **Task Node** represents one atomic unit of work.
|
|
23
|
+
- Edges represent **depends-on** relationships (a node cannot execute until all predecessors complete).
|
|
24
|
+
- Nodes with no edges between them are eligible for parallel execution.
|
|
25
|
+
- The graph supports dynamic refinement: a node in progress can be further decomposed into sub-DAGs at runtime.
|
|
26
|
+
|
|
27
|
+
This choice over a flat list (which cannot express dependencies) or a tree (which cannot express cross-branch dependencies like "both frontend and backend depend on the shared schema change").
|
|
28
|
+
|
|
29
|
+
### LLM-Based Planner over Algorithmic Decomposition
|
|
30
|
+
|
|
31
|
+
We use an LLM-based planner (configurable per project, defaulting to `deepseek-reasoner`) to decompose tasks rather than a rule-based algorithm. Rationale:
|
|
32
|
+
|
|
33
|
+
- **Arbitrary tech stacks:** The planner reads the repo structure and task description, then generates a decomposition customized to the actual codebase — no hardcoded "microservice decomposition" rules needed.
|
|
34
|
+
- **Context-aware granularity:** The LLM decides how fine-grained each sub-task should be based on complexity, rather than a fixed heuristic.
|
|
35
|
+
- **Adaptive refinement:** If the initial decomposition is too coarse, the planner can further decompose a node mid-execution using the same LLM.
|
|
36
|
+
- **Human-readable plans:** The LLM generates natural language descriptions for each node, which feed into the approval UI and decision log.
|
|
37
|
+
|
|
38
|
+
### Configuration
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
decomposition:
|
|
42
|
+
maxTaskGraphDepth: 3 # Max depth of the Task Graph (node depth)
|
|
43
|
+
maxAgentSpawnDepth: 3 # Max levels of subagent spawning
|
|
44
|
+
maxNodesPerGraph: 50 # Safety limit on graph size
|
|
45
|
+
plannerProvider: opencode # Which agent backend to use for planning
|
|
46
|
+
plannerModel: deepseek-reasoner # Model for the planner LLM call
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The two depth limits (`maxTaskGraphDepth` and `maxAgentSpawnDepth`) are tracked separately — a deep task graph does not force deep agent spawning if the planner assigns shallow agents to deep nodes.
|
|
50
|
+
|
|
51
|
+
## Consequences
|
|
52
|
+
|
|
53
|
+
- **Positive:** DAG enables maximum parallelism — independent sub-tasks execute concurrently.
|
|
54
|
+
- **Positive:** LLM planner adapts to any codebase without rule maintenance.
|
|
55
|
+
- **Negative:** LLM planner calls add latency and cost to the decomposition phase.
|
|
56
|
+
- **Negative:** DAG complexity requires a scheduler with dependency resolution (no simple FIFO queue).
|
|
57
|
+
- **Neutral:** The `maxTaskGraphDepth`/`maxAgentSpawnDepth` split prevents confusion between graph depth and agent hierarchy depth (per FR-89).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ADR-0004: Local-First Security with Two-Layer Defense
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
Speexor manages AI agents that write code, execute commands, and interact with git providers. This introduces two distinct security surfaces:
|
|
10
|
+
|
|
11
|
+
1. **Third-party extensions** (installed via the future Marketplace) that can access the file system, shell, and network.
|
|
12
|
+
2. **Runtime agent actions** — file edits, git operations, PR creation, CI interactions — some of which are irreversible (e.g., force-push to main).
|
|
13
|
+
|
|
14
|
+
The architecture must ensure that a malicious or buggy extension cannot compromise the host system, and that high-risk agent actions require explicit human approval.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
### Local-First Architecture
|
|
19
|
+
|
|
20
|
+
All data, credentials, and execution remain on the user's machine. There is no cloud relay, no telemetry by default, and no remote control plane. This means:
|
|
21
|
+
|
|
22
|
+
- Secrets are stored in the OS keychain (via `conf` with `encryptionKey`), never in plaintext config files.
|
|
23
|
+
- The dashboard runs on localhost only (`127.0.0.1`) by default.
|
|
24
|
+
- The decision log and session state never leave the `~/.speexor/` directory.
|
|
25
|
+
|
|
26
|
+
### Two-Layer Defense: Extension Permissions + Action Risk Tiers
|
|
27
|
+
|
|
28
|
+
These are two independent, complementary layers documented in `SECURITY-DEFAULTS.md`:
|
|
29
|
+
|
|
30
|
+
**Layer 1 — Extension Permissions (install-time capability gating):**
|
|
31
|
+
|
|
32
|
+
Defined by `extensions.permissionsMode` in config (`strict` | `permissive`). Each extension declares capabilities (`shell`, `network`, `fileSystem`, `clipboard`) at install time. In `strict` mode, the user must explicitly approve each capability; in `permissive` mode, all declared capabilities are auto-granted. This layer gates what an extension *can ever do* — set once, at install.
|
|
33
|
+
|
|
34
|
+
Extensions with `shell: none` and `network: none` run in `isolated-vm` (true V8 isolate, no access to Node built-ins). Extensions requiring `fileSystem`/`shell`/`network` run as separate OS processes with minimum privileges and a permission-enforcing proxy layer intercepting `fs`/`net`/`child_process` calls.
|
|
35
|
+
|
|
36
|
+
`worker_threads` is explicitly **not** used as a security boundary — it is a performance-only primitive for orchestrator-internal CPU-bound work (per FR-85).
|
|
37
|
+
|
|
38
|
+
**Layer 2 — Action Risk Tiers (runtime action gating):**
|
|
39
|
+
|
|
40
|
+
Defined by `riskPolicy` in config. Every action an agent or extension takes is classified into a risk tier. Actions in `requireApproval` tiers (e.g., `irreversible-high-stakes`) block until the user approves. Actions in `autoApprove` tiers (e.g., `reversible-low`) execute autonomously. Unknown actions default to `high-stakes` (safe default).
|
|
41
|
+
|
|
42
|
+
This layer gates what *any* action (from any already-permitted extension or core agent) *does right now* — evaluated every time, separate from the install-time capability grant.
|
|
43
|
+
|
|
44
|
+
### Sandboxing: isolated-vm over worker_threads
|
|
45
|
+
|
|
46
|
+
| Mechanism | Security Boundary | Use Case |
|
|
47
|
+
|-----------------|-------------------|----------------------------------|
|
|
48
|
+
| `isolated-vm` | True V8 isolate | Extensions with no shell/network |
|
|
49
|
+
| OS process | OS-level | Extensions with shell/network |
|
|
50
|
+
| `worker_threads`| None (same proc) | Orchestrator-internal CPU work |
|
|
51
|
+
|
|
52
|
+
## Consequences
|
|
53
|
+
|
|
54
|
+
- **Positive:** Two layers provide defense-in-depth — an extension with "write files" capability still cannot force-push to main without risk-tier approval.
|
|
55
|
+
- **Positive:** Local-first ensures no external dependency for security; no cloud outage can leak secrets.
|
|
56
|
+
- **Negative:** `isolated-vm` is a native dependency that complicates cross-platform builds and installs.
|
|
57
|
+
- **Negative:** Two-layer model requires clear documentation (covered by `SECURITY-DEFAULTS.md`).
|
|
58
|
+
- **Neutral:** `worker_threads` reclassification from v4's proposal removes a false sense of security.
|