Ctrl K
ComunidadGuías…

AGENTS.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# AGENTS.md

Repo-wide agent instructions for `sixb`.

## Scope

- This file applies to the whole repository unless a nearer `AGENTS.md` is added later.
- Keep one root `AGENTS.md` for now. Add nested files only when a package genuinely needs different instructions.

## Repo Map

- `packages/core`: runtime, ontology builders, providers, and validation
- `packages/server`: Elysia HTTP/WebSocket API and OpenAPI generation
- `packages/ui`: shared React component library; knows nothing about Sixb, so the docs site uses it
- `packages/client`: generated typed client artifacts
- `packages/cli`: CLI entrypoint for `sixb`
- `packages/create-sixb`: zero-dependency project scaffolder and template
- `packages/app`: the project app: shell, built-in pages (Home, the agent, object pages, and the
  Console and Settings sections in `src/pages/`), dev server and build
- `models/`: model providers such as Anthropic and Vercel AI Gateway
- `connectors/`, `storage/`, `broker/`: integrations and infrastructure providers
- `env/`: where a project's environment variables live, such as Doppler
- `examples/`: runnable sample projects

## Toolchain

- Bun only for package management, scripts, and runtime. Do not use `npm`, `pnpm`, `yarn`, or Vite CLI commands.
- TypeScript is `strict`, targets ES2022, uses ESNext modules, and `moduleResolution: "bundler"`.
- Formatting and linting are enforced with Biome.
- Prefer `rg` and `rg --files` for search.

## Core Commands

Repo-wide:

```bash
bun install
bun run build
bun run typecheck
bun run test
bun run test:e2e
bun run test:all
bun run check
bun run check:fix
bun run generate:client
bun sixb dev
bun create-sixb my-app
```

Targeted:

```bash
bun --filter @sixb/core build
bun --filter @sixb/core typecheck
bun test packages/core/tests/create-sixb.test.ts
bun test packages/server/tests/
```

CI runs these as independent parallel jobs (each does `bun install --frozen-lockfile` first):

- `typecheck`: `bun run typecheck`
- `build`: `bun run build`, then `bun run typecheck:consumers`, then `bun run test:publish`
- `client`: `bun run generate:client`, then `git diff --exit-code`
- `test`: `bun run test:ci`
- `lint`: `bun run check`
- `e2e`: package-scoped matrix jobs for packages with `test:e2e`

`test:ci` is `bun test` wrapped in `scripts/ci-guard.ts`, which fails the run at the first 60-second
silence and prints the last test file, the process tree, and each thread's kernel wait state. The
job's `timeout-minutes` is only a backstop: a job that dies at its own wall clock reports
"cancelled" with the log ending mid-stream, which is indistinguishable from every other cause. The
guard exists because a `Bun.build()` deadlock once cost five 15-minute runs before anyone found the
one named failure buried in the log.

Run `test:ci` outside restricted process sandboxes. Its self-tests exercise process inspection and
signaling, and several suite fixtures require local process or network access. In Codex, request
elevated sandbox permissions before the first full-suite run instead of rerunning after an expected
restricted failure.

`typecheck` runs `bun check`, Bun's built-in TypeScript 7 checker, over source: the build graph
(`-b -p tsconfig.build.json`, every package's `src` once), the test files (`tsconfig.tests.json`),
the template and the docs app. The root `paths` map resolves `@sixb/*` to source, so nothing has to
be built first. Every call passes `--no-script`: the root `check` script is Biome, and `bun check`
runs a package's `check` script instead of the checker when one exists. It emits nothing, so
declaration-emit errors surface in `build:types` (`tsc -b`, TypeScript 5.9) in the build job.

`typecheck:consumers` checks the examples and the client's ontology-registry type program the way an
app is checked: with `tsc`, the version apps install, against the emitted `.d.ts`. It needs a prior
`bun run build` (or `build:types`), which is why CI runs it in the build job.

The root config maps `@sixb/*` to `packages/*/src`, which is right for workspace development and
wrong for consumer typechecks: it pulls the whole framework into each example's program. Examples
keep that config as their default because Bun reads it while bundling dev apps. Their typecheck
scripts alone pass `--paths null`, which clears the inherited mapping and lets `tsc` resolve each
package's `exports.types`.

That override applies only there. `apps/docs` stays entirely on the root config because Vercel
deploys it with `prepare:docs && next build` and never emits declarations — pointing it at `dist`
broke the deployment once already. Anything built or run outside `typecheck:consumers` reads
source.

## Architecture

- Define ontology types with `defineObjectType`, `prop`, `link`, `action`, and `defineValueType`.
- Most runtimes start with `createSixb()`.
- `createSixb()` auto-discovers `ontology/`, `actions/`, `datasets/`, `syncs/`, `schedules/`, `pipelines/`, `projections/`, `connectors/`, `rules/`, `workflows/`, `shares/`, and `security/{groups,roles,markings,policies}/`, plus the Agent's `skills/<name>/SKILL.md` and project instructions in `SIXB.md`. The `app/` directory is served separately and is not part of `createSixb()` discovery.
- `sixb.objects(MyType)` is the typed API for object CRUD, telemetry, links, and actions.
- Important domain events include `object.created`, `object.updated`, `object.deleted`, `link.created`, `link.updated`, `link.deleted`, `telemetry.appended`, and `schedule.triggered`.
- Convention-based discovery is the normal registration model.
- Generated client files live in `packages/client/src/generated/`.
- If routes, schemas, or public contracts change, run `bun run generate:client`.

## Export Surfaces

- Exports are curated — never re-export something from a barrel just because it exists. If nothing imports it, it does not belong on a public surface; a selector or helper that can only return nothing is dead API.
- A package root (`.`) is for app authors: `@sixb/core` exports the authoring API (`define*`, `createSixb`, config types, and the `InMemory*` providers that fill a `createSixb` slot); other packages export only what consumers call (workers export just their `*Worker` class).
- These six are the provider contracts a third party implements: `@sixb/core/{broker,queues,sandboxes,lake-storage,blob-storage/server,auth/strategy}`.
- `@sixb/core/storage` is broader: it is both the read/run-history contract and where the in-memory storage implementations live. A third-party storage provider is not supported in 0.1.x — the materialization contract is still moving.
- A type that appears in a public interface signature must be exported from the same subpath as the interface, or the interface cannot be implemented from outside.
- `@sixb/core/internal/*` is for this repo's packages only — no compatibility promise. Nothing in `docs/`, `examples/`, `templates/`, or `apps/` may import from it.
- Export types freely (users need them to annotate their own code); keep runtime values minimal. Connectors export all their wire types on purpose.
- A package may import a sibling; it must never absorb one. Every bare specifier its JavaScript and TypeScript import — in `src` and in `dist` — has to be a declared `dependencies`/`peerDependencies`/`optionalDependencies` entry, and `test:publish` rejects the rest in both directions. `tsc` cannot: the root `paths` map resolves an undeclared `@sixb/*` import to source, so it type-checks and then the bundler inlines it. `scripts/package-boundaries.ts` holds the rule and explains the failure.
- It must not resolve a sibling to a second copy either. Bun applies the nearest `tsconfig.json` `paths` map to every import it resolves, `node_modules` included, so a built module inherits whatever map is above it: the build writes `dist/tsconfig.json` to stop that lookup, and it ships in the tarball because the map that reaches our `dist` is the consumer's. The same rule is why the root `paths` map has to keep naming exactly the file each subpath's `exports.bun` names — `test:publish` rejects it when it stops. A duplicated module is silent: the custom-app dev bundle once held two generated SDK clients, one configured and one answering to the page origin.
- Stylesheets served from `src` sit outside that check and stay a manual call. A bare `@import` in CSS is resolved by the consumer's Tailwind — relative to the stylesheet, then up through `node_modules` — not by the module resolver. `@sixb/ui` takes `tailwindcss` as an optional peer for exactly that reason: `@sixb/ui/globals.css` opens with `@import "tailwindcss"`, and only the consumer can satisfy it.

## Code Style

- Biome uses 2 spaces, LF endings, 100 column width, double quotes, ES5 trailing commas, and no semicolons unless required.
- Use `import type` and `export type` for type-only imports and re-exports.
- Prefer explicit public types, but preserve inference where Sixb's typed APIs are designed to carry it.
- Avoid `any`; narrow `unknown` instead of unchecked casts.
- Validate inputs early and throw clear, actionable errors.
- Package-prefixed error messages such as `[Sixb] ...`, `[SixbServer] ...`, or `[RokuTV] ...` are preferred.
- The framework never speaks in the user's logger. Report terminal failures through `onError` and write everything else to a prefixed `console.*`. A swallowed `events.append()` is a lost trigger edge: emit through `events.emit(input, { source })` when the work that produced the events has already succeeded, and `events.append(input)` when the caller owns the outcome. Never write a bare `catch` around an append.
- Keep builders and definitions declarative; avoid unnecessary indirection around ontology setup.
- Preserve the existing visual language in `packages/app` (and `packages/ui`) and keep both desktop and mobile behavior working.
- The code should be well-spaced and easy to read.

## Tests

- Test framework is `bun:test`.
- Tests live under `<package>/tests/`.
- Fast tests use `*.test.ts`.
- E2e tests use `*.e2e.ts` and run through `bun run test:e2e`.
- Prefer deterministic tests with temp directories, explicit cleanup, and fixed timestamps.
- `bun test` prints only when a file finishes, so a test's runtime is a silence. The unit suite's
  longest legitimate silence is a few seconds; `test:ci` fails at 60. A `*.test.ts` that can
  legitimately go quiet for longer belongs in `*.e2e.ts` with its own bound, not in the unit suite.
- Drive the bundler through a child process with a bound, not `Bun.build()` in the test process.
  Bun's bundler has deadlocked on hosted runners, a wedged bundler stays wedged for the life of the
  process, and the per-test timeout stops being a bound once it does — it fired for the deadlocked
  build and then not at all for the next bundler call, which hung until the job's wall clock.
  `packages/core/tests/published-artifacts.e2e.ts` shows the shape. The in-process exception is
  the dev-server cases in `packages/app/tests/createCustomApp.test.ts`, which serve Bun's HTML
  entry because that bundling *is* the behavior under test — it is why `test:ci` runs behind a
  guard at all.
- A guard is proven by removing it. Before landing a test that locks in a fix, revert the fix and
  watch the test fail — a test that passes either way locks in nothing, and reads for years as if
  it did. Say in the test how to reproduce that check, and say it there when a toolchain version
  is what makes the failure reachable.
- No `Bun.spawnSync` in a test. Inside `bun test --parallel` it sometimes never sees its child
  exit, so the test dies at its timeout or the worker spins beside a zombie until the CI guard
  kills the run. Spawn with async `Bun.spawn` and a kill timer, or call the code in-process when
  the process boundary is not what the test is about.
- Don't wait on real time. A test that sleeps through a backoff, a deadline or a "nothing
  arrives" window pays for it on every run and flakes under load. Drive the timer with
  `jest.useFakeTimers()`, or wait for the event the code emits; restore real timers in
  `afterEach`, because a fake-timer test that times out never reaches its own `finally`. A
  production option that exists only to shorten a test's wait is a test-only seam — don't add one.
- Await a rejection that might never settle as `await promise.catch((error) => error)`, not
  `expect(promise).rejects`: on Bun 1.4.4 the latter hangs the whole file past the per-test
  timeout, so a regression shows up as a guard stall instead of a named failure.
- A negative check must be able to fail. Asserting that a spy was not called before the async work
  that would call it could run, or that nothing arrived during a quiet window, passes either way.
  Assert on the durable record, or publish what should be filtered out first so the first thing
  delivered proves the filter.
- One owner per contract. Provider semantics belong to the shared suites in
  `packages/core/src/testing`, a helper's behavior to the helper's tests, a guard enforced for
  every route to that guard; a provider, resource or route suite proves only what is specific to
  it. Size fixtures to just past the page or chunk boundary they cross.
- Run targeted tests first, then broader checks when shared behavior changes.

## Contribution Flow

- `CONTRIBUTING.md` describes the repo's idea lifecycle, async handoff, and merge flow.
- Rough ideas are acceptable. Help shape them toward the clearest outcome and the simplest
  implementation.
- Issue and PR title patterns are:
  - `Idea: <desired outcome>`
  - `Task: <small shippable slice>`
  - `<area>: <what changed>`
- Ideas use the `idea` label and exactly one lifecycle label: `status:draft`, `status:review`,
  `status:approved`, or `status:completed`.
- AI-authored changes must still be cleaned up, verified, and human-readable before review.

## Local Drafts

- `/.local/` is a gitignored scratchpad for local-only working notes.
- Keep longer-running product or architecture notes in `/.local/bible.md`.
- Put draft ideas, draft specs, and issue writeups in `/.local/drafts/`.
- Treat `/.local/` files as staging material that will usually become GitHub issues, not committed repo docs.
- Only create or commit tracked docs when the content is ready to be shared, referenced, and maintained in the repository.

## Documentation

- Write documentation in English.
- Public docs address developers discovering Sixb: what they need to do and what behavior to
  expect. Explain features without requiring knowledge of the internal architecture. Include
  technical details and limitations only when they affect usage or a developer's decision.
- Document internals close to the code: execution flow, responsibilities, invariants, failure
  handling, and recovery. Use a focused README for mechanisms spanning multiple files; comments
  for local constraints.
- Explain what is not obvious from the code. Keep documentation concise, current, and free of
  duplicated explanations.
- Keep change history, implementation plans, and future work in PRs or local drafts.

## Working Norms

- Prefer focused, minimal diffs that match nearby code.
- Read the nearest `package.json`, source files, and tests before editing shared behavior.
- Update docs and tests when behavior or public APIs change.
- Do not switch package managers or add alternate tooling without explicit instruction.
- Do not revert unrelated dirty-worktree changes.
- Avoid destructive git operations unless explicitly requested.

## Quick References

- `packages/core/src/runtime/`: runtime entrypoints
- `packages/core/src/ontology/`: ontology builders and types
- `packages/server/src/routes/`: server routes
- `packages/client/src/generated/`: generated client output
- `packages/app/src/`: the app (built-in pages in `pages/`, sections listed in `sections/catalog.ts`,
  the agent in `agent/`, shared components in `packages/ui/src/`)