@theia/plugin-ext 1.66.0-next.32 → 1.66.0-next.44

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.
Files changed (55) hide show
  1. package/lib/common/plugin-identifiers.d.ts +8 -2
  2. package/lib/common/plugin-identifiers.d.ts.map +1 -1
  3. package/lib/common/plugin-identifiers.js +13 -4
  4. package/lib/common/plugin-identifiers.js.map +1 -1
  5. package/lib/common/plugin-protocol.d.ts +7 -6
  6. package/lib/common/plugin-protocol.d.ts.map +1 -1
  7. package/lib/common/plugin-protocol.js.map +1 -1
  8. package/lib/hosted/common/hosted-plugin.d.ts.map +1 -1
  9. package/lib/hosted/common/hosted-plugin.js +9 -3
  10. package/lib/hosted/common/hosted-plugin.js.map +1 -1
  11. package/lib/hosted/node/metadata-scanner.js +1 -1
  12. package/lib/hosted/node/metadata-scanner.js.map +1 -1
  13. package/lib/hosted/node/plugin-deployer-handler-impl.d.ts +2 -2
  14. package/lib/hosted/node/plugin-deployer-handler-impl.d.ts.map +1 -1
  15. package/lib/hosted/node/plugin-deployer-handler-impl.js.map +1 -1
  16. package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
  17. package/lib/hosted/node/plugin-reader.js +2 -1
  18. package/lib/hosted/node/plugin-reader.js.map +1 -1
  19. package/lib/hosted/node/plugin-service.d.ts +4 -3
  20. package/lib/hosted/node/plugin-service.d.ts.map +1 -1
  21. package/lib/hosted/node/plugin-service.js +11 -13
  22. package/lib/hosted/node/plugin-service.js.map +1 -1
  23. package/lib/main/browser/lm-main.d.ts.map +1 -1
  24. package/lib/main/browser/lm-main.js +21 -8
  25. package/lib/main/browser/lm-main.js.map +1 -1
  26. package/lib/main/node/plugin-deployer-impl.d.ts +2 -2
  27. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  28. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  29. package/lib/main/node/plugin-server-impl.d.ts +3 -3
  30. package/lib/main/node/plugin-server-impl.d.ts.map +1 -1
  31. package/lib/main/node/plugin-server-impl.js.map +1 -1
  32. package/lib/main/node/plugin-uninstallation-manager.d.ts +7 -7
  33. package/lib/main/node/plugin-uninstallation-manager.d.ts.map +1 -1
  34. package/lib/main/node/plugin-uninstallation-manager.js +2 -1
  35. package/lib/main/node/plugin-uninstallation-manager.js.map +1 -1
  36. package/lib/plugin/output-channel/log-output-channel.d.ts.map +1 -1
  37. package/lib/plugin/output-channel/log-output-channel.js +9 -0
  38. package/lib/plugin/output-channel/log-output-channel.js.map +1 -1
  39. package/lib/plugin/output-channel/output-channel-item.d.ts.map +1 -1
  40. package/lib/plugin/output-channel/output-channel-item.js +8 -0
  41. package/lib/plugin/output-channel/output-channel-item.js.map +1 -1
  42. package/package.json +29 -29
  43. package/src/common/plugin-identifiers.ts +11 -3
  44. package/src/common/plugin-protocol.ts +8 -6
  45. package/src/hosted/common/hosted-plugin.ts +11 -3
  46. package/src/hosted/node/metadata-scanner.ts +1 -1
  47. package/src/hosted/node/plugin-deployer-handler-impl.ts +2 -2
  48. package/src/hosted/node/plugin-reader.ts +2 -1
  49. package/src/hosted/node/plugin-service.ts +15 -15
  50. package/src/main/browser/lm-main.ts +23 -9
  51. package/src/main/node/plugin-deployer-impl.ts +2 -2
  52. package/src/main/node/plugin-server-impl.ts +3 -3
  53. package/src/main/node/plugin-uninstallation-manager.ts +11 -9
  54. package/src/plugin/output-channel/log-output-channel.ts +10 -0
  55. package/src/plugin/output-channel/output-channel-item.ts +8 -0
@@ -36,7 +36,7 @@ export class MetadataScanner {
36
36
  host: PLUGIN_HOST_BACKEND,
37
37
  model: scanner.getModel(plugin),
38
38
  lifecycle: scanner.getLifecycle(plugin),
39
- outOfSync: this.uninstallationManager.isUninstalled(id) || await this.uninstallationManager.isDisabled(id),
39
+ outOfSync: this.uninstallationManager.isUninstalled(id) || await this.uninstallationManager.isDisabled(PluginIdentifiers.toUnversioned(id)),
40
40
  };
41
41
  }
42
42
 
@@ -275,11 +275,11 @@ export class PluginDeployerHandlerImpl implements PluginDeployerHandler {
275
275
  this.sourceLocations.set(id, knownLocations);
276
276
  }
277
277
 
278
- async enablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
278
+ async enablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
279
279
  return this.uninstallationManager.markAsEnabled(pluginId);
280
280
  }
281
281
 
282
- async disablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
282
+ async disablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
283
283
  return this.uninstallationManager.markAsDisabled(pluginId);
284
284
  }
285
285
  }
@@ -49,7 +49,8 @@ export class HostedPluginReader implements BackendApplicationContribution {
49
49
 
50
50
  const localPath = this.pluginsIdsFiles.get(pluginId);
51
51
  if (localPath) {
52
- res.sendFile(filePath, { root: localPath }, e => {
52
+ const absolutePath = path.resolve(localPath, filePath);
53
+ res.sendFile(absolutePath, e => {
53
54
  if (!e) {
54
55
  // the file was found and successfully transferred
55
56
  return;
@@ -63,7 +63,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
63
63
  protected toDispose = new DisposableCollection();
64
64
 
65
65
  protected uninstalledPlugins: Set<PluginIdentifiers.VersionedId>;
66
- protected disabledPlugins: Set<PluginIdentifiers.VersionedId>;
66
+ protected disabledPlugins: Set<PluginIdentifiers.UnversionedId>;
67
67
 
68
68
  protected readonly pluginVersions = new Map<PluginIdentifiers.UnversionedId, string>();
69
69
 
@@ -129,6 +129,11 @@ export class HostedPluginServerImpl implements HostedPluginServer {
129
129
  }
130
130
 
131
131
  async getDeployedPluginIds(): Promise<PluginIdentifiers.VersionedId[]> {
132
+ return this.getInstalledPluginIds()
133
+ .then(ids => ids.filter(candidate => this.isInstalledPlugin(candidate) && !this.disabledPlugins.has(PluginIdentifiers.toUnversioned(candidate))));
134
+ }
135
+
136
+ async getInstalledPluginIds(): Promise<PluginIdentifiers.VersionedId[]> {
132
137
  await this.initialized.promise;
133
138
  const backendPlugins = (await this.deployerHandler.getDeployedBackendPlugins())
134
139
  .filter(this.backendPluginHostableFilter);
@@ -136,15 +141,13 @@ export class HostedPluginServerImpl implements HostedPluginServer {
136
141
  this.hostedPlugin.runPluginServer(this.getServerName());
137
142
  }
138
143
  const plugins = new Set<PluginIdentifiers.VersionedId>();
139
- const addIds = async (identifiers: PluginIdentifiers.VersionedId[]): Promise<void> => {
140
- for (const pluginId of identifiers) {
141
- if (this.isRelevantPlugin(pluginId)) {
142
- plugins.add(pluginId);
143
- }
144
- }
145
- };
146
- addIds(await this.deployerHandler.getDeployedFrontendPluginIds());
147
- addIds(await this.deployerHandler.getDeployedBackendPluginIds());
144
+ const addIds = (identifiers: Promise<PluginIdentifiers.VersionedId[]>): Promise<void> => identifiers
145
+ .then(ids => ids.forEach(id => this.isInstalledPlugin(id) && plugins.add(id)));
146
+
147
+ await Promise.all([
148
+ addIds(this.deployerHandler.getDeployedFrontendPluginIds()),
149
+ addIds(this.deployerHandler.getDeployedBackendPluginIds()),
150
+ ]);
148
151
  return Array.from(plugins);
149
152
  }
150
153
 
@@ -155,7 +158,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
155
158
  * The deployment system may have multiple versions of the same plugin available, but
156
159
  * a single session should only ever activate one of them.
157
160
  */
158
- protected isRelevantPlugin(identifier: PluginIdentifiers.VersionedId): boolean {
161
+ protected isInstalledPlugin(identifier: PluginIdentifiers.VersionedId): boolean {
159
162
  const versionAndId = PluginIdentifiers.idAndVersionFromVersionedId(identifier);
160
163
  if (!versionAndId) {
161
164
  return false;
@@ -168,9 +171,6 @@ export class HostedPluginServerImpl implements HostedPluginServer {
168
171
  return false;
169
172
  }
170
173
 
171
- if (this.disabledPlugins.has(identifier)) {
172
- return false;
173
- }
174
174
  if (knownVersion === undefined) {
175
175
  this.pluginVersions.set(versionAndId.id, versionAndId.version);
176
176
  }
@@ -181,7 +181,7 @@ export class HostedPluginServerImpl implements HostedPluginServer {
181
181
  return Promise.resolve(this.uninstallationManager.getUninstalledPluginIds());
182
182
  }
183
183
 
184
- getDisabledPluginIds(): Promise<readonly PluginIdentifiers.VersionedId[]> {
184
+ getDisabledPluginIds(): Promise<readonly PluginIdentifiers.UnversionedId[]> {
185
185
  return Promise.resolve(this.uninstallationManager.getDisabledPluginIds());
186
186
  }
187
187
 
@@ -23,7 +23,7 @@ import {
23
23
  isMcpHttpServerDefinitionDto,
24
24
  } from '../../common/lm-protocol';
25
25
  import { MAIN_RPC_CONTEXT } from '../../common/plugin-api-rpc';
26
- import { MCPServerManager, MCPServerDescription } from '@theia/ai-mcp/lib/common';
26
+ import { MCPServerManager, MCPServerDescription, RemoteMCPServerDescription } from '@theia/ai-mcp/lib/common';
27
27
  import { URI } from '@theia/core';
28
28
 
29
29
  export class McpServerDefinitionRegistryMainImpl implements McpServerDefinitionRegistryMain {
@@ -106,18 +106,16 @@ export class McpServerDefinitionRegistryMainImpl implements McpServerDefinitionR
106
106
  const definitions = await this.$getServerDefinitions(handle);
107
107
 
108
108
  for (const definition of definitions) {
109
- const resolved = await this.$resolveServerDefinition(handle, definition);
110
- if (resolved) {
111
- const mcpServerDescription = this.convertToMcpServerDescription(resolved);
112
- this.mcpServerManager.addOrUpdateServer(mcpServerDescription);
113
- }
109
+ const mcpServerDescription = this.convertToMcpServerDescription(handle, definition);
110
+ this.mcpServerManager.addOrUpdateServer(mcpServerDescription);
114
111
  }
115
112
  } catch (error) {
116
113
  console.error('Error loading MCP server definitions:', error);
117
114
  }
118
115
  }
119
116
 
120
- private convertToMcpServerDescription(definition: McpServerDefinitionDto): MCPServerDescription {
117
+ private convertToMcpServerDescription(handle: number, definition: McpServerDefinitionDto): MCPServerDescription {
118
+ const self = this;
121
119
  if (isMcpHttpServerDefinitionDto(definition)) {
122
120
  // Convert headers values to strings, filtering out null values
123
121
  let convertedHeaders: Record<string, string> | undefined;
@@ -130,12 +128,21 @@ export class McpServerDefinitionRegistryMainImpl implements McpServerDefinitionR
130
128
  }
131
129
  }
132
130
 
133
- return {
131
+ const serverDescription: RemoteMCPServerDescription = {
134
132
  name: definition.label,
135
133
  serverUrl: URI.fromComponents(definition.uri).toString(),
136
134
  headers: convertedHeaders,
137
- autostart: false, // Extensions should manage their own server lifecycle
135
+ autostart: false,
136
+ async resolve(description: MCPServerDescription): Promise<MCPServerDescription> {
137
+ const resolved = await self.$resolveServerDefinition(handle, definition);
138
+ if (resolved) {
139
+ return self.convertToMcpServerDescription(handle, resolved);
140
+ }
141
+ return description;
142
+ }
138
143
  };
144
+
145
+ return serverDescription;
139
146
  }
140
147
 
141
148
  // Convert env values to strings, filtering out null values
@@ -155,6 +162,13 @@ export class McpServerDefinitionRegistryMainImpl implements McpServerDefinitionR
155
162
  args: definition.args,
156
163
  env: convertedEnv,
157
164
  autostart: false, // Extensions should manage their own server lifecycle
165
+ async resolve(serverDescription: MCPServerDescription): Promise<MCPServerDescription> {
166
+ const resolved = await self.$resolveServerDefinition(handle, definition);
167
+ if (resolved) {
168
+ return self.convertToMcpServerDescription(handle, resolved);
169
+ }
170
+ return serverDescription;
171
+ }
158
172
  };
159
173
  }
160
174
  }
@@ -141,11 +141,11 @@ export class PluginDeployerImpl implements PluginDeployer {
141
141
  await this.pluginDeployerHandler.uninstallPlugin(pluginId);
142
142
  }
143
143
 
144
- enablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
144
+ enablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
145
145
  return this.pluginDeployerHandler.enablePlugin(pluginId);
146
146
  }
147
147
 
148
- disablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
148
+ disablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
149
149
  return this.pluginDeployerHandler.disablePlugin(pluginId);
150
150
  }
151
151
 
@@ -64,7 +64,7 @@ export class PluginServerImpl implements PluginServer {
64
64
  return Promise.resolve(this.uninstallationManager.getUninstalledPluginIds());
65
65
  }
66
66
 
67
- getDisabledPlugins(): Promise<readonly PluginIdentifiers.VersionedId[]> {
67
+ getDisabledPlugins(): Promise<readonly PluginIdentifiers.UnversionedId[]> {
68
68
  return Promise.resolve(this.uninstallationManager.getDisabledPluginIds());
69
69
  }
70
70
 
@@ -72,11 +72,11 @@ export class PluginServerImpl implements PluginServer {
72
72
  return this.pluginDeployer.uninstall(pluginId);
73
73
  }
74
74
 
75
- enablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
75
+ enablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
76
76
  return this.pluginDeployer.enablePlugin(pluginId);
77
77
  }
78
78
 
79
- disablePlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
79
+ disablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
80
80
  return this.pluginDeployer.disablePlugin(pluginId);
81
81
  }
82
82
 
@@ -30,11 +30,11 @@ export class PluginUninstallationManager {
30
30
  protected readonly onDidChangeUninstalledPluginsEmitter = new Emitter<readonly PluginIdentifiers.VersionedId[]>();
31
31
  onDidChangeUninstalledPlugins: Event<readonly PluginIdentifiers.VersionedId[]> = this.onDidChangeUninstalledPluginsEmitter.event;
32
32
 
33
- protected readonly onDidChangeDisabledPluginsEmitter = new Emitter<readonly PluginIdentifiers.VersionedId[]>();
34
- onDidChangeDisabledPlugins: Event<readonly PluginIdentifiers.VersionedId[]> = this.onDidChangeDisabledPluginsEmitter.event;
33
+ protected readonly onDidChangeDisabledPluginsEmitter = new Emitter<readonly PluginIdentifiers.UnversionedId[]>();
34
+ onDidChangeDisabledPlugins: Event<readonly PluginIdentifiers.UnversionedId[]> = this.onDidChangeDisabledPluginsEmitter.event;
35
35
 
36
36
  protected uninstalledPlugins: Set<PluginIdentifiers.VersionedId> = new Set();
37
- protected disabledPlugins: Set<PluginIdentifiers.VersionedId> = new Set();
37
+ protected disabledPlugins: Set<PluginIdentifiers.UnversionedId> = new Set();
38
38
 
39
39
  protected readonly initialized = new Deferred<void>();
40
40
 
@@ -45,8 +45,10 @@ export class PluginUninstallationManager {
45
45
 
46
46
  protected async load(): Promise<void> {
47
47
  try {
48
- const disabled: PluginIdentifiers.VersionedId[] = JSON.parse(await this.settingService.get(PluginUninstallationManager.DISABLED_PLUGINS) || '[]');
49
- disabled.forEach(id => this.disabledPlugins.add(id));
48
+ const disabled: (PluginIdentifiers.VersionedId | PluginIdentifiers.UnversionedId)[] =
49
+ JSON.parse(await this.settingService.get(PluginUninstallationManager.DISABLED_PLUGINS) || '[]');
50
+
51
+ disabled.forEach(id => this.disabledPlugins.add(PluginIdentifiers.toUnversioned(id)));
50
52
  } catch (e) {
51
53
  // settings may be corrupt; just carry on
52
54
  console.warn(e);
@@ -91,7 +93,7 @@ export class PluginUninstallationManager {
91
93
  return [...this.uninstalledPlugins];
92
94
  }
93
95
 
94
- async markAsDisabled(...pluginIds: PluginIdentifiers.VersionedId[]): Promise<boolean> {
96
+ async markAsDisabled(...pluginIds: PluginIdentifiers.UnversionedId[]): Promise<boolean> {
95
97
  await this.initialized.promise;
96
98
  let didChange = false;
97
99
  for (const id of pluginIds) {
@@ -107,7 +109,7 @@ export class PluginUninstallationManager {
107
109
  return didChange;
108
110
  }
109
111
 
110
- async markAsEnabled(...pluginIds: PluginIdentifiers.VersionedId[]): Promise<boolean> {
112
+ async markAsEnabled(...pluginIds: PluginIdentifiers.UnversionedId[]): Promise<boolean> {
111
113
  await this.initialized.promise;
112
114
  let didChange = false;
113
115
  for (const id of pluginIds) {
@@ -120,12 +122,12 @@ export class PluginUninstallationManager {
120
122
  return didChange;
121
123
  }
122
124
 
123
- async isDisabled(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
125
+ async isDisabled(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean> {
124
126
  await this.initialized.promise;
125
127
  return this.disabledPlugins.has(pluginId);
126
128
  }
127
129
 
128
- async getDisabledPluginIds(): Promise<readonly PluginIdentifiers.VersionedId[]> {
130
+ async getDisabledPluginIds(): Promise<readonly PluginIdentifiers.UnversionedId[]> {
129
131
  await this.initialized.promise;
130
132
  return [...this.disabledPlugins];
131
133
  }
@@ -32,6 +32,16 @@ export class LogOutputChannelImpl extends OutputChannelImpl implements theia.Log
32
32
  constructor(name: string, proxy: OutputChannelRegistryMain, pluginInfo: PluginInfo) {
33
33
  super(name, proxy, pluginInfo);
34
34
  this.setLogLevel(LogLevel.Info);
35
+
36
+ // Bind overridden and new methods to preserve 'this' context
37
+ // These bindings are needed because the parent class bindings don't apply to overridden methods
38
+ this.append = this.append.bind(this);
39
+ this.appendLine = this.appendLine.bind(this);
40
+ this.trace = this.trace.bind(this);
41
+ this.debug = this.debug.bind(this);
42
+ this.info = this.info.bind(this);
43
+ this.warn = this.warn.bind(this);
44
+ this.error = this.error.bind(this);
35
45
  }
36
46
 
37
47
  setLogLevel(level: theia.LogLevel): void {
@@ -21,6 +21,14 @@ export class OutputChannelImpl implements theia.OutputChannel {
21
21
  private disposed: boolean;
22
22
 
23
23
  constructor(readonly name: string, protected readonly proxy: OutputChannelRegistryMain, protected readonly pluginInfo: PluginInfo) {
24
+ // Bind methods to preserve 'this' context when passed as callbacks
25
+ // This ensures compatibility with extensions that pass these methods as function references
26
+ this.append = this.append.bind(this);
27
+ this.appendLine = this.appendLine.bind(this);
28
+ this.replace = this.replace.bind(this);
29
+ this.clear = this.clear.bind(this);
30
+ this.show = this.show.bind(this);
31
+ this.hide = this.hide.bind(this);
24
32
  }
25
33
 
26
34
  dispose(): void {