ai-extension-preview 0.1.12 → 0.1.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/dist/index.js CHANGED
@@ -138,6 +138,21 @@ const WORK_DIR = path.join(HOME_DIR, '.ai-extension-preview', options.job || 'de
138
138
  await ctx.actions.runAction('core:log', { level: 'error', message: 'Initial check failed. Could not verify job or download extension.' });
139
139
  process.exit(1);
140
140
  }
141
+ // Wait for Extension files (Manifest)
142
+ const manifestPath = path.join(WORK_DIR, 'dist', 'manifest.json');
143
+ let attempts = 0;
144
+ const maxAttempts = 60; // 2 minutes
145
+ console.log('[DEBUG] Waiting for extension files...');
146
+ while (!fs.existsSync(manifestPath) && attempts < maxAttempts) {
147
+ await new Promise(r => setTimeout(r, 2000));
148
+ attempts++;
149
+ if (attempts % 5 === 0)
150
+ console.log(`Waiting for extension generation... (${attempts * 2}s)`);
151
+ }
152
+ if (!fs.existsSync(manifestPath)) {
153
+ await ctx.actions.runAction('core:log', { level: 'error', message: 'Timed out waiting for extension files. Status check succeeded but files are missing.' });
154
+ process.exit(1);
155
+ }
141
156
  // Launch Browser
142
157
  await ctx.actions.runAction('browser:start', {});
143
158
  // Keep process alive
@@ -34,7 +34,7 @@ export const DownloaderPlugin = {
34
34
  return axios.create({
35
35
  baseURL: config.host,
36
36
  headers: {
37
- 'Authorization': token ? `Bearer ${token}` : undefined,
37
+ 'X-Preview-Token': token,
38
38
  'X-User-Id': userId
39
39
  },
40
40
  httpsAgent: new https.Agent({
@@ -199,34 +199,7 @@ console.log('[Hot Reload] Active for Job:', CURRENT_JOB_ID);
199
199
  }
200
200
  }
201
201
  });
202
- // Start Polling (Loop)
203
- void ctx.actions.runAction('core:log', { level: 'info', message: 'Starting polling loop (Interval: 2000ms)' });
204
- // Listen for browser failure to stop polling
205
- ctx.events.on('browser:launch-failed', () => {
206
- if (checkInterval) {
207
- clearInterval(checkInterval);
208
- checkInterval = undefined;
209
- ctx.actions.runAction('core:log', { level: 'warn', message: 'Polling stopped due to browser launch failure.' });
210
- // Update status happens in UI
211
- }
212
- });
213
- checkInterval = setInterval(async () => {
214
- try {
215
- // Use actions for main log (UI Plugin captures this)
216
- // console.error('[DownloaderPlugin] Tick - Checking Status...'); // REMOVE (Outside UI)
217
- // Silent polling for CLI mode
218
- // await ctx.actions.runAction('core:log', { level: 'info', message: '[DEBUG] Polling...' });
219
- await ctx.actions.runAction('downloader:check', null);
220
- }
221
- catch (err) {
222
- await ctx.actions.runAction('core:log', { level: 'error', message: `Poll Error: ${err.message}` });
223
- }
224
- }, 2000);
225
- },
226
- dispose(ctx) {
227
- if (checkInterval) {
228
- clearInterval(checkInterval);
229
- checkInterval = undefined;
230
- }
202
+ // Polling removed in favor of push-based updates (POST /refresh)
203
+ ctx.actions.runAction('core:log', { level: 'info', message: 'Ready. Waiting for update signals...' });
231
204
  }
232
205
  };
@@ -22,6 +22,7 @@ export const ServerPlugin = {
22
22
  res.setHeader('Access-Control-Allow-Origin', '*');
23
23
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
24
24
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
25
+ res.setHeader('Access-Control-Allow-Private-Network', 'true');
25
26
  if (req.method === 'OPTIONS') {
26
27
  res.writeHead(204);
27
28
  res.end();
@@ -36,6 +37,17 @@ export const ServerPlugin = {
36
37
  port: allocatedPort
37
38
  }));
38
39
  }
40
+ else if (req.url === '/refresh' && req.method === 'POST') {
41
+ // Trigger manual check
42
+ ctx.actions.runAction('core:log', { level: 'info', message: '[API] Refresh request received' });
43
+ ctx.actions.runAction('downloader:check', null).then((result) => {
44
+ ctx.actions.runAction('core:log', { level: 'info', message: `[API] Check result: ${result}` });
45
+ }).catch((err) => {
46
+ ctx.actions.runAction('core:log', { level: 'error', message: `[API] Check failed: ${err.message}` });
47
+ });
48
+ res.writeHead(200, { 'Content-Type': 'application/json' });
49
+ res.end(JSON.stringify({ success: true }));
50
+ }
39
51
  else if (req.url === '/disconnect' && req.method === 'POST') {
40
52
  // Trigger browser stop
41
53
  ctx.actions.runAction('core:log', { level: 'info', message: '[API] Disconnect request received' });
@@ -49,12 +49,14 @@ export const BrowserManagerPlugin = {
49
49
  stagingDir: STAGING_DIR
50
50
  });
51
51
  };
52
+ let isInitialized = false;
52
53
  // Action: Start Browser (Orchestrator)
53
54
  ctx.actions.registerAction({
54
55
  id: 'browser:start',
55
56
  handler: async () => {
56
57
  await syncToStaging();
57
58
  await launchBrowser();
59
+ isInitialized = true;
58
60
  return true;
59
61
  }
60
62
  });
@@ -69,8 +71,10 @@ export const BrowserManagerPlugin = {
69
71
  });
70
72
  // Event: Update detected
71
73
  ctx.events.on('downloader:updated', async () => {
72
- await ctx.actions.runAction('core:log', { level: 'info', message: 'Update detected. Syncing to staging...' });
73
- await ctx.actions.runAction('browser:start', {});
74
+ if (isInitialized) {
75
+ await ctx.actions.runAction('core:log', { level: 'info', message: 'Update detected. Syncing to staging...' });
76
+ await ctx.actions.runAction('browser:start', {});
77
+ }
74
78
  });
75
79
  // Event: Browser closed (from launcher)
76
80
  ctx.events.on('browser:closed', async (data) => {
@@ -36,8 +36,8 @@ export const NativeLauncherPlugin = {
36
36
  await ctx.actions.runAction('core:log', { level: 'info', message: `Native Launch Executable: ${executable} ` });
37
37
  await ctx.actions.runAction('core:log', { level: 'info', message: `Native Launch Target: ${safeDist} ` });
38
38
  const cleanArgs = [
39
- `--load - extension=${safeDist} `,
40
- `--user - data - dir=${safeProfile} `,
39
+ `--load-extension=${safeDist}`,
40
+ `--user-data-dir=${safeProfile}`,
41
41
  '--no-first-run',
42
42
  '--no-default-browser-check',
43
43
  '--disable-gpu',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-extension-preview",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "Local preview tool for AI Extension Builder",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,6 +21,7 @@
21
21
  "license": "MIT",
22
22
  "scripts": {
23
23
  "build": "shx rm -rf dist && tsc -b && shx chmod +x dist/index.js",
24
+ "prepublishOnly": "npm run build",
24
25
  "start": "tsx src/index.ts",
25
26
  "dev": "tsx watch src/index.ts",
26
27
  "preview": "node dist/index.js"
@@ -50,4 +51,4 @@
50
51
  "typescript": "^5.7.2",
51
52
  "vitest": "^4.0.16"
52
53
  }
53
- }
54
+ }