ℹ️Idioma

Esta página está em português. A versão em inglês é a referência principal quando houver divergência.

Development Patterns

This page turns architecture boundaries into contributor decisions. Read Architecture Overview and relevant subsystem page first, then use this guide before editing architecture-facing code in AP-DIGITAL-SERVICES/cfly-factory or its cross-repository contracts.

ℹ️Default rule

Prefer CFactory-owned seams over broad changes to shared CFactory CLI files. Follow neighboring style when changing existing modules.

How to use this page

  1. Identify owning subsystem in architecture docs.
  2. Choose narrowest source boundary that can hold change.
  3. Update generated or cross-repository contracts when public surface changes.
  4. Run smallest relevant checks plus affected repository guards.

Where should change live?

Change shapePreferred location or actionReason
Additive CFactory CLI behaviorpackages/opencode/src/cfactory/Keeps related CFactory-specific behavior grouped together
CFactory CLI test for additive behaviorpackages/opencode/test/cfactory/Keeps CFactory-specific tests grouped together
VS Code, JetBrains, docs, indexing, UI, gateway, or telemetry changeExisting packageEdit the owning package directly
CLI server endpoint changeEffect HttpApi route plus handler; then run root SDK generatorKeeps server contract and generated JavaScript SDK aligned
JetBrains API contract changeShared CLI OpenAPI change; let Gradle regenerate build-local Kotlin clientKotlin client is generated during JetBrains build
CFactory-only config-key changeUpdate CLI Effect Schema and cloud JSON Schema overlayRuntime acceptance and editor validation are separate cross-repository paths
Docs page move or removalUpdate nav and add permanent redirectPreserves external links and bookmarks

Relationship to CFactory CLI

CFactory CLI began as a fork of CFactory CLI but is now a hard fork — the codebase is maintained independently with no upstream sync. Edit any file directly as first-party code; there are no change markers or shared-file merge constraints. CFactory-specific logic that was historically isolated still lives under packages/opencode/src/cfactory/ (tests under test/cfactory/); keep related new code near those modules for consistency.

GuardWhen to run
bun run script/check-forbidden-strings.tsAny change; fails on leftover upstream branding (e.g. opencode.ai referers)
bun run script/check-workflows.tsWorkflow add or remove changes; keeps workflow allowlist explicit

CLI server API

CLI server uses Effect HttpApi and publishes OpenAPI-compatible HTTP + SSE surfaces consumed by JavaScript SDK and JetBrains build-local Kotlin client.

RuleReason
Define shared routes under packages/opencode/src/server/routes/instance/httpapi/Keeps route contract close to runtime handlers
Normalize public spec in packages/opencode/src/server/routes/instance/httpapi/public.tsPreserves legacy-compatible request and response shapes during Effect migration
Put additive CFactory groups and handlers under packages/opencode/src/cfactory/server/httpapi/Reduces edits in shared upstream-owned files
Inject CFactory APIs through narrow shared seamKeeps upstream diff small and marker placement obvious
Preserve route spans and stable attributesKeeps diagnostics and telemetry understandable

SDK generation

CLI Runtime SDK contract owns generation pipeline detail. Contributor rules are short:

ChangeAction
Add or change CLI server endpointRun root ./script/generate.ts after route and handler edits
JavaScript SDK generated files under packages/sdk/js/src/v2/gen/Do not edit by hand
JavaScript SDK wrapper behaviorEdit handwritten packages/sdk/js/src/v2/client.ts
JetBrains generated Kotlin clientLet Gradle regenerate build-local client from normalized OpenAPI

CLI config schema

Runtime config loading and editor validation are separate paths. New CFactory-only config key requires CLI Effect Schema change in AP-DIGITAL-SERVICES/cfly-factory and JSON Schema overlay change in CFactory-Org/cloud. Follow CLI Config Schema for exact workflow.

Module export pattern

For new public APIs, prefer flat ESM exports inside module, then namespace re-exports from index files when grouped access helps callers.

// packages/opencode/src/session/session.ts
export const create = fn(CreateSchema, async (input) => {
  // ...
})

export const list = fn(ListSchema, async (input) => {
  // ...
})

// packages/opencode/src/session/index.ts
export * as Session from "./session"

Import specific export when practical. Use namespace shape (Session.create) when preserving existing API or grouped module access improves clarity. Existing CFactory-owned namespaces remain valid; do not refactor them solely for style.

Tool implementation

Tools use Tool.define("id", Effect.gen(...)) with Effect Schema validation and typed execution.

export const ExampleTool = Tool.define(
  "example",
  Effect.gen(function* () {
    return {
      description: "Example tool",
      parameters: Schema.Struct({
        value: Schema.String,
      }),
      execute(args) {
        return Effect.succeed({
          title: args.value,
          metadata: {},
          output: args.value,
        })
      },
    }
  }),
)

Reuse tool helpers, permission gates, and telemetry conventions before adding abstractions. Tests should exercise implementation behavior rather than duplicating logic in mocks.

Build system

AreaTooling
Package managerBun workspaces
Task orchestrationTurborepo
CLI executableBun compile build in packages/opencode/script/build.ts
VS Code extension and webviewsesbuild
JetBrains pluginGradle, Kotlin JVM toolchain 21, build-local OpenAPI generation
Type checkingtsgo through bun turbo typecheck; Gradle compile checks for JetBrains
TestsPackage-level Bun test, Vitest, or Gradle test depending on package
DocsNext.js, Markdoc, Mermaid, and custom Markdoc components

Documentation changes

When adding or moving docs pages:

  • Create page under pages/.
  • Update matching navigation file in lib/nav/.
  • Add redirects when removing or moving routes.
  • Use compact markdown tables with unpadded cells.
  • Use /docs prefix for docs image paths.

Source map

Paths below are relative to AP-DIGITAL-SERVICES/cfly-factory.

ConcernSource path
Tool definition APIpackages/opencode/src/tool/tool.ts
Tool examplepackages/opencode/src/tool/read.ts
Server APIspackages/opencode/src/server/routes/instance/httpapi/
Public OpenAPI normalizationpackages/opencode/src/server/routes/instance/httpapi/public.ts
CFactory route seampackages/opencode/src/cfactory/server/httpapi/
JavaScript SDK generationpackages/sdk/js/script/build.ts
script/generate.ts
JetBrains client generationpackages/cfactory-jetbrains/backend/build.gradle.kts
Upstream merge automationscript/upstream/

Upstream merge workflow

bun install runs script/setup-git.ts, which sets repo-local merge conflict style to zdiff3. Base-aware markers make manual resolution and syntax-aware tooling more useful. Upstream automation under script/upstream/ applies transforms before merge, forces zdiff3 for merge operation, and runs mergiraf against remaining textual conflicts. mergiraf is required by merge script.

From script/upstream/, use:

bun run analyze.ts --version <tag>
bun run merge.ts --version <tag> --dry-run
bun run merge.ts --version <tag>

Keep CFactory-specific logic extracted, shared seams narrow, markers accurate, and CI guards green before upstream merge work lands.