coding-tool-x 3.7.11 → 3.7.13
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 +9 -0
- package/README.md +1 -1
- package/dist/web/assets/{Analytics-Ck_00Brj.js → Analytics-8dRv1aYW.js} +1 -1
- package/dist/web/assets/{ConfigTemplates-Cpw2vUa8.js → ConfigTemplates-BQRXSICO.js} +1 -1
- package/dist/web/assets/Home-BtzWhKIa.js +1 -0
- package/dist/web/assets/Home-DYVy4cGZ.css +1 -0
- package/dist/web/assets/{PluginManager-2RlvEJCT.js → PluginManager-BTa-Ygf6.js} +1 -1
- package/dist/web/assets/{ProjectList-_ecCngpl.js → ProjectList-F_cB8ldA.js} +1 -1
- package/dist/web/assets/{SessionList-DlWcw3hO.js → SessionList-LOrbPQvu.js} +1 -1
- package/dist/web/assets/SkillManager-BsX8Qpj0.css +1 -0
- package/dist/web/assets/SkillManager-BzI_t-yV.js +1 -0
- package/dist/web/assets/{WorkspaceManager-3mqghi09.js → WorkspaceManager-Db9RGiz7.js} +1 -1
- package/dist/web/assets/index-DIWJmyL6.js +2 -0
- package/dist/web/assets/{index-BceXgSSe.css → index-bJRG3RXH.css} +1 -1
- package/dist/web/index.html +2 -2
- package/docs/superpowers/plans/2026-08-01-omp-skill-scan-settings.md +759 -0
- package/docs/superpowers/specs/2026-08-01-omp-skill-scan-settings-design.md +224 -0
- package/package.json +1 -1
- package/src/commands/proxy-control.js +12 -12
- package/src/commands/toggle-proxy.js +9 -9
- package/src/config/paths.js +53 -29
- package/src/index.js +1 -1
- package/src/server/api/plugins.js +119 -47
- package/src/server/api/skills.js +63 -10
- package/src/server/omp-proxy-server.js +17 -4
- package/src/server/services/channel-health.js +5 -0
- package/src/server/services/channel-sync-utils.js +1 -1
- package/src/server/services/model-definition-schema.js +2 -1
- package/src/server/services/omp-channels.js +213 -26
- package/src/server/services/omp-config.js +71 -6
- package/src/server/services/omp-native-plugin-adapter.js +456 -0
- package/src/server/services/omp-settings-manager.js +3 -1
- package/src/server/services/omp-skill-discovery.js +358 -0
- package/src/server/services/omp-skill-settings-service.js +97 -0
- package/src/server/services/pi-omp-migration.js +273 -0
- package/src/server/services/platform-resolution.js +44 -0
- package/src/server/services/plugins-service.js +85 -561
- package/src/server/services/project-path-validation.js +65 -0
- package/src/server/services/skill-service.js +169 -77
- package/dist/web/assets/Home-Bft3Kztl.js +0 -1
- package/dist/web/assets/Home-CHZJkkjH.css +0 -1
- package/dist/web/assets/SkillManager-CnY7IXkX.js +0 -1
- package/dist/web/assets/SkillManager-D7pd-d_P.css +0 -1
- package/dist/web/assets/index-k5oP7c-A.js +0 -2
|
@@ -12,14 +12,18 @@ const path = require('path');
|
|
|
12
12
|
const { execFileSync } = require('child_process');
|
|
13
13
|
const toml = require('toml');
|
|
14
14
|
const tomlStringify = require('@iarna/toml').stringify;
|
|
15
|
-
const yaml = require('js-yaml');
|
|
16
15
|
const AdmZip = require('adm-zip');
|
|
17
16
|
const { listPlugins, getPlugin, updatePlugin: updatePluginRegistry } = require('../../plugins/registry');
|
|
18
17
|
const { installPlugin: installPluginCore, uninstallPlugin: uninstallPluginCore } = require('../../plugins/plugin-installer');
|
|
19
18
|
const { initializePlugins, shutdownPlugins } = require('../../plugins/plugin-manager');
|
|
20
19
|
const { INSTALLED_DIR, CONFIG_DIR } = require('../../plugins/constants');
|
|
21
20
|
const { NATIVE_PATHS, PATHS } = require('../../config/paths');
|
|
22
|
-
const {
|
|
21
|
+
const { OmpNativePluginAdapter } = require('./omp-native-plugin-adapter');
|
|
22
|
+
const {
|
|
23
|
+
importLegacyPluginRepos,
|
|
24
|
+
migratePiStorage
|
|
25
|
+
} = require('./pi-omp-migration');
|
|
26
|
+
const { resolveManagedPlatform } = require('./platform-resolution');
|
|
23
27
|
const { maskToken } = require('./oauth-utils');
|
|
24
28
|
const {
|
|
25
29
|
assertInsideAllowedRoots,
|
|
@@ -48,7 +52,6 @@ const DEFAULT_REPOS_BY_PLATFORM = {
|
|
|
48
52
|
opencode: [],
|
|
49
53
|
omp: []
|
|
50
54
|
};
|
|
51
|
-
const SUPPORTED_PLATFORMS = ['claude', 'codex', 'gemini', 'opencode', 'omp'];
|
|
52
55
|
const PLATFORM_CAPABILITIES = {
|
|
53
56
|
claude: {
|
|
54
57
|
platform: 'claude',
|
|
@@ -109,8 +112,11 @@ const PLATFORM_CAPABILITIES = {
|
|
|
109
112
|
toggle: true,
|
|
110
113
|
config: true,
|
|
111
114
|
import: false,
|
|
112
|
-
syncRepos:
|
|
113
|
-
pluginKindLabel: '
|
|
115
|
+
syncRepos: true,
|
|
116
|
+
pluginKindLabel: 'plugins/extensions',
|
|
117
|
+
repositoryMode: 'native-marketplace',
|
|
118
|
+
repositoryToggle: false,
|
|
119
|
+
repositoryAuth: false
|
|
114
120
|
}
|
|
115
121
|
};
|
|
116
122
|
|
|
@@ -194,58 +200,6 @@ function splitPluginMarketplaceKey(key = '') {
|
|
|
194
200
|
};
|
|
195
201
|
}
|
|
196
202
|
|
|
197
|
-
function normalizeOmpPackageEntry(item = null) {
|
|
198
|
-
if (typeof item === 'string') {
|
|
199
|
-
const name = item.trim();
|
|
200
|
-
return name ? {
|
|
201
|
-
name,
|
|
202
|
-
source: name,
|
|
203
|
-
directory: name,
|
|
204
|
-
installSource: name,
|
|
205
|
-
resourceTypes: []
|
|
206
|
-
} : null;
|
|
207
|
-
}
|
|
208
|
-
if (!item || typeof item !== 'object') return null;
|
|
209
|
-
|
|
210
|
-
const rawName = item.name || item.package || item.id || item.source || item.path || '';
|
|
211
|
-
const name = String(rawName || '').trim();
|
|
212
|
-
if (!name) return null;
|
|
213
|
-
|
|
214
|
-
const directory = String(item.directory || item.path || name).trim() || name;
|
|
215
|
-
const installSource = String(item.installSource || item.source || item.url || item.packageSource || name).trim() || name;
|
|
216
|
-
return {
|
|
217
|
-
...item,
|
|
218
|
-
name,
|
|
219
|
-
source: item.source || installSource,
|
|
220
|
-
directory,
|
|
221
|
-
installSource,
|
|
222
|
-
resourceTypes: normalizeOmpResourceTypes(item.resourceTypes || item.resources || item.provides || item.capabilities)
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function getOmpPackageIdentity(item = null) {
|
|
227
|
-
const normalized = normalizeOmpPackageEntry(item);
|
|
228
|
-
return normalized?.name || '';
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function ompPackageSettingValue(item = null) {
|
|
232
|
-
const normalized = normalizeOmpPackageEntry(item);
|
|
233
|
-
if (!normalized) return null;
|
|
234
|
-
if (typeof item === 'string') return normalized.name;
|
|
235
|
-
|
|
236
|
-
const next = { ...item };
|
|
237
|
-
next.name = normalized.name;
|
|
238
|
-
next.directory = normalized.directory;
|
|
239
|
-
next.source = normalized.installSource;
|
|
240
|
-
const resourceTypes = normalizeOmpResourceTypes(next.resourceTypes || next.resources || normalized.resourceTypes);
|
|
241
|
-
if (resourceTypes.length > 0) {
|
|
242
|
-
next.resourceTypes = resourceTypes;
|
|
243
|
-
} else {
|
|
244
|
-
delete next.resourceTypes;
|
|
245
|
-
}
|
|
246
|
-
return next;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
203
|
function normalizeOmpResourceType(value = '') {
|
|
250
204
|
const normalized = String(value || '').trim();
|
|
251
205
|
if (!normalized) return '';
|
|
@@ -304,17 +258,6 @@ function normalizeOmpResourceTypes(input = []) {
|
|
|
304
258
|
return values;
|
|
305
259
|
}
|
|
306
260
|
|
|
307
|
-
function isOmpPackageInstallSource(value = '') {
|
|
308
|
-
const source = String(value || '').trim();
|
|
309
|
-
if (!source) return false;
|
|
310
|
-
if (isLikelyLocalPath(source)) return true;
|
|
311
|
-
if (/^(npm|git):/i.test(source)) return true;
|
|
312
|
-
if (/^https?:\/\//i.test(source)) return true;
|
|
313
|
-
if (/^ssh:\/\//i.test(source)) return true;
|
|
314
|
-
if (/^git@[^:]+:.+/i.test(source)) return true;
|
|
315
|
-
return !source.startsWith('-');
|
|
316
|
-
}
|
|
317
|
-
|
|
318
261
|
function normalizeMarketplaceSkillPaths(skills = []) {
|
|
319
262
|
if (!Array.isArray(skills)) return [];
|
|
320
263
|
return skills
|
|
@@ -493,7 +436,12 @@ function stripJsonComments(input = '') {
|
|
|
493
436
|
|
|
494
437
|
class PluginsService {
|
|
495
438
|
constructor(platform = 'claude') {
|
|
496
|
-
this.platform =
|
|
439
|
+
this.platform = resolveManagedPlatform(platform).platform;
|
|
440
|
+
this._ompMigrationWarnings = [];
|
|
441
|
+
if (this.platform === 'omp') {
|
|
442
|
+
const migration = migratePiStorage(PATHS);
|
|
443
|
+
this._ompMigrationWarnings.push(...migration.warnings);
|
|
444
|
+
}
|
|
497
445
|
this.configDir = PATHS.config || path.join((PATHS.base || process.env.HOME || os.homedir()), 'config');
|
|
498
446
|
this.ccToolConfigDir = path.dirname(PATHS.pluginRepos.claude);
|
|
499
447
|
this.opencodePluginsDir = path.join(OPENCODE_CONFIG_DIR, 'plugins');
|
|
@@ -501,12 +449,19 @@ class PluginsService {
|
|
|
501
449
|
this.codexPluginsCacheDir = CODEX_PLUGINS_CACHE_DIR;
|
|
502
450
|
this.marketCachePath = PATHS.pluginMarketCache[this.platform] || PATHS.pluginMarketCache.claude;
|
|
503
451
|
this._marketCache = null;
|
|
452
|
+
this.ompNativeAdapter = this.platform === 'omp'
|
|
453
|
+
? new OmpNativePluginAdapter()
|
|
454
|
+
: null;
|
|
504
455
|
}
|
|
505
456
|
|
|
506
457
|
getCapabilities() {
|
|
507
458
|
return { ...(PLATFORM_CAPABILITIES[this.platform] || PLATFORM_CAPABILITIES.claude) };
|
|
508
459
|
}
|
|
509
460
|
|
|
461
|
+
getMigrationWarnings() {
|
|
462
|
+
return [...this._ompMigrationWarnings];
|
|
463
|
+
}
|
|
464
|
+
|
|
510
465
|
_pluginsSupported() {
|
|
511
466
|
return this.getCapabilities().supportsPlugins !== false;
|
|
512
467
|
}
|
|
@@ -748,195 +703,6 @@ class PluginsService {
|
|
|
748
703
|
return json;
|
|
749
704
|
}
|
|
750
705
|
|
|
751
|
-
_readOmpSettings() {
|
|
752
|
-
const filePath = NATIVE_PATHS.omp.settings;
|
|
753
|
-
if (!fs.existsSync(filePath)) {
|
|
754
|
-
const legacyPath = NATIVE_PATHS.omp.settingsJsonLegacy;
|
|
755
|
-
if (legacyPath && fs.existsSync(legacyPath)) {
|
|
756
|
-
try {
|
|
757
|
-
const raw = fs.readFileSync(legacyPath, 'utf8');
|
|
758
|
-
return raw.trim() ? JSON.parse(raw) : {};
|
|
759
|
-
} catch (err) {
|
|
760
|
-
console.error('[PluginsService] Failed to read legacy OMP settings:', err.message);
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
return {};
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
try {
|
|
767
|
-
const raw = fs.readFileSync(filePath, 'utf8');
|
|
768
|
-
const parsed = raw.trim() ? yaml.load(raw) : {};
|
|
769
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
770
|
-
} catch (err) {
|
|
771
|
-
console.error('[PluginsService] Failed to read OMP settings:', err.message);
|
|
772
|
-
return {};
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
_writeOmpSettings(settings = {}) {
|
|
777
|
-
this._ensureDir(path.dirname(NATIVE_PATHS.omp.settings));
|
|
778
|
-
fs.writeFileSync(NATIVE_PATHS.omp.settings, yaml.dump(settings, {
|
|
779
|
-
lineWidth: 120,
|
|
780
|
-
noRefs: true,
|
|
781
|
-
sortKeys: false
|
|
782
|
-
}), 'utf8');
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
_listOmpPackages() {
|
|
786
|
-
const settings = this._readOmpSettings();
|
|
787
|
-
return Array.isArray(settings.packages)
|
|
788
|
-
? settings.packages.map(normalizeOmpPackageEntry).filter(Boolean)
|
|
789
|
-
: [];
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
_setOmpPackages(packages = []) {
|
|
793
|
-
const settings = this._readOmpSettings();
|
|
794
|
-
const seen = new Set();
|
|
795
|
-
settings.packages = packages
|
|
796
|
-
.map(item => ompPackageSettingValue(item))
|
|
797
|
-
.filter((item) => {
|
|
798
|
-
const name = getOmpPackageIdentity(item);
|
|
799
|
-
if (!name || seen.has(name)) return false;
|
|
800
|
-
seen.add(name);
|
|
801
|
-
return true;
|
|
802
|
-
});
|
|
803
|
-
this._writeOmpSettings(settings);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
_listOmpDisabledPackageEntries() {
|
|
807
|
-
const settings = this._readOmpSettings();
|
|
808
|
-
return Array.isArray(settings.disabledPackages)
|
|
809
|
-
? settings.disabledPackages.map(normalizeOmpPackageEntry).filter(Boolean)
|
|
810
|
-
: [];
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
_listOmpDisabledPackages() {
|
|
814
|
-
return this._listOmpDisabledPackageEntries().map(item => item.name).filter(Boolean);
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
_setOmpDisabledPackages(packages = []) {
|
|
818
|
-
const settings = this._readOmpSettings();
|
|
819
|
-
const seen = new Set();
|
|
820
|
-
settings.disabledPackages = packages
|
|
821
|
-
.map(item => ompPackageSettingValue(item))
|
|
822
|
-
.filter((item) => {
|
|
823
|
-
const name = getOmpPackageIdentity(item);
|
|
824
|
-
if (!name || seen.has(name)) return false;
|
|
825
|
-
seen.add(name);
|
|
826
|
-
return true;
|
|
827
|
-
});
|
|
828
|
-
this._writeOmpSettings(settings);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
_runOmpPackageCommand(args = []) {
|
|
832
|
-
execFileSync(getOmpCommand(), args, {
|
|
833
|
-
cwd: process.cwd(),
|
|
834
|
-
encoding: 'utf8',
|
|
835
|
-
stdio: 'pipe',
|
|
836
|
-
timeout: 120000,
|
|
837
|
-
windowsHide: true
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
_registerOmpPackageReference(packageName, metadata = {}) {
|
|
842
|
-
const packages = this._listOmpPackages();
|
|
843
|
-
const installSource = String(metadata.installSource || metadata.source || packageName || '').trim();
|
|
844
|
-
const displayName = String(metadata.name || packageName || installSource).trim();
|
|
845
|
-
if (!packages.some(pkg => pkg.name === displayName || pkg.installSource === installSource)) {
|
|
846
|
-
const resourceTypes = normalizeOmpResourceTypes(metadata.resourceTypes || metadata.resources);
|
|
847
|
-
const entry = installSource && installSource !== displayName
|
|
848
|
-
? {
|
|
849
|
-
name: displayName,
|
|
850
|
-
source: installSource,
|
|
851
|
-
...(metadata.version ? { version: metadata.version } : {}),
|
|
852
|
-
...(metadata.description ? { description: metadata.description } : {}),
|
|
853
|
-
...(resourceTypes.length > 0 ? { resourceTypes } : {})
|
|
854
|
-
}
|
|
855
|
-
: displayName;
|
|
856
|
-
packages.push(entry);
|
|
857
|
-
this._setOmpPackages(packages);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
_buildOmpPackagePlugin(packageName, metadata = {}) {
|
|
862
|
-
const installSource = String(metadata.installSource || metadata.source || packageName || '').trim();
|
|
863
|
-
const name = String(metadata.name || packageName || installSource).trim();
|
|
864
|
-
const resourceTypes = normalizeOmpResourceTypes(metadata.resourceTypes || metadata.resources);
|
|
865
|
-
return {
|
|
866
|
-
name,
|
|
867
|
-
directory: name,
|
|
868
|
-
installSource: installSource || name,
|
|
869
|
-
version: metadata.version || 'latest',
|
|
870
|
-
description: metadata.description || '',
|
|
871
|
-
pluginKind: 'package',
|
|
872
|
-
pluginType: 'package',
|
|
873
|
-
...(resourceTypes.length > 0 ? { resourceTypes } : {})
|
|
874
|
-
};
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
_installOmpPackage(packageName, metadata = {}) {
|
|
878
|
-
const installSource = String(metadata.installSource || metadata.source || packageName || '').trim();
|
|
879
|
-
const plugin = this._buildOmpPackagePlugin(packageName, { ...metadata, installSource });
|
|
880
|
-
try {
|
|
881
|
-
this._runOmpPackageCommand(['install', installSource || packageName]);
|
|
882
|
-
return {
|
|
883
|
-
success: true,
|
|
884
|
-
plugin
|
|
885
|
-
};
|
|
886
|
-
} catch (err) {
|
|
887
|
-
this._registerOmpPackageReference(packageName, { ...metadata, installSource, name: plugin.name });
|
|
888
|
-
return {
|
|
889
|
-
success: true,
|
|
890
|
-
registeredOnly: true,
|
|
891
|
-
warning: `Failed to run "${getOmpCommand()} install"; saved the package reference so OMP can resolve it later. ${err.message}`,
|
|
892
|
-
plugin
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
_removeOmpPackage(packageName) {
|
|
898
|
-
try {
|
|
899
|
-
this._runOmpPackageCommand(['remove', packageName]);
|
|
900
|
-
return true;
|
|
901
|
-
} catch (err) {
|
|
902
|
-
return false;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
_listOmpLocalExtensions() {
|
|
907
|
-
const plugins = [];
|
|
908
|
-
const extensionsDir = NATIVE_PATHS.omp.extensions;
|
|
909
|
-
if (!fs.existsSync(extensionsDir)) return plugins;
|
|
910
|
-
|
|
911
|
-
try {
|
|
912
|
-
const disabled = new Set(this._listOmpDisabledPackages());
|
|
913
|
-
const entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
|
914
|
-
for (const entry of entries) {
|
|
915
|
-
if (entry.name.startsWith('.')) continue;
|
|
916
|
-
const fullPath = path.join(extensionsDir, entry.name);
|
|
917
|
-
const ext = path.extname(entry.name).toLowerCase();
|
|
918
|
-
if (!entry.isDirectory() && !['.js', '.mjs', '.cjs', '.ts'].includes(ext)) continue;
|
|
919
|
-
const name = entry.isDirectory() ? entry.name : entry.name.slice(0, -ext.length);
|
|
920
|
-
plugins.push({
|
|
921
|
-
name,
|
|
922
|
-
directory: entry.name,
|
|
923
|
-
installPath: fullPath,
|
|
924
|
-
source: 'omp-extension',
|
|
925
|
-
version: 'local',
|
|
926
|
-
description: '',
|
|
927
|
-
installed: true,
|
|
928
|
-
enabled: !disabled.has(name) && !disabled.has(entry.name),
|
|
929
|
-
pluginType: entry.isDirectory() ? 'extension-directory' : 'extension-file',
|
|
930
|
-
pluginKind: 'extension'
|
|
931
|
-
});
|
|
932
|
-
}
|
|
933
|
-
} catch (err) {
|
|
934
|
-
console.error('[PluginsService] Failed to list OMP extensions:', err.message);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
return plugins;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
706
|
_readOpenCodeConfig() {
|
|
941
707
|
const filePath = this._getOpenCodeConfigPath();
|
|
942
708
|
if (!fs.existsSync(filePath)) return { filePath, config: {} };
|
|
@@ -1415,7 +1181,7 @@ class PluginsService {
|
|
|
1415
1181
|
* Reads from Claude Code's native installed_plugins.json
|
|
1416
1182
|
* @returns {Object} { plugins: Array }
|
|
1417
1183
|
*/
|
|
1418
|
-
listPlugins() {
|
|
1184
|
+
listPlugins(options = {}) {
|
|
1419
1185
|
if (!this._pluginsSupported()) {
|
|
1420
1186
|
return { plugins: [] };
|
|
1421
1187
|
}
|
|
@@ -1454,38 +1220,7 @@ class PluginsService {
|
|
|
1454
1220
|
}
|
|
1455
1221
|
|
|
1456
1222
|
if (this._isOmp()) {
|
|
1457
|
-
|
|
1458
|
-
const disabled = new Set(disabledEntries.flatMap(item => [item.name, item.installSource].filter(Boolean)));
|
|
1459
|
-
const plugins = [];
|
|
1460
|
-
const seen = new Set();
|
|
1461
|
-
|
|
1462
|
-
for (const pkg of this._listOmpPackages()) {
|
|
1463
|
-
const seenKey = pkg.installSource || pkg.name;
|
|
1464
|
-
if (seen.has(seenKey)) continue;
|
|
1465
|
-
seen.add(seenKey);
|
|
1466
|
-
plugins.push({
|
|
1467
|
-
...pkg,
|
|
1468
|
-
name: pkg.name,
|
|
1469
|
-
directory: pkg.directory || pkg.name,
|
|
1470
|
-
installSource: pkg.installSource || pkg.source || pkg.name,
|
|
1471
|
-
resourceTypes: normalizeOmpResourceTypes(pkg.resourceTypes || pkg.resources),
|
|
1472
|
-
source: 'omp-settings',
|
|
1473
|
-
version: pkg.version || 'latest',
|
|
1474
|
-
description: pkg.description || '',
|
|
1475
|
-
installed: true,
|
|
1476
|
-
enabled: !disabled.has(pkg.name) && !disabled.has(pkg.installSource),
|
|
1477
|
-
pluginType: 'package',
|
|
1478
|
-
pluginKind: 'package'
|
|
1479
|
-
});
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
for (const extension of this._listOmpLocalExtensions()) {
|
|
1483
|
-
if (seen.has(extension.name)) continue;
|
|
1484
|
-
seen.add(extension.name);
|
|
1485
|
-
plugins.push(extension);
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
return { plugins };
|
|
1223
|
+
return this.ompNativeAdapter.listPlugins(options);
|
|
1489
1224
|
}
|
|
1490
1225
|
|
|
1491
1226
|
const plugins = [];
|
|
@@ -1604,7 +1339,7 @@ class PluginsService {
|
|
|
1604
1339
|
* @param {string} name - Plugin name
|
|
1605
1340
|
* @returns {Object|null} Plugin details or null
|
|
1606
1341
|
*/
|
|
1607
|
-
getPlugin(name) {
|
|
1342
|
+
getPlugin(name, options = {}) {
|
|
1608
1343
|
if (this._isCodex()) {
|
|
1609
1344
|
const plugin = this.listPlugins().plugins.find(p => p.name === name || `${p.name}@${p.marketplace}` === name);
|
|
1610
1345
|
if (!plugin) return null;
|
|
@@ -1628,7 +1363,9 @@ class PluginsService {
|
|
|
1628
1363
|
}
|
|
1629
1364
|
|
|
1630
1365
|
if (this._isOmp()) {
|
|
1631
|
-
const plugin = this.listPlugins().plugins.find(p =>
|
|
1366
|
+
const plugin = this.listPlugins(options).plugins.find(p =>
|
|
1367
|
+
p.pluginId === name || p.id === name || p.name === name
|
|
1368
|
+
);
|
|
1632
1369
|
if (!plugin) return null;
|
|
1633
1370
|
return plugin;
|
|
1634
1371
|
}
|
|
@@ -1667,7 +1404,7 @@ class PluginsService {
|
|
|
1667
1404
|
* @param {Object} repoInfo - Optional repo info { owner, name, branch, directory }
|
|
1668
1405
|
* @returns {Promise<Object>} Installation result
|
|
1669
1406
|
*/
|
|
1670
|
-
async installPlugin(source, repoInfo = null) {
|
|
1407
|
+
async installPlugin(source, repoInfo = null, options = {}) {
|
|
1671
1408
|
if (this._isCodex()) {
|
|
1672
1409
|
if (hasRepoInstallInfo(repoInfo)) {
|
|
1673
1410
|
return this._installFromRepoDirectory(repoInfo);
|
|
@@ -1697,48 +1434,15 @@ class PluginsService {
|
|
|
1697
1434
|
}
|
|
1698
1435
|
|
|
1699
1436
|
if (this._isOmp()) {
|
|
1700
|
-
const
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
const explicitPackageSource = String(source || packageMetadata.installSource || '').trim();
|
|
1710
|
-
|
|
1711
|
-
if (
|
|
1712
|
-
repoInfo?.pluginKind === 'package' ||
|
|
1713
|
-
repoInfo?.pluginType === 'package' ||
|
|
1714
|
-
(explicitPackageSource && isOmpPackageInstallSource(explicitPackageSource) && !hasRepoInstallInfo(repoInfo))
|
|
1715
|
-
) {
|
|
1716
|
-
return this._installOmpPackage(explicitPackageSource, packageMetadata);
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
if (hasRepoInstallInfo(repoInfo)) {
|
|
1720
|
-
return this._installFromRepoDirectory(repoInfo, { installRoot: NATIVE_PATHS.omp.extensions });
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
const parsedSource = this.parseRepoTreeSource(source);
|
|
1724
|
-
if (parsedSource) {
|
|
1725
|
-
return this._installOmpPackage(source);
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
const parsedRepo = this._repoFromGitUrl(source, 'main');
|
|
1729
|
-
if (parsedRepo) {
|
|
1730
|
-
return this._installOmpPackage(source);
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
const packageName = String(source || '').trim();
|
|
1734
|
-
if (packageName && isOmpPackageInstallSource(packageName)) {
|
|
1735
|
-
return this._installOmpPackage(packageName);
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
return {
|
|
1739
|
-
success: false,
|
|
1740
|
-
error: 'OMP plugin install expects package name, repository metadata, a GitHub/GitLab tree URL, or a Git repository URL'
|
|
1741
|
-
};
|
|
1437
|
+
const metadata = repoInfo && typeof repoInfo === 'object' ? repoInfo : {};
|
|
1438
|
+
const target = String(
|
|
1439
|
+
source
|
|
1440
|
+
|| metadata.pluginId
|
|
1441
|
+
|| metadata.installTarget
|
|
1442
|
+
|| metadata.installSource
|
|
1443
|
+
|| ''
|
|
1444
|
+
).trim();
|
|
1445
|
+
return this.ompNativeAdapter.installPlugin(target, metadata, options);
|
|
1742
1446
|
}
|
|
1743
1447
|
|
|
1744
1448
|
if (this._isOpenCode()) {
|
|
@@ -1979,7 +1683,7 @@ class PluginsService {
|
|
|
1979
1683
|
} catch (e) {
|
|
1980
1684
|
console.error('[PluginsService] Failed to update native installed_plugins.json:', e.message);
|
|
1981
1685
|
}
|
|
1982
|
-
} else if (!this._isOpenCode()
|
|
1686
|
+
} else if (!this._isOpenCode()) {
|
|
1983
1687
|
const installTimestamp = new Date().toISOString();
|
|
1984
1688
|
const sourceUrl = this.buildRepoBrowserUrl(normalizedRepo, directory) || buildRepoUrl(normalizedRepo);
|
|
1985
1689
|
const repoSourceMeta = {
|
|
@@ -2009,21 +1713,6 @@ class PluginsService {
|
|
|
2009
1713
|
}
|
|
2010
1714
|
|
|
2011
1715
|
this.writeRepoSourceMeta(pluginDir, repoSourceMeta);
|
|
2012
|
-
} else if (this._isOmp()) {
|
|
2013
|
-
const sourceUrl = this.buildRepoBrowserUrl(normalizedRepo, directory) || buildRepoUrl(normalizedRepo);
|
|
2014
|
-
this.writeRepoSourceMeta(pluginDir, {
|
|
2015
|
-
repoId: normalizedRepo.id,
|
|
2016
|
-
repoProvider: normalizedRepo.provider,
|
|
2017
|
-
repoOwner: normalizedRepo.owner || '',
|
|
2018
|
-
repoName: normalizedRepo.name || '',
|
|
2019
|
-
repoBranch: normalizedRepo.branch,
|
|
2020
|
-
repoDirectory: directory,
|
|
2021
|
-
repoHost: normalizedRepo.host || '',
|
|
2022
|
-
repoProjectPath: normalizedRepo.projectPath || '',
|
|
2023
|
-
repoLocalPath: normalizedRepo.localPath || '',
|
|
2024
|
-
repoUrl: normalizedRepo.repoUrl || buildRepoUrl(normalizedRepo),
|
|
2025
|
-
source: sourceUrl
|
|
2026
|
-
});
|
|
2027
1716
|
}
|
|
2028
1717
|
|
|
2029
1718
|
return {
|
|
@@ -2049,9 +1738,6 @@ class PluginsService {
|
|
|
2049
1738
|
if (this._isOpenCode()) {
|
|
2050
1739
|
return ['package.json', 'plugin.json'];
|
|
2051
1740
|
}
|
|
2052
|
-
if (this._isOmp()) {
|
|
2053
|
-
return ['omp.json', 'extension.json', 'plugin.json', 'package.json'];
|
|
2054
|
-
}
|
|
2055
1741
|
return ['.claude-plugin/plugin.json', 'plugin.json', 'package.json'];
|
|
2056
1742
|
}
|
|
2057
1743
|
|
|
@@ -2140,7 +1826,7 @@ class PluginsService {
|
|
|
2140
1826
|
* @param {string} name - Plugin name
|
|
2141
1827
|
* @returns {Object} Uninstallation result
|
|
2142
1828
|
*/
|
|
2143
|
-
uninstallPlugin(name) {
|
|
1829
|
+
uninstallPlugin(name, options = {}) {
|
|
2144
1830
|
if (this._isCodex()) {
|
|
2145
1831
|
const plugins = this.listPlugins().plugins;
|
|
2146
1832
|
const target = plugins.find(plugin => plugin.name === name || `${plugin.name}@${plugin.marketplace}` === name);
|
|
@@ -2184,68 +1870,7 @@ class PluginsService {
|
|
|
2184
1870
|
}
|
|
2185
1871
|
|
|
2186
1872
|
if (this._isOmp()) {
|
|
2187
|
-
|
|
2188
|
-
let safeName = '';
|
|
2189
|
-
try {
|
|
2190
|
-
safeName = normalizePluginPathName(targetName, 'plugin name');
|
|
2191
|
-
} catch {
|
|
2192
|
-
safeName = '';
|
|
2193
|
-
}
|
|
2194
|
-
const packages = this._listOmpPackages();
|
|
2195
|
-
let removed = false;
|
|
2196
|
-
const packageToRemove = packages.find(pkg =>
|
|
2197
|
-
pkg.name === targetName ||
|
|
2198
|
-
pkg.name === safeName ||
|
|
2199
|
-
pkg.installSource === targetName ||
|
|
2200
|
-
pkg.installSource === safeName
|
|
2201
|
-
);
|
|
2202
|
-
if (packageToRemove) {
|
|
2203
|
-
this._removeOmpPackage(packageToRemove.installSource || packageToRemove.name);
|
|
2204
|
-
}
|
|
2205
|
-
const nextPackages = packages.filter(pkg =>
|
|
2206
|
-
pkg.name !== safeName &&
|
|
2207
|
-
pkg.name !== targetName &&
|
|
2208
|
-
pkg.installSource !== safeName &&
|
|
2209
|
-
pkg.installSource !== targetName
|
|
2210
|
-
);
|
|
2211
|
-
if (nextPackages.length !== packages.length) {
|
|
2212
|
-
this._setOmpPackages(nextPackages);
|
|
2213
|
-
const disabledEntries = this._listOmpDisabledPackageEntries().filter(pkg =>
|
|
2214
|
-
pkg.name !== safeName &&
|
|
2215
|
-
pkg.name !== targetName &&
|
|
2216
|
-
pkg.installSource !== safeName &&
|
|
2217
|
-
pkg.installSource !== targetName &&
|
|
2218
|
-
pkg.name !== packageToRemove?.name &&
|
|
2219
|
-
pkg.installSource !== packageToRemove?.installSource
|
|
2220
|
-
);
|
|
2221
|
-
this._setOmpDisabledPackages(disabledEntries);
|
|
2222
|
-
removed = true;
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
|
-
const extensionsDir = NATIVE_PATHS.omp.extensions;
|
|
2226
|
-
if (safeName && fs.existsSync(extensionsDir)) {
|
|
2227
|
-
const directPath = resolveInsideRoot(extensionsDir, safeName, 'OMP extension path');
|
|
2228
|
-
if (fs.existsSync(directPath)) {
|
|
2229
|
-
fs.rmSync(directPath, { recursive: true, force: true });
|
|
2230
|
-
removed = true;
|
|
2231
|
-
} else {
|
|
2232
|
-
const entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
|
2233
|
-
for (const entry of entries) {
|
|
2234
|
-
const baseName = entry.name.replace(path.extname(entry.name), '');
|
|
2235
|
-
if (entry.name === safeName || baseName === safeName) {
|
|
2236
|
-
const entryPath = resolveInsideRoot(extensionsDir, entry.name, 'OMP extension path');
|
|
2237
|
-
fs.rmSync(entryPath, { recursive: true, force: true });
|
|
2238
|
-
removed = true;
|
|
2239
|
-
break;
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
return {
|
|
2246
|
-
success: true,
|
|
2247
|
-
message: removed ? 'Plugin removed successfully' : 'Plugin not found'
|
|
2248
|
-
};
|
|
1873
|
+
return this.ompNativeAdapter.uninstallPlugin(name, options);
|
|
2249
1874
|
}
|
|
2250
1875
|
|
|
2251
1876
|
if (this._isOpenCode()) {
|
|
@@ -2361,7 +1986,7 @@ class PluginsService {
|
|
|
2361
1986
|
* @param {boolean} enabled - Enable or disable
|
|
2362
1987
|
* @returns {Object} Updated plugin info
|
|
2363
1988
|
*/
|
|
2364
|
-
togglePlugin(name, enabled) {
|
|
1989
|
+
togglePlugin(name, enabled, options = {}) {
|
|
2365
1990
|
if (this._isCodex()) {
|
|
2366
1991
|
const plugins = this.listPlugins().plugins;
|
|
2367
1992
|
const target = plugins.find(plugin => plugin.name === name || `${plugin.name}@${plugin.marketplace}` === name);
|
|
@@ -2381,26 +2006,7 @@ class PluginsService {
|
|
|
2381
2006
|
}
|
|
2382
2007
|
|
|
2383
2008
|
if (this._isOmp()) {
|
|
2384
|
-
|
|
2385
|
-
const packages = this._listOmpPackages();
|
|
2386
|
-
const targetPackage = packages.find(pkg => pkg.name === targetName || pkg.installSource === targetName);
|
|
2387
|
-
const disabledEntries = this._listOmpDisabledPackageEntries();
|
|
2388
|
-
const disabled = new Set(disabledEntries.flatMap(item => [item.name, item.installSource].filter(Boolean)));
|
|
2389
|
-
if (enabled) {
|
|
2390
|
-
disabled.delete(targetName);
|
|
2391
|
-
if (targetPackage) {
|
|
2392
|
-
disabled.delete(targetPackage.name);
|
|
2393
|
-
disabled.delete(targetPackage.installSource);
|
|
2394
|
-
}
|
|
2395
|
-
} else {
|
|
2396
|
-
disabled.add(targetPackage || targetName);
|
|
2397
|
-
}
|
|
2398
|
-
this._setOmpDisabledPackages(Array.from(disabled));
|
|
2399
|
-
return {
|
|
2400
|
-
name: targetName,
|
|
2401
|
-
enabled,
|
|
2402
|
-
success: true
|
|
2403
|
-
};
|
|
2009
|
+
return this.ompNativeAdapter.togglePlugin(name, enabled, options);
|
|
2404
2010
|
}
|
|
2405
2011
|
|
|
2406
2012
|
if (this._isOpenCode()) {
|
|
@@ -2487,7 +2093,7 @@ class PluginsService {
|
|
|
2487
2093
|
* @param {Object} config - Configuration object
|
|
2488
2094
|
* @returns {Object} Result
|
|
2489
2095
|
*/
|
|
2490
|
-
updatePluginConfig(name, config) {
|
|
2096
|
+
updatePluginConfig(name, config, options = {}) {
|
|
2491
2097
|
if (this._isCodex()) {
|
|
2492
2098
|
throw new Error('Codex cached plugins do not support config updates');
|
|
2493
2099
|
}
|
|
@@ -2497,16 +2103,7 @@ class PluginsService {
|
|
|
2497
2103
|
}
|
|
2498
2104
|
|
|
2499
2105
|
if (this._isOmp()) {
|
|
2500
|
-
|
|
2501
|
-
settings.packageConfig = settings.packageConfig && typeof settings.packageConfig === 'object' && !Array.isArray(settings.packageConfig)
|
|
2502
|
-
? settings.packageConfig
|
|
2503
|
-
: {};
|
|
2504
|
-
settings.packageConfig[name] = config;
|
|
2505
|
-
this._writeOmpSettings(settings);
|
|
2506
|
-
return {
|
|
2507
|
-
success: true,
|
|
2508
|
-
message: `Configuration updated for plugin "${name}"`
|
|
2509
|
-
};
|
|
2106
|
+
return this.ompNativeAdapter.updatePluginConfig(name, config, options);
|
|
2510
2107
|
}
|
|
2511
2108
|
|
|
2512
2109
|
if (this._isOpenCode()) {
|
|
@@ -2591,10 +2188,15 @@ class PluginsService {
|
|
|
2591
2188
|
* Reads from both our config and Claude Code's native marketplace config
|
|
2592
2189
|
* @returns {Array} Repos list
|
|
2593
2190
|
*/
|
|
2594
|
-
getRepos() {
|
|
2191
|
+
getRepos(options = {}) {
|
|
2595
2192
|
if (!this.getCapabilities().repositories) {
|
|
2596
2193
|
return [];
|
|
2597
2194
|
}
|
|
2195
|
+
if (this._isOmp()) {
|
|
2196
|
+
const migration = importLegacyPluginRepos(this.ompNativeAdapter, PATHS, options);
|
|
2197
|
+
this._ompMigrationWarnings = migration.warnings;
|
|
2198
|
+
return this.ompNativeAdapter.listMarketplaces(options);
|
|
2199
|
+
}
|
|
2598
2200
|
|
|
2599
2201
|
const repos = [];
|
|
2600
2202
|
const seenRepos = new Set();
|
|
@@ -2667,7 +2269,12 @@ class PluginsService {
|
|
|
2667
2269
|
* @param {Object} repo - Repository info { url, owner, name, branch, enabled }
|
|
2668
2270
|
* @returns {Array} Updated repos list
|
|
2669
2271
|
*/
|
|
2670
|
-
addRepo(repo) {
|
|
2272
|
+
addRepo(repo, options = {}) {
|
|
2273
|
+
if (this._isOmp()) {
|
|
2274
|
+
const source = repo.source || repo.sourceUri || repo.repoUrl || repo.url
|
|
2275
|
+
|| repo.localPath || [repo.owner, repo.name].filter(Boolean).join('/');
|
|
2276
|
+
return this.ompNativeAdapter.addMarketplace(source, options);
|
|
2277
|
+
}
|
|
2671
2278
|
const config = this.loadReposConfig();
|
|
2672
2279
|
const normalizedRepo = this.normalizeRepoConfig({
|
|
2673
2280
|
...repo,
|
|
@@ -2693,7 +2300,10 @@ class PluginsService {
|
|
|
2693
2300
|
* @param {string} name - Repository name
|
|
2694
2301
|
* @returns {Array} Updated repos list
|
|
2695
2302
|
*/
|
|
2696
|
-
removeRepo(owner, name, repoId = '') {
|
|
2303
|
+
removeRepo(owner, name, repoId = '', options = {}) {
|
|
2304
|
+
if (this._isOmp()) {
|
|
2305
|
+
return this.ompNativeAdapter.removeMarketplace(repoId || name, options);
|
|
2306
|
+
}
|
|
2697
2307
|
const config = this.loadReposConfig();
|
|
2698
2308
|
config.repos = config.repos.filter(r => {
|
|
2699
2309
|
if (repoId) {
|
|
@@ -2713,7 +2323,10 @@ class PluginsService {
|
|
|
2713
2323
|
* @param {boolean} enabled - Enable or disable
|
|
2714
2324
|
* @returns {Array} Updated repos list
|
|
2715
2325
|
*/
|
|
2716
|
-
toggleRepo(owner, name, enabled, repoId = '') {
|
|
2326
|
+
toggleRepo(owner, name, enabled, repoId = '', options = {}) {
|
|
2327
|
+
if (this._isOmp()) {
|
|
2328
|
+
throw new Error('OMP native marketplaces do not support repository toggles');
|
|
2329
|
+
}
|
|
2717
2330
|
const config = this.loadReposConfig();
|
|
2718
2331
|
const repo = config.repos.find(r => {
|
|
2719
2332
|
if (repoId) return r.id === repoId;
|
|
@@ -2729,6 +2342,9 @@ class PluginsService {
|
|
|
2729
2342
|
}
|
|
2730
2343
|
|
|
2731
2344
|
updateRepoAuth(owner, name, token = '', clearToken = false, repoId = '') {
|
|
2345
|
+
if (this._isOmp()) {
|
|
2346
|
+
throw new Error('OMP native marketplaces do not support per-repository authentication');
|
|
2347
|
+
}
|
|
2732
2348
|
const config = this.loadReposConfig();
|
|
2733
2349
|
const repo = config.repos.find(r => {
|
|
2734
2350
|
if (repoId) return r.id === repoId;
|
|
@@ -3178,7 +2794,11 @@ class PluginsService {
|
|
|
3178
2794
|
* Sync repositories to Claude Code marketplace
|
|
3179
2795
|
* @returns {Promise<Object>} Sync results
|
|
3180
2796
|
*/
|
|
3181
|
-
async syncRepos() {
|
|
2797
|
+
async syncRepos(options = {}) {
|
|
2798
|
+
if (this._isOmp()) {
|
|
2799
|
+
const repos = this.ompNativeAdapter.updateMarketplaces('', options);
|
|
2800
|
+
return { success: true, repos, results: [] };
|
|
2801
|
+
}
|
|
3182
2802
|
if (!this.getCapabilities().syncRepos) {
|
|
3183
2803
|
return { success: true, results: [] };
|
|
3184
2804
|
}
|
|
@@ -3213,8 +2833,8 @@ class PluginsService {
|
|
|
3213
2833
|
* Sync plugins from Claude Code
|
|
3214
2834
|
* @returns {Promise<Object>} Updated plugins list
|
|
3215
2835
|
*/
|
|
3216
|
-
async syncPlugins() {
|
|
3217
|
-
return this.listPlugins();
|
|
2836
|
+
async syncPlugins(options = {}) {
|
|
2837
|
+
return this.listPlugins(options);
|
|
3218
2838
|
}
|
|
3219
2839
|
|
|
3220
2840
|
/**
|
|
@@ -3599,104 +3219,20 @@ class PluginsService {
|
|
|
3599
3219
|
return results;
|
|
3600
3220
|
}
|
|
3601
3221
|
|
|
3602
|
-
_normalizeOmpCatalogEntries(catalog = null) {
|
|
3603
|
-
if (Array.isArray(catalog)) return catalog;
|
|
3604
|
-
if (!catalog || typeof catalog !== 'object') return [];
|
|
3605
|
-
for (const key of ['packages', 'plugins', 'extensions']) {
|
|
3606
|
-
if (Array.isArray(catalog[key])) return catalog[key];
|
|
3607
|
-
}
|
|
3608
|
-
return [];
|
|
3609
|
-
}
|
|
3610
|
-
|
|
3611
|
-
_normalizeOmpCatalogPackage(repo, entry = {}, catalog = {}, defaults = {}) {
|
|
3612
|
-
if (!entry || typeof entry !== 'object') return null;
|
|
3613
|
-
const installSource = String(
|
|
3614
|
-
entry.installSource ||
|
|
3615
|
-
entry.source ||
|
|
3616
|
-
entry.package ||
|
|
3617
|
-
entry.url ||
|
|
3618
|
-
entry.repo ||
|
|
3619
|
-
entry.repository ||
|
|
3620
|
-
entry.name ||
|
|
3621
|
-
''
|
|
3622
|
-
).trim();
|
|
3623
|
-
const name = String(entry.name || entry.id || entry.package || installSource || '').trim();
|
|
3624
|
-
if (!name || !installSource) return null;
|
|
3625
|
-
|
|
3626
|
-
const resourceTypes = normalizeOmpResourceTypes(
|
|
3627
|
-
entry.resourceTypes ||
|
|
3628
|
-
entry.resources ||
|
|
3629
|
-
entry.provides ||
|
|
3630
|
-
entry.omp?.resources ||
|
|
3631
|
-
defaults.resourceTypes
|
|
3632
|
-
);
|
|
3633
|
-
return this.buildMarketPluginItem(repo, {
|
|
3634
|
-
name,
|
|
3635
|
-
displayName: entry.displayName || entry.title || '',
|
|
3636
|
-
description: entry.description || '',
|
|
3637
|
-
author: entry.author || catalog.author || repo.owner,
|
|
3638
|
-
version: entry.version || 'latest',
|
|
3639
|
-
category: entry.category || 'general',
|
|
3640
|
-
directory: entry.directory || name,
|
|
3641
|
-
marketplace: entry.marketplace || repo.marketplace || catalog.name || defaults.marketplace || '',
|
|
3642
|
-
installSource,
|
|
3643
|
-
marketplaceFormat: defaults.marketplaceFormat || 'omp-package-catalog',
|
|
3644
|
-
pluginKind: 'package',
|
|
3645
|
-
pluginType: 'package',
|
|
3646
|
-
resourceTypes,
|
|
3647
|
-
resources: entry.resources || entry.provides || null,
|
|
3648
|
-
repoUrl: entry.repoUrl || entry.repositoryUrl || entry.repository || repo.repoUrl || buildRepoUrl(repo)
|
|
3649
|
-
});
|
|
3650
|
-
}
|
|
3651
|
-
|
|
3652
|
-
async _fetchOmpPackageCatalogPlugins(repo, fileMap, readJson) {
|
|
3653
|
-
if (!this._isOmp()) return [];
|
|
3654
|
-
const catalogFiles = ['omp-packages.json', '.omp/packages.json', 'packages.json'];
|
|
3655
|
-
for (const catalogPath of catalogFiles) {
|
|
3656
|
-
if (!fileMap.has(catalogPath)) continue;
|
|
3657
|
-
const catalog = await readJson(catalogPath);
|
|
3658
|
-
const entries = this._normalizeOmpCatalogEntries(catalog);
|
|
3659
|
-
const plugins = entries
|
|
3660
|
-
.map(entry => this._normalizeOmpCatalogPackage(repo, entry, catalog, {
|
|
3661
|
-
marketplaceFormat: 'omp-package-catalog'
|
|
3662
|
-
}))
|
|
3663
|
-
.filter(Boolean);
|
|
3664
|
-
if (plugins.length > 0) return plugins;
|
|
3665
|
-
}
|
|
3666
|
-
|
|
3667
|
-
const manifestPath = fileMap.has('omp.json') ? 'omp.json' : (fileMap.has('package.json') ? 'package.json' : '');
|
|
3668
|
-
if (!manifestPath) return [];
|
|
3669
|
-
const manifest = await readJson(manifestPath);
|
|
3670
|
-
const ompMeta = manifest.omp && typeof manifest.omp === 'object' ? manifest.omp: {};
|
|
3671
|
-
const installSource = ompMeta.installSource || manifest.installSource || manifest.name;
|
|
3672
|
-
const resourceTypes = normalizeOmpResourceTypes(
|
|
3673
|
-
ompMeta.resourceTypes ||
|
|
3674
|
-
ompMeta.resources ||
|
|
3675
|
-
manifest.resourceTypes ||
|
|
3676
|
-
manifest.resources
|
|
3677
|
-
);
|
|
3678
|
-
if (!installSource || resourceTypes.length === 0) return [];
|
|
3679
|
-
const plugin = this._normalizeOmpCatalogPackage(repo, {
|
|
3680
|
-
name: manifest.name || repo.name,
|
|
3681
|
-
installSource,
|
|
3682
|
-
version: manifest.version,
|
|
3683
|
-
description: manifest.description,
|
|
3684
|
-
author: manifest.author,
|
|
3685
|
-
resourceTypes
|
|
3686
|
-
}, { name: repo.marketplace || repo.name }, {
|
|
3687
|
-
marketplaceFormat: manifestPath === 'omp.json' ? 'omp-manifest' : 'omp-package-manifest'
|
|
3688
|
-
});
|
|
3689
|
-
return plugin ? [plugin] : [];
|
|
3690
|
-
}
|
|
3691
|
-
|
|
3692
3222
|
/**
|
|
3693
3223
|
* Get market plugins from configured repositories
|
|
3694
3224
|
* @returns {Promise<Array>} List of available market plugins
|
|
3695
3225
|
*/
|
|
3696
|
-
async getMarketPlugins(forceRefresh = false) {
|
|
3226
|
+
async getMarketPlugins(forceRefresh = false, options = {}) {
|
|
3697
3227
|
if (!this.getCapabilities().market) {
|
|
3698
3228
|
return [];
|
|
3699
3229
|
}
|
|
3230
|
+
if (this._isOmp()) {
|
|
3231
|
+
if (forceRefresh) {
|
|
3232
|
+
this.ompNativeAdapter.updateMarketplaces('', options);
|
|
3233
|
+
}
|
|
3234
|
+
return this.ompNativeAdapter.discover(options);
|
|
3235
|
+
}
|
|
3700
3236
|
|
|
3701
3237
|
if (forceRefresh) {
|
|
3702
3238
|
this.clearMarketCache({ removeFile: false });
|
|
@@ -3765,15 +3301,6 @@ class PluginsService {
|
|
|
3765
3301
|
}
|
|
3766
3302
|
}
|
|
3767
3303
|
|
|
3768
|
-
// OMP package catalog format; legacy catalog filenames may still include omp.
|
|
3769
|
-
if (this._isOmp()) {
|
|
3770
|
-
const ompPackagePlugins = await this._fetchOmpPackageCatalogPlugins(repo, fileMap, readJson);
|
|
3771
|
-
if (ompPackagePlugins.length > 0) {
|
|
3772
|
-
marketPlugins.push(...ompPackagePlugins);
|
|
3773
|
-
continue;
|
|
3774
|
-
}
|
|
3775
|
-
}
|
|
3776
|
-
|
|
3777
3304
|
const nestedManifestFiles = files.filter(file => {
|
|
3778
3305
|
if (this._isCodex()) {
|
|
3779
3306
|
return file.path === '.codex-plugin/plugin.json' || file.path.endsWith('/.codex-plugin/plugin.json');
|
|
@@ -3819,9 +3346,7 @@ class PluginsService {
|
|
|
3819
3346
|
|
|
3820
3347
|
for (const dir of pluginDirs) {
|
|
3821
3348
|
try {
|
|
3822
|
-
const manifest =
|
|
3823
|
-
? await this._readManifestFromRepo(repo, dir, ['omp.json', 'extension.json', 'plugin.json', 'package.json'])
|
|
3824
|
-
: await readJson(`${dir}/plugin.json`);
|
|
3349
|
+
const manifest = await readJson(`${dir}/plugin.json`);
|
|
3825
3350
|
if (!manifest) {
|
|
3826
3351
|
throw new Error(`File not found: ${dir}/plugin.json`);
|
|
3827
3352
|
}
|
|
@@ -3832,7 +3357,6 @@ class PluginsService {
|
|
|
3832
3357
|
author: manifest.author || repo.owner,
|
|
3833
3358
|
version: manifest.version || '1.0.0',
|
|
3834
3359
|
directory: dir,
|
|
3835
|
-
pluginKind: this._isOmp() ? 'extension' : undefined,
|
|
3836
3360
|
commands: manifest.commands || [],
|
|
3837
3361
|
hooks: manifest.hooks || []
|
|
3838
3362
|
}));
|