opencode-swarm 4.3.2 → 4.4.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/dist/cli/index.js +67 -0
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/history.d.ts +5 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/index.js +124 -23
- package/dist/utils/errors.d.ts +33 -0
- package/dist/utils/index.d.ts +2 -1
- package/package.json +4 -4
package/dist/cli/index.js
CHANGED
|
@@ -96,6 +96,66 @@ Next steps:`);
|
|
|
96
96
|
console.log(" what expertise is needed and requests it dynamically.");
|
|
97
97
|
return 0;
|
|
98
98
|
}
|
|
99
|
+
async function uninstall() {
|
|
100
|
+
try {
|
|
101
|
+
console.log(`\uD83D\uDC1D Uninstalling OpenCode Swarm...
|
|
102
|
+
`);
|
|
103
|
+
const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
104
|
+
if (!opencodeConfig) {
|
|
105
|
+
if (fs.existsSync(OPENCODE_CONFIG_PATH)) {
|
|
106
|
+
console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
|
|
107
|
+
return 1;
|
|
108
|
+
} else {
|
|
109
|
+
console.log(`\u26A0 No opencode config found at: ${OPENCODE_CONFIG_PATH}`);
|
|
110
|
+
console.log("Nothing to uninstall.");
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!opencodeConfig.plugin || opencodeConfig.plugin.length === 0) {
|
|
115
|
+
console.log("\u26A0 opencode-swarm is not installed (no plugins configured).");
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
const pluginName = "opencode-swarm";
|
|
119
|
+
const filteredPlugins = opencodeConfig.plugin.filter((p) => p !== pluginName && !p.startsWith(`${pluginName}@`));
|
|
120
|
+
if (filteredPlugins.length === opencodeConfig.plugin.length) {
|
|
121
|
+
console.log("\u26A0 opencode-swarm is not installed.");
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
opencodeConfig.plugin = filteredPlugins;
|
|
125
|
+
if (opencodeConfig.agent) {
|
|
126
|
+
delete opencodeConfig.agent.explore;
|
|
127
|
+
delete opencodeConfig.agent.general;
|
|
128
|
+
if (Object.keys(opencodeConfig.agent).length === 0) {
|
|
129
|
+
delete opencodeConfig.agent;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
saveJson(OPENCODE_CONFIG_PATH, opencodeConfig);
|
|
133
|
+
console.log("\u2713 Removed opencode-swarm from OpenCode plugins");
|
|
134
|
+
console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
|
|
135
|
+
if (process.argv.includes("--clean")) {
|
|
136
|
+
let cleaned = false;
|
|
137
|
+
if (fs.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
138
|
+
fs.unlinkSync(PLUGIN_CONFIG_PATH);
|
|
139
|
+
console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
|
|
140
|
+
cleaned = true;
|
|
141
|
+
}
|
|
142
|
+
if (fs.existsSync(PROMPTS_DIR)) {
|
|
143
|
+
fs.rmSync(PROMPTS_DIR, { recursive: true });
|
|
144
|
+
console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
|
|
145
|
+
cleaned = true;
|
|
146
|
+
}
|
|
147
|
+
if (!cleaned) {
|
|
148
|
+
console.log("\u2713 No config files to clean up");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
console.log(`
|
|
152
|
+
\u2705 Uninstall complete!`);
|
|
153
|
+
return 0;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.log("\u2717 Uninstall failed: " + (error instanceof Error ? error.message : String(error)));
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
99
159
|
function printHelp() {
|
|
100
160
|
console.log(`
|
|
101
161
|
opencode-swarm - Architect-centric agentic swarm plugin for OpenCode
|
|
@@ -104,8 +164,10 @@ Usage: bunx opencode-swarm [command] [OPTIONS]
|
|
|
104
164
|
|
|
105
165
|
Commands:
|
|
106
166
|
install Install and configure the plugin (default)
|
|
167
|
+
uninstall Remove the plugin from OpenCode config
|
|
107
168
|
|
|
108
169
|
Options:
|
|
170
|
+
--clean Also remove config files and custom prompts (with uninstall)
|
|
109
171
|
-h, --help Show this help message
|
|
110
172
|
|
|
111
173
|
Configuration:
|
|
@@ -122,6 +184,8 @@ Custom Prompts:
|
|
|
122
184
|
|
|
123
185
|
Examples:
|
|
124
186
|
bunx opencode-swarm install
|
|
187
|
+
bunx opencode-swarm uninstall
|
|
188
|
+
bunx opencode-swarm uninstall --clean
|
|
125
189
|
bunx opencode-swarm --help
|
|
126
190
|
`);
|
|
127
191
|
}
|
|
@@ -135,6 +199,9 @@ async function main() {
|
|
|
135
199
|
if (command === "install") {
|
|
136
200
|
const exitCode = await install();
|
|
137
201
|
process.exit(exitCode);
|
|
202
|
+
} else if (command === "uninstall") {
|
|
203
|
+
const exitCode = await uninstall();
|
|
204
|
+
process.exit(exitCode);
|
|
138
205
|
} else {
|
|
139
206
|
console.error(`Unknown command: ${command}`);
|
|
140
207
|
console.error("Run with --help for usage information");
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AgentDefinition } from '../agents';
|
|
2
2
|
export { handleAgentsCommand } from './agents';
|
|
3
|
+
export { handleConfigCommand } from './config';
|
|
4
|
+
export { handleHistoryCommand } from './history';
|
|
3
5
|
export { handlePlanCommand } from './plan';
|
|
4
6
|
export { handleStatusCommand } from './status';
|
|
5
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -14410,9 +14410,46 @@ function handleAgentsCommand(agents) {
|
|
|
14410
14410
|
`);
|
|
14411
14411
|
}
|
|
14412
14412
|
|
|
14413
|
-
// src/
|
|
14413
|
+
// src/commands/config.ts
|
|
14414
|
+
import * as os2 from "os";
|
|
14414
14415
|
import * as path2 from "path";
|
|
14416
|
+
function getUserConfigDir2() {
|
|
14417
|
+
return process.env.XDG_CONFIG_HOME || path2.join(os2.homedir(), ".config");
|
|
14418
|
+
}
|
|
14419
|
+
async function handleConfigCommand(directory, _args) {
|
|
14420
|
+
const config2 = loadPluginConfig(directory);
|
|
14421
|
+
const userConfigPath = path2.join(getUserConfigDir2(), "opencode", "opencode-swarm.json");
|
|
14422
|
+
const projectConfigPath = path2.join(directory, ".opencode", "opencode-swarm.json");
|
|
14423
|
+
const lines = [
|
|
14424
|
+
"## Swarm Configuration",
|
|
14425
|
+
"",
|
|
14426
|
+
"### Config Files",
|
|
14427
|
+
`- User: \`${userConfigPath}\``,
|
|
14428
|
+
`- Project: \`${projectConfigPath}\``,
|
|
14429
|
+
"",
|
|
14430
|
+
"### Resolved Config",
|
|
14431
|
+
"```json",
|
|
14432
|
+
JSON.stringify(config2, null, 2),
|
|
14433
|
+
"```"
|
|
14434
|
+
];
|
|
14435
|
+
return lines.join(`
|
|
14436
|
+
`);
|
|
14437
|
+
}
|
|
14415
14438
|
|
|
14439
|
+
// src/hooks/utils.ts
|
|
14440
|
+
import * as path3 from "path";
|
|
14441
|
+
|
|
14442
|
+
// src/utils/errors.ts
|
|
14443
|
+
class SwarmError extends Error {
|
|
14444
|
+
code;
|
|
14445
|
+
guidance;
|
|
14446
|
+
constructor(message, code, guidance) {
|
|
14447
|
+
super(message);
|
|
14448
|
+
this.name = "SwarmError";
|
|
14449
|
+
this.code = code;
|
|
14450
|
+
this.guidance = guidance;
|
|
14451
|
+
}
|
|
14452
|
+
}
|
|
14416
14453
|
// src/utils/logger.ts
|
|
14417
14454
|
var DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
14418
14455
|
function log(message, data) {
|
|
@@ -14440,7 +14477,12 @@ function safeHook(fn) {
|
|
|
14440
14477
|
await fn(input, output);
|
|
14441
14478
|
} catch (_error) {
|
|
14442
14479
|
const functionName = fn.name || "unknown";
|
|
14443
|
-
|
|
14480
|
+
if (_error instanceof SwarmError) {
|
|
14481
|
+
warn(`Hook '${functionName}' failed: ${_error.message}
|
|
14482
|
+
\u2192 ${_error.guidance}`);
|
|
14483
|
+
} else {
|
|
14484
|
+
warn(`Hook function '${functionName}' failed:`, _error);
|
|
14485
|
+
}
|
|
14444
14486
|
}
|
|
14445
14487
|
};
|
|
14446
14488
|
}
|
|
@@ -14462,14 +14504,14 @@ function validateSwarmPath(directory, filename) {
|
|
|
14462
14504
|
if (/\.\.[/\\]/.test(filename)) {
|
|
14463
14505
|
throw new Error("Invalid filename: path traversal detected");
|
|
14464
14506
|
}
|
|
14465
|
-
const baseDir =
|
|
14466
|
-
const resolved =
|
|
14507
|
+
const baseDir = path3.normalize(path3.resolve(directory, ".swarm"));
|
|
14508
|
+
const resolved = path3.normalize(path3.resolve(baseDir, filename));
|
|
14467
14509
|
if (process.platform === "win32") {
|
|
14468
|
-
if (!resolved.toLowerCase().startsWith((baseDir +
|
|
14510
|
+
if (!resolved.toLowerCase().startsWith((baseDir + path3.sep).toLowerCase())) {
|
|
14469
14511
|
throw new Error("Invalid filename: path escapes .swarm directory");
|
|
14470
14512
|
}
|
|
14471
14513
|
} else {
|
|
14472
|
-
if (!resolved.startsWith(baseDir +
|
|
14514
|
+
if (!resolved.startsWith(baseDir + path3.sep)) {
|
|
14473
14515
|
throw new Error("Invalid filename: path escapes .swarm directory");
|
|
14474
14516
|
}
|
|
14475
14517
|
}
|
|
@@ -14492,6 +14534,57 @@ function estimateTokens(text) {
|
|
|
14492
14534
|
return Math.ceil(text.length * 0.33);
|
|
14493
14535
|
}
|
|
14494
14536
|
|
|
14537
|
+
// src/commands/history.ts
|
|
14538
|
+
async function handleHistoryCommand(directory, _args) {
|
|
14539
|
+
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
14540
|
+
if (!planContent) {
|
|
14541
|
+
return "No history available.";
|
|
14542
|
+
}
|
|
14543
|
+
const phaseRegex = /^## Phase (\d+):?\s*(.+?)(?:\s*\[(COMPLETE|IN PROGRESS|PENDING)\])?\s*$/gm;
|
|
14544
|
+
const phases = [];
|
|
14545
|
+
const lines = planContent.split(`
|
|
14546
|
+
`);
|
|
14547
|
+
for (let match = phaseRegex.exec(planContent);match !== null; match = phaseRegex.exec(planContent)) {
|
|
14548
|
+
const num = parseInt(match[1], 10);
|
|
14549
|
+
const name = match[2].trim();
|
|
14550
|
+
const status = match[3] || "PENDING";
|
|
14551
|
+
const headerLineIndex = lines.indexOf(match[0]);
|
|
14552
|
+
let completed = 0;
|
|
14553
|
+
let total = 0;
|
|
14554
|
+
if (headerLineIndex !== -1) {
|
|
14555
|
+
for (let i = headerLineIndex + 1;i < lines.length; i++) {
|
|
14556
|
+
const line = lines[i];
|
|
14557
|
+
if (/^## Phase \d+/.test(line) || line.trim() === "---" && total > 0) {
|
|
14558
|
+
break;
|
|
14559
|
+
}
|
|
14560
|
+
if (/^- \[x\]/.test(line)) {
|
|
14561
|
+
completed++;
|
|
14562
|
+
total++;
|
|
14563
|
+
} else if (/^- \[ \]/.test(line)) {
|
|
14564
|
+
total++;
|
|
14565
|
+
}
|
|
14566
|
+
}
|
|
14567
|
+
}
|
|
14568
|
+
phases.push({ num, name, status, completed, total });
|
|
14569
|
+
}
|
|
14570
|
+
if (phases.length === 0) {
|
|
14571
|
+
return "No history available.";
|
|
14572
|
+
}
|
|
14573
|
+
const tableLines = [
|
|
14574
|
+
"## Swarm History",
|
|
14575
|
+
"",
|
|
14576
|
+
"| Phase | Name | Status | Tasks |",
|
|
14577
|
+
"|-------|------|--------|-------|"
|
|
14578
|
+
];
|
|
14579
|
+
for (const phase of phases) {
|
|
14580
|
+
const statusIcon = phase.status === "COMPLETE" ? "\u2705" : phase.status === "IN PROGRESS" ? "\uD83D\uDD04" : "\u23F3";
|
|
14581
|
+
const tasks = phase.total > 0 ? `${phase.completed}/${phase.total}` : "-";
|
|
14582
|
+
tableLines.push(`| ${phase.num} | ${phase.name} | ${statusIcon} ${phase.status} | ${tasks} |`);
|
|
14583
|
+
}
|
|
14584
|
+
return tableLines.join(`
|
|
14585
|
+
`);
|
|
14586
|
+
}
|
|
14587
|
+
|
|
14495
14588
|
// src/commands/plan.ts
|
|
14496
14589
|
async function handlePlanCommand(directory, args) {
|
|
14497
14590
|
const planContent = await readSwarmFileAsync(directory, "plan.md");
|
|
@@ -14709,7 +14802,9 @@ var HELP_TEXT = [
|
|
|
14709
14802
|
"",
|
|
14710
14803
|
"- `/swarm status` \u2014 Show current swarm state",
|
|
14711
14804
|
"- `/swarm plan [phase]` \u2014 Show plan (optionally filter by phase number)",
|
|
14712
|
-
"- `/swarm agents` \u2014 List registered agents"
|
|
14805
|
+
"- `/swarm agents` \u2014 List registered agents",
|
|
14806
|
+
"- `/swarm history` \u2014 Show completed phases summary",
|
|
14807
|
+
"- `/swarm config` \u2014 Show current resolved configuration"
|
|
14713
14808
|
].join(`
|
|
14714
14809
|
`);
|
|
14715
14810
|
function createSwarmCommandHandler(directory, agents) {
|
|
@@ -14730,6 +14825,12 @@ function createSwarmCommandHandler(directory, agents) {
|
|
|
14730
14825
|
case "agents":
|
|
14731
14826
|
text = handleAgentsCommand(agents);
|
|
14732
14827
|
break;
|
|
14828
|
+
case "history":
|
|
14829
|
+
text = await handleHistoryCommand(directory, args);
|
|
14830
|
+
break;
|
|
14831
|
+
case "config":
|
|
14832
|
+
text = await handleConfigCommand(directory, args);
|
|
14833
|
+
break;
|
|
14733
14834
|
default:
|
|
14734
14835
|
text = HELP_TEXT;
|
|
14735
14836
|
break;
|
|
@@ -14817,8 +14918,8 @@ async function doFlush(directory) {
|
|
|
14817
14918
|
const activitySection = renderActivitySection();
|
|
14818
14919
|
const updated = replaceOrAppendSection(existing, "## Agent Activity", activitySection);
|
|
14819
14920
|
const flushedCount = swarmState.pendingEvents;
|
|
14820
|
-
const
|
|
14821
|
-
await Bun.write(
|
|
14921
|
+
const path4 = `${directory}/.swarm/context.md`;
|
|
14922
|
+
await Bun.write(path4, updated);
|
|
14822
14923
|
swarmState.pendingEvents = Math.max(0, swarmState.pendingEvents - flushedCount);
|
|
14823
14924
|
} catch (error49) {
|
|
14824
14925
|
warn("Agent activity flush failed:", error49);
|
|
@@ -15837,10 +15938,10 @@ function mergeDefs2(...defs) {
|
|
|
15837
15938
|
function cloneDef2(schema) {
|
|
15838
15939
|
return mergeDefs2(schema._zod.def);
|
|
15839
15940
|
}
|
|
15840
|
-
function getElementAtPath2(obj,
|
|
15841
|
-
if (!
|
|
15941
|
+
function getElementAtPath2(obj, path4) {
|
|
15942
|
+
if (!path4)
|
|
15842
15943
|
return obj;
|
|
15843
|
-
return
|
|
15944
|
+
return path4.reduce((acc, key) => acc?.[key], obj);
|
|
15844
15945
|
}
|
|
15845
15946
|
function promiseAllObject2(promisesObj) {
|
|
15846
15947
|
const keys = Object.keys(promisesObj);
|
|
@@ -16199,11 +16300,11 @@ function aborted2(x, startIndex = 0) {
|
|
|
16199
16300
|
}
|
|
16200
16301
|
return false;
|
|
16201
16302
|
}
|
|
16202
|
-
function prefixIssues2(
|
|
16303
|
+
function prefixIssues2(path4, issues) {
|
|
16203
16304
|
return issues.map((iss) => {
|
|
16204
16305
|
var _a2;
|
|
16205
16306
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
16206
|
-
iss.path.unshift(
|
|
16307
|
+
iss.path.unshift(path4);
|
|
16207
16308
|
return iss;
|
|
16208
16309
|
});
|
|
16209
16310
|
}
|
|
@@ -16371,7 +16472,7 @@ function treeifyError2(error49, _mapper) {
|
|
|
16371
16472
|
return issue3.message;
|
|
16372
16473
|
};
|
|
16373
16474
|
const result = { errors: [] };
|
|
16374
|
-
const processError = (error50,
|
|
16475
|
+
const processError = (error50, path4 = []) => {
|
|
16375
16476
|
var _a2, _b;
|
|
16376
16477
|
for (const issue3 of error50.issues) {
|
|
16377
16478
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
@@ -16381,7 +16482,7 @@ function treeifyError2(error49, _mapper) {
|
|
|
16381
16482
|
} else if (issue3.code === "invalid_element") {
|
|
16382
16483
|
processError({ issues: issue3.issues }, issue3.path);
|
|
16383
16484
|
} else {
|
|
16384
|
-
const fullpath = [...
|
|
16485
|
+
const fullpath = [...path4, ...issue3.path];
|
|
16385
16486
|
if (fullpath.length === 0) {
|
|
16386
16487
|
result.errors.push(mapper(issue3));
|
|
16387
16488
|
continue;
|
|
@@ -16413,8 +16514,8 @@ function treeifyError2(error49, _mapper) {
|
|
|
16413
16514
|
}
|
|
16414
16515
|
function toDotPath2(_path) {
|
|
16415
16516
|
const segs = [];
|
|
16416
|
-
const
|
|
16417
|
-
for (const seg of
|
|
16517
|
+
const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
16518
|
+
for (const seg of path4) {
|
|
16418
16519
|
if (typeof seg === "number")
|
|
16419
16520
|
segs.push(`[${seg}]`);
|
|
16420
16521
|
else if (typeof seg === "symbol")
|
|
@@ -27610,7 +27711,7 @@ Use these as DOMAIN values when delegating to @sme.`;
|
|
|
27610
27711
|
});
|
|
27611
27712
|
// src/tools/file-extractor.ts
|
|
27612
27713
|
import * as fs2 from "fs";
|
|
27613
|
-
import * as
|
|
27714
|
+
import * as path4 from "path";
|
|
27614
27715
|
var EXT_MAP = {
|
|
27615
27716
|
python: ".py",
|
|
27616
27717
|
py: ".py",
|
|
@@ -27688,12 +27789,12 @@ var extract_code_blocks = tool({
|
|
|
27688
27789
|
if (prefix) {
|
|
27689
27790
|
filename = `${prefix}_${filename}`;
|
|
27690
27791
|
}
|
|
27691
|
-
let filepath =
|
|
27692
|
-
const base =
|
|
27693
|
-
const ext =
|
|
27792
|
+
let filepath = path4.join(targetDir, filename);
|
|
27793
|
+
const base = path4.basename(filepath, path4.extname(filepath));
|
|
27794
|
+
const ext = path4.extname(filepath);
|
|
27694
27795
|
let counter = 1;
|
|
27695
27796
|
while (fs2.existsSync(filepath)) {
|
|
27696
|
-
filepath =
|
|
27797
|
+
filepath = path4.join(targetDir, `${base}_${counter}${ext}`);
|
|
27697
27798
|
counter++;
|
|
27698
27799
|
}
|
|
27699
27800
|
try {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all swarm errors.
|
|
3
|
+
* Includes a machine-readable `code` and a user-facing `guidance` string.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SwarmError extends Error {
|
|
6
|
+
readonly code: string;
|
|
7
|
+
readonly guidance: string;
|
|
8
|
+
constructor(message: string, code: string, guidance: string);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when configuration loading or validation fails.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ConfigError extends SwarmError {
|
|
14
|
+
constructor(message: string, guidance: string);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Error thrown when a hook execution fails.
|
|
18
|
+
*/
|
|
19
|
+
export declare class HookError extends SwarmError {
|
|
20
|
+
constructor(message: string, guidance: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when a tool execution fails.
|
|
24
|
+
*/
|
|
25
|
+
export declare class ToolError extends SwarmError {
|
|
26
|
+
constructor(message: string, guidance: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown when CLI operations fail.
|
|
30
|
+
*/
|
|
31
|
+
export declare class CLIError extends SwarmError {
|
|
32
|
+
constructor(message: string, guidance: string);
|
|
33
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { CLIError, ConfigError, HookError, SwarmError, ToolError, } from './errors';
|
|
2
|
+
export { error, log, warn } from './logger';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"prepublishOnly": "bun run build"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@opencode-ai/plugin": "^1.1.
|
|
39
|
-
"@opencode-ai/sdk": "^1.1.
|
|
38
|
+
"@opencode-ai/plugin": "^1.1.53",
|
|
39
|
+
"@opencode-ai/sdk": "^1.1.53",
|
|
40
40
|
"zod": "^4.1.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@biomejs/biome": "2.3.
|
|
43
|
+
"@biomejs/biome": "2.3.14",
|
|
44
44
|
"bun-types": "latest",
|
|
45
45
|
"typescript": "^5.7.3"
|
|
46
46
|
}
|