@khalilgharbaoui/opencode-claude-code-plugin 0.26.2 → 0.26.3

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/README.md CHANGED
@@ -250,6 +250,7 @@ What a pick does, in full:
250
250
  - **The conversation is replayed, not resumed.** Claude transcripts live under each account's own `CLAUDE_CONFIG_DIR`, so `--resume` cannot cross accounts. The plugin starts a fresh Claude session on the target and replays the thread from opencode's history, then tells it to carry on. That costs input tokens on the new account, and anything the CLI held but opencode did not is gone.
251
251
  - **Per-profile MCP servers do not come along.** A server configured only in the limited account's Claude profile is simply absent on the target.
252
252
  - **`stop`, dismissing the form, or any answer that is not one of the offered accounts** ends the turn exactly the way the rate-limit error ends it today.
253
+ - **An account that cannot serve at all gets the same form.** When Claude Code reports that an account's login expired (`authentication_failed`), or that it is on hold, unverified or has a billing problem, the plugin writes a note naming the account and what to do, and offers the switch if another account is configured. For an expired login the note gives the exact command, for example `CLAUDE_CONFIG_DIR=~/.claude-work claude auth login`. The switch lasts until opencode restarts, so restart after logging in again to move back. With a single account you get the note alone.
253
254
 
254
255
  Only two things open the form: a `rate_limit_event` the CLI marked `rejected`, and the two known account-limit error texts (`Third-party apps now draw from your extra usage…`, `You've hit your individual spend limit`). A generic 4xx, a timeout or a bad flag never does, deliberately: a transient failure must not quietly move where your usage is billed.
255
256
 
package/dist/index.d.ts CHANGED
@@ -804,6 +804,12 @@ interface ClaudeStreamMessage {
804
804
  agent_id?: string;
805
805
  description?: string;
806
806
  };
807
+ /**
808
+ * On an `assistant` message the CLI synthesised to report a failure: the
809
+ * kind of failure (`authentication_failed`, `billing_error`, ...). Read by
810
+ * `accountBlockKind`; schema confirmed on Claude Code 2.1.280.
811
+ */
812
+ error?: string;
807
813
  message?: {
808
814
  role?: string;
809
815
  model?: string;
package/dist/index.js CHANGED
@@ -514,6 +514,9 @@ function translateStreamForHost(stream, dialect = "v1") {
514
514
  );
515
515
  }
516
516
 
517
+ // src/account-failover.ts
518
+ import { homedir as homedir2 } from "os";
519
+
517
520
  // src/accounts.ts
518
521
  import { chmod, lstat, mkdir, readlink, symlink, writeFile } from "fs/promises";
519
522
  import path from "path";
@@ -1082,6 +1085,35 @@ var ACCOUNT_LIMIT_PATTERNS = [
1082
1085
  /third-party apps now draw from your extra usage/i,
1083
1086
  /you[’'`]?ve hit your individual spend limit/i
1084
1087
  ];
1088
+ var ACCOUNT_BLOCK_MARKER = "\u258C **claude account:**";
1089
+ var ACCOUNT_BLOCKS = {
1090
+ authentication_failed: { what: "is not logged in (its login expired or was revoked)", login: true },
1091
+ oauth_org_not_allowed: { what: "belongs to an organization that does not allow this login", login: false },
1092
+ account_on_hold: { what: "is on hold", login: false },
1093
+ verification_required: { what: "needs to be verified at claude.ai", login: false },
1094
+ billing_error: { what: "has a billing problem", login: false }
1095
+ };
1096
+ function accountBlockKind(msg) {
1097
+ if (msg.type !== "assistant" || typeof msg.error !== "string") return null;
1098
+ return Object.prototype.hasOwnProperty.call(ACCOUNT_BLOCKS, msg.error) ? msg.error : null;
1099
+ }
1100
+ function describeAccountBlock(kind) {
1101
+ return ACCOUNT_BLOCKS[kind].what;
1102
+ }
1103
+ function loginCommandFor(configDir, home = homedir2()) {
1104
+ if (!configDir) return "claude auth login";
1105
+ const shown = configDir === home || configDir.startsWith(`${home}/`) ? `~${configDir.slice(home.length)}` : configDir;
1106
+ return `CLAUDE_CONFIG_DIR=${shown} claude auth login`;
1107
+ }
1108
+ function formatAccountBlockNote(input) {
1109
+ const block = ACCOUNT_BLOCKS[input.kind];
1110
+ const account = normalizeAccountName(input.account || DEFAULT_ACCOUNT);
1111
+ const fix = block.login ? `Log in again with \`${loginCommandFor(input.configDir)}\`, then resend your message.` : "Check the account at claude.ai, then resend your message.";
1112
+ const then = input.offeringSwitch ? " Or pick another account below." : "";
1113
+ return `
1114
+ ${ACCOUNT_BLOCK_MARKER} the Claude account "${account}" ${block.what}. ${fix}${then}
1115
+ `;
1116
+ }
1085
1117
  function isAccountLimitError(input) {
1086
1118
  if (input.rateLimit && isRateLimitRejected(input.rateLimit)) return true;
1087
1119
  const text = input.resultText;
@@ -1187,7 +1219,7 @@ function createAccountFailoverQuestionCall(sessionKey2, input, toolCallId = `${A
1187
1219
  const candidates = input.candidates.map((c) => normalizeAccountName(c));
1188
1220
  const resets = describeReset(input.resetsAt);
1189
1221
  const until = resets ?? "opencode restarts";
1190
- const question = [
1222
+ const question = input.reason ? `The Claude account "${source}" ${input.reason}. Continue this task on another configured account? Leaving this unanswered waits, at no cost.` : [
1191
1223
  `The Claude account "${source}" is out of usage`,
1192
1224
  input.window ? ` in ${input.window}` : "",
1193
1225
  resets ? `, which resets at ${resets}` : "",
@@ -4693,7 +4725,8 @@ var PLUGIN_NOTE_MARKERS = [
4693
4725
  RESULT_ERROR_MARKER,
4694
4726
  DOCTOR_MARKER,
4695
4727
  STREAM_TIMEOUT_MARKER,
4696
- FAILOVER_MARKER
4728
+ FAILOVER_MARKER,
4729
+ ACCOUNT_BLOCK_MARKER
4697
4730
  ];
4698
4731
  function isPluginNote(part) {
4699
4732
  if (!part || part.type !== "text" || typeof part.text !== "string") return false;
@@ -6289,7 +6322,7 @@ function spawnInteractiveProcess(opts) {
6289
6322
  // src/claude-code-language-model.ts
6290
6323
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
6291
6324
  import { unlink as unlink3 } from "fs/promises";
6292
- import { homedir as homedir5, tmpdir as tmpdir2 } from "os";
6325
+ import { homedir as homedir6, tmpdir as tmpdir2 } from "os";
6293
6326
  import { randomUUID as randomUUID5 } from "crypto";
6294
6327
  import { dirname as dirname5, join as join8 } from "path";
6295
6328
  async function isProxyCallStillServed(callId) {
@@ -6653,7 +6686,7 @@ ${options.compressionSummary.trim()}`
6653
6686
  for (const s of extraSystemContent) {
6654
6687
  if (s.trim()) parts.push(s.trim());
6655
6688
  }
6656
- const configRoot = process.env.XDG_CONFIG_HOME ?? join8(homedir5(), ".config");
6689
+ const configRoot = process.env.XDG_CONFIG_HOME ?? join8(homedir6(), ".config");
6657
6690
  const globalAgents = readPromptFileIfPresent(join8(configRoot, "opencode", "AGENTS.md"));
6658
6691
  const workspaceAgents = nearestWorkspaceAgentsPrompt(cwd);
6659
6692
  const forwarded = extraSystemContent.join("\n\n");
@@ -8591,6 +8624,7 @@ ${plan}
8591
8624
  let resultMeta = {};
8592
8625
  let resultFailure;
8593
8626
  let accountLimitHit = null;
8627
+ let accountBlock = null;
8594
8628
  const drainBuffer = [];
8595
8629
  let drainTimer = null;
8596
8630
  const DRAIN_QUIET_MS = 100;
@@ -8752,20 +8786,21 @@ ${plan}
8752
8786
  });
8753
8787
  }
8754
8788
  activeProcess?.pendingProxyCompletions?.clear();
8755
- if (accountLimitHit && failoverAskActive && msg.is_error === true) {
8789
+ if ((accountLimitHit || accountBlock) && failoverAskActive && msg.is_error === true) {
8756
8790
  const call = createAccountFailoverQuestionCall(sk, {
8757
8791
  sourceAccount,
8758
8792
  candidates: failoverAccounts,
8759
- resetsAt: accountLimitHit.resetsAt,
8760
- window: accountLimitHit.window
8793
+ resetsAt: accountLimitHit?.resetsAt,
8794
+ window: accountLimitHit?.window,
8795
+ reason: accountLimitHit || !accountBlock ? void 0 : describeAccountBlock(accountBlock)
8761
8796
  });
8762
8797
  log.warn(
8763
- `Claude account "${sourceAccount}" is out of usage; asking which account to continue on.`,
8798
+ `Claude account "${sourceAccount}" ${accountLimitHit || !accountBlock ? "is out of usage" : `cannot serve (${accountBlock})`}; asking which account to continue on.`,
8764
8799
  {
8765
8800
  sessionKey: sk,
8766
8801
  candidates: failoverAccounts,
8767
8802
  toolCallId: call.toolCallId,
8768
- resetsAt: accountLimitHit.resetsAt ?? null
8803
+ resetsAt: accountLimitHit?.resetsAt ?? null
8769
8804
  }
8770
8805
  );
8771
8806
  finishWithQuestionCall(call);
@@ -8903,6 +8938,8 @@ ${plan}
8903
8938
  endTextBlock();
8904
8939
  }
8905
8940
  }
8941
+ const block = accountBlockKind(msg);
8942
+ if (block) accountBlock = block;
8906
8943
  if (msg.type === "rate_limit_event") {
8907
8944
  const info = parseRateLimitEvent(msg);
8908
8945
  if (info && isRateLimitRejected(info)) {
@@ -8919,58 +8956,58 @@ ${plan}
8919
8956
  return;
8920
8957
  }
8921
8958
  if (msg.type === "content_block_start" && msg.content_block && msg.index !== void 0) {
8922
- const block = msg.content_block;
8959
+ const block2 = msg.content_block;
8923
8960
  const idx = msg.index;
8924
- if (block.type === "thinking") {
8961
+ if (block2.type === "thinking") {
8925
8962
  noteReasoning();
8926
8963
  const reasoningId = generateId();
8927
8964
  reasoningIds.set(idx, reasoningId);
8928
8965
  }
8929
- if (block.type === "text") {
8966
+ if (block2.type === "text") {
8930
8967
  textBlockIndices.add(idx);
8931
8968
  resetLastVisibleTextBlock();
8932
- if (block.text) {
8969
+ if (block2.text) {
8933
8970
  if (!currentTextId) startTextBlock();
8934
8971
  controller.enqueue({
8935
8972
  type: "text-delta",
8936
8973
  id: currentTextId,
8937
- delta: block.text
8974
+ delta: block2.text
8938
8975
  });
8939
- noteVisibleText(block.text);
8976
+ noteVisibleText(block2.text);
8940
8977
  hasReceivedContent = true;
8941
8978
  }
8942
8979
  }
8943
- if (block.type === "tool_use" && block.id && block.name) {
8980
+ if (block2.type === "tool_use" && block2.id && block2.name) {
8944
8981
  noteToolActivity();
8945
8982
  const entry = {
8946
- id: block.id,
8947
- name: block.name,
8983
+ id: block2.id,
8984
+ name: block2.name,
8948
8985
  inputJson: "",
8949
8986
  started: false
8950
8987
  };
8951
8988
  toolCallMap.set(idx, entry);
8952
- if (block.name !== "AskUserQuestion" && block.name !== "ask_user_question" && block.name !== "ExitPlanMode" && !block.name.startsWith(PROXY_TOOL_PREFIX)) {
8989
+ if (block2.name !== "AskUserQuestion" && block2.name !== "ask_user_question" && block2.name !== "ExitPlanMode" && !block2.name.startsWith(PROXY_TOOL_PREFIX)) {
8953
8990
  const { name: mappedName, skip, executed } = mapTool(
8954
- block.name,
8991
+ block2.name,
8955
8992
  void 0,
8956
8993
  {
8957
8994
  webSearch: self.config.webSearch,
8958
8995
  sessionId: getClaudeSessionId(sk),
8959
- toolUseId: block.id
8996
+ toolUseId: block2.id
8960
8997
  }
8961
8998
  );
8962
8999
  if (!skip) {
8963
9000
  entry.started = true;
8964
9001
  controller.enqueue({
8965
9002
  type: "tool-input-start",
8966
- id: block.id,
9003
+ id: block2.id,
8967
9004
  toolName: mappedName,
8968
9005
  providerExecuted: executed
8969
9006
  });
8970
9007
  log.info("tool started", {
8971
- name: block.name,
9008
+ name: block2.name,
8972
9009
  mappedName,
8973
- id: block.id
9010
+ id: block2.id
8974
9011
  });
8975
9012
  }
8976
9013
  }
@@ -9161,8 +9198,8 @@ ${plan}
9161
9198
  hadStreamThinking: hadThinkingTextFromStream
9162
9199
  });
9163
9200
  if (!hadThinkingTextFromStream) {
9164
- for (const block of thinkingBlocks) {
9165
- if (block.thinking && block.thinking.length > 0) {
9201
+ for (const block2 of thinkingBlocks) {
9202
+ if (block2.thinking && block2.thinking.length > 0) {
9166
9203
  noteReasoning();
9167
9204
  hadThinkingTextFromStream = true;
9168
9205
  const thinkingId = generateId();
@@ -9173,7 +9210,7 @@ ${plan}
9173
9210
  controller.enqueue({
9174
9211
  type: "reasoning-delta",
9175
9212
  id: thinkingId,
9176
- delta: block.thinking
9213
+ delta: block2.thinking
9177
9214
  });
9178
9215
  controller.enqueue({
9179
9216
  type: "reasoning-end",
@@ -9200,20 +9237,20 @@ ${plan}
9200
9237
  if (hasToolUse) {
9201
9238
  clearFallbackTimer();
9202
9239
  }
9203
- for (const block of msg.message.content) {
9204
- if (block.type === "text" && block.text) {
9240
+ for (const block2 of msg.message.content) {
9241
+ if (block2.type === "text" && block2.text) {
9205
9242
  resetLastVisibleTextBlock();
9206
9243
  const blockId = startTextBlock();
9207
9244
  controller.enqueue({
9208
9245
  type: "text-delta",
9209
9246
  id: blockId,
9210
- delta: block.text
9247
+ delta: block2.text
9211
9248
  });
9212
9249
  endTextBlock();
9213
- noteVisibleText(block.text);
9250
+ noteVisibleText(block2.text);
9214
9251
  hasReceivedContent = true;
9215
9252
  }
9216
- if (block.type === "thinking" && block.thinking) {
9253
+ if (block2.type === "thinking" && block2.thinking) {
9217
9254
  noteReasoning();
9218
9255
  const thinkingId = generateId();
9219
9256
  controller.enqueue({
@@ -9223,17 +9260,17 @@ ${plan}
9223
9260
  controller.enqueue({
9224
9261
  type: "reasoning-delta",
9225
9262
  id: thinkingId,
9226
- delta: block.thinking
9263
+ delta: block2.thinking
9227
9264
  });
9228
9265
  controller.enqueue({
9229
9266
  type: "reasoning-end",
9230
9267
  id: thinkingId
9231
9268
  });
9232
9269
  }
9233
- if (block.type === "tool_use" && block.id && block.name) {
9270
+ if (block2.type === "tool_use" && block2.id && block2.name) {
9234
9271
  noteToolActivity();
9235
- const parsedInput = block.input ?? {};
9236
- if (isAskUserQuestionTool(block.name)) {
9272
+ const parsedInput = block2.input ?? {};
9273
+ if (isAskUserQuestionTool(block2.name)) {
9237
9274
  const askId = startTextBlock();
9238
9275
  controller.enqueue({
9239
9276
  type: "text-delta",
@@ -9241,12 +9278,12 @@ ${plan}
9241
9278
  delta: formatAskUserQuestion(parsedInput)
9242
9279
  });
9243
9280
  endTextBlock();
9244
- } else if (block.name === "ExitPlanMode") {
9281
+ } else if (block2.name === "ExitPlanMode") {
9245
9282
  const plan = parsedInput?.plan || "";
9246
9283
  if (planModeQuestionActive) {
9247
9284
  const questionCall = createExitPlanModeQuestionCall(
9248
9285
  sk,
9249
- block.id,
9286
+ block2.id,
9250
9287
  plan
9251
9288
  );
9252
9289
  const planId2 = startTextBlock();
@@ -9271,8 +9308,8 @@ ${plan}
9271
9308
  `
9272
9309
  });
9273
9310
  endTextBlock();
9274
- } else if (isWebSearchTool(block.name) && isWebSearchHandledByCli(self.config.webSearch)) {
9275
- toolCallsById.delete(block.id);
9311
+ } else if (isWebSearchTool(block2.name) && isWebSearchHandledByCli(self.config.webSearch)) {
9312
+ toolCallsById.delete(block2.id);
9276
9313
  const query = typeof parsedInput?.query === "string" ? parsedInput.query : JSON.stringify(parsedInput);
9277
9314
  const searchId = startTextBlock();
9278
9315
  controller.enqueue({
@@ -9283,11 +9320,11 @@ ${plan}
9283
9320
  `
9284
9321
  });
9285
9322
  endTextBlock();
9286
- } else if (block.name.startsWith(PROXY_TOOL_PREFIX)) {
9323
+ } else if (block2.name.startsWith(PROXY_TOOL_PREFIX)) {
9287
9324
  noteProxyActivity();
9288
9325
  log.debug("ignoring proxy tool_use from assistant message", {
9289
- name: block.name,
9290
- id: block.id
9326
+ name: block2.name,
9327
+ id: block2.id
9291
9328
  });
9292
9329
  } else {
9293
9330
  const {
@@ -9295,61 +9332,61 @@ ${plan}
9295
9332
  input: mappedInput,
9296
9333
  executed,
9297
9334
  skip
9298
- } = mapTool(block.name, parsedInput, {
9335
+ } = mapTool(block2.name, parsedInput, {
9299
9336
  webSearch: self.config.webSearch,
9300
9337
  sessionId: getClaudeSessionId(sk),
9301
- toolUseId: block.id
9338
+ toolUseId: block2.id
9302
9339
  });
9303
9340
  if (!skip) {
9304
- toolCallsById.set(block.id, {
9305
- id: block.id,
9306
- name: block.name,
9341
+ toolCallsById.set(block2.id, {
9342
+ id: block2.id,
9343
+ name: block2.name,
9307
9344
  input: parsedInput
9308
9345
  });
9309
- if (!executed) skipResultForIds.add(block.id);
9346
+ if (!executed) skipResultForIds.add(block2.id);
9310
9347
  controller.enqueue({
9311
9348
  type: "tool-input-start",
9312
- id: block.id,
9349
+ id: block2.id,
9313
9350
  toolName: mappedName,
9314
9351
  providerExecuted: executed
9315
9352
  });
9316
9353
  controller.enqueue({
9317
9354
  type: "tool-call",
9318
- toolCallId: block.id,
9355
+ toolCallId: block2.id,
9319
9356
  toolName: mappedName,
9320
9357
  input: JSON.stringify(mappedInput),
9321
9358
  providerExecuted: executed
9322
9359
  });
9323
9360
  }
9324
9361
  log.info("tool_use from assistant message", {
9325
- name: block.name,
9362
+ name: block2.name,
9326
9363
  mappedName,
9327
- id: block.id,
9364
+ id: block2.id,
9328
9365
  executed
9329
9366
  });
9330
9367
  }
9331
9368
  }
9332
- if (block.type === "tool_result") {
9369
+ if (block2.type === "tool_result") {
9333
9370
  log.debug("tool_result", {
9334
- toolUseId: block.tool_use_id
9371
+ toolUseId: block2.tool_use_id
9335
9372
  });
9336
9373
  }
9337
9374
  }
9338
9375
  }
9339
9376
  if (msg.type === "user" && msg.message?.content) {
9340
- for (const block of msg.message.content) {
9341
- if (block.type === "tool_result" && block.tool_use_id) {
9342
- if (skipResultForIds.has(block.tool_use_id)) {
9377
+ for (const block2 of msg.message.content) {
9378
+ if (block2.type === "tool_result" && block2.tool_use_id) {
9379
+ if (skipResultForIds.has(block2.tool_use_id)) {
9343
9380
  log.debug("skipping tool-result (opencode runs it)", {
9344
- toolUseId: block.tool_use_id
9381
+ toolUseId: block2.tool_use_id
9345
9382
  });
9346
9383
  continue;
9347
9384
  }
9348
9385
  let resultText = "";
9349
- if (typeof block.content === "string") {
9350
- resultText = block.content;
9351
- } else if (Array.isArray(block.content)) {
9352
- resultText = block.content.filter(
9386
+ if (typeof block2.content === "string") {
9387
+ resultText = block2.content;
9388
+ } else if (Array.isArray(block2.content)) {
9389
+ resultText = block2.content.filter(
9353
9390
  (c) => c.type === "text" && typeof c.text === "string"
9354
9391
  ).map((c) => c.text).join("\n");
9355
9392
  }
@@ -9357,11 +9394,11 @@ ${plan}
9357
9394
  if (claudeSessionId) {
9358
9395
  const list2 = applyTaskCreateToolResult(
9359
9396
  claudeSessionId,
9360
- block.tool_use_id,
9397
+ block2.tool_use_id,
9361
9398
  resultText
9362
9399
  );
9363
9400
  if (list2) {
9364
- const synthId = `todowrite_${block.tool_use_id}`;
9401
+ const synthId = `todowrite_${block2.tool_use_id}`;
9365
9402
  controller.enqueue({
9366
9403
  type: "tool-input-start",
9367
9404
  id: synthId,
@@ -9385,12 +9422,12 @@ ${plan}
9385
9422
  noteToolActivity();
9386
9423
  }
9387
9424
  }
9388
- const toolCall = toolCallsById.get(block.tool_use_id);
9425
+ const toolCall = toolCallsById.get(block2.tool_use_id);
9389
9426
  if (toolCall) {
9390
- const isError = block.is_error === true;
9427
+ const isError = block2.is_error === true;
9391
9428
  controller.enqueue({
9392
9429
  type: "tool-result",
9393
- toolCallId: block.tool_use_id,
9430
+ toolCallId: block2.tool_use_id,
9394
9431
  toolName: toolCall.name,
9395
9432
  result: {
9396
9433
  output: resultText,
@@ -9402,11 +9439,11 @@ ${plan}
9402
9439
  });
9403
9440
  noteToolActivity();
9404
9441
  log.info("tool result emitted", {
9405
- toolUseId: block.tool_use_id,
9442
+ toolUseId: block2.tool_use_id,
9406
9443
  name: toolCall.name,
9407
9444
  isError
9408
9445
  });
9409
- toolCallsById.delete(block.tool_use_id);
9446
+ toolCallsById.delete(block2.tool_use_id);
9410
9447
  }
9411
9448
  }
9412
9449
  }
@@ -9432,6 +9469,26 @@ ${plan}
9432
9469
  })) {
9433
9470
  accountLimitHit = {};
9434
9471
  }
9472
+ if (accountBlock && msg.is_error) {
9473
+ resultFailure ??= accountBlock;
9474
+ const offeringSwitch = failoverAskActive;
9475
+ controller.enqueue({
9476
+ type: "text-delta",
9477
+ id: startTextBlock(),
9478
+ delta: formatAccountBlockNote({
9479
+ kind: accountBlock,
9480
+ account: sourceAccount,
9481
+ configDir: self.config.configDir,
9482
+ offeringSwitch
9483
+ })
9484
+ });
9485
+ endTextBlock();
9486
+ log.warn(`Claude account "${sourceAccount}" cannot serve requests`, {
9487
+ sessionKey: sk,
9488
+ kind: accountBlock,
9489
+ offeringSwitch
9490
+ });
9491
+ }
9435
9492
  const failure = describeResultFailure(msg);
9436
9493
  if (failure) {
9437
9494
  resultFailure = msg.subtype;
@@ -9877,7 +9934,7 @@ import {
9877
9934
  rmSync as rmSync3,
9878
9935
  writeFileSync as writeFileSync5
9879
9936
  } from "fs";
9880
- import { homedir as homedir6 } from "os";
9937
+ import { homedir as homedir7 } from "os";
9881
9938
  import { join as join9, resolve as resolve4 } from "path";
9882
9939
  import { fileURLToPath as fileURLToPath3 } from "url";
9883
9940
  var STALE_PACKAGE_NAME = "opencode-claude-code-plugin";
@@ -9887,12 +9944,12 @@ function candidateCacheRoots() {
9887
9944
  const xdg = process.env.XDG_CACHE_HOME;
9888
9945
  return [
9889
9946
  xdg ? join9(xdg, "opencode") : null,
9890
- join9(homedir6(), ".cache", "opencode"),
9891
- join9(homedir6(), "Library", "Caches", "opencode")
9947
+ join9(homedir7(), ".cache", "opencode"),
9948
+ join9(homedir7(), "Library", "Caches", "opencode")
9892
9949
  ].filter((p) => Boolean(p));
9893
9950
  }
9894
9951
  function userOpencodeJsonPath() {
9895
- const xdgConfig = process.env.XDG_CONFIG_HOME ?? join9(homedir6(), ".config");
9952
+ const xdgConfig = process.env.XDG_CONFIG_HOME ?? join9(homedir7(), ".config");
9896
9953
  return join9(xdgConfig, "opencode", "opencode.json");
9897
9954
  }
9898
9955
  function userIntendsToUseUnscoped() {