mcp-subagents-opencode 1.0.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/LICENSE +21 -0
- package/README.md +602 -0
- package/build/config/timeouts.d.ts +9 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +18 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/helpers.d.ts +6 -0
- package/build/helpers.d.ts.map +1 -0
- package/build/helpers.js +47 -0
- package/build/helpers.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +245 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +32 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +58 -0
- package/build/models.js.map +1 -0
- package/build/server/register-notifications.d.ts +3 -0
- package/build/server/register-notifications.d.ts.map +1 -0
- package/build/server/register-notifications.js +77 -0
- package/build/server/register-notifications.js.map +1 -0
- package/build/server/register-resources.d.ts +3 -0
- package/build/server/register-resources.d.ts.map +1 -0
- package/build/server/register-resources.js +210 -0
- package/build/server/register-resources.js.map +1 -0
- package/build/server/register-retry-execution.d.ts +2 -0
- package/build/server/register-retry-execution.d.ts.map +1 -0
- package/build/server/register-retry-execution.js +28 -0
- package/build/server/register-retry-execution.js.map +1 -0
- package/build/server/register-tasks.d.ts +3 -0
- package/build/server/register-tasks.d.ts.map +1 -0
- package/build/server/register-tasks.js +52 -0
- package/build/server/register-tasks.js.map +1 -0
- package/build/server/register-tools.d.ts +3 -0
- package/build/server/register-tools.d.ts.map +1 -0
- package/build/server/register-tools.js +32 -0
- package/build/server/register-tools.js.map +1 -0
- package/build/server/resource-helpers.d.ts +21 -0
- package/build/server/resource-helpers.d.ts.map +1 -0
- package/build/server/resource-helpers.js +84 -0
- package/build/server/resource-helpers.js.map +1 -0
- package/build/services/account-manager.d.ts +88 -0
- package/build/services/account-manager.d.ts.map +1 -0
- package/build/services/account-manager.js +239 -0
- package/build/services/account-manager.js.map +1 -0
- package/build/services/claude-code-runner.d.ts +15 -0
- package/build/services/claude-code-runner.d.ts.map +1 -0
- package/build/services/claude-code-runner.js +475 -0
- package/build/services/claude-code-runner.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/exhaustion-fallback.d.ts +27 -0
- package/build/services/exhaustion-fallback.d.ts.map +1 -0
- package/build/services/exhaustion-fallback.js +30 -0
- package/build/services/exhaustion-fallback.js.map +1 -0
- package/build/services/fallback-orchestrator.d.ts +16 -0
- package/build/services/fallback-orchestrator.d.ts.map +1 -0
- package/build/services/fallback-orchestrator.js +48 -0
- package/build/services/fallback-orchestrator.js.map +1 -0
- package/build/services/opencode-client.d.ts +40 -0
- package/build/services/opencode-client.d.ts.map +1 -0
- package/build/services/opencode-client.js +147 -0
- package/build/services/opencode-client.js.map +1 -0
- package/build/services/opencode-spawner.d.ts +56 -0
- package/build/services/opencode-spawner.d.ts.map +1 -0
- package/build/services/opencode-spawner.js +426 -0
- package/build/services/opencode-spawner.js.map +1 -0
- package/build/services/output-file.d.ts +24 -0
- package/build/services/output-file.d.ts.map +1 -0
- package/build/services/output-file.js +90 -0
- package/build/services/output-file.js.map +1 -0
- package/build/services/progress-registry.d.ts +12 -0
- package/build/services/progress-registry.d.ts.map +1 -0
- package/build/services/progress-registry.js +97 -0
- package/build/services/progress-registry.js.map +1 -0
- package/build/services/question-registry.d.ts +79 -0
- package/build/services/question-registry.d.ts.map +1 -0
- package/build/services/question-registry.js +249 -0
- package/build/services/question-registry.js.map +1 -0
- package/build/services/retry-queue.d.ts +41 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +195 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/sdk-client-manager.d.ts +149 -0
- package/build/services/sdk-client-manager.d.ts.map +1 -0
- package/build/services/sdk-client-manager.js +632 -0
- package/build/services/sdk-client-manager.js.map +1 -0
- package/build/services/sdk-session-adapter.d.ts +203 -0
- package/build/services/sdk-session-adapter.d.ts.map +1 -0
- package/build/services/sdk-session-adapter.js +1088 -0
- package/build/services/sdk-session-adapter.js.map +1 -0
- package/build/services/sdk-spawner.d.ts +42 -0
- package/build/services/sdk-spawner.d.ts.map +1 -0
- package/build/services/sdk-spawner.js +488 -0
- package/build/services/sdk-spawner.js.map +1 -0
- package/build/services/session-hooks.d.ts +24 -0
- package/build/services/session-hooks.d.ts.map +1 -0
- package/build/services/session-hooks.js +130 -0
- package/build/services/session-hooks.js.map +1 -0
- package/build/services/session-snapshot.d.ts +19 -0
- package/build/services/session-snapshot.d.ts.map +1 -0
- package/build/services/session-snapshot.js +203 -0
- package/build/services/session-snapshot.js.map +1 -0
- package/build/services/subscription-registry.d.ts +12 -0
- package/build/services/subscription-registry.d.ts.map +1 -0
- package/build/services/subscription-registry.js +27 -0
- package/build/services/subscription-registry.js.map +1 -0
- package/build/services/task-manager.d.ts +150 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +765 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +159 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/services/task-status-mapper.d.ts +21 -0
- package/build/services/task-status-mapper.d.ts.map +1 -0
- package/build/services/task-status-mapper.js +171 -0
- package/build/services/task-status-mapper.js.map +1 -0
- package/build/templates/index.d.ts +22 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +147 -0
- package/build/templates/index.js.map +1 -0
- package/build/templates/overlays/coder-csharp.mdx +58 -0
- package/build/templates/overlays/coder-go.mdx +53 -0
- package/build/templates/overlays/coder-java.mdx +54 -0
- package/build/templates/overlays/coder-kotlin.mdx +56 -0
- package/build/templates/overlays/coder-nextjs.mdx +65 -0
- package/build/templates/overlays/coder-python.mdx +53 -0
- package/build/templates/overlays/coder-react.mdx +55 -0
- package/build/templates/overlays/coder-ruby.mdx +59 -0
- package/build/templates/overlays/coder-rust.mdx +48 -0
- package/build/templates/overlays/coder-supabase.mdx +268 -0
- package/build/templates/overlays/coder-supastarter.mdx +313 -0
- package/build/templates/overlays/coder-swift.mdx +56 -0
- package/build/templates/overlays/coder-tauri.mdx +566 -0
- package/build/templates/overlays/coder-triggerdev.mdx +296 -0
- package/build/templates/overlays/coder-typescript.mdx +45 -0
- package/build/templates/overlays/coder-vue.mdx +62 -0
- package/build/templates/overlays/planner-architecture.mdx +78 -0
- package/build/templates/overlays/planner-bugfix.mdx +36 -0
- package/build/templates/overlays/planner-feature.mdx +38 -0
- package/build/templates/overlays/planner-migration.mdx +50 -0
- package/build/templates/overlays/planner-refactor.mdx +57 -0
- package/build/templates/overlays/researcher-library.mdx +59 -0
- package/build/templates/overlays/researcher-performance.mdx +68 -0
- package/build/templates/overlays/researcher-security.mdx +86 -0
- package/build/templates/overlays/tester-graphql.mdx +191 -0
- package/build/templates/overlays/tester-playwright.mdx +621 -0
- package/build/templates/overlays/tester-rest.mdx +101 -0
- package/build/templates/overlays/tester-suite.mdx +177 -0
- package/build/templates/super-coder.mdx +529 -0
- package/build/templates/super-planner.mdx +568 -0
- package/build/templates/super-researcher.mdx +406 -0
- package/build/templates/super-tester.mdx +243 -0
- package/build/tools/answer-question.d.ts +30 -0
- package/build/tools/answer-question.d.ts.map +1 -0
- package/build/tools/answer-question.js +108 -0
- package/build/tools/answer-question.js.map +1 -0
- package/build/tools/cancel-task.d.ts +44 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +144 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/send-message.d.ts +39 -0
- package/build/tools/send-message.d.ts.map +1 -0
- package/build/tools/send-message.js +124 -0
- package/build/tools/send-message.js.map +1 -0
- package/build/tools/shared-spawn.d.ts +56 -0
- package/build/tools/shared-spawn.d.ts.map +1 -0
- package/build/tools/shared-spawn.js +114 -0
- package/build/tools/shared-spawn.js.map +1 -0
- package/build/tools/spawn-agent.d.ts +85 -0
- package/build/tools/spawn-agent.d.ts.map +1 -0
- package/build/tools/spawn-agent.js +133 -0
- package/build/tools/spawn-agent.js.map +1 -0
- package/build/tools/spawn-coder.d.ts +70 -0
- package/build/tools/spawn-coder.d.ts.map +1 -0
- package/build/tools/spawn-coder.js +71 -0
- package/build/tools/spawn-coder.js.map +1 -0
- package/build/tools/spawn-planner.d.ts +70 -0
- package/build/tools/spawn-planner.d.ts.map +1 -0
- package/build/tools/spawn-planner.js +71 -0
- package/build/tools/spawn-planner.js.map +1 -0
- package/build/tools/spawn-researcher.d.ts +70 -0
- package/build/tools/spawn-researcher.d.ts.map +1 -0
- package/build/tools/spawn-researcher.js +70 -0
- package/build/tools/spawn-researcher.js.map +1 -0
- package/build/tools/spawn-task.d.ts +74 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +107 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/spawn-tester.d.ts +70 -0
- package/build/tools/spawn-tester.d.ts.map +1 -0
- package/build/tools/spawn-tester.js +69 -0
- package/build/tools/spawn-tester.js.map +1 -0
- package/build/types.d.ts +101 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +28 -0
- package/build/types.js.map +1 -0
- package/build/utils/brief-validator.d.ts +30 -0
- package/build/utils/brief-validator.d.ts.map +1 -0
- package/build/utils/brief-validator.js +254 -0
- package/build/utils/brief-validator.js.map +1 -0
- package/build/utils/format.d.ts +34 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +55 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +240 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +89 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Spawner - Spawns and manages tasks using the OpenCode headless server HTTP API.
|
|
3
|
+
*
|
|
4
|
+
* OpenCode Spawner - Spawns and manages tasks using the OpenCode headless server HTTP API.
|
|
5
|
+
*
|
|
6
|
+
* Uses the OpenCode HTTP API to:
|
|
7
|
+
* - Create sessions
|
|
8
|
+
* - Send messages/prompts
|
|
9
|
+
* - Poll for completion
|
|
10
|
+
* - Get results
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync } from 'fs';
|
|
13
|
+
import { taskManager } from './task-manager.js';
|
|
14
|
+
import { clientContext } from './client-context.js';
|
|
15
|
+
import { resolveModel } from '../models.js';
|
|
16
|
+
import { createRetryInfo } from './retry-queue.js';
|
|
17
|
+
import { TASK_TIMEOUT_DEFAULT_MS } from '../config/timeouts.js';
|
|
18
|
+
import { TaskStatus, isTerminalStatus } from '../types.js';
|
|
19
|
+
import { resolveSessionStatus, formatMessageResponse } from '../helpers.js';
|
|
20
|
+
const SESSION_POLL_INTERVAL_MS = 3000;
|
|
21
|
+
/** Reference to the shared OpenCodeClient, set during init. */
|
|
22
|
+
let openCodeClient = null;
|
|
23
|
+
/** Active polling abort controllers, keyed by taskId. */
|
|
24
|
+
const activePollers = new Map();
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the spawner with the OpenCode client instance.
|
|
27
|
+
*/
|
|
28
|
+
export function initSpawner(client) {
|
|
29
|
+
openCodeClient = client;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the shared client (throws if not initialized).
|
|
33
|
+
*/
|
|
34
|
+
function getClient() {
|
|
35
|
+
if (!openCodeClient) {
|
|
36
|
+
throw new Error('[opencode-spawner] Client not initialized. Call initSpawner() first.');
|
|
37
|
+
}
|
|
38
|
+
return openCodeClient;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Sleep utility.
|
|
42
|
+
*/
|
|
43
|
+
function sleep(ms) {
|
|
44
|
+
return new Promise(r => setTimeout(r, ms));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Spawn a new task using the OpenCode headless server.
|
|
48
|
+
*/
|
|
49
|
+
export async function spawnOpenCodeTask(options) {
|
|
50
|
+
const prompt = options.prompt?.trim() || '';
|
|
51
|
+
const cwd = options.cwd && existsSync(options.cwd)
|
|
52
|
+
? options.cwd
|
|
53
|
+
: clientContext.getDefaultCwd();
|
|
54
|
+
const model = resolveModel(options.model, options.taskType);
|
|
55
|
+
const task = taskManager.createTask(prompt, cwd, model, {
|
|
56
|
+
autonomous: options.autonomous ?? true,
|
|
57
|
+
isResume: !!options.resumeSessionId,
|
|
58
|
+
retryInfo: options.retryInfo,
|
|
59
|
+
dependsOn: options.dependsOn,
|
|
60
|
+
labels: options.labels,
|
|
61
|
+
provider: 'opencode',
|
|
62
|
+
fallbackAttempted: options.fallbackAttempted,
|
|
63
|
+
switchAttempted: options.switchAttempted,
|
|
64
|
+
timeout: options.timeout,
|
|
65
|
+
});
|
|
66
|
+
// If task is waiting for dependencies, don't start execution yet
|
|
67
|
+
if (task.status === TaskStatus.WAITING) {
|
|
68
|
+
console.error(`[opencode-spawner] Task ${task.id} waiting for dependencies: ${task.dependsOn?.join(', ')}`);
|
|
69
|
+
return task.id;
|
|
70
|
+
}
|
|
71
|
+
// Execute the task asynchronously
|
|
72
|
+
setImmediate(() => {
|
|
73
|
+
runOpenCodeSession(task.id, prompt, cwd, model, options).catch((err) => {
|
|
74
|
+
console.error(`[opencode-spawner] Task ${task.id} execution error:`, err);
|
|
75
|
+
const currentTask = taskManager.getTask(task.id);
|
|
76
|
+
if (currentTask && !isTerminalStatus(currentTask.status)) {
|
|
77
|
+
taskManager.updateTask(task.id, {
|
|
78
|
+
status: TaskStatus.FAILED,
|
|
79
|
+
endTime: new Date().toISOString(),
|
|
80
|
+
error: err instanceof Error ? err.message : String(err),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
return task.id;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Execute a waiting task (called when dependencies are satisfied).
|
|
89
|
+
*/
|
|
90
|
+
export async function executeWaitingTask(task) {
|
|
91
|
+
const prompt = task.prompt?.trim() || '';
|
|
92
|
+
const cwd = task.cwd || clientContext.getDefaultCwd();
|
|
93
|
+
const model = resolveModel(task.model);
|
|
94
|
+
taskManager.updateTask(task.id, { status: TaskStatus.PENDING });
|
|
95
|
+
const options = {
|
|
96
|
+
prompt,
|
|
97
|
+
cwd,
|
|
98
|
+
model,
|
|
99
|
+
timeout: task.timeout,
|
|
100
|
+
autonomous: task.autonomous,
|
|
101
|
+
labels: task.labels,
|
|
102
|
+
provider: task.provider,
|
|
103
|
+
fallbackAttempted: task.fallbackAttempted,
|
|
104
|
+
switchAttempted: task.switchAttempted,
|
|
105
|
+
retryInfo: task.retryInfo,
|
|
106
|
+
};
|
|
107
|
+
setImmediate(() => {
|
|
108
|
+
runOpenCodeSession(task.id, prompt, cwd, model, options).catch((err) => {
|
|
109
|
+
console.error(`[opencode-spawner] Task ${task.id} execution error:`, err);
|
|
110
|
+
const currentTask = taskManager.getTask(task.id);
|
|
111
|
+
if (currentTask && !isTerminalStatus(currentTask.status)) {
|
|
112
|
+
taskManager.updateTask(task.id, {
|
|
113
|
+
status: TaskStatus.FAILED,
|
|
114
|
+
endTime: new Date().toISOString(),
|
|
115
|
+
error: err instanceof Error ? err.message : String(err),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Run a task using the OpenCode headless server API.
|
|
123
|
+
*/
|
|
124
|
+
async function runOpenCodeSession(taskId, prompt, cwd, model, options) {
|
|
125
|
+
const client = getClient();
|
|
126
|
+
const task = taskManager.getTask(taskId);
|
|
127
|
+
if (!task) {
|
|
128
|
+
console.error(`[opencode-spawner] Task ${taskId} not found`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const timeout = options.timeout ?? TASK_TIMEOUT_DEFAULT_MS;
|
|
132
|
+
const timeoutAt = new Date(Date.now() + timeout).toISOString();
|
|
133
|
+
taskManager.updateTask(taskId, {
|
|
134
|
+
timeout,
|
|
135
|
+
timeoutAt,
|
|
136
|
+
status: TaskStatus.RUNNING,
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
let sessionId;
|
|
140
|
+
if (options.resumeSessionId) {
|
|
141
|
+
// Resume existing session
|
|
142
|
+
sessionId = options.resumeSessionId;
|
|
143
|
+
console.error(`[opencode-spawner] Resuming session ${sessionId} for task ${taskId}`);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Create a new session
|
|
147
|
+
const promptSlice = prompt.slice(0, 60).replace(/\n/g, ' ');
|
|
148
|
+
console.error(`[opencode-spawner] Creating session for task ${taskId}: "${promptSlice}..."`);
|
|
149
|
+
const sessionResponse = await client.post('/session', {
|
|
150
|
+
title: `Task: ${taskId} - ${promptSlice}`,
|
|
151
|
+
}, { directory: cwd });
|
|
152
|
+
sessionId = sessionResponse.id;
|
|
153
|
+
console.error(`[opencode-spawner] Session created: ${sessionId}`);
|
|
154
|
+
}
|
|
155
|
+
// Store session ID in task
|
|
156
|
+
taskManager.updateTask(taskId, { sessionId });
|
|
157
|
+
// Build the message body — let the OpenCode server pick the model
|
|
158
|
+
const messageBody = {
|
|
159
|
+
parts: [{ type: 'text', text: prompt }],
|
|
160
|
+
};
|
|
161
|
+
// Send the message
|
|
162
|
+
console.error(`[opencode-spawner] Sending message to session ${sessionId} for task ${taskId} (model: ${model})`);
|
|
163
|
+
taskManager.appendOutput(taskId, `[opencode] Sending prompt to session ${sessionId}...`);
|
|
164
|
+
const messageResponse = await client.post(`/session/${sessionId}/message`, messageBody, {
|
|
165
|
+
directory: cwd,
|
|
166
|
+
timeout: timeout + 30000, // Allow extra time beyond task timeout
|
|
167
|
+
});
|
|
168
|
+
// If we got a synchronous response, extract output immediately
|
|
169
|
+
if (messageResponse && typeof messageResponse === 'object') {
|
|
170
|
+
const resp = messageResponse;
|
|
171
|
+
const formatted = formatMessageResponse(resp);
|
|
172
|
+
if (formatted.trim()) {
|
|
173
|
+
taskManager.appendOutput(taskId, `[assistant] ${formatted.slice(0, 2000)}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Poll for completion
|
|
177
|
+
const abortController = new AbortController();
|
|
178
|
+
activePollers.set(taskId, abortController);
|
|
179
|
+
try {
|
|
180
|
+
await pollForCompletion(client, taskId, sessionId, timeout, abortController.signal, cwd);
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
activePollers.delete(taskId);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
const currentTask = taskManager.getTask(taskId);
|
|
188
|
+
if (currentTask && isTerminalStatus(currentTask.status)) {
|
|
189
|
+
// Already handled (e.g., cancelled)
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
193
|
+
// Check for rate-limit errors
|
|
194
|
+
const statusCode = extractStatusCode(errorMessage);
|
|
195
|
+
if (statusCode === 429) {
|
|
196
|
+
const retryInfo = createRetryInfo(task, errorMessage, task.retryInfo);
|
|
197
|
+
taskManager.updateTask(taskId, {
|
|
198
|
+
status: TaskStatus.RATE_LIMITED,
|
|
199
|
+
endTime: new Date().toISOString(),
|
|
200
|
+
error: errorMessage,
|
|
201
|
+
retryInfo,
|
|
202
|
+
});
|
|
203
|
+
console.error(`[opencode-spawner] Task ${taskId} rate-limited, retry #${retryInfo.retryCount} at ${retryInfo.nextRetryTime}`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
// Check for timeout
|
|
207
|
+
if (errorMessage.includes('Timeout') || errorMessage.includes('timeout') || errorMessage.includes('aborted')) {
|
|
208
|
+
taskManager.updateTask(taskId, {
|
|
209
|
+
status: TaskStatus.TIMED_OUT,
|
|
210
|
+
endTime: new Date().toISOString(),
|
|
211
|
+
error: `Task timed out after ${timeout}ms`,
|
|
212
|
+
timeoutReason: 'session_timeout',
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// Generic failure
|
|
217
|
+
taskManager.updateTask(taskId, {
|
|
218
|
+
status: TaskStatus.FAILED,
|
|
219
|
+
endTime: new Date().toISOString(),
|
|
220
|
+
error: errorMessage,
|
|
221
|
+
exitCode: 1,
|
|
222
|
+
});
|
|
223
|
+
console.error(`[opencode-spawner] Task ${taskId} failed: ${errorMessage}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Poll the OpenCode server for session completion.
|
|
228
|
+
*/
|
|
229
|
+
async function pollForCompletion(client, taskId, sessionId, timeout, signal, cwd) {
|
|
230
|
+
const startTime = Date.now();
|
|
231
|
+
let lastMessageCount = 0;
|
|
232
|
+
while (!signal.aborted) {
|
|
233
|
+
// Check timeout
|
|
234
|
+
if (Date.now() - startTime > timeout) {
|
|
235
|
+
taskManager.updateTask(taskId, {
|
|
236
|
+
status: TaskStatus.TIMED_OUT,
|
|
237
|
+
endTime: new Date().toISOString(),
|
|
238
|
+
error: `Task timed out after ${timeout}ms`,
|
|
239
|
+
timeoutReason: 'poll_timeout',
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Check if task was cancelled externally
|
|
244
|
+
const currentTask = taskManager.getTask(taskId);
|
|
245
|
+
if (!currentTask || isTerminalStatus(currentTask.status)) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
// Check session status
|
|
250
|
+
const statusResponse = await client.get('/session/status', undefined, cwd);
|
|
251
|
+
const sessionStatus = resolveSessionStatus(statusResponse?.[sessionId] ?? statusResponse);
|
|
252
|
+
// Try to get new messages for output
|
|
253
|
+
try {
|
|
254
|
+
const messages = await client.get(`/session/${sessionId}/message`, undefined, cwd);
|
|
255
|
+
if (Array.isArray(messages) && messages.length > lastMessageCount) {
|
|
256
|
+
// Process new messages
|
|
257
|
+
for (let i = lastMessageCount; i < messages.length; i++) {
|
|
258
|
+
const msg = messages[i];
|
|
259
|
+
const role = msg.role;
|
|
260
|
+
const formatted = formatMessageResponse(msg);
|
|
261
|
+
if (formatted.trim()) {
|
|
262
|
+
const prefix = role === 'assistant' ? '[assistant]' : `[${role}]`;
|
|
263
|
+
taskManager.appendOutput(taskId, `${prefix} ${formatted.slice(0, 500)}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
lastMessageCount = messages.length;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Message fetch failure is non-critical
|
|
271
|
+
}
|
|
272
|
+
// Determine if session is done
|
|
273
|
+
if (sessionStatus === 'idle' || sessionStatus === 'completed' || sessionStatus === 'done') {
|
|
274
|
+
// Session completed - get final result
|
|
275
|
+
console.error(`[opencode-spawner] Task ${taskId} session completed (status: ${sessionStatus})`);
|
|
276
|
+
// Fetch final messages
|
|
277
|
+
try {
|
|
278
|
+
const finalMessages = await client.get(`/session/${sessionId}/message`, undefined, cwd);
|
|
279
|
+
if (Array.isArray(finalMessages) && finalMessages.length > 0) {
|
|
280
|
+
const lastMsg = finalMessages[finalMessages.length - 1];
|
|
281
|
+
const finalText = formatMessageResponse(lastMsg);
|
|
282
|
+
if (finalText.trim() && finalMessages.length > lastMessageCount) {
|
|
283
|
+
taskManager.appendOutput(taskId, `[result] ${finalText.slice(0, 2000)}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// Non-critical
|
|
289
|
+
}
|
|
290
|
+
taskManager.updateTask(taskId, {
|
|
291
|
+
status: TaskStatus.COMPLETED,
|
|
292
|
+
endTime: new Date().toISOString(),
|
|
293
|
+
});
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
if (sessionStatus === 'error' || sessionStatus === 'failed') {
|
|
297
|
+
taskManager.updateTask(taskId, {
|
|
298
|
+
status: TaskStatus.FAILED,
|
|
299
|
+
endTime: new Date().toISOString(),
|
|
300
|
+
error: `Session ended with error status: ${sessionStatus}`,
|
|
301
|
+
exitCode: 1,
|
|
302
|
+
});
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
// Still running — wait and poll again
|
|
306
|
+
}
|
|
307
|
+
catch (pollError) {
|
|
308
|
+
// If polling itself fails, log but continue
|
|
309
|
+
const errMsg = pollError instanceof Error ? pollError.message : String(pollError);
|
|
310
|
+
console.error(`[opencode-spawner] Poll error for task ${taskId}: ${errMsg}`);
|
|
311
|
+
taskManager.appendOutputFileOnly(taskId, `[poll-error] ${errMsg}`);
|
|
312
|
+
}
|
|
313
|
+
await sleep(SESSION_POLL_INTERVAL_MS);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Extract HTTP status code from error message.
|
|
318
|
+
*/
|
|
319
|
+
function extractStatusCode(errorMessage) {
|
|
320
|
+
if (/\b429\b/.test(errorMessage))
|
|
321
|
+
return 429;
|
|
322
|
+
if (/\b500\b/.test(errorMessage))
|
|
323
|
+
return 500;
|
|
324
|
+
if (/\b502\b/.test(errorMessage))
|
|
325
|
+
return 502;
|
|
326
|
+
if (/\b503\b/.test(errorMessage))
|
|
327
|
+
return 503;
|
|
328
|
+
if (/\b504\b/.test(errorMessage))
|
|
329
|
+
return 504;
|
|
330
|
+
if (/rate.?limit/i.test(errorMessage))
|
|
331
|
+
return 429;
|
|
332
|
+
if (/too many requests/i.test(errorMessage))
|
|
333
|
+
return 429;
|
|
334
|
+
if (/quota/i.test(errorMessage))
|
|
335
|
+
return 429;
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Cancel a running task. Aliased as both cancelOpenCodeTask and cancelTask.
|
|
340
|
+
*/
|
|
341
|
+
export async function cancelOpenCodeTask(taskId) {
|
|
342
|
+
const task = taskManager.getTask(taskId);
|
|
343
|
+
if (!task)
|
|
344
|
+
return false;
|
|
345
|
+
// Abort polling
|
|
346
|
+
const poller = activePollers.get(taskId);
|
|
347
|
+
if (poller) {
|
|
348
|
+
poller.abort();
|
|
349
|
+
activePollers.delete(taskId);
|
|
350
|
+
}
|
|
351
|
+
taskManager.updateTask(taskId, {
|
|
352
|
+
status: TaskStatus.CANCELLED,
|
|
353
|
+
endTime: new Date().toISOString(),
|
|
354
|
+
});
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
export { cancelOpenCodeTask as cancelTask };
|
|
358
|
+
/**
|
|
359
|
+
* Send a follow-up message to an existing session.
|
|
360
|
+
*/
|
|
361
|
+
export async function sendMessageToSession(taskId, message) {
|
|
362
|
+
const task = taskManager.getTask(taskId);
|
|
363
|
+
if (!task || !task.sessionId) {
|
|
364
|
+
return { success: false, error: 'Task not found or no session ID' };
|
|
365
|
+
}
|
|
366
|
+
try {
|
|
367
|
+
const client = getClient();
|
|
368
|
+
const cwd = task.cwd || clientContext.getDefaultCwd();
|
|
369
|
+
const messageBody = {
|
|
370
|
+
parts: [{ type: 'text', text: message }],
|
|
371
|
+
};
|
|
372
|
+
await client.post(`/session/${task.sessionId}/message`, messageBody, {
|
|
373
|
+
directory: cwd,
|
|
374
|
+
});
|
|
375
|
+
taskManager.appendOutput(taskId, `[user] ${message}`);
|
|
376
|
+
// Wait briefly for response
|
|
377
|
+
await sleep(2000);
|
|
378
|
+
// Fetch latest messages for response preview
|
|
379
|
+
try {
|
|
380
|
+
const messages = await client.get(`/session/${task.sessionId}/message`, undefined, cwd);
|
|
381
|
+
if (Array.isArray(messages) && messages.length > 0) {
|
|
382
|
+
const lastMsg = messages[messages.length - 1];
|
|
383
|
+
const response = formatMessageResponse(lastMsg);
|
|
384
|
+
taskManager.appendOutput(taskId, `[assistant] ${response.slice(0, 500)}`);
|
|
385
|
+
return { success: true, response };
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
// Non-critical
|
|
390
|
+
}
|
|
391
|
+
return { success: true };
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Check if the OpenCode server is healthy.
|
|
399
|
+
*/
|
|
400
|
+
export async function checkOpenCodeAvailable() {
|
|
401
|
+
if (!openCodeClient)
|
|
402
|
+
return false;
|
|
403
|
+
return openCodeClient.isHealthy();
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Shutdown the spawner - cancel all active pollers.
|
|
407
|
+
*/
|
|
408
|
+
export function shutdownSpawner() {
|
|
409
|
+
for (const [taskId, controller] of activePollers) {
|
|
410
|
+
controller.abort();
|
|
411
|
+
console.error(`[opencode-spawner] Cancelled poller for task ${taskId}`);
|
|
412
|
+
}
|
|
413
|
+
activePollers.clear();
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get spawner statistics.
|
|
417
|
+
*/
|
|
418
|
+
export function getSpawnerStats() {
|
|
419
|
+
return {
|
|
420
|
+
activeTasks: activePollers.size,
|
|
421
|
+
activePollers: activePollers.size,
|
|
422
|
+
clientInitialized: openCodeClient !== null,
|
|
423
|
+
baseUrl: openCodeClient?.getBaseUrl() ?? 'not initialized',
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=opencode-spawner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-spawner.js","sourceRoot":"","sources":["../../src/services/opencode-spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the output directory path for a given cwd
|
|
3
|
+
* Returns: {cwd}/.super-agents/
|
|
4
|
+
*/
|
|
5
|
+
export declare function getOutputDir(cwd: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Get the output file path for a task
|
|
8
|
+
* Returns: {cwd}/.super-agents/{taskId}.output
|
|
9
|
+
*/
|
|
10
|
+
export declare function getOutputPath(cwd: string, taskId: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Create an empty output file for a task
|
|
13
|
+
* Returns the absolute path to the output file, or null on failure
|
|
14
|
+
*/
|
|
15
|
+
export declare function createOutputFile(cwd: string, taskId: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Append a line to the task's output file
|
|
18
|
+
*/
|
|
19
|
+
export declare function appendToOutputFile(cwd: string, taskId: string, line: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Append completion footer to output file
|
|
22
|
+
*/
|
|
23
|
+
export declare function finalizeOutputFile(cwd: string, taskId: string, status: string, error?: string): boolean;
|
|
24
|
+
//# sourceMappingURL=output-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-file.d.ts","sourceRoot":"","sources":["../../src/services/output-file.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjE;AAkBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAYrF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAiBvG"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, appendFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
const OUTPUT_DIR_NAME = '.super-agents';
|
|
4
|
+
/**
|
|
5
|
+
* Get the output directory path for a given cwd
|
|
6
|
+
* Returns: {cwd}/.super-agents/
|
|
7
|
+
*/
|
|
8
|
+
export function getOutputDir(cwd) {
|
|
9
|
+
return join(cwd, OUTPUT_DIR_NAME);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the output file path for a task
|
|
13
|
+
* Returns: {cwd}/.super-agents/{taskId}.output
|
|
14
|
+
*/
|
|
15
|
+
export function getOutputPath(cwd, taskId) {
|
|
16
|
+
return join(getOutputDir(cwd), `${taskId}.output`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Ensure output directory exists
|
|
20
|
+
*/
|
|
21
|
+
function ensureOutputDir(cwd) {
|
|
22
|
+
try {
|
|
23
|
+
const dir = getOutputDir(cwd);
|
|
24
|
+
if (!existsSync(dir)) {
|
|
25
|
+
mkdirSync(dir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(`[output-file] Failed to create output directory: ${error}`);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create an empty output file for a task
|
|
36
|
+
* Returns the absolute path to the output file, or null on failure
|
|
37
|
+
*/
|
|
38
|
+
export function createOutputFile(cwd, taskId) {
|
|
39
|
+
if (!ensureOutputDir(cwd)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const outputPath = getOutputPath(cwd, taskId);
|
|
43
|
+
try {
|
|
44
|
+
// Create with header
|
|
45
|
+
const header = `# Task: ${taskId}\n# Started: ${new Date().toISOString()}\n# Working directory: ${cwd}\n${'─'.repeat(60)}\n\n`;
|
|
46
|
+
writeFileSync(outputPath, header, 'utf-8');
|
|
47
|
+
return outputPath;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`[output-file] Failed to create output file: ${error}`);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Append a line to the task's output file
|
|
56
|
+
*/
|
|
57
|
+
export function appendToOutputFile(cwd, taskId, line) {
|
|
58
|
+
const outputPath = getOutputPath(cwd, taskId);
|
|
59
|
+
try {
|
|
60
|
+
// Ensure directory exists (in case it was deleted)
|
|
61
|
+
ensureOutputDir(cwd);
|
|
62
|
+
appendFileSync(outputPath, line + '\n', 'utf-8');
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
// Silent failure - don't break task execution for file I/O issues
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Append completion footer to output file
|
|
72
|
+
*/
|
|
73
|
+
export function finalizeOutputFile(cwd, taskId, status, error) {
|
|
74
|
+
const outputPath = getOutputPath(cwd, taskId);
|
|
75
|
+
try {
|
|
76
|
+
const footer = [
|
|
77
|
+
'',
|
|
78
|
+
'─'.repeat(60),
|
|
79
|
+
`# Completed: ${new Date().toISOString()}`,
|
|
80
|
+
`# Status: ${status}`,
|
|
81
|
+
error ? `# Error: ${error}` : null,
|
|
82
|
+
].filter(Boolean).join('\n') + '\n';
|
|
83
|
+
appendFileSync(outputPath, footer, 'utf-8');
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=output-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-file.js","sourceRoot":"","sources":["../../src/services/output-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ServerNotification } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
declare class ProgressRegistry {
|
|
3
|
+
private bindings;
|
|
4
|
+
register(taskId: string, progressToken: string | number, sendNotification: (notification: ServerNotification) => Promise<void>): void;
|
|
5
|
+
unregister(taskId: string): void;
|
|
6
|
+
has(taskId: string): boolean;
|
|
7
|
+
sendProgress(taskId: string, message: string, total?: number): void;
|
|
8
|
+
private doSend;
|
|
9
|
+
}
|
|
10
|
+
export declare const progressRegistry: ProgressRegistry;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=progress-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-registry.d.ts","sourceRoot":"","sources":["../../src/services/progress-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAc7E,cAAM,gBAAgB;IACpB,OAAO,CAAC,QAAQ,CAAsC;IAEtD,QAAQ,CACN,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GAAG,MAAM,EAC9B,gBAAgB,EAAE,CAAC,YAAY,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,GACpE,IAAI;IAcP,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAehC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI5B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAgDnE,OAAO,CAAC,MAAM;CAkBf;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|