Files
blb-throne-of-the-bone-king/manifest.llm.json
T

646 lines
21 KiB
JSON
Raw Normal View History

2026-06-10 15:01:09 -05:00
{
"schemaVersion": "1.0.0",
"project": {
"name": "blb-throne-of-the-bone-king",
2026-06-12 08:19:40 -05:00
"displayName": "Bone Lord Bob - Throne of the Bone King",
"purpose": "Landscape-first game shell with shared React Native UI across browser, Electron, and future native mobile targets.",
2026-06-10 15:01:09 -05:00
"root": ".",
"model": "single-repo",
"repo": {
"gitea": "http://100.79.253.19:3000/jacob-mathison/blb-throne-of-the-bone-king",
"slug": "jacob-mathison/blb-throne-of-the-bone-king",
"defaultBranch": "main"
},
2026-06-12 08:19:40 -05:00
"universe": "Bone Lord Bob (BLB) - Mathison Projects Inc.",
2026-06-10 15:01:09 -05:00
"status": "early-development",
2026-06-16 11:19:24 -05:00
"summary": "Menu shell with persisted route navigation, settings, policies, changelog, credits, gameplay phase scaffolding, local saves, build metadata display, background music, browser/Electron rendering, and a browser-only socket-gated Toolkit for volatile gameplay/content systems."
2026-06-10 15:01:09 -05:00
},
"principles": [
"Start with llm.txt for human-readable orientation.",
"Use manifest.llm.json for machine-readable routing, commands, targets, and known gaps.",
2026-06-12 08:19:40 -05:00
"Read AGENTS.md for coding-agent operating rules before broad changes.",
"Shared UI under src/ is React Native, not raw HTML.",
2026-06-10 15:01:09 -05:00
"Do not use DOM APIs in shared src/ code; platform shims belong in .web.ts files or src/web/.",
2026-06-12 08:19:40 -05:00
"Metro bundles mobile; Vite bundles web and the Electron renderer.",
2026-06-10 15:01:09 -05:00
"Navigation is Zustand-based; do not add React Navigation unless explicitly requested.",
2026-06-12 08:19:40 -05:00
"Persistence is platform-split via persistStorage.ts for native and persistStorage.web.ts for web/Electron.",
"Toolkit is browser-only, requires Browser resolution, and requires an active Socket.IO connection for entry.",
2026-06-10 15:01:09 -05:00
"Commit as Jacob Mathison (jacob@mathisonprojects.com); never commit as an AI identity."
],
"guideFiles": [
{
"path": "llm.txt",
"type": "root-orientation",
"purpose": "First-read guide for project shape, stack, architecture, commands, conventions, and LLM notes.",
"alwaysRead": true
},
{
"path": "manifest.llm.json",
"type": "machine-manifest",
"purpose": "Machine-readable routing manifest: targets, commands, task routes, known gaps, and verification baseline.",
"alwaysRead": true
},
{
"path": "AGENTS.md",
"type": "agent-instructions",
"purpose": "Operational instructions for coding agents: ground rules, structure conventions, and common tasks.",
"alwaysRead": true
2026-06-12 08:19:40 -05:00
},
{
"path": "README.md",
"type": "human-overview",
"purpose": "Human-facing overview for setup, commands, architecture, toolkit behavior, and validation."
2026-06-10 15:01:09 -05:00
}
],
"globalReadOrder": [
"llm.txt",
"manifest.llm.json",
2026-06-12 08:19:40 -05:00
"AGENTS.md",
"README.md"
2026-06-10 15:01:09 -05:00
],
"globalReadOrderSemantics": "Broad orientation order. Task routers should prefer taskRoutes read arrays to avoid over-reading.",
"documentationFiles": [
{
"path": "llm.txt",
"type": "root-orientation",
"purpose": "Human-readable first-read guide."
},
{
"path": "manifest.llm.json",
"type": "machine-manifest",
"purpose": "Machine-readable project manifest."
},
{
"path": "AGENTS.md",
"type": "agent-instructions",
"purpose": "Agent operating instructions."
},
{
"path": "README.md",
"type": "human-overview",
2026-06-12 08:19:40 -05:00
"purpose": "Human-facing setup and development guide."
},
{
"path": "socket/README.md",
"type": "toolkit-socket-notes",
"purpose": "Socket folder notes."
2026-06-16 11:19:24 -05:00
},
{
"path": "src/data/AGENTS.md",
"type": "data-instructions",
"purpose": "Rules for editable JSON content and Toolkit placeholder resources."
2026-06-10 15:01:09 -05:00
}
],
"targets": [
{
"id": "web",
"label": "Web",
"runtime": "react-native-web in browser",
"bundler": "Vite",
2026-06-12 08:19:40 -05:00
"entry": "index.html -> src/web/main.tsx -> App.tsx",
2026-06-10 15:01:09 -05:00
"devCommand": "npm run web",
"devUrl": "http://127.0.0.1:5173",
"primary": true
},
{
"id": "electron",
"label": "Desktop",
2026-06-12 08:19:40 -05:00
"runtime": "Electron Chromium renderer",
"bundler": "Vite renderer + TypeScript main/preload compile",
"entry": "electron/main.ts loads the Vite dev server in development or dist/renderer/ in production",
2026-06-10 15:01:09 -05:00
"devCommand": "npm run electron:dev",
2026-06-12 08:19:40 -05:00
"buildCommand": "npm run electron:build",
"packageCommand": "npm run electron:package",
"primary": true
},
{
"id": "toolkit-socket",
"label": "Toolkit Socket",
"runtime": "Node + Socket.IO",
"entry": "socket/server.mjs",
"devCommand": "npm run dev:toolkit",
"healthUrl": "http://127.0.0.1:5174/health",
2026-06-10 15:01:09 -05:00
"primary": true
},
{
"id": "android",
"label": "Android",
"runtime": "React Native",
"bundler": "Metro",
2026-06-12 08:19:40 -05:00
"entry": "index.js -> App.tsx",
"devCommand": "npm run android",
"status": "native android/ folder is not currently present in this checkout"
2026-06-10 15:01:09 -05:00
},
{
"id": "ios",
"label": "iOS",
"runtime": "React Native",
"bundler": "Metro",
2026-06-12 08:19:40 -05:00
"entry": "index.js -> App.tsx",
"devCommand": "npm run ios",
"status": "native ios/ folder is not currently present in this checkout"
2026-06-10 15:01:09 -05:00
}
],
"stack": [
"React Native 0.85.3",
"React 19.2.3",
2026-06-12 08:19:40 -05:00
"react-native-web ^0.21.2",
2026-06-10 15:01:09 -05:00
"TypeScript ^5.8.3",
"Zustand ^5.0.14",
2026-06-12 08:19:40 -05:00
"@react-native-async-storage/async-storage ^3.1.1",
"Vite ^8.0.16",
"Electron ^42.4.0",
"Socket.IO and socket.io-client ^4.8.3",
"Sass ^1.101.0",
2026-06-10 15:01:09 -05:00
"Jest",
"ESLint + Prettier",
2026-06-16 11:19:24 -05:00
"Husky pre-commit build version bump and validation",
2026-06-10 15:01:09 -05:00
"Node >= 22.12.0"
],
2026-06-12 08:19:40 -05:00
"scripts": {
"dev": "npm run web",
"web": "vite --host 127.0.0.1",
"web:build": "vite build",
"web:preview": "vite preview --host 127.0.0.1",
"dev:toolkit": "node socket/server.mjs",
"dev:all": "concurrently -k -n app,toolkit -c blue,magenta \"npm run dev\" \"npm run dev:toolkit\"",
"dev:clear": "node socket/clear.mjs",
"electron:dev": "npm run electron:compile && cross-env NODE_ENV=development VITE_DEV_SERVER_URL=http://127.0.0.1:5173 concurrently -k \"vite --host 127.0.0.1\" \"wait-on http://127.0.0.1:5173 && electron .\"",
"electron:build": "npm run web:build && npm run electron:compile",
"electron:compile": "tsc -p tsconfig.electron.json",
"electron:package": "npm run electron:build && electron-builder",
"lint": "eslint .",
"test": "jest",
2026-06-16 11:19:24 -05:00
"validate:commit": "npm run lint && npm run test -- --runInBand && npm run electron:build",
"version:bump-build": "node tools/bump-build-version.mjs"
2026-06-12 08:19:40 -05:00
},
2026-06-10 15:01:09 -05:00
"architecture": {
"rootComponent": "App.tsx",
"componentTree": [
"SafeAreaProvider",
"GameViewport",
"AppNavigator"
],
"navigation": {
2026-06-12 08:19:40 -05:00
"type": "zustand-store with animated fade transitions",
2026-06-10 15:01:09 -05:00
"routes": "src/navigation/routes.ts",
"navigator": "src/navigation/AppNavigator.tsx",
2026-06-12 08:19:40 -05:00
"store": "src/state/navigationStore.ts",
"persistKey": "blb-navigation"
2026-06-10 15:01:09 -05:00
},
"state": {
"library": "zustand",
"stores": [
{
"file": "src/state/navigationStore.ts",
2026-06-12 08:19:40 -05:00
"persistKey": "blb-navigation",
"purpose": "Current route and pending route persistence."
2026-06-10 15:01:09 -05:00
},
{
"file": "src/state/gameSettingsStore.ts",
2026-06-12 08:19:40 -05:00
"persistKey": "blb-game-settings",
"purpose": "Resolution, autosave, mute, and audio volume settings."
},
2026-06-16 11:19:24 -05:00
{
"file": "src/state/gameplayStore.ts",
"persistKey": "blb-gameplay",
"purpose": "Active gameplay run, day counter, phase state, and phase navigation."
},
{
"file": "src/state/saveGameStore.ts",
"persistKey": "blb-save-games",
"purpose": "Local save slots for gameplay runs."
},
2026-06-12 08:19:40 -05:00
{
"file": "src/state/toolkitSocketStore.ts",
"purpose": "Toolkit socket connection status."
},
{
"file": "src/state/toolkitContentStore.ts",
"purpose": "Toolkit credits content, revision, load status, and socket refresh/save actions."
2026-06-10 15:01:09 -05:00
}
],
"persistHelper": "src/state/createPersistOptions.ts",
"platformStorage": {
"mobile": "src/state/persistStorage.ts",
"web": "src/state/persistStorage.web.ts"
}
},
2026-06-12 08:19:40 -05:00
"settings": {
"file": "src/settings/gameSettings.ts",
"resolutionIds": [
"browser",
"iphoneMini",
"iphoneDefault",
"androidDefault",
"phoneLarge"
],
"volumeKeys": [
"master",
"music",
"ambience",
"speech",
"sfx"
]
},
2026-06-10 15:01:09 -05:00
"screens": [
"src/screens/HomeScreen.tsx",
2026-06-16 11:19:24 -05:00
"src/screens/GameplayScreen.tsx",
"src/screens/SavesScreen.tsx",
"src/screens/ChangelogScreen.tsx",
2026-06-10 15:01:09 -05:00
"src/screens/SettingsScreen.tsx",
"src/screens/PoliciesScreen.tsx",
"src/screens/ToolkitScreen.tsx",
"src/screens/PageScreen.tsx"
],
"components": [
"src/components/GameViewport.tsx",
"src/components/ScreenLayout.tsx",
"src/components/MenuButton.tsx",
"src/components/BackHomeButton.tsx"
],
2026-06-12 08:19:40 -05:00
"assets": {
"images": "src/assets/images/",
"fonts": "src/assets/fonts/",
"music": "src/assets/music/",
"scss": "src/assets/scss/",
"favicon": "src/assets/images/favicon.svg"
},
"data": {
2026-06-16 11:19:24 -05:00
"changelog": {
"json": "src/data/changelog.json",
"typedExport": "src/data/changelog.ts",
"sortOrder": "newest-created-first"
},
2026-06-12 08:19:40 -05:00
"credits": {
"json": "src/data/credits.json",
"typedExport": "src/data/credits.ts"
},
"legal": {
"json": "src/data/legal.json"
2026-06-16 11:19:24 -05:00
},
"toolkitPlaceholders": {
"directory": "src/data/toolkit/",
"shape": "empty arrays until schemas stabilize",
"files": [
"audio.json",
"credits.json",
"endings.json",
"factions.json",
"flags.json",
"lore.json",
"map.json",
"opening.json",
"petitioners.json",
"references.json",
"resources.json",
"rulings.json",
"seed.json",
"story.json"
]
2026-06-12 08:19:40 -05:00
}
},
"audio": {
"hook": "src/hooks/useBackgroundMusic.ts",
"webHook": "src/hooks/useBackgroundMusic.web.ts",
"defaultTrack": "src/assets/music/throne-of-the-bone-king.mp3",
"volumeControls": [
"master",
"music",
"mute"
]
},
"toolkit": {
"screen": "src/screens/ToolkitScreen.tsx",
"accessRules": [
"resolution setting must be browser",
"socket status must be connected"
],
"routes": [
"toolkitOpening",
"toolkitPetitioners",
"toolkitRulings",
"toolkitSeed",
"toolkitResources",
"toolkitMap",
"toolkitFactions",
"toolkitFlags",
"toolkitStory",
"toolkitLore",
"toolkitAudio",
"toolkitCredits",
"toolkitEndings",
"toolkitReferences"
],
"contentSync": {
"server": "socket/server.mjs",
"serverHelpers": "socket/contentStore.cjs",
"client": "src/socket/toolkitSocketClient.ts",
"store": "src/state/toolkitContentStore.ts",
"events": [
"toolkit:content:read",
"toolkit:content:save",
"toolkit:content:changed",
"toolkit:content:error"
]
}
},
2026-06-10 15:01:09 -05:00
"webEntry": "src/web/main.tsx",
"electronMain": "electron/main.ts",
"electronPreload": "electron/preload.ts",
"buildOutputs": [
"dist/renderer/",
"dist/electron/"
]
},
"taskRoutes": {
"ui-screen": {
"description": "Add or modify screens, navigation routes, or shared UI components.",
"read": [
"llm.txt",
"manifest.llm.json",
"AGENTS.md",
"src/navigation/routes.ts",
"src/navigation/AppNavigator.tsx",
"<target screen or component>"
],
"update": [
"src/navigation/routes.ts when adding a route",
"src/navigation/AppNavigator.tsx when wiring a route",
"manifest.llm.json when screens, routes, or architecture sections change"
]
},
"state": {
2026-06-12 08:19:40 -05:00
"description": "Zustand stores, persistence, navigation, or game settings.",
2026-06-10 15:01:09 -05:00
"read": [
"llm.txt",
"manifest.llm.json",
"src/state/",
"src/settings/gameSettings.ts",
"src/state/persistStorage.ts",
"src/state/persistStorage.web.ts"
],
"policies": [
2026-06-12 08:19:40 -05:00
"Extend persistStorage.ts and persistStorage.web.ts for platform storage changes.",
"Do not embed DOM or AsyncStorage calls directly in stores.",
"Add merge handling when persisted state shape changes."
2026-06-10 15:01:09 -05:00
],
"update": [
"manifest.llm.json when stores, persist keys, or settings surface change"
]
},
"web-electron": {
2026-06-12 08:19:40 -05:00
"description": "Vite config, web entry, Electron shell, browser assets, SCSS, or platform-specific .web.ts overrides.",
2026-06-10 15:01:09 -05:00
"read": [
"llm.txt",
"manifest.llm.json",
"vite.config.ts",
"index.html",
"src/web/",
2026-06-12 08:19:40 -05:00
"src/assets/",
2026-06-10 15:01:09 -05:00
"electron/",
"tsconfig.electron.json"
],
"policies": [
"DOM APIs are allowed in src/web/ and .web.ts shims only.",
2026-06-12 08:19:40 -05:00
"Electron main/preload compile to dist/electron/.",
"Vite emits renderer assets to dist/renderer/."
],
"verify": [
"npm run lint",
"npm run web:build",
"npm run electron:build"
2026-06-10 15:01:09 -05:00
],
"update": [
"manifest.llm.json when targets, build outputs, or dev commands change"
]
},
2026-06-12 08:19:40 -05:00
"toolkit": {
"description": "Toolkit screens, socket-gated browser tooling, JSON content sync, or Toolkit content panels.",
"read": [
"llm.txt",
"manifest.llm.json",
"src/screens/ToolkitScreen.tsx",
"src/navigation/routes.ts",
"src/state/toolkitSocketStore.ts",
"src/state/toolkitContentStore.ts",
"src/socket/toolkitSocketClient.ts",
"socket/"
],
"policies": [
"Keep Toolkit browser-only unless explicitly requested.",
"Keep Toolkit accessible only through Browser resolution and connected socket status.",
"Use src/data JSON as canonical editable content until schemas stabilize.",
"Do not add full CRUD forms unless explicitly requested."
],
"verify": [
"npm run test -- --runInBand",
"npm run dev:toolkit and check /health"
]
},
"data-content": {
"description": "Editable JSON content, typed data exports, and content validation.",
"read": [
"llm.txt",
"manifest.llm.json",
2026-06-16 11:19:24 -05:00
"src/data/AGENTS.md",
2026-06-12 08:19:40 -05:00
"src/data/",
"socket/contentStore.cjs"
],
"policies": [
"Keep JSON valid and typed through src/data exports.",
"Add runtime validation for data imported by stores or socket helpers.",
"Use atomic writes for server-side JSON save behavior."
],
"verify": [
"npm run test -- --runInBand"
]
},
"realtime": {
"description": "Socket.IO server/client wiring for Toolkit connection status and content sync.",
"read": [
"llm.txt",
"manifest.llm.json",
"socket/server.mjs",
"socket/contentStore.cjs",
"src/hooks/useToolkitSocketConnection.ts",
"src/socket/toolkitSocketClient.ts",
"src/state/toolkitSocketStore.ts",
"src/state/toolkitContentStore.ts",
"package.json"
],
"policies": [
"Keep socket host/port configurable through environment variables.",
"Broadcast content changes after valid reads or saves.",
"Emit toolkit:content:error for read, parse, validation, or write failures."
],
"verify": [
"npm run test -- --runInBand",
"npm run dev:toolkit and check http://127.0.0.1:5174/health"
]
},
2026-06-10 15:01:09 -05:00
"mobile": {
2026-06-12 08:19:40 -05:00
"description": "React Native mobile target changes, Metro behavior, or native dependency setup.",
2026-06-10 15:01:09 -05:00
"read": [
"llm.txt",
"manifest.llm.json",
"AGENTS.md",
"metro.config.js",
"index.js",
"App.tsx"
],
"policies": [
2026-06-12 08:19:40 -05:00
"Do not modify android/ or ios/ native files unless explicitly requested and those folders exist.",
"Run pod install inside ios/ after native dependency changes when ios/ exists.",
"Keep shared src/ free of browser-only APIs."
2026-06-10 15:01:09 -05:00
]
},
"testing": {
2026-06-12 08:19:40 -05:00
"description": "Jest tests for logic, stores, routes, socket helpers, or screen scaffolding.",
2026-06-10 15:01:09 -05:00
"read": [
"llm.txt",
"manifest.llm.json",
"<target source>",
"<related __tests__ file>"
],
"verify": [
2026-06-12 08:19:40 -05:00
"npm run test -- --runInBand"
2026-06-10 15:01:09 -05:00
]
},
2026-06-12 08:19:40 -05:00
"docs": {
"description": "README, AGENTS, llm.txt, manifest, docs, or wiki maintenance.",
2026-06-10 15:01:09 -05:00
"read": [
2026-06-12 08:19:40 -05:00
"README.md",
"AGENTS.md",
2026-06-10 15:01:09 -05:00
"llm.txt",
"manifest.llm.json",
2026-06-12 08:19:40 -05:00
"package.json",
"src/navigation/routes.ts"
2026-06-10 15:01:09 -05:00
],
2026-06-12 08:19:40 -05:00
"verify": [
"node -e \"JSON.parse(require('fs').readFileSync('manifest.llm.json','utf8')); console.log('manifest ok')\"",
"npm run lint"
2026-06-10 15:01:09 -05:00
]
}
},
"rootCommands": [
2026-06-12 08:19:40 -05:00
{
"command": "npm run dev",
"purpose": "Alias for browser development.",
"target": "web"
},
2026-06-10 15:01:09 -05:00
{
"command": "npm run web",
"purpose": "Vite dev server for browser iteration.",
"target": "web"
},
{
"command": "npm run web:build",
"purpose": "Production web build to dist/renderer/.",
"target": "web"
},
{
"command": "npm run web:preview",
"purpose": "Preview production web build.",
"target": "web"
},
2026-06-12 08:19:40 -05:00
{
"command": "npm run dev:toolkit",
"purpose": "Start local Toolkit Socket.IO server.",
"target": "toolkit-socket"
},
{
"command": "npm run dev:all",
"purpose": "Start browser app and Toolkit socket together.",
"target": "web+toolkit-socket"
},
{
"command": "npm run dev:clear",
"purpose": "Stop related local dev processes if a run hangs.",
"target": "local-dev"
},
2026-06-10 15:01:09 -05:00
{
"command": "npm run electron:dev",
"purpose": "Run Vite dev server and Electron concurrently.",
"target": "electron"
},
{
"command": "npm run electron:build",
2026-06-12 08:19:40 -05:00
"purpose": "Build renderer and compile Electron main/preload files.",
2026-06-10 15:01:09 -05:00
"target": "electron"
},
{
"command": "npm run electron:package",
"purpose": "Build and package desktop installer via electron-builder.",
"target": "electron"
},
{
"command": "npm run start",
"purpose": "Start Metro bundler.",
2026-06-12 08:19:40 -05:00
"target": "mobile"
2026-06-10 15:01:09 -05:00
},
{
"command": "npm run android",
2026-06-12 08:19:40 -05:00
"purpose": "Run on Android emulator or device when android/ exists.",
2026-06-10 15:01:09 -05:00
"target": "android"
},
{
"command": "npm run ios",
2026-06-12 08:19:40 -05:00
"purpose": "Run on iOS simulator or device when ios/ exists.",
2026-06-10 15:01:09 -05:00
"target": "ios"
},
{
"command": "npm run lint",
"purpose": "ESLint."
},
{
"command": "npm run test",
"purpose": "Jest test suite."
2026-06-12 08:19:40 -05:00
},
{
"command": "npm run validate:commit",
"purpose": "Pre-commit safety check: lint, Jest, and Electron build."
2026-06-16 11:19:24 -05:00
},
{
"command": "npm run version:bump-build",
"purpose": "Increment the package patch version, update public .env build metadata, and stage package/env metadata before a commit."
2026-06-10 15:01:09 -05:00
}
],
"knownGaps": [
2026-06-16 11:19:24 -05:00
"docs/ is still a placeholder README stub.",
2026-06-12 08:19:40 -05:00
"No JSON Schema validator exists yet for manifest.llm.json.",
"Toolkit content panels are read-only scaffolds except for socket/store save plumbing.",
2026-06-16 11:19:24 -05:00
"Toolkit placeholder JSON files are intentionally empty arrays until content schemas are requested.",
2026-06-12 08:19:40 -05:00
"Native android/ and ios/ folders are not currently present in this checkout.",
"No database exists yet; editable content is intentionally JSON-backed until schemas stabilize."
2026-06-10 15:01:09 -05:00
],
"verificationBaseline": {
"logicOrStoreChanges": [
2026-06-12 08:19:40 -05:00
"npm run test -- --runInBand"
2026-06-10 15:01:09 -05:00
],
"uiChanges": [
"npm run lint",
2026-06-12 08:19:40 -05:00
"npm run test -- --runInBand",
"npm run web:build"
2026-06-10 15:01:09 -05:00
],
"webElectronChanges": [
"npm run lint",
2026-06-12 08:19:40 -05:00
"npm run test -- --runInBand",
"npm run electron:build"
],
"socketChanges": [
"npm run test -- --runInBand",
"npm run dev:toolkit",
"curl http://127.0.0.1:5174/health"
2026-06-10 15:01:09 -05:00
],
"mobileChanges": [
"npm run lint",
2026-06-12 08:19:40 -05:00
"npm run test -- --runInBand"
],
"docsChanges": [
"node -e \"JSON.parse(require('fs').readFileSync('manifest.llm.json','utf8')); console.log('manifest ok')\"",
"npm run lint"
2026-06-10 15:01:09 -05:00
]
}
}