Files
gf/CLAUDE.md
John Guo 94623a19d1 feat(cmd/gf): add gendao fileNameCase and ai coding stuffs (#4764)
This pull request introduces new and updated prompt and instruction
documents for the experimental OPSX workflow system, providing detailed,
step-by-step guidance for proposing, applying, archiving, and exploring
changes using OpenSpec. The changes standardize workflow guardrails,
clarify user interactions, and ensure consistent artifact handling
across all major workflow operations.

**OPSX Workflow Prompt Additions and Enhancements:**

* **Propose Workflow**
- Adds `.agents/prompts/opsx/propose.md` outlining how to propose a new
change, including artifact creation order, dependency handling, and user
input requirements. Emphasizes using schema-defined instructions and
templates, and clarifies that context/rules are for internal guidance
only.

* **Apply Workflow**
- Introduces `.agents/prompts/opsx/apply.md` detailing the process for
implementing tasks from an OpenSpec change. Covers change selection,
context reading, task loop execution, state handling, and output
formatting. Includes guardrails for ambiguity, blockers, and minimal
change scope.

* **Archive Workflow**
- Adds `.agents/prompts/opsx/archive.md` specifying the process for
archiving completed changes, including artifact/task completion checks,
delta spec sync assessment, user prompts for incomplete work, and
summary output. Ensures robust handling of archive naming conflicts and
user confirmations.

* **Explore Mode**
- Adds `.agents/prompts/opsx/explore.md` describing "explore mode" for
non-implementation discovery, problem investigation, and requirements
clarification. Outlines stance, behaviors, and guardrails for thinking
and artifact capture without code changes.

**Documentation Standardization:**

* **Markdown Formatting Standards**
- Adds `.agents/instructions/markdown-format.instructions.md` to
standardize markdown document formatting, including heading levels, code
block usage, list formatting, and language-specific punctuation rules
for improved clarity and consistency.
2026-04-25 17:47:05 +08:00

16 KiB

Repository Overview

This is the GoFrame framework (github.com/gogf/gf/v2) — a modular Go application framework. The repository is a multi-module monorepo: the root module hosts the core framework, while cmd/gf and every directory under contrib/ are independent Go modules with their own go.mod.

  • Root module: github.com/gogf/gf/v2 (Go 1.23+)
  • Tooling module: cmd/gf (CLI: gf command, separate go.work)
  • Plugin modules under contrib/: config/*, drivers/* (mysql, pgsql, mssql, oracle, sqlite, clickhouse, dm, gaussdb, mariadb, oceanbase, tidb, sqlitecgo), metric/*, nosql/*, registry/*, rpc/grpcx, sdk/*, trace/*. Each is published as its own module so users only pull what they need.

The root framework intentionally has minimal external dependencies (see go.mod). Anything requiring a heavy third-party dep (a DB driver, a registry client, an RPC stack) lives in contrib/.

Top-level package map

Path Purpose
frame/g, frame/gins Convenience facade (g.Server(), g.DB(), g.Cfg()) and the singleton/instance container
net/ ghttp (HTTP server/router), gclient (HTTP client), gtcp, gudp, gsel (load balancing), gsvc (service discovery), gtrace, goai (OpenAPI)
os/ OS abstractions: gcfg (config), gcmd (CLI), gcron, glog, gfile, gres (resource embedding), gview (templating), gcache, gsession, gctx, gtimer, gproc, gmetric, gfsnotify, gstructs
database/ gdb (ORM/query builder, driver-agnostic core), gredis (Redis client core)
container/ Concurrent-safe data structures: garray, gmap, gset, gtree, glist, gqueue, gring, gpool, gtype, gvar
encoding/ Codecs for JSON/XML/YAML/TOML/INI/Properties, base64, charsets, compression, hashes, HTML, URL
text/ gstr, gregex
util/ gconv (universal conversion — heavily used), gvalid (validation), gutil, grand, guid, gtag, gmeta, gpage, gmode
crypto/ gaes, gdes, grsa, gmd5, gsha*, gcrc32
errors/ gerror (stack-aware errors), gcode (error code registry)
internal/ Framework-internal helpers (do not import from outside the root module)
test/gtest The framework's own testing helpers — used throughout the test suite

Concrete database drivers and Redis adapters live under contrib/drivers/ and contrib/nosql/; the database/gdb and database/gredis packages define the abstract layer.

Common Commands

All commands run from the repository root unless noted.

Build / lint / tidy

# Tidy every go.mod in the repo (root, cmd/gf, contrib/*) — strips // indirect and toolchain lines
make tidy

# Run the project's golangci-lint config (.golangci.yml)
make lint
# Equivalent: golangci-lint run -c .golangci.yml

make tidy invokes .make_tidy.sh, which cds into every directory containing a go.mod (skipping testdata/ and examples/) and runs go mod tidy. After editing imports in any module, run this from the repo root.

Tests

Each Go module must be tested from inside its own directory because they are separate modules. The CI script (.github/workflows/scripts/ci-main.sh) iterates every go.mod:

# Build + race-enabled tests for the root module
go build ./...
go test ./... -count=1 -race

# Coverage (matches CI 'coverage' mode)
go test ./... -count=1 -race -coverprofile=coverage.out -covermode=atomic \
  -coverpkg=./...,github.com/gogf/gf/...

# Run a single package's tests
go test -count=1 -race ./os/gcfg/...

# Run a single test by name
go test -count=1 -race -run TestCfg_Get ./os/gcfg/

# Test a contrib module — must cd in first (separate go.mod)
cd contrib/drivers/mysql && go test ./... -count=1 -race

Many tests (database drivers, registry clients, redis cluster, apollo/nacos config) require backing services. CI starts them via docker-compose files under .github/workflows/{redis,apollo,nacos,consul}/. Locally, use:

make docker                      # start the default local stack
make docker cmd=start svc=mysql  # start a specific service
make docker cmd=stop  svc=mysql

CLI tool

cd cmd/gf && go run . <subcommand>   # iterate on the gf CLI itself

Architecture Notes Worth Knowing Up Front

  • The frame/g package is a facade, not a library. It re-exports types and provides singleton accessors (g.DB(), g.Server(), g.Cfg(), g.Log()) backed by frame/gins. Examples in docs use g.* heavily; framework-internal code generally imports the underlying packages directly.
  • util/gconv is foundational. Most public APIs accept any and use gconv for type coercion. When changing argument handling, search for gconv. usage to understand the conversion contract.
  • gdb is driver-agnostic. The core in database/gdb exposes interfaces; concrete drivers (contrib/drivers/mysql, etc.) register themselves via init() when imported. The same model pattern applies to gredis, gcfg (apollo/nacos/polaris adapters), and gsvc (etcd/consul/nacos/polaris/zookeeper registries).
  • internal/ is private. Sub-packages (intlog, instance, reflection, utils, json, command) are not part of the public API surface — do not import them from outside the root module, and avoid leaking their types in exported signatures.
  • Tests use gtest, not stdlib testing directly. test/gtest provides gtest.C(t, func(t *gtest.T){...}) blocks, fluent assertions (t.Assert, t.AssertNE, t.AssertNil), and is the project-wide convention. Match this style when adding tests.
  • CI matrix. Tests run on Go 1.23, 1.24, 1.25 across 386 and amd64. contrib/* only runs on the latest Go version (LATEST_GO_VERSION in .github/workflows/ci-main.yml). Code that requires the latest stdlib should live in contrib/ or be guarded.
  • Lint config matters. .golangci.yml enforces a 380-char line limit, function length up to 340 lines, custom import grouping (gci with prefix(github.com/gogf/gf/v2) ahead of cmd/contrib/example), gofmt -s with rewrites (interface{}any, ioutil.*io/os, reflect.Ptrreflect.Pointer). Run make lint before pushing.
  • OpenSpec changes live under openspec/changes/ and drive every non-trivial change through the workflow defined below. The active iteration directory must be checked before starting work — see the Development Workflow Rules section.

Karpathy Guidelines

Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment.

1. Think Before Coding

Don't assume. Don't hide confusion. Surface tradeoffs.

Before implementing:

  • State your assumptions explicitly. If uncertain, ask.
  • If multiple interpretations exist, present them - don't pick silently.
  • If a simpler approach exists, say so. Push back when warranted.
  • If something is unclear, stop. Name what's confusing. Ask.

2. Simplicity First

Minimum code that solves the problem. Nothing speculative.

  • No features beyond what was asked.
  • No abstractions for single-use code.
  • No "flexibility" or "configurability" that wasn't requested.
  • No error handling for impossible scenarios.
  • If you write 200 lines and it could be 50, rewrite it.

Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.

3. Surgical Changes

Touch only what you must. Clean up only your own mess.

When editing existing code:

  • Don't "improve" adjacent code, comments, or formatting.
  • Don't refactor things that aren't broken.
  • Match existing style, even if you'd do it differently.
  • If you notice unrelated dead code, mention it - don't delete it.

When your changes create orphans:

  • Remove imports/variables/functions that YOUR changes made unused.
  • Don't remove pre-existing dead code unless asked.

The test: Every changed line should trace directly to the user's request.

4. Goal-Driven Execution

Define success criteria. Loop until verified.

Transform tasks into verifiable goals:

  • "Add validation" → "Write tests for invalid inputs, then make them pass"
  • "Fix the bug" → "Write a test that reproduces it, then make it pass"
  • "Refactor X" → "Ensure tests pass before and after"

For multi-step tasks, state a brief plan:

1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]

Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.

Documentation Writing Rules

Technical documentation such as README.md must follow .agents/instructions/markdown-format.instructions.md.

  • All directory-level primary documentation files in the repository must use the English README.md and provide a matching Chinese mirror in README.zh_CN.md.
  • When adding a new directory documentation file, create both README.md and README.zh_CN.md in the same change. Maintaining only one language version is not allowed.

Development Workflow Rules

This project follows SDD and uses the OpenSpec tool to drive implementation. Change records are stored under openspec/changes/. Each change includes proposal.md, design.md, specs/, and tasks.md.

Execution workflow:

  1. Use the /opsx:explore slash command at .agents/prompts/opsx/explore.md to conduct an exploratory discussion based on the requirement description, analyze the problem, design the solution, and assess risks.
  2. Once the exploratory discussion finishes and the solution is clear, use the /opsx:propose slash command at .agents/prompts/opsx/propose.md to turn it into a formal OpenSpec change proposal. The command format is /opsx:propose feature-name, where feature-name is a descriptive name for the current change in kebab-case, such as user-auth or data-export. A new change directory will then be generated automatically under openspec/changes, containing incremental spec documents (spec/), the technical implementation plan (design.md), the proposal and rationale (proposal.md), and the implementation task list (tasks.md).
  3. Then run the /opsx:apply slash command at .agents/prompts/opsx/apply.md to execute the items in tasks.md one by one, completing code changes, tests, and documentation updates. After the work is done, the /gf-review skill must be invoked for code and spec review.
  4. When users report issues or improvement requests, the /gf-feedback skill must be used to fix and verify them, and the related OpenSpec documents must be updated. After the work is done, the /gf-review skill must be invoked for review.
  5. After the user confirms that the current iteration is complete and has no remaining issues, run the /opsx:archive slash command at .agents/prompts/opsx/archive.md to archive the change. Before archiving, the /gf-review skill must be used for a full change review to ensure code quality and compliance with the spec.

Key rules:

  • An OpenSpec change is considered active until it is archived: any change directory that still exists directly under openspec/changes/ and has not been moved to openspec/changes/archive/ is an active change. Even if the change has completed all tasks and openspec list --json shows status: complete, it must still be treated as active until the archive step has been executed.
  • When a user reports a bug, defect, or improvement request in either Chinese or English, and there is an active OpenSpec change in the project, the gf-feedback skill must be used. Unless the user explicitly asks to create a new change, the feedback must always be appended to the current active iteration, even if it is unrelated to the main feature of that iteration, so that everything can be managed and archived together.
  • The /gf-review review skill is triggered automatically after /opsx:apply completes, after /opsx:feedback completes, and before /opsx:archive.
  • During development tasks executed with tools such as Claude Code or Codex CLI, if the work can be parallelized effectively with SubAgent and doing so would clearly improve efficiency, that option must be evaluated first and adopted whenever appropriate. Only skip SubAgent when the task is strongly dependent on serial context, the split cost is too high, or it introduces obvious collaboration risk.
  • When creating new iteration documents, the content of proposal.md, design.md, tasks.md, and the incremental specs must be written in English.

Code Development Rules

  • All source code must include comments, such as package comments, file comments, method comments for both public and private methods, constant comments, variable comments, and comments for key logic.
  • All submitted code changes must include unit tests: every submitted code change must add or update focused unit tests that directly cover the affected logic and expected behavior of the changed code path, and the coverage for newly added code must stay at or above 80%; 90% or above is the preferred target when feasible.
  • Do not hardcode string literals with enum semantics in backend implementation code: values that represent statuses, types, stages, actions, execution modes, sort directions, filter operators, or any other enum-like semantics must be managed through Go named types and constants. Writing raw string literals directly in business branching, comparisons, assignments, or persistence logic is forbidden.
  • Do not ignore any error return value: every call that may return an error must be handled explicitly. Do not use patterns such as _ = someFunc(), _, _ = someFunc(), or direct calls that discard returned errors. In business flows, errors should be returned explicitly or converted before returning; in initialization, startup, or other critical non-recoverable paths, they should panic; in tests and cleanup paths, they must still be asserted, logged, or otherwise handled explicitly rather than silently ignored.
  • Do not use stand-alone assignments like _ = var to mask unused parameters or local variables: this placeholder pattern has no business meaning and creates misleading signals about whether the variable was supposed to participate in the logic. Prefer deleting unused variables. If a parameter must be kept to satisfy an interface signature or callback contract, use the blank identifier directly in the function signature, such as func(ctx context.Context, _ gdb.TX) error, or omit an unused receiver name instead of adding one-line statements like _ = tx, _ = req, or _ = ctx in the function body.
  • File header comment rules:
    • Every Go source file must include a file-purpose comment at the top of the file. Component-level comments should appear in the component's main file, meaning the file with the same name as the component, such as plugin.go, config.go, or file.go.
    • In a main file, the component comment must be placed immediately before the package xxx declaration with no blank line in between. For example:
    // Package plugin implements plugin manifest discovery, lifecycle orchestration,
    // governance metadata synchronization, and host integration for LinaPro plugins.
    package plugin
    
    • Other implementation files must keep only file comments that describe the responsibility of the current file, such as plugin_xxx.go or config_xxx.go. There must be one blank line between the file comment and package xxx, and non-main files must not duplicate component-level descriptions.
  • Variable Declarations: When defining multiple variables, use a var block to group them for better alignment and readability:
    // Good - aligned and clean
    var (
        authSvc       *auth.Service
        bizCtxSvc     *bizctx.Service
        k8sSvc        *svcK8s.Service
        notebookSvc   *notebook.Service
        middlewareSvc *middleware.Service
    )
    
    // Avoid - scattered declarations
    authSvc := auth.New()
    bizCtxSvc := bizctx.New()
    k8sSvc := svcK8s.New()
    
    Apply this pattern when you have 3 or more related variable declarations in the same scope.