@khalilgharbaoui/opencode-claude-code-plugin 0.42.1 → 0.42.2
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 +72 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/claude-code-plugin/SKILL.md +8 -3
package/dist/index.js
CHANGED
|
@@ -1723,6 +1723,21 @@ function cliSupportsDontAsk(v) {
|
|
|
1723
1723
|
if (!v) return false;
|
|
1724
1724
|
return gte(v, { major: 2, minor: 1, patch: 263 });
|
|
1725
1725
|
}
|
|
1726
|
+
var INTERACTIVE_MEASURED_CLI = "2.1.288";
|
|
1727
|
+
var INTERACTIVE_MEASURED = { major: 2, minor: 1, patch: 288 };
|
|
1728
|
+
function isUnmeasuredInteractiveCli(v) {
|
|
1729
|
+
if (!v) return false;
|
|
1730
|
+
return gte(v, INTERACTIVE_MEASURED) && !(v.major === INTERACTIVE_MEASURED.major && v.minor === INTERACTIVE_MEASURED.minor && v.patch === INTERACTIVE_MEASURED.patch);
|
|
1731
|
+
}
|
|
1732
|
+
var warnedUnmeasuredInteractive = /* @__PURE__ */ new Set();
|
|
1733
|
+
function reportUnmeasuredInteractiveCli(v) {
|
|
1734
|
+
if (!v || !isUnmeasuredInteractiveCli(v) || warnedUnmeasuredInteractive.has(v.raw)) return;
|
|
1735
|
+
warnedUnmeasuredInteractive.add(v.raw);
|
|
1736
|
+
log.warn(
|
|
1737
|
+
"the interactive transport has not been measured on this Claude Code version; it reads the TUI's screen and transcript, which a new release can change. If a turn hangs or a dialog is not handled, run /claude-code-doctor bundle and report it",
|
|
1738
|
+
{ cliVersion: v.raw, measuredCli: INTERACTIVE_MEASURED_CLI }
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1726
1741
|
function cliSupportsSideQuestion(v) {
|
|
1727
1742
|
if (!v) return false;
|
|
1728
1743
|
return gte(v, { major: 2, minor: 1, patch: 258 });
|
|
@@ -5431,6 +5446,7 @@ function snapshotActiveProcesses(now = Date.now()) {
|
|
|
5431
5446
|
ageMs: ap.startedAt === void 0 ? void 0 : Math.max(0, now - ap.startedAt),
|
|
5432
5447
|
effort: ap.effort,
|
|
5433
5448
|
attached: ap.lineEmitter.listenerCount("line") > 0,
|
|
5449
|
+
transport: ap.interactiveControl ? "interactive" : "headless",
|
|
5434
5450
|
proxyUrl: ap.proxyServer?.url,
|
|
5435
5451
|
lastStderr: typeof lastStderr === "string" ? lastStderr : void 0
|
|
5436
5452
|
});
|
|
@@ -5845,6 +5861,7 @@ var PLUGIN_LOG_MESSAGES = /* @__PURE__ */ new Set([
|
|
|
5845
5861
|
"skipping remote MCP server with no url",
|
|
5846
5862
|
"stale scratch directory sweep failed",
|
|
5847
5863
|
"task_batch resolving with child results missing",
|
|
5864
|
+
"the interactive transport has not been measured on this Claude Code version; it reads the TUI's screen and transcript, which a new release can change. If a turn hangs or a dialog is not handled, run /claude-code-doctor bundle and report it",
|
|
5848
5865
|
"this opencode process is running an older plugin build than the one on disk",
|
|
5849
5866
|
"timed out pending proxy call",
|
|
5850
5867
|
"turn abort listener threw",
|
|
@@ -5994,6 +6011,7 @@ var BUNDLE_DATA_ALLOWLIST = {
|
|
|
5994
6011
|
toolNames: "name",
|
|
5995
6012
|
cliFloor: "version",
|
|
5996
6013
|
cliVersion: "version",
|
|
6014
|
+
measuredCli: "version",
|
|
5997
6015
|
// The two halves of the stale-build WARN: what this process loaded and what
|
|
5998
6016
|
// is on disk now. Both are this package's own version strings.
|
|
5999
6017
|
loadedVersion: "version",
|
|
@@ -6453,6 +6471,34 @@ import * as fs4 from "fs";
|
|
|
6453
6471
|
import * as path5 from "path";
|
|
6454
6472
|
import { promisify as promisify2 } from "util";
|
|
6455
6473
|
import { fileURLToPath } from "url";
|
|
6474
|
+
|
|
6475
|
+
// src/transport.ts
|
|
6476
|
+
function requestedTransport(config, env = process.env.CLAUDE_CODE_INTERACTIVE_TRANSPORT) {
|
|
6477
|
+
if (config.transport !== void 0) {
|
|
6478
|
+
if (!["auto", "headless", "interactive"].includes(config.transport)) {
|
|
6479
|
+
throw new Error(`Unknown Claude transport: ${config.transport}`);
|
|
6480
|
+
}
|
|
6481
|
+
return config.transport;
|
|
6482
|
+
}
|
|
6483
|
+
const enabled = config.interactive ?? (env !== void 0 && !["", "0", "false", "no", "off"].includes(env.trim().toLowerCase()));
|
|
6484
|
+
return enabled ? "interactive" : "headless";
|
|
6485
|
+
}
|
|
6486
|
+
function hasInteractiveTransport() {
|
|
6487
|
+
const runtime = globalThis;
|
|
6488
|
+
return typeof runtime.Bun?.Terminal === "function";
|
|
6489
|
+
}
|
|
6490
|
+
async function selectTransport(requested, cliPath, available = hasInteractiveTransport()) {
|
|
6491
|
+
if (requested === "headless") return "headless";
|
|
6492
|
+
if (requested === "interactive") {
|
|
6493
|
+
if (!available) throw new Error("Interactive Claude transport requires Bun.Terminal. Run opencode under a Bun runtime with PTY support.");
|
|
6494
|
+
return "interactive";
|
|
6495
|
+
}
|
|
6496
|
+
if (await detectHeadlessSupport(cliPath) !== "unsupported") return "headless";
|
|
6497
|
+
if (!available) throw new Error("Claude no longer supports the headless flags, and Bun.Terminal is unavailable. Run opencode under a Bun runtime with PTY support.");
|
|
6498
|
+
return "interactive";
|
|
6499
|
+
}
|
|
6500
|
+
|
|
6501
|
+
// src/startup-diagnostics.ts
|
|
6456
6502
|
var cachedPluginVersion;
|
|
6457
6503
|
function pluginVersion() {
|
|
6458
6504
|
if (cachedPluginVersion) return cachedPluginVersion;
|
|
@@ -6535,6 +6581,15 @@ function collectStartupDiagnostics(providers, opencodeVersion) {
|
|
|
6535
6581
|
error: err instanceof Error ? err.message : String(err)
|
|
6536
6582
|
});
|
|
6537
6583
|
}
|
|
6584
|
+
let transport;
|
|
6585
|
+
try {
|
|
6586
|
+
transport = requestedTransport({
|
|
6587
|
+
transport: firstOption(providers, "transport"),
|
|
6588
|
+
interactive: firstOption(providers, "interactive")
|
|
6589
|
+
});
|
|
6590
|
+
} catch {
|
|
6591
|
+
transport = "invalid";
|
|
6592
|
+
}
|
|
6538
6593
|
return {
|
|
6539
6594
|
plugin: pluginVersion(),
|
|
6540
6595
|
opencode: opencodeVersion ?? process.env.OPENCODE_VERSION ?? "unknown",
|
|
@@ -6547,7 +6602,8 @@ function collectStartupDiagnostics(providers, opencodeVersion) {
|
|
|
6547
6602
|
permissionPresets: Object.entries(providers).map(
|
|
6548
6603
|
([name, entry]) => summarizePermissionPreset(name, entry?.options)
|
|
6549
6604
|
),
|
|
6550
|
-
|
|
6605
|
+
transport,
|
|
6606
|
+
interactiveTransport: transport === "interactive",
|
|
6551
6607
|
planModeQuestion: firstOption(providers, "planModeQuestion") === true,
|
|
6552
6608
|
anthropicApiKeyInEnv: Boolean(
|
|
6553
6609
|
process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN
|
|
@@ -6816,7 +6872,14 @@ function formatDoctorReport(report) {
|
|
|
6816
6872
|
lines.push(`| proxyTools | ${list(report.proxyTools)} |`);
|
|
6817
6873
|
lines.push(`| MCP servers (on disk) | ${list(report.mcpServers)} |`);
|
|
6818
6874
|
lines.push(`| permissionPreset | ${describePermissionPresets(report.permissionPresets)} |`);
|
|
6819
|
-
lines.push(
|
|
6875
|
+
lines.push(
|
|
6876
|
+
`| transport | ${report.transport}${report.transport === "auto" ? " (headless until claude refuses `--print`)" : ""}; this conversation: ${report.transportInUse} |`
|
|
6877
|
+
);
|
|
6878
|
+
if (report.interactiveMeasured) {
|
|
6879
|
+
lines.push(
|
|
6880
|
+
`| interactive transport measured on | Claude Code ${report.interactiveMeasured.measured}${report.interactiveMeasured.unmeasured ? ` (this CLI, ${report.claudeCli.version}, is newer and unmeasured: if a turn hangs, send \`/claude-code-doctor bundle\`)` : ""} |`
|
|
6881
|
+
);
|
|
6882
|
+
}
|
|
6820
6883
|
lines.push(`| planModeQuestion | ${report.planModeQuestion} |`);
|
|
6821
6884
|
lines.push(`| turnStats | ${report.turnStats} |`);
|
|
6822
6885
|
lines.push(`| ANTHROPIC_API_KEY in env | ${report.anthropicApiKeyInEnv ? "yes" : "no"} |`);
|
|
@@ -6837,11 +6900,11 @@ function formatDoctorReport(report) {
|
|
|
6837
6900
|
if (report.processes.length === 0) {
|
|
6838
6901
|
lines.push("None. The next message in a Claude Code session spawns one.");
|
|
6839
6902
|
} else {
|
|
6840
|
-
lines.push("| session | model | pid | in flight | age | effort |");
|
|
6841
|
-
lines.push("
|
|
6903
|
+
lines.push("| session | model | transport | pid | in flight | age | effort |");
|
|
6904
|
+
lines.push("|---|---|---|---|---|---|---|");
|
|
6842
6905
|
for (const proc of report.processes) {
|
|
6843
6906
|
lines.push(
|
|
6844
|
-
`| ${proc.session}${proc.compaction ? " (compaction)" : ""} | ${proc.model} | ${proc.pid ?? "unknown"} | ${proc.inFlight ? "yes" : "no"} | ${formatAge(proc.ageMs)} | ${proc.effort ?? "inherited"} |`
|
|
6907
|
+
`| ${proc.session}${proc.compaction ? " (compaction)" : ""} | ${proc.model} | ${proc.transport} | ${proc.pid ?? "unknown"} | ${proc.inFlight ? "yes" : "no"} | ${formatAge(proc.ageMs)} | ${proc.effort ?? "inherited"} |`
|
|
6845
6908
|
);
|
|
6846
6909
|
}
|
|
6847
6910
|
}
|
|
@@ -7061,7 +7124,9 @@ async function gatherDoctorReport(options) {
|
|
|
7061
7124
|
proxyTools: base.proxyTools,
|
|
7062
7125
|
mcpServers: base.mcpServers,
|
|
7063
7126
|
permissionPresets: base.permissionPresets,
|
|
7064
|
-
transport:
|
|
7127
|
+
transport: base.transport,
|
|
7128
|
+
transportInUse: options.interactive ? "interactive" : "headless",
|
|
7129
|
+
interactiveMeasured: base.transport !== "headless" || options.interactive || processes.some((proc) => proc.transport === "interactive") ? { measured: INTERACTIVE_MEASURED_CLI, unmeasured: isUnmeasuredInteractiveCli(cli) } : void 0,
|
|
7065
7130
|
planModeQuestion: base.planModeQuestion,
|
|
7066
7131
|
turnStats: options.turnStats,
|
|
7067
7132
|
anthropicApiKeyInEnv: base.anthropicApiKeyInEnv,
|
|
@@ -10064,32 +10129,6 @@ function spawnInteractiveProcess(opts) {
|
|
|
10064
10129
|
return ap;
|
|
10065
10130
|
}
|
|
10066
10131
|
|
|
10067
|
-
// src/transport.ts
|
|
10068
|
-
function requestedTransport(config, env = process.env.CLAUDE_CODE_INTERACTIVE_TRANSPORT) {
|
|
10069
|
-
if (config.transport !== void 0) {
|
|
10070
|
-
if (!["auto", "headless", "interactive"].includes(config.transport)) {
|
|
10071
|
-
throw new Error(`Unknown Claude transport: ${config.transport}`);
|
|
10072
|
-
}
|
|
10073
|
-
return config.transport;
|
|
10074
|
-
}
|
|
10075
|
-
const enabled = config.interactive ?? (env !== void 0 && !["", "0", "false", "no", "off"].includes(env.trim().toLowerCase()));
|
|
10076
|
-
return enabled ? "interactive" : "headless";
|
|
10077
|
-
}
|
|
10078
|
-
function hasInteractiveTransport() {
|
|
10079
|
-
const runtime = globalThis;
|
|
10080
|
-
return typeof runtime.Bun?.Terminal === "function";
|
|
10081
|
-
}
|
|
10082
|
-
async function selectTransport(requested, cliPath, available = hasInteractiveTransport()) {
|
|
10083
|
-
if (requested === "headless") return "headless";
|
|
10084
|
-
if (requested === "interactive") {
|
|
10085
|
-
if (!available) throw new Error("Interactive Claude transport requires Bun.Terminal. Run opencode under a Bun runtime with PTY support.");
|
|
10086
|
-
return "interactive";
|
|
10087
|
-
}
|
|
10088
|
-
if (await detectHeadlessSupport(cliPath) !== "unsupported") return "headless";
|
|
10089
|
-
if (!available) throw new Error("Claude no longer supports the headless flags, and Bun.Terminal is unavailable. Run opencode under a Bun runtime with PTY support.");
|
|
10090
|
-
return "interactive";
|
|
10091
|
-
}
|
|
10092
|
-
|
|
10093
10132
|
// src/prompts.ts
|
|
10094
10133
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
10095
10134
|
import { homedir as homedir8 } from "os";
|
|
@@ -13333,6 +13372,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
13333
13372
|
return abortedBeforeWork("waiting for opencode's MCP status and the CLI version");
|
|
13334
13373
|
}
|
|
13335
13374
|
const [runtimeStatus, cliVersion] = prologue.value;
|
|
13375
|
+
if (useInteractive) reportUnmeasuredInteractiveCli(cliVersion);
|
|
13336
13376
|
const ptyReadOnly = useInteractive && !compactionMode && !doctor && isReadOnlyPermissionMode(this.config.permissionMode);
|
|
13337
13377
|
const ptyReadOnlySupported = cliSupportsRestricted(cliVersion) && cliSupportsDontAsk(cliVersion);
|
|
13338
13378
|
if (ptyReadOnly && !ptyReadOnlySupported) {
|