Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ title: Documentation Index

- [Config Matching](technical/config-matching.md): How agnos resolves glob-aware documentation ignores and rule fragments.
- [MCP Env Resolution](technical/mcp-env-resolution.md): How MCP env key declarations are resolved into secret-bearing agent files.
- [Rules Bootstrap](technical/rules-bootstrap.md): How rule catalogs are discovered and copied into a configured project.
- [Skills Reconciliation](technical/skills-reconciliation.md): How declared skill sources are reconciled with materialized skills and lock entries.

### technical-decisions
Expand Down
2 changes: 2 additions & 0 deletions .docs/technical/config-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ timestamp: 2026-07-08T00:00:00Z

## Rule fragments

- Fragment paths resolve relative to `rules.dir` when it is configured.
- Fragment paths resolve relative to the project root when `rules.dir` is absent.
- `rules.files` fragment entries may resolve to files, directories, or glob patterns.
- Literal files preserve existing single-fragment behavior.
- Directory entries expand to Markdown files recursively.
Expand Down
36 changes: 36 additions & 0 deletions .docs/technical/rules-bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
type: Technical Doc
title: Rules Bootstrap
description: How rule catalogs are discovered and copied into a configured project.
resource: ""
tags: [configuration, rules, bootstrap]
timestamp: 2026-08-18T00:00:00Z
---

# Rules Bootstrap

## Configuration

- `agnos.json` declares the bootstrap destination under `rules.dir`.
- Injectable paths are resolved from `rules.dir` when configured and from the project root otherwise.
- Rules initialization configures the directory, adds `.` to the selected canonical rules file, and references the docs index relative to that directory when docs are configured.
- Bootstrap is optional and runs only through the rules command.

## Catalog discovery

- The default catalog is the `.rules` directory in the Agnos repository.
- Custom Git and local repository sources use their top-level `.rules` directory.
- An explicit Git repository path replaces the conventional directory.
- Discovery includes Markdown files recursively and presents repository-relative paths in sorted order.

## Copy behavior

- Selected files preserve their catalog-relative paths under `rules.dir`.
- Existing files at the same paths are overwritten.
- Bootstrap does not record copied files in project state or lock files.
- Dry runs report copy operations without changing the destination.

## References

- Rules command: [bootstrap.ts](../../src/domains/rules/bootstrap.ts).
- Rules configuration: [public.ts](../../src/core/types/public.ts).
14 changes: 14 additions & 0 deletions .rules/general/_flagging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
type: Rule
title: Flagging
description: Define the flagging and warning behavior.
resource: ""
tags: [flag, warn, recommendation]
timestamp: 2026-08-19T00:00:00Z
---

Whenever asked to flag something, add the flagged content at the end of your response with the following format:

> ⚠️ **<type> gap detected:** <decision-summary>.
> Recommendation: <recommended-action>
> _Consider updating [`<filename>`](targeted-file-path.md)_.
32 changes: 32 additions & 0 deletions .rules/general/_git.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
type: Rule
title: Working with Git
description: Manage branches, commits, history, and pull requests safely.
resource: ""
tags: [git, version-control, workflow]
timestamp: 2026-08-19T00:00:00Z
---

### History management

- Maintain a linear history: Prioritize `rebase` and `squash` over `merge`.
- Never take credit for code authoring. The author is always the developer.
- Don't ever sign commits.

### Branch management

- **`main` branch is locked**: Never push to `main` directly, instead create a branch and a PR.
- Strictly adhere to **[conventional branches](conventionalbranch.org/#specification)**.
- Branch names can never be called `<ai-agent-name>/*`. They have to strictly follow the conventional names.

### Commit strategy

- Strictly adhere to **[conventional commits](conventionalcommits.org/en/v1.0.0/#specification)**
- Conventional multi-line messages: subject < 70 chars in imperative mood; body explains why.
- Always group related changes logically and split unrelated work. Do not do a big single commit. Do not commit atomically.
- Never amend pushed commits without explicit approval. Never --no-verify.
- Run the full `lint`, `format`, `typecheck`, and `test` suite before committing code.

### Pull requests

- Use `gh auth switch -u <GH_USER>`: Always use the `GH_USER` secret declared in `.env.agents` to work with the GitHub CLI.
38 changes: 38 additions & 0 deletions .rules/general/_secrets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
type: Rule
title: Secrets and Environment Variables
description: Protect environment files and document required variables safely.
resource: ""
tags: [secrets, environment, security]
timestamp: 2026-08-19T00:00:00Z
---

- **Never** print secrets in `.env.*` files, nor environmental variables, keys, secrets, etc...
- **Never** commit `.env.*` files except for `.env.example` which is meant to be used for documentation purposes.
- `.env.example` must **never** contain secrets.
- `.env.agents` is meant to host secrets only used by the agents. Its information must not be sensitive, and it may be committed.
- If `.env.*` are not ignored, warn the user with:
> You're about to commit your secrets! Please add the following to `.gitignore`:
>
> ```
> # ENV
> .env
> .env.*
> !.env.example
> ```
- Always keep the `.env.example` of every package up to date.
- `.env.example` must be segmented by platform like:

```env
# --------------------------------------------------------------------
# <Platform>: <What is this platform used for?>

# Purpose: <What is the variable used for?>
# Source : <Where to get it from? (prefer URL over a description)>
# Path : <Path -> of -> Menu -> Items -> user -> must -> follow>
# Example: <example value or recommended default, e.g.: sk_test_...>
<ENV_VAR_NAME>=<default value or empty>

...
...
```
110 changes: 110 additions & 0 deletions .rules/general/coding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
type: Rule
title: Coding Standards
description: Repository-wide language, package, quality, and implementation standards.
resource: ""
tags:
- coding
- typescript
timestamp: 2026-08-19T00:00:00Z
---

Enforced repo-wide. Non-negotiable.

### Package manager

**Use `pnpm` only.**

Never use other package managers, like `npm`, `yarn`, or `bun`.

### Turborepo

- **TurboRepo with remote caching**: Use remote caching to ensure fast build and deploy times.
- subcommands like `<command>:<sub>` should write to the same cache as the parent `<command>`

### TypeScript

- End-to-end.
- No `any` without justification.
- Strict mode + noUncheckedIndexedAccess + verbatimModuleSyntax.
- Always use `type`. Avoid `interface` unless necessary.
- Always use `async/await` and `try/catch`. Avoid `.then()` chains.
- Always use named exports. Avoid default exports unless necessary.
- Always use arrow functions. Avoid named functions unless necessary or when explicitly told to use them.
- Always declare function components, never class components.
- Use aliases (`@`) to keep the import paths clean.
- Prefer single-line syntax for brief statements, functions, and control structures. Avoid unnecessary curly braces and line breaks. Examples:

```ts
// dont's
const double = (x: number): number => {
return x * 2;
};

if (!user) {
return null;
}

const age = 30;
const user = {
name: name,
age: age,
};

type Status = "idle" | "loading" | "success";

interface Point {
x: number;
y: number;
}

let label: string;

if (isAdmin) {
label = "Admin";
} else {
label = "User";
}

// prefer
const double = (x: number): number => x * 2;

if (!user) return null;

const user = { name, age };

type Status = "idle" | "loading" | "success";

type Point = { x: number; y: number };

const label = isAdmin ? "Admin" : "User";
```

### Comments

- Write self-documenting code.
- Use JSDoc when appropriate.
- Prefer clear naming over comments.
- Comments are used to explain why, never what.
- Only comment what can not be inferred from code.
- Do not use comments for documentation. Use the documentation for this.
- Do not leave `TODO` or `FIXME` comments unresolved in committed code.
- Do not duplicate information already in the documentation.

### Errors

- Throw Error with descriptive messages, preserving causes via { cause: originalErr }.
- Catch only when you can do something useful. Empty try/catch reserved for genuinely optional cleanup (e.g., unlink of a maybe-missing file).
- Return { ok: boolean } from orchestrator-level functions; don't throw across the CLI boundary.

### Logging

- Five levels: info, success, warn, error, debug. Use the level that matches the meaning.
- No manual ANSI codes: The logger handles color and TTY detection.
- Hook implementations log without manual indentation prefixes; the orchestrator wraps the logger.
- would: <action> prefix for dry-run output.

### Code health

- Use ESLint, Prettier, and `tsc` to validate code.
- Execute linting, formatting, type checking and testing before committing. Always.
14 changes: 14 additions & 0 deletions .rules/general/conventions-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
type: Rule
title: Conventions
description: Define shared reuse, module, and localization conventions.
resource: ""
tags: [conventions, modularity]
timestamp: 2026-08-19T00:00:00Z
---

- Idempotency is mandatory for anything that touches the filesystem.
- If a pattern appears twice, extract it.
- Use barrel exports and keep them updated.
- Organize logic by functionality and concern.
- One concept per file.
30 changes: 30 additions & 0 deletions .rules/general/conventions-change-discipline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
type: Rule
title: "Change Discipline"
description: Keep changes intentional, scoped, reversible, and respectful of existing work.
resource: ""
tags: [changes, scope, collaboration]
timestamp: 2026-08-26T14:20:00Z
---

- Understand the requested outcome before changing files or external state.
- Inspect relevant or shared code, configuration, documentation, and established patterns first. Codebase is small; grep first.
- Limit changes to the requested outcome and its necessary supporting work.
- No abstractions for hypothetical needs. Build for what's asked; symmetry over flexibility when adding hooks (if there's onAdded, there's probably onRemoved).
- Preserve unrelated edits and user-owned work.
- Do not perform opportunistic refactors, migrations, or cleanup.
- Follow the existing architecture unless the task explicitly changes it.
- Identify generated files and update their source of truth instead of editing generated output directly.

### Decisions and risk

- State assumptions that materially affect behavior or scope.
- Ask for direction when unresolved ambiguity would produce meaningfully different outcomes.
- Resolve exact targets before destructive, irreversible, or externally visible actions.
- Preserve compatibility unless the task explicitly authorizes a breaking change.

### Completion

- Review the final diff for unrelated changes, accidental formatting, generated noise, and sensitive information.
- Report completed work, verification results, assumptions, and remaining limitations.
- Do not claim completion while required work or verification remains unfinished.
43 changes: 43 additions & 0 deletions .rules/general/conventions-i18n.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
type: Rule
title: "Internationalization: modular i18n"
description: Define shared reuse, module, and localization conventions.
resource: ""
tags: [conventions, i18n, internationalization]
timestamp: 2026-08-19T00:00:00Z
---

- Always **prepare for i18n**.
- Hardcoded strings in components are a defect.
- Co-locate dictionaries next to the consuming organism.
- Never bundle all strings into a single dictionary file. Keep one disctionary per supported language.
- Use a schema file to define the `i18nSchema`, the Zod schema for the dictionary.
- Dictionaries (json files) are always fetched over the network and validated with the zod schema once received.

```
src/
└─ .../<domain>/
├─ index.ts
├─ ...
├─ <domain>.i18n._schema.ts
└─ <domain>.i18n.<lang>.json
```

```ts
// .../<domain>.i18n._schema.ts
import z from 'zod'

// declare the shape of the dictionary
export const i18nSchema = z.object({ ... })

// .../<domain>.<role>.ts
import { i18nSchema } from './<domain>.i18n._schema.ts'

export const DomainRole = async () => {
// fetch json dictionary
const json = await fetchI18nLang(lang)
// validate it with the schema
const validDictionary = i18nSchema.safeParse(json)
...
}
```
49 changes: 49 additions & 0 deletions .rules/general/conventions-naming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
type: Rule
title: Naming Conventions...
description: Define shared reuse, module, and localization conventions.
resource: ""
tags: [conventions, naming]
timestamp: 2026-08-19T00:00:00Z
---

### ... for directories

Directories use `camelCase` unless explicitly told otherwise.

### ... for files

For files we use:

- `<domain>.<role>.<ext>`: A declarative, **dot-delimited** `cammelCase` file naming strategy with a predictable pattern that encodes the domain and the architectural role, for the pieces that compose a feature.
- `index`: for the barrel files.

Examples of roles:
| Role | Use for... |
| ------------------------------------------------ | -------------------------------------------------------- |
| module | bundling a feature |
| controller, component | orchestraiton and coordination |
| modal, dialog, drawer, presentation, form, etc.. | ui blocks like overlays, modals, drawers, popups, etc... |
| dto, entity, schema | data shapes, contracts, models, etc... |
| api, service | business logic |
| hook.<useHookName>, store, context, repository | data fetching, state, external apis, etc... |
| css stylesheet, css module | styling rules |
| utility, helper, command | pure funtions, commands, directives, parsers, etc... |
| i18n.<lang>, i18n.\_schema | internationalization |
| test, test.input, test.seed | tests and test files |

Never use `kebab-case`.

In the case the files in a directory grow too much due to expanding sub-roles, the roles can be moved to a directory within the domain that logacally represents what it contains, e.g.:

- `i18n` role has an additional part for language and schema. They can be moved to `i18n/`.
- `tests` role might grow to have too many files. They can be moved to `tests/`.
- multiple roles like `dialog`, `drawer`, and `modal` cover overlapping concerns. They can be moved to `components/`.

### ... for code

Whenever writting code, use:

- `UPPER_SNAKE_CASE` for constants.
- `PascalCase` for type declarations, classes, components, generics, and enums.
- `camelCase` for everything else.
Loading
Loading