@adhdev/daemon-core 0.6.79 → 0.7.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/index.d.mts +84 -87
- package/dist/index.d.ts +84 -87
- package/dist/index.js +798 -706
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +797 -702
- package/dist/index.mjs.map +1 -1
- package/dist/{normalize-igHDb198.d.mts → normalize-S2PmiRgB.d.mts} +32 -53
- package/dist/{normalize-igHDb198.d.ts → normalize-S2PmiRgB.d.ts} +32 -53
- package/dist/status/normalize.d.mts +1 -1
- package/dist/status/normalize.d.ts +1 -1
- package/package.json +1 -1
- package/src/agent-stream/manager.ts +203 -180
- package/src/agent-stream/poller.ts +45 -22
- package/src/boot/daemon-lifecycle.ts +28 -9
- package/src/cdp/initializer.ts +47 -0
- package/src/cdp/manager.ts +19 -1
- package/src/cdp/setup.ts +26 -11
- package/src/commands/chat-commands.ts +136 -88
- package/src/commands/cli-manager.ts +31 -6
- package/src/commands/handler.ts +69 -138
- package/src/commands/router.ts +4 -20
- package/src/commands/stream-commands.ts +34 -162
- package/src/daemon-core.ts +3 -9
- package/src/index.ts +6 -5
- package/src/logging/command-log.ts +1 -1
- package/src/providers/acp-provider-instance.ts +4 -0
- package/src/providers/provider-instance-manager.ts +1 -0
- package/src/sessions/registry.ts +76 -0
- package/src/shared-types.ts +45 -54
- package/src/status/builders.ts +156 -120
- package/src/status/reporter.ts +16 -15
- package/src/status/snapshot.ts +3 -11
|
@@ -15,6 +15,7 @@ import type { DaemonAgentStreamManager } from './manager.js';
|
|
|
15
15
|
import type { ProviderLoader } from '../providers/provider-loader.js';
|
|
16
16
|
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
17
17
|
import { registerExtensionProviders } from '../cdp/setup.js';
|
|
18
|
+
import type { SessionRegistry } from '../sessions/registry.js';
|
|
18
19
|
import { LOG } from '../logging/logger.js';
|
|
19
20
|
import type { AgentStreamState } from './types.js';
|
|
20
21
|
|
|
@@ -25,6 +26,7 @@ export interface AgentStreamPollerDeps {
|
|
|
25
26
|
providerLoader: ProviderLoader;
|
|
26
27
|
instanceManager: ProviderInstanceManager;
|
|
27
28
|
cdpManagers: Map<string, DaemonCdpManager>;
|
|
29
|
+
sessionRegistry: SessionRegistry;
|
|
28
30
|
/** Callback when agent streams are updated */
|
|
29
31
|
onStreamsUpdated?: (ideType: string, streams: AgentStreamState[]) => void;
|
|
30
32
|
}
|
|
@@ -43,8 +45,8 @@ export class AgentStreamPoller {
|
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/** Reset active IDE tracking (e.g., when IDE is stopped) */
|
|
46
|
-
resetActiveIde(
|
|
47
|
-
this.deps.agentStreamManager.
|
|
48
|
+
resetActiveIde(parentSessionId: string): void {
|
|
49
|
+
this.deps.agentStreamManager.resetParentSession(parentSessionId);
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
/** Start polling (idempotent — ignored if already started) */
|
|
@@ -71,6 +73,7 @@ export class AgentStreamPoller {
|
|
|
71
73
|
providerLoader,
|
|
72
74
|
instanceManager,
|
|
73
75
|
cdpManagers,
|
|
76
|
+
sessionRegistry,
|
|
74
77
|
} = this.deps;
|
|
75
78
|
|
|
76
79
|
if (!agentStreamManager || cdpManagers.size === 0) return;
|
|
@@ -82,6 +85,7 @@ export class AgentStreamPoller {
|
|
|
82
85
|
|
|
83
86
|
// 1b. Dynamically add/remove IDE instance extensions
|
|
84
87
|
const ideInstance = instanceManager.getInstance(`ide:${ideType}`) as any;
|
|
88
|
+
const parentSessionId = ideInstance?.getInstanceId?.();
|
|
85
89
|
if (ideInstance?.getExtensionTypes && ideInstance?.addExtension && ideInstance?.removeExtension) {
|
|
86
90
|
const currentExtTypes = new Set(ideInstance.getExtensionTypes() as string[]);
|
|
87
91
|
const enabledExtTypes = new Set(
|
|
@@ -91,6 +95,10 @@ export class AgentStreamPoller {
|
|
|
91
95
|
// Remove disabled extensions
|
|
92
96
|
for (const extType of currentExtTypes) {
|
|
93
97
|
if (!enabledExtTypes.has(extType)) {
|
|
98
|
+
const extInstance = ideInstance.getExtension?.(extType);
|
|
99
|
+
if (extInstance?.getInstanceId) {
|
|
100
|
+
sessionRegistry.unregister(extInstance.getInstanceId());
|
|
101
|
+
}
|
|
94
102
|
ideInstance.removeExtension(extType);
|
|
95
103
|
LOG.info('AgentStream', `Extension removed: ${extType} (disabled for ${ideType})`);
|
|
96
104
|
}
|
|
@@ -103,6 +111,18 @@ export class AgentStreamPoller {
|
|
|
103
111
|
if (extProvider) {
|
|
104
112
|
const extSettings = providerLoader.getSettings(extType);
|
|
105
113
|
ideInstance.addExtension(extProvider, extSettings);
|
|
114
|
+
const extInstance = ideInstance.getExtension?.(extType);
|
|
115
|
+
if (parentSessionId && extInstance?.getInstanceId) {
|
|
116
|
+
sessionRegistry.register({
|
|
117
|
+
sessionId: extInstance.getInstanceId(),
|
|
118
|
+
parentSessionId,
|
|
119
|
+
providerType: extType,
|
|
120
|
+
providerCategory: 'extension',
|
|
121
|
+
transport: 'cdp-webview',
|
|
122
|
+
cdpManagerKey: ideType,
|
|
123
|
+
instanceKey: `ide:${ideType}`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
106
126
|
LOG.info('AgentStream', `Extension added: ${extType} (enabled for ${ideType})`);
|
|
107
127
|
}
|
|
108
128
|
}
|
|
@@ -110,47 +130,50 @@ export class AgentStreamPoller {
|
|
|
110
130
|
}
|
|
111
131
|
|
|
112
132
|
// 1c. If the active agent stream belongs to a now-disabled extension, detach it
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
await agentStreamManager.switchActiveAgent(cdp, ideType, null);
|
|
133
|
+
const activeSessionId = parentSessionId ? agentStreamManager.getActiveSessionId(parentSessionId) : null;
|
|
134
|
+
if (activeSessionId) {
|
|
135
|
+
const activeTarget = sessionRegistry.get(activeSessionId);
|
|
136
|
+
const enabledExtTypes = new Set(providerLoader.getEnabledExtensionProviders(ideType).map((p: any) => p.type));
|
|
137
|
+
if (!activeTarget || !enabledExtTypes.has(activeTarget.providerType)) {
|
|
138
|
+
LOG.info('AgentStream', `Active agent ${activeTarget?.providerType || activeSessionId} was disabled for ${ideType} — detaching`);
|
|
139
|
+
await agentStreamManager.setActiveSession(cdp, parentSessionId!, null);
|
|
121
140
|
// Report empty streams so dashboard removes the tab
|
|
122
141
|
this.deps.onStreamsUpdated?.(ideType, []);
|
|
123
142
|
}
|
|
124
143
|
}
|
|
125
144
|
if (!cdp.isConnected) {
|
|
126
|
-
if (
|
|
127
|
-
agentStreamManager.
|
|
145
|
+
if (parentSessionId && activeSessionId) {
|
|
146
|
+
agentStreamManager.resetParentSession(parentSessionId);
|
|
128
147
|
this.deps.onStreamsUpdated?.(ideType, []);
|
|
129
148
|
}
|
|
130
149
|
continue;
|
|
131
150
|
}
|
|
132
151
|
|
|
133
152
|
// ─── Phase 2: Agent session sync + collect ───
|
|
134
|
-
let
|
|
153
|
+
let resolvedActiveSessionId = activeSessionId;
|
|
135
154
|
|
|
136
155
|
// ─── Phase 3: Auto-discover agents ───
|
|
137
|
-
if (!
|
|
156
|
+
if (!resolvedActiveSessionId && parentSessionId) {
|
|
138
157
|
try {
|
|
139
158
|
const discovered = await cdp.discoverAgentWebviews();
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
159
|
+
for (const target of discovered) {
|
|
160
|
+
const sessionId = agentStreamManager.resolveSessionForAgent(parentSessionId, target.agentType);
|
|
161
|
+
if (sessionId) {
|
|
162
|
+
resolvedActiveSessionId = sessionId;
|
|
163
|
+
await agentStreamManager.setActiveSession(cdp, parentSessionId, sessionId);
|
|
164
|
+
LOG.info('AgentStream', `Auto-activated: ${target.agentType} (${ideType})`);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
144
167
|
}
|
|
145
168
|
} catch { }
|
|
146
169
|
}
|
|
147
170
|
|
|
148
|
-
if (!
|
|
171
|
+
if (!resolvedActiveSessionId || !parentSessionId) continue;
|
|
149
172
|
|
|
150
173
|
try {
|
|
151
|
-
await agentStreamManager.
|
|
152
|
-
const
|
|
153
|
-
this.deps.onStreamsUpdated?.(ideType,
|
|
174
|
+
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
175
|
+
const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
176
|
+
this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
|
|
154
177
|
} catch { }
|
|
155
178
|
}
|
|
156
179
|
}
|
|
@@ -20,6 +20,7 @@ import { VersionArchive, detectAllVersions } from '../providers/version-archive.
|
|
|
20
20
|
import { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
21
21
|
import { DevServer } from '../daemon/dev-server.js';
|
|
22
22
|
import { detectIDEs } from '../detection/ide-detector.js';
|
|
23
|
+
import { SessionRegistry } from '../sessions/registry.js';
|
|
23
24
|
import { installGlobalInterceptor, LOG } from '../logging/logger.js';
|
|
24
25
|
import { loadConfig } from '../config/config.js';
|
|
25
26
|
|
|
@@ -70,7 +71,7 @@ export interface DaemonComponents {
|
|
|
70
71
|
poller: AgentStreamPoller;
|
|
71
72
|
cdpInitializer: DaemonCdpInitializer;
|
|
72
73
|
cdpManagers: Map<string, DaemonCdpManager>;
|
|
73
|
-
|
|
74
|
+
sessionRegistry: SessionRegistry;
|
|
74
75
|
detectedIdes: { value: any[] };
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -141,13 +142,16 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
141
142
|
// 3. Shared state
|
|
142
143
|
const instanceManager = new ProviderInstanceManager();
|
|
143
144
|
const cdpManagers = new Map<string, DaemonCdpManager>();
|
|
144
|
-
const
|
|
145
|
+
const sessionRegistry = new SessionRegistry();
|
|
145
146
|
const detectedIdesRef = { value: [] as any[] };
|
|
147
|
+
let agentStreamManager: DaemonAgentStreamManager | null = null;
|
|
148
|
+
let poller: AgentStreamPoller | null = null;
|
|
146
149
|
|
|
147
150
|
// 4. CLI Manager
|
|
148
151
|
const cliManager = new DaemonCliManager({
|
|
149
152
|
...config.cliManagerDeps,
|
|
150
153
|
getInstanceManager: () => instanceManager,
|
|
154
|
+
getSessionRegistry: () => sessionRegistry,
|
|
151
155
|
}, providerLoader);
|
|
152
156
|
|
|
153
157
|
// 5. Detect IDEs
|
|
@@ -161,7 +165,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
161
165
|
providerLoader,
|
|
162
166
|
instanceManager,
|
|
163
167
|
cdpManagers,
|
|
164
|
-
|
|
168
|
+
sessionRegistry,
|
|
165
169
|
};
|
|
166
170
|
|
|
167
171
|
const cdpInitializer = new DaemonCdpInitializer({
|
|
@@ -174,6 +178,21 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
174
178
|
// Transport-specific extras
|
|
175
179
|
await config.onCdpManagerSetup?.(ideType, manager, managerKey);
|
|
176
180
|
},
|
|
181
|
+
onDisconnected: async (_ideType, _manager, managerKey) => {
|
|
182
|
+
sessionRegistry.unregisterByManagerKey(managerKey);
|
|
183
|
+
const instanceKey = `ide:${managerKey}`;
|
|
184
|
+
const ideInstance = instanceManager.getInstance(instanceKey) as any;
|
|
185
|
+
|
|
186
|
+
if (ideInstance) {
|
|
187
|
+
instanceManager.removeInstance(instanceKey);
|
|
188
|
+
LOG.info('CDP', `Instance removed after disconnect: ${instanceKey}`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (ideInstance?.getInstanceId) {
|
|
192
|
+
agentStreamManager?.resetParentSession(ideInstance.getInstanceId());
|
|
193
|
+
}
|
|
194
|
+
config.onStatusChange?.();
|
|
195
|
+
},
|
|
177
196
|
});
|
|
178
197
|
await cdpInitializer.connectAll(detectedIdesRef.value);
|
|
179
198
|
cdpInitializer.startPeriodicScan(config.cdpScanIntervalMs ?? 30_000);
|
|
@@ -186,20 +205,19 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
186
205
|
adapters: cliManager.adapters,
|
|
187
206
|
providerLoader,
|
|
188
207
|
instanceManager,
|
|
189
|
-
|
|
208
|
+
sessionRegistry,
|
|
190
209
|
});
|
|
191
210
|
|
|
192
211
|
// 8. AgentStreamManager
|
|
193
|
-
|
|
212
|
+
agentStreamManager = new DaemonAgentStreamManager(
|
|
194
213
|
LOG.forComponent('AgentStream').asLogFn(),
|
|
195
214
|
providerLoader,
|
|
215
|
+
sessionRegistry,
|
|
196
216
|
);
|
|
197
217
|
commandHandler.setAgentStreamManager(agentStreamManager);
|
|
198
218
|
|
|
199
219
|
// 9. Router + Poller (with internal cross-wiring)
|
|
200
220
|
// Note: poller is declared first so router's onIdeConnected closure captures it
|
|
201
|
-
let poller: AgentStreamPoller;
|
|
202
|
-
|
|
203
221
|
const router = new DaemonCommandRouter({
|
|
204
222
|
commandHandler,
|
|
205
223
|
cliManager,
|
|
@@ -207,7 +225,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
207
225
|
providerLoader,
|
|
208
226
|
instanceManager,
|
|
209
227
|
detectedIdes: detectedIdesRef,
|
|
210
|
-
|
|
228
|
+
sessionRegistry,
|
|
211
229
|
onCdpManagerCreated: async (ideType: string, manager: DaemonCdpManager) => {
|
|
212
230
|
// For launch_ide: register instance + extension providers
|
|
213
231
|
await setupIdeInstance(cdpSetupContext, { ideType, manager });
|
|
@@ -224,6 +242,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
224
242
|
providerLoader,
|
|
225
243
|
instanceManager,
|
|
226
244
|
cdpManagers,
|
|
245
|
+
sessionRegistry,
|
|
227
246
|
onStreamsUpdated: config.onStreamsUpdated,
|
|
228
247
|
});
|
|
229
248
|
poller.start();
|
|
@@ -241,7 +260,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
241
260
|
poller,
|
|
242
261
|
cdpInitializer,
|
|
243
262
|
cdpManagers,
|
|
244
|
-
|
|
263
|
+
sessionRegistry,
|
|
245
264
|
detectedIdes: detectedIdesRef,
|
|
246
265
|
};
|
|
247
266
|
}
|
package/src/cdp/initializer.ts
CHANGED
|
@@ -24,6 +24,13 @@ export interface CdpInitializerConfig {
|
|
|
24
24
|
enabledIdes?: string[];
|
|
25
25
|
/** Callback when a new CDP manager is connected */
|
|
26
26
|
onConnected?: (ideType: string, manager: DaemonCdpManager, managerKey: string) => void | Promise<void>;
|
|
27
|
+
/** Callback when a stale/disconnected CDP manager is removed */
|
|
28
|
+
onDisconnected?: (
|
|
29
|
+
ideType: string,
|
|
30
|
+
manager: DaemonCdpManager,
|
|
31
|
+
managerKey: string,
|
|
32
|
+
reason: 'ide_closed' | 'target_closed' | 'target_rekeyed',
|
|
33
|
+
) => void | Promise<void>;
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
export class DaemonCdpInitializer {
|
|
@@ -88,6 +95,7 @@ export class DaemonCdpInitializer {
|
|
|
88
95
|
|
|
89
96
|
// 1. Try multi-window: list all workbench pages on this port
|
|
90
97
|
const targets = await DaemonCdpManager.listAllTargets(port);
|
|
98
|
+
await this.pruneStaleManagers(port, ide, targets);
|
|
91
99
|
|
|
92
100
|
if (targets.length === 0) {
|
|
93
101
|
// Prevent duplicate fallback connection
|
|
@@ -153,6 +161,45 @@ export class DaemonCdpInitializer {
|
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
164
|
+
private async pruneStaleManagers(
|
|
165
|
+
port: number,
|
|
166
|
+
ide: string,
|
|
167
|
+
targets: Array<{ id: string }>,
|
|
168
|
+
): Promise<void> {
|
|
169
|
+
const trackedTargetIds = new Set(targets.map((target) => target.id));
|
|
170
|
+
const removals: Array<{
|
|
171
|
+
key: string;
|
|
172
|
+
manager: DaemonCdpManager;
|
|
173
|
+
reason: 'ide_closed' | 'target_closed' | 'target_rekeyed';
|
|
174
|
+
}> = [];
|
|
175
|
+
|
|
176
|
+
for (const [key, manager] of this.config.cdpManagers.entries()) {
|
|
177
|
+
if (!(key === ide || key.startsWith(`${ide}_`))) continue;
|
|
178
|
+
if (manager.getPort() !== port) continue;
|
|
179
|
+
|
|
180
|
+
if (targets.length === 0) {
|
|
181
|
+
removals.push({ key, manager, reason: 'ide_closed' });
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (manager.targetId && !trackedTargetIds.has(manager.targetId)) {
|
|
186
|
+
removals.push({ key, manager, reason: 'target_closed' });
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (key === ide && !manager.targetId && targets.length > 1) {
|
|
191
|
+
removals.push({ key, manager, reason: 'target_rekeyed' });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for (const { key, manager, reason } of removals) {
|
|
196
|
+
try { manager.disconnect(); } catch { /* noop */ }
|
|
197
|
+
this.config.cdpManagers.delete(key);
|
|
198
|
+
LOG.info('CDP', `Removed stale manager: ${key} (${reason})`);
|
|
199
|
+
await this.config.onDisconnected?.(ide, manager, key, reason);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
156
203
|
// ─── Periodic scanning ───
|
|
157
204
|
|
|
158
205
|
/**
|
package/src/cdp/manager.ts
CHANGED
|
@@ -828,7 +828,10 @@ export class DaemonCdpManager {
|
|
|
828
828
|
async attachToAgent(target: AgentWebviewTarget): Promise<string | null> {
|
|
829
829
|
if (!this.isConnected) return null;
|
|
830
830
|
for (const [sid, t] of this.agentSessions) {
|
|
831
|
-
if (t.
|
|
831
|
+
if (t.targetId === target.targetId) return sid;
|
|
832
|
+
if (t.agentType === target.agentType && t.targetId !== target.targetId) {
|
|
833
|
+
await this.detachAgent(sid).catch(() => { });
|
|
834
|
+
}
|
|
832
835
|
}
|
|
833
836
|
try {
|
|
834
837
|
// Attach via Browser WS (iframes can only be attached from browser-level)
|
|
@@ -971,6 +974,21 @@ export class DaemonCdpManager {
|
|
|
971
974
|
|
|
972
975
|
private async getCurrentPageWebviewUrls(): Promise<Set<string>> {
|
|
973
976
|
if (!this.isConnected) return new Set();
|
|
977
|
+
|
|
978
|
+
try {
|
|
979
|
+
const urls = new Set<string>();
|
|
980
|
+
const { frameTree } = await this.sendInternal('Page.getFrameTree', {}, 5000);
|
|
981
|
+
const visit = (node: any) => {
|
|
982
|
+
const url = node?.frame?.url;
|
|
983
|
+
if (typeof url === 'string' && url.includes('vscode-webview')) {
|
|
984
|
+
urls.add(url);
|
|
985
|
+
}
|
|
986
|
+
for (const child of node?.childFrames || []) visit(child);
|
|
987
|
+
};
|
|
988
|
+
if (frameTree) visit(frameTree);
|
|
989
|
+
if (urls.size > 0) return urls;
|
|
990
|
+
} catch { /* fall through to DOM scan */ }
|
|
991
|
+
|
|
974
992
|
try {
|
|
975
993
|
const raw = await this.evaluate(
|
|
976
994
|
`JSON.stringify(Array.from(document.querySelectorAll('iframe,webview'))
|
package/src/cdp/setup.ts
CHANGED
|
@@ -9,14 +9,13 @@ import { DaemonCdpManager } from './manager.js';
|
|
|
9
9
|
import { ProviderLoader } from '../providers/provider-loader.js';
|
|
10
10
|
import { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
11
11
|
import { IdeProviderInstance } from '../providers/ide-provider-instance.js';
|
|
12
|
-
import
|
|
12
|
+
import { SessionRegistry } from '../sessions/registry.js';
|
|
13
13
|
|
|
14
14
|
export interface CdpSetupContext {
|
|
15
15
|
providerLoader: ProviderLoader;
|
|
16
16
|
instanceManager: ProviderInstanceManager;
|
|
17
17
|
cdpManagers: Map<string, DaemonCdpManager>;
|
|
18
|
-
|
|
19
|
-
instanceIdMap: Map<string, string>;
|
|
18
|
+
sessionRegistry: SessionRegistry;
|
|
20
19
|
/** Server connection (optional) */
|
|
21
20
|
serverConn?: any;
|
|
22
21
|
}
|
|
@@ -58,7 +57,7 @@ export function registerExtensionProviders(
|
|
|
58
57
|
* 2. Create IdeProviderInstance
|
|
59
58
|
* 3. Register in InstanceManager
|
|
60
59
|
* 4. Register enabled extensions
|
|
61
|
-
* 5.
|
|
60
|
+
* 5. Register runtime sessions (workspace + extension children)
|
|
62
61
|
*
|
|
63
62
|
* @returns The created IdeProviderInstance, or null if provider not found
|
|
64
63
|
*/
|
|
@@ -66,7 +65,7 @@ export async function setupIdeInstance(
|
|
|
66
65
|
ctx: CdpSetupContext,
|
|
67
66
|
opts: SetupIdeInstanceOptions,
|
|
68
67
|
): Promise<IdeProviderInstance | null> {
|
|
69
|
-
const { providerLoader, instanceManager,
|
|
68
|
+
const { providerLoader, instanceManager, sessionRegistry } = ctx;
|
|
70
69
|
const { ideType, manager, settings } = opts;
|
|
71
70
|
const managerKey = opts.managerKey || ideType;
|
|
72
71
|
|
|
@@ -91,18 +90,34 @@ export async function setupIdeInstance(
|
|
|
91
90
|
settings: resolvedSettings,
|
|
92
91
|
});
|
|
93
92
|
|
|
94
|
-
// 5.
|
|
95
|
-
|
|
93
|
+
// 5. Register workspace session
|
|
94
|
+
sessionRegistry.register({
|
|
95
|
+
sessionId: ideInstance.getInstanceId(),
|
|
96
|
+
parentSessionId: null,
|
|
97
|
+
providerType: ideType,
|
|
98
|
+
providerCategory: 'ide',
|
|
99
|
+
transport: 'cdp-page',
|
|
100
|
+
cdpManagerKey: managerKey,
|
|
101
|
+
instanceKey: `ide:${managerKey}`,
|
|
102
|
+
});
|
|
96
103
|
|
|
97
104
|
// 6. Register enabled extensions
|
|
98
105
|
const extensionProviders = providerLoader.getEnabledByCategory('extension', ideType);
|
|
99
106
|
for (const extProvider of extensionProviders) {
|
|
100
107
|
const extSettings = providerLoader.getSettings(extProvider.type);
|
|
101
108
|
await ideInstance.addExtension(extProvider, extSettings);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const ext of ideInstance.getExtensionInstances()) {
|
|
112
|
+
sessionRegistry.register({
|
|
113
|
+
sessionId: ext.getInstanceId(),
|
|
114
|
+
parentSessionId: ideInstance.getInstanceId(),
|
|
115
|
+
providerType: ext.type,
|
|
116
|
+
providerCategory: 'extension',
|
|
117
|
+
transport: 'cdp-webview',
|
|
118
|
+
cdpManagerKey: managerKey,
|
|
119
|
+
instanceKey: `ide:${managerKey}`,
|
|
120
|
+
});
|
|
106
121
|
}
|
|
107
122
|
|
|
108
123
|
return ideInstance;
|