@jingyi0605/codingns 0.5.1 → 0.6.0
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/dist/public/assets/{AdaptiveButlerPage-SffCV4Vb.js → AdaptiveButlerPage-uFwDdN-F.js} +3 -3
- package/dist/public/assets/App-BZvapsi8.js +30 -0
- package/dist/public/assets/App-CcDXqFl1.css +1 -0
- package/dist/public/assets/{BootstrapPage--zExdgfM.js → BootstrapPage-gHSoa4JN.js} +1 -1
- package/dist/public/assets/ConversationPage-z3sXtKZ7.js +4 -0
- package/dist/public/assets/{DesktopDetachPreviewPage-DvI9CIKi.js → DesktopDetachPreviewPage-4eMRxiBW.js} +1 -1
- package/dist/public/assets/DesktopWindowPage-CZcoGApB.js +2 -0
- package/dist/public/assets/FileContextPanel-C3qex8bb.js +1 -0
- package/dist/public/assets/GitSidebar-BK6H16XU.js +6 -0
- package/dist/public/assets/{MobileCreateSessionSheet-CXSKMnYn.js → MobileCreateSessionSheet-BYfbvK8o.js} +1 -1
- package/dist/public/assets/MobileSheet-Ckug8hTb.js +1 -0
- package/dist/public/assets/{MobileTopHeaderFrame-BWorAJ1C.js → MobileTopHeaderFrame-Bwv8Ovm_.js} +1 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-RqWrBdn2.js +1 -0
- package/dist/public/assets/RelayConnectEntryPage-D_4YL-YH.js +1 -0
- package/dist/public/assets/ServerSettingsModal-CMSm3BZU.js +1 -0
- package/dist/public/assets/SessionIndexPage-DuK10DL5.js +1 -0
- package/dist/public/assets/SettingsPage-fyD-xaHL.js +1 -0
- package/dist/public/assets/TerminalManagerPanel-CCLr1Ypk.js +1 -0
- package/dist/public/assets/{TerminalPage-CvnHXBhw.js → TerminalPage-DaooFaJ4.js} +19 -19
- package/dist/public/assets/{TerminalRuntimeFallbackModal-D7Aq186N.js → TerminalRuntimeFallbackModal-aUzjEBwP.js} +1 -1
- package/dist/public/assets/ToolFilesPage-CGxBvYG0.js +1 -0
- package/dist/public/assets/ToolGitPage-C264yjS9.js +1 -0
- package/dist/public/assets/ToolProcessesPage-BOP4A1cb.js +1 -0
- package/dist/public/assets/ToolsHomePage-CQxGiKQA.js +1 -0
- package/dist/public/assets/WorkbenchLandingPage-CvAY68ca.js +1 -0
- package/dist/public/assets/WorkbenchLayout-DGm8Tc5M.js +3 -0
- package/dist/public/assets/{WorkbenchModal-B09hC9b5.js → WorkbenchModal-0tPIIhca.js} +1 -1
- package/dist/public/assets/{WorkbenchShellRoute-DsW4mBTX.css → WorkbenchShellRoute-BF0nHWOk.css} +1 -1
- package/dist/public/assets/WorkbenchShellRoute-DBBOsJo9.js +1 -0
- package/dist/public/assets/WorkspaceDebugDetailPage-CDerFYd2.js +1 -0
- package/dist/public/assets/WorkspaceDetailPage-BlJc1CHE.js +1 -0
- package/dist/public/assets/WorkspaceHomePage-BUsKJ3lv.js +1 -0
- package/dist/public/assets/client-runtime-manager-BZpL17fc.js +1 -0
- package/dist/public/assets/{default-session-permission-mode-D0wZ9Jek.js → default-session-permission-mode-DT4SGiwp.js} +1 -1
- package/dist/public/assets/file-tree-icon-Db5LXC8h.js +31 -0
- package/dist/public/assets/index-BZLcEHW3.js +42 -0
- package/dist/public/assets/index-BbspQPC2.css +1 -0
- package/dist/public/assets/login-direct-candidate-resolver-1mxe_Oh8.js +1 -0
- package/dist/public/assets/{preferences-service-gOt2ZjKZ.js → preferences-service-DWnzl5a0.js} +1 -1
- package/dist/public/assets/relay-entry-C5_Iay0I.js +1 -0
- package/dist/public/assets/session-runtime-machine-DdLeDqQr.js +17 -0
- package/dist/public/assets/{styles-BWPBZvze.css → styles-CsEMfdaS.css} +1 -1
- package/dist/public/assets/{terminal-runtime-meta-BMT-rSEe.js → terminal-runtime-meta-cdtWVfCm.js} +1 -1
- package/dist/public/assets/{useRegisteredDebugTemplates-zMcEOGca.js → useRegisteredDebugTemplates-oFAQNIqh.js} +1 -1
- package/dist/public/assets/window-BVUB8gMK.js +1 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.d.ts +2 -0
- package/dist/server/config/env.js +39 -0
- package/dist/server/config/env.js.map +1 -1
- package/dist/server/modules/client/npm-global-package-service.d.ts +7 -1
- package/dist/server/modules/client/npm-global-package-service.js +149 -43
- package/dist/server/modules/client/npm-global-package-service.js.map +1 -1
- package/dist/server/modules/client/service-update-task-service.js +6 -2
- package/dist/server/modules/client/service-update-task-service.js.map +1 -1
- package/dist/server/modules/client/service-update-types.d.ts +2 -0
- package/dist/server/modules/git/git-controller.d.ts +3 -0
- package/dist/server/modules/git/git-controller.js +3 -0
- package/dist/server/modules/git/git-controller.js.map +1 -1
- package/dist/server/modules/git/git-read-service.js +47 -1
- package/dist/server/modules/git/git-read-service.js.map +1 -1
- package/dist/server/modules/git/git-write-service.d.ts +4 -0
- package/dist/server/modules/git/git-write-service.js +24 -0
- package/dist/server/modules/git/git-write-service.js.map +1 -1
- package/dist/server/modules/git/types.d.ts +1 -0
- package/dist/server/modules/git/workspace-repo-guard.d.ts +2 -0
- package/dist/server/modules/git/workspace-repo-guard.js +24 -10
- package/dist/server/modules/git/workspace-repo-guard.js.map +1 -1
- package/dist/server/modules/parallel-sessions/parallel-session-controller.d.ts +53 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js +70 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js.map +1 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.d.ts +83 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js +591 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js.map +1 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.d.ts +56 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.js +483 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.js.map +1 -0
- package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-packets.d.ts +16 -1
- package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-packets.js.map +1 -1
- package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.d.ts +2 -1
- package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.js +18 -0
- package/dist/server/modules/relay-tunnel/crypto/relay-tunnel-protocol.js.map +1 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.d.ts +2 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.js +129 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.js.map +1 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-client-context.d.ts +13 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-client-context.js +2 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-client-context.js.map +1 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.d.ts +6 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js +110 -10
- package/dist/server/modules/relay-tunnel/relay-tunnel-gateway-service.js.map +1 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.d.ts +16 -4
- package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js +220 -102
- package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js.map +1 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-service.d.ts +4 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-service.js +257 -162
- package/dist/server/modules/relay-tunnel/relay-tunnel-service.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +3 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +56 -45
- package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-process.js +21 -2
- package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
- package/dist/server/modules/sessions/session-activity-inspector.js +6 -8
- package/dist/server/modules/sessions/session-activity-inspector.js.map +1 -1
- package/dist/server/modules/sessions/session-history-service.d.ts +11 -1
- package/dist/server/modules/sessions/session-history-service.js +204 -21
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +8 -0
- package/dist/server/modules/sessions/session-live-runtime-service.js +208 -25
- package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
- package/dist/server/modules/workbench/codex-archive-watcher.d.ts +16 -0
- package/dist/server/modules/workbench/codex-archive-watcher.js +50 -0
- package/dist/server/modules/workbench/codex-archive-watcher.js.map +1 -0
- package/dist/server/modules/workbench/workbench-service.d.ts +43 -4
- package/dist/server/modules/workbench/workbench-service.js +72 -9
- package/dist/server/modules/workbench/workbench-service.js.map +1 -1
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +1 -1
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +26 -3
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
- package/dist/server/modules/workspace/workspace-service.d.ts +3 -1
- package/dist/server/modules/workspace/workspace-service.js +10 -2
- package/dist/server/modules/workspace/workspace-service.js.map +1 -1
- package/dist/server/modules/worktree/worktree-base-ref-resolver.d.ts +20 -0
- package/dist/server/modules/worktree/worktree-base-ref-resolver.js +111 -0
- package/dist/server/modules/worktree/worktree-base-ref-resolver.js.map +1 -0
- package/dist/server/modules/worktree/worktree-cleanup-service.js +9 -3
- package/dist/server/modules/worktree/worktree-cleanup-service.js.map +1 -1
- package/dist/server/modules/worktree/worktree-manager.d.ts +0 -1
- package/dist/server/modules/worktree/worktree-manager.js +14 -20
- package/dist/server/modules/worktree/worktree-manager.js.map +1 -1
- package/dist/server/routes/git.js +1 -0
- package/dist/server/routes/git.js.map +1 -1
- package/dist/server/routes/parallel-groups.d.ts +3 -0
- package/dist/server/routes/parallel-groups.js +9 -0
- package/dist/server/routes/parallel-groups.js.map +1 -0
- package/dist/server/server/create-server.d.ts +8 -0
- package/dist/server/server/create-server.js +48 -9
- package/dist/server/server/create-server.js.map +1 -1
- package/dist/server/server/workbench-runtime-terminal-sync.d.ts +14 -0
- package/dist/server/server/workbench-runtime-terminal-sync.js +17 -0
- package/dist/server/server/workbench-runtime-terminal-sync.js.map +1 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.d.ts +11 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.js +131 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.js.map +1 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.d.ts +12 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.js +150 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.js.map +1 -0
- package/dist/server/storage/repositories/session-isolated-workspace-repository.d.ts +15 -0
- package/dist/server/storage/repositories/session-isolated-workspace-repository.js +230 -0
- package/dist/server/storage/repositories/session-isolated-workspace-repository.js.map +1 -0
- package/dist/server/storage/sqlite/schema.sql +73 -0
- package/dist/server/types/domain.d.ts +72 -0
- package/dist/server/ws/workbench-ws-hub.d.ts +3 -1
- package/dist/server/ws/workbench-ws-hub.js +189 -20
- package/dist/server/ws/workbench-ws-hub.js.map +1 -1
- package/dist/server/ws/ws-server.js +141 -8
- package/dist/server/ws/ws-server.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +67 -6
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +3 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +46 -22
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +558 -309
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +29 -5
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/public/assets/App-DUAg5urj.css +0 -1
- package/dist/public/assets/App-WOLwMld_.js +0 -30
- package/dist/public/assets/ConversationPage-D9pzRmOg.js +0 -2
- package/dist/public/assets/DesktopWindowPage-D8FpOSLE.js +0 -2
- package/dist/public/assets/FileContextPanel-C8T7oqRN.js +0 -1
- package/dist/public/assets/GitSidebar-Bze7DNnc.js +0 -6
- package/dist/public/assets/MobileSheet-Gzc14EpR.js +0 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-DOr4pTUq.js +0 -1
- package/dist/public/assets/ServerSettingsModal-BYB0GvTl.js +0 -1
- package/dist/public/assets/SessionIndexPage-CR3IARXX.js +0 -1
- package/dist/public/assets/SettingsPage-B_BQtnwE.js +0 -1
- package/dist/public/assets/TerminalManagerPanel-PQ-EM64j.js +0 -1
- package/dist/public/assets/ToolFilesPage-Qzkc6K2I.js +0 -1
- package/dist/public/assets/ToolGitPage-BdNDN-cV.js +0 -1
- package/dist/public/assets/ToolProcessesPage-EXJ9DHWI.js +0 -1
- package/dist/public/assets/ToolsHomePage-CjF3CWzR.js +0 -1
- package/dist/public/assets/WorkbenchLandingPage-DZPk4SmX.js +0 -1
- package/dist/public/assets/WorkbenchLayout-rwQib5In.js +0 -3
- package/dist/public/assets/WorkbenchShellRoute-Cerk5uK7.js +0 -1
- package/dist/public/assets/WorkspaceDebugDetailPage-Bcq8s-Ma.js +0 -1
- package/dist/public/assets/WorkspaceDetailPage-DNAa8pKr.js +0 -1
- package/dist/public/assets/WorkspaceHomePage-BoiLuACV.js +0 -1
- package/dist/public/assets/client-runtime-manager-CRQ-F5d2.js +0 -1
- package/dist/public/assets/file-tree-icon-Dp_xhVfD.js +0 -31
- package/dist/public/assets/index-C2G8Gmf1.js +0 -42
- package/dist/public/assets/index-CpPTUeA3.css +0 -1
- package/dist/public/assets/session-runtime-machine-Dq3pW-UF.js +0 -17
- package/dist/public/assets/window-BWqRixxq.js +0 -1
- /package/dist/public/assets/{styles-CSUx5LGe.js → styles-DRVvx_kv.js} +0 -0
|
@@ -187,6 +187,7 @@ export declare class SessionLiveRuntimeService {
|
|
|
187
187
|
private readonly sessionPermissionRequestService;
|
|
188
188
|
private readonly runtimeAdapterDisposables;
|
|
189
189
|
private readonly externalRuntimeSnapshots;
|
|
190
|
+
private readonly externalRuntimeInterruptSuppressions;
|
|
190
191
|
private readonly runtimeListeners;
|
|
191
192
|
private readonly terminalStateListeners;
|
|
192
193
|
private readonly deadRuntimeReconciliationSessions;
|
|
@@ -246,6 +247,8 @@ export declare class SessionLiveRuntimeService {
|
|
|
246
247
|
private buildBindingSnapshot;
|
|
247
248
|
private persistRuntimeEvent;
|
|
248
249
|
private emitTerminalStateEvent;
|
|
250
|
+
private reconcileTerminalRuntimeSnapshot;
|
|
251
|
+
private forceInterruptInactiveSession;
|
|
249
252
|
private beginPendingSendDebugTrace;
|
|
250
253
|
private logSendDebugStep;
|
|
251
254
|
private markSendDebugResponseReady;
|
|
@@ -265,6 +268,11 @@ export declare class SessionLiveRuntimeService {
|
|
|
265
268
|
private upsertSnapshot;
|
|
266
269
|
private shouldIgnoreClaudeExternalRuntimeUpdate;
|
|
267
270
|
private clearExternalRuntimeSnapshot;
|
|
271
|
+
private getFreshExternalRuntimeSnapshot;
|
|
272
|
+
private suppressInterruptedExternalRuntime;
|
|
273
|
+
private clearExternalRuntimeInterruptSuppression;
|
|
274
|
+
private shouldIgnoreInterruptedExternalRuntime;
|
|
275
|
+
private forceInterruptExternalSession;
|
|
268
276
|
private resolveActiveClaudePermissionSession;
|
|
269
277
|
}
|
|
270
278
|
export {};
|
|
@@ -14,6 +14,8 @@ import { ClaudeRuntimeHelperAdapter } from "./claude-runtime-helper-client.js";
|
|
|
14
14
|
import { CodexAppServerHelperClient } from "./codex-app-server-helper-client.js";
|
|
15
15
|
const RUNTIME_START_BINDING_WAIT_TIMEOUT_MS = 10_000;
|
|
16
16
|
const START_BINDING_POLL_INTERVAL_MS = 50;
|
|
17
|
+
const EXTERNAL_RUNTIME_INTERRUPT_SUPPRESSION_MS = 30_000;
|
|
18
|
+
const EXTERNAL_RUNTIME_SNAPSHOT_MAX_AGE_MS = 90_000;
|
|
17
19
|
export class SessionLiveRuntimeService {
|
|
18
20
|
sessionHistoryService;
|
|
19
21
|
sessionMessageAttachmentService;
|
|
@@ -31,6 +33,7 @@ export class SessionLiveRuntimeService {
|
|
|
31
33
|
sessionPermissionRequestService;
|
|
32
34
|
runtimeAdapterDisposables;
|
|
33
35
|
externalRuntimeSnapshots = new Map();
|
|
36
|
+
externalRuntimeInterruptSuppressions = new Map();
|
|
34
37
|
runtimeListeners = new Map();
|
|
35
38
|
terminalStateListeners = new Set();
|
|
36
39
|
deadRuntimeReconciliationSessions = new Set();
|
|
@@ -435,7 +438,7 @@ export class SessionLiveRuntimeService {
|
|
|
435
438
|
async getSessionRuntime(sessionId, userId) {
|
|
436
439
|
const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
|
|
437
440
|
const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
438
|
-
const externalRuntimeSnapshot = this.
|
|
441
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
439
442
|
const runtimeHasActiveRun = runtimeSnapshot ? isActiveRuntimeState(runtimeSnapshot.runningState) : false;
|
|
440
443
|
const externalHasActiveRun = externalRuntimeSnapshot
|
|
441
444
|
? isActiveRuntimeState(externalRuntimeSnapshot.runningState)
|
|
@@ -485,7 +488,7 @@ export class SessionLiveRuntimeService {
|
|
|
485
488
|
runningState: resolution.runningState,
|
|
486
489
|
hasActiveRun: externalHasActiveRun,
|
|
487
490
|
canAttach: false,
|
|
488
|
-
canInterrupt:
|
|
491
|
+
canInterrupt: externalHasActiveRun,
|
|
489
492
|
inRunInputMode: capabilities.inRunInputMode,
|
|
490
493
|
activityResolutionSource: resolution.activityResolutionSource,
|
|
491
494
|
activityConfidence: resolution.activityConfidence,
|
|
@@ -528,32 +531,59 @@ export class SessionLiveRuntimeService {
|
|
|
528
531
|
if (runtimeSnapshot) {
|
|
529
532
|
return createRuntimeActivityObservation(runtimeSessionId, runtimeSnapshot);
|
|
530
533
|
}
|
|
531
|
-
const externalRuntimeSnapshot = this.
|
|
534
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
532
535
|
if (externalRuntimeSnapshot) {
|
|
533
536
|
return createExternalRuntimeActivityObservation(runtimeSessionId, externalRuntimeSnapshot);
|
|
534
537
|
}
|
|
535
538
|
return null;
|
|
536
539
|
}
|
|
537
540
|
async interruptSession(sessionId, userId) {
|
|
538
|
-
this.sessionHistoryService.getSession(sessionId, userId);
|
|
541
|
+
const session = this.sessionHistoryService.getSession(sessionId, userId);
|
|
539
542
|
const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
|
|
540
543
|
const runtime = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
541
|
-
const externalRuntimeSnapshot = this.
|
|
544
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
542
545
|
if (!runtime || (runtime.runningState !== "running" && runtime.runningState !== "starting")) {
|
|
546
|
+
if (runtime && !isActiveRuntimeState(runtime.runningState)) {
|
|
547
|
+
await this.reconcileTerminalRuntimeSnapshot(sessionId, runtime);
|
|
548
|
+
return {
|
|
549
|
+
sessionId,
|
|
550
|
+
interrupted: true,
|
|
551
|
+
detail: runtime.detail ?? "当前会话已结束,已自动同步状态"
|
|
552
|
+
};
|
|
553
|
+
}
|
|
543
554
|
if (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
555
|
+
const refreshedSession = await Promise.resolve(this.sessionHistoryService.refreshRuntimeFallbackSession(sessionId, userId)).catch(() => null);
|
|
556
|
+
if (refreshedSession && !isPendingSessionRunningState(refreshedSession.runningState)) {
|
|
557
|
+
await this.forceInterruptInactiveSession(sessionId);
|
|
558
|
+
return {
|
|
559
|
+
sessionId,
|
|
560
|
+
interrupted: true,
|
|
561
|
+
detail: "当前会话已停止,已自动同步状态"
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
await this.forceInterruptExternalSession(sessionId);
|
|
565
|
+
return {
|
|
566
|
+
sessionId,
|
|
567
|
+
interrupted: true,
|
|
568
|
+
detail: "Claude 外部运行当前无法直接中断,已强制清理本地运行状态"
|
|
569
|
+
};
|
|
550
570
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
571
|
+
const refreshedSession = isPendingSessionRunningState(session.runningState)
|
|
572
|
+
? await Promise.resolve(this.sessionHistoryService.refreshRuntimeFallbackSession(sessionId, userId)).catch(() => null)
|
|
573
|
+
: session;
|
|
574
|
+
if (refreshedSession && !isPendingSessionRunningState(refreshedSession.runningState)) {
|
|
575
|
+
return {
|
|
576
|
+
sessionId,
|
|
577
|
+
interrupted: true,
|
|
578
|
+
detail: "当前会话已停止,已自动同步状态"
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
await this.forceInterruptInactiveSession(sessionId);
|
|
582
|
+
return {
|
|
583
|
+
sessionId,
|
|
584
|
+
interrupted: true,
|
|
585
|
+
detail: "当前会话已停止,已自动修正残留运行状态"
|
|
586
|
+
};
|
|
557
587
|
}
|
|
558
588
|
const interrupted = await this.providerRuntimeService.interrupt(runtimeSessionId).catch((error) => {
|
|
559
589
|
if (error instanceof Error && error.message === "INTERRUPT_NOT_SUPPORTED") {
|
|
@@ -589,7 +619,7 @@ export class SessionLiveRuntimeService {
|
|
|
589
619
|
subscribeRuntime(sessionId, onEnvelope) {
|
|
590
620
|
const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
|
|
591
621
|
const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
592
|
-
const externalRuntimeSnapshot = this.
|
|
622
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
593
623
|
const initialActivityEnvelope = this.buildSessionActivityEnvelope(sessionId, runtimeSessionId);
|
|
594
624
|
if (runtimeSnapshot) {
|
|
595
625
|
void onEnvelope({
|
|
@@ -767,13 +797,13 @@ export class SessionLiveRuntimeService {
|
|
|
767
797
|
sessionId
|
|
768
798
|
};
|
|
769
799
|
}
|
|
770
|
-
const externalRuntimeSnapshot = this.
|
|
800
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
771
801
|
if (externalRuntimeSnapshot) {
|
|
772
802
|
const resolution = this.sessionActivityAuthorityService.observe(createExternalRuntimeActivityObservation(runtimeSessionId, externalRuntimeSnapshot));
|
|
773
803
|
return {
|
|
774
804
|
...this.mapResolutionToActivityEnvelope(resolution, {
|
|
775
805
|
hasActiveRun: isActiveRuntimeState(externalRuntimeSnapshot.runningState),
|
|
776
|
-
canInterrupt:
|
|
806
|
+
canInterrupt: isActiveRuntimeState(externalRuntimeSnapshot.runningState)
|
|
777
807
|
}),
|
|
778
808
|
sessionId
|
|
779
809
|
};
|
|
@@ -792,7 +822,7 @@ export class SessionLiveRuntimeService {
|
|
|
792
822
|
}
|
|
793
823
|
resolveRuntimeSessionId(sessionId) {
|
|
794
824
|
if (this.providerRuntimeService.getSnapshot(sessionId)
|
|
795
|
-
|| this.
|
|
825
|
+
|| this.getFreshExternalRuntimeSnapshot(sessionId)) {
|
|
796
826
|
return sessionId;
|
|
797
827
|
}
|
|
798
828
|
const listSnapshots = "listSnapshots" in this.providerRuntimeService
|
|
@@ -898,6 +928,12 @@ export class SessionLiveRuntimeService {
|
|
|
898
928
|
};
|
|
899
929
|
}
|
|
900
930
|
async applyExternalRuntimeUpdate(input) {
|
|
931
|
+
if (input.runningState === "running" && this.shouldIgnoreInterruptedExternalRuntime(input.sessionId)) {
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
if (input.runningState !== "running") {
|
|
935
|
+
this.clearExternalRuntimeInterruptSuppression(input.sessionId);
|
|
936
|
+
}
|
|
901
937
|
const userIds = this.authUserRepository.listIds();
|
|
902
938
|
if (userIds.length === 0) {
|
|
903
939
|
return;
|
|
@@ -994,6 +1030,7 @@ export class SessionLiveRuntimeService {
|
|
|
994
1030
|
async startRuntimeRun(request, userId, mode) {
|
|
995
1031
|
this.runtimeMessageSeenSessions.delete(request.sessionId);
|
|
996
1032
|
this.runtimeHistoryFallbackSentSessions.delete(request.sessionId);
|
|
1033
|
+
this.clearExternalRuntimeInterruptSuppression(request.sessionId);
|
|
997
1034
|
if (request.provider === "claude-code") {
|
|
998
1035
|
this.clearExternalRuntimeSnapshot(request.sessionId);
|
|
999
1036
|
}
|
|
@@ -1061,7 +1098,7 @@ export class SessionLiveRuntimeService {
|
|
|
1061
1098
|
};
|
|
1062
1099
|
const runtimeSessionId = this.resolveRuntimeSessionId(input.sessionId);
|
|
1063
1100
|
const activeRun = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
1064
|
-
const externalRuntimeSnapshot = this.
|
|
1101
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
1065
1102
|
if (activeRun &&
|
|
1066
1103
|
activeRun.provider === "claude-code" &&
|
|
1067
1104
|
isActiveRuntimeState(activeRun.runningState)) {
|
|
@@ -1156,7 +1193,7 @@ export class SessionLiveRuntimeService {
|
|
|
1156
1193
|
this.queueDispatchSessions.add(sessionId);
|
|
1157
1194
|
try {
|
|
1158
1195
|
const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
|
|
1159
|
-
const externalRuntimeSnapshot = this.
|
|
1196
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(sessionId);
|
|
1160
1197
|
if ((runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState))
|
|
1161
1198
|
|| (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
|
|
1162
1199
|
return;
|
|
@@ -1222,7 +1259,7 @@ export class SessionLiveRuntimeService {
|
|
|
1222
1259
|
if (runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState)) {
|
|
1223
1260
|
return true;
|
|
1224
1261
|
}
|
|
1225
|
-
const externalRuntimeSnapshot = this.
|
|
1262
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(session.sessionId);
|
|
1226
1263
|
if (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
1227
1264
|
return true;
|
|
1228
1265
|
}
|
|
@@ -1259,7 +1296,7 @@ export class SessionLiveRuntimeService {
|
|
|
1259
1296
|
return session;
|
|
1260
1297
|
}
|
|
1261
1298
|
const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
|
|
1262
|
-
const externalRuntimeSnapshot = this.
|
|
1299
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(sessionId);
|
|
1263
1300
|
if ((runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState))
|
|
1264
1301
|
|| (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
|
|
1265
1302
|
return session;
|
|
@@ -1482,6 +1519,112 @@ export class SessionLiveRuntimeService {
|
|
|
1482
1519
|
await listener(event);
|
|
1483
1520
|
}
|
|
1484
1521
|
}
|
|
1522
|
+
async reconcileTerminalRuntimeSnapshot(sessionId, runtime) {
|
|
1523
|
+
const timestamp = runtime.lastEventAt ?? runtime.completedAt ?? runtime.startedAt;
|
|
1524
|
+
const runningState = toStoredRunningState(runtime.runningState);
|
|
1525
|
+
const currentSnapshot = this.sessionStatusSnapshotRepository.findBySessionId(sessionId);
|
|
1526
|
+
for (const userId of this.authUserRepository.listIds()) {
|
|
1527
|
+
const current = this.sessionStateRepository.findBySessionAndUser(sessionId, userId);
|
|
1528
|
+
if (current?.lastEventAt
|
|
1529
|
+
&& current.lastEventAt.localeCompare(timestamp) > 0
|
|
1530
|
+
&& isTerminalSessionRunningState(current.runningState)) {
|
|
1531
|
+
continue;
|
|
1532
|
+
}
|
|
1533
|
+
this.sessionStateRepository.upsert({
|
|
1534
|
+
sessionId,
|
|
1535
|
+
userId,
|
|
1536
|
+
runningState,
|
|
1537
|
+
activitySource: "runtime",
|
|
1538
|
+
favorite: current?.favorite ?? false,
|
|
1539
|
+
lastEventAt: timestamp,
|
|
1540
|
+
completedAt: isTerminalSessionRunningState(runningState)
|
|
1541
|
+
? (runtime.completedAt ?? timestamp)
|
|
1542
|
+
: current?.completedAt ?? null,
|
|
1543
|
+
lastSeenAt: current?.lastSeenAt ?? null,
|
|
1544
|
+
updatedAt: nowIso()
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
this.upsertSnapshot(sessionId, {
|
|
1548
|
+
syncStatus: runningState === "failed" ? "error" : "idle",
|
|
1549
|
+
syncCursor: currentSnapshot?.syncCursor ?? null,
|
|
1550
|
+
lastSyncAt: timestamp,
|
|
1551
|
+
lastErrorCode: runningState === "failed" ? runtime.errorCode ?? null : null,
|
|
1552
|
+
lastErrorDetail: runningState === "failed" ? runtime.detail ?? null : null,
|
|
1553
|
+
resumedAt: currentSnapshot?.resumedAt ?? null
|
|
1554
|
+
});
|
|
1555
|
+
this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(sessionId, runtime));
|
|
1556
|
+
await this.emitExternalRuntimeEnvelope({
|
|
1557
|
+
type: "session.runtime_status",
|
|
1558
|
+
sessionId,
|
|
1559
|
+
status: runtime.runningState,
|
|
1560
|
+
detail: runtime.detail,
|
|
1561
|
+
interruptSource: runtime.interruptSource,
|
|
1562
|
+
timestamp
|
|
1563
|
+
});
|
|
1564
|
+
if (isTerminalSessionRunningState(runningState)) {
|
|
1565
|
+
await this.emitTerminalStateEvent({
|
|
1566
|
+
sessionId,
|
|
1567
|
+
status: runningState,
|
|
1568
|
+
timestamp,
|
|
1569
|
+
detail: runtime.detail,
|
|
1570
|
+
source: "runtime"
|
|
1571
|
+
});
|
|
1572
|
+
void this.dispatchNextQueuedMessage(sessionId);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
async forceInterruptInactiveSession(sessionId) {
|
|
1576
|
+
const timestamp = nowIso();
|
|
1577
|
+
const currentSnapshot = this.sessionStatusSnapshotRepository.findBySessionId(sessionId);
|
|
1578
|
+
for (const userId of this.authUserRepository.listIds()) {
|
|
1579
|
+
const current = this.sessionStateRepository.findBySessionAndUser(sessionId, userId);
|
|
1580
|
+
if (!current || !isPendingSessionRunningState(current.runningState)) {
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
this.sessionStateRepository.upsert({
|
|
1584
|
+
...current,
|
|
1585
|
+
runningState: "interrupted",
|
|
1586
|
+
activitySource: "runtime",
|
|
1587
|
+
completedAt: timestamp,
|
|
1588
|
+
updatedAt: timestamp
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
this.clearExternalRuntimeSnapshot(sessionId);
|
|
1592
|
+
this.upsertSnapshot(sessionId, {
|
|
1593
|
+
syncStatus: "idle",
|
|
1594
|
+
syncCursor: currentSnapshot?.syncCursor ?? null,
|
|
1595
|
+
lastSyncAt: timestamp,
|
|
1596
|
+
lastErrorCode: null,
|
|
1597
|
+
lastErrorDetail: null,
|
|
1598
|
+
resumedAt: currentSnapshot?.resumedAt ?? null
|
|
1599
|
+
});
|
|
1600
|
+
this.sessionActivityAuthorityService.observe({
|
|
1601
|
+
sessionId,
|
|
1602
|
+
runId: null,
|
|
1603
|
+
runningState: "interrupted",
|
|
1604
|
+
source: "authoritative_runtime",
|
|
1605
|
+
confidence: "strong",
|
|
1606
|
+
detail: "检测到会话实际已停止,已自动修正残留运行状态",
|
|
1607
|
+
interruptSource: "runtime",
|
|
1608
|
+
errorCode: null,
|
|
1609
|
+
observedAt: timestamp
|
|
1610
|
+
});
|
|
1611
|
+
await this.emitExternalRuntimeEnvelope({
|
|
1612
|
+
type: "session.runtime_status",
|
|
1613
|
+
sessionId,
|
|
1614
|
+
status: "interrupted",
|
|
1615
|
+
detail: "检测到会话实际已停止,已自动修正残留运行状态",
|
|
1616
|
+
interruptSource: "runtime",
|
|
1617
|
+
timestamp
|
|
1618
|
+
});
|
|
1619
|
+
await this.emitTerminalStateEvent({
|
|
1620
|
+
sessionId,
|
|
1621
|
+
status: "interrupted",
|
|
1622
|
+
timestamp,
|
|
1623
|
+
detail: "检测到会话实际已停止,已自动修正残留运行状态",
|
|
1624
|
+
source: "runtime"
|
|
1625
|
+
});
|
|
1626
|
+
void this.dispatchNextQueuedMessage(sessionId);
|
|
1627
|
+
}
|
|
1485
1628
|
beginPendingSendDebugTrace(input) {
|
|
1486
1629
|
if (!isPerfDebugEnabled()) {
|
|
1487
1630
|
return null;
|
|
@@ -1764,6 +1907,39 @@ export class SessionLiveRuntimeService {
|
|
|
1764
1907
|
clearExternalRuntimeSnapshot(sessionId) {
|
|
1765
1908
|
this.externalRuntimeSnapshots.delete(sessionId);
|
|
1766
1909
|
}
|
|
1910
|
+
getFreshExternalRuntimeSnapshot(sessionId) {
|
|
1911
|
+
const snapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
|
|
1912
|
+
if (!snapshot) {
|
|
1913
|
+
return null;
|
|
1914
|
+
}
|
|
1915
|
+
if (!isExternalRuntimeSnapshotExpired(snapshot)) {
|
|
1916
|
+
return snapshot;
|
|
1917
|
+
}
|
|
1918
|
+
this.clearExternalRuntimeSnapshot(sessionId);
|
|
1919
|
+
this.sessionActivityAuthorityService.clearSession(sessionId);
|
|
1920
|
+
return null;
|
|
1921
|
+
}
|
|
1922
|
+
suppressInterruptedExternalRuntime(sessionId) {
|
|
1923
|
+
this.externalRuntimeInterruptSuppressions.set(sessionId, Date.now() + EXTERNAL_RUNTIME_INTERRUPT_SUPPRESSION_MS);
|
|
1924
|
+
}
|
|
1925
|
+
clearExternalRuntimeInterruptSuppression(sessionId) {
|
|
1926
|
+
this.externalRuntimeInterruptSuppressions.delete(sessionId);
|
|
1927
|
+
}
|
|
1928
|
+
shouldIgnoreInterruptedExternalRuntime(sessionId) {
|
|
1929
|
+
const expiresAt = this.externalRuntimeInterruptSuppressions.get(sessionId);
|
|
1930
|
+
if (!expiresAt) {
|
|
1931
|
+
return false;
|
|
1932
|
+
}
|
|
1933
|
+
if (Date.now() >= expiresAt) {
|
|
1934
|
+
this.externalRuntimeInterruptSuppressions.delete(sessionId);
|
|
1935
|
+
return false;
|
|
1936
|
+
}
|
|
1937
|
+
return true;
|
|
1938
|
+
}
|
|
1939
|
+
async forceInterruptExternalSession(sessionId) {
|
|
1940
|
+
this.suppressInterruptedExternalRuntime(sessionId);
|
|
1941
|
+
await this.forceInterruptInactiveSession(sessionId);
|
|
1942
|
+
}
|
|
1767
1943
|
async resolveActiveClaudePermissionSession(input) {
|
|
1768
1944
|
const activeSnapshots = this.providerRuntimeService
|
|
1769
1945
|
.listSnapshots()
|
|
@@ -1835,6 +2011,13 @@ function createExternalRuntimeActivityObservation(sessionId, snapshot) {
|
|
|
1835
2011
|
observedAt: snapshot.updatedAt
|
|
1836
2012
|
};
|
|
1837
2013
|
}
|
|
2014
|
+
function isExternalRuntimeSnapshotExpired(snapshot) {
|
|
2015
|
+
const updatedAtMs = Date.parse(snapshot.updatedAt);
|
|
2016
|
+
if (!Number.isFinite(updatedAtMs)) {
|
|
2017
|
+
return true;
|
|
2018
|
+
}
|
|
2019
|
+
return Date.now() - updatedAtMs > EXTERNAL_RUNTIME_SNAPSHOT_MAX_AGE_MS;
|
|
2020
|
+
}
|
|
1838
2021
|
function createRuntimeEventObservation(sessionId, event, startedAt) {
|
|
1839
2022
|
return {
|
|
1840
2023
|
sessionId,
|