Updated to fetch from git-based directory with index.json

This commit is contained in:
2026-04-17 02:02:26 +10:00
parent f423c50d68
commit e486dbbbf8
3 changed files with 151 additions and 12 deletions

107
package-lock.json generated Normal file
View File

@@ -0,0 +1,107 @@
{
"name": "@pluginhost/core",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pluginhost/core",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"node-fetch": "^3.3.2"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"deprecated": "Use your platform's native DOMException instead",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
}
}
}

View File

@@ -1,9 +1,13 @@
import { EventEmitter } from 'events';
import { readdir, readFile, mkdir } from 'fs/promises';
import { join, resolve } from 'path';
import { join, resolve, dirname } from 'path';
import { existsSync } from 'fs';
import { fileURLToPath } from 'url';
import fetch from 'node-fetch';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
/**
* Plugin Host - Manages plugin lifecycle and provides plugin API
*/
@@ -11,7 +15,10 @@ export class PluginHost extends EventEmitter {
constructor(options = {}) {
super();
this.directoryUrl = options.directoryUrl;
this.pluginsDir = resolve(options.pluginsDir || './plugins');
// Resolve relative to the PluginHost.js file location (src/), then go up one level
this.pluginsDir = options.pluginsDir ?
(options.pluginsDir.startsWith('.') ? resolve(__dirname, '..', options.pluginsDir) : resolve(options.pluginsDir))
: resolve(__dirname, '../plugins');
this.autoUpdate = options.autoUpdate ?? true;
this.updateInterval = options.updateInterval || 300000;
@@ -42,18 +49,32 @@ export class PluginHost extends EventEmitter {
*/
async updateRegistry() {
try {
const response = await fetch(this.directoryUrl);
if (!response.ok) {
console.warn('Failed to fetch plugin registry:', response.statusText);
// First fetch the index to get the list of available plugins
const indexUrl = `${this.directoryUrl}/index.json`;
const indexResponse = await fetch(indexUrl);
if (!indexResponse.ok) {
console.warn('Failed to fetch plugin index:', indexResponse.statusText);
return;
}
const html = await response.text();
const pluginFiles = this._parseDirectoryListing(html);
const index = await indexResponse.json();
const pluginIds = index.plugins || [];
console.log(`Found ${pluginIds.length} plugins in directory`);
for (const file of pluginFiles) {
if (file.endsWith('.json')) {
await this._fetchPluginDefinition(file);
// Fetch each plugin definition
for (const pluginId of pluginIds) {
const pluginUrl = `${this.directoryUrl}/${pluginId}.json`;
try {
const response = await fetch(pluginUrl);
if (response.ok) {
const plugin = await response.json();
this.pluginRegistry.set(plugin.id, plugin);
console.log(`${plugin.name} v${plugin.version}`);
}
} catch (error) {
console.warn(` ✗ Could not fetch ${pluginId}:`, error.message);
}
}

View File

@@ -3,11 +3,22 @@ import { PluginHost } from './PluginHost.js';
const host = new PluginHost({
directoryUrl: 'http://synbox.ruv.wtf:8418/litruv/Plugin-Directory/raw/branch/main/plugins',
pluginsDir: './plugins',
autoUpdate: true,
autoUpdate: true, // Auto-fetch registry updates
updateInterval: 300000 // 5 minutes
});
console.log('🔌 Initializing Plugin Host...\n');
await host.initialize();
await host.loadPlugins();
console.log('Plugin Host initialized with plugins:', host.getLoadedPlugins().map(p => p.name));
console.log('\n📊 Plugin Host Status:');
console.log('====================');
console.log('Loaded plugins:', host.getLoadedPlugins().map(p => `${p.name} v${p.version}`).join(', ') || 'none');
console.log('Plugin directory:', host.pluginsDir);
console.log('\n📦 Available in Registry:', host.getRegistry().length);
host.getRegistry().forEach(p => {
console.log(` - ${p.name} v${p.version} (${p.id})`);
});
console.log('\n✨ Plugin Host ready!');