two things, and the second is why the first was painful. TAGS. the marketplace is going to be browsed rather than scrolled: tags on the left, the plugins carrying one on the right. a plugin declares its own in the manifest and the catalogue caches it on sync, exactly as it already does for label and summary — the alternative is editing a table every time a plugin ships, and a plugin that cannot say what it is. the vocabulary is CLOSED (PLUGIN_TAGS) because free text becomes homelab, home-lab, Home Lab and selfhosted inside a month, and a filter list of synonyms is worse than no filter. an unknown tag is refused at discovery BY NAME, so the author is told which tag rather than which array index. all 21 are tagged, each with a one-line note saying why, so a later disagreement is with a stated reason rather than a mystery. every tag has at least three plugins behind it — no filter opens onto an empty page. PLUGINS:CHECK. getting one commit into 21 repositories failed seven times and none of the reasons were about the commit: six remotes were HTTPS and cannot authenticate unattended, three checkouts were behind their remote, one URL had no .git suffix so the catalogue published a clone URL unlike every other, and offscale's fetch refspec named a branch that does not exist. that last one is why this is a script and not a habit. every command reported on a phantom — `git push` said "Everything up-to-date" while the branch looked diverged — and the repository was fine the whole time. twenty minutes spent in a repo with nothing wrong with it. none of it is visible until you try to push, which is the worst moment to learn it: mid-task, across 21 repositories, and every failure looks like it is about your change. so it checks the facts with one right answer — remote URL, fetch refspec, branch, upstream, dirty tree, ahead/behind — and exits non-zero. `--fix` is a separate flag so running the check can never be what changes your tree, and divergence is never auto-repaired because it needs a decision about content. verified by breaking each case on purpose and watching it catch them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
204 lines
7.4 KiB
JSON
204 lines
7.4 KiB
JSON
{
|
|
"name": "officer",
|
|
"version": "2026.08.26.02",
|
|
"private": true,
|
|
"type": "module",
|
|
"workspaces": [
|
|
"src/databases/*",
|
|
"src/workspaces/*"
|
|
],
|
|
"engines": {
|
|
"bun": "1.3.x"
|
|
},
|
|
"scripts": {
|
|
"preinstall": "node -e \"var v = +process.versions.node.split('.')[0]; if (v < 22) { console.error('Node 22 or newer required (got ' + process.versions.node + '). Run: nvm use 22'); process.exit(1); }\"",
|
|
"gen:index": "bun run ./scripts/gen-index.ts",
|
|
"fix:env": "bun run ./scripts/fix-env.ts",
|
|
"todo:index": "bun run ./scripts/todo-index.ts",
|
|
"plugins:update": "bun run ./scripts/update-plugins.ts",
|
|
"nudge": "bun run --env-file=.env ./scripts/nudge-agent.ts",
|
|
"doctor": "bun run --env-file=.env ./scripts/doctor.ts",
|
|
"secret:set": "bun run --env-file=.env ./scripts/secret-set.ts",
|
|
"notify:test": "bun run --env-file=.env ./scripts/notify-test.ts",
|
|
"gen:ecosystem": "bun run --env-file=.env ./scripts/gen-ecosystem.ts",
|
|
"predev": "bun run ./scripts/gen-index.ts",
|
|
"dev": "bun --env-file=.env --watch src/server.tsx",
|
|
"prestart": "bun run ./scripts/gen-index.ts",
|
|
"start": "NODE_ENV=production bun src/server.tsx",
|
|
"prebuild": "bun run ./scripts/prebuild.ts",
|
|
"build:web": "bun run ./scripts/build/web.ts",
|
|
"build:dashboard": "bun run ./scripts/build/dashboard.ts",
|
|
"db:gen": "cd src/databases/officer_db && bun run generate",
|
|
"db:push": "bun run scripts/gen-plugin-schemas.ts && cd src/databases/officer_db && bun run push",
|
|
"postdb:push": "bun run --env-file=.env scripts/backfill-session-models.ts && bun run --env-file=.env scripts/seed-roles.ts",
|
|
"db:migrate": "cd src/databases/officer_db && bun run migrate",
|
|
"dev:emailer": "cd src/workspaces/emailer && bun run dev",
|
|
"format": "{ git diff --name-only HEAD -- 'src/**/*.ts' 'src/**/*.tsx'; git ls-files --others --exclude-standard -- 'src/**/*.ts' 'src/**/*.tsx'; } | xargs -r prettier --write",
|
|
"format:all": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
"setup": "bash scripts/install.sh",
|
|
"check:theme": "bun scripts/check-theme-tokens.ts",
|
|
"docs:check": "bun run scripts/docs-check.ts",
|
|
"skills:platform": "bun run scripts/gen-platform-skill.ts",
|
|
"plugins:check": "bun run scripts/plugins-check.ts"
|
|
},
|
|
"dependencies": {
|
|
"@anthropic-ai/claude-agent-sdk": "^0.2.41",
|
|
"@bitcoinerlab/secp256k1": "1.2.0",
|
|
"@getalby/sdk": "^8.0.3",
|
|
"@hookform/resolvers": "^5.2.2",
|
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
"@monaco-editor/react": "^4.7.0",
|
|
"@noble/hashes": "2.2.0",
|
|
"@noble/secp256k1": "^3.1.0",
|
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
|
"@radix-ui/react-avatar": "^1.1.10",
|
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
"@radix-ui/react-context-menu": "^2.2.16",
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
"@radix-ui/react-hover-card": "^1.1.15",
|
|
"@radix-ui/react-label": "^2.1.7",
|
|
"@radix-ui/react-menubar": "^1.1.16",
|
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
"@radix-ui/react-popover": "^1.1.15",
|
|
"@radix-ui/react-progress": "^1.1.7",
|
|
"@radix-ui/react-radio-group": "^1.3.8",
|
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
"@radix-ui/react-select": "^2.2.6",
|
|
"@radix-ui/react-separator": "^1.1.7",
|
|
"@radix-ui/react-slider": "^1.3.6",
|
|
"@radix-ui/react-slot": "^1.2.3",
|
|
"@radix-ui/react-switch": "^1.2.6",
|
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
"@react-oauth/google": "^0.13.4",
|
|
"@react-three/drei": "^10.7.7",
|
|
"@react-three/fiber": "^9.5.0",
|
|
"@scure/bip32": "^2.2.0",
|
|
"@scure/bip39": "1.6.0",
|
|
"@simplewebauthn/browser": "^13.2.2",
|
|
"@simplewebauthn/server": "^13.2.2",
|
|
"@tabler/icons-react": "^3.36.0",
|
|
"@tanstack/react-query": "^5.90.5",
|
|
"@tanstack/react-virtual": "^3.13.18",
|
|
"@tiptap/extension-text-align": "^3.15.3",
|
|
"@types/mailparser": "^3.4.6",
|
|
"@types/three": "^0.182.0",
|
|
"@typescript/native-preview": "^7.0.0-dev.20260107.1",
|
|
"@uiw/react-textarea-code-editor": "^3.1.1",
|
|
"@visual-json/core": "^0.1.1",
|
|
"@visual-json/react": "^0.1.1",
|
|
"@xterm/addon-fit": "^0.11.0",
|
|
"@xterm/addon-search": "^0.16.0",
|
|
"@xterm/addon-serialize": "^0.14.0",
|
|
"@xterm/addon-unicode11": "^0.9.0",
|
|
"@xterm/addon-web-links": "^0.12.0",
|
|
"@xterm/addon-webgl": "^0.19.0",
|
|
"@xterm/xterm": "^6.0.0",
|
|
"argon2": "^0.44.0",
|
|
"bech32": "2.0.0",
|
|
"bitcoinjs-lib": "6.1.5",
|
|
"bun-plugin-tailwind": "^0.1.2",
|
|
"check-password-strength": "^3.0.0",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"cmdk": "^1.1.1",
|
|
"config": "workspace:*",
|
|
"cron": "^4.3.3",
|
|
"date-fns": "^4.1.0",
|
|
"definitions": "workspace:*",
|
|
"dotenv": "^17.2.3",
|
|
"drizzle-orm": "^0.45.1",
|
|
"ecpair": "3.0.1",
|
|
"emailer": "workspace:*",
|
|
"embla-carousel-react": "^8.6.0",
|
|
"googleapis": "^169.0.0",
|
|
"helpers": "workspace:*",
|
|
"hono": "^4.11.1",
|
|
"hooks": "workspace:*",
|
|
"html-to-image": "^1.11.13",
|
|
"html2canvas": "^1.4.1",
|
|
"i18n": "workspace:*",
|
|
"idb-keyval": "^6.2.2",
|
|
"imapflow": "^1.2.10",
|
|
"injector": "workspace:*",
|
|
"input-otp": "^1.4.2",
|
|
"js-beautify": "^1.15.4",
|
|
"jsqr": "^1.4.0",
|
|
"jwt-decode": "^4.0.0",
|
|
"lucide-react": "^0.562.0",
|
|
"mailparser": "^3.9.3",
|
|
"maplibre-gl": "^5.24.0",
|
|
"markdown-it": "^14.1.0",
|
|
"material-file-icons": "^2.4.0",
|
|
"monaco-editor": "^0.55.1",
|
|
"next-themes": "^0.4.6",
|
|
"node-pty": "^1.1.0",
|
|
"nodemailer": "^7.0.12",
|
|
"officerdb": "workspace:*",
|
|
"officerdev": "workspace:*",
|
|
"pg": "^8.16.3",
|
|
"postgres": "^3.4.5",
|
|
"qrcode": "^1.5.4",
|
|
"react": "^19",
|
|
"react-countup": "^6.5.3",
|
|
"react-day-picker": "^9.13.0",
|
|
"react-dom": "^19",
|
|
"react-hook-form": "^7.69.0",
|
|
"react-markdown": "^10.1.0",
|
|
"react-router": "^7.11.0",
|
|
"react-spinners": "^0.17.0",
|
|
"recharts": "3.6.0",
|
|
"redis": "^5.8.3",
|
|
"rehype-raw": "^7.0.0",
|
|
"rehype-sanitize": "^6.0.0",
|
|
"rehype-slug": "^6.0.0",
|
|
"remark-gfm": "^4.0.1",
|
|
"shiki": "^3.22.0",
|
|
"sonner": "^2.0.7",
|
|
"sounds": "workspace:*",
|
|
"state": "workspace:*",
|
|
"tailwind-merge": "^3.3.1",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"theme": "workspace:*",
|
|
"three": "^0.182.0",
|
|
"types": "workspace:*",
|
|
"varuint-bitcoin": "^2.0.0",
|
|
"vaul": "^1.1.2",
|
|
"widgets": "workspace:*",
|
|
"workspaces": "workspace:*",
|
|
"ws": "^8.18.1",
|
|
"zod": "^4.2.1"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.57.0",
|
|
"@testing-library/dom": "^10.4.1",
|
|
"@testing-library/react": "^16.3.2",
|
|
"@types/bun": "1.3.5",
|
|
"@types/chrome": "^0.1.36",
|
|
"@types/markdown-it": "^14.1.2",
|
|
"@types/node-telegram-bot-api": "^0.64.14",
|
|
"@types/nodemailer": "^7.0.5",
|
|
"@types/pg": "^8.15.5",
|
|
"@types/qrcode": "^1.5.6",
|
|
"@types/react": "^19",
|
|
"@types/react-dom": "^19",
|
|
"drizzle-kit": "^0.31.8",
|
|
"happy-dom": "^20.3.7",
|
|
"playwright": "^1.57.0",
|
|
"prettier": "^3.6.2",
|
|
"tailwindcss": "^4.1.11",
|
|
"tsx": "^4.20.6",
|
|
"tw-animate-css": "^1.4.0",
|
|
"typescript": "^5.9.3",
|
|
"vite": "^7.3.0",
|
|
"vite-plugin-compression": "^0.5.1"
|
|
}
|
|
}
|