opencode-swarm 7.0.0 → 7.0.1
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.d.ts +30 -0
- package/dist/cli/index.js +172 -56
- package/dist/commands/reset.d.ts +1 -1
- package/dist/config/cache-paths.d.ts +6 -0
- package/dist/index.js +535 -481
- package/dist/plan/checkpoint.d.ts +2 -2
- package/dist/tools/checkpoint.d.ts +10 -0
- package/package.json +1 -1
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
export declare function isSafeCachePath(p: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Safety guard for lock file deletion. Lock files have different basenames
|
|
5
|
+
* than cache directories so they need a separate check. Mirrors
|
|
6
|
+
* isSafeCachePath()'s defense-in-depth: minimum segment depth, recognized
|
|
7
|
+
* basename, and parent directory must be 'opencode'.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isSafeLockFilePath(p: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Recursively delete every known opencode plugin cache location for
|
|
12
|
+
* opencode-swarm. Returns paths actually cleared and paths that errored.
|
|
13
|
+
* Skips paths that don't exist or fail the safety guard.
|
|
14
|
+
*/
|
|
15
|
+
export declare function evictPluginCaches(): {
|
|
16
|
+
cleared: string[];
|
|
17
|
+
failed: string[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Delete every known opencode plugin lock file (bun.lock, bun.lockb,
|
|
21
|
+
* package-lock.json). Returns paths actually cleared and paths that
|
|
22
|
+
* errored. Skips paths that don't exist or fail the safety guard.
|
|
23
|
+
*
|
|
24
|
+
* Why: opencode runs `bun install` at startup; bun.lock pins the
|
|
25
|
+
* installed plugin version. Deleting the lock forces re-resolution
|
|
26
|
+
* from npm so users actually receive the @latest version after `update`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function evictLockFiles(): {
|
|
29
|
+
cleared: string[];
|
|
30
|
+
failed: string[];
|
|
31
|
+
};
|
|
2
32
|
/**
|
|
3
33
|
* Dispatch function for routing argv tokens to plugin command handlers.
|
|
4
34
|
* Used by the "run" subcommand entry point.
|
package/dist/cli/index.js
CHANGED
|
@@ -14736,7 +14736,7 @@ async function loadPlan(directory) {
|
|
|
14736
14736
|
const rebuilt = await replayFromLedger(directory);
|
|
14737
14737
|
if (rebuilt) {
|
|
14738
14738
|
await rebuildPlan(directory, rebuilt);
|
|
14739
|
-
warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
|
|
14739
|
+
warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at .swarm/SWARM_PLAN.md if it exists.");
|
|
14740
14740
|
return rebuilt;
|
|
14741
14741
|
}
|
|
14742
14742
|
} catch (replayError) {
|
|
@@ -14757,7 +14757,7 @@ async function loadPlan(directory) {
|
|
|
14757
14757
|
return approved.plan;
|
|
14758
14758
|
}
|
|
14759
14759
|
} catch {}
|
|
14760
|
-
warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
|
|
14760
|
+
warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check .swarm/SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
|
|
14761
14761
|
}
|
|
14762
14762
|
}
|
|
14763
14763
|
}
|
|
@@ -14803,7 +14803,7 @@ async function loadPlan(directory) {
|
|
|
14803
14803
|
}
|
|
14804
14804
|
return validated;
|
|
14805
14805
|
} catch (error49) {
|
|
14806
|
-
warn(`[loadPlan] plan.json validation failed: ${error49 instanceof Error ? error49.message : String(error49)}. Attempting rebuild from ledger. If rebuild fails, check SWARM_PLAN.md for a checkpoint.`);
|
|
14806
|
+
warn(`[loadPlan] plan.json validation failed: ${error49 instanceof Error ? error49.message : String(error49)}. Attempting rebuild from ledger. If rebuild fails, check .swarm/SWARM_PLAN.md for a checkpoint.`);
|
|
14807
14807
|
let rawPlanId = null;
|
|
14808
14808
|
try {
|
|
14809
14809
|
const rawParsed = JSON.parse(planJsonContent);
|
|
@@ -18577,11 +18577,11 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
18577
18577
|
// src/cli/index.ts
|
|
18578
18578
|
import * as fs21 from "fs";
|
|
18579
18579
|
import * as os7 from "os";
|
|
18580
|
-
import * as
|
|
18580
|
+
import * as path34 from "path";
|
|
18581
18581
|
// package.json
|
|
18582
18582
|
var package_default = {
|
|
18583
18583
|
name: "opencode-swarm",
|
|
18584
|
-
version: "7.0.
|
|
18584
|
+
version: "7.0.1",
|
|
18585
18585
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
18586
18586
|
main: "dist/index.js",
|
|
18587
18587
|
types: "dist/index.d.ts",
|
|
@@ -35492,22 +35492,20 @@ async function handleCloseCommand(directory, args) {
|
|
|
35492
35492
|
}
|
|
35493
35493
|
} catch {}
|
|
35494
35494
|
let swarmPlanFilesRemoved = 0;
|
|
35495
|
-
const
|
|
35496
|
-
|
|
35497
|
-
|
|
35498
|
-
|
|
35499
|
-
|
|
35500
|
-
|
|
35501
|
-
|
|
35502
|
-
|
|
35503
|
-
|
|
35504
|
-
|
|
35505
|
-
|
|
35506
|
-
|
|
35507
|
-
|
|
35508
|
-
|
|
35509
|
-
if (err?.code !== "ENOENT") {
|
|
35510
|
-
warnings.push(`Failed to remove SWARM_PLAN.md: ${err instanceof Error ? err.message : String(err)}`);
|
|
35495
|
+
const candidates = [
|
|
35496
|
+
path12.join(directory, ".swarm", "SWARM_PLAN.json"),
|
|
35497
|
+
path12.join(directory, ".swarm", "SWARM_PLAN.md"),
|
|
35498
|
+
path12.join(directory, "SWARM_PLAN.json"),
|
|
35499
|
+
path12.join(directory, "SWARM_PLAN.md")
|
|
35500
|
+
];
|
|
35501
|
+
for (const candidate of candidates) {
|
|
35502
|
+
try {
|
|
35503
|
+
await fs7.unlink(candidate);
|
|
35504
|
+
swarmPlanFilesRemoved++;
|
|
35505
|
+
} catch (err) {
|
|
35506
|
+
if (err?.code !== "ENOENT") {
|
|
35507
|
+
warnings.push(`Failed to remove ${path12.basename(candidate)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
35508
|
+
}
|
|
35511
35509
|
}
|
|
35512
35510
|
}
|
|
35513
35511
|
clearAllScopes(directory);
|
|
@@ -35582,9 +35580,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
35582
35580
|
"- Reset context.md for next session",
|
|
35583
35581
|
"- Cleared agent sessions and delegation chains",
|
|
35584
35582
|
...configBackupsRemoved > 0 ? [`- Removed ${configBackupsRemoved} stale config backup file(s)`] : [],
|
|
35585
|
-
...swarmPlanFilesRemoved > 0 ? [
|
|
35586
|
-
`- Removed ${swarmPlanFilesRemoved} root-level SWARM_PLAN checkpoint artifact(s)`
|
|
35587
|
-
] : [],
|
|
35583
|
+
...swarmPlanFilesRemoved > 0 ? [`- Removed ${swarmPlanFilesRemoved} SWARM_PLAN checkpoint artifact(s)`] : [],
|
|
35588
35584
|
...planExists && !planAlreadyDone ? ["- Set non-completed phases/tasks to closed status"] : [],
|
|
35589
35585
|
...curationSucceeded && allLessons.length > 0 ? [`- Committed ${allLessons.length} lesson(s) to knowledge store`] : [],
|
|
35590
35586
|
"",
|
|
@@ -36471,11 +36467,39 @@ function getPluginConfigDir() {
|
|
|
36471
36467
|
function getPluginCachePaths() {
|
|
36472
36468
|
const cacheBase = process.env.XDG_CACHE_HOME || path17.join(os5.homedir(), ".cache");
|
|
36473
36469
|
const configDir = getPluginConfigDir();
|
|
36474
|
-
|
|
36470
|
+
const paths = [
|
|
36471
|
+
path17.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
|
|
36475
36472
|
path17.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
|
|
36476
|
-
path17.join(configDir, "node_modules", "opencode-swarm")
|
|
36477
|
-
path17.join(cacheBase, "opencode", "node_modules", "opencode-swarm")
|
|
36473
|
+
path17.join(configDir, "node_modules", "opencode-swarm")
|
|
36478
36474
|
];
|
|
36475
|
+
if (process.platform === "darwin") {
|
|
36476
|
+
const libCaches = path17.join(os5.homedir(), "Library", "Caches");
|
|
36477
|
+
paths.push(path17.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path17.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
|
|
36478
|
+
}
|
|
36479
|
+
if (process.platform === "win32") {
|
|
36480
|
+
const localAppData = process.env.LOCALAPPDATA || path17.join(os5.homedir(), "AppData", "Local");
|
|
36481
|
+
const appData = process.env.APPDATA || path17.join(os5.homedir(), "AppData", "Roaming");
|
|
36482
|
+
paths.push(path17.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path17.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path17.join(appData, "opencode", "node_modules", "opencode-swarm"));
|
|
36483
|
+
}
|
|
36484
|
+
return paths;
|
|
36485
|
+
}
|
|
36486
|
+
function getPluginLockFilePaths() {
|
|
36487
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path17.join(os5.homedir(), ".cache");
|
|
36488
|
+
const configDir = getPluginConfigDir();
|
|
36489
|
+
const paths = [
|
|
36490
|
+
path17.join(cacheBase, "opencode", "bun.lock"),
|
|
36491
|
+
path17.join(cacheBase, "opencode", "bun.lockb"),
|
|
36492
|
+
path17.join(configDir, "package-lock.json")
|
|
36493
|
+
];
|
|
36494
|
+
if (process.platform === "darwin") {
|
|
36495
|
+
const libCaches = path17.join(os5.homedir(), "Library", "Caches");
|
|
36496
|
+
paths.push(path17.join(libCaches, "opencode", "bun.lock"), path17.join(libCaches, "opencode", "bun.lockb"));
|
|
36497
|
+
}
|
|
36498
|
+
if (process.platform === "win32") {
|
|
36499
|
+
const localAppData = process.env.LOCALAPPDATA || path17.join(os5.homedir(), "AppData", "Local");
|
|
36500
|
+
paths.push(path17.join(localAppData, "opencode", "bun.lock"), path17.join(localAppData, "opencode", "bun.lockb"));
|
|
36501
|
+
}
|
|
36502
|
+
return paths;
|
|
36479
36503
|
}
|
|
36480
36504
|
|
|
36481
36505
|
// src/services/diagnose-service.ts
|
|
@@ -44454,6 +44478,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
|
|
|
44454
44478
|
|
|
44455
44479
|
// src/commands/reset.ts
|
|
44456
44480
|
import * as fs18 from "fs";
|
|
44481
|
+
import * as path30 from "path";
|
|
44457
44482
|
|
|
44458
44483
|
// src/background/manager.ts
|
|
44459
44484
|
init_utils();
|
|
@@ -45141,7 +45166,7 @@ async function handleResetCommand(directory, args) {
|
|
|
45141
45166
|
return [
|
|
45142
45167
|
"## Swarm Reset",
|
|
45143
45168
|
"",
|
|
45144
|
-
"\u26A0\uFE0F This will delete
|
|
45169
|
+
"\u26A0\uFE0F This will delete all swarm state from .swarm/ (plan, context, checkpoints, SWARM_PLAN artifacts)",
|
|
45145
45170
|
"",
|
|
45146
45171
|
"**Tip**: Run `/swarm export` first to backup your state.",
|
|
45147
45172
|
"",
|
|
@@ -45149,7 +45174,15 @@ async function handleResetCommand(directory, args) {
|
|
|
45149
45174
|
].join(`
|
|
45150
45175
|
`);
|
|
45151
45176
|
}
|
|
45152
|
-
const filesToReset = [
|
|
45177
|
+
const filesToReset = [
|
|
45178
|
+
"plan.md",
|
|
45179
|
+
"plan.json",
|
|
45180
|
+
"context.md",
|
|
45181
|
+
"SWARM_PLAN.md",
|
|
45182
|
+
"SWARM_PLAN.json",
|
|
45183
|
+
"checkpoints.json",
|
|
45184
|
+
"events.jsonl"
|
|
45185
|
+
];
|
|
45153
45186
|
const results = [];
|
|
45154
45187
|
for (const filename of filesToReset) {
|
|
45155
45188
|
try {
|
|
@@ -45164,6 +45197,15 @@ async function handleResetCommand(directory, args) {
|
|
|
45164
45197
|
results.push(`- \u274C Failed to delete ${filename}`);
|
|
45165
45198
|
}
|
|
45166
45199
|
}
|
|
45200
|
+
for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
|
|
45201
|
+
try {
|
|
45202
|
+
const rootPath = path30.join(directory, filename);
|
|
45203
|
+
if (fs18.existsSync(rootPath)) {
|
|
45204
|
+
fs18.unlinkSync(rootPath);
|
|
45205
|
+
results.push(`- \u2705 Deleted ${filename} (root)`);
|
|
45206
|
+
}
|
|
45207
|
+
} catch {}
|
|
45208
|
+
}
|
|
45167
45209
|
try {
|
|
45168
45210
|
resetAutomationManager();
|
|
45169
45211
|
results.push("- \u2705 Stopped background automation (in-memory queues cleared)");
|
|
@@ -45194,7 +45236,7 @@ async function handleResetCommand(directory, args) {
|
|
|
45194
45236
|
// src/commands/reset-session.ts
|
|
45195
45237
|
init_utils2();
|
|
45196
45238
|
import * as fs19 from "fs";
|
|
45197
|
-
import * as
|
|
45239
|
+
import * as path31 from "path";
|
|
45198
45240
|
async function handleResetSessionCommand(directory, _args) {
|
|
45199
45241
|
const results = [];
|
|
45200
45242
|
try {
|
|
@@ -45209,13 +45251,13 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
45209
45251
|
results.push("\u274C Failed to delete state.json");
|
|
45210
45252
|
}
|
|
45211
45253
|
try {
|
|
45212
|
-
const sessionDir =
|
|
45254
|
+
const sessionDir = path31.dirname(validateSwarmPath(directory, "session/state.json"));
|
|
45213
45255
|
if (fs19.existsSync(sessionDir)) {
|
|
45214
45256
|
const files = fs19.readdirSync(sessionDir);
|
|
45215
45257
|
const otherFiles = files.filter((f) => f !== "state.json");
|
|
45216
45258
|
let deletedCount = 0;
|
|
45217
45259
|
for (const file3 of otherFiles) {
|
|
45218
|
-
const filePath =
|
|
45260
|
+
const filePath = path31.join(sessionDir, file3);
|
|
45219
45261
|
if (fs19.lstatSync(filePath).isFile()) {
|
|
45220
45262
|
fs19.unlinkSync(filePath);
|
|
45221
45263
|
deletedCount++;
|
|
@@ -45245,7 +45287,7 @@ async function handleResetSessionCommand(directory, _args) {
|
|
|
45245
45287
|
// src/summaries/manager.ts
|
|
45246
45288
|
init_utils2();
|
|
45247
45289
|
init_utils();
|
|
45248
|
-
import * as
|
|
45290
|
+
import * as path32 from "path";
|
|
45249
45291
|
var SUMMARY_ID_REGEX = /^S\d+$/;
|
|
45250
45292
|
function sanitizeSummaryId(id) {
|
|
45251
45293
|
if (!id || id.length === 0) {
|
|
@@ -45269,7 +45311,7 @@ function sanitizeSummaryId(id) {
|
|
|
45269
45311
|
}
|
|
45270
45312
|
async function loadFullOutput(directory, id) {
|
|
45271
45313
|
const sanitizedId = sanitizeSummaryId(id);
|
|
45272
|
-
const relativePath =
|
|
45314
|
+
const relativePath = path32.join("summaries", `${sanitizedId}.json`);
|
|
45273
45315
|
validateSwarmPath(directory, relativePath);
|
|
45274
45316
|
const content = await readSwarmFileAsync(directory, relativePath);
|
|
45275
45317
|
if (content === null) {
|
|
@@ -45325,7 +45367,7 @@ init_plan_schema();
|
|
|
45325
45367
|
init_utils2();
|
|
45326
45368
|
init_ledger();
|
|
45327
45369
|
import * as fs20 from "fs";
|
|
45328
|
-
import * as
|
|
45370
|
+
import * as path33 from "path";
|
|
45329
45371
|
async function handleRollbackCommand(directory, args) {
|
|
45330
45372
|
const phaseArg = args[0];
|
|
45331
45373
|
if (!phaseArg) {
|
|
@@ -45390,8 +45432,8 @@ async function handleRollbackCommand(directory, args) {
|
|
|
45390
45432
|
if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
|
|
45391
45433
|
continue;
|
|
45392
45434
|
}
|
|
45393
|
-
const src =
|
|
45394
|
-
const dest =
|
|
45435
|
+
const src = path33.join(checkpointDir, file3);
|
|
45436
|
+
const dest = path33.join(swarmDir, file3);
|
|
45395
45437
|
try {
|
|
45396
45438
|
fs20.cpSync(src, dest, { recursive: true, force: true });
|
|
45397
45439
|
successes.push(file3);
|
|
@@ -45410,12 +45452,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
45410
45452
|
].join(`
|
|
45411
45453
|
`);
|
|
45412
45454
|
}
|
|
45413
|
-
const existingLedgerPath =
|
|
45455
|
+
const existingLedgerPath = path33.join(swarmDir, "plan-ledger.jsonl");
|
|
45414
45456
|
if (fs20.existsSync(existingLedgerPath)) {
|
|
45415
45457
|
fs20.unlinkSync(existingLedgerPath);
|
|
45416
45458
|
}
|
|
45417
45459
|
try {
|
|
45418
|
-
const planJsonPath =
|
|
45460
|
+
const planJsonPath = path33.join(swarmDir, "plan.json");
|
|
45419
45461
|
if (fs20.existsSync(planJsonPath)) {
|
|
45420
45462
|
const planRaw = fs20.readFileSync(planJsonPath, "utf-8");
|
|
45421
45463
|
const plan = PlanSchema.parse(JSON.parse(planRaw));
|
|
@@ -45488,9 +45530,9 @@ async function handleSimulateCommand(directory, args) {
|
|
|
45488
45530
|
const report = reportLines.filter(Boolean).join(`
|
|
45489
45531
|
`);
|
|
45490
45532
|
const fs21 = await import("fs/promises");
|
|
45491
|
-
const
|
|
45492
|
-
const reportPath =
|
|
45493
|
-
await fs21.mkdir(
|
|
45533
|
+
const path34 = await import("path");
|
|
45534
|
+
const reportPath = path34.join(directory, ".swarm", "simulate-report.md");
|
|
45535
|
+
await fs21.mkdir(path34.dirname(reportPath), { recursive: true });
|
|
45494
45536
|
await fs21.writeFile(reportPath, report, "utf-8");
|
|
45495
45537
|
return `${darkMatterPairs.length} hidden coupling pairs detected`;
|
|
45496
45538
|
}
|
|
@@ -46038,34 +46080,55 @@ function resolveCommand(tokens) {
|
|
|
46038
46080
|
// src/cli/index.ts
|
|
46039
46081
|
var { version: version4 } = package_default;
|
|
46040
46082
|
var CONFIG_DIR = getPluginConfigDir();
|
|
46041
|
-
var OPENCODE_CONFIG_PATH =
|
|
46042
|
-
var PLUGIN_CONFIG_PATH =
|
|
46043
|
-
var PROMPTS_DIR =
|
|
46083
|
+
var OPENCODE_CONFIG_PATH = path34.join(CONFIG_DIR, "opencode.json");
|
|
46084
|
+
var PLUGIN_CONFIG_PATH = path34.join(CONFIG_DIR, "opencode-swarm.json");
|
|
46085
|
+
var PROMPTS_DIR = path34.join(CONFIG_DIR, "opencode-swarm");
|
|
46044
46086
|
var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
|
|
46087
|
+
var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
|
|
46045
46088
|
function isSafeCachePath(p) {
|
|
46046
|
-
const resolved =
|
|
46047
|
-
const home =
|
|
46089
|
+
const resolved = path34.resolve(p);
|
|
46090
|
+
const home = path34.resolve(os7.homedir());
|
|
46048
46091
|
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
46049
46092
|
return false;
|
|
46050
46093
|
}
|
|
46051
|
-
const segments = resolved.split(
|
|
46094
|
+
const segments = resolved.split(path34.sep).filter((s) => s.length > 0);
|
|
46052
46095
|
if (segments.length < 4) {
|
|
46053
46096
|
return false;
|
|
46054
46097
|
}
|
|
46055
|
-
const leaf =
|
|
46098
|
+
const leaf = path34.basename(resolved);
|
|
46056
46099
|
if (leaf !== "opencode-swarm@latest" && leaf !== "opencode-swarm") {
|
|
46057
46100
|
return false;
|
|
46058
46101
|
}
|
|
46059
|
-
const parent =
|
|
46102
|
+
const parent = path34.basename(path34.dirname(resolved));
|
|
46060
46103
|
if (parent !== "packages" && parent !== "node_modules") {
|
|
46061
46104
|
return false;
|
|
46062
46105
|
}
|
|
46063
|
-
const grandparent =
|
|
46106
|
+
const grandparent = path34.basename(path34.dirname(path34.dirname(resolved)));
|
|
46064
46107
|
if (grandparent !== "opencode") {
|
|
46065
46108
|
return false;
|
|
46066
46109
|
}
|
|
46067
46110
|
return true;
|
|
46068
46111
|
}
|
|
46112
|
+
function isSafeLockFilePath(p) {
|
|
46113
|
+
const resolved = path34.resolve(p);
|
|
46114
|
+
const home = path34.resolve(os7.homedir());
|
|
46115
|
+
if (resolved === "/" || resolved === home || resolved.length <= home.length) {
|
|
46116
|
+
return false;
|
|
46117
|
+
}
|
|
46118
|
+
const segments = resolved.split(path34.sep).filter((s) => s.length > 0);
|
|
46119
|
+
if (segments.length < 4) {
|
|
46120
|
+
return false;
|
|
46121
|
+
}
|
|
46122
|
+
const leaf = path34.basename(resolved);
|
|
46123
|
+
if (leaf !== "bun.lock" && leaf !== "bun.lockb" && leaf !== "package-lock.json") {
|
|
46124
|
+
return false;
|
|
46125
|
+
}
|
|
46126
|
+
const parent = path34.basename(path34.dirname(resolved));
|
|
46127
|
+
if (parent !== "opencode") {
|
|
46128
|
+
return false;
|
|
46129
|
+
}
|
|
46130
|
+
return true;
|
|
46131
|
+
}
|
|
46069
46132
|
function ensureDir(dir) {
|
|
46070
46133
|
if (!fs21.existsSync(dir)) {
|
|
46071
46134
|
fs21.mkdirSync(dir, { recursive: true });
|
|
@@ -46086,8 +46149,8 @@ function saveJson(filepath, data) {
|
|
|
46086
46149
|
}
|
|
46087
46150
|
function writeProjectConfigIfMissing(cwd) {
|
|
46088
46151
|
try {
|
|
46089
|
-
const opencodeDir =
|
|
46090
|
-
const projectConfigPath =
|
|
46152
|
+
const opencodeDir = path34.join(cwd, ".opencode");
|
|
46153
|
+
const projectConfigPath = path34.join(opencodeDir, "opencode-swarm.json");
|
|
46091
46154
|
if (fs21.existsSync(projectConfigPath)) {
|
|
46092
46155
|
return;
|
|
46093
46156
|
}
|
|
@@ -46105,7 +46168,7 @@ async function install() {
|
|
|
46105
46168
|
`);
|
|
46106
46169
|
ensureDir(CONFIG_DIR);
|
|
46107
46170
|
ensureDir(PROMPTS_DIR);
|
|
46108
|
-
const LEGACY_CONFIG_PATH =
|
|
46171
|
+
const LEGACY_CONFIG_PATH = path34.join(CONFIG_DIR, "config.json");
|
|
46109
46172
|
let opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
46110
46173
|
if (!opencodeConfig) {
|
|
46111
46174
|
const legacyConfig = loadJson(LEGACY_CONFIG_PATH);
|
|
@@ -46144,6 +46207,14 @@ async function install() {
|
|
|
46144
46207
|
console.warn(`\u26A0 Could not clear opencode plugin cache \u2014 you may need to delete it manually:
|
|
46145
46208
|
${failed}`);
|
|
46146
46209
|
}
|
|
46210
|
+
const lockEvicted = evictLockFiles();
|
|
46211
|
+
if (lockEvicted.cleared.length > 0) {
|
|
46212
|
+
console.log(`\u2713 Cleared opencode lock file(s) (next start will fetch latest): ${lockEvicted.cleared.join(", ")}`);
|
|
46213
|
+
}
|
|
46214
|
+
for (const failed of lockEvicted.failed) {
|
|
46215
|
+
console.warn(`\u26A0 Could not clear opencode lock file \u2014 you may need to delete it manually:
|
|
46216
|
+
${failed}`);
|
|
46217
|
+
}
|
|
46147
46218
|
if (!fs21.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
46148
46219
|
const defaultConfig = {
|
|
46149
46220
|
agents: {
|
|
@@ -46246,6 +46317,7 @@ async function update() {
|
|
|
46246
46317
|
console.log(`\uD83D\uDC1D Refreshing OpenCode Swarm plugin cache...
|
|
46247
46318
|
`);
|
|
46248
46319
|
const result = evictPluginCaches();
|
|
46320
|
+
const lockResult = evictLockFiles();
|
|
46249
46321
|
if (result.cleared.length > 0) {
|
|
46250
46322
|
for (const cleared of result.cleared) {
|
|
46251
46323
|
console.log(`\u2713 Cleared: ${cleared}`);
|
|
@@ -46253,17 +46325,33 @@ async function update() {
|
|
|
46253
46325
|
console.log(`
|
|
46254
46326
|
Restart OpenCode to fetch the latest version from npm.`);
|
|
46255
46327
|
}
|
|
46256
|
-
if (
|
|
46328
|
+
if (lockResult.cleared.length > 0) {
|
|
46329
|
+
for (const cleared of lockResult.cleared) {
|
|
46330
|
+
console.log(`\u2713 Cleared lock file: ${cleared}`);
|
|
46331
|
+
}
|
|
46332
|
+
}
|
|
46333
|
+
if (lockResult.failed.length > 0) {
|
|
46334
|
+
for (const failed of lockResult.failed) {
|
|
46335
|
+
console.error(`\u2717 Could not clear lock file: ${failed}`);
|
|
46336
|
+
}
|
|
46337
|
+
}
|
|
46338
|
+
if (result.cleared.length === 0 && result.failed.length === 0 && lockResult.cleared.length === 0 && lockResult.failed.length === 0) {
|
|
46257
46339
|
console.log("No cached plugin found. Restart OpenCode to fetch the latest version from npm.");
|
|
46258
46340
|
console.log("Checked locations:");
|
|
46259
46341
|
for (const p of OPENCODE_PLUGIN_CACHE_PATHS) {
|
|
46260
46342
|
console.log(` - ${p}`);
|
|
46261
46343
|
}
|
|
46344
|
+
console.log("Lock files checked:");
|
|
46345
|
+
for (const p of OPENCODE_PLUGIN_LOCK_FILE_PATHS) {
|
|
46346
|
+
console.log(` - ${p}`);
|
|
46347
|
+
}
|
|
46262
46348
|
}
|
|
46263
46349
|
if (result.failed.length > 0) {
|
|
46264
46350
|
for (const failed of result.failed) {
|
|
46265
46351
|
console.error(`\u2717 Could not clear: ${failed}`);
|
|
46266
46352
|
}
|
|
46353
|
+
}
|
|
46354
|
+
if (result.failed.length > 0 || lockResult.failed.length > 0) {
|
|
46267
46355
|
return 1;
|
|
46268
46356
|
}
|
|
46269
46357
|
return 0;
|
|
@@ -46287,6 +46375,30 @@ function evictPluginCaches() {
|
|
|
46287
46375
|
}
|
|
46288
46376
|
return { cleared, failed };
|
|
46289
46377
|
}
|
|
46378
|
+
function evictLockFiles() {
|
|
46379
|
+
const cleared = [];
|
|
46380
|
+
const failed = [];
|
|
46381
|
+
for (const lockPath of OPENCODE_PLUGIN_LOCK_FILE_PATHS) {
|
|
46382
|
+
if (!fs21.existsSync(lockPath))
|
|
46383
|
+
continue;
|
|
46384
|
+
if (!isSafeLockFilePath(lockPath)) {
|
|
46385
|
+
failed.push(`${lockPath} (refused: failed safety check)`);
|
|
46386
|
+
continue;
|
|
46387
|
+
}
|
|
46388
|
+
try {
|
|
46389
|
+
fs21.unlinkSync(lockPath);
|
|
46390
|
+
cleared.push(lockPath);
|
|
46391
|
+
} catch (err) {
|
|
46392
|
+
const code = err?.code;
|
|
46393
|
+
if (code === "EISDIR") {
|
|
46394
|
+
failed.push(`${lockPath} (path is a directory, not a file)`);
|
|
46395
|
+
} else {
|
|
46396
|
+
failed.push(`${lockPath} (${err instanceof Error ? err.message : String(err)})`);
|
|
46397
|
+
}
|
|
46398
|
+
}
|
|
46399
|
+
}
|
|
46400
|
+
return { cleared, failed };
|
|
46401
|
+
}
|
|
46290
46402
|
async function uninstall() {
|
|
46291
46403
|
try {
|
|
46292
46404
|
console.log(`\uD83D\uDC1D Uninstalling OpenCode Swarm...
|
|
@@ -46452,5 +46564,9 @@ Valid commands: ${VALID_COMMANDS.join(", ")}`);
|
|
|
46452
46564
|
return 0;
|
|
46453
46565
|
}
|
|
46454
46566
|
export {
|
|
46455
|
-
run
|
|
46567
|
+
run,
|
|
46568
|
+
isSafeLockFilePath,
|
|
46569
|
+
isSafeCachePath,
|
|
46570
|
+
evictPluginCaches,
|
|
46571
|
+
evictLockFiles
|
|
46456
46572
|
};
|
package/dist/commands/reset.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Handles the /swarm reset command.
|
|
3
|
-
* Clears
|
|
3
|
+
* Clears all swarm state files from .swarm/ and project root.
|
|
4
4
|
* Stops background automation and resets in-memory queues.
|
|
5
5
|
* Requires --confirm flag as a safety gate.
|
|
6
6
|
*/
|
|
@@ -9,3 +9,9 @@ export declare function getPluginConfigDir(): string;
|
|
|
9
9
|
* path at the top.
|
|
10
10
|
*/
|
|
11
11
|
export declare function getPluginCachePaths(): readonly string[];
|
|
12
|
+
/**
|
|
13
|
+
* All known locations where OpenCode stores npm lock files for the plugin
|
|
14
|
+
* environment. These pin the installed version of opencode-swarm and must
|
|
15
|
+
* be cleared during update/install to force a fresh resolution from npm.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getPluginLockFilePaths(): readonly string[];
|