@yu_robotics/remote-cli 1.6.158 → 1.6.165
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 +10 -3
- package/dist/client/MessageHandler.d.ts +4 -5
- package/dist/client/MessageHandler.d.ts.map +1 -1
- package/dist/client/MessageHandler.js +102 -9
- package/dist/client/MessageHandler.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +15 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/session.d.ts +17 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +37 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/delegation/GitCheckpoint.d.ts +1 -0
- package/dist/delegation/GitCheckpoint.d.ts.map +1 -1
- package/dist/delegation/GitCheckpoint.js +15 -4
- package/dist/delegation/GitCheckpoint.js.map +1 -1
- package/dist/executor/IExecutor.d.ts +21 -0
- package/dist/executor/IExecutor.d.ts.map +1 -1
- package/dist/executor/PiExecutor.d.ts +26 -1
- package/dist/executor/PiExecutor.d.ts.map +1 -1
- package/dist/executor/PiExecutor.js +256 -15
- package/dist/executor/PiExecutor.js.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/maintenance/release-notes.json +1 -1
- package/dist/session/SessionCatalog.d.ts +76 -0
- package/dist/session/SessionCatalog.d.ts.map +1 -0
- package/dist/session/SessionCatalog.js +197 -0
- package/dist/session/SessionCatalog.js.map +1 -0
- package/dist/session/SessionControl.d.ts +56 -0
- package/dist/session/SessionControl.d.ts.map +1 -0
- package/dist/session/SessionControl.js +262 -0
- package/dist/session/SessionControl.js.map +1 -0
- package/dist/session/SessionLocalInfo.d.ts +48 -0
- package/dist/session/SessionLocalInfo.d.ts.map +1 -0
- package/dist/session/SessionLocalInfo.js +145 -0
- package/dist/session/SessionLocalInfo.js.map +1 -0
- package/dist/session/SessionMenu.d.ts +102 -0
- package/dist/session/SessionMenu.d.ts.map +1 -0
- package/dist/session/SessionMenu.js +144 -0
- package/dist/session/SessionMenu.js.map +1 -0
- package/dist/session/SessionResumeService.d.ts +38 -0
- package/dist/session/SessionResumeService.d.ts.map +1 -0
- package/dist/session/SessionResumeService.js +147 -0
- package/dist/session/SessionResumeService.js.map +1 -0
- package/dist/session/adapters/ClaudeSessionCatalog.d.ts +10 -0
- package/dist/session/adapters/ClaudeSessionCatalog.d.ts.map +1 -0
- package/dist/session/adapters/ClaudeSessionCatalog.js +156 -0
- package/dist/session/adapters/ClaudeSessionCatalog.js.map +1 -0
- package/dist/session/adapters/CodexSessionCatalog.d.ts +9 -0
- package/dist/session/adapters/CodexSessionCatalog.d.ts.map +1 -0
- package/dist/session/adapters/CodexSessionCatalog.js +214 -0
- package/dist/session/adapters/CodexSessionCatalog.js.map +1 -0
- package/dist/session/adapters/PiSessionCatalog.d.ts +52 -0
- package/dist/session/adapters/PiSessionCatalog.d.ts.map +1 -0
- package/dist/session/adapters/PiSessionCatalog.js +252 -0
- package/dist/session/adapters/PiSessionCatalog.js.map +1 -0
- package/dist/session/adapters/index.d.ts +13 -0
- package/dist/session/adapters/index.d.ts.map +1 -0
- package/dist/session/adapters/index.js +17 -0
- package/dist/session/adapters/index.js.map +1 -0
- package/dist/types/config.d.ts +11 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,7 +178,7 @@ Linux users upgrading from version 1.6.23 or earlier should run `remote-cli serv
|
|
|
178
178
|
| `/model [name]` | Open native model settings, or set the active backend model with a text argument |
|
|
179
179
|
| `/effort [auto|level]` | Open native effort settings, or set/clear the active backend effort with a text argument |
|
|
180
180
|
| `/sandbox [on/off/read-only/default]` | Configure the current Codex or Claude Code thread sandbox, directory grants, and networking |
|
|
181
|
-
| `/backend` | Open backend settings;
|
|
181
|
+
| `/backend` | Open backend settings; click a backend to switch immediately, defaulting to Current thread |
|
|
182
182
|
| `/delegation [on|off]` | Inspect or enable delegation between installed agent backends in this thread |
|
|
183
183
|
| `/backend <index>` | Switch all threads and clear per-thread backend overrides |
|
|
184
184
|
| `/backend <index> @` | Switch only the current thread |
|
|
@@ -187,9 +187,9 @@ Linux users upgrading from version 1.6.23 or earlier should run `remote-cli serv
|
|
|
187
187
|
| `/unbind` | Unbind all devices |
|
|
188
188
|
| `/device` | List and switch between bound devices |
|
|
189
189
|
|
|
190
|
-
CLI and Router 1.6.152 add standalone settings cards. `/backend` lists all eight stable backend choices, disables missing installations and
|
|
190
|
+
CLI and Router 1.6.152 add standalone settings cards. `/backend` lists all eight stable backend choices, disables missing installations and defaults to Current thread, with All threads on this device opt-in. From Router 1.6.160, clicking a backend submits immediately without Confirm; scope controls only set the next click's target. Scope persists in the same card across backend acknowledgements, while a new card defaults to Current thread. Follow global applies immediately to the original thread and restores Current thread scope after acknowledgement. `/model` and `/effort` submit native options immediately, and show applied state only after a saved-setting acknowledgement. Their target-backend selector configures future worker launches without switching the coordinator. Busy work, expired cards and changed settings require refresh; older peers and parameterized text commands retain their existing behavior. See [Model and Reasoning Effort](../../README.md#model-and-reasoning-effort).
|
|
191
191
|
|
|
192
|
-
From 1.6.154, numbered sections separate backend selection
|
|
192
|
+
From 1.6.154, numbered sections separate backend selection above scope (Confirm removed in Router 1.6.160), or target backend, model/effort choices and secondary actions. The acknowledged backend, selected scope and known preferences carry explicit checks; changing the target still never switches the coordinator. AGY model catalogs accept tab-delimited and formatted multi-space native rows, with exact IDs and explicit failures for empty, unusable or oversized responses. No inference or additional protocol capability is needed.
|
|
193
193
|
|
|
194
194
|
From Router 1.6.155, the selected backend application scope is highlighted in blue, and model/effort target selectors separate the main backend from other backends' worker preferences. Choices are shown together when the complete card fits its node and byte budgets; only oversized catalogs paginate, with headers, groups and pending/retry controls included. Viewing a target never changes the coordinator, and same-backend workers continue to share its per-thread preference. Existing CLI settings metadata is sufficient; no new capability or native request is required.
|
|
195
195
|
|
|
@@ -328,6 +328,7 @@ source reservations remain held until owned operations settle, even on cancellat
|
|
|
328
328
|
no late worker is launched. Failed collection after confirmed exit preserves only
|
|
329
329
|
the affected lane and files for recovery rather than quarantining the source.
|
|
330
330
|
Individual Git command deadlines remain; cancellation may wait for Git to settle.
|
|
331
|
+
From CLI 1.6.159, delegated `git worktree add` and `git checkout` commands have a 120-second deadline per command. Other Git commands, including worktree listing/removal and nested object transfers, retain their 15-second deadlines. Git command timeout errors show the operation, elapsed milliseconds and deadline without paths or checkout references. Preparation remains pending until the Git child exits; cancellation can wait for this bounded cleanup, and the existing task ID remains available for polling.
|
|
331
332
|
Slow launch/cancel tools return the accepted task ID and a pending status before
|
|
332
333
|
the adapter timeout; poll that ID with `remote_cli_result`, not a new delegation.
|
|
333
334
|
The response does not claim cancellation cleanup or workspace release is complete.
|
|
@@ -451,6 +452,12 @@ Claude Code also supports opt-in `/sandbox` policies. Workspace-write mode autom
|
|
|
451
452
|
- **Device authentication**: Each device has a unique hardware-based ID
|
|
452
453
|
- **Binding codes**: Expire after 5 minutes
|
|
453
454
|
|
|
455
|
+
## Session Resume
|
|
456
|
+
|
|
457
|
+
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).
|
|
458
|
+
|
|
459
|
+
From CLI 1.6.165, Pi connection and detach confirmations exclude simultaneous settings/context mutations and reject queued work, active delegated tasks, and automatic updates. One daemon reserves a selected Pi file before startup; successful connection/detach requires pointer persistence. Failed writes keep the previous association. Uncertain process cleanup keeps the selected file reserved; confirm Pi has exited before restarting the client to clear that quarantine. Discovery respects `PI_CODING_AGENT_DIR`, and Pi local reopen commands quote file paths. These guards do not lock unmanaged terminals or other CLI instances. Claude Code and Codex catalogs remain read-only; their executor, settings, and history behavior is unchanged.
|
|
460
|
+
|
|
454
461
|
## Documentation
|
|
455
462
|
|
|
456
463
|
For full documentation including router server deployment, see the [project README](https://github.com/Yu-Robotics/remote-cli#readme).
|
|
@@ -13,11 +13,6 @@ export interface Message {
|
|
|
13
13
|
content?: string;
|
|
14
14
|
timestamp?: number;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Thread-aware Message Handler.
|
|
18
|
-
* Each thread has its own executor process managed by ThreadExecutorPool.
|
|
19
|
-
* Commands without a threadId are routed to the default thread.
|
|
20
|
-
*/
|
|
21
16
|
export declare class MessageHandler {
|
|
22
17
|
private wsClient;
|
|
23
18
|
private threadPool;
|
|
@@ -33,6 +28,10 @@ export declare class MessageHandler {
|
|
|
33
28
|
private readonly pendingQueueConfirmations;
|
|
34
29
|
private readonly pausedQueues;
|
|
35
30
|
private readonly messageOpenIds;
|
|
31
|
+
/** Thread operations held by session controls (adopt and detach). */
|
|
32
|
+
private readonly sessionOperations;
|
|
33
|
+
/** `/resume` and `/session`: read-only listing plus confirmed, strict native adoption. */
|
|
34
|
+
private readonly sessionControl;
|
|
36
35
|
private readonly activeThreadOperations;
|
|
37
36
|
private readonly abortOperations;
|
|
38
37
|
private automaticUpdateInProgress;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/client/MessageHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,8 @@ const FileInbox_1 = require("../files/FileInbox");
|
|
|
8
8
|
const DeviceIdentity_1 = require("../files/DeviceIdentity");
|
|
9
9
|
const crypto_1 = require("crypto");
|
|
10
10
|
const DocumentExtractor_1 = require("../files/DocumentExtractor");
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
11
13
|
const path_1 = __importDefault(require("path"));
|
|
12
14
|
const DelegationSettings_1 = require("../thread/DelegationSettings");
|
|
13
15
|
const hooks_1 = require("../hooks");
|
|
@@ -17,8 +19,8 @@ const WorkingDirectory_1 = require("../utils/WorkingDirectory");
|
|
|
17
19
|
const MachineCommands_1 = require("../machines/MachineCommands");
|
|
18
20
|
const child_process_1 = require("child_process");
|
|
19
21
|
const promises_1 = require("fs/promises");
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
+
const fs_2 = require("fs");
|
|
23
|
+
const os_2 = require("os");
|
|
22
24
|
const path_2 = require("path");
|
|
23
25
|
const config_1 = require("../types/config");
|
|
24
26
|
const uuid_1 = require("uuid");
|
|
@@ -35,6 +37,10 @@ const ActivityProgress_1 = require("../utils/ActivityProgress");
|
|
|
35
37
|
const SettingsAdmission_1 = require("../settings/SettingsAdmission");
|
|
36
38
|
const SettingsCatalog_1 = require("../settings/SettingsCatalog");
|
|
37
39
|
const SettingsService_1 = require("../settings/SettingsService");
|
|
40
|
+
const SessionResumeService_1 = require("../session/SessionResumeService");
|
|
41
|
+
const adapters_1 = require("../session/adapters");
|
|
42
|
+
const PiSessionCatalog_1 = require("../session/adapters/PiSessionCatalog");
|
|
43
|
+
const SessionControl_1 = require("../session/SessionControl");
|
|
38
44
|
const EFFORT_BACKENDS = new Set(['claude', 'codex', 'agy', 'opencode', 'kimi', 'zcode', 'pi', 'dsh']);
|
|
39
45
|
const SLASH_SESSION_BACKENDS = new Set(['opencode', 'kimi', 'zcode', 'pi']);
|
|
40
46
|
const NATIVE_SKILLS_BACKENDS = new Set(['claude', 'agy', 'opencode', 'kimi', 'zcode', 'pi']);
|
|
@@ -92,6 +98,20 @@ const MAX_THREAD_QUEUE_LENGTH = 10;
|
|
|
92
98
|
* Each thread has its own executor process managed by ThreadExecutorPool.
|
|
93
99
|
* Commands without a threadId are routed to the default thread.
|
|
94
100
|
*/
|
|
101
|
+
/** Same base directory PiExecutor uses for its per-thread pointers. */
|
|
102
|
+
function remoteCliDirectory() {
|
|
103
|
+
return path_1.default.join(process.env.HOME || os_1.default.homedir(), '.remote-cli');
|
|
104
|
+
}
|
|
105
|
+
/** Read the thread's Pi pointer binding flags without starting an executor. */
|
|
106
|
+
function readPiBinding(threadId) {
|
|
107
|
+
try {
|
|
108
|
+
const pointer = JSON.parse(fs_1.default.readFileSync(path_1.default.join(remoteCliDirectory(), 'pi-sessions', `${threadId}.json`), 'utf8'));
|
|
109
|
+
return { id: typeof pointer.id === 'string' ? pointer.id : undefined, adopted: pointer.adopted === true };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
95
115
|
class MessageHandler {
|
|
96
116
|
wsClient;
|
|
97
117
|
threadPool;
|
|
@@ -107,6 +127,43 @@ class MessageHandler {
|
|
|
107
127
|
pendingQueueConfirmations = new Map();
|
|
108
128
|
pausedQueues = new Set();
|
|
109
129
|
messageOpenIds = new Map();
|
|
130
|
+
/** Thread operations held by session controls (adopt and detach). */
|
|
131
|
+
sessionOperations = new Map();
|
|
132
|
+
/** `/resume` and `/session`: read-only listing plus confirmed, strict native adoption. */
|
|
133
|
+
sessionControl = new SessionControl_1.SessionControl({
|
|
134
|
+
sharingConfig: () => this.config.get('sessionSharing'),
|
|
135
|
+
backendOf: threadId => this.threadPool.getBackendKey(threadId),
|
|
136
|
+
workingDirectory: threadId => {
|
|
137
|
+
const directory = this.threadManager.getThread(threadId)?.workingDirectory;
|
|
138
|
+
try {
|
|
139
|
+
return directory ? this.directoryGuard.resolveWorkingDirectory(directory) : undefined;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
threadName: threadId => this.threadManager.getThread(threadId)?.name,
|
|
146
|
+
// Queued or pending work counts as busy: a confirmation must never redirect it into another session.
|
|
147
|
+
isBusy: threadId => this.threadPool.isThreadBusy(threadId) || this.hasThreadQueueState(threadId)
|
|
148
|
+
|| this.abortOperations.has(threadId) || this.isDestroyed || this.automaticUpdateInProgress
|
|
149
|
+
|| this.delegation.hasActiveTasks(threadId) || this.settingsAdmission.hasCommand(threadId),
|
|
150
|
+
setBusy: (threadId, busy) => {
|
|
151
|
+
if (busy) {
|
|
152
|
+
this.sessionOperations.set(threadId, this.beginThreadOperation(threadId));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const token = this.sessionOperations.get(threadId);
|
|
156
|
+
this.sessionOperations.delete(threadId);
|
|
157
|
+
// Messages that arrived during the operation were queued; resume draining them.
|
|
158
|
+
if (token && this.finishThreadOperation(threadId, token))
|
|
159
|
+
void this.startNextQueuedCommand(threadId);
|
|
160
|
+
},
|
|
161
|
+
executor: threadId => this.threadPool.getExecutor(threadId),
|
|
162
|
+
readCatalog: (backend, cwd) => (0, adapters_1.readSessionCatalog)(backend, cwd),
|
|
163
|
+
resolvePi: (cwd, id) => (0, PiSessionCatalog_1.resolvePiSessionLocator)(cwd, id, { remoteCliDirectory: remoteCliDirectory() }),
|
|
164
|
+
piHolder: (file, threadId) => (0, PiSessionCatalog_1.piSessionHolder)(file, threadId, { remoteCliDirectory: remoteCliDirectory() }),
|
|
165
|
+
piBinding: threadId => readPiBinding(threadId),
|
|
166
|
+
});
|
|
110
167
|
activeThreadOperations = new Map();
|
|
111
168
|
abortOperations = new Map();
|
|
112
169
|
automaticUpdateInProgress = false;
|
|
@@ -310,6 +367,41 @@ class MessageHandler {
|
|
|
310
367
|
const content = message.content?.trim() ?? '';
|
|
311
368
|
const body = () => this.handleAdmittedCommandMessage(message, fileOrder);
|
|
312
369
|
this.messageOpenIds.set(message.messageId, message.openId);
|
|
370
|
+
if ((0, SessionResumeService_1.isSessionControl)(content)) {
|
|
371
|
+
if (!this.threadManager.getThread(threadId)) {
|
|
372
|
+
this.sendResponse(message.messageId, undefined, { success: false, error: 'The selected thread no longer exists.' });
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
let response;
|
|
376
|
+
try {
|
|
377
|
+
const control = () => this.sessionControl.handle(content, { openId: message.openId, threadId });
|
|
378
|
+
// Only Pi confirmations mutate native context. Other catalogs remain read-only.
|
|
379
|
+
if (this.threadPool.getBackendKey(threadId) === 'pi' && /^\/(?:resume|r|session)\s+confirm(?:\s|$)/i.test(content)) {
|
|
380
|
+
try {
|
|
381
|
+
response = await this.settingsAdmission.mutation(threadId, async () => {
|
|
382
|
+
this.settingsService.invalidate(threadId);
|
|
383
|
+
try {
|
|
384
|
+
return await control();
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
this.settingsService.invalidate(threadId);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
finally {
|
|
392
|
+
void this.startNextQueuedCommand(threadId);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
response = await control();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
response = { success: false, error: `Session control failed: ${error instanceof Error ? error.message : String(error)}. No task was sent.` };
|
|
401
|
+
}
|
|
402
|
+
this.sendResponse(message.messageId, threadId, { ...response, threads: this.threadPool.getSummaries() }, true);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
313
405
|
try {
|
|
314
406
|
// Abort and addressed human replies must remain available during native work.
|
|
315
407
|
if (content === '/abort' || /^(?:yes|no)(?:\s|$)/.test(content) || content.startsWith('/input '))
|
|
@@ -907,6 +999,8 @@ Use /compact to reduce conversation context or /clear to start a fresh context.`
|
|
|
907
999
|
- /thread list - List all threads with their status
|
|
908
1000
|
- /thread new [name] - Create a new thread
|
|
909
1001
|
- /thread delete <name> - Delete a thread (only when idle)
|
|
1002
|
+
- /session - Show this thread's native session binding; /session detach
|
|
1003
|
+
- /resume - List this workspace's Pi sessions and connect one after confirmation (Pi only)
|
|
910
1004
|
|
|
911
1005
|
Remote Machine commands:
|
|
912
1006
|
- /proxy set <proxyHost> <proxyPort> <hostSuffix> [proxyAuth] - Configure global proxy
|
|
@@ -1680,8 +1774,6 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1680
1774
|
*/
|
|
1681
1775
|
expandCommandShortcuts(content) {
|
|
1682
1776
|
const trimmed = content.trim();
|
|
1683
|
-
if (trimmed === '/r' || trimmed === '/resume')
|
|
1684
|
-
return 'Please resume the previous conversation';
|
|
1685
1777
|
if (trimmed === '/c' || trimmed === '/continue')
|
|
1686
1778
|
return 'Please continue from where we left off';
|
|
1687
1779
|
return content;
|
|
@@ -1699,8 +1791,8 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1699
1791
|
]);
|
|
1700
1792
|
async listLocalSkills(cwd, backend) {
|
|
1701
1793
|
const roots = backend === 'codex'
|
|
1702
|
-
? [(0, path_2.join)(cwd, '.agents', 'skills'), (0, path_2.join)((0,
|
|
1703
|
-
: [(0, path_2.join)(cwd, '.claude', 'skills'), (0, path_2.join)((0,
|
|
1794
|
+
? [(0, path_2.join)(cwd, '.agents', 'skills'), (0, path_2.join)((0, os_2.homedir)(), '.codex', 'skills'), (0, path_2.join)((0, os_2.homedir)(), '.codex', 'skills', '.system')]
|
|
1795
|
+
: [(0, path_2.join)(cwd, '.claude', 'skills'), (0, path_2.join)((0, os_2.homedir)(), '.claude', 'skills')];
|
|
1704
1796
|
const skills = [];
|
|
1705
1797
|
const seen = new Set();
|
|
1706
1798
|
for (const root of roots) {
|
|
@@ -1967,7 +2059,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
1967
2059
|
if (other.id === threadId || !this.threadPool.isThreadBusy(other.id))
|
|
1968
2060
|
return false;
|
|
1969
2061
|
try {
|
|
1970
|
-
return (0, DelegationManager_1.workspacesOverlap)((0,
|
|
2062
|
+
return (0, DelegationManager_1.workspacesOverlap)((0, fs_2.realpathSync)(this.threadPool.getExecutor(other.id).getCurrentWorkingDirectory()), cwd);
|
|
1971
2063
|
}
|
|
1972
2064
|
catch {
|
|
1973
2065
|
return true;
|
|
@@ -2504,7 +2596,7 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2504
2596
|
console.error('Failed to send structured content:', error);
|
|
2505
2597
|
}
|
|
2506
2598
|
}
|
|
2507
|
-
sendResponse(messageId, threadId, result) {
|
|
2599
|
+
sendResponse(messageId, threadId, result, metadataOnly = false) {
|
|
2508
2600
|
if (!result.queueConfirmation)
|
|
2509
2601
|
this.fileInbox?.release(messageId, !result.success);
|
|
2510
2602
|
try {
|
|
@@ -2512,7 +2604,8 @@ You can also use natural language commands to control Claude Code CLI.`,
|
|
|
2512
2604
|
let cwd;
|
|
2513
2605
|
try {
|
|
2514
2606
|
if (threadId) {
|
|
2515
|
-
cwd = this.
|
|
2607
|
+
cwd = metadataOnly ? this.threadManager.getThread(threadId)?.workingDirectory
|
|
2608
|
+
: this.threadPool.getExecutor(threadId).getCurrentWorkingDirectory();
|
|
2516
2609
|
}
|
|
2517
2610
|
}
|
|
2518
2611
|
catch {
|