@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.
Files changed (68) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +106 -0
  3. package/content/defaults.json +10 -0
  4. package/content/rules/comments.md +31 -0
  5. package/content/rules/lint-and-format.md +26 -0
  6. package/content/rules/reactive-state.md +15 -0
  7. package/content/rules/styling.md +35 -0
  8. package/content/skills/angular-patterns/SKILL.md +60 -0
  9. package/content/skills/git-commit/SKILL.md +29 -0
  10. package/content/skills/handoff/SKILL.md +98 -0
  11. package/content/skills/query/SKILL.md +114 -0
  12. package/content/skills/rxjs-signals/SKILL.md +65 -0
  13. package/content/skills/sdk-docs/SKILL.md +70 -0
  14. package/content/skills/story-styling/SKILL.md +83 -0
  15. package/content/skills/styleguide/SKILL.md +66 -0
  16. package/content/skills/styleguide/STYLEGUIDE.md +520 -0
  17. package/content/skills/theming/SKILL.md +110 -0
  18. package/content/skills/verify-in-storybook/SKILL.md +78 -0
  19. package/content/skills/verify-in-storybook/verify-template.mjs +42 -0
  20. package/package.json +15 -0
  21. package/src/index.d.ts +2 -0
  22. package/src/index.js +79 -0
  23. package/src/index.js.map +1 -0
  24. package/src/lib/config.d.ts +21 -0
  25. package/src/lib/config.js +54 -0
  26. package/src/lib/config.js.map +1 -0
  27. package/src/lib/filter.d.ts +16 -0
  28. package/src/lib/filter.js +49 -0
  29. package/src/lib/filter.js.map +1 -0
  30. package/src/lib/frontmatter.d.ts +23 -0
  31. package/src/lib/frontmatter.js +117 -0
  32. package/src/lib/frontmatter.js.map +1 -0
  33. package/src/lib/index.d.ts +9 -0
  34. package/src/lib/index.js +13 -0
  35. package/src/lib/index.js.map +1 -0
  36. package/src/lib/load-content.d.ts +19 -0
  37. package/src/lib/load-content.js +79 -0
  38. package/src/lib/load-content.js.map +1 -0
  39. package/src/lib/owned-paths.d.ts +7 -0
  40. package/src/lib/owned-paths.js +47 -0
  41. package/src/lib/owned-paths.js.map +1 -0
  42. package/src/lib/plan.d.ts +20 -0
  43. package/src/lib/plan.js +57 -0
  44. package/src/lib/plan.js.map +1 -0
  45. package/src/lib/render.d.ts +39 -0
  46. package/src/lib/render.js +73 -0
  47. package/src/lib/render.js.map +1 -0
  48. package/src/lib/sync.d.ts +9 -0
  49. package/src/lib/sync.js +90 -0
  50. package/src/lib/sync.js.map +1 -0
  51. package/src/lib/targets/claude.d.ts +7 -0
  52. package/src/lib/targets/claude.js +46 -0
  53. package/src/lib/targets/claude.js.map +1 -0
  54. package/src/lib/targets/codex.d.ts +11 -0
  55. package/src/lib/targets/codex.js +26 -0
  56. package/src/lib/targets/codex.js.map +1 -0
  57. package/src/lib/targets/copilot.d.ts +11 -0
  58. package/src/lib/targets/copilot.js +43 -0
  59. package/src/lib/targets/copilot.js.map +1 -0
  60. package/src/lib/targets/cursor.d.ts +7 -0
  61. package/src/lib/targets/cursor.js +35 -0
  62. package/src/lib/targets/cursor.js.map +1 -0
  63. package/src/lib/targets/neutral.d.ts +8 -0
  64. package/src/lib/targets/neutral.js +29 -0
  65. package/src/lib/targets/neutral.js.map +1 -0
  66. package/src/lib/targets/shared.d.ts +60 -0
  67. package/src/lib/targets/shared.js +50 -0
  68. 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).