@pooder/core 2.0.0 → 2.2.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/CHANGELOG.md +12 -0
- package/dist/index.d.mts +196 -21
- package/dist/index.d.ts +196 -21
- package/dist/index.js +718 -157
- package/dist/index.mjs +707 -156
- package/package.json +1 -1
- package/src/command.ts +10 -10
- package/src/context.ts +22 -17
- package/src/contribution/index.ts +12 -12
- package/src/contribution/points.ts +27 -3
- package/src/contribution/registry.ts +118 -118
- package/src/disposable.ts +3 -3
- package/src/extension.ts +177 -164
- package/src/index.ts +338 -145
- package/src/run-test-full.ts +98 -98
- package/src/service.ts +191 -11
- package/src/services/CommandService.ts +79 -79
- package/src/services/ConfigurationService.ts +107 -107
- package/src/services/ToolRegistryService.ts +41 -0
- package/src/services/ToolSessionService.ts +213 -0
- package/src/services/WorkbenchService.ts +187 -8
- package/src/services/index.ts +23 -1
- package/src/services/tokens.ts +27 -0
- package/src/test-extension-full.ts +79 -79
package/dist/index.js
CHANGED
|
@@ -20,6 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
COMMAND_SERVICE: () => COMMAND_SERVICE,
|
|
24
|
+
CONFIGURATION_SERVICE: () => CONFIGURATION_SERVICE,
|
|
25
|
+
CORE_SERVICE_TOKENS: () => CORE_SERVICE_TOKENS,
|
|
23
26
|
CommandService: () => CommandService,
|
|
24
27
|
ConfigurationService: () => ConfigurationService,
|
|
25
28
|
ContributionPointIds: () => ContributionPointIds,
|
|
@@ -29,27 +32,122 @@ __export(index_exports, {
|
|
|
29
32
|
ExtensionRegistry: () => ExtensionRegistry,
|
|
30
33
|
Pooder: () => Pooder,
|
|
31
34
|
ServiceRegistry: () => ServiceRegistry,
|
|
32
|
-
|
|
35
|
+
TOOL_REGISTRY_SERVICE: () => TOOL_REGISTRY_SERVICE,
|
|
36
|
+
TOOL_SESSION_SERVICE: () => TOOL_SESSION_SERVICE,
|
|
37
|
+
ToolRegistryService: () => ToolRegistryService,
|
|
38
|
+
ToolSessionService: () => ToolSessionService,
|
|
39
|
+
WORKBENCH_SERVICE: () => WORKBENCH_SERVICE,
|
|
40
|
+
WorkbenchService: () => WorkbenchService,
|
|
41
|
+
createServiceToken: () => createServiceToken,
|
|
42
|
+
isServiceToken: () => isServiceToken
|
|
33
43
|
});
|
|
34
44
|
module.exports = __toCommonJS(index_exports);
|
|
35
45
|
|
|
36
46
|
// src/service.ts
|
|
47
|
+
function createServiceToken(name) {
|
|
48
|
+
if (!name) {
|
|
49
|
+
throw new Error("Service token name is required.");
|
|
50
|
+
}
|
|
51
|
+
return Object.freeze({
|
|
52
|
+
kind: "service-token",
|
|
53
|
+
key: Symbol(name),
|
|
54
|
+
name
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function isServiceToken(identifier) {
|
|
58
|
+
return typeof identifier === "object" && identifier !== null && "kind" in identifier && identifier.kind === "service-token";
|
|
59
|
+
}
|
|
37
60
|
var ServiceRegistry = class {
|
|
38
61
|
constructor() {
|
|
39
|
-
this.
|
|
62
|
+
this.servicesByName = /* @__PURE__ */ new Map();
|
|
63
|
+
this.servicesByToken = /* @__PURE__ */ new Map();
|
|
64
|
+
this.registrationOrder = [];
|
|
40
65
|
}
|
|
41
|
-
register(
|
|
42
|
-
this.
|
|
66
|
+
register(identifier, service, options = {}) {
|
|
67
|
+
const normalized = this.normalizeIdentifier(identifier);
|
|
68
|
+
const existing = this.findEntry(normalized);
|
|
69
|
+
if (existing && !options.allowOverride) {
|
|
70
|
+
throw new Error(`Service "${normalized.name}" is already registered.`);
|
|
71
|
+
}
|
|
72
|
+
if (existing) {
|
|
73
|
+
this.removeEntry(existing);
|
|
74
|
+
}
|
|
75
|
+
const entry = {
|
|
76
|
+
token: normalized.token,
|
|
77
|
+
name: normalized.name,
|
|
78
|
+
service
|
|
79
|
+
};
|
|
80
|
+
this.servicesByName.set(entry.name, entry);
|
|
81
|
+
if (entry.token) {
|
|
82
|
+
this.servicesByToken.set(entry.token.key, entry);
|
|
83
|
+
}
|
|
84
|
+
this.registrationOrder.push(entry);
|
|
43
85
|
return service;
|
|
44
86
|
}
|
|
45
|
-
get(
|
|
46
|
-
|
|
87
|
+
get(identifier) {
|
|
88
|
+
const normalized = this.normalizeIdentifier(identifier);
|
|
89
|
+
const entry = this.findEntry(normalized);
|
|
90
|
+
return entry == null ? void 0 : entry.service;
|
|
91
|
+
}
|
|
92
|
+
getOrThrow(identifier, errorMessage) {
|
|
93
|
+
const service = this.get(identifier);
|
|
94
|
+
if (service) {
|
|
95
|
+
return service;
|
|
96
|
+
}
|
|
97
|
+
const normalized = this.normalizeIdentifier(identifier);
|
|
98
|
+
throw new Error(errorMessage != null ? errorMessage : `Service "${normalized.name}" not found.`);
|
|
47
99
|
}
|
|
48
|
-
has(
|
|
49
|
-
|
|
100
|
+
has(identifier) {
|
|
101
|
+
const normalized = this.normalizeIdentifier(identifier);
|
|
102
|
+
return Boolean(this.findEntry(normalized));
|
|
50
103
|
}
|
|
51
|
-
delete(
|
|
52
|
-
this.
|
|
104
|
+
delete(identifier) {
|
|
105
|
+
const normalized = this.normalizeIdentifier(identifier);
|
|
106
|
+
const entry = this.findEntry(normalized);
|
|
107
|
+
if (!entry) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
this.removeEntry(entry);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
list() {
|
|
114
|
+
return this.registrationOrder.map((entry) => ({
|
|
115
|
+
id: entry.name,
|
|
116
|
+
token: entry.token,
|
|
117
|
+
service: entry.service
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
clear() {
|
|
121
|
+
this.servicesByName.clear();
|
|
122
|
+
this.servicesByToken.clear();
|
|
123
|
+
this.registrationOrder.length = 0;
|
|
124
|
+
}
|
|
125
|
+
findEntry(identifier) {
|
|
126
|
+
var _a;
|
|
127
|
+
if (identifier.token) {
|
|
128
|
+
return (_a = this.servicesByToken.get(identifier.token.key)) != null ? _a : this.servicesByName.get(identifier.name);
|
|
129
|
+
}
|
|
130
|
+
return this.servicesByName.get(identifier.name);
|
|
131
|
+
}
|
|
132
|
+
normalizeIdentifier(identifier) {
|
|
133
|
+
if (isServiceToken(identifier)) {
|
|
134
|
+
return { token: identifier, name: identifier.name };
|
|
135
|
+
}
|
|
136
|
+
const name = identifier.trim();
|
|
137
|
+
if (!name) {
|
|
138
|
+
throw new Error("Service identifier must be a non-empty string.");
|
|
139
|
+
}
|
|
140
|
+
return { name };
|
|
141
|
+
}
|
|
142
|
+
removeEntry(entry) {
|
|
143
|
+
this.servicesByName.delete(entry.name);
|
|
144
|
+
if (entry.token) {
|
|
145
|
+
this.servicesByToken.delete(entry.token.key);
|
|
146
|
+
}
|
|
147
|
+
const index = this.registrationOrder.lastIndexOf(entry);
|
|
148
|
+
if (index >= 0) {
|
|
149
|
+
this.registrationOrder.splice(index, 1);
|
|
150
|
+
}
|
|
53
151
|
}
|
|
54
152
|
};
|
|
55
153
|
|
|
@@ -207,122 +305,6 @@ var ContributionRegistry = class {
|
|
|
207
305
|
}
|
|
208
306
|
};
|
|
209
307
|
|
|
210
|
-
// src/extension.ts
|
|
211
|
-
var ExtensionRegistry = class extends Map {
|
|
212
|
-
};
|
|
213
|
-
var ExtensionManager = class {
|
|
214
|
-
constructor(context) {
|
|
215
|
-
this.extensionRegistry = new ExtensionRegistry();
|
|
216
|
-
this.extensionDisposables = /* @__PURE__ */ new Map();
|
|
217
|
-
this.context = context;
|
|
218
|
-
}
|
|
219
|
-
register(extension) {
|
|
220
|
-
if (this.extensionRegistry.has(extension.id)) {
|
|
221
|
-
console.warn(
|
|
222
|
-
`Plugin "${extension.id}" already registered. It will be overwritten.`
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
this.extensionDisposables.set(extension.id, []);
|
|
226
|
-
const disposables = this.extensionDisposables.get(extension.id);
|
|
227
|
-
if (extension.contribute) {
|
|
228
|
-
for (const [pointId, items] of Object.entries(extension.contribute())) {
|
|
229
|
-
if (Array.isArray(items)) {
|
|
230
|
-
items.forEach((item, index) => {
|
|
231
|
-
const contributionId = item.id || (item.command ? item.command : `${extension.id}.${pointId}.${index}`);
|
|
232
|
-
const contribution = {
|
|
233
|
-
id: contributionId,
|
|
234
|
-
metadata: {
|
|
235
|
-
extensionId: extension.id,
|
|
236
|
-
...item == null ? void 0 : item.metadata
|
|
237
|
-
},
|
|
238
|
-
data: item
|
|
239
|
-
};
|
|
240
|
-
const disposable = this.context.contributions.register(
|
|
241
|
-
pointId,
|
|
242
|
-
contribution
|
|
243
|
-
);
|
|
244
|
-
disposables.push(disposable);
|
|
245
|
-
const dispose = this.collectContribution(pointId, contribution);
|
|
246
|
-
if (dispose) {
|
|
247
|
-
disposables.push(dispose);
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
try {
|
|
254
|
-
this.extensionRegistry.set(extension.id, extension);
|
|
255
|
-
this.context.eventBus.emit("extension:register", extension);
|
|
256
|
-
} catch (error) {
|
|
257
|
-
console.error(
|
|
258
|
-
`Error in onCreate hook for plugin "${extension.id}":`,
|
|
259
|
-
error
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
try {
|
|
263
|
-
extension.activate(this.context);
|
|
264
|
-
} catch (error) {
|
|
265
|
-
console.error(
|
|
266
|
-
`Error in onActivate hook for plugin "${extension.id}":`,
|
|
267
|
-
error
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
console.log(`Plugin "${extension.id}" registered successfully`);
|
|
271
|
-
}
|
|
272
|
-
collectContribution(pointId, item) {
|
|
273
|
-
if (pointId === ContributionPointIds.CONFIGURATIONS) {
|
|
274
|
-
const configService = this.context.services.get(
|
|
275
|
-
"ConfigurationService"
|
|
276
|
-
);
|
|
277
|
-
configService == null ? void 0 : configService.initializeDefaults([item.data]);
|
|
278
|
-
}
|
|
279
|
-
if (pointId === ContributionPointIds.COMMANDS && item.data.handler) {
|
|
280
|
-
const commandService = this.context.services.get("CommandService");
|
|
281
|
-
return commandService.registerCommand(item.id, item.data.handler);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
unregister(name) {
|
|
285
|
-
const extension = this.extensionRegistry.get(name);
|
|
286
|
-
if (!extension) {
|
|
287
|
-
console.warn(`Plugin "${name}" not found.`);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
try {
|
|
291
|
-
extension.deactivate(this.context);
|
|
292
|
-
} catch (error) {
|
|
293
|
-
console.error(`Error in deactivate for plugin "${name}":`, error);
|
|
294
|
-
}
|
|
295
|
-
const disposables = this.extensionDisposables.get(name);
|
|
296
|
-
if (disposables) {
|
|
297
|
-
disposables.forEach((d) => d.dispose());
|
|
298
|
-
this.extensionDisposables.delete(name);
|
|
299
|
-
}
|
|
300
|
-
this.extensionRegistry.delete(name);
|
|
301
|
-
console.log(`Plugin "${name}" unregistered`);
|
|
302
|
-
return true;
|
|
303
|
-
}
|
|
304
|
-
enable(name) {
|
|
305
|
-
const extension = this.extensionRegistry.get(name);
|
|
306
|
-
if (!extension) {
|
|
307
|
-
console.warn(`Plugin "${name}" not found.`);
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
disable(name) {
|
|
312
|
-
const extension = this.extensionRegistry.get(name);
|
|
313
|
-
if (!extension) {
|
|
314
|
-
console.warn(`Plugin "${name}" not found.`);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
update() {
|
|
319
|
-
}
|
|
320
|
-
destroy() {
|
|
321
|
-
const extensionNames = Array.from(this.extensionRegistry.keys());
|
|
322
|
-
extensionNames.forEach((name) => this.unregister(name));
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
|
|
326
308
|
// src/services/CommandService.ts
|
|
327
309
|
var CommandService = class {
|
|
328
310
|
constructor() {
|
|
@@ -482,27 +464,486 @@ var ConfigurationService = class {
|
|
|
482
464
|
}
|
|
483
465
|
};
|
|
484
466
|
|
|
467
|
+
// src/services/ToolRegistryService.ts
|
|
468
|
+
var ToolRegistryService = class {
|
|
469
|
+
constructor() {
|
|
470
|
+
this.tools = /* @__PURE__ */ new Map();
|
|
471
|
+
}
|
|
472
|
+
registerTool(tool) {
|
|
473
|
+
if (!(tool == null ? void 0 : tool.id)) {
|
|
474
|
+
throw new Error("ToolContribution.id is required.");
|
|
475
|
+
}
|
|
476
|
+
this.tools.set(tool.id, tool);
|
|
477
|
+
return {
|
|
478
|
+
dispose: () => {
|
|
479
|
+
if (this.tools.get(tool.id) === tool) {
|
|
480
|
+
this.tools.delete(tool.id);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
unregisterTool(toolId) {
|
|
486
|
+
this.tools.delete(toolId);
|
|
487
|
+
}
|
|
488
|
+
getTool(toolId) {
|
|
489
|
+
return this.tools.get(toolId);
|
|
490
|
+
}
|
|
491
|
+
listTools() {
|
|
492
|
+
return Array.from(this.tools.values());
|
|
493
|
+
}
|
|
494
|
+
hasTool(toolId) {
|
|
495
|
+
return this.tools.has(toolId);
|
|
496
|
+
}
|
|
497
|
+
dispose() {
|
|
498
|
+
this.tools.clear();
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
// src/services/tokens.ts
|
|
503
|
+
var COMMAND_SERVICE = createServiceToken(
|
|
504
|
+
"CommandService"
|
|
505
|
+
);
|
|
506
|
+
var CONFIGURATION_SERVICE = createServiceToken(
|
|
507
|
+
"ConfigurationService"
|
|
508
|
+
);
|
|
509
|
+
var TOOL_REGISTRY_SERVICE = createServiceToken("ToolRegistryService");
|
|
510
|
+
var TOOL_SESSION_SERVICE = createServiceToken("ToolSessionService");
|
|
511
|
+
var WORKBENCH_SERVICE = createServiceToken("WorkbenchService");
|
|
512
|
+
var CORE_SERVICE_TOKENS = {
|
|
513
|
+
COMMAND: COMMAND_SERVICE,
|
|
514
|
+
CONFIGURATION: CONFIGURATION_SERVICE,
|
|
515
|
+
TOOL_REGISTRY: TOOL_REGISTRY_SERVICE,
|
|
516
|
+
TOOL_SESSION: TOOL_SESSION_SERVICE,
|
|
517
|
+
WORKBENCH: WORKBENCH_SERVICE
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
// src/services/ToolSessionService.ts
|
|
521
|
+
var ToolSessionService = class {
|
|
522
|
+
constructor(dependencies = {}) {
|
|
523
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
524
|
+
this.dirtyTrackers = /* @__PURE__ */ new Map();
|
|
525
|
+
this.commandService = dependencies.commandService;
|
|
526
|
+
this.toolRegistry = dependencies.toolRegistry;
|
|
527
|
+
}
|
|
528
|
+
init(context) {
|
|
529
|
+
var _a, _b;
|
|
530
|
+
(_a = this.commandService) != null ? _a : this.commandService = context.get(COMMAND_SERVICE);
|
|
531
|
+
(_b = this.toolRegistry) != null ? _b : this.toolRegistry = context.get(TOOL_REGISTRY_SERVICE);
|
|
532
|
+
if (!this.commandService) {
|
|
533
|
+
throw new Error("ToolSessionService requires CommandService.");
|
|
534
|
+
}
|
|
535
|
+
if (!this.toolRegistry) {
|
|
536
|
+
throw new Error("ToolSessionService requires ToolRegistryService.");
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
setCommandService(commandService) {
|
|
540
|
+
this.commandService = commandService;
|
|
541
|
+
}
|
|
542
|
+
setToolRegistry(toolRegistry) {
|
|
543
|
+
this.toolRegistry = toolRegistry;
|
|
544
|
+
}
|
|
545
|
+
registerDirtyTracker(toolId, callback) {
|
|
546
|
+
const wrapped = () => {
|
|
547
|
+
try {
|
|
548
|
+
return callback();
|
|
549
|
+
} catch (e) {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
this.dirtyTrackers.set(toolId, wrapped);
|
|
554
|
+
return {
|
|
555
|
+
dispose: () => {
|
|
556
|
+
if (this.dirtyTrackers.get(toolId) === wrapped) {
|
|
557
|
+
this.dirtyTrackers.delete(toolId);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
ensureSession(toolId) {
|
|
563
|
+
const existing = this.sessions.get(toolId);
|
|
564
|
+
if (existing) return existing;
|
|
565
|
+
const created = {
|
|
566
|
+
toolId,
|
|
567
|
+
status: "idle",
|
|
568
|
+
dirty: false
|
|
569
|
+
};
|
|
570
|
+
this.sessions.set(toolId, created);
|
|
571
|
+
return created;
|
|
572
|
+
}
|
|
573
|
+
getState(toolId) {
|
|
574
|
+
return { ...this.ensureSession(toolId) };
|
|
575
|
+
}
|
|
576
|
+
isDirty(toolId) {
|
|
577
|
+
const tracker = this.dirtyTrackers.get(toolId);
|
|
578
|
+
if (tracker) return tracker();
|
|
579
|
+
return this.ensureSession(toolId).dirty;
|
|
580
|
+
}
|
|
581
|
+
markDirty(toolId, dirty = true) {
|
|
582
|
+
const session = this.ensureSession(toolId);
|
|
583
|
+
session.dirty = dirty;
|
|
584
|
+
session.lastUpdatedAt = Date.now();
|
|
585
|
+
}
|
|
586
|
+
resolveTool(toolId) {
|
|
587
|
+
return this.getToolRegistry().getTool(toolId);
|
|
588
|
+
}
|
|
589
|
+
async runCommand(commandId, ...args) {
|
|
590
|
+
if (!commandId) return void 0;
|
|
591
|
+
return await this.getCommandService().executeCommand(commandId, ...args);
|
|
592
|
+
}
|
|
593
|
+
getCommandService() {
|
|
594
|
+
if (!this.commandService) {
|
|
595
|
+
throw new Error("ToolSessionService is not initialized.");
|
|
596
|
+
}
|
|
597
|
+
return this.commandService;
|
|
598
|
+
}
|
|
599
|
+
getToolRegistry() {
|
|
600
|
+
if (!this.toolRegistry) {
|
|
601
|
+
throw new Error("ToolSessionService is not initialized.");
|
|
602
|
+
}
|
|
603
|
+
return this.toolRegistry;
|
|
604
|
+
}
|
|
605
|
+
async begin(toolId) {
|
|
606
|
+
var _a;
|
|
607
|
+
const tool = this.resolveTool(toolId);
|
|
608
|
+
const session = this.ensureSession(toolId);
|
|
609
|
+
if (session.status === "active") return;
|
|
610
|
+
await this.runCommand((_a = tool == null ? void 0 : tool.commands) == null ? void 0 : _a.begin);
|
|
611
|
+
session.status = "active";
|
|
612
|
+
session.startedAt = Date.now();
|
|
613
|
+
session.lastUpdatedAt = session.startedAt;
|
|
614
|
+
}
|
|
615
|
+
async validate(toolId) {
|
|
616
|
+
var _a;
|
|
617
|
+
const tool = this.resolveTool(toolId);
|
|
618
|
+
if (!((_a = tool == null ? void 0 : tool.commands) == null ? void 0 : _a.validate)) {
|
|
619
|
+
return { ok: true };
|
|
620
|
+
}
|
|
621
|
+
const result = await this.runCommand(tool.commands.validate);
|
|
622
|
+
if (result === false) return { ok: false, result };
|
|
623
|
+
if (result && typeof result === "object" && "ok" in result) {
|
|
624
|
+
return { ok: Boolean(result.ok), result };
|
|
625
|
+
}
|
|
626
|
+
return { ok: true, result };
|
|
627
|
+
}
|
|
628
|
+
async commit(toolId) {
|
|
629
|
+
var _a;
|
|
630
|
+
const tool = this.resolveTool(toolId);
|
|
631
|
+
const validateResult = await this.validate(toolId);
|
|
632
|
+
if (!validateResult.ok) return validateResult;
|
|
633
|
+
const result = await this.runCommand((_a = tool == null ? void 0 : tool.commands) == null ? void 0 : _a.commit);
|
|
634
|
+
const session = this.ensureSession(toolId);
|
|
635
|
+
session.dirty = false;
|
|
636
|
+
session.status = "idle";
|
|
637
|
+
session.lastUpdatedAt = Date.now();
|
|
638
|
+
return { ok: true, result };
|
|
639
|
+
}
|
|
640
|
+
async rollback(toolId) {
|
|
641
|
+
var _a, _b;
|
|
642
|
+
const tool = this.resolveTool(toolId);
|
|
643
|
+
await this.runCommand(((_a = tool == null ? void 0 : tool.commands) == null ? void 0 : _a.rollback) || ((_b = tool == null ? void 0 : tool.commands) == null ? void 0 : _b.reset));
|
|
644
|
+
const session = this.ensureSession(toolId);
|
|
645
|
+
session.dirty = false;
|
|
646
|
+
session.status = "idle";
|
|
647
|
+
session.lastUpdatedAt = Date.now();
|
|
648
|
+
}
|
|
649
|
+
deactivateSession(toolId) {
|
|
650
|
+
const session = this.ensureSession(toolId);
|
|
651
|
+
session.status = "idle";
|
|
652
|
+
session.lastUpdatedAt = Date.now();
|
|
653
|
+
}
|
|
654
|
+
async handleBeforeLeave(toolId) {
|
|
655
|
+
var _a, _b;
|
|
656
|
+
const tool = this.resolveTool(toolId);
|
|
657
|
+
if (!tool) return { decision: "allow" };
|
|
658
|
+
if (tool.interaction !== "session") return { decision: "allow" };
|
|
659
|
+
const dirty = this.isDirty(toolId);
|
|
660
|
+
if (!dirty) return { decision: "allow" };
|
|
661
|
+
const leavePolicy = (_b = (_a = tool.session) == null ? void 0 : _a.leavePolicy) != null ? _b : "block";
|
|
662
|
+
if (leavePolicy === "commit") {
|
|
663
|
+
const committed = await this.commit(toolId);
|
|
664
|
+
if (!committed.ok) {
|
|
665
|
+
return { decision: "blocked", reason: "session-validation-failed" };
|
|
666
|
+
}
|
|
667
|
+
return { decision: "allow" };
|
|
668
|
+
}
|
|
669
|
+
if (leavePolicy === "rollback") {
|
|
670
|
+
await this.rollback(toolId);
|
|
671
|
+
return { decision: "allow" };
|
|
672
|
+
}
|
|
673
|
+
return { decision: "blocked", reason: "session-dirty" };
|
|
674
|
+
}
|
|
675
|
+
dispose() {
|
|
676
|
+
this.sessions.clear();
|
|
677
|
+
this.dirtyTrackers.clear();
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
|
|
485
681
|
// src/services/WorkbenchService.ts
|
|
486
682
|
var WorkbenchService = class {
|
|
487
|
-
constructor() {
|
|
683
|
+
constructor(dependencies = {}) {
|
|
488
684
|
this._activeToolId = null;
|
|
685
|
+
this.guards = [];
|
|
686
|
+
this.eventBus = dependencies.eventBus;
|
|
687
|
+
this.toolRegistry = dependencies.toolRegistry;
|
|
688
|
+
this.sessionService = dependencies.sessionService;
|
|
489
689
|
}
|
|
490
|
-
init() {
|
|
690
|
+
init(context) {
|
|
691
|
+
var _a, _b, _c;
|
|
692
|
+
(_a = this.eventBus) != null ? _a : this.eventBus = context.eventBus;
|
|
693
|
+
(_b = this.toolRegistry) != null ? _b : this.toolRegistry = context.get(TOOL_REGISTRY_SERVICE);
|
|
694
|
+
(_c = this.sessionService) != null ? _c : this.sessionService = context.get(TOOL_SESSION_SERVICE);
|
|
695
|
+
if (!this.eventBus) {
|
|
696
|
+
throw new Error("WorkbenchService requires EventBus.");
|
|
697
|
+
}
|
|
698
|
+
if (!this.toolRegistry) {
|
|
699
|
+
throw new Error("WorkbenchService requires ToolRegistryService.");
|
|
700
|
+
}
|
|
701
|
+
if (!this.sessionService) {
|
|
702
|
+
throw new Error("WorkbenchService requires ToolSessionService.");
|
|
703
|
+
}
|
|
491
704
|
}
|
|
492
705
|
dispose() {
|
|
706
|
+
this.guards = [];
|
|
493
707
|
}
|
|
494
708
|
setEventBus(bus) {
|
|
495
709
|
this.eventBus = bus;
|
|
496
710
|
}
|
|
711
|
+
setToolRegistry(toolRegistry) {
|
|
712
|
+
this.toolRegistry = toolRegistry;
|
|
713
|
+
}
|
|
714
|
+
setToolSessionService(sessionService) {
|
|
715
|
+
this.sessionService = sessionService;
|
|
716
|
+
}
|
|
497
717
|
get activeToolId() {
|
|
498
718
|
return this._activeToolId;
|
|
499
719
|
}
|
|
500
|
-
|
|
720
|
+
registerSwitchGuard(guard, priority = 0) {
|
|
721
|
+
const item = { guard, priority };
|
|
722
|
+
this.guards.push(item);
|
|
723
|
+
this.guards.sort((a, b) => b.priority - a.priority);
|
|
724
|
+
return {
|
|
725
|
+
dispose: () => {
|
|
726
|
+
const index = this.guards.indexOf(item);
|
|
727
|
+
if (index >= 0) this.guards.splice(index, 1);
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
async runGuards(context) {
|
|
732
|
+
for (const { guard } of this.guards) {
|
|
733
|
+
const allowed = await Promise.resolve(guard(context));
|
|
734
|
+
if (!allowed) return false;
|
|
735
|
+
}
|
|
736
|
+
return true;
|
|
737
|
+
}
|
|
738
|
+
async switchTool(id, options) {
|
|
501
739
|
var _a;
|
|
502
|
-
|
|
740
|
+
const eventBus = this.getEventBus();
|
|
741
|
+
const toolRegistry = this.getToolRegistry();
|
|
742
|
+
const sessionService = this.getSessionService();
|
|
743
|
+
if (this._activeToolId === id) {
|
|
744
|
+
return { ok: true, from: this._activeToolId, to: id };
|
|
745
|
+
}
|
|
746
|
+
if (id && !toolRegistry.hasTool(id)) {
|
|
747
|
+
return {
|
|
748
|
+
ok: false,
|
|
749
|
+
from: this._activeToolId,
|
|
750
|
+
to: id,
|
|
751
|
+
reason: `tool-not-registered:${id}`
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
const context = {
|
|
755
|
+
from: this._activeToolId,
|
|
756
|
+
to: id,
|
|
757
|
+
reason: options == null ? void 0 : options.reason
|
|
758
|
+
};
|
|
759
|
+
const guardAllowed = await this.runGuards(context);
|
|
760
|
+
if (!guardAllowed) {
|
|
761
|
+
eventBus.emit("tool:switch:blocked", {
|
|
762
|
+
...context,
|
|
763
|
+
reason: "blocked-by-guard"
|
|
764
|
+
});
|
|
765
|
+
return {
|
|
766
|
+
ok: false,
|
|
767
|
+
from: this._activeToolId,
|
|
768
|
+
to: id,
|
|
769
|
+
reason: "blocked-by-guard"
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
if (context.from) {
|
|
773
|
+
const leaveResult = await sessionService.handleBeforeLeave(context.from);
|
|
774
|
+
if (leaveResult.decision === "blocked") {
|
|
775
|
+
eventBus.emit("tool:switch:blocked", {
|
|
776
|
+
...context,
|
|
777
|
+
reason: leaveResult.reason || "session-blocked"
|
|
778
|
+
});
|
|
779
|
+
return {
|
|
780
|
+
ok: false,
|
|
781
|
+
from: this._activeToolId,
|
|
782
|
+
to: id,
|
|
783
|
+
reason: leaveResult.reason || "session-blocked"
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
sessionService.deactivateSession(context.from);
|
|
787
|
+
}
|
|
788
|
+
if (id) {
|
|
789
|
+
const tool = toolRegistry.getTool(id);
|
|
790
|
+
if ((tool == null ? void 0 : tool.interaction) === "session" && ((_a = tool.session) == null ? void 0 : _a.autoBegin) !== false) {
|
|
791
|
+
await sessionService.begin(id);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
503
794
|
const previous = this._activeToolId;
|
|
504
795
|
this._activeToolId = id;
|
|
505
|
-
|
|
796
|
+
const reason = options == null ? void 0 : options.reason;
|
|
797
|
+
eventBus.emit("tool:activated", { id, previous, reason });
|
|
798
|
+
eventBus.emit("tool:switch", { from: previous, to: id, reason });
|
|
799
|
+
return { ok: true, from: previous, to: id };
|
|
800
|
+
}
|
|
801
|
+
async activate(id) {
|
|
802
|
+
return await this.switchTool(id, { reason: "activate" });
|
|
803
|
+
}
|
|
804
|
+
async deactivate() {
|
|
805
|
+
return await this.switchTool(null, { reason: "deactivate" });
|
|
806
|
+
}
|
|
807
|
+
getEventBus() {
|
|
808
|
+
if (!this.eventBus) {
|
|
809
|
+
throw new Error("WorkbenchService is not initialized.");
|
|
810
|
+
}
|
|
811
|
+
return this.eventBus;
|
|
812
|
+
}
|
|
813
|
+
getToolRegistry() {
|
|
814
|
+
if (!this.toolRegistry) {
|
|
815
|
+
throw new Error("WorkbenchService is not initialized.");
|
|
816
|
+
}
|
|
817
|
+
return this.toolRegistry;
|
|
818
|
+
}
|
|
819
|
+
getSessionService() {
|
|
820
|
+
if (!this.sessionService) {
|
|
821
|
+
throw new Error("WorkbenchService is not initialized.");
|
|
822
|
+
}
|
|
823
|
+
return this.sessionService;
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
// src/extension.ts
|
|
828
|
+
var ExtensionRegistry = class extends Map {
|
|
829
|
+
};
|
|
830
|
+
var ExtensionManager = class {
|
|
831
|
+
constructor(context) {
|
|
832
|
+
this.extensionRegistry = new ExtensionRegistry();
|
|
833
|
+
this.extensionDisposables = /* @__PURE__ */ new Map();
|
|
834
|
+
this.context = context;
|
|
835
|
+
}
|
|
836
|
+
register(extension) {
|
|
837
|
+
if (this.extensionRegistry.has(extension.id)) {
|
|
838
|
+
console.warn(
|
|
839
|
+
`Plugin "${extension.id}" already registered. It will be overwritten.`
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
this.extensionDisposables.set(extension.id, []);
|
|
843
|
+
const disposables = this.extensionDisposables.get(extension.id);
|
|
844
|
+
if (extension.contribute) {
|
|
845
|
+
for (const [pointId, items] of Object.entries(extension.contribute())) {
|
|
846
|
+
if (Array.isArray(items)) {
|
|
847
|
+
items.forEach((item, index) => {
|
|
848
|
+
const contributionId = item.id || (item.command ? item.command : `${extension.id}.${pointId}.${index}`);
|
|
849
|
+
const contribution = {
|
|
850
|
+
id: contributionId,
|
|
851
|
+
metadata: {
|
|
852
|
+
extensionId: extension.id,
|
|
853
|
+
...item == null ? void 0 : item.metadata
|
|
854
|
+
},
|
|
855
|
+
data: item
|
|
856
|
+
};
|
|
857
|
+
const disposable = this.context.contributions.register(
|
|
858
|
+
pointId,
|
|
859
|
+
contribution
|
|
860
|
+
);
|
|
861
|
+
disposables.push(disposable);
|
|
862
|
+
const dispose = this.collectContribution(pointId, contribution);
|
|
863
|
+
if (dispose) {
|
|
864
|
+
disposables.push(dispose);
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
try {
|
|
871
|
+
this.extensionRegistry.set(extension.id, extension);
|
|
872
|
+
this.context.eventBus.emit("extension:register", extension);
|
|
873
|
+
} catch (error) {
|
|
874
|
+
console.error(
|
|
875
|
+
`Error in onCreate hook for plugin "${extension.id}":`,
|
|
876
|
+
error
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
try {
|
|
880
|
+
extension.activate(this.context);
|
|
881
|
+
} catch (error) {
|
|
882
|
+
console.error(
|
|
883
|
+
`Error in onActivate hook for plugin "${extension.id}":`,
|
|
884
|
+
error
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
console.log(`Plugin "${extension.id}" registered successfully`);
|
|
888
|
+
}
|
|
889
|
+
collectContribution(pointId, item) {
|
|
890
|
+
if (pointId === ContributionPointIds.CONFIGURATIONS) {
|
|
891
|
+
const configService = this.context.services.get(
|
|
892
|
+
CONFIGURATION_SERVICE
|
|
893
|
+
);
|
|
894
|
+
configService == null ? void 0 : configService.initializeDefaults([item.data]);
|
|
895
|
+
}
|
|
896
|
+
if (pointId === ContributionPointIds.COMMANDS && item.data.handler) {
|
|
897
|
+
const commandService = this.context.services.get(COMMAND_SERVICE);
|
|
898
|
+
return commandService.registerCommand(item.id, item.data.handler);
|
|
899
|
+
}
|
|
900
|
+
if (pointId === ContributionPointIds.TOOLS) {
|
|
901
|
+
const toolRegistry = this.context.services.get(
|
|
902
|
+
TOOL_REGISTRY_SERVICE
|
|
903
|
+
);
|
|
904
|
+
if (!toolRegistry) return;
|
|
905
|
+
return toolRegistry.registerTool(item.data);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
unregister(name) {
|
|
909
|
+
const extension = this.extensionRegistry.get(name);
|
|
910
|
+
if (!extension) {
|
|
911
|
+
console.warn(`Plugin "${name}" not found.`);
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
try {
|
|
915
|
+
extension.deactivate(this.context);
|
|
916
|
+
} catch (error) {
|
|
917
|
+
console.error(`Error in deactivate for plugin "${name}":`, error);
|
|
918
|
+
}
|
|
919
|
+
const disposables = this.extensionDisposables.get(name);
|
|
920
|
+
if (disposables) {
|
|
921
|
+
disposables.forEach((d) => d.dispose());
|
|
922
|
+
this.extensionDisposables.delete(name);
|
|
923
|
+
}
|
|
924
|
+
this.extensionRegistry.delete(name);
|
|
925
|
+
console.log(`Plugin "${name}" unregistered`);
|
|
926
|
+
return true;
|
|
927
|
+
}
|
|
928
|
+
enable(name) {
|
|
929
|
+
const extension = this.extensionRegistry.get(name);
|
|
930
|
+
if (!extension) {
|
|
931
|
+
console.warn(`Plugin "${name}" not found.`);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
disable(name) {
|
|
936
|
+
const extension = this.extensionRegistry.get(name);
|
|
937
|
+
if (!extension) {
|
|
938
|
+
console.warn(`Plugin "${name}" not found.`);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
update() {
|
|
943
|
+
}
|
|
944
|
+
destroy() {
|
|
945
|
+
const extensionNames = Array.from(this.extensionRegistry.keys());
|
|
946
|
+
extensionNames.forEach((name) => this.unregister(name));
|
|
506
947
|
}
|
|
507
948
|
};
|
|
508
949
|
|
|
@@ -511,19 +952,37 @@ var Pooder = class {
|
|
|
511
952
|
constructor() {
|
|
512
953
|
this.eventBus = new event_default();
|
|
513
954
|
this.services = new ServiceRegistry();
|
|
955
|
+
this.serviceContext = {
|
|
956
|
+
eventBus: this.eventBus,
|
|
957
|
+
get: (identifier) => this.services.get(identifier),
|
|
958
|
+
getOrThrow: (identifier, errorMessage) => this.services.getOrThrow(identifier, errorMessage),
|
|
959
|
+
has: (identifier) => this.services.has(identifier)
|
|
960
|
+
};
|
|
514
961
|
this.contributions = new ContributionRegistry();
|
|
515
962
|
this.initDefaultContributionPoints();
|
|
516
963
|
const commandService = new CommandService();
|
|
517
|
-
this.registerService(commandService,
|
|
964
|
+
this.registerService(commandService, CORE_SERVICE_TOKENS.COMMAND);
|
|
518
965
|
const configurationService = new ConfigurationService();
|
|
519
|
-
this.registerService(configurationService,
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
966
|
+
this.registerService(configurationService, CORE_SERVICE_TOKENS.CONFIGURATION);
|
|
967
|
+
const toolRegistryService = new ToolRegistryService();
|
|
968
|
+
this.registerService(toolRegistryService, CORE_SERVICE_TOKENS.TOOL_REGISTRY);
|
|
969
|
+
const toolSessionService = new ToolSessionService({
|
|
970
|
+
commandService,
|
|
971
|
+
toolRegistry: toolRegistryService
|
|
972
|
+
});
|
|
973
|
+
this.registerService(toolSessionService, CORE_SERVICE_TOKENS.TOOL_SESSION);
|
|
974
|
+
const workbenchService = new WorkbenchService({
|
|
975
|
+
eventBus: this.eventBus,
|
|
976
|
+
toolRegistry: toolRegistryService,
|
|
977
|
+
sessionService: toolSessionService
|
|
978
|
+
});
|
|
979
|
+
this.registerService(workbenchService, CORE_SERVICE_TOKENS.WORKBENCH);
|
|
523
980
|
const context = {
|
|
524
981
|
eventBus: this.eventBus,
|
|
525
982
|
services: {
|
|
526
|
-
get: (
|
|
983
|
+
get: (identifier) => this.services.get(identifier),
|
|
984
|
+
getOrThrow: (identifier, errorMessage) => this.services.getOrThrow(identifier, errorMessage),
|
|
985
|
+
has: (identifier) => this.services.has(identifier)
|
|
527
986
|
},
|
|
528
987
|
contributions: {
|
|
529
988
|
get: (pointId) => this.getContributions(pointId),
|
|
@@ -555,38 +1014,102 @@ var Pooder = class {
|
|
|
555
1014
|
});
|
|
556
1015
|
}
|
|
557
1016
|
// --- Service Management ---
|
|
558
|
-
registerService(service,
|
|
559
|
-
|
|
560
|
-
const serviceId =
|
|
1017
|
+
registerService(service, identifier, options = {}) {
|
|
1018
|
+
const serviceIdentifier = this.resolveServiceIdentifier(service, identifier);
|
|
1019
|
+
const serviceId = this.getServiceLabel(serviceIdentifier);
|
|
561
1020
|
try {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
1021
|
+
const initResult = this.invokeServiceHook(service, "init");
|
|
1022
|
+
if (this.isPromiseLike(initResult)) {
|
|
1023
|
+
throw new Error(
|
|
1024
|
+
`Service "${serviceId}" init() is async. Use registerServiceAsync() instead.`
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
this.services.register(serviceIdentifier, service, options);
|
|
1028
|
+
this.eventBus.emit("service:register", service, { id: serviceId });
|
|
1029
|
+
return true;
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
console.error(`Error initializing service ${serviceId}:`, error);
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
async registerServiceAsync(service, identifier, options = {}) {
|
|
1036
|
+
const serviceIdentifier = this.resolveServiceIdentifier(service, identifier);
|
|
1037
|
+
const serviceId = this.getServiceLabel(serviceIdentifier);
|
|
1038
|
+
try {
|
|
1039
|
+
await this.invokeServiceHookAsync(service, "init");
|
|
1040
|
+
this.services.register(serviceIdentifier, service, options);
|
|
1041
|
+
this.eventBus.emit("service:register", service, { id: serviceId });
|
|
1042
|
+
return true;
|
|
1043
|
+
} catch (error) {
|
|
1044
|
+
console.error(`Error initializing service ${serviceId}:`, error);
|
|
565
1045
|
return false;
|
|
566
1046
|
}
|
|
567
|
-
|
|
568
|
-
|
|
1047
|
+
}
|
|
1048
|
+
unregisterService(serviceOrIdentifier, id) {
|
|
1049
|
+
const resolvedIdentifier = this.resolveUnregisterIdentifier(
|
|
1050
|
+
serviceOrIdentifier,
|
|
1051
|
+
id
|
|
1052
|
+
);
|
|
1053
|
+
const serviceId = this.getServiceLabel(resolvedIdentifier);
|
|
1054
|
+
const registeredService = this.services.get(resolvedIdentifier);
|
|
1055
|
+
if (!registeredService) {
|
|
1056
|
+
console.warn(`Service ${serviceId} is not registered.`);
|
|
1057
|
+
return true;
|
|
1058
|
+
}
|
|
1059
|
+
try {
|
|
1060
|
+
const disposeResult = this.invokeServiceHook(registeredService, "dispose");
|
|
1061
|
+
if (this.isPromiseLike(disposeResult)) {
|
|
1062
|
+
throw new Error(
|
|
1063
|
+
`Service "${serviceId}" dispose() is async. Use unregisterServiceAsync() instead.`
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
console.error(`Error disposing service ${serviceId}:`, error);
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
this.services.delete(resolvedIdentifier);
|
|
1071
|
+
this.eventBus.emit("service:unregister", registeredService, { id: serviceId });
|
|
569
1072
|
return true;
|
|
570
1073
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
1074
|
+
async unregisterServiceAsync(serviceOrIdentifier, id) {
|
|
1075
|
+
const resolvedIdentifier = this.resolveUnregisterIdentifier(
|
|
1076
|
+
serviceOrIdentifier,
|
|
1077
|
+
id
|
|
1078
|
+
);
|
|
1079
|
+
const serviceId = this.getServiceLabel(resolvedIdentifier);
|
|
1080
|
+
const registeredService = this.services.get(resolvedIdentifier);
|
|
1081
|
+
if (!registeredService) {
|
|
575
1082
|
console.warn(`Service ${serviceId} is not registered.`);
|
|
576
1083
|
return true;
|
|
577
1084
|
}
|
|
578
1085
|
try {
|
|
579
|
-
(
|
|
580
|
-
} catch (
|
|
581
|
-
console.error(`Error disposing service ${serviceId}:`,
|
|
1086
|
+
await this.invokeServiceHookAsync(registeredService, "dispose");
|
|
1087
|
+
} catch (error) {
|
|
1088
|
+
console.error(`Error disposing service ${serviceId}:`, error);
|
|
582
1089
|
return false;
|
|
583
1090
|
}
|
|
584
|
-
this.services.delete(
|
|
585
|
-
this.eventBus.emit("service:unregister",
|
|
1091
|
+
this.services.delete(resolvedIdentifier);
|
|
1092
|
+
this.eventBus.emit("service:unregister", registeredService, { id: serviceId });
|
|
586
1093
|
return true;
|
|
587
1094
|
}
|
|
588
|
-
getService(
|
|
589
|
-
return this.services.get(
|
|
1095
|
+
getService(identifier) {
|
|
1096
|
+
return this.services.get(identifier);
|
|
1097
|
+
}
|
|
1098
|
+
getServiceOrThrow(identifier, errorMessage) {
|
|
1099
|
+
return this.services.getOrThrow(identifier, errorMessage);
|
|
1100
|
+
}
|
|
1101
|
+
hasService(identifier) {
|
|
1102
|
+
return this.services.has(identifier);
|
|
1103
|
+
}
|
|
1104
|
+
async dispose() {
|
|
1105
|
+
var _a;
|
|
1106
|
+
this.extensionManager.destroy();
|
|
1107
|
+
const registrations = this.services.list().slice().reverse();
|
|
1108
|
+
for (const item of registrations) {
|
|
1109
|
+
const identifier = (_a = item.token) != null ? _a : item.id;
|
|
1110
|
+
await this.unregisterServiceAsync(identifier);
|
|
1111
|
+
}
|
|
1112
|
+
this.services.clear();
|
|
590
1113
|
}
|
|
591
1114
|
// --- Contribution Management ---
|
|
592
1115
|
registerContributionPoint(point) {
|
|
@@ -601,9 +1124,40 @@ var Pooder = class {
|
|
|
601
1124
|
getContributions(pointId) {
|
|
602
1125
|
return this.contributions.get(pointId);
|
|
603
1126
|
}
|
|
1127
|
+
resolveServiceIdentifier(service, identifier) {
|
|
1128
|
+
return identifier != null ? identifier : service.constructor.name;
|
|
1129
|
+
}
|
|
1130
|
+
resolveUnregisterIdentifier(serviceOrIdentifier, id) {
|
|
1131
|
+
if (typeof serviceOrIdentifier === "string" || isServiceToken(serviceOrIdentifier)) {
|
|
1132
|
+
return serviceOrIdentifier;
|
|
1133
|
+
}
|
|
1134
|
+
return id != null ? id : serviceOrIdentifier.constructor.name;
|
|
1135
|
+
}
|
|
1136
|
+
getServiceLabel(identifier) {
|
|
1137
|
+
if (typeof identifier === "string") {
|
|
1138
|
+
return identifier;
|
|
1139
|
+
}
|
|
1140
|
+
return identifier.name;
|
|
1141
|
+
}
|
|
1142
|
+
invokeServiceHook(service, hook) {
|
|
1143
|
+
const handler = service[hook];
|
|
1144
|
+
if (!handler) {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
return handler.call(service, this.serviceContext);
|
|
1148
|
+
}
|
|
1149
|
+
async invokeServiceHookAsync(service, hook) {
|
|
1150
|
+
await this.invokeServiceHook(service, hook);
|
|
1151
|
+
}
|
|
1152
|
+
isPromiseLike(value) {
|
|
1153
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
1154
|
+
}
|
|
604
1155
|
};
|
|
605
1156
|
// Annotate the CommonJS export names for ESM import in node:
|
|
606
1157
|
0 && (module.exports = {
|
|
1158
|
+
COMMAND_SERVICE,
|
|
1159
|
+
CONFIGURATION_SERVICE,
|
|
1160
|
+
CORE_SERVICE_TOKENS,
|
|
607
1161
|
CommandService,
|
|
608
1162
|
ConfigurationService,
|
|
609
1163
|
ContributionPointIds,
|
|
@@ -613,5 +1167,12 @@ var Pooder = class {
|
|
|
613
1167
|
ExtensionRegistry,
|
|
614
1168
|
Pooder,
|
|
615
1169
|
ServiceRegistry,
|
|
616
|
-
|
|
1170
|
+
TOOL_REGISTRY_SERVICE,
|
|
1171
|
+
TOOL_SESSION_SERVICE,
|
|
1172
|
+
ToolRegistryService,
|
|
1173
|
+
ToolSessionService,
|
|
1174
|
+
WORKBENCH_SERVICE,
|
|
1175
|
+
WorkbenchService,
|
|
1176
|
+
createServiceToken,
|
|
1177
|
+
isServiceToken
|
|
617
1178
|
});
|