sliccy 1.16.0 → 1.18.0
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/README.md +3 -3
- package/dist/{cli → node-server}/electron-controller.js +1 -1
- package/dist/{cli → node-server}/electron-runtime.js +2 -2
- package/dist/{cli → node-server}/index.js +21 -1
- package/dist/{cli → node-server}/launch-url.js +1 -1
- package/dist/{cli → node-server}/release-package.js +2 -2
- package/dist/{cli → node-server}/sync-release-version.js +2 -2
- package/dist/ui/assets/{___vite-browser-external_commonjs-proxy-C2C29KbX.js → ___vite-browser-external_commonjs-proxy-BwJgphaY.js} +1 -1
- package/dist/ui/assets/{bsh-watchdog-DLby3z6c.js → bsh-watchdog-qD-Teoo4.js} +1 -1
- package/dist/ui/assets/{index-463jowYW.js → index-B8IwKAYd.js} +1 -1
- package/dist/ui/assets/{index-sEg6tmeB.js → index-BAVxG_Su.js} +1 -1
- package/dist/ui/assets/{index-DX0bAF7S.js → index-BsoP4arC.js} +1 -1
- package/dist/ui/assets/{index-DArWQIsE.js → index-BvZFUJlY.js} +1 -1
- package/dist/ui/assets/{index-Dg-Ybyxq.js → index-CL0Bwyen.js} +1791 -1849
- package/dist/ui/assets/{index-Dmh7QWIR.js → index-DZrFxY8C.js} +1 -1
- package/dist/ui/assets/{index-DBbOSBAp.js → index-JXeYDsaX.js} +1 -1
- package/dist/ui/assets/{index-ChSghHzD.js → index-KFWCKVJQ.js} +1 -1
- package/dist/ui/assets/{index-sXI7NX5v.js → index-fbqdhDlF.js} +1 -1
- package/dist/ui/assets/{offscreen-client-C3P1alsB.js → offscreen-client-CFibtznc.js} +1 -1
- package/dist/ui/assets/{sql-wasm-u4qgPtVl.js → sql-wasm-DD4iv2bM.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/ui/logos/favicon.png +0 -0
- package/dist/ui/logos/index.html +148 -0
- package/dist/ui/logos/neon-A-transparent.png +0 -0
- package/dist/ui/logos/neon-A.png +0 -0
- package/dist/ui/logos/palette.json +8 -0
- package/dist/ui/logos/slicc-favicon-128.png +0 -0
- package/dist/ui/logos/slicc-favicon-16.png +0 -0
- package/dist/ui/logos/slicc-favicon-32.png +0 -0
- package/dist/ui/logos/slicc-favicon-48.png +0 -0
- package/dist/ui/packages/webapp/index.html +14 -0
- package/dist/ui/preview-sw.js +1 -1
- package/package.json +22 -20
- package/dist/ui/assets/magic-string.es-BPLJknd7.js +0 -10
- package/dist/ui/assets/pyodide-D73G_Ygx.mjs +0 -4
- /package/dist/{cli → node-server}/chrome-launch.d.ts +0 -0
- /package/dist/{cli → node-server}/chrome-launch.js +0 -0
- /package/dist/{cli → node-server}/cli-log-dedup.d.ts +0 -0
- /package/dist/{cli → node-server}/cli-log-dedup.js +0 -0
- /package/dist/{cli → node-server}/electron-controller.d.ts +0 -0
- /package/dist/{cli → node-server}/electron-main.d.ts +0 -0
- /package/dist/{cli → node-server}/electron-main.js +0 -0
- /package/dist/{cli → node-server}/electron-runtime.d.ts +0 -0
- /package/dist/{cli → node-server}/file-logger.d.ts +0 -0
- /package/dist/{cli → node-server}/file-logger.js +0 -0
- /package/dist/{cli → node-server}/index.d.ts +0 -0
- /package/dist/{cli → node-server}/launch-url.d.ts +0 -0
- /package/dist/{cli → node-server}/qa-setup.d.ts +0 -0
- /package/dist/{cli → node-server}/qa-setup.js +0 -0
- /package/dist/{cli → node-server}/release-package.d.ts +0 -0
- /package/dist/{cli → node-server}/runtime-flags.d.ts +0 -0
- /package/dist/{cli → node-server}/runtime-flags.js +0 -0
- /package/dist/{cli → node-server}/sync-release-version.d.ts +0 -0
- /package/dist/{tray-url-shared.d.ts → node-server/tray-url-shared.d.ts} +0 -0
- /package/dist/{tray-url-shared.js → node-server/tray-url-shared.js} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
You are looking at a macOS desktop, with four windows running:
|
|
4
4
|
|
|
@@ -85,8 +85,8 @@ npm install
|
|
|
85
85
|
npm start
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
- Optionally pre-configure providers: `cp providers.example.json providers.json`
|
|
89
|
-
- See [providers.example.json](providers.example.json) for the available provider fields.
|
|
88
|
+
- Optionally pre-configure providers: `cp packages/dev-tools/providers.example.json packages/webapp/providers.json`
|
|
89
|
+
- See [packages/dev-tools/providers.example.json](packages/dev-tools/providers.example.json) for the available provider fields.
|
|
90
90
|
- For contributor-focused setup details, see [docs/development.md](docs/development.md).
|
|
91
91
|
|
|
92
92
|
### 4. Chrome extension
|
|
@@ -22,7 +22,7 @@ export function findMatchingElectronAppPids(runningProcesses, processMatchPatter
|
|
|
22
22
|
const matches = runningProcesses.filter((processInfo) => {
|
|
23
23
|
// Skip Node.js tool-chain processes and shell wrappers — they may have the app path
|
|
24
24
|
// as a CLI argument but are not the Electron app itself
|
|
25
|
-
// (e.g. npx tsx src/
|
|
25
|
+
// (e.g. npx tsx packages/node-server/src/index.ts --electron /Applications/Slack.app)
|
|
26
26
|
// Shell wrappers like `zsh -c ... /Applications/Slack.app --kill` or
|
|
27
27
|
// `timeout 30 npm run dev:electron -- /Applications/Slack.app` also match.
|
|
28
28
|
const cmdTrimmed = processInfo.commandLine.trimStart();
|
|
@@ -235,13 +235,13 @@ export function buildElectronServerSpawnConfig(projectRoot, options) {
|
|
|
235
235
|
if (options.dev) {
|
|
236
236
|
return {
|
|
237
237
|
command: (options.platform ?? process.platform) === 'win32' ? 'npx.cmd' : 'npx',
|
|
238
|
-
args: ['tsx', 'src/
|
|
238
|
+
args: ['tsx', 'packages/node-server/src/index.ts', '--dev', '--serve-only', `--cdp-port=${options.cdpPort}`],
|
|
239
239
|
};
|
|
240
240
|
}
|
|
241
241
|
return {
|
|
242
242
|
command: options.nodePath ?? process.env['npm_node_execpath'] ?? 'node',
|
|
243
243
|
args: [
|
|
244
|
-
resolve(projectRoot, 'dist/
|
|
244
|
+
resolve(projectRoot, 'dist/node-server/index.js'),
|
|
245
245
|
'--serve-only',
|
|
246
246
|
`--cdp-port=${options.cdpPort}`,
|
|
247
247
|
],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createServer } from 'http';
|
|
3
3
|
import { createServer as createNetServer } from 'net';
|
|
4
4
|
import { spawn } from 'child_process';
|
|
5
|
-
import { existsSync } from 'fs';
|
|
5
|
+
import { existsSync, readFileSync } from 'fs';
|
|
6
6
|
import { join, resolve } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import express from 'express';
|
|
@@ -826,6 +826,7 @@ async function main() {
|
|
|
826
826
|
if (DEV_MODE) {
|
|
827
827
|
// Dev mode: use Vite's dev server as middleware for HMR
|
|
828
828
|
const { createServer: createViteServer } = await import('vite');
|
|
829
|
+
const webappIndexHtml = resolve(process.cwd(), 'packages/webapp/index.html');
|
|
829
830
|
const vite = await createViteServer({
|
|
830
831
|
server: {
|
|
831
832
|
middlewareMode: true,
|
|
@@ -833,9 +834,28 @@ async function main() {
|
|
|
833
834
|
port: HMR_PORT, // Use a separate port for HMR WebSocket to avoid conflicting with /cdp
|
|
834
835
|
},
|
|
835
836
|
},
|
|
837
|
+
appType: 'custom', // We handle index.html serving ourselves via the handler below
|
|
836
838
|
root: process.cwd(),
|
|
837
839
|
});
|
|
838
840
|
app.use(vite.middlewares);
|
|
841
|
+
app.use(async (req, res, next) => {
|
|
842
|
+
if (req.method !== 'GET' || !req.headers.accept?.includes('text/html') || req.path.includes('.')) {
|
|
843
|
+
next();
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
try {
|
|
847
|
+
const template = readFileSync(webappIndexHtml, 'utf-8');
|
|
848
|
+
const html = await vite.transformIndexHtml(req.originalUrl, template);
|
|
849
|
+
res.status(200).setHeader('Content-Type', 'text/html');
|
|
850
|
+
res.end(html);
|
|
851
|
+
}
|
|
852
|
+
catch (err) {
|
|
853
|
+
if (err instanceof Error) {
|
|
854
|
+
vite.ssrFixStacktrace(err);
|
|
855
|
+
}
|
|
856
|
+
next(err);
|
|
857
|
+
}
|
|
858
|
+
});
|
|
839
859
|
console.log(`Vite dev server middleware attached (HMR active on port ${HMR_PORT})`);
|
|
840
860
|
}
|
|
841
861
|
else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildCanonicalTrayLaunchUrl, normalizeTrayWorkerBaseUrl, parseTrayJoinUrl, } from '
|
|
1
|
+
import { buildCanonicalTrayLaunchUrl, normalizeTrayWorkerBaseUrl, parseTrayJoinUrl, } from './tray-url-shared.js';
|
|
2
2
|
function buildTrayJoinLaunchUrl(locationHref, joinUrl) {
|
|
3
3
|
const parsedJoinUrl = parseTrayJoinUrl(joinUrl);
|
|
4
4
|
if (!parsedJoinUrl) {
|
|
@@ -178,7 +178,7 @@ function createExtensionArchive(metadata) {
|
|
|
178
178
|
return zipPath;
|
|
179
179
|
}
|
|
180
180
|
function createNpmPackageTarball() {
|
|
181
|
-
requirePath(resolve(PROJECT_ROOT, 'dist', '
|
|
181
|
+
requirePath(resolve(PROJECT_ROOT, 'dist', 'node-server'), 'CLI build output');
|
|
182
182
|
requirePath(resolve(PROJECT_ROOT, 'dist', 'ui'), 'UI build output');
|
|
183
183
|
const npm = resolveNpmCommand();
|
|
184
184
|
const result = spawnSync(npm.command, [...npm.argsPrefix, 'pack', '--json', '--ignore-scripts', '--pack-destination', RELEASE_DIR], {
|
|
@@ -198,7 +198,7 @@ function writeReleaseManifest(manifest) {
|
|
|
198
198
|
}
|
|
199
199
|
export function packageReleaseArtifacts() {
|
|
200
200
|
const packageJson = readJsonFile(resolve(PROJECT_ROOT, 'package.json'));
|
|
201
|
-
const extensionManifest = readJsonFile(resolve(PROJECT_ROOT, 'manifest.json'));
|
|
201
|
+
const extensionManifest = readJsonFile(resolve(PROJECT_ROOT, 'packages/chrome-extension/manifest.json'));
|
|
202
202
|
assertMatchingVersions(packageJson.version, extensionManifest.version);
|
|
203
203
|
rmSync(RELEASE_DIR, { recursive: true, force: true });
|
|
204
204
|
mkdirSync(RELEASE_DIR, { recursive: true });
|
|
@@ -17,9 +17,9 @@ export function writeManifestVersion(manifestPath, version) {
|
|
|
17
17
|
function main() {
|
|
18
18
|
const version = process.argv[2];
|
|
19
19
|
if (!version) {
|
|
20
|
-
throw new Error('Usage: node dist/
|
|
20
|
+
throw new Error('Usage: node dist/node-server/sync-release-version.js <version>');
|
|
21
21
|
}
|
|
22
|
-
writeManifestVersion(resolve(PROJECT_ROOT, 'manifest.json'), version);
|
|
22
|
+
writeManifestVersion(resolve(PROJECT_ROOT, 'packages/chrome-extension/manifest.json'), version);
|
|
23
23
|
console.log(`Updated manifest.json version to ${version}`);
|
|
24
24
|
}
|
|
25
25
|
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./__vite-browser-external-D7Ct-6yo.js";import{g as r}from"./index-
|
|
1
|
+
import{_ as e}from"./__vite-browser-external-D7Ct-6yo.js";import{g as r}from"./index-CL0Bwyen.js";const a=r(e);export{a as r};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as u}from"./index-
|
|
1
|
+
import{c as u}from"./index-CL0Bwyen.js";const l=["/workspace","/shared"];async function d(s){const t=[],e=new Set;for(const r of l)await s.exists(r)&&await p(s,r,t,e);return t}async function p(s,t,e,r){for await(const n of s.walk(t)){if(!n.endsWith(".bsh")||r.has(n))continue;r.add(n);const i=g(n);if(!i)continue;const a=await s.readFile(n,{encoding:"utf-8"}),c=typeof a=="string"?a:new TextDecoder().decode(a),f=m(c);e.push({path:n,hostnamePattern:i,matchPatterns:f})}}function g(s){const t=s.split("/").pop()??"";if(!t.endsWith(".bsh"))return null;const e=t.slice(0,-4);return e?e.startsWith("-.")?"*"+e.slice(1):e:null}function m(s){const t=s.split(`
|
|
2
2
|
`).slice(0,10),e=[];for(const r of t){const n=r.match(/^\s*\/\/\s*@match\s+(.+)$/);n&&e.push(n[1].trim())}return e}function h(s,t){if(t.startsWith("*.")){const e=t.slice(1);return s.endsWith(e)&&s.length>e.length}return s===t}function v(s,t){try{const e=new URL(s),r=t.match(/^(\*|https?):\/\/([^/]+)(\/.*)?$/);if(!r)return!1;const[,n,i,a]=r;return n!=="*"&&e.protocol.slice(0,-1)!==n||!h(e.hostname,i)?!1:a?x(e.pathname+e.search,a):!0}catch{return!1}}function x(s,t){const e="^"+t.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")+"$";return new RegExp(e).test(s)}function w(s,t){try{const e=new URL(t);return s.filter(r=>h(e.hostname,r.hostnamePattern)?r.matchPatterns.length>0?r.matchPatterns.some(n=>v(t,n)):!0:!1)}catch{return[]}}const o=u("bsh-watchdog");class S{transport;fs;execute;discoveryIntervalMs;entries=[];discoveryTimer=null;running=!1;executing=new Set;constructor(t){this.transport=t.transport,this.fs=t.fs,this.execute=t.execute,this.discoveryIntervalMs=t.discoveryIntervalMs??3e4}async start(){this.running||(this.running=!0,await this.discover(),this.discoveryTimer=setInterval(()=>{this.discover()},this.discoveryIntervalMs),this.transport.on("Page.frameNavigated",this.onFrameNavigated),o.info("BSH watchdog started",{scriptCount:this.entries.length}))}stop(){this.running&&(this.running=!1,this.transport.off("Page.frameNavigated",this.onFrameNavigated),this.discoveryTimer&&(clearInterval(this.discoveryTimer),this.discoveryTimer=null),this.entries=[],this.executing.clear(),o.info("BSH watchdog stopped"))}async discover(){try{this.entries=await d(this.fs),o.debug("BSH discovery complete",{count:this.entries.length})}catch(t){o.error("BSH discovery failed",{error:t instanceof Error?t.message:String(t)})}}getEntries(){return this.entries}onFrameNavigated=t=>{const e=t.frame;if(e?.parentId||!e?.url)return;const r=e.url;if(!r.startsWith("http://")&&!r.startsWith("https://")||this.entries.length===0)return;const n=w(this.entries,r);if(n.length!==0)for(const i of n){const a=`${i.path}::${r}`;this.executing.has(a)||(this.executing.add(a),o.info("BSH watchdog executing script",{script:i.path,url:r}),this.execute(i.path).then(c=>{c.exitCode!==0?o.warn("BSH script failed",{script:i.path,url:r,exitCode:c.exitCode,stderr:c.stderr.slice(0,200)}):o.info("BSH script completed",{script:i.path,url:r})}).catch(c=>{o.error("BSH script execution error",{script:i.path,url:r,error:c instanceof Error?c.message:String(c)})}).finally(()=>{this.executing.delete(a)}))}}}export{S as BshWatchdog};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as F,r as g,a as A,b as L,d as T,e as _,h as C,j as D,k as P}from"./index-
|
|
1
|
+
import{i as F,r as g,a as A,b as L,d as T,e as _,h as C,j as D,k as P}from"./index-CL0Bwyen.js";import{M as b,l as V,S as B,m as X,n as Y,o as q,p as z,q as U,W as Z,s as G,u as J,v as Q,w as N,x as ee,y as se,z as ie}from"./index-CL0Bwyen.js";function I(s){return s.startsWith("/")?{valid:!1,error:`Absolute path not allowed: ${s}`}:s.split("/").some(l=>l==="..")?{valid:!1,error:`Path traversal not allowed: ${s}`}:s.includes("%2e%2e")||s.includes("%2E%2E")?{valid:!1,error:`Encoded path traversal not allowed: ${s}`}:{valid:!0}}async function x(s,i){const l=i.split("/").filter(Boolean);let o="";for(const e of l){o+="/"+e;try{await s.mkdir(o)}catch{}}}async function O(s,i,l="/workspace/skills"){const o=`${l}/${i}`;await F(s);let e;try{e=await g(s,o)}catch(d){return{success:!1,skill:i,version:"unknown",error:`Failed to read manifest: ${d instanceof Error?d.message:String(d)}`}}if(e.skill!==i)return{success:!1,skill:i,version:e.version,error:`Manifest skill name "${e.skill}" does not match directory name "${i}"`};const p=await A(s);if(p.includes(e.skill))return{success:!1,skill:e.skill,version:e.version,error:`Skill "${e.skill}" is already installed`};const u=L(e,p);if(!u.ok)return{success:!1,skill:e.skill,version:e.version,error:`Missing dependencies: ${u.missing.join(", ")}`};const t=T(e,p);if(!t.ok)return{success:!1,skill:e.skill,version:e.version,error:`Conflicting skills: ${t.conflicting.join(", ")}`};const c={},h=[];try{if(e.adds&&e.adds.length>0)for(const n of e.adds){const k=I(n);if(!k.valid)return{success:!1,skill:e.skill,version:e.version,error:k.error};const $=`${o}/add/${n}`,a=`/${n}`;try{const r=a.substring(0,a.lastIndexOf("/"));r&&await x(s,r),await s.copyFile($,a),h.push(n);const f=await s.readTextFile(a);c[n]=await _(f)}catch(r){return{success:!1,skill:e.skill,version:e.version,error:`Failed to copy ${n}: ${r instanceof Error?r.message:String(r)}`}}}if(e.modifies&&e.modifies.length>0)for(const n of e.modifies){const k=I(n);if(!k.valid)return{success:!1,skill:e.skill,version:e.version,error:k.error};const $=`${o}/modify/${n}`;try{const a=await s.readTextFile($);let r="";try{r=await s.readTextFile(`/${n}`)}catch{}let f;if(a.includes("// APPEND_AFTER:")){const w=a.split(`
|
|
2
2
|
`),v=w.find(S=>S.includes("// APPEND_AFTER:"))?.split("// APPEND_AFTER:")[1]?.trim(),m=w.filter(S=>!S.includes("// APPEND_AFTER:")).join(`
|
|
3
3
|
`);if(v&&r.includes(v)){const S=r.indexOf(v)+v.length,E=r.indexOf(`
|
|
4
4
|
`,S);if(E===-1){const y=r.endsWith(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as f,B as C}from"./index-
|
|
1
|
+
import{c as f,B as C}from"./index-CL0Bwyen.js";import{C as P,H as v,R as H}from"./index-CL0Bwyen.js";const u="[slicc-tab-group]";let g=null;async function p(o){try{if(g!==null)try{await chrome.tabs.group({tabIds:o,groupId:g});return}catch(e){console.info(u,"Tab group removed by user, recreating",{tabId:o,previousGroupId:g,error:e instanceof Error?e.message:String(e)}),g=null}g=await chrome.tabs.group({tabIds:o}),await chrome.tabGroups.update(g,{title:"slicc",color:"pink",collapsed:!1})}catch(e){console.warn(u,"Tab grouping failed (best-effort, continuing without group)",{tabId:o,error:e instanceof Error?e.message:String(e)})}}const h=f("cdp:debugger");class y{_state="disconnected";listeners=new Map;sessionToTab=new Map;attachedTabs=new Set;onEventHandler=(e,s,t)=>{if(!this.attachedTabs.has(e.tabId))return;let n;for(const[a,i]of this.sessionToTab)if(i===e.tabId){n=a;break}h.debug("Event",{tabId:e.tabId,method:s,sessionId:n});const r=this.listeners.get(s);if(r){const a=n?{...t,sessionId:n}:t??{};for(const i of r)try{i(a)}catch(d){h.error("CDP event listener error",{method:s,error:d instanceof Error?d.message:String(d)})}}};onDetachHandler=(e,s)=>{h.warn("Debugger detached",{tabId:e.tabId,reason:s}),this.attachedTabs.delete(e.tabId);for(const[t,n]of this.sessionToTab)n===e.tabId&&this.sessionToTab.delete(t);this.attachedTabs.size===0&&(this._state="disconnected")};get state(){return this._state}async connect(e){if(this._state!=="disconnected")throw new Error(`Cannot connect: state is ${this._state}`);chrome.debugger.onEvent.addListener(this.onEventHandler),chrome.debugger.onDetach.addListener(this.onDetachHandler),this._state="connected",h.info("DebuggerClient connected (extension mode)")}disconnect(){for(const e of this.attachedTabs)chrome.debugger.detach({tabId:e}).catch(s=>{h.debug("Detach during disconnect",{tabId:e,error:s instanceof Error?s.message:String(s)})});chrome.debugger.onEvent.removeListener(this.onEventHandler),chrome.debugger.onDetach.removeListener(this.onDetachHandler),this.attachedTabs.clear(),this.sessionToTab.clear(),this._state="disconnected",h.info("DebuggerClient disconnected")}async send(e,s,t,n){if(this._state!=="connected")throw new Error("DebuggerClient is not connected");switch(e){case"Target.getTargets":return this.handleGetTargets();case"Target.attachToTarget":return this.handleAttachToTarget(s);case"Target.detachFromTarget":return this.handleDetachFromTarget(s);case"Target.createTarget":return this.handleCreateTarget(s);case"Target.closeTarget":return this.handleCloseTarget(s);default:return this.sendCdpCommand(e,s,t)}}on(e,s){let t=this.listeners.get(e);t||(t=new Set,this.listeners.set(e,t)),t.add(s)}off(e,s){const t=this.listeners.get(e);t&&(t.delete(s),t.size===0&&this.listeners.delete(e))}once(e,s=3e4){return new Promise((t,n)=>{const r=setTimeout(()=>{this.off(e,a),n(new Error(`Timed out waiting for event: ${e}`))},s),a=i=>{clearTimeout(r),this.off(e,a),t(i)};this.on(e,a)})}async handleGetTargets(){const[e,s]=await Promise.all([chrome.tabs.query({}),chrome.tabs.query({active:!0,currentWindow:!0})]),t=new Set(s.map(r=>r.id));return{targetInfos:e.map(r=>({targetId:String(r.id),type:"page",title:r.title??"",url:r.url??"",attached:this.attachedTabs.has(r.id),active:t.has(r.id)}))}}async handleAttachToTarget(e){const s=e.targetId,t=parseInt(s,10);if(!Number.isFinite(t)||t<=0)throw new Error(`Invalid targetId: ${s}`);this.attachedTabs.has(t)||(await chrome.debugger.attach({tabId:t},"1.3"),this.attachedTabs.add(t));const n=s;return this.sessionToTab.set(n,t),{sessionId:n}}async handleDetachFromTarget(e){const s=e.sessionId,t=this.sessionToTab.get(s);return t!==void 0&&(this.sessionToTab.delete(s),[...this.sessionToTab.values()].includes(t)||(this.attachedTabs.delete(t),await chrome.debugger.detach({tabId:t}).catch(r=>{h.debug("Detach failed (tab may be closed)",{tabId:t,error:r instanceof Error?r.message:String(r)})}))),{}}async handleCreateTarget(e){const s=e.url??"about:blank",t=await chrome.tabs.create({url:s,active:!1});return await p(t.id),{targetId:String(t.id)}}async handleCloseTarget(e){const s=e.targetId,t=parseInt(s,10);if(!Number.isFinite(t)||t<=0)throw new Error(`Invalid targetId: ${s}`);for(const[n,r]of this.sessionToTab)r===t&&this.sessionToTab.delete(n);return this.attachedTabs.has(t)&&(this.attachedTabs.delete(t),await chrome.debugger.detach({tabId:t}).catch(n=>{h.debug("Detach before close failed",{tabId:t,error:n instanceof Error?n.message:String(n)})})),await chrome.tabs.remove(t),{success:!0}}async sendCdpCommand(e,s,t){const n=t?this.sessionToTab.get(t):void 0;if(n===void 0)throw new Error(`No tab attached for sessionId: ${t??"(none)"}. Attach to a target first.`);return h.debug("Send",{method:e,tabId:n,sessionId:t}),await chrome.debugger.sendCommand({tabId:n},e,s)??{}}}class I{_state="disconnected";nextCommandId=1;listeners=new Map;pendingCommands=new Map;messageHandler=null;get state(){return this._state}async connect(e){if(this._state!=="disconnected")throw new Error(`Cannot connect: state is ${this._state}`);this.messageHandler=s=>{if(!T(s))return;const t=s;if(t.source!=="service-worker")return;const n=t.payload;n.type==="cdp-response"?this.handleCdpResponse(n):n.type==="cdp-event"&&this.handleCdpEvent(n)},chrome.runtime.onMessage.addListener(this.messageHandler),this._state="connected"}disconnect(){this.messageHandler&&(chrome.runtime.onMessage.removeListener(this.messageHandler),this.messageHandler=null);for(const[,e]of this.pendingCommands)clearTimeout(e.timer),e.reject(new Error("CDP proxy disconnected"));this.pendingCommands.clear(),this.listeners.clear(),this._state="disconnected"}async send(e,s,t,n=3e4){if(this._state!=="connected")throw new Error("OffscreenCdpProxy is not connected");const r=this.nextCommandId++,a={type:"cdp-command",id:r,method:e,params:s,sessionId:t};return new Promise((i,d)=>{let c=!1;const m=setTimeout(()=>{c||(c=!0,this.pendingCommands.delete(r),d(new Error(`CDP command timed out after ${n}ms: ${e}`)))},n);this.pendingCommands.set(r,{resolve:i,reject:d,timer:m}),chrome.runtime.sendMessage({source:"offscreen",payload:a}).catch(l=>{c||(c=!0,this.pendingCommands.delete(r),clearTimeout(m),d(new Error(`Failed to send CDP command: ${l instanceof Error?l.message:String(l)}`)))})})}on(e,s){let t=this.listeners.get(e);t||(t=new Set,this.listeners.set(e,t)),t.add(s)}off(e,s){const t=this.listeners.get(e);t&&(t.delete(s),t.size===0&&this.listeners.delete(e))}once(e,s=3e4){return new Promise((t,n)=>{const r=setTimeout(()=>{this.off(e,a),n(new Error(`Timed out waiting for event: ${e}`))},s),a=i=>{clearTimeout(r),this.off(e,a),t(i)};this.on(e,a)})}handleCdpResponse(e){const s=this.pendingCommands.get(e.id);s&&(this.pendingCommands.delete(e.id),clearTimeout(s.timer),e.error?s.reject(new Error(e.error)):s.resolve(e.result??{}))}handleCdpEvent(e){const s=this.listeners.get(e.method);if(s)for(const t of s)try{t(e.params??{})}catch{}}}function T(o){return typeof o=="object"&&o!==null&&"source"in o&&"payload"in o}class E{_state="disconnected";nextCommandId=1;listeners=new Map;pendingCommands=new Map;messageHandler=null;get state(){return this._state}async connect(e){if(this._state!=="disconnected")throw new Error(`Cannot connect: state is ${this._state}`);this.messageHandler=s=>{try{if(!b(s))return;const t=s;t.source==="offscreen"&&t.payload.type==="panel-cdp-response"&&this.handleCdpResponse(t.payload),t.source==="service-worker"&&t.payload.type==="cdp-event"&&this.handleCdpEvent(t.payload)}catch(t){console.error("[panel-cdp-proxy] Error in message handler:",t)}},chrome.runtime.onMessage.addListener(this.messageHandler),this._state="connected"}disconnect(){this.messageHandler&&(chrome.runtime.onMessage.removeListener(this.messageHandler),this.messageHandler=null);for(const[,e]of this.pendingCommands)clearTimeout(e.timer),e.reject(new Error("Panel CDP proxy disconnected"));this.pendingCommands.clear(),this.listeners.clear(),this._state="disconnected"}async send(e,s,t,n=3e4){if(this._state!=="connected")throw new Error("PanelCdpProxy is not connected");const r=this.nextCommandId++,a={type:"panel-cdp-command",id:r,method:e,params:s,sessionId:t};return new Promise((i,d)=>{let c=!1;const m=setTimeout(()=>{c||(c=!0,this.pendingCommands.delete(r),d(new Error(`CDP command timed out after ${n}ms: ${e}`)))},n);this.pendingCommands.set(r,{resolve:i,reject:d,timer:m}),chrome.runtime.sendMessage({source:"panel",payload:a}).catch(l=>{c||(c=!0,this.pendingCommands.delete(r),clearTimeout(m),d(new Error(`Failed to send CDP command: ${l instanceof Error?l.message:String(l)}`)))})})}on(e,s){let t=this.listeners.get(e);t||(t=new Set,this.listeners.set(e,t)),t.add(s)}off(e,s){const t=this.listeners.get(e);t&&(t.delete(s),t.size===0&&this.listeners.delete(e))}once(e,s=3e4){return new Promise((t,n)=>{const r=setTimeout(()=>{this.off(e,a),n(new Error(`Timed out waiting for event: ${e}`))},s),a=i=>{clearTimeout(r),this.off(e,a),t(i)};this.on(e,a)})}handleCdpResponse(e){const s=this.pendingCommands.get(e.id);if(!s){console.warn(`[panel-cdp-proxy] Ignoring CDP response with unknown id ${e.id}`);return}this.pendingCommands.delete(e.id),clearTimeout(s.timer),e.error?s.reject(new Error(e.error)):s.resolve(e.result??{})}handleCdpEvent(e){const s=this.listeners.get(e.method);if(s)for(const t of s)try{t(e.params??{})}catch(n){console.error(`[panel-cdp-proxy] Listener error for event "${e.method}":`,n)}}}function b(o){return typeof o=="object"&&o!==null&&"source"in o&&"payload"in o}export{C as BrowserAPI,P as CDPClient,y as DebuggerClient,v as HarRecorder,I as OffscreenCdpProxy,E as PanelCdpProxy,H as RemoteCDPTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as z,f as x}from"./index-
|
|
1
|
+
import{t as z,f as x}from"./index-CL0Bwyen.js";class T{marshaller;serializer;deserializer;serdeContext;defaultContentType;constructor({marshaller:i,serializer:n,deserializer:o,serdeContext:c,defaultContentType:y}){this.marshaller=i,this.serializer=n,this.deserializer=o,this.serdeContext=c,this.defaultContentType=y}async serializeEventStream({eventStream:i,requestSchema:n,initialRequest:o}){const c=this.marshaller,y=n.getEventStreamMember(),p=n.getMemberSchema(y),d=this.serializer,u=this.defaultContentType,h=Symbol("initialRequestMarker"),S={async*[Symbol.asyncIterator](){if(o){const r={":event-type":{type:"string",value:"initial-request"},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:u}};d.write(n,o);const t=d.flush();yield{[h]:!0,headers:r,body:t}}for await(const r of i)yield r}};return c.serialize(S,r=>{if(r[h])return{headers:r.headers,body:r.body};const t=Object.keys(r).find(s=>s!=="__type")??"",{additionalHeaders:e,body:a,eventType:l,explicitPayloadContentType:m}=this.writeEventBody(t,p,r);return{headers:{":event-type":{type:"string",value:l},":message-type":{type:"string",value:"event"},":content-type":{type:"string",value:m??u},...e},body:a}})}async deserializeEventStream({response:i,responseSchema:n,initialResponseContainer:o}){const c=this.marshaller,y=n.getEventStreamMember(),d=n.getMemberSchema(y).getMemberSchemas(),u=Symbol("initialResponseMarker"),h=c.deserialize(i.body,async t=>{const e=Object.keys(t).find(l=>l!=="__type")??"",a=t[e].body;if(e==="initial-response"){const l=await this.deserializer.read(n,a);return delete l[y],{[u]:!0,...l}}else if(e in d){const l=d[e];if(l.isStructSchema()){const m={};let f=!1;for(const[s,g]of l.structIterator()){const{eventHeader:v,eventPayload:w}=g.getMergedTraits();if(f=f||!!(v||w),w)g.isBlobSchema()?m[s]=a:g.isStringSchema()?m[s]=(this.serdeContext?.utf8Encoder??z)(a):g.isStructSchema()&&(m[s]=await this.deserializer.read(g,a));else if(v){const b=t[e].headers[s]?.value;b!=null&&(g.isNumericSchema()?b&&typeof b=="object"&&"bytes"in b?m[s]=BigInt(b.toString()):m[s]=Number(b):m[s]=b)}}if(f)return{[e]:m};if(a.byteLength===0)return{[e]:{}}}return{[e]:await this.deserializer.read(l,a)}}else return{$unknown:t}}),S=h[Symbol.asyncIterator](),r=await S.next();if(r.done)return h;if(r.value?.[u]){if(!n)throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");for(const[t,e]of Object.entries(r.value))o[t]=e}return{async*[Symbol.asyncIterator](){for(r?.value?.[u]||(yield r.value);;){const{done:t,value:e}=await S.next();if(t)break;yield e}}}}writeEventBody(i,n,o){const c=this.serializer;let y=i,p=null,d;const u=n.getSchema()[4].includes(i),h={};if(u){const t=n.getMemberSchema(i);if(t.isStructSchema()){for(const[e,a]of t.structIterator()){const{eventHeader:l,eventPayload:m}=a.getMergedTraits();if(m)p=e;else if(l){const f=o[i][e];let s="binary";a.isNumericSchema()?(-2)**31<=f&&f<=2**31-1?s="integer":s="long":a.isTimestampSchema()?s="timestamp":a.isStringSchema()?s="string":a.isBooleanSchema()&&(s="boolean"),f!=null&&(h[e]={type:s,value:f},delete o[i][e])}}if(p!==null){const e=t.getMemberSchema(p);e.isBlobSchema()?d="application/octet-stream":e.isStringSchema()&&(d="text/plain"),c.write(e,o[i][p])}else c.write(t,o[i])}else if(t.isUnitSchema())c.write(t,{});else throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.")}else{const[t,e]=o[i];y=t,c.write(15,e)}const S=c.flush();return{body:typeof S=="string"?(this.serdeContext?.utf8Decoder??x)(S):S,eventType:y,explicitPayloadContentType:d,additionalHeaders:h}}}export{T as EventStreamSerde};
|