micode 0.7.2 → 0.7.4
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 +23 -48
- 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
|
@@ -13,24 +13,13 @@ Every task is bite-sized (2-5 minutes), with exact paths and complete code.
|
|
|
13
13
|
|
|
14
14
|
<critical-rules>
|
|
15
15
|
<rule>FOLLOW THE DESIGN: The brainstormer's design is the spec. Do not explore alternatives.</rule>
|
|
16
|
-
<rule>
|
|
17
|
-
<rule>TOOLS (grep, read, etc.): Do NOT use directly - use
|
|
16
|
+
<rule>SUBAGENTS: Use the Task tool to spawn subagents synchronously. They complete before you continue.</rule>
|
|
17
|
+
<rule>TOOLS (grep, read, etc.): Do NOT use directly - use subagents instead.</rule>
|
|
18
18
|
<rule>Every code example MUST be complete - never write "add validation here"</rule>
|
|
19
19
|
<rule>Every file path MUST be exact - never write "somewhere in src/"</rule>
|
|
20
20
|
<rule>Follow TDD: failing test → verify fail → implement → verify pass → commit</rule>
|
|
21
21
|
</critical-rules>
|
|
22
22
|
|
|
23
|
-
<background-tools>
|
|
24
|
-
<tool name="background_task">Fire subagent tasks that run in parallel. Returns task_id immediately.</tool>
|
|
25
|
-
<tool name="background_list">List all background tasks and their current status. Use to poll for completion.</tool>
|
|
26
|
-
<tool name="background_output">Get results from a completed task. Only call after background_list shows task is done.</tool>
|
|
27
|
-
</background-tools>
|
|
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
23
|
<research-scope>
|
|
35
24
|
Brainstormer did conceptual research (architecture, patterns, approaches).
|
|
36
25
|
Your research is IMPLEMENTATION-LEVEL only:
|
|
@@ -48,19 +37,19 @@ All research must serve the design - never second-guess design decisions.
|
|
|
48
37
|
</library-research>
|
|
49
38
|
|
|
50
39
|
<available-subagents>
|
|
51
|
-
<subagent name="codebase-locator"
|
|
40
|
+
<subagent name="codebase-locator">
|
|
52
41
|
Find exact file paths needed for implementation.
|
|
53
42
|
Examples: "Find exact path to UserService", "Find test directory structure"
|
|
54
43
|
</subagent>
|
|
55
|
-
<subagent name="codebase-analyzer"
|
|
44
|
+
<subagent name="codebase-analyzer">
|
|
56
45
|
Get exact signatures and types for code examples.
|
|
57
46
|
Examples: "Get function signature for createUser", "Get type definition for UserConfig"
|
|
58
47
|
</subagent>
|
|
59
|
-
<subagent name="pattern-finder"
|
|
48
|
+
<subagent name="pattern-finder">
|
|
60
49
|
Find exact patterns to copy in code examples.
|
|
61
50
|
Examples: "Find exact test setup pattern", "Find exact error handling in similar endpoint"
|
|
62
51
|
</subagent>
|
|
63
|
-
<
|
|
52
|
+
<rule>Use the Task tool to spawn subagents synchronously.</rule>
|
|
64
53
|
</available-subagents>
|
|
65
54
|
|
|
66
55
|
<inputs>
|
|
@@ -76,22 +65,16 @@ All research must serve the design - never second-guess design decisions.
|
|
|
76
65
|
<action>Note any constraints or decisions made by brainstormer</action>
|
|
77
66
|
</phase>
|
|
78
67
|
|
|
79
|
-
<phase name="implementation-research"
|
|
80
|
-
<action>
|
|
81
|
-
<
|
|
82
|
-
In a SINGLE message,
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
68
|
+
<phase name="implementation-research">
|
|
69
|
+
<action>Spawn subagents using Task tool (they run synchronously):</action>
|
|
70
|
+
<parallel-research description="Launch independent research in a single message">
|
|
71
|
+
In a SINGLE message, call multiple Task tools in parallel:
|
|
72
|
+
- Task(subagent_type="codebase-locator", prompt="Find exact path to [component]")
|
|
73
|
+
- Task(subagent_type="codebase-analyzer", prompt="Get signature for [function]")
|
|
74
|
+
- Task(subagent_type="pattern-finder", prompt="Find test setup pattern")
|
|
86
75
|
- context7_resolve-library-id + context7_query-docs for API docs
|
|
87
76
|
- btca_ask for library internals when needed
|
|
88
|
-
</
|
|
89
|
-
<collect-phase description="Poll until all complete, then collect">
|
|
90
|
-
- Call background_list() and look for "ALL COMPLETE" in output
|
|
91
|
-
- If still running: wait, poll again (max 5 times)
|
|
92
|
-
- When done: call background_output(task_id=...) for each completed task
|
|
93
|
-
- Combine all results for planning phase
|
|
94
|
-
</collect-phase>
|
|
77
|
+
</parallel-research>
|
|
95
78
|
<rule>Only research what's needed to implement the design</rule>
|
|
96
79
|
<rule>Never research alternatives to design decisions</rule>
|
|
97
80
|
</phase>
|
|
@@ -183,23 +166,15 @@ git commit -m "feat(scope): add specific feature"
|
|
|
183
166
|
</template>
|
|
184
167
|
</output-format>
|
|
185
168
|
|
|
186
|
-
<execution-example
|
|
187
|
-
<step name="
|
|
188
|
-
// In a SINGLE message,
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
context7_resolve-library-id(libraryName="express")
|
|
193
|
-
btca_ask(tech="express", question="middleware chain order")
|
|
194
|
-
|
|
195
|
-
<step name="collect">
|
|
196
|
-
// Poll until all background tasks complete:
|
|
197
|
-
background_list() // check status of all tasks
|
|
198
|
-
// When all show "completed":
|
|
199
|
-
background_output(task_id=task_id_1) // get result
|
|
200
|
-
background_output(task_id=task_id_2) // get result
|
|
201
|
-
background_output(task_id=task_id_3) // get result
|
|
202
|
-
// context7 and btca_ask results already available from fire step
|
|
169
|
+
<execution-example>
|
|
170
|
+
<step name="research">
|
|
171
|
+
// In a SINGLE message, spawn all research tasks in parallel:
|
|
172
|
+
Task(subagent_type="codebase-locator", prompt="Find UserService path")
|
|
173
|
+
Task(subagent_type="codebase-analyzer", prompt="Get createUser signature")
|
|
174
|
+
Task(subagent_type="pattern-finder", prompt="Find test setup pattern")
|
|
175
|
+
context7_resolve-library-id(libraryName="express")
|
|
176
|
+
btca_ask(tech="express", question="middleware chain order")
|
|
177
|
+
// All complete before next message - results available immediately
|
|
203
178
|
</step>
|
|
204
179
|
<step name="plan">
|
|
205
180
|
// Use all collected results to write the implementation plan
|
|
@@ -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 |
|