@yu_robotics/remote-cli 1.6.25 → 1.6.30
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 +9 -8
- package/dist/client/MessageHandler.d.ts +4 -1
- package/dist/client/MessageHandler.d.ts.map +1 -1
- package/dist/client/MessageHandler.js +70 -22
- package/dist/client/MessageHandler.js.map +1 -1
- package/dist/client/WebSocketClient.js +1 -1
- package/dist/client/WebSocketClient.js.map +1 -1
- package/dist/commands/start.d.ts +1 -4
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +29 -19
- package/dist/commands/start.js.map +1 -1
- package/dist/executor/KimiExecutor.d.ts +18 -0
- package/dist/executor/KimiExecutor.d.ts.map +1 -0
- package/dist/executor/KimiExecutor.js +28 -0
- package/dist/executor/KimiExecutor.js.map +1 -0
- package/dist/executor/OpenCodeExecutor.d.ts +80 -0
- package/dist/executor/OpenCodeExecutor.d.ts.map +1 -0
- package/dist/executor/OpenCodeExecutor.js +513 -0
- package/dist/executor/OpenCodeExecutor.js.map +1 -0
- package/dist/executor/acp/AcpClient.d.ts +47 -40
- package/dist/executor/acp/AcpClient.d.ts.map +1 -1
- package/dist/executor/acp/AcpClient.js +113 -189
- package/dist/executor/acp/AcpClient.js.map +1 -1
- package/dist/executor/acp/AcpTypes.d.ts +27 -68
- package/dist/executor/acp/AcpTypes.d.ts.map +1 -1
- package/dist/executor/acp/AcpTypes.js +0 -9
- package/dist/executor/acp/AcpTypes.js.map +1 -1
- package/dist/executor/index.d.ts +4 -6
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +32 -27
- package/dist/executor/index.js.map +1 -1
- package/dist/thread/ThreadExecutorPool.js +1 -1
- package/dist/thread/ThreadExecutorPool.js.map +1 -1
- package/dist/thread/types.d.ts +1 -1
- package/dist/thread/types.d.ts.map +1 -1
- package/dist/types/config.d.ts +19 -13
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +6 -2
- package/dist/types/config.js.map +1 -1
- package/dist/update/AutomaticUpdater.d.ts +26 -0
- package/dist/update/AutomaticUpdater.d.ts.map +1 -0
- package/dist/update/AutomaticUpdater.js +109 -0
- package/dist/update/AutomaticUpdater.js.map +1 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +20 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @yu_robotics/remote-cli
|
|
2
2
|
|
|
3
|
-
Remote control
|
|
3
|
+
Remote control Claude Code, AGY CLI, Codex CLI, OpenCode CLI, or Kimi Code CLI from anywhere using your mobile phone through Feishu (Lark) messaging.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -8,16 +8,17 @@ Remote control your [Claude Code](https://claude.ai/code) CLI from anywhere usin
|
|
|
8
8
|
- **Secure**: Directory whitelisting, command filtering, and device authentication
|
|
9
9
|
- **Mobile-Optimized**: Simplified commands and rich text formatting for Feishu
|
|
10
10
|
- **Readable Code Changes**: Edit operations show collapsible, line-aware diff previews inside the existing progress card
|
|
11
|
-
- **Multi-Backend Support**: Supports Claude Code and
|
|
12
|
-
- **Image Input and Output**: Forward standalone images and mixed text-image Feishu posts to Claude Persistent
|
|
11
|
+
- **Multi-Backend Support**: Supports Claude Code, AGY CLI (Antigravity), Codex CLI (OpenAI), OpenCode CLI, and Kimi Code CLI
|
|
12
|
+
- **Image Input and Output**: Forward standalone images and mixed text-image Feishu posts to Claude Persistent, Codex App Server, OpenCode ACP, and Kimi Code ACP backends, and forward Codex App Server generated images back through Router
|
|
13
13
|
- **Multi-session (Threads)**: Create independent chat threads to parallelize tasks
|
|
14
14
|
- **Remote Machine Management**: Control remote servers or Docker via SSH
|
|
15
15
|
- **Persistent Process**: Long-running AI process with bidirectional streaming
|
|
16
|
+
- **Non-Interactive Auto-Update**: Reconnect to a newer Router, wait for idle work, install its exact version, and exit for the process supervisor to restart
|
|
16
17
|
|
|
17
18
|
## Prerequisites
|
|
18
19
|
|
|
19
20
|
- **Node.js** >= 18.0.0
|
|
20
|
-
- **Claude Code CLI** installed and configured
|
|
21
|
+
- **Claude Code CLI**, **AGY CLI**, **Codex CLI**, **OpenCode CLI**, or **Kimi Code CLI** installed and configured
|
|
21
22
|
- Access to a Feishu (Lark) bot connected to a [remote-cli-router](https://www.npmjs.com/package/@yu_robotics/remote-cli-router) server
|
|
22
23
|
|
|
23
24
|
The client is normally installed and run directly on the developer's machine rather than in Docker, so it can access local project directories and the installed AI CLI binaries. Docker is recommended for the shared Router server instead.
|
|
@@ -96,7 +97,7 @@ Linux users upgrading from version 1.6.23 or earlier should run `remote-cli serv
|
|
|
96
97
|
| `/compact` | Compress history to save tokens |
|
|
97
98
|
| `/cd <dir>` | Change working directory for this thread |
|
|
98
99
|
| `/model [name]` | List models for the active backend or set this thread's model |
|
|
99
|
-
| `/effort [auto|
|
|
100
|
+
| `/effort [auto|level]` | Show or set Codex/AGY/OpenCode/Kimi reasoning effort |
|
|
100
101
|
| `/backend` | List backends and show the current thread's effective backend |
|
|
101
102
|
| `/backend <index>` | Switch all threads and clear per-thread backend overrides |
|
|
102
103
|
| `/backend <index> @` | Switch only the current thread |
|
|
@@ -118,7 +119,7 @@ Linux users upgrading from version 1.6.23 or earlier should run `remote-cli serv
|
|
|
118
119
|
|
|
119
120
|
### AI CLI Commands Passthrough
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
Backend-specific commands are forwarded only where the active backend supports them. The built-in `/status`, `/context`, and `/skills` commands provide a consistent remote view across backends.
|
|
122
123
|
- `/commit` - Commit code changes
|
|
123
124
|
- `/review` - Code review
|
|
124
125
|
- `/test` - Run tests
|
|
@@ -128,11 +129,11 @@ All commands/skills supported by local Claude Code or Gemini CLI are passed thro
|
|
|
128
129
|
|
|
129
130
|
Use one thread per project or task so each thread keeps its own working directory, backend session, model, and queue. Use `/backend <index>` for a global switch, or `/backend <index> @` to override only the current thread. `/backend default @` removes that override.
|
|
130
131
|
|
|
131
|
-
When a thread is busy, ordinary messages require confirmation before they enter its queue. Use `/queue` to inspect pending work, `/queue clear` to discard queued messages, and `/abort` to stop the active task and clear that thread's queue. A message received during abort cleanup waits and starts after the backend is safe to reuse. Context-changing commands such as `/model`, `/effort`, `/cd`, `/compact`, and `/clear` are handled separately rather than queued as ordinary messages.
|
|
132
|
+
When a thread is busy, ordinary messages require confirmation before they enter its queue. Use `/queue` to inspect pending work, `/queue clear` to discard queued messages, and `/abort` to stop the active task and clear that thread's queue. A message received during abort cleanup waits and starts after the backend is safe to reuse. A backend failure in the active task still advances to the first confirmed queued message; a failure in a task taken from the queue pauses the remaining queue. Context-changing commands such as `/model`, `/effort`, `/cd`, `/compact`, and `/clear` are handled separately rather than queued as ordinary messages.
|
|
132
133
|
|
|
133
134
|
## Expert Usage
|
|
134
135
|
|
|
135
|
-
For a shared deployment, run the Router with Docker Compose on an internal server and run one CLI client on each developer machine. Keep project directories and Claude Code, AGY, or
|
|
136
|
+
For a shared deployment, run the Router with Docker Compose on an internal server and run one CLI client on each developer machine. Keep project directories and Claude Code, AGY, Codex, OpenCode, or Kimi Code credentials on the client machine; the Router persists its configuration and bindings in `./router-data`. On Linux, create that directory as the deployment user and set `ROUTER_UID` and `ROUTER_GID` in `.env` to `id -u` and `id -g` so the container can write to the bind mount.
|
|
136
137
|
|
|
137
138
|
To update a Router deployment without losing bindings:
|
|
138
139
|
|
|
@@ -35,11 +35,14 @@ export declare class MessageHandler {
|
|
|
35
35
|
private readonly messageOpenIds;
|
|
36
36
|
private readonly activeThreadOperations;
|
|
37
37
|
private readonly abortOperations;
|
|
38
|
+
private automaticUpdateInProgress;
|
|
38
39
|
constructor(wsClient: WebSocketClient, threadPool: ThreadExecutorPool, threadManager: ThreadManager, directoryGuard: DirectoryGuard, config: ConfigManager);
|
|
39
40
|
/**
|
|
40
41
|
* Handle message (supports new IncomingMessage format)
|
|
41
42
|
*/
|
|
42
43
|
handleMessage(message: Message | IncomingMessage): Promise<void>;
|
|
44
|
+
tryBeginAutomaticUpdate(): boolean;
|
|
45
|
+
endAutomaticUpdate(): void;
|
|
43
46
|
/**
|
|
44
47
|
* Handle command message — route to the correct thread executor.
|
|
45
48
|
*/
|
|
@@ -73,6 +76,7 @@ export declare class MessageHandler {
|
|
|
73
76
|
* - claude: `claude --print /model` prints current + available aliases
|
|
74
77
|
* - agy: `agy models` prints "slug<TAB>Display Name" lines
|
|
75
78
|
* - codex app-server: `model/list` returns the authenticated catalog
|
|
79
|
+
* - opencode ACP: session config options expose enabled models
|
|
76
80
|
* - codex exec fallback: listing is unavailable
|
|
77
81
|
*/
|
|
78
82
|
private handleModelList;
|
|
@@ -117,7 +121,6 @@ export declare class MessageHandler {
|
|
|
117
121
|
private listLocalSkills;
|
|
118
122
|
/**
|
|
119
123
|
* Which backend slash commands should be forwarded to for a thread.
|
|
120
|
-
* 'auto'/claude-* always resolve to Claude; legacy 'gemini' means AGY.
|
|
121
124
|
*/
|
|
122
125
|
private resolveSlashBackend;
|
|
123
126
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/client/MessageHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAkH,MAAM,UAAU,CAAC;AAC3J,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAKxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AA4CxD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA+C;IACzF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyC;IACxE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAA4C;IACnF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;
|
|
1
|
+
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/client/MessageHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ class MessageHandler {
|
|
|
34
34
|
messageOpenIds = new Map();
|
|
35
35
|
activeThreadOperations = new Map();
|
|
36
36
|
abortOperations = new Map();
|
|
37
|
+
automaticUpdateInProgress = false;
|
|
37
38
|
constructor(wsClient, threadPool, threadManager, directoryGuard, config) {
|
|
38
39
|
this.wsClient = wsClient;
|
|
39
40
|
this.threadPool = threadPool;
|
|
@@ -77,6 +78,25 @@ class MessageHandler {
|
|
|
77
78
|
});
|
|
78
79
|
}
|
|
79
80
|
}
|
|
81
|
+
tryBeginAutomaticUpdate() {
|
|
82
|
+
this.removeExpiredQueueConfirmations();
|
|
83
|
+
const hasQueuedCommands = Array.from(this.threadQueues.values()).some((queue) => queue.length > 0);
|
|
84
|
+
const hasRunningThread = this.threadPool.getSummaries().some((thread) => thread.status === 'running');
|
|
85
|
+
if (this.automaticUpdateInProgress
|
|
86
|
+
|| hasRunningThread
|
|
87
|
+
|| hasQueuedCommands
|
|
88
|
+
|| this.pendingQueueConfirmations.size > 0
|
|
89
|
+
|| this.pendingReplaces.size > 0
|
|
90
|
+
|| this.activeThreadOperations.size > 0
|
|
91
|
+
|| this.abortOperations.size > 0) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
this.automaticUpdateInProgress = true;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
endAutomaticUpdate() {
|
|
98
|
+
this.automaticUpdateInProgress = false;
|
|
99
|
+
}
|
|
80
100
|
/**
|
|
81
101
|
* Handle command message — route to the correct thread executor.
|
|
82
102
|
*/
|
|
@@ -97,6 +117,13 @@ class MessageHandler {
|
|
|
97
117
|
return;
|
|
98
118
|
}
|
|
99
119
|
const resolvedThreadId = thread.id;
|
|
120
|
+
if (this.automaticUpdateInProgress) {
|
|
121
|
+
this.sendResponse(messageId, resolvedThreadId, {
|
|
122
|
+
success: false,
|
|
123
|
+
error: 'The client is installing an automatic update. Please retry after it reconnects.',
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
100
127
|
const executor = this.threadPool.getExecutor(resolvedThreadId);
|
|
101
128
|
// Handle /abort for this specific thread (bypasses busy check)
|
|
102
129
|
if (content?.trim() === '/abort') {
|
|
@@ -228,10 +255,7 @@ class MessageHandler {
|
|
|
228
255
|
}
|
|
229
256
|
const expandedContent = this.expandCommandShortcuts(content);
|
|
230
257
|
const processedContent = (0, FileReadDetector_1.processFileReadContent)(expandedContent);
|
|
231
|
-
|
|
232
|
-
if (!success && this.threadQueues.has(resolvedThreadId)) {
|
|
233
|
-
this.pausedQueues.add(resolvedThreadId);
|
|
234
|
-
}
|
|
258
|
+
await this.executeCommand(messageId, resolvedThreadId, processedContent, executor, attachments);
|
|
235
259
|
}
|
|
236
260
|
catch (error) {
|
|
237
261
|
this.threadPool.setThreadError(resolvedThreadId, true);
|
|
@@ -389,7 +413,7 @@ Use /compact to reduce conversation context or /clear to start a fresh context.`
|
|
|
389
413
|
}
|
|
390
414
|
if (trimmed === '/skills') {
|
|
391
415
|
const backend = this.threadPool.getBackendKey(threadId);
|
|
392
|
-
if (backend === 'claude' || backend === 'agy') {
|
|
416
|
+
if (backend === 'claude' || backend === 'agy' || backend === 'opencode' || backend === 'kimi') {
|
|
393
417
|
await this.executeSlashCommand(messageId, threadId, trimmed, executor);
|
|
394
418
|
}
|
|
395
419
|
else {
|
|
@@ -417,7 +441,7 @@ Use /compact to reduce conversation context or /clear to start a fresh context.`
|
|
|
417
441
|
- /compact - Compress conversation history to reduce context size
|
|
418
442
|
- /cd <directory> - Change working directory for this thread
|
|
419
443
|
- /model [name] - Show models for the active backend, or set this thread's model
|
|
420
|
-
- /effort [auto|
|
|
444
|
+
- /effort [auto|level] - Show or set effort for Codex/AGY/OpenCode/Kimi (Claude Code is unsupported)
|
|
421
445
|
- /backend - List backends and show the current thread's effective backend
|
|
422
446
|
- /backend <index> - Switch all threads and clear per-thread backend overrides
|
|
423
447
|
- /backend <index> @ - Switch only the current thread
|
|
@@ -506,7 +530,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
506
530
|
if (trimmed === '/effort' || trimmed.startsWith('/effort ')) {
|
|
507
531
|
const executorConfig = this.config.get('executor') ?? { type: 'auto' };
|
|
508
532
|
const key = this.threadPool.getBackendKey(threadId);
|
|
509
|
-
if (key !== 'codex' && key !== 'agy') {
|
|
533
|
+
if (key !== 'codex' && key !== 'agy' && key !== 'opencode' && key !== 'kimi') {
|
|
510
534
|
this.sendResponse(messageId, threadId, {
|
|
511
535
|
success: false,
|
|
512
536
|
error: '/effort is not supported yet for Claude Code.',
|
|
@@ -522,13 +546,17 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
522
546
|
output: [
|
|
523
547
|
`Current reasoning effort: ${thread?.efforts?.agy ?? 'auto'}`,
|
|
524
548
|
'Supported levels: low, medium, high',
|
|
525
|
-
'Set with: /effort <auto|
|
|
549
|
+
'Set with: /effort <auto|level>',
|
|
526
550
|
].join('\n'),
|
|
527
551
|
});
|
|
528
552
|
return true;
|
|
529
553
|
}
|
|
530
|
-
const configuredModel =
|
|
531
|
-
|
|
554
|
+
const configuredModel = key === 'codex'
|
|
555
|
+
? thread?.models?.codex ?? executorConfig.codex?.model
|
|
556
|
+
: key === 'opencode'
|
|
557
|
+
? thread?.models?.opencode ?? executorConfig.opencode?.model
|
|
558
|
+
: thread?.models?.kimi ?? executorConfig.kimi?.model;
|
|
559
|
+
const lines = [`Current reasoning effort: ${thread?.efforts?.[key] ?? 'auto'}`];
|
|
532
560
|
if ('listModels' in executor && typeof executor.listModels === 'function') {
|
|
533
561
|
try {
|
|
534
562
|
const models = await executor.listModels();
|
|
@@ -542,7 +570,8 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
542
570
|
}
|
|
543
571
|
}
|
|
544
572
|
catch (error) {
|
|
545
|
-
|
|
573
|
+
const label = key === 'opencode' ? 'OpenCode' : key === 'kimi' ? 'Kimi Code' : 'Codex';
|
|
574
|
+
lines.push(`Could not fetch ${label} effort metadata: ${error instanceof Error ? error.message : String(error)}`);
|
|
546
575
|
}
|
|
547
576
|
}
|
|
548
577
|
lines.push('Set with: /effort <auto|level>');
|
|
@@ -552,7 +581,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
552
581
|
if (!('setEffort' in executor && typeof executor.setEffort === 'function')) {
|
|
553
582
|
this.sendResponse(messageId, threadId, {
|
|
554
583
|
success: false,
|
|
555
|
-
error: `/effort is not supported by this ${key === 'agy' ? 'AGY' : 'Codex'} executor version.`,
|
|
584
|
+
error: `/effort is not supported by this ${key === 'agy' ? 'AGY' : key === 'opencode' ? 'OpenCode' : key === 'kimi' ? 'Kimi Code' : 'Codex'} executor version.`,
|
|
556
585
|
});
|
|
557
586
|
return true;
|
|
558
587
|
}
|
|
@@ -801,6 +830,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
801
830
|
* - claude: `claude --print /model` prints current + available aliases
|
|
802
831
|
* - agy: `agy models` prints "slug<TAB>Display Name" lines
|
|
803
832
|
* - codex app-server: `model/list` returns the authenticated catalog
|
|
833
|
+
* - opencode ACP: session config options expose enabled models
|
|
804
834
|
* - codex exec fallback: listing is unavailable
|
|
805
835
|
*/
|
|
806
836
|
async handleModelList(messageId, threadId) {
|
|
@@ -808,12 +838,16 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
808
838
|
const key = this.threadPool.getBackendKey(threadId);
|
|
809
839
|
const thread = this.threadManager.getThread(threadId);
|
|
810
840
|
const current = thread?.models?.[key] ?? (key === 'claude' ? thread?.model : undefined);
|
|
811
|
-
const backendLabel = key === 'claude' ? 'Claude Code'
|
|
841
|
+
const backendLabel = key === 'claude' ? 'Claude Code'
|
|
842
|
+
: key === 'agy' ? 'AGY CLI'
|
|
843
|
+
: key === 'opencode' ? 'OpenCode CLI'
|
|
844
|
+
: key === 'kimi' ? 'Kimi Code CLI'
|
|
845
|
+
: 'Codex CLI';
|
|
812
846
|
const lines = [
|
|
813
847
|
`🎯 Backend: ${backendLabel}`,
|
|
814
848
|
`Current model: ${current ?? 'backend default'}`,
|
|
815
849
|
];
|
|
816
|
-
if (key === 'codex') {
|
|
850
|
+
if (key === 'codex' || key === 'opencode' || key === 'kimi') {
|
|
817
851
|
const executor = this.threadPool.getExecutor(threadId);
|
|
818
852
|
if ('listModels' in executor && typeof executor.listModels === 'function') {
|
|
819
853
|
try {
|
|
@@ -826,15 +860,15 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
826
860
|
}
|
|
827
861
|
}
|
|
828
862
|
else {
|
|
829
|
-
lines.push('',
|
|
863
|
+
lines.push('', `⚠️ ${backendLabel} returned an empty model list.`);
|
|
830
864
|
}
|
|
831
865
|
}
|
|
832
866
|
catch (error) {
|
|
833
|
-
lines.push('', `⚠️ Could not fetch the model list from
|
|
867
|
+
lines.push('', `⚠️ Could not fetch the model list from ${backendLabel}: ${error instanceof Error ? error.message : String(error)}`);
|
|
834
868
|
}
|
|
835
869
|
}
|
|
836
870
|
else {
|
|
837
|
-
lines.push('',
|
|
871
|
+
lines.push('', `Model listing is unavailable in this ${backendLabel} transport.`);
|
|
838
872
|
}
|
|
839
873
|
}
|
|
840
874
|
else {
|
|
@@ -1256,7 +1290,6 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1256
1290
|
}
|
|
1257
1291
|
/**
|
|
1258
1292
|
* Which backend slash commands should be forwarded to for a thread.
|
|
1259
|
-
* 'auto'/claude-* always resolve to Claude; legacy 'gemini' means AGY.
|
|
1260
1293
|
*/
|
|
1261
1294
|
resolveSlashBackend(threadId) {
|
|
1262
1295
|
return this.threadPool.getBackendKey(threadId);
|
|
@@ -1274,6 +1307,19 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1274
1307
|
*/
|
|
1275
1308
|
async executeSlashCommand(messageId, threadId, command, executor) {
|
|
1276
1309
|
const backend = this.resolveSlashBackend(threadId);
|
|
1310
|
+
if (backend === 'opencode' || backend === 'kimi') {
|
|
1311
|
+
const result = await executor.execute(command, {
|
|
1312
|
+
onStream: (chunk) => this.sendStreamChunk(messageId, threadId, chunk),
|
|
1313
|
+
onToolUse: (toolUse) => this.sendToolUse(messageId, threadId, toolUse),
|
|
1314
|
+
onToolResult: (toolResult) => this.sendToolResult(messageId, threadId, toolResult),
|
|
1315
|
+
onPlanMode: (plan) => this.sendPlanMode(messageId, threadId, plan),
|
|
1316
|
+
onImage: (image) => this.sendImage(messageId, threadId, image),
|
|
1317
|
+
});
|
|
1318
|
+
this.sendResponse(messageId, threadId, result.success
|
|
1319
|
+
? { success: true, output: result.output || '✅ Command executed successfully' }
|
|
1320
|
+
: { success: false, error: result.error || `${backend === 'kimi' ? 'Kimi Code' : 'OpenCode'} command failed` });
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1277
1323
|
if (backend === 'codex') {
|
|
1278
1324
|
this.sendResponse(messageId, threadId, {
|
|
1279
1325
|
success: false,
|
|
@@ -1586,14 +1632,18 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1586
1632
|
});
|
|
1587
1633
|
}
|
|
1588
1634
|
async detectBackends() {
|
|
1589
|
-
const [claudeInstalled, codexInstalled, agyInstalled] = await Promise.all([
|
|
1635
|
+
const [claudeInstalled, codexInstalled, openCodeInstalled, kimiInstalled, agyInstalled] = await Promise.all([
|
|
1590
1636
|
this.checkCommand('claude', ['--version']),
|
|
1591
1637
|
this.checkCommand('codex', ['--version']),
|
|
1638
|
+
this.checkCommand('opencode', ['--version']),
|
|
1639
|
+
this.checkCommand('kimi', ['--version']),
|
|
1592
1640
|
this.checkCommand('agy', ['--version']),
|
|
1593
1641
|
]);
|
|
1594
1642
|
return [
|
|
1595
1643
|
{ id: 'auto', label: 'Claude Code', installed: claudeInstalled },
|
|
1596
1644
|
{ id: 'codex', label: 'Codex CLI (OpenAI)', installed: codexInstalled },
|
|
1645
|
+
{ id: 'opencode', label: 'OpenCode CLI', installed: openCodeInstalled },
|
|
1646
|
+
{ id: 'kimi', label: 'Kimi Code CLI', installed: kimiInstalled },
|
|
1597
1647
|
{ id: 'agy', label: 'AGY CLI (Antigravity)', installed: agyInstalled },
|
|
1598
1648
|
];
|
|
1599
1649
|
}
|
|
@@ -1616,9 +1666,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1616
1666
|
const lines = installed.map((b, i) => {
|
|
1617
1667
|
const isClaudeActive = b.id === 'auto' &&
|
|
1618
1668
|
(currentType === 'auto' || currentType === 'claude-persistent' || currentType === 'claude-spawn');
|
|
1619
|
-
|
|
1620
|
-
const isAgyActive = b.id === 'agy' &&
|
|
1621
|
-
(currentType === 'agy' || currentType === 'gemini');
|
|
1669
|
+
const isAgyActive = b.id === 'agy' && currentType === 'agy';
|
|
1622
1670
|
const active = b.id === currentType || isClaudeActive || isAgyActive ? ' ★ (active)' : '';
|
|
1623
1671
|
return `${i + 1}. ${b.label}${active}`;
|
|
1624
1672
|
});
|