package.json
{
"name": "birdbrain",
"version": "1.0.1-beta.24",
"description": "Open source web investigation & capture tool",
"main": "./out/main/index.js",
"private": true,
"packageManager": "pnpm@10.28.2",
"author": "Matt Donovan",
"license": "MIT",
"homepage": "https://github.com/thebristolsound/birdbrain",
"engines": {
"node": ">=20.19.0"
},
"scripts": {
"dev": "electron-vite dev",
"dev:seed": "node scripts/dev-seed.mjs",
"build": "electron-vite build",
"preview": "electron-vite preview",
"postinstall": "node scripts/ensure-electron.mjs && node scripts/rebuild-native.mjs",
"prepublishOnly": "node scripts/no-registry-publish.mjs",
"rebuild:electron": "node scripts/rebuild-native.mjs",
"build:test-sharp": "node scripts/build-test-sharp.mjs",
"build:extension": "vite build --config extension/vite.config.ts && cross-env BUILD_TARGET=content vite build --config extension/vite.config.ts",
"dev:extension": "node scripts/dev-extension.mjs",
"build:verifier": "node scripts/build-verifier.mjs",
"build:demo-fixture": "node scripts/build-demo-fixture.mjs",
"eval:retrieval": "node scripts/run-retrieval-eval.mjs",
"build:notices": "node scripts/third-party-notices/notices.mjs",
"design-system": "node design-system/build.mjs",
"test": "cross-env ELECTRON_RUN_AS_NODE=1 electron ./node_modules/vitest/vitest.mjs run",
"test:watch": "cross-env ELECTRON_RUN_AS_NODE=1 electron ./node_modules/vitest/vitest.mjs",
"test:coverage": "cross-env ELECTRON_RUN_AS_NODE=1 electron ./node_modules/vitest/vitest.mjs run --coverage",
"coverage:report": "node scripts/coverage-report.mjs",
"coverage:diff": "node scripts/diff-coverage.mjs",
"coverage:all": "node scripts/coverage-all.mjs",
"test:reliability": "node scripts/test-reliability/cli.mjs",
"preflight": "node scripts/preflight.mjs",
"check": "node scripts/check.mjs",
"lint": "eslint . --ext .ts,.tsx",
"lint:boundaries": "depcruise src extension/src tests e2e",
"mcp": "cross-env ELECTRON_RUN_AS_NODE=1 electron ./out/main/mcp.js",
"lint:agents-md": "node scripts/lint-agents-md.mjs",
"lint:adr": "node scripts/check-adr-numbers.mjs",
"db:migration:new": "node scripts/new-migration.mjs",
"lint:slop": "node scripts/slop-audit/cli.mjs",
"audit:check": "node scripts/audit-check.mjs",
"typecheck": "tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json && tsc --noEmit -p extension/tsconfig.json && tsc --noEmit -p tsconfig.test.node.json && tsc --noEmit -p tsconfig.test.web.json && tsc --noEmit -p e2e/tsconfig.json",
"format": "prettier --write \"src/**/*.{ts,tsx}\" \"tests/**/*.{ts,tsx}\" \"extension/**/*.{ts,tsx}\" \"e2e/**/*.{ts,tsx}\" \"scripts/**/*.{mjs,js,ts}\" \"*.{ts,mjs,js}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx}\" \"tests/**/*.{ts,tsx}\" \"extension/**/*.{ts,tsx}\" \"e2e/**/*.{ts,tsx}\" \"scripts/**/*.{mjs,js,ts}\" \"*.{ts,mjs,js}\"",
"pretest:e2e": "pnpm build",
"test:e2e": "npx playwright test",
"test:e2e:debug": "npx playwright test --debug",
"pretest:e2e:debug": "pnpm build",
"package": "pnpm build:extension && electron-vite build && pnpm build:notices && electron-builder --publish never",
"package:win": "pnpm build:extension && electron-vite build && pnpm build:notices && electron-builder --win --publish never",
"package:mac": "pnpm build:extension && electron-vite build && pnpm build:notices && electron-builder --mac --publish never",
"package:linux": "pnpm build:extension && electron-vite build && pnpm build:notices && electron-builder --linux --publish never"
},
"build": {
"appId": "com.birdbrain.app",
"productName": "Birdbrain",
"icon": "resources/icon.png",
"protocols": [
{
"name": "Birdbrain",
"schemes": [
"birdbrain"
]
}
],
"directories": {
"output": "dist"
},
"files": [
"out/**/*",
"resources/**/*",
"package.json",
"node_modules/**/*"
],
"publish": [
{
"provider": "github",
"owner": "thebristolsound",
"repo": "birdbrain"
}
],
"asarUnpack": [
"**/node_modules/sharp/**",
"**/node_modules/@img/**",
"**/node_modules/@number0/**"
],
"extraResources": [
{
"from": "extension/dist",
"to": "extension",
"filter": [
"**/*"
]
},
{
"from": "resources/demo-case.birdbrain",
"to": "demo-case.birdbrain"
},
{
"from": "out/THIRD_PARTY_NOTICES.txt",
"to": "THIRD_PARTY_NOTICES.txt"
}
],
"win": {
"target": [
"nsis"
]
},
"nsis": {
"artifactName": "${productName}-Setup-${version}.${ext}"
},
"mac": {
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64"
]
},
{
"target": "zip",
"arch": [
"x64",
"arm64"
]
}
]
},
"linux": {
"target": [
"AppImage",
"deb"
],
"icon": "resources/icons",
"category": "Utility",
"maintainer": "Matt Donovan <thebristolsound@users.noreply.github.com>"
}
},
"dependencies": {
"@fontsource-variable/inter": "^5.3.0",
"@fontsource-variable/jetbrains-mono": "^5.3.0",
"@ghostery/adblocker-electron": "^2.20.1",
"@hono/node-server": "^2.1.5",
"@hono/zod-validator": "^0.9.1",
"@modelcontextprotocol/server": "^2.4.0",
"@number0/iroh": "1.2.0",
"@peculiar/asn1-cms": "^2.11.0",
"@peculiar/asn1-schema": "^2.11.0",
"@peculiar/asn1-tsp": "^2.11.0",
"@peculiar/asn1-x509": "^2.11.0",
"@tanstack/react-query": "^5.104.5",
"@tanstack/react-router": "^1.170.46",
"@tiptap/core": "3.32.0",
"@tiptap/pm": "3.32.0",
"@tiptap/react": "3.32.0",
"@tiptap/starter-kit": "3.32.0",
"@tiptap/static-renderer": "3.32.0",
"@tiptap/suggestion": "3.32.0",
"better-sqlite3": "^13.0.3",
"cborg": "6.1.4",
"cheerio": "^1.2.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"electron-updater": "^6.8.11",
"hono": "^4.13.13",
"ioc-extractor": "^8.2.0",
"konva": "^10.9.0",
"lucide-react": "^1.61.0",
"motion": "^14.6.0",
"qrcode-generator": "2.0.4",
"radix-ui": "^1.8.1",
"react-konva": "^19.3.2",
"react-markdown": "^10.1.0",
"react-resizable-panels": "^4.14.8",
"sharp": "^0.35.5",
"sonner": "^2.0.8",
"tailwind-merge": "^3.7.0",
"tldts": "^7.4.19",
"use-image": "^1.1.4",
"uuid": "^14.0.3",
"warcio": "2.4.12",
"zod": "^4.6.7",
"zustand": "^5.0.16"
},
"devDependencies": {
"@commitlint/cli": "^21.2.4",
"@commitlint/config-conventional": "^21.2.4",
"@electron-toolkit/utils": "^4.0.0",
"@eslint/js": "^10.0.1",
"@playwright/test": "^1.64.1",
"@tailwindcss/vite": "^4.3.3",
"@tanstack/react-query-devtools": "^5.104.5",
"@tanstack/router-devtools": "^1.167.2",
"@testing-library/dom": "^10.4.2",
"@testing-library/react": "^16.3.3",
"@types/better-sqlite3": "^9.6.0",
"@types/chrome": "^0.3.6",
"@types/node": "^26.6.5",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"@types/uuid": "^11.0.0",
"@vitejs/plugin-react": "^5.2.0",
"@vitest/coverage-v8": "^5.0.5",
"babel-plugin-react-compiler": "^1.0.0",
"cross-env": "^10.1.0",
"dependency-cruiser": "^17.4.3",
"electron": "^45.0.0",
"electron-builder": "^26.18.0",
"electron-vite": "^6.0.0",
"esbuild": "^0.28.2",
"eslint": "^10.13.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-react-hooks": "^7.1.1",
"happy-dom": "^21.0.4",
"jsdom": "^30.1.3",
"node-gyp": "^12.4.0",
"postject": "1.0.0-alpha.6",
"prettier": "^3.9.10",
"react": "^19.3.1",
"react-dom": "^19.3.1",
"shadcn": "^4.22.1",
"tailwindcss": "^4.3.3",
"typescript": "^6.0.3",
"typescript-eslint": "^8.72.0",
"vite": "^8.3.5",
"vitest": "^5.0.5"
}
}