teableio_teable/agents.md
2026-02-11 12:28:13 +08:00

3.8 KiB

Teable v2 agent guide

DDD/domain-model guidance has moved to the skill teable-ddd-domain-model in .codex/skills/teable-ddd-domain-model. Use that skill for any v2/core domain, specification, or aggregate changes.

Git hygiene

  • Ignore git changes that you did not make by default; never revert unknown/unrelated modifications unless explicitly instructed.

v2 API contracts (HTTP)

For HTTP-ish integrations, keep framework-independent contracts/mappers in packages/v2/contract-http:

  • Define API paths (e.g. /tables) as constants.
  • Use action-style paths with camelCase action names (e.g. /tables/create, /tables/get, /tables/rename); avoid RESTful nested resources like /bases/{baseId}/tables/{tableId}.
  • Re-export command input schemas (zod) for route-level validation if needed.
  • Keep DTO types + domain-to-DTO mappers here.
  • Router packages (e.g. @teable/v2-contract-http-express, @teable/v2-contract-http-fastify) should be thin adapters that only:
    • parse JSON/body
    • create a container
    • resolve handlers
    • call the endpoint executor/mappers from @teable/v2-contract-http
  • OpenAPI is generated from the ts-rest contract via @teable/v2-contract-http-openapi.

UI components (frontend)

  • In app UIs (e.g. apps/playground), use shadcn wrappers from apps/playground/src/components/ui/* (or @teable/ui-lib) instead of importing Radix primitives directly.
  • If a shadcn wrapper is missing, add it under apps/playground/src/components/ui before using the primitive.

Dependency injection (DI)

  • Do not import tsyringe / reflect-metadata directly anywhere; use @teable/v2-di.
  • Do not use DI inside v2/core/src/domain/**; DI is only for application wiring (e.g. v2/core/src/commands/**).
  • Prefer constructor injection with explicit tokens for ports (interfaces).
  • Provide environment-level composition roots as separate packages (e.g. @teable/v2-container-node, @teable/v2-container-browser) that register all port implementations.

Build tooling (v2)

  • v2 packages build with tsdown (not tsc emit). tsc is used only for typecheck (--noEmit).
  • Each v2 package has a local tsdown.config.ts that extends the shared base config from @teable/v2-tsdown-config.
  • Outputs are written to dist/ (ESM .js + .d.ts), and workspace deps (@teable/v2-*) are kept external (no bundling across packages).

Source visibility (v2 packages)

All v2 packages must support source visibility to allow consumers to reference TypeScript sources without building dist/ outputs. This is required for development workflows, testing, and tools like Vitest/Vite that can consume TypeScript directly.

Required configuration:

  • In package.json:
    • Set types field to "src/index.ts" (not "dist/index.d.ts")
    • Set exports["."].types to "./src/index.ts" (not "./dist/index.d.ts")
    • Set exports["."].import to "./src/index.ts" (not "./dist/index.js") to allow Vite/Vitest to use source files directly
    • Keep exports["."].require pointing to "./dist/index.cjs" for CommonJS compatibility
    • Include "src" in the files array (in addition to "dist")
  • In tsconfig.json:
    • Map workspace dependencies to their src paths in compilerOptions.paths (e.g. "@teable/v2-core": ["../core/src"])
    • Include those source paths in the include array

Example package.json configuration:

{
  "types": "src/index.ts",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "import": "./src/index.ts",
      "require": "./dist/index.cjs"
    }
  },
  "files": ["dist", "src"]
}

Note: Since v2 packages are workspace-only ("private": true) and not published to npm, pointing import to source files is safe. Vite/Vitest can process TypeScript files directly, enabling faster development cycles without requiring dist/ to be built first.