@ethlete/agent-rules 0.1.0-next.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 +23 -0
- package/README.md +106 -0
- package/content/defaults.json +10 -0
- package/content/rules/comments.md +31 -0
- package/content/rules/lint-and-format.md +26 -0
- package/content/rules/reactive-state.md +15 -0
- package/content/rules/styling.md +35 -0
- package/content/skills/angular-patterns/SKILL.md +60 -0
- package/content/skills/git-commit/SKILL.md +29 -0
- package/content/skills/handoff/SKILL.md +98 -0
- package/content/skills/query/SKILL.md +114 -0
- package/content/skills/rxjs-signals/SKILL.md +65 -0
- package/content/skills/sdk-docs/SKILL.md +70 -0
- package/content/skills/story-styling/SKILL.md +83 -0
- package/content/skills/styleguide/SKILL.md +66 -0
- package/content/skills/styleguide/STYLEGUIDE.md +520 -0
- package/content/skills/theming/SKILL.md +110 -0
- package/content/skills/verify-in-storybook/SKILL.md +78 -0
- package/content/skills/verify-in-storybook/verify-template.mjs +42 -0
- package/package.json +15 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +79 -0
- package/src/index.js.map +1 -0
- package/src/lib/config.d.ts +21 -0
- package/src/lib/config.js +54 -0
- package/src/lib/config.js.map +1 -0
- package/src/lib/filter.d.ts +16 -0
- package/src/lib/filter.js +49 -0
- package/src/lib/filter.js.map +1 -0
- package/src/lib/frontmatter.d.ts +23 -0
- package/src/lib/frontmatter.js +117 -0
- package/src/lib/frontmatter.js.map +1 -0
- package/src/lib/index.d.ts +9 -0
- package/src/lib/index.js +13 -0
- package/src/lib/index.js.map +1 -0
- package/src/lib/load-content.d.ts +19 -0
- package/src/lib/load-content.js +79 -0
- package/src/lib/load-content.js.map +1 -0
- package/src/lib/owned-paths.d.ts +7 -0
- package/src/lib/owned-paths.js +47 -0
- package/src/lib/owned-paths.js.map +1 -0
- package/src/lib/plan.d.ts +20 -0
- package/src/lib/plan.js +57 -0
- package/src/lib/plan.js.map +1 -0
- package/src/lib/render.d.ts +39 -0
- package/src/lib/render.js +73 -0
- package/src/lib/render.js.map +1 -0
- package/src/lib/sync.d.ts +9 -0
- package/src/lib/sync.js +90 -0
- package/src/lib/sync.js.map +1 -0
- package/src/lib/targets/claude.d.ts +7 -0
- package/src/lib/targets/claude.js +46 -0
- package/src/lib/targets/claude.js.map +1 -0
- package/src/lib/targets/codex.d.ts +11 -0
- package/src/lib/targets/codex.js +26 -0
- package/src/lib/targets/codex.js.map +1 -0
- package/src/lib/targets/copilot.d.ts +11 -0
- package/src/lib/targets/copilot.js +43 -0
- package/src/lib/targets/copilot.js.map +1 -0
- package/src/lib/targets/cursor.d.ts +7 -0
- package/src/lib/targets/cursor.js +35 -0
- package/src/lib/targets/cursor.js.map +1 -0
- package/src/lib/targets/neutral.d.ts +8 -0
- package/src/lib/targets/neutral.js +29 -0
- package/src/lib/targets/neutral.js.map +1 -0
- package/src/lib/targets/shared.d.ts +60 -0
- package/src/lib/targets/shared.js +50 -0
- package/src/lib/targets/shared.js.map +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdk-docs
|
|
3
|
+
description: Where the @ethlete SDK is documented and how to find the right page. Read BEFORE using any @ethlete component, directive or API you have not already used in this repo - the docs site and Storybook are the source of truth, and inputs/outputs must never be guessed from a component's name.
|
|
4
|
+
kind: skill
|
|
5
|
+
scope: consumer
|
|
6
|
+
vars: [docsBaseUrl, sdkStorybookUrl]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Finding the @ethlete SDK docs
|
|
10
|
+
|
|
11
|
+
The SDK lives in another repository. Its source is **not** in this project, so the only
|
|
12
|
+
reliable way to learn a component's inputs, outputs, defaults or required directives is
|
|
13
|
+
to read its documentation - never infer an API from the name, and never copy a shape
|
|
14
|
+
from an unrelated component.
|
|
15
|
+
|
|
16
|
+
Two sources, both authoritative for different things:
|
|
17
|
+
|
|
18
|
+
| Source | URL | Use it for |
|
|
19
|
+
| ------------- | ------------------- | ------------------------------------------------------------------------------------------------ |
|
|
20
|
+
| **Docs site** | {%docsBaseUrl%} | Prose guides: what a thing is for, options, defaults, behaviour, migration notes |
|
|
21
|
+
| **Storybook** | {%sdkStorybookUrl%} | The live component: every variant rendered, the real controls, and the exact markup a story uses |
|
|
22
|
+
|
|
23
|
+
## Finding the right page
|
|
24
|
+
|
|
25
|
+
Page URLs follow `{%docsBaseUrl%}/<lib>/<topic>`. The library sections:
|
|
26
|
+
|
|
27
|
+
| Section | Covers |
|
|
28
|
+
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
29
|
+
| `/components/` | The active UI library - one guide per domain (see the list below) |
|
|
30
|
+
| `/core/` | Framework primitives: `theming`, `overlay-runtime`, `signal-utils`, `element-signals`, `animations`, `scrolling`, `drag-resize`, `directives-pipes`, `providers`, `seo`, `utilities` |
|
|
31
|
+
| `/query/` | Data fetching - see the dedicated {%skill:query%} guide first |
|
|
32
|
+
| `/cdk/` | The predecessor UI toolkit, maintenance mode. Only for code that still uses it |
|
|
33
|
+
| `/contentful/`, `/cli/`, `/eslint/`, `/types/` | The remaining packages |
|
|
34
|
+
|
|
35
|
+
Component domains under `/components/`:
|
|
36
|
+
|
|
37
|
+
`accordion` `bracket` `bracket-rounds-list` `breadcrumb` `button` `calendar` `carousel`
|
|
38
|
+
`cascader` `chip` `choice-inputs` `date-time-inputs` `dropzone` `error-codes`
|
|
39
|
+
`filter-overlay` `floating-action` `focus-ring` `forms` `grid` `icon` `loader`
|
|
40
|
+
`localization` `masonry` `match` `menu` `mixed-state` `notification` `overlay-openers`
|
|
41
|
+
`overlays` `pagination` `picture` `query-devtools` `query-error` `rich-text-editor`
|
|
42
|
+
`scrollable` `select` `skeleton` `slider` `sport-recipes` `standings` `stream` `table`
|
|
43
|
+
`tabs` `text-inputs` `time-picker` `toggletip` `tooltip`
|
|
44
|
+
|
|
45
|
+
So the table guide is `{%docsBaseUrl%}/components/table`, the menu guide
|
|
46
|
+
`{%docsBaseUrl%}/components/menu`, and so on. When a name isn't in that list, start at
|
|
47
|
+
`{%docsBaseUrl%}/components/` and follow the sidebar rather than guessing a URL.
|
|
48
|
+
|
|
49
|
+
## How to use them
|
|
50
|
+
|
|
51
|
+
- **Read before writing.** Fetch the guide for the domain you are about to touch. A
|
|
52
|
+
component's required host directives, its two-way models, and which imports array to
|
|
53
|
+
pull in (`MENU_IMPORTS`, `TABLE_IMPORTS`, …) are all things the docs state and the
|
|
54
|
+
name does not imply.
|
|
55
|
+
- **Storybook shows the real thing.** When the prose is ambiguous about markup or a
|
|
56
|
+
variant's look, open the story - the source panel is the exact template that renders it.
|
|
57
|
+
- **Match the docs to your installed version.** Check the `@ethlete/*` versions in
|
|
58
|
+
`package.json`. The main docs and Storybook track the released line; a repo on
|
|
59
|
+
`-next` prereleases should read `{%docsBaseUrl%}` and `{%sdkStorybookUrl%}` only if
|
|
60
|
+
they are the matching prerelease deployments, otherwise expect drift and verify
|
|
61
|
+
against the installed `.d.ts` in `node_modules/@ethlete/<lib>`.
|
|
62
|
+
- **`node_modules` is the tiebreaker.** If the docs and the installed package disagree,
|
|
63
|
+
the installed type definitions win - report the drift rather than working around it.
|
|
64
|
+
- **Never treat a `subtle` namespace as public API.** Anything exposed under `subtle` is
|
|
65
|
+
an unsupported escape hatch that can change without a major version.
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- Data fetching has its own guide: {%skill:query%}
|
|
70
|
+
- Theming tokens and how to register themes: {%skill:theming%}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: story-styling
|
|
3
|
+
description: How to style Storybook story files - where Tailwind is (and isn't) allowed, and how to check which utilities actually exist in your trimmed Tailwind theme before reaching for one. Read BEFORE writing or editing any `*.stories.ts` / `stories/` component, or when a class in a story renders with no visible effect.
|
|
4
|
+
kind: skill
|
|
5
|
+
scope: consumer
|
|
6
|
+
requires: ['@ethlete/core']
|
|
7
|
+
paths: ['**/*.stories.ts', '**/stories/**']
|
|
8
|
+
vars: [themeStylesheet]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Styling story files
|
|
12
|
+
|
|
13
|
+
Two separate rules, often confused:
|
|
14
|
+
|
|
15
|
+
1. **Component source is plain CSS, never Tailwind.** The `.css` next to a
|
|
16
|
+
component, wrapped in `@layer components`, using surface/color tokens - see
|
|
17
|
+
{%skill:theming%}.
|
|
18
|
+
2. **Story files may use Tailwind** (`*.stories.ts`, anything under a `stories/`
|
|
19
|
+
folder) for demo layout only - the frame around the component, not the
|
|
20
|
+
component's own look.
|
|
21
|
+
|
|
22
|
+
## The trap: an unknown utility fails silently
|
|
23
|
+
|
|
24
|
+
A Tailwind v4 `@theme` that resets a token group deletes every utility built from
|
|
25
|
+
it. Tailwind then emits **no class at all** for the name you typed - there is no
|
|
26
|
+
error and no warning, the element just renders unstyled. A theme that does this:
|
|
27
|
+
|
|
28
|
+
```css
|
|
29
|
+
--color-*: initial; /* the entire default palette is GONE */
|
|
30
|
+
--text-*: initial; /* the entire default type scale is GONE */
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
leaves `bg-blue-500`, `text-gray-700` and `text-sm` as dead strings, even though
|
|
34
|
+
they are "real" Tailwind classes.
|
|
35
|
+
|
|
36
|
+
**Read the theme before reaching for an unfamiliar utility.** This project's is
|
|
37
|
+
`{%themeStylesheet%}`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
grep -nE -- '--(color|text|font|spacing)-' {%themeStylesheet%}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If `@theme` doesn't define the token, the class doesn't exist. Check rather than
|
|
44
|
+
guess, and prefer utilities from groups the theme leaves untouched (layout, flex,
|
|
45
|
+
grid, radius, opacity, borders) over ones it redefines.
|
|
46
|
+
|
|
47
|
+
Watch the root font size too: a theme that sets `html { font-size: 62.5% }` makes
|
|
48
|
+
`1rem` = 10px, so every rem-based utility is 62.5% of its nominal value. That mostly
|
|
49
|
+
reads fine when `--spacing` is scaled to match, but it bites on the container scale -
|
|
50
|
+
`max-w-3xl` becomes 480px, not 768px, and silently truncates a demo you sized by eye.
|
|
51
|
+
When a width or height actually matters, bind px:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<div [style.max-inline-size.px]="768" class="p-8">…</div>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Colours in a story come from theming, not utilities
|
|
58
|
+
|
|
59
|
+
A story renders inside a **surface theme** and a **colour theme**, so any colour it
|
|
60
|
+
paints must come from those tokens - the same rule as component CSS
|
|
61
|
+
({%skill:theming%} is the reference for the token names).
|
|
62
|
+
|
|
63
|
+
- A tinted panel: put `etAutoSurface` on it (next elevation up) and read the token:
|
|
64
|
+
`style="background: var(--et-surface-background-solid)"`.
|
|
65
|
+
- An accent: scope it with `[etProvideColor]="'brand'"` and read
|
|
66
|
+
`--et-theme-color-primary-solid` / `--et-theme-color-ink-solid`. Theme names are
|
|
67
|
+
whatever **your app** registers - fine to name in a story, never in library code.
|
|
68
|
+
- Better still: don't hand-paint. Compose the component that already does it
|
|
69
|
+
(`<et-chip>` for a badge, `<et-button>` for an action) - that's also what a real
|
|
70
|
+
consumer would write.
|
|
71
|
+
- **Never `dark:`.** It resolves to `prefers-color-scheme`, which knows nothing about
|
|
72
|
+
the surface theme the story is rendered on: a story on a dark surface would keep its
|
|
73
|
+
light styling on an OS in light mode. Elevation and light/dark come from
|
|
74
|
+
`[etProvideSurface]` / `etAutoSurface`.
|
|
75
|
+
|
|
76
|
+
## Checklist for a story you just wrote
|
|
77
|
+
|
|
78
|
+
- Utilities only for layout/spacing/typography; the component's own look comes from the component.
|
|
79
|
+
- Every colour is a theme token, or a utility built on a token the theme still defines.
|
|
80
|
+
- Text sizes from your theme's scale, not Tailwind's default `text-sm`/`text-xs`.
|
|
81
|
+
- No `dark:` variants.
|
|
82
|
+
- Width/height that matters is px, not the rem container scale.
|
|
83
|
+
- Then verify it actually renders - {%skill:verify-in-storybook%}.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: styleguide
|
|
3
|
+
description: Entry point for the Ethlete coding styleguide. Read when writing or reviewing TypeScript/Angular code. The mechanical rules are enforced by `@ethlete/eslint-plugin` (run lint with `--fix`); this covers the cross-cutting judgment calls (accessibility modifiers, `@internal`, naming intent, file/folder structure).
|
|
4
|
+
kind: skill
|
|
5
|
+
scope: consumer
|
|
6
|
+
requires: ['@ethlete/eslint-plugin']
|
|
7
|
+
vars: [lintCommand, lintFixCommand]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Styleguide - the parts lint can't check
|
|
11
|
+
|
|
12
|
+
Most of the styleguide is enforced automatically by **`@ethlete/eslint-plugin`**.
|
|
13
|
+
Don't hand-check or hand-fix those - **run lint with `--fix` first**; many rules
|
|
14
|
+
ship auto-fixers, so most violations are corrected for you:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
{%lintFixCommand%} # auto-fixes first (case, ordering, $ suffix, metadata, …)
|
|
18
|
+
{%lintCommand%} # then re-run to see what needs a manual fix
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Full prose reference, including the rule → lint-rule table and the worked
|
|
22
|
+
file-structure example: {%resource:STYLEGUIDE.md%}.
|
|
23
|
+
|
|
24
|
+
## Focused guides
|
|
25
|
+
|
|
26
|
+
- {%skill:rxjs-signals%} - synchronous state vs async, subscriptions, effects.
|
|
27
|
+
- {%skill:angular-patterns%} - components, directives, services, pipes, templates,
|
|
28
|
+
lifecycle.
|
|
29
|
+
|
|
30
|
+
The rest of this guide is the cross-cutting judgment that doesn't belong to one
|
|
31
|
+
of those.
|
|
32
|
+
|
|
33
|
+
## Accessibility & visibility
|
|
34
|
+
|
|
35
|
+
Lint auto-fixes injected providers to `private` and flags template/host-visible
|
|
36
|
+
members, but the _intent_ is yours:
|
|
37
|
+
|
|
38
|
+
- Injected provider → `private` by default; `protected` **only** when referenced
|
|
39
|
+
from the HTML template or a `host:` binding; **drop the modifier entirely** if
|
|
40
|
+
keeping it `private` would force a member alias (a property whose sole purpose
|
|
41
|
+
is re-exposing a nested member - expose the injected symbol directly instead).
|
|
42
|
+
- Never add a member that only **aliases** another member's nested property
|
|
43
|
+
(`foo = this.thing.foo`) - widen the source member's visibility and use it.
|
|
44
|
+
- For a member that must stay technically public purely for cross-class/DI use
|
|
45
|
+
(e.g. a self-registration method called by a sub-directive), keep it `public`
|
|
46
|
+
and tag `/** @internal */` so build tooling strips it from the published
|
|
47
|
+
`.d.ts`. Never put `@internal` on `private`/`protected` members.
|
|
48
|
+
|
|
49
|
+
## Naming with intent
|
|
50
|
+
|
|
51
|
+
- Name things after **what they do**, not the mechanism: an `onChange` that posts
|
|
52
|
+
a form → `sendFormValueToApi`. (Lint catches `on`-prefixed _outputs_; plain
|
|
53
|
+
functions/methods are on you.)
|
|
54
|
+
- More than two params → a single **object parameter** with a named `type`.
|
|
55
|
+
- Descriptive generics (`TValue`, `TResult`) and descriptive const/var names.
|
|
56
|
+
|
|
57
|
+
## File & folder structure
|
|
58
|
+
|
|
59
|
+
- Mirror routes in the folder tree; routing components end in `-view`.
|
|
60
|
+
- Reusable pieces → `components/`; a component's private children → `partials/`
|
|
61
|
+
(used only by that parent); Storybook helpers → `storybook/` (never exported
|
|
62
|
+
from the component's public surface); generic dumb components → `uikit/`;
|
|
63
|
+
app-shell pieces → `shell/`.
|
|
64
|
+
- Each exportable folder has an `index.ts` barrel - but **import from the source
|
|
65
|
+
file, not the barrel** (barrel imports are lint-banned; they break lazy loading).
|
|
66
|
+
- Don't import from a parent directory in a subdirectory (circular-dep risk).
|