vg-coder-cli 2.0.69 → 2.0.71
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/package.json
CHANGED
package/src/server/api-server.js
CHANGED
|
@@ -848,6 +848,51 @@ class ApiServer {
|
|
|
848
848
|
} catch (e) { res.status(launcherErr(e)).json({ error: e.message }); }
|
|
849
849
|
});
|
|
850
850
|
|
|
851
|
+
// Proxy a chrome.* command through a worker (content-script → SW
|
|
852
|
+
// message bridge). Use when the launcher SW socket is offline but the
|
|
853
|
+
// worker socket is alive — sending the message also wakes the SW.
|
|
854
|
+
// Body: { chromeId? | workerLabel?, cmd, args?, timeoutMs? }
|
|
855
|
+
// Available cmds (mirror of launcher.exec, run via SW message):
|
|
856
|
+
// tabs.query | tabs.remove | tabs.update | tabs.reload
|
|
857
|
+
// storage.sync.get | storage.local.get | runtime.reload | wake
|
|
858
|
+
this.app.post('/api/worker/exec', async (req, res) => {
|
|
859
|
+
try {
|
|
860
|
+
const body = req.body || {};
|
|
861
|
+
if (!body.cmd) return res.status(400).json({ error: 'cmd required' });
|
|
862
|
+
const opts = workerOpts(req); // accepts label/workerLabel/chromeId via req
|
|
863
|
+
// workerOpts only reads label/workerLabel — pass chromeId via opts
|
|
864
|
+
// directly when body has it (workers are addressed by socket, not
|
|
865
|
+
// chromeId, so we resolve chromeId → workerLabel client-side here).
|
|
866
|
+
if (body.chromeId && !opts.workerLabel) {
|
|
867
|
+
// Find any worker matching chromeId; route via its socketId.
|
|
868
|
+
const w = [...taskQueue.workers.values()].find(w => w.chromeId === body.chromeId);
|
|
869
|
+
if (w) opts.socketId = w.id;
|
|
870
|
+
else return res.status(404).json({ error: 'worker_not_found', chromeId: body.chromeId });
|
|
871
|
+
}
|
|
872
|
+
const timeoutMs = Math.min(Math.max(parseInt(body.timeoutMs, 10) || 10_000, 1_000), 30_000);
|
|
873
|
+
const result = await taskQueue.requestWorker('worker:exec', { cmd: body.cmd, args: body.args }, opts, timeoutMs);
|
|
874
|
+
res.json(result);
|
|
875
|
+
} catch (e) { res.status(503).json({ error: e.message }); }
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
// Dump extension metadata (id, version, install type, permissions) via
|
|
879
|
+
// the worker → SW message bridge. Useful when multiple installs of the
|
|
880
|
+
// same extension exist (Web Store + Load Unpacked) and we need to know
|
|
881
|
+
// which one is actually running.
|
|
882
|
+
this.app.get('/api/worker/extension-info', async (req, res) => {
|
|
883
|
+
try {
|
|
884
|
+
const opts = workerOpts(req);
|
|
885
|
+
const chromeIdQuery = (req.query?.chromeId || '').toString().trim();
|
|
886
|
+
if (chromeIdQuery && !opts.workerLabel) {
|
|
887
|
+
const w = [...taskQueue.workers.values()].find(w => w.chromeId === chromeIdQuery);
|
|
888
|
+
if (w) opts.socketId = w.id;
|
|
889
|
+
else return res.status(404).json({ error: 'worker_not_found', chromeId: chromeIdQuery });
|
|
890
|
+
}
|
|
891
|
+
const result = await taskQueue.requestWorker('worker:ext-info', {}, opts, 5_000);
|
|
892
|
+
res.json(result);
|
|
893
|
+
} catch (e) { res.status(503).json({ error: e.message }); }
|
|
894
|
+
});
|
|
895
|
+
|
|
851
896
|
this.app.get('/api/worker/status', (req, res) => {
|
|
852
897
|
const label = (req.query?.label || req.query?.workerLabel || '').toString().toLowerCase().trim();
|
|
853
898
|
res.json(taskQueue.workerStatus(label || undefined));
|
|
@@ -496,6 +496,46 @@ function connect() {
|
|
|
496
496
|
} catch (e) { ack && ack({ ok: false, error: e.message, stack: e.stack }); }
|
|
497
497
|
});
|
|
498
498
|
|
|
499
|
+
// Proxy chrome.* commands to the extension background SW via runtime
|
|
500
|
+
// message passing. Receiving the message also wakes the SW if it was
|
|
501
|
+
// evicted — that's the recovery path for "launcher offline" cases
|
|
502
|
+
// where the launcher socket is dead but the content-script socket
|
|
503
|
+
// (this worker) is alive.
|
|
504
|
+
socket.on('worker:exec', async ({ cmd, args } = {}, ack) => {
|
|
505
|
+
try {
|
|
506
|
+
if (!cmd) return ack && ack({ ok: false, error: 'cmd_required' });
|
|
507
|
+
if (typeof chrome === 'undefined' || !chrome.runtime?.sendMessage) {
|
|
508
|
+
return ack && ack({ ok: false, error: 'no_chrome_runtime' });
|
|
509
|
+
}
|
|
510
|
+
const reply = await new Promise((resolve) => {
|
|
511
|
+
try {
|
|
512
|
+
chrome.runtime.sendMessage({ action: 'WORKER_EXEC', cmd, args: args || {} }, (resp) => {
|
|
513
|
+
if (chrome.runtime.lastError) {
|
|
514
|
+
resolve({ ok: false, error: chrome.runtime.lastError.message });
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
resolve(resp || { ok: false, error: 'no_response' });
|
|
518
|
+
});
|
|
519
|
+
} catch (err) {
|
|
520
|
+
resolve({ ok: false, error: err?.message || String(err) });
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
ack && ack(reply);
|
|
524
|
+
} catch (e) { ack && ack({ ok: false, error: e.message }); }
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
// Dump extension metadata — version, installType, ID, permissions.
|
|
528
|
+
// Comes from window.vetgo.extInfo which background.ts injects when the
|
|
529
|
+
// controller script loads. (Page context has no chrome.runtime.* so
|
|
530
|
+
// we can't query at runtime — pre-injection is the only path.)
|
|
531
|
+
socket.on('worker:ext-info', async (_payload, ack) => {
|
|
532
|
+
try {
|
|
533
|
+
const info = (window.vetgo && window.vetgo.extInfo) || null;
|
|
534
|
+
if (!info) return ack && ack({ ok: false, error: 'extInfo not injected — extension may be outdated' });
|
|
535
|
+
ack && ack({ ok: true, info, tabUrl: location.href, vetgo: window.vetgo });
|
|
536
|
+
} catch (e) { ack && ack({ ok: false, error: e.message }); }
|
|
537
|
+
});
|
|
538
|
+
|
|
499
539
|
socket.on('debug:logs', ({ since = 0, level = null, limit = 100, clear = false } = {}, ack) => {
|
|
500
540
|
try {
|
|
501
541
|
let logs = logBuffer.filter(e => e.at > Number(since || 0));
|