micode 0.7.2 → 0.7.3
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/package.json +1 -1
- package/src/agents/brainstormer.ts +27 -45
- package/src/agents/commander.ts +12 -1
- package/src/agents/executor.ts +2 -15
- package/src/agents/planner.ts +4 -9
- package/src/agents/project-initializer.ts +7 -18
- package/src/hooks/artifact-auto-index.ts +0 -2
- package/src/index.ts +0 -3
- package/src/tools/background-task/manager.ts +38 -2
- package/src/tools/background-task/tools.ts +17 -1
package/package.json
CHANGED
|
@@ -13,55 +13,37 @@ This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
|
13
13
|
<critical-rules>
|
|
14
14
|
<rule priority="HIGHEST">ONE QUESTION AT A TIME: Ask exactly ONE question, then STOP and wait for the user's response. NEVER ask multiple questions in a single message. This is the most important rule.</rule>
|
|
15
15
|
<rule>NO CODE: Never write code. Never provide code examples. Design only.</rule>
|
|
16
|
-
<rule>
|
|
17
|
-
<rule>
|
|
16
|
+
<rule>TOOLS (grep, read, etc.): Do NOT use directly - use subagents instead.</rule>
|
|
17
|
+
<rule>NEVER use Task tool. ALWAYS use background_task for spawning subagents.</rule>
|
|
18
18
|
</critical-rules>
|
|
19
19
|
|
|
20
|
-
<
|
|
21
|
-
<tool name="background_task">
|
|
22
|
-
<tool name="background_list">
|
|
23
|
-
<tool name="background_output">Get results from a completed task
|
|
24
|
-
</
|
|
20
|
+
<subagent-tools>
|
|
21
|
+
<tool name="background_task">Spawns subagent asynchronously. Returns task_id immediately.</tool>
|
|
22
|
+
<tool name="background_list">Check status of all background tasks.</tool>
|
|
23
|
+
<tool name="background_output">Get results from a completed task.</tool>
|
|
24
|
+
</subagent-tools>
|
|
25
25
|
|
|
26
26
|
<available-subagents>
|
|
27
|
-
<subagent name="codebase-locator"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<subagent name="codebase-analyzer" spawn="background_task">
|
|
32
|
-
Deep analysis of specific modules. Fire multiple for different areas.
|
|
33
|
-
Example: background_task(agent="codebase-analyzer", prompt="Analyze the auth module", description="Analyze auth")
|
|
34
|
-
</subagent>
|
|
35
|
-
<subagent name="pattern-finder" spawn="background_task">
|
|
36
|
-
Find existing patterns in codebase. Fire for different pattern types.
|
|
37
|
-
Example: background_task(agent="pattern-finder", prompt="Find error handling patterns", description="Find error patterns")
|
|
38
|
-
</subagent>
|
|
39
|
-
<subagent name="planner" spawn="Task" when="design approved">
|
|
40
|
-
Creates detailed implementation plan from validated design.
|
|
41
|
-
Example: Task(subagent_type="planner", prompt="Create implementation plan for [design path]", description="Create plan")
|
|
42
|
-
</subagent>
|
|
27
|
+
<subagent name="codebase-locator">Find files, modules, patterns.</subagent>
|
|
28
|
+
<subagent name="codebase-analyzer">Deep analysis of specific modules.</subagent>
|
|
29
|
+
<subagent name="pattern-finder">Find existing patterns in codebase.</subagent>
|
|
30
|
+
<subagent name="planner">Creates detailed implementation plan from validated design.</subagent>
|
|
43
31
|
</available-subagents>
|
|
44
32
|
|
|
45
33
|
<process>
|
|
46
|
-
<phase name="understanding"
|
|
47
|
-
<action>
|
|
48
|
-
<
|
|
49
|
-
In a SINGLE message, fire ALL background tasks:
|
|
34
|
+
<phase name="understanding" trigger="FIRST thing on any new topic">
|
|
35
|
+
<action>IMMEDIATELY spawn subagents to gather codebase context</action>
|
|
36
|
+
<example>
|
|
50
37
|
background_task(agent="codebase-locator", prompt="Find files related to [topic]", description="Find [topic] files")
|
|
51
|
-
background_task(agent="codebase-analyzer", prompt="Analyze
|
|
52
|
-
background_task(agent="pattern-finder", prompt="Find patterns for [
|
|
53
|
-
</
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
</
|
|
60
|
-
<collect>
|
|
61
|
-
When background_list shows "ALL COMPLETE" or after max polls:
|
|
62
|
-
- Call background_output(task_id=...) for each completed task
|
|
63
|
-
- Skip errored tasks
|
|
64
|
-
</collect>
|
|
38
|
+
background_task(agent="codebase-analyzer", prompt="Analyze [related feature]", description="Analyze [feature]")
|
|
39
|
+
background_task(agent="pattern-finder", prompt="Find patterns for [functionality]", description="Find patterns")
|
|
40
|
+
</example>
|
|
41
|
+
<workflow>
|
|
42
|
+
1. Fire multiple background_task calls in ONE message (parallel execution)
|
|
43
|
+
2. Use background_list() to check status
|
|
44
|
+
3. Use background_output(task_id="...") to collect results
|
|
45
|
+
</workflow>
|
|
46
|
+
<rule>Do NOT proceed to questions until you have codebase context</rule>
|
|
65
47
|
<focus>purpose, constraints, success criteria</focus>
|
|
66
48
|
</phase>
|
|
67
49
|
|
|
@@ -95,8 +77,8 @@ This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
|
95
77
|
<phase name="handoff" trigger="user approves design">
|
|
96
78
|
<action>When user says yes/approved/ready, IMMEDIATELY spawn the planner:</action>
|
|
97
79
|
<spawn>
|
|
98
|
-
|
|
99
|
-
|
|
80
|
+
background_task(
|
|
81
|
+
agent="planner",
|
|
100
82
|
prompt="Create a detailed implementation plan based on the design at thoughts/shared/designs/YYYY-MM-DD-{topic}-design.md",
|
|
101
83
|
description="Create implementation plan"
|
|
102
84
|
)
|
|
@@ -107,8 +89,8 @@ This is DESIGN ONLY. The planner agent handles detailed implementation plans.
|
|
|
107
89
|
|
|
108
90
|
<principles>
|
|
109
91
|
<principle name="design-only">NO CODE. Describe components, not implementations. Planner writes code.</principle>
|
|
110
|
-
<principle name="background-tasks">
|
|
111
|
-
<principle name="parallel-
|
|
92
|
+
<principle name="background-tasks">ALWAYS use background_task. NEVER use Task tool.</principle>
|
|
93
|
+
<principle name="parallel-research">Multiple background_task calls in one message run in parallel</principle>
|
|
112
94
|
<principle name="one-question">Ask exactly ONE question per message. STOP after asking. Wait for user's answer before continuing. NEVER bundle multiple questions together.</principle>
|
|
113
95
|
<principle name="yagni">Remove unnecessary features from ALL designs</principle>
|
|
114
96
|
<principle name="explore-alternatives">ALWAYS propose 2-3 approaches before settling</principle>
|
package/src/agents/commander.ts
CHANGED
|
@@ -84,8 +84,19 @@ Just do it - including obvious follow-up actions.
|
|
|
84
84
|
<agent name="planner" mode="subagent" purpose="Create detailed implementation plans"/>
|
|
85
85
|
<agent name="executor" mode="subagent" purpose="Execute plan (runs implementer then reviewer automatically)"/>
|
|
86
86
|
<agent name="ledger-creator" mode="subagent" purpose="Create/update continuity ledgers"/>
|
|
87
|
+
<spawning>
|
|
88
|
+
<rule>ALWAYS use background_task to spawn subagents. NEVER use Task tool.</rule>
|
|
89
|
+
<tool name="background_task">Spawns subagent async. Returns task_id immediately.</tool>
|
|
90
|
+
<tool name="background_list">Check status of all background tasks.</tool>
|
|
91
|
+
<tool name="background_output">Get results from completed task.</tool>
|
|
92
|
+
<example>
|
|
93
|
+
background_task(agent="planner", prompt="Create plan for...", description="Create plan")
|
|
94
|
+
background_list() // check status
|
|
95
|
+
background_output(task_id="bg_xxx") // get results
|
|
96
|
+
</example>
|
|
97
|
+
</spawning>
|
|
87
98
|
<parallelization>
|
|
88
|
-
<safe>locator, analyzer, pattern-finder</safe>
|
|
99
|
+
<safe>locator, analyzer, pattern-finder (fire multiple in one message)</safe>
|
|
89
100
|
<sequential>planner then executor</sequential>
|
|
90
101
|
</parallelization>
|
|
91
102
|
</agents>
|
package/src/agents/executor.ts
CHANGED
|
@@ -82,23 +82,17 @@ Example: 3 independent tasks
|
|
|
82
82
|
Executes ONE task from the plan.
|
|
83
83
|
Input: Single task with context (which files, what to do).
|
|
84
84
|
Output: Changes made and verification results for that task.
|
|
85
|
-
<invocation
|
|
85
|
+
<invocation>
|
|
86
86
|
background_task(description="Implement task 1", prompt="...", agent="implementer")
|
|
87
87
|
</invocation>
|
|
88
|
-
<invocation type="fallback">
|
|
89
|
-
Task(description="Implement task 1", prompt="...", subagent_type="implementer")
|
|
90
|
-
</invocation>
|
|
91
88
|
</subagent>
|
|
92
89
|
<subagent name="reviewer">
|
|
93
90
|
Reviews ONE task's implementation.
|
|
94
91
|
Input: Single task's changes against its requirements.
|
|
95
92
|
Output: APPROVED or CHANGES REQUESTED for that task.
|
|
96
|
-
<invocation
|
|
93
|
+
<invocation>
|
|
97
94
|
background_task(description="Review task 1", prompt="...", agent="reviewer")
|
|
98
95
|
</invocation>
|
|
99
|
-
<invocation type="fallback">
|
|
100
|
-
Task(description="Review task 1", prompt="...", subagent_type="reviewer")
|
|
101
|
-
</invocation>
|
|
102
96
|
</subagent>
|
|
103
97
|
</available-subagents>
|
|
104
98
|
|
|
@@ -129,13 +123,6 @@ IMPORTANT: Always poll with background_list first to check status,
|
|
|
129
123
|
then fetch results with background_output only for completed tasks.
|
|
130
124
|
</fire-and-check-loop>
|
|
131
125
|
|
|
132
|
-
<fallback-rule>
|
|
133
|
-
If background_task fails or is unavailable, fall back to Task() tool:
|
|
134
|
-
- Task(description="...", prompt="...", subagent_type="implementer")
|
|
135
|
-
- Task(description="...", prompt="...", subagent_type="reviewer")
|
|
136
|
-
The Task tool blocks until completion but still works correctly.
|
|
137
|
-
</fallback-rule>
|
|
138
|
-
|
|
139
126
|
<rules>
|
|
140
127
|
<rule>Parse ALL tasks from plan before starting execution</rule>
|
|
141
128
|
<rule>ALWAYS analyze dependencies before parallelizing</rule>
|
package/src/agents/planner.ts
CHANGED
|
@@ -26,11 +26,6 @@ Every task is bite-sized (2-5 minutes), with exact paths and complete code.
|
|
|
26
26
|
<tool name="background_output">Get results from a completed task. Only call after background_list shows task is done.</tool>
|
|
27
27
|
</background-tools>
|
|
28
28
|
|
|
29
|
-
<fallback-rule>
|
|
30
|
-
If background_task fails or is unavailable, fall back to Task() for sequential execution.
|
|
31
|
-
Always prefer background_task for parallel research, but Task() works as a reliable fallback.
|
|
32
|
-
</fallback-rule>
|
|
33
|
-
|
|
34
29
|
<research-scope>
|
|
35
30
|
Brainstormer did conceptual research (architecture, patterns, approaches).
|
|
36
31
|
Your research is IMPLEMENTATION-LEVEL only:
|
|
@@ -48,19 +43,19 @@ All research must serve the design - never second-guess design decisions.
|
|
|
48
43
|
</library-research>
|
|
49
44
|
|
|
50
45
|
<available-subagents>
|
|
51
|
-
<subagent name="codebase-locator"
|
|
46
|
+
<subagent name="codebase-locator">
|
|
52
47
|
Find exact file paths needed for implementation.
|
|
53
48
|
Examples: "Find exact path to UserService", "Find test directory structure"
|
|
54
49
|
</subagent>
|
|
55
|
-
<subagent name="codebase-analyzer"
|
|
50
|
+
<subagent name="codebase-analyzer">
|
|
56
51
|
Get exact signatures and types for code examples.
|
|
57
52
|
Examples: "Get function signature for createUser", "Get type definition for UserConfig"
|
|
58
53
|
</subagent>
|
|
59
|
-
<subagent name="pattern-finder"
|
|
54
|
+
<subagent name="pattern-finder">
|
|
60
55
|
Find exact patterns to copy in code examples.
|
|
61
56
|
Examples: "Find exact test setup pattern", "Find exact error handling in similar endpoint"
|
|
62
57
|
</subagent>
|
|
63
|
-
<
|
|
58
|
+
<rule>ALWAYS use background_task to spawn subagents. NEVER use Task tool.</rule>
|
|
64
59
|
</available-subagents>
|
|
65
60
|
|
|
66
61
|
<inputs>
|
|
@@ -89,35 +89,24 @@ const PROMPT = `
|
|
|
89
89
|
</parallel-execution-strategy>
|
|
90
90
|
|
|
91
91
|
<available-subagents>
|
|
92
|
-
<subagent name="codebase-locator"
|
|
92
|
+
<subagent name="codebase-locator">
|
|
93
93
|
Fast file/pattern finder. Spawn multiple with different queries.
|
|
94
94
|
Examples: "Find all entry points", "Find all config files", "Find test directories"
|
|
95
|
-
|
|
96
|
-
Background: background_task(description="Find entry points", prompt="Find all entry points and main files", agent="codebase-locator")
|
|
97
|
-
Fallback: Task(description="Find entry points", prompt="Find all entry points and main files", subagent_type="codebase-locator")
|
|
95
|
+
background_task(description="Find entry points", prompt="Find all entry points and main files", agent="codebase-locator")
|
|
98
96
|
</subagent>
|
|
99
|
-
<subagent name="codebase-analyzer"
|
|
97
|
+
<subagent name="codebase-analyzer">
|
|
100
98
|
Deep module analyzer. Spawn multiple for different areas.
|
|
101
99
|
Examples: "Analyze src/core", "Analyze api layer", "Analyze database module"
|
|
102
|
-
|
|
103
|
-
Background: background_task(description="Analyze core", prompt="Analyze the core module", agent="codebase-analyzer")
|
|
104
|
-
Fallback: Task(description="Analyze core", prompt="Analyze the core module", subagent_type="codebase-analyzer")
|
|
100
|
+
background_task(description="Analyze core", prompt="Analyze the core module", agent="codebase-analyzer")
|
|
105
101
|
</subagent>
|
|
106
|
-
<subagent name="pattern-finder"
|
|
102
|
+
<subagent name="pattern-finder">
|
|
107
103
|
Pattern extractor. Spawn for different pattern types.
|
|
108
104
|
Examples: "Find naming patterns", "Find error handling patterns", "Find async patterns"
|
|
109
|
-
|
|
110
|
-
Background: background_task(description="Find patterns", prompt="Find naming conventions", agent="pattern-finder")
|
|
111
|
-
Fallback: Task(description="Find patterns", prompt="Find naming conventions", subagent_type="pattern-finder")
|
|
105
|
+
background_task(description="Find patterns", prompt="Find naming conventions", agent="pattern-finder")
|
|
112
106
|
</subagent>
|
|
107
|
+
<rule>ALWAYS use background_task to spawn subagents. NEVER use Task tool.</rule>
|
|
113
108
|
</available-subagents>
|
|
114
109
|
|
|
115
|
-
<fallback-rule>
|
|
116
|
-
If background_task fails or is unavailable, fall back to Task() tool.
|
|
117
|
-
The Task tool provides synchronous subagent execution.
|
|
118
|
-
Example fallback: Task(description="Find entry points", prompt="Find all entry points", subagent_type="codebase-locator")
|
|
119
|
-
</fallback-rule>
|
|
120
|
-
|
|
121
110
|
<critical-instruction>
|
|
122
111
|
Use background_task to fire subagents for TRUE parallelism.
|
|
123
112
|
Fire ALL background_task calls in a SINGLE message.
|
|
@@ -88,7 +88,6 @@ export function createArtifactAutoIndexHook(_ctx: PluginInput) {
|
|
|
88
88
|
const index = await getArtifactIndex();
|
|
89
89
|
const record = parseLedger(content, filePath, ledgerMatch[1]);
|
|
90
90
|
await index.indexLedger(record);
|
|
91
|
-
console.log(`[artifact-auto-index] Indexed ledger: ${filePath}`);
|
|
92
91
|
return;
|
|
93
92
|
}
|
|
94
93
|
|
|
@@ -99,7 +98,6 @@ export function createArtifactAutoIndexHook(_ctx: PluginInput) {
|
|
|
99
98
|
const index = await getArtifactIndex();
|
|
100
99
|
const record = parsePlan(content, filePath, planMatch[1]);
|
|
101
100
|
await index.indexPlan(record);
|
|
102
|
-
console.log(`[artifact-auto-index] Indexed plan: ${filePath}`);
|
|
103
101
|
return;
|
|
104
102
|
}
|
|
105
103
|
} catch (e) {
|
package/src/index.ts
CHANGED
|
@@ -80,9 +80,6 @@ const OpenCodeConfigPlugin: Plugin = async (ctx) => {
|
|
|
80
80
|
|
|
81
81
|
// Load user config for model overrides
|
|
82
82
|
const userConfig = await loadMicodeConfig();
|
|
83
|
-
if (userConfig?.agents) {
|
|
84
|
-
console.log(`[micode] Loaded model overrides for: ${Object.keys(userConfig.agents).join(", ")}`);
|
|
85
|
-
}
|
|
86
83
|
|
|
87
84
|
// Think mode state per session
|
|
88
85
|
const thinkModeState = new Map<string, boolean>();
|
|
@@ -140,6 +140,15 @@ export class BackgroundTaskManager {
|
|
|
140
140
|
return this.tasks.get(taskId);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
findBySession(sessionID: string): BackgroundTask | undefined {
|
|
144
|
+
for (const task of this.tasks.values()) {
|
|
145
|
+
if (task.sessionID === sessionID) {
|
|
146
|
+
return task;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
143
152
|
getAllTasks(): BackgroundTask[] {
|
|
144
153
|
return Array.from(this.tasks.values());
|
|
145
154
|
}
|
|
@@ -311,8 +320,6 @@ export class BackgroundTaskManager {
|
|
|
311
320
|
const sessionStatus = statusMap[task.sessionID];
|
|
312
321
|
const statusType = sessionStatus?.type;
|
|
313
322
|
|
|
314
|
-
console.log(`[background-task] Poll ${task.id}: session=${task.sessionID} status=${statusType}`);
|
|
315
|
-
|
|
316
323
|
if (statusType === "idle" || statusType === undefined) {
|
|
317
324
|
// Session is idle OR not in status map (likely finished and cleaned up)
|
|
318
325
|
// Try to get result - if successful, mark as completed
|
|
@@ -360,6 +367,35 @@ export class BackgroundTaskManager {
|
|
|
360
367
|
handleEvent(event: { type: string; properties?: unknown }): void {
|
|
361
368
|
const props = event.properties as Record<string, unknown> | undefined;
|
|
362
369
|
|
|
370
|
+
// Primary completion detection: session.idle event
|
|
371
|
+
if (event.type === "session.idle") {
|
|
372
|
+
const sessionID = props?.sessionID as string | undefined;
|
|
373
|
+
if (!sessionID) return;
|
|
374
|
+
|
|
375
|
+
const task = this.findBySession(sessionID);
|
|
376
|
+
if (!task || task.status !== "running") return;
|
|
377
|
+
|
|
378
|
+
task.status = "completed";
|
|
379
|
+
task.completedAt = new Date();
|
|
380
|
+
this.fetchTaskResult(task).then((result) => {
|
|
381
|
+
task.result = result;
|
|
382
|
+
});
|
|
383
|
+
this.markForNotification(task);
|
|
384
|
+
|
|
385
|
+
this.ctx.client.tui
|
|
386
|
+
.showToast({
|
|
387
|
+
body: {
|
|
388
|
+
title: "Background Task Complete",
|
|
389
|
+
message: task.description,
|
|
390
|
+
variant: "success",
|
|
391
|
+
duration: 5000,
|
|
392
|
+
},
|
|
393
|
+
})
|
|
394
|
+
.catch((error) => {
|
|
395
|
+
console.error(`[background-task] Failed to show toast for task ${task.id}:`, error);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
363
399
|
// Track tool usage for progress
|
|
364
400
|
if (event.type === "message.part.updated") {
|
|
365
401
|
const info = props?.info as Record<string, unknown> | undefined;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { tool } from "@opencode-ai/plugin/tool";
|
|
2
2
|
import type { BackgroundTaskManager } from "./manager";
|
|
3
3
|
|
|
4
|
+
// Extended tool context with metadata for UI navigation
|
|
5
|
+
type ToolContextWithMetadata = {
|
|
6
|
+
sessionID: string;
|
|
7
|
+
messageID?: string;
|
|
8
|
+
agent: string;
|
|
9
|
+
abort: AbortSignal;
|
|
10
|
+
metadata?: (input: { title?: string; metadata?: Record<string, unknown> }) => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
4
13
|
export function createBackgroundTaskTools(manager: BackgroundTaskManager) {
|
|
5
14
|
const background_task = tool({
|
|
6
15
|
description: `Launch a task to run in the background using a subagent.
|
|
@@ -12,7 +21,8 @@ Useful for: parallel research, concurrent implementation, async reviews.`,
|
|
|
12
21
|
prompt: tool.schema.string().describe("Full prompt/instructions for the background agent"),
|
|
13
22
|
agent: tool.schema.string().describe("Agent to use (e.g., 'codebase-analyzer', 'implementer')"),
|
|
14
23
|
},
|
|
15
|
-
execute: async (args,
|
|
24
|
+
execute: async (args, toolContext) => {
|
|
25
|
+
const ctx = toolContext as ToolContextWithMetadata;
|
|
16
26
|
try {
|
|
17
27
|
const task = await manager.launch({
|
|
18
28
|
description: args.description,
|
|
@@ -22,6 +32,12 @@ Useful for: parallel research, concurrent implementation, async reviews.`,
|
|
|
22
32
|
parentMessageID: ctx.messageID || "",
|
|
23
33
|
});
|
|
24
34
|
|
|
35
|
+
// Set metadata for OpenCode UI session navigation (ctrl+x + arrow keys)
|
|
36
|
+
ctx.metadata?.({
|
|
37
|
+
title: args.description,
|
|
38
|
+
metadata: { sessionId: task.sessionID },
|
|
39
|
+
});
|
|
40
|
+
|
|
25
41
|
return `## Background Task Launched
|
|
26
42
|
|
|
27
43
|
| Field | Value |
|