@khalilgharbaoui/opencode-claude-code-plugin 0.61.2 → 0.62.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/index.js +192 -53
- package/dist/index.js.map +1 -1
- package/dist/tui.js +75 -34
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/skills/claude-code-plugin/SKILL.md +11 -7
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/claude-code-language-model.ts
|
|
2
|
-
import { join as
|
|
2
|
+
import { join as join20 } from "path";
|
|
3
3
|
|
|
4
4
|
// src/ids.ts
|
|
5
5
|
import { randomInt } from "crypto";
|
|
@@ -906,6 +906,44 @@ function recordUsageReading(account, window, reading, now = Date.now()) {
|
|
|
906
906
|
cache = { path: file, usage: kept };
|
|
907
907
|
return writeStore(file, kept, store.known) ? entry : null;
|
|
908
908
|
}
|
|
909
|
+
function usageReadingsFromObservation(observation, previous, now = Date.now()) {
|
|
910
|
+
const out = [];
|
|
911
|
+
const windows = observation.windows ?? {};
|
|
912
|
+
const limiting = observation.window;
|
|
913
|
+
if (limiting && observation.status) {
|
|
914
|
+
const own = windows[limiting];
|
|
915
|
+
out.push([
|
|
916
|
+
limiting,
|
|
917
|
+
{
|
|
918
|
+
utilization: finite(observation.utilization) ? observation.utilization : own && finite(own.utilization) ? own.utilization : null,
|
|
919
|
+
resetsAt: finite(observation.resetsAt) ? observation.resetsAt : own?.resetsAt,
|
|
920
|
+
status: observation.status
|
|
921
|
+
}
|
|
922
|
+
]);
|
|
923
|
+
}
|
|
924
|
+
for (const [window, own] of Object.entries(windows)) {
|
|
925
|
+
if (window === limiting || !finite(own.utilization)) continue;
|
|
926
|
+
const before = previous(window);
|
|
927
|
+
const stillRefused = before !== void 0 && before.status === "rejected" && isReadingCurrent(before, now) && own.utilization >= 1;
|
|
928
|
+
out.push([window, { utilization: own.utilization, resetsAt: own.resetsAt, status: stillRefused ? "rejected" : "allowed" }]);
|
|
929
|
+
}
|
|
930
|
+
return out;
|
|
931
|
+
}
|
|
932
|
+
function recordRateLimitObservation(account, observation, now = Date.now()) {
|
|
933
|
+
if (!NAME.test(account)) return false;
|
|
934
|
+
const file = accountUsageStorePath();
|
|
935
|
+
const store = parseStore(file, now);
|
|
936
|
+
const merged = store.usage;
|
|
937
|
+
const windows = merged.get(account) ?? /* @__PURE__ */ new Map();
|
|
938
|
+
const previous = (window) => windows.get(window) ?? cached(now).get(account)?.get(window);
|
|
939
|
+
const readings = usageReadingsFromObservation(observation, previous, now).filter(([window]) => NAME.test(window));
|
|
940
|
+
if (readings.length === 0) return false;
|
|
941
|
+
for (const [window, reading] of readings) windows.set(window, applyReading(previous(window), reading, now));
|
|
942
|
+
merged.set(account, windows);
|
|
943
|
+
const kept = bounded(merged, now);
|
|
944
|
+
cache = { path: file, usage: kept };
|
|
945
|
+
return writeStore(file, kept, store.known);
|
|
946
|
+
}
|
|
909
947
|
function markUsageNoted(account, window, thresholds, now = Date.now()) {
|
|
910
948
|
if (!NAME.test(account) || !NAME.test(window) || thresholds.length === 0) return false;
|
|
911
949
|
const file = accountUsageStorePath();
|
|
@@ -992,6 +1030,18 @@ function str(value) {
|
|
|
992
1030
|
function num(value) {
|
|
993
1031
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
994
1032
|
}
|
|
1033
|
+
function parseUnifiedWindows(value) {
|
|
1034
|
+
if (!isRecord(value)) return void 0;
|
|
1035
|
+
const out = {};
|
|
1036
|
+
for (const [window, raw] of Object.entries(value)) {
|
|
1037
|
+
if (!isRecord(raw)) continue;
|
|
1038
|
+
const utilization = num(raw.utilization);
|
|
1039
|
+
if (utilization === void 0 || utilization < 0) continue;
|
|
1040
|
+
const resetsAt = num(raw.resetsAt);
|
|
1041
|
+
out[window] = resetsAt === void 0 ? { utilization } : { utilization, resetsAt };
|
|
1042
|
+
}
|
|
1043
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1044
|
+
}
|
|
995
1045
|
var RATE_LIMIT_MARKER = "\u258C **rate limit:**";
|
|
996
1046
|
var RATE_LIMIT_ACTION = "Enable extra usage or add credits on the account, wait for the window to reset, switch account, org or plan, or authenticate with an API key.";
|
|
997
1047
|
var OVERAGE_DISABLED_REASONS = {
|
|
@@ -1020,6 +1070,7 @@ function parseRateLimitEvent(msg) {
|
|
|
1020
1070
|
if (msg.type !== "rate_limit_event") return null;
|
|
1021
1071
|
const info = msg.rate_limit_info;
|
|
1022
1072
|
if (!isRecord(info)) return null;
|
|
1073
|
+
const windows = parseUnifiedWindows(info.unifiedWindows);
|
|
1023
1074
|
return {
|
|
1024
1075
|
status: str(info.status),
|
|
1025
1076
|
rateLimitType: str(info.rateLimitType),
|
|
@@ -1028,7 +1079,8 @@ function parseRateLimitEvent(msg) {
|
|
|
1028
1079
|
isUsingOverage: info.isUsingOverage === true,
|
|
1029
1080
|
overageStatus: str(info.overageStatus),
|
|
1030
1081
|
overageResetsAt: num(info.overageResetsAt),
|
|
1031
|
-
overageDisabledReason: str(info.overageDisabledReason)
|
|
1082
|
+
overageDisabledReason: str(info.overageDisabledReason),
|
|
1083
|
+
...windows ? { windows } : {}
|
|
1032
1084
|
};
|
|
1033
1085
|
}
|
|
1034
1086
|
function resetsAtToMs(resetsAt) {
|
|
@@ -7804,6 +7856,71 @@ async function requestSideQuestion(activeProcess, question, options) {
|
|
|
7804
7856
|
});
|
|
7805
7857
|
}
|
|
7806
7858
|
|
|
7859
|
+
// src/session-event-relay.ts
|
|
7860
|
+
var RELAY_KEY = /* @__PURE__ */ Symbol.for("@khalilgharbaoui/opencode-claude-code-plugin/session-event-relay");
|
|
7861
|
+
function relayState() {
|
|
7862
|
+
const holder = globalThis;
|
|
7863
|
+
let state = holder[RELAY_KEY];
|
|
7864
|
+
if (!state) {
|
|
7865
|
+
state = { members: /* @__PURE__ */ new Set(), followers: 0 };
|
|
7866
|
+
holder[RELAY_KEY] = state;
|
|
7867
|
+
}
|
|
7868
|
+
return state;
|
|
7869
|
+
}
|
|
7870
|
+
function safely(action) {
|
|
7871
|
+
try {
|
|
7872
|
+
action();
|
|
7873
|
+
} catch {
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7876
|
+
var ownMember;
|
|
7877
|
+
var ownFollowers = 0;
|
|
7878
|
+
var ownServed = false;
|
|
7879
|
+
function join10() {
|
|
7880
|
+
if (!ownMember) return;
|
|
7881
|
+
const state = relayState();
|
|
7882
|
+
if (state.members.has(ownMember)) return;
|
|
7883
|
+
state.members.add(ownMember);
|
|
7884
|
+
if (state.followers > 0) safely(() => ownMember?.feedOpened());
|
|
7885
|
+
}
|
|
7886
|
+
function leave() {
|
|
7887
|
+
if (!ownMember) return;
|
|
7888
|
+
if (relayState().members.delete(ownMember)) safely(() => ownMember?.feedClosed());
|
|
7889
|
+
}
|
|
7890
|
+
function defineOwnRelayMember(member) {
|
|
7891
|
+
ownMember = member;
|
|
7892
|
+
if (ownServed) join10();
|
|
7893
|
+
}
|
|
7894
|
+
function noteRelayMemberServing() {
|
|
7895
|
+
ownServed = true;
|
|
7896
|
+
join10();
|
|
7897
|
+
}
|
|
7898
|
+
function openRelayFollower() {
|
|
7899
|
+
const state = relayState();
|
|
7900
|
+
join10();
|
|
7901
|
+
ownFollowers += 1;
|
|
7902
|
+
state.followers += 1;
|
|
7903
|
+
if (state.followers === 1) {
|
|
7904
|
+
for (const member of state.members) safely(() => member.feedOpened());
|
|
7905
|
+
}
|
|
7906
|
+
let closed = false;
|
|
7907
|
+
return () => {
|
|
7908
|
+
if (closed) return;
|
|
7909
|
+
closed = true;
|
|
7910
|
+
ownFollowers = Math.max(0, ownFollowers - 1);
|
|
7911
|
+
state.followers = Math.max(0, state.followers - 1);
|
|
7912
|
+
if (state.followers === 0) {
|
|
7913
|
+
for (const member of state.members) safely(() => member.feedClosed());
|
|
7914
|
+
}
|
|
7915
|
+
if (ownFollowers === 0 && !ownServed) leave();
|
|
7916
|
+
};
|
|
7917
|
+
}
|
|
7918
|
+
function relaySessionEvent(event) {
|
|
7919
|
+
const members = relayState().members;
|
|
7920
|
+
if (ownMember && !members.has(ownMember)) safely(() => ownMember?.handle(event));
|
|
7921
|
+
for (const member of [...members]) safely(() => member.handle(event));
|
|
7922
|
+
}
|
|
7923
|
+
|
|
7807
7924
|
// src/session-manager.ts
|
|
7808
7925
|
function findActiveProcessBySessionId(sessionID) {
|
|
7809
7926
|
let found;
|
|
@@ -8030,6 +8147,7 @@ function processBelongsToAnotherAccount(active, cliPath, configDir) {
|
|
|
8030
8147
|
function setActiveProcess(key, ap) {
|
|
8031
8148
|
cancelIdleProcessEviction(key);
|
|
8032
8149
|
activeProcesses.set(key, ap);
|
|
8150
|
+
noteRelayMemberServing();
|
|
8033
8151
|
}
|
|
8034
8152
|
function noteInteractiveProcessExit(sessionKey2, ap, code) {
|
|
8035
8153
|
if (activeProcesses.get(sessionKey2) !== ap) return;
|
|
@@ -8324,8 +8442,7 @@ function spawnClaudeProcess(cliPath, cliArgs, cwd, sessionKey2, proxyServer, mcp
|
|
|
8324
8442
|
settleTurn(ap);
|
|
8325
8443
|
lineEmitter.emit("close");
|
|
8326
8444
|
});
|
|
8327
|
-
|
|
8328
|
-
activeProcesses.set(sessionKey2, ap);
|
|
8445
|
+
setActiveProcess(sessionKey2, ap);
|
|
8329
8446
|
proc.on("error", (err) => {
|
|
8330
8447
|
log.error("claude process error", { sessionKey: sessionKey2, error: err.message });
|
|
8331
8448
|
});
|
|
@@ -10063,20 +10180,20 @@ async function fetchPlanUsage(cliPath, options = {}) {
|
|
|
10063
10180
|
// src/turn-history.ts
|
|
10064
10181
|
import { mkdirSync as mkdirSync7, readFileSync as readFileSync7, renameSync as renameSync6, statSync as statSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
10065
10182
|
import { homedir as homedir11 } from "os";
|
|
10066
|
-
import { join as
|
|
10183
|
+
import { join as join12 } from "path";
|
|
10067
10184
|
|
|
10068
10185
|
// src/turn-progress-store.ts
|
|
10069
10186
|
import { mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync as renameSync5, statSync as statSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
10070
10187
|
import { homedir as homedir10 } from "os";
|
|
10071
|
-
import { join as
|
|
10188
|
+
import { join as join11 } from "path";
|
|
10072
10189
|
var MAX_TURN_PROGRESS = 64;
|
|
10073
10190
|
var TURN_PROGRESS_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
10074
10191
|
var TAG = /^[0-9a-f]{8}$/;
|
|
10075
10192
|
var pathOverride4 = null;
|
|
10076
10193
|
function turnProgressStorePath() {
|
|
10077
10194
|
if (pathOverride4) return pathOverride4;
|
|
10078
|
-
const stateRoot = process.env.XDG_STATE_HOME ||
|
|
10079
|
-
return
|
|
10195
|
+
const stateRoot = process.env.XDG_STATE_HOME || join11(homedir10(), ".local", "state");
|
|
10196
|
+
return join11(stateRoot, "opencode-claude-code-plugin", "turn-progress.json");
|
|
10080
10197
|
}
|
|
10081
10198
|
function isProgress(value) {
|
|
10082
10199
|
const record = value;
|
|
@@ -10106,7 +10223,7 @@ function recordTurnProgress(tag, progress, now = Date.now()) {
|
|
|
10106
10223
|
merged.set(tag, { ...record, out: Math.round(record.out) });
|
|
10107
10224
|
const kept = [...merged.entries()].slice(-MAX_TURN_PROGRESS);
|
|
10108
10225
|
try {
|
|
10109
|
-
mkdirSync6(
|
|
10226
|
+
mkdirSync6(join11(file, ".."), { recursive: true, mode: 448 });
|
|
10110
10227
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
10111
10228
|
writeFileSync6(tmp, JSON.stringify({ version: 1, turns: Object.fromEntries(kept) }), { mode: 384 });
|
|
10112
10229
|
renameSync5(tmp, file);
|
|
@@ -10124,8 +10241,8 @@ var SESSION_TAG = /^[0-9a-f]{8}$/;
|
|
|
10124
10241
|
var pathOverride5 = null;
|
|
10125
10242
|
function turnHistoryStorePath() {
|
|
10126
10243
|
if (pathOverride5) return pathOverride5;
|
|
10127
|
-
const stateRoot = process.env.XDG_STATE_HOME ||
|
|
10128
|
-
return
|
|
10244
|
+
const stateRoot = process.env.XDG_STATE_HOME || join12(homedir11(), ".local", "state");
|
|
10245
|
+
return join12(stateRoot, "opencode-claude-code-plugin", "turn-history.json");
|
|
10129
10246
|
}
|
|
10130
10247
|
function turnHistoryKey(agent, model) {
|
|
10131
10248
|
return `${agent || "main"}/${model}`;
|
|
@@ -10309,7 +10426,7 @@ function recordTurnSample(key, sample) {
|
|
|
10309
10426
|
merged.set(key, samples);
|
|
10310
10427
|
const kept = bounded2(merged);
|
|
10311
10428
|
try {
|
|
10312
|
-
mkdirSync7(
|
|
10429
|
+
mkdirSync7(join12(file, ".."), { recursive: true, mode: 448 });
|
|
10313
10430
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
10314
10431
|
writeFileSync7(tmp, JSON.stringify({ version: 1, turns: Object.fromEntries(kept) }), { mode: 384 });
|
|
10315
10432
|
renameSync6(tmp, file);
|
|
@@ -12733,7 +12850,7 @@ import { EventEmitter as EventEmitter4 } from "events";
|
|
|
12733
12850
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
12734
12851
|
import { existsSync as existsSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
12735
12852
|
import { unlink as unlink2 } from "fs/promises";
|
|
12736
|
-
import { join as
|
|
12853
|
+
import { join as join17 } from "path";
|
|
12737
12854
|
|
|
12738
12855
|
// src/claude-session-bun.ts
|
|
12739
12856
|
import * as os6 from "os";
|
|
@@ -13915,7 +14032,7 @@ ${text2}`
|
|
|
13915
14032
|
}
|
|
13916
14033
|
function stageImage(data, extension) {
|
|
13917
14034
|
try {
|
|
13918
|
-
const file =
|
|
14035
|
+
const file = join17(pluginTmpDir(), `attachment-${randomUUID5()}.${extension}`);
|
|
13919
14036
|
writeFileSync9(file, data, { mode: 384, flag: "wx" });
|
|
13920
14037
|
return file;
|
|
13921
14038
|
} catch (err) {
|
|
@@ -14399,15 +14516,15 @@ function spawnInteractiveProcess(opts) {
|
|
|
14399
14516
|
// src/spawn-record-store.ts
|
|
14400
14517
|
import { mkdirSync as mkdirSync9, readFileSync as readFileSync11, renameSync as renameSync7, statSync as statSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
14401
14518
|
import { homedir as homedir14 } from "os";
|
|
14402
|
-
import { join as
|
|
14519
|
+
import { join as join18 } from "path";
|
|
14403
14520
|
var MAX_SPAWN_RECORDS = 256;
|
|
14404
14521
|
var SPAWN_RECORD_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
14405
14522
|
var pathOverride6 = null;
|
|
14406
14523
|
var lastWritten = /* @__PURE__ */ new Map();
|
|
14407
14524
|
function spawnRecordStorePath() {
|
|
14408
14525
|
if (pathOverride6) return pathOverride6;
|
|
14409
|
-
const stateRoot = process.env.XDG_STATE_HOME ||
|
|
14410
|
-
return
|
|
14526
|
+
const stateRoot = process.env.XDG_STATE_HOME || join18(homedir14(), ".local", "state");
|
|
14527
|
+
return join18(stateRoot, "opencode-claude-code-plugin", "session-spawns.json");
|
|
14411
14528
|
}
|
|
14412
14529
|
function isRecord5(value) {
|
|
14413
14530
|
const record = value;
|
|
@@ -14459,7 +14576,7 @@ ${record.agent ?? ""}`;
|
|
|
14459
14576
|
const cutoff = now - SPAWN_RECORD_MAX_AGE_MS;
|
|
14460
14577
|
const kept = [...merged.entries()].filter(([, entry]) => entry.at >= cutoff).sort((a, b) => a[1].at - b[1].at).slice(-MAX_SPAWN_RECORDS);
|
|
14461
14578
|
try {
|
|
14462
|
-
mkdirSync9(
|
|
14579
|
+
mkdirSync9(join18(file, ".."), { recursive: true, mode: 448 });
|
|
14463
14580
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
14464
14581
|
writeFileSync10(tmp, JSON.stringify({ version: 1, sessions: Object.fromEntries(kept) }), {
|
|
14465
14582
|
mode: 384
|
|
@@ -14537,7 +14654,7 @@ function dedupe2(dirs) {
|
|
|
14537
14654
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync11 } from "fs";
|
|
14538
14655
|
import { homedir as homedir15 } from "os";
|
|
14539
14656
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
14540
|
-
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as
|
|
14657
|
+
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute3, join as join19 } from "path";
|
|
14541
14658
|
function readPromptFileIfPresent(path15) {
|
|
14542
14659
|
try {
|
|
14543
14660
|
const content = readFileSync12(path15, "utf8").trim();
|
|
@@ -14549,7 +14666,7 @@ function readPromptFileIfPresent(path15) {
|
|
|
14549
14666
|
function nearestWorkspaceAgentsPrompt(cwd) {
|
|
14550
14667
|
let dir = cwd;
|
|
14551
14668
|
while (true) {
|
|
14552
|
-
const content = readPromptFileIfPresent(
|
|
14669
|
+
const content = readPromptFileIfPresent(join19(dir, "AGENTS.md"));
|
|
14553
14670
|
if (content) return content;
|
|
14554
14671
|
const parent = dirname6(dir);
|
|
14555
14672
|
if (parent === dir) return void 0;
|
|
@@ -14701,8 +14818,8 @@ ${options.compressionSummary.trim()}`
|
|
|
14701
14818
|
for (const s of extraSystemContent) {
|
|
14702
14819
|
if (s.trim()) parts.push(s.trim());
|
|
14703
14820
|
}
|
|
14704
|
-
const configRoot = process.env.XDG_CONFIG_HOME ??
|
|
14705
|
-
const globalAgents = readPromptFileIfPresent(
|
|
14821
|
+
const configRoot = process.env.XDG_CONFIG_HOME ?? join19(homedir15(), ".config");
|
|
14822
|
+
const globalAgents = readPromptFileIfPresent(join19(configRoot, "opencode", "AGENTS.md"));
|
|
14706
14823
|
const workspaceAgents = nearestWorkspaceAgentsPrompt(cwd);
|
|
14707
14824
|
const forwarded = extraSystemContent.join("\n\n");
|
|
14708
14825
|
const pushGlobal = !!globalAgents && !forwarded.includes(globalAgents);
|
|
@@ -14718,7 +14835,7 @@ ${options.compressionSummary.trim()}`
|
|
|
14718
14835
|
if (includeMultiStepHint) parts.push(MULTI_STEP_TASK_HINT);
|
|
14719
14836
|
const content = parts.join("\n\n");
|
|
14720
14837
|
if (!content) return void 0;
|
|
14721
|
-
const path15 =
|
|
14838
|
+
const path15 = join19(pluginTmpDir(), `opencode-cc-sys-${randomUUID7()}.md`);
|
|
14722
14839
|
try {
|
|
14723
14840
|
writeFileSync11(path15, content, { encoding: "utf8", mode: 384 });
|
|
14724
14841
|
return path15;
|
|
@@ -16544,11 +16661,18 @@ function createLineHandler(state, ctx) {
|
|
|
16544
16661
|
};
|
|
16545
16662
|
rememberAccountLimit(ctx.sourceAccount, state.accountLimitHit);
|
|
16546
16663
|
}
|
|
16547
|
-
if (info
|
|
16548
|
-
|
|
16549
|
-
|
|
16664
|
+
if (info) {
|
|
16665
|
+
recordRateLimitObservation(ctx.usageAccount, {
|
|
16666
|
+
window: info.rateLimitType,
|
|
16667
|
+
status: info.status,
|
|
16668
|
+
utilization: info.utilization,
|
|
16550
16669
|
resetsAt: resetsAtToMs(info.resetsAt),
|
|
16551
|
-
|
|
16670
|
+
windows: info.windows ? Object.fromEntries(
|
|
16671
|
+
Object.entries(info.windows).map(([window, own]) => [
|
|
16672
|
+
window,
|
|
16673
|
+
{ utilization: own.utilization, resetsAt: resetsAtToMs(own.resetsAt) }
|
|
16674
|
+
])
|
|
16675
|
+
) : void 0
|
|
16552
16676
|
});
|
|
16553
16677
|
}
|
|
16554
16678
|
const note = reportRateLimitEvent(msg);
|
|
@@ -18555,7 +18679,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
18555
18679
|
let replayReason = "no-session-for-key";
|
|
18556
18680
|
if (this.config.resumeAfterRestart !== false && includeHistoryContext && !compactionMode && !forkFromClaudeSessionId && failoverAnswer?.kind !== "switch") {
|
|
18557
18681
|
const configDir = resolveConfigDir(this.config.configDir);
|
|
18558
|
-
const transcriptPath2 = (id, dir) =>
|
|
18682
|
+
const transcriptPath2 = (id, dir) => join20(dir ?? configDir, "projects", encodeCwd(cwd), `${id}.jsonl`);
|
|
18559
18683
|
const resumePoint = findResumePoint({
|
|
18560
18684
|
sessionKey: sk,
|
|
18561
18685
|
prompt: options.prompt,
|
|
@@ -20230,7 +20354,7 @@ import {
|
|
|
20230
20354
|
writeFileSync as writeFileSync12
|
|
20231
20355
|
} from "fs";
|
|
20232
20356
|
import { homedir as homedir16 } from "os";
|
|
20233
|
-
import { dirname as dirname7, join as
|
|
20357
|
+
import { dirname as dirname7, join as join21, resolve as resolve6 } from "path";
|
|
20234
20358
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
20235
20359
|
var STALE_PACKAGE_NAME = "opencode-claude-code-plugin";
|
|
20236
20360
|
var SUSPECT_DESCRIPTION_TOKEN = "Claude Code";
|
|
@@ -20238,14 +20362,14 @@ var alreadyRan = false;
|
|
|
20238
20362
|
function candidateCacheRoots() {
|
|
20239
20363
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
20240
20364
|
return [
|
|
20241
|
-
xdg ?
|
|
20242
|
-
|
|
20243
|
-
|
|
20365
|
+
xdg ? join21(xdg, "opencode") : null,
|
|
20366
|
+
join21(homedir16(), ".cache", "opencode"),
|
|
20367
|
+
join21(homedir16(), "Library", "Caches", "opencode")
|
|
20244
20368
|
].filter((p) => Boolean(p));
|
|
20245
20369
|
}
|
|
20246
20370
|
function userOpencodeJsonPath() {
|
|
20247
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
20248
|
-
return
|
|
20371
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join21(homedir16(), ".config");
|
|
20372
|
+
return join21(xdgConfig, "opencode", "opencode.json");
|
|
20249
20373
|
}
|
|
20250
20374
|
function userIntendsToUseUnscoped() {
|
|
20251
20375
|
const cfg = userOpencodeJsonPath();
|
|
@@ -20272,15 +20396,15 @@ function ourLoadedDir() {
|
|
|
20272
20396
|
function ourVersion(dir) {
|
|
20273
20397
|
if (!dir) return null;
|
|
20274
20398
|
try {
|
|
20275
|
-
const pkg = JSON.parse(readFileSync14(
|
|
20399
|
+
const pkg = JSON.parse(readFileSync14(join21(dir, "package.json"), "utf8"));
|
|
20276
20400
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
20277
20401
|
} catch {
|
|
20278
20402
|
return null;
|
|
20279
20403
|
}
|
|
20280
20404
|
}
|
|
20281
20405
|
function markerPath() {
|
|
20282
|
-
const stateRoot = process.env.XDG_STATE_HOME ??
|
|
20283
|
-
return
|
|
20406
|
+
const stateRoot = process.env.XDG_STATE_HOME ?? join21(homedir16(), ".local", "state");
|
|
20407
|
+
return join21(stateRoot, "opencode-claude-code-plugin", "cleanup-stale.json");
|
|
20284
20408
|
}
|
|
20285
20409
|
function markerVersion() {
|
|
20286
20410
|
try {
|
|
@@ -20329,7 +20453,7 @@ function cleanupStaleUnscopedInstall() {
|
|
|
20329
20453
|
}
|
|
20330
20454
|
function cleanupOne(cacheRoot, ourDir) {
|
|
20331
20455
|
if (!existsSync5(cacheRoot)) return;
|
|
20332
|
-
const stalePath =
|
|
20456
|
+
const stalePath = join21(cacheRoot, "node_modules", STALE_PACKAGE_NAME);
|
|
20333
20457
|
if (!existsSync5(stalePath)) return;
|
|
20334
20458
|
let realStalePath = stalePath;
|
|
20335
20459
|
try {
|
|
@@ -20337,7 +20461,7 @@ function cleanupOne(cacheRoot, ourDir) {
|
|
|
20337
20461
|
} catch {
|
|
20338
20462
|
}
|
|
20339
20463
|
if (ourDir && realStalePath === ourDir) return;
|
|
20340
|
-
const pkgJsonPath =
|
|
20464
|
+
const pkgJsonPath = join21(stalePath, "package.json");
|
|
20341
20465
|
if (!existsSync5(pkgJsonPath)) return;
|
|
20342
20466
|
let pkg = {};
|
|
20343
20467
|
try {
|
|
@@ -20357,7 +20481,7 @@ function cleanupOne(cacheRoot, ourDir) {
|
|
|
20357
20481
|
});
|
|
20358
20482
|
return;
|
|
20359
20483
|
}
|
|
20360
|
-
const cachePkgJson =
|
|
20484
|
+
const cachePkgJson = join21(cacheRoot, "package.json");
|
|
20361
20485
|
if (!existsSync5(cachePkgJson)) return;
|
|
20362
20486
|
try {
|
|
20363
20487
|
const cfg = JSON.parse(readFileSync14(cachePkgJson, "utf8"));
|
|
@@ -20763,22 +20887,37 @@ function stoppedSessionIdV2(event) {
|
|
|
20763
20887
|
const id = event.data?.sessionID;
|
|
20764
20888
|
return typeof id === "string" && id.length > 0 ? id : void 0;
|
|
20765
20889
|
}
|
|
20890
|
+
function handleSessionEventHere(event) {
|
|
20891
|
+
noteSessionRunEvent(event);
|
|
20892
|
+
const deleted = deletedSessionIdV2(event);
|
|
20893
|
+
if (deleted) {
|
|
20894
|
+
const released = deleteActiveProcessesForSession(deleted);
|
|
20895
|
+
if (released.length > 0) {
|
|
20896
|
+
log.info("released claude state for deleted session", { sessionID: deleted, released });
|
|
20897
|
+
}
|
|
20898
|
+
return;
|
|
20899
|
+
}
|
|
20900
|
+
const stopped = stoppedSessionIdV2(event);
|
|
20901
|
+
if (stopped) releaseParkedProxyCallsForSession(stopped);
|
|
20902
|
+
}
|
|
20903
|
+
var closeOwnFeed;
|
|
20904
|
+
defineOwnRelayMember({
|
|
20905
|
+
handle: (event) => handleSessionEventHere(event),
|
|
20906
|
+
feedOpened: () => {
|
|
20907
|
+
closeOwnFeed ??= openSessionRunEventFeed();
|
|
20908
|
+
},
|
|
20909
|
+
feedClosed: () => {
|
|
20910
|
+
const close = closeOwnFeed;
|
|
20911
|
+
closeOwnFeed = void 0;
|
|
20912
|
+
close?.();
|
|
20913
|
+
}
|
|
20914
|
+
});
|
|
20766
20915
|
async function followSessionEvents(subscribe, signal) {
|
|
20767
|
-
const
|
|
20916
|
+
const closeFollower = openRelayFollower();
|
|
20768
20917
|
try {
|
|
20769
20918
|
for await (const event of subscribe({ signal })) {
|
|
20770
20919
|
if (signal.aborted) break;
|
|
20771
|
-
|
|
20772
|
-
const deleted = deletedSessionIdV2(event);
|
|
20773
|
-
if (deleted) {
|
|
20774
|
-
const released = deleteActiveProcessesForSession(deleted);
|
|
20775
|
-
if (released.length > 0) {
|
|
20776
|
-
log.info("released claude state for deleted session", { sessionID: deleted, released });
|
|
20777
|
-
}
|
|
20778
|
-
continue;
|
|
20779
|
-
}
|
|
20780
|
-
const stopped = stoppedSessionIdV2(event);
|
|
20781
|
-
if (stopped) releaseParkedProxyCallsForSession(stopped);
|
|
20920
|
+
relaySessionEvent(event);
|
|
20782
20921
|
}
|
|
20783
20922
|
} catch (err) {
|
|
20784
20923
|
if (!signal.aborted) {
|
|
@@ -20788,7 +20927,7 @@ async function followSessionEvents(subscribe, signal) {
|
|
|
20788
20927
|
);
|
|
20789
20928
|
}
|
|
20790
20929
|
} finally {
|
|
20791
|
-
|
|
20930
|
+
closeFollower();
|
|
20792
20931
|
}
|
|
20793
20932
|
}
|
|
20794
20933
|
var noticeEmitters = /* @__PURE__ */ new Set();
|