| … | … | @@ -31,7 +31,7 @@ whose subject matches `PEARBROWSER_WINDOWS_SIGNING_SUBJECT`. |
| 31 | 31 | |
| 32 | 32 | Run `npm run check:appling-release -- --tag v0.5.0` before cutting a release. |
| 33 | 33 | It verifies that `CMakeLists.txt` uses the same version as the desktop package |
| 34 | and the same Pear key as `pear.json`. | |
| 34 | and the same Pear OTA update channel as `package.json`. | |
| 35 | 35 | |
| 36 | 36 | Run `npm run check:native-signing -- --require-public-trust` from the repo root |
| 37 | 37 | before publishing public desktop assets. It validates that the macOS Developer |
| … | … | @@ -1265,7 +1265,6 @@ rpc.handle(C.CMD_RESET_APP, async () => { |
| 1265 | 1265 | |
| 1266 | 1266 | // Give the reply a tick to reach the UI before we exit. |
| 1267 | 1267 | setTimeout(() => { |
| 1268 | try { if (typeof Pear !== 'undefined' && Pear.exit) Pear.exit() } catch {} | |
| 1269 | 1268 | try { Bare.exit?.() } catch {} |
| 1270 | 1269 | }, 200) |
| 1271 | 1270 | |
| … | … | @@ -3420,7 +3419,8 @@ async function cleanupOldData () { |
| 3420 | 3419 | Bare.on('suspend', () => IPC.unref()) |
| 3421 | 3420 | Bare.on('resume', () => IPC.ref()) |
| 3422 | 3421 | |
| 3423 | // When main closes the IPC pipe (window closed, Pear.teardown), run | |
| 3422 | // When the native host closes the IPC pipe (for example, when its window | |
| 3423 | // closes), run | |
| 3424 | 3424 | // a clean shutdown so Corestore flushes, Hyperswarm closes, and |
| 3425 | 3425 | // rocksdb releases its LOCK. Without this the next launch trips on |
| 3426 | 3426 | // EADDRINUSE or a stale LOCK. |
| … | … | @@ -2,14 +2,12 @@ |
| 2 | 2 | * Pear adapter for PearBrowser backend. |
| 3 | 3 | * |
| 4 | 4 | * The original backend assumes a mobile BareKit host that injects |
| 5 | * `BareKit.IPC` (a duplex stream) before the backend loads. In the | |
| 6 | * desktop Pear fork we run the backend in the renderer for M1 and | |
| 7 | * fake that injection with an in-memory pipe pair. | |
| 5 | * `BareKit.IPC` (a duplex stream) before the backend loads. For the | |
| 6 | * desktop worker adapter we use an in-memory pipe pair. | |
| 8 | 7 | * |
| 9 | * Migration to a real 2-process layout (pear-run + pear-pipe) only | |
| 10 | * has to swap the two "sides" returned here for a real `bare-pipe` | |
| 11 | * duplex; the backend code above and the UI RPC client below don't | |
| 12 | * change. | |
| 8 | * The v3 Electron host owns the worker lifecycle. If it later provides a | |
| 9 | * native duplex, only the two sides returned here need replacing; the backend | |
| 10 | * and renderer RPC contracts remain unchanged. | |
| 13 | 11 | */ |
| 14 | 12 | |
| 15 | 13 | const EventEmitter = require('bare-events') |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | # PearBrowser → mainstream-browser parity plan |
| 2 | 2 | |
| 3 | Status: Phases 1–3 shipped with gates closed; Phase 4 clearnet proxy + session-bridge facade shipped; Phase 5 privacy ladder shipped (HTTPS-only, tracking strip, farbling, cookie isolation in proxy mode). P2P distribution live 2026-07-16: filter-list drive subscriptions (`shield-list-sync.cjs`) and plugin installs from drives (`plugin-drive-loader.cjs` with the capability-escalation guard), plus the plugin catalogue (`plugin-catalog.cjs`, anonGPT in the builtin seed). All four distribution drives published, pinned, and fresh-peer verified — keys in `filter-lists/README.md`. Remaining: the native pear-electron session.webRequest bridge for direct-mode shields. | |
| 3 | Status: Phases 1–3 shipped with gates closed; Phase 4 clearnet proxy + session-bridge facade shipped; Phase 5 privacy ladder shipped (HTTPS-only, tracking strip, farbling, cookie isolation in proxy mode). P2P distribution live 2026-07-16: filter-list drive subscriptions (`shield-list-sync.cjs`) and plugin installs from drives (`plugin-drive-loader.cjs` with the capability-escalation guard), plus the plugin catalogue (`plugin-catalog.cjs`, anonGPT in the builtin seed). All four distribution drives published, pinned, and fresh-peer verified — keys in `filter-lists/README.md`. The v3 native host now owns Electron directly. Remaining: wire the existing ContentShield contract to Electron's native `session.webRequest` only after a dedicated policy/RPC boundary and cross-platform GUI evidence are in place. | |
| 4 | 4 | Date: 2026-07-16 |
| 5 | 5 | |
| 6 | 6 | The goal: make PearBrowser as capable a daily browser as Brave — ad blocking, |
| … | … | @@ -13,9 +13,9 @@ browser would do. The constraints below decide everything. |
| 13 | 13 | |
| 14 | 14 | ## 1. Ground truth: what PearBrowser is today |
| 15 | 15 | |
| 16 | - **Runtime split.** A Bare main process runs the backend | |
| 17 | (`backend/index.js`); a prebuilt pear-electron renderer runs the React UI | |
| 18 | (`ui/shell.js`). They speak length-prefixed JSON RPC over a loopback | |
| 16 | - **Runtime split.** An Electron main process owns the window and lifecycle; | |
| 17 | an embedded Pear OTA worker runs the Bare backend (`index.js`); the renderer | |
| 18 | hosts the UI (`ui/shell.js`). They speak length-prefixed JSON RPC over a loopback | |
| 19 | 19 | WebSocket (ports 9876–9880). |
| 20 | 20 | - **Tabs are sandboxed `<iframe>`s**, not Electron `<webview>`s |
| 21 | 21 | (`ui/shell.js`, `.webview` iframes; sandbox |
| … | … | @@ -28,10 +28,10 @@ browser would do. The constraints below decide everything. |
| 28 | 28 | injects `<base>`, tokens, and `window.pear.*` shims into every served HTML |
| 29 | 29 | document, and re-writes the page CSP to hash-authorize exactly the scripts |
| 30 | 30 | the browser injects (`injectCspShimHashes`) — never `unsafe-inline`. |
| 31 | - **Chromium's net stack is out of reach.** The Electron main process ships | |
| 32 | inside pear-electron's prebuilt boot bundle. App code cannot register | |
| 33 | `session.webRequest`, `declarativeNetRequest`, or protocol handlers without | |
| 34 | forking that bundle. | |
| 31 | - **Chromium's net stack is host-owned, but not yet policy-wired.** The | |
| 32 | Electron main process can register `session.webRequest`, but it must not do | |
| 33 | so until the browser's existing shield policy is exposed through a narrow, | |
| 34 | testable native-host boundary. | |
| 35 | 35 | - **Clearnet `https://` sites are not browsable.** `CMD_NAVIGATE` maps |
| 36 | 36 | non-loopback URLs onto `/hyper/<host>/…`, which 400s for non-drive hosts. |
| 37 | 37 | - **Capability permissions already exist.** Drive manifests declare |
| … | … | @@ -109,7 +109,7 @@ toolchain that was tested locally. |
| 109 | 109 | `scripts/check-appling-release.mjs` fails the workflow when: |
| 110 | 110 | |
| 111 | 111 | - the requested tag does not match `package.json` version |
| 112 | - `appling/CMakeLists.txt` does not match the production Pear key in `pear.json` | |
| 112 | - `appling/CMakeLists.txt` does not match the Pear OTA update channel in `package.json` | |
| 113 | 113 | - the appling CMake version is stale |
| 114 | 114 | - the appling package no longer exposes `generate`, `build`, and `package` |
| 115 | 115 | - the native wrapper toolchain lockfile, pinned Bare headers, macOS ICNS asset, |
| … | … | @@ -15,11 +15,21 @@ that presents verified applications and installs as distinct user actions. |
| 15 | 15 | |
| 16 | 16 | ## Runtime boundary |
| 17 | 17 | |
| 18 | The browser’s embedded runtime starts only a bundled local worker using the | |
| 19 | equivalent of `PearRuntime.run(require.resolve('./worker.js'))`. A remote | |
| 20 | catalogue link is discovery metadata, not executable worker input. The | |
| 21 | renderer cannot invoke an installer or runtime directly; those operations stay | |
| 22 | in the privileged local backend and require explicit user confirmation. | |
| 18 | PearBrowser v3 is a conventional Electron application. The Electron main | |
| 19 | process owns windows, OS lifecycle, and the narrow preload bridge; it starts | |
| 20 | only the bundled `workers/main.js` through | |
| 21 | `PearRuntime.run(require.resolve(...))`. That worker owns the Bare backend and | |
| 22 | the authenticated localhost RPC service. | |
| 23 | ||
| 24 | The renderer receives a freshly generated, per-launch session token through | |
| 25 | the context-isolated preload bridge. It cannot invoke the runtime, install an | |
| 26 | application, or obtain Node integration. A remote catalogue link remains | |
| 27 | discovery metadata, never a `PearRuntime.run()` input. | |
| 28 | ||
| 29 | The `package.json#upgrade` field is a v3 OTA deployment identity, not a | |
| 30 | browser-launch affordance. It must move to the project’s production multisig | |
| 31 | link before a public v3 release. The existing value is retained only to keep | |
| 32 | the source buildable while the signing quorum establishes that channel. | |
| 23 | 33 | |
| 24 | 34 | ## Data continuity |
| 25 | 35 | |
| … | … | @@ -30,8 +40,15 @@ evidence, not a substitute for package signature or local data validation. |
| 30 | 40 | |
| 31 | 41 | ## Release gate |
| 32 | 42 | |
| 33 | This source branch has removed remote legacy execution. Before it can be | |
| 34 | promoted as a v3 native runtime build, the pinned `pear-runtime@1.3.1` host, | |
| 35 | local worker boot/shutdown test, supported native package targets, and an | |
| 36 | approved v3 package installer flow must all be present and independently | |
| 37 | verified. | |
| 43 | This source branch contains the pinned `pear-runtime@1.3.1` native host and | |
| 44 | local-worker boundary, and tests the source contract. Promotion remains | |
| 45 | blocked until all of the following have independent evidence: | |
| 46 | ||
| 47 | - a real Electron launch plus worker/backend handshake on each supported OS; | |
| 48 | - a v3 `pear build` deployment assembled from those signed OS artifacts; | |
| 49 | - stage → provision → multisig release evidence for the production upgrade | |
| 50 | link (the signing quorum is human-controlled); | |
| 51 | - storage discovery, migration, validation, and rollback evidence for an | |
| 52 | existing v2 profile; and | |
| 53 | - installer/update/recovery UX evidence that treats HiveRelay as availability, | |
| 54 | never package attestation. |
| … | … | @@ -136,8 +136,9 @@ QVAC_SMOKE_MODEL_PATH=/absolute/path/to/model.gguf \ |
| 136 | 136 | This local path is host configuration for the diagnostic fixture only. An app |
| 137 | 137 | still chooses a browser-approved alias and can never submit a path to QVAC. |
| 138 | 138 | |
| 139 | `npm run smoke:qvac:pear` exercises the same terminal fixture through the Pear | |
| 140 | launcher when the local Pear runtime is fully installed. | |
| 139 | `npm run smoke:qvac:pear` is retained as a compatibility alias for the native | |
| 140 | Bare-worker smoke. PearBrowser's Electron host owns the embedded Pear OTA | |
| 141 | worker; it never uses a CLI launcher for this check. | |
| 141 | 142 | |
| 142 | 143 | ## Current proof |
| 143 | 144 |
| … | … | @@ -68,9 +68,9 @@ covered by `npm test`. |
| 68 | 68 | | --- | --- | |
| 69 | 69 | | `node scripts/runtime-rpc-smoke.mjs --timeout 20000 --max-storage-percent 100 --json` | Diagnostic WebSocket smoke against an already-running app. Requires PearBrowser to be launched first; public smoke should fail if the profile is over quota | |
| 70 | 70 | | `PEARBROWSER_RPC_DIAGNOSTIC_TOKEN=<random> node scripts/release-rpc-story-smoke.mjs --timeout 60000 --request-timeout 80000 --desktop-gui-stories --site-story --json` | Nonvisual story preflight against an app launched with the same `PEARBROWSER_RPC_DIAGNOSTIC_TOKEN`. Loads the release catalogues, fetches/reloads the PearBrowser homepage through the local proxy, verifies drive-info/site metadata, validates featured catalogue rows, confirms Peercord remains window-only, proves catalogue search/action rows, opens a safe catalogue-row Hyperdrive app through Browse, proves local search first-paint, curated/petname naming, bookmark/session round-trips with diagnostic reconnect, runs the Nostr trusted-contact proof, and emits release-evidence row suggestions. With `--site-story` it publishes/fetches/deletes a temporary site with HiveRelay unseed cleanup. It does not launch third-party Pear apps or approve trust prompts | |
| 71 | | `npm run start` | Interactive Pear dev launch: `pear run --dev .` | | |
| 72 | | `npm run run` | Interactive Pear launch: `pear run .` | | |
| 73 | | `pear run pear://tco5k7h38uoxatedp1wongdbhjxow1x7jiwm3t1i9cujbebhsbty` | Production browser launch/manual smoke gate | | |
| 71 | | `npm run start` | Interactive native Electron development launch with the embedded Pear OTA worker. | | |
| 72 | | `npm run run` | Interactive native Electron launch with the embedded Pear OTA worker. | | |
| 73 | | Signed PearBrowser native package | Production browser launch/manual smoke gate; the package contains the host and resolves its approved OTA update channel locally. | | |
| 74 | 74 | |
| 75 | 75 | Use `docs/MANUAL_RELEASE_SMOKE_2026-06-23.md` for GUI proof. Record machine, |
| 76 | 76 | commit SHA, screenshots/logs, and pass/fail notes beside each checked item. |
| … | … | @@ -0,0 +1,103 @@ |
| 1 | // Native v3 host. Electron owns application lifecycle and Pear OTA owns only | |
| 2 | // the embedded Bare backend/update worker; there is no `pear run` launch path. | |
| 3 | const { app, BrowserWindow, ipcMain } = require('electron') | |
| 4 | const crypto = require('node:crypto') | |
| 5 | const os = require('node:os') | |
| 6 | const path = require('node:path') | |
| 7 | const PearRuntime = require('pear-runtime') | |
| 8 | const pkg = require('../package.json') | |
| 9 | ||
| 10 | const sessionToken = crypto.randomBytes(32).toString('hex') | |
| 11 | const appName = pkg.productName || pkg.name | |
| 12 | let workerPipe = null | |
| 13 | let pearRuntime = null | |
| 14 | let quitting = false | |
| 15 | ||
| 16 | ipcMain.on('pearbrowser:runtime-session', (event) => { | |
| 17 | event.returnValue = sessionToken | |
| 18 | }) | |
| 19 | ||
| 20 | ipcMain.handle('pearbrowser:open-devtools', (event) => { | |
| 21 | event.sender.openDevTools({ mode: 'detach' }) | |
| 22 | }) | |
| 23 | ||
| 24 | function storagePath () { | |
| 25 | if (!app.isPackaged) return path.join(os.tmpdir(), 'pearbrowser-desktop') | |
| 26 | return app.getPath('userData') | |
| 27 | } | |
| 28 | ||
| 29 | function appBundlePath () { | |
| 30 | if (!app.isPackaged) return null | |
| 31 | if (process.platform === 'linux' && process.env.APPIMAGE) return process.env.APPIMAGE | |
| 32 | if (process.platform === 'win32') return process.execPath | |
| 33 | return path.join(process.resourcesPath, '..', '..') | |
| 34 | } | |
| 35 | ||
| 36 | async function startBackendWorker () { | |
| 37 | if (workerPipe) return workerPipe | |
| 38 | pearRuntime = new PearRuntime({ | |
| 39 | dir: storagePath(), | |
| 40 | name: appName, | |
| 41 | version: pkg.version, | |
| 42 | upgrade: pkg.upgrade, | |
| 43 | app: appBundlePath(), | |
| 44 | updates: app.isPackaged | |
| 45 | }) | |
| 46 | pearRuntime.on('error', (error) => console.error('Pear OTA runtime error:', error)) | |
| 47 | pearRuntime.updater.on('updating', () => console.log('PearBrowser update is downloading')) | |
| 48 | pearRuntime.updater.on('updated', () => console.log('PearBrowser update is ready; restart to apply it')) | |
| 49 | // OTA readiness is deliberately non-blocking: a browser must still open | |
| 50 | // offline using its installed build and local data. | |
| 51 | pearRuntime.ready().catch((error) => console.error('Pear OTA initialization failed:', error)) | |
| 52 | ||
| 53 | const worker = pearRuntime.run(require.resolve('../workers/main.js'), [pearRuntime.storage, sessionToken]) | |
| 54 | workerPipe = worker | |
| 55 | worker.once('exit', (code) => { | |
| 56 | workerPipe = null | |
| 57 | if (!quitting) console.error(`PearBrowser backend worker exited unexpectedly (${code})`) | |
| 58 | }) | |
| 59 | return workerPipe | |
| 60 | } | |
| 61 | ||
| 62 | async function createWindow () { | |
| 63 | const window = new BrowserWindow({ | |
| 64 | width: 1280, | |
| 65 | height: 800, | |
| 66 | minWidth: 920, | |
| 67 | minHeight: 600, | |
| 68 | backgroundColor: '#f6f8f7', | |
| 69 | webPreferences: { | |
| 70 | preload: path.join(__dirname, 'preload.cjs'), | |
| 71 | sandbox: true, | |
| 72 | nodeIntegration: false, | |
| 73 | contextIsolation: true | |
| 74 | } | |
| 75 | }) | |
| 76 | ||
| 77 | await window.loadFile(path.join(__dirname, '..', 'index.html')) | |
| 78 | } | |
| 79 | ||
| 80 | const singleInstance = app.requestSingleInstanceLock() | |
| 81 | if (!singleInstance) { | |
| 82 | app.quit() | |
| 83 | } else { | |
| 84 | app.whenReady().then(async () => { | |
| 85 | await startBackendWorker() | |
| 86 | await createWindow() | |
| 87 | app.on('activate', async () => { | |
| 88 | if (BrowserWindow.getAllWindows().length === 0) await createWindow() | |
| 89 | }) | |
| 90 | }).catch((error) => { | |
| 91 | console.error('Failed to start PearBrowser:', error) | |
| 92 | app.quit() | |
| 93 | }) | |
| 94 | ||
| 95 | app.on('window-all-closed', () => { | |
| 96 | if (process.platform !== 'darwin') app.quit() | |
| 97 | }) | |
| 98 | app.on('before-quit', () => { | |
| 99 | quitting = true | |
| 100 | try { workerPipe?.destroy() } catch {} | |
| 101 | pearRuntime?.close().catch((error) => console.error('Pear OTA runtime shutdown failed:', error)) | |
| 102 | }) | |
| 103 | } |
| … | … | @@ -0,0 +1,6 @@ |
| 1 | const { contextBridge, ipcRenderer } = require('electron') | |
| 2 | ||
| 3 | contextBridge.exposeInMainWorld('pearbrowserRuntime', { | |
| 4 | sessionToken: ipcRenderer.sendSync('pearbrowser:runtime-session'), | |
| 5 | openDevTools: () => ipcRenderer.invoke('pearbrowser:open-devtools') | |
| 6 | }) |
| … | … | @@ -0,0 +1,8 @@ |
| 1 | { | |
| 2 | "historical": true, | |
| 3 | "purpose": "Migration lookup only. These identifiers are never passed to an executable launch path.", | |
| 4 | "links": { | |
| 5 | "production": "pear://tco5k7h38uoxatedp1wongdbhjxow1x7jiwm3t1i9cujbebhsbty", | |
| 6 | "provisionTarget": "pear://pdsd1p3m1xsz8aofyndbwux5hqs19h8uswnsrfee5cz8sj9pmj4o" | |
| 7 | } | |
| 8 | } |
| … | … | @@ -1,5 +1,3 @@ |
| 1 | import Runtime from 'pear-electron' | |
| 2 | import Bridge from 'pear-bridge' | |
| 3 | 1 | import ws from 'bare-ws' |
| 4 | 2 | import http from 'bare-http1' |
| 5 | 3 | import fs from 'bare-fs' |
| … | … | @@ -26,9 +24,13 @@ const { authorizeRpcWebSocket, DiagnosticRpcRouter } = rpcWebSocketAuth |
| 26 | 24 | const RPC_PORT_BASE = 9876 |
| 27 | 25 | const RPC_PORT_COUNT = 5 |
| 28 | 26 | const RENDERER_RECONNECT_GRACE_MS = 8000 |
| 29 | const rpcSessionToken = String(Pear.config?.startId || '') | |
| 27 | // Pear v3 executes this file as a worker owned by `pear-runtime`. The Electron | |
| 28 | // host supplies the two values below before loading us; unlike the retired | |
| 29 | // `pear run` host, no ambient global `Pear` API is involved. | |
| 30 | const runtimeContext = globalThis.PearBrowserRuntime || {} | |
| 31 | const rpcSessionToken = String(runtimeContext.sessionToken || '') | |
| 30 | 32 | const diagnosticToken = String(env.PEARBROWSER_RPC_DIAGNOSTIC_TOKEN || '') |
| 31 | if (!rpcSessionToken) throw new Error('Pear runtime did not provide a per-launch RPC session token') | |
| 33 | if (!rpcSessionToken) throw new Error('PearBrowser v3 host did not provide a per-launch RPC session token') | |
| 32 | 34 | |
| 33 | 35 | // --- 1. Boot the backend in this Bare main process. --- |
| 34 | 36 | // |
| … | … | @@ -41,8 +43,8 @@ if (!rpcSessionToken) throw new Error('Pear runtime did not provide a per-launch |
| 41 | 43 | // Instead: catch the boot failure, still bind the WS server, and when |
| 42 | 44 | // the renderer connects send it a structured `backend-boot-failed` |
| 43 | 45 | // event so the UI can render a clear error. The dev logs also get a |
| 44 | // loud banner that makes the cause obvious in `pear run --dev` output. | |
| 45 | const storagePath = (Pear.config?.storage || '.') + '/pearbrowser-storage' | |
| 46 | // loud banner that makes the cause obvious in the native host logs. | |
| 47 | const storagePath = String(runtimeContext.storagePath || '.') + '/pearbrowser-storage' | |
| 46 | 48 | const ollamaModels = env.PEARBROWSER_QVAC_OLLAMA === '0' |
| 47 | 49 | ? {} |
| 48 | 50 | : discoverOllamaQwenModels({ |
| … | … | @@ -92,10 +94,9 @@ try { |
| 92 | 94 | console.error('display this error instead of "could not reach backend".') |
| 93 | 95 | console.error('') |
| 94 | 96 | console.error('Common causes:') |
| 95 | console.error(' • Staged drive is incomplete on disk (relay partial pin)') | |
| 96 | console.error(' Try: rm -rf "$HOME/Library/Application Support/pear/by-dkey/00f61fc1473b9d01a199833fc96e76d5e99000c603ec697bc842f8d978538f4d"') | |
| 97 | console.error(' then re-run `pear run pear://tco5...`') | |
| 98 | console.error(' • Pear runtime too old — update with: pear run pear://runtime') | |
| 97 | console.error(' • The local PearBrowser installation is incomplete') | |
| 98 | console.error(' Reinstall the verified native package, then relaunch it.') | |
| 99 | console.error(' • The embedded Pear OTA runtime is incompatible with this OS/arch') | |
| 99 | 100 | console.error(' • Missing native addon for this OS/arch') |
| 100 | 101 | console.error('========================================================') |
| 101 | 102 | console.error('') |
| … | … | @@ -294,16 +295,10 @@ if (!rpcServer) { |
| 294 | 295 | throw new Error(`No free WS RPC port in ${RPC_PORT_BASE}-${RPC_PORT_BASE + RPC_PORT_COUNT - 1}`) |
| 295 | 296 | } |
| 296 | 297 | |
| 297 | // --- 3. Open the UI window via pear-electron. --- | |
| 298 | const runtime = new Runtime() | |
| 299 | const bridge = new Bridge() | |
| 300 | await bridge.ready() | |
| 301 | const pipe = runtime.start({ bridge }) | |
| 302 | ||
| 303 | // Real shutdown: when the renderer pipe ends, close + force-exit. | |
| 304 | // Pear.teardown alone didn't fire consistently; hooking every | |
| 305 | // exit signal so lingering processes stop blocking subsequent | |
| 306 | // launches with EADDRINUSE / rocksdb LOCK conflicts. | |
| 298 | // --- 3. Worker lifecycle. --- | |
| 299 | // The Electron host owns windows and terminates this Pear OTA worker when the | |
| 300 | // last window exits. Keep the backend cleanup local to the worker rather than | |
| 301 | // relying on Pear v2's renderer pipe or global teardown hooks. | |
| 307 | 302 | let tornDown = false |
| 308 | 303 | function teardown (reason) { |
| 309 | 304 | if (tornDown) return |
| … | … | @@ -314,33 +309,16 @@ function teardown (reason) { |
| 314 | 309 | try { rpcServer?.close() } catch {} |
| 315 | 310 | try { client?.end?.() } catch {} |
| 316 | 311 | try { backendPipe.end?.() } catch {} |
| 317 | try { pipe?.end?.() } catch {} | |
| 318 | 312 | // Hard-exit fast: hypercore/corestore can hold the event loop |
| 319 | 313 | // open for tens of seconds on graceful close, and that's what |
| 320 | 314 | // was letting zombies survive. 300ms is plenty for our WS |
| 321 | 315 | // client to flush. |
| 322 | 316 | setTimeout(() => { |
| 323 | 317 | console.log('[teardown] hard-exit') |
| 324 | try { Pear.exit?.(0) } catch {} | |
| 325 | 318 | try { Bare.exit?.(0) } catch {} |
| 326 | 319 | try { process?.exit?.(0) } catch {} |
| 327 | 320 | }, 300) |
| 328 | 321 | } |
| 329 | // pear-electron's runtime.start() return shape varies across versions: | |
| 330 | // older builds returned a duplex pipe (.on/.end), newer ones return a | |
| 331 | // plain object. Detect what we got and only attach listeners that exist. | |
| 332 | // The WS-renderer-close path is our reliable shutdown trigger; these | |
| 333 | // pipe listeners are belt-and-braces so any other exit signal still | |
| 334 | // teardowns. Wrap each in try/catch so an unsupported runtime never | |
| 335 | // throws an [uncaughtException] at boot. | |
| 336 | if (pipe && typeof pipe.on === 'function') { | |
| 337 | try { pipe.on('close', () => teardown('pipe close')) } catch {} | |
| 338 | try { pipe.on('end', () => teardown('pipe end')) } catch {} | |
| 339 | try { pipe.on('error', (err) => teardown('pipe error: ' + (err && err.message))) } catch {} | |
| 340 | } else { | |
| 341 | console.log('[boot] runtime.start() returned non-emitter pipe; using WS-close + Pear.teardown only') | |
| 342 | } | |
| 343 | try { Pear.teardown(() => teardown('Pear.teardown')) } catch {} | |
| 344 | 322 | try { Bare.on?.('beforeExit', () => teardown('beforeExit')) } catch {} |
| 345 | 323 | try { Bare.on?.('exit', () => teardown('exit')) } catch {} |
| 346 | 324 | try { process?.on?.('SIGTERM', () => teardown('SIGTERM')) } catch {} |
| … | … | @@ -28,6 +28,7 @@ |
| 28 | 28 | "bip39-mnemonic": "^2.5.0", |
| 29 | 29 | "blind-pairing": "^2.3.1", |
| 30 | 30 | "corestore": "^7.9.2", |
| 31 | "electron": "43.2.0", | |
| 31 | 32 | "framed-stream": "^1.0.0", |
| 32 | 33 | "htm": "^3.1.1", |
| 33 | 34 | "hyperbee": "^2.27.3", |
| … | … | @@ -38,9 +39,7 @@ |
| 38 | 39 | "p2p-hiverelay": "latest", |
| 39 | 40 | "p2p-hiverelay-client": "latest", |
| 40 | 41 | "p2p-hiverelay-verifier": "latest", |
| 41 | "pear-bridge": "1.2.5", | |
| 42 | "pear-electron": "1.7.28", | |
| 43 | "pear-run": "2.0.0", | |
| 42 | "pear-runtime": "1.3.1", | |
| 44 | 43 | "react": "^18.3.1", |
| 45 | 44 | "react-dom": "^18.3.1", |
| 46 | 45 | "schema-sheets": "^3.1.1" |
| … | … | @@ -49,6 +48,35 @@ |
| 49 | 48 | "bare": "1.30.3" |
| 50 | 49 | } |
| 51 | 50 | }, |
| 51 | "node_modules/@electron-internal/extract-zip": { | |
| 52 | "version": "1.0.4", | |
| 53 | "resolved": "https://registry.npmjs.org/@electron-internal/extract-zip/-/extract-zip-1.0.4.tgz", | |
| 54 | "integrity": "sha512-Zr1Vs7E9tpCNhZHDAbFVXc2gEVCG9RqPDjrno5+bdgB6LRAuvgyMHJut4NCVyYwtAieapMzc3fiQ3CSTi75ARg==", | |
| 55 | "license": "BSD-2-Clause", | |
| 56 | "engines": { | |
| 57 | "node": ">=22.12.0" | |
| 58 | } | |
| 59 | }, | |
| 60 | "node_modules/@electron/get": { | |
| 61 | "version": "5.0.0", | |
| 62 | "resolved": "https://registry.npmjs.org/@electron/get/-/get-5.0.0.tgz", | |
| 63 | "integrity": "sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==", | |
| 64 | "license": "MIT", | |
| 65 | "dependencies": { | |
| 66 | "debug": "^4.1.1", | |
| 67 | "env-paths": "^3.0.0", | |
| 68 | "graceful-fs": "^4.2.11", | |
| 69 | "progress": "^2.0.3", | |
| 70 | "semver": "^7.6.3", | |
| 71 | "sumchecker": "^3.0.1" | |
| 72 | }, | |
| 73 | "engines": { | |
| 74 | "node": ">=22.12.0" | |
| 75 | }, | |
| 76 | "optionalDependencies": { | |
| 77 | "undici": "^7.24.4" | |
| 78 | } | |
| 79 | }, | |
| 52 | 80 | "node_modules/@grpc/grpc-js": { |
| 53 | 81 | "version": "1.14.4", |
| 54 | 82 | "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz", |
| … | … | @@ -1022,18 +1050,6 @@ |
| 1022 | 1050 | "undici-types": "~8.3.0" |
| 1023 | 1051 | } |
| 1024 | 1052 | }, |
| 1025 | "node_modules/acorn": { | |
| 1026 | "version": "8.16.0", | |
| 1027 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", | |
| 1028 | "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", | |
| 1029 | "license": "MIT", | |
| 1030 | "bin": { | |
| 1031 | "acorn": "bin/acorn" | |
| 1032 | }, | |
| 1033 | "engines": { | |
| 1034 | "node": ">=0.4.0" | |
| 1035 | } | |
| 1036 | }, | |
| 1037 | 1053 | "node_modules/adaptive-timeout": { |
| 1038 | 1054 | "version": "1.0.1", |
| 1039 | 1055 | "resolved": "https://registry.npmjs.org/adaptive-timeout/-/adaptive-timeout-1.0.1.tgz", |
| … | … | @@ -1261,6 +1277,17 @@ |
| 1261 | 1277 | "bare-inspect": "^3.1.2" |
| 1262 | 1278 | } |
| 1263 | 1279 | }, |
| 1280 | "node_modules/bare-broadcast-channel": { | |
| 1281 | "version": "0.2.0", | |
| 1282 | "resolved": "https://registry.npmjs.org/bare-broadcast-channel/-/bare-broadcast-channel-0.2.0.tgz", | |
| 1283 | "integrity": "sha512-MuAwdKWr4cSjNwqvbE3tA9Wn6w69q6iXYnP2Wb0nlDa6sKNSMSfY7LXkV4FzWlq9JFP9d0HkCAKPboTLKnUfWQ==", | |
| 1284 | "license": "Apache-2.0", | |
| 1285 | "dependencies": { | |
| 1286 | "bare-events": "^2.0.0", | |
| 1287 | "bare-stream": "^2.7.0", | |
| 1288 | "bare-structured-clone": "^1.4.0" | |
| 1289 | } | |
| 1290 | }, | |
| 1264 | 1291 | "node_modules/bare-buffer": { |
| 1265 | 1292 | "version": "3.6.2", |
| 1266 | 1293 | "resolved": "https://registry.npmjs.org/bare-buffer/-/bare-buffer-3.6.2.tgz", |
| … | … | @@ -1288,6 +1315,20 @@ |
| 1288 | 1315 | } |
| 1289 | 1316 | } |
| 1290 | 1317 | }, |
| 1318 | "node_modules/bare-channel": { | |
| 1319 | "version": "5.2.4", | |
| 1320 | "resolved": "https://registry.npmjs.org/bare-channel/-/bare-channel-5.2.4.tgz", | |
| 1321 | "integrity": "sha512-enkaOtvXUiZsLBSbataxV/QBjehCOK+SUTd2JQWUYW2iIOufpPu9jyZ9bqJqkEquktrK/rpEMVEmKsPzoci/sA==", | |
| 1322 | "license": "Apache-2.0", | |
| 1323 | "dependencies": { | |
| 1324 | "bare-events": "^2.0.0", | |
| 1325 | "bare-stream": "^2.7.0", | |
| 1326 | "bare-structured-clone": "^1.4.0" | |
| 1327 | }, | |
| 1328 | "engines": { | |
| 1329 | "bare": ">=1.7.0" | |
| 1330 | } | |
| 1331 | }, | |
| 1291 | 1332 | "node_modules/bare-crypto": { |
| 1292 | 1333 | "version": "1.15.3", |
| 1293 | 1334 | "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.15.3.tgz", |
| … | … | @@ -1306,17 +1347,6 @@ |
| 1306 | 1347 | } |
| 1307 | 1348 | } |
| 1308 | 1349 | }, |
| 1309 | "node_modules/bare-daemon": { | |
| 1310 | "version": "1.2.4", | |
| 1311 | "resolved": "https://registry.npmjs.org/bare-daemon/-/bare-daemon-1.2.4.tgz", | |
| 1312 | "integrity": "sha512-pyWmqqsN9x2RNzXFpHObyU8+9vgFL7q63Nhtk+xRTXcWL/LkZrYpLmIpYlyPzwZrT2vL+lrjBwVMyCljThfC+A==", | |
| 1313 | "license": "Apache-2.0", | |
| 1314 | "dependencies": { | |
| 1315 | "bare-env": "^3.0.0", | |
| 1316 | "bare-os": "^3.6.2", | |
| 1317 | "require-addon": "^1.1.0" | |
| 1318 | } | |
| 1319 | }, | |
| 1320 | 1350 | "node_modules/bare-debug-log": { |
| 1321 | 1351 | "version": "2.0.0", |
| 1322 | 1352 | "resolved": "https://registry.npmjs.org/bare-debug-log/-/bare-debug-log-2.0.0.tgz", |
| … | … | @@ -1574,9 +1604,9 @@ |
| 1574 | 1604 | } |
| 1575 | 1605 | }, |
| 1576 | 1606 | "node_modules/bare-module-lexer": { |
| 1577 | "version": "1.5.3", | |
| 1578 | "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.5.3.tgz", | |
| 1579 | "integrity": "sha512-URLPza0jP3aVzeIX5MDKAl5tGH7zLW1dNCVmSvg3so6PM0/HhoDk2AfVQVeTFJ1xZaxFfaLuGa43q8uC1MmY1g==", | |
| 1607 | "version": "1.6.3", | |
| 1608 | "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.6.3.tgz", | |
| 1609 | "integrity": "sha512-NQY7cnPV3GZlHJphX4nXmPdNPER/Tp17pVi9/he2ODw/GNZ7FXzrZlrS7WMF8zbtWigqW/NMc9aQc2BH8UJXqA==", | |
| 1580 | 1610 | "license": "Apache-2.0", |
| 1581 | 1611 | "dependencies": { |
| 1582 | 1612 | "require-addon": "^1.0.2" |
| … | … | @@ -1607,6 +1637,30 @@ |
| 1607 | 1637 | } |
| 1608 | 1638 | } |
| 1609 | 1639 | }, |
| 1640 | "node_modules/bare-module-traverse": { | |
| 1641 | "version": "2.4.4", | |
| 1642 | "resolved": "https://registry.npmjs.org/bare-module-traverse/-/bare-module-traverse-2.4.4.tgz", | |
| 1643 | "integrity": "sha512-zK4bDxqeD15Tvu/C5B1Mi/epl9PavjIhU3SVh5RhDb4Hpet6applPVX8Q9rinu7nT80yzgSSlBn0exzJaNXv0A==", | |
| 1644 | "license": "Apache-2.0", | |
| 1645 | "dependencies": { | |
| 1646 | "bare-addon-resolve": "^1.5.0", | |
| 1647 | "bare-mime": "^1.0.0", | |
| 1648 | "bare-module-lexer": "^1.6.0", | |
| 1649 | "bare-module-resolve": "^1.7.0" | |
| 1650 | }, | |
| 1651 | "peerDependencies": { | |
| 1652 | "bare-buffer": "*", | |
| 1653 | "bare-url": "*" | |
| 1654 | }, | |
| 1655 | "peerDependenciesMeta": { | |
| 1656 | "bare-buffer": { | |
| 1657 | "optional": true | |
| 1658 | }, | |
| 1659 | "bare-url": { | |
| 1660 | "optional": true | |
| 1661 | } | |
| 1662 | } | |
| 1663 | }, | |
| 1610 | 1664 | "node_modules/bare-net": { |
| 1611 | 1665 | "version": "2.3.1", |
| 1612 | 1666 | "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.3.1.tgz", |
| … | … | @@ -1638,9 +1692,9 @@ |
| 1638 | 1692 | } |
| 1639 | 1693 | }, |
| 1640 | 1694 | "node_modules/bare-pipe": { |
| 1641 | "version": "4.1.5", | |
| 1642 | "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.1.5.tgz", | |
| 1643 | "integrity": "sha512-6OfxaG8JSkRh3Gc4hzHRsxNt+yu2PpN7lrv1V+T78GdknWQkVGwiEvu4m+1nbfk8cMVQ0TGxRvQ90XA4rhnTuw==", | |
| 1695 | "version": "4.2.2", | |
| 1696 | "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.2.2.tgz", | |
| 1697 | "integrity": "sha512-Wkf6//CmKS8inHrkgi3X/xNMeaGfs2I0ayLM0B8cbPB4DxYHcoes6Ng+muCBfXNIJ9qmEjwDDJjAUz7nRxxjgQ==", | |
| 1644 | 1698 | "license": "Apache-2.0", |
| 1645 | 1699 | "dependencies": { |
| 1646 | 1700 | "bare-events": "^2.0.0", |
| … | … | @@ -1678,16 +1732,6 @@ |
| 1678 | 1732 | "integrity": "sha512-pUtEM6JrX53MbEJFwO92F0Ch7BwZ67KD7LyglcB8/tvkkVdwTgN1f7oIklRe+NTT/WCYZgwjDFYS9efBxDSq8g==", |
| 1679 | 1733 | "license": "Apache-2.0" |
| 1680 | 1734 | }, |
| 1681 | "node_modules/bare-readline": { | |
| 1682 | "version": "1.3.1", | |
| 1683 | "resolved": "https://registry.npmjs.org/bare-readline/-/bare-readline-1.3.1.tgz", | |
| 1684 | "integrity": "sha512-QtSU4ZfgQcDI6AQssjDFqTiRe4rCiciMn+Yqx6siMJZBIftAIFrNSOK0sa5SBrmNv/a7CD9Dm0onUDCRyn5Fdg==", | |
| 1685 | "license": "Apache-2.0", | |
| 1686 | "dependencies": { | |
| 1687 | "bare-ansi-escapes": "^2.0.0", | |
| 1688 | "bare-stream": "^2.0.0" | |
| 1689 | } | |
| 1690 | }, | |
| 1691 | 1735 | "node_modules/bare-rpc": { |
| 1692 | 1736 | "version": "1.3.8", |
| 1693 | 1737 | "resolved": "https://registry.npmjs.org/bare-rpc/-/bare-rpc-1.3.8.tgz", |
| … | … | @@ -2026,21 +2070,6 @@ |
| 2026 | 2070 | "bare": "bin/bare.exe" |
| 2027 | 2071 | } |
| 2028 | 2072 | }, |
| 2029 | "node_modules/bare-runtime/node_modules/bare-pipe": { | |
| 2030 | "version": "4.2.2", | |
| 2031 | "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.2.2.tgz", | |
| 2032 | "integrity": "sha512-Wkf6//CmKS8inHrkgi3X/xNMeaGfs2I0ayLM0B8cbPB4DxYHcoes6Ng+muCBfXNIJ9qmEjwDDJjAUz7nRxxjgQ==", | |
| 2033 | "dev": true, | |
| 2034 | "license": "Apache-2.0", | |
| 2035 | "peer": true, | |
| 2036 | "dependencies": { | |
| 2037 | "bare-events": "^2.0.0", | |
| 2038 | "bare-stream": "^2.0.0" | |
| 2039 | }, | |
| 2040 | "engines": { | |
| 2041 | "bare": ">=1.16.0" | |
| 2042 | } | |
| 2043 | }, | |
| 2044 | 2073 | "node_modules/bare-runtime/node_modules/bare-subprocess": { |
| 2045 | 2074 | "version": "6.1.0", |
| 2046 | 2075 | "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-6.1.0.tgz", |
| … | … | @@ -2069,36 +2098,54 @@ |
| 2069 | 2098 | } |
| 2070 | 2099 | } |
| 2071 | 2100 | }, |
| 2072 | "node_modules/bare-runtime/node_modules/bare-tcp": { | |
| 2073 | "version": "2.5.2", | |
| 2074 | "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.5.2.tgz", | |
| 2075 | "integrity": "sha512-9SAF0r+p5w3QxsI9BGBqj/0VlNwJGkEj/1AAJi+4Pl0W7ke2JiYmt7GhJss/uaEnY0s4/N/A/Os6Dr+dVfVzyQ==", | |
| 2076 | "dev": true, | |
| 2101 | "node_modules/bare-semver": { | |
| 2102 | "version": "1.0.3", | |
| 2103 | "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.3.tgz", | |
| 2104 | "integrity": "sha512-HS/A30bi2+PiRJfU6R4+Kp+6KeLSCSByjYM2iiobOKzLAvtu1CT+S8xWfiU7wz0erknjkUoC+yXy108tzIuP5Q==", | |
| 2105 | "license": "Apache-2.0" | |
| 2106 | }, | |
| 2107 | "node_modules/bare-sidecar": { | |
| 2108 | "version": "0.5.3", | |
| 2109 | "resolved": "https://registry.npmjs.org/bare-sidecar/-/bare-sidecar-0.5.3.tgz", | |
| 2110 | "integrity": "sha512-TO/FHNUWgNEfDGiqrvmYT7+1ZxRpa4J0fWQsdVIjh5FY5xC+PocdMQPw/LiTp7iyhTUatZEeTDWr4l8DQ3jaeA==", | |
| 2077 | 2111 | "license": "Apache-2.0", |
| 2078 | "peer": true, | |
| 2079 | 2112 | "dependencies": { |
| 2080 | "bare-dns": "^2.0.4", | |
| 2113 | "bare-fs": "^4.5.1", | |
| 2114 | "bare-module": "^6.1.3", | |
| 2115 | "bare-path": "^3.0.0", | |
| 2116 | "bare-pipe": "^4.1.3", | |
| 2117 | "bare-stream": "^2.7.0", | |
| 2118 | "bare-subprocess": "^6.0.0", | |
| 2119 | "bare-url": "^2.3.2", | |
| 2120 | "require-asset": "^1.1.0" | |
| 2121 | } | |
| 2122 | }, | |
| 2123 | "node_modules/bare-sidecar/node_modules/bare-subprocess": { | |
| 2124 | "version": "6.1.0", | |
| 2125 | "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-6.1.0.tgz", | |
| 2126 | "integrity": "sha512-8L6KtbmreDy4Fc1BdDqaDo9fg0nbedUmTSFQxYPV0uHIM2BBAX8+E0LyMDKgkk0I+mlKto80WYzOnIhT8VDdOg==", | |
| 2127 | "license": "Apache-2.0", | |
| 2128 | "dependencies": { | |
| 2129 | "bare-env": "^3.0.0", | |
| 2081 | 2130 | "bare-events": "^2.5.4", |
| 2082 | "bare-stream": "^2.6.4" | |
| 2131 | "bare-os": "^3.0.1", | |
| 2132 | "bare-pipe": "^4.2.0", | |
| 2133 | "bare-structured-clone": "^1.5.2", | |
| 2134 | "bare-tcp": "^2.4.1", | |
| 2135 | "bare-url": "^2.2.2" | |
| 2083 | 2136 | }, |
| 2084 | 2137 | "engines": { |
| 2085 | "bare": ">=1.16.0" | |
| 2138 | "bare": ">=1.7.0" | |
| 2086 | 2139 | }, |
| 2087 | 2140 | "peerDependencies": { |
| 2088 | "bare-pipe": "*" | |
| 2141 | "bare-buffer": "*" | |
| 2089 | 2142 | }, |
| 2090 | 2143 | "peerDependenciesMeta": { |
| 2091 | "bare-pipe": { | |
| 2144 | "bare-buffer": { | |
| 2092 | 2145 | "optional": true |
| 2093 | 2146 | } |
| 2094 | 2147 | } |
| 2095 | 2148 | }, |
| 2096 | "node_modules/bare-semver": { | |
| 2097 | "version": "1.0.3", | |
| 2098 | "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.3.tgz", | |
| 2099 | "integrity": "sha512-HS/A30bi2+PiRJfU6R4+Kp+6KeLSCSByjYM2iiobOKzLAvtu1CT+S8xWfiU7wz0erknjkUoC+yXy108tzIuP5Q==", | |
| 2100 | "license": "Apache-2.0" | |
| 2101 | }, | |
| 2102 | 2149 | "node_modules/bare-signals": { |
| 2103 | 2150 | "version": "4.2.0", |
| 2104 | 2151 | "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz", |
| … | … | @@ -2124,11 +2171,12 @@ |
| 2124 | 2171 | } |
| 2125 | 2172 | }, |
| 2126 | 2173 | "node_modules/bare-stream": { |
| 2127 | "version": "2.13.0", | |
| 2128 | "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz", | |
| 2129 | "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==", | |
| 2174 | "version": "2.13.3", | |
| 2175 | "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz", | |
| 2176 | "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==", | |
| 2130 | 2177 | "license": "Apache-2.0", |
| 2131 | 2178 | "dependencies": { |
| 2179 | "b4a": "^1.8.1", | |
| 2132 | 2180 | "streamx": "^2.25.0", |
| 2133 | 2181 | "teex": "^1.0.1" |
| 2134 | 2182 | }, |
| … | … | @@ -2149,13 +2197,25 @@ |
| 2149 | 2197 | } |
| 2150 | 2198 | } |
| 2151 | 2199 | }, |
| 2200 | "node_modules/bare-stream/node_modules/b4a": { | |
| 2201 | "version": "1.8.1", | |
| 2202 | "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", | |
| 2203 | "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", | |
| 2204 | "license": "Apache-2.0", | |
| 2205 | "peerDependencies": { | |
| 2206 | "react-native-b4a": "*" | |
| 2207 | }, | |
| 2208 | "peerDependenciesMeta": { | |
| 2209 | "react-native-b4a": { | |
| 2210 | "optional": true | |
| 2211 | } | |
| 2212 | } | |
| 2213 | }, | |
| 2152 | 2214 | "node_modules/bare-structured-clone": { |
| 2153 | 2215 | "version": "1.6.0", |
| 2154 | 2216 | "resolved": "https://registry.npmjs.org/bare-structured-clone/-/bare-structured-clone-1.6.0.tgz", |
| 2155 | 2217 | "integrity": "sha512-AZjEERyqF7kAuudlmgrweT2KwwWM0LsGG4Gx/bWyFwJrKU7E3wNG8c09z2DIrdw93p3vDtfOX8fyHOcXfy5m+g==", |
| 2156 | "dev": true, | |
| 2157 | 2218 | "license": "Apache-2.0", |
| 2158 | "peer": true, | |
| 2159 | 2219 | "dependencies": { |
| 2160 | 2220 | "bare-buffer": "^3.6.0", |
| 2161 | 2221 | "bare-type": "^1.1.0", |
| … | … | @@ -2170,9 +2230,7 @@ |
| 2170 | 2230 | "version": "3.3.0", |
| 2171 | 2231 | "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz", |
| 2172 | 2232 | "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==", |
| 2173 | "dev": true, | |
| 2174 | 2233 | "license": "Apache-2.0", |
| 2175 | "peer": true, | |
| 2176 | 2234 | "dependencies": { |
| 2177 | 2235 | "b4a": "^1.3.0" |
| 2178 | 2236 | } |
| … | … | @@ -2187,42 +2245,38 @@ |
| 2187 | 2245 | "bare-process": "^4.2.1" |
| 2188 | 2246 | } |
| 2189 | 2247 | }, |
| 2190 | "node_modules/bare-subprocess": { | |
| 2191 | "version": "5.2.3", | |
| 2192 | "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz", | |
| 2193 | "integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==", | |
| 2248 | "node_modules/bare-tcp": { | |
| 2249 | "version": "2.5.2", | |
| 2250 | "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.5.2.tgz", | |
| 2251 | "integrity": "sha512-9SAF0r+p5w3QxsI9BGBqj/0VlNwJGkEj/1AAJi+4Pl0W7ke2JiYmt7GhJss/uaEnY0s4/N/A/Os6Dr+dVfVzyQ==", | |
| 2194 | 2252 | "license": "Apache-2.0", |
| 2195 | 2253 | "dependencies": { |
| 2196 | "bare-env": "^3.0.0", | |
| 2254 | "bare-dns": "^2.0.4", | |
| 2197 | 2255 | "bare-events": "^2.5.4", |
| 2198 | "bare-os": "^3.0.1", | |
| 2199 | "bare-pipe": "^4.0.0", | |
| 2200 | "bare-url": "^2.2.2" | |
| 2256 | "bare-stream": "^2.6.4" | |
| 2201 | 2257 | }, |
| 2202 | 2258 | "engines": { |
| 2203 | "bare": ">=1.7.0" | |
| 2259 | "bare": ">=1.16.0" | |
| 2204 | 2260 | }, |
| 2205 | 2261 | "peerDependencies": { |
| 2206 | "bare-buffer": "*" | |
| 2262 | "bare-pipe": "*" | |
| 2207 | 2263 | }, |
| 2208 | 2264 | "peerDependenciesMeta": { |
| 2209 | "bare-buffer": { | |
| 2265 | "bare-pipe": { | |
| 2210 | 2266 | "optional": true |
| 2211 | 2267 | } |
| 2212 | 2268 | } |
| 2213 | 2269 | }, |
| 2214 | "node_modules/bare-tcp": { | |
| 2215 | "version": "2.2.7", | |
| 2216 | "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.2.7.tgz", | |
| 2217 | "integrity": "sha512-rjpqNQ2cOCkNo3NeYA/W4GTK3DRkl8sDHO3uos+AEswUjLC8XXMQF8WrJCSjlIowCbS6NUVxKE92X5RGXjyefg==", | |
| 2270 | "node_modules/bare-thread": { | |
| 2271 | "version": "1.2.4", | |
| 2272 | "resolved": "https://registry.npmjs.org/bare-thread/-/bare-thread-1.2.4.tgz", | |
| 2273 | "integrity": "sha512-MnqMCGVp2JJJNXgwUBC8hw+J4FrTeLkLgfCPPl5tQK6MbtV2Efi6LKK5v819VRY0da+AXlCbgssbAVge31NfRg==", | |
| 2218 | 2274 | "license": "Apache-2.0", |
| 2219 | 2275 | "dependencies": { |
| 2220 | "bare-dns": "^2.0.4", | |
| 2221 | "bare-events": "^2.5.4", | |
| 2222 | "bare-stream": "^2.6.4" | |
| 2223 | }, | |
| 2224 | "engines": { | |
| 2225 | "bare": ">=1.16.0" | |
| 2276 | "bare-bundle": "^1.9.0", | |
| 2277 | "bare-module-resolve": "^1.11.2", | |
| 2278 | "bare-module-traverse": "^2.0.0", | |
| 2279 | "bare-url": "^2.4.2" | |
| 2226 | 2280 | } |
| 2227 | 2281 | }, |
| 2228 | 2282 | "node_modules/bare-tls": { |
| … | … | @@ -2279,9 +2333,9 @@ |
| 2279 | 2333 | } |
| 2280 | 2334 | }, |
| 2281 | 2335 | "node_modules/bare-url": { |
| 2282 | "version": "2.4.1", | |
| 2283 | "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.1.tgz", | |
| 2284 | "integrity": "sha512-fZapLWNB25gS+etK27NV9KgBNXgo2yeYHuj+OyPblQd6GYAE3JVy6aKxszMV5jhGGFwraXQKA5fldvf3lMyEqw==", | |
| 2336 | "version": "2.4.6", | |
| 2337 | "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.6.tgz", | |
| 2338 | "integrity": "sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==", | |
| 2285 | 2339 | "license": "Apache-2.0", |
| 2286 | 2340 | "dependencies": { |
| 2287 | 2341 | "bare-path": "^3.0.0" |
| … | … | @@ -2301,6 +2355,20 @@ |
| 2301 | 2355 | "bare-type": "^1.0.6" |
| 2302 | 2356 | } |
| 2303 | 2357 | }, |
| 2358 | "node_modules/bare-worker": { | |
| 2359 | "version": "4.4.0", | |
| 2360 | "resolved": "https://registry.npmjs.org/bare-worker/-/bare-worker-4.4.0.tgz", | |
| 2361 | "integrity": "sha512-zSc1biis9ks03nj/24M7tYS2V0CPhefizzRIxVYdglbbUAgA0zakwSgTKLJshZ6P+9NA55M/eG4k/rBALZVbxg==", | |
| 2362 | "license": "Apache-2.0", | |
| 2363 | "dependencies": { | |
| 2364 | "bare-broadcast-channel": "^0.2.0", | |
| 2365 | "bare-channel": "^5.1.5", | |
| 2366 | "bare-events": "^2.2.1", | |
| 2367 | "bare-module": "^6.4.0", | |
| 2368 | "bare-stream": "^2.13.3", | |
| 2369 | "bare-thread": "^1.2.2" | |
| 2370 | } | |
| 2371 | }, | |
| 2304 | 2372 | "node_modules/bare-ws": { |
| 2305 | 2373 | "version": "2.1.0", |
| 2306 | 2374 | "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-2.1.0.tgz", |
| … | … | @@ -2387,26 +2455,6 @@ |
| 2387 | 2455 | "b4a": "^1.5.0" |
| 2388 | 2456 | } |
| 2389 | 2457 | }, |
| 2390 | "node_modules/blake2b": { | |
| 2391 | "version": "2.1.4", | |
| 2392 | "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", | |
| 2393 | "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", | |
| 2394 | "license": "ISC", | |
| 2395 | "dependencies": { | |
| 2396 | "blake2b-wasm": "^2.4.0", | |
| 2397 | "nanoassert": "^2.0.0" | |
| 2398 | } | |
| 2399 | }, | |
| 2400 | "node_modules/blake2b-wasm": { | |
| 2401 | "version": "2.4.0", | |
| 2402 | "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", | |
| 2403 | "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", | |
| 2404 | "license": "MIT", | |
| 2405 | "dependencies": { | |
| 2406 | "b4a": "^1.0.1", | |
| 2407 | "nanoassert": "^2.0.0" | |
| 2408 | } | |
| 2409 | }, | |
| 2410 | 2458 | "node_modules/blind-pairing": { |
| 2411 | 2459 | "version": "2.3.1", |
| 2412 | 2460 | "resolved": "https://registry.npmjs.org/blind-pairing/-/blind-pairing-2.3.1.tgz", |
| … | … | @@ -2504,12 +2552,6 @@ |
| 2504 | 2552 | } |
| 2505 | 2553 | } |
| 2506 | 2554 | }, |
| 2507 | "node_modules/cjs-module-lexer": { | |
| 2508 | "version": "1.4.3", | |
| 2509 | "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", | |
| 2510 | "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", | |
| 2511 | "license": "MIT" | |
| 2512 | }, | |
| 2513 | 2555 | "node_modules/cli-box": { |
| 2514 | 2556 | "version": "6.0.10", |
| 2515 | 2557 | "resolved": "https://registry.npmjs.org/cli-box/-/cli-box-6.0.10.tgz", |
| … | … | @@ -2659,6 +2701,23 @@ |
| 2659 | 2701 | "integrity": "sha512-eKuHDVfJVg+u/0nPy8P+fhnLgbyuTgVxuCRrS/R7EpDSMMkBDgSes41MJtSAY1F1hcqfHz3Zy/qpqHHIp/EhdA==", |
| 2660 | 2702 | "license": "MIT" |
| 2661 | 2703 | }, |
| 2704 | "node_modules/debug": { | |
| 2705 | "version": "4.4.3", | |
| 2706 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", | |
| 2707 | "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", | |
| 2708 | "license": "MIT", | |
| 2709 | "dependencies": { | |
| 2710 | "ms": "^2.1.3" | |
| 2711 | }, | |
| 2712 | "engines": { | |
| 2713 | "node": ">=6.0" | |
| 2714 | }, | |
| 2715 | "peerDependenciesMeta": { | |
| 2716 | "supports-color": { | |
| 2717 | "optional": true | |
| 2718 | } | |
| 2719 | } | |
| 2720 | }, | |
| 2662 | 2721 | "node_modules/deffy": { |
| 2663 | 2722 | "version": "2.2.5", |
| 2664 | 2723 | "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.5.tgz", |
| … | … | @@ -2739,17 +2798,39 @@ |
| 2739 | 2798 | "node": ">=6" |
| 2740 | 2799 | } |
| 2741 | 2800 | }, |
| 2742 | "node_modules/drive-resolve": { | |
| 2743 | "version": "1.3.1", | |
| 2744 | "resolved": "https://registry.npmjs.org/drive-resolve/-/drive-resolve-1.3.1.tgz", | |
| 2745 | "integrity": "sha512-Fn88wa5vry4JKtE1g4md1SPzU9/fO2h8l73Fr9kmQtaatFIvquR/V6UGjTOcBsWbNgrRMQjY8N6SNoY40o57JQ==", | |
| 2746 | "license": "Apache-2.0", | |
| 2801 | "node_modules/electron": { | |
| 2802 | "version": "43.2.0", | |
| 2803 | "resolved": "https://registry.npmjs.org/electron/-/electron-43.2.0.tgz", | |
| 2804 | "integrity": "sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==", | |
| 2805 | "license": "MIT", | |
| 2747 | 2806 | "dependencies": { |
| 2748 | "b4a": "^1.6.4", | |
| 2749 | "bare-module-resolve": "^1.2.5", | |
| 2750 | "unix-path-resolve": "^1.0.2" | |
| 2807 | "@electron-internal/extract-zip": "^1.0.1", | |
| 2808 | "@electron/get": "^5.0.0", | |
| 2809 | "@types/node": "^24.9.0" | |
| 2810 | }, | |
| 2811 | "bin": { | |
| 2812 | "electron": "cli.js", | |
| 2813 | "install-electron": "install.js" | |
| 2814 | }, | |
| 2815 | "engines": { | |
| 2816 | "node": ">= 22.12.0" | |
| 2751 | 2817 | } |
| 2752 | 2818 | }, |
| 2819 | "node_modules/electron/node_modules/@types/node": { | |
| 2820 | "version": "24.13.3", | |
| 2821 | "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", | |
| 2822 | "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", | |
| 2823 | "license": "MIT", | |
| 2824 | "dependencies": { | |
| 2825 | "undici-types": "~7.18.0" | |
| 2826 | } | |
| 2827 | }, | |
| 2828 | "node_modules/electron/node_modules/undici-types": { | |
| 2829 | "version": "7.18.2", | |
| 2830 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", | |
| 2831 | "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", | |
| 2832 | "license": "MIT" | |
| 2833 | }, | |
| 2753 | 2834 | "node_modules/emoji-regex": { |
| 2754 | 2835 | "version": "8.0.0", |
| 2755 | 2836 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", |
| … | … | @@ -2765,11 +2846,17 @@ |
| 2765 | 2846 | "hyperschema": "^1.19.0" |
| 2766 | 2847 | } |
| 2767 | 2848 | }, |
| 2768 | "node_modules/es-module-lexer": { | |
| 2769 | "version": "1.7.0", | |
| 2770 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", | |
| 2771 | "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", | |
| 2772 | "license": "MIT" | |
| 2849 | "node_modules/env-paths": { | |
| 2850 | "version": "3.0.0", | |
| 2851 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", | |
| 2852 | "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", | |
| 2853 | "license": "MIT", | |
| 2854 | "engines": { | |
| 2855 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" | |
| 2856 | }, | |
| 2857 | "funding": { | |
| 2858 | "url": "https://github.com/sponsors/sindresorhus" | |
| 2859 | } | |
| 2773 | 2860 | }, |
| 2774 | 2861 | "node_modules/escalade": { |
| 2775 | 2862 | "version": "3.2.0", |
| … | … | @@ -2919,18 +3006,6 @@ |
| 2919 | 3006 | "which-runtime": "^1.2.0" |
| 2920 | 3007 | } |
| 2921 | 3008 | }, |
| 2922 | "node_modules/fs-native-lock": { | |
| 2923 | "version": "1.2.0", | |
| 2924 | "resolved": "https://registry.npmjs.org/fs-native-lock/-/fs-native-lock-1.2.0.tgz", | |
| 2925 | "integrity": "sha512-x2KlVzvJbNhI2vc+z9+5naq04+6XMyoeLv816sGmP4DWFonu+/N+pigIoDzFV+bdnC5BD3GLeI8eqV/dwCY57Q==", | |
| 2926 | "license": "Apache-2.0", | |
| 2927 | "dependencies": { | |
| 2928 | "bare-fs": "^4.0.1", | |
| 2929 | "bare-path": "^3.0.0", | |
| 2930 | "fs-native-extensions": "^1.3.4", | |
| 2931 | "resource-on-exit": "^1.0.0" | |
| 2932 | } | |
| 2933 | }, | |
| 2934 | 3009 | "node_modules/function.name": { |
| 2935 | 3010 | "version": "1.0.14", |
| 2936 | 3011 | "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.14.tgz", |
| … | … | @@ -2964,11 +3039,11 @@ |
| 2964 | 3039 | "node": "6.* || 8.* || >= 10.*" |
| 2965 | 3040 | } |
| 2966 | 3041 | }, |
| 2967 | "node_modules/get-mime-type": { | |
| 2968 | "version": "2.0.2", | |
| 2969 | "resolved": "https://registry.npmjs.org/get-mime-type/-/get-mime-type-2.0.2.tgz", | |
| 2970 | "integrity": "sha512-pTrc0SYvnFGSri+yjvEIq/m/cg2Ti7Vlrlki13RDicWJzLQgKTCDt8Rhdo80vhEzanOGjbpa+KLYjOiJcA26tQ==", | |
| 2971 | "license": "Apache-2.0" | |
| 3042 | "node_modules/graceful-fs": { | |
| 3043 | "version": "4.2.11", | |
| 3044 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", | |
| 3045 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", | |
| 3046 | "license": "ISC" | |
| 2972 | 3047 | }, |
| 2973 | 3048 | "node_modules/graceful-goodbye": { |
| 2974 | 3049 | "version": "1.3.3", |
| … | … | @@ -3464,12 +3539,6 @@ |
| 3464 | 3539 | "integrity": "sha512-qaX2mymwUhMq+NQPnx5iR/u2PgqhL6jLzDunMmonOgVofqoFhxzd6kOmiL0DLYZUkN/RvNWYPenoANVn5phlaA==", |
| 3465 | 3540 | "license": "MIT" |
| 3466 | 3541 | }, |
| 3467 | "node_modules/is-valid-variable": { | |
| 3468 | "version": "1.0.1", | |
| 3469 | "resolved": "https://registry.npmjs.org/is-valid-variable/-/is-valid-variable-1.0.1.tgz", | |
| 3470 | "integrity": "sha512-ucsrYzt8kcgu2CAOFFWSfOTwa+vPNzQHK1RL6RooSkwozJ92e9wl4cyG/GLDeuNEVj56kvuNZGCR7eSkzrhudg==", | |
| 3471 | "license": "MIT" | |
| 3472 | }, | |
| 3473 | 3542 | "node_modules/is-win": { |
| 3474 | 3543 | "version": "1.0.11", |
| 3475 | 3544 | "resolved": "https://registry.npmjs.org/is-win/-/is-win-1.0.11.tgz", |
| … | … | @@ -3520,12 +3589,6 @@ |
| 3520 | 3589 | "b4a": "^1.3.0" |
| 3521 | 3590 | } |
| 3522 | 3591 | }, |
| 3523 | "node_modules/listen-async": { | |
| 3524 | "version": "1.0.0", | |
| 3525 | "resolved": "https://registry.npmjs.org/listen-async/-/listen-async-1.0.0.tgz", | |
| 3526 | "integrity": "sha512-i8x+jPmM3YaeU+5zL+NWMwzPT0/WV0q23rviQuu9EkdPuAYjnnsa5LDL406hJ/QNNkziKpnJ1T+3VxJQELskqw==", | |
| 3527 | "license": "Apache-2.0" | |
| 3528 | }, | |
| 3529 | 3592 | "node_modules/livefiles": { |
| 3530 | 3593 | "version": "1.1.0", |
| 3531 | 3594 | "resolved": "https://registry.npmjs.org/livefiles/-/livefiles-1.1.0.tgz", |
| … | … | @@ -3544,33 +3607,12 @@ |
| 3544 | 3607 | "integrity": "sha512-Yqi947Vk5Ps2YqhOV8K+RR6bseLhZLIVfovpWJH5cT7GE4Pca8/3iny/3oQ47scD7SfQd3whhxMfc+KgxTgDHA==", |
| 3545 | 3608 | "license": "MIT" |
| 3546 | 3609 | }, |
| 3547 | "node_modules/localdrive": { | |
| 3548 | "version": "1.12.2", | |
| 3549 | "resolved": "https://registry.npmjs.org/localdrive/-/localdrive-1.12.2.tgz", | |
| 3550 | "integrity": "sha512-kISUZK6naLZrvcK/+IqXk5IsAu8S6owlVM0MUT6MZrQSIzLplZ4FXljkEBHwPDe3InVue4FDG9d4p8lKXGgRCQ==", | |
| 3551 | "license": "Apache-2.0", | |
| 3552 | "dependencies": { | |
| 3553 | "b4a": "^1.6.1", | |
| 3554 | "bare-fs": "^4.0.1", | |
| 3555 | "bare-path": "^3.0.0", | |
| 3556 | "mirror-drive": "^1.2.0", | |
| 3557 | "mutexify": "^1.4.0", | |
| 3558 | "streamx": "^2.12.5", | |
| 3559 | "unix-path-resolve": "^1.0.2" | |
| 3560 | } | |
| 3561 | }, | |
| 3562 | 3610 | "node_modules/lodash.camelcase": { |
| 3563 | 3611 | "version": "4.3.0", |
| 3564 | 3612 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", |
| 3565 | 3613 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", |
| 3566 | 3614 | "license": "MIT" |
| 3567 | 3615 | }, |
| 3568 | "node_modules/lodash.sortby": { | |
| 3569 | "version": "4.7.0", | |
| 3570 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", | |
| 3571 | "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", | |
| 3572 | "license": "MIT" | |
| 3573 | }, | |
| 3574 | 3616 | "node_modules/long": { |
| 3575 | 3617 | "version": "5.3.2", |
| 3576 | 3618 | "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", |
| … | … | @@ -3623,6 +3665,23 @@ |
| 3623 | 3665 | "bare-module": "*" |
| 3624 | 3666 | } |
| 3625 | 3667 | }, |
| 3668 | "node_modules/ms": { | |
| 3669 | "version": "2.1.3", | |
| 3670 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", | |
| 3671 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", | |
| 3672 | "license": "MIT" | |
| 3673 | }, | |
| 3674 | "node_modules/msix-manager": { | |
| 3675 | "version": "0.2.5", | |
| 3676 | "resolved": "https://registry.npmjs.org/msix-manager/-/msix-manager-0.2.5.tgz", | |
| 3677 | "integrity": "sha512-bfAqCBIIoxCsBCuDCr9wCfucmL0fy8jE4GBf9Yx24ZXDxQe4L7r/CJcNcGQxWx9RdHGCqCuNKrrNLfTYOue3fw==", | |
| 3678 | "license": "Apache-2.0", | |
| 3679 | "dependencies": { | |
| 3680 | "bare-events": "^2.8.2", | |
| 3681 | "bare-url": "^2.3.2", | |
| 3682 | "require-addon": "^1.2.0" | |
| 3683 | } | |
| 3684 | }, | |
| 3626 | 3685 | "node_modules/multicast-dns": { |
| 3627 | 3686 | "version": "7.2.5", |
| 3628 | 3687 | "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", |
| … | … | @@ -4025,215 +4084,66 @@ |
| 4025 | 4084 | "hypercore-id-encoding": "^1.3.0" |
| 4026 | 4085 | } |
| 4027 | 4086 | }, |
| 4028 | "node_modules/pear-api": { | |
| 4029 | "version": "1.30.0", | |
| 4030 | "resolved": "https://registry.npmjs.org/pear-api/-/pear-api-1.30.0.tgz", | |
| 4031 | "integrity": "sha512-b9y4hCBTCmP7m3riC4O+mc5g8KNKJsLjbqi7TOFSZyvuIjJeP/d/caBYXdhKab0rcOz/kkSdNWvedox4zBtERQ==", | |
| 4032 | "license": "Apache-2.0", | |
| 4033 | "dependencies": { | |
| 4034 | "pear-constants": "^1.0.0", | |
| 4035 | "pear-errors": "^1.0.0", | |
| 4036 | "pear-gracedown": "^1.0.0", | |
| 4037 | "pear-gunk": "^1.0.0", | |
| 4038 | "pear-message": "^1.0.0", | |
| 4039 | "pear-messages": "^1.0.0", | |
| 4040 | "pear-pipe": "^1.0.1", | |
| 4041 | "pear-ref": "^1.0.2", | |
| 4042 | "pear-run": "^1.0.0", | |
| 4043 | "pear-updates": "^1.0.1", | |
| 4044 | "pear-wakeups": "^1.0.0" | |
| 4045 | } | |
| 4046 | }, | |
| 4047 | "node_modules/pear-api/node_modules/pear-run": { | |
| 4048 | "version": "1.0.8", | |
| 4049 | "resolved": "https://registry.npmjs.org/pear-run/-/pear-run-1.0.8.tgz", | |
| 4050 | "integrity": "sha512-X56S6WJEvE5UKxH+XI1WhsgN2oCzPMg2jO/FH/bNFWX9a/LQmQobcIuxLPDBH+iuiHPM1inFScrYWVNZGWqWDw==", | |
| 4051 | "license": "Apache-2.0", | |
| 4052 | "dependencies": { | |
| 4053 | "b4a": "^1.6.7", | |
| 4054 | "bare-path": "^3.0.0", | |
| 4055 | "bare-subprocess": "^5.1.0", | |
| 4056 | "paparam": "^1.8.5", | |
| 4057 | "pear-cmd": "^1.0.0", | |
| 4058 | "pear-link": "^4.1.0", | |
| 4059 | "pear-ref": "^1.0.0", | |
| 4060 | "unix-path-resolve": "^1.0.2", | |
| 4061 | "url-file-url": "^1.0.5", | |
| 4062 | "which-runtime": "^1.3.2" | |
| 4063 | } | |
| 4064 | }, | |
| 4065 | "node_modules/pear-appdrive": { | |
| 4066 | "version": "1.1.2", | |
| 4067 | "resolved": "https://registry.npmjs.org/pear-appdrive/-/pear-appdrive-1.1.2.tgz", | |
| 4068 | "integrity": "sha512-AmCrZaNGFU/BvHR+oFP/cNEUCH1vbzezsJV9wqASoggyg8d4sSb0L6kr99ugGkAuUFlOBI2uHni71hBTaO2rDA==", | |
| 4069 | "license": "Apache-2.0", | |
| 4070 | "dependencies": { | |
| 4071 | "pear-ipc": "^6.6.1", | |
| 4072 | "pear-ref": "^1.0.1", | |
| 4073 | "ready-resource": "^1.1.2" | |
| 4074 | } | |
| 4075 | }, | |
| 4076 | "node_modules/pear-bridge": { | |
| 4077 | "version": "1.2.5", | |
| 4078 | "resolved": "https://registry.npmjs.org/pear-bridge/-/pear-bridge-1.2.5.tgz", | |
| 4079 | "integrity": "sha512-n6ILZteZOcESljImP/78Jv35aRNUk6TFMJyNmbVBah7cpV8W0H3IsQEvzTt1d2vCywNN+Tv7RoCVL6V3BAcC9A==", | |
| 4080 | "license": "Apache-2.0", | |
| 4081 | "dependencies": { | |
| 4082 | "bare-http1": "^4.0.2", | |
| 4083 | "get-mime-type": "^2.0.0", | |
| 4084 | "listen-async": "^1.0.0", | |
| 4085 | "pear-appdrive": "^1.0.0", | |
| 4086 | "pear-errors": "^1.0.0", | |
| 4087 | "pear-gunk": "^1.0.0", | |
| 4088 | "pear-stamp": "^1.0.1", | |
| 4089 | "ready-resource": "^1.1.1", | |
| 4090 | "script-linker": "^2.5.3", | |
| 4091 | "sodium-native": "^5.0.9", | |
| 4092 | "streamx": "^2.21.1" | |
| 4093 | } | |
| 4094 | }, | |
| 4095 | "node_modules/pear-cmd": { | |
| 4096 | "version": "1.0.2", | |
| 4097 | "resolved": "https://registry.npmjs.org/pear-cmd/-/pear-cmd-1.0.2.tgz", | |
| 4098 | "integrity": "sha512-vecXkSAFUS0ODh9I2zgsDcC4cW6sTQ1ZZTq5Fj/6G20HprvPNARbvraGJrkv5dRZ8Epezdgjws0vqB4W4VVd6w==", | |
| 4099 | "license": "Apache-2.0", | |
| 4100 | "dependencies": { | |
| 4101 | "paparam": "^1.8.5" | |
| 4102 | } | |
| 4103 | }, | |
| 4104 | "node_modules/pear-constants": { | |
| 4105 | "version": "1.1.3", | |
| 4106 | "resolved": "https://registry.npmjs.org/pear-constants/-/pear-constants-1.1.3.tgz", | |
| 4107 | "integrity": "sha512-dW8EkiLXjmzr8C8gUqZEIZ4dEKKljRNBznlRM53JPzkDhd053alCbq+T18sE/D2KvzMBW69/Pp1ExFN07xi1EA==", | |
| 4108 | "license": "Apache-2.0", | |
| 4109 | "dependencies": { | |
| 4110 | "b4a": "^1.6.7", | |
| 4111 | "blake2b": "^2.1.4", | |
| 4112 | "pear-aliases": "^1.0.2", | |
| 4113 | "pear-rti": "^1.0.1", | |
| 4114 | "sodium-native": "^5.0.6", | |
| 4115 | "url-file-url": "^1.0.5", | |
| 4116 | "which-runtime": "^1.3.0" | |
| 4117 | } | |
| 4118 | }, | |
| 4119 | "node_modules/pear-crasher": { | |
| 4120 | "version": "1.0.1", | |
| 4121 | "resolved": "https://registry.npmjs.org/pear-crasher/-/pear-crasher-1.0.1.tgz", | |
| 4122 | "integrity": "sha512-Ott6ANdu01t5zUXDQ50g0QRQ57SZu35KLuRjuKRsrOLLwdKeBTNYscX4VCgLnfKINlpGtRz/vzUGFPgBXGf6lg==", | |
| 4123 | "license": "Apache-2.0", | |
| 4124 | "dependencies": { | |
| 4125 | "pear-rti": "^1.0.1" | |
| 4126 | } | |
| 4127 | }, | |
| 4128 | "node_modules/pear-electron": { | |
| 4129 | "version": "1.7.28", | |
| 4130 | "resolved": "https://registry.npmjs.org/pear-electron/-/pear-electron-1.7.28.tgz", | |
| 4131 | "integrity": "sha512-ZCOFvVmUZgPxl8bCG0EllweW+eO2svGM5BLFNI8nppXdiIeE7ns8fLsQnGS2JdVALpG7ilaNja5pq1XRHbvhYw==", | |
| 4132 | "license": "Apache-2.0", | |
| 4133 | "dependencies": { | |
| 4134 | "bare-env": "^3.0.0", | |
| 4135 | "bare-fs": "^4.0.1", | |
| 4136 | "bare-os": "^3.4.0", | |
| 4137 | "bare-path": "^3.0.0", | |
| 4138 | "bare-subprocess": "^5.0.2", | |
| 4139 | "compact-encoding": "^2.16.1", | |
| 4140 | "localdrive": "^1.12.1", | |
| 4141 | "paparam": "^1.6.1", | |
| 4142 | "pear-api": "^1.29.1", | |
| 4143 | "pear-cmd": "^1.0.0", | |
| 4144 | "pear-constants": "^1.0.0", | |
| 4145 | "pear-crasher": "^1.0.1", | |
| 4146 | "pear-errors": "^1.0.0", | |
| 4147 | "pear-gunk": "^1.0.0", | |
| 4148 | "pear-ipc": "^6.4.0", | |
| 4149 | "pear-link": "^4.1.0", | |
| 4150 | "pear-logger": "^1.0.0", | |
| 4151 | "pear-pipe": "^1.0.2", | |
| 4152 | "pear-run": "^1.0.0", | |
| 4153 | "pear-state": "^1.0.2", | |
| 4154 | "pear-terminal": "^1.0.0", | |
| 4155 | "pear-tryboot": "^1.0.0", | |
| 4156 | "script-linker": "^2.5.3", | |
| 4157 | "streamx": "^2.20.2", | |
| 4158 | "unix-path-resolve": "^1.0.2", | |
| 4159 | "url-file-url": "^1.0.4", | |
| 4160 | "which-runtime": "^1.2.1" | |
| 4161 | } | |
| 4162 | }, | |
| 4163 | "node_modules/pear-electron/node_modules/pear-run": { | |
| 4164 | "version": "1.0.8", | |
| 4165 | "resolved": "https://registry.npmjs.org/pear-run/-/pear-run-1.0.8.tgz", | |
| 4166 | "integrity": "sha512-X56S6WJEvE5UKxH+XI1WhsgN2oCzPMg2jO/FH/bNFWX9a/LQmQobcIuxLPDBH+iuiHPM1inFScrYWVNZGWqWDw==", | |
| 4167 | "license": "Apache-2.0", | |
| 4168 | "dependencies": { | |
| 4169 | "b4a": "^1.6.7", | |
| 4170 | "bare-path": "^3.0.0", | |
| 4171 | "bare-subprocess": "^5.1.0", | |
| 4172 | "paparam": "^1.8.5", | |
| 4173 | "pear-cmd": "^1.0.0", | |
| 4174 | "pear-link": "^4.1.0", | |
| 4175 | "pear-ref": "^1.0.0", | |
| 4176 | "unix-path-resolve": "^1.0.2", | |
| 4177 | "url-file-url": "^1.0.5", | |
| 4178 | "which-runtime": "^1.3.2" | |
| 4179 | } | |
| 4180 | }, | |
| 4181 | 4087 | "node_modules/pear-errors": { |
| 4182 | 4088 | "version": "1.0.1", |
| 4183 | 4089 | "resolved": "https://registry.npmjs.org/pear-errors/-/pear-errors-1.0.1.tgz", |
| 4184 | 4090 | "integrity": "sha512-KQyhym09QpLT4H/z3uLW0bqixgIZic2Eip2Q8Z72QmIpFzPtp6QmnzOUwB3kuHB4dqKNa+FQWHWH0NSK5lJjlw==", |
| 4185 | 4091 | "license": "Apache-2.0" |
| 4186 | 4092 | }, |
| 4187 | "node_modules/pear-gracedown": { | |
| 4188 | "version": "1.0.3", | |
| 4189 | "resolved": "https://registry.npmjs.org/pear-gracedown/-/pear-gracedown-1.0.3.tgz", | |
| 4190 | "integrity": "sha512-PVh4AmpMDFxd+kMiCkuTyJ7NzRPgb0AEE7TR5GCl91x90uzWmFWon4TZMrCVhGtADG26OrQpOI+kL6S/o2w00w==", | |
| 4093 | "node_modules/pear-runtime": { | |
| 4094 | "version": "1.3.1", | |
| 4095 | "resolved": "https://registry.npmjs.org/pear-runtime/-/pear-runtime-1.3.1.tgz", | |
| 4096 | "integrity": "sha512-IoEr3c52L40BrXkjFnMYbeNbbnjuEF8L2toFIe3IyB0lkrUOBZ/mleBiMV6Mq4YLVmp6fWTMHIefMvT/oU3LXw==", | |
| 4191 | 4097 | "license": "Apache-2.0", |
| 4192 | 4098 | "dependencies": { |
| 4193 | "bare-os": "^3.6.1", | |
| 4194 | "bare-signals": "^4.0.3", | |
| 4195 | "safety-catch": "^1.0.2", | |
| 4196 | "url-file-url": "^1.0.5" | |
| 4099 | "bare-path": "^3.0.0", | |
| 4100 | "bare-sidecar": "^0.5.2", | |
| 4101 | "bare-worker": "^4.4.0", | |
| 4102 | "corestore": "^7.9.1", | |
| 4103 | "hyperswarm": "^4.17.0", | |
| 4104 | "pear-runtime-updater": "^3.0.0", | |
| 4105 | "ready-resource": "^1.2.0" | |
| 4197 | 4106 | } |
| 4198 | 4107 | }, |
| 4199 | "node_modules/pear-gunk": { | |
| 4200 | "version": "1.0.1", | |
| 4201 | "resolved": "https://registry.npmjs.org/pear-gunk/-/pear-gunk-1.0.1.tgz", | |
| 4202 | "integrity": "sha512-xN2aGZxGXY/rpSlq24UHsc/RMX12DLJzCM5XPJriDBn7MHUrHoKmD/SZTLT6RlFeL2z9MheRnrge6oR6eIGUMA==", | |
| 4108 | "node_modules/pear-runtime-updater": { | |
| 4109 | "version": "3.2.0", | |
| 4110 | "resolved": "https://registry.npmjs.org/pear-runtime-updater/-/pear-runtime-updater-3.2.0.tgz", | |
| 4111 | "integrity": "sha512-KLHefj2y0ehG3lE3iAgGSxSbl51ZIM9Arpzb/BW8LTjOmC3n9ydclMgvjlbuA12efQu4MnUvE7nNQ3leISxwLw==", | |
| 4203 | 4112 | "license": "Apache-2.0", |
| 4204 | 4113 | "dependencies": { |
| 4205 | "crc-universal": "^1.0.4", | |
| 4206 | "fs-native-extensions": "^1.4.3", | |
| 4207 | "quickbit-universal": "^2.2.0", | |
| 4208 | "rocksdb-native": "^3.7.5", | |
| 4209 | "script-linker": "^2.5.4", | |
| 4210 | "sodium-native": "^5.0.8", | |
| 4211 | "udx-native": "^1.18.3" | |
| 4114 | "bare-fs": "^4.5.3", | |
| 4115 | "bare-path": "^3.0.0", | |
| 4116 | "bare-semver": "^1.0.2", | |
| 4117 | "debounceify": "^1.1.0", | |
| 4118 | "fs-native-extensions": "^1.4.5", | |
| 4119 | "hypercore-id-encoding": "^1.3.0", | |
| 4120 | "hyperdrive": "^13.2.1", | |
| 4121 | "localdrive": "^2.2.0", | |
| 4122 | "msix-manager": "^0.2.4", | |
| 4123 | "pear-link": "^5.0.0", | |
| 4124 | "ready-resource": "^1.2.0", | |
| 4125 | "which-runtime": "^1.3.2" | |
| 4212 | 4126 | } |
| 4213 | 4127 | }, |
| 4214 | "node_modules/pear-ipc": { | |
| 4215 | "version": "6.11.0", | |
| 4216 | "resolved": "https://registry.npmjs.org/pear-ipc/-/pear-ipc-6.11.0.tgz", | |
| 4217 | "integrity": "sha512-7peANATe7VlhbLfTHx3CpIQO9AiHqPkfHK0Wgw5T0EY9KllO/XTPVNAV49VNJ5o0QASrPdrUy6FOvB46HWJflA==", | |
| 4128 | "node_modules/pear-runtime-updater/node_modules/localdrive": { | |
| 4129 | "version": "2.2.1", | |
| 4130 | "resolved": "https://registry.npmjs.org/localdrive/-/localdrive-2.2.1.tgz", | |
| 4131 | "integrity": "sha512-r7AMrscOky3zIjzOrbH+90P12WmFdQaIlJ26TXaUJrM3hGQ6lIQkWhy8eQs5xDI5ukEyrXp4962EIgO9DFdm+g==", | |
| 4218 | 4132 | "license": "Apache-2.0", |
| 4219 | 4133 | "dependencies": { |
| 4134 | "b4a": "^1.6.1", | |
| 4220 | 4135 | "bare-fs": "^4.0.1", |
| 4221 | "bare-os": "^3.2.0", | |
| 4222 | 4136 | "bare-path": "^3.0.0", |
| 4223 | "bare-pipe": "^4.0.5", | |
| 4224 | "framed-stream": "^1.0.1", | |
| 4225 | "fs-native-extensions": "^1.2.7", | |
| 4226 | "fs-native-lock": "^1.1.0", | |
| 4227 | "ready-resource": "^1.0.3", | |
| 4228 | "streamx": "^2.16.1", | |
| 4229 | "tiny-buffer-rpc": "^2.2.0", | |
| 4230 | "which-runtime": "^1.2.0" | |
| 4137 | "mirror-drive": "^1.2.0", | |
| 4138 | "mutexify": "^1.4.0", | |
| 4139 | "streamx": "^2.12.5", | |
| 4140 | "unix-path-resolve": "^1.0.2" | |
| 4231 | 4141 | } |
| 4232 | 4142 | }, |
| 4233 | "node_modules/pear-link": { | |
| 4234 | "version": "4.2.1", | |
| 4235 | "resolved": "https://registry.npmjs.org/pear-link/-/pear-link-4.2.1.tgz", | |
| 4236 | "integrity": "sha512-Y6xSOY36EkWmaeTYqNVT2iV0xWfzCDCBtPCF898793ADk9Lbzfq7RLJ7PhqHRS+dLI7yTlLtCCfjGR3erQ0FKQ==", | |
| 4143 | "node_modules/pear-runtime-updater/node_modules/pear-link": { | |
| 4144 | "version": "5.0.0", | |
| 4145 | "resolved": "https://registry.npmjs.org/pear-link/-/pear-link-5.0.0.tgz", | |
| 4146 | "integrity": "sha512-Va2xz1vdm4akNonOXOQLsvsxIcT/SWai2R03l9JA5i7YTZa9F3y9AsxtUNBRNLkC4sA6Bk6+9XIa2FzvuoK/FA==", | |
| 4237 | 4147 | "license": "Apache-2.0", |
| 4238 | 4148 | "dependencies": { |
| 4239 | 4149 | "bare-path": "^3.0.0", |
| … | … | @@ -4242,173 +4152,6 @@ |
| 4242 | 4152 | "pear-errors": "^1.0.0" |
| 4243 | 4153 | } |
| 4244 | 4154 | }, |
| 4245 | "node_modules/pear-logger": { | |
| 4246 | "version": "1.0.1", | |
| 4247 | "resolved": "https://registry.npmjs.org/pear-logger/-/pear-logger-1.0.1.tgz", | |
| 4248 | "integrity": "sha512-DMFcqReoaAoxliOSAgw09RwVmWdwXaEPXG/rZ/aITPAVqZetY06P17ipuywEKECH1N1kt5JZ2hVvJPRE/nUllg==", | |
| 4249 | "license": "Apache-2.0", | |
| 4250 | "dependencies": { | |
| 4251 | "bare-format": "^1.0.1", | |
| 4252 | "bare-hrtime": "^2.0.11", | |
| 4253 | "pear-cmd": "^1.0.0", | |
| 4254 | "which-runtime": "^1.3.0" | |
| 4255 | } | |
| 4256 | }, | |
| 4257 | "node_modules/pear-message": { | |
| 4258 | "version": "1.0.0", | |
| 4259 | "resolved": "https://registry.npmjs.org/pear-message/-/pear-message-1.0.0.tgz", | |
| 4260 | "integrity": "sha512-ZBZsaIv4PVS38psP/x32D2xaRKf1qI9FnB0gTsRPY0NChV38qhWsnQDbXOhAYGxkTqjREC0OkDoQAha7z6wo/Q==", | |
| 4261 | "license": "Apache-2.0", | |
| 4262 | "dependencies": { | |
| 4263 | "pear-ref": "^1.0.1", | |
| 4264 | "sodium-native": "^5.0.6" | |
| 4265 | } | |
| 4266 | }, | |
| 4267 | "node_modules/pear-messages": { | |
| 4268 | "version": "1.0.5", | |
| 4269 | "resolved": "https://registry.npmjs.org/pear-messages/-/pear-messages-1.0.5.tgz", | |
| 4270 | "integrity": "sha512-2kCw5lnnFxBZ+d4wz8L+AmKi25M0rwdgPWsMTGLBbmkyKmaPVBQBpG8ZktsFwVPGBSLu9dFtGC79VYYDSaA3Vw==", | |
| 4271 | "license": "Apache-2.0", | |
| 4272 | "dependencies": { | |
| 4273 | "b4a": "^1.6.7", | |
| 4274 | "pear-ipc": "^6.5.0", | |
| 4275 | "pear-ref": "^1.0.1", | |
| 4276 | "sodium-native": "^5.0.6" | |
| 4277 | } | |
| 4278 | }, | |
| 4279 | "node_modules/pear-opwait": { | |
| 4280 | "version": "1.0.0", | |
| 4281 | "resolved": "https://registry.npmjs.org/pear-opwait/-/pear-opwait-1.0.0.tgz", | |
| 4282 | "integrity": "sha512-V8h7GWihtc5Cam4e0EDJebuwpTxndSRfVsIPAll1YZgf+QG5XrpwQeF8umvxiDBYJXwtJ9P3pVnbsM4jk7vDuA==", | |
| 4283 | "license": "Apache-2.0", | |
| 4284 | "dependencies": { | |
| 4285 | "pear-errors": "^1.0.0" | |
| 4286 | } | |
| 4287 | }, | |
| 4288 | "node_modules/pear-pipe": { | |
| 4289 | "version": "1.0.6", | |
| 4290 | "resolved": "https://registry.npmjs.org/pear-pipe/-/pear-pipe-1.0.6.tgz", | |
| 4291 | "integrity": "sha512-7XApSERIgctSlSjsZ8ATkFXwbkIyCEHG90GQdsc1DG2GkDYxYuGrq4c4H/YEE2jt1oq6VywwE/eNtvrlOEUeHg==", | |
| 4292 | "license": "Apache-2.0", | |
| 4293 | "dependencies": { | |
| 4294 | "bare-fs": "^4.1.6", | |
| 4295 | "bare-pipe": "^4.0.6", | |
| 4296 | "streamx": "^2.22.1", | |
| 4297 | "which-runtime": "^1.3.0" | |
| 4298 | } | |
| 4299 | }, | |
| 4300 | "node_modules/pear-ref": { | |
| 4301 | "version": "1.0.2", | |
| 4302 | "resolved": "https://registry.npmjs.org/pear-ref/-/pear-ref-1.0.2.tgz", | |
| 4303 | "integrity": "sha512-IUGGSULYVF6jfdtsHY0XOokMp1v1KI89q8yPhsnqrLFf+Wq8EEOD0capny8gqXyu0eGkIh753X1cFUVL36n7FA==", | |
| 4304 | "license": "Apache-2.0", | |
| 4305 | "dependencies": { | |
| 4306 | "bare-events": "^2.6.1" | |
| 4307 | } | |
| 4308 | }, | |
| 4309 | "node_modules/pear-rti": { | |
| 4310 | "version": "1.0.1", | |
| 4311 | "resolved": "https://registry.npmjs.org/pear-rti/-/pear-rti-1.0.1.tgz", | |
| 4312 | "integrity": "sha512-rpVNVY9Zwu8ng5sTywaMV8exCkzRWATVElmCsgFH2zfdvVqvsYMxVN1oW9xKSAP2eKJ8cInoL1UmMJLcdbFIXA==", | |
| 4313 | "license": "Apache-2.0", | |
| 4314 | "dependencies": { | |
| 4315 | "bare-path": "^3.0.0" | |
| 4316 | } | |
| 4317 | }, | |
| 4318 | "node_modules/pear-run": { | |
| 4319 | "version": "2.0.0", | |
| 4320 | "resolved": "https://registry.npmjs.org/pear-run/-/pear-run-2.0.0.tgz", | |
| 4321 | "integrity": "sha512-BD+XZkaY7UaIZZ2CKx0lhsliuGUfA+SMgIXHck9tXhP7NVMqkaE5kzYHBtz0A115ap2AjCyfPobCpEtj+5KAiw==", | |
| 4322 | "license": "Apache-2.0", | |
| 4323 | "dependencies": { | |
| 4324 | "b4a": "^1.6.7", | |
| 4325 | "bare-path": "^3.0.0", | |
| 4326 | "bare-subprocess": "^5.1.0", | |
| 4327 | "paparam": "^1.8.5", | |
| 4328 | "pear-cmd": "^1.0.0", | |
| 4329 | "pear-errors": "^1.0.1", | |
| 4330 | "pear-link": "^4.1.0", | |
| 4331 | "pear-ref": "^1.0.0", | |
| 4332 | "unix-path-resolve": "^1.0.2", | |
| 4333 | "url-file-url": "^1.0.5", | |
| 4334 | "which-runtime": "^1.3.2" | |
| 4335 | } | |
| 4336 | }, | |
| 4337 | "node_modules/pear-stamp": { | |
| 4338 | "version": "1.0.2", | |
| 4339 | "resolved": "https://registry.npmjs.org/pear-stamp/-/pear-stamp-1.0.2.tgz", | |
| 4340 | "integrity": "sha512-1cU2EnHlcLsixP9cPZqIWJORxbCKyDCQ6G9JL1d+GFaEqwVmyOCSxHwzxzSdfTccWzpBI4Zs/5r/l0YpbQuvIg==", | |
| 4341 | "license": "Apache-2.0", | |
| 4342 | "dependencies": { | |
| 4343 | "streamx": "^2.22.1" | |
| 4344 | } | |
| 4345 | }, | |
| 4346 | "node_modules/pear-state": { | |
| 4347 | "version": "1.1.0", | |
| 4348 | "resolved": "https://registry.npmjs.org/pear-state/-/pear-state-1.1.0.tgz", | |
| 4349 | "integrity": "sha512-zs09OU6hwvx/25OuMVaCRgLQWKGXVIcd0yFWjCqa1yo9SY9u5GMSxix7nWjtGusTYTtBKAJhFo+i53GcXsosfg==", | |
| 4350 | "license": "Apache-2.0", | |
| 4351 | "dependencies": { | |
| 4352 | "bare-env": "^3.0.0", | |
| 4353 | "bare-fs": "^4.2.0", | |
| 4354 | "bare-os": "^3.6.1", | |
| 4355 | "bare-path": "^3.0.0", | |
| 4356 | "hypercore-crypto": "^3.6.1", | |
| 4357 | "hypercore-id-encoding": "^1.3.0", | |
| 4358 | "pear-constants": "^1.0.0", | |
| 4359 | "pear-link": "^4.1.0", | |
| 4360 | "which-runtime": "^1.3.0" | |
| 4361 | } | |
| 4362 | }, | |
| 4363 | "node_modules/pear-terminal": { | |
| 4364 | "version": "1.2.1", | |
| 4365 | "resolved": "https://registry.npmjs.org/pear-terminal/-/pear-terminal-1.2.1.tgz", | |
| 4366 | "integrity": "sha512-NPdghB3DAHb8F/BQS1YyZiIAzjtwYxwfzhlk6pkZpFGtT6Lizk0oyM97eq0Np+h/gIyny+l7/Z8G6uZkJyYfSw==", | |
| 4367 | "license": "Apache-2.0", | |
| 4368 | "dependencies": { | |
| 4369 | "bare-events": "^2.6.1", | |
| 4370 | "bare-fs": "^4.2.0", | |
| 4371 | "bare-readline": "^1.0.9", | |
| 4372 | "bare-stream": "^2.7.0", | |
| 4373 | "bare-tty": "^5.0.2", | |
| 4374 | "hypercore-id-encoding": "^1.3.0", | |
| 4375 | "pear-constants": "^1.0.0", | |
| 4376 | "pear-errors": "^1.0.1", | |
| 4377 | "pear-gracedown": "^1.0.0", | |
| 4378 | "pear-opwait": "^1.0.0", | |
| 4379 | "streamx": "^2.22.1", | |
| 4380 | "tiny-byte-size": "^1.1.0", | |
| 4381 | "which-runtime": "^1.3.0" | |
| 4382 | } | |
| 4383 | }, | |
| 4384 | "node_modules/pear-tryboot": { | |
| 4385 | "version": "1.0.0", | |
| 4386 | "resolved": "https://registry.npmjs.org/pear-tryboot/-/pear-tryboot-1.0.0.tgz", | |
| 4387 | "integrity": "sha512-0zTaj9vAXsXoKjtKhJfDBRDcfNY+1+zXu9Ttks9UgnCH0yNYTffghABjqNEOvwX5xPwLqzvHlxBamV9MckBkRA==", | |
| 4388 | "license": "Apache-2.0", | |
| 4389 | "dependencies": { | |
| 4390 | "bare-daemon": "^1.2.1", | |
| 4391 | "pear-constants": "^1.0.0" | |
| 4392 | } | |
| 4393 | }, | |
| 4394 | "node_modules/pear-updates": { | |
| 4395 | "version": "1.1.0", | |
| 4396 | "resolved": "https://registry.npmjs.org/pear-updates/-/pear-updates-1.1.0.tgz", | |
| 4397 | "integrity": "sha512-cD759YRSDFLqlr7sM44imVtdQTc18hflvV2v4ENtoBoKfrLnn5HWklsbgTYfE82az7G+3qaE1JBCtBih/W5dvg==", | |
| 4398 | "license": "Apache-2.0", | |
| 4399 | "dependencies": { | |
| 4400 | "pear-messages": "^1.0.0" | |
| 4401 | } | |
| 4402 | }, | |
| 4403 | "node_modules/pear-wakeups": { | |
| 4404 | "version": "1.0.0", | |
| 4405 | "resolved": "https://registry.npmjs.org/pear-wakeups/-/pear-wakeups-1.0.0.tgz", | |
| 4406 | "integrity": "sha512-by8XW24RjQcgETxwGJYnOAnnyFtMOC6++G/3zdwDDBuxouKZnib3JVWBdGvNdTiI8IpedApCOLqNZaHrkBxyvA==", | |
| 4407 | "license": "Apache-2.0", | |
| 4408 | "dependencies": { | |
| 4409 | "pear-messages": "^1.0.0" | |
| 4410 | } | |
| 4411 | }, | |
| 4412 | 4155 | "node_modules/pino": { |
| 4413 | 4156 | "version": "9.14.0", |
| 4414 | 4157 | "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", |
| … | … | @@ -4503,6 +4246,15 @@ |
| 4503 | 4246 | ], |
| 4504 | 4247 | "license": "MIT" |
| 4505 | 4248 | }, |
| 4249 | "node_modules/progress": { | |
| 4250 | "version": "2.0.3", | |
| 4251 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", | |
| 4252 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", | |
| 4253 | "license": "MIT", | |
| 4254 | "engines": { | |
| 4255 | "node": ">=0.4.0" | |
| 4256 | } | |
| 4257 | }, | |
| 4506 | 4258 | "node_modules/protobufjs": { |
| 4507 | 4259 | "version": "7.6.4", |
| 4508 | 4260 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz", |
| … | … | @@ -4587,15 +4339,6 @@ |
| 4587 | 4339 | "protomux": "^3.10.1" |
| 4588 | 4340 | } |
| 4589 | 4341 | }, |
| 4590 | "node_modules/punycode": { | |
| 4591 | "version": "2.3.1", | |
| 4592 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", | |
| 4593 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", | |
| 4594 | "license": "MIT", | |
| 4595 | "engines": { | |
| 4596 | "node": ">=6" | |
| 4597 | } | |
| 4598 | }, | |
| 4599 | 4342 | "node_modules/qrcode-terminal": { |
| 4600 | 4343 | "version": "0.12.0", |
| 4601 | 4344 | "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", |
| … | … | @@ -4784,10 +4527,7 @@ |
| 4784 | 4527 | "version": "1.2.2", |
| 4785 | 4528 | "resolved": "https://registry.npmjs.org/require-asset/-/require-asset-1.2.2.tgz", |
| 4786 | 4529 | "integrity": "sha512-uc8nWKhqAxVD9Z4rST2b4yaemrC9Xb5vA1wlCz5AiCYnBYdwGRWNqFjneA5zRILzlo1MNrB63ry9+pc8wNR26w==", |
| 4787 | "dev": true, | |
| 4788 | 4530 | "license": "Apache-2.0", |
| 4789 | "optional": true, | |
| 4790 | "peer": true, | |
| 4791 | 4531 | "dependencies": { |
| 4792 | 4532 | "bare-module-resolve": "^1.6.2" |
| 4793 | 4533 | }, |
| … | … | @@ -4906,23 +4646,6 @@ |
| 4906 | 4646 | "integrity": "sha512-BpSd8VCuCxW9ZitcdIC/vjs3gMaP9bRBL5nkHcyfX2VrS52n13/rHuBA2xJ/S/4DPuRdAO/Bk8pWd8eD/gHCIA==", |
| 4907 | 4647 | "license": "Apache-2.0" |
| 4908 | 4648 | }, |
| 4909 | "node_modules/script-linker": { | |
| 4910 | "version": "2.5.4", | |
| 4911 | "resolved": "https://registry.npmjs.org/script-linker/-/script-linker-2.5.4.tgz", | |
| 4912 | "integrity": "sha512-hzVNCEyu/1g9egVPk7s+jTgus+ZGd12d/Rjkm2QjOmPW5l07EANXd20cjAjA3aLPRY/n5z1UUESKHUf4tli5Tg==", | |
| 4913 | "license": "Apache-2.0", | |
| 4914 | "dependencies": { | |
| 4915 | "acorn": "^8.6.0", | |
| 4916 | "b4a": "^1.3.1", | |
| 4917 | "cjs-module-lexer": "^1.2.2", | |
| 4918 | "drive-resolve": "^1.0.1", | |
| 4919 | "es-module-lexer": "^1.6.0", | |
| 4920 | "is-valid-variable": "^1.0.0", | |
| 4921 | "read-write-mutexify": "^2.0.0", | |
| 4922 | "source-map-bare": "^1.0.0", | |
| 4923 | "unix-path-resolve": "^1.0.2" | |
| 4924 | } | |
| 4925 | }, | |
| 4926 | 4649 | "node_modules/semver": { |
| 4927 | 4650 | "version": "7.8.5", |
| 4928 | 4651 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", |
| … | … | @@ -5078,18 +4801,6 @@ |
| 5078 | 4801 | "atomic-sleep": "^1.0.0" |
| 5079 | 4802 | } |
| 5080 | 4803 | }, |
| 5081 | "node_modules/source-map-bare": { | |
| 5082 | "version": "1.0.0", | |
| 5083 | "resolved": "https://registry.npmjs.org/source-map-bare/-/source-map-bare-1.0.0.tgz", | |
| 5084 | "integrity": "sha512-e1AGLUcnbp8l4URDmHXuCRlts4CRwjPVd/2XDD6a3zUdcF5lr7hp2pTYMoklJXaN4CArYBb53jXGVRsSsVsDPA==", | |
| 5085 | "license": "BSD-3-Clause", | |
| 5086 | "dependencies": { | |
| 5087 | "whatwg-url": "^7.0.0" | |
| 5088 | }, | |
| 5089 | "engines": { | |
| 5090 | "node": ">= 12" | |
| 5091 | } | |
| 5092 | }, | |
| 5093 | 4804 | "node_modules/speedometer": { |
| 5094 | 4805 | "version": "1.1.0", |
| 5095 | 4806 | "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-1.1.0.tgz", |
| … | … | @@ -5152,6 +4863,18 @@ |
| 5152 | 4863 | "codecs": "^3.1.0" |
| 5153 | 4864 | } |
| 5154 | 4865 | }, |
| 4866 | "node_modules/sumchecker": { | |
| 4867 | "version": "3.0.1", | |
| 4868 | "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", | |
| 4869 | "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", | |
| 4870 | "license": "Apache-2.0", | |
| 4871 | "dependencies": { | |
| 4872 | "debug": "^4.1.0" | |
| 4873 | }, | |
| 4874 | "engines": { | |
| 4875 | "node": ">= 8.0" | |
| 4876 | } | |
| 4877 | }, | |
| 5155 | 4878 | "node_modules/tar-stream": { |
| 5156 | 4879 | "version": "3.2.0", |
| 5157 | 4880 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", |
| … | … | @@ -5218,18 +4941,6 @@ |
| 5218 | 4941 | "b4a": "^1.6.0" |
| 5219 | 4942 | } |
| 5220 | 4943 | }, |
| 5221 | "node_modules/tiny-buffer-rpc": { | |
| 5222 | "version": "2.3.1", | |
| 5223 | "resolved": "https://registry.npmjs.org/tiny-buffer-rpc/-/tiny-buffer-rpc-2.3.1.tgz", | |
| 5224 | "integrity": "sha512-oJvKOwEKYAt3IwqX9TOI76DaLKebbWyf3/A723mSw1Vm2qKswV21w0Qc34sSJ1bbBQTmo9IT7ToA7diwz4sgCg==", | |
| 5225 | "license": "Apache-2.0", | |
| 5226 | "dependencies": { | |
| 5227 | "b4a": "^1.6.3", | |
| 5228 | "compact-encoding": "^2.11.0", | |
| 5229 | "safety-catch": "^1.0.2", | |
| 5230 | "streamx": "^2.13.2" | |
| 5231 | } | |
| 5232 | }, | |
| 5233 | 4944 | "node_modules/tiny-byte-size": { |
| 5234 | 4945 | "version": "1.1.0", |
| 5235 | 4946 | "resolved": "https://registry.npmjs.org/tiny-byte-size/-/tiny-byte-size-1.1.0.tgz", |
| … | … | @@ -5252,15 +4963,6 @@ |
| 5252 | 4963 | "yarn": ">= 1.20.0" |
| 5253 | 4964 | } |
| 5254 | 4965 | }, |
| 5255 | "node_modules/tr46": { | |
| 5256 | "version": "1.0.1", | |
| 5257 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", | |
| 5258 | "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", | |
| 5259 | "license": "MIT", | |
| 5260 | "dependencies": { | |
| 5261 | "punycode": "^2.1.0" | |
| 5262 | } | |
| 5263 | }, | |
| 5264 | 4966 | "node_modules/typpy": { |
| 5265 | 4967 | "version": "2.4.0", |
| 5266 | 4968 | "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.4.0.tgz", |
| … | … | @@ -5295,6 +4997,16 @@ |
| 5295 | 4997 | "typpy": "^2.3.4" |
| 5296 | 4998 | } |
| 5297 | 4999 | }, |
| 5000 | "node_modules/undici": { | |
| 5001 | "version": "7.28.0", | |
| 5002 | "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", | |
| 5003 | "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", | |
| 5004 | "license": "MIT", | |
| 5005 | "optional": true, | |
| 5006 | "engines": { | |
| 5007 | "node": ">=20.18.1" | |
| 5008 | } | |
| 5009 | }, | |
| 5298 | 5010 | "node_modules/undici-types": { |
| 5299 | 5011 | "version": "8.3.0", |
| 5300 | 5012 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", |
| … | … | @@ -5332,39 +5044,12 @@ |
| 5332 | 5044 | "bare-path": "^3.0.0" |
| 5333 | 5045 | } |
| 5334 | 5046 | }, |
| 5335 | "node_modules/url-file-url": { | |
| 5336 | "version": "1.0.5", | |
| 5337 | "resolved": "https://registry.npmjs.org/url-file-url/-/url-file-url-1.0.5.tgz", | |
| 5338 | "integrity": "sha512-RkUWAFWSmCDpyFn2qf2QO8Gnwf0y5RadgJuDpBeFD6gEzDuh6hTNpd/jox4znFFqZ79ghAS0gGM7F3ZU4nrMWw==", | |
| 5339 | "license": "Apache-2.0", | |
| 5340 | "dependencies": { | |
| 5341 | "bare-path": "^3.0.0", | |
| 5342 | "which-runtime": "^1.2.0" | |
| 5343 | } | |
| 5344 | }, | |
| 5345 | 5047 | "node_modules/varint": { |
| 5346 | 5048 | "version": "5.0.0", |
| 5347 | 5049 | "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", |
| 5348 | 5050 | "integrity": "sha512-gC13b/bWrqQoKY2EmROCZ+AR0jitc6DnDGaQ6Ls9QpKmuSgJB1eQ7H3KETtQm7qSdMWMKCmsshyCmUwMLh3OAA==", |
| 5349 | 5051 | "license": "MIT" |
| 5350 | 5052 | }, |
| 5351 | "node_modules/webidl-conversions": { | |
| 5352 | "version": "4.0.2", | |
| 5353 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", | |
| 5354 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", | |
| 5355 | "license": "BSD-2-Clause" | |
| 5356 | }, | |
| 5357 | "node_modules/whatwg-url": { | |
| 5358 | "version": "7.1.0", | |
| 5359 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", | |
| 5360 | "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", | |
| 5361 | "license": "MIT", | |
| 5362 | "dependencies": { | |
| 5363 | "lodash.sortby": "^4.7.0", | |
| 5364 | "tr46": "^1.0.1", | |
| 5365 | "webidl-conversions": "^4.0.2" | |
| 5366 | } | |
| 5367 | }, | |
| 5368 | 5053 | "node_modules/which-runtime": { |
| 5369 | 5054 | "version": "1.4.0", |
| 5370 | 5055 | "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.4.0.tgz", |
| … | … | @@ -1,13 +1,16 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "pearbrowser-desktop", |
| 3 | "productName": "PearBrowser", | |
| 3 | 4 | "version": "0.7.1", |
| 4 | "description": "P2P browser + decentralized app store + site builder, desktop Pear fork of PearBrowser (jj10133/Vinjari family)", | |
| 5 | "description": "Local-first P2P browser, catalogue, and publishing platform with an embedded Pear OTA runtime.", | |
| 5 | 6 | "license": "Apache-2.0 AND MIT", |
| 6 | 7 | "type": "module", |
| 8 | "main": "electron/main.cjs", | |
| 9 | "upgrade": "pear://tco5k7h38uoxatedp1wongdbhjxow1x7jiwm3t1i9cujbebhsbty", | |
| 7 | 10 | "scripts": { |
| 8 | 11 | "preinstall": "node scripts/check-hiverelay-layout.mjs", |
| 9 | "start": "node scripts/native-runtime-required.mjs --dev", | |
| 10 | "run": "node scripts/native-runtime-required.mjs", | |
| 12 | "start": "electron electron/main.cjs", | |
| 13 | "run": "electron electron/main.cjs", | |
| 11 | 14 | "check:release-evidence": "node scripts/check-release-evidence.mjs", |
| 12 | 15 | "check:origin-isolation-smoke-evidence": "node scripts/check-origin-isolation-smoke-evidence.mjs", |
| 13 | 16 | "generate:release-evidence-handoff": "node scripts/generate-release-evidence-handoff.mjs", |
| … | … | @@ -30,7 +33,7 @@ |
| 30 | 33 | "package:macos-dmg": "node scripts/create-macos-dmg.mjs", |
| 31 | 34 | "smoke:qvac:native": "node node_modules/bare/bin/bare qvac-smoke/index.mjs", |
| 32 | 35 | "smoke:qvac:browser": "node node_modules/bare/bin/bare qvac-smoke/browser.mjs", |
| 33 | "smoke:qvac:pear": "node scripts/native-runtime-required.mjs --smoke qvac-smoke", | |
| 36 | "smoke:qvac:pear": "npm run smoke:qvac:native", | |
| 34 | 37 | "smoke:ask-browser:ui": "node qvac-smoke/ask-browser-ui.mjs", |
| 35 | 38 | "smoke:ask-browser:native": "node node_modules/bare/bin/bare qvac-smoke/ask-browser.mjs", |
| 36 | 39 | "smoke:runtime": "node scripts/runtime-rpc-smoke.mjs", |
| … | … | @@ -40,7 +43,6 @@ |
| 40 | 43 | "pear": { |
| 41 | 44 | "name": "pearbrowser-desktop", |
| 42 | 45 | "type": "desktop", |
| 43 | "pre": "pear-electron/pre", | |
| 44 | 46 | "stage": { |
| 45 | 47 | "ignore": [ |
| 46 | 48 | "/.git", |
| … | … | @@ -111,9 +113,8 @@ |
| 111 | 113 | "p2p-hiverelay": "latest", |
| 112 | 114 | "p2p-hiverelay-client": "latest", |
| 113 | 115 | "p2p-hiverelay-verifier": "latest", |
| 114 | "pear-bridge": "1.2.5", | |
| 115 | "pear-electron": "1.7.28", | |
| 116 | "pear-run": "2.0.0", | |
| 116 | "electron": "43.2.0", | |
| 117 | "pear-runtime": "1.3.1", | |
| 117 | 118 | "react": "^18.3.1", |
| 118 | 119 | "react-dom": "^18.3.1", |
| 119 | 120 | "schema-sheets": "^3.1.1" |
| … | … | @@ -1,7 +0,0 @@ |
| 1 | { | |
| 2 | "_comment": "Legacy v2 release identifiers retained only for migration lookup. They are not executable runtime inputs or a v3 publishing workflow.", | |
| 3 | "links": { | |
| 4 | "production": "pear://tco5k7h38uoxatedp1wongdbhjxow1x7jiwm3t1i9cujbebhsbty", | |
| 5 | "provisionTarget": "pear://pdsd1p3m1xsz8aofyndbwux5hqs19h8uswnsrfee5cz8sj9pmj4o" | |
| 6 | } | |
| 7 | } |
| … | … | @@ -1115,7 +1115,7 @@ |
| 1115 | 1115 | <path d="M12 3 5 6v5c0 5 3 8 7 10 4-2 7-5 7-10V6l-7-3Z"></path> |
| 1116 | 1116 | <path d="M9 12l2 2 4-5"></path> |
| 1117 | 1117 | </svg> |
| 1118 | <input value="pear://explore" aria-label="Address value" /> | |
| 1118 | <input value="hyper://explore" aria-label="Address value" /> | |
| 1119 | 1119 | <span class="route-chip">hybrid</span> |
| 1120 | 1120 | </label> |
| 1121 | 1121 | |
| … | … | @@ -1231,7 +1231,7 @@ |
| 1231 | 1231 | <p class="card-copy">Encrypted P2P chat and calls.</p> |
| 1232 | 1232 | </div> |
| 1233 | 1233 | </div> |
| 1234 | <div class="mono-line">pear://oeeoz3...jzpo</div> | |
| 1234 | <div class="mono-line">Native v3 package required</div> | |
| 1235 | 1235 | </article> |
| 1236 | 1236 | <article class="app-card"> |
| 1237 | 1237 | <div class="app-row"> |
| … | … | @@ -1241,7 +1241,7 @@ |
| 1241 | 1241 | <p class="card-copy">Private pay-per-inference chat.</p> |
| 1242 | 1242 | </div> |
| 1243 | 1243 | </div> |
| 1244 | <div class="mono-line">pear://rpzh3f...b6wo</div> | |
| 1244 | <div class="mono-line">Native v3 package required</div> | |
| 1245 | 1245 | </article> |
| 1246 | 1246 | <article class="app-card"> |
| 1247 | 1247 | <div class="app-row"> |
| … | … | @@ -1251,7 +1251,7 @@ |
| 1251 | 1251 | <p class="card-copy">Local-first password manager.</p> |
| 1252 | 1252 | </div> |
| 1253 | 1253 | </div> |
| 1254 | <div class="mono-line">pear://tywsat...mtzo</div> | |
| 1254 | <div class="mono-line">Native v3 package required</div> | |
| 1255 | 1255 | </article> |
| 1256 | 1256 | <article class="app-card"> |
| 1257 | 1257 | <div class="app-row"> |
| … | … | @@ -1261,7 +1261,7 @@ |
| 1261 | 1261 | <p class="card-copy">Community chat over peers.</p> |
| 1262 | 1262 | </div> |
| 1263 | 1263 | </div> |
| 1264 | <div class="mono-line">pear://wmir47...mouy</div> | |
| 1264 | <div class="mono-line">Native v3 package required</div> | |
| 1265 | 1265 | </article> |
| 1266 | 1266 | </div> |
| 1267 | 1267 | </div> |
| … | … | @@ -1322,7 +1322,7 @@ |
| 1322 | 1322 | <article class="setting-row"> |
| 1323 | 1323 | <div> |
| 1324 | 1324 | <div class="row-title">Keet app bundle</div> |
| 1325 | <div class="row-sub">pear://oeeoz3w6...zpo</div> | |
| 1325 | <div class="row-sub">Legacy native record · package required</div> | |
| 1326 | 1326 | </div> |
| 1327 | 1327 | <span class="badge">app</span> |
| 1328 | 1328 | </article> |
| … | … | @@ -1432,11 +1432,11 @@ |
| 1432 | 1432 | const address = document.querySelector('.address input') |
| 1433 | 1433 | const title = document.querySelector('.browser-tab.active .tab-title') |
| 1434 | 1434 | const addresses = { |
| 1435 | browse: 'pear://explore', | |
| 1435 | browse: 'hyper://explore', | |
| 1436 | 1436 | apps: 'hyperbee://pearbrowser-network/apps', |
| 1437 | sites: 'pear://sites', | |
| 1438 | library: 'pear://library', | |
| 1439 | settings: 'pear://settings' | |
| 1437 | sites: 'hyper://sites', | |
| 1438 | library: 'hyper://library', | |
| 1439 | settings: 'hyper://settings' | |
| 1440 | 1440 | } |
| 1441 | 1441 | const titles = { |
| 1442 | 1442 | browse: 'PearBrowser Home', |
| … | … | @@ -1451,7 +1451,7 @@ |
| 1451 | 1451 | const view = button.dataset.view |
| 1452 | 1452 | buttons.forEach((item) => item.classList.toggle('active', item === button)) |
| 1453 | 1453 | panels.forEach((panel) => panel.classList.toggle('active', panel.dataset.panel === view)) |
| 1454 | if (address) address.value = addresses[view] || 'pear://explore' | |
| 1454 | if (address) address.value = addresses[view] || 'hyper://explore' | |
| 1455 | 1455 | if (title) title.textContent = titles[view] || 'PearBrowser' |
| 1456 | 1456 | }) |
| 1457 | 1457 | }) |
| … | … | @@ -83,7 +83,7 @@ |
| 83 | 83 | <div class="app-info"> |
| 84 | 84 | <div class="app-name">Keet</div> |
| 85 | 85 | <div class="app-desc">End-to-end encrypted P2P chat, voice, and video.</div> |
| 86 | <div class="app-meta">pear://oeeoz3... · standalone</div> | |
| 86 | <div class="app-meta">Legacy native record · verified package required</div> | |
| 87 | 87 | </div> |
| 88 | 88 | <div class="app-actions"> |
| 89 | 89 | <button class="btn primary">Open</button> |
| … | … | @@ -5,7 +5,7 @@ import { createLazyQvacService } from '../backend/ai/qvac-host.mjs' |
| 5 | 5 | |
| 6 | 6 | if (!globalThis.process) globalThis.process = bareProcess |
| 7 | 7 | |
| 8 | const origin = 'pear://pearbrowser-qvac-native-smoke' | |
| 8 | const origin = 'p2p-local://pearbrowser-qvac-native-smoke' | |
| 9 | 9 | const prompt = process.argv.slice(2).join(' ') || 'Reply with exactly: QVAC native smoke passed.' |
| 10 | 10 | const smokeHome = process.env.QVAC_SMOKE_HOME || path.join(os.tmpdir(), 'pearbrowser-qvac-native-smoke') |
| 11 | 11 | const localModelPath = process.env.QVAC_SMOKE_MODEL_PATH |
| … | … | @@ -35,14 +35,14 @@ async function shutdown (code) { |
| 35 | 35 | if (shuttingDown) return |
| 36 | 36 | shuttingDown = true |
| 37 | 37 | try { await service.close() } catch (err) { console.error('[qvac-smoke] cleanup failed:', err?.message || err) } |
| 38 | if (globalThis.Pear?.exit) Pear.exit(code) | |
| 39 | else process.exit(code) | |
| 38 | process.exit(code) | |
| 40 | 39 | } |
| 41 | 40 | |
| 42 | if (globalThis.Pear?.teardown) Pear.teardown(() => shutdown(0)) | |
| 41 | process.once('SIGINT', () => { void shutdown(0) }) | |
| 42 | process.once('SIGTERM', () => { void shutdown(0) }) | |
| 43 | 43 | |
| 44 | 44 | try { |
| 45 | console.log(`[qvac-smoke] runtime=Pear/Bare model=${modelAlias} device=${device}`) | |
| 45 | console.log(`[qvac-smoke] runtime=Bare worker model=${modelAlias} device=${device}`) | |
| 46 | 46 | if (localModelPath) console.log(`[qvac-smoke] model-path=${localModelPath}`) |
| 47 | 47 | console.log(`[qvac-smoke] storage=${smokeHome}`) |
| 48 | 48 | if (!localModelPath) console.log('[qvac-smoke] first run downloads about 386 MB; later runs use QVAC cache') |
| … | … | @@ -3,7 +3,6 @@ |
| 3 | 3 | import { existsSync, readFileSync, statSync } from 'node:fs' |
| 4 | 4 | |
| 5 | 5 | const rootPackage = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) |
| 6 | const pearConfig = JSON.parse(readFileSync(new URL('../pear.json', import.meta.url), 'utf8')) | |
| 7 | 6 | const applingPackage = JSON.parse(readFileSync(new URL('../appling/package.json', import.meta.url), 'utf8')) |
| 8 | 7 | const applingLock = JSON.parse(readFileSync(new URL('../appling/package-lock.json', import.meta.url), 'utf8')) |
| 9 | 8 | const cmake = readFileSync(new URL('../appling/CMakeLists.txt', import.meta.url), 'utf8') |
| … | … | @@ -12,7 +11,7 @@ const addPearApplingBlock = cmake.match(/add_pear_appling\([\s\S]*?\n\)/)?.[0] | |
| 12 | 11 | const errors = [] |
| 13 | 12 | const args = parseArgs(process.argv.slice(2)) |
| 14 | 13 | const expectedVersion = versionFromTag(args.tag) || rootPackage.version |
| 15 | const productionLink = pearConfig.links?.production || '' | |
| 14 | const productionLink = rootPackage.upgrade || '' | |
| 16 | 15 | const productionId = productionLink.replace(/^pear:\/\//, '') |
| 17 | 16 | |
| 18 | 17 | const cmakeId = matchValue(/\bID\s+"([^"]+)"/, 'ID', addPearApplingBlock) |
| … | … | @@ -25,7 +24,7 @@ if (rootPackage.version !== expectedVersion) { |
| 25 | 24 | errors.push(`package.json version ${rootPackage.version} does not match release tag ${args.tag}`) |
| 26 | 25 | } |
| 27 | 26 | if (!/^pear:\/\/[a-z0-9]{52}$/i.test(productionLink)) { |
| 28 | errors.push(`pear.json links.production is not a pear:// link: ${productionLink || '(missing)'}`) | |
| 27 | errors.push(`package.json upgrade is not a Pear OTA channel: ${productionLink || '(missing)'}`) | |
| 29 | 28 | } |
| 30 | 29 | if (cmakeId !== productionId) { |
| 31 | 30 | errors.push(`appling CMake ID ${cmakeId || '(missing)'} does not match production key ${productionId || '(missing)'}`) |
| … | … | @@ -4,7 +4,6 @@ import { execFileSync } from 'node:child_process' |
| 4 | 4 | import { readFileSync } from 'node:fs' |
| 5 | 5 | |
| 6 | 6 | const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) |
| 7 | const pearConfig = JSON.parse(readFileSync(new URL('../pear.json', import.meta.url), 'utf8')) | |
| 8 | 7 | |
| 9 | 8 | const SUPPORTED_TARGETS = [ |
| 10 | 9 | { label: 'macOS Apple Silicon', platform: 'macos', arch: 'arm64' }, |
| … | … | @@ -327,7 +326,6 @@ function printInstallGuide (report) { |
| 327 | 326 | const windows = report.targets.find((target) => target.platform === 'windows') |
| 328 | 327 | const linux = report.targets.find((target) => target.platform === 'linux') |
| 329 | 328 | const macosExample = macos[0] |
| 330 | const fallback = pearConfig?.links?.production || '' | |
| 331 | 329 | |
| 332 | 330 | console.log('# Install Native Packages') |
| 333 | 331 | console.log() |
| … | … | @@ -431,13 +429,6 @@ function printInstallGuide (report) { |
| 431 | 429 | console.log(`chmod +x ${linux?.asset?.name || 'PearBrowser-<version>-linux-x64.AppImage'}`) |
| 432 | 430 | console.log(`./${linux?.asset?.name || 'PearBrowser-<version>-linux-x64.AppImage'}`) |
| 433 | 431 | console.log('```') |
| 434 | if (fallback) { | |
| 435 | console.log() | |
| 436 | console.log('## Legacy Migration Record') | |
| 437 | console.log() | |
| 438 | console.log(`Legacy migration record: \`${fallback}\`.`) | |
| 439 | console.log('Keep existing data intact while migrating. This record is not a v3 launch or install command; use the native package and app-specific migration guidance.') | |
| 440 | } | |
| 441 | 432 | } |
| 442 | 433 | |
| 443 | 434 | function unique (values) { |
| … | … | @@ -1,14 +0,0 @@ |
| 1 | #!/usr/bin/env node | |
| 2 | ||
| 3 | // The old source commands started PearBrowser through `pear run`. That command | |
| 4 | // accepted remote project links and hides the boundary a native v3 browser must | |
| 5 | // own. Do not revive it as a fallback. This guard stays explicit until the | |
| 6 | // pinned embedded runtime host, local worker boot/shutdown smoke, and native | |
| 7 | // package build are present in this checkout. | |
| 8 | ||
| 9 | const mode = process.argv.includes('--smoke') ? 'smoke' : process.argv.includes('--dev') ? 'development' : 'run' | |
| 10 | ||
| 11 | console.error(`PearBrowser v3 ${mode} host is not configured in this source checkout.`) | |
| 12 | console.error('Use a verified native package, or complete the embedded pear-runtime host migration first.') | |
| 13 | console.error('A remote pear:// record must never be passed to PearRuntime.run().') | |
| 14 | process.exitCode = 1 |
| … | … | @@ -22,7 +22,6 @@ import { readCatalogBee } from './lib/catalog-bee.js' |
| 22 | 22 | |
| 23 | 23 | const DEFAULT_KEY = 'f5fb7500bccd60a976d2b1d24246108f4444a210b9ca591533114dffc089934d' |
| 24 | 24 | const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) |
| 25 | const pearConfig = JSON.parse(readFileSync(new URL('../pear.json', import.meta.url), 'utf8')) | |
| 26 | 25 | const catalogSource = JSON.parse(readFileSync(new URL('../catalog-source/pearbrowser-network.catalog.json', import.meta.url), 'utf8')) |
| 27 | 26 | const browserSource = catalogSource.apps.find((app) => app.id === 'pearbrowser-desktop') |
| 28 | 27 | if (!browserSource) throw new Error('catalogue source is missing pearbrowser-desktop') |
| … | … | @@ -37,7 +36,7 @@ function parseArgs (argv) { |
| 37 | 36 | expectCount: 14, |
| 38 | 37 | expectName: 'PearBrowser Network', |
| 39 | 38 | expectBrowserVersion: pkg.version, |
| 40 | expectBrowserLink: pearConfig.links.production, | |
| 39 | expectBrowserLink: pkg.upgrade, | |
| 41 | 40 | expectBrowserHomepage: browserSource.homepage |
| 42 | 41 | } |
| 43 | 42 | for (let i = 0; i < argv.length; i++) { |
| … | … | @@ -45,7 +45,7 @@ const BLOB_SAMPLE_TIMEOUT_MS = 20_000 |
| 45 | 45 | const BLOB_LIST_TIMEOUT_MS = 20_000 |
| 46 | 46 | const HIVERELAY_TIMEOUT_MS = 45_000 |
| 47 | 47 | const HIVERELAY_PROOF_TIMEOUT_MS = 30_000 |
| 48 | const DEFAULT_SAMPLE_PATHS = ['/index.html', '/package.json', '/pear.json'] | |
| 48 | const DEFAULT_SAMPLE_PATHS = ['/index.html', '/package.json', '/electron/main.cjs'] | |
| 49 | 49 | |
| 50 | 50 | function parseArgs (argv) { |
| 51 | 51 | const args = { |
| … | … | @@ -14,7 +14,7 @@ const SAMPLE = { |
| 14 | 14 | name: ' Pear Picks ', |
| 15 | 15 | version: 1, |
| 16 | 16 | apps: [ |
| 17 | { id: 'keet', name: 'Keet', type: 'standalone', description: 'P2P chat', link: 'pear://keetkey', categories: ['chat'], author: 'Holepunch', homepage: 'https://keet.io', source: 'https://github.com/holepunchto/keet', license: 'Apache-2.0' }, | |
| 17 | { id: 'keet', name: 'Keet', type: 'standalone', description: 'P2P chat', link: 'hyper://' + 'b'.repeat(64) + '/', categories: ['chat'], author: 'Holepunch', homepage: 'https://keet.io', source: 'https://github.com/holepunchto/keet', license: 'Apache-2.0' }, | |
| 18 | 18 | { id: 'pearpass', name: 'PearPass', driveKey: 'a'.repeat(64), version: '2.0' } |
| 19 | 19 | ] |
| 20 | 20 | } |
| … | … | @@ -38,7 +38,7 @@ test('normalizeManifest rejects bad input', () => { |
| 38 | 38 | assert.throws(() => normalizeManifest({}), /apps must be an array/) |
| 39 | 39 | assert.throws(() => normalizeManifest({ apps: 'nope' }), /apps must be an array/) |
| 40 | 40 | assert.throws(() => normalizeManifest({ apps: [{}] }), /needs an id/) |
| 41 | assert.throws(() => normalizeManifest({ apps: [{ id: 'x', link: 'pear://one' }, { id: 'x', link: 'pear://two' }] }), /duplicate app id/) | |
| 41 | assert.throws(() => normalizeManifest({ apps: [{ id: 'x', link: 'hyper://' + 'c'.repeat(64) + '/' }, { id: 'x', link: 'hyper://' + 'd'.repeat(64) + '/' }] }), /duplicate app id/) | |
| 42 | 42 | }) |
| 43 | 43 | |
| 44 | 44 | test('normalizeManifest allows an explicitly empty community catalog', () => { |
| … | … | @@ -48,8 +48,9 @@ test('normalizeManifest allows an explicitly empty community catalog', () => { |
| 48 | 48 | }) |
| 49 | 49 | |
| 50 | 50 | test('derives an id from driveKey/link when id is absent', () => { |
| 51 | const n = normalizeManifest({ apps: [{ link: 'pear://only-a-link' }] }) | |
| 52 | assert.equal(n.apps[0].id, 'pear://only-a-link') | |
| 51 | const link = 'hyper://' + 'e'.repeat(64) + '/' | |
| 52 | const n = normalizeManifest({ apps: [{ link }] }) | |
| 53 | assert.equal(n.apps[0].id, 'e'.repeat(64)) | |
| 53 | 54 | }) |
| 54 | 55 | |
| 55 | 56 | test('round-trips through a real Hyperbee using the loader query', async () => { |
| … | … | @@ -79,7 +80,7 @@ test('round-trips through a real Hyperbee using the loader query', async () => { |
| 79 | 80 | const byId = Object.fromEntries(data.apps.map((a) => [a.id, a])) |
| 80 | 81 | assert.equal(byId.keet.name, 'Keet') |
| 81 | 82 | assert.equal(byId.keet.type, 'standalone') |
| 82 | assert.equal(byId.keet.link, 'pear://keetkey') | |
| 83 | assert.equal(byId.keet.link, 'hyper://' + 'b'.repeat(64) + '/') | |
| 83 | 84 | assert.equal(byId.keet.source, 'hyperbee') |
| 84 | 85 | assert.equal(byId.keet.sourceUrl, 'https://github.com/holepunchto/keet') |
| 85 | 86 | assert.equal(byId.keet.homepage, 'https://keet.io') |
| … | … | @@ -40,16 +40,16 @@ test("resolves a trusted contact's claim (owner == contact root)", async () => { |
| 40 | 40 | assert.equal(res.candidates, 1) |
| 41 | 41 | }) |
| 42 | 42 | |
| 43 | test("resolves a trusted contact's link-only app claim", async () => { | |
| 43 | test("resolves a trusted contact's hyper link claim", async () => { | |
| 44 | 44 | const root = K('aa') |
| 45 | const link = 'pear://contact-app' | |
| 45 | const link = `hyper://${K('ee')}/contact-app` | |
| 46 | 46 | const r = stubResolver({ |
| 47 | 47 | contacts: [{ pubkey: root, displayName: 'Bob', verifiedAt: 1, bindingKey: K('bb') }], |
| 48 | 48 | bindings: { [root]: { nameRegKey: K('cc') } }, |
| 49 | 49 | registries: { [K('cc')]: fakeReg({ app: { target: link, owner: root, version: 1 } }) }, |
| 50 | 50 | }) |
| 51 | 51 | const res = await r.resolve('app') |
| 52 | assert.equal(res.key, null) | |
| 52 | assert.equal(res.key, K('ee')) | |
| 53 | 53 | assert.equal(res.link, link) |
| 54 | 54 | assert.equal(res.source, 'Bob') |
| 55 | 55 | }) |
| … | … | @@ -1,9 +1,12 @@ |
| 1 | 1 | import test from 'node:test' |
| 2 | 2 | import assert from 'node:assert/strict' |
| 3 | import { readFileSync } from 'node:fs' | |
| 3 | import { existsSync, readFileSync } from 'node:fs' | |
| 4 | ||
| 5 | const mobileRoot = new URL('../../PearBrowser/', import.meta.url) | |
| 6 | const hasMobileCheckout = existsSync(mobileRoot) | |
| 4 | 7 | |
| 5 | 8 | function source (path) { |
| 6 | return readFileSync(new URL(`../../PearBrowser/${path}`, import.meta.url), 'utf8') | |
| 9 | return readFileSync(new URL(path, mobileRoot), 'utf8') | |
| 7 | 10 | } |
| 8 | 11 | |
| 9 | 12 | function includesAll (text, fragments) { |
| … | … | @@ -12,7 +15,7 @@ function includesAll (text, fragments) { |
| 12 | 15 | } |
| 13 | 16 | } |
| 14 | 17 | |
| 15 | test('mobile QR scanner accepts supported P2P QR forms and is wired from Home to Browse', () => { | |
| 18 | test('mobile QR scanner accepts supported P2P QR forms and is wired from Home to Browse', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 16 | 19 | const qr = source('app/screens/QRScannerScreen.tsx') |
| 17 | 20 | const app = source('app/App.tsx') |
| 18 | 21 | |
| … | … | @@ -38,7 +41,7 @@ test('mobile QR scanner accepts supported P2P QR forms and is wired from Home to |
| 38 | 41 | ]) |
| 39 | 42 | }) |
| 40 | 43 | |
| 41 | test('mobile Bookmarks, History, and More hub expose local data workflows and status actions', () => { | |
| 44 | test('mobile Bookmarks, History, and More hub expose local data workflows and status actions', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 42 | 45 | const bookmarks = source('app/screens/BookmarksScreen.tsx') |
| 43 | 46 | const history = source('app/screens/HistoryScreen.tsx') |
| 44 | 47 | const more = source('app/screens/MoreScreen.tsx') |
| … | … | @@ -90,7 +93,7 @@ test('mobile Bookmarks, History, and More hub expose local data workflows and st |
| 90 | 93 | ]) |
| 91 | 94 | }) |
| 92 | 95 | |
| 93 | test('mobile My Sites creates, lists, publishes, previews, shares, and deletes sites', () => { | |
| 96 | test('mobile My Sites creates, lists, publishes, previews, shares, and deletes sites', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 94 | 97 | const mySites = source('app/screens/MySitesScreen.tsx') |
| 95 | 98 | const app = source('app/App.tsx') |
| 96 | 99 | |
| … | … | @@ -114,7 +117,7 @@ test('mobile My Sites creates, lists, publishes, previews, shares, and deletes s |
| 114 | 117 | ]) |
| 115 | 118 | }) |
| 116 | 119 | |
| 117 | test('mobile template picker provides selectable starter templates and opens editor after site creation', () => { | |
| 120 | test('mobile template picker provides selectable starter templates and opens editor after site creation', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 118 | 121 | const picker = source('app/screens/TemplatePickerScreen.tsx') |
| 119 | 122 | const app = source('app/App.tsx') |
| 120 | 123 | |
| … | … | @@ -137,7 +140,7 @@ test('mobile template picker provides selectable starter templates and opens edi |
| 137 | 140 | ]) |
| 138 | 141 | }) |
| 139 | 142 | |
| 140 | test('mobile site editor supports block editing, theme selection, preview, save, publish, and sharing', () => { | |
| 143 | test('mobile site editor supports block editing, theme selection, preview, save, publish, and sharing', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 141 | 144 | const editor = source('app/screens/SiteEditorScreen.tsx') |
| 142 | 145 | const app = source('app/App.tsx') |
| 143 | 146 | |
| … | … | @@ -179,7 +182,7 @@ test('mobile site editor supports block editing, theme selection, preview, save, |
| 179 | 182 | ]) |
| 180 | 183 | }) |
| 181 | 184 | |
| 182 | test('mobile native Explore screens preserve safe catalog targets like React Native Explore', () => { | |
| 185 | test('mobile native Explore screens preserve safe catalog targets like React Native Explore', { skip: !hasMobileCheckout && 'mobile checkout is not present in this isolated desktop worktree' }, () => { | |
| 183 | 186 | const rn = source('app/screens/ExploreScreen.tsx') |
| 184 | 187 | const ios = source('ios-native/PearBrowser/Sources/UI/Screens/ExploreScreen.swift') |
| 185 | 188 | const android = source('android-native/app/src/main/java/com/pearbrowser/app/ui/screens/ExploreScreen.kt') |
| … | … | @@ -20,7 +20,7 @@ const hex = (x) => b4a.toString(x, 'hex') |
| 20 | 20 | const signer = (kp) => (msg) => hex(crypto.sign(b4a.from(msg, 'utf-8'), kp.secretKey)) |
| 21 | 21 | const owner = (kp) => hex(kp.publicKey) |
| 22 | 22 | const TARGET_A = 'aa'.repeat(32); const TARGET_B = 'bb'.repeat(32); const TARGET_C = 'cc'.repeat(32) |
| 23 | const PEAR_LINK = 'pear://link-only-app' | |
| 23 | const HYPER_LINK = `hyper://${TARGET_C}/link-only-app` | |
| 24 | 24 | |
| 25 | 25 | const tmps = [] |
| 26 | 26 | const sleep = (ms) => new Promise((r) => setTimeout(r, ms)) |
| … | … | @@ -129,7 +129,7 @@ test('end-to-end: claim → activeMap → resolveName (the CMD_NAME_RESOLVE path |
| 129 | 129 | const R = await new NameRegistry(s.store, { encryptionKey: ENC, namespace: 'nr' }).ready() |
| 130 | 130 | try { |
| 131 | 131 | await R.claim({ name: 'Alice', target: TARGET_A, owner: owner(ka) }, signer(ka)) |
| 132 | await R.claim({ name: 'LinkApp', target: PEAR_LINK, owner: owner(ka) }, signer(ka)) | |
| 132 | await R.claim({ name: 'LinkApp', target: HYPER_LINK, owner: owner(ka) }, signer(ka)) | |
| 133 | 133 | const registry = await R.activeMap() // what the backend injects into the resolver |
| 134 | 134 | // a typed bare name resolves through the registry tier to a navigable key |
| 135 | 135 | const r = resolveName('alice', { petnames: {}, registry }) |
| … | … | @@ -137,8 +137,8 @@ test('end-to-end: claim → activeMap → resolveName (the CMD_NAME_RESOLVE path |
| 137 | 137 | assert.equal(r.key, TARGET_A) // → go() builds hyper://<target>/ |
| 138 | 138 | const link = resolveName('linkapp', { petnames: {}, registry }) |
| 139 | 139 | assert.equal(link.provenance, 'registry') |
| 140 | assert.equal(link.key, null) | |
| 141 | assert.equal(link.link, PEAR_LINK) | |
| 140 | assert.equal(link.key, TARGET_C) | |
| 141 | assert.equal(link.link, HYPER_LINK) | |
| 142 | 142 | // a petname still wins over the registry (tier order preserved end-to-end) |
| 143 | 143 | const pet = resolveName('alice', { petnames: { alice: { key: TARGET_B } }, registry }) |
| 144 | 144 | assert.equal(pet.provenance, 'petname') |
| … | … | @@ -46,12 +46,19 @@ async function withStore (fn) { |
| 46 | 46 | } |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | test('curated floor answers a bare name offline (Tier 3)', async () => { | |
| 49 | test('legacy native curated names do not resolve to executable targets', async () => { | |
| 50 | 50 | await withStore(async (names) => { |
| 51 | 51 | const r = await resolveThroughStore(names, 'keet') |
| 52 | assert.equal(r.provenance, 'curated') | |
| 53 | assert.equal(r.link, lookupAlias('keet').link) // the curated bootstrap target | |
| 54 | assert.equal(r.name, 'keet') | |
| 52 | assert.equal(lookupAlias('keet')?.link, undefined) | |
| 53 | assert.deepEqual(r, { | |
| 54 | name: 'keet', | |
| 55 | key: null, | |
| 56 | link: null, | |
| 57 | legacyMigrationId: lookupAlias('keet').legacyMigrationId, | |
| 58 | target: null, | |
| 59 | label: 'Keet', | |
| 60 | provenance: 'curated' | |
| 61 | }) | |
| 55 | 62 | }) |
| 56 | 63 | }) |
| 57 | 64 | |
| … | … | @@ -82,12 +89,13 @@ test('an unknown word resolves to null (URL bar falls through to plain handling) |
| 82 | 89 | }) |
| 83 | 90 | }) |
| 84 | 91 | |
| 85 | test('a petname pointing at a link (not a key) is returned with its link', async () => { | |
| 92 | test('a petname pointing at a browsable Hyper link is returned with its link', async () => { | |
| 86 | 93 | await withStore(async (names) => { |
| 87 | await names.setPetname({ name: 'home', link: 'pear://example/' }) | |
| 94 | const link = `hyper://${PET_KEY}/home` | |
| 95 | await names.setPetname({ name: 'home', link }) | |
| 88 | 96 | const r = await resolveThroughStore(names, 'home') |
| 89 | 97 | assert.equal(r.provenance, 'petname') |
| 90 | assert.equal(r.link, 'pear://example/') | |
| 98 | assert.equal(r.link, link) | |
| 91 | 99 | assert.equal(r.key, null) |
| 92 | 100 | }) |
| 93 | 101 | }) |
| … | … | @@ -0,0 +1,33 @@ |
| 1 | import test from 'node:test' | |
| 2 | import assert from 'node:assert/strict' | |
| 3 | import { readFileSync } from 'node:fs' | |
| 4 | ||
| 5 | const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) | |
| 6 | const worker = readFileSync(new URL('../workers/main.js', import.meta.url), 'utf8') | |
| 7 | const host = readFileSync(new URL('../electron/main.cjs', import.meta.url), 'utf8') | |
| 8 | const preload = readFileSync(new URL('../electron/preload.cjs', import.meta.url), 'utf8') | |
| 9 | const backendEntry = readFileSync(new URL('../index.js', import.meta.url), 'utf8') | |
| 10 | const boot = readFileSync(new URL('../ui/boot.js', import.meta.url), 'utf8') | |
| 11 | ||
| 12 | test('PearBrowser v3 uses an embedded Pear OTA worker behind a native Electron host', () => { | |
| 13 | assert.equal(pkg.main, 'electron/main.cjs') | |
| 14 | assert.equal(pkg.scripts.start, 'electron electron/main.cjs') | |
| 15 | assert.equal(pkg.dependencies?.['pear-runtime'], '1.3.1') | |
| 16 | assert.equal(pkg.dependencies?.electron, '43.2.0') | |
| 17 | assert.match(pkg.upgrade, /^pear:\/\/[13-9a-km-uw-z]{52}$/) | |
| 18 | ||
| 19 | assert.match(host, /new PearRuntime\(/) | |
| 20 | assert.match(host, /pearRuntime\.run/) | |
| 21 | assert.match(host, /pearRuntime\.updater\.on\('updated'/) | |
| 22 | assert.match(host, /pearRuntime\?\.close/) | |
| 23 | assert.match(host, /crypto\.randomBytes\(32\)/) | |
| 24 | assert.match(host, /contextIsolation: true/) | |
| 25 | assert.match(host, /nodeIntegration: false/) | |
| 26 | assert.match(preload, /contextBridge\.exposeInMainWorld\('pearbrowserRuntime'/) | |
| 27 | assert.match(worker, /Bare\.argv\[2\]/) | |
| 28 | assert.match(worker, /PearBrowserRuntime = \{ storagePath, sessionToken \}/) | |
| 29 | assert.match(backendEntry, /globalThis\.PearBrowserRuntime/) | |
| 30 | assert.doesNotMatch(backendEntry, /from 'pear-electron'/) | |
| 31 | assert.doesNotMatch(backendEntry, /Pear\.config/) | |
| 32 | assert.match(boot, /globalThis\.pearbrowserRuntime\?\.sessionToken/) | |
| 33 | }) |
| … | … | @@ -6,13 +6,15 @@ import { readFileSync } from 'node:fs' |
| 6 | 6 | const require = createRequire(import.meta.url) |
| 7 | 7 | const { SEED_APPS } = require('../backend/catalogue-seed.js') |
| 8 | 8 | |
| 9 | const PEERCORD_LINK = 'pear://wmir47w7mai3b1skj66mx7fzso6k6o91kipaney7gtt69npimouy' | |
| 9 | const PEERCORD_MIGRATION_ID = 'wmir47w7mai3b1skj66mx7fzso6k6o91kipaney7gtt69npimouy' | |
| 10 | 10 | |
| 11 | test('Peercord is seeded as a launchable standalone Pear app', () => { | |
| 11 | test('Peercord is seeded as a migration-required native app, never a remote launcher', () => { | |
| 12 | 12 | const app = SEED_APPS.find((row) => row.name === 'Peercord') |
| 13 | 13 | assert.ok(app, 'Peercord seed row missing') |
| 14 | assert.equal(app.link, PEERCORD_LINK) | |
| 14 | assert.equal(app.link, undefined) | |
| 15 | 15 | assert.equal(app.type, 'standalone') |
| 16 | assert.equal(app.legacyMigrationId, PEERCORD_MIGRATION_ID) | |
| 17 | assert.equal(app.nativeDeliveryStatus, 'migration-required') | |
| 16 | 18 | assert.equal(app.driveKey, undefined) |
| 17 | 19 | assert.equal(app.author, 'Mastercodeon') |
| 18 | 20 | assert.equal(app.version, '1.0.8') |
| … | … | @@ -22,34 +24,32 @@ test('Peercord is seeded as a launchable standalone Pear app', () => { |
| 22 | 24 | assert.ok(app.description.toLowerCase().includes('discord-style')) |
| 23 | 25 | }) |
| 24 | 26 | |
| 25 | test('Peercord catalogue source declares window launch mode explicitly', () => { | |
| 27 | test('Peercord catalogue source preserves provenance without an executable target', () => { | |
| 26 | 28 | const source = JSON.parse(readFileSync(new URL('../catalog-source/pearbrowser-network.catalog.json', import.meta.url), 'utf8')) |
| 27 | 29 | const app = source.apps.find((row) => row.id === 'peercord') |
| 28 | 30 | assert.ok(app, 'Peercord source row missing') |
| 29 | 31 | assert.equal(app.type, 'standalone') |
| 30 | assert.equal(app.link, PEERCORD_LINK) | |
| 32 | assert.equal(app.link, undefined) | |
| 33 | assert.equal(app.legacyMigrationId, PEERCORD_MIGRATION_ID) | |
| 34 | assert.equal(app.nativeDelivery?.status, 'migration-required') | |
| 31 | 35 | assert.equal(app.driveKey, undefined) |
| 32 | 36 | assert.equal(app.homepage, 'https://git.churchofmalware.org/mastercodeon/Peercord') |
| 33 | 37 | assert.equal(app.source, 'https://git.churchofmalware.org/mastercodeon/Peercord') |
| 34 | 38 | assert.equal(app.license, 'GPL-3.0') |
| 35 | 39 | }) |
| 36 | 40 | |
| 37 | test('Featured Peercord card uses the window launch path until a headless worker exists', () => { | |
| 41 | test('Featured Peercord card communicates that publisher migration is required', () => { | |
| 38 | 42 | const shell = readFileSync(new URL('../ui/shell.js', import.meta.url), 'utf8') |
| 39 | 43 | const entry = shell.match(/id: 'peercord'[\s\S]*?gradient: 'linear-gradient\([^']+\)'/) |
| 40 | 44 | assert.ok(entry, 'Peercord featured entry missing') |
| 41 | assert.match(entry[0], /type: 'standalone'/) | |
| 42 | assert.match(shell, new RegExp(`const PEERCORD_LINK = '${PEERCORD_LINK.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}'`)) | |
| 43 | assert.match(entry[0], /link: PEERCORD_LINK/) | |
| 44 | assert.match(shell, /catalogue type is/) | |
| 45 | assert.match(entry[0], /nativeDelivery: \{ status: 'migration-required' \}/) | |
| 46 | assert.match(entry[0], new RegExp(`legacyMigrationId: '${PEERCORD_MIGRATION_ID}'`)) | |
| 47 | assert.match(shell, /verified native v3 package/) | |
| 45 | 48 | }) |
| 46 | 49 | |
| 47 | test('Peercord launch shows a first-run standalone trust warning', () => { | |
| 50 | test('Peercord has no legacy standalone launch warning because it is not launchable', () => { | |
| 48 | 51 | const shell = readFileSync(new URL('../ui/shell.js', import.meta.url), 'utf8') |
| 49 | assert.match(shell, /STANDALONE_PRELAUNCH_WARNINGS/) | |
| 50 | assert.match(shell, /persistent third-party trust prompt/) | |
| 51 | assert.match(shell, /Approving it executes third-party code and creates a persistent trust decision/) | |
| 52 | assert.match(shell, /standaloneLaunchWarningsSeen/) | |
| 53 | assert.match(shell, /pendingStandaloneLaunch/) | |
| 54 | assert.match(shell, /app\.type === 'hypersite'/) | |
| 52 | assert.doesNotMatch(shell, /STANDALONE_PRELAUNCH_WARNINGS/) | |
| 53 | assert.doesNotMatch(shell, /pendingStandaloneLaunch/) | |
| 54 | assert.match(shell, /nativeDelivery.*migration-required/) | |
| 55 | 55 | }) |
| … | … | @@ -20,7 +20,6 @@ import { fileURLToPath, pathToFileURL } from 'node:url' |
| 20 | 20 | const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) |
| 21 | 21 | const require = createRequire(import.meta.url) |
| 22 | 22 | const packageLock = JSON.parse(readFileSync(new URL('../package-lock.json', import.meta.url), 'utf8')) |
| 23 | const pearConfig = JSON.parse(readFileSync(new URL('../pear.json', import.meta.url), 'utf8')) | |
| 24 | 23 | const catalogSource = JSON.parse(readFileSync(new URL('../catalog-source/pearbrowser-network.catalog.json', import.meta.url), 'utf8')) |
| 25 | 24 | const { SEED_APPS } = require('../backend/catalogue-seed.js') |
| 26 | 25 | const rootLicense = readFileSync(new URL('../LICENSE', import.meta.url), 'utf8') |
| … | … | @@ -278,7 +277,7 @@ test('PearBrowser catalogue row is a migration-required native record, not a rem |
| 278 | 277 | assert.ok(source, 'catalogue source row missing') |
| 279 | 278 | assert.ok(seed, 'offline catalogue seed row missing') |
| 280 | 279 | assert.equal(source.version, pkg.version) |
| 281 | assert.equal(source.legacyMigrationId, pearConfig.links.production.replace(/^pear:\/\//, '')) | |
| 280 | assert.equal(source.legacyMigrationId, pkg.upgrade.replace(/^pear:\/\//, '')) | |
| 282 | 281 | assert.equal(source.nativeDelivery?.status, 'migration-required') |
| 283 | 282 | assert.equal(source.driveKey, homepageKey) |
| 284 | 283 | assert.equal(source.homepage, `hyper://${homepageKey}/`) |
| … | … | @@ -726,7 +725,7 @@ test('macOS DMG packager is exposed for public-trust native releases', () => { |
| 726 | 725 | }) |
| 727 | 726 | |
| 728 | 727 | test('appling release metadata stays in sync with the production Pear channel', () => { |
| 729 | const productionId = pearConfig.links.production.replace(/^pear:\/\//, '') | |
| 728 | const productionId = pkg.upgrade.replace(/^pear:\/\//, '') | |
| 730 | 729 | assert.match(applingCmake, new RegExp(`ID "${productionId}"`)) |
| 731 | 730 | assert.match(applingCmake, new RegExp(`VERSION ${pkg.version.replace(/\./g, '\\.')}`)) |
| 732 | 731 | assert.equal(applingPkg.name, 'pearbrowser-desktop-appling') |
| … | … | @@ -1473,7 +1472,7 @@ test('native install snippet generator emits release-note packages for every des |
| 1473 | 1472 | assert.match(guide.stdout, /\[PearBrowser-0\.5\.0-macos-arm64\.dmg\]\(https:\/\/example\.invalid\/PearBrowser-0\.5\.0-macos-arm64\.dmg\)/) |
| 1474 | 1473 | assert.match(guide.stdout, /npm run -s generate:native-install-guide/) |
| 1475 | 1474 | assert.match(guide.stdout, /PowerShell/) |
| 1476 | assert.match(guide.stdout, /legacy migration record/i) | |
| 1475 | assert.doesNotMatch(guide.stdout, /legacy migration record/i) | |
| 1477 | 1476 | |
| 1478 | 1477 | const packageProofDir = join(fixture, 'package-proof') |
| 1479 | 1478 | mkdirSync(packageProofDir) |
| … | … | @@ -61,7 +61,7 @@ test('listApps passes a row-scan limit to sheets.list', async () => { |
| 61 | 61 | test('listApps caps the returned row set at MAX_SHEETS_ROWS', async () => { |
| 62 | 62 | const huge = Array.from({ length: MAX_SHEETS_ROWS + 50 }, (_, i) => ({ |
| 63 | 63 | uuid: 'app-' + i, |
| 64 | json: { name: 'App ' + i, type: 'standalone', link: 'pear://' + i } | |
| 64 | json: { name: 'App ' + i, type: 'standalone', link: 'hyper://' + i.toString(16).padStart(64, '0') + '/' } | |
| 65 | 65 | })) |
| 66 | 66 | const sc = makeCatalog(async () => huge) |
| 67 | 67 | const apps = await sc.listApps() |
| … | … | @@ -16,7 +16,7 @@ import { RpcClient } from './rpc-client.js' |
| 16 | 16 | const RPC_PORT_BASE = 9876 |
| 17 | 17 | const RPC_PORT_COUNT = 5 |
| 18 | 18 | const RPC_PROBE_ID = 900000001 |
| 19 | const RPC_SESSION_TOKEN = String(globalThis.Pear?.config?.startId || '') | |
| 19 | const RPC_SESSION_TOKEN = String(globalThis.pearbrowserRuntime?.sessionToken || '') | |
| 20 | 20 | |
| 21 | 21 | // Must match backend/constants.js exactly (numeric wire codes). This is a |
| 22 | 22 | // COMPLETE mirror — every command/event the renderer can send or receive. |
| … | … | @@ -315,7 +315,7 @@ function diagnosticUrlFor (url) { |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | function rendererUrlFor (port) { |
| 318 | if (!RPC_SESSION_TOKEN) throw new Error('Pear runtime RPC session token is unavailable') | |
| 318 | if (!RPC_SESSION_TOKEN) throw new Error('PearBrowser v3 runtime session token is unavailable') | |
| 319 | 319 | return `ws://127.0.0.1:${port}/?session=${encodeURIComponent(RPC_SESSION_TOKEN)}` |
| 320 | 320 | } |
| 321 | 321 | |
| … | … | @@ -415,8 +415,8 @@ export async function startBackend () { |
| 415 | 415 | // running or crashed before binding the WS server. Since v0.4.4 |
| 416 | 416 | // the main process catches synchronous boot failures and still |
| 417 | 417 | // binds the WS — emitting a `backend-boot-failed` event — so a |
| 418 | // pure port-scan failure means the main process itself didn't | |
| 419 | // start (pear-electron handoff issue, NOT a backend crash). | |
| 418 | // pure port-scan failure means the native host itself did not start, not | |
| 419 | // that the backend reported a structured boot failure. | |
| 420 | 420 | // |
| 421 | 421 | // Most common cause: an interrupted local installation. Do not revive a |
| 422 | 422 | // remote app reference; reinstall the verified signed native package. |
| … | … | @@ -1457,23 +1457,20 @@ function Browse ({ rpc, C, navUrl, onNavigated, tabs, setTabs, activeId, setActi |
| 1457 | 1457 | )))) |
| 1458 | 1458 | } |
| 1459 | 1459 | |
| 1460 | // Try to open devtools for the active tab's iframe. pear-electron | |
| 1461 | // exposes Pear.Window.devtools(...) on some channels; fall back to | |
| 1462 | // a console log if unavailable. | |
| 1460 | // Ask the native v3 host to open devtools for the active renderer. Fall back | |
| 1461 | // to a concise status message if the host capability is unavailable. | |
| 1463 | 1462 | const openDevtools = () => { |
| 1464 | 1463 | try { |
| 1465 | 1464 | const el = iframeRefs.current[activeId] |
| 1466 | 1465 | const cw = el?.contentWindow |
| 1467 | 1466 | if (!cw) return |
| 1468 | // Path 1: pear-electron exposes Pear.Window.openDevTools() | |
| 1469 | if (typeof Pear !== 'undefined' && Pear.Window?.openDevTools) { | |
| 1470 | Pear.Window.openDevTools({ mode: 'detach' }) | |
| 1467 | // The native v3 host exposes only this focused devtools capability. | |
| 1468 | if (globalThis.pearbrowserRuntime?.openDevTools) { | |
| 1469 | globalThis.pearbrowserRuntime.openDevTools() | |
| 1471 | 1470 | return |
| 1472 | 1471 | } |
| 1473 | // Path 2: chrome devtools protocol via remote debugging is not | |
| 1474 | // exposed by default; surface a hint instead. | |
| 1475 | console.log('[devtools] runtime does not expose openDevTools — relaunch with --devtools') | |
| 1476 | updateTab(activeId, { status: 'devtools: relaunch with `pear run --dev --devtools .`' }) | |
| 1472 | console.log('[devtools] native host does not expose openDevTools') | |
| 1473 | updateTab(activeId, { status: 'devtools are unavailable in this native build' }) | |
| 1477 | 1474 | setTimeout(() => updateTab(activeId, { status: '' }), 3000) |
| 1478 | 1475 | } catch (err) { |
| 1479 | 1476 | console.error('[devtools] failed:', err) |
| … | … | @@ -0,0 +1,15 @@ |
| 1 | // PearBrowser's v3 Bare worker. PearRuntime.run() places user-supplied worker | |
| 2 | // arguments after the executable and worker specifier, so the first two live | |
| 3 | // at Bare.argv[2] and Bare.argv[3]. Keep this tiny bootstrap separate from the | |
| 4 | // backend so its launch contract is explicit and testable. | |
| 5 | const args = globalThis.Bare?.argv || [] | |
| 6 | const storagePath = String(args[2] || '') | |
| 7 | const sessionToken = String(args[3] || '') | |
| 8 | ||
| 9 | if (!storagePath || !sessionToken) { | |
| 10 | throw new Error('PearBrowser v3 worker requires storage path and session token') | |
| 11 | } | |
| 12 | ||
| 13 | globalThis.PearBrowserRuntime = { storagePath, sessionToken } | |
| 14 | ||
| 15 | await import('../index.js') |