@yu_robotics/remote-cli 1.6.173 → 1.6.177
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 +24 -3
- package/dist/client/MessageHandler.d.ts +2 -0
- package/dist/client/MessageHandler.d.ts.map +1 -1
- package/dist/client/MessageHandler.js +73 -18
- package/dist/client/MessageHandler.js.map +1 -1
- package/dist/client/WebSocketClient.d.ts.map +1 -1
- package/dist/client/WebSocketClient.js +1 -0
- package/dist/client/WebSocketClient.js.map +1 -1
- package/dist/delegation/DelegatedWorkerSessionStore.d.ts +11 -1
- package/dist/delegation/DelegatedWorkerSessionStore.d.ts.map +1 -1
- package/dist/delegation/DelegatedWorkerSessionStore.js +98 -51
- package/dist/delegation/DelegatedWorkerSessionStore.js.map +1 -1
- package/dist/delegation/DelegationManager.d.ts +2 -0
- package/dist/delegation/DelegationManager.d.ts.map +1 -1
- package/dist/delegation/DelegationManager.js +12 -1
- package/dist/delegation/DelegationManager.js.map +1 -1
- package/dist/executor/AcpExecutor.d.ts +6 -0
- package/dist/executor/AcpExecutor.d.ts.map +1 -1
- package/dist/executor/AcpExecutor.js +81 -10
- package/dist/executor/AcpExecutor.js.map +1 -1
- package/dist/executor/CodexAppServerClient.d.ts +2 -1
- package/dist/executor/CodexAppServerClient.d.ts.map +1 -1
- package/dist/executor/CodexAppServerClient.js +15 -11
- package/dist/executor/CodexAppServerClient.js.map +1 -1
- package/dist/executor/CodexAppServerExecutor.d.ts +12 -1
- package/dist/executor/CodexAppServerExecutor.d.ts.map +1 -1
- package/dist/executor/CodexAppServerExecutor.js +197 -4
- package/dist/executor/CodexAppServerExecutor.js.map +1 -1
- package/dist/executor/IExecutor.d.ts +19 -0
- package/dist/executor/IExecutor.d.ts.map +1 -1
- package/dist/executor/KimiExecutor.d.ts +9 -0
- package/dist/executor/KimiExecutor.d.ts.map +1 -1
- package/dist/executor/KimiExecutor.js +45 -0
- package/dist/executor/KimiExecutor.js.map +1 -1
- package/dist/executor/PiExecutor.d.ts.map +1 -1
- package/dist/executor/PiExecutor.js +2 -1
- package/dist/executor/PiExecutor.js.map +1 -1
- package/dist/executor/index.d.ts +2 -1
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +1 -0
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/kimi/KimiAccountUsage.d.ts +2 -6
- package/dist/executor/kimi/KimiAccountUsage.d.ts.map +1 -1
- package/dist/executor/kimi/KimiAccountUsage.js +11 -71
- package/dist/executor/kimi/KimiAccountUsage.js.map +1 -1
- package/dist/executor/kimi/KimiLocalServer.d.ts +28 -0
- package/dist/executor/kimi/KimiLocalServer.d.ts.map +1 -0
- package/dist/executor/kimi/KimiLocalServer.js +192 -0
- package/dist/executor/kimi/KimiLocalServer.js.map +1 -0
- package/dist/executor/kimi/KimiModelCatalog.d.ts +6 -0
- package/dist/executor/kimi/KimiModelCatalog.d.ts.map +1 -0
- package/dist/executor/kimi/KimiModelCatalog.js +86 -0
- package/dist/executor/kimi/KimiModelCatalog.js.map +1 -0
- package/dist/maintenance/release-notes.json +1 -1
- package/dist/settings/SettingsCatalog.d.ts +1 -1
- package/dist/settings/SettingsCatalog.d.ts.map +1 -1
- package/dist/settings/SettingsCatalog.js +6 -2
- package/dist/settings/SettingsCatalog.js.map +1 -1
- package/dist/settings/SettingsService.d.ts +3 -1
- package/dist/settings/SettingsService.d.ts.map +1 -1
- package/dist/settings/SettingsService.js +17 -5
- package/dist/settings/SettingsService.js.map +1 -1
- package/dist/thread/ThreadContextReset.d.ts +12 -0
- package/dist/thread/ThreadContextReset.d.ts.map +1 -0
- package/dist/thread/ThreadContextReset.js +59 -0
- package/dist/thread/ThreadContextReset.js.map +1 -0
- package/dist/thread/ThreadExecutorPool.d.ts +11 -2
- package/dist/thread/ThreadExecutorPool.d.ts.map +1 -1
- package/dist/thread/ThreadExecutorPool.js +97 -2
- package/dist/thread/ThreadExecutorPool.js.map +1 -1
- package/dist/thread/ThreadManager.d.ts +3 -1
- package/dist/thread/ThreadManager.d.ts.map +1 -1
- package/dist/thread/ThreadManager.js +3 -0
- package/dist/thread/ThreadManager.js.map +1 -1
- package/dist/thread/types.d.ts +2 -0
- package/dist/thread/types.d.ts.map +1 -1
- package/dist/types/Settings.d.ts +8 -0
- package/dist/types/Settings.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Remote control Claude Code, AGY CLI, Codex CLI, OpenCode CLI, Kimi Code CLI, ZCode, or Pi from anywhere using your mobile phone through Feishu (Lark) messaging.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- **Remote Control**: Control your local development environment from anywhere via mobile
|
|
@@ -179,8 +181,8 @@ Linux users upgrading from version 1.6.23 or earlier should run `remote-cli serv
|
|
|
179
181
|
| `/skills` | List available skills for the active backend |
|
|
180
182
|
| `/abort` | Abort executing task in current thread |
|
|
181
183
|
| `/queue` | Inspect or manage confirmed messages waiting in thread queues |
|
|
182
|
-
| `/clear` |
|
|
183
|
-
| `/new` | Alias for `/clear`; start
|
|
184
|
+
| `/clear` | Reset all direct backend and managed worker conversations for this thread |
|
|
185
|
+
| `/new` | Alias for `/clear`; start fresh across this thread's backends and workers |
|
|
184
186
|
| `/compact` | Compress history to save tokens |
|
|
185
187
|
| `/cd [dir]` | Browse directories as a card, or change directory directly with a path |
|
|
186
188
|
| `/model [name]` | Open native model settings, or set the active backend model with a text argument |
|
|
@@ -429,6 +431,10 @@ Backend-specific commands are forwarded only where the active backend supports t
|
|
|
429
431
|
|
|
430
432
|
## Advanced Usage
|
|
431
433
|
|
|
434
|
+
From CLI 1.6.175, opening or refreshing Kimi's `/model` list also refreshes the native OAuth-managed model catalog through Kimi's authenticated loopback server. Manual terminal refresh and repeated sign-in are not required. Kimi must expose the native model-refresh endpoint; account permissions and upstream availability still determine the returned choices. Failed or timed-out refreshes are reported rather than treated as a successful refresh of an old list. Upgrade the local CLI to use this behavior; the Router protocol is unchanged. Applying a discovered model to an idle Kimi thread reloads the native ACP process and resumes the same conversation binding, so its process-local catalog cannot reject the new alias.
|
|
435
|
+
|
|
436
|
+
From CLI and Router 1.6.176, the `/model` card includes a separate **Speed** section when the selected Codex model advertises native service tiers. Choose a native tier, explicit **Standard**, or **Follow native config**. Native names and descriptions are preserved; Fast is a processing tier, not an invented model ID, and availability and usage depend on the native backend and account. Speed is saved per thread/backend and applies to future delegated workers and native goal continuations. Model changes that conflict with a saved speed are refused until Follow native config is selected. Untouched threads keep native behavior without extra speed settings requests. Both peers must negotiate model speed settings; older peers, Kimi Highspeed model IDs, and OpenCode models/variants keep their existing paths. If a saved speed disappears, a recovery-only Speed section retains Follow native config. Older native protocols that cannot safely clear a saved conversation's tier require a Codex upgrade or `/clear` before that conversation resumes.
|
|
437
|
+
|
|
432
438
|
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.
|
|
433
439
|
|
|
434
440
|
With CLI and Router 1.6.168 or newer, `/cd` opens a directory-only browser with child, Parent, Allowed roots, Refresh, Use this directory, and Cancel controls. Navigation never changes context or runs a backend. Only Apply changes the original thread, following the existing all-backend context reset and delegation-lane invalidation; the same directory remains a no-op. Both card Apply and text `/cd <path>` share exclusive settings admission and reject active, delegated, queued, aborting, or updating work. Older peers retain text behavior. Symbolic-link directories are omitted; Parent stops at the nearest allowed root. Snapshots expire after ten minutes and reject changed policy, cwd, root, directory, or ancestor identity. Scans cap at 4096 entries, 128 directories, or five seconds between filesystem operations, with explicit partial-list guidance; at most 32 roots are offered. Cards fill before budget-driven paging. Application-level canonical and identity checks are not an OS sandbox or protection against all external filesystem races and bind mounts.
|
|
@@ -437,7 +443,7 @@ With CLI 1.6.93 or newer, `/cd` to a different normalized directory clears saved
|
|
|
437
443
|
|
|
438
444
|
Thread switch panels show `Reply from:` with the reply's full thread name and workspace. Under `Switch thread`, a check mark (`✓`) and primary button styling identify the destination of new top-level messages when the card is finalized or clicked. Selected buttons remain clickable. Switching updates only the clicked card; other historical cards retain their last displayed selection.
|
|
439
445
|
|
|
440
|
-
From Router 1.6.
|
|
446
|
+
From Router 1.6.174, completed cards show thread-switch buttons and **+ New** directly, without a folding panel or an extra expand click. The reply-source caption remains visible, and thread selection keeps the existing routing and permission checks. Cards use a 180-tagged-node budget, including nested controls and reserved completion elements; size and table limits still apply. This presentation change requires a Router upgrade and does not change the CLI wire protocol. Previously sent cards are not automatically rewritten by an upgrade.
|
|
441
447
|
|
|
442
448
|
From CLI 1.6.172, Codex threads support native goals through `/goal` (status), `/goal <objective>` (start), `/goal pause`, `/goal resume`, and `/goal clear`. Start or resume only when the thread and queue are idle, with managed delegation explicitly disabled using `/delegation off`. This initial restriction does not disable Codex's native subagents. Optional `--budget <tokens>` on start or resume sets an explicit positive token budget; omitting it does not invent a budget. For example:
|
|
443
449
|
|
|
@@ -486,6 +492,21 @@ Claude Code also supports opt-in `/sandbox` policies. Workspace-write mode autom
|
|
|
486
492
|
- **Device authentication**: Each device has a unique hardware-based ID
|
|
487
493
|
- **Binding codes**: Expire after 5 minutes
|
|
488
494
|
|
|
495
|
+
From CLI 1.6.177, `/clear` and its `/new` alias reset the entire current
|
|
496
|
+
thread's conversation context: all direct backend session bindings and every
|
|
497
|
+
managed worker conversation, across backends and parallel worker lanes. The
|
|
498
|
+
working directory, files, Git artifacts, archived native transcripts, login,
|
|
499
|
+
backend/model/effort selections, delegation preference, and sandbox grants are
|
|
500
|
+
preserved. Other threads are unaffected. A later backend switch starts fresh
|
|
501
|
+
instead of restoring a pre-clear binding. Busy tasks, queued work, and workers
|
|
502
|
+
with unconfirmed shutdowns must settle before clearing. Reset intent is saved
|
|
503
|
+
before any session binding changes. A persisted reset intent blocks old
|
|
504
|
+
conversations until clearing succeeds, including after a CLI restart. If
|
|
505
|
+
clearing fails, resolve the reported problem and retry `/clear` or `/new`.
|
|
506
|
+
Service shutdown waits for retained cleanup and reports unconfirmed native exits
|
|
507
|
+
before acknowledging completion.
|
|
508
|
+
Single-worker **Clear context** controls still reset only the selected worker.
|
|
509
|
+
|
|
489
510
|
## Session Resume
|
|
490
511
|
|
|
491
512
|
CLI 1.6.164 supports confirmed Pi native session connections and read-only Pi/Codex/Claude Code discovery. Adopted Pi history reloads before every remote turn; `/session detach` preserves it and `/session release` is removed. Foreground Pi `/new` and `/clear` also preserve old history and start independent IDs; new default names use native session IDs and persisted names are not overwritten on reopen. Worker/metadata cleanup is unchanged. Resume drafts keep ordinary messages in the current conversation until confirmation succeeds. Use only one side at a time. Local Pi windows may stay open but must use native `/resume` before their next local turn; automatic local refresh and writer locking are not provided. Existing Router command/response envelopes support the text workflow without a new wire capability. See the [session resume specification](../../SESSION_RESUME_SPEC.md).
|
|
@@ -44,6 +44,7 @@ export declare class MessageHandler {
|
|
|
44
44
|
private activityProgressSupported;
|
|
45
45
|
private workerContextResetSupported;
|
|
46
46
|
private settingsCardsSupported;
|
|
47
|
+
private modelSpeedSettingsSupported;
|
|
47
48
|
private directoryCardsSupported;
|
|
48
49
|
private readonly directoryBrowser;
|
|
49
50
|
private delegationCardsSupported;
|
|
@@ -79,6 +80,7 @@ export declare class MessageHandler {
|
|
|
79
80
|
private handleStatusQuery;
|
|
80
81
|
private isValidMessage;
|
|
81
82
|
private handleWorkerContextReset;
|
|
83
|
+
private clearThreadConversation;
|
|
82
84
|
/**
|
|
83
85
|
* Handle built-in commands (thread-scoped).
|
|
84
86
|
* Returns true if handled.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/client/MessageHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAgK,MAAM,UAAU,CAAC;AACzM,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAOxD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/client/MessageHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,7 @@ const uuid_1 = require("uuid");
|
|
|
29
29
|
const ZCodeCommand_1 = require("../executor/zcode/ZCodeCommand");
|
|
30
30
|
const DelegationManager_1 = require("../delegation/DelegationManager");
|
|
31
31
|
const DelegationBridge_1 = require("../delegation/DelegationBridge");
|
|
32
|
+
const DelegatedWorkerSessionStore_1 = require("../delegation/DelegatedWorkerSessionStore");
|
|
32
33
|
const contract_1 = require("../delegation/contract");
|
|
33
34
|
const DelegationStatusFormatter_1 = require("../delegation/DelegationStatusFormatter");
|
|
34
35
|
const WorkerPolicy_1 = require("../delegation/WorkerPolicy");
|
|
@@ -179,6 +180,7 @@ class MessageHandler {
|
|
|
179
180
|
activityProgressSupported = false;
|
|
180
181
|
workerContextResetSupported = false;
|
|
181
182
|
settingsCardsSupported = false;
|
|
183
|
+
modelSpeedSettingsSupported = false;
|
|
182
184
|
directoryCardsSupported = false;
|
|
183
185
|
directoryBrowser;
|
|
184
186
|
delegationCardsSupported = false;
|
|
@@ -204,7 +206,7 @@ class MessageHandler {
|
|
|
204
206
|
for (const delivery of this.imageDeliveries.values())
|
|
205
207
|
delivery.invalidatePending();
|
|
206
208
|
});
|
|
207
|
-
this.delegation = new DelegationManager_1.DelegationManager(directoryGuard);
|
|
209
|
+
this.delegation = new DelegationManager_1.DelegationManager(directoryGuard, undefined, undefined, undefined, undefined, undefined, new DelegatedWorkerSessionStore_1.DelegatedWorkerSessionStore(undefined, threadManager.contextResets));
|
|
208
210
|
this.settingsCatalogReader = new SettingsCatalog_1.SettingsCatalogReader(directoryGuard);
|
|
209
211
|
this.settingsService = new SettingsService_1.SettingsService({
|
|
210
212
|
state: id => this.settingsState(id),
|
|
@@ -224,7 +226,7 @@ class MessageHandler {
|
|
|
224
226
|
if (!thread)
|
|
225
227
|
throw new Error('This thread no longer exists.');
|
|
226
228
|
const config = this.executorConfiguration();
|
|
227
|
-
return this.settingsCatalogReader.read(config, thread, this.threadPool.getBackendKey(id), target, kind);
|
|
229
|
+
return this.settingsCatalogReader.read(config, thread, this.threadPool.getBackendKey(id), target, kind, this.modelSpeedSettingsSupported);
|
|
228
230
|
},
|
|
229
231
|
busy: (id, except, queue = true) => this.settingsBusy(id, except, queue),
|
|
230
232
|
threads: () => this.threadManager.listThreads().map(thread => thread.id),
|
|
@@ -242,6 +244,7 @@ class MessageHandler {
|
|
|
242
244
|
preference: (id, target, kind, value) => this.applyPreference(id, target, kind, value),
|
|
243
245
|
delegation: (id, enabled) => this.applyDelegationSetting(id, enabled),
|
|
244
246
|
delegationSupported: id => Boolean(this.threadPool.getExecutor(id).configureDelegation),
|
|
247
|
+
speedSettingsSupported: () => this.modelSpeedSettingsSupported,
|
|
245
248
|
});
|
|
246
249
|
this.directoryBrowser = new DirectoryBrowser_1.DirectoryBrowser({
|
|
247
250
|
guard: this.directoryGuard,
|
|
@@ -352,6 +355,7 @@ class MessageHandler {
|
|
|
352
355
|
this.delegationProgressSupported = data.capabilities?.delegationProgress === true;
|
|
353
356
|
this.workerContextResetSupported = this.delegationProgressSupported && data.capabilities?.workerContextReset === true;
|
|
354
357
|
this.settingsCardsSupported = data.capabilities?.settingsCards === true;
|
|
358
|
+
this.modelSpeedSettingsSupported = this.settingsCardsSupported && data.capabilities?.modelSpeedSettings === true;
|
|
355
359
|
this.directoryCardsSupported = this.settingsCardsSupported && data.capabilities?.directoryCards === true;
|
|
356
360
|
this.delegationCardsSupported = this.settingsCardsSupported && data.capabilities?.delegationCards === true;
|
|
357
361
|
this.delegationProgressTextSupported = this.delegationProgressSupported
|
|
@@ -407,7 +411,12 @@ class MessageHandler {
|
|
|
407
411
|
async handleCommandMessage(message, fileOrder) {
|
|
408
412
|
const threadId = message.threadId ?? this.threadManager.getDefaultThread().id;
|
|
409
413
|
const content = message.content?.trim() ?? '';
|
|
410
|
-
const
|
|
414
|
+
const clearing = content === '/clear' || content === '/new';
|
|
415
|
+
const body = () => {
|
|
416
|
+
if (!clearing)
|
|
417
|
+
this.threadManager.contextResets.assertReady(threadId);
|
|
418
|
+
return this.handleAdmittedCommandMessage(message, fileOrder);
|
|
419
|
+
};
|
|
411
420
|
this.messageOpenIds.set(message.messageId, message.openId);
|
|
412
421
|
if ((0, SessionResumeService_1.isSessionControl)(content)) {
|
|
413
422
|
if (!this.threadManager.getThread(threadId)) {
|
|
@@ -416,11 +425,13 @@ class MessageHandler {
|
|
|
416
425
|
}
|
|
417
426
|
let response;
|
|
418
427
|
try {
|
|
428
|
+
this.threadManager.contextResets.assertReady(threadId);
|
|
419
429
|
const control = () => this.sessionControl.handle(content, { openId: message.openId, threadId });
|
|
420
430
|
// Only Pi confirmations mutate native context. Other catalogs remain read-only.
|
|
421
431
|
if (this.threadPool.getBackendKey(threadId) === 'pi' && /^\/(?:resume|r|session)\s+confirm(?:\s|$)/i.test(content)) {
|
|
422
432
|
try {
|
|
423
433
|
response = await this.settingsAdmission.mutation(threadId, async () => {
|
|
434
|
+
this.threadManager.contextResets.assertReady(threadId);
|
|
424
435
|
this.settingsService.invalidate(threadId);
|
|
425
436
|
try {
|
|
426
437
|
return await control();
|
|
@@ -448,7 +459,7 @@ class MessageHandler {
|
|
|
448
459
|
// Abort and addressed human replies must remain available during native work.
|
|
449
460
|
if (content === '/abort' || /^(?:yes|no)(?:\s|$)/.test(content) || content.startsWith('/input '))
|
|
450
461
|
return await body();
|
|
451
|
-
if (/^\/(?:backend|model|effort|cd)\s+\S/.test(content)) {
|
|
462
|
+
if (clearing || /^\/(?:backend|model|effort|cd)\s+\S/.test(content)) {
|
|
452
463
|
const global = /^\/backend\s/.test(content) && !/\s@$/.test(content);
|
|
453
464
|
await this.settingsAdmission.mutation(global ? '*' : threadId, async () => {
|
|
454
465
|
this.settingsService.invalidate(global ? undefined : threadId);
|
|
@@ -466,7 +477,7 @@ class MessageHandler {
|
|
|
466
477
|
}
|
|
467
478
|
}
|
|
468
479
|
catch (error) {
|
|
469
|
-
this.sendResponse(message.messageId, threadId, { success: false, error: error instanceof Error ? error.message : 'Command admission failed.' });
|
|
480
|
+
this.sendResponse(message.messageId, threadId, { success: false, error: error instanceof Error ? error.message : 'Command admission failed.' }, clearing);
|
|
470
481
|
}
|
|
471
482
|
}
|
|
472
483
|
async handleAdmittedCommandMessage(message, fileOrder) {
|
|
@@ -494,6 +505,10 @@ class MessageHandler {
|
|
|
494
505
|
return;
|
|
495
506
|
}
|
|
496
507
|
const settingsCommand = content?.trim() ?? '';
|
|
508
|
+
if (settingsCommand === '/clear' || settingsCommand === '/new') {
|
|
509
|
+
await this.clearThreadConversation(messageId, resolvedThreadId);
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
497
512
|
if (this.directoryCardsSupported && openId && settingsCommand === '/cd') {
|
|
498
513
|
try {
|
|
499
514
|
const menu = await this.directoryBrowser.open(resolvedThreadId, openId, messageId);
|
|
@@ -929,6 +944,30 @@ class MessageHandler {
|
|
|
929
944
|
this.wsClient.send({ type: 'worker_context_reset_result', messageId: request.messageId,
|
|
930
945
|
success: !error, ...(error ? { error } : {}), timestamp: Date.now() });
|
|
931
946
|
}
|
|
947
|
+
async clearThreadConversation(messageId, threadId) {
|
|
948
|
+
if (this.threadPool.isThreadBusy(threadId) || this.hasThreadQueueState(threadId)
|
|
949
|
+
|| this.abortOperations.has(threadId) || this.activeThreadOperations.has(threadId)) {
|
|
950
|
+
throw new Error('This thread is busy or has queued messages. Wait for it to finish and clear its queue before retrying /clear.');
|
|
951
|
+
}
|
|
952
|
+
this.threadPool.assertContextResettable(threadId);
|
|
953
|
+
const token = this.beginThreadOperation(threadId);
|
|
954
|
+
try {
|
|
955
|
+
await this.delegation.assertThreadContextResettable(threadId);
|
|
956
|
+
await this.threadManager.contextResets.begin(threadId);
|
|
957
|
+
await this.threadPool.clearThreadContext(threadId);
|
|
958
|
+
await this.delegation.clearThreadContexts(threadId);
|
|
959
|
+
await this.threadManager.contextResets.complete(threadId);
|
|
960
|
+
this.sendResponse(messageId, threadId, { success: true,
|
|
961
|
+
output: 'Conversation context cleared for all direct backends and managed workers in this thread.' }, true);
|
|
962
|
+
}
|
|
963
|
+
catch (error) {
|
|
964
|
+
const detail = error instanceof Error ? error.message : 'Local context storage is unavailable';
|
|
965
|
+
throw new Error(`Could not clear thread conversation: ${detail}. Check local CLI storage and retry /clear or /new.`);
|
|
966
|
+
}
|
|
967
|
+
finally {
|
|
968
|
+
this.finishThreadOperation(threadId, token);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
932
971
|
/**
|
|
933
972
|
* Handle built-in commands (thread-scoped).
|
|
934
973
|
* Returns true if handled.
|
|
@@ -1162,14 +1201,6 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1162
1201
|
});
|
|
1163
1202
|
return true;
|
|
1164
1203
|
}
|
|
1165
|
-
if (trimmed === '/clear' || trimmed === '/new') {
|
|
1166
|
-
executor.resetContext();
|
|
1167
|
-
this.sendResponse(messageId, threadId, {
|
|
1168
|
-
success: true,
|
|
1169
|
-
output: '✅ Conversation context cleared',
|
|
1170
|
-
});
|
|
1171
|
-
return true;
|
|
1172
|
-
}
|
|
1173
1204
|
if (trimmed === '/compact') {
|
|
1174
1205
|
if (!('compactWhenFull' in executor && typeof executor.compactWhenFull === 'function')) {
|
|
1175
1206
|
this.sendResponse(messageId, threadId, {
|
|
@@ -2834,12 +2865,13 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2834
2865
|
return { success: true, output: `✅ Changed working directory to: ${cwd}${changed ? '\nConversation context cleared for all direct and delegated backends in this thread.' : ''}${cleanup.failed ? `\n⚠️ ${cleanup.failed} delegated worker lane(s) could not be cleaned up. Retry with /delegation reset after checking filesystem permissions.` : ''}` };
|
|
2835
2866
|
}
|
|
2836
2867
|
settingsState(threadId) {
|
|
2868
|
+
this.threadManager.contextResets.assertReady(threadId);
|
|
2837
2869
|
const thread = this.threadManager.getThread(threadId);
|
|
2838
2870
|
if (!thread)
|
|
2839
2871
|
return undefined;
|
|
2840
2872
|
const projection = (entry) => ({ id: entry.id, backend: entry.backend,
|
|
2841
2873
|
cwd: entry.workingDirectory, generation: entry.delegationWorkspaceGeneration, model: entry.model,
|
|
2842
|
-
models: entry.models, efforts: entry.efforts, delegation: entry.delegation, delegationBackends: entry.delegationBackends });
|
|
2874
|
+
models: entry.models, efforts: entry.efforts, speeds: entry.speeds, delegation: entry.delegation, delegationBackends: entry.delegationBackends });
|
|
2843
2875
|
const all = this.threadManager.listThreads().map(projection).sort((a, b) => a.id.localeCompare(b.id));
|
|
2844
2876
|
const configuredModels = { ...thread.models };
|
|
2845
2877
|
if (configuredModels.claude === undefined && thread.model)
|
|
@@ -2899,6 +2931,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2899
2931
|
}
|
|
2900
2932
|
/** Shared native/persistent mutation for cards and parameterized text commands. */
|
|
2901
2933
|
async applyPreference(threadId, backend, kind, value, onStream) {
|
|
2934
|
+
this.threadManager.contextResets.assertReady(threadId);
|
|
2902
2935
|
const thread = this.threadManager.getThread(threadId);
|
|
2903
2936
|
if (!thread)
|
|
2904
2937
|
return { success: false, error: 'This thread no longer exists.' };
|
|
@@ -2907,6 +2940,11 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2907
2940
|
const config = this.executorConfiguration();
|
|
2908
2941
|
const coordinator = this.threadPool.getBackendKey(threadId);
|
|
2909
2942
|
const apply = async (executor) => {
|
|
2943
|
+
if (kind === 'speed') {
|
|
2944
|
+
if (!this.modelSpeedSettingsSupported || !executor.setSpeed)
|
|
2945
|
+
return { success: false, error: 'Native speed settings are unavailable.' };
|
|
2946
|
+
return executor.setSpeed(value);
|
|
2947
|
+
}
|
|
2910
2948
|
if (kind === 'effort') {
|
|
2911
2949
|
if (!executor.setEffort)
|
|
2912
2950
|
return { success: false, error: 'This backend does not expose effort controls.' };
|
|
@@ -2943,7 +2981,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2943
2981
|
await this.threadManager.updateThread(threadId, { models: Object.keys(models).length ? models : undefined,
|
|
2944
2982
|
...(backend === 'claude' ? { model: value } : {}) });
|
|
2945
2983
|
}
|
|
2946
|
-
else {
|
|
2984
|
+
else if (kind === 'effort') {
|
|
2947
2985
|
const efforts = { ...current.efforts };
|
|
2948
2986
|
if (value === undefined)
|
|
2949
2987
|
delete efforts[backend];
|
|
@@ -2951,6 +2989,14 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2951
2989
|
efforts[backend] = value;
|
|
2952
2990
|
await this.threadManager.updateThread(threadId, { efforts: Object.keys(efforts).length ? efforts : undefined });
|
|
2953
2991
|
}
|
|
2992
|
+
else {
|
|
2993
|
+
const speeds = { ...current.speeds };
|
|
2994
|
+
// Null records an explicit return to native configuration, so resumed
|
|
2995
|
+
// worker lanes also clear any previously sticky tier. Unset old threads
|
|
2996
|
+
// retain their original RPC shapes without additional settings reads.
|
|
2997
|
+
speeds[backend] = value ?? null;
|
|
2998
|
+
await this.threadManager.updateThread(threadId, { speeds: Object.keys(speeds).length ? speeds : undefined });
|
|
2999
|
+
}
|
|
2954
3000
|
return result;
|
|
2955
3001
|
}
|
|
2956
3002
|
finally {
|
|
@@ -2959,6 +3005,9 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2959
3005
|
}
|
|
2960
3006
|
async applyBackendSetting(threadId, backend, scope, followGlobal = false) {
|
|
2961
3007
|
try {
|
|
3008
|
+
for (const thread of scope === 'all' ? this.threadManager.listThreads() : [{ id: threadId }]) {
|
|
3009
|
+
this.threadManager.contextResets.assertReady(thread.id);
|
|
3010
|
+
}
|
|
2962
3011
|
if (followGlobal) {
|
|
2963
3012
|
await this.threadPool.destroyThread(threadId, { deleteData: false });
|
|
2964
3013
|
await this.threadManager.updateThread(threadId, { backend: undefined });
|
|
@@ -3124,14 +3173,20 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
3124
3173
|
await this.fileInbox?.destroy();
|
|
3125
3174
|
this.notificationAdapter.unregister();
|
|
3126
3175
|
try {
|
|
3127
|
-
await
|
|
3128
|
-
|
|
3176
|
+
const results = await Promise.allSettled([
|
|
3177
|
+
this.delegation.destroy(),
|
|
3178
|
+
...[...this.delegationBridges.values()].map(bridge => bridge.close()),
|
|
3179
|
+
this.threadPool.destroyAll({ deleteData: false, shutdown: true }),
|
|
3180
|
+
]);
|
|
3181
|
+
const failure = results.find((result) => result.status === 'rejected');
|
|
3182
|
+
if (failure)
|
|
3183
|
+
throw failure.reason;
|
|
3129
3184
|
this.delegationBridges.clear();
|
|
3130
|
-
await this.threadPool.destroyAll({ deleteData: false });
|
|
3131
3185
|
this.pendingApprovalCards.clear();
|
|
3132
3186
|
}
|
|
3133
3187
|
catch (err) {
|
|
3134
3188
|
console.error('Error destroying thread executors:', err);
|
|
3189
|
+
throw err;
|
|
3135
3190
|
}
|
|
3136
3191
|
}
|
|
3137
3192
|
}
|