agentleFS
niieaniniieani/caara/AGENTS.md

caara

AGENTS.md4 starsChanged 4 months agoMITView on GitHub

This project ("caara") an OpenAI-compatible Responses API wrapper for other code agents (Claude Code, Antigravity) designed to enable spawning those agents as Codex's subagents. Context on project + vocabulary in: ./CONTEXT.md Decisions in ./docs/adr/ The spec in ./docs/caara.md Codex subagent smoke flow in ./docs/agents/smoke-testing.md Lint: bun lint (biome + oxlint) Format: bun fmt (oxfmt) Stack: Bun + TypeScript + Vitest + Effect TS (v4, latest beta) Use Bun instead of Node.js for both engine and package manager. Run Bun scripts…

  • Reads credentials

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

31 rules. About 0 are common, 7 are distinctive, and 24 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 24

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use Bun instead of Node.js for both engine and package manager.

    line 13
  2. Very specific:

    Run Bun scripts as bun run <script> <args>.

    line 14
  3. Very specific:

    Never run bun test, always run bun run test <vitest filters/options> for testing (vitest, not bun's built-in test runner).

    line 15
  4. Distinctive:

    AVOID making assumptions about APIs.

    line 28
  5. Very specific:

    Do not assume CLI flags/args.

    line 33
  6. Very specific:

    Test files: *.test.ts; no __tests__ directories.

    line 37
  7. Distinctive:

    When creating/fixing tests, run individual files instead of the whole project.

    line 38
  8. Very specific:

    Create and use the src/__experiments__/ subdirectory under any of the packages for throwaway code, and prototyping.

    line 40
  9. Distinctive:

    Treat typecheck suggestions TS377* as blocking and resolve any issues before finishing.

    line 42
  10. Very specific:

    Read docs/agents/testing-patterns.md before writing or modifying tests.

    line 46
  11. Very specific:

    Use the tstyche testing library when writing type tests.

    line 56
  12. Very specific:

    Use existing project .tst.ts files first.

    line 59
  13. Very specific:

    If a type exists, use it. NEVER use any, or cast to any, for external/unverified inputs use unknown, and use an Effect Schema to validate …

    line 71
  14. Very specific:

    use import type or import { type X } whenever possible (verbatimModuleSyntax: true)

    line 72
  15. Very specific:

    never use dynamic imports (await import(...)), unless asked to

    line 73
  16. Very specific:

    prefer satisfies ... and as const where possible, avoid casting using as

    line 74
  17. Distinctive:

    prefer immutable/readonly types

    line 75
  18. Distinctive:

    Do not add extra defensive checks or try/catch blocks

    line 79
  19. Very specific:

    Prefer nullish coalescing ??

    line 82
  20. Very specific:

    Prefer undefined over null if valid

    line 83
  21. Very specific:

    Use ??= operator when appropriate

    line 84
  22. Very specific:

    When writing functions, prefer a single destructured object as the only argument (fn({opt1, opt2})).

    line 85
  23. Very specific:

    Use latest ECMAScript 2026 features (esnext) including all stage 4 TC39 proposal up to 2025, like Symbol.dispose, using, etc.

    line 86
  24. Distinctive:

    Do not create barrel files, or files that re-export everything from a module.

    line 87
  25. Very specific:

    If committing, run bun run fmt prior.

    line 93
  26. Very specific:

    If any dependency is missing, install it, use matching version with the rest of effect if possible.

    line 129
  27. Very specific:

    Prefer the class syntax when working with Context.Service.

    line 156
  28. Very specific:

    Instead use Effect apis like Effect.fnUntraced, Effect.gen, Effect.tryPromise etc.

    line 168
  29. Distinctive:

    Look at existing code in the repository to learn and follow established patterns

    line 171
  30. Very specific:

    Instead use the Clock module, and TestClock for adjusting time in tests.

    line 175
  31. Very specific:

    CRITICAL: Always use return yield* when yielding terminal effects.

    line 209

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

This project ("caara") an OpenAI-compatible Responses API wrapper for other code agents (Claude Code, Antigravity) designed to enable spawning those agents as Codex's subagents.

Context on project + vocabulary in: ./CONTEXT.md Decisions in ./docs/adr/ The spec in ./docs/caara.md Codex subagent smoke flow in ./docs/agents/smoke-testing.md

Lint: bun lint (biome + oxlint) Format: bun fmt (oxfmt)

Stack: Bun + TypeScript + Vitest + Effect TS (v4, latest beta)

Use Bun instead of Node.js for both engine and package manager. Run Bun scripts as bun run <script> <args>; do not insert -- before script args. Never run bun test, always run bun run test <vitest filters/options> for testing (vitest, not bun's built-in test runner). Bun automatically loads .env, so don't use dotenv.

To quickly eval some code, run a command like:

FOO="$foo" bun run - <<'BUN'
console.log("hello", process.env.FOO);
BUN

References

AVOID making assumptions about APIs. Whenever working with a library, ALWAYS consult:

  • node_modules/bun-types/docs/**.mdx - Bun engine, API and PM
  • references/effect/* - Effect library and docs
  • references/vitest/docs/{guide,api}/* - docs and reference for Vitest
  • Do not assume CLI flags/args; verify with --help or run the command.

Validation and testing

Test files: *.test.ts; no __tests__ directories. Type tests: *.tst.ts. When creating/fixing tests, run individual files instead of the whole project.

Create and use the src/__experiments__/ subdirectory under any of the packages for throwaway code, and prototyping. Bravely create throwaway code and tests to explore, troubleshoot, understand how to use a library or API. They're ignored by git and linters.

Treat typecheck suggestions TS377* as blocking and resolve any issues before finishing.

Testing patterns

Read docs/agents/testing-patterns.md before writing or modifying tests; it is authoritative. Runtime lane = service-process integration tests under src/runtime, split into concurrent and serial Vitest projects. Non-runtime lane = in-process unit/integration tests outside src/runtime. For manual Codex subagent smoke tests, follow docs/agents/smoke-testing.md. Authenticated or metered Agent smokes must never be implemented as Vitest or other executable test code. Specify them as Markdown agent-executed playbooks under docs/agents/smoke-prompts/, linked from docs/agents/smoke-testing.md, and run them only after explicit user authorization. Automated tests must intercept or simulate the real Codex, Claude, and Antigravity boundaries.

Type level tests

Use the tstyche testing library when writing type tests. You can run them with bun run test:types <filename>.

Use existing project .tst.ts files first; use references/effect examples only when project examples are insufficient.

Code Style Guidelines

Implement using a maximally decoupled, DI/component/plugin-based architecture whenever possible. Performance is key! Avoid workarounds, do things the right way, not the quick way. Code should be clean, readable, and maintainable. Prioritize clarity over cleverness. Each symbol (incl. const, function, class) should be annotated with TSDoc with a detailed description of what it does and what it is for. Don't repeat types in TSDoc, they are already present in the code.

TypeScript:

  • strict mode
  • If a type exists, use it. NEVER use any, or cast to any, for external/unverified inputs use unknown, and use an Effect Schema to validate them to a strict type
  • use import type or import { type X } whenever possible (verbatimModuleSyntax: true)
  • never use dynamic imports (await import(...)), unless asked to
  • prefer satisfies ... and as const where possible, avoid casting using as
  • prefer immutable/readonly types

Code:

  • Do not add extra defensive checks or try/catch blocks
  • Files or folders whose names contain .gen are generated artifacts. Never edit them manually; update the generator or source inputs and regenerate them.
  • Node Builtins: use the node: prefix when importing, e.g. node:fs instead of fs.
  • Prefer nullish coalescing ?? operator instead of || when applicable
  • Prefer undefined over null if valid
  • Use ??= operator when appropriate
  • When writing functions, prefer a single destructured object as the only argument (fn({opt1, opt2})). In some cases fn(requiredArgument, {opt1, opt2}) signature is acceptable. Do NOT create functions with >3 arguments, unless absolutely necessary.
  • Use latest ECMAScript 2026 features (esnext) including all stage 4 TC39 proposal up to 2025, like Symbol.dispose, using, etc.
  • Do not create barrel files, or files that re-export everything from a module.
  • Constructors should be synchronous and never start any async operations; use methods if async initialization is required
  • Naming: camelCase for variables/functions/filenames, PascalCase for classes/types

Handoff

If committing, run bun run fmt prior.

Agent skills

Issue tracker

Issues are tracked in fp. See docs/agents/issue-tracker.md.

Brainstorms and other fp features: @FP_AGENTS.md

Triage labels

Triage roles use the default label vocabulary. See docs/agents/triage-labels.md.

Domain docs

This is a single-context repo: read root CONTEXT.md and root docs/adr/ when present. See docs/agents/domain.md.

Effect v4

Full source code and docs available in references/effect/*. Review patterns from there to understand how to write Effect v4 code.

v4 has some differences from the previous major versions:

Functionality that was spread across @effect/platform, @effect/rpc, @effect/cluster, and others now lives directly inside effect

Packages that remain separate are platform-specific, provider-specific, or technology-specific implementations:

  • @effect/platform-* — platform packages
  • @effect/sql-* — SQL driver packages
  • @effect/ai-* — AI provider packages
  • @effect/opentelemetry — OpenTelemetry integration
  • @effect/atom-* — framework-specific atom bindings
  • @effect/vitest — Vitest testing utilities

If any dependency is missing, install it, use matching version with the rest of effect if possible.

Effect AI MCP no-arg tools exposed to Codex/OpenAI need raw JSON Schema parameters: { type: "object", properties: {}, additionalProperties: false }. Schema.Struct({}) advertises an object-or-array union, and Tool.EmptyParams omits explicit properties.

Prefer Effect.fnUntraced over functions that return Effect.gen

Instead of writing:

const fn = (param: string) =>
  Effect.gen(function*() {
    // ...
  })

Prefer:

const fn = Effect.fnUntraced(function*(param: string) {
  // ...
})

Using Context.Service

Prefer the class syntax when working with Context.Service. For example:

import { Context } from "effect"

class MyService extends Context.Service<MyService, {
  readonly doSomething: (input: string) => number
}>()("MyService") {}

Never use async / await or try / catch

Instead use Effect apis like Effect.fnUntraced, Effect.gen, Effect.tryPromise etc.

Look at existing code in the repository to learn and follow established patterns

Never use Date.now or new Date

Instead use the Clock module, and TestClock for adjusting time in tests.

Effect Library Development Patterns

NEVER: try-catch in Effect.gen

REASON: Effect generators handle errors through the Effect type system, not JavaScript exceptions.

// ❌ WRONG - This will cause runtime errors
Effect.gen(function*() {
  try {
    const result = yield* someEffect
    return result
  } catch (error) {
    // This will never be reached and breaks Effect semantics
    console.error(error)
  }
})

// ✅ CORRECT - Use Effect's built-in error handling
Effect.gen(function*() {
  const result = yield* Effect.result(someEffect)
  if (result._tag === "Failure") {
    // Handle error case properly
    console.error("Effect failed:", result.cause)
    return yield* Effect.fail("Handled error")
  }
  return result.value
})

return yield* Pattern for Errors

CRITICAL: Always use return yield* when yielding terminal effects.

// ✅ CORRECT - Makes termination explicit
Effect.gen(function*() {
  if (invalidCondition) {
    return yield* Effect.fail("Validation failed")
  }

  if (shouldInterrupt) {
    return yield* Effect.interrupt
  }

  // Continue with normal flow
  const result = yield* someOtherEffect
  return result
})

// ❌ WRONG - Missing return keyword leads to unreachable code
Effect.gen(function*() {
  if (invalidCondition) {
    yield* Effect.fail("Validation failed") // Missing return!
    // Unreachable code after error!
  }
})

When to Use What

Use Effect.gen when:

  • Writing inline effect composition
  • One-off operations that don't need to be reused
  • Inside other functions already being traced

Use Effect.fnUntraced when:

  • Building library implementations
  • Performance is critical (hot paths)
  • Function is called many times per operation
  • Tracing overhead is unacceptable

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.