@lucasreiners/lead 0.1.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/README.md +337 -0
- package/dist/agents/agent-builder.d.ts +30 -0
- package/dist/agents/architect/index.d.ts +4 -0
- package/dist/agents/builtin-agents.d.ts +32 -0
- package/dist/agents/code-analyst/index.d.ts +4 -0
- package/dist/agents/cto/index.d.ts +11 -0
- package/dist/agents/custom-agent-factory.d.ts +27 -0
- package/dist/agents/dynamic-prompt-builder.d.ts +22 -0
- package/dist/agents/engineer/index.d.ts +4 -0
- package/dist/agents/executor/index.d.ts +6 -0
- package/dist/agents/guardian/index.d.ts +4 -0
- package/dist/agents/index.d.ts +17 -0
- package/dist/agents/lead/index.d.ts +11 -0
- package/dist/agents/lead-dev/index.d.ts +6 -0
- package/dist/agents/model-resolution.d.ts +44 -0
- package/dist/agents/prompt-loader.d.ts +30 -0
- package/dist/agents/prompt-utils.d.ts +12 -0
- package/dist/agents/researcher/index.d.ts +4 -0
- package/dist/agents/reviewer/index.d.ts +4 -0
- package/dist/agents/scout/index.d.ts +4 -0
- package/dist/agents/tech-lead/index.d.ts +11 -0
- package/dist/agents/tester/index.d.ts +4 -0
- package/dist/agents/types.d.ts +37 -0
- package/dist/config/continuation.d.ts +13 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/loader.d.ts +12 -0
- package/dist/config/merge.d.ts +8 -0
- package/dist/config/scaffold.d.ts +12 -0
- package/dist/config/schema.d.ts +140 -0
- package/dist/create-managers.d.ts +32 -0
- package/dist/create-tools.d.ts +24 -0
- package/dist/domain/plans/index.d.ts +2 -0
- package/dist/domain/policy/policy-result.d.ts +23 -0
- package/dist/domain/session/index.d.ts +41 -0
- package/dist/domain/workflows/index.d.ts +4 -0
- package/dist/domain/workflows/workflow-completion.d.ts +9 -0
- package/dist/domain/workflows/workflow-context.d.ts +9 -0
- package/dist/domain/workflows/workflow-repository.d.ts +19 -0
- package/dist/domain/workflows/workflow-service.d.ts +32 -0
- package/dist/features/skill-loader/discovery.d.ts +36 -0
- package/dist/features/skill-loader/index.d.ts +6 -0
- package/dist/features/skill-loader/loader.d.ts +15 -0
- package/dist/features/skill-loader/opencode-client.d.ts +6 -0
- package/dist/features/skill-loader/resolver.d.ts +8 -0
- package/dist/features/skill-loader/types.d.ts +14 -0
- package/dist/features/work-state/constants.d.ts +4 -0
- package/dist/features/work-state/index.d.ts +5 -0
- package/dist/features/work-state/storage.d.ts +20 -0
- package/dist/features/work-state/types.d.ts +16 -0
- package/dist/features/work-state/validation-types.d.ts +8 -0
- package/dist/features/work-state/validation.d.ts +6 -0
- package/dist/features/workflow/commands.d.ts +10 -0
- package/dist/features/workflow/completion.d.ts +5 -0
- package/dist/features/workflow/constants.d.ts +8 -0
- package/dist/features/workflow/context.d.ts +16 -0
- package/dist/features/workflow/discovery.d.ts +19 -0
- package/dist/features/workflow/engine.d.ts +19 -0
- package/dist/features/workflow/hook.d.ts +45 -0
- package/dist/features/workflow/index.d.ts +9 -0
- package/dist/features/workflow/schema.d.ts +43 -0
- package/dist/features/workflow/storage.d.ts +7 -0
- package/dist/features/workflow/types.d.ts +89 -0
- package/dist/hooks/architect-md-only.d.ts +11 -0
- package/dist/hooks/compaction-recovery.d.ts +20 -0
- package/dist/hooks/compaction-todo-preserver.d.ts +21 -0
- package/dist/hooks/context-window-monitor.d.ts +26 -0
- package/dist/hooks/create-hooks.d.ts +45 -0
- package/dist/hooks/first-message-variant.d.ts +23 -0
- package/dist/hooks/index.d.ts +28 -0
- package/dist/hooks/keyword-detector.d.ts +17 -0
- package/dist/hooks/rules-injector.d.ts +16 -0
- package/dist/hooks/session-token-state.d.ts +31 -0
- package/dist/hooks/start-implementation-hook.d.ts +26 -0
- package/dist/hooks/start-work-hook.d.ts +26 -0
- package/dist/hooks/todo-continuation-enforcer.d.ts +22 -0
- package/dist/hooks/todo-description-override.d.ts +10 -0
- package/dist/hooks/todo-writer.d.ts +20 -0
- package/dist/hooks/verification-reminder.d.ts +21 -0
- package/dist/hooks/work-continuation.d.ts +23 -0
- package/dist/hooks/write-existing-file-guard.d.ts +34 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +3811 -0
- package/dist/infrastructure/fs/config-fs-loader.d.ts +6 -0
- package/dist/managers/background-manager.d.ts +48 -0
- package/dist/managers/config-handler.d.ts +31 -0
- package/dist/managers/index.d.ts +6 -0
- package/dist/managers/skill-mcp-manager.d.ts +31 -0
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/plugin-interface.d.ts +7 -0
- package/dist/plugin/types.d.ts +18 -0
- package/dist/runtime/opencode/plugin-adapter.d.ts +17 -0
- package/dist/shared/agent-display-names.d.ts +3 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/log.d.ts +9 -0
- package/dist/shared/resolve-safe-path.d.ts +7 -0
- package/dist/shared/types.d.ts +3 -0
- package/dist/shared/version.d.ts +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# L.E.A.D. - Lucas Engineering Automation & Delivery
|
|
2
|
+
|
|
3
|
+
Enterprise-grade [OpenCode](https://opencode.ai) plugin that turns a single AI agent into a **coordinated team of 9
|
|
4
|
+
specialists** — from planning and research through implementation, testing, and review.
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
1. **Add L.E.A.D.** to your OpenCode config (`~/.config/opencode/opencode.jsonc`):
|
|
9
|
+
|
|
10
|
+
```jsonc
|
|
11
|
+
{
|
|
12
|
+
"plugin": ["@lucasreiners/lead@latest"]
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. **Restart OpenCode** — the plugin installs automatically from npm.
|
|
17
|
+
|
|
18
|
+
## The Big Picture
|
|
19
|
+
|
|
20
|
+
Instead of one AI agent, L.E.A.D. gives you a **team of 9 specialist agents** that work together — like a real
|
|
21
|
+
engineering team. Each agent has its own role, permissions, and expertise.
|
|
22
|
+
|
|
23
|
+
## How It Starts Up
|
|
24
|
+
|
|
25
|
+
When OpenCode loads, it finds L.E.A.D. in the plugin config and runs the entry point:
|
|
26
|
+
|
|
27
|
+
**`src/index.ts`** → This is "main()". It does 5 things in order:
|
|
28
|
+
|
|
29
|
+
1. **Load config** → reads `.opencode/lead.jsonc` (project) and `~/.config/opencode/lead.jsonc` (global) to get your
|
|
30
|
+
customizations
|
|
31
|
+
2. **Load skills** → finds any skill files (reusable prompt snippets) from disk
|
|
32
|
+
3. **Create agents** → builds all 9 builtin agents + any custom ones you defined
|
|
33
|
+
4. **Create hooks** → sets up ~15 lifecycle hooks that monitor and enhance agent behavior
|
|
34
|
+
5. **Return the plugin interface** → hands everything to OpenCode as a set of hooks
|
|
35
|
+
|
|
36
|
+
## The Agent Team
|
|
37
|
+
|
|
38
|
+
Each agent is defined in `src/agents/<name>/index.ts` with an accompanying `prompt.md`:
|
|
39
|
+
|
|
40
|
+
| Agent | Role | Can Write Code? | When It's Used |
|
|
41
|
+
|--------------------|----------------------------------------------------|-----------------|----------------------------------------------|
|
|
42
|
+
| **Tech Lead** | Orchestrator — routes work to the right specialist | ❌ No | Default agent, handles all incoming requests |
|
|
43
|
+
| **Engineer** | Writes code, fixes bugs, implements features | ✅ Yes | Direct implementation tasks |
|
|
44
|
+
| **Lead Developer** | Executes plans step-by-step | ✅ Yes | Activated by `/implement` command |
|
|
45
|
+
| **Architect** | Creates implementation plans (`.md` files only) | 📝 Only `.md` | Complex features needing planning first |
|
|
46
|
+
| **Code Analyst** | Explores codebases, traces dependencies | ❌ Read-only | Understanding existing code |
|
|
47
|
+
| **Researcher** | Looks up external docs, libraries, APIs | ❌ Read-only | "How does library X work?" |
|
|
48
|
+
| **Reviewer** | Code review, gives APPROVE/REJECT verdict | ❌ Read-only | Quality validation |
|
|
49
|
+
| **Tester** | Runs tests, linters, type checks — reports PASS/FAIL | ❌ Read + bash | Verification after each implementation task |
|
|
50
|
+
| **Guardian** | Security audit, OWASP checks | ❌ Read-only | Security-sensitive changes |
|
|
51
|
+
|
|
52
|
+
### How Agents Are Built
|
|
53
|
+
|
|
54
|
+
- Each agent starts as a **factory function** (`src/agents/agent-builder.ts`) that takes a model name and returns a
|
|
55
|
+
config
|
|
56
|
+
- The factory has a `mode` property (`"primary"`, `"subagent"`, or `"all"`) that controls visibility in the UI
|
|
57
|
+
- `createBuiltinAgents()` in `src/agents/builtin-agents.ts` calls each factory, resolves the model, and applies any
|
|
58
|
+
config overrides
|
|
59
|
+
|
|
60
|
+
### How Agents Get Registered
|
|
61
|
+
|
|
62
|
+
- The `ConfigHandler` (`src/managers/config-handler.ts`) takes all built agents and writes them into OpenCode's config
|
|
63
|
+
object
|
|
64
|
+
- Agent keys use display names ("Tech Lead" not "tech-lead") for cleaner UI
|
|
65
|
+
- Sets `config.default_agent = "Tech Lead"` so it appears first
|
|
66
|
+
|
|
67
|
+
### Architecture
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
User
|
|
71
|
+
|
|
|
72
|
+
Tech Lead (orchestrator, read-only)
|
|
73
|
+
/ | \
|
|
74
|
+
Architect Code Analyst Researcher (planning / exploration / research)
|
|
75
|
+
|
|
|
76
|
+
Lead Dev (plan execution, full permissions)
|
|
77
|
+
/ \
|
|
78
|
+
Engineer Tester (implement → verify cycle)
|
|
79
|
+
|
|
|
80
|
+
Reviewer + Guardian (validation, read-only)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Tool Permissions
|
|
84
|
+
|
|
85
|
+
| Agent | bash | edit | write | read/glob/grep | web |
|
|
86
|
+
|------------|------|------|----------|----------------|-----|
|
|
87
|
+
| Tech Lead | - | - | - | yes | yes |
|
|
88
|
+
| Lead Dev | yes | yes | yes | yes | yes |
|
|
89
|
+
| Engineer | yes | yes | yes | yes | yes |
|
|
90
|
+
| Architect | - | - | .md only | yes | yes |
|
|
91
|
+
| Code Analyst | - | - | - | yes | - |
|
|
92
|
+
| Researcher | - | - | - | yes | yes |
|
|
93
|
+
| Reviewer | - | - | - | yes | - |
|
|
94
|
+
| Tester | yes | - | - | yes | - |
|
|
95
|
+
| Guardian | - | - | - | yes | - |
|
|
96
|
+
|
|
97
|
+
## The Hooks System
|
|
98
|
+
|
|
99
|
+
Hooks are the plugin's nervous system — they intercept events at every stage of OpenCode's lifecycle. They're created in
|
|
100
|
+
`src/hooks/create-hooks.ts` and wired up in `src/runtime/opencode/plugin-adapter.ts`.
|
|
101
|
+
|
|
102
|
+
### Plugin Adapter Hooks
|
|
103
|
+
|
|
104
|
+
| Hook | What Triggers It | What L.E.A.D. Does |
|
|
105
|
+
|-----------------------------------|---------------------------|---------------------------------------------------------------|
|
|
106
|
+
| `config` | Plugin loads | Registers all agents |
|
|
107
|
+
| `chat.message` | Every message sent | Tracks active agent, injects any pending continuation prompts |
|
|
108
|
+
| `event` (session.idle) | Agent finishes responding | Checks if there's more plan work to do → auto-continues |
|
|
109
|
+
| `command.execute.before` | User runs a `/command` | Handles `/implement` and `/run-workflow` |
|
|
110
|
+
| `tool.execute.before` | Agent calls a tool | Guards architect (only `.md`), captures todo writes |
|
|
111
|
+
| `tool.execute.after` | Tool finishes | Reminds agent to verify (typecheck, test) |
|
|
112
|
+
| `tool.definition` | Tool list requested | Overrides todowrite description |
|
|
113
|
+
| `experimental.session.compacting` | Context window compressed | Preserves work state & todos through compaction |
|
|
114
|
+
|
|
115
|
+
### Individual Hook Files (`src/hooks/`)
|
|
116
|
+
|
|
117
|
+
| Hook | File | Purpose |
|
|
118
|
+
|--------------------------------|---------------------------------|-----------------------------------------------------------------------|
|
|
119
|
+
| **start-implementation** | `start-implementation-hook.ts` | `/implement` command — find plan, create work state |
|
|
120
|
+
| **work-continuation** | `work-continuation.ts` | On idle, check active work, detect stale continuations, return prompt |
|
|
121
|
+
| **architect-md-only** | `architect-md-only.ts` | Guard: architect only writes `.md` in `.lead/` |
|
|
122
|
+
| **todo-writer** | `todo-writer.ts` | Capture todowrite operations for state tracking |
|
|
123
|
+
| **verification-reminder** | `verification-reminder.ts` | After edit/write/bash, remind agent to typecheck and test |
|
|
124
|
+
| **compaction-recovery** | `compaction-recovery.ts` | After context compaction, re-inject active work summary |
|
|
125
|
+
| **compaction-todo-preserver** | `compaction-todo-preserver.ts` | Save/restore todo state through compaction |
|
|
126
|
+
| **context-window-monitor** | `context-window-monitor.ts` | Warn at 75% and 90% context window usage |
|
|
127
|
+
| **write-existing-file-guard** | `write-existing-file-guard.ts` | Prevent overwriting files the agent hasn't read first |
|
|
128
|
+
| **keyword-detector** | `keyword-detector.ts` | Detect `/implement`, `/run-workflow`, workflow control keywords |
|
|
129
|
+
| **rules-injector** | `rules-injector.ts` | Inject project rules from `.opencode/rules/*.md` |
|
|
130
|
+
| **first-message-variant** | `first-message-variant.ts` | Track sessions for first-message-only prompt injection |
|
|
131
|
+
| **todo-continuation-enforcer** | `todo-continuation-enforcer.ts` | Detect stale in-progress todos, prompt to complete/cancel |
|
|
132
|
+
| **todo-description-override** | `todo-description-override.ts` | Override todowrite description with executor discipline rules |
|
|
133
|
+
| **session-token-state** | `session-token-state.ts` | Track input/output tokens per session |
|
|
134
|
+
|
|
135
|
+
## The `/implement` Command Flow
|
|
136
|
+
|
|
137
|
+
This is the core workflow for executing plans:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
1. User: /implement PROJ-123 (or /implement my-feature)
|
|
141
|
+
↓
|
|
142
|
+
2. start-implementation-hook.ts
|
|
143
|
+
- Searches .lead/PROJ-123/plan.md, .lead/_adhoc/my-feature.md, .lead/plans/ (legacy)
|
|
144
|
+
- Creates work state in .lead/state.json
|
|
145
|
+
- Returns prompt: "You are now the Executor..."
|
|
146
|
+
↓
|
|
147
|
+
3. Lead Developer agent starts working
|
|
148
|
+
- Reads the plan file
|
|
149
|
+
- Finds first unchecked - [ ] task
|
|
150
|
+
- Implements it (code, tests, etc.)
|
|
151
|
+
↓
|
|
152
|
+
4. Lead Dev delegates to Tester agent
|
|
153
|
+
- Tester reads AGENTS.md for project-specific commands
|
|
154
|
+
- Runs typecheck → lint → tests
|
|
155
|
+
- Returns [PASS] or [FAIL]
|
|
156
|
+
↓
|
|
157
|
+
5. If [FAIL]: Lead Dev fixes issues → back to step 4 (max 3 cycles)
|
|
158
|
+
If [PASS]: marks task - [x], moves to next task
|
|
159
|
+
↓
|
|
160
|
+
6. Session goes idle → work-continuation.ts
|
|
161
|
+
- Checks: are there remaining tasks?
|
|
162
|
+
- Yes → injects "Continue working on plan..."
|
|
163
|
+
- Agent resumes automatically
|
|
164
|
+
↓
|
|
165
|
+
7. All tasks checked → work complete
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### State Files
|
|
169
|
+
|
|
170
|
+
- `.lead/state.json` — tracks active plan, session, pause status
|
|
171
|
+
- `.lead/<ticket>/plan.md` — ticket-linked plans (e.g. `.lead/PROJ-123/plan.md`)
|
|
172
|
+
- `.lead/_adhoc/*.md` — ad-hoc plans with no ticket reference
|
|
173
|
+
|
|
174
|
+
## The Workflow Engine
|
|
175
|
+
|
|
176
|
+
Beyond `/implement`, there's a full workflow system in `src/features/workflow/`:
|
|
177
|
+
|
|
178
|
+
- Workflow definitions live in `.opencode/workflows/*.jsonc`
|
|
179
|
+
- Each workflow has ordered **steps** with specific agents, prompts, and completion criteria
|
|
180
|
+
- The engine (`engine.ts`) is a state machine that advances through steps
|
|
181
|
+
- Steps can complete via: user confirmation, plan created, review verdict, etc.
|
|
182
|
+
|
|
183
|
+
### Workflow Flow
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
1. User: /run-workflow my-workflow "build new feature"
|
|
187
|
+
↓
|
|
188
|
+
2. handleRunWorkflow()
|
|
189
|
+
- Discovers workflows in .opencode/workflows/*.jsonc
|
|
190
|
+
- Validates schema, starts first step
|
|
191
|
+
- Saves state to .lead/workflow/{id}.json
|
|
192
|
+
↓
|
|
193
|
+
3. Step agent executes (e.g., Architect creates plan)
|
|
194
|
+
↓
|
|
195
|
+
4. On session.idle → checkWorkflowContinuation()
|
|
196
|
+
- Checks step completion (user_confirm, plan_created, etc.)
|
|
197
|
+
- Marks step complete, advances to next
|
|
198
|
+
- Switches agent, injects next step prompt
|
|
199
|
+
↓
|
|
200
|
+
5. Last step completes → workflow done
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Configuration
|
|
204
|
+
|
|
205
|
+
**`src/config/`** handles loading and merging config:
|
|
206
|
+
|
|
207
|
+
- `schema.ts` — Zod schemas define what's valid
|
|
208
|
+
- `loader.ts` — Loads global + project configs
|
|
209
|
+
- `merge.ts` — Deep merges them (project wins)
|
|
210
|
+
|
|
211
|
+
L.E.A.D. loads config from `.opencode/lead.jsonc` (project-level) and `~/.config/opencode/lead.jsonc` (global). Project
|
|
212
|
+
config takes precedence.
|
|
213
|
+
|
|
214
|
+
```jsonc
|
|
215
|
+
{
|
|
216
|
+
// Override model for all agents
|
|
217
|
+
"model": "anthropic/claude-sonnet-4-5",
|
|
218
|
+
|
|
219
|
+
// Disable specific builtin agents
|
|
220
|
+
"disabled_agents": ["guardian"],
|
|
221
|
+
|
|
222
|
+
// Disable specific hooks
|
|
223
|
+
"disabled_hooks": ["verification-reminder"],
|
|
224
|
+
|
|
225
|
+
// Add custom agents
|
|
226
|
+
"custom_agents": {
|
|
227
|
+
"my-agent": {
|
|
228
|
+
"model": "anthropic/claude-sonnet-4-5",
|
|
229
|
+
"prompt": "You are a specialized agent for...",
|
|
230
|
+
"mode": "subagent"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Build Process
|
|
237
|
+
|
|
238
|
+
`script/build.ts` uses Bun's bundler:
|
|
239
|
+
|
|
240
|
+
- Entry: `src/index.ts` → Output: `dist/index.js` (ESM)
|
|
241
|
+
- Externals: `@opencode-ai/plugin`, `@opencode-ai/sdk`, `zod`, `picocolors`
|
|
242
|
+
- OpenCode loads `dist/index.js` at startup
|
|
243
|
+
|
|
244
|
+
## Key Project Directories
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
your-project/
|
|
248
|
+
├── .opencode/
|
|
249
|
+
│ ├── lead.jsonc ← project config
|
|
250
|
+
│ ├── rules/*.md ← project rules injected into prompts
|
|
251
|
+
│ └── workflows/*.jsonc ← workflow definitions
|
|
252
|
+
├── .lead/
|
|
253
|
+
│ ├── state.json ← active work tracking
|
|
254
|
+
│ ├── PROJ-123/plan.md ← ticket-linked plans
|
|
255
|
+
│ ├── _adhoc/*.md ← ad-hoc plans (no ticket)
|
|
256
|
+
│ └── workflow/ ← workflow state
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Source File Organization
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
src/
|
|
263
|
+
├── index.ts ← MAIN ENTRY POINT
|
|
264
|
+
├── create-tools.ts ← skill loading orchestration
|
|
265
|
+
├── create-managers.ts ← agent & manager factory
|
|
266
|
+
│
|
|
267
|
+
├── config/ ← configuration layer
|
|
268
|
+
│ ├── schema.ts (zod validation)
|
|
269
|
+
│ ├── loader.ts (load from disk)
|
|
270
|
+
│ ├── merge.ts (deep merge logic)
|
|
271
|
+
│ └── continuation.ts (continuation defaults)
|
|
272
|
+
│
|
|
273
|
+
├── plugin/ ← plugin interface wrapper
|
|
274
|
+
│ ├── plugin-interface.ts (adapter → Hooks)
|
|
275
|
+
│ └── types.ts (PluginContext, LeadHooks)
|
|
276
|
+
│
|
|
277
|
+
├── runtime/opencode/
|
|
278
|
+
│ └── plugin-adapter.ts ← ALL HOOK IMPLEMENTATIONS
|
|
279
|
+
│
|
|
280
|
+
├── agents/ ← the agent team
|
|
281
|
+
│ ├── types.ts (AgentFactory, AgentMode)
|
|
282
|
+
│ ├── builtin-agents.ts (factory registry + metadata)
|
|
283
|
+
│ ├── agent-builder.ts (factory → AgentConfig)
|
|
284
|
+
│ ├── custom-agent-factory.ts (custom agent builder)
|
|
285
|
+
│ ├── model-resolution.ts (model selection logic)
|
|
286
|
+
│ ├── dynamic-prompt-builder.ts (Tech Lead delegation table)
|
|
287
|
+
│ ├── prompt-loader.ts (read prompt.md files)
|
|
288
|
+
│ ├── prompt-utils.ts (normalize prompts)
|
|
289
|
+
│ ├── tech-lead/ (orchestrator)
|
|
290
|
+
│ ├── lead-dev/ (plan executor)
|
|
291
|
+
│ ├── engineer/ (implementer)
|
|
292
|
+
│ ├── architect/ (planner)
|
|
293
|
+
│ ├── code-analyst/ (explorer)
|
|
294
|
+
│ ├── researcher/ (external research)
|
|
295
|
+
│ ├── reviewer/ (quality review)
|
|
296
|
+
│ ├── tester/ (verification — runs tests/lint)
|
|
297
|
+
│ └── guardian/ (security audit)
|
|
298
|
+
│
|
|
299
|
+
├── managers/ ← system managers
|
|
300
|
+
│ ├── config-handler.ts (register agents into OpenCode)
|
|
301
|
+
│ ├── background-manager.ts (concurrent task tracking)
|
|
302
|
+
│ └── skill-mcp-manager.ts (MCP server stub)
|
|
303
|
+
│
|
|
304
|
+
├── features/ ← feature modules
|
|
305
|
+
│ ├── skill-loader/ (API + FS skill discovery)
|
|
306
|
+
│ ├── work-state/ (plan execution tracking)
|
|
307
|
+
│ └── workflow/ (workflow state machine)
|
|
308
|
+
│
|
|
309
|
+
├── hooks/ ← ~15 lifecycle hooks
|
|
310
|
+
│ ├── create-hooks.ts (hook factory)
|
|
311
|
+
│ ├── start-implementation-hook.ts (/implement command)
|
|
312
|
+
│ ├── work-continuation.ts (auto-continue work)
|
|
313
|
+
│ ├── architect-md-only.ts (write guard)
|
|
314
|
+
│ ├── verification-reminder.ts (test/typecheck reminders)
|
|
315
|
+
│ ├── compaction-recovery.ts (context preservation)
|
|
316
|
+
│ ├── context-window-monitor.ts (usage warnings)
|
|
317
|
+
│ ├── write-existing-file-guard.ts (read-before-write)
|
|
318
|
+
│ ├── keyword-detector.ts (command detection)
|
|
319
|
+
│ ├── rules-injector.ts (project rules)
|
|
320
|
+
│ └── ... (+ 5 more hooks)
|
|
321
|
+
│
|
|
322
|
+
├── shared/ ← utilities
|
|
323
|
+
│ ├── log.ts (structured logging)
|
|
324
|
+
│ ├── agent-display-names.ts (ID → display name)
|
|
325
|
+
│ ├── resolve-safe-path.ts (path traversal protection)
|
|
326
|
+
│ └── version.ts (version constant)
|
|
327
|
+
│
|
|
328
|
+
├── domain/ ← domain types (stubs)
|
|
329
|
+
│ └── policy/policy-result.ts (allow/deny verdicts)
|
|
330
|
+
│
|
|
331
|
+
└── infrastructure/fs/
|
|
332
|
+
└── config-fs-loader.ts (JSONC file loading)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentSource } from "./types";
|
|
3
|
+
import type { CategoriesConfig } from "../config/schema";
|
|
4
|
+
export type ResolveSkillsFn = (skillNames: string[], disabledSkills?: Set<string>) => string;
|
|
5
|
+
export interface BuildAgentOptions {
|
|
6
|
+
categories?: CategoriesConfig;
|
|
7
|
+
disabledSkills?: Set<string>;
|
|
8
|
+
resolveSkills?: ResolveSkillsFn;
|
|
9
|
+
disabledAgents?: Set<string>;
|
|
10
|
+
}
|
|
11
|
+
export declare function registerAgentNameVariants(name: string, variants: string[]): void;
|
|
12
|
+
export declare function addBuiltinNameVariant(name: string, variant: string): void;
|
|
13
|
+
export declare function resetNameVariants(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Removes lines from a prompt that mention disabled agent names.
|
|
16
|
+
* A "line" is considered to mention an agent if it contains any of that
|
|
17
|
+
* agent's known variant strings.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stripDisabledAgentReferences(prompt: string, disabledAgents: Set<string>): string;
|
|
20
|
+
/**
|
|
21
|
+
* Resolves an `AgentSource` (factory or static config) into a fully
|
|
22
|
+
* populated `AgentConfig`.
|
|
23
|
+
*
|
|
24
|
+
* Steps:
|
|
25
|
+
* 1. Resolve factory → config
|
|
26
|
+
* 2. Apply category overrides
|
|
27
|
+
* 3. Prepend skill content to prompt
|
|
28
|
+
* 4. Strip references to disabled agents
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildAgent(source: AgentSource, model: string, options?: BuildAgentOptions): AgentConfig;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { LeadAgentName, AgentFactory } from "./types";
|
|
3
|
+
import type { BuildAgentOptions } from "./agent-builder";
|
|
4
|
+
import type { AgentOverrideConfig } from "../config/schema";
|
|
5
|
+
export interface AgentMetadata {
|
|
6
|
+
category: string;
|
|
7
|
+
cost: "CHEAP" | "MODERATE" | "EXPENSIVE";
|
|
8
|
+
triggers: Array<{
|
|
9
|
+
domain: string;
|
|
10
|
+
trigger: string;
|
|
11
|
+
}>;
|
|
12
|
+
useWhen?: string;
|
|
13
|
+
avoidWhen?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CreateBuiltinAgentsOptions {
|
|
16
|
+
uiModel?: string;
|
|
17
|
+
disabledAgents?: Set<string>;
|
|
18
|
+
configOverrides?: Record<string, AgentOverrideConfig>;
|
|
19
|
+
buildOptions?: Omit<BuildAgentOptions, "disabledAgents">;
|
|
20
|
+
}
|
|
21
|
+
export declare const AGENT_FACTORIES: Record<LeadAgentName, AgentFactory>;
|
|
22
|
+
export declare const AGENT_METADATA: Record<LeadAgentName, AgentMetadata>;
|
|
23
|
+
export declare function registerCustomAgentMetadata(name: string, metadata: AgentMetadata): void;
|
|
24
|
+
export declare function getAllAgentMetadata(): Record<string, AgentMetadata>;
|
|
25
|
+
/**
|
|
26
|
+
* Builds all 8 builtin agents, respecting disabled list, model overrides,
|
|
27
|
+
* config overrides, and skill resolution options.
|
|
28
|
+
*
|
|
29
|
+
* Returns a record mapping agent names to their resolved `AgentConfig`.
|
|
30
|
+
* Disabled agents are excluded from the result.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createBuiltinAgents(options?: CreateBuiltinAgentsOptions): Partial<Record<LeadAgentName, AgentConfig>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentFactory } from "../types";
|
|
3
|
+
import { type AvailableAgent } from "../dynamic-prompt-builder";
|
|
4
|
+
export declare const LEAD_DEFAULTS: AgentConfig;
|
|
5
|
+
export interface CreateLeadAgentOptions {
|
|
6
|
+
disabledAgents?: Set<string>;
|
|
7
|
+
fingerprint?: string;
|
|
8
|
+
customAgents?: AvailableAgent[];
|
|
9
|
+
}
|
|
10
|
+
export declare function createLeadAgentWithOptions(model: string, options?: CreateLeadAgentOptions): AgentConfig;
|
|
11
|
+
export declare const createLeadAgent: AgentFactory;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { CustomAgentConfig } from "../config/schema";
|
|
3
|
+
import type { AgentMetadata } from "./builtin-agents";
|
|
4
|
+
import type { BuildAgentOptions } from "./agent-builder";
|
|
5
|
+
export interface BuildCustomAgentOptions extends BuildAgentOptions {
|
|
6
|
+
directory?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Builds an `AgentConfig` from a custom agent definition loaded from config.
|
|
10
|
+
*
|
|
11
|
+
* Supports:
|
|
12
|
+
* - Inline `prompt` string
|
|
13
|
+
* - `prompt_file` path (relative to directory, sandboxed via resolveSafePath)
|
|
14
|
+
* - `model`, `tools`, `skills`, `mode`, `description`
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildCustomAgent(name: string, config: CustomAgentConfig, options?: BuildCustomAgentOptions): AgentConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Derives `AgentMetadata` from a `CustomAgentConfig`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildCustomAgentMetadata(name: string, config: CustomAgentConfig): AgentMetadata;
|
|
21
|
+
declare module "./agent-builder" {
|
|
22
|
+
interface BuildAgentOptions {
|
|
23
|
+
buildOptions?: {
|
|
24
|
+
model?: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LeadAgentName } from "./types";
|
|
2
|
+
export interface AvailableAgent {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
useWhen?: string;
|
|
7
|
+
avoidWhen?: string;
|
|
8
|
+
isCustom?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface BuildDynamicLeadPromptOptions {
|
|
11
|
+
enabledAgents: AvailableAgent[];
|
|
12
|
+
fingerprint?: string;
|
|
13
|
+
customAgentCount?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds the dynamic section of the CTO agent's system prompt.
|
|
17
|
+
*
|
|
18
|
+
* This is appended to the static prompt.md at runtime so it always reflects
|
|
19
|
+
* the current set of enabled agents and any custom agents loaded from config.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildDynamicLeadPrompt(options: BuildDynamicLeadPromptOptions): string;
|
|
22
|
+
export declare const BUILTIN_AGENT_DISPLAY: Record<LeadAgentName, AvailableAgent>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentFactory } from "../types";
|
|
3
|
+
import type { ContinuationConfig } from "../../config/schema";
|
|
4
|
+
export declare const EXECUTOR_DEFAULTS: AgentConfig;
|
|
5
|
+
export declare function createExecutorAgentWithOptions(model: string, _disabledAgents?: Set<string>, _continuation?: ContinuationConfig): AgentConfig;
|
|
6
|
+
export declare const createExecutorAgent: AgentFactory;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./agent-builder";
|
|
3
|
+
export * from "./builtin-agents";
|
|
4
|
+
export * from "./custom-agent-factory";
|
|
5
|
+
export * from "./model-resolution";
|
|
6
|
+
export * from "./dynamic-prompt-builder";
|
|
7
|
+
export * from "./prompt-utils";
|
|
8
|
+
export * from "./prompt-loader";
|
|
9
|
+
export { createLeadAgent, createLeadAgentWithOptions, LEAD_DEFAULTS } from "./tech-lead/index";
|
|
10
|
+
export { createExecutorAgent, createExecutorAgentWithOptions, EXECUTOR_DEFAULTS } from "./lead-dev/index";
|
|
11
|
+
export { createEngineerAgent, ENGINEER_DEFAULTS } from "./engineer/index";
|
|
12
|
+
export { createArchitectAgent, ARCHITECT_DEFAULTS } from "./architect/index";
|
|
13
|
+
export { createCodeAnalystAgent, CODE_ANALYST_DEFAULTS } from "./code-analyst/index";
|
|
14
|
+
export { createResearcherAgent, RESEARCHER_DEFAULTS } from "./researcher/index";
|
|
15
|
+
export { createReviewerAgent, REVIEWER_DEFAULTS } from "./reviewer/index";
|
|
16
|
+
export { createTesterAgent, TESTER_DEFAULTS } from "./tester/index";
|
|
17
|
+
export { createGuardianAgent, GUARDIAN_DEFAULTS } from "./guardian/index";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentFactory } from "../types";
|
|
3
|
+
import { type AvailableAgent } from "../dynamic-prompt-builder";
|
|
4
|
+
export declare const LEAD_DEFAULTS: AgentConfig;
|
|
5
|
+
export interface CreateLeadAgentOptions {
|
|
6
|
+
disabledAgents?: Set<string>;
|
|
7
|
+
fingerprint?: string;
|
|
8
|
+
customAgents?: AvailableAgent[];
|
|
9
|
+
}
|
|
10
|
+
export declare function createLeadAgentWithOptions(model: string, options?: CreateLeadAgentOptions): AgentConfig;
|
|
11
|
+
export declare const createLeadAgent: AgentFactory;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentFactory } from "../types";
|
|
3
|
+
import type { ContinuationConfig } from "../../config/schema";
|
|
4
|
+
export declare const EXECUTOR_DEFAULTS: AgentConfig;
|
|
5
|
+
export declare function createExecutorAgentWithOptions(model: string, _disabledAgents?: Set<string>, _continuation?: ContinuationConfig): AgentConfig;
|
|
6
|
+
export declare const createExecutorAgent: AgentFactory;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { LeadAgentName } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Engineering tier — implementation & analysis agents.
|
|
4
|
+
* Gets a fast, capable model optimized for code tasks.
|
|
5
|
+
*/
|
|
6
|
+
/** Strategic tier: prefer Opus 4.6, fall back through capable models */
|
|
7
|
+
export declare const STRATEGIC_MODEL_CHAIN: readonly string[];
|
|
8
|
+
/** Engineering tier: prefer Sonnet 4.6, fall back through fast models */
|
|
9
|
+
export declare const ENGINEERING_MODEL_CHAIN: readonly string[];
|
|
10
|
+
export interface ResolveAgentModelOptions {
|
|
11
|
+
/** The model selected by the user in the UI (only relevant for primary agents) */
|
|
12
|
+
uiModel?: string;
|
|
13
|
+
/** Per-agent model override from config */
|
|
14
|
+
configOverride?: string;
|
|
15
|
+
/** Global fallback model from config */
|
|
16
|
+
globalFallback?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns the default model chain for an agent based on its tier.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getModelChain(agentName: LeadAgentName | string): readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* Returns the default (first) model for an agent based on its tier.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getDefaultModel(agentName: LeadAgentName | string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Determines which model to use for a given agent.
|
|
28
|
+
*
|
|
29
|
+
* Resolution order:
|
|
30
|
+
* 1. Per-agent config override (highest priority)
|
|
31
|
+
* 2. For primary agents: UI-selected model
|
|
32
|
+
* 3. Global fallback from config
|
|
33
|
+
* 4. Tier default (strategic → Opus, engineering → Sonnet)
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveAgentModel(agentName: LeadAgentName | string, options?: ResolveAgentModelOptions): string;
|
|
36
|
+
/**
|
|
37
|
+
* Returns true if the agent is a primary agent (tech-lead, lead-dev).
|
|
38
|
+
* Primary agents appear in the UI model selector.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isPrimaryAgent(agentName: LeadAgentName | string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the agent is in the strategic tier (uses Opus-class models).
|
|
43
|
+
*/
|
|
44
|
+
export declare function isStrategicAgent(agentName: LeadAgentName | string): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LeadAgentName } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Prompt loader for agent definitions.
|
|
4
|
+
*
|
|
5
|
+
* At runtime, agent prompt strings are embedded directly in their respective
|
|
6
|
+
* `index.ts` factory files (via the prompt.md files read at build time or
|
|
7
|
+
* inlined as template literals). This module provides a thin utility that
|
|
8
|
+
* loads an agent's default prompt from its `prompt.md` file.
|
|
9
|
+
*
|
|
10
|
+
* If the file cannot be read (e.g. in a bundled/dist context where the file
|
|
11
|
+
* isn't present), it returns `null` and the caller falls back to the inline
|
|
12
|
+
* default prompt string.
|
|
13
|
+
*/
|
|
14
|
+
export interface PromptLoadResult {
|
|
15
|
+
prompt: string;
|
|
16
|
+
source: "file" | "inline";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Attempts to load a prompt string from the agent's prompt.md file.
|
|
20
|
+
* Returns null if the file does not exist or cannot be read.
|
|
21
|
+
*/
|
|
22
|
+
export declare function tryLoadPromptFile(agentName: LeadAgentName | string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Synchronously reads the prompt.md embedded during module evaluation.
|
|
25
|
+
* Agent factories call this at module load time to read their adjacent prompt.md.
|
|
26
|
+
*
|
|
27
|
+
* Usage in an agent index.ts:
|
|
28
|
+
* const PROMPT = readPromptMd(import.meta.url) ?? INLINE_FALLBACK
|
|
29
|
+
*/
|
|
30
|
+
export declare function readPromptMd(importMetaUrl: string): string | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trims leading/trailing whitespace from each line and collapses consecutive
|
|
3
|
+
* blank lines into at most one blank line. Also trims the entire result.
|
|
4
|
+
*
|
|
5
|
+
* Used by agent prompt builders to normalize inline prompt strings.
|
|
6
|
+
*/
|
|
7
|
+
export declare function trimPrompt(text: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Strips leading/trailing blank lines from each section of an XML-style tag.
|
|
10
|
+
* Useful for cleaning up agent prompt templates before injection.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeXmlSection(tag: string, content: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk";
|
|
2
|
+
import type { AgentFactory } from "../types";
|
|
3
|
+
import { type AvailableAgent } from "../dynamic-prompt-builder";
|
|
4
|
+
export declare const LEAD_DEFAULTS: AgentConfig;
|
|
5
|
+
export interface CreateLeadAgentOptions {
|
|
6
|
+
disabledAgents?: Set<string>;
|
|
7
|
+
fingerprint?: string;
|
|
8
|
+
customAgents?: AvailableAgent[];
|
|
9
|
+
}
|
|
10
|
+
export declare function createLeadAgentWithOptions(model: string, options?: CreateLeadAgentOptions): AgentConfig;
|
|
11
|
+
export declare const createLeadAgent: AgentFactory;
|