ai-extension-preview 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { Runtime } from 'skeleton-crew-runtime';
|
|
|
9
9
|
import { CorePlugin } from './plugins/CorePlugin.js';
|
|
10
10
|
import { DownloaderPlugin } from './plugins/DownloaderPlugin.js';
|
|
11
11
|
import { BrowserPlugin } from './plugins/BrowserPlugin.js';
|
|
12
|
+
import { ServerPlugin } from './plugins/ServerPlugin.js';
|
|
12
13
|
import axios from 'axios';
|
|
13
14
|
import chalk from 'chalk';
|
|
14
15
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -100,6 +101,7 @@ async function main() {
|
|
|
100
101
|
runtime.registerPlugin(CorePlugin);
|
|
101
102
|
runtime.registerPlugin(DownloaderPlugin);
|
|
102
103
|
runtime.registerPlugin(BrowserPlugin);
|
|
104
|
+
runtime.registerPlugin(ServerPlugin);
|
|
103
105
|
runtime.logger.info('Initializing runtime...');
|
|
104
106
|
await runtime.initialize();
|
|
105
107
|
const ctx = runtime.getContext();
|
|
@@ -97,6 +97,57 @@ export const DownloaderPlugin = {
|
|
|
97
97
|
await fs.emptyDir(DIST_DIR);
|
|
98
98
|
const zip = new AdmZip(DOWNLOAD_PATH);
|
|
99
99
|
zip.extractAllTo(DIST_DIR, true);
|
|
100
|
+
// --- HOT RELOAD INJECTION ---
|
|
101
|
+
try {
|
|
102
|
+
const HOT_RELOAD_CODE = `
|
|
103
|
+
const EVENT_SOURCE_URL = 'http://localhost:3500/status';
|
|
104
|
+
let lastVersion = null;
|
|
105
|
+
|
|
106
|
+
setInterval(async () => {
|
|
107
|
+
try {
|
|
108
|
+
const res = await fetch(EVENT_SOURCE_URL);
|
|
109
|
+
const data = await res.json();
|
|
110
|
+
|
|
111
|
+
if (lastVersion && data.version !== lastVersion) {
|
|
112
|
+
console.log('[Hot Reload] New version detected:', data.version);
|
|
113
|
+
chrome.runtime.reload();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
lastVersion = data.version;
|
|
117
|
+
} catch (err) {
|
|
118
|
+
// Build tool might be offline
|
|
119
|
+
}
|
|
120
|
+
}, 1000);
|
|
121
|
+
console.log('[Hot Reload] Active');
|
|
122
|
+
`;
|
|
123
|
+
const hotReloadPath = path.join(DIST_DIR, 'hot-reload.js');
|
|
124
|
+
await fs.writeFile(hotReloadPath, HOT_RELOAD_CODE);
|
|
125
|
+
// Patch Manifest / Background
|
|
126
|
+
const manifestPath = path.join(DIST_DIR, 'manifest.json');
|
|
127
|
+
if (await fs.pathExists(manifestPath)) {
|
|
128
|
+
const manifest = await fs.readJson(manifestPath);
|
|
129
|
+
// MV3 Module Worker Strategy
|
|
130
|
+
if (manifest.manifest_version === 3 && manifest.background?.service_worker) {
|
|
131
|
+
const swPath = path.join(DIST_DIR, manifest.background.service_worker);
|
|
132
|
+
if (await fs.pathExists(swPath)) {
|
|
133
|
+
const swContent = await fs.readFile(swPath, 'utf-8');
|
|
134
|
+
// Prepend import
|
|
135
|
+
await fs.writeFile(swPath, "import './hot-reload.js';\n" + swContent);
|
|
136
|
+
await ctx.actions.runAction('core:log', { level: 'info', message: 'Injected Hot Reload script into background worker.' });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// MV2 Scripts Strategy (Fallback if user generates MV2)
|
|
140
|
+
else if (manifest.background?.scripts) {
|
|
141
|
+
manifest.background.scripts.push('hot-reload.js');
|
|
142
|
+
await fs.writeJson(manifestPath, manifest, { spaces: 2 });
|
|
143
|
+
await ctx.actions.runAction('core:log', { level: 'info', message: 'Injected Hot Reload script into background scripts.' });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch (injectErr) {
|
|
148
|
+
await ctx.actions.runAction('core:log', { level: 'error', message: `Hot Reload Injection Failed: ${injectErr.message}` });
|
|
149
|
+
}
|
|
150
|
+
// ----------------------------
|
|
100
151
|
spinner.succeed('Updated extension code!');
|
|
101
152
|
return true;
|
|
102
153
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
export const ServerPlugin = {
|
|
3
|
+
name: 'server',
|
|
4
|
+
version: '1.0.0',
|
|
5
|
+
setup(ctx) {
|
|
6
|
+
let currentVersion = '0.0.0';
|
|
7
|
+
const PORT = 3500;
|
|
8
|
+
// Listen for version updates
|
|
9
|
+
ctx.events.on('downloader:updated', (data) => {
|
|
10
|
+
if (data && data.version) {
|
|
11
|
+
currentVersion = data.version;
|
|
12
|
+
ctx.actions.runAction('core:log', { level: 'info', message: `Server: Reporting version ${currentVersion}` });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const server = http.createServer((req, res) => {
|
|
16
|
+
// CORS Headers
|
|
17
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
18
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
19
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
20
|
+
if (req.method === 'OPTIONS') {
|
|
21
|
+
res.writeHead(204);
|
|
22
|
+
res.end();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (req.url === '/status') {
|
|
26
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
27
|
+
res.end(JSON.stringify({ version: currentVersion }));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
res.writeHead(404);
|
|
31
|
+
res.end('Not Found');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
server.listen(PORT, () => {
|
|
35
|
+
ctx.actions.runAction('core:log', { level: 'info', message: `Hot Reload Server running on port ${PORT}` });
|
|
36
|
+
});
|
|
37
|
+
server.on('error', (err) => {
|
|
38
|
+
if (err.code === 'EADDRINUSE') {
|
|
39
|
+
ctx.actions.runAction('core:log', { level: 'error', message: `Port ${PORT} is busy. Hot reload may fail.` });
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
ctx.actions.runAction('core:log', { level: 'error', message: `Server error: ${err.message}` });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// Store server instance to close later
|
|
46
|
+
ctx._serverInstance = server;
|
|
47
|
+
},
|
|
48
|
+
dispose(ctx) {
|
|
49
|
+
const server = ctx._serverInstance;
|
|
50
|
+
if (server) {
|
|
51
|
+
server.close();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|