Skip to content

Contributing

Development Setup

sh
git clone https://github.com/runeya/runeya.git
cd runeya
yarn install
yarn build
yarn dev

The UI is available at http://localhost:5173, the server at http://localhost:9545.

Essential Commands

sh
# Full build (turbo, respects dependency order)
yarn build

# Tests
yarn test
yarn workspace @runeya/apps-agent vitest run

# Lint
yarn lint

# Validate monorepo conventions
yarn check-monorepo

# Codebase index (for navigation)
node scripts/index-codebase.mjs | grep -i "keyword"

Adding a Field to ServiceConfig

Required order (do not skip any step):

  1. packages/shared/src/schemas/service.schema.ts — add the Zod field
  2. yarn workspace @runeya/packages-shared buildmandatory before any other step
  3. apps/server/src/trpc/routers/service.ts — two inline schemas: create and update
  4. apps/server/src/services/service-store.tscreate() and update() spreads
  5. apps/web/src/components/service/ServiceConfigGeneral.vue — form ref, watch, save, template

Code Conventions

ESM Imports

typescript
// ✅ Always use .js extension (even for .ts files)
import { foo } from './foo.js'

// ❌ Without extension
import { foo } from './foo'

tRPC Subscriptions

typescript
// ✅ Async generator (tRPC v11)
myProcedure: protectedProcedure.subscription(async function* ({ ctx }) {
  for await (const event of ctx.emitter) {
    yield event
  }
})

Security

  • All routes → protectedProcedure (except health.check)
  • Zod schemas: .max() on all strings and arrays
  • Never ...process.env → use buildSafeEnv() instead
  • decryptValue() throws on error, never returns the ciphertext

Vue 3 — Reactivity

typescript
// ✅ Replace ref arrays (never mutate in place)
items.value = [...items.value, newItem]

// ❌ In-place mutation
items.value.push(newItem)

Git Hooks

Husky + lint-staged run on git commit:

  • eslint --fix on staged .ts/.tsx/.js/.jsx files

Tests

  • Vitest for all packages
  • Singleton pattern: vi.resetModules() + vi.doMock() + dynamic import
  • Never mark a flaky test as "to ignore" without authorization

PR Checklist

  • [ ] yarn build passes without errors
  • [ ] yarn test passes
  • [ ] yarn lint passes
  • [ ] yarn check-monorepo passes
  • [ ] New ServiceConfig fields: all 5 steps completed
  • [ ] No console.debug in production
  • [ ] Secrets never in plaintext in logs
  • [ ] No unjustified shell: true

Released under the MIT License.