opencode-orchestrator 1.2.38 → 1.2.46
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/dist/core/agents/concurrency-token.d.ts +23 -0
- package/dist/core/agents/concurrency.d.ts +72 -15
- package/dist/core/agents/index.d.ts +0 -1
- package/dist/core/agents/interfaces/index.d.ts +4 -3
- package/dist/core/agents/logger.d.ts +4 -3
- package/dist/core/agents/manager/event-handler.d.ts +1 -1
- package/dist/core/agents/manager/task-launcher.d.ts +1 -1
- package/dist/core/agents/manager/task-poller.d.ts +15 -1
- package/dist/core/agents/manager/task-resumer.d.ts +1 -1
- package/dist/core/agents/manager.d.ts +5 -1
- package/dist/core/agents/persistence/task-wal.d.ts +11 -13
- package/dist/core/agents/session-pool.d.ts +9 -1
- package/dist/core/agents/task-store.d.ts +25 -1
- package/dist/core/cleanup/cleanup-scheduler.d.ts +16 -0
- package/dist/core/commands/interfaces/background-task.d.ts +1 -0
- package/dist/core/commands/manager.d.ts +4 -0
- package/dist/core/lifecycle/shutdown-manager.d.ts +29 -0
- package/dist/core/plugins/interfaces.d.ts +4 -0
- package/dist/core/plugins/plugin-manager.d.ts +4 -0
- package/dist/core/pool/buffer-pool.d.ts +48 -0
- package/dist/core/pool/object-pool.d.ts +59 -0
- package/dist/core/pool/string-pool.d.ts +40 -0
- package/dist/core/pool/task-pool.d.ts +13 -0
- package/dist/core/queue/work-stealing-deque.d.ts +47 -0
- package/dist/core/queue/worker-pool.d.ts +78 -0
- package/dist/core/sync/todo-sync-service.d.ts +5 -0
- package/dist/index.js +17903 -16834
- package/dist/scripts/postinstall.js +156 -25
- package/dist/scripts/preuninstall.js +159 -17
- package/dist/shared/task/interfaces/parallel-task.d.ts +6 -4
- package/dist/tools/registry.d.ts +14 -0
- package/dist/tools/rust-pool.d.ts +63 -0
- package/dist/tools/rust.d.ts +4 -0
- package/package.json +1 -1
- package/dist/core/agents/interfaces/concurrency-config.interface.d.ts +0 -9
- package/dist/core/agents/interfaces/parallel-task.interface.d.ts +0 -26
- package/dist/core/agents/interfaces/task-progress.interface.d.ts +0 -9
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
// scripts/postinstall.ts
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "fs";
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync, copyFileSync, renameSync, unlinkSync } from "fs";
|
|
5
11
|
import { homedir, tmpdir } from "os";
|
|
6
12
|
import { join } from "path";
|
|
7
13
|
var LOG_FILE = join(tmpdir(), "opencode-orchestrator.log");
|
|
@@ -57,74 +63,199 @@ function getConfigPaths() {
|
|
|
57
63
|
}
|
|
58
64
|
return paths;
|
|
59
65
|
}
|
|
66
|
+
function validateConfig(config) {
|
|
67
|
+
try {
|
|
68
|
+
if (typeof config !== "object" || config === null) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (config.plugin !== void 0 && !Array.isArray(config.plugin)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (config.plugin) {
|
|
75
|
+
for (const p of config.plugin) {
|
|
76
|
+
if (typeof p !== "string") {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function createBackup(configFile) {
|
|
87
|
+
try {
|
|
88
|
+
if (!existsSync(configFile)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
92
|
+
const backupFile = `${configFile}.backup.${timestamp}`;
|
|
93
|
+
copyFileSync(configFile, backupFile);
|
|
94
|
+
log("Backup created", { backupFile });
|
|
95
|
+
return backupFile;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
log("Failed to create backup", { error: String(error) });
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function atomicWriteJSON(filePath, data) {
|
|
102
|
+
const tempFile = `${filePath}.tmp.${Date.now()}`;
|
|
103
|
+
try {
|
|
104
|
+
writeFileSync(tempFile, JSON.stringify(data, null, 2) + "\n", { mode: 420 });
|
|
105
|
+
renameSync(tempFile, filePath);
|
|
106
|
+
log("Atomic write successful", { filePath });
|
|
107
|
+
} catch (error) {
|
|
108
|
+
try {
|
|
109
|
+
if (existsSync(tempFile)) {
|
|
110
|
+
unlinkSync(tempFile);
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
60
117
|
function registerInConfig(configDir) {
|
|
61
118
|
const configFile = join(configDir, "opencode.json");
|
|
119
|
+
let backupFile = null;
|
|
62
120
|
try {
|
|
63
121
|
if (!existsSync(configDir)) {
|
|
64
|
-
mkdirSync(configDir, { recursive: true });
|
|
122
|
+
mkdirSync(configDir, { recursive: true, mode: 493 });
|
|
123
|
+
log("Created config directory", { configDir });
|
|
65
124
|
}
|
|
125
|
+
backupFile = createBackup(configFile);
|
|
66
126
|
let config = {};
|
|
67
127
|
if (existsSync(configFile)) {
|
|
68
128
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
129
|
+
const content = readFileSync(configFile, "utf-8").trim();
|
|
130
|
+
if (content) {
|
|
131
|
+
config = JSON.parse(content);
|
|
132
|
+
if (!validateConfig(config)) {
|
|
133
|
+
log("Invalid config structure detected, using safe defaults", { config });
|
|
134
|
+
config = { plugin: [] };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
log("Failed to parse existing config, creating new one", { error: String(error) });
|
|
139
|
+
if (backupFile) {
|
|
140
|
+
console.log(`\u26A0\uFE0F Corrupted config detected. Backup saved: ${backupFile}`);
|
|
141
|
+
}
|
|
142
|
+
config = { plugin: [] };
|
|
72
143
|
}
|
|
73
144
|
}
|
|
74
145
|
if (!config.plugin) {
|
|
75
146
|
config.plugin = [];
|
|
76
147
|
}
|
|
77
|
-
const hasPlugin = config.plugin.some(
|
|
78
|
-
(p)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return
|
|
148
|
+
const hasPlugin = config.plugin.some((p) => {
|
|
149
|
+
if (typeof p !== "string") return false;
|
|
150
|
+
return p === PLUGIN_NAME || p.includes(PLUGIN_NAME);
|
|
151
|
+
});
|
|
152
|
+
if (hasPlugin) {
|
|
153
|
+
log("Plugin already registered", { configFile });
|
|
154
|
+
return { success: false, backupFile };
|
|
155
|
+
}
|
|
156
|
+
config.plugin.push(PLUGIN_NAME);
|
|
157
|
+
log("Adding plugin to config", { plugin: PLUGIN_NAME, configFile });
|
|
158
|
+
atomicWriteJSON(configFile, config);
|
|
159
|
+
try {
|
|
160
|
+
const verifyContent = readFileSync(configFile, "utf-8");
|
|
161
|
+
const verifyConfig = JSON.parse(verifyContent);
|
|
162
|
+
if (!verifyConfig.plugin?.includes(PLUGIN_NAME)) {
|
|
163
|
+
throw new Error("Verification failed: plugin not found after write");
|
|
164
|
+
}
|
|
165
|
+
} catch (verifyError) {
|
|
166
|
+
log("Write verification failed, rolling back", { error: String(verifyError) });
|
|
167
|
+
if (backupFile && existsSync(backupFile)) {
|
|
168
|
+
copyFileSync(backupFile, configFile);
|
|
169
|
+
console.log(`\u26A0\uFE0F Write verification failed. Restored from backup.`);
|
|
170
|
+
}
|
|
171
|
+
throw verifyError;
|
|
172
|
+
}
|
|
173
|
+
log("Plugin registered successfully", { configFile });
|
|
174
|
+
return { success: true, backupFile };
|
|
175
|
+
} catch (error) {
|
|
176
|
+
log("Registration failed", { error: String(error), configFile });
|
|
177
|
+
if (backupFile && existsSync(backupFile)) {
|
|
178
|
+
try {
|
|
179
|
+
copyFileSync(backupFile, configFile);
|
|
180
|
+
log("Rolled back to backup", { backupFile });
|
|
181
|
+
console.log(`\u26A0\uFE0F Registration failed. Restored from backup: ${backupFile}`);
|
|
182
|
+
} catch (rollbackError) {
|
|
183
|
+
log("Rollback failed", { error: String(rollbackError) });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return { success: false, backupFile };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function cleanupOldBackups(configFile) {
|
|
190
|
+
try {
|
|
191
|
+
const configDir = join(configFile, "..");
|
|
192
|
+
const files = __require("fs").readdirSync(configDir);
|
|
193
|
+
const backupFiles = files.filter((f) => f.startsWith("opencode.json.backup.")).sort().reverse();
|
|
194
|
+
for (let i = 5; i < backupFiles.length; i++) {
|
|
195
|
+
const backupPath = join(configDir, backupFiles[i]);
|
|
196
|
+
try {
|
|
197
|
+
unlinkSync(backupPath);
|
|
198
|
+
log("Deleted old backup", { file: backupFiles[i] });
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
84
201
|
}
|
|
85
|
-
return false;
|
|
86
202
|
} catch {
|
|
87
|
-
return false;
|
|
88
203
|
}
|
|
89
204
|
}
|
|
90
205
|
try {
|
|
91
206
|
console.log("\u{1F3AF} OpenCode Orchestrator - Installing...");
|
|
92
|
-
log("Installation started", { platform: process.platform });
|
|
207
|
+
log("Installation started", { platform: process.platform, node: process.version });
|
|
93
208
|
const configPaths = getConfigPaths();
|
|
94
209
|
log("Config paths to check", configPaths);
|
|
95
210
|
let registered = false;
|
|
96
211
|
let alreadyRegistered = false;
|
|
212
|
+
let backupCreated = null;
|
|
97
213
|
for (const configDir of configPaths) {
|
|
98
214
|
const configFile = join(configDir, "opencode.json");
|
|
99
215
|
if (existsSync(configFile)) {
|
|
100
216
|
try {
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
217
|
+
const content = readFileSync(configFile, "utf-8").trim();
|
|
218
|
+
if (content) {
|
|
219
|
+
const config = JSON.parse(content);
|
|
220
|
+
if (config.plugin?.some((p) => typeof p === "string" && (p === PLUGIN_NAME || p.includes(PLUGIN_NAME)))) {
|
|
221
|
+
alreadyRegistered = true;
|
|
222
|
+
log("Plugin already registered in this location", { configFile });
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
105
225
|
}
|
|
106
|
-
} catch {
|
|
226
|
+
} catch (error) {
|
|
227
|
+
log("Error checking existing config", { error: String(error), configFile });
|
|
107
228
|
}
|
|
108
229
|
}
|
|
109
|
-
|
|
230
|
+
const result = registerInConfig(configDir);
|
|
231
|
+
if (result.success) {
|
|
110
232
|
console.log(`\u2705 Plugin registered: ${configFile}`);
|
|
111
|
-
|
|
233
|
+
if (result.backupFile) {
|
|
234
|
+
console.log(` Backup created: ${result.backupFile}`);
|
|
235
|
+
backupCreated = result.backupFile;
|
|
236
|
+
}
|
|
112
237
|
registered = true;
|
|
238
|
+
cleanupOldBackups(configFile);
|
|
239
|
+
} else if (result.backupFile) {
|
|
240
|
+
backupCreated = result.backupFile;
|
|
113
241
|
}
|
|
114
242
|
}
|
|
115
243
|
if (!registered && alreadyRegistered) {
|
|
116
244
|
console.log("\u2705 Plugin already registered.");
|
|
117
245
|
log("Plugin was already registered");
|
|
118
246
|
} else if (!registered) {
|
|
119
|
-
console.log("\u26A0\uFE0F
|
|
247
|
+
console.log("\u26A0\uFE0F Could not register plugin in any config location.");
|
|
248
|
+
console.log(" This may be due to permissions or file system issues.");
|
|
249
|
+
console.log(` Check logs: ${LOG_FILE}`);
|
|
120
250
|
log("Failed to register plugin in any location");
|
|
121
251
|
}
|
|
122
252
|
console.log("");
|
|
123
253
|
console.log("\u{1F680} Ready! Restart OpenCode to use.");
|
|
124
254
|
console.log("");
|
|
125
|
-
log("Installation completed", { registered, alreadyRegistered });
|
|
255
|
+
log("Installation completed", { registered, alreadyRegistered, backupCreated });
|
|
126
256
|
} catch (error) {
|
|
127
257
|
log("Installation error", { error: String(error) });
|
|
128
|
-
console.error(formatError(error, "register plugin"));
|
|
258
|
+
console.error("\u274C " + formatError(error, "register plugin"));
|
|
259
|
+
console.log(` Check logs: ${LOG_FILE}`);
|
|
129
260
|
process.exit(0);
|
|
130
261
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
// scripts/preuninstall.ts
|
|
4
|
-
import { existsSync, readFileSync, writeFileSync, appendFileSync } from "fs";
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, appendFileSync, copyFileSync, renameSync, unlinkSync } from "fs";
|
|
5
11
|
import { homedir, tmpdir } from "os";
|
|
6
12
|
import { join } from "path";
|
|
7
13
|
var LOG_FILE = join(tmpdir(), "opencode-orchestrator.log");
|
|
@@ -57,50 +63,186 @@ function getConfigPaths() {
|
|
|
57
63
|
}
|
|
58
64
|
return paths;
|
|
59
65
|
}
|
|
66
|
+
function validateConfig(config) {
|
|
67
|
+
try {
|
|
68
|
+
if (typeof config !== "object" || config === null) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (config.plugin !== void 0 && !Array.isArray(config.plugin)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (config.plugin) {
|
|
75
|
+
for (const p of config.plugin) {
|
|
76
|
+
if (typeof p !== "string") {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function createBackup(configFile) {
|
|
87
|
+
try {
|
|
88
|
+
if (!existsSync(configFile)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
92
|
+
const backupFile = `${configFile}.backup.${timestamp}`;
|
|
93
|
+
copyFileSync(configFile, backupFile);
|
|
94
|
+
log("Backup created", { backupFile });
|
|
95
|
+
return backupFile;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
log("Failed to create backup", { error: String(error) });
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function atomicWriteJSON(filePath, data) {
|
|
102
|
+
const tempFile = `${filePath}.tmp.${Date.now()}`;
|
|
103
|
+
try {
|
|
104
|
+
writeFileSync(tempFile, JSON.stringify(data, null, 2) + "\n", { mode: 420 });
|
|
105
|
+
renameSync(tempFile, filePath);
|
|
106
|
+
log("Atomic write successful", { filePath });
|
|
107
|
+
} catch (error) {
|
|
108
|
+
try {
|
|
109
|
+
if (existsSync(tempFile)) {
|
|
110
|
+
unlinkSync(tempFile);
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
60
117
|
function removeFromConfig(configDir) {
|
|
61
118
|
const configFile = join(configDir, "opencode.json");
|
|
119
|
+
let backupFile = null;
|
|
62
120
|
try {
|
|
63
121
|
if (!existsSync(configFile)) {
|
|
64
|
-
|
|
122
|
+
log("Config file does not exist", { configFile });
|
|
123
|
+
return { success: false, backupFile: null };
|
|
124
|
+
}
|
|
125
|
+
backupFile = createBackup(configFile);
|
|
126
|
+
const content = readFileSync(configFile, "utf-8").trim();
|
|
127
|
+
if (!content) {
|
|
128
|
+
log("Empty config file", { configFile });
|
|
129
|
+
return { success: false, backupFile };
|
|
130
|
+
}
|
|
131
|
+
let config;
|
|
132
|
+
try {
|
|
133
|
+
config = JSON.parse(content);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
log("Failed to parse config, skipping", { error: String(error), configFile });
|
|
136
|
+
console.log(`\u26A0\uFE0F Corrupted config detected. Backup saved: ${backupFile}`);
|
|
137
|
+
return { success: false, backupFile };
|
|
138
|
+
}
|
|
139
|
+
if (!validateConfig(config)) {
|
|
140
|
+
log("Invalid config structure, skipping", { config, configFile });
|
|
141
|
+
return { success: false, backupFile };
|
|
65
142
|
}
|
|
66
|
-
const config = JSON.parse(readFileSync(configFile, "utf-8"));
|
|
67
143
|
if (!config.plugin || !Array.isArray(config.plugin)) {
|
|
68
|
-
|
|
144
|
+
log("No plugin array found", { configFile });
|
|
145
|
+
return { success: false, backupFile };
|
|
69
146
|
}
|
|
70
147
|
const originalLength = config.plugin.length;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
148
|
+
const originalPlugins = [...config.plugin];
|
|
149
|
+
config.plugin = config.plugin.filter((p) => {
|
|
150
|
+
if (typeof p !== "string") return true;
|
|
151
|
+
return p !== PLUGIN_NAME && !p.includes(PLUGIN_NAME);
|
|
152
|
+
});
|
|
153
|
+
if (config.plugin.length === originalLength) {
|
|
154
|
+
log("Plugin not found in config", { configFile });
|
|
155
|
+
return { success: false, backupFile };
|
|
156
|
+
}
|
|
157
|
+
const removedCount = originalLength - config.plugin.length;
|
|
158
|
+
log("Removing plugin from config", {
|
|
159
|
+
plugin: PLUGIN_NAME,
|
|
160
|
+
removedCount,
|
|
161
|
+
originalPlugins,
|
|
162
|
+
newPlugins: config.plugin,
|
|
163
|
+
configFile
|
|
164
|
+
});
|
|
165
|
+
atomicWriteJSON(configFile, config);
|
|
166
|
+
try {
|
|
167
|
+
const verifyContent = readFileSync(configFile, "utf-8");
|
|
168
|
+
const verifyConfig = JSON.parse(verifyContent);
|
|
169
|
+
const stillHasPlugin = verifyConfig.plugin?.some(
|
|
170
|
+
(p) => typeof p === "string" && (p === PLUGIN_NAME || p.includes(PLUGIN_NAME))
|
|
171
|
+
);
|
|
172
|
+
if (stillHasPlugin) {
|
|
173
|
+
throw new Error("Verification failed: plugin still present after removal");
|
|
174
|
+
}
|
|
175
|
+
} catch (verifyError) {
|
|
176
|
+
log("Write verification failed, rolling back", { error: String(verifyError) });
|
|
177
|
+
if (backupFile && existsSync(backupFile)) {
|
|
178
|
+
copyFileSync(backupFile, configFile);
|
|
179
|
+
console.log(`\u26A0\uFE0F Write verification failed. Restored from backup.`);
|
|
180
|
+
}
|
|
181
|
+
throw verifyError;
|
|
182
|
+
}
|
|
183
|
+
log("Plugin removed successfully", { configFile, removedCount });
|
|
184
|
+
return { success: true, backupFile };
|
|
185
|
+
} catch (error) {
|
|
186
|
+
log("Removal failed", { error: String(error), configFile });
|
|
187
|
+
if (backupFile && existsSync(backupFile)) {
|
|
188
|
+
try {
|
|
189
|
+
copyFileSync(backupFile, configFile);
|
|
190
|
+
log("Rolled back to backup", { backupFile });
|
|
191
|
+
console.log(`\u26A0\uFE0F Removal failed. Restored from backup: ${backupFile}`);
|
|
192
|
+
} catch (rollbackError) {
|
|
193
|
+
log("Rollback failed", { error: String(rollbackError) });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return { success: false, backupFile };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function cleanupOldBackups(configFile) {
|
|
200
|
+
try {
|
|
201
|
+
const configDir = join(configFile, "..");
|
|
202
|
+
const files = __require("fs").readdirSync(configDir);
|
|
203
|
+
const backupFiles = files.filter((f) => f.startsWith("opencode.json.backup.")).sort().reverse();
|
|
204
|
+
for (let i = 5; i < backupFiles.length; i++) {
|
|
205
|
+
const backupPath = join(configDir, backupFiles[i]);
|
|
206
|
+
try {
|
|
207
|
+
unlinkSync(backupPath);
|
|
208
|
+
log("Deleted old backup", { file: backupFiles[i] });
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
77
211
|
}
|
|
78
|
-
return false;
|
|
79
212
|
} catch {
|
|
80
|
-
return false;
|
|
81
213
|
}
|
|
82
214
|
}
|
|
83
215
|
try {
|
|
84
216
|
console.log("\u{1F9F9} OpenCode Orchestrator - Uninstalling...");
|
|
85
|
-
log("Uninstallation started", { platform: process.platform });
|
|
217
|
+
log("Uninstallation started", { platform: process.platform, node: process.version });
|
|
86
218
|
const configPaths = getConfigPaths();
|
|
87
219
|
log("Config paths to check", configPaths);
|
|
88
220
|
let removed = false;
|
|
221
|
+
let backupCreated = null;
|
|
89
222
|
for (const configDir of configPaths) {
|
|
90
223
|
const configFile = join(configDir, "opencode.json");
|
|
91
|
-
|
|
224
|
+
const result = removeFromConfig(configDir);
|
|
225
|
+
if (result.success) {
|
|
92
226
|
console.log(`\u2705 Plugin removed: ${configFile}`);
|
|
93
|
-
|
|
227
|
+
if (result.backupFile) {
|
|
228
|
+
console.log(` Backup created: ${result.backupFile}`);
|
|
229
|
+
backupCreated = result.backupFile;
|
|
230
|
+
}
|
|
94
231
|
removed = true;
|
|
232
|
+
cleanupOldBackups(configFile);
|
|
233
|
+
} else if (result.backupFile) {
|
|
234
|
+
backupCreated = result.backupFile;
|
|
95
235
|
}
|
|
96
236
|
}
|
|
97
237
|
if (!removed) {
|
|
98
238
|
console.log("\u2705 Plugin was not registered. Nothing to clean up.");
|
|
99
239
|
log("Plugin was not registered");
|
|
100
240
|
}
|
|
101
|
-
log("
|
|
241
|
+
console.log("");
|
|
242
|
+
log("Uninstallation completed", { removed, backupCreated });
|
|
102
243
|
} catch (error) {
|
|
103
244
|
log("Uninstallation error", { error: String(error) });
|
|
104
|
-
console.error(formatError(error, "clean up config"));
|
|
245
|
+
console.error("\u274C " + formatError(error, "clean up config"));
|
|
246
|
+
console.log(` Check logs: ${LOG_FILE}`);
|
|
105
247
|
process.exit(0);
|
|
106
248
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parallel task running in child session
|
|
3
|
+
* MERGED: Contains both core and shared fields
|
|
3
4
|
*/
|
|
4
5
|
import type { ParallelTaskStatus } from "../types/index.js";
|
|
5
6
|
import type { TaskProgress } from "./task-progress.js";
|
|
6
|
-
|
|
7
|
+
import type { Poolable } from "../../../core/pool/object-pool.js";
|
|
8
|
+
export interface ParallelTask extends Poolable {
|
|
7
9
|
id: string;
|
|
8
10
|
sessionID: string;
|
|
9
11
|
parentSessionID: string;
|
|
@@ -16,11 +18,11 @@ export interface ParallelTask {
|
|
|
16
18
|
error?: string;
|
|
17
19
|
result?: string;
|
|
18
20
|
concurrencyKey?: string;
|
|
19
|
-
/** Depth tracking - prevents infinite recursion */
|
|
20
21
|
depth: number;
|
|
21
|
-
|
|
22
|
+
mode?: "normal" | "race" | "fractal";
|
|
23
|
+
groupID?: string;
|
|
22
24
|
lastMsgCount?: number;
|
|
23
25
|
stablePolls?: number;
|
|
24
|
-
/** Progress tracking */
|
|
25
26
|
progress?: TaskProgress;
|
|
27
|
+
hasStartedOutputting?: boolean;
|
|
26
28
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry - Centralized tool registration
|
|
3
|
+
*
|
|
4
|
+
* Consolidates all tool definitions for cleaner plugin initialization
|
|
5
|
+
*/
|
|
6
|
+
import type { ToolDefinition } from "@opencode-ai/plugin";
|
|
7
|
+
/**
|
|
8
|
+
* Register all tools in one place
|
|
9
|
+
* @param directory - Working directory
|
|
10
|
+
* @param asyncAgentTools - Parallel agent tools from ParallelAgentManager
|
|
11
|
+
* @param dynamicTools - Dynamic tools from PluginManager
|
|
12
|
+
* @returns Complete tool registry
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerAllTools(directory: string, asyncAgentTools: Record<string, ToolDefinition>, dynamicTools: Record<string, ToolDefinition>): Record<string, ToolDefinition>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust Tool Connection Pool
|
|
3
|
+
*
|
|
4
|
+
* Maintains persistent Rust processes for faster tool calls.
|
|
5
|
+
* First call: ~50-100ms (spawn overhead)
|
|
6
|
+
* Subsequent calls: ~5-10ms (10x faster!)
|
|
7
|
+
*/
|
|
8
|
+
export declare class RustToolPool {
|
|
9
|
+
private processes;
|
|
10
|
+
private maxSize;
|
|
11
|
+
private idleTimeout;
|
|
12
|
+
private cleanupInterval;
|
|
13
|
+
private shuttingDown;
|
|
14
|
+
constructor(maxSize?: number);
|
|
15
|
+
/**
|
|
16
|
+
* Call a Rust tool using pooled connection
|
|
17
|
+
*/
|
|
18
|
+
call(name: string, args: Record<string, unknown>): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Get an available process from pool
|
|
21
|
+
*/
|
|
22
|
+
private getAvailable;
|
|
23
|
+
/**
|
|
24
|
+
* Wait for a process to become available
|
|
25
|
+
*/
|
|
26
|
+
private waitForAvailable;
|
|
27
|
+
/**
|
|
28
|
+
* Create a new pooled process
|
|
29
|
+
*/
|
|
30
|
+
private createProcess;
|
|
31
|
+
/**
|
|
32
|
+
* Send a request to a pooled process
|
|
33
|
+
*/
|
|
34
|
+
private sendRequest;
|
|
35
|
+
/**
|
|
36
|
+
* Release a process back to the pool
|
|
37
|
+
*/
|
|
38
|
+
private release;
|
|
39
|
+
/**
|
|
40
|
+
* Start cleanup timer for idle processes
|
|
41
|
+
*/
|
|
42
|
+
private startCleanupTimer;
|
|
43
|
+
/**
|
|
44
|
+
* Shutdown the pool
|
|
45
|
+
*/
|
|
46
|
+
shutdown(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Get pool statistics
|
|
49
|
+
*/
|
|
50
|
+
getStats(): {
|
|
51
|
+
total: number;
|
|
52
|
+
busy: number;
|
|
53
|
+
idle: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get or create the global pool
|
|
58
|
+
*/
|
|
59
|
+
export declare function getRustToolPool(): RustToolPool;
|
|
60
|
+
/**
|
|
61
|
+
* Shutdown the global pool
|
|
62
|
+
*/
|
|
63
|
+
export declare function shutdownRustToolPool(): Promise<void>;
|
package/dist/tools/rust.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "opencode-orchestrator",
|
|
3
3
|
"displayName": "OpenCode Orchestrator",
|
|
4
4
|
"description": "Distributed Cognitive Architecture for OpenCode. Turns simple prompts into specialized multi-agent workflows (Planner, Coder, Reviewer).",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.46",
|
|
6
6
|
"author": "agnusdei1207",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ParallelTask Interface - Represents a task running in a parallel session
|
|
3
|
-
*/
|
|
4
|
-
import type { ParallelTaskStatus } from "../types/parallel-task-status.type.js";
|
|
5
|
-
import type { TaskProgress } from "./task-progress.interface.js";
|
|
6
|
-
export interface ParallelTask {
|
|
7
|
-
id: string;
|
|
8
|
-
sessionID: string;
|
|
9
|
-
parentSessionID: string;
|
|
10
|
-
description: string;
|
|
11
|
-
prompt: string;
|
|
12
|
-
agent: string;
|
|
13
|
-
status: ParallelTaskStatus;
|
|
14
|
-
startedAt: Date;
|
|
15
|
-
completedAt?: Date;
|
|
16
|
-
error?: string;
|
|
17
|
-
result?: string;
|
|
18
|
-
concurrencyKey?: string;
|
|
19
|
-
depth: number;
|
|
20
|
-
mode?: "normal" | "race" | "fractal";
|
|
21
|
-
groupID?: string;
|
|
22
|
-
lastMsgCount?: number;
|
|
23
|
-
stablePolls?: number;
|
|
24
|
-
progress?: TaskProgress;
|
|
25
|
-
hasStartedOutputting?: boolean;
|
|
26
|
-
}
|