opencode-resolve 0.1.2 → 0.1.4

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.
@@ -1,5 +1,5 @@
1
1
  import { constants } from "node:fs"
2
- import { access, copyFile, mkdir, readFile, writeFile } from "node:fs/promises"
2
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises"
3
3
  import { homedir } from "node:os"
4
4
  import { dirname, join, resolve } from "node:path"
5
5
  import { fileURLToPath } from "node:url"
@@ -13,20 +13,34 @@ const exampleConfigPath = join(root, "opencode-resolve.example.json")
13
13
 
14
14
  const ADDITIVE_DEFAULTS = {
15
15
  autoApprove: true,
16
- maxParallelSubagents: 1,
16
+ maxParallelSubagents: 2,
17
17
  }
18
18
 
19
19
  if (process.env.OPENCODE_RESOLVE_SKIP_POSTINSTALL === "1") {
20
20
  process.exit(0)
21
21
  }
22
22
 
23
+ const pluginVersion = await readOwnVersion()
24
+ console.log(`[${packageName}] installing v${pluginVersion}`)
25
+
23
26
  try {
24
27
  await registerPlugin()
28
+ console.log(`[${packageName}] v${pluginVersion} install complete — restart OpenCode to load the plugin`)
25
29
  } catch (error) {
26
30
  console.warn(`[${packageName}] automatic OpenCode registration skipped: ${formatError(error)}`)
27
31
  console.warn(`[${packageName}] add "${packageName}" to your OpenCode plugin list manually if needed.`)
28
32
  }
29
33
 
34
+ async function readOwnVersion() {
35
+ try {
36
+ const raw = await readFile(join(root, "package.json"), "utf8")
37
+ const parsed = JSON.parse(raw)
38
+ return typeof parsed?.version === "string" ? parsed.version : "unknown"
39
+ } catch {
40
+ return "unknown"
41
+ }
42
+ }
43
+
30
44
  async function registerPlugin() {
31
45
  await mkdir(configDir, { recursive: true })
32
46
 
@@ -41,15 +55,107 @@ async function registerPlugin() {
41
55
  }
42
56
 
43
57
  if (!(await exists(resolveConfigPath))) {
44
- await assertReadable(exampleConfigPath)
45
- await copyFile(exampleConfigPath, resolveConfigPath)
46
- console.log(`[${packageName}] created ${resolveConfigPath}`)
58
+ await createAdaptiveResolveConfig(config)
47
59
  return
48
60
  }
49
61
 
50
62
  await migrateResolveConfig()
51
63
  }
52
64
 
65
+ async function createAdaptiveResolveConfig(opencodeConfig) {
66
+ await assertReadable(exampleConfigPath)
67
+ const raw = await readFile(exampleConfigPath, "utf8")
68
+ const example = JSON.parse(raw)
69
+
70
+ const currentModel = detectOpenCodeModel(opencodeConfig)
71
+ const preset = buildModelPreset(currentModel)
72
+
73
+ const resolveConfig = { ...example }
74
+ if (preset && Object.keys(preset).length > 0) {
75
+ resolveConfig.models = preset
76
+ }
77
+
78
+ await writeFile(resolveConfigPath, `${JSON.stringify(resolveConfig, null, 2)}\n`)
79
+
80
+ const label = getPresetLabel(currentModel)
81
+ console.log(`[${packageName}] created ${resolveConfigPath} (preset: ${label})`)
82
+ }
83
+
84
+ function detectOpenCodeModel(config) {
85
+ // Prefer top-level `model` as primary signal
86
+ if (typeof config.model === "string" && config.model.length > 0) {
87
+ return config.model
88
+ }
89
+
90
+ // Check top-level `models` object values if present
91
+ if (isObject(config.models)) {
92
+ for (const value of Object.values(config.models)) {
93
+ if (typeof value === "string" && value.length > 0) {
94
+ return value
95
+ }
96
+ }
97
+ }
98
+
99
+ // Check agent.*.model values if present
100
+ if (isObject(config.agent)) {
101
+ for (const agentConfig of Object.values(config.agent)) {
102
+ if (isObject(agentConfig) && typeof agentConfig.model === "string" && agentConfig.model.length > 0) {
103
+ return agentConfig.model
104
+ }
105
+ }
106
+ }
107
+
108
+ return null
109
+ }
110
+
111
+ function buildModelPreset(currentModel) {
112
+ if (!currentModel) return {}
113
+
114
+ const lower = currentModel.toLowerCase()
115
+
116
+ // GLM / ZAI mixed preset
117
+ if (lower.includes("glm") || lower.includes("zai")) {
118
+ return {
119
+ glm: "zai-coding-plan/glm-5.1",
120
+ gpt: "openai/gpt-5.5",
121
+ fast: "glm",
122
+ strong: "gpt",
123
+ coder: "glm",
124
+ resolver: "gpt",
125
+ reviewer: "gpt",
126
+ "deep-reviewer": "gpt",
127
+ explorer: "fast",
128
+ }
129
+ }
130
+
131
+ // OpenAI / GPT single-provider preset
132
+ if (lower.includes("openai/") || lower.includes("gpt")) {
133
+ return {
134
+ gpt: currentModel,
135
+ fast: "gpt",
136
+ strong: "gpt",
137
+ mini: "gpt",
138
+ codex: "gpt",
139
+ coder: "gpt",
140
+ resolver: "gpt",
141
+ explorer: "gpt",
142
+ reviewer: "gpt",
143
+ "deep-reviewer": "gpt",
144
+ }
145
+ }
146
+
147
+ // Unknown provider — keep model-neutral
148
+ return {}
149
+ }
150
+
151
+ function getPresetLabel(currentModel) {
152
+ if (!currentModel) return "inherited"
153
+ const lower = currentModel.toLowerCase()
154
+ if (lower.includes("glm") || lower.includes("zai")) return "glm+gpt"
155
+ if (lower.includes("openai/") || lower.includes("gpt")) return "gpt-only"
156
+ return "inherited"
157
+ }
158
+
53
159
  async function migrateResolveConfig() {
54
160
  let raw
55
161
  try {