@mkappelhof/agent-instructions 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ # @mkappelhof/agent-instructions
package/README.md CHANGED
@@ -1,3 +1,34 @@
1
- # Temporary Holding Version
1
+ # Shared agent instructions
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Project-level instructions for AI coding agents, covering code structure and conventions rather
4
+ than tool configuration. Pair them with the `AGENTS.md` files shipped by the config packages in
5
+ this repo, which describe the tool rules.
6
+
7
+ | File | For |
8
+ | --- | --- |
9
+ | `base.md` | Every project: verifying instead of assuming, workflow, git, imports, TypeScript, design tokens, versioning |
10
+ | `react.md` | React and Next.js projects (components, contexts, i18next, SCSS modules, Vitest) |
11
+ | `astro.md` | Static Astro sites (rendering, styling, data, images) |
12
+
13
+ `react.md` and `astro.md` both tell agents to read `base.md` first, so you only need to reference
14
+ the file for your project type.
15
+
16
+ ## Installation
17
+
18
+ ```sh
19
+ pnpm add -D @mkappelhof/agent-instructions
20
+ ```
21
+
22
+ Reference the file for your project type from the `AGENTS.md` at the root of your project:
23
+
24
+ ```md
25
+ # AGENTS.md
26
+
27
+ ## Conventions
28
+
29
+ - Follow `node_modules/@mkappelhof/agent-instructions/react.md`
30
+ ```
31
+
32
+ Put anything project-specific (architecture, extra commands, exceptions to the shared conventions)
33
+ in your own `AGENTS.md`. The shared files tell agents that the project's own instructions take
34
+ precedence.
package/astro.md ADDED
@@ -0,0 +1,34 @@
1
+ # Astro — agent instructions
2
+
3
+ Conventions for static Astro sites written in TypeScript and styled with SCSS. Everything in
4
+ [`base.md`](./base.md) applies as well; read it first.
5
+
6
+ The site ships static HTML/CSS with no client-side framework. Use small inline `<script>` tags only
7
+ where genuinely needed (e.g. a mobile nav toggle).
8
+
9
+ ## Rendering
10
+
11
+ - Keep `output: 'static'` in `astro.config.mjs`: no server rendering and no framework islands
12
+ (`@astrojs/react` etc.). Reach for an inline `<script>` before adding a framework.
13
+
14
+ ## Styling
15
+
16
+ - Write styles in component-scoped `<style lang="scss">` blocks.
17
+ - Import the design token stylesheet (see `base.md`) once, in the base layout.
18
+
19
+ ## Data
20
+
21
+ - Keep content data in `src/data/` as typed TypeScript modules. Each data set (features, pricing,
22
+ FAQ, etc.) has a single source of truth there; pages render from it instead of repeating it.
23
+ - Generate derived output such as `llms.txt` and JSON-LD structured data from the same data
24
+ modules, so they can't drift from what the pages show.
25
+ - Values that come from outside the site (e.g. a product version or description from another
26
+ `package.json`) are read once in `astro.config.mjs` and exposed through `vite.define` constants.
27
+ Read them in the config file, because its `import.meta.url` stays reliable while app modules get
28
+ bundled and relocated. Never hardcode such values elsewhere.
29
+
30
+ ## Images
31
+
32
+ - Keep images in `src/assets/` and render them with Astro's `<Image>` (or `<Picture>`) component
33
+ from `astro:assets` so they're optimized at build time. Never reference them as raw
34
+ `<img src>` paths.
package/base.md ADDED
@@ -0,0 +1,80 @@
1
+ # Base — agent instructions
2
+
3
+ Conventions that apply to every project type. `react.md` and `astro.md` build on this file. Where
4
+ the project's own `AGENTS.md` says something different, the project wins.
5
+
6
+ Tool rules (TypeScript, Biome, Stylelint) are described in the `AGENTS.md` of the matching
7
+ `@mkappelhof/*` config package. Follow those as well.
8
+
9
+ ## Don't assume, verify or ask
10
+
11
+ - Base every claim and every change on what you have actually read: the code, the config, the
12
+ installed packages' docs, or the user's instructions. Do not invent files, functions, props,
13
+ scripts, config options, package APIs or CLI flags.
14
+ - Before you use an API, component, helper or token, check that it exists and how it is used in
15
+ this project (search the codebase, read the type definitions or the package's docs in
16
+ `node_modules`). Your training data may describe a different version.
17
+ - When the request is ambiguous, information is missing, or several reasonable interpretations
18
+ lead to different results, stop and ask the user a clarifying question instead of guessing.
19
+ Don't ask about things you can find out yourself by reading the code.
20
+ - If you make an assumption anyway (e.g. for a small detail that doesn't block the work), state it
21
+ explicitly in your reply so the user can correct it.
22
+ - Say "I don't know" or "I couldn't verify this" rather than presenting a guess as fact. Report
23
+ results honestly: if a check fails or a step was skipped, say so.
24
+ - Stay within the scope of the request. Don't add features, refactors or dependencies that weren't
25
+ asked for; suggest them instead.
26
+
27
+ ## Working on a task
28
+
29
+ - Check the project's `package.json` for the available scripts (`dev`, `build`, `test`, lint and
30
+ type-check scripts) instead of guessing commands.
31
+ - A change is done when the type check, tests and linters pass for the files you changed.
32
+ - Never run `git commit`, create a branch, or push, unless you are explicitly asked to. Leave
33
+ changes as uncommitted working-tree edits and let the user commit, branch and push themselves.
34
+
35
+ ## Imports
36
+
37
+ - Use **path aliases** for cross-directory imports, never relative `../../` paths. Check
38
+ `compilerOptions.paths` in the project's `tsconfig.json` for the available aliases (e.g.
39
+ `@components/*`, `@helpers/*`, or `@/*`).
40
+
41
+ ## TypeScript
42
+
43
+ - Declare all types with `type`; do not use `interface`. Export a type when it is shared.
44
+ - Do not use double casts (`as unknown as T`) to silence TypeScript errors; narrow values to the
45
+ required type instead.
46
+ - Constants belong in `src/constants/`, never inline in components. Define sets of options as a
47
+ `SCREAMING_SNAKE_CASE` object with `as const` and derive the type from it:
48
+
49
+ ```ts
50
+ // src/constants/sizes.ts
51
+ export const SIZES = {
52
+ SMALL: 'small',
53
+ MEDIUM: 'medium',
54
+ LARGE: 'large',
55
+ } as const;
56
+
57
+ export type Size = (typeof SIZES)[keyof typeof SIZES];
58
+ ```
59
+
60
+ ## Design tokens
61
+
62
+ - Design tokens are CSS custom properties, defined once in a global stylesheet. Reference them with
63
+ `var()`:
64
+
65
+ ```scss
66
+ .root {
67
+ padding: var(--spacing-md);
68
+ color: var(--color-text-primary);
69
+ border-radius: var(--border-radius-sm);
70
+ }
71
+ ```
72
+
73
+ - Do not use Sass variables (`$color-*`) or a `@use`d tokens module for design tokens.
74
+ - Never hardcode colors or spacing values; always use a design token. If a token is missing, add it
75
+ to the token stylesheet instead of inlining a value.
76
+
77
+ ## Versioning
78
+
79
+ - If the project uses [Changesets](https://github.com/changesets/changesets) (a `.changeset/`
80
+ folder exists), every PR must include a changeset describing the change and its semver bump.
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "@mkappelhof/agent-instructions",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0",
4
+ "description": "Shared instructions for AI coding agents working on React/Next.js and Astro projects",
5
+ "exports": {
6
+ "./base.md": "./base.md",
7
+ "./react.md": "./react.md",
8
+ "./astro.md": "./astro.md",
9
+ "./package.json": "./package.json"
10
+ },
11
+ "files": [
12
+ "base.md",
13
+ "react.md",
14
+ "astro.md",
15
+ "README.md",
16
+ "CHANGELOG.md"
17
+ ],
18
+ "license": "MIT",
19
+ "repository": "git@github.com:mkappelhof/frontend-tools.git",
20
+ "author": "Maurice Kappelhof <maurice@mauricekappelhof.nl>",
21
+ "scripts": {
22
+ "test": "echo 'no test step'"
23
+ },
24
+ "keywords": [
25
+ "agents",
26
+ "agents.md",
27
+ "ai",
28
+ "react",
29
+ "nextjs",
30
+ "astro"
31
+ ]
6
32
  }
package/react.md ADDED
@@ -0,0 +1,131 @@
1
+ # React / Next.js — agent instructions
2
+
3
+ Conventions for React projects (Vite, Next.js or another bundler) written in TypeScript and styled
4
+ with SCSS modules. Everything in [`base.md`](./base.md) applies as well; read it first.
5
+
6
+ ## Project structure
7
+
8
+ - **`src/components/`** — Feature components, each co-located with its `.module.scss`.
9
+ - **`src/helpers/`** — Pure utility functions. Every function lives in its own dedicated helper file.
10
+ - **`src/contexts/`** — React context providers (`*.context.tsx`).
11
+ - **`src/constants/`** — Constants and option sets.
12
+ - **`src/interfaces/`** — Shared TypeScript types.
13
+ - **`src/i18n/`** — Localization: `config.ts` initializes i18next, `locales/<locale>.json` holds
14
+ the nested translation keys.
15
+
16
+ In a Next.js project the routes live in `src/app/`; keep route files thin and put reusable UI in
17
+ `src/components/`.
18
+
19
+ ## Components
20
+
21
+ - Components are named arrow-function exports typed as `FC<Props>`, never `function` declarations.
22
+ - **One component per file.** Subcomponents get their own file.
23
+ - Type DOM-wrapping components with `ComponentPropsWithoutRef<'element'>` and wrappers with
24
+ `PropsWithChildren<Props>`.
25
+ - Destructure props in the parameter list instead of using `props.x`. Use default parameter values,
26
+ not `defaultProps` or `propTypes`.
27
+ - Always render text through the project's `Text` component (e.g. `@components/text/text`); never
28
+ place raw strings in bare DOM elements such as `<span>` or `<p>`.
29
+ - **Composition over configuration**: pass content as `children` rather than through content props
30
+ (`label`, `icon`, `text`).
31
+ - **Compound components**: build multi-part components using composition, not props. Keep
32
+ subcomponents in an `elements/` folder and re-export them from the parent module (no
33
+ `elements/index.ts` barrel). The parent manages state and shares it with its subcomponents
34
+ through a context.
35
+
36
+ ```tsx
37
+ // Usage of src/components/tabs/tabs.tsx
38
+ <Tabs defaultValue="account">
39
+ <Tabs.List>
40
+ <Tabs.Tab value="account">{t('settings.account')}</Tabs.Tab>
41
+ <Tabs.Tab value="billing">{t('settings.billing')}</Tabs.Tab>
42
+ </Tabs.List>
43
+ <Tabs.Panel value="account">...</Tabs.Panel>
44
+ <Tabs.Panel value="billing">...</Tabs.Panel>
45
+ </Tabs>
46
+ ```
47
+
48
+ ### Naming
49
+
50
+ - Boolean props start with `is` or `has`: `isOpen`, `hasError`.
51
+ - `useState` pairs are named `[value, setValue]`.
52
+ - Event handler props are named `onX`, and the handlers you pass are named `handleX`:
53
+ `onClick={handleClick}`.
54
+
55
+ ### JSX
56
+
57
+ - Import `clsx` as `classnames`: `import classnames from 'clsx'`. Compose class names as
58
+ `classnames(css.root, className)`.
59
+ - No useless braces: `variant="primary"`, not `variant={'primary'}`.
60
+ - Self-close elements without children: `<Icon />`, `<div />`.
61
+ - Only use a fragment (`<>…</>`) when you need to wrap several children.
62
+ - Every element in a list needs a stable `key`. Do not use the array index if items can reorder.
63
+ - Keep JSX nesting to 4 levels or fewer. Extract a component when it gets deeper.
64
+
65
+ ## Contexts
66
+
67
+ Create all contexts in `src/contexts/` named `*.context.tsx`. A context file exports the context
68
+ value type, the context, a dedicated provider component, and a `use*Context` consumer hook that
69
+ throws when used outside its provider. Always consume a context through its hook, never with
70
+ `useContext` directly. Memoize the value you pass to a provider with `useMemo`; never pass a new
71
+ object or array literal.
72
+
73
+ ```tsx
74
+ // src/contexts/tabs.context.tsx
75
+ export type TabsContextValue = {
76
+ activeValue: string;
77
+ setActiveValue: (value: string) => void;
78
+ };
79
+
80
+ export const TabsContext = createContext<TabsContextValue | undefined>(undefined);
81
+
82
+ export const TabsProvider: FC<PropsWithChildren<{ value: TabsContextValue }>> = ({ value, children }) => (
83
+ <TabsContext.Provider value={value}>{children}</TabsContext.Provider>
84
+ );
85
+
86
+ export const useTabsContext = (): TabsContextValue => {
87
+ const context = useContext(TabsContext);
88
+
89
+ if (!context) throw new Error('useTabsContext must be used within a TabsProvider');
90
+
91
+ return context;
92
+ };
93
+ ```
94
+
95
+ ## Next.js
96
+
97
+ - Components in `app/` are Server Components by default. Add `'use client'` only to the components
98
+ that need state, effects, browser APIs or context, and keep that boundary as low in the tree as
99
+ possible.
100
+ - Context providers are client components; wrap them in a small `'use client'` providers component
101
+ and render it from the layout.
102
+ - Use `next/link` for internal navigation, not a plain `<a href="/…">`.
103
+ - Use `next/image` instead of `<img>`, and `next/script` instead of a raw `<script>` tag.
104
+ - Load fonts with `next/font`, not `<link>` tags to font CDNs.
105
+ - Set page metadata with the Metadata API (`export const metadata` / `generateMetadata`). Do not
106
+ import `next/head` or `next/document` in `app/`.
107
+
108
+ ## Localization
109
+
110
+ - Never hardcode user-facing text (labels, placeholders, aria-labels, messages). Add a key to the
111
+ matching group in the locale file (e.g. `src/i18n/locales/en-US.json`) and render it with
112
+ `const { t } = useTranslation()` from `react-i18next`.
113
+ - Interpolate values with `t('group.key', { name })`, matching `{{name}}` in the translation. Use
114
+ i18next `_one` / `_other` suffixed keys with `{ count }` for plurals.
115
+ - Non-component code (helpers, constants) returns a `TranslationKey` instead of translated text, so
116
+ the component can translate it.
117
+
118
+ ## Styling
119
+
120
+ - Use SCSS modules (`.module.scss`) co-located with each component.
121
+ - Import the design token stylesheet (see `base.md`) once at the app root, e.g. in `main.tsx` or
122
+ the root `layout.tsx`.
123
+
124
+ ## Testing
125
+
126
+ - Use **Vitest** with the JSDOM environment for unit tests.
127
+ - Co-locate tests with their source as `*.spec.ts` or `*.spec.tsx`.
128
+ - Every helper must have a unit test. Add or update the co-located `*.spec.ts` whenever you add or
129
+ change one.
130
+ - Test pure helpers directly. Mock browser APIs and external dependencies at module boundaries with
131
+ Vitest mocks.