agentleFS
gravitee-iogravitee-io/gravitee-api-management/gravitee-apim-console-webui/AGENTS.md

gravitee-api-management / gravitee-apim-console-webui

AGENTS.md469 starsChanged 5 months agoApache-2.0View on GitHub

Root conventions also apply: read ../AGENTS.md; where they disagree, the closest file wins for its directory and below. If your tool cannot read it, restart it from the repository root. Angular-specific conventions for Gravitee repositories. Global engineering, security, accessibility, TypeScript, and TDD rules still apply.

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

25 rules. About 0 are common, 21 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈21

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use the repo's documented scripts for build, test, lint, and serve.

    line 21
  2. Distinctive:

    Prefer the Angular patterns already established in the repo.

    line 22
  3. Distinctive:

    Keep components focused. Containers orchestrate data and side effects.

    line 26
  4. Distinctive:

    Prefer typed inputs, outputs, forms, services, and API models.

    line 27
  5. Distinctive:

    Prefer signals or template async binding for UI state.

    line 28
  6. Distinctive:

    Do not create nested subscriptions.

    line 31
  7. Distinctive:

    Use the repo's established Angular template syntax.

    line 36
  8. Distinctive:

    Avoid method calls in templates for derived state.

    line 37
  9. Distinctive:

    Use semantic HTML and accessible interactions before adding ARIA-only custom widgets.

    line 38
  10. Distinctive:

    Use design-system tokens, CSS variables, and existing component APIs.

    line 39
  11. Distinctive:

    Do not use ::ng-deep / :ng-deep unless there is no supported component API, token, or documented styling hook.

    line 40
  12. Distinctive:

    Use typed reactive forms where the repo supports them.

    line 44
  13. Distinctive:

    Use the repo's existing Angular test stack and utilities.

    line 49
  14. Distinctive:

    Test behaviour, not implementation details.

    line 50
  15. Distinctive:

    Prefer component harnesses or stable user-facing selectors such as roles, labels, and data-testid where available.

    line 51
  16. Distinctive:

    Keep async tests deterministic.

    line 54
  17. Distinctive:

    Treat changes to any of these as compatibility-sensitive — call them out explicitly in the PR description and final response summary:

    line 64
  18. Distinctive:

    Keep each id on the control or value it identifies.

    line 86
  19. Distinctive:

    Write an id as a string literal.

    line 87
  20. Distinctive:

    When no existing design-system component or pattern fits, suggest collaborating with UX rather than inventing a new one.

    line 107
  21. Very specific:

    Use lodash for common transforms (kebabCase, isEmpty, isEqual, merge, ...) before writing a new utility.

    line 122
  22. Very specific:

    Use fixture.destroy() instead of discardPeriodicTasks.

    line 123
  23. Very specific:

    Use GioTestingModule and CONSTANTS_TESTING from shared/testing in specs — they register provideHttpClient() + provideHttpClientTesting() …

    line 162
  24. Very specific:

    Add methods to the component's harness (.harness.ts) and use them in specs.

    line 163
  25. Distinctive:

    Before creating a custom harness class, search the codebase for existing patterns.

    line 164

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md
<!-- Generated by gravitee-ai. Do not edit directly. Edit the source rules and re-run: gbuddy setup Source rules: - context/rules/tech/angular.md - context/rules/tech/typescript.md - context/rules/tech/ui-test-ids.md - .ai/rules/apim-angular.md - .ai/rules/console-webui.md -->

Root conventions also apply: read ../AGENTS.md; where they disagree, the closest file wins for its directory and below. If your tool cannot read it, restart it from the repository root.

Angular Conventions

Angular-specific conventions for Gravitee repositories. Global engineering, security, accessibility, TypeScript, and TDD rules still apply.

Follow the repo

  • Match the repository's Node version, package manager, lockfile, Angular version, formatter, lint rules, folder structure, naming style, and test stack. Do not introduce a second convention.
  • Use the repo's documented scripts for build, test, lint, and serve. Do not invent new entrypoints unless explicitly required.
  • Prefer the Angular patterns already established in the repo. Use standalone components, signals, and modern control flow where the repo has adopted them.

Components, state, and RxJS

  • Keep components focused. Containers orchestrate data and side effects; presentational components receive inputs and emit outputs.
  • Prefer typed inputs, outputs, forms, services, and API models.
  • Prefer signals or template async binding for UI state. Avoid duplicate reactive state for the same value.
  • For async data, prefer rxResource or the repo's equivalent where available, because it co-locates loading/error/value. Fall back to the async pipe for template-only values, and to toSignal() when the class needs a signal.
  • Reserve subscribe() for side effects such as navigation, dialogs, analytics, or toasts, using the repo's existing destroy pattern.
  • Do not create nested subscriptions. Use the appropriate RxJS flattening operator instead.
  • On Angular code using dependency injection, prefer the repo's established style. In modern Angular code, prefer inject() where it improves clarity.

Templates, styling, and accessibility

  • Use the repo's established Angular template syntax. Prefer modern control flow (@if, @for, @switch) where the repo has adopted it.
  • Avoid method calls in templates for derived state. Use computed values, signals, observables, or pipes.
  • Use semantic HTML and accessible interactions before adding ARIA-only custom widgets.
  • Use design-system tokens, CSS variables, and existing component APIs. Do not hard-code colours, spacing, or one-off visual patterns unless already local convention.
  • Do not use ::ng-deep / :ng-deep unless there is no supported component API, token, or documented styling hook.

Forms

  • Use typed reactive forms where the repo supports them.
  • Validate at the boundary and surface errors with accessible, user-visible messaging.

Testing

  • Use the repo's existing Angular test stack and utilities.
  • Test behaviour, not implementation details. Do not assert private state, framework internals, or ng-reflect-*.
  • Prefer component harnesses or stable user-facing selectors such as roles, labels, and data-testid where available.
  • For HTTP and service wiring, prefer the repo's existing HTTP testing utilities rather than mocking away request/response behaviour.
  • Exception to Follow the repo: for components using rxResource (or other resource-based async data), use the provider-style HTTP testing setup (provideHttpClient + provideHttpClientTesting), even where the repo's other tests use the module style. Module-style setups such as HttpClientTestingModule have hung such tests on whenStable().
  • Keep async tests deterministic. Await async work explicitly; avoid sleeps, wall-clock assumptions, real network calls, and order-dependent assertions.
  • For bug fixes, add or update a regression test where practical.

Shared UI and design system

  • Reuse existing project utilities, design-system components, and Angular Material/Gio patterns before creating new helpers or UI components.
  • Extend the design system; do not fork or duplicate it inside feature code.

Compatibility-sensitive surfaces

Treat changes to any of these as compatibility-sensitive — call them out explicitly in the PR description and final response summary:

  • Public routes, navigation behaviour, guards, and permissions.
  • Generated API models, DTOs, and on-wire data shapes.
  • Form field names, validation behaviour, and submitted payloads.
  • Design-system components, tokens, shared styles, and global theme behaviour.
  • Accessibility semantics, keyboard behaviour, and focus management.
  • Build configuration, environment files, package manager files, and CI configuration.

TypeScript Conventions

TypeScript-specific conventions; the general engineering rules (clean code, fail-loud boundaries) still apply.

  • Match the repository's module system and tsconfig.json strictness. In an existing package, do not loosen or tighten these settings unless asked. A new package inside an existing repository follows the repository; default to ESM with strict and noUncheckedIndexedAccess only where the repository has no established setting.
  • No any — use unknown and narrow with type guards.
  • Type the boundaries (function signatures, exported types); let inference handle the rest.

UI Test Ids

Automated tests, including end-to-end suites in other repositories, select elements by data-testid. A changed or removed id breaks them without failing any test here. This holds whether or not a suite covers the screen today.

  • Every element your change adds, or whose markup it rewrites, that reads or writes data carries a data-testid: form controls, toggles, selects, displayed application data (status, names, counts), and the buttons that create, save, delete or change state. A styling, formatting or mechanical change does not require ids on elements it does not otherwise touch.
  • Keep each id on the control or value it identifies; an id on a wrapper does not count. Replacing a component that keeps the same job is not a removal: its id stays. Do not strip ids from production builds.
  • Write an id as a string literal. Where it must vary per item, keep a literal prefix and vary only the suffix, taken from a stable key, not the position or display text.
  • While its element stays in the product, never rename or remove an existing data-testid value, built at run time or not, even when its name is poor, its case is inconsistent, or it no longer fits its context. Cleaning up the code around it does not extend to the id.
  • When you move markup into a shared component, the original screen keeps rendering its original ids. A reusable component takes the id or prefix from its caller (an input or prop) and hard-codes none; when the caller passes none, the inner control renders without one. The original caller passes the old value, new callers may use new ones.
  • Remove an id only when its element leaves the product. Name each removed id, or the prefix of a removed family, with the reason, in the pull request description (the commit message when there is no pull request yet) and in your final summary, as a compatibility-sensitive change.

APIM Angular Conventions

Absolutes

The shared Angular rule's "where the repo has adopted them" conditions are settled here — these are binary:

  • Standalone: new components, directives, and pipes are standalone — on this Angular version that is the default, so do not write standalone: true. Do not convert existing standalone: false declarations as a side effect of an unrelated change.
  • Signals first: signals for local state (signal()), derived state (computed()), inputs (input() / input.required()), and outputs (output()).
  • New control flow strictly: @if, @for, @switch — never *ngIf or *ngFor.

Components

  • Class member order: 1. private readonly injections (inject()), 2. inputs, 3. outputs, 4. state, 5. computed (computed(), toSignal(), rxResource()), 6. methods (public then private).
  • DI: always private readonly service = inject(ServiceName); — never constructor injection, and no constructor or ngOnInit subscription setup.
  • The destroy pattern the shared Angular rule refers to is takeUntilDestroyed(this.destroyRef) — every .subscribe() gets it.
  • When no existing design-system component or pattern fits, suggest collaborating with UX rather than inventing a new one.
  • The consuming-observables decision table, rxResource patterns, and exemplar components live in .ai/guides/angular-async-patterns.md (a repository-root path) — read it before wiring async data.

Dialogs

  • Strictly type dialog opens: this.matDialog.open<ComponentType, InputType, OutputType>(...).

Naming

  • Functions: verb + noun that reflects the operation (extract, collect, derive, compute, find).
  • Variables: name the concept they hold, not the type; no contractions (comp, el, attr) unless established in the file.
  • Booleans: is / has / can / should prefixes. Observables: $ suffix.

Utilities and testing

  • Use lodash for common transforms (kebabCase, isEmpty, isEqual, merge, ...) before writing a new utility.
  • Use fixture.destroy() instead of discardPeriodicTasks.

Console Web UI Conventions

Particles design system

  • Components: Particles (gio-*) first; Angular Material (mat-*) only when no Particles equivalent exists. Icons: gio-icons first, Material Icons as fallback.
  • Hierarchy when adding UI: Particles (gio-*) → Console shared (src/shared/components/, gio-*) → Angular Material (mat-*) → from scratch (ask the requester: feature-scoped or src/shared?).
  • Key shared components: gio-permission, gio-license-banner, gio-table-wrapper, gio-api-select-dialog, gio-widget-layout. Feature code imports from shared/ rather than reimplementing.

Styling

  • Tokens only: no hex/RGB values and no arbitrary font-size px — use design tokens and CSS/SCSS variables. The shared Angular rule's "unless already local convention" escape is closed here.
  • 4px grid: all margins, padding, and gaps are multiples of 4.
  • Material overrides via SCSS mixins (e.g. @include mat.button-overrides), not ad-hoc CSS variables.
  • Card surfaces stay distinct from the app background, with spacing between card elements on the 4px grid.
  • Layout single source of truth: src/scss/gio-layout.scss — @use '<path>/scss/gio-layout' as gio-layout;, breakpoint mixins small-desktop, desktop, large-desktop. Use Flexbox/Grid for layout.

Layout and UI patterns

  • Layout uses containers with centered content — not full-width — where a centered layout is intended.
  • Each screen has a single primary CTA; button spacing and placement stay consistent.
  • Table headers align with cell content and use current header styles; tables use appropriate padding and action-column sizing.
  • Page titles sit outside cards at the top. Links use themed colors.

Accessibility (WCAG 2.1 AA)

  • Color contrast meets AA for text and interactive elements.
  • Focus outlines remain visible, or a replacement is provided.
  • Respect prefers-reduced-motion.

Shared guards and services

  • Guards from shared/: PermissionGuard, HasLicenseGuard, HasUnsavedChangesGuard.
  • Permissions: GioPermissionService, ApimFeature, GioLicenseBannerModule.
  • Utilities: prefer shared/utils, shared/pipes, shared/validators.

Testing

  • Use GioTestingModule and CONSTANTS_TESTING from shared/testing in specs — they register provideHttpClient() + provideHttpClientTesting() internally, so they satisfy the shared Angular rule's rxResource testing exception.
  • Add methods to the component's harness (.harness.ts) and use them in specs; reach for document.querySelector only when no harness path exists.
  • Before creating a custom harness class, search the codebase for existing patterns. Prefer built-in harnesses (SpanHarness, DivHarness, MatButtonHarness, ...) from @gravitee/ui-particles-angular/testing or Angular Material with locatorFor / locatorForOptional / locatorForAll and a selector, e.g. locatorForOptional(SpanHarness.with({ selector: '[data-testid="..."]' })).

Storybook

  • Shared components have .stories.ts files (e.g. under "Shared / ...").

Legacy AngularJS

  • Preserve existing AngularJS patterns. Do not mix Angular and AngularJS in the same component.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.