AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Shared build conventions for browser games: Vite 8, Vitest browser testing, Capacitor, tsup, TypeScript and Biome configs
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Shared build conventions for browser games. One dependency gives a project its Vite 8 config, its Vitest unit and real-browser test fragments, a Capacitor config, a tsup library build, and the TypeScript and Biome base configs, so a dozen game repositories stop drifting apart.
base, Rolldown code-splitting groups for
heavy vendors (three.js, Rapier, Phaser, Tone.js) or your own vendor chunks, HMR
watch-ignore, and an optional @ alias.server.hostname keeps
server.androidScheme.tsconfig.base.json and biome.base.json to extend.pnpm add -D build-preset vite vitest @vitest/browser-playwright playwright game-harness
game-harness provides the browser test config in the quick start below.
tsup is an optional peer: install it only if you use build-preset/tsup.
// vite.config.ts
import { defineGamePreset } from "build-preset/vite";
import path from "node:path";
export default defineGamePreset({
appName: "my-game",
srcDir: path.resolve(import.meta.dirname, "src"),
heavyDeps: { three: true, rapier: true },
});
// vitest.browser.config.ts: browser tests come from game-harness, the owner of browser QA
import { defineBrowserTestConfig } from "game-harness/vitest";
import { defineConfig } from "vitest/config";
const browserTest = defineBrowserTestConfig({
include: ["tests/browser/**/*.browser.test.ts"],
});
export default defineConfig({
optimizeDeps: { include: browserTest.__optimizeDepsInclude ?? [] },
test: browserTest,
});
// tsconfig.json
{ "extends": "build-preset/tsconfig.base.json" }
// biome.json
{ "extends": ["build-preset/biome.base.json"] }
heavyDeps toggles fixed groups. A game that splits vendor code by when it loads names its own
chunks. In declaration order, the first chunk matching a module takes it; chunks outrank
heavyDeps:
defineGamePreset({
appName: "example-game",
chunks: {
three: ["three"], // the title preloads these three...
r3f: ["@react-three/fiber"],
drei: ["@react-three/drei"],
rapier: ["@react-three/rapier", "@dimforge/rapier3d-compat"], // ...the room loads these
post: ["@react-three/postprocessing", "postprocessing", "n8ao"],
tone: ["tone"],
},
});
A string is an npm package name; a RegExp is tested against the module id. See
the Vite page for the precedence rules.
| Import | Exports |
|---|---|
build-preset | Everything below except /tsup (a thin barrel; prefer the subpaths) |
build-preset/vite | defineGamePreset, staticRouteExport, StaticRouteExportOptions, HeavyDepsOptions, VendorChunks, ChunkPattern |
build-preset/vitest | defineUnitTest, defineBrowserTest, defaultBrowserLaunchArgs |
build-preset/capacitor | defineCapacitorPreset, mergeCapacitorConfig, androidVersionGradleSnippet |
build-preset/tsup | libraryBuild |
build-preset/tsconfig.base.json, build-preset/biome.base.json | Shared configuration to extends |
The build-preset init-android command prints the CI-parameterized versionName and
versionCode block to paste into android/app/build.gradle.
See the API reference for every option and the architecture notes for why the presets behave as they do.
defineBrowserTest and defaultBrowserLaunchArgs are deprecated: browser QA has one owner, and it
is game-harness (defineBrowserTestConfig from game-harness/vitest). They stay for existing
consumers and are removed in the next major.
defineBrowserTest is headed-only. It constructs the Vitest Playwright provider itself and puts
--mute-audio in provider.options.launchOptions.args, so a silent run does not depend on a
consumer remembering to copy a launch-argument array. It throws on a headless option and on any
hidden --headless Chromium argument. Muting the audio does not change a player's saved audio
preference: the consumer still asserts a non-persistent runtime mute route in its own tests.
| Supported | |
|---|---|
| Node.js | 22, 24 and 26 (CI verifies each on Linux; Windows on 26) |
| Vite | ^8.2.1 |
| Vitest | ^4.1.10 or ^5.0.0 |
@vitest/browser-playwright | ^4.1.10 or ^5.0.0, matching Vitest |
| Playwright | >=1.62.1 <2 |
| tsup (optional) | ^8.5.0 |
The Vitest 4 and Vitest 5 lines are both exercised by the packed-consumer smoke in CI.
mise install # Node 26 and pnpm 12, or `corepack enable`
pnpm install
pnpm verify # Biome, markdownlint, tsc, tests with coverage, build, publint, attw, packed-consumer smoke
pnpm docs:build # the Sourcey documentation site
See CONTRIBUTING.md. Releases are automated by Release Please and published to npm with provenance from GitHub Actions.