opencode-resolve 0.1.16 → 0.1.18

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.ko.md CHANGED
@@ -52,6 +52,15 @@ opencode plugin opencode-resolve --global --force
52
52
 
53
53
  ## 설치
54
54
 
55
+ ### 한 줄 설치 (권장)
56
+
57
+ ```sh
58
+ npm install -g opencode-resolve@latest
59
+ opencode-resolve setup
60
+ ```
61
+
62
+ `opencode-resolve setup`이 `opencode.json`의 provider/model을 자동 감지하고, 합리적인 기본값으로 짧은 Q&A를 거친 뒤(엔터로 모두 통과 가능) `resolve.json`을 작성하고 OpenCode 플러그인 캐시를 새로고침합니다. 모델 핀을 보존한 채 언제든 다시 실행해 재설정할 수 있습니다.
63
+
55
64
  ### 요구 사항
56
65
 
57
66
  - OpenCode 실행 가능: `opencode --version`
package/README.md CHANGED
@@ -52,6 +52,15 @@ Default enabled agents:
52
52
 
53
53
  ## Install
54
54
 
55
+ ### One command (recommended)
56
+
57
+ ```sh
58
+ npm install -g opencode-resolve@latest
59
+ opencode-resolve setup
60
+ ```
61
+
62
+ `opencode-resolve setup` auto-detects your providers and models from `opencode.json`, walks you through a short Q&A with sensible defaults (press enter to accept each), writes `resolve.json`, and refreshes the OpenCode plugin cache. Re-run any time to reconfigure without losing your model pins.
63
+
55
64
  ### Requirements
56
65
 
57
66
  - OpenCode installed and runnable: `opencode --version`
package/dist/index.js CHANGED
@@ -3,9 +3,20 @@ export * from "./agents.js";
3
3
  export * from "./utils.js";
4
4
  export * from "./config.js";
5
5
  export * from "./state.js";
6
+ import { fileURLToPath } from "node:url";
7
+ import { dirname } from "node:path";
6
8
  import { getTools } from "./tools/index.js";
7
9
  import { getHooks } from "./hooks/index.js";
8
10
  import { createSessionState } from "./state.js";
11
+ import { PLUGIN_VERSION } from "./utils.js";
12
+ if (process.env.OPENCODE_RESOLVE_QUIET !== "1") {
13
+ let where = "";
14
+ try {
15
+ where = ` (from: ${dirname(fileURLToPath(import.meta.url))})`;
16
+ }
17
+ catch { /* ignore */ }
18
+ console.log(`[opencode-resolve] v${PLUGIN_VERSION} loaded${where}`);
19
+ }
9
20
  export const OpencodeResolve = async ({ directory }, options) => {
10
21
  const sessionState = createSessionState();
11
22
  return {
@@ -238,6 +238,11 @@ export declare function getTools(sessionState: SessionState): {
238
238
  args: {};
239
239
  execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
240
240
  };
241
+ "resolve-version": {
242
+ description: string;
243
+ args: {};
244
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
245
+ };
241
246
  "resolve-state": {
242
247
  description: string;
243
248
  args: {
@@ -2,7 +2,9 @@ import { tool } from "@opencode-ai/plugin";
2
2
  import { stat, readFile, access } from "node:fs/promises";
3
3
  import { resolve, join } from "node:path";
4
4
  import { writeFileSync, mkdirSync } from "node:fs";
5
- import { classifyBashCommand, runCommand, sanitizeShellArg, truncateOutput } from "../utils.js";
5
+ import { fileURLToPath } from "node:url";
6
+ import { dirname } from "node:path";
7
+ import { classifyBashCommand, runCommand, sanitizeShellArg, truncateOutput, PLUGIN_VERSION } from "../utils.js";
6
8
  import { DIAGNOSTICS_TTL_MS } from "../state.js";
7
9
  import { VALID_PROFILES, VALID_TIERS, VALID_AGENT_NAME_SET, VALID_AGENT_NAMES } from "../agents.js";
8
10
  const WRITE_CAPABLE_AGENTS = new Set(["resolver", "codex", "coder", "glm", "gpt-coder", "debugger"]);
@@ -1140,6 +1142,23 @@ export function getTools(sessionState) {
1140
1142
  return results.join("\n");
1141
1143
  },
1142
1144
  }),
1145
+ "resolve-version": tool({
1146
+ description: "Report the currently loaded opencode-resolve plugin version and the cache path it was loaded from. Use to confirm whether a recent install/update actually took effect inside OpenCode.",
1147
+ args: {},
1148
+ async execute(_args, ctx) {
1149
+ let loadedFrom = "unknown";
1150
+ try {
1151
+ loadedFrom = dirname(fileURLToPath(import.meta.url));
1152
+ }
1153
+ catch { /* ignore */ }
1154
+ const lines = [
1155
+ `opencode-resolve v${PLUGIN_VERSION}`,
1156
+ `loaded from: ${loadedFrom}`,
1157
+ ];
1158
+ ctx.metadata({ title: `version: v${PLUGIN_VERSION}` });
1159
+ return lines.join("\n");
1160
+ },
1161
+ }),
1143
1162
  "resolve-state": tool({
1144
1163
  description: "Read or write session state checkpoints to .opencode/resolve-state.json. Enables session resumption and cross-turn state persistence. Use 'save' to checkpoint current progress, 'load' to read last checkpoint.",
1145
1164
  args: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-resolve",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "OpenCode plugin that adds a lightweight resolver/coder harness for continuous agentic coding.",
5
5
  "type": "module",
6
6
  "homepage": "https://jshsakura.github.io/opencode-resolve/",
@@ -84,11 +84,41 @@ if (process.env.OPENCODE_RESOLVE_SKIP_POSTINSTALL === "1") {
84
84
  const pluginVersion = await readOwnVersion()
85
85
  console.log(`[${packageName}] installing v${pluginVersion}`)
86
86
 
87
+ async function printSummaryBanner(version) {
88
+ let resolveSummary = ""
89
+ try {
90
+ const raw = await readFile(resolveConfigPath, "utf8")
91
+ const cfg = JSON.parse(raw)
92
+ const parts = []
93
+ if (cfg.profile) parts.push(`profile=${cfg.profile}`)
94
+ if (cfg.tier) parts.push(`tier=${cfg.tier}`)
95
+ const enabled = Array.isArray(cfg.enabled) ? cfg.enabled.length : Object.keys(cfg.agents ?? {}).length
96
+ if (enabled) parts.push(`${enabled} agents`)
97
+ if (parts.length > 0) resolveSummary = parts.join(", ")
98
+ } catch { /* file may not exist on partial flows */ }
99
+
100
+ const lines = [
101
+ `✓ opencode-resolve v${version} installed`,
102
+ ` Config: ${resolveConfigPath}${resolveSummary ? ` (${resolveSummary})` : ""}`,
103
+ ` Next: restart OpenCode to load the plugin`,
104
+ ` Verify: opencode run "list available agents" (must show resolver + coder)`,
105
+ ` or inside any session: run resolve-version`,
106
+ ]
107
+ const width = Math.max(...lines.map((l) => l.length)) + 2
108
+ const bar = "═".repeat(Math.min(width, 100))
109
+ console.log("")
110
+ console.log(bar)
111
+ for (const line of lines) console.log(line)
112
+ console.log(bar)
113
+ console.log("")
114
+ }
115
+
87
116
  try {
88
117
  await registerPlugin()
89
118
  await refreshSelfPluginCache(pluginVersion)
90
119
  await offerCompanionPlugins()
91
120
  console.log(`[${packageName}] v${pluginVersion} install complete — restart OpenCode to load the plugin`)
121
+ await printSummaryBanner(pluginVersion)
92
122
  } catch (error) {
93
123
  console.warn(`[${packageName}] automatic OpenCode registration skipped: ${formatError(error)}`)
94
124
  console.warn(`[${packageName}] add "${packageName}" to your OpenCode plugin list manually if needed.`)
@@ -359,8 +389,10 @@ async function createAdaptiveResolveConfig(opencodeConfig, scriptedAnswers, opti
359
389
  } else if (preservedModels) {
360
390
  resolveConfig.models = { ...preservedModels }
361
391
  } else {
362
- console.log(`[${packageName}] no GPT/GLM models detected in opencode.json — agents inherit the top-level model`)
363
- console.log(`[${packageName}] to configure model pinning, rerun setup in a TTY or edit ${resolveConfigPath}`)
392
+ const providerHint = currentModel ? ` (top-level model: ${currentModel})` : ""
393
+ console.log(`[${packageName}] no GPT/GLM models detected in opencode.json agents inherit the top-level model${providerHint}`)
394
+ console.log(`[${packageName}] to pin role-specific models, edit ${resolveConfigPath} ("models" section)`)
395
+ console.log(`[${packageName}] or rerun setup in a TTY: ${packageName} setup --models`)
364
396
  }
365
397
 
366
398
  await writeFile(resolveConfigPath, `${JSON.stringify(resolveConfig, null, 2)}\n`)
@@ -563,8 +595,13 @@ async function buildInteractivePreset(currentModel, allModels, scriptedAnswers)
563
595
  const rl = createPromptInterface(scriptedAnswers)
564
596
  try {
565
597
  console.log("")
566
- console.log(`[${packageName}] Choose resolve profile:`)
567
- console.log(" 1. mix — neutral resolver plus optional Codex and GLM primary agents")
598
+ console.log("──────────────────────────────────────────────────────────────")
599
+ console.log(` opencode-resolve setup`)
600
+ console.log(` Press enter at any prompt to accept the default in [brackets].`)
601
+ console.log("──────────────────────────────────────────────────────────────")
602
+ console.log("")
603
+ console.log(`[${packageName}] Step 1/2 — Choose resolve profile:`)
604
+ console.log(" 1. mix — neutral resolver plus optional Codex and GLM primary agents (recommended)")
568
605
  console.log(" 2. gpt — GPT/Codex-only, three-tier")
569
606
  console.log(" 3. glm — GLM-only, three-tier")
570
607
  const profileAnswer = await askChoice(rl, "Profile [1=mix, 2=gpt, 3=glm, default 1]: ", ["1", "2", "3"], "1")