opencode-enhancer-plugin 1.0.1 ā 1.5.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 +159 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +756 -18
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/sessionStore.d.ts +21 -0
- package/dist/utils/sessionStore.d.ts.map +1 -0
- package/dist/utils/sessionStore.js +70 -0
- package/dist/utils/sessionStore.js.map +1 -0
- package/dist/utils/todoParser.d.ts +9 -0
- package/dist/utils/todoParser.d.ts.map +1 -0
- package/dist/utils/todoParser.js +79 -0
- package/dist/utils/todoParser.js.map +1 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1,29 +1,325 @@
|
|
|
1
|
+
import { TodoParser } from "./utils/todoParser.js";
|
|
2
|
+
import { todoStore } from "./utils/sessionStore.js";
|
|
3
|
+
// === TODO ENFORCER CONSTANTS ===
|
|
4
|
+
const TODO_ENFORCER_AGENTS = ['ultraplan', 'strategos'];
|
|
5
|
+
const TODO_MARKER_START = '<!-- TODOS-START -->';
|
|
6
|
+
const TODO_MARKER_END = '<!-- TODOS-END -->';
|
|
7
|
+
// === STRATEGOS MODE CONSTANTS ===
|
|
8
|
+
const STRATEGOS_KEYWORDS = [
|
|
9
|
+
'strategos',
|
|
10
|
+
'strategy',
|
|
11
|
+
'strat',
|
|
12
|
+
'interview mode',
|
|
13
|
+
'strategic plan',
|
|
14
|
+
'complex plan',
|
|
15
|
+
'architecture decision',
|
|
16
|
+
'design review',
|
|
17
|
+
'comprehensive plan',
|
|
18
|
+
'šÆ',
|
|
19
|
+
];
|
|
20
|
+
// Validation Constants
|
|
21
|
+
const VALID_MODEL_PATTERNS = [
|
|
22
|
+
/^opencode\//,
|
|
23
|
+
/^anthropic\//,
|
|
24
|
+
/^openai\//,
|
|
25
|
+
/^google\//,
|
|
26
|
+
/^mistral\//,
|
|
27
|
+
/^cohere\//,
|
|
28
|
+
/^ollama\//,
|
|
29
|
+
/^zai-coding-plan\//,
|
|
30
|
+
/^kimi-for-coding\//
|
|
31
|
+
];
|
|
32
|
+
const DEFAULT_MODEL = "opencode/kimi-k2.5-free";
|
|
33
|
+
// Model Validation Function
|
|
34
|
+
function validateModel(model, agentName, client) {
|
|
35
|
+
if (!model || typeof model !== 'string') {
|
|
36
|
+
client.app.log({
|
|
37
|
+
service: "enhancer",
|
|
38
|
+
level: "warn",
|
|
39
|
+
message: `Invalid model for ${agentName}, using default`
|
|
40
|
+
}).catch(() => { });
|
|
41
|
+
return DEFAULT_MODEL;
|
|
42
|
+
}
|
|
43
|
+
const isValid = VALID_MODEL_PATTERNS.some(pattern => pattern.test(model));
|
|
44
|
+
if (!isValid) {
|
|
45
|
+
client.app.log({
|
|
46
|
+
service: "enhancer",
|
|
47
|
+
level: "warn",
|
|
48
|
+
message: `Unknown model provider for ${agentName}: ${model}, using default`
|
|
49
|
+
}).catch(() => { });
|
|
50
|
+
return DEFAULT_MODEL;
|
|
51
|
+
}
|
|
52
|
+
return model;
|
|
53
|
+
}
|
|
54
|
+
// Model Resolver with Hierarchical Configuration
|
|
55
|
+
function resolveModel(agentName, agentType, existingConfig, client) {
|
|
56
|
+
let model;
|
|
57
|
+
// 1. Check existing OpenCode Config (highest priority)
|
|
58
|
+
if (existingConfig?.model) {
|
|
59
|
+
return validateModel(existingConfig.model, agentName, client);
|
|
60
|
+
}
|
|
61
|
+
// 2. Specific environment variable (e.g., ENHANCER_MODEL_REVIEW_PLAN)
|
|
62
|
+
const specificVar = `ENHANCER_MODEL_${agentName.toUpperCase().replace(/-/g, '_')}`;
|
|
63
|
+
model = process.env[specificVar];
|
|
64
|
+
if (model) {
|
|
65
|
+
client.app.log({
|
|
66
|
+
service: "enhancer",
|
|
67
|
+
level: "info",
|
|
68
|
+
message: `Using specific env var ${specificVar} for ${agentName}`
|
|
69
|
+
}).catch(() => { });
|
|
70
|
+
return validateModel(model, agentName, client);
|
|
71
|
+
}
|
|
72
|
+
// 3. Grouped environment variable (ENHANCER_MODEL_SUBAGENT or ENHANCER_MODEL_PRIMARY)
|
|
73
|
+
const groupVar = `ENHANCER_MODEL_${agentType.toUpperCase()}`;
|
|
74
|
+
model = process.env[groupVar];
|
|
75
|
+
if (model) {
|
|
76
|
+
client.app.log({
|
|
77
|
+
service: "enhancer",
|
|
78
|
+
level: "info",
|
|
79
|
+
message: `Using group env var ${groupVar} for ${agentName}`
|
|
80
|
+
}).catch(() => { });
|
|
81
|
+
return validateModel(model, agentName, client);
|
|
82
|
+
}
|
|
83
|
+
// 4. Default
|
|
84
|
+
return DEFAULT_MODEL;
|
|
85
|
+
}
|
|
1
86
|
export const EnhancerPlugin = async ({ client }) => {
|
|
2
87
|
client.app.log({
|
|
3
88
|
service: "enhancer",
|
|
4
89
|
level: "info",
|
|
5
|
-
message: "Enhancer plugin initialized"
|
|
90
|
+
message: "š„ Enhancer plugin v1.5.0 initialized with 5 Specialized Subagents"
|
|
6
91
|
}).catch(() => { });
|
|
7
92
|
return {
|
|
8
93
|
config: async (input) => {
|
|
9
94
|
if (!input.agent) {
|
|
10
95
|
input.agent = {};
|
|
11
96
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
97
|
+
// Helper function to configure agent with merging logic
|
|
98
|
+
const configureAgent = (name, type, defaultConfig) => {
|
|
99
|
+
const existing = input.agent[name] || {};
|
|
100
|
+
const resolvedModel = resolveModel(name, type, existing, client);
|
|
101
|
+
// Merge: Default ā User Config ā Resolved Model ā Fixed Props
|
|
102
|
+
input.agent[name] = {
|
|
103
|
+
...defaultConfig,
|
|
104
|
+
...existing,
|
|
105
|
+
model: resolvedModel,
|
|
106
|
+
mode: type === 'subagent' ? 'subagent' : 'primary',
|
|
107
|
+
...(type === 'subagent' ? { hidden: true } : {})
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
// === SUBAGENTS (4 spezialisierte Experten) ===
|
|
111
|
+
// 1. LIBRARIAN - Dokumentation & Recherche
|
|
112
|
+
configureAgent('librarian', 'subagent', {
|
|
113
|
+
prompt: `You are LIBRARIAN - a documentation and codebase research specialist.
|
|
114
|
+
|
|
115
|
+
YOUR EXPERTISE:
|
|
116
|
+
- Find official documentation (Context7)
|
|
117
|
+
- Search GitHub for implementation examples (codesearch)
|
|
118
|
+
- Map project structure and entry points
|
|
119
|
+
- Identify tech stack and frameworks
|
|
120
|
+
|
|
121
|
+
WORKFLOW:
|
|
122
|
+
1. ALWAYS check context7 first for detected libraries
|
|
123
|
+
2. Use codesearch for real-world usage patterns
|
|
124
|
+
3. List project structure with glob
|
|
125
|
+
4. Return structured findings
|
|
126
|
+
|
|
127
|
+
OUTPUT FORMAT:
|
|
128
|
+
# š Librarian Report
|
|
129
|
+
|
|
130
|
+
## Tech Stack Detected
|
|
131
|
+
- **Framework**: [Name + Version]
|
|
132
|
+
- **Language**: [TypeScript/Python/etc.]
|
|
133
|
+
- **Key Libraries**: [List with Context7 links]
|
|
134
|
+
|
|
135
|
+
## Project Structure
|
|
136
|
+
- **Entry Point**: [Main file]
|
|
137
|
+
- **Core Directories**: [src/, lib/, etc.]
|
|
138
|
+
- **Config Files**: [package.json, tsconfig.json, etc.]
|
|
139
|
+
|
|
140
|
+
## Documentation Resources
|
|
141
|
+
- Context7 Libraries: [List of libraries with docs available]
|
|
142
|
+
- GitHub Examples: [Patterns found via codesearch]
|
|
143
|
+
|
|
144
|
+
## Recommendations
|
|
145
|
+
- [What should the primary agent know?]
|
|
146
|
+
- [Any missing dependencies?]`,
|
|
17
147
|
tools: {
|
|
18
148
|
list: true,
|
|
19
149
|
read: true,
|
|
20
150
|
grep: true,
|
|
21
|
-
|
|
151
|
+
context7_resolve_library_id: true,
|
|
152
|
+
context7_query_docs: true,
|
|
153
|
+
codesearch: true
|
|
22
154
|
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
155
|
+
});
|
|
156
|
+
// 2. ORACLE - Debugging & Code Analysis
|
|
157
|
+
configureAgent('oracle', 'subagent', {
|
|
158
|
+
prompt: `You are ORACLE - a debugging and code architecture specialist.
|
|
159
|
+
|
|
160
|
+
YOUR EXPERTISE:
|
|
161
|
+
- Deep code analysis and understanding
|
|
162
|
+
- Error pattern recognition
|
|
163
|
+
- Architecture evaluation
|
|
164
|
+
- Root cause analysis (not symptoms!)
|
|
165
|
+
|
|
166
|
+
WORKFLOW:
|
|
167
|
+
1. Read relevant source files thoroughly
|
|
168
|
+
2. Analyze patterns and relationships
|
|
169
|
+
3. Identify issues or architectural concerns
|
|
170
|
+
4. Provide specific, actionable insights
|
|
171
|
+
|
|
172
|
+
OUTPUT FORMAT:
|
|
173
|
+
# š® Oracle Analysis
|
|
174
|
+
|
|
175
|
+
## Code Understanding
|
|
176
|
+
- **File**: [path/to/file.ts]
|
|
177
|
+
- **Purpose**: [What does this code do?]
|
|
178
|
+
- **Key Functions**: [List important functions/classes]
|
|
179
|
+
|
|
180
|
+
## Issues Found
|
|
181
|
+
- **[SEVERITY: Critical/Warning/Info]** [Issue description]
|
|
182
|
+
- Location: [File:Line]
|
|
183
|
+
- Impact: [What could go wrong]
|
|
184
|
+
- Fix: [Specific recommendation]
|
|
185
|
+
|
|
186
|
+
## Architecture Assessment
|
|
187
|
+
- **Patterns Used**: [Singleton, Factory, etc.]
|
|
188
|
+
- **Coupling**: [High/Medium/Low]
|
|
189
|
+
- **Recommendations**: [Improvements]`,
|
|
190
|
+
tools: {
|
|
191
|
+
read: true,
|
|
192
|
+
grep: true
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
// 3. ARCHITECT - Dependencies & System Design
|
|
196
|
+
configureAgent('architect', 'subagent', {
|
|
197
|
+
prompt: `You are ARCHITECT - a dependency and system design specialist.
|
|
198
|
+
|
|
199
|
+
YOUR EXPERTISE:
|
|
200
|
+
- Dependency analysis and conflicts
|
|
201
|
+
- Import patterns and module relationships
|
|
202
|
+
- System architecture evaluation
|
|
203
|
+
- Integration complexity assessment
|
|
204
|
+
|
|
205
|
+
WORKFLOW:
|
|
206
|
+
1. Analyze package.json / requirements / dependencies
|
|
207
|
+
2. Map import patterns across codebase
|
|
208
|
+
3. Check for version conflicts or deprecated packages
|
|
209
|
+
4. Assess system boundaries
|
|
210
|
+
|
|
211
|
+
OUTPUT FORMAT:
|
|
212
|
+
# šļø Architecture Report
|
|
213
|
+
|
|
214
|
+
## Dependencies Analysis
|
|
215
|
+
- **Core Libraries**: [List with versions]
|
|
216
|
+
- **Dev Dependencies**: [Testing, build tools]
|
|
217
|
+
- **Peer Dependencies**: [Compatibility requirements]
|
|
218
|
+
|
|
219
|
+
## Import Patterns
|
|
220
|
+
- **Common Imports**: [Most used modules]
|
|
221
|
+
- **Circular Dependencies**: [If any found]
|
|
222
|
+
- **Unused Dependencies**: [Potential cleanup]
|
|
223
|
+
|
|
224
|
+
## System Boundaries
|
|
225
|
+
- **External APIs**: [Services integrated]
|
|
226
|
+
- **Database/Storage**: [Data layer]
|
|
227
|
+
- **Authentication**: [Auth mechanism]
|
|
228
|
+
|
|
229
|
+
## Risk Assessment
|
|
230
|
+
- **Version Conflicts**: [Issues]
|
|
231
|
+
- **Deprecated Packages**: [Needs update]
|
|
232
|
+
- **Security Concerns**: [Vulnerabilities]`,
|
|
233
|
+
tools: {
|
|
234
|
+
read: true,
|
|
235
|
+
grep: true,
|
|
236
|
+
glob: true
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
// 4. REVIEWER - Plan Validation
|
|
240
|
+
configureAgent('reviewer', 'subagent', {
|
|
241
|
+
prompt: `You are REVIEWER - a critical plan validation specialist.
|
|
242
|
+
|
|
243
|
+
YOUR EXPERTISE:
|
|
244
|
+
- Spot missing steps in plans
|
|
245
|
+
- Identify technical risks early
|
|
246
|
+
- Validate file paths and assumptions
|
|
247
|
+
- Ensure test coverage
|
|
248
|
+
|
|
249
|
+
WORKFLOW:
|
|
250
|
+
1. Analyze the proposed plan
|
|
251
|
+
2. Check for completeness gaps
|
|
252
|
+
3. Verify technical feasibility
|
|
253
|
+
4. Provide critical feedback
|
|
254
|
+
|
|
255
|
+
OUTPUT FORMAT:
|
|
256
|
+
# ā
Plan Review
|
|
257
|
+
|
|
258
|
+
## Summary
|
|
259
|
+
- **Status**: [APPROVED / NEEDS_REVISION]
|
|
260
|
+
- **Completeness**: [X%]
|
|
261
|
+
- **Risk Level**: [Low/Medium/High]
|
|
262
|
+
|
|
263
|
+
## Critical Issues
|
|
264
|
+
1. [Issue] ā [Fix]
|
|
265
|
+
|
|
266
|
+
## Warnings
|
|
267
|
+
1. [Concern] ā [Mitigation]
|
|
268
|
+
|
|
269
|
+
## Missing Elements
|
|
270
|
+
- [What was forgotten?]
|
|
271
|
+
|
|
272
|
+
## Final Verdict
|
|
273
|
+
[One paragraph assessment]`,
|
|
274
|
+
tools: {
|
|
275
|
+
read: true,
|
|
276
|
+
task: true
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// 5. INTERVIEWER (nur für strategos)
|
|
280
|
+
configureAgent('interviewer', 'subagent', {
|
|
281
|
+
prompt: `You are INTERVIEWER - a requirements clarification specialist.
|
|
282
|
+
|
|
283
|
+
YOUR EXPERTISE:
|
|
284
|
+
- Ask the right questions
|
|
285
|
+
- Uncover hidden assumptions
|
|
286
|
+
- Define clear scope and success criteria
|
|
287
|
+
- Identify stakeholders and constraints
|
|
288
|
+
|
|
289
|
+
RULES:
|
|
290
|
+
- Ask 3-5 questions maximum
|
|
291
|
+
- Focus on "Must Have" vs "Nice to Have"
|
|
292
|
+
- Clarify technical constraints
|
|
293
|
+
- Define "Done"
|
|
294
|
+
|
|
295
|
+
OUTPUT FORMAT:
|
|
296
|
+
# š¤ Interview Report
|
|
297
|
+
|
|
298
|
+
## Clarification Questions
|
|
299
|
+
|
|
300
|
+
### Q1: [Question]
|
|
301
|
+
**Why**: [Context]
|
|
302
|
+
|
|
303
|
+
### Q2: [Question]
|
|
304
|
+
**Why**: [Context]
|
|
305
|
+
|
|
306
|
+
### Q3: [Question]
|
|
307
|
+
**Why**: [Context]
|
|
308
|
+
|
|
309
|
+
## Anticipated Complexity
|
|
310
|
+
- **Level**: [Low/Medium/High]
|
|
311
|
+
- **Estimated Effort**: [X hours/days]
|
|
312
|
+
- **Main Risks**: [List]
|
|
313
|
+
|
|
314
|
+
## Next Steps
|
|
315
|
+
[What to do after getting answers]`,
|
|
316
|
+
tools: {
|
|
317
|
+
read: true
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
// Configure Primary Agents
|
|
321
|
+
// enhancer - Prompt Enhancement
|
|
322
|
+
configureAgent('enhancer', 'primary', {
|
|
27
323
|
description: "Universal Technical Architect & Prompt Enhancer",
|
|
28
324
|
color: "#9C27B0",
|
|
29
325
|
steps: 15,
|
|
@@ -34,36 +330,478 @@ export const EnhancerPlugin = async ({ client }) => {
|
|
|
34
330
|
edit: false,
|
|
35
331
|
write: false
|
|
36
332
|
},
|
|
37
|
-
|
|
38
|
-
|
|
333
|
+
permission: {
|
|
334
|
+
edit: "deny",
|
|
335
|
+
bash: "deny"
|
|
336
|
+
},
|
|
337
|
+
prompt: `You are ENHANCER - generate enhanced, executable prompts.
|
|
338
|
+
|
|
339
|
+
WORKFLOW:
|
|
340
|
+
1. Classify intent: FIX/FEAT/REFACTOR/TEST/EXPLAIN
|
|
341
|
+
2. Call subagents IN PARALLEL:
|
|
342
|
+
- FIX/FEAT: librarian + oracle + architect
|
|
343
|
+
- REFACTOR: librarian + oracle + reviewer
|
|
344
|
+
- TEST: librarian + oracle + architect + reviewer
|
|
345
|
+
- EXPLAIN: librarian + oracle
|
|
346
|
+
3. Synthesize results
|
|
347
|
+
4. Generate markdown prompt
|
|
348
|
+
|
|
349
|
+
OUTPUT FORMAT:
|
|
350
|
+
# Task: [Title]
|
|
351
|
+
|
|
352
|
+
## Context
|
|
353
|
+
[Tech stack and key files]
|
|
354
|
+
|
|
355
|
+
## Instructions
|
|
356
|
+
1. [Specific step]
|
|
357
|
+
2. [Specific step]
|
|
358
|
+
|
|
359
|
+
## Technical Constraints
|
|
360
|
+
- [Constraint 1]
|
|
361
|
+
- [Constraint 2]
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
**Run in Build mode to execute**
|
|
365
|
+
|
|
366
|
+
=== RULES ===
|
|
367
|
+
- ALL paths from subagents
|
|
368
|
+
- Be specific, never vague`
|
|
369
|
+
});
|
|
370
|
+
// ultraplan - Vereinfacht & Fokussiert
|
|
371
|
+
configureAgent('ultraplan', 'primary', {
|
|
372
|
+
description: "Planning Agent with Parallel Discovery š",
|
|
373
|
+
color: "#FF5722",
|
|
374
|
+
steps: 20,
|
|
375
|
+
tools: {
|
|
376
|
+
task: true,
|
|
377
|
+
read: true,
|
|
378
|
+
bash: false,
|
|
379
|
+
edit: false,
|
|
380
|
+
write: false,
|
|
381
|
+
todowrite: true // ā Todo-Integration
|
|
382
|
+
},
|
|
383
|
+
permission: {
|
|
384
|
+
edit: "deny",
|
|
385
|
+
bash: "deny"
|
|
386
|
+
},
|
|
387
|
+
prompt: `You are ULTRAPLAN - create implementation plans through parallel discovery.
|
|
388
|
+
|
|
389
|
+
=== WORKFLOW (STRICT) ===
|
|
390
|
+
|
|
391
|
+
**STEP 1: PARALLEL DISCOVERY** ā”
|
|
392
|
+
Call ALL subagents IN PARALLEL:
|
|
393
|
+
- librarian: Map project structure & docs
|
|
394
|
+
- oracle: Analyze relevant code
|
|
395
|
+
- architect: Check dependencies & system design
|
|
396
|
+
|
|
397
|
+
WAIT for all results. Do NOT proceed before all return.
|
|
398
|
+
|
|
399
|
+
**STEP 2: CREATE TODOS** š
|
|
400
|
+
MUST use todowrite tool:
|
|
401
|
+
\`\`\`
|
|
402
|
+
todowrite({
|
|
403
|
+
todos: [
|
|
404
|
+
{ id: "1", content: "Step 1: [Specific task]", status: "pending", priority: "high" },
|
|
405
|
+
{ id: "2", content: "Step 2: [Specific task]", status: "pending", priority: "high" },
|
|
406
|
+
// 3-8 todos depending on complexity
|
|
407
|
+
]
|
|
408
|
+
})
|
|
409
|
+
\`\`\`
|
|
410
|
+
|
|
411
|
+
**STEP 3: CREATE PLAN**
|
|
412
|
+
Generate markdown plan with:
|
|
413
|
+
- File paths from discovery (NEVER invent!)
|
|
414
|
+
- Specific implementation steps
|
|
415
|
+
- Error handling strategy
|
|
416
|
+
|
|
417
|
+
**STEP 4: REQUEST REVIEW** (optional for complex tasks)
|
|
418
|
+
Call reviewer subagent if plan is high-risk.
|
|
419
|
+
|
|
420
|
+
=== RULES ===
|
|
421
|
+
- ALL file paths must come from librarian/oracle/architect
|
|
422
|
+
- ALWAYS create todos via todowrite tool
|
|
423
|
+
- NEVER enable write/edit tools
|
|
424
|
+
- End with: "Copy this plan and run in **Build** mode"
|
|
425
|
+
|
|
426
|
+
=== WHEN TO USE ===
|
|
427
|
+
- Simple bugfixes
|
|
428
|
+
- Small features (1-3 files)
|
|
429
|
+
- Documentation
|
|
430
|
+
- Adding tests
|
|
431
|
+
|
|
432
|
+
=== WHEN TO USE STRATEGOS ===
|
|
433
|
+
- New features (>3 files)
|
|
434
|
+
- Architecture changes
|
|
435
|
+
- Integrations (APIs, DBs)
|
|
436
|
+
- Performance/Security work`
|
|
437
|
+
});
|
|
438
|
+
// ask - Question Answering
|
|
439
|
+
configureAgent('ask', 'primary', {
|
|
440
|
+
description: "Context-Aware Question Answering",
|
|
441
|
+
color: "#2196F3",
|
|
442
|
+
steps: 15,
|
|
443
|
+
tools: {
|
|
444
|
+
task: true,
|
|
445
|
+
read: true,
|
|
446
|
+
bash: false,
|
|
447
|
+
edit: false,
|
|
448
|
+
write: false
|
|
449
|
+
},
|
|
450
|
+
permission: {
|
|
451
|
+
edit: "deny",
|
|
452
|
+
bash: "deny"
|
|
453
|
+
},
|
|
454
|
+
prompt: `You are ASK - a context-aware research assistant.
|
|
455
|
+
|
|
456
|
+
=== WORKFLOW ===
|
|
457
|
+
|
|
458
|
+
**STEP 1: CLASSIFY QUESTION**
|
|
459
|
+
- CODE: "How does X work?", "Explain this function"
|
|
460
|
+
- ARCHITECTURE: "How is this project structured?"
|
|
461
|
+
- DEBUG: "Why is this not working?"
|
|
462
|
+
- GENERAL: "What is this project about?"
|
|
463
|
+
|
|
464
|
+
**STEP 2: PARALLEL SUBAGENTS**
|
|
465
|
+
Call based on type:
|
|
466
|
+
|
|
467
|
+
| Type | Subagents |
|
|
468
|
+
|------|-----------|
|
|
469
|
+
| CODE | librarian + oracle + architect |
|
|
470
|
+
| ARCHITECTURE | librarian + oracle |
|
|
471
|
+
| DEBUG | librarian + oracle + architect + reviewer |
|
|
472
|
+
| GENERAL | librarian |
|
|
473
|
+
|
|
474
|
+
**STEP 3: SYNTHESIZE**
|
|
475
|
+
- Wait for ALL results
|
|
476
|
+
- Combine findings
|
|
477
|
+
- Resolve conflicts
|
|
478
|
+
|
|
479
|
+
**STEP 4: ANSWER FORMAT**
|
|
480
|
+
|
|
481
|
+
## Answer
|
|
482
|
+
[2-4 sentences]
|
|
483
|
+
|
|
484
|
+
## Details
|
|
485
|
+
|
|
486
|
+
### Relevant Files
|
|
487
|
+
- \`path/to/file.ts\` - [Why it matters]
|
|
488
|
+
|
|
489
|
+
### Key Code
|
|
490
|
+
\`\`\`typescript
|
|
491
|
+
// From: path/to/file.ts
|
|
492
|
+
[Snippet]
|
|
493
|
+
\`\`\`
|
|
494
|
+
|
|
495
|
+
### Context
|
|
496
|
+
- **Tech Stack**: [Technologies]
|
|
497
|
+
- **Pattern**: [Design patterns]
|
|
498
|
+
|
|
499
|
+
## Explore Further
|
|
500
|
+
- [Suggestion 1]
|
|
501
|
+
- [Suggestion 2]
|
|
502
|
+
|
|
503
|
+
=== RULES ===
|
|
504
|
+
- ALL paths from subagents (never invent)
|
|
505
|
+
- Cite sources (which subagent found what)
|
|
506
|
+
- Be concise but thorough`
|
|
507
|
+
});
|
|
508
|
+
// strategos - Strategic Planning
|
|
509
|
+
configureAgent('strategos', 'primary', {
|
|
510
|
+
description: "šÆ Strategic Planner with Interview Mode",
|
|
511
|
+
color: "#FF6F00",
|
|
512
|
+
steps: 30,
|
|
513
|
+
tools: {
|
|
514
|
+
task: true,
|
|
515
|
+
read: true,
|
|
516
|
+
bash: false,
|
|
517
|
+
edit: false,
|
|
518
|
+
write: false,
|
|
519
|
+
todowrite: true
|
|
520
|
+
},
|
|
521
|
+
permission: {
|
|
522
|
+
edit: "deny",
|
|
523
|
+
bash: "deny",
|
|
524
|
+
},
|
|
525
|
+
prompt: `You are STRATEGOS - the Strategic General.
|
|
526
|
+
|
|
527
|
+
=== STRATEGOS WORKFLOW ===
|
|
528
|
+
|
|
529
|
+
**PHASE 1: INTERVIEW (If needed)**
|
|
530
|
+
When requirements are unclear:
|
|
531
|
+
1. Call interviewer subagent
|
|
532
|
+
2. Present questions to user
|
|
533
|
+
3. Wait for answers
|
|
534
|
+
4. Analyze and confirm understanding
|
|
535
|
+
|
|
536
|
+
**PHASE 2: DISCOVERY**
|
|
537
|
+
Call ALL in PARALLEL:
|
|
538
|
+
- librarian: Project & docs
|
|
539
|
+
- oracle: Code analysis
|
|
540
|
+
- architect: Dependencies & system
|
|
541
|
+
|
|
542
|
+
**PHASE 3: STRATEGIC PLANNING**
|
|
543
|
+
|
|
544
|
+
Create structured plan:
|
|
545
|
+
|
|
546
|
+
# šÆ Strategos Strategic Plan
|
|
547
|
+
|
|
548
|
+
## Mission Statement
|
|
549
|
+
[1-2 sentences]
|
|
550
|
+
|
|
551
|
+
## Requirements Analysis
|
|
552
|
+
### Must Have
|
|
553
|
+
- [ ]
|
|
554
|
+
### Should Have
|
|
555
|
+
- [ ]
|
|
556
|
+
### Could Have
|
|
557
|
+
- [ ]
|
|
558
|
+
|
|
559
|
+
## Architecture Decisions
|
|
560
|
+
| Decision | Rationale | Trade-offs |
|
|
561
|
+
|----------|-----------|------------|
|
|
562
|
+
| [Decision] | [Why] | [Pros/Cons] |
|
|
563
|
+
|
|
564
|
+
## Implementation Roadmap
|
|
565
|
+
|
|
566
|
+
### Phase 1: Foundation
|
|
567
|
+
**Goal**: [What to achieve]
|
|
568
|
+
**Deliverables**:
|
|
569
|
+
- [ ] [Specific deliverable]
|
|
570
|
+
**Files**:
|
|
571
|
+
- \`path/to/file.ts\` - [Why?]
|
|
572
|
+
**Steps**:
|
|
573
|
+
1. [Concrete step]
|
|
574
|
+
|
|
575
|
+
### Phase 2: Core Implementation
|
|
576
|
+
...
|
|
577
|
+
|
|
578
|
+
### Phase 3: Integration & Testing
|
|
579
|
+
...
|
|
580
|
+
|
|
581
|
+
## Risk Assessment
|
|
582
|
+
| Risk | Probability | Impact | Mitigation |
|
|
583
|
+
|------|------------|--------|------------|
|
|
584
|
+
| [Risk] | High/Med/Low | High/Med/Low | [Strategy] |
|
|
585
|
+
|
|
586
|
+
## ā
Quality Gates
|
|
587
|
+
- [ ] Gate 1: [Criterion]
|
|
588
|
+
- [ ] Gate 2: [Criterion]
|
|
589
|
+
|
|
590
|
+
## š§Ŗ Validation Plan
|
|
591
|
+
[How to test success]
|
|
592
|
+
|
|
593
|
+
**NEXT STEP**: Run in **Build** mode.
|
|
594
|
+
|
|
595
|
+
=== TODO CREATION ===
|
|
596
|
+
MUST create todos via todowrite:
|
|
597
|
+
- Phase 1: [Description]
|
|
598
|
+
- Phase 2: [Description]
|
|
599
|
+
- Phase 3: [Description]
|
|
600
|
+
|
|
601
|
+
ā ļø You cannot stop until all todos are completed!
|
|
602
|
+
|
|
603
|
+
=== WHEN TO USE STRATEGOS ===
|
|
604
|
+
- New features (>3 files)
|
|
605
|
+
- Architecture changes
|
|
606
|
+
- Integrations (APIs, DBs)
|
|
607
|
+
- Performance/Security work
|
|
608
|
+
- Complex refactoring
|
|
609
|
+
|
|
610
|
+
=== WHEN TO USE ULTRAPLAN ===
|
|
611
|
+
- Simple tasks (<3 files)
|
|
612
|
+
- Bugfixes
|
|
613
|
+
- Documentation`,
|
|
614
|
+
});
|
|
615
|
+
// Log configured agent models
|
|
616
|
+
const configuredAgents = [
|
|
617
|
+
'librarian', 'oracle', 'architect', 'reviewer', 'interviewer',
|
|
618
|
+
'enhancer', 'ultraplan', 'ask', 'strategos'
|
|
619
|
+
];
|
|
620
|
+
const modelSummary = configuredAgents
|
|
621
|
+
.map(name => `${name}=${input.agent[name]?.model || 'default'}`)
|
|
622
|
+
.join(', ');
|
|
623
|
+
client.app.log({
|
|
624
|
+
service: "enhancer",
|
|
625
|
+
level: "info",
|
|
626
|
+
message: `š„ Registered ${Object.keys(input.agent).length} agents: ${Object.keys(input.agent).join(", ")}`
|
|
627
|
+
}).catch(() => { });
|
|
628
|
+
client.app.log({
|
|
629
|
+
service: "enhancer",
|
|
630
|
+
level: "debug",
|
|
631
|
+
message: `Agent models configured: ${modelSummary}`
|
|
632
|
+
}).catch(() => { });
|
|
39
633
|
},
|
|
40
634
|
"tool.execute.before": async (input, output) => {
|
|
41
635
|
if (input.tool === "task") {
|
|
42
636
|
const args = output.args;
|
|
43
|
-
|
|
637
|
+
const validSubagents = [
|
|
638
|
+
"librarian", "oracle", "architect", "reviewer", "interviewer"
|
|
639
|
+
];
|
|
640
|
+
if (args?.subagent_type && validSubagents.includes(args.subagent_type)) {
|
|
44
641
|
client.app.log({
|
|
45
642
|
service: "enhancer",
|
|
46
643
|
level: "debug",
|
|
47
|
-
message:
|
|
644
|
+
message: `Calling ${args.subagent_type} subagent`
|
|
48
645
|
}).catch(() => { });
|
|
49
646
|
}
|
|
50
647
|
}
|
|
51
648
|
},
|
|
52
649
|
"message.updated": async (input, output) => {
|
|
53
|
-
|
|
650
|
+
const agentName = input.session?.agent?.name;
|
|
651
|
+
if (!["enhancer", "ultraplan", "ask", "strategos"].includes(agentName)) {
|
|
54
652
|
return;
|
|
55
653
|
}
|
|
56
654
|
const content = input.message?.content || "";
|
|
57
655
|
if (content.includes("Build mode") || content.includes("Build Mode")) {
|
|
58
656
|
return;
|
|
59
657
|
}
|
|
60
|
-
if (content.includes("
|
|
658
|
+
if (content.includes("\`\`\`markdown") || content.includes("# Task:")) {
|
|
61
659
|
const hint = "\n\n---\n**Next Step**: Copy this entire block and run it in **Build** mode to execute the plan.";
|
|
62
660
|
if (output && typeof output === "object") {
|
|
63
661
|
output.content = content + hint;
|
|
64
662
|
}
|
|
65
663
|
}
|
|
66
|
-
}
|
|
664
|
+
},
|
|
665
|
+
// === TODO ENFORCER: Message Completed Hook ===
|
|
666
|
+
// Extracts todos from agent responses and stores them
|
|
667
|
+
"message.completed": async (input, output) => {
|
|
668
|
+
const agentName = input.session?.agent?.name;
|
|
669
|
+
const sessionId = input.session?.id || input.sessionId || 'default';
|
|
670
|
+
// Only for Todo-enforced agents
|
|
671
|
+
if (!TODO_ENFORCER_AGENTS.includes(agentName)) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
try {
|
|
675
|
+
const content = input.message?.content || output?.content || "";
|
|
676
|
+
// Extract todos
|
|
677
|
+
const result = TodoParser.extractTodos(content);
|
|
678
|
+
if (result.hasTodos) {
|
|
679
|
+
// Store todos
|
|
680
|
+
todoStore.set(sessionId, result.todos, agentName);
|
|
681
|
+
// Log for debugging
|
|
682
|
+
await client.app.log({
|
|
683
|
+
service: "enhancer",
|
|
684
|
+
level: "info",
|
|
685
|
+
message: `š Todos detected in ${agentName}: ${result.completedCount}/${result.todos.length} completed`
|
|
686
|
+
}).catch(() => { });
|
|
687
|
+
// Add visual todo block if pending todos exist
|
|
688
|
+
if (result.pendingCount > 0) {
|
|
689
|
+
const todoBlock = `\n\n${TODO_MARKER_START}\n## š Open Todos (${result.pendingCount}/${result.todos.length})\n\n${TodoParser.formatTodoList(result.todos, true)}\n\nā ļø **Note**: You cannot stop until all Todos are completed!\n${TODO_MARKER_END}`;
|
|
690
|
+
if (output && typeof output === "object") {
|
|
691
|
+
output.content = content + todoBlock;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
catch (error) {
|
|
697
|
+
await client.app.log({
|
|
698
|
+
service: "enhancer",
|
|
699
|
+
level: "warn",
|
|
700
|
+
message: `Error in todo extraction: ${error}`
|
|
701
|
+
}).catch(() => { });
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
// === TODO ENFORCER: Stop Requested Hook ===
|
|
705
|
+
// Prevents stop when todos are open
|
|
706
|
+
"stop.requested": async (input, output) => {
|
|
707
|
+
const agentName = input.session?.agent?.name;
|
|
708
|
+
const sessionId = input.session?.id || input.sessionId || 'default';
|
|
709
|
+
// Only for Todo-enforced agents
|
|
710
|
+
if (!TODO_ENFORCER_AGENTS.includes(agentName)) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
try {
|
|
714
|
+
const unfinishedCount = todoStore.countUnfinished(sessionId);
|
|
715
|
+
if (unfinishedCount > 0) {
|
|
716
|
+
const pendingTodos = todoStore.getAllPending(sessionId);
|
|
717
|
+
// DENY STOP
|
|
718
|
+
output.continue = true;
|
|
719
|
+
output.reason = `š **STOP DENIED** - ${unfinishedCount} TODO(S) STILL OPEN!\n\nYou cannot end the session until all tasks are completed. Please work on the remaining todos:\n\n${pendingTodos.map((t, i) => `${i + 1}. [ ] ${t.description}`).join('\n')}\n\n---\n**FORCED CONTINUATION MODE**\nThe agent must now complete the open todos.`;
|
|
720
|
+
await client.app.log({
|
|
721
|
+
service: "enhancer",
|
|
722
|
+
level: "warn",
|
|
723
|
+
message: `š Stop blocked for ${agentName}: ${unfinishedCount} todos open`
|
|
724
|
+
}).catch(() => { });
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
// All todos completed - clean up store
|
|
728
|
+
if (todoStore.has(sessionId)) {
|
|
729
|
+
todoStore.delete(sessionId);
|
|
730
|
+
await client.app.log({
|
|
731
|
+
service: "enhancer",
|
|
732
|
+
level: "info",
|
|
733
|
+
message: `ā
All todos completed in ${agentName} - Store cleaned`
|
|
734
|
+
}).catch(() => { });
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
await client.app.log({
|
|
740
|
+
service: "enhancer",
|
|
741
|
+
level: "error",
|
|
742
|
+
message: `Error in stop.requested hook: ${error}`
|
|
743
|
+
}).catch(() => { });
|
|
744
|
+
}
|
|
745
|
+
},
|
|
746
|
+
// === TODO ENFORCER: Session Start Hook ===
|
|
747
|
+
// Cleans old todos on new session
|
|
748
|
+
"session.start": async (input, output) => {
|
|
749
|
+
const agentName = input.agent?.name;
|
|
750
|
+
if (TODO_ENFORCER_AGENTS.includes(agentName)) {
|
|
751
|
+
// Cleanup old sessions
|
|
752
|
+
todoStore.cleanup();
|
|
753
|
+
await client.app.log({
|
|
754
|
+
service: "enhancer",
|
|
755
|
+
level: "debug",
|
|
756
|
+
message: `š New ${agentName} session started - Todo Store cleaned`
|
|
757
|
+
}).catch(() => { });
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
// === TODO ENFORCER: Session End Hook ===
|
|
761
|
+
"session.end": async (input, output) => {
|
|
762
|
+
const agentName = input.agent?.name;
|
|
763
|
+
const sessionId = input.session?.id || input.sessionId || 'default';
|
|
764
|
+
if (TODO_ENFORCER_AGENTS.includes(agentName)) {
|
|
765
|
+
// Check if open todos exist
|
|
766
|
+
if (todoStore.has(sessionId)) {
|
|
767
|
+
const stats = todoStore.get(sessionId);
|
|
768
|
+
const unfinished = stats?.todos.filter(t => t.status !== 'completed').length || 0;
|
|
769
|
+
if (unfinished > 0) {
|
|
770
|
+
await client.app.log({
|
|
771
|
+
service: "enhancer",
|
|
772
|
+
level: "warn",
|
|
773
|
+
message: `ā ļø Session ended with ${unfinished} open todos`
|
|
774
|
+
}).catch(() => { });
|
|
775
|
+
}
|
|
776
|
+
// Clean up
|
|
777
|
+
todoStore.delete(sessionId);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
// === STRATEGOS MODE ACTIVATION ===
|
|
782
|
+
// Auto-switch to strategos on keywords
|
|
783
|
+
"user.prompt.submitted": async (input, output) => {
|
|
784
|
+
const prompt = input.prompt || "";
|
|
785
|
+
const currentAgent = input.agent?.name;
|
|
786
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
787
|
+
// Check for Strategos keywords
|
|
788
|
+
const detectedKeyword = STRATEGOS_KEYWORDS.find(kw => lowerPrompt.includes(kw.toLowerCase()));
|
|
789
|
+
if (detectedKeyword && currentAgent !== 'strategos') {
|
|
790
|
+
// Switch to strategos Agent
|
|
791
|
+
output.agent = 'strategos';
|
|
792
|
+
// Add hint
|
|
793
|
+
output.hint = `šÆ **Strategos Mode activated** (Keyword: "${detectedKeyword}")\n\nI will interview you first to clarify requirements, then create a strategic plan.`;
|
|
794
|
+
await client.app.log({
|
|
795
|
+
service: "enhancer",
|
|
796
|
+
level: "info",
|
|
797
|
+
message: `šÆ Strategos Mode activated by keyword: "${detectedKeyword}"`
|
|
798
|
+
}).catch(() => { });
|
|
799
|
+
}
|
|
800
|
+
// Alternative: Interview Mode hint for ultraplan
|
|
801
|
+
if (lowerPrompt.includes('interview me') && currentAgent === 'ultraplan') {
|
|
802
|
+
output.hint = `š” **Tip**: For complex tasks with interview, use the **strategos** Agent (Tab ā strategos)`;
|
|
803
|
+
}
|
|
804
|
+
},
|
|
67
805
|
};
|
|
68
806
|
};
|
|
69
807
|
export default EnhancerPlugin;
|