mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-03 15:11:42 +00:00
200 lines
8.0 KiB
Markdown
200 lines
8.0 KiB
Markdown
# CCS Code Standards
|
|
|
|
These standards describe current repository practice. Enforced configuration
|
|
and tests take precedence over prose.
|
|
|
|
## Source of Truth
|
|
|
|
| Contract | Authoritative source |
|
|
| --- | --- |
|
|
| TypeScript and CLI lint rules | [`eslint.config.mjs`](../eslint.config.mjs) |
|
|
| Formatting | [`.prettierrc`](../.prettierrc) |
|
|
| Root commands and test entry points | [`package.json`](../package.json) |
|
|
| UI commands and dependencies | [`ui/package.json`](../ui/package.json) |
|
|
| Commit syntax | [`commitlint.config.cjs`](../commitlint.config.cjs) |
|
|
| Release effects | [`.releaserc.cjs`](../.releaserc.cjs) |
|
|
| Repository workflow | [`CLAUDE.md`](../CLAUDE.md) and [`CONTRIBUTING.md`](../CONTRIBUTING.md) |
|
|
|
|
Update this document when one of those contracts changes. Do not duplicate
|
|
exhaustive rule, command, target, or dependency lists here.
|
|
|
|
## Design Priorities
|
|
|
|
Apply these in order:
|
|
|
|
1. **YAGNI**: build only behavior required by the accepted scope.
|
|
2. **KISS**: prefer a small local change over a new abstraction or dependency.
|
|
3. **DRY**: share stable domain behavior, not incidental similarity.
|
|
|
|
Preserve public contracts unless the change intentionally updates them. Error
|
|
messages should explain recovery, and configuration changes should remain
|
|
CLI-complete with dashboard parity where the feature supports both surfaces.
|
|
|
|
## Organization and Imports
|
|
|
|
- Keep code inside the domain that owns its behavior.
|
|
- Split files at cohesive boundaries such as types, pure utilities, lifecycle
|
|
services, hooks, or view components.
|
|
- Follow nearby naming and import patterns. New TypeScript files normally use
|
|
descriptive kebab-case names.
|
|
- There is no universal maximum directory depth.
|
|
- Barrel exports are optional compatibility boundaries, not a repository-wide
|
|
requirement. Preserve an existing barrel when consumers depend on it; use a
|
|
direct import when that is the local pattern or the symbol is intentionally
|
|
private.
|
|
- Before creating a module, check whether the runtime, standard library,
|
|
installed dependencies, or an existing repository utility already owns the
|
|
behavior.
|
|
|
|
## File Size
|
|
|
|
Two different thresholds serve different purposes:
|
|
|
|
- **200 lines is a review heuristic.** When a code file grows beyond roughly
|
|
200 lines, check whether it contains multiple responsibilities. A cohesive
|
|
file may remain larger.
|
|
- **400 lines is the current CLI lint warning.**
|
|
[`eslint.config.mjs`](../eslint.config.mjs) configures `max-lines` as a
|
|
warning for `src/**/*.ts`, excluding blank lines and comments.
|
|
|
|
Do not split mechanically to satisfy a number. Split when the result improves
|
|
ownership, testing, reuse, or reviewability. Preserve existing exports and
|
|
behavior when they are part of a consumed contract.
|
|
|
|
## TypeScript and Linting
|
|
|
|
The CLI uses strict TypeScript. Current enforced CLI rules include:
|
|
|
|
- no explicit `any`
|
|
- no non-null assertions
|
|
- no unused variables, except names intentionally prefixed with `_`
|
|
- `prefer-const`, `no-var`, and strict equality
|
|
|
|
Use `unknown` at untrusted boundaries and narrow it before use. Keep types close
|
|
to their owning domain; export types only when another module consumes them.
|
|
|
|
New generic `throw new Error(...)` sites are blocked by the local
|
|
`ccs/no-new-throw-error` rule. Use the typed errors in
|
|
[`src/errors/error-types.ts`](../src/errors/error-types.ts) so
|
|
[`src/errors/error-handler.ts`](../src/errors/error-handler.ts) can map failures
|
|
consistently. The generated baseline in
|
|
[`eslint-rules/throw-error-baseline.json`](../eslint-rules/throw-error-baseline.json)
|
|
grandfathers existing sites; do not expand it to bypass a new error design.
|
|
|
|
## Terminal and Process Behavior
|
|
|
|
- CLI terminal output is ASCII only: `[OK]`, `[!]`, `[X]`, `[i]`.
|
|
- Respect `NO_COLOR` and TTY-aware output.
|
|
- Prefer argument arrays when spawning processes. When a platform wrapper
|
|
requires a shell, use the existing quoting and wrapper utilities rather than
|
|
interpolating untrusted input.
|
|
- Preserve target-specific stdio, signal, and exit-code behavior. The adapter
|
|
contract lives in
|
|
[`src/targets/target-adapter.ts`](../src/targets/target-adapter.ts).
|
|
|
|
## Target Adapters
|
|
|
|
Runtime target behavior is divided across:
|
|
|
|
| Concern | Source |
|
|
| --- | --- |
|
|
| Target names, aliases, persistence | [`src/targets/target-metadata.ts`](../src/targets/target-metadata.ts) |
|
|
| Selection priority and flag parsing | [`src/targets/target-resolver.ts`](../src/targets/target-resolver.ts) |
|
|
| Adapter contract | [`src/targets/target-adapter.ts`](../src/targets/target-adapter.ts) |
|
|
| Registration and lookup | [`src/targets/target-registry.ts`](../src/targets/target-registry.ts) |
|
|
| Startup registration | [`src/ccs.ts`](../src/ccs.ts) |
|
|
|
|
A target change should update metadata, implementation, registration, tests,
|
|
help text, and public documentation as applicable. Do not copy the target list
|
|
into new guides; link to metadata when maintainers need the current set.
|
|
|
|
## Configuration and Test Isolation
|
|
|
|
- Treat persisted environment values as strings.
|
|
- Route CCS paths through `getCcsDir()` in
|
|
[`src/utils/config-manager.ts`](../src/utils/config-manager.ts).
|
|
- Never run tests against a contributor's real `~/.ccs/` or `~/.claude/`.
|
|
Set `CCS_HOME` to a temporary directory.
|
|
- Preserve documented configuration and profile-resolution priority. Add a
|
|
focused test when changing precedence or fallback behavior.
|
|
- Treat Docker service `ccs` and network `ccs-net` as public contracts; see
|
|
[`CONTRIBUTING.md`](../CONTRIBUTING.md#if-you-change-the-docker-network-or-service-name).
|
|
|
|
## Dashboard Code
|
|
|
|
- Keep page orchestration in `ui/src/pages/`, reusable UI in
|
|
`ui/src/components/`, server-state access in `ui/src/hooks/`, and shared
|
|
helpers in `ui/src/lib/` when that matches the owning domain.
|
|
- Preserve unsaved input across background refreshes. Destructive replacement
|
|
of dirty state requires an explicit user action or confirmation.
|
|
- Use the existing API and query helpers before adding a new data-access layer.
|
|
- Keep accessibility, keyboard interaction, responsive layout, loading,
|
|
empty, and error states in scope for user-facing changes.
|
|
- Locale codes and normalization are owned by
|
|
[`ui/src/lib/locales.ts`](../ui/src/lib/locales.ts); translations are wired
|
|
through [`ui/src/lib/i18n.ts`](../ui/src/lib/i18n.ts).
|
|
|
|
The UI has its own ESLint, TypeScript, Prettier, and Vitest configuration.
|
|
Verify commands against [`ui/package.json`](../ui/package.json).
|
|
|
|
## Tests and Quality Gates
|
|
|
|
The root TypeScript suites run with Bun's test runner. The dashboard uses
|
|
Vitest. Native shell and PowerShell probes cover platform-specific behavior.
|
|
See [`tests/README.md`](../tests/README.md) for ownership and commands.
|
|
|
|
Run the smallest relevant test first, then the normal gate:
|
|
|
|
```bash
|
|
bun run format
|
|
bun run lint:fix
|
|
bun run validate
|
|
```
|
|
|
|
Before review or merge confidence:
|
|
|
|
```bash
|
|
bun run validate:ci-parity
|
|
```
|
|
|
|
For dashboard changes:
|
|
|
|
```bash
|
|
cd ui
|
|
bun run format
|
|
bun run validate
|
|
bun run test:run
|
|
```
|
|
|
|
Do not weaken or skip a failing check to make a change pass. If a full gate
|
|
cannot run, report the exact focused checks completed and the blocker.
|
|
|
|
## Commits and Releases
|
|
|
|
Commitlint accepts conventional types defined in
|
|
[`commitlint.config.cjs`](../commitlint.config.cjs), with a 100-character header
|
|
limit. Use focused subjects such as:
|
|
|
|
```text
|
|
fix(doctor): handle missing config
|
|
feat(cliproxy): add provider quota check
|
|
docs(contributing): clarify validation
|
|
```
|
|
|
|
Semantic-release owns versions, changelog entries, tags, npm publishing, and
|
|
GitHub releases. Do not bump versions, tag, or publish manually. Release effects
|
|
for each branch and commit type are defined in
|
|
[`.releaserc.cjs`](../.releaserc.cjs).
|
|
|
|
## Documentation Triggers
|
|
|
|
Update the owning guide when a change affects behavior, commands, setup,
|
|
architecture, security posture, public contracts, or future maintainer
|
|
decisions. Start at [`docs/README.md`](./README.md). Public CLI, provider,
|
|
configuration, installation, or workflow changes also require the matching page
|
|
in the separate `kaitranntt/ccs-docs` repository; see the docs index for
|
|
checkout guidance.
|
|
|
|
Prefer source links over copied trees and metrics. Remove stale sections rather
|
|
than leaving TODO markers.
|