Skip to content
cccskills
FreePublished on GitHubEnglish overview

source-layout

Follow an existing codebase’s conventions for source and test file placement, naming, exports, and splitting files over 1,200 lines. The guide explains how to organize extracted modules while preserving import paths and behavior.

OriginalShow the original description

Use for where a file lives, how it is named, where its tests go, and how to split a source or test file over 1200 lines (拆分大文件, 目录结构, 文件命名).

lobehub/lobehub83,502 stars(GitHub 83,502 + cccskills 0)

Run score Not tested

See how to install

Good for

  • Choosing where a new source file belongs
  • Placing tests beside the code they cover
  • Planning a large file split

Overview

What it does

This guide explains conventions for file names, placement, exports, and tests within a codebase. It covers naming for React components, hooks, regular modules, and packages, and when to use named exports. It describes test placement: tests for one module sit beside it, while tests spanning several modules or real infrastructure belong in __tests__/. For files over 1,200 lines, it recommends splitting along cohesive boundaries while preserving public import paths and behavior.

When it helps

Use it when adding a file, deciding where a test belongs, or planning the structure of a large file split. It is intended to help keep new files and extracted modules consistent with the codebase’s conventions, rather than to rename existing code across the board.

Example requests

  • “Where should I put the hook and tests for this feature?”
  • “Suggest a directory structure for splitting this large file.”

Notes

Top-level directory ownership is defined by AGENTS.md and project-overview. This guide covers placement and naming within those roots.

This overview was written by AI (OpenAI Codex) from the public SKILL.md. Check the original below for the exact behavior.

Document check

AI checked the SKILL.md for operations that need care and for setup requirements. The score comes only from actually running the skill (hands-on test).

SafetyAre sending data, deleting files, and running commands disclosed?
AGoodIt discourages convention-only renames and preserves import paths and behavior.
Easy setupDoes it need few tools or API keys, and are they documented?
AGoodNo external services or credentials are required; it follows repository conventions.

Not counted in the score. Rated by AI (OpenAI Codex) as of Oct 26, 2026. Treat it as a guide and read the original before installing.

Disagree? Request a re-evaluation

Tell us which point is wrong and why. No login needed. We will check it against the SKILL.md, redo the evaluation, and show the result here.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Files included (1)

  • SKILL.md8.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Source Layout

Top-level ownership (src/features, src/routes, apps/server/src, packages, …) is in AGENTS.md and project-overview. This skill owns placement and naming inside those roots, test placement, and how a large file becomes a directory. The rules record the conventions the codebase already follows; where it was split between two forms, the rule names the one to use for new files. Do not rename existing files only to match.

1. Names

WhatFormExample
React component file / component directoryPascalCasePlanCard.tsx, ChatInput/ControlBar/
HookuseXxx.ts(x)ChatInputNotice/useChatInputNotice.ts
Other modulecamelCase or one wordoriginLink.ts, recentDirs.ts
Server class modulethe class nameservices/agentRuntime/StaleOperationReaper.ts
Service, router, store, and other non-component dirscamelCaseservices/aiAgent/, store/chat/slices/
Package directorykebab-casepackages/agent-runtime/
Files inside a packagecamelCasepackages/database/src/models/

A package whose files are already kebab-case (alint, openapi, builtin-skills) keeps kebab-case internally. Shared per-directory modules are constants.ts, types.ts, style.ts, and utils.ts, not const.ts, type.ts, styles.ts, or helpers.ts. Create one only when two or more modules in that directory use it; a constant or type used by one module stays in that module.

New files use named exports (export const PlanCard = …), even when the neighboring files default-export; do not copy the older default-export habit. The exceptions are modules a framework, tool, or loader imports by their default export: route segments under src/routes (see spa-routes), Next.js special files (page.tsx, layout.tsx, not-found.tsx), *.config.ts files, desktop controllers and services (*Ctr.ts, *Srv.ts, globbed by apps/desktop/src/main/core/App.ts), and locale resource files. Lint does not enforce this: this repository's eslint.config.mjs overrides no-restricted-syntax, which drops the shared @lobehub/lint warning on export default. When moving an existing file, keep its exports unchanged so its callers do not change.

2. Tests

One rule for every app and package:

  • A test of one module sits beside it: Foo.ts → Foo.test.ts; a directory entry's test is index.test.ts.
  • __tests__/ holds only tests that do not belong to one module: integration tests that run several modules together or real infrastructure (database, Redis, the tRPC or Hono request stack), such as routers/lambda/__tests__/integration/ and the database model and repository tests in testing, plus their shared setup, fixtures, and fakes.
  • New tests follow this rule even in a directory whose existing unit tests sit in __tests__/. Move an existing unit test beside its module when you split or rewrite that test file; do not migrate tests as a side task.
  • Split a large test file by scenario: Foo.<scenario>.test.ts(x), keeping the original extension (index.<scenario>.test.ts(x) for a directory entry). Put shared mock factories and fixtures in a testUtils.ts beside them; each test file keeps its own vi.mock calls, because Vitest hoists them per file.
  • Do not add React component tests, including to guard a split. Extract the logic into a hook or pure function and test that in .test.ts (testing).

3. File size

Source and test files stay at or below 1200 lines. Generated code (*.gen.ts, generated/ directories) and the locales/default/ tables are exempt:

  • A new file over 1200 lines, or an existing file that crosses 1200 lines in this change, is split in the same change. bun run check, the pre-commit hook, and the PR's File Size Gate job fail on both.
  • A file already over 1200 lines must not grow, including for a bug fix: the change may only keep or reduce its line count. Before adding code, extract the cohesive part the change touches into a sibling inside the file's own directory (Foo.ts becomes Foo/index.ts, §4), not into a neighboring file or another slice. Put a new test in a scenario test file under the limit (§2), splitting the old test file first when the test belongs to one of its scenarios. Because hundreds of legacy files are over the limit, these checks report their growth as an advisory (a warning annotation in CI) instead of failing; it is still a required fix.

The limit says when to split, not where. Split on a real boundary (state, reuse, render update, sub-domain, pipeline stage), as react requires; never cut a file at an arbitrary line count. When a heavy feature is mounted by several hosts, use compose-atoms instead.

4. Turning a file into a directory

A split keeps the public import path: Foo.tsx becomes Foo/index.tsx, so import Foo from './Foo' keeps working and callers do not change. Commit the move (mkdir -p Foo && git mv Foo.tsx Foo/index.tsx) alone before extracting, so reviewers can read the extraction diff separately and Git keeps the rename while those commits stay intact (a squash merge folds them together). split-large-file has the full procedure.

Kindindex keepsSiblingsPrecedent
React componentPublic API, shared top-level state, compositionChild components (PascalCase), useXxx.ts for state transitions and side effects, pure logic modules with their own testsConversation/Messages/GoalTaskCard/
Server serviceThe class and its orchestration methodsStage functions taking an explicit deps object (pipeline/<stage>.ts), sub-domain foldersservices/aiAgent/, services/comfyui/
tRPC routerThe merged routerOne sub-router per sub-domain (market/agent.ts exports agentRouter)routers/lambda/market/
Zustand storeThe action class and its public method signaturesLogic modules exporting a function that takes one params object plus get; the class method delegates to itagentRun/actions/entries/conversationLifecycle/
  • Prefer flat siblings. Add a sub-folder for a sub-area with several files of its own (ChatInput/ControlBar/).
  • Kind folders (components/, hooks/, utils/) follow who uses the code:
    • One user: keep it in that file or beside it (PlanGrid/usePlanActions.ts).
    • A few modules in the directory share it: flat siblings for hooks and components, one utils.ts for pure functions.
    • Three or more files of one kind shared by sibling modules: collect them in a kind folder (Dashboard/utils/, ChatInput/hooks/, ResourceManager/components/).
    • Shared across features: src/utils, src/hooks, src/components, or a packages/* package.
    • Do not create helpers/; name the module by its content or use utils.
  • A split moves code without changing behavior. Collapsing duplicated branches that become one component is in scope when existing tests cover each branch; any other behavior change belongs in a separate commit.
  • Move the matching tests with the code they cover, then run bun run check with the test files passed explicitly: related-test discovery finds only <name>.test.* and <name>.<scenario>.test.* of each changed file, so the entry's tests do not run for an extracted sibling such as usePlanActions.ts.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

acceptance

FreeSummary

Use this skill to verify a delivery by exercising the real product through a suitable surface such as a CLI, web app, desktop app, or iOS Simulator. It helps create or find a verification plan, capture evidence, and publish an acceptance report.

  • Verifying a completed product change
  • Collecting screenshots or other evidence
  • Creating a verification plan and report
lobehub/lobehub83.5KUpdated Oct 26, 2026

Use this skill to add an AI model provider to LobeHub across runtime integration, model cards, settings, branding, documentation, and acceptance checks. It also covers provider documentation updates and distinguishes new providers from models added to an existing provider.

  • Integrating a new AI model provider into LobeHub
  • Updating setup or usage documentation for a provider
  • Checking whether a model needs a new provider integration
lobehub/lobehub83.5KUpdated Oct 26, 2026

add-setting-env

FreeSummary

Use this skill to add a server-side environment variable that sets a default for a user setting. It walks through validation, server configuration and store merging, plus updating the example environment file and self-hosting documentation.

  • Adding an environment variable for a setting default
  • Wiring a new setting domain into server config
  • Documenting a new variable for self-hosting
lobehub/lobehub83.5KUpdated Oct 26, 2026

Provides guidance for registering hooks around an agent’s execution steps, tool calls, human approvals, context compression, and sub-agent calls. Hooks can observe events, supply local mock tool results, or use webhooks to allow or deny tool results under configured policies.

  • Observing agent steps and tool errors
  • Mocking tool results during local execution
  • Requiring webhook decisions before or after a tool call
lobehub/lobehub83.5KUpdated Oct 26, 2026

agent-signal

FreeSummary

Build event-driven background workflows for agents by defining sources, interpreting them as signals, and running actions through policies. It also guides asynchronous handoffs, deduplication, scoped execution, completion receipts, and observability.

  • Adding a new event source to an agent workflow
  • Routing interpreted signals to concrete background actions
  • Enqueuing work for asynchronous processing
lobehub/lobehub83.5KUpdated Oct 26, 2026

Use this skill to run end-to-end acceptance checks for bot channels in real desktop chat apps. It drives apps such as Discord, Slack, Telegram, WeChat, Lark, and QQ to send a message, wait for a response, and capture the result.

  • Checking a bot response in a real Discord channel
  • Testing chat behavior through Slack or Telegram
  • Capturing a bot interaction in a native macOS app
lobehub/lobehub83.5KUpdated Oct 26, 2026

See all skills by lobehub

Report a problem with this skill