diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 5972e5c..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Managed by sh1pt Actions Fleet -# pack: node-pnpm-test@1.1.0 -# install: sh1pt-actions-store -# hash: sha256:d753421a4244bd39c13dd7444a29709ac978395b34c359adf0be2bfec9e48268 -name: test - -on: - pull_request: - push: - branches: [main] - -permissions: - contents: read - -jobs: - test: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@v5 - - # pnpm version is read from the "packageManager" field in package.json. - # Do not pin a version here — it conflicts with packageManager and fails - # with ERR_PNPM_BAD_PM_VERSION. - - uses: pnpm/action-setup@v6 - - - uses: actions/setup-node@v5 - with: - node-version: lts/* - cache: pnpm - - - run: pnpm install --frozen-lockfile - - - run: pnpm test - env: - CI: true diff --git a/apps/desktop/extensions/ai-sidebar/markdown.js b/apps/desktop/extensions/ai-sidebar/markdown.js index 5ead4a6..26e342b 100644 Binary files a/apps/desktop/extensions/ai-sidebar/markdown.js and b/apps/desktop/extensions/ai-sidebar/markdown.js differ diff --git a/apps/desktop/extensions/ai-sidebar/options.js b/apps/desktop/extensions/ai-sidebar/options.js index c8828ef..3ddb85c 100644 --- a/apps/desktop/extensions/ai-sidebar/options.js +++ b/apps/desktop/extensions/ai-sidebar/options.js @@ -1,9 +1,19 @@ -import { PROVIDERS, KNOWN_MODELS, listModels } from './providers.js'; -import { mountSettingsSections } from './settings-sections.js'; -import { coinpaySignIn, coinpayState, coinpaySignOut, emailSignIn, emailSignUp } from './coinpay-auth.js'; -import { pushSettings, pullSettings } from './settings-store.js'; -import { encryptVault, decryptVault } from './vault.js'; -import { connect as btrConnect, disconnect as btrDisconnect, verify as btrVerify } from './bittorrented.js'; +import { PROVIDERS, KNOWN_MODELS, listModels } from "./providers.js"; +import { mountSettingsSections } from "./settings-sections.js"; +import { + coinpaySignIn, + coinpayState, + coinpaySignOut, + emailSignIn, + emailSignUp, +} from "./coinpay-auth.js"; +import { pushSettings, pullSettings } from "./settings-store.js"; +import { encryptVault, decryptVault } from "./vault.js"; +import { + connect as btrConnect, + disconnect as btrDisconnect, + verify as btrVerify, +} from "./bittorrented.js"; const el = (id) => document.getElementById(id); const PROV_LIST = Object.entries(PROVIDERS); @@ -15,109 +25,157 @@ function isConfigured(meta, cur) { /* ---------- AI providers (multiple, with reveal + E2E vault) ---------- */ function buildProviders(aiProviders, aiDefault) { - const sel = el('default'); sel.innerHTML = ''; - const box = el('providers'); box.innerHTML = ''; + const sel = el("default"); + sel.innerHTML = ""; + const box = el("providers"); + box.innerHTML = ""; // Default-provider menu lists ONLY configured providers; fall back to all // when nothing is configured yet so the menu is never empty. - const configured = PROV_LIST.filter(([id, meta]) => isConfigured(meta, aiProviders[id])); + const configured = PROV_LIST.filter(([id, meta]) => + isConfigured(meta, aiProviders[id]), + ); const menu = configured.length ? configured : PROV_LIST; for (const [id, meta] of menu) { - const o = document.createElement('option'); o.value = id; o.textContent = meta.label; sel.appendChild(o); + const o = document.createElement("option"); + o.value = id; + o.textContent = meta.label; + sel.appendChild(o); } // Key inputs still list every provider so you can add new keys. for (const [id, meta] of PROV_LIST) { const cur = aiProviders[id] || {}; - const val = meta.keyless ? (cur.baseUrl || '') : (cur.apiKey || ''); - const row = document.createElement('div'); row.className = 'prow'; - row.innerHTML = - `${escape(meta.label)} - + const val = meta.keyless ? cur.baseUrl || "" : cur.apiKey || ""; + const row = document.createElement("div"); + row.className = "prow"; + row.innerHTML = `${escape(meta.label)} + `; box.appendChild(row); } - sel.value = (menu.find(([id]) => id === aiDefault) ? aiDefault : menu[0]?.[0]) || 'anthropic'; - box.querySelectorAll('[data-reveal]').forEach((b) => b.addEventListener('click', () => { - const inp = box.querySelector(`[data-prov="${b.getAttribute('data-reveal')}"]`); - const show = inp.type === 'password'; - inp.type = show ? 'text' : 'password'; - b.textContent = show ? 'hide' : 'show'; - })); + sel.value = + (menu.find(([id]) => id === aiDefault) ? aiDefault : menu[0]?.[0]) || + "anthropic"; + box.querySelectorAll("[data-reveal]").forEach((b) => + b.addEventListener("click", () => { + const inp = box.querySelector( + `[data-prov="${b.getAttribute("data-reveal")}"]`, + ); + const show = inp.type === "password"; + inp.type = show ? "text" : "password"; + b.textContent = show ? "hide" : "show"; + }), + ); fetchModels(); } // Populate the model datalist for the selected provider: known models first // (instant), then merge the provider's live list when a key is present. function setModelOptions(models) { - const dl = el('modelList'); dl.innerHTML = ''; + const dl = el("modelList"); + dl.innerHTML = ""; const seen = new Set(); for (const m of models) { if (!m || seen.has(m)) continue; seen.add(m); - const o = document.createElement('option'); o.value = m; dl.appendChild(o); + const o = document.createElement("option"); + o.value = m; + dl.appendChild(o); } - if (!el('model').value.trim() && seen.size) el('model').value = [...seen][0]; + if (!el("model").value.trim() && seen.size) el("model").value = [...seen][0]; return [...seen]; } async function fetchModels() { - const provider = el('default').value; + const provider = el("default").value; const meta = PROVIDERS[provider]; if (!meta) return; const known = KNOWN_MODELS[provider] || []; const merged = setModelOptions(known); - const keyInput = el('providers').querySelector(`[data-prov="${provider}"]`); - const val = keyInput ? keyInput.value.trim() : ''; - const cfg = meta.keyless ? { provider, baseUrl: val } : { provider, apiKey: val }; - if (!meta.keyless && !val) { el('modelHint').textContent = `${merged.length} common models — add your key above to load the full list`; return; } + const keyInput = el("providers").querySelector(`[data-prov="${provider}"]`); + const val = keyInput ? keyInput.value.trim() : ""; + const cfg = meta.keyless + ? { provider, baseUrl: val } + : { provider, apiKey: val }; + if (!meta.keyless && !val) { + el("modelHint").textContent = + `${merged.length} common models — add your key above to load the full list`; + return; + } - el('modelHint').textContent = 'loading models…'; + el("modelHint").textContent = "loading models…"; try { const live = await listModels(cfg); if (live.length) { const all = setModelOptions([...known, ...live]); - el('modelHint').textContent = `${all.length} models — pick or type`; + el("modelHint").textContent = `${all.length} models — pick or type`; } else { - el('modelHint').textContent = `${merged.length} common models`; + el("modelHint").textContent = `${merged.length} common models`; } - } catch (e) { - el('modelHint').textContent = `${merged.length} common models (couldn't reach provider)`; + } catch (_e) { + el("modelHint").textContent = + `${merged.length} common models (couldn't reach provider)`; } } -el('default').addEventListener('change', () => { el('model').value = ''; fetchModels(); }); -el('providers').addEventListener('input', (e) => { if (e.target.matches(`[data-prov="${el('default').value}"]`)) fetchModels(); }); +el("default").addEventListener("change", () => { + el("model").value = ""; + fetchModels(); +}); +el("providers").addEventListener("input", (e) => { + if (e.target.matches(`[data-prov="${el("default").value}"]`)) fetchModels(); +}); function collectProviders() { const aiProviders = {}; - el('providers').querySelectorAll('[data-prov]').forEach((inp) => { - const id = inp.getAttribute('data-prov'); const v = inp.value.trim(); - if (!v) return; - aiProviders[id] = PROVIDERS[id].keyless ? { baseUrl: v } : { apiKey: v }; - }); + el("providers") + .querySelectorAll("[data-prov]") + .forEach((inp) => { + const id = inp.getAttribute("data-prov"); + const v = inp.value.trim(); + if (!v) return; + aiProviders[id] = PROVIDERS[id].keyless ? { baseUrl: v } : { apiKey: v }; + }); return aiProviders; } -el('saveAi').addEventListener('click', async () => { +el("saveAi").addEventListener("click", async () => { const aiProviders = collectProviders(); - const aiDefault = el('default').value; - const model = el('model').value.trim(); + const aiDefault = el("default").value; + const model = el("model").value.trim(); const def = aiProviders[aiDefault] || {}; // aiConfig is the active provider; stays LOCAL (never synced in plaintext). - const aiConfig = { provider: aiDefault, model, apiKey: def.apiKey || '', baseUrl: def.baseUrl || '' }; - await chrome.storage.local.set({ aiProviders, aiDefault, aiModel: model, aiConfig }); + const aiConfig = { + provider: aiDefault, + model, + apiKey: def.apiKey || "", + baseUrl: def.baseUrl || "", + }; + await chrome.storage.local.set({ + aiProviders, + aiDefault, + aiModel: model, + aiConfig, + }); // E2E: with a vault passphrase, encrypt the keys so only ciphertext syncs. - const pass = el('vault').value; + const pass = el("vault").value; if (pass) { - await chrome.storage.local.set({ aiVault: await encryptVault(pass, aiProviders) }); - sessionStorage.setItem('tb_vault_pass', pass); + await chrome.storage.local.set({ + aiVault: await encryptVault(pass, aiProviders), + }); + sessionStorage.setItem("tb_vault_pass", pass); } else { - await chrome.storage.local.remove('aiVault'); + await chrome.storage.local.remove("aiVault"); } await pushSettings(); - flash('savedAi', el('vault').value ? 'saved (encrypted) ✓' : 'saved ✓ — set a vault passphrase to sync keys'); + flash( + "savedAi", + el("vault").value + ? "saved (encrypted) ✓" + : "saved ✓ — set a vault passphrase to sync keys", + ); await loadAll(); // refresh so the default-provider menu reflects newly-added keys }); @@ -125,20 +183,29 @@ el('saveAi').addEventListener('click', async () => { async function renderBtr() { const st = await btrVerify(); if (st.connected) { - el('btrAccount').textContent = `Connected${st.email ? ' as ' + st.email : ''} — your favorites sync to TronBrowser.`; - el('btrConnect').textContent = 'Disconnect'; + el("btrAccount").textContent = + `Connected${st.email ? " as " + st.email : ""} — your favorites sync to TronBrowser.`; + el("btrConnect").textContent = "Disconnect"; } else { - el('btrAccount').textContent = 'Not connected.'; - el('btrConnect').textContent = 'Connect bittorrented.com'; + el("btrAccount").textContent = "Not connected."; + el("btrConnect").textContent = "Connect bittorrented.com"; } } -el('btrConnect').addEventListener('click', async () => { +el("btrConnect").addEventListener("click", async () => { const st = await btrVerify(); - if (st.connected) { await btrDisconnect(); await renderBtr(); return; } - el('btrMsg').textContent = 'opening bittorrented.com…'; - try { await btrConnect(); el('btrMsg').textContent = 'connected ✓'; } - catch (e) { el('btrMsg').textContent = 'connect failed: ' + e.message; } - setTimeout(() => (el('btrMsg').textContent = ''), 2500); + if (st.connected) { + await btrDisconnect(); + await renderBtr(); + return; + } + el("btrMsg").textContent = "opening bittorrented.com…"; + try { + await btrConnect(); + el("btrMsg").textContent = "connected ✓"; + } catch (e) { + el("btrMsg").textContent = "connect failed: " + e.message; + } + setTimeout(() => (el("btrMsg").textContent = ""), 2500); await renderBtr(); }); @@ -150,24 +217,26 @@ const sectionsStore = { set: async (obj) => { await chrome.storage.local.set(obj); const inval = []; - if ('feeds' in obj) inval.push('feedCache'); - if ('tickers' in obj || 'leagues' in obj) inval.push('marketCache', 'sportsCache'); + if ("feeds" in obj) inval.push("feedCache"); + if ("tickers" in obj || "leagues" in obj) + inval.push("marketCache", "sportsCache"); if (inval.length) await chrome.storage.local.remove(inval); await pushSettings(); }, }; -const mountSections = () => mountSettingsSections({ store: sectionsStore, el, flash }); +const mountSections = () => + mountSettingsSections({ store: sectionsStore, el, flash }); /* ---------- Account + sync (CoinPay or email — same as the website) ---------- */ async function renderAccount() { const st = await coinpayState(); - const how = st.method === 'email' ? 'email' : 'CoinPay'; - el('account').textContent = st.signedIn - ? `Signed in with ${how}${st.label ? ' (' + st.label + ')' : ''} — settings sync to the cloud.` - : 'Not signed in. (Settings stay on this device until you sign in.)'; - el('coinpay').textContent = st.signedIn ? 'Sign out' : 'Sign in with CoinPay'; + const how = st.method === "email" ? "email" : "CoinPay"; + el("account").textContent = st.signedIn + ? `Signed in with ${how}${st.label ? " (" + st.label + ")" : ""} — settings sync to the cloud.` + : "Not signed in. (Settings stay on this device until you sign in.)"; + el("coinpay").textContent = st.signedIn ? "Sign out" : "Sign in with CoinPay"; // The email form is only for signing in; hide it once signed in. - el('emailAuth').style.display = st.signedIn ? 'none' : ''; + el("emailAuth").style.display = st.signedIn ? "none" : ""; } // After any successful sign-in, pull cloud settings down and re-render. @@ -176,48 +245,64 @@ async function afterSignIn() { await loadAll(); } -el('coinpay').addEventListener('click', async () => { +el("coinpay").addEventListener("click", async () => { const st = await coinpayState(); - if (st.signedIn) { await coinpaySignOut(); } - else { - try { await coinpaySignIn(); await afterSignIn(); } - catch (e) { el('account').textContent = 'Sign-in failed: ' + e.message; return; } + if (st.signedIn) { + await coinpaySignOut(); + } else { + try { + await coinpaySignIn(); + await afterSignIn(); + } catch (e) { + el("account").textContent = "Sign-in failed: " + e.message; + return; + } } renderAccount(); }); -el('emailLogin').addEventListener('click', async () => { - const email = el('authEmail').value.trim(); - const password = el('authPassword').value; - if (!email || !password) { flash('emailMsg', 'email and password required'); return; } - el('emailMsg').textContent = 'signing in…'; +el("emailLogin").addEventListener("click", async () => { + const email = el("authEmail").value.trim(); + const password = el("authPassword").value; + if (!email || !password) { + flash("emailMsg", "email and password required"); + return; + } + el("emailMsg").textContent = "signing in…"; try { const { emailVerified } = await emailSignIn(email, password); - el('authPassword').value = ''; + el("authPassword").value = ""; await afterSignIn(); await renderAccount(); - if (!emailVerified) flash('emailMsg', 'signed in — check your inbox to verify your email'); - } catch (e) { flash('emailMsg', e.message); } + if (!emailVerified) + flash("emailMsg", "signed in — check your inbox to verify your email"); + } catch (e) { + flash("emailMsg", e.message); + } }); -el('emailSignup').addEventListener('click', async () => { - const email = el('authEmail').value.trim(); - const password = el('authPassword').value; - if (!email || password.length < 8) { flash('emailMsg', 'email and 8+ char password required'); return; } - el('emailMsg').textContent = 'creating account…'; +el("emailSignup").addEventListener("click", async () => { + const email = el("authEmail").value.trim(); + const password = el("authPassword").value; + if (!email || password.length < 8) { + flash("emailMsg", "email and 8+ char password required"); + return; + } + el("emailMsg").textContent = "creating account…"; try { const { message } = await emailSignUp(email, password); - el('emailMsg').textContent = message; // persistent — user needs to go verify - } catch (e) { flash('emailMsg', e.message); } + el("emailMsg").textContent = message; // persistent — user needs to go verify + } catch (e) { + flash("emailMsg", e.message); + } }); /* ---------- masked passphrase dialog (prompt() can't hide input) ---------- */ function promptPassword(message) { return new Promise((resolve) => { - const dlg = document.createElement('dialog'); - dlg.className = 'pw-dialog'; - dlg.innerHTML = - `
+ const dlg = document.createElement("dialog"); + dlg.className = "pw-dialog"; + dlg.innerHTML = `

@@ -225,12 +310,14 @@ function promptPassword(message) {
`; - dlg.querySelector('.pw-msg').textContent = message; // text node — no HTML injection - const input = dlg.querySelector('input'); - dlg.querySelector('[data-cancel]').addEventListener('click', () => dlg.close('')); + dlg.querySelector(".pw-msg").textContent = message; // text node — no HTML injection + const input = dlg.querySelector("input"); + dlg + .querySelector("[data-cancel]") + .addEventListener("click", () => dlg.close("")); // Enter submits ("ok"); Esc/backdrop fire 'cancel' → returnValue stays ''. - dlg.addEventListener('close', () => { - const val = dlg.returnValue === 'ok' ? input.value : ''; + dlg.addEventListener("close", () => { + const val = dlg.returnValue === "ok" ? input.value : ""; dlg.remove(); resolve(val); }); @@ -242,35 +329,72 @@ function promptPassword(message) { /* ---------- load ---------- */ async function loadAll() { - const { aiProviders, aiDefault, aiModel, aiVault, coinpayConfig, syncConfig } = - await chrome.storage.local.get(['aiProviders', 'aiDefault', 'aiModel', 'aiVault', 'coinpayConfig', 'syncConfig']); + const { + aiProviders, + aiDefault, + aiModel, + aiVault, + coinpayConfig, + syncConfig, + } = await chrome.storage.local.get([ + "aiProviders", + "aiDefault", + "aiModel", + "aiVault", + "coinpayConfig", + "syncConfig", + ]); let provs = aiProviders || {}; // Cross-device: only an encrypted vault present → decrypt with the passphrase. if (!Object.keys(provs).length && aiVault) { - let pass = sessionStorage.getItem('tb_vault_pass'); - if (!pass) pass = await promptPassword('Enter your TronBrowser vault passphrase to decrypt your AI keys:'); + let pass = sessionStorage.getItem("tb_vault_pass"); + if (!pass) + pass = await promptPassword( + "Enter your TronBrowser vault passphrase to decrypt your AI keys:", + ); if (pass) { - try { provs = (await decryptVault(pass, aiVault)) || {}; sessionStorage.setItem('tb_vault_pass', pass); } - catch { provs = {}; flash('savedAi', 'wrong vault passphrase'); } + try { + provs = (await decryptVault(pass, aiVault)) || {}; + sessionStorage.setItem("tb_vault_pass", pass); + } catch { + provs = {}; + flash("savedAi", "wrong vault passphrase"); + } } } - el('model').value = aiModel || ''; + el("model").value = aiModel || ""; buildProviders(provs, aiDefault); - el('cpClient').value = coinpayConfig?.clientId || ''; - el('syncUrl').value = syncConfig?.url || ''; + el("cpClient").value = coinpayConfig?.clientId || ""; + el("syncUrl").value = syncConfig?.url || ""; await renderAccount(); await mountSections(); // Search / Markets / Sports / RSS feeds (shared module) await renderBtr(); } -el('cpClient').addEventListener('change', async () => { - await chrome.storage.local.set({ coinpayConfig: { ...(await get('coinpayConfig')), clientId: el('cpClient').value.trim() } }); +el("cpClient").addEventListener("change", async () => { + await chrome.storage.local.set({ + coinpayConfig: { + ...(await get("coinpayConfig")), + clientId: el("cpClient").value.trim(), + }, + }); }); -el('syncUrl').addEventListener('change', async () => { - await chrome.storage.local.set({ syncConfig: { url: el('syncUrl').value.trim() } }); +el("syncUrl").addEventListener("change", async () => { + await chrome.storage.local.set({ + syncConfig: { url: el("syncUrl").value.trim() }, + }); }); -async function get(k) { return (await chrome.storage.local.get(k))[k] || {}; } +async function get(k) { + return (await chrome.storage.local.get(k))[k] || {}; +} -function flash(id, msg) { el(id).textContent = msg; setTimeout(() => (el(id).textContent = ''), 1600); } -function escape(s) { const d = document.createElement('div'); d.textContent = s || ''; return d.innerHTML; } +function flash(id, msg) { + el(id).textContent = msg; + setTimeout(() => (el(id).textContent = ""), 1600); +} +function escape(s) { + const d = document.createElement("div"); + d.textContent = s || ""; + return d.innerHTML; +} loadAll(); diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 101b7da..1f6e910 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] desktop: stub\"", + "lint": "eslint src extensions", "chromium:fetch": "chromium/scripts/fetch.sh", "chromium:sync": "chromium/scripts/sync.sh", "chromium:patch": "chromium/scripts/apply-patches.sh", diff --git a/apps/docs/package.json b/apps/docs/package.json index 897fb3b..4c56ada 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] docs: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/apps/extensions/package.json b/apps/extensions/package.json index 0d7cf3b..c5e58a9 100644 --- a/apps/extensions/package.json +++ b/apps/extensions/package.json @@ -17,7 +17,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", "serve": "python3 -m http.server 4322 --directory public", - "lint": "echo \"[lint] extensions: stub\"" + "lint": "eslint src public" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 4857976..c99ae7e 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] mobile: stub\"", + "lint": "eslint src", "_comment": "Phase 2: run `pnpm add expo react react-native expo-status-bar` then use the scripts below.", "start": "expo start", "android": "expo start --android", diff --git a/apps/web/package.json b/apps/web/package.json index cd04d22..acab274 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -17,7 +17,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", "serve": "python3 -m http.server 4321 --directory public", - "lint": "echo \"[lint] web: stub\"" + "lint": "eslint src public" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..7aa5bcf --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,104 @@ +// Flat ESLint config for the whole pnpm workspace (apps/*, packages/*, services/*). +// One config, ESLint v9 flat format — avoids 18+ duplicate per-package configs. +// Each package's `lint` script runs `eslint ` against this root config. +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import globals from 'globals'; + +export default tseslint.config( + { + // Build output and vendored/fetched code never gets linted. + ignores: [ + '**/dist/**', + '**/build/**', + '**/out/**', + '**/coverage/**', + '**/.expo/**', + '**/node_modules/**', + 'apps/desktop/chromium/**', + 'apps/desktop/extensions/ublock-origin/**', // fetched at build time, GPL, not vendored + 'pnpm-lock.yaml', + ], + }, + + js.configs.recommended, + ...tseslint.configs.recommended.map((c) => ({ ...c, files: c.files ?? ['**/*.{ts,mts,cts,tsx}'] })), + + // Plain-JS files (no type info) still get the underscore-prefix convention + // used throughout this repo for intentionally-discarded destructured values + // (e.g. `const { a: _a, ...rest } = obj`). TS files get the equivalent via + // @typescript-eslint/no-unused-vars below. + { + files: ['**/*.{js,mjs,cjs,jsx}'], + rules: { + 'no-unused-vars': [ + 'warn', + { + args: 'after-used', + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + }, + }, + + // --- Default: Node-targeted TypeScript (packages/*, services/*, most apps/*) --- + { + files: ['**/*.{ts,mts,cts}'], + languageOptions: { + globals: { ...globals.node }, + }, + rules: { + // The codebase leans on `any` in a handful of intentionally-loose spots + // (Hono context params, third-party JSON payloads). Warn, don't block CI. + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }, + ], + 'no-console': 'off', + }, + }, + + // --- Plain Node scripts (scripts/*.mjs, *.config.js at package roots) --- + { + files: ['scripts/**/*.{js,mjs,cjs}', '**/*.config.{js,mjs,cjs}'], + languageOptions: { + globals: { ...globals.node }, + }, + }, + + // --- Browser extension content (apps/desktop/extensions/**, apps/extensions/public/**) --- + // MV3 extension context: browser globals + the `chrome` extension API. + { + files: [ + 'apps/desktop/extensions/**/*.js', + 'apps/extensions/**/*.js', + ], + languageOptions: { + sourceType: 'module', + globals: { ...globals.browser, chrome: 'readonly' }, + }, + }, + + // --- Plain browser JS served as static assets (apps/web/public/**) --- + // Some of these files (feeds.js, settings-sections.js) are shared verbatim + // with the ai-sidebar extension, so `chrome` needs to be available here too. + { + files: ['apps/web/public/**/*.js'], + languageOptions: { + sourceType: 'module', + globals: { ...globals.browser, chrome: 'readonly' }, + }, + }, + + // Test files: vitest globals (describe/it/expect are imported explicitly in + // this repo, but keep the env available for any that don't). + { + files: ['**/*.test.{ts,js}'], + languageOptions: { + globals: { ...globals.node }, + }, + }, +); \ No newline at end of file diff --git a/package.json b/package.json index 470b23e..3c5590c 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "build": "pnpm -r build", "test": "pnpm -r test", - "lint": "pnpm -r lint", + "lint": "eslint scripts && pnpm -r lint", "typecheck": "pnpm -r typecheck", "version:set": "node scripts/set-version.mjs", "clean": "pnpm -r exec rm -rf dist", @@ -22,6 +22,10 @@ "@types/node": "^24.0.0", "typescript": "^5.6.3", "vitest": "^2.1.4", - "@libsql/client": "^0.14.0" + "@libsql/client": "^0.14.0", + "@eslint/js": "^9.18.0", + "eslint": "^9.18.0", + "globals": "^15.14.0", + "typescript-eslint": "^8.62.0" } } diff --git a/packages/agent-runtime/package.json b/packages/agent-runtime/package.json index d4449b9..10c2e90 100644 --- a/packages/agent-runtime/package.json +++ b/packages/agent-runtime/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] agent-runtime: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/ai-core/package.json b/packages/ai-core/package.json index 5318a4e..cc76893 100644 --- a/packages/ai-core/package.json +++ b/packages/ai-core/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] ai-core: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/auth/package.json b/packages/auth/package.json index 02e2ce7..684bff1 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] auth: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/browser-core/package.json b/packages/browser-core/package.json index 9537480..14e0840 100644 --- a/packages/browser-core/package.json +++ b/packages/browser-core/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] browser-core: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/model-providers/package.json b/packages/model-providers/package.json index 4507fc6..3d82d23 100644 --- a/packages/model-providers/package.json +++ b/packages/model-providers/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] model-providers: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/payments/package.json b/packages/payments/package.json index 5105aee..60be2bd 100644 --- a/packages/payments/package.json +++ b/packages/payments/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] payments: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/plugins/package.json b/packages/plugins/package.json index 6f08c19..f5e49fb 100644 --- a/packages/plugins/package.json +++ b/packages/plugins/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] plugins: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5318842..8c4a5f0 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] sdk: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/shared/package.json b/packages/shared/package.json index ff357f2..db91fe8 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] shared: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/storage/package.json b/packages/storage/package.json index 25f73f2..68efdc6 100644 --- a/packages/storage/package.json +++ b/packages/storage/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] storage: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/sync/package.json b/packages/sync/package.json index d72eecf..2855fa5 100644 --- a/packages/sync/package.json +++ b/packages/sync/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] sync: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/ui/package.json b/packages/ui/package.json index 54eb4c5..29ff5ae 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] ui: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/packages/workflow-engine/package.json b/packages/workflow-engine/package.json index 66f491a..33ef227 100644 --- a/packages/workflow-engine/package.json +++ b/packages/workflow-engine/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] workflow-engine: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66b10c2..f5f7637 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,27 @@ importers: .: devDependencies: + '@eslint/js': + specifier: ^9.18.0 + version: 9.39.4 '@libsql/client': specifier: ^0.14.0 version: 0.14.0 '@types/node': specifier: ^24.0.0 version: 24.13.2 + eslint: + specifier: ^9.18.0 + version: 9.39.4 + globals: + specifier: ^15.14.0 + version: 15.15.0 typescript: specifier: ^5.6.3 version: 5.9.3 + typescript-eslint: + specifier: ^8.62.0 + version: 8.62.0(eslint@9.39.4)(typescript@5.9.3) vitest: specifier: ^2.1.4 version: 2.1.9(@types/node@24.13.2) @@ -400,12 +412,70 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@hono/node-server@1.19.14': resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} engines: {node: '>=18.14.1'} peerDependencies: hono: ^4 + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} @@ -683,6 +753,65 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.62.0': + resolution: {integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.62.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.62.0': + resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.62.0': + resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.62.0': + resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.62.0': + resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.62.0': + resolution: {integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.62.0': + resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.62.0': + resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.62.0': + resolution: {integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.62.0': + resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitest/expect@2.1.9': resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} @@ -712,13 +841,47 @@ packages: '@vitest/utils@2.1.9': resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -727,14 +890,36 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + check-error@2.1.3: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -752,6 +937,9 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepagents@1.10.5: resolution: {integrity: sha512-UFXoH3obz+/3ACuq515UHxXGiDQXHlXvK99ywZ2FSw/HrlrKwI0SKgd0damIj7Tpz7UYrCk4YRzufeDzaOEaQg==} peerDependencies: @@ -769,9 +957,59 @@ packages: engines: {node: '>=12'} hasBin: true + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -782,24 +1020,57 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-sha256@1.3.0: resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -813,10 +1084,42 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + hono@4.12.27: resolution: {integrity: sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==} engines: {node: '>=16.9.0'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -833,16 +1136,35 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + js-base64@3.7.8: resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} js-tiktoken@1.0.21: resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} + js-yaml@4.3.0: + resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-schema-to-ts@3.1.1: resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} engines: {node: '>=16'} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + langchain@1.5.2: resolution: {integrity: sha512-5vCWYvzxuY7gJ8UCgSZ17SM45gou5PtRguFgeQIyCnHzGZQUFLHKi/eQArL3Ad98fJ/UiOEAaTXiI3jfIdoABg==} engines: {node: '>=20'} @@ -869,11 +1191,21 @@ packages: ws: optional: true + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + libsql@0.4.7: resolution: {integrity: sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw==} - cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} @@ -888,6 +1220,13 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -900,6 +1239,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -929,10 +1271,22 @@ packages: zod: optional: true + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -953,6 +1307,18 @@ packages: resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -967,16 +1333,32 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + postcss@8.5.15: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + promise-limit@2.7.0: resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -989,6 +1371,19 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1005,12 +1400,24 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinypool@1.1.1: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1030,6 +1437,23 @@ packages: ts-algebra@2.0.0: resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.62.0: + resolution: {integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -1038,6 +1462,9 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + vite-node@2.1.9: resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1103,11 +1530,20 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + ws@8.21.0: resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} @@ -1125,6 +1561,10 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + zod@4.4.3: resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} @@ -1210,10 +1650,72 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.3.0 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + '@hono/node-server@1.19.14(hono@4.12.27)': dependencies: hono: 4.12.27 + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + '@jridgewell/sourcemap-codec@1.5.5': {} '@langchain/anthropic@1.5.1(@langchain/core@1.2.1(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0))': @@ -1444,6 +1946,97 @@ snapshots: dependencies: '@types/node': 24.13.2 + '@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/type-utils': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.62.0 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.62.0 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.62.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@5.9.3) + '@typescript-eslint/types': 8.62.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.62.0': + dependencies: + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 + + '@typescript-eslint/tsconfig-utils@8.62.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.62.0': {} + + '@typescript-eslint/typescript-estree@8.62.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.62.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@5.9.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.62.0': + dependencies: + '@typescript-eslint/types': 8.62.0 + eslint-visitor-keys: 5.0.1 + '@vitest/expect@2.1.9': dependencies: '@vitest/spy': 2.1.9 @@ -1484,16 +2077,50 @@ snapshots: loupe: 3.2.1 tinyrainbow: 1.2.0 + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + assertion-error@2.0.1: {} + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + base64-js@1.5.1: {} + brace-expansion@1.1.15: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 cac@6.7.14: {} + callsites@3.1.0: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -1502,8 +2129,27 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + check-error@2.1.3: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + data-uri-to-buffer@4.0.1: {} debug@4.4.3: @@ -1512,6 +2158,8 @@ snapshots: deep-eql@5.0.2: {} + deep-is@0.1.4: {} + deepagents@1.10.5(langsmith@0.7.12(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0))(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0): dependencies: '@langchain/core': 1.2.1(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0) @@ -1565,16 +2213,88 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + escape-string-regexp@4.0.0: {} + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 + esutils@2.0.3: {} + eventemitter3@4.0.7: {} eventemitter3@5.0.4: {} expect-type@1.3.0: {} + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1583,21 +2303,45 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + fast-sha256@1.3.0: {} fastq@1.20.1: dependencies: reusify: 1.1.0 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -1609,8 +2353,29 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@15.15.0: {} + + has-flag@4.0.0: {} + hono@4.12.27: {} + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + is-extglob@2.1.1: {} is-glob@4.0.3: @@ -1621,17 +2386,33 @@ snapshots: is-number@7.0.0: {} + isexe@2.0.0: {} + js-base64@3.7.8: {} js-tiktoken@1.0.21: dependencies: base64-js: 1.5.1 + js-yaml@4.3.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + json-schema-to-ts@3.1.1: dependencies: '@babel/runtime': 7.29.7 ts-algebra: 2.0.0 + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + langchain@1.5.2(@langchain/core@1.2.1(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0))(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0): dependencies: '@langchain/core': 1.2.1(openai@6.45.0(ws@8.21.0)(zod@4.4.3))(ws@8.21.0) @@ -1658,6 +2439,11 @@ snapshots: openai: 6.45.0(ws@8.21.0)(zod@4.4.3) ws: 8.21.0 + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + libsql@0.4.7: dependencies: '@neon-rs/load': 0.0.4 @@ -1671,6 +2457,12 @@ snapshots: '@libsql/linux-x64-musl': 0.4.7 '@libsql/win32-x64-msvc': 0.4.7 + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + loupe@3.2.1: {} magic-string@0.30.21: @@ -1684,12 +2476,22 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.15 + ms@2.1.3: {} mustache@4.2.0: {} nanoid@3.3.15: {} + natural-compare@1.4.0: {} + node-domexception@1.0.0: {} node-fetch@3.3.2: @@ -1703,8 +2505,25 @@ snapshots: ws: 8.21.0 zod: 4.4.3 + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + p-finally@1.0.0: {} + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -1725,6 +2544,14 @@ snapshots: p-timeout@7.0.1: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + pathe@1.1.2: {} pathval@2.0.1: {} @@ -1733,16 +2560,24 @@ snapshots: picomatch@2.3.2: {} + picomatch@4.0.4: {} + postcss@8.5.15: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 source-map-js: 1.2.1 + prelude-ls@1.2.1: {} + promise-limit@2.7.0: {} + punycode@2.3.1: {} + queue-microtask@1.2.3: {} + resolve-from@4.0.0: {} + reusify@1.1.0: {} rollup@4.62.2: @@ -1780,6 +2615,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 + semver@7.8.5: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + siginfo@2.0.0: {} source-map-js@1.2.1: {} @@ -1793,10 +2636,21 @@ snapshots: std-env@3.10.0: {} + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + tinybench@2.9.0: {} tinyexec@0.3.2: {} + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinypool@1.1.1: {} tinyrainbow@1.2.0: {} @@ -1809,10 +2663,33 @@ snapshots: ts-algebra@2.0.0: {} + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.62.0(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.62.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.62.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + typescript@5.9.3: {} undici-types@7.18.2: {} + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + vite-node@2.1.9(@types/node@24.13.2): dependencies: cac: 6.7.14 @@ -1877,13 +2754,21 @@ snapshots: web-streams-polyfill@3.3.3: {} + which@2.0.2: + dependencies: + isexe: 2.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 + word-wrap@1.2.5: {} + ws@8.21.0: {} yaml@2.9.0: {} + yocto-queue@0.1.0: {} + zod@4.4.3: {} diff --git a/scripts/set-version.mjs b/scripts/set-version.mjs index 332267c..7cc362e 100644 --- a/scripts/set-version.mjs +++ b/scripts/set-version.mjs @@ -2,15 +2,15 @@ // Sets ONE version across every app/package/service in the monorepo, plus the // Expo app and the AI sidebar extension. The release tag is the source of truth: // `node scripts/set-version.mjs 0.1.0` (or `pnpm version:set 0.1.0`). -import { readFileSync, writeFileSync, existsSync } from 'node:fs'; -import { readdirSync } from 'node:fs'; -import { join, dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { readFileSync, writeFileSync, existsSync } from "node:fs"; +import { readdirSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; -const root = join(dirname(fileURLToPath(import.meta.url)), '..'); +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); const version = process.argv[2]; if (!version || !/^\d+\.\d+\.\d+/.test(version)) { - console.error('usage: set-version.mjs (e.g. 0.1.0)'); + console.error("usage: set-version.mjs (e.g. 0.1.0)"); process.exit(1); } @@ -18,29 +18,36 @@ const updated = []; function setJson(path, mutate) { if (!existsSync(path)) return; - const json = JSON.parse(readFileSync(path, 'utf8')); + const json = JSON.parse(readFileSync(path, "utf8")); if (mutate(json)) { - writeFileSync(path, JSON.stringify(json, null, 2) + '\n'); - updated.push(path.replace(root + '/', '')); + writeFileSync(path, JSON.stringify(json, null, 2) + "\n"); + updated.push(path.replace(root + "/", "")); } } // Root + every workspace member package.json. -const groups = ['.', 'apps', 'packages', 'services']; -const pkgJsons = [join(root, 'package.json')]; -for (const g of ['apps', 'packages', 'services']) { +const groups = ["apps", "packages", "services"]; +const pkgJsons = [join(root, "package.json")]; +for (const g of groups) { const dir = join(root, g); if (!existsSync(dir)) continue; - for (const name of readdirSync(dir)) pkgJsons.push(join(dir, name, 'package.json')); + for (const name of readdirSync(dir)) + pkgJsons.push(join(dir, name, "package.json")); } -for (const p of pkgJsons) setJson(p, (j) => (j.version = version, true)); +for (const p of pkgJsons) setJson(p, (j) => ((j.version = version), true)); // Expo app + AI sidebar extension carry their own version fields. -setJson(join(root, 'apps/mobile/app.json'), (j) => { - if (j.expo) { j.expo.version = version; return true; } +setJson(join(root, "apps/mobile/app.json"), (j) => { + if (j.expo) { + j.expo.version = version; + return true; + } return false; }); -setJson(join(root, 'apps/desktop/extensions/ai-sidebar/manifest.json'), (j) => (j.version = version, true)); +setJson( + join(root, "apps/desktop/extensions/ai-sidebar/manifest.json"), + (j) => ((j.version = version), true), +); console.log(`Set version ${version} in ${updated.length} files:`); -for (const f of updated) console.log(' ' + f); +for (const f of updated) console.log(" " + f); diff --git a/scripts/submit-packages.mjs b/scripts/submit-packages.mjs index e78385c..db12f59 100644 --- a/scripts/submit-packages.mjs +++ b/scripts/submit-packages.mjs @@ -10,26 +10,43 @@ // the checked-in manifests under distribution/. Actual submission (push to a tap // repo / scoop bucket / AUR / winget-pkgs PR / choco push) is gated on the // relevant secret being present and is intentionally a no-op without it. -import { readFileSync, writeFileSync, existsSync } from 'node:fs'; -import { join, dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { createHash } from 'node:crypto'; +import { readFileSync, writeFileSync, existsSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; +import { createHash } from "node:crypto"; -const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); -const REPO = process.env.TRONBROWSER_REPO || 'profullstack/tronbrowser.dev'; -const ALL = ['homebrew', 'scoop', 'winget', 'aur', 'apt', 'rpm', 'gentoo', 'nix', 'chocolatey', 'snap', 'flatpak', 'appimage', 'freebsd']; +const ROOT = join(dirname(fileURLToPath(import.meta.url)), ".."); +const REPO = process.env.TRONBROWSER_REPO || "profullstack/tronbrowser.dev"; +const ALL = [ + "homebrew", + "scoop", + "winget", + "aur", + "apt", + "rpm", + "gentoo", + "nix", + "chocolatey", + "snap", + "flatpak", + "appimage", + "freebsd", +]; const args = process.argv.slice(2); -let version = ''; +let version = ""; let dryRun = false; const pms = []; for (let i = 0; i < args.length; i++) { - if (args[i] === '-v') version = (args[++i] || '').replace(/^v/, ''); - else if (args[i] === '-p') pms.push(args[++i]); - else if (args[i] === '--dry-run') dryRun = true; + if (args[i] === "-v") version = (args[++i] || "").replace(/^v/, ""); + else if (args[i] === "-p") pms.push(args[++i]); + else if (args[i] === "--dry-run") dryRun = true; } -if (!version) { console.error('usage: submit-packages.mjs -v -p [--dry-run]'); process.exit(1); } -const targets = pms.includes('all') || pms.length === 0 ? ALL : pms; +if (!version) { + console.error("usage: submit-packages.mjs -v -p [--dry-run]"); + process.exit(1); +} +const targets = pms.includes("all") || pms.length === 0 ? ALL : pms; const ASSET = { linux: `tronbrowser-linux-x64.tar.gz`, @@ -42,16 +59,19 @@ async function sha256(asset) { const res = await fetch(url); if (!res.ok) return null; const buf = Buffer.from(await res.arrayBuffer()); - return createHash('sha256').update(buf).digest('hex'); + return createHash("sha256").update(buf).digest("hex"); } function patch(file, replacers) { const path = join(ROOT, file); if (!existsSync(path)) return console.log(` skip (missing): ${file}`); - let s = readFileSync(path, 'utf8'); + let s = readFileSync(path, "utf8"); for (const [re, val] of replacers) s = s.replace(re, val); if (dryRun) console.log(` [dry-run] would update ${file}`); - else { writeFileSync(path, s); console.log(` updated ${file}`); } + else { + writeFileSync(path, s); + console.log(` updated ${file}`); + } } const sums = {}; @@ -60,76 +80,143 @@ for (const [k, a] of Object.entries(ASSET)) sums[k] = await sha256(a); for (const pm of targets) { console.log(`\n== ${pm} ==`); switch (pm) { - case 'homebrew': - patch('distribution/homebrew/tronbrowser.rb', [ + case "homebrew": + patch("distribution/homebrew/tronbrowser.rb", [ [/version "[^"]+"/, `version "${version}"`], - [/download\/v[^/]+\/tronbrowser-macos\.zip/g, `download/v${version}/tronbrowser-macos.zip`], - [/download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, `download/v${version}/tronbrowser-linux-x64.tar.gz`], - ...(sums.macos ? [[/sha256 "[0-9a-f]{64}"\n\n on_linux/, `sha256 "${sums.macos}"\n\n on_linux`]] : []), - ...(sums.linux ? [[/sha256 "[0-9a-f]{64}"\n end\n\n def/, `sha256 "${sums.linux}"\n end\n\n def`]] : []), + [ + /download\/v[^/]+\/tronbrowser-macos\.zip/g, + `download/v${version}/tronbrowser-macos.zip`, + ], + [ + /download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, + `download/v${version}/tronbrowser-linux-x64.tar.gz`, + ], + ...(sums.macos + ? [ + [ + /sha256 "[0-9a-f]{64}"\n{2} {2}on_linux/, + `sha256 "${sums.macos}"\n\n on_linux`, + ], + ] + : []), + ...(sums.linux + ? [ + [ + /sha256 "[0-9a-f]{64}"\n {2}end\n{2} {2}def/, + `sha256 "${sums.linux}"\n end\n\n def`, + ], + ] + : []), ]); break; - case 'aur': - patch('distribution/aur/PKGBUILD', [ + case "aur": + patch("distribution/aur/PKGBUILD", [ [/pkgver=[^\n]+/, `pkgver=${version}`], - ...(sums.linux ? [[/sha256sums=\('[0-9a-f]{64}'\)/, `sha256sums=('${sums.linux}')`]] : []), + ...(sums.linux + ? [[/sha256sums=\('[0-9a-f]{64}'\)/, `sha256sums=('${sums.linux}')`]] + : []), ]); break; - case 'nix': - patch('distribution/nix/tronbrowser.nix', [ + case "nix": + patch("distribution/nix/tronbrowser.nix", [ [/version = "[^"]+"/, `version = "${version}"`], - ...(sums.linux ? [[/sha256 = "[0-9a-f]{64}"/, `sha256 = "${sums.linux}"`]] : []), + ...(sums.linux + ? [[/sha256 = "[0-9a-f]{64}"/, `sha256 = "${sums.linux}"`]] + : []), ]); break; - case 'gentoo': - console.log(` rename distribution/gentoo/tronbrowser-bin-${version}.ebuild and bump SRC_URI (uses \${PV})`); + case "gentoo": + console.log( + ` rename distribution/gentoo/tronbrowser-bin-${version}.ebuild and bump SRC_URI (uses \${PV})`, + ); break; - case 'scoop': - patch('distribution/scoop/tronbrowser.json', [ + case "scoop": + patch("distribution/scoop/tronbrowser.json", [ [/"version": "[^"]+"/, `"version": "${version}"`], - [/download\/v[^/]+\/tronbrowser-win-x64\.zip/g, `download/v${version}/tronbrowser-win-x64.zip`], - ...(sums.windows ? [[/"hash": "[^"]+"/, `"hash": "${sums.windows}"`]] : []), + [ + /download\/v[^/]+\/tronbrowser-win-x64\.zip/g, + `download/v${version}/tronbrowser-win-x64.zip`, + ], + ...(sums.windows + ? [[/"hash": "[^"]+"/, `"hash": "${sums.windows}"`]] + : []), ]); break; - case 'winget': - patch('distribution/winget/Profullstack.TronBrowser.installer.yaml', [ + case "winget": + patch("distribution/winget/Profullstack.TronBrowser.installer.yaml", [ [/PackageVersion: .*/, `PackageVersion: ${version}`], - [/download\/v[^/]+\/tronbrowser-win-x64\.zip/g, `download/v${version}/tronbrowser-win-x64.zip`], - ...(sums.windows ? [[/InstallerSha256: .*/, `InstallerSha256: ${sums.windows.toUpperCase()}`]] : []), + [ + /download\/v[^/]+\/tronbrowser-win-x64\.zip/g, + `download/v${version}/tronbrowser-win-x64.zip`, + ], + ...(sums.windows + ? [ + [ + /InstallerSha256: .*/, + `InstallerSha256: ${sums.windows.toUpperCase()}`, + ], + ] + : []), ]); break; - case 'chocolatey': - patch('distribution/chocolatey/tronbrowser.nuspec', [[/[^<]+<\/version>/, `${version}`]]); - patch('distribution/chocolatey/tools/chocolateyinstall.ps1', [ - [/download\/v[^/]+\/tronbrowser-win-x64\.zip/g, `download/v${version}/tronbrowser-win-x64.zip`], - ...(sums.windows ? [[/checksum64\s+= '[^']+'/, `checksum64 = '${sums.windows}'`]] : []), + case "chocolatey": + patch("distribution/chocolatey/tronbrowser.nuspec", [ + [/[^<]+<\/version>/, `${version}`], + ]); + patch("distribution/chocolatey/tools/chocolateyinstall.ps1", [ + [ + /download\/v[^/]+\/tronbrowser-win-x64\.zip/g, + `download/v${version}/tronbrowser-win-x64.zip`, + ], + ...(sums.windows + ? [[/checksum64\s+= '[^']+'/, `checksum64 = '${sums.windows}'`]] + : []), ]); break; - case 'snap': - patch('distribution/snap/snapcraft.yaml', [ + case "snap": + patch("distribution/snap/snapcraft.yaml", [ [/version: '[^']+'/, `version: '${version}'`], - [/download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, `download/v${version}/tronbrowser-linux-x64.tar.gz`], + [ + /download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, + `download/v${version}/tronbrowser-linux-x64.tar.gz`, + ], ]); break; - case 'flatpak': - patch('distribution/flatpak/dev.tronbrowser.TronBrowser.yml', [ - [/download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, `download/v${version}/tronbrowser-linux-x64.tar.gz`], - ...(sums.linux ? [[/sha256: (__SHA256_LINUX__|[0-9a-f]{64})/, `sha256: ${sums.linux}`]] : []), + case "flatpak": + patch("distribution/flatpak/dev.tronbrowser.TronBrowser.yml", [ + [ + /download\/v[^/]+\/tronbrowser-linux-x64\.tar\.gz/g, + `download/v${version}/tronbrowser-linux-x64.tar.gz`, + ], + ...(sums.linux + ? [ + [ + /sha256: (__SHA256_LINUX__|[0-9a-f]{64})/, + `sha256: ${sums.linux}`, + ], + ] + : []), ]); break; - case 'freebsd': - patch('distribution/freebsd/Makefile', [[/DISTVERSION=\t[^\n]+/, `DISTVERSION=\t${version}`]]); + case "freebsd": + patch("distribution/freebsd/Makefile", [ + [/DISTVERSION=\t[^\n]+/, `DISTVERSION=\t${version}`], + ]); break; - case 'apt': - case 'rpm': - console.log(` built by distribution/deb-rpm/build.sh (nfpm) during release; nothing to template`); + case "apt": + case "rpm": + console.log( + ` built by distribution/deb-rpm/build.sh (nfpm) during release; nothing to template`, + ); break; - case 'appimage': - console.log(` built by distribution/appimage/build.sh during release; attached to the GitHub release`); + case "appimage": + console.log( + ` built by distribution/appimage/build.sh during release; attached to the GitHub release`, + ); break; default: console.log(` unknown package manager: ${pm}`); } } -console.log(`\nDone (${dryRun ? 'dry run' : 'manifests updated'}).`); +console.log(`\nDone (${dryRun ? "dry run" : "manifests updated"}).`); diff --git a/services/api/package.json b/services/api/package.json index 062b587..dc2d7d6 100644 --- a/services/api/package.json +++ b/services/api/package.json @@ -9,7 +9,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] api: stub\"", + "lint": "eslint src", "start": "node dist/index.js", "migrate": "node ../../scripts/db-migrate.mjs" }, diff --git a/services/scheduler/package.json b/services/scheduler/package.json index 0b471fd..3d09d69 100644 --- a/services/scheduler/package.json +++ b/services/scheduler/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] scheduler: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/services/sync-server/package.json b/services/sync-server/package.json index 7f325c4..88c9acc 100644 --- a/services/sync-server/package.json +++ b/services/sync-server/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] sync-server: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3", diff --git a/services/worker/package.json b/services/worker/package.json index 49b79a3..efcc43c 100644 --- a/services/worker/package.json +++ b/services/worker/package.json @@ -16,7 +16,7 @@ "build": "tsc -p tsconfig.json", "typecheck": "tsc -p tsconfig.json --noEmit", "test": "vitest run --passWithNoTests", - "lint": "echo \"[lint] worker: stub\"" + "lint": "eslint src" }, "devDependencies": { "typescript": "^5.6.3",