diff --git a/docs/mdx-components.tsx b/docs/mdx-components.tsx new file mode 100644 index 0000000..0c1120f --- /dev/null +++ b/docs/mdx-components.tsx @@ -0,0 +1,83 @@ +import type { MDXComponents } from "mdx/types"; +import Link from "next/link"; +import { CodeBlock } from "@/components/code-block"; + +function slugify(text: string): string { + return text + .toLowerCase() + .replace(/[^\w\s-]/g, "") + .replace(/\s+/g, "-") + .trim(); +} + +function extractText(children: React.ReactNode): string { + if (typeof children === "string") return children; + if (typeof children === "number") return String(children); + if (Array.isArray(children)) return children.map(extractText).join(""); + if (children && typeof children === "object") { + const obj = children as unknown as Record; + if ("props" in obj) { + const props = obj.props as { children?: React.ReactNode } | undefined; + return extractText(props?.children); + } + } + return ""; +} + +export function useMDXComponents(components: MDXComponents): MDXComponents { + return { + ...components, + h2: ({ children }: { children?: React.ReactNode }) => { + const id = slugify(extractText(children)); + return

{children}

; + }, + h3: ({ children }: { children?: React.ReactNode }) => { + const id = slugify(extractText(children)); + return

{children}

; + }, + a: ({ + href, + children, + }: { + href?: string; + children?: React.ReactNode; + }) => { + if (href?.startsWith("/")) { + return {children}; + } + return ( + + {children} + + ); + }, + code: ({ + children, + className, + }: { + children?: React.ReactNode; + className?: string; + }) => { + if (className) { + return {children}; + } + return {children}; + }, + pre: async ({ children }: { children?: React.ReactNode }) => { + const codeElement = children as React.ReactElement<{ + className?: string; + children?: string; + }>; + const className = codeElement?.props?.className || ""; + const lang = className.replace("language-", "") || "bash"; + const code = codeElement?.props?.children || ""; + + return ( + + ); + }, + }; +} diff --git a/docs/next.config.mjs b/docs/next.config.mjs new file mode 100644 index 0000000..75ba345 --- /dev/null +++ b/docs/next.config.mjs @@ -0,0 +1,10 @@ +import createMDX from "@next/mdx"; + +/** @type {import('next').NextConfig} */ +const nextConfig = { + pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"], +}; + +const withMDX = createMDX({}); + +export default withMDX(nextConfig); diff --git a/docs/next.config.ts b/docs/next.config.ts deleted file mode 100644 index e9ffa30..0000000 --- a/docs/next.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = { - /* config options here */ -}; - -export default nextConfig; diff --git a/docs/package.json b/docs/package.json index e0c31c2..62a3f17 100644 --- a/docs/package.json +++ b/docs/package.json @@ -9,13 +9,26 @@ "lint": "eslint" }, "dependencies": { + "@ai-sdk/react": "^3.0.80", + "@mdx-js/loader": "^3.1.1", + "@mdx-js/mdx": "^3.1.1", + "@mdx-js/react": "^3.1.1", + "@next/mdx": "^16.1.6", + "@upstash/ratelimit": "^2.0.8", + "@upstash/redis": "^1.36.2", + "ai": "^6.0.78", + "bash-tool": "^1.3.14", + "just-bash": "^2.9.6", "next": "16.1.1", + "next-themes": "^0.4.6", "react": "19.2.3", "react-dom": "19.2.3", - "shiki": "^3.21.0" + "shiki": "^3.21.0", + "streamdown": "^2.1.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", + "@types/mdx": "^2.0.13", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 1d5efef..2ee0229 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -8,9 +8,42 @@ importers: .: dependencies: + '@ai-sdk/react': + specifier: ^3.0.80 + version: 3.0.80(react@19.2.3)(zod@4.3.5) + '@mdx-js/loader': + specifier: ^3.1.1 + version: 3.1.1 + '@mdx-js/mdx': + specifier: ^3.1.1 + version: 3.1.1 + '@mdx-js/react': + specifier: ^3.1.1 + version: 3.1.1(@types/react@19.2.8)(react@19.2.3) + '@next/mdx': + specifier: ^16.1.6 + version: 16.1.6(@mdx-js/loader@3.1.1)(@mdx-js/react@3.1.1(@types/react@19.2.8)(react@19.2.3)) + '@upstash/ratelimit': + specifier: ^2.0.8 + version: 2.0.8(@upstash/redis@1.36.2) + '@upstash/redis': + specifier: ^1.36.2 + version: 1.36.2 + ai: + specifier: ^6.0.78 + version: 6.0.78(zod@4.3.5) + bash-tool: + specifier: ^1.3.14 + version: 1.3.14(ai@6.0.78(zod@4.3.5))(just-bash@2.9.6) + just-bash: + specifier: ^2.9.6 + version: 2.9.6 next: specifier: 16.1.1 - version: 16.1.1(@babel/core@7.28.6)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + version: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: specifier: 19.2.3 version: 19.2.3 @@ -20,10 +53,16 @@ importers: shiki: specifier: ^3.21.0 version: 3.21.0 + streamdown: + specifier: ^2.1.0 + version: 2.1.0(react@19.2.3) devDependencies: '@tailwindcss/postcss': specifier: ^4 version: 4.1.18 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 '@types/node': specifier: ^20 version: 20.19.28 @@ -48,6 +87,28 @@ importers: packages: + '@ai-sdk/gateway@3.0.39': + resolution: {integrity: sha512-SeCZBAdDNbWpVUXiYgOAqis22p5MEYfrjRw0hiBa5hM+7sDGYQpMinUjkM8kbPXMkY+AhKLrHleBl+SuqpzlgA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.14': + resolution: {integrity: sha512-7bzKd9lgiDeXM7O4U4nQ8iTxguAOkg8LZGD9AfDVZYjO5cKYRwBPwVjboFcVrxncRHu0tYxZtXZtiLKpG4pEng==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@3.0.8': + resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} + engines: {node: '>=18'} + + '@ai-sdk/react@3.0.80': + resolution: {integrity: sha512-ERdj1fxRYiYX2xyy2lIahdcnrdbZ5/Xi/LSFiCU6wGISrFmtYiSkILUaBX4YtDYgqMdRIuyOl9+rkrwwo9l0ZQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -119,6 +180,9 @@ packages: resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} + '@borewit/text-codec@0.2.1': + resolution: {integrity: sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==} + '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} @@ -319,6 +383,14 @@ packages: cpu: [x64] os: [win32] + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.1': + resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} + engines: {node: 20 || >=22} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -335,6 +407,30 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@mdx-js/loader@3.1.1': + resolution: {integrity: sha512-0TTacJyZ9mDmY+VefuthVshaNIyCGZHJG2fMnGaDttCt8HmjUF7SizlHJpaCDoGnN635nK1wpzfpx/Xx5S4WnQ==} + peerDependencies: + webpack: '>=5' + peerDependenciesMeta: + webpack: + optional: true + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + + '@mongodb-js/zstd@7.0.0': + resolution: {integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==} + engines: {node: '>= 20.19.0'} + '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -344,6 +440,17 @@ packages: '@next/eslint-plugin-next@16.1.1': resolution: {integrity: sha512-Ovb/6TuLKbE1UiPcg0p39Ke3puyTCIKN9hGbNItmpQsp+WX3qrjO3WaMVSi6JHr9X1NrmthqIguVHodMJbh/dw==} + '@next/mdx@16.1.6': + resolution: {integrity: sha512-PT5JR4WPPYOls7WD6xEqUVVI9HDY8kY7XLQsNYB2lSZk5eJSXWu3ECtIYmfR0hZpx8Sg7BKZYKi2+u5OTSEx0w==} + peerDependencies: + '@mdx-js/loader': '>=0.15.0' + '@mdx-js/react': '>=0.15.0' + peerDependenciesMeta: + '@mdx-js/loader': + optional: true + '@mdx-js/react': + optional: true + '@next/swc-darwin-arm64@16.1.1': resolution: {integrity: sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA==} engines: {node: '>= 10'} @@ -408,6 +515,10 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -432,6 +543,9 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -523,9 +637,22 @@ packages: '@tailwindcss/postcss@4.1.18': resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==} + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -541,6 +668,12 @@ packages: '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@20.19.28': resolution: {integrity: sha512-VyKBr25BuFDzBFCK5sUM6ZXiWfqgCTwTAOK8qzGV/m9FCirXYDlmczJ+d5dXBAQALGCdRRdbteKYfJ84NGEusw==} @@ -552,6 +685,9 @@ packages: '@types/react@19.2.8': resolution: {integrity: sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -712,6 +848,22 @@ packages: cpu: [x64] os: [win32] + '@upstash/core-analytics@0.0.10': + resolution: {integrity: sha512-7qJHGxpQgQr9/vmeS1PktEwvNAF7TI4iJDi8Pu2CFZ9YUGHZH4fOP5TfYlZ4aVxfopnELiE4BS4FBjyK7V1/xQ==} + engines: {node: '>=16.0.0'} + + '@upstash/ratelimit@2.0.8': + resolution: {integrity: sha512-YSTMBJ1YIxsoPkUMX/P4DDks/xV5YYCswWMamU8ZIfK9ly6ppjRnVOyBhMDXBmzjODm4UQKcxsJPvaeFAijp5w==} + peerDependencies: + '@upstash/redis': ^1.34.3 + + '@upstash/redis@1.36.2': + resolution: {integrity: sha512-C0Yt8hc12vLaQYRG1fMci8iPrLtnTdbJG0HR5T8vKnvEP/1RdMMblsOJs5/jp0JXZJ1oSzMnQz4J9EVezNpI6A==} + + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + engines: {node: '>= 20'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -722,13 +874,26 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + ai@6.0.78: + resolution: {integrity: sha512-eriIX/NLWfWNDeE/OJy8wmIp9fyaH7gnxTOCPT5bp0MNkvORstp1TwRUql9au8XjXzH7o2WApqbwgxJDDV0Rbw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -771,6 +936,10 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} @@ -787,13 +956,35 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.9.14: resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true + bash-tool@1.3.14: + resolution: {integrity: sha512-M4D+ai/uk684FAIaHJUyt01SvS9AqR1sgQEFv9ZmBaunmIdJWdrycxDTQL921dvB8vyYNhitHH/tJF8eScsltA==} + engines: {node: '>=18'} + peerDependencies: + '@vercel/sandbox': '*' + ai: ^6.0.0 + just-bash: ^2.9.3 + peerDependenciesMeta: + '@vercel/sandbox': + optional: true + just-bash: + optional: true + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -809,6 +1000,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -841,9 +1035,25 @@ packages: character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -854,6 +1064,14 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@2.8.1: + resolution: {integrity: sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==} + engines: {node: '>= 0.6.x'} + + compressjs@1.0.3: + resolution: {integrity: sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==} + hasBin: true + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -899,6 +1117,17 @@ packages: supports-color: optional: true + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -921,6 +1150,10 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} + engines: {node: '>=0.3.1'} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -935,10 +1168,17 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.18.4: resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} engines: {node: '>=10.13.0'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + es-abstract@1.24.1: resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} engines: {node: '>= 0.4'} @@ -971,6 +1211,12 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -979,6 +1225,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-config-next@16.1.1: resolution: {integrity: sha512-55nTpVWm3qeuxoQKLOjQVciKZJUphKrNM0fCcQHAIOGl6VFXgaqeMfv0aKJhs7QtcnlAPhNVqsqRfRjeKBPIUA==} peerDependencies: @@ -1079,6 +1329,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -1091,10 +1346,46 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + 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'} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1102,12 +1393,20 @@ packages: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} + 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-xml-parser@5.3.5: + resolution: {integrity: sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==} + hasBin: true + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -1124,6 +1423,10 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@21.3.0: + resolution: {integrity: sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==} + engines: {node: '>=20'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1143,6 +1446,9 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -1176,6 +1482,9 @@ packages: get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1203,6 +1512,13 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graceful-readlink@1.0.1: + resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -1230,21 +1546,51 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-sanitize@5.0.2: + resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + hast-util-to-html@9.0.5: resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hermes-estree@0.25.1: resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1261,10 +1607,29 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -1300,6 +1665,13 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1316,6 +1688,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -1332,6 +1707,10 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -1385,6 +1764,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -1400,6 +1783,9 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -1416,9 +1802,17 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + just-bash@2.9.6: + resolution: {integrity: sha512-DYYJvuLt3ygZCZW7hrE7wAxyL/VyXjwqGA1EyXKRZbIsfXGLkgUF/00ATHcH2qg4vP2CG9WKqpGiduHMf80nFg==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -1507,6 +1901,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1517,36 +1914,191 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@17.0.1: + resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==} + engines: {node: '>= 20'} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@13.2.1: resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + micromark-util-character@2.1.1: resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + micromark-util-encode@2.0.1: resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + micromark-util-sanitize-uri@2.0.1: resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + micromark-util-symbol@2.0.1: resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} micromark-util-types@2.0.2: resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@10.1.2: + resolution: {integrity: sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1557,6 +2109,13 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + modern-tar@0.7.3: + resolution: {integrity: sha512-4W79zekKGyYU4JXVmB78DOscMFaJth2gGhgfTl2alWE4rNe3nf4N2pqenQ0rEtIewrnD79M687Ouba3YGTLOvg==} + engines: {node: '>=18.0.0'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1565,6 +2124,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + napi-postinstall@0.3.4: resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1573,6 +2135,12 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + next@16.1.1: resolution: {integrity: sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w==} engines: {node: '>=20.9.0'} @@ -1594,6 +2162,23 @@ packages: sass: optional: true + node-abi@3.87.0: + resolution: {integrity: sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==} + engines: {node: '>=10'} + + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + engines: {node: ^18 || ^20 || >= 21} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-liblzma@2.2.0: + resolution: {integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==} + engines: {node: '>=16.0.0'} + hasBin: true + node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -1629,6 +2214,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} @@ -1651,10 +2239,19 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + papaparse@5.5.3: + resolution: {integrity: sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1689,6 +2286,11 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + hasBin: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1699,13 +2301,27 @@ packages: property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pyodide@0.27.7: + resolution: {integrity: sha512-RUSVJlhQdfWfgO9hVHCiXoG+nVZQRS5D9FzgpLJ/VcgGBLSAKoPL8kTiOikxbHQm1kRISeWUBdulEgO26qpSRA==} + engines: {node: '>=18.0.0'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + re2js@1.2.1: + resolution: {integrity: sha512-pMQCWm/GsGambkqCl0l02SZUUd5yQ4u8D72K90TJWHMALuYg8BWCdcfXdXIvEQYGEM8K9QrxYAFtVgeQ+LZKFw==} + react-dom@19.2.3: resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} peerDependencies: @@ -1718,6 +2334,24 @@ packages: resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -1735,6 +2369,36 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + rehype-harden@1.1.7: + resolution: {integrity: sha512-j5DY0YSK2YavvNGV+qBHma15J9m0WZmRe8posT5AtKDS6TNWtMVTo6RiqF8SidfcASYz8f3k2J/1RWmq5zTXUw==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-sanitize@6.0.0: + resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remend@1.1.0: + resolution: {integrity: sha512-JENGyuIhTwzUfCarW43X4r9cehoqTo9QyYxfNDZSud2AmqeuWjZ5pfybasTa4q0dxTJAj5m8NB+wR+YueAFpxQ==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1762,6 +2426,9 @@ packages: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -1773,6 +2440,10 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -1825,13 +2496,36 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + smol-toml@1.6.0: + resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + sql.js@1.13.0: + resolution: {integrity: sha512-RJbVP1HRDlUUXahJ7VMTcu9Rm1Nzw+EBpoPr94vnbD4LwR715F3CcxE2G2k45PewcaZ57pjetYa+LoSJLAASgA==} + stable-hash@0.0.5: resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} @@ -1839,6 +2533,11 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + streamdown@2.1.0: + resolution: {integrity: sha512-u9gWd0AmjKg1d+74P44XaPlGrMeC21oDOSIhjGNEYMAttDMzCzlJO6lpTyJ9JkSinQQF65YcK4eOd3q9iTvULw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + string.prototype.includes@2.0.1: resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} engines: {node: '>= 0.4'} @@ -1862,17 +2561,41 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strnum@2.1.2: + resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + engines: {node: '>=18'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + styled-jsx@5.1.6: resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} @@ -1894,6 +2617,14 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swr@2.4.0: + resolution: {integrity: sha512-sUlC20T8EOt1pHmDiqueUWMmRRX03W7w5YxovWX7VR2KHEPCTMly85x05vpkP5i6Bu4h44ePSMD9Tc+G2MItFw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + tailwindcss@4.1.18: resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} @@ -1901,6 +2632,17 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + throttleit@2.1.0: + resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -1909,9 +2651,16 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} @@ -1924,6 +2673,12 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + turndown@7.2.2: + resolution: {integrity: sha512-1F7db8BiExOKxjSMU2b7if62D/XOyQyZbPKq/nUwopfgnHlqXHqQ0lvfUTeUIr1lZJzOPFn43dODyMSIfvWRKQ==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -1956,16 +2711,29 @@ packages: engines: {node: '>=14.17'} hasBin: true + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unist-util-is@6.0.1: resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} @@ -1990,12 +2758,26 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -2021,9 +2803,29 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2034,6 +2836,9 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.3.5: resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} @@ -2042,6 +2847,34 @@ packages: snapshots: + '@ai-sdk/gateway@3.0.39(zod@4.3.5)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) + '@vercel/oidc': 3.1.0 + zod: 4.3.5 + + '@ai-sdk/provider-utils@4.0.14(zod@4.3.5)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.6 + zod: 4.3.5 + + '@ai-sdk/provider@3.0.8': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/react@3.0.80(react@19.2.3)(zod@4.3.5)': + dependencies: + '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) + ai: 6.0.78(zod@4.3.5) + react: 19.2.3 + swr: 2.4.0(react@19.2.3) + throttleit: 2.1.0 + transitivePeerDependencies: + - zod + '@alloc/quick-lru@5.2.0': {} '@babel/code-frame@7.28.6': @@ -2144,6 +2977,8 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@borewit/text-codec@0.2.1': {} + '@emnapi/core@1.8.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -2314,6 +3149,12 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.1': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -2333,6 +3174,57 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@mdx-js/loader@3.1.1': + dependencies: + '@mdx-js/mdx': 3.1.1 + source-map: 0.7.6 + transitivePeerDependencies: + - supports-color + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.8)(react@19.2.3)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.8 + react: 19.2.3 + + '@mixmark-io/domino@2.2.0': {} + + '@mongodb-js/zstd@7.0.0': + dependencies: + node-addon-api: 8.5.0 + prebuild-install: 7.1.3 + optional: true + '@napi-rs/wasm-runtime@0.2.12': dependencies: '@emnapi/core': 1.8.1 @@ -2346,6 +3238,13 @@ snapshots: dependencies: fast-glob: 3.3.1 + '@next/mdx@16.1.6(@mdx-js/loader@3.1.1)(@mdx-js/react@3.1.1(@types/react@19.2.8)(react@19.2.3))': + dependencies: + source-map: 0.7.6 + optionalDependencies: + '@mdx-js/loader': 3.1.1 + '@mdx-js/react': 3.1.1(@types/react@19.2.8)(react@19.2.3) + '@next/swc-darwin-arm64@16.1.1': optional: true @@ -2384,6 +3283,8 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} + '@opentelemetry/api@1.9.0': {} + '@rtsao/scc@1.1.0': {} '@shikijs/core@3.21.0': @@ -2419,6 +3320,8 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@standard-schema/spec@1.1.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -2492,11 +3395,28 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.18 + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 optional: true + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + '@types/estree@1.0.8': {} '@types/hast@3.0.4': @@ -2511,6 +3431,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + '@types/node@20.19.28': dependencies: undici-types: 6.21.0 @@ -2523,6 +3447,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/unist@2.0.11': {} + '@types/unist@3.0.3': {} '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': @@ -2677,12 +3603,35 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + '@upstash/core-analytics@0.0.10': + dependencies: + '@upstash/redis': 1.36.2 + + '@upstash/ratelimit@2.0.8(@upstash/redis@1.36.2)': + dependencies: + '@upstash/core-analytics': 0.0.10 + '@upstash/redis': 1.36.2 + + '@upstash/redis@1.36.2': + dependencies: + uncrypto: 0.1.3 + + '@vercel/oidc@3.1.0': {} + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 acorn@8.15.0: {} + ai@6.0.78(zod@4.3.5): + dependencies: + '@ai-sdk/gateway': 3.0.39(zod@4.3.5) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) + '@opentelemetry/api': 1.9.0 + zod: 4.3.5 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -2690,10 +3639,16 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + amdefine@1.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} aria-query@5.3.2: {} @@ -2767,6 +3722,8 @@ snapshots: ast-types-flow@0.0.8: {} + astring@1.9.0: {} + async-function@1.0.0: {} available-typed-arrays@1.0.7: @@ -2777,10 +3734,31 @@ snapshots: axobject-query@4.1.0: {} + bail@2.0.2: {} + balanced-match@1.0.2: {} + base64-js@1.5.1: + optional: true + baseline-browser-mapping@2.9.14: {} + bash-tool@1.3.14(ai@6.0.78(zod@4.3.5))(just-bash@2.9.6): + dependencies: + ai: 6.0.78(zod@4.3.5) + fast-glob: 3.3.3 + gray-matter: 4.0.3 + zod: 3.25.76 + optionalDependencies: + just-bash: 2.9.6 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -2802,6 +3780,12 @@ snapshots: node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + optional: true + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -2834,8 +3818,19 @@ snapshots: character-entities-legacy@3.0.0: {} + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chownr@1.1.4: + optional: true + client-only@0.0.1: {} + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2844,6 +3839,15 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@2.8.1: + dependencies: + graceful-readlink: 1.0.1 + + compressjs@1.0.3: + dependencies: + amdefine: 1.0.1 + commander: 2.8.1 + concat-map@0.0.1: {} convert-source-map@2.0.0: {} @@ -2884,6 +3888,18 @@ snapshots: dependencies: ms: 2.1.3 + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + optional: true + + deep-extend@0.6.0: + optional: true + deep-is@0.1.4: {} define-data-property@1.1.4: @@ -2906,6 +3922,8 @@ snapshots: dependencies: dequal: 2.0.3 + diff@8.0.3: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -2920,11 +3938,18 @@ snapshots: emoji-regex@9.2.2: {} + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + enhanced-resolve@5.18.4: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 + entities@6.0.1: {} + es-abstract@1.24.1: dependencies: array-buffer-byte-length: 1.0.2 @@ -3026,10 +4051,26 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-config-next@16.1.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 16.1.1 @@ -3221,6 +4262,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -3231,8 +4274,52 @@ snapshots: estraverse@5.3.0: {} + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} + eventsource-parser@3.0.6: {} + + expand-template@2.0.3: + optional: true + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.1: @@ -3243,10 +4330,22 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} + fast-xml-parser@5.3.5: + dependencies: + strnum: 2.1.2 + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -3259,6 +4358,15 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-type@21.3.0: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.3.4 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -3279,6 +4387,9 @@ snapshots: dependencies: is-callable: 1.2.7 + fs-constants@1.0.0: + optional: true + function-bind@1.1.2: {} function.prototype.name@1.1.8: @@ -3324,6 +4435,9 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + github-from-package@0.0.0: + optional: true + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3345,6 +4459,15 @@ snapshots: graceful-fs@4.2.11: {} + graceful-readlink@1.0.1: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -3367,6 +4490,64 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-sanitize@5.0.2: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + unist-util-position: 5.0.0 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + hast-util-to-html@9.0.5: dependencies: '@types/hast': 3.0.4 @@ -3381,18 +4562,60 @@ snapshots: stringify-entities: 4.0.4 zwitch: 2.0.4 + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + hast-util-whitespace@3.0.0: dependencies: '@types/hast': 3.0.4 + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + hermes-estree@0.25.1: {} hermes-parser@0.25.1: dependencies: hermes-estree: 0.25.1 + html-url-attributes@3.0.1: {} + html-void-elements@3.0.0: {} + ieee754@1.2.1: {} + ignore@5.3.2: {} ignore@7.0.5: {} @@ -3404,12 +4627,29 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: + optional: true + + ini@1.3.8: + optional: true + + ini@6.0.0: {} + + inline-style-parser@0.2.7: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.1.0 + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -3454,6 +4694,10 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.1.1: @@ -3472,6 +4716,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-map@2.0.3: {} is-negative-zero@2.0.3: {} @@ -3483,6 +4729,8 @@ snapshots: is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -3539,6 +4787,11 @@ snapshots: js-tokens@4.0.0: {} + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -3549,6 +4802,8 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema@0.4.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: @@ -3564,10 +4819,37 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + just-bash@2.9.6: + dependencies: + compressjs: 1.0.3 + diff: 8.0.3 + fast-xml-parser: 5.3.5 + file-type: 21.3.0 + ini: 6.0.0 + minimatch: 10.1.2 + modern-tar: 0.7.3 + papaparse: 5.5.3 + pyodide: 0.27.7 + re2js: 1.2.1 + smol-toml: 1.6.0 + sprintf-js: 1.1.3 + sql.js: 1.13.0 + turndown: 7.2.2 + yaml: 2.8.2 + optionalDependencies: + '@mongodb-js/zstd': 7.0.0 + node-liblzma: 2.2.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + kind-of@6.0.3: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -3634,6 +4916,8 @@ snapshots: lodash.merge@4.6.2: {} + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3646,8 +4930,149 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + marked@17.0.1: {} + math-intrinsics@1.1.0: {} + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 @@ -3660,30 +5085,300 @@ snapshots: unist-util-visit: 5.0.0 vfile: 6.0.3 + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-encode@2.0.1: {} + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + micromark-util-sanitize-uri@2.0.1: dependencies: micromark-util-character: 2.1.1 micromark-util-encode: 2.0.1 micromark-util-symbol: 2.0.1 + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-symbol@2.0.1: {} micromark-util-types@2.0.2: {} + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 + mimic-response@3.1.0: + optional: true + + minimatch@10.1.2: + dependencies: + '@isaacs/brace-expansion': 5.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -3694,15 +5389,28 @@ snapshots: minimist@1.2.8: {} + mkdirp-classic@0.5.3: + optional: true + + modern-tar@0.7.3: {} + ms@2.1.3: {} nanoid@3.3.11: {} + napi-build-utils@2.0.0: + optional: true + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} - next@16.1.1(@babel/core@7.28.6)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + next-themes@0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: '@next/env': 16.1.1 '@swc/helpers': 0.5.15 @@ -3721,11 +5429,29 @@ snapshots: '@next/swc-linux-x64-musl': 16.1.1 '@next/swc-win32-arm64-msvc': 16.1.1 '@next/swc-win32-x64-msvc': 16.1.1 + '@opentelemetry/api': 1.9.0 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + node-abi@3.87.0: + dependencies: + semver: 7.7.3 + optional: true + + node-addon-api@8.5.0: + optional: true + + node-gyp-build@4.8.4: + optional: true + + node-liblzma@2.2.0: + dependencies: + node-addon-api: 8.5.0 + node-gyp-build: 4.8.4 + optional: true + node-releases@2.0.27: {} object-assign@4.1.1: {} @@ -3770,6 +5496,11 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optional: true + oniguruma-parser@0.12.1: {} oniguruma-to-es@4.3.4: @@ -3801,10 +5532,26 @@ snapshots: dependencies: p-limit: 3.1.0 + papaparse@5.5.3: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -3831,6 +5578,22 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.87.0 + pump: 3.0.3 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + optional: true + prelude-ls@1.2.1: {} prop-types@15.8.1: @@ -3841,10 +5604,33 @@ snapshots: property-information@7.1.0: {} + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + optional: true + punycode@2.3.1: {} + pyodide@0.27.7: + dependencies: + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + queue-microtask@1.2.3: {} + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + + re2js@1.2.1: {} + react-dom@19.2.3(react@19.2.3): dependencies: react: 19.2.3 @@ -3854,6 +5640,42 @@ snapshots: react@19.2.3: {} + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + optional: true + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -3884,6 +5706,72 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + rehype-harden@1.1.7: + dependencies: + unist-util-visit: 5.0.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-sanitize@6.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-sanitize: 5.0.2 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remend@1.1.0: {} + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -3914,6 +5802,9 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 + safe-buffer@5.2.1: + optional: true + safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -3927,6 +5818,11 @@ snapshots: scheduler@0.27.0: {} + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + semver@6.3.1: {} semver@7.7.3: {} @@ -4030,10 +5926,30 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + simple-concat@1.0.1: + optional: true + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + optional: true + + smol-toml@1.6.0: {} + source-map-js@1.2.1: {} + source-map@0.7.6: {} + space-separated-tokens@2.0.2: {} + sprintf-js@1.0.3: {} + + sprintf-js@1.1.3: {} + + sql.js@1.13.0: {} + stable-hash@0.0.5: {} stop-iteration-iterator@1.1.0: @@ -4041,6 +5957,26 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + streamdown@2.1.0(react@19.2.3): + dependencies: + clsx: 2.1.1 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + marked: 17.0.1 + react: 19.2.3 + rehype-harden: 1.1.7 + rehype-raw: 7.0.0 + rehype-sanitize: 6.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remend: 1.1.0 + tailwind-merge: 3.4.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + transitivePeerDependencies: + - supports-color + string.prototype.includes@2.0.1: dependencies: call-bind: 1.0.8 @@ -4091,15 +6027,39 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + strip-bom-string@1.0.0: {} + strip-bom@3.0.0: {} + strip-json-comments@2.0.1: + optional: true + strip-json-comments@3.1.1: {} + strnum@2.1.2: {} + + strtok3@10.3.4: + dependencies: + '@tokenizer/token': 0.3.0 + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + styled-jsx@5.1.6(@babel/core@7.28.6)(react@19.2.3): dependencies: client-only: 0.0.1 @@ -4113,10 +6073,37 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swr@2.4.0(react@19.2.3): + dependencies: + dequal: 2.0.3 + react: 19.2.3 + use-sync-external-store: 1.6.0(react@19.2.3) + + tailwind-merge@3.4.0: {} + tailwindcss@4.1.18: {} tapable@2.3.0: {} + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.3 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + throttleit@2.1.0: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -4126,8 +6113,16 @@ snapshots: dependencies: is-number: 7.0.0 + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.1 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + trim-lines@3.0.1: {} + trough@2.2.0: {} + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -4141,6 +6136,15 @@ snapshots: tslib@2.8.1: {} + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + turndown@7.2.2: + dependencies: + '@mixmark-io/domino': 2.2.0 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -4191,6 +6195,8 @@ snapshots: typescript@5.9.3: {} + uint8array-extras@1.5.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -4198,12 +6204,28 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + uncrypto@0.1.3: {} + undici-types@6.21.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + unist-util-is@6.0.1: dependencies: '@types/unist': 3.0.3 + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-position@5.0.0: dependencies: '@types/unist': 3.0.3 @@ -4257,6 +6279,18 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.3): + dependencies: + react: 19.2.3 + + util-deprecate@1.0.2: + optional: true + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -4267,6 +6301,8 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + web-namespaces@2.0.1: {} + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -4314,14 +6350,23 @@ snapshots: word-wrap@1.2.5: {} + wrappy@1.0.2: + optional: true + + ws@8.19.0: {} + yallist@3.1.1: {} + yaml@2.8.2: {} + yocto-queue@0.1.0: {} zod-validation-error@4.0.2(zod@4.3.5): dependencies: zod: 4.3.5 + zod@3.25.76: {} + zod@4.3.5: {} zwitch@2.0.4: {} diff --git a/docs/src/app/api/docs-chat/route.ts b/docs/src/app/api/docs-chat/route.ts new file mode 100644 index 0000000..cddfb12 --- /dev/null +++ b/docs/src/app/api/docs-chat/route.ts @@ -0,0 +1,115 @@ +import { readFile } from "fs/promises"; +import { join } from "path"; +import { convertToModelMessages, stepCountIs, streamText } from "ai"; +import type { ModelMessage, UIMessage } from "ai"; +import { createBashTool } from "bash-tool"; +import { headers } from "next/headers"; +import { allDocsPages } from "@/lib/docs-navigation"; +import { mdxToCleanMarkdown } from "@/lib/mdx-to-markdown"; +import { minuteRateLimit, dailyRateLimit } from "@/lib/rate-limit"; + +export const maxDuration = 60; + +const DEFAULT_MODEL = "anthropic/claude-haiku-4.5"; + +const SYSTEM_PROMPT = `You are a helpful documentation assistant for agent-browser, a headless browser automation CLI designed for AI agents. + +GitHub repository: https://github.com/vercel-labs/agent-browser +Documentation: https://agent-browser.dev +npm package: agent-browser + +You have access to the full agent-browser documentation via the bash and readFile tools. The docs are available as markdown files in the /workspace/ directory. + +When answering questions: +- Use the bash tool to list files (ls /workspace/) or search for content (grep -r "keyword" /workspace/) +- Use the readFile tool to read specific documentation pages (e.g. readFile with path "/workspace/index.md") +- Always base your answers on the actual documentation content +- Be concise and accurate +- If the docs don't cover a topic, say so honestly +- Do NOT include source references or file paths in your response`; + +async function loadDocsFiles(): Promise> { + const files: Record = {}; + + const results = await Promise.allSettled( + allDocsPages.map(async (page) => { + const slug = page.href === "/" ? "" : page.href.replace(/^\//, ""); + const filePath = slug + ? join(process.cwd(), "src", "app", slug, "page.mdx") + : join(process.cwd(), "src", "app", "page.mdx"); + + const raw = await readFile(filePath, "utf-8"); + const md = mdxToCleanMarkdown(raw); + const fileName = slug ? `/${slug}.md` : "/index.md"; + return { fileName, md }; + }), + ); + + for (const result of results) { + if (result.status === "fulfilled") { + files[result.value.fileName] = result.value.md; + } + } + + return files; +} + +function addCacheControl(messages: ModelMessage[]): ModelMessage[] { + if (messages.length === 0) return messages; + return messages.map((message, index) => { + if (index === messages.length - 1) { + return { + ...message, + providerOptions: { + ...message.providerOptions, + anthropic: { cacheControl: { type: "ephemeral" } }, + }, + }; + } + return message; + }); +} + +export async function POST(req: Request) { + const headersList = await headers(); + const ip = headersList.get("x-forwarded-for")?.split(",")[0] ?? "anonymous"; + + const [minuteResult, dailyResult] = await Promise.all([ + minuteRateLimit.limit(ip), + dailyRateLimit.limit(ip), + ]); + + if (!minuteResult.success || !dailyResult.success) { + const isMinuteLimit = !minuteResult.success; + return new Response( + JSON.stringify({ + error: "Rate limit exceeded", + message: isMinuteLimit + ? "Too many requests. Please wait a moment before trying again." + : "Daily limit reached. Please try again tomorrow.", + }), + { + status: 429, + headers: { "Content-Type": "application/json" }, + }, + ); + } + + const { messages }: { messages: UIMessage[] } = await req.json(); + + const docsFiles = await loadDocsFiles(); + const { tools } = await createBashTool({ files: docsFiles }); + + const result = streamText({ + model: DEFAULT_MODEL, + system: SYSTEM_PROMPT, + messages: await convertToModelMessages(messages), + stopWhen: stepCountIs(5), + tools, + prepareStep: ({ messages: stepMessages }) => ({ + messages: addCacheControl(stepMessages), + }), + }); + + return result.toUIMessageStreamResponse(); +} diff --git a/docs/src/app/cdp-mode/page.mdx b/docs/src/app/cdp-mode/page.mdx new file mode 100644 index 0000000..69435ac --- /dev/null +++ b/docs/src/app/cdp-mode/page.mdx @@ -0,0 +1,87 @@ +export const metadata = { title: "CDP Mode" } + +# CDP Mode + +Connect to an existing browser via Chrome DevTools Protocol: + +```bash +# Start Chrome with: google-chrome --remote-debugging-port=9222 + +# Connect once, then run commands without --cdp +agent-browser connect 9222 +agent-browser snapshot +agent-browser tab +agent-browser close + +# Or pass --cdp on each command +agent-browser --cdp 9222 snapshot +``` + +## Remote WebSocket URLs + +Connect to remote browser services via WebSocket URL: + +```bash +# Connect to remote browser service +agent-browser --cdp "wss://browser-service.com/cdp?token=..." snapshot + +# Works with any CDP-compatible service +agent-browser --cdp "ws://localhost:9222/devtools/browser/abc123" open example.com +``` + +The `--cdp` flag accepts either: + +- A port number (e.g., `9222`) for local connections via `http://localhost:{port}` +- A full WebSocket URL (e.g., `wss://...` or `ws://...`) for remote browser services + +## Use cases + +This enables control of: + +- Electron apps +- Chrome/Chromium with remote debugging +- WebView2 applications +- Remote browser services (via WebSocket URL) +- Any browser exposing a CDP endpoint + +## Global options + +| Option | Description | +| --- | --- | +| `--session ` | Use isolated session | +| `--profile ` | Persistent browser profile directory | +| `-p ` | Cloud browser provider (`browserbase`, `browseruse`) | +| `--headers ` | HTTP headers scoped to origin | +| `--executable-path` | Custom browser executable | +| `--args ` | Browser launch args (comma-separated) | +| `--user-agent ` | Custom User-Agent string | +| `--proxy ` | Proxy server URL | +| `--proxy-bypass ` | Hosts to bypass proxy | +| `--json` | JSON output for scripts | +| `--full, -f` | Full page screenshot | +| `--name, -n` | Locator name filter | +| `--exact` | Exact text match | +| `--headed` | Show browser window | +| `--cdp ` | CDP connection (port or WebSocket URL) | +| `--debug` | Debug output | + +## Cloud providers + +Use cloud browser infrastructure when local browsers aren't available: + +```bash +# Browserbase +export BROWSERBASE_API_KEY="your-api-key" +export BROWSERBASE_PROJECT_ID="your-project-id" +agent-browser -p browserbase open https://example.com + +# Browser Use +export BROWSER_USE_API_KEY="your-api-key" +agent-browser -p browseruse open https://example.com + +# Or via environment variable +export AGENT_BROWSER_PROVIDER=browserbase +agent-browser open https://example.com +``` + +The `-p` flag takes precedence over `AGENT_BROWSER_PROVIDER`. diff --git a/docs/src/app/cdp-mode/page.tsx b/docs/src/app/cdp-mode/page.tsx deleted file mode 100644 index 522cbea..0000000 --- a/docs/src/app/cdp-mode/page.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function CDPMode() { - return ( -
-
-

CDP Mode

-

Connect to an existing browser via Chrome DevTools Protocol:

- - -

Remote WebSocket URLs

-

Connect to remote browser services via WebSocket URL:

- -

The --cdp flag accepts either:

-
    -
  • A port number (e.g., 9222) for local connections via http://localhost:{port}
  • -
  • A full WebSocket URL (e.g., wss://... or ws://...) for remote browser services
  • -
- -

Use cases

-

This enables control of:

-
    -
  • Electron apps
  • -
  • Chrome/Chromium with remote debugging
  • -
  • WebView2 applications
  • -
  • Remote browser services (via WebSocket URL)
  • -
  • Any browser exposing a CDP endpoint
  • -
- -

Global options

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
--session <name>Use isolated session
--profile <path>Persistent browser profile directory
-p <provider>Cloud browser provider (browserbase, browseruse)
--headers <json>HTTP headers scoped to origin
--executable-pathCustom browser executable
--args <args>Browser launch args (comma-separated)
--user-agent <ua>Custom User-Agent string
--proxy <url>Proxy server URL
--proxy-bypass <hosts>Hosts to bypass proxy
--jsonJSON output for scripts
--full, -fFull page screenshot
--name, -nLocator name filter
--exactExact text match
--headedShow browser window
--cdp <port|url>CDP connection (port or WebSocket URL)
--debugDebug output
- -

Cloud providers

-

Use cloud browser infrastructure when local browsers aren't available:

- -

The -p flag takes precedence over AGENT_BROWSER_PROVIDER.

-
-
- ); -} diff --git a/docs/src/app/changelog/page.mdx b/docs/src/app/changelog/page.mdx new file mode 100644 index 0000000..2092651 --- /dev/null +++ b/docs/src/app/changelog/page.mdx @@ -0,0 +1,193 @@ +export const metadata = { title: "Changelog" } + +# Changelog + +## v0.8.0 + +

January 2026

+ +### New Features + +- **Kernel cloud browser provider** - Connect to Kernel (kernel.sh) for remote browser infrastructure with stealth mode and persistent profiles + +```bash +# Via -p flag +agent-browser -p kernel open https://example.com + +# Via environment variable +export AGENT_BROWSER_PROVIDER=kernel +export KERNEL_API_KEY=your-api-key +agent-browser open https://example.com + +# With persistent profile +export KERNEL_PROFILE_NAME=my-profile +agent-browser open https://example.com +``` + +- **Ignore HTTPS certificate errors** - New flag for working with self-signed certificates and development environments + +```bash +agent-browser --ignore-https-errors open https://localhost:3000 +``` + +- **Enhanced cookie management** - Extended `cookies set` command with additional flags for setting cookies before page load + +```bash +agent-browser cookies set session_id "abc123" --url https://app.example.com --httpOnly --secure +agent-browser cookies set token "xyz" --domain .example.com --path /api --expires 1735689600 +``` + +### Bug Fixes + +- Fixed tab list command not recognizing new pages opened via clicks or `target="_blank"` links +- Fixed `check` command hanging indefinitely +- Fixed `set device` not applying deviceScaleFactor - HiDPI screenshots now work correctly +- Fixed state load and profile persistence not working in v0.7.6 +- Screenshots now save to temp directory when no path is provided + +### Security + +- Daemon and stream server now reject cross-origin connections + +--- + +## v0.7.1 + +

January 2026

+ +### Bug Fixes + +- **Fix native binary distribution** - Native binaries for all platforms (Linux x64/arm64, macOS x64/arm64, Windows x64) are now included in the npm package. Previously, the release workflow published to npm before building binaries, causing "No binary found" errors on installation. + +--- + +## v0.7.0 + +

January 2026

+ +### New Features + +- **Cloud browser providers** - Connect to Browserbase or Browser Use for remote browser infrastructure + +```bash +# Via -p flag (recommended) +agent-browser -p browserbase open https://example.com +agent-browser -p browseruse open https://example.com + +# Via environment variable +export AGENT_BROWSER_PROVIDER=browserbase +agent-browser open https://example.com +``` + +- **Persistent browser profiles** - Store cookies, localStorage, and login sessions across browser restarts + +```bash +agent-browser --profile ~/.myapp-profile open myapp.com +# Login persists across restarts +``` + +- **Remote CDP WebSocket URLs** - Connect to remote browser services via WebSocket + +```bash +agent-browser --cdp "wss://browser-service.com/cdp?token=..." snapshot +``` + +- **`download` command** - Trigger downloads and wait for completion + +```bash +agent-browser download @e1 ./file.pdf +agent-browser wait --download ./output.zip --timeout 30000 +``` + +- **Browser launch configuration** - Fine-grained control over browser startup + +```bash +agent-browser --args "--disable-gpu,--no-sandbox" open example.com +agent-browser --user-agent "Custom UA" open example.com +agent-browser --proxy-bypass "localhost,*.internal" open example.com +``` + +- **Enhanced skills** - Hierarchical structure with references and templates for Claude Code + +### Bug Fixes + +- Screenshot command now supports refs and has improved error messages +- WebSocket URLs work in `connect` command +- Fixed socket file location (uses `~/.agent-browser` instead of TMPDIR) +- Windows binary path fix (.exe extension) +- State load and path-based actions now show correct output messages + +### Documentation + +- Added Claude Code marketplace plugin installation instructions +- Updated skill documentation with references and templates +- Improved error documentation + +--- + +## v0.6.0 + +

January 2026

+ +### New Features + +- **Video recording** - Record browser sessions to WebM using Playwright's native recording + +```bash +agent-browser record start ./demo.webm +agent-browser click @e1 +agent-browser record stop +``` + +- **`connect` command** - Connect to a browser via CDP and persist the connection for subsequent commands + +```bash +agent-browser connect 9222 +agent-browser snapshot # No --cdp needed after connect +``` + +- **`--proxy` flag** - Configure browser proxy with optional authentication + +```bash +agent-browser --proxy http://user:pass@proxy.com:8080 open example.com +``` + +- **`get styles` command** - Extract computed styles from elements + +```bash +agent-browser get styles "button" +``` + +- **Claude marketplace plugin** - Added `.claude-plugin/marketplace.json` for Claude Code integration +- **Enhanced network output** - `network requests` now shows method, URL, and resource type +- **`--version` flag** - Display CLI version + +### Bug Fixes + +- Fix Windows daemon startup and port calculation +- Support `libasound2t64` on newer Ubuntu versions (24.04+) +- Prevent CDP timeout on empty URL tabs +- Output screenshot as base64 when no path provided +- Resolve refs in `get value` command +- Support URL parameter in `tab new` command +- Allow `about:`, `data:`, and `file:` URL schemes +- Detect stale unix socket by attempting connection +- Respect `AGENT_BROWSER_HEADED` environment variable +- Handle SIGPIPE to prevent panic when piping to `head`/`tail` +- Fix null path validation in screenshot command + +### Protocol Alignment + +These changes align the CLI with the daemon protocol for consistency: + +- `select` command now uses `values` field (supports multiple selections) +- `frame main` uses `mainframe` action +- `mouse wheel` uses `wheel` action +- `set media` uses `emulatemedia` action +- Console output uses `messages` field + +### Documentation + +- Expanded SKILL.md with comprehensive command reference +- Updated README with new commands and options +- Updated CDP mode documentation with `connect` workflow diff --git a/docs/src/app/changelog/page.tsx b/docs/src/app/changelog/page.tsx deleted file mode 100644 index 3cbf371..0000000 --- a/docs/src/app/changelog/page.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Changelog() { - return ( -
-
-

Changelog

- -

v0.8.0

-

January 2026

- -

New Features

-
    -
  • - Kernel cloud browser provider - Connect to Kernel (kernel.sh) for remote browser infrastructure with stealth mode and persistent profiles - -
  • -
  • - Ignore HTTPS certificate errors - New flag for working with self-signed certificates and development environments - -
  • -
  • - Enhanced cookie management - Extended cookies set command with additional flags for setting cookies before page load - -
  • -
- -

Bug Fixes

-
    -
  • Fixed tab list command not recognizing new pages opened via clicks or target="_blank" links
  • -
  • Fixed check command hanging indefinitely
  • -
  • Fixed set device not applying deviceScaleFactor - HiDPI screenshots now work correctly
  • -
  • Fixed state load and profile persistence not working in v0.7.6
  • -
  • Screenshots now save to temp directory when no path is provided
  • -
- -

Security

-
    -
  • Daemon and stream server now reject cross-origin connections
  • -
- -
- -

v0.7.1

-

January 2026

- -

Bug Fixes

-
    -
  • - Fix native binary distribution - Native binaries for all platforms (Linux x64/arm64, macOS x64/arm64, Windows x64) are now included in the npm package. Previously, the release workflow published to npm before building binaries, causing "No binary found" errors on installation. -
  • -
- -
- -

v0.7.0

-

January 2026

- -

New Features

-
    -
  • - Cloud browser providers - Connect to Browserbase or Browser Use for remote browser infrastructure - -
  • -
  • - Persistent browser profiles - Store cookies, localStorage, and login sessions across browser restarts - -
  • -
  • - Remote CDP WebSocket URLs - Connect to remote browser services via WebSocket - -
  • -
  • - download command - Trigger downloads and wait for completion - -
  • -
  • - Browser launch configuration - Fine-grained control over browser startup - -
  • -
  • - Enhanced skills - Hierarchical structure with references and templates for Claude Code -
  • -
- -

Bug Fixes

-
    -
  • Screenshot command now supports refs and has improved error messages
  • -
  • WebSocket URLs work in connect command
  • -
  • Fixed socket file location (uses ~/.agent-browser instead of TMPDIR)
  • -
  • Windows binary path fix (.exe extension)
  • -
  • State load and path-based actions now show correct output messages
  • -
- -

Documentation

-
    -
  • Added Claude Code marketplace plugin installation instructions
  • -
  • Updated skill documentation with references and templates
  • -
  • Improved error documentation
  • -
- -
- -

v0.6.0

-

January 2026

- -

New Features

-
    -
  • - Video recording - Record browser sessions to WebM using Playwright's native recording - -
  • -
  • - connect command - Connect to a browser via CDP and persist the connection for subsequent commands - -
  • -
  • - --proxy flag - Configure browser proxy with optional authentication - -
  • -
  • - get styles command - Extract computed styles from elements - -
  • -
  • - Claude marketplace plugin - Added .claude-plugin/marketplace.json for Claude Code integration -
  • -
  • - Enhanced network output - network requests now shows method, URL, and resource type -
  • -
  • - --version flag - Display CLI version -
  • -
- -

Bug Fixes

-
    -
  • Fix Windows daemon startup and port calculation
  • -
  • Support libasound2t64 on newer Ubuntu versions (24.04+)
  • -
  • Prevent CDP timeout on empty URL tabs
  • -
  • Output screenshot as base64 when no path provided
  • -
  • Resolve refs in get value command
  • -
  • Support URL parameter in tab new command
  • -
  • Allow about:, data:, and file: URL schemes
  • -
  • Detect stale unix socket by attempting connection
  • -
  • Respect AGENT_BROWSER_HEADED environment variable
  • -
  • Handle SIGPIPE to prevent panic when piping to head/tail
  • -
  • Fix null path validation in screenshot command
  • -
- -

Protocol Alignment

-

These changes align the CLI with the daemon protocol for consistency:

-
    -
  • select command now uses values field (supports multiple selections)
  • -
  • frame main uses mainframe action
  • -
  • mouse wheel uses wheel action
  • -
  • set media uses emulatemedia action
  • -
  • Console output uses messages field
  • -
- -

Documentation

-
    -
  • Expanded SKILL.md with comprehensive command reference
  • -
  • Updated README with new commands and options
  • -
  • Updated CDP mode documentation with connect workflow
  • -
- -
-
- ); -} diff --git a/docs/src/app/commands/page.tsx b/docs/src/app/commands/page.mdx similarity index 56% rename from docs/src/app/commands/page.tsx rename to docs/src/app/commands/page.mdx index 059b8bd..b06f1c6 100644 --- a/docs/src/app/commands/page.tsx +++ b/docs/src/app/commands/page.mdx @@ -1,13 +1,11 @@ -import { CodeBlock } from "@/components/code-block"; +export const metadata = { title: "Commands" } -export default function Commands() { - return ( -
-
-

Commands

+# Commands -

Core

- # Navigate (aliases: goto, navigate) +## Core + +```bash +agent-browser open # Navigate (aliases: goto, navigate) agent-browser click # Click element agent-browser dblclick # Double-click agent-browser fill # Clear and fill @@ -21,67 +19,96 @@ agent-browser scroll [px] # Scroll (up/down/left/right) agent-browser screenshot [path] # Screenshot (--full for full page) agent-browser snapshot # Accessibility tree with refs agent-browser eval # Run JavaScript -agent-browser close # Close browser`} /> +agent-browser close # Close browser +``` -

Get info

- # Get text content +## Get info + +```bash +agent-browser get text # Get text content agent-browser get html # Get innerHTML agent-browser get value # Get input value agent-browser get attr # Get attribute agent-browser get title # Get page title agent-browser get url # Get current URL agent-browser get count # Count matching elements -agent-browser get box # Get bounding box`} /> +agent-browser get box # Get bounding box +``` -

Check state

- # Check if visible +## Check state + +```bash +agent-browser is visible # Check if visible agent-browser is enabled # Check if enabled -agent-browser is checked # Check if checked`} /> +agent-browser is checked # Check if checked +``` -

Find elements

-

Semantic locators with actions (click, fill, check, hover, text):

- [value] +## Find elements + +Semantic locators with actions (`click`, `fill`, `check`, `hover`, `text`): + +```bash +agent-browser find role [value] agent-browser find text agent-browser find label
-
- ); -} +agent-browser screenshot output.png +``` + +The `--allow-file-access` flag enables JavaScript to access other local files. Chromium only. diff --git a/docs/src/app/globals.css b/docs/src/app/globals.css index bfc5bd1..4ad0925 100644 --- a/docs/src/app/globals.css +++ b/docs/src/app/globals.css @@ -1,19 +1,79 @@ @import "tailwindcss"; :root { - --background: #000000; - --foreground: #ededed; - --muted: #888888; - --border: #222222; - --accent: #ededed; + --radius: 0.5rem; + --background: oklch(1.0 0 0); + --foreground: oklch(0.1 0 0); + --card: oklch(0.98 0 0); + --card-foreground: oklch(0.1 0 0); + --popover: oklch(0.98 0 0); + --popover-foreground: oklch(0.1 0 0); + --primary: oklch(0.1 0 0); + --primary-foreground: oklch(1.0 0 0); + --secondary: oklch(0.92 0 0); + --secondary-foreground: oklch(0.1 0 0); + --muted: oklch(0.92 0 0); + --muted-foreground: oklch(0.45 0 0); + --accent: oklch(0.92 0 0); + --accent-foreground: oklch(0.1 0 0); + --destructive: oklch(0.55 0.2 25); + --destructive-foreground: oklch(1.0 0 0); + --border: oklch(0.85 0 0); + --input: oklch(0.85 0 0); + --ring: oklch(0.6 0 0); + --chat-bg: oklch(0.95 0 0); } +.dark { + --background: oklch(0.0 0 0); + --foreground: oklch(0.98 0 0); + --card: oklch(0.08 0 0); + --card-foreground: oklch(0.98 0 0); + --popover: oklch(0.08 0 0); + --popover-foreground: oklch(0.98 0 0); + --primary: oklch(0.98 0 0); + --primary-foreground: oklch(0.0 0 0); + --secondary: oklch(0.15 0 0); + --secondary-foreground: oklch(0.98 0 0); + --muted: oklch(0.15 0 0); + --muted-foreground: oklch(0.6 0 0); + --accent: oklch(0.15 0 0); + --accent-foreground: oklch(0.1 0 0); + --destructive: oklch(0.65 0.2 25); + --destructive-foreground: oklch(0.98 0 0); + --border: oklch(0.25 0 0); + --input: oklch(0.25 0 0); + --ring: oklch(0.4 0 0); + --chat-bg: oklch(0.25 0 0); +} + +@custom-variant dark (&:is(.dark *)); + @theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --radius-2xl: calc(var(--radius) + 8px); --color-background: var(--background); --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); - --color-border: var(--border); + --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); --font-sans: var(--font-geist); --font-mono: var(--font-geist-mono); } @@ -35,17 +95,17 @@ body { } ::-webkit-scrollbar-thumb { - background: #333; + background: var(--border); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { - background: #444; + background: var(--muted-foreground); } /* Code blocks */ pre { - background: #111 !important; + background: var(--card) !important; border: 1px solid var(--border); border-radius: 4px; padding: 0.875rem; @@ -75,7 +135,7 @@ code { } :not(pre) > code { - background: #1a1a1a; + background: var(--card); padding: 0.125rem 0.375rem; border-radius: 3px; font-size: 0.875em; @@ -91,7 +151,7 @@ code { font-weight: 500; letter-spacing: -0.02em; margin-bottom: 0.5rem; - color: #fff; + color: var(--foreground); } @media (min-width: 640px) { @@ -105,7 +165,7 @@ code { font-weight: 500; letter-spacing: 0; text-transform: uppercase; - color: var(--muted); + color: var(--muted-foreground); margin-top: 3rem; margin-bottom: 1rem; } @@ -115,13 +175,14 @@ code { font-weight: 500; margin-top: 2rem; margin-bottom: 0.75rem; - color: #ccc; + color: var(--foreground); + opacity: 0.85; } .prose p { margin-bottom: 1.25rem; line-height: 1.7; - color: var(--muted); + color: var(--muted-foreground); font-size: 0.9375rem; } @@ -132,13 +193,14 @@ code { .prose li { margin-bottom: 0.5rem; - color: var(--muted); + color: var(--muted-foreground); font-size: 0.9375rem; line-height: 1.6; } .prose li strong { - color: #ccc; + color: var(--foreground); + opacity: 0.85; font-weight: 500; } @@ -149,7 +211,7 @@ code { } .prose a:hover { - color: #fff; + color: var(--foreground); } .prose table { @@ -167,16 +229,61 @@ code { .prose th { font-weight: 500; - color: var(--muted); + color: var(--muted-foreground); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.025em; } .prose td { - color: var(--muted); + color: var(--muted-foreground); } .prose td code { color: var(--foreground); } + +/* Tool call shimmer animation */ +@keyframes tool-shimmer { + 0% { opacity: 0.5; } + 50% { opacity: 1; } + 100% { opacity: 0.5; } +} + +.animate-tool-shimmer { + animation: tool-shimmer 1.5s ease-in-out infinite; +} + +/* Dark mode: use page bg color for borders in chat message content */ +.dark .docs-chat-content * { + border-color: var(--background); +} + +/* Override prose text color inside chat content so agent responses appear brighter */ +.docs-chat-content p, +.docs-chat-content li, +.docs-chat-content td { + color: var(--foreground); + opacity: 0.9; +} + +/* Fix list rendering in chat content */ +.docs-chat-content ul, +.docs-chat-content ol { + list-style-position: outside; + padding-left: 1.25em; +} + +.docs-chat-content li > p { + display: inline; + margin: 0; +} + +.docs-chat-content li { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +button { + cursor: pointer; +} diff --git a/docs/src/app/installation/page.mdx b/docs/src/app/installation/page.mdx new file mode 100644 index 0000000..4ed7c7d --- /dev/null +++ b/docs/src/app/installation/page.mdx @@ -0,0 +1,104 @@ +export const metadata = { title: "Installation" } + +# Installation + +## npm (recommended) + +```bash +npm install -g agent-browser +agent-browser install # Download Chromium +``` + +## Homebrew (macOS) + +```bash +brew install agent-browser +agent-browser install # Download Chromium +``` + +## From source + +```bash +git clone https://github.com/vercel-labs/agent-browser +cd agent-browser +pnpm install +pnpm build +pnpm build:native +./bin/agent-browser install +pnpm link --global +``` + +## Linux dependencies + +On Linux, install system dependencies: + +```bash +agent-browser install --with-deps +# or manually: npx playwright install-deps chromium +``` + +## Custom browser + +Use a custom browser executable instead of bundled Chromium: + +- **Serverless** - Use `@sparticuz/chromium` (~50MB vs ~684MB) +- **System browser** - Use existing Chrome installation +- **Custom builds** - Use modified browser builds + +```bash +# Via flag +agent-browser --executable-path /path/to/chromium open example.com + +# Via environment variable +AGENT_BROWSER_EXECUTABLE_PATH=/path/to/chromium agent-browser open example.com +``` + +### Serverless example + +```typescript +import chromium from '@sparticuz/chromium'; +import { BrowserManager } from 'agent-browser'; + +export async function handler() { + const browser = new BrowserManager(); + await browser.launch({ + executablePath: await chromium.executablePath(), + headless: true, + }); + // ... use browser +} +``` + +## AI agent setup + +agent-browser works with any AI agent out of the box. For richer context: + +### AGENTS.md / CLAUDE.md + +Add to your instructions file: + +```markdown +## Browser Automation + +Use `agent-browser` for web automation. Run `agent-browser --help` for all commands. + +Core workflow: +1. `agent-browser open ` - Navigate to page +2. `agent-browser snapshot -i` - Get interactive elements with refs (@e1, @e2) +3. `agent-browser click @e1` / `fill @e2 "text"` - Interact using refs +4. Re-snapshot after page changes +``` + +### Claude Code skill + +```bash +cp -r node_modules/agent-browser/skills/agent-browser .claude/skills/ +``` + +Or download: + +```bash +mkdir -p .claude/skills/agent-browser +curl -o .claude/skills/agent-browser/SKILL.md \ + https://raw.githubusercontent.com/vercel-labs/agent-browser/main/skills/agent-browser/SKILL.md +``` diff --git a/docs/src/app/installation/page.tsx b/docs/src/app/installation/page.tsx deleted file mode 100644 index 3d02c60..0000000 --- a/docs/src/app/installation/page.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Installation() { - return ( -
-
-

Installation

- -

npm (recommended)

- - -

Homebrew (macOS)

- - -

From source

- - -

Linux dependencies

-

On Linux, install system dependencies:

- - -

Custom browser

-

- Use a custom browser executable instead of bundled Chromium: -

-
    -
  • Serverless - Use @sparticuz/chromium (~50MB vs ~684MB)
  • -
  • System browser - Use existing Chrome installation
  • -
  • Custom builds - Use modified browser builds
  • -
- - - -

Serverless example

- - -

AI agent setup

-

agent-browser works with any AI agent out of the box. For richer context:

- -

AGENTS.md / CLAUDE.md

-

Add to your instructions file:

- \` - Navigate to page -2. \`agent-browser snapshot -i\` - Get interactive elements with refs (@e1, @e2) -3. \`agent-browser click @e1\` / \`fill @e2 "text"\` - Interact using refs -4. Re-snapshot after page changes`} /> - -

Claude Code skill

- -

Or download:

- -
-
- ); -} diff --git a/docs/src/app/ios/page.mdx b/docs/src/app/ios/page.mdx new file mode 100644 index 0000000..9aaa889 --- /dev/null +++ b/docs/src/app/ios/page.mdx @@ -0,0 +1,199 @@ +export const metadata = { title: "iOS Simulator" } + +# iOS Simulator + +Control real Mobile Safari in the iOS Simulator for authentic mobile +web testing. Uses Appium with XCUITest for native automation. + +## Requirements + +- macOS with Xcode installed +- iOS Simulator runtimes (download via Xcode) +- Appium with XCUITest driver + +## Setup + +```bash +# Install Appium globally +npm install -g appium + +# Install the XCUITest driver for iOS +appium driver install xcuitest +``` + +## List available devices + +See all iOS simulators available on your system: + +```bash +agent-browser device list + +# Output: +# Available iOS Simulators: +# +# ○ iPhone 16 Pro (iOS 18.0) +# F21EEC0D-7618-419F-811B-33AF27A8B2FD +# ○ iPhone 16 Pro Max (iOS 18.0) +# 50402807-C9B8-4D37-9F13-2E00E782C744 +# ○ iPad Pro 13-inch (M4) (iOS 18.0) +# 3A6C6436-B909-4593-866D-91D1062BB070 +# ... +``` + +## Basic usage + +Use the `-p ios` flag to enable iOS mode. The workflow is +identical to desktop: + +```bash +# Launch Safari on iPhone 16 Pro +agent-browser -p ios --device "iPhone 16 Pro" open https://example.com + +# Get snapshot with refs (same as desktop) +agent-browser -p ios snapshot -i + +# Interact using refs +agent-browser -p ios tap @e1 +agent-browser -p ios fill @e2 "text" + +# Take screenshot +agent-browser -p ios screenshot mobile.png + +# Close session (shuts down simulator) +agent-browser -p ios close +``` + +## Mobile-specific commands + +```bash +# Swipe gestures +agent-browser -p ios swipe up +agent-browser -p ios swipe down +agent-browser -p ios swipe left +agent-browser -p ios swipe right + +# Swipe with distance (pixels) +agent-browser -p ios swipe up 500 + +# Tap (alias for click, semantically clearer for touch) +agent-browser -p ios tap @e1 +``` + +## Environment variables + +Configure iOS mode via environment variables: + +```bash +export AGENT_BROWSER_PROVIDER=ios +export AGENT_BROWSER_IOS_DEVICE="iPhone 16 Pro" + +# Now all commands use iOS +agent-browser open https://example.com +agent-browser snapshot -i +agent-browser tap @e1 +``` + +| Variable | Description | +| --- | --- | +| `AGENT_BROWSER_PROVIDER` | Set to `ios` to enable iOS mode | +| `AGENT_BROWSER_IOS_DEVICE` | Device name (e.g., "iPhone 16 Pro") | +| `AGENT_BROWSER_IOS_UDID` | Device UDID (alternative to device name) | + +## Supported devices + +All iOS Simulators available in Xcode are supported, including: + +- All iPhone models (iPhone 15, 16, 17, SE, etc.) +- All iPad models (iPad Pro, iPad Air, iPad mini, etc.) +- Multiple iOS versions (17.x, 18.x, etc.) + +**Real devices** are also supported via USB connection (see below). + +## Real device support + +Appium can control Safari on real iOS devices connected via USB. This +requires additional one-time setup. + +### 1. Get your device UDID + +```bash +# List connected devices +xcrun xctrace list devices + +# Or via system profiler +system_profiler SPUSBDataType | grep -A 5 "iPhone\|iPad" +``` + +### 2. Sign WebDriverAgent (one-time) + +WebDriverAgent needs to be signed with your Apple Developer +certificate to run on real devices. + +```bash +# Open the WebDriverAgent Xcode project +cd ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent +open WebDriverAgent.xcodeproj +``` + +In Xcode: + +1. Select the `WebDriverAgentRunner` target +2. Go to Signing & Capabilities +3. Select your Team (requires Apple Developer account, free tier works) +4. Let Xcode manage signing automatically + +### 3. Use with agent-browser + +```bash +# Connect device via USB, then use the UDID +agent-browser -p ios --device "" open https://example.com + +# Or use the device name if unique +agent-browser -p ios --device "John's iPhone" open https://example.com +``` + +### Real device notes + +- First run installs WebDriverAgent to the device (may require Trust prompt on device) +- Device must be unlocked and connected via USB +- Slightly slower initial connection than simulator +- Tests against real Safari performance and behavior +- On first install, go to Settings → General → VPN & Device Management to trust the developer certificate + +## Performance notes + +- **First launch:** Takes 30-60 seconds to boot the simulator and start Appium +- **Subsequent commands:** Fast (simulator stays running) +- **Close command:** Shuts down simulator and Appium server + +## Differences from desktop + +| Feature | Desktop | iOS | +| --- | --- | --- | +| Browser | Chromium/Firefox/WebKit | Safari only | +| Tabs | Supported | Single tab only | +| PDF export | Supported | Not supported | +| Screencast | Supported | Not supported | +| Swipe gestures | Not native | Native support | + +## Troubleshooting + +### Appium not found + +```bash +# Make sure Appium is installed globally +npm install -g appium +appium driver install xcuitest + +# Verify installation +appium --version +``` + +### No simulators available + +Open Xcode and download iOS Simulator runtimes from **Settings → Platforms**. + +### Simulator won't boot + +Try booting the simulator manually from Xcode or the Simulator app to +ensure it works, then retry with agent-browser. diff --git a/docs/src/app/ios/page.tsx b/docs/src/app/ios/page.tsx deleted file mode 100644 index 896bdb1..0000000 --- a/docs/src/app/ios/page.tsx +++ /dev/null @@ -1,280 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function iOS() { - return ( -
-
-

iOS Simulator

-

- Control real Mobile Safari in the iOS Simulator for authentic mobile - web testing. Uses Appium with XCUITest for native automation. -

- -

Requirements

-
    -
  • macOS with Xcode installed
  • -
  • iOS Simulator runtimes (download via Xcode)
  • -
  • Appium with XCUITest driver
  • -
- -

Setup

- - -

List available devices

-

See all iOS simulators available on your system:

- - -

Basic usage

-

- Use the -p ios flag to enable iOS mode. The workflow is - identical to desktop: -

- - -

Mobile-specific commands

- - -

Environment variables

-

Configure iOS mode via environment variables:

- - - - - - - - - - - - - - - - - - - - - - - -
VariableDescription
- AGENT_BROWSER_PROVIDER - - Set to ios to enable iOS mode -
- AGENT_BROWSER_IOS_DEVICE - Device name (e.g., "iPhone 16 Pro")
- AGENT_BROWSER_IOS_UDID - Device UDID (alternative to device name)
- -

Supported devices

-

- All iOS Simulators available in Xcode are supported, including: -

-
    -
  • All iPhone models (iPhone 15, 16, 17, SE, etc.)
  • -
  • All iPad models (iPad Pro, iPad Air, iPad mini, etc.)
  • -
  • Multiple iOS versions (17.x, 18.x, etc.)
  • -
-

- Real devices are also supported via USB connection - (see below). -

- -

Real device support

-

- Appium can control Safari on real iOS devices connected via USB. This - requires additional one-time setup. -

- -

1. Get your device UDID

- - -

2. Sign WebDriverAgent (one-time)

-

- WebDriverAgent needs to be signed with your Apple Developer - certificate to run on real devices. -

- -

In Xcode:

-
    -
  1. - Select the WebDriverAgentRunner target -
  2. -
  3. Go to Signing & Capabilities
  4. -
  5. - Select your Team (requires Apple Developer account, free tier works) -
  6. -
  7. Let Xcode manage signing automatically
  8. -
- -

3. Use with agent-browser

- " open https://example.com - -# Or use the device name if unique -agent-browser -p ios --device "John's iPhone" open https://example.com`} - /> - -

Real device notes

-
    -
  • - First run installs WebDriverAgent to the device (may require Trust - prompt on device) -
  • -
  • Device must be unlocked and connected via USB
  • -
  • Slightly slower initial connection than simulator
  • -
  • Tests against real Safari performance and behavior
  • -
  • - On first install, go to Settings → General → VPN & - Device Management to trust the developer certificate -
  • -
- -

Performance notes

-
    -
  • - First launch: Takes 30-60 seconds to boot the - simulator and start Appium -
  • -
  • - Subsequent commands: Fast (simulator stays running) -
  • -
  • - Close command: Shuts down simulator and Appium - server -
  • -
- -

Differences from desktop

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureDesktopiOS
BrowserChromium/Firefox/WebKitSafari only
TabsSupportedSingle tab only
PDF exportSupportedNot supported
ScreencastSupportedNot supported
Swipe gesturesNot nativeNative support
- -

Troubleshooting

-

Appium not found

- - -

No simulators available

-

- Open Xcode and download iOS Simulator runtimes from{" "} - Settings → Platforms. -

- -

Simulator won't boot

-

- Try booting the simulator manually from Xcode or the Simulator app to - ensure it works, then retry with agent-browser. -

-
-
- ); -} diff --git a/docs/src/app/layout.tsx b/docs/src/app/layout.tsx index 9f73c0d..349521e 100644 --- a/docs/src/app/layout.tsx +++ b/docs/src/app/layout.tsx @@ -1,9 +1,11 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; +import { ThemeProvider } from "@/components/theme-provider"; import { MobileNavProvider } from "@/components/mobile-nav-context"; import { Header } from "@/components/header"; import { Sidebar } from "@/components/sidebar"; +import { DocsChat } from "@/components/docs-chat"; const geist = Geist({ variable: "--font-geist", @@ -26,19 +28,26 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - -
-
- -
- {children} -
-
- + + +
+
+ +
+
+
+ {children} +
+
+
+
+ + + ); diff --git a/docs/src/app/page.mdx b/docs/src/app/page.mdx new file mode 100644 index 0000000..3497322 --- /dev/null +++ b/docs/src/app/page.mdx @@ -0,0 +1,63 @@ +export const metadata = { title: "agent-browser" } + +# agent-browser + +Browser automation CLI designed for AI agents. Compact text output minimizes context usage. Fast Rust CLI with Node.js fallback. + +```bash +npm install -g agent-browser # all platforms +brew install agent-browser # macOS +``` + +## Features + +- **Agent-first** - Compact text output uses fewer tokens than JSON, designed for AI context efficiency +- **Ref-based** - Snapshot returns accessibility tree with refs for deterministic element selection +- **Fast** - Native Rust CLI for instant command parsing +- **Complete** - 50+ commands for navigation, forms, screenshots, network, storage +- **Sessions** - Multiple isolated browser instances with separate auth +- **Cross-platform** - macOS, Linux, Windows with native binaries + +## Works with + +Claude Code, Cursor, GitHub Copilot, OpenAI Codex, Google Gemini, opencode, and any agent that can run shell commands. + +## Example + +```bash +# Navigate and get snapshot +agent-browser open example.com +agent-browser snapshot -i + +# Output: +# - heading "Example Domain" [ref=e1] +# - link "More information..." [ref=e2] + +# Interact using refs +agent-browser click @e2 +agent-browser screenshot page.png +agent-browser close +``` + +## Why refs? + +The `snapshot` command returns a compact accessibility tree where each element +has a unique ref like `@e1`, `@e2`. This provides: + +- **Context-efficient** - Text output uses ~200-400 tokens vs ~3000-5000 for full DOM +- **Deterministic** - Ref points to exact element from snapshot +- **Fast** - No DOM re-query needed +- **AI-friendly** - LLMs parse text output naturally + +## Architecture + +Client-daemon architecture for optimal performance: + +1. **Rust CLI** - Parses commands, communicates with daemon +2. **Node.js Daemon** - Manages Playwright browser instance + +Daemon starts automatically and persists between commands. + +## Platforms + +Native Rust binaries for macOS (ARM64, x64), Linux (ARM64, x64), and Windows (x64). diff --git a/docs/src/app/page.tsx b/docs/src/app/page.tsx deleted file mode 100644 index 7bd3fd2..0000000 --- a/docs/src/app/page.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Home() { - return ( -
-
-

agent-browser

-

- Browser automation CLI designed for AI agents. Compact text output minimizes context usage. Fast Rust CLI with Node.js fallback. -

- - - -

Features

-
    -
  • Agent-first - Compact text output uses fewer tokens than JSON, designed for AI context efficiency
  • -
  • Ref-based - Snapshot returns accessibility tree with refs for deterministic element selection
  • -
  • Fast - Native Rust CLI for instant command parsing
  • -
  • Complete - 50+ commands for navigation, forms, screenshots, network, storage
  • -
  • Sessions - Multiple isolated browser instances with separate auth
  • -
  • Cross-platform - macOS, Linux, Windows with native binaries
  • -
- -

Works with

-

- Claude Code, Cursor, GitHub Copilot, OpenAI Codex, Google Gemini, opencode, and any agent that can run shell commands. -

- -

Example

- - -

Why refs?

-

- The snapshot command returns a compact accessibility tree where each element - has a unique ref like @e1, @e2. This provides: -

-
    -
  • Context-efficient - Text output uses ~200-400 tokens vs ~3000-5000 for full DOM
  • -
  • Deterministic - Ref points to exact element from snapshot
  • -
  • Fast - No DOM re-query needed
  • -
  • AI-friendly - LLMs parse text output naturally
  • -
- -

Architecture

-

- Client-daemon architecture for optimal performance: -

-
    -
  1. Rust CLI - Parses commands, communicates with daemon
  2. -
  3. Node.js Daemon - Manages Playwright browser instance
  4. -
-

- Daemon starts automatically and persists between commands. -

- -

Platforms

-

- Native Rust binaries for macOS (ARM64, x64), Linux (ARM64, x64), and Windows (x64). -

-
-
- ); -} diff --git a/docs/src/app/quick-start/page.mdx b/docs/src/app/quick-start/page.mdx new file mode 100644 index 0000000..c0c4db4 --- /dev/null +++ b/docs/src/app/quick-start/page.mdx @@ -0,0 +1,75 @@ +export const metadata = { title: "Quick Start" } + +# Quick Start + +## Core workflow + +Every browser automation follows this pattern: + +```bash +# 1. Navigate +agent-browser open example.com + +# 2. Snapshot to get element refs +agent-browser snapshot -i +# Output: +# @e1 [heading] "Example Domain" +# @e2 [link] "More information..." + +# 3. Interact using refs +agent-browser click @e2 + +# 4. Re-snapshot after page changes +agent-browser snapshot -i +``` + +## Common commands + +```bash +agent-browser open example.com +agent-browser snapshot -i # Get interactive elements with refs +agent-browser click @e2 # Click by ref +agent-browser fill @e3 "test@example.com" # Fill input by ref +agent-browser get text @e1 # Get text content +agent-browser screenshot # Save to temp directory +agent-browser screenshot page.png # Save to specific path +agent-browser close +``` + +## Traditional selectors + +CSS selectors and semantic locators also supported: + +```bash +agent-browser click "#submit" +agent-browser fill "#email" "test@example.com" +agent-browser find role button click --name "Submit" +``` + +## Headed mode + +Show browser window for debugging: + +```bash +agent-browser open example.com --headed +``` + +## Wait for content + +```bash +agent-browser wait @e1 # Wait for element +agent-browser wait --load networkidle # Wait for network idle +agent-browser wait --url "**/dashboard" # Wait for URL pattern +agent-browser wait 2000 # Wait milliseconds +``` + +## JSON output + +For programmatic parsing in scripts: + +```bash +agent-browser snapshot --json +agent-browser get text @e1 --json +``` + +Note: The default text output is more compact and preferred for AI agents. diff --git a/docs/src/app/quick-start/page.tsx b/docs/src/app/quick-start/page.tsx deleted file mode 100644 index 0121355..0000000 --- a/docs/src/app/quick-start/page.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function QuickStart() { - return ( -
-
-

Quick Start

- -

Core workflow

-

Every browser automation follows this pattern:

- - -

Common commands

- - -

Traditional selectors

-

CSS selectors and semantic locators also supported:

- - -

Headed mode

-

Show browser window for debugging:

- - -

Wait for content

- - -

JSON output

-

For programmatic parsing in scripts:

- -

- Note: The default text output is more compact and preferred for AI agents. -

-
-
- ); -} diff --git a/docs/src/app/selectors/page.mdx b/docs/src/app/selectors/page.mdx new file mode 100644 index 0000000..1ab7013 --- /dev/null +++ b/docs/src/app/selectors/page.mdx @@ -0,0 +1,56 @@ +export const metadata = { title: "Selectors" } + +# Selectors + +## Refs (recommended) + +Refs provide deterministic element selection from snapshots. Best for AI agents. + +```bash +# 1. Get snapshot with refs +agent-browser snapshot +# Output: +# - heading "Example Domain" [ref=e1] [level=1] +# - button "Submit" [ref=e2] +# - textbox "Email" [ref=e3] +# - link "Learn more" [ref=e4] + +# 2. Use refs to interact +agent-browser click @e2 # Click the button +agent-browser fill @e3 "test@example.com" # Fill the textbox +agent-browser get text @e1 # Get heading text +agent-browser hover @e4 # Hover the link +``` + +### Why refs? + +- **Deterministic** - Ref points to exact element from snapshot +- **Fast** - No DOM re-query needed +- **AI-friendly** - LLMs can reliably parse and use refs + +## CSS selectors + +```bash +agent-browser click "#id" +agent-browser click ".class" +agent-browser click "div > button" +agent-browser click "[data-testid='submit']" +``` + +## Text & XPath + +```bash +agent-browser click "text=Submit" +agent-browser click "xpath=//button[@type='submit']" +``` + +## Semantic locators + +Find elements by role, label, or other semantic properties: + +```bash +agent-browser find role button click --name "Submit" +agent-browser find label "Email" fill "test@test.com" +agent-browser find placeholder "Search..." fill "query" +agent-browser find testid "submit-btn" click +``` diff --git a/docs/src/app/selectors/page.tsx b/docs/src/app/selectors/page.tsx deleted file mode 100644 index 3fceae6..0000000 --- a/docs/src/app/selectors/page.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Selectors() { - return ( -
-
-

Selectors

- -

Refs (recommended)

-

- Refs provide deterministic element selection from snapshots. Best for AI agents. -

- - -

Why refs?

-
    -
  • Deterministic - Ref points to exact element from snapshot
  • -
  • Fast - No DOM re-query needed
  • -
  • AI-friendly - LLMs can reliably parse and use refs
  • -
- -

CSS selectors

- button" -agent-browser click "[data-testid='submit']"`} /> - -

Text & XPath

- - -

Semantic locators

-

Find elements by role, label, or other semantic properties:

- -
-
- ); -} diff --git a/docs/src/app/sessions/page.mdx b/docs/src/app/sessions/page.mdx new file mode 100644 index 0000000..0bad201 --- /dev/null +++ b/docs/src/app/sessions/page.mdx @@ -0,0 +1,94 @@ +export const metadata = { title: "Sessions" } + +# Sessions + +Run multiple isolated browser instances: + +```bash +# Different sessions +agent-browser --session agent1 open site-a.com +agent-browser --session agent2 open site-b.com + +# Or via environment variable +AGENT_BROWSER_SESSION=agent1 agent-browser click "#btn" + +# List active sessions +agent-browser session list +# Output: +# Active sessions: +# -> default +# agent1 + +# Show current session +agent-browser session +``` + +## Session isolation + +Each session has its own: + +- Browser instance +- Cookies and storage +- Navigation history +- Authentication state + +## Persistent profiles + +By default, browser state is lost when the browser closes. Use `--profile` to persist state across restarts: + +```bash +# Use a persistent profile directory +agent-browser --profile ~/.myapp-profile open myapp.com + +# Login once, then reuse the authenticated session +agent-browser --profile ~/.myapp-profile open myapp.com/dashboard + +# Or via environment variable +AGENT_BROWSER_PROFILE=~/.myapp-profile agent-browser open myapp.com +``` + +The profile directory stores: + +- Cookies and localStorage +- IndexedDB data +- Service workers +- Browser cache +- Login sessions + +## Authenticated sessions + +Use `--headers` to set HTTP headers for a specific origin: + +```bash +# Headers scoped to api.example.com only +agent-browser open api.example.com --headers '{"Authorization": "Bearer "}' + +# Requests to api.example.com include the auth header +agent-browser snapshot -i --json +agent-browser click @e2 + +# Navigate to another domain - headers NOT sent +agent-browser open other-site.com +``` + +Useful for: + +- **Skipping login flows** - Authenticate via headers +- **Switching users** - Different auth tokens per session +- **API testing** - Access protected endpoints +- **Security** - Headers scoped to origin, not leaked + +## Multiple origins + +```bash +agent-browser open api.example.com --headers '{"Authorization": "Bearer token1"}' +agent-browser open api.acme.com --headers '{"Authorization": "Bearer token2"}' +``` + +## Global headers + +For headers on all domains: + +```bash +agent-browser set headers '{"X-Custom-Header": "value"}' +``` diff --git a/docs/src/app/sessions/page.tsx b/docs/src/app/sessions/page.tsx deleted file mode 100644 index 6b53423..0000000 --- a/docs/src/app/sessions/page.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Sessions() { - return ( -
-
-

Sessions

-

Run multiple isolated browser instances:

- default -# agent1 - -# Show current session -agent-browser session`} /> - -

Session isolation

-

Each session has its own:

-
    -
  • Browser instance
  • -
  • Cookies and storage
  • -
  • Navigation history
  • -
  • Authentication state
  • -
- -

Persistent profiles

-

By default, browser state is lost when the browser closes. Use --profile to persist state across restarts:

- -

The profile directory stores:

-
    -
  • Cookies and localStorage
  • -
  • IndexedDB data
  • -
  • Service workers
  • -
  • Browser cache
  • -
  • Login sessions
  • -
- -

Authenticated sessions

-

- Use --headers to set HTTP headers for a specific origin: -

- "}' - -# Requests to api.example.com include the auth header -agent-browser snapshot -i --json -agent-browser click @e2 - -# Navigate to another domain - headers NOT sent -agent-browser open other-site.com`} /> -

Useful for:

-
    -
  • Skipping login flows - Authenticate via headers
  • -
  • Switching users - Different auth tokens per session
  • -
  • API testing - Access protected endpoints
  • -
  • Security - Headers scoped to origin, not leaked
  • -
- -

Multiple origins

- - -

Global headers

-

For headers on all domains:

- -
-
- ); -} diff --git a/docs/src/app/snapshots/page.mdx b/docs/src/app/snapshots/page.mdx new file mode 100644 index 0000000..21308f0 --- /dev/null +++ b/docs/src/app/snapshots/page.mdx @@ -0,0 +1,97 @@ +export const metadata = { title: "Snapshots" } + +# Snapshots + +The `snapshot` command returns a compact accessibility tree with refs for element interaction. + +## Options + +Filter output to reduce size: + +```bash +agent-browser snapshot # Full accessibility tree +agent-browser snapshot -i # Interactive elements only (recommended) +agent-browser snapshot -i -C # Include cursor-interactive elements +agent-browser snapshot -c # Compact (remove empty elements) +agent-browser snapshot -d 3 # Limit depth to 3 levels +agent-browser snapshot -s "#main" # Scope to CSS selector +agent-browser snapshot -i -c -d 5 # Combine options +``` + +| Option | Description | +| --- | --- | +| `-i, --interactive` | Only interactive elements (buttons, links, inputs) | +| `-C, --cursor` | Include cursor-interactive elements (cursor:pointer, onclick, tabindex) | +| `-c, --compact` | Remove empty structural elements | +| `-d, --depth` | Limit tree depth | +| `-s, --selector` | Scope to CSS selector | + +## Cursor-interactive elements + +Many modern web apps use custom clickable elements (divs, spans) instead of standard buttons or links. +The `-C` flag detects these by looking for: + +- `cursor: pointer` CSS style +- `onclick` attribute or handler +- `tabindex` attribute (keyboard focusable) + +```bash +agent-browser snapshot -i -C +# Output includes: +# @e1 [button] "Submit" +# @e2 [link] "Learn more" +# Cursor-interactive elements: +# @e3 [clickable] "Menu Item" [cursor:pointer, onclick] +# @e4 [clickable] "Card" [cursor:pointer] +``` + +## Output format + +The default text output is compact and AI-friendly: + +```bash +agent-browser snapshot -i +# Output: +# @e1 [heading] "Example Domain" [level=1] +# @e2 [button] "Submit" +# @e3 [input type="email"] placeholder="Email" +# @e4 [link] "Learn more" +``` + +## Using refs + +Refs from the snapshot map directly to commands: + +```bash +agent-browser click @e2 # Click the Submit button +agent-browser fill @e3 "a@b.com" # Fill the email input +agent-browser get text @e1 # Get heading text +``` + +## Ref lifecycle + +Refs are invalidated when the page changes. Always re-snapshot after navigation or DOM updates: + +```bash +agent-browser click @e4 # Navigates to new page +agent-browser snapshot -i # Get fresh refs +agent-browser click @e1 # Use new refs +``` + +## Best practices + +1. Use `-i` to reduce output to actionable elements +2. Re-snapshot after page changes to get updated refs +3. Scope with `-s` for specific page sections +4. Use `-d` to limit depth on complex pages + +## JSON output + +For programmatic parsing in scripts: + +```bash +agent-browser snapshot --json +# {"success":true,"data":{"snapshot":"...","refs":{"e1":{"role":"heading","name":"Title"},...}}} +``` + +Note: JSON uses more tokens than text output. The default text format is preferred for AI agents. diff --git a/docs/src/app/snapshots/page.tsx b/docs/src/app/snapshots/page.tsx deleted file mode 100644 index 2120c68..0000000 --- a/docs/src/app/snapshots/page.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { CodeBlock } from "@/components/code-block"; - -export default function Snapshots() { - return ( -
-
-

Snapshots

-

- The snapshot command returns a compact accessibility tree with refs for element interaction. -

- -

Options

-

Filter output to reduce size:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-i, --interactiveOnly interactive elements (buttons, links, inputs)
-C, --cursorInclude cursor-interactive elements (cursor:pointer, onclick, tabindex)
-c, --compactRemove empty structural elements
-d, --depthLimit tree depth
-s, --selectorScope to CSS selector
- -

Cursor-interactive elements

-

- Many modern web apps use custom clickable elements (divs, spans) instead of standard buttons or links. - The -C flag detects these by looking for: -

-
    -
  • cursor: pointer CSS style
  • -
  • onclick attribute or handler
  • -
  • tabindex attribute (keyboard focusable)
  • -
- - -

Output format

-

The default text output is compact and AI-friendly:

- - -

Using refs

-

Refs from the snapshot map directly to commands:

- - -

Ref lifecycle

-

- Refs are invalidated when the page changes. Always re-snapshot after navigation or DOM updates: -

- - -

Best practices

-
    -
  1. Use -i to reduce output to actionable elements
  2. -
  3. Re-snapshot after page changes to get updated refs
  4. -
  5. Scope with -s for specific page sections
  6. -
  7. Use -d to limit depth on complex pages
  8. -
- -

JSON output

-

For programmatic parsing in scripts:

- -

- Note: JSON uses more tokens than text output. The default text format is preferred for AI agents. -

-
-
- ); -} diff --git a/docs/src/app/streaming/page.tsx b/docs/src/app/streaming/page.mdx similarity index 53% rename from docs/src/app/streaming/page.tsx rename to docs/src/app/streaming/page.mdx index aa93037..15af7b9 100644 --- a/docs/src/app/streaming/page.tsx +++ b/docs/src/app/streaming/page.mdx @@ -1,32 +1,31 @@ -import { CodeBlock } from "@/components/code-block"; +export const metadata = { title: "Streaming" } -export default function Streaming() { - return ( -
-
-

Streaming

-

- Stream the browser viewport via WebSocket for live preview or "pair browsing" - where a human can watch and interact alongside an AI agent. -

+# Streaming -

Enable streaming

-

- Set the AGENT_BROWSER_STREAM_PORT environment variable to start - a WebSocket server: -

- +Stream the browser viewport via WebSocket for live preview or "pair browsing" +where a human can watch and interact alongside an AI agent. -

- The server streams viewport frames and accepts input events (mouse, keyboard, touch). -

+## Enable streaming -

WebSocket protocol

-

Connect to ws://localhost:9223 to receive frames and send input.

+Set the `AGENT_BROWSER_STREAM_PORT` environment variable to start +a WebSocket server: -

Frame messages

-

The server sends frame messages with base64-encoded images:

- ", "metadata": { @@ -37,23 +36,31 @@ export default function Streaming() { "scrollOffsetX": 0, "scrollOffsetY": 0 } -}`} /> +} +``` -

Status messages

-

Connection and screencast status:

- +} +``` -

Input injection

-

Send input events to control the browser remotely.

+## Input injection -

Mouse events

- +} +``` -

Keyboard events

- +} +``` -

Touch events

- +} +``` -

Programmatic API

-

For advanced use, control streaming directly via the TypeScript API:

- +await browser.stopScreencast(); +``` -

Use cases

-
    -
  • Pair browsing - Human watches and assists AI agent in real-time
  • -
  • Remote preview - View browser output in a separate UI
  • -
  • Recording - Capture frames for video generation
  • -
  • Mobile testing - Inject touch events for mobile emulation
  • -
  • Accessibility testing - Manual interaction during automated tests
  • -
-
-
- ); -} +## Use cases + +- **Pair browsing** - Human watches and assists AI agent in real-time +- **Remote preview** - View browser output in a separate UI +- **Recording** - Capture frames for video generation +- **Mobile testing** - Inject touch events for mobile emulation +- **Accessibility testing** - Manual interaction during automated tests diff --git a/docs/src/components/docs-chat.tsx b/docs/src/components/docs-chat.tsx new file mode 100644 index 0000000..800235c --- /dev/null +++ b/docs/src/components/docs-chat.tsx @@ -0,0 +1,437 @@ +"use client"; + +import { useRef, useEffect, useState } from "react"; +import { useChat } from "@ai-sdk/react"; +import { DefaultChatTransport } from "ai"; +import { Streamdown } from "streamdown"; +import Link from "next/link"; + +const STORAGE_KEY = "docs-chat-messages"; +const transport = new DefaultChatTransport({ api: "/api/docs-chat" }); + +const TOOL_LABELS: Record< + string, + { label: string; pastLabel: string; argKey?: string } +> = { + readFile: { label: "Reading", pastLabel: "Read", argKey: "path" }, + bash: { label: "Running", pastLabel: "Ran", argKey: "command" }, +}; + +function isToolPart(part: { type: string }): part is { + type: string; + toolCallId: string; + toolName?: string; + state: string; + input?: Record; + output?: unknown; + errorText?: string; +} { + return part.type.startsWith("tool-") || part.type === "dynamic-tool"; +} + +function getToolName(part: { type: string; toolName?: string }): string { + if (part.type === "dynamic-tool") return part.toolName ?? "tool"; + return part.type.replace(/^tool-/, ""); +} + +function ToolCallDisplay({ + part, +}: { + part: { + type: string; + toolCallId: string; + toolName?: string; + state: string; + input?: Record; + output?: unknown; + errorText?: string; + }; +}) { + const toolName = getToolName(part); + const config = TOOL_LABELS[toolName] ?? { + label: toolName, + pastLabel: toolName, + }; + const isDone = part.state === "output-available"; + const isError = part.state === "output-error"; + const isRunning = !isDone && !isError; + const displayLabel = isRunning ? config.label : config.pastLabel; + + const args = (part.input ?? {}) as Record; + const argValue = config.argKey ? args[config.argKey] : undefined; + const argPreview = + argValue != null + ? String(argValue) + .replace(/^\/workspace\//, "/") + .replace(/\.md$/, "") + .replace(/\/index$/, "") || "/" + : ""; + + // Link to the docs page if it's a readFile path + const docsLink = + toolName === "readFile" && argPreview.startsWith("/") ? argPreview : null; + + const argEl = argPreview ? ( + docsLink ? ( + + {argPreview} + + ) : ( + {argPreview} + ) + ) : null; + + return ( +
+ {isRunning ? ( + + {displayLabel} + {argEl} + + ) : ( + + {displayLabel} + {argEl} + {isError && failed} + + )} +
+ ); +} + +const SUGGESTIONS = [ + "What is agent-browser?", + "How do I install it?", + "What commands are available?", + "How do snapshots work?", + "How do I use CDP mode?", +]; + +export function DocsChat() { + const [open, setOpen] = useState(false); + const [input, setInput] = useState(""); + const [focused, setFocused] = useState(false); + const messagesEndRef = useRef(null); + const inputRef = useRef(null); + const containerRef = useRef(null); + const restoredRef = useRef(false); + + const { messages, sendMessage, status, setMessages, error } = useChat({ + transport, + }); + + const isLoading = status === "streaming" || status === "submitted"; + + // Restore messages from sessionStorage on mount + useEffect(() => { + if (restoredRef.current) return; + restoredRef.current = true; + try { + const stored = sessionStorage.getItem(STORAGE_KEY); + if (stored) { + const parsed = JSON.parse(stored); + if (Array.isArray(parsed) && parsed.length > 0) { + setMessages(parsed); + } + } + } catch { + // ignore parse errors + } + }, [setMessages]); + + // Save completed messages to sessionStorage + useEffect(() => { + if (!restoredRef.current) return; + if (isLoading) return; + if (messages.length === 0) { + sessionStorage.removeItem(STORAGE_KEY); + return; + } + try { + sessionStorage.setItem(STORAGE_KEY, JSON.stringify(messages)); + } catch { + // ignore quota errors + } + }, [messages, isLoading]); + + // Auto-open when new messages arrive (but not on initial restore) + const prevMessageCount = useRef(null); + const initializedRef = useRef(false); + useEffect(() => { + // Skip until after the first sessionStorage restore cycle + if (!initializedRef.current) { + // Wait one tick after mount to let restore settle + const id = requestAnimationFrame(() => { + prevMessageCount.current = messages.length; + initializedRef.current = true; + }); + return () => cancelAnimationFrame(id); + } + if ( + prevMessageCount.current !== null && + messages.length > prevMessageCount.current + ) { + setOpen(true); + } + prevMessageCount.current = messages.length; + }, [messages.length]); + + // Scroll to bottom when messages change or error occurs + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages, error]); + + // Cmd+K to focus prompt, Esc to close + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "k" && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + inputRef.current?.focus(); + } + if (e.key === "Escape" && open) { + setOpen(false); + inputRef.current?.blur(); + } + }; + document.addEventListener("keydown", handleKeyDown); + return () => document.removeEventListener("keydown", handleKeyDown); + }, [open]); + + // Close message area when clicking outside + useEffect(() => { + if (!open) return; + const handleClickOutside = (e: MouseEvent) => { + if ( + containerRef.current && + !containerRef.current.contains(e.target as Node) + ) { + setOpen(false); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, [open]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + if (!input.trim() || isLoading) return; + sendMessage({ text: input }); + setInput(""); + }; + + const handleClear = () => { + setMessages([]); + sessionStorage.removeItem(STORAGE_KEY); + setOpen(false); + inputRef.current?.focus(); + }; + + const hasVisibleContent = ( + parts: (typeof messages)[number]["parts"], + ): boolean => { + return parts.some( + (p) => (p.type === "text" && p.text.length > 0) || isToolPart(p), + ); + }; + + // Auto-open when error occurs + useEffect(() => { + if (error) setOpen(true); + }, [error]); + + const showMessages = open && (messages.length > 0 || !!error); + const showSuggestions = focused && messages.length === 0 && !isLoading; + + return ( +
+
+
+ {/* Suggestions panel */} + {showSuggestions && ( +
+
+ + agent-browser Docs + +
+
+ {SUGGESTIONS.map((s) => ( + + ))} +
+
+ )} + {/* Messages panel */} + {showMessages && ( +
+
+ + agent-browser Docs + + +
+
{ + if ((e.target as HTMLElement).closest("a")) { + setOpen(false); + } + }} + > + {messages.map((message) => { + if (!hasVisibleContent(message.parts)) return null; + return ( +
+ {message.role === "user" ? ( +
+ {message.parts + .filter( + (p): p is Extract => + p.type === "text", + ) + .map((p) => p.text) + .join("")} +
+ ) : ( +
+ {message.parts.map((part, i) => { + if (part.type === "text" && part.text) { + return ( +
+ {part.text} +
+ ); + } + if (isToolPart(part)) { + return ( + + ); + } + return null; + })} +
+ )} +
+ ); + })} + {error && ( +
+ {(() => { + try { + const parsed = JSON.parse(error.message); + return parsed.message || parsed.error || error.message; + } catch { + return ( + error.message || + "Something went wrong. Please try again." + ); + } + })()} +
+ )} +
+
+
+ )} + + {/* Input bar */} +
inputRef.current?.focus()} + className={`relative flex items-end gap-2 px-3 py-2 cursor-text${showMessages ? " border-t border-background" : ""}`} + > + {!input && ( +
+ + Ask a question... + + {!focused && !showMessages && ( + + ⌘K + + )} +
+ )} +