chore(.agents/skills,AGENTS.md): new harness prompt
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: enforce-rules-for-unocss
|
||||
description: Enforce AIRI's UnoCSS, Vue styling, shared UI component, animation, icon, and color-mode practices. Use when creating, editing, refactoring, or reviewing Vue templates, component styles, utility classes, UnoCSS configuration, animations, icons, UI primitives, packages/ui components, or VueUse dark-mode behavior in the AIRI monorepo.
|
||||
---
|
||||
|
||||
# Enforce AIRI UnoCSS Rules
|
||||
|
||||
Apply these rules to every affected UI file in AIRI.
|
||||
|
||||
## Compose Utility Classes Readably
|
||||
|
||||
- Prefer UnoCSS over Tailwind CSS.
|
||||
- In Vue templates, bind grouped class arrays for readability:
|
||||
|
||||
```vue
|
||||
:class="[
|
||||
'px-2 py-1',
|
||||
'flex items-center',
|
||||
'bg-white/50 dark:bg-black/50',
|
||||
]"
|
||||
```
|
||||
|
||||
- Do not use long inline class strings such as `class="px-2 py-1 flex items-center bg-white/50 dark:bg-black/50"`.
|
||||
- Do not use attributify-style groups such as `px="2" py="1" flex="~ items-center" bg="white/50 dark:black/50"`.
|
||||
- When touching legacy utility classes, progressively refactor them into readable grouped arrays.
|
||||
|
||||
## Reuse Project Styling Infrastructure
|
||||
|
||||
- Use or extend shortcuts and rules in `uno.config.ts` when styles should be standardized or reused.
|
||||
- Search `apps/stage-web/src/styles` for existing animations before adding one. Reuse or extend an existing animation when it fits.
|
||||
- Consult `apps/stage-web/tsconfig.json` and `uno.config.ts` when configuration context is needed.
|
||||
- Keep animations intuitive, lively, and readable.
|
||||
|
||||
## Build on Shared UI Primitives
|
||||
|
||||
- Build primitives on `@proj-airi/ui`, which is based on reka-ui, instead of raw DOM controls.
|
||||
- Read `docs/ai/context/ui-components.md` for the component API and `packages/ui/src/components/Form` for implementation patterns.
|
||||
- When adding or updating a component in `packages/ui`, update `docs/ai/context/ui-components.md` with its description, props, slots, and emits.
|
||||
- Use Iconify icon sets instead of bespoke SVGs.
|
||||
|
||||
## Preserve Theme Behavior
|
||||
|
||||
- When using VueUse `useDark`, set `disableTransition: false` or use an existing composable from `packages/ui`.
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "Enforce UnoCSS Rules"
|
||||
short_description: "Apply AIRI styling and component standards"
|
||||
default_prompt: "Use $enforce-rules-for-unocss to implement or review AIRI UI styling."
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: enforce-rules-for-vitest
|
||||
description: Enforce AIRI's testing and Vitest practices. Use when creating, editing, reviewing, or debugging tests; reproducing a reported bug or issue; changing Vitest configuration; mocking IPC, services, providers, platform APIs, or imports; or diagnosing test import and runtime-boundary failures in the AIRI monorepo.
|
||||
---
|
||||
|
||||
# Enforce AIRI Vitest Rules
|
||||
|
||||
Apply these rules to every test change in AIRI.
|
||||
|
||||
## Choose the Test Scope
|
||||
|
||||
- Use the Vitest project that owns the affected code and keep runs targeted for speed.
|
||||
- Grow component and end-to-end coverage progressively. Prefer Vitest browser mode when the behavior depends on DOM or Web Platform APIs.
|
||||
- Use the smallest automated test that faithfully exercises the behavior: prefer a unit test, then the smallest suitable higher-level test.
|
||||
|
||||
## Reproduce Bugs Before Fixing Them
|
||||
|
||||
1. For an investigated bug or issue, try to add a test-only reproduction before changing production code.
|
||||
2. When reproduction is possible, include the tracker identifier in the test case name:
|
||||
- Use `Issue #<number>` for a GitHub issue.
|
||||
- Use the Linear issue key for an internal Linear bug.
|
||||
3. Put the actual report URL in a comment directly above the regression test. Use the GitHub issue URL, Discord message or thread URL, or Linear issue URL as appropriate.
|
||||
4. Confirm that the reproduction fails for the reported reason before implementing the fix.
|
||||
|
||||
## Mock Real Boundaries
|
||||
|
||||
- Mock Electron IPC and Electron services with `vi.fn` or `vi.mock`; never require a real Electron runtime.
|
||||
- For external providers and services, add mock-based tests and, when feasible, integration-style tests guarded by environment variables, but do not mock Pinia, Vue components. Vitest import mocks are allowed for these boundaries.
|
||||
- Assert observable behavior, including mock calls and parameters, with explicit `expect` statements.
|
||||
- Prefer one assertion per line so failures remain readable.
|
||||
|
||||
## Preserve Runtime Integrity
|
||||
|
||||
- Do not test impossible runtime states. Avoid assertions against constants that cannot change or object mutations that can only occur inside the same test setup.
|
||||
- Do not replace `globalThis` properties or built-in modules with direct `Object.defineProperty(...)` mocks.
|
||||
- When behavior depends on a different Node global or built-in state, use `node:worker_threads` to load an isolated worker or build a minimal CLI reproduction.
|
||||
- For DOM and Web Platform APIs, use Vitest browser mode instead of hard-mocking platform internals. Progressively refactor existing direct platform mocks when touched.
|
||||
|
||||
## Fix Import Boundaries, Not Tests
|
||||
|
||||
Never use Vitest mocks, hoisting, dynamic imports, `as unknown as`, or test-only alternate import paths to conceal a real import failure.
|
||||
|
||||
If a test cannot import a module, investigate and fix the production boundary:
|
||||
|
||||
- package exports and declarations;
|
||||
- import-time side effects;
|
||||
- mixed Node and browser type dependencies;
|
||||
- circular imports;
|
||||
- an incorrect public module shape.
|
||||
|
||||
Keep the test importing the same supported boundary that production consumers use.
|
||||
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "Enforce Vitest Rules"
|
||||
short_description: "Apply AIRI testing and Vitest standards"
|
||||
default_prompt: "Use $enforce-rules-for-vitest to implement or review tests under AIRI's testing standards."
|
||||
@@ -1,89 +0,0 @@
|
||||
---
|
||||
name: server-gateway-refactor
|
||||
description: Use when refactoring AIRI apps/server routes that mix Hono route wiring, business operation orchestration, external gateway calls, billing, rate limiting, telemetry, or websocket session state. Applies especially to OpenAI-compatible, speech, Stripe, and websocket gateway surfaces.
|
||||
---
|
||||
|
||||
# Server Gateway Refactor
|
||||
|
||||
Use this skill when an `apps/server` route file has grown into a mixed transport/business/infra module and the user wants it engineered rather than merely split by line count.
|
||||
|
||||
## First Read
|
||||
|
||||
Start from the exact route file the user named. Read nearby tests and domain services before editing. Use `rg` for call sites and avoid deleting legacy routes without checking tests/docs/env references.
|
||||
|
||||
Look for these responsibilities:
|
||||
|
||||
- HTTP/WebSocket transport shape: Hono routes, auth, request parsing, response mounting, upgrade setup.
|
||||
- Gateway operation shape: authenticated user, parsed body/query, operation id, model/provider routing, external calls.
|
||||
- Infra behavior: billing, rate limiting, telemetry/tracing, request logs, PostHog, retries, cache.
|
||||
- Domain services: persistence, Stripe records, character/provider ownership, chat messages, flux transactions.
|
||||
|
||||
## Boundary Rules
|
||||
|
||||
- Keep Hono middleware as Hono middleware only when it can run from raw `Context`: auth, config availability, static files, IP-level limits.
|
||||
- Use gateway middleware when the decision needs parsed gateway context: user id, operation id, request body, requested model, resolved model, streaming lifecycle, usage, or billing state.
|
||||
- Prefer route-group scoped middleware for endpoint-specific behavior:
|
||||
- Good: `gateway.route('openai').use('chat.completions', rateLimit).post(...)`
|
||||
- Avoid: global gateway `.use('chat.completions', ...)` when the middleware is only meaningful for one endpoint group.
|
||||
- Do not create handler files that only pass through parse + operation. Inline thin adapters in the route index unless they hide meaningful protocol decisions.
|
||||
- Do not split by execution order alone. A module boundary should own a policy, operation, middleware, or external boundary.
|
||||
|
||||
## Naming
|
||||
|
||||
- File names use kebab-case, not camelCase.
|
||||
- Use HTTP names for transport files and operation names for business files.
|
||||
- Prefer `middlewares/` for both Hono and gateway middleware in this project when they are part of a route gateway surface.
|
||||
- Prefer `operations/<operation>/index.ts` for reusable operation orchestration.
|
||||
- Avoid `gateway` as a domain name unless the module really owns route/runtime composition.
|
||||
|
||||
## Preferred Shape
|
||||
|
||||
For gateway-like HTTP surfaces:
|
||||
|
||||
```ts
|
||||
const gateway = createXGateway(deps)
|
||||
.useHono('*', '*', authGuard)
|
||||
.useHono('surface', '/path/*', configGuard(...))
|
||||
|
||||
const surfaceRoutes = gateway.route('surface')
|
||||
.use('operation.id', operationMiddleware(...))
|
||||
.post('/path', surface.handler(
|
||||
'operation.id',
|
||||
async (c) => parseInput(c),
|
||||
operation(deps),
|
||||
))
|
||||
.route
|
||||
```
|
||||
|
||||
Keep route index readable:
|
||||
|
||||
- It should show route groups, endpoint paths, and endpoint-scoped middleware.
|
||||
- It may inline small parse adapters.
|
||||
- It should not contain long external-provider workflows, webhook switches, or billing settlement logic.
|
||||
|
||||
## Candidate Signals
|
||||
|
||||
Use this pattern when:
|
||||
|
||||
- One route file exceeds roughly 200-300 lines and mixes route wiring with external provider orchestration.
|
||||
- There are endpoint-specific middleware needs that cannot be represented as Hono middleware.
|
||||
- Tests describe operation behavior more than route matching.
|
||||
- The route has multiple business operations under one transport surface.
|
||||
|
||||
Do not force this pattern when:
|
||||
|
||||
- A CRUD route is already thin and delegates to a domain service.
|
||||
- The route mostly mounts framework-owned handlers, static assets, or metadata endpoints.
|
||||
- The logic belongs in an existing domain service instead of a new route gateway.
|
||||
|
||||
## Verification
|
||||
|
||||
After changes, run targeted validation before broader checks:
|
||||
|
||||
```sh
|
||||
pnpm exec vitest run apps/server/src/routes/<route>/route.test.ts
|
||||
pnpm -F @proj-airi/server typecheck
|
||||
pnpm exec eslint <changed files>
|
||||
```
|
||||
|
||||
If full `pnpm lint` fails from unrelated repo-wide issues, report that separately and keep targeted lint evidence.
|
||||
Reference in New Issue
Block a user