@osanoai/multicli 1.5.18 → 1.5.19
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 +35 -10
- package/dist/clientFilter.d.ts.map +1 -1
- package/dist/clientFilter.js +1 -0
- package/dist/clientFilter.js.map +1 -1
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -1
- package/dist/modelCatalog.d.ts +4 -3
- package/dist/modelCatalog.d.ts.map +1 -1
- package/dist/modelCatalog.js.map +1 -1
- package/dist/tierConfig.d.ts +3 -1
- package/dist/tierConfig.d.ts.map +1 -1
- package/dist/tierConfig.js +15 -0
- package/dist/tierConfig.js.map +1 -1
- package/dist/tools/ask-opencode.tool.d.ts +3 -0
- package/dist/tools/ask-opencode.tool.d.ts.map +1 -0
- package/dist/tools/ask-opencode.tool.js +25 -0
- package/dist/tools/ask-opencode.tool.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/simple-tools.d.ts +2 -0
- package/dist/tools/simple-tools.d.ts.map +1 -1
- package/dist/tools/simple-tools.js +25 -0
- package/dist/tools/simple-tools.js.map +1 -1
- package/dist/utils/cliDetector.d.ts +3 -2
- package/dist/utils/cliDetector.d.ts.map +1 -1
- package/dist/utils/cliDetector.js +6 -5
- package/dist/utils/cliDetector.js.map +1 -1
- package/dist/utils/commandExecutor.d.ts +1 -1
- package/dist/utils/commandExecutor.d.ts.map +1 -1
- package/dist/utils/commandExecutor.js +19 -1
- package/dist/utils/commandExecutor.js.map +1 -1
- package/dist/utils/opencodeCatalog.d.ts +33 -0
- package/dist/utils/opencodeCatalog.d.ts.map +1 -0
- package/dist/utils/opencodeCatalog.js +171 -0
- package/dist/utils/opencodeCatalog.js.map +1 -0
- package/dist/utils/opencodeExecutor.d.ts +2 -0
- package/dist/utils/opencodeExecutor.d.ts.map +1 -0
- package/dist/utils/opencodeExecutor.js +11 -0
- package/dist/utils/opencodeExecutor.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/@osanoai/multicli)
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
|
|
10
|
-
**An MCP server that lets Claude, Gemini, and
|
|
10
|
+
**An MCP server that lets Claude, Gemini, Codex, and OpenCode call each other as tools.**
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
Claude:
|
|
14
|
-
Gemini:
|
|
15
|
-
Codex:
|
|
13
|
+
Claude: "Hey Gemini, what do you think about this code?"
|
|
14
|
+
Gemini: "It's mass. Let me ask Codex for a second opinion."
|
|
15
|
+
Codex: "You're both wrong. Here's the fix."
|
|
16
|
+
OpenCode: "I checked with three providers. They all agree with Codex."
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
---
|
|
@@ -31,9 +32,10 @@ Detects which AI CLIs you have installed and configures Multi-CLI for all of the
|
|
|
31
32
|
|
|
32
33
|
Multi-CLI sits between your AI clients and bridges them via the [Model Context Protocol](https://modelcontextprotocol.io/). Install it once, and whichever AI you're talking to gains the ability to call the others.
|
|
33
34
|
|
|
34
|
-
- **Claude** can ask Gemini or
|
|
35
|
-
- **Gemini** can delegate to Claude or
|
|
36
|
-
- **Codex** can consult Claude or
|
|
35
|
+
- **Claude** can ask Gemini, Codex, or OpenCode for help
|
|
36
|
+
- **Gemini** can delegate to Claude, Codex, or OpenCode
|
|
37
|
+
- **Codex** can consult Claude, Gemini, or OpenCode
|
|
38
|
+
- **OpenCode** can call Claude, Gemini, or Codex (across 75+ providers)
|
|
37
39
|
- Each client's own tools are hidden (no talking to yourself, that's weird)
|
|
38
40
|
- Auto-detects which CLIs you have installed — only shows what's available
|
|
39
41
|
|
|
@@ -43,7 +45,7 @@ Multi-CLI sits between your AI clients and bridges them via the [Model Context P
|
|
|
43
45
|
|
|
44
46
|
This tool was built by the very AIs it connects.
|
|
45
47
|
|
|
46
|
-
Claude, Gemini, and
|
|
48
|
+
Claude, Gemini, Codex, and OpenCode wrote the code. Claude, Gemini, Codex, and OpenCode maintain it. Every night, a CI job queries the latest stable release of each CLI for its current model list, diffs the results against what's in the repo, and automatically publishes a new version if anything changed. New model releases get picked up within 24 hours. Deprecated models get cleaned out. The repo stays current without anyone touching it.
|
|
47
49
|
|
|
48
50
|
Because all install commands use `@latest`, your MCP client pulls the newest version every time it starts — no manual updates, no stale model lists, no maintenance.
|
|
49
51
|
|
|
@@ -60,6 +62,7 @@ You need **Node.js >= 20** and at least **two** of these CLIs installed:
|
|
|
60
62
|
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) | `npm install -g @anthropic-ai/claude-code` |
|
|
61
63
|
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `npm install -g @google/gemini-cli` |
|
|
62
64
|
| [Codex CLI](https://github.com/openai/codex) | `npm install -g @openai/codex` |
|
|
65
|
+
| [OpenCode](https://opencode.ai) | `curl -fsSL https://opencode.ai/install | bash` |
|
|
63
66
|
|
|
64
67
|
> Why two? Because one AI talking to itself is a monologue, not a collaboration.
|
|
65
68
|
|
|
@@ -148,6 +151,25 @@ Where `mcp.json` contains:
|
|
|
148
151
|
|
|
149
152
|
---
|
|
150
153
|
|
|
154
|
+
### OpenCode
|
|
155
|
+
|
|
156
|
+
OpenCode's `mcp add` command is interactive, so add Multi-CLI to `~/.config/opencode/opencode.json` directly:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"mcp": {
|
|
161
|
+
"Multi-CLI": {
|
|
162
|
+
"type": "local",
|
|
163
|
+
"command": ["npx", "-y", "@osanoai/multicli@latest"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If the file already exists, merge the `"Multi-CLI"` entry into the existing `"mcp"` object.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
151
173
|
### Any Other MCP Client
|
|
152
174
|
|
|
153
175
|
Multi-CLI uses standard stdio transport. If your client supports MCP, point it at:
|
|
@@ -174,6 +196,9 @@ Once connected, your AI client gains access to tools for the *other* CLIs (never
|
|
|
174
196
|
| `List-Claude-Models` | List available Claude models |
|
|
175
197
|
| `Ask-Claude` | Ask-Claude a question or give it a task |
|
|
176
198
|
| `Claude-Help` | Get Claude Code CLI help info |
|
|
199
|
+
| `List-OpenCode-Models` | List available OpenCode models from all configured providers |
|
|
200
|
+
| `Ask-OpenCode` | Ask-OpenCode a question or give it a task |
|
|
201
|
+
| `OpenCode-Help` | Get OpenCode CLI help info |
|
|
177
202
|
|
|
178
203
|
---
|
|
179
204
|
|
|
@@ -185,7 +210,7 @@ Once installed, just talk naturally to your AI:
|
|
|
185
210
|
"Ask-Gemini what it thinks about this architecture"
|
|
186
211
|
"Have Codex review this function for performance issues"
|
|
187
212
|
"Get Claude's opinion on this error message"
|
|
188
|
-
"Use
|
|
213
|
+
"Use OpenCode to get a second opinion from Llama"
|
|
189
214
|
```
|
|
190
215
|
|
|
191
216
|
Or get a second opinion on anything:
|
|
@@ -219,7 +244,7 @@ Or get a second opinion on anything:
|
|
|
219
244
|
**"No usable AI CLIs detected"**
|
|
220
245
|
Make sure at least one other CLI is installed and on your PATH:
|
|
221
246
|
```bash
|
|
222
|
-
which gemini && which codex && which claude
|
|
247
|
+
which gemini && which codex && which claude && which opencode
|
|
223
248
|
```
|
|
224
249
|
|
|
225
250
|
**No tools showing up?**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientFilter.d.ts","sourceRoot":"","sources":["../src/clientFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"clientFilter.d.ts","sourceRoot":"","sources":["../src/clientFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAclD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,SAAS,CAGvG;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAKxG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAI7G"}
|
package/dist/clientFilter.js
CHANGED
package/dist/clientFilter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientFilter.js","sourceRoot":"","sources":["../src/clientFilter.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,iBAAiB,GAA4C;IACjE,aAAa,EAAa,QAAQ;IAClC,kBAAkB,EAAQ,OAAO;IACjC,uBAAuB,EAAG,QAAQ;
|
|
1
|
+
{"version":3,"file":"clientFilter.js","sourceRoot":"","sources":["../src/clientFilter.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,iBAAiB,GAA4C;IACjE,aAAa,EAAa,QAAQ;IAClC,kBAAkB,EAAQ,OAAO;IACjC,uBAAuB,EAAG,QAAQ;IAClC,UAAU,EAAgB,UAAU;CACrC,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,UAA8B;IAChE,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAoB,EAAE,UAA8B;IACvF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAA6B,EAAE,UAA8B;IAClG,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACjD,OAAO,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAC9D,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const STATUS_MESSAGES: {
|
|
|
9
9
|
readonly GEMINI_RESPONSE: "Gemini response:";
|
|
10
10
|
readonly CODEX_RESPONSE: "Codex response:";
|
|
11
11
|
readonly CLAUDE_RESPONSE: "Claude response:";
|
|
12
|
+
readonly OPENCODE_RESPONSE: "OpenCode response:";
|
|
12
13
|
readonly PROCESSING_START: "🔍 Starting analysis (may take 5-15 minutes for large codebases)";
|
|
13
14
|
readonly PROCESSING_CONTINUE: "⏳ Still processing...";
|
|
14
15
|
readonly PROCESSING_COMPLETE: "✅ Analysis completed successfully";
|
|
@@ -37,6 +38,7 @@ export declare const CLI: {
|
|
|
37
38
|
readonly GEMINI: "gemini";
|
|
38
39
|
readonly CODEX: "codex";
|
|
39
40
|
readonly CLAUDE: "claude";
|
|
41
|
+
readonly OPENCODE: "opencode";
|
|
40
42
|
readonly ECHO: "echo";
|
|
41
43
|
};
|
|
42
44
|
readonly FLAGS: {
|
|
@@ -66,6 +68,16 @@ export declare const CLI: {
|
|
|
66
68
|
readonly TOOLS: "--tools";
|
|
67
69
|
readonly HELP: "--help";
|
|
68
70
|
};
|
|
71
|
+
readonly OPENCODE_FLAGS: {
|
|
72
|
+
readonly MODEL: "-m";
|
|
73
|
+
readonly CONTINUE: "-c";
|
|
74
|
+
readonly SESSION: "-s";
|
|
75
|
+
readonly HELP: "--help";
|
|
76
|
+
};
|
|
77
|
+
readonly OPENCODE_SUBCOMMANDS: {
|
|
78
|
+
readonly RUN: "run";
|
|
79
|
+
readonly MODELS: "models";
|
|
80
|
+
};
|
|
69
81
|
readonly DEFAULTS: {
|
|
70
82
|
readonly BOOLEAN_TRUE: "true";
|
|
71
83
|
readonly BOOLEAN_FALSE: "false";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAGX,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAGX,eAAO,MAAM,eAAe;;;;;;;;;CAUlB,CAAC;AAGX,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;CAuBX,CAAC;AAIX,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDN,CAAC;AAIX,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;CACtD"}
|
package/dist/constants.js
CHANGED
|
@@ -11,6 +11,7 @@ export const STATUS_MESSAGES = {
|
|
|
11
11
|
GEMINI_RESPONSE: "Gemini response:",
|
|
12
12
|
CODEX_RESPONSE: "Codex response:",
|
|
13
13
|
CLAUDE_RESPONSE: "Claude response:",
|
|
14
|
+
OPENCODE_RESPONSE: "OpenCode response:",
|
|
14
15
|
// Timeout prevention messages
|
|
15
16
|
PROCESSING_START: "🔍 Starting analysis (may take 5-15 minutes for large codebases)",
|
|
16
17
|
PROCESSING_CONTINUE: "⏳ Still processing...",
|
|
@@ -48,6 +49,7 @@ export const CLI = {
|
|
|
48
49
|
GEMINI: "gemini",
|
|
49
50
|
CODEX: "codex",
|
|
50
51
|
CLAUDE: "claude",
|
|
52
|
+
OPENCODE: "opencode",
|
|
51
53
|
ECHO: "echo",
|
|
52
54
|
},
|
|
53
55
|
// Gemini command flags
|
|
@@ -81,6 +83,18 @@ export const CLI = {
|
|
|
81
83
|
TOOLS: "--tools",
|
|
82
84
|
HELP: "--help",
|
|
83
85
|
},
|
|
86
|
+
// OpenCode flags
|
|
87
|
+
OPENCODE_FLAGS: {
|
|
88
|
+
MODEL: "-m",
|
|
89
|
+
CONTINUE: "-c",
|
|
90
|
+
SESSION: "-s",
|
|
91
|
+
HELP: "--help",
|
|
92
|
+
},
|
|
93
|
+
// OpenCode subcommands
|
|
94
|
+
OPENCODE_SUBCOMMANDS: {
|
|
95
|
+
RUN: "run",
|
|
96
|
+
MODELS: "models",
|
|
97
|
+
},
|
|
84
98
|
// Default values
|
|
85
99
|
DEFAULTS: {
|
|
86
100
|
BOOLEAN_TRUE: "true",
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,cAAc,EAAE,0CAA0C;IAC1D,oBAAoB,EAAE,yDAAyD;IAC/E,cAAc,EAAE,uBAAuB;IACvC,kBAAkB,EAAE,6IAA6I;CACzJ,CAAC;AAEX,kBAAkB;AAClB,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,iBAAiB,EAAE,6CAA6C;IAChE,eAAe,EAAE,kBAAkB;IACnC,cAAc,EAAE,iBAAiB;IACjC,eAAe,EAAE,kBAAkB;IACnC,8BAA8B;IAC9B,gBAAgB,EAAE,kEAAkE;IACpF,mBAAmB,EAAE,uBAAuB;IAC5C,mBAAmB,EAAE,mCAAmC;CAChD,CAAC;AAEX,yBAAyB;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,gBAAgB;IAChB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,WAAW;KACvB;IACD,gBAAgB;IAChB,aAAa,EAAE;QACb,IAAI,EAAE,MAAM;KACb;IACD,eAAe;IACf,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;KACjB;IACD,uBAAuB;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,wBAAwB;KACnC;IACD,qBAAqB;IACrB,kBAAkB,EAAE,KAAK,EAAE,aAAa;CAChC,CAAC;AAGX,gBAAgB;AAChB,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,gBAAgB;IAChB,QAAQ,EAAE;QACR,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,MAAM;KACb;IACD,uBAAuB;IACvB,KAAK,EAAE;QACL,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,OAAO;KACd;IACD,oBAAoB;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM;KACb;IACD,uBAAuB;IACvB,WAAW,EAAE;QACX,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,aAAa;QACxB,cAAc,EAAE,uBAAuB;KACxC;IACD,oBAAoB;IACpB,YAAY,EAAE;QACZ,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,SAAS;QAChB,aAAa,EAAE,iBAAiB;QAChC,eAAe,EAAE,mBAAmB;QACpC,UAAU,EAAE,kBAAkB;QAC9B,aAAa,EAAE,iBAAiB;QAChC,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,QAAQ;KACf;IACD,iBAAiB;IACjB,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM;QACpB,aAAa,EAAE,OAAO;KACvB;CACO,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,cAAc,EAAE,0CAA0C;IAC1D,oBAAoB,EAAE,yDAAyD;IAC/E,cAAc,EAAE,uBAAuB;IACvC,kBAAkB,EAAE,6IAA6I;CACzJ,CAAC;AAEX,kBAAkB;AAClB,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,iBAAiB,EAAE,6CAA6C;IAChE,eAAe,EAAE,kBAAkB;IACnC,cAAc,EAAE,iBAAiB;IACjC,eAAe,EAAE,kBAAkB;IACnC,iBAAiB,EAAE,oBAAoB;IACvC,8BAA8B;IAC9B,gBAAgB,EAAE,kEAAkE;IACpF,mBAAmB,EAAE,uBAAuB;IAC5C,mBAAmB,EAAE,mCAAmC;CAChD,CAAC;AAEX,yBAAyB;AACzB,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,gBAAgB;IAChB,KAAK,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,WAAW;KACvB;IACD,gBAAgB;IAChB,aAAa,EAAE;QACb,IAAI,EAAE,MAAM;KACb;IACD,eAAe;IACf,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;KACjB;IACD,uBAAuB;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,wBAAwB;KACnC;IACD,qBAAqB;IACrB,kBAAkB,EAAE,KAAK,EAAE,aAAa;CAChC,CAAC;AAGX,gBAAgB;AAChB,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,gBAAgB;IAChB,QAAQ,EAAE;QACR,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,MAAM;KACb;IACD,uBAAuB;IACvB,KAAK,EAAE;QACL,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,OAAO;KACd;IACD,oBAAoB;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM;KACb;IACD,uBAAuB;IACvB,WAAW,EAAE;QACX,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,SAAS;QAChB,SAAS,EAAE,aAAa;QACxB,cAAc,EAAE,uBAAuB;KACxC;IACD,oBAAoB;IACpB,YAAY,EAAE;QACZ,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,SAAS;QAChB,aAAa,EAAE,iBAAiB;QAChC,eAAe,EAAE,mBAAmB;QACpC,UAAU,EAAE,kBAAkB;QAC9B,aAAa,EAAE,iBAAiB;QAChC,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,QAAQ;KACf;IACD,iBAAiB;IACjB,cAAc,EAAE;QACd,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;KACf;IACD,uBAAuB;IACvB,oBAAoB,EAAE;QACpB,GAAG,EAAE,KAAK;QACV,MAAM,EAAE,QAAQ;KACjB;IACD,iBAAiB;IACjB,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM;QACpB,aAAa,EAAE,OAAO;KACvB;CACO,CAAC"}
|
package/dist/modelCatalog.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StaticCLIName } from './tierConfig.js';
|
|
1
2
|
export interface ModelTier {
|
|
2
3
|
tier: 'fast' | 'balanced' | 'powerful';
|
|
3
4
|
label: string;
|
|
@@ -5,10 +6,10 @@ export interface ModelTier {
|
|
|
5
6
|
useWhen: string;
|
|
6
7
|
}
|
|
7
8
|
export interface CLICatalog {
|
|
8
|
-
cli:
|
|
9
|
+
cli: StaticCLIName;
|
|
9
10
|
tiers: ModelTier[];
|
|
10
11
|
note: string;
|
|
11
12
|
}
|
|
12
|
-
export declare function getCatalog(cli:
|
|
13
|
-
export declare function formatCatalog(cli:
|
|
13
|
+
export declare function getCatalog(cli: StaticCLIName): CLICatalog;
|
|
14
|
+
export declare function formatCatalog(cli: StaticCLIName): string;
|
|
14
15
|
//# sourceMappingURL=modelCatalog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modelCatalog.d.ts","sourceRoot":"","sources":["../src/modelCatalog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"modelCatalog.d.ts","sourceRoot":"","sources":["../src/modelCatalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,iBAAiB,CAAC;AAE/D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAuFD,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAEzD;AAQD,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAgBxD"}
|
package/dist/modelCatalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modelCatalog.js","sourceRoot":"","sources":["../src/modelCatalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAiCzD,IAAI,aAA4B,CAAC;AACjC,IAAI,CAAC;IACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,+BAA+B,CAAY,CAAC;IAChE,IACE,CAAC,GAAG;QACJ,OAAO,GAAG,KAAK,QAAQ;QACvB,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC;QACpB,OAAQ,GAA+B,CAAC,QAAQ,KAAK,QAAQ,EAC7D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IACD,aAAa,GAAG,GAAoB,CAAC;AACvC,CAAC;AAAC,MAAM,CAAC;IACP,MAAM,IAAI,KAAK,CACb,8CAA8C;QAC5C,wDAAwD;QACxD,gEAAgE,CACnE,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,+EAA+E;AAE/E,SAAS,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"modelCatalog.js","sourceRoot":"","sources":["../src/modelCatalog.ts"],"names":[],"mappings":"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"}
|
package/dist/tierConfig.d.ts
CHANGED
|
@@ -8,7 +8,9 @@ export interface TierDisplayConfig {
|
|
|
8
8
|
useWhen: string;
|
|
9
9
|
}
|
|
10
10
|
export type TierName = 'fast' | 'balanced' | 'powerful';
|
|
11
|
-
export type CLIName = 'claude' | 'gemini' | 'codex';
|
|
11
|
+
export type CLIName = 'claude' | 'gemini' | 'codex' | 'opencode';
|
|
12
|
+
/** CLIs that use the static generated model catalog (not dynamic discovery). */
|
|
13
|
+
export type StaticCLIName = 'claude' | 'gemini' | 'codex';
|
|
12
14
|
export declare const TIER_CONFIG: Record<CLIName, Record<TierName, TierDisplayConfig>>;
|
|
13
15
|
export declare const CLI_NOTES: Record<CLIName, string>;
|
|
14
16
|
//# sourceMappingURL=tierConfig.d.ts.map
|
package/dist/tierConfig.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tierConfig.d.ts","sourceRoot":"","sources":["../src/tierConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AACxD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tierConfig.d.ts","sourceRoot":"","sources":["../src/tierConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AACxD,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AACjE,gFAAgF;AAChF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAiE5E,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAM7C,CAAC"}
|
package/dist/tierConfig.js
CHANGED
|
@@ -46,10 +46,25 @@ export const TIER_CONFIG = {
|
|
|
46
46
|
useWhen: 'Complex architecture, large refactors, deep reasoning, nuanced analysis, multi-step planning.',
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
|
+
opencode: {
|
|
50
|
+
fast: {
|
|
51
|
+
label: 'Fast',
|
|
52
|
+
useWhen: 'Only for: trivial lookups, simple math, quick one-line answers.',
|
|
53
|
+
},
|
|
54
|
+
balanced: {
|
|
55
|
+
label: 'Balanced (DEFAULT)',
|
|
56
|
+
useWhen: 'Most tasks: coding, analysis, multi-step work, debugging, code review. USE THIS BY DEFAULT.',
|
|
57
|
+
},
|
|
58
|
+
powerful: {
|
|
59
|
+
label: 'Powerful',
|
|
60
|
+
useWhen: 'Complex reasoning, nuanced analysis, architectural decisions, large refactors, or when you need the highest quality.',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
49
63
|
};
|
|
50
64
|
export const CLI_NOTES = {
|
|
51
65
|
claude: 'Run Claude-Help for the latest CLI options.',
|
|
52
66
|
gemini: 'Run Gemini-Help for the latest CLI options. Model IDs may change as Google releases new versions.',
|
|
53
67
|
codex: 'Run Codex-Help for the latest CLI options. Model IDs may change as OpenAI releases new versions.',
|
|
68
|
+
opencode: 'OpenCode models are dynamically discovered from your configured providers. Models are classified into tiers automatically. Run OpenCode-Help for CLI options.',
|
|
54
69
|
};
|
|
55
70
|
//# sourceMappingURL=tierConfig.js.map
|
package/dist/tierConfig.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tierConfig.js","sourceRoot":"","sources":["../src/tierConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"tierConfig.js","sourceRoot":"","sources":["../src/tierConfig.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,MAAM,CAAC,MAAM,WAAW,GAAyD;IAC/E,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,iEAAiE;SAC3E;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,kBAAkB;YACzB,OAAO,EACL,6FAA6F;SAChG;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,MAAM;YACb,OAAO,EACL,sHAAsH;SACzH;KACF;IACD,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,iEAAiE;SAC3E;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,yBAAyB;YAChC,OAAO,EACL,6FAA6F;SAChG;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,KAAK;YACZ,OAAO,EACL,4GAA4G;SAC/G;KACF;IACD,KAAK,EAAE;QACL,IAAI,EAAE;YACJ,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,iEAAiE;SAC3E;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,iBAAiB;YACxB,OAAO,EACL,gGAAgG;SACnG;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,iBAAiB;YACxB,OAAO,EACL,+FAA+F;SAClG;KACF;IACD,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,iEAAiE;SAC3E;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EACL,6FAA6F;SAChG;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,UAAU;YACjB,OAAO,EACL,sHAAsH;SACzH;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAA4B;IAChD,MAAM,EAAE,6CAA6C;IACrD,MAAM,EACJ,mGAAmG;IACrG,KAAK,EAAE,kGAAkG;IACzG,QAAQ,EAAE,+JAA+J;CAC1K,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-opencode.tool.d.ts","sourceRoot":"","sources":["../../src/tools/ask-opencode.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS5C,eAAO,MAAM,eAAe,EAAE,WAuB7B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { executeOpencodeCLI } from '../utils/opencodeExecutor.js';
|
|
3
|
+
import { ERROR_MESSAGES, STATUS_MESSAGES } from '../constants.js';
|
|
4
|
+
const askOpencodeArgsSchema = z.object({
|
|
5
|
+
prompt: z.string().min(1).describe("The question or task for OpenCode. REQUIRED — MUST be a non-empty string. OpenCode has full filesystem access and will read files itself. Do NOT pre-read or inline file contents — just describe the task."),
|
|
6
|
+
model: z.string().min(1).describe("REQUIRED — you MUST first call List-OpenCode-Models, review the available models and their tiers, then select the best model for your task. Use the full provider/model format (e.g., 'google-vertex/gemini-2.5-flash'). Empty strings will be rejected."),
|
|
7
|
+
});
|
|
8
|
+
export const askOpencodeTool = {
|
|
9
|
+
name: "Ask-OpenCode",
|
|
10
|
+
description: "Ask OpenCode a question or give it a task. OpenCode supports multiple AI providers and has full filesystem access. You MUST call List-OpenCode-Models first to select an appropriate model. Use the full provider/model format for the model parameter.",
|
|
11
|
+
zodSchema: askOpencodeArgsSchema,
|
|
12
|
+
prompt: {
|
|
13
|
+
description: "Execute 'opencode run <prompt> -m <model>' to get OpenCode's response.",
|
|
14
|
+
},
|
|
15
|
+
category: 'opencode',
|
|
16
|
+
execute: async (args, onProgress) => {
|
|
17
|
+
const { prompt, model } = args;
|
|
18
|
+
if (!prompt?.trim()) {
|
|
19
|
+
throw new Error(ERROR_MESSAGES.NO_PROMPT_PROVIDED);
|
|
20
|
+
}
|
|
21
|
+
const result = await executeOpencodeCLI(prompt, model, onProgress);
|
|
22
|
+
return `${STATUS_MESSAGES.OPENCODE_RESPONSE}\n${result}`;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=ask-opencode.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-opencode.tool.js","sourceRoot":"","sources":["../../src/tools/ask-opencode.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElE,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6MAA6M,CAAC;IACjP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0PAA0P,CAAC;CAC9R,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAgB;IAC1C,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,yPAAyP;IACtQ,SAAS,EAAE,qBAAqB;IAChC,MAAM,EAAE;QACN,WAAW,EAAE,wEAAwE;KACtF;IACD,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;QAClC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAE/B,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,MAAgB,EAChB,KAAe,EACf,UAAU,CACX,CAAC;QAEF,OAAO,GAAG,eAAe,CAAC,iBAAiB,KAAK,MAAM,EAAE,CAAC;IAC3D,CAAC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAuB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/E;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC,CAqC1D;AAED,cAAc,eAAe,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Tool Registry Index - Registers tools based on CLI availability
|
|
2
2
|
import { toolRegistry } from './registry.js';
|
|
3
3
|
import { askGeminiTool } from './ask-gemini.tool.js';
|
|
4
|
-
import { geminiHelpTool, codexHelpTool, claudeHelpTool, geminiListModelsTool, codexListModelsTool, claudeListModelsTool, } from './simple-tools.js';
|
|
4
|
+
import { geminiHelpTool, codexHelpTool, claudeHelpTool, opencodeHelpTool, geminiListModelsTool, codexListModelsTool, claudeListModelsTool, opencodeListModelsTool, } from './simple-tools.js';
|
|
5
5
|
import { fetchChunkTool } from './fetch-chunk.tool.js';
|
|
6
6
|
import { askCodexTool } from './ask-codex.tool.js';
|
|
7
7
|
import { askClaudeTool } from './ask-claude.tool.js';
|
|
8
|
+
import { askOpencodeTool } from './ask-opencode.tool.js';
|
|
8
9
|
import { detectAvailableClis } from '../utils/cliDetector.js';
|
|
9
10
|
/**
|
|
10
11
|
* Initialize the tool registry based on which CLIs are available.
|
|
@@ -28,6 +29,11 @@ export async function initTools() {
|
|
|
28
29
|
askClaudeTool, // Ask-Claude
|
|
29
30
|
claudeHelpTool);
|
|
30
31
|
}
|
|
32
|
+
if (availability.opencode) {
|
|
33
|
+
toolRegistry.push(opencodeListModelsTool, // List-OpenCode-Models
|
|
34
|
+
askOpencodeTool, // Ask-OpenCode
|
|
35
|
+
opencodeHelpTool);
|
|
36
|
+
}
|
|
31
37
|
return availability;
|
|
32
38
|
}
|
|
33
39
|
export * from './registry.js';
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,cAAc,EAAE,aAAa,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAC/D,oBAAoB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,GACxF,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAmB,MAAM,yBAAyB,CAAC;AAE/E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,YAAY,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAEjD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,YAAY,CAAC,IAAI,CACf,oBAAoB,EAAI,qBAAqB;QAC7C,aAAa,EAAW,aAAa;QACrC,cAAc,EAAU,cAAc;QACtC,cAAc,CACf,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QACvB,YAAY,CAAC,IAAI,CACf,mBAAmB,EAAK,oBAAoB;QAC5C,YAAY,EAAY,YAAY;QACpC,aAAa,CACd,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,YAAY,CAAC,IAAI,CACf,oBAAoB,EAAI,qBAAqB;QAC7C,aAAa,EAAW,aAAa;QACrC,cAAc,CACf,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC1B,YAAY,CAAC,IAAI,CACf,sBAAsB,EAAE,uBAAuB;QAC/C,eAAe,EAAS,eAAe;QACvC,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,cAAc,eAAe,CAAC"}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface UnifiedTool {
|
|
|
14
14
|
}>;
|
|
15
15
|
};
|
|
16
16
|
execute: (args: ToolArguments, onProgress?: (newOutput: string) => void) => Promise<string>;
|
|
17
|
-
category?: 'gemini' | 'codex' | 'claude' | 'utility';
|
|
17
|
+
category?: 'gemini' | 'codex' | 'claude' | 'opencode' | 'utility';
|
|
18
18
|
}
|
|
19
19
|
export declare const toolRegistry: UnifiedTool[];
|
|
20
20
|
export declare function toolExists(toolName: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAY,MAAM,KAAK,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC;IAErB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,KAAK,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC,CAAC;KACJ,CAAC;IAEF,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,CAAC,EAAY,MAAM,KAAK,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC;IAErB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,KAAK,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC,CAAC;KACJ,CAAC;IAEF,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;CACnE;AAED,eAAO,MAAM,YAAY,EAAE,WAAW,EAAO,CAAC;AAC9C,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AACD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAejE;AAcD,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAQrE;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBlI;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAsBpF"}
|
|
@@ -5,4 +5,6 @@ export declare const claudeHelpTool: UnifiedTool;
|
|
|
5
5
|
export declare const geminiListModelsTool: UnifiedTool;
|
|
6
6
|
export declare const codexListModelsTool: UnifiedTool;
|
|
7
7
|
export declare const claudeListModelsTool: UnifiedTool;
|
|
8
|
+
export declare const opencodeHelpTool: UnifiedTool;
|
|
9
|
+
export declare const opencodeListModelsTool: UnifiedTool;
|
|
8
10
|
//# sourceMappingURL=simple-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-tools.d.ts","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"simple-tools.d.ts","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,eAAO,MAAM,cAAc,EAAE,WAW5B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAW3B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAW5B,CAAC;AAIF,eAAO,MAAM,oBAAoB,EAAE,WAWlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,WAWjC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAWlC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,WAW9B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAWpC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { executeCommand } from '../utils/commandExecutor.js';
|
|
3
3
|
import { formatCatalog } from '../modelCatalog.js';
|
|
4
|
+
import { getOpencodeClassifiedCatalog } from '../utils/opencodeCatalog.js';
|
|
4
5
|
const helpArgsSchema = z.object({});
|
|
5
6
|
export const geminiHelpTool = {
|
|
6
7
|
name: "Gemini-Help",
|
|
@@ -75,4 +76,28 @@ export const claudeListModelsTool = {
|
|
|
75
76
|
return formatCatalog('claude');
|
|
76
77
|
}
|
|
77
78
|
};
|
|
79
|
+
export const opencodeHelpTool = {
|
|
80
|
+
name: "OpenCode-Help",
|
|
81
|
+
description: "Receive help information from the OpenCode CLI",
|
|
82
|
+
zodSchema: helpArgsSchema,
|
|
83
|
+
prompt: {
|
|
84
|
+
description: "Receive help information from the OpenCode CLI",
|
|
85
|
+
},
|
|
86
|
+
category: 'opencode',
|
|
87
|
+
execute: async (args, onProgress) => {
|
|
88
|
+
return executeCommand("opencode", ["--help"], onProgress);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export const opencodeListModelsTool = {
|
|
92
|
+
name: "List-OpenCode-Models",
|
|
93
|
+
description: "List available OpenCode models from all configured providers, classified into tiers. You MUST call this before Ask-OpenCode to choose the right model for your task. Models are dynamically discovered from your providers.",
|
|
94
|
+
zodSchema: noArgsSchema,
|
|
95
|
+
prompt: {
|
|
96
|
+
description: "List available OpenCode models with tier classifications",
|
|
97
|
+
},
|
|
98
|
+
category: 'opencode',
|
|
99
|
+
execute: async () => {
|
|
100
|
+
return getOpencodeClassifiedCatalog();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
78
103
|
//# sourceMappingURL=simple-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-tools.js","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"simple-tools.js","sourceRoot":"","sources":["../../src/tools/simple-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,10 +8,11 @@ export interface CliAvailability {
|
|
|
8
8
|
gemini: boolean;
|
|
9
9
|
codex: boolean;
|
|
10
10
|
claude: boolean;
|
|
11
|
+
opencode: boolean;
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
|
-
* Detect which of the
|
|
14
|
-
* Runs all
|
|
14
|
+
* Detect which of the four supported CLIs are available on the system.
|
|
15
|
+
* Runs all four checks in parallel for speed.
|
|
15
16
|
*/
|
|
16
17
|
export declare function detectAvailableClis(): Promise<CliAvailability>;
|
|
17
18
|
//# sourceMappingURL=cliDetector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliDetector.d.ts","sourceRoot":"","sources":["../../src/utils/cliDetector.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBrE;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cliDetector.d.ts","sourceRoot":"","sources":["../../src/utils/cliDetector.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBrE;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,CAAC,CAepE"}
|
|
@@ -27,19 +27,20 @@ export async function commandExists(command) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
* Detect which of the
|
|
31
|
-
* Runs all
|
|
30
|
+
* Detect which of the four supported CLIs are available on the system.
|
|
31
|
+
* Runs all four checks in parallel for speed.
|
|
32
32
|
*/
|
|
33
33
|
export async function detectAvailableClis() {
|
|
34
34
|
if (process.env.QA_NO_CLIS === 'true') {
|
|
35
|
-
return { gemini: false, codex: false, claude: false };
|
|
35
|
+
return { gemini: false, codex: false, claude: false, opencode: false };
|
|
36
36
|
}
|
|
37
|
-
const [gemini, codex, claude] = await Promise.all([
|
|
37
|
+
const [gemini, codex, claude, opencode] = await Promise.all([
|
|
38
38
|
commandExists(CLI.COMMANDS.GEMINI),
|
|
39
39
|
commandExists(CLI.COMMANDS.CODEX),
|
|
40
40
|
commandExists(CLI.COMMANDS.CLAUDE),
|
|
41
|
+
commandExists(CLI.COMMANDS.OPENCODE),
|
|
41
42
|
]);
|
|
42
|
-
const availability = { gemini, codex, claude };
|
|
43
|
+
const availability = { gemini, codex, claude, opencode };
|
|
43
44
|
return availability;
|
|
44
45
|
}
|
|
45
46
|
//# sourceMappingURL=cliDetector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cliDetector.js","sourceRoot":"","sources":["../../src/utils/cliDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;gBACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;gBACrC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrB,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;
|
|
1
|
+
{"version":3,"file":"cliDetector.js","sourceRoot":"","sources":["../../src/utils/cliDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;gBACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;gBACrC,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACrB,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1D,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;KACrC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAE1E,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* - `^` prefix for cmd.exe operators: & | < > ^
|
|
7
7
|
*/
|
|
8
8
|
export declare function sanitizeArgForCmd(arg: string): string;
|
|
9
|
-
export declare function executeCommand(command: string, args: string[], onProgress?: (newOutput: string) => void): Promise<string>;
|
|
9
|
+
export declare function executeCommand(command: string, args: string[], onProgress?: (newOutput: string) => void, timeoutMs?: number): Promise<string>;
|
|
10
10
|
//# sourceMappingURL=commandExecutor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandExecutor.d.ts","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"commandExecutor.d.ts","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EACxC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAuEjB"}
|
|
@@ -15,7 +15,7 @@ export function sanitizeArgForCmd(arg) {
|
|
|
15
15
|
.replace(/[&|<>^]/g, c => `^${c}`) // caret-escape shell operators
|
|
16
16
|
;
|
|
17
17
|
}
|
|
18
|
-
export async function executeCommand(command, args, onProgress) {
|
|
18
|
+
export async function executeCommand(command, args, onProgress, timeoutMs) {
|
|
19
19
|
return new Promise((resolve, reject) => {
|
|
20
20
|
// Use shell: true on Windows to properly execute .cmd files and resolve PATH.
|
|
21
21
|
// Sanitize args to prevent cmd.exe metacharacter injection.
|
|
@@ -29,7 +29,19 @@ export async function executeCommand(command, args, onProgress) {
|
|
|
29
29
|
let stderr = "";
|
|
30
30
|
let isResolved = false;
|
|
31
31
|
let lastReportedLength = 0;
|
|
32
|
+
let timer;
|
|
33
|
+
if (timeoutMs && timeoutMs > 0) {
|
|
34
|
+
timer = setTimeout(() => {
|
|
35
|
+
if (!isResolved) {
|
|
36
|
+
isResolved = true;
|
|
37
|
+
childProcess.kill('SIGTERM');
|
|
38
|
+
reject(new Error(`Command timed out after ${timeoutMs}ms`));
|
|
39
|
+
}
|
|
40
|
+
}, timeoutMs);
|
|
41
|
+
}
|
|
32
42
|
childProcess.stdout.on("data", (data) => {
|
|
43
|
+
if (isResolved)
|
|
44
|
+
return;
|
|
33
45
|
stdout += data.toString();
|
|
34
46
|
// Report new content if callback provided
|
|
35
47
|
if (onProgress && stdout.length > lastReportedLength) {
|
|
@@ -40,6 +52,8 @@ export async function executeCommand(command, args, onProgress) {
|
|
|
40
52
|
});
|
|
41
53
|
// CLI level errors
|
|
42
54
|
childProcess.stderr.on("data", (data) => {
|
|
55
|
+
if (isResolved)
|
|
56
|
+
return;
|
|
43
57
|
stderr += data.toString();
|
|
44
58
|
// find RESOURCE_EXHAUSTED when gemini quota is exceeded
|
|
45
59
|
if (stderr.includes("RESOURCE_EXHAUSTED")) {
|
|
@@ -49,12 +63,16 @@ export async function executeCommand(command, args, onProgress) {
|
|
|
49
63
|
childProcess.on("error", (error) => {
|
|
50
64
|
if (!isResolved) {
|
|
51
65
|
isResolved = true;
|
|
66
|
+
if (timer)
|
|
67
|
+
clearTimeout(timer);
|
|
52
68
|
reject(new Error(`Failed to spawn command: ${error.message}`));
|
|
53
69
|
}
|
|
54
70
|
});
|
|
55
71
|
childProcess.on("close", (code) => {
|
|
56
72
|
if (!isResolved) {
|
|
57
73
|
isResolved = true;
|
|
74
|
+
if (timer)
|
|
75
|
+
clearTimeout(timer);
|
|
58
76
|
if (code === 0) {
|
|
59
77
|
resolve(stdout.trim());
|
|
60
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandExecutor.js","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,kDAAkD;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAe,gCAAgC;SAClE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAe,0BAA0B;SAC5D,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,+BAA+B;KACnE;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe,EACf,IAAc,EACd,UAAwC;
|
|
1
|
+
{"version":3,"file":"commandExecutor.js","sourceRoot":"","sources":["../../src/utils/commandExecutor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TierName } from '../tierConfig.js';
|
|
2
|
+
export interface OpencodeClassification {
|
|
3
|
+
fast: string[];
|
|
4
|
+
balanced: string[];
|
|
5
|
+
powerful: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface OpencodeCacheFile {
|
|
8
|
+
hash: string;
|
|
9
|
+
classifications: OpencodeClassification;
|
|
10
|
+
}
|
|
11
|
+
export declare function getCacheDir(): string;
|
|
12
|
+
export declare function getCachePath(): string;
|
|
13
|
+
export declare function listOpencodeModels(): Promise<string[]>;
|
|
14
|
+
export declare function hashModelList(models: string[]): string;
|
|
15
|
+
export declare function readCache(): Promise<OpencodeCacheFile | null>;
|
|
16
|
+
export declare function writeCache(cache: OpencodeCacheFile): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Classify a single model into a tier using name-based heuristics.
|
|
19
|
+
* Returns 'fast', 'powerful', or 'balanced' (default).
|
|
20
|
+
*/
|
|
21
|
+
export declare function classifyModelByName(model: string): TierName;
|
|
22
|
+
/**
|
|
23
|
+
* Classify all models using heuristics. Instant and requires no API calls.
|
|
24
|
+
*/
|
|
25
|
+
export declare function classifyModelsViaHeuristics(models: string[]): OpencodeClassification;
|
|
26
|
+
/**
|
|
27
|
+
* Get the classified OpenCode model catalog.
|
|
28
|
+
* Runs `opencode models` to discover available models, then classifies via heuristics.
|
|
29
|
+
* Caches results so repeated calls with the same model set are instant.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getOpencodeClassifiedCatalog(): Promise<string>;
|
|
32
|
+
export declare function formatOpencodeCatalog(classifications: OpencodeClassification): string;
|
|
33
|
+
//# sourceMappingURL=opencodeCatalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencodeCatalog.d.ts","sourceRoot":"","sources":["../../src/utils/opencodeCatalog.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,sBAAsB,CAAC;CACzC;AAID,wBAAgB,WAAW,IAAI,MAAM,CAcpC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAOD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAW5D;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAGtD;AAID,wBAAsB,SAAS,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAWnE;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxE;AAmCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAQ3D;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAapF;AAID;;;;GAIG;AACH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC,CAsBpE;AAUD,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,sBAAsB,GAAG,MAAM,CAmBrF"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir, platform } from 'node:os';
|
|
5
|
+
import { executeCommand } from './commandExecutor.js';
|
|
6
|
+
import { CLI } from '../constants.js';
|
|
7
|
+
import { TIER_CONFIG, CLI_NOTES } from '../tierConfig.js';
|
|
8
|
+
// ── Cache location ───────────────────────────────────────────────────────────
|
|
9
|
+
export function getCacheDir() {
|
|
10
|
+
if (process.env.MULTICLI_CACHE_DIR) {
|
|
11
|
+
return process.env.MULTICLI_CACHE_DIR;
|
|
12
|
+
}
|
|
13
|
+
const os = platform();
|
|
14
|
+
if (os === 'darwin') {
|
|
15
|
+
return join(homedir(), 'Library', 'Caches', 'osanoai');
|
|
16
|
+
}
|
|
17
|
+
if (os === 'win32') {
|
|
18
|
+
return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'osanoai');
|
|
19
|
+
}
|
|
20
|
+
// Linux / other: XDG_CACHE_HOME or ~/.cache
|
|
21
|
+
return join(process.env.XDG_CACHE_HOME || join(homedir(), '.cache'), 'osanoai');
|
|
22
|
+
}
|
|
23
|
+
export function getCachePath() {
|
|
24
|
+
return join(getCacheDir(), 'multicli-opencode.json');
|
|
25
|
+
}
|
|
26
|
+
// ── Model discovery ──────────────────────────────────────────────────────────
|
|
27
|
+
/** Patterns that indicate a model is not suitable for text generation */
|
|
28
|
+
const EMBEDDING_PATTERNS = /embedding|embed[-_]|rerank/i;
|
|
29
|
+
export async function listOpencodeModels() {
|
|
30
|
+
const raw = await executeCommand(CLI.COMMANDS.OPENCODE, [CLI.OPENCODE_SUBCOMMANDS.MODELS]);
|
|
31
|
+
return raw
|
|
32
|
+
.split('\n')
|
|
33
|
+
.map(line => line.trim())
|
|
34
|
+
.filter(line => line.length > 0 && line.includes('/'))
|
|
35
|
+
.filter(line => !EMBEDDING_PATTERNS.test(line));
|
|
36
|
+
}
|
|
37
|
+
// ── Hashing ──────────────────────────────────────────────────────────────────
|
|
38
|
+
export function hashModelList(models) {
|
|
39
|
+
const sorted = [...models].sort();
|
|
40
|
+
return createHash('sha256').update(sorted.join('\n')).digest('hex');
|
|
41
|
+
}
|
|
42
|
+
// ── Cache read/write ─────────────────────────────────────────────────────────
|
|
43
|
+
export async function readCache() {
|
|
44
|
+
try {
|
|
45
|
+
const raw = await readFile(getCachePath(), 'utf-8');
|
|
46
|
+
const parsed = JSON.parse(raw);
|
|
47
|
+
if (parsed.hash && parsed.classifications) {
|
|
48
|
+
return parsed;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function writeCache(cache) {
|
|
57
|
+
const dir = getCacheDir();
|
|
58
|
+
await mkdir(dir, { recursive: true });
|
|
59
|
+
await writeFile(getCachePath(), JSON.stringify(cache, null, 2), 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
// ── Heuristic-based classification ──────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Name patterns → tier mapping. Checked in order; first match wins.
|
|
64
|
+
* Patterns are tested against the full model identifier (provider/name).
|
|
65
|
+
*/
|
|
66
|
+
const FAST_PATTERNS = [
|
|
67
|
+
/\bflash-lite\b/i,
|
|
68
|
+
/\bnano\b/i,
|
|
69
|
+
/\bmini\b/i,
|
|
70
|
+
/\bsmall\b/i,
|
|
71
|
+
/\b8b\b/i,
|
|
72
|
+
/\b3b\b/i,
|
|
73
|
+
/\bhaiku\b/i,
|
|
74
|
+
/\blite\b/i,
|
|
75
|
+
/\bMiMo\b/,
|
|
76
|
+
];
|
|
77
|
+
const POWERFUL_PATTERNS = [
|
|
78
|
+
/\bopus\b/i,
|
|
79
|
+
/\b405b\b/i,
|
|
80
|
+
/\bgpt-5\.4\b/i,
|
|
81
|
+
/\bo3\b/i,
|
|
82
|
+
/\bo1\b/i,
|
|
83
|
+
/\bDeepSeek-R1\b/,
|
|
84
|
+
/\bpro\b/i,
|
|
85
|
+
/\b235b\b/i,
|
|
86
|
+
/\b120b\b/i,
|
|
87
|
+
/\b480b\b/i,
|
|
88
|
+
/\b397b\b/i,
|
|
89
|
+
/\bCoder-Next\b/,
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Classify a single model into a tier using name-based heuristics.
|
|
93
|
+
* Returns 'fast', 'powerful', or 'balanced' (default).
|
|
94
|
+
*/
|
|
95
|
+
export function classifyModelByName(model) {
|
|
96
|
+
for (const pattern of FAST_PATTERNS) {
|
|
97
|
+
if (pattern.test(model))
|
|
98
|
+
return 'fast';
|
|
99
|
+
}
|
|
100
|
+
for (const pattern of POWERFUL_PATTERNS) {
|
|
101
|
+
if (pattern.test(model))
|
|
102
|
+
return 'powerful';
|
|
103
|
+
}
|
|
104
|
+
return 'balanced';
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Classify all models using heuristics. Instant and requires no API calls.
|
|
108
|
+
*/
|
|
109
|
+
export function classifyModelsViaHeuristics(models) {
|
|
110
|
+
const fast = [];
|
|
111
|
+
const balanced = [];
|
|
112
|
+
const powerful = [];
|
|
113
|
+
for (const model of models) {
|
|
114
|
+
const tier = classifyModelByName(model);
|
|
115
|
+
if (tier === 'fast')
|
|
116
|
+
fast.push(model);
|
|
117
|
+
else if (tier === 'powerful')
|
|
118
|
+
powerful.push(model);
|
|
119
|
+
else
|
|
120
|
+
balanced.push(model);
|
|
121
|
+
}
|
|
122
|
+
return { fast, balanced, powerful };
|
|
123
|
+
}
|
|
124
|
+
// ── Orchestrator ─────────────────────────────────────────────────────────────
|
|
125
|
+
/**
|
|
126
|
+
* Get the classified OpenCode model catalog.
|
|
127
|
+
* Runs `opencode models` to discover available models, then classifies via heuristics.
|
|
128
|
+
* Caches results so repeated calls with the same model set are instant.
|
|
129
|
+
*/
|
|
130
|
+
export async function getOpencodeClassifiedCatalog() {
|
|
131
|
+
const models = await listOpencodeModels();
|
|
132
|
+
if (models.length === 0) {
|
|
133
|
+
return 'No models available. Ensure providers are configured via `opencode auth login`.';
|
|
134
|
+
}
|
|
135
|
+
const hash = hashModelList(models);
|
|
136
|
+
const cache = await readCache();
|
|
137
|
+
let classifications;
|
|
138
|
+
if (cache && cache.hash === hash) {
|
|
139
|
+
classifications = cache.classifications;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
classifications = classifyModelsViaHeuristics(models);
|
|
143
|
+
// Write cache (fire-and-forget, don't block response)
|
|
144
|
+
writeCache({ hash, classifications }).catch(() => { });
|
|
145
|
+
}
|
|
146
|
+
return formatOpencodeCatalog(classifications);
|
|
147
|
+
}
|
|
148
|
+
// ── Formatting ───────────────────────────────────────────────────────────────
|
|
149
|
+
const SELECTION_RULE = `MODEL SELECTION RULE: Default to the "balanced" tier for most tasks. ` +
|
|
150
|
+
`Use "powerful" for complex reasoning, architecture, nuanced analysis, or when quality matters most. ` +
|
|
151
|
+
`Reserve "fast" only for trivial lookups, simple math, or quick one-line answers. ` +
|
|
152
|
+
`Models are in provider/model format — use the full string (e.g., "google-vertex/gemini-2.5-flash") when calling Ask-OpenCode.\n`;
|
|
153
|
+
export function formatOpencodeCatalog(classifications) {
|
|
154
|
+
const lines = [
|
|
155
|
+
`OPENCODE — Available Models\n`,
|
|
156
|
+
SELECTION_RULE,
|
|
157
|
+
];
|
|
158
|
+
for (const tierName of ['fast', 'balanced', 'powerful']) {
|
|
159
|
+
const models = classifications[tierName];
|
|
160
|
+
if (!models || models.length === 0)
|
|
161
|
+
continue;
|
|
162
|
+
const config = TIER_CONFIG.opencode[tierName];
|
|
163
|
+
lines.push(`[${tierName.toUpperCase()}] ${config.label}`);
|
|
164
|
+
lines.push(` Use when: ${config.useWhen}`);
|
|
165
|
+
lines.push(` Model IDs: ${models.join(', ')}`);
|
|
166
|
+
lines.push('');
|
|
167
|
+
}
|
|
168
|
+
lines.push(`> ${CLI_NOTES.opencode}`);
|
|
169
|
+
return lines.join('\n');
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=opencodeCatalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencodeCatalog.js","sourceRoot":"","sources":["../../src/utils/opencodeCatalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencodeExecutor.d.ts","sourceRoot":"","sources":["../../src/utils/opencodeExecutor.ts"],"names":[],"mappings":"AAGA,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACvC,OAAO,CAAC,MAAM,CAAC,CAQjB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { executeCommand } from './commandExecutor.js';
|
|
2
|
+
import { CLI } from '../constants.js';
|
|
3
|
+
export async function executeOpencodeCLI(prompt, model, onProgress) {
|
|
4
|
+
const args = [
|
|
5
|
+
CLI.OPENCODE_SUBCOMMANDS.RUN,
|
|
6
|
+
prompt,
|
|
7
|
+
CLI.OPENCODE_FLAGS.MODEL, model,
|
|
8
|
+
];
|
|
9
|
+
return executeCommand(CLI.COMMANDS.OPENCODE, args, onProgress);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=opencodeExecutor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencodeExecutor.js","sourceRoot":"","sources":["../../src/utils/opencodeExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,KAAa,EACb,UAAwC;IAExC,MAAM,IAAI,GAAa;QACrB,GAAG,CAAC,oBAAoB,CAAC,GAAG;QAC5B,MAAM;QACN,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK;KAChC,CAAC;IAEF,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AACjE,CAAC"}
|