@khalilgharbaoui/opencode-claude-code-plugin 0.36.5 → 0.37.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/index.js +290 -107
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/skills/claude-code-plugin/SKILL.md +13 -0
package/dist/index.js
CHANGED
|
@@ -5471,6 +5471,7 @@ var PLUGIN_LOG_MESSAGES = /* @__PURE__ */ new Set([
|
|
|
5471
5471
|
"skipping remote MCP server with no url",
|
|
5472
5472
|
"stale scratch directory sweep failed",
|
|
5473
5473
|
"task_batch resolving with child results missing",
|
|
5474
|
+
"this opencode process is running an older plugin build than the one on disk",
|
|
5474
5475
|
"timed out pending proxy call",
|
|
5475
5476
|
"turn abort listener threw",
|
|
5476
5477
|
"two different skills share a name; bridging the one the nearest root claimed",
|
|
@@ -5619,6 +5620,10 @@ var BUNDLE_DATA_ALLOWLIST = {
|
|
|
5619
5620
|
toolNames: "name",
|
|
5620
5621
|
cliFloor: "version",
|
|
5621
5622
|
cliVersion: "version",
|
|
5623
|
+
// The two halves of the stale-build WARN: what this process loaded and what
|
|
5624
|
+
// is on disk now. Both are this package's own version strings.
|
|
5625
|
+
loadedVersion: "version",
|
|
5626
|
+
onDiskVersion: "version",
|
|
5622
5627
|
opencode: "version",
|
|
5623
5628
|
plugin: "version",
|
|
5624
5629
|
version: "version",
|
|
@@ -5868,8 +5873,8 @@ function redactLogLine(raw, context) {
|
|
|
5868
5873
|
if (!parsed.data || Object.keys(parsed.data).length === 0) return head;
|
|
5869
5874
|
return `${head} ${JSON.stringify(sanitizeLogData(parsed.data, context))}`;
|
|
5870
5875
|
}
|
|
5871
|
-
function readLogTail(
|
|
5872
|
-
const fd = openSync(
|
|
5876
|
+
function readLogTail(path11, maxBytes = BUNDLE_TAIL_BYTES) {
|
|
5877
|
+
const fd = openSync(path11, "r");
|
|
5873
5878
|
try {
|
|
5874
5879
|
const size = fstatSync(fd).size;
|
|
5875
5880
|
const length = Math.min(size, maxBytes);
|
|
@@ -6059,6 +6064,11 @@ async function fetchPlanUsage(cliPath, options = {}) {
|
|
|
6059
6064
|
}
|
|
6060
6065
|
}
|
|
6061
6066
|
|
|
6067
|
+
// src/stale-build.ts
|
|
6068
|
+
import * as fs5 from "fs";
|
|
6069
|
+
import * as path6 from "path";
|
|
6070
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6071
|
+
|
|
6062
6072
|
// src/startup-diagnostics.ts
|
|
6063
6073
|
import { execFile as execFile3 } from "child_process";
|
|
6064
6074
|
import * as fs4 from "fs";
|
|
@@ -6198,6 +6208,161 @@ function logStartupDiagnostics(providers, opencodeVersion) {
|
|
|
6198
6208
|
})();
|
|
6199
6209
|
}
|
|
6200
6210
|
|
|
6211
|
+
// src/stale-build.ts
|
|
6212
|
+
var STALE_BUILD_MARKER = "\u258C **restart opencode:**";
|
|
6213
|
+
var STALE_BUILD_THROTTLE_MS = 6e4;
|
|
6214
|
+
var STALE_BUILD_SESSION_CAP = 64;
|
|
6215
|
+
function compareBuilds(loaded, onDisk) {
|
|
6216
|
+
if (!onDisk) return null;
|
|
6217
|
+
if (onDisk.version !== loaded.version) {
|
|
6218
|
+
return {
|
|
6219
|
+
kind: "version",
|
|
6220
|
+
loadedVersion: loaded.version,
|
|
6221
|
+
onDiskVersion: onDisk.version,
|
|
6222
|
+
loadedAt: loaded.loadedAt
|
|
6223
|
+
};
|
|
6224
|
+
}
|
|
6225
|
+
if (loaded.mtimeMs === void 0 || loaded.size === void 0) return null;
|
|
6226
|
+
if (onDisk.mtimeMs === loaded.mtimeMs && onDisk.size === loaded.size) return null;
|
|
6227
|
+
return {
|
|
6228
|
+
kind: "rebuilt",
|
|
6229
|
+
loadedVersion: loaded.version,
|
|
6230
|
+
onDiskVersion: onDisk.version,
|
|
6231
|
+
loadedAt: loaded.loadedAt,
|
|
6232
|
+
rebuiltAt: onDisk.mtimeMs
|
|
6233
|
+
};
|
|
6234
|
+
}
|
|
6235
|
+
function formatLocalMinute(ms) {
|
|
6236
|
+
const when = new Date(ms);
|
|
6237
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
6238
|
+
return `${when.getFullYear()}-${pad(when.getMonth() + 1)}-${pad(when.getDate())} ${pad(when.getHours())}:${pad(when.getMinutes())}`;
|
|
6239
|
+
}
|
|
6240
|
+
function formatStaleBuildNote(stale) {
|
|
6241
|
+
const loadedAt = formatLocalMinute(stale.loadedAt);
|
|
6242
|
+
if (stale.kind === "version") {
|
|
6243
|
+
return `${STALE_BUILD_MARKER} plugin ${stale.onDiskVersion} is on disk, but this opencode process still runs ${stale.loadedVersion}, loaded ${loadedAt}. opencode reads a plugin once at startup, so fixes since then are not active here: quit every opencode window and relaunch.`;
|
|
6244
|
+
}
|
|
6245
|
+
const rebuiltAt = stale.rebuiltAt === void 0 ? "since" : `at ${formatLocalMinute(stale.rebuiltAt)}`;
|
|
6246
|
+
return `${STALE_BUILD_MARKER} this opencode process loaded plugin ${stale.loadedVersion} at ${loadedAt}, and that build was rebuilt on disk ${rebuiltAt}. opencode reads a plugin once at startup, so what you just built is not running here: quit every opencode window and relaunch.`;
|
|
6247
|
+
}
|
|
6248
|
+
function describeBuildStatus(status) {
|
|
6249
|
+
const loadedAt = formatLocalMinute(status.loaded.loadedAt);
|
|
6250
|
+
switch (status.verdict) {
|
|
6251
|
+
case "current":
|
|
6252
|
+
return `${status.loaded.version}, loaded ${loadedAt}, current`;
|
|
6253
|
+
case "version":
|
|
6254
|
+
return `${status.loaded.version}, loaded ${loadedAt}; on disk ${status.onDisk?.version ?? "unknown"}. Restart opencode to run it`;
|
|
6255
|
+
case "rebuilt":
|
|
6256
|
+
return `${status.loaded.version}, loaded ${loadedAt}; the same version was rebuilt on disk ${status.onDisk ? `at ${formatLocalMinute(status.onDisk.mtimeMs)}` : "since"}. Restart opencode to run it`;
|
|
6257
|
+
case "unreadable":
|
|
6258
|
+
return `${status.loaded.version}, loaded ${loadedAt}; the build on disk could not be read`;
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6261
|
+
function createStaleBuildWatch(io) {
|
|
6262
|
+
const throttleMs = io.throttleMs ?? STALE_BUILD_THROTTLE_MS;
|
|
6263
|
+
const warn = io.warn ?? ((data) => {
|
|
6264
|
+
log.warn(
|
|
6265
|
+
"this opencode process is running an older plugin build than the one on disk",
|
|
6266
|
+
data
|
|
6267
|
+
);
|
|
6268
|
+
});
|
|
6269
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
6270
|
+
const warned = /* @__PURE__ */ new Set();
|
|
6271
|
+
let checkedAt;
|
|
6272
|
+
let cached = null;
|
|
6273
|
+
const read = () => {
|
|
6274
|
+
let onDisk;
|
|
6275
|
+
try {
|
|
6276
|
+
onDisk = io.readOnDisk();
|
|
6277
|
+
} catch {
|
|
6278
|
+
onDisk = void 0;
|
|
6279
|
+
}
|
|
6280
|
+
const stale = compareBuilds(io.loaded, onDisk);
|
|
6281
|
+
const verdict = !onDisk ? "unreadable" : stale ? stale.kind : "current";
|
|
6282
|
+
return { loaded: io.loaded, onDisk, stale, verdict };
|
|
6283
|
+
};
|
|
6284
|
+
return {
|
|
6285
|
+
get loaded() {
|
|
6286
|
+
return io.loaded;
|
|
6287
|
+
},
|
|
6288
|
+
check() {
|
|
6289
|
+
const now = io.now();
|
|
6290
|
+
if (checkedAt !== void 0 && now - checkedAt < throttleMs) return cached;
|
|
6291
|
+
checkedAt = now;
|
|
6292
|
+
const status = read();
|
|
6293
|
+
cached = status.stale;
|
|
6294
|
+
if (status.stale && status.onDisk) {
|
|
6295
|
+
const identity = `${status.stale.kind}:${status.onDisk.version}:${status.onDisk.mtimeMs}:${status.onDisk.size}`;
|
|
6296
|
+
if (!warned.has(identity)) {
|
|
6297
|
+
warned.add(identity);
|
|
6298
|
+
warn({
|
|
6299
|
+
kind: status.stale.kind,
|
|
6300
|
+
loadedVersion: status.stale.loadedVersion,
|
|
6301
|
+
onDiskVersion: status.stale.onDiskVersion,
|
|
6302
|
+
path: io.loaded.entryPath
|
|
6303
|
+
});
|
|
6304
|
+
}
|
|
6305
|
+
}
|
|
6306
|
+
return cached;
|
|
6307
|
+
},
|
|
6308
|
+
describe() {
|
|
6309
|
+
return read();
|
|
6310
|
+
},
|
|
6311
|
+
claimSession(sessionId) {
|
|
6312
|
+
if (claimed.has(sessionId)) return false;
|
|
6313
|
+
claimed.add(sessionId);
|
|
6314
|
+
while (claimed.size > STALE_BUILD_SESSION_CAP) {
|
|
6315
|
+
const oldest = claimed.values().next();
|
|
6316
|
+
if (oldest.done) break;
|
|
6317
|
+
claimed.delete(oldest.value);
|
|
6318
|
+
}
|
|
6319
|
+
return true;
|
|
6320
|
+
},
|
|
6321
|
+
claimedSessions() {
|
|
6322
|
+
return [...claimed];
|
|
6323
|
+
}
|
|
6324
|
+
};
|
|
6325
|
+
}
|
|
6326
|
+
function defaultEntryPath() {
|
|
6327
|
+
return fileURLToPath2(import.meta.url);
|
|
6328
|
+
}
|
|
6329
|
+
function readOnDiskBuild(entryPath) {
|
|
6330
|
+
try {
|
|
6331
|
+
const raw = fs5.readFileSync(path6.join(path6.dirname(entryPath), "..", "package.json"), "utf8");
|
|
6332
|
+
const version = JSON.parse(raw).version;
|
|
6333
|
+
if (typeof version !== "string" || version.length === 0) return void 0;
|
|
6334
|
+
const stat = fs5.statSync(entryPath);
|
|
6335
|
+
return { version, mtimeMs: stat.mtimeMs, size: stat.size };
|
|
6336
|
+
} catch {
|
|
6337
|
+
return void 0;
|
|
6338
|
+
}
|
|
6339
|
+
}
|
|
6340
|
+
function recordLoadedBuild() {
|
|
6341
|
+
const entryPath = defaultEntryPath();
|
|
6342
|
+
let mtimeMs;
|
|
6343
|
+
let size;
|
|
6344
|
+
try {
|
|
6345
|
+
const stat = fs5.statSync(entryPath);
|
|
6346
|
+
mtimeMs = stat.mtimeMs;
|
|
6347
|
+
size = stat.size;
|
|
6348
|
+
} catch {
|
|
6349
|
+
}
|
|
6350
|
+
return { version: pluginVersion(), entryPath, mtimeMs, size, loadedAt: Date.now() };
|
|
6351
|
+
}
|
|
6352
|
+
var loadedAtImport = recordLoadedBuild();
|
|
6353
|
+
var watch;
|
|
6354
|
+
function staleBuildWatch() {
|
|
6355
|
+
if (!watch) {
|
|
6356
|
+
const loaded = loadedAtImport;
|
|
6357
|
+
watch = createStaleBuildWatch({
|
|
6358
|
+
loaded,
|
|
6359
|
+
readOnDisk: () => readOnDiskBuild(loaded.entryPath),
|
|
6360
|
+
now: () => Date.now()
|
|
6361
|
+
});
|
|
6362
|
+
}
|
|
6363
|
+
return watch;
|
|
6364
|
+
}
|
|
6365
|
+
|
|
6201
6366
|
// src/doctor.ts
|
|
6202
6367
|
var DOCTOR_COMMAND = "claude-code-doctor";
|
|
6203
6368
|
var DOCTOR_COMMAND_DESCRIPTION = "Report what the Claude Code plugin sees: versions, cwd, live processes, pending proxy calls. Add `usage` for plan windows, or `bundle` for a redacted log you can paste into an issue";
|
|
@@ -6269,6 +6434,7 @@ function formatDoctorReport(report) {
|
|
|
6269
6434
|
lines.push("| Field | Value |");
|
|
6270
6435
|
lines.push("|---|---|");
|
|
6271
6436
|
lines.push(`| plugin | ${report.plugin} |`);
|
|
6437
|
+
lines.push(`| plugin build | ${describeBuildStatus(report.build)} |`);
|
|
6272
6438
|
lines.push(`| opencode | ${report.opencode} |`);
|
|
6273
6439
|
lines.push(`| claude CLI | \`${report.claudeCli.path}\` (${report.claudeCli.version}) |`);
|
|
6274
6440
|
lines.push(`| cwd | \`${report.cwd.resolved}\` (${report.cwd.source}) |`);
|
|
@@ -6512,6 +6678,8 @@ async function gatherDoctorReport(options) {
|
|
|
6512
6678
|
}) : { status: "not-requested" };
|
|
6513
6679
|
return {
|
|
6514
6680
|
plugin: base.plugin,
|
|
6681
|
+
// `describe`, not `check`: unthrottled, silent, and it claims no session.
|
|
6682
|
+
build: staleBuildWatch().describe(),
|
|
6515
6683
|
opencode: base.opencode,
|
|
6516
6684
|
claudeCli: { path: cliPath, version: cli?.raw ?? "not detected" },
|
|
6517
6685
|
cwd: base.cwd,
|
|
@@ -6578,6 +6746,7 @@ async function buildDoctorReport(options) {
|
|
|
6578
6746
|
const report = await gatherDoctorReport(options);
|
|
6579
6747
|
log.info("claude-code doctor report", {
|
|
6580
6748
|
plugin: report.plugin,
|
|
6749
|
+
verdict: report.build.verdict,
|
|
6581
6750
|
opencode: report.opencode,
|
|
6582
6751
|
cwd: report.cwd,
|
|
6583
6752
|
processes: report.processes.length,
|
|
@@ -6601,7 +6770,7 @@ Could not build the report: ${message}`;
|
|
|
6601
6770
|
|
|
6602
6771
|
// src/agent-models.ts
|
|
6603
6772
|
import { readFile, readdir } from "fs/promises";
|
|
6604
|
-
import
|
|
6773
|
+
import path7 from "path";
|
|
6605
6774
|
|
|
6606
6775
|
// src/models.ts
|
|
6607
6776
|
var PROVIDER_ID = "claude-code";
|
|
@@ -7104,11 +7273,11 @@ async function readAgentMarkdownRecords(directories) {
|
|
|
7104
7273
|
const name = entry.slice(0, -3);
|
|
7105
7274
|
if (records[name]) continue;
|
|
7106
7275
|
try {
|
|
7107
|
-
const text = await readFile(
|
|
7276
|
+
const text = await readFile(path7.join(directory, entry), "utf8");
|
|
7108
7277
|
records[name] = parseAgentFrontmatter(text);
|
|
7109
7278
|
} catch (err) {
|
|
7110
7279
|
log.debug("failed to read agent markdown", {
|
|
7111
|
-
file:
|
|
7280
|
+
file: path7.join(directory, entry),
|
|
7112
7281
|
error: String(err)
|
|
7113
7282
|
});
|
|
7114
7283
|
}
|
|
@@ -7120,12 +7289,12 @@ function agentDirectories(home, projectDirectory) {
|
|
|
7120
7289
|
const directories = [];
|
|
7121
7290
|
if (projectDirectory) {
|
|
7122
7291
|
for (const name of AGENT_DIR_NAMES) {
|
|
7123
|
-
directories.push(
|
|
7292
|
+
directories.push(path7.join(projectDirectory, ".opencode", name));
|
|
7124
7293
|
}
|
|
7125
7294
|
}
|
|
7126
7295
|
if (home) {
|
|
7127
7296
|
for (const name of AGENT_DIR_NAMES) {
|
|
7128
|
-
directories.push(
|
|
7297
|
+
directories.push(path7.join(home, ".config", "opencode", name));
|
|
7129
7298
|
}
|
|
7130
7299
|
}
|
|
7131
7300
|
return directories;
|
|
@@ -7294,7 +7463,8 @@ var PLUGIN_NOTE_MARKERS = [
|
|
|
7294
7463
|
FAILOVER_MARKER,
|
|
7295
7464
|
ACCOUNT_BLOCK_MARKER,
|
|
7296
7465
|
MODEL_FALLBACK_MARKER,
|
|
7297
|
-
UNATTENDED_REPLAY_MARKER
|
|
7466
|
+
UNATTENDED_REPLAY_MARKER,
|
|
7467
|
+
STALE_BUILD_MARKER
|
|
7298
7468
|
];
|
|
7299
7469
|
function isPluginNote(part) {
|
|
7300
7470
|
if (!part || part.type !== "text" || typeof part.text !== "string") return false;
|
|
@@ -7681,14 +7851,14 @@ Now continuing with the current message:
|
|
|
7681
7851
|
|
|
7682
7852
|
// src/skill-bridge.ts
|
|
7683
7853
|
import * as crypto3 from "crypto";
|
|
7684
|
-
import * as
|
|
7854
|
+
import * as fs6 from "fs";
|
|
7685
7855
|
import * as os3 from "os";
|
|
7686
|
-
import * as
|
|
7687
|
-
import { fileURLToPath as
|
|
7856
|
+
import * as path8 from "path";
|
|
7857
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7688
7858
|
function bundledSkillsDir() {
|
|
7689
7859
|
try {
|
|
7690
|
-
const here =
|
|
7691
|
-
const dir =
|
|
7860
|
+
const here = fileURLToPath3(import.meta.url);
|
|
7861
|
+
const dir = path8.resolve(path8.dirname(here), "..", "skills");
|
|
7692
7862
|
return dirExists2(dir) ? dir : null;
|
|
7693
7863
|
} catch {
|
|
7694
7864
|
return null;
|
|
@@ -7696,16 +7866,16 @@ function bundledSkillsDir() {
|
|
|
7696
7866
|
}
|
|
7697
7867
|
function dirExists2(p) {
|
|
7698
7868
|
try {
|
|
7699
|
-
return
|
|
7869
|
+
return fs6.statSync(p).isDirectory();
|
|
7700
7870
|
} catch {
|
|
7701
7871
|
return false;
|
|
7702
7872
|
}
|
|
7703
7873
|
}
|
|
7704
7874
|
function realPath(p) {
|
|
7705
7875
|
try {
|
|
7706
|
-
return
|
|
7876
|
+
return fs6.realpathSync(p);
|
|
7707
7877
|
} catch {
|
|
7708
|
-
return
|
|
7878
|
+
return path8.resolve(p);
|
|
7709
7879
|
}
|
|
7710
7880
|
}
|
|
7711
7881
|
function envEnabled(name) {
|
|
@@ -7726,10 +7896,10 @@ function declaredSkillName(source) {
|
|
|
7726
7896
|
return SAFE_SKILL_NAME.test(name) ? name : null;
|
|
7727
7897
|
}
|
|
7728
7898
|
function readSkill(root, entry) {
|
|
7729
|
-
const dir =
|
|
7899
|
+
const dir = path8.join(root, entry);
|
|
7730
7900
|
let source;
|
|
7731
7901
|
try {
|
|
7732
|
-
source =
|
|
7902
|
+
source = fs6.readFileSync(path8.join(dir, "SKILL.md"), "utf8");
|
|
7733
7903
|
} catch {
|
|
7734
7904
|
return null;
|
|
7735
7905
|
}
|
|
@@ -7747,47 +7917,47 @@ function skillRoots(cwd) {
|
|
|
7747
7917
|
const roots = [];
|
|
7748
7918
|
const seen = /* @__PURE__ */ new Set();
|
|
7749
7919
|
const push = (p) => {
|
|
7750
|
-
const abs =
|
|
7920
|
+
const abs = path8.resolve(p);
|
|
7751
7921
|
if (seen.has(abs)) return;
|
|
7752
7922
|
seen.add(abs);
|
|
7753
7923
|
if (dirExists2(abs)) roots.push(abs);
|
|
7754
7924
|
};
|
|
7755
7925
|
const home = os3.homedir();
|
|
7756
|
-
const homeDir = home ?
|
|
7757
|
-
let current =
|
|
7926
|
+
const homeDir = home ? path8.resolve(home) : null;
|
|
7927
|
+
let current = path8.resolve(cwd);
|
|
7758
7928
|
while (true) {
|
|
7759
|
-
push(
|
|
7929
|
+
push(path8.join(current, ".opencode", "skills"));
|
|
7760
7930
|
if (current !== homeDir) {
|
|
7761
|
-
push(
|
|
7762
|
-
push(
|
|
7931
|
+
push(path8.join(current, ".claude", "skills"));
|
|
7932
|
+
push(path8.join(current, ".agents", "skills"));
|
|
7763
7933
|
}
|
|
7764
|
-
const parent =
|
|
7934
|
+
const parent = path8.dirname(current);
|
|
7765
7935
|
if (parent === current) break;
|
|
7766
7936
|
current = parent;
|
|
7767
7937
|
}
|
|
7768
|
-
if (homeDir) push(
|
|
7938
|
+
if (homeDir) push(path8.join(homeDir, ".opencode", "skills"));
|
|
7769
7939
|
const envDir = process.env.OPENCODE_CONFIG_DIR;
|
|
7770
7940
|
if (envDir) {
|
|
7771
|
-
push(
|
|
7772
|
-
push(
|
|
7941
|
+
push(path8.join(envDir, "skills"));
|
|
7942
|
+
push(path8.join(envDir, "skill"));
|
|
7773
7943
|
}
|
|
7774
|
-
const xdg = process.env.XDG_CONFIG_HOME ?? (homeDir ?
|
|
7944
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? (homeDir ? path8.join(homeDir, ".config") : null);
|
|
7775
7945
|
if (xdg) {
|
|
7776
|
-
push(
|
|
7777
|
-
push(
|
|
7946
|
+
push(path8.join(xdg, "opencode", "skills"));
|
|
7947
|
+
push(path8.join(xdg, "opencode", "skill"));
|
|
7778
7948
|
}
|
|
7779
7949
|
if (homeDir && !envEnabled("OPENCODE_DISABLE_EXTERNAL_SKILLS")) {
|
|
7780
7950
|
if (!envEnabled("OPENCODE_DISABLE_CLAUDE_CODE_SKILLS")) {
|
|
7781
|
-
push(
|
|
7951
|
+
push(path8.join(homeDir, ".claude", "skills"));
|
|
7782
7952
|
}
|
|
7783
|
-
push(
|
|
7953
|
+
push(path8.join(homeDir, ".agents", "skills"));
|
|
7784
7954
|
}
|
|
7785
7955
|
return roots;
|
|
7786
7956
|
}
|
|
7787
7957
|
function collectSkills(root, claimed, found) {
|
|
7788
7958
|
let entries;
|
|
7789
7959
|
try {
|
|
7790
|
-
entries =
|
|
7960
|
+
entries = fs6.readdirSync(root, { withFileTypes: true });
|
|
7791
7961
|
} catch {
|
|
7792
7962
|
return;
|
|
7793
7963
|
}
|
|
@@ -7827,23 +7997,23 @@ function discoverBundledSkills() {
|
|
|
7827
7997
|
}
|
|
7828
7998
|
function claudeConfigDir(configDir) {
|
|
7829
7999
|
const explicit = configDir ?? process.env.CLAUDE_CONFIG_DIR;
|
|
7830
|
-
if (explicit) return
|
|
8000
|
+
if (explicit) return path8.resolve(expandHome(explicit));
|
|
7831
8001
|
const home = os3.homedir();
|
|
7832
|
-
return home ?
|
|
8002
|
+
return home ? path8.resolve(home, ".claude") : null;
|
|
7833
8003
|
}
|
|
7834
8004
|
function installedPluginSkillRoots(configDir, cwd) {
|
|
7835
8005
|
if (!configDir) return [];
|
|
7836
8006
|
let parsed;
|
|
7837
8007
|
try {
|
|
7838
8008
|
parsed = JSON.parse(
|
|
7839
|
-
|
|
8009
|
+
fs6.readFileSync(path8.join(configDir, "plugins", "installed_plugins.json"), "utf8")
|
|
7840
8010
|
);
|
|
7841
8011
|
} catch {
|
|
7842
8012
|
return [];
|
|
7843
8013
|
}
|
|
7844
8014
|
const plugins = parsed?.plugins;
|
|
7845
8015
|
if (!plugins || typeof plugins !== "object") return [];
|
|
7846
|
-
const workspace =
|
|
8016
|
+
const workspace = path8.resolve(cwd);
|
|
7847
8017
|
const roots = [];
|
|
7848
8018
|
for (const installs of Object.values(plugins)) {
|
|
7849
8019
|
if (!Array.isArray(installs)) continue;
|
|
@@ -7851,28 +8021,28 @@ function installedPluginSkillRoots(configDir, cwd) {
|
|
|
7851
8021
|
const entry = install;
|
|
7852
8022
|
if (typeof entry?.installPath !== "string" || !entry.installPath) continue;
|
|
7853
8023
|
if (entry.scope !== "user" && !coversWorkspace(entry.projectPath, workspace)) continue;
|
|
7854
|
-
roots.push(
|
|
8024
|
+
roots.push(path8.join(entry.installPath, "skills"));
|
|
7855
8025
|
}
|
|
7856
8026
|
}
|
|
7857
8027
|
return roots;
|
|
7858
8028
|
}
|
|
7859
8029
|
function coversWorkspace(projectPath, workspace) {
|
|
7860
8030
|
if (typeof projectPath !== "string" || !projectPath) return false;
|
|
7861
|
-
const root =
|
|
8031
|
+
const root = path8.resolve(projectPath);
|
|
7862
8032
|
if (root === workspace) return true;
|
|
7863
|
-
const rel =
|
|
7864
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
8033
|
+
const rel = path8.relative(root, workspace);
|
|
8034
|
+
return rel !== "" && !rel.startsWith("..") && !path8.isAbsolute(rel);
|
|
7865
8035
|
}
|
|
7866
8036
|
function discoverNativeClaudeSkills(opts) {
|
|
7867
8037
|
const found = [];
|
|
7868
8038
|
const scanned = /* @__PURE__ */ new Set();
|
|
7869
8039
|
const scan = (root, scope) => {
|
|
7870
|
-
const abs =
|
|
8040
|
+
const abs = path8.resolve(root);
|
|
7871
8041
|
if (scanned.has(abs)) return;
|
|
7872
8042
|
scanned.add(abs);
|
|
7873
8043
|
let entries;
|
|
7874
8044
|
try {
|
|
7875
|
-
entries =
|
|
8045
|
+
entries = fs6.readdirSync(abs, { withFileTypes: true });
|
|
7876
8046
|
} catch {
|
|
7877
8047
|
return;
|
|
7878
8048
|
}
|
|
@@ -7884,13 +8054,13 @@ function discoverNativeClaudeSkills(opts) {
|
|
|
7884
8054
|
}
|
|
7885
8055
|
};
|
|
7886
8056
|
const configDir = claudeConfigDir(opts.configDir);
|
|
7887
|
-
if (configDir) scan(
|
|
8057
|
+
if (configDir) scan(path8.join(configDir, "skills"), "user");
|
|
7888
8058
|
const home = os3.homedir();
|
|
7889
|
-
const homeDir = home ?
|
|
7890
|
-
let current =
|
|
8059
|
+
const homeDir = home ? path8.resolve(home) : null;
|
|
8060
|
+
let current = path8.resolve(opts.cwd);
|
|
7891
8061
|
while (true) {
|
|
7892
|
-
if (current !== homeDir) scan(
|
|
7893
|
-
const parent =
|
|
8062
|
+
if (current !== homeDir) scan(path8.join(current, ".claude", "skills"), "project");
|
|
8063
|
+
const parent = path8.dirname(current);
|
|
7894
8064
|
if (parent === current) break;
|
|
7895
8065
|
current = parent;
|
|
7896
8066
|
}
|
|
@@ -7924,10 +8094,10 @@ function dropNativelyLoadedSkills(skills, native) {
|
|
|
7924
8094
|
}
|
|
7925
8095
|
function readBundledSkillInfos() {
|
|
7926
8096
|
return discoverBundledSkills().flatMap((skill) => {
|
|
7927
|
-
const file =
|
|
8097
|
+
const file = path8.join(skill.dir, "SKILL.md");
|
|
7928
8098
|
let text;
|
|
7929
8099
|
try {
|
|
7930
|
-
text =
|
|
8100
|
+
text = fs6.readFileSync(file, "utf8");
|
|
7931
8101
|
} catch {
|
|
7932
8102
|
return [];
|
|
7933
8103
|
}
|
|
@@ -7951,15 +8121,15 @@ function readBundledSkillInfos() {
|
|
|
7951
8121
|
}
|
|
7952
8122
|
function linkSkill(source, target) {
|
|
7953
8123
|
try {
|
|
7954
|
-
|
|
8124
|
+
fs6.symlinkSync(source, target, process.platform === "win32" ? "junction" : "dir");
|
|
7955
8125
|
return;
|
|
7956
8126
|
} catch {
|
|
7957
|
-
|
|
8127
|
+
fs6.cpSync(source, target, { recursive: true, dereference: true });
|
|
7958
8128
|
}
|
|
7959
8129
|
}
|
|
7960
8130
|
function fileExists2(p) {
|
|
7961
8131
|
try {
|
|
7962
|
-
return
|
|
8132
|
+
return fs6.statSync(p).isFile();
|
|
7963
8133
|
} catch {
|
|
7964
8134
|
return false;
|
|
7965
8135
|
}
|
|
@@ -7968,14 +8138,14 @@ function buildSkillPluginDir(skills) {
|
|
|
7968
8138
|
if (skills.length === 0) return null;
|
|
7969
8139
|
const fingerprint = skills.map((s) => `${s.name}\0${s.dir}`).join("\n");
|
|
7970
8140
|
const hash = crypto3.createHash("sha256").update(fingerprint).digest("hex").slice(0, 12);
|
|
7971
|
-
const root =
|
|
7972
|
-
const manifest =
|
|
8141
|
+
const root = path8.join(pluginTmpDir(), `skills-${hash}`);
|
|
8142
|
+
const manifest = path8.join(root, ".claude-plugin", "plugin.json");
|
|
7973
8143
|
if (fileExists2(manifest)) return root;
|
|
7974
8144
|
try {
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
8145
|
+
fs6.rmSync(root, { recursive: true, force: true });
|
|
8146
|
+
fs6.mkdirSync(path8.join(root, ".claude-plugin"), { recursive: true });
|
|
8147
|
+
fs6.mkdirSync(path8.join(root, "skills"), { recursive: true });
|
|
8148
|
+
fs6.writeFileSync(
|
|
7979
8149
|
manifest,
|
|
7980
8150
|
JSON.stringify(
|
|
7981
8151
|
{
|
|
@@ -7988,7 +8158,7 @@ function buildSkillPluginDir(skills) {
|
|
|
7988
8158
|
{ encoding: "utf8", mode: 384 }
|
|
7989
8159
|
);
|
|
7990
8160
|
for (const skill of skills) {
|
|
7991
|
-
linkSkill(skill.dir,
|
|
8161
|
+
linkSkill(skill.dir, path8.join(root, "skills", skill.name));
|
|
7992
8162
|
}
|
|
7993
8163
|
} catch (err) {
|
|
7994
8164
|
log.warn("failed to stage opencode skill plugin dir", {
|
|
@@ -8004,7 +8174,7 @@ function registerBundledSkillPath(config) {
|
|
|
8004
8174
|
if (!dir) return false;
|
|
8005
8175
|
config.skills ??= {};
|
|
8006
8176
|
const paths = config.skills.paths ??= [];
|
|
8007
|
-
if (paths.some((p) =>
|
|
8177
|
+
if (paths.some((p) => path8.resolve(p) === dir)) return false;
|
|
8008
8178
|
paths.push(dir);
|
|
8009
8179
|
return true;
|
|
8010
8180
|
}
|
|
@@ -8055,12 +8225,12 @@ import { unlink as unlink2 } from "fs/promises";
|
|
|
8055
8225
|
|
|
8056
8226
|
// src/claude-session-bun.ts
|
|
8057
8227
|
import * as os4 from "os";
|
|
8058
|
-
import * as
|
|
8059
|
-
import * as
|
|
8228
|
+
import * as fs7 from "fs";
|
|
8229
|
+
import * as path9 from "path";
|
|
8060
8230
|
import { execFileSync } from "child_process";
|
|
8061
8231
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
8062
8232
|
function resolveClaude(cmd = "claude") {
|
|
8063
|
-
if (
|
|
8233
|
+
if (path9.isAbsolute(cmd) && fs7.existsSync(cmd)) return cmd;
|
|
8064
8234
|
const viaBun = Bun.which(cmd);
|
|
8065
8235
|
if (viaBun) return viaBun;
|
|
8066
8236
|
const isWin = os4.platform() === "win32";
|
|
@@ -8069,17 +8239,17 @@ function resolveClaude(cmd = "claude") {
|
|
|
8069
8239
|
encoding: "utf8",
|
|
8070
8240
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8071
8241
|
});
|
|
8072
|
-
const first = out.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).find((p) =>
|
|
8242
|
+
const first = out.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).find((p) => fs7.existsSync(p));
|
|
8073
8243
|
if (first) return first;
|
|
8074
8244
|
} catch {
|
|
8075
8245
|
}
|
|
8076
8246
|
throw new Error(`Could not resolve command on PATH: ${cmd}`);
|
|
8077
8247
|
}
|
|
8078
8248
|
function encodeCwd(cwd) {
|
|
8079
|
-
const resolved =
|
|
8249
|
+
const resolved = path9.resolve(cwd);
|
|
8080
8250
|
let real = resolved;
|
|
8081
8251
|
try {
|
|
8082
|
-
real =
|
|
8252
|
+
real = fs7.realpathSync.native(resolved);
|
|
8083
8253
|
} catch {
|
|
8084
8254
|
}
|
|
8085
8255
|
return real.replace(/[^a-zA-Z0-9]/g, "-");
|
|
@@ -8164,12 +8334,12 @@ var TERMINAL_STOP = /* @__PURE__ */ new Set(["end_turn", "stop_sequence", "max_t
|
|
|
8164
8334
|
var delay = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
8165
8335
|
function resolveConfigDir(configDir) {
|
|
8166
8336
|
const value = configDir ?? process.env.CLAUDE_CONFIG_DIR;
|
|
8167
|
-
if (!value) return
|
|
8337
|
+
if (!value) return path9.join(os4.homedir(), ".claude");
|
|
8168
8338
|
if (value === "~") return os4.homedir();
|
|
8169
8339
|
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
8170
|
-
return
|
|
8340
|
+
return path9.join(os4.homedir(), value.slice(2));
|
|
8171
8341
|
}
|
|
8172
|
-
return
|
|
8342
|
+
return path9.resolve(value);
|
|
8173
8343
|
}
|
|
8174
8344
|
var ClaudeSession = class {
|
|
8175
8345
|
sessionId;
|
|
@@ -8187,11 +8357,11 @@ var ClaudeSession = class {
|
|
|
8187
8357
|
signal;
|
|
8188
8358
|
o;
|
|
8189
8359
|
constructor(opts = {}) {
|
|
8190
|
-
this.cwd =
|
|
8360
|
+
this.cwd = path9.resolve(opts.cwd ?? process.cwd());
|
|
8191
8361
|
this.configDir = resolveConfigDir(opts.configDir);
|
|
8192
8362
|
this.signal = opts.signal;
|
|
8193
8363
|
this.sessionId = randomUUID4();
|
|
8194
|
-
this.jsonlPath =
|
|
8364
|
+
this.jsonlPath = path9.join(
|
|
8195
8365
|
this.configDir,
|
|
8196
8366
|
"projects",
|
|
8197
8367
|
encodeCwd(this.cwd),
|
|
@@ -8314,7 +8484,7 @@ var ClaudeSession = class {
|
|
|
8314
8484
|
}
|
|
8315
8485
|
readRawLines() {
|
|
8316
8486
|
try {
|
|
8317
|
-
return
|
|
8487
|
+
return fs7.readFileSync(this.jsonlPath, "utf8").split("\n");
|
|
8318
8488
|
} catch {
|
|
8319
8489
|
return [];
|
|
8320
8490
|
}
|
|
@@ -8711,13 +8881,13 @@ function spawnInteractiveProcess(opts) {
|
|
|
8711
8881
|
}
|
|
8712
8882
|
|
|
8713
8883
|
// src/prompts.ts
|
|
8714
|
-
import { readFileSync as
|
|
8884
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
8715
8885
|
import { homedir as homedir7 } from "os";
|
|
8716
8886
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
8717
|
-
import { dirname as
|
|
8718
|
-
function readPromptFileIfPresent(
|
|
8887
|
+
import { dirname as dirname6, join as join9 } from "path";
|
|
8888
|
+
function readPromptFileIfPresent(path11) {
|
|
8719
8889
|
try {
|
|
8720
|
-
const content =
|
|
8890
|
+
const content = readFileSync6(path11, "utf8").trim();
|
|
8721
8891
|
return content || void 0;
|
|
8722
8892
|
} catch {
|
|
8723
8893
|
return void 0;
|
|
@@ -8726,9 +8896,9 @@ function readPromptFileIfPresent(path10) {
|
|
|
8726
8896
|
function nearestWorkspaceAgentsPrompt(cwd) {
|
|
8727
8897
|
let dir = cwd;
|
|
8728
8898
|
while (true) {
|
|
8729
|
-
const content = readPromptFileIfPresent(
|
|
8899
|
+
const content = readPromptFileIfPresent(join9(dir, "AGENTS.md"));
|
|
8730
8900
|
if (content) return content;
|
|
8731
|
-
const parent =
|
|
8901
|
+
const parent = dirname6(dir);
|
|
8732
8902
|
if (parent === dir) return void 0;
|
|
8733
8903
|
dir = parent;
|
|
8734
8904
|
}
|
|
@@ -8835,8 +9005,8 @@ ${options.compressionSummary.trim()}`
|
|
|
8835
9005
|
for (const s of extraSystemContent) {
|
|
8836
9006
|
if (s.trim()) parts.push(s.trim());
|
|
8837
9007
|
}
|
|
8838
|
-
const configRoot = process.env.XDG_CONFIG_HOME ??
|
|
8839
|
-
const globalAgents = readPromptFileIfPresent(
|
|
9008
|
+
const configRoot = process.env.XDG_CONFIG_HOME ?? join9(homedir7(), ".config");
|
|
9009
|
+
const globalAgents = readPromptFileIfPresent(join9(configRoot, "opencode", "AGENTS.md"));
|
|
8840
9010
|
const workspaceAgents = nearestWorkspaceAgentsPrompt(cwd);
|
|
8841
9011
|
const forwarded = extraSystemContent.join("\n\n");
|
|
8842
9012
|
const pushGlobal = !!globalAgents && !forwarded.includes(globalAgents);
|
|
@@ -8847,10 +9017,10 @@ ${options.compressionSummary.trim()}`
|
|
|
8847
9017
|
if (includeMultiStepHint) parts.push(MULTI_STEP_TASK_HINT);
|
|
8848
9018
|
const content = parts.join("\n\n");
|
|
8849
9019
|
if (!content) return void 0;
|
|
8850
|
-
const
|
|
9020
|
+
const path11 = join9(pluginTmpDir(), `opencode-cc-sys-${randomUUID5()}.md`);
|
|
8851
9021
|
try {
|
|
8852
|
-
writeFileSync4(
|
|
8853
|
-
return
|
|
9022
|
+
writeFileSync4(path11, content, { encoding: "utf8", mode: 384 });
|
|
9023
|
+
return path11;
|
|
8854
9024
|
} catch (err) {
|
|
8855
9025
|
log.warn("failed to write system prompt file", { error: String(err) });
|
|
8856
9026
|
return void 0;
|
|
@@ -11903,6 +12073,11 @@ var ClaudeCodeLanguageModel = class {
|
|
|
11903
12073
|
// the operator is usually not even looking at.
|
|
11904
12074
|
childSession: !!await fetchSessionParentId(affinity)
|
|
11905
12075
|
});
|
|
12076
|
+
let staleBuild = null;
|
|
12077
|
+
if (!compactionMode && mode !== "generate" && affinity !== "default") {
|
|
12078
|
+
staleBuild = staleBuildWatch().check();
|
|
12079
|
+
if (staleBuild && await fetchSessionParentId(affinity)) staleBuild = null;
|
|
12080
|
+
}
|
|
11906
12081
|
log.info("doStream starting", {
|
|
11907
12082
|
cwd,
|
|
11908
12083
|
model: effectiveModelId,
|
|
@@ -12363,6 +12538,14 @@ var ClaudeCodeLanguageModel = class {
|
|
|
12363
12538
|
if (stoppedBeforeWork()) return;
|
|
12364
12539
|
state.streamStarted = true;
|
|
12365
12540
|
controller.enqueue({ type: "stream-start", warnings });
|
|
12541
|
+
if (staleBuild && staleBuildWatch().claimSession(affinity)) {
|
|
12542
|
+
controller.enqueue({
|
|
12543
|
+
type: "text-delta",
|
|
12544
|
+
id: state.startTextBlock(),
|
|
12545
|
+
delta: formatStaleBuildNote(staleBuild)
|
|
12546
|
+
});
|
|
12547
|
+
state.endTextBlock();
|
|
12548
|
+
}
|
|
12366
12549
|
if (failoverNote) {
|
|
12367
12550
|
controller.enqueue({
|
|
12368
12551
|
type: "text-delta",
|
|
@@ -12810,34 +12993,34 @@ var ClaudeCodeLanguageModel = class {
|
|
|
12810
12993
|
import {
|
|
12811
12994
|
existsSync as existsSync3,
|
|
12812
12995
|
mkdirSync as mkdirSync4,
|
|
12813
|
-
readFileSync as
|
|
12996
|
+
readFileSync as readFileSync7,
|
|
12814
12997
|
realpathSync as realpathSync4,
|
|
12815
12998
|
rmSync as rmSync3,
|
|
12816
12999
|
writeFileSync as writeFileSync5
|
|
12817
13000
|
} from "fs";
|
|
12818
13001
|
import { homedir as homedir8 } from "os";
|
|
12819
|
-
import { dirname as
|
|
12820
|
-
import { fileURLToPath as
|
|
13002
|
+
import { dirname as dirname7, join as join10, resolve as resolve5 } from "path";
|
|
13003
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
12821
13004
|
var STALE_PACKAGE_NAME = "opencode-claude-code-plugin";
|
|
12822
13005
|
var SUSPECT_DESCRIPTION_TOKEN = "Claude Code";
|
|
12823
13006
|
var alreadyRan = false;
|
|
12824
13007
|
function candidateCacheRoots() {
|
|
12825
13008
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
12826
13009
|
return [
|
|
12827
|
-
xdg ?
|
|
12828
|
-
|
|
12829
|
-
|
|
13010
|
+
xdg ? join10(xdg, "opencode") : null,
|
|
13011
|
+
join10(homedir8(), ".cache", "opencode"),
|
|
13012
|
+
join10(homedir8(), "Library", "Caches", "opencode")
|
|
12830
13013
|
].filter((p) => Boolean(p));
|
|
12831
13014
|
}
|
|
12832
13015
|
function userOpencodeJsonPath() {
|
|
12833
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
12834
|
-
return
|
|
13016
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join10(homedir8(), ".config");
|
|
13017
|
+
return join10(xdgConfig, "opencode", "opencode.json");
|
|
12835
13018
|
}
|
|
12836
13019
|
function userIntendsToUseUnscoped() {
|
|
12837
13020
|
const cfg = userOpencodeJsonPath();
|
|
12838
13021
|
if (!existsSync3(cfg)) return false;
|
|
12839
13022
|
try {
|
|
12840
|
-
const json = JSON.parse(
|
|
13023
|
+
const json = JSON.parse(readFileSync7(cfg, "utf8"));
|
|
12841
13024
|
const plugins = json.plugin;
|
|
12842
13025
|
if (!Array.isArray(plugins)) return false;
|
|
12843
13026
|
return plugins.some(
|
|
@@ -12849,7 +13032,7 @@ function userIntendsToUseUnscoped() {
|
|
|
12849
13032
|
}
|
|
12850
13033
|
function ourLoadedDir() {
|
|
12851
13034
|
try {
|
|
12852
|
-
const filePath =
|
|
13035
|
+
const filePath = fileURLToPath4(import.meta.url);
|
|
12853
13036
|
return realpathSync4(resolve5(filePath, "..", ".."));
|
|
12854
13037
|
} catch {
|
|
12855
13038
|
return null;
|
|
@@ -12858,19 +13041,19 @@ function ourLoadedDir() {
|
|
|
12858
13041
|
function ourVersion(dir) {
|
|
12859
13042
|
if (!dir) return null;
|
|
12860
13043
|
try {
|
|
12861
|
-
const pkg = JSON.parse(
|
|
13044
|
+
const pkg = JSON.parse(readFileSync7(join10(dir, "package.json"), "utf8"));
|
|
12862
13045
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
12863
13046
|
} catch {
|
|
12864
13047
|
return null;
|
|
12865
13048
|
}
|
|
12866
13049
|
}
|
|
12867
13050
|
function markerPath() {
|
|
12868
|
-
const stateRoot = process.env.XDG_STATE_HOME ??
|
|
12869
|
-
return
|
|
13051
|
+
const stateRoot = process.env.XDG_STATE_HOME ?? join10(homedir8(), ".local", "state");
|
|
13052
|
+
return join10(stateRoot, "opencode-claude-code-plugin", "cleanup-stale.json");
|
|
12870
13053
|
}
|
|
12871
13054
|
function markerVersion() {
|
|
12872
13055
|
try {
|
|
12873
|
-
const marker = JSON.parse(
|
|
13056
|
+
const marker = JSON.parse(readFileSync7(markerPath(), "utf8"));
|
|
12874
13057
|
return typeof marker.version === "string" ? marker.version : null;
|
|
12875
13058
|
} catch {
|
|
12876
13059
|
return null;
|
|
@@ -12879,7 +13062,7 @@ function markerVersion() {
|
|
|
12879
13062
|
function writeMarker(version) {
|
|
12880
13063
|
const file = markerPath();
|
|
12881
13064
|
try {
|
|
12882
|
-
mkdirSync4(
|
|
13065
|
+
mkdirSync4(dirname7(file), { recursive: true });
|
|
12883
13066
|
writeFileSync5(
|
|
12884
13067
|
file,
|
|
12885
13068
|
JSON.stringify({ version, at: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n",
|
|
@@ -12915,7 +13098,7 @@ function cleanupStaleUnscopedInstall() {
|
|
|
12915
13098
|
}
|
|
12916
13099
|
function cleanupOne(cacheRoot, ourDir) {
|
|
12917
13100
|
if (!existsSync3(cacheRoot)) return;
|
|
12918
|
-
const stalePath =
|
|
13101
|
+
const stalePath = join10(cacheRoot, "node_modules", STALE_PACKAGE_NAME);
|
|
12919
13102
|
if (!existsSync3(stalePath)) return;
|
|
12920
13103
|
let realStalePath = stalePath;
|
|
12921
13104
|
try {
|
|
@@ -12923,11 +13106,11 @@ function cleanupOne(cacheRoot, ourDir) {
|
|
|
12923
13106
|
} catch {
|
|
12924
13107
|
}
|
|
12925
13108
|
if (ourDir && realStalePath === ourDir) return;
|
|
12926
|
-
const pkgJsonPath =
|
|
13109
|
+
const pkgJsonPath = join10(stalePath, "package.json");
|
|
12927
13110
|
if (!existsSync3(pkgJsonPath)) return;
|
|
12928
13111
|
let pkg = {};
|
|
12929
13112
|
try {
|
|
12930
|
-
pkg = JSON.parse(
|
|
13113
|
+
pkg = JSON.parse(readFileSync7(pkgJsonPath, "utf8"));
|
|
12931
13114
|
} catch {
|
|
12932
13115
|
return;
|
|
12933
13116
|
}
|
|
@@ -12943,10 +13126,10 @@ function cleanupOne(cacheRoot, ourDir) {
|
|
|
12943
13126
|
});
|
|
12944
13127
|
return;
|
|
12945
13128
|
}
|
|
12946
|
-
const cachePkgJson =
|
|
13129
|
+
const cachePkgJson = join10(cacheRoot, "package.json");
|
|
12947
13130
|
if (!existsSync3(cachePkgJson)) return;
|
|
12948
13131
|
try {
|
|
12949
|
-
const cfg = JSON.parse(
|
|
13132
|
+
const cfg = JSON.parse(readFileSync7(cachePkgJson, "utf8"));
|
|
12950
13133
|
if (cfg?.dependencies?.[STALE_PACKAGE_NAME]) {
|
|
12951
13134
|
delete cfg.dependencies[STALE_PACKAGE_NAME];
|
|
12952
13135
|
writeFileSync5(cachePkgJson, JSON.stringify(cfg, null, 2) + "\n");
|
|
@@ -12960,7 +13143,7 @@ function cleanupOne(cacheRoot, ourDir) {
|
|
|
12960
13143
|
}
|
|
12961
13144
|
|
|
12962
13145
|
// src/v2-client.ts
|
|
12963
|
-
import
|
|
13146
|
+
import path10 from "path";
|
|
12964
13147
|
function formatAgentTypeList(agents) {
|
|
12965
13148
|
const lines = agents.flatMap((agent) => {
|
|
12966
13149
|
if (agent.hidden === true || agent.mode === "primary") return [];
|
|
@@ -12989,7 +13172,7 @@ function toV1Session(info) {
|
|
|
12989
13172
|
if (!info || typeof info !== "object") return void 0;
|
|
12990
13173
|
const session = info;
|
|
12991
13174
|
const root = session.location?.directory;
|
|
12992
|
-
const directory = typeof root === "string" ? typeof session.subpath === "string" && session.subpath.length > 0 ?
|
|
13175
|
+
const directory = typeof root === "string" ? typeof session.subpath === "string" && session.subpath.length > 0 ? path10.resolve(root, session.subpath) : root : void 0;
|
|
12993
13176
|
return { ...info, directory, parentID: session.parentID };
|
|
12994
13177
|
}
|
|
12995
13178
|
function toV1Messages(messages) {
|