diff --git a/AGENTS.md b/AGENTS.md index 90a8a67f2e..c765fbbb48 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,15 +19,18 @@ All AI assistants reference these files to understand: ```bash # Clone & install git clone https://github.com/openshift/console.git && cd console -make install # yarn + go deps +cd frontend && yarn install # Development server -make start +cd frontend && yarn dev # Core commands -make lint # ESLint + Prettier -make test # Jest unit + Cypress E2E -make build # Production build +cd frontend && yarn lint # ESLint + Prettier +cd frontend && yarn test # Jest unit tests +cd frontend && yarn build # Production build + +# Full build (frontend + backend) +./build.sh ``` ### Frontend Development Commands @@ -57,16 +60,19 @@ make build # Production build **REQUIRED FOR ALL CODING AGENTS: Before generating or modifying code, always consult the relevant file(s) to ensure full compliance. These files are the single source of truth for architecture, coding standards, and testing.** - +**General:** - **[ARCHITECTURE.md](ARCHITECTURE.md)** - **[CONVENTIONS.md](CONVENTIONS.md)** - **[TESTING.md](TESTING.md)** - **[README.md](README.md)** - **[CONTRIBUTING.md](CONTRIBUTING.md)** -- **[STYLEGUIDE.md](STYLEGUIDE.md)** -- **[INTERNATIONALIZATION.md](INTERNATIONALIZATION.md)** +- **[STYLEGUIDE.md](STYLEGUIDE.md)** +- **[INTERNATIONALIZATION.md](INTERNATIONALIZATION.md)** + +**Plugin Development:** +- **[frontend/packages/console-dynamic-plugin-sdk/README.md](frontend/packages/console-dynamic-plugin-sdk/README.md)** - Comprehensive dynamic plugin SDK documentation **Tool-specific:** -- Claude → [CLAUDE.md](CLAUDE.md) and `.claude/` -- Cursor → `.cursor/context.md` +- Claude → [CLAUDE.md](CLAUDE.md) and `.claude/` +- Cursor → `.cursor/context.md` - CodeRabbit → [coderabbit.yaml](coderabbit.yaml) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bc0facd028..82263a8f10 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -5,57 +5,76 @@ The `console-dynamic-plugin-sdk` is a key part of this repository - it's the public API that enables OpenShift Console's extensibility. ## Key Packages & Areas + +**Core Packages:** - **console-dynamic-plugin-sdk**: Public API for external plugins (⚠️ breaking changes require careful vetting) -- **dev-console**: Developer perspective, topology, add flows -- **pipelines-plugin**: Tekton pipelines integration -- **knative-plugin**: Serverless/Knative support -- **helm-plugin**: Helm chart management -- **topology**: Application topology views +- **console-app**: Main application that loads all plugins - **console-shared**: Shared utilities and components +- **console-internal**: Core UI and Kubernetes integration + +**Dynamic Plugins:** +For the complete list of console plugins, see `console-app/package.json` dependencies. Static plugins (built-in) may be deprecated or extracted over time. - **Extension Points System**: 25+ extension types (NavItem, Page, ResourceListPage, DashboardsCard, etc.) - **Module Federation**: Runtime plugin loading via Webpack Module Federation - **Type Safety**: Comprehensive TypeScript definitions for all extension points - **Code References**: Lazy loading with `$codeRef` for performance -### Key Extension Types (reference) +### Extension Types + +OpenShift Console provides 75+ extension types for plugin integration. **For comprehensive documentation, see [frontend/packages/console-dynamic-plugin-sdk/README.md](frontend/packages/console-dynamic-plugin-sdk/README.md).** + +Additional resources: +- [Extension type reference](frontend/packages/console-dynamic-plugin-sdk/docs/console-extensions.md) - Full type definitions, naming convention (`console.*`), and deprecation notices +- [API documentation](frontend/packages/console-dynamic-plugin-sdk/docs/api.md) - React components, hooks, and utilities -| Category | Types | Purpose | -|----------------|------------------------------------------------------------|----------------------------------| -| Navigation | NavItem, HrefNavItem, Separator | Sidebar / top nav | -| Pages | Page, RoutePage, StandaloneRoutePage | Full or nested pages | -| Resources | ModelDefinition, ResourceListPage, ResourceDetailsPage | CRUD views | -| Actions | ActionGroup, ResourceActionProvider | Kebab / row menus | -| Dashboards | DashboardsCard, DashboardsTab | Overview health cards | -| Catalog | CatalogItemType, CatalogItemProvider | Operator / Helm catalog | -| Perspectives | Perspective, PerspectiveContext | Top-level views | +Common categories include navigation, pages, resources, actions, dashboards, catalog, and perspectives. ### Plugin Structure -```typescript -// GOOD – Dynamic extensions (runtime-loaded) -export const plugin: Plugin = [ + +Dynamic plugins define their extensions in a `console-extensions.json` file (JSONC format) located in the plugin package root. Extension types use the naming convention `console.foo/bar`. + +**Example `console-extensions.json`:** +```json +[ { - type: 'Page', - properties: { - exact: true, - path: '/my-plugin-page', - component: { $codeRef: 'MyPluginPage' }, // Lazy-load reference - }, + "type": "console.page/route", + "properties": { + "exact": true, + "path": "/my-plugin-page", + "component": { "$codeRef": "MyPluginPage" } + } }, { - type: 'NavItem', - properties: { - section: 'home', - componentProps: { name: 'My Plugin', href: '/my-plugin-page' }, - }, + "type": "console.navigation/href", + "properties": { + "id": "my-plugin-nav", + "name": "My Plugin", + "href": "/my-plugin-page", + "section": "home" + } }, -]; - -// BAD – Static (avoid—breaks extensibility) -export const staticPlugin = { extensions: [...] }; + { + "type": "console.perspective", + "properties": { + "id": "my-perspective", + "name": "%my-plugin~My Perspective%", + "icon": { "$codeRef": "perspective.icon" }, + "landingPageURL": { "$codeRef": "perspective.getLandingPageURL" } + } + } +] ``` +**Key Concepts:** +- **File Location**: `console-extensions.json` in package root (e.g., `frontend/packages/my-plugin/console-extensions.json`) +- **Type Naming**: `console.*` convention (e.g., `console.page/route`, `console.navigation/href`, `console.dashboards/card`) +- **Code References**: Use `$codeRef` to lazily load components and functions for performance +- **i18n**: Use `%namespace~key%` format for translatable strings (e.g., `"%my-plugin~My Label%"`) + +**Real-world examples:** See `console-extensions.json` files in `frontend/packages/dev-console/`, `frontend/packages/helm-plugin/`, etc. + ### Critical Considerations - **⚠️ BREAKING CHANGES REQUIRE EXTREME CARE**: This is a public API consumed by external plugins - **Backward Compatibility**: Must maintain compatibility across versions @@ -64,28 +83,15 @@ export const staticPlugin = { extensions: [...] }; - **Type Safety**: Strong TypeScript support prevents runtime errors ### ⚠️ Public API Sources - Breaking Change Risk -The dynamic plugin SDK re-exports APIs from multiple Console packages. **Changing these source modules could inadvertently break the public API**: - -#### APIs Re-exported from `@console/shared` -- **Dashboard Components**: `ActivityItem`, `ActivityBody`, `RecentEventsBody`, `OngoingActivityBody`, `AlertsBody`, `AlertItem`, `HealthItem`, `HealthBody`, `ResourceInventoryItem`, `UtilizationItem`, `UtilizationBody`, `UtilizationDurationDropdown`, `VirtualizedGrid`, `LazyActionMenu` -- **UI Components**: `Overview`, `OverviewGrid`, `InventoryItem`, `InventoryItemTitle`, `InventoryItemBody`, `InventoryItemStatus`, `InventoryItemLoading`, `StatusPopupSection`, `StatusPopupItem`, `DocumentTitle`, `Timestamp`, `ActionServiceProvider`, `ErrorBoundaryFallbackPage`, `QueryBrowser` -- **Hooks**: `useUtilizationDuration`, `useDashboardResources`, `useUserSettings`, `useAnnotationsModal`, `useDeleteModal`, `useLabelsModal`, `useActiveNamespace`, `useQuickStartContext` -- **Other**: `PaneBody` (via `ListPageBody`) - -#### APIs Re-exported from `@console/internal` -- **Core UI**: `HorizontalNav`, `VirtualizedTable`, `TableData`, `ListPageHeader`, `ListPageCreate`, `ListPageCreateLink`, `ListPageCreateButton`, `ListPageCreateDropdown`, `ListPageFilter`, `ResourceLink`, `ResourceIcon`, `ResourceEventStream`, `NamespaceBar` -- **Editors**: `YAMLEditor`, `CodeEditor`, `ResourceYAMLEditor` -- **Hooks**: `useActiveColumns`, `useListPageFilter`, `usePrometheusPoll`, `useURLPoll` -- **K8s Utilities**: Redux store access, HTTP utilities -#### APIs Re-exported from `@console/plugin-sdk` -- **Extension System**: `useExtensions` (via `useResolvedExtensions`) -- **Plugin Infrastructure**: Plugin loading, subscription services, store management +The dynamic plugin SDK re-exports APIs from multiple Console packages: +- **`@console/shared`** - Dashboard components, UI components, hooks +- **`@console/internal`** - Core UI, editors, hooks, K8s utilities +- **`@console/plugin-sdk`** - Extension system, plugin infrastructure +- **`@console/app`** - Application context +- **`@console/topology`** - Topology components, data transforms, graph views -#### APIs Re-exported from `@console/app` -- **Application Context**: `QuickStartsLoader`, `useLastNamespace` - -**Before modifying any of these source packages, verify impact on the dynamic plugin SDK public API.** +**BEFORE MODIFYING ANYTHING IN THESE OR OTHER PACKAGES:** Verify SDK re-exports by checking `frontend/packages/console-dynamic-plugin-sdk/src/api/internal-*.ts` files to avoid breaking the public API. ### SDK Utilities - **Resource Hooks**: `useK8sWatchResource`, `useActivePerspective`, `useActiveNamespace` @@ -93,8 +99,10 @@ The dynamic plugin SDK re-exports APIs from multiple Console packages. **Changin - **Build Integration**: `ConsoleRemotePlugin` for Webpack Module Federation ### Development Guidelines + +**SDK-Specific:** - Always consider impact on external plugin developers -- Extensive testing required for any API changes -- Clear deprecation paths with version-based removal +- Maintain backward compatibility as it's a public API - Comprehensive documentation for all public APIs -- Performance monitoring for plugin loading \ No newline at end of file + +**For detailed plugin API review guidelines and workflow, see [.claude/commands/plugin-api-review.md](.claude/commands/plugin-api-review.md)** \ No newline at end of file diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 5c91a51dae..2255c77ba3 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -12,10 +12,10 @@ - **Routing**: Plugin routes go in plugin-specific route files - **Extensions**: Use console extension points for plugin integration - **Types**: Check existing types in `console-shared` before creating new ones -- **Dynamic Plugins**: Prefer implementing new features using the console dynamic plugin SDK (`frontend/packages/console-dynamic-plugin-sdk/`) for extensibility +- **Dynamic Plugins**: Use console extension points for plugin integration. The dynamic plugin SDK is a re-export layer - implement new features in source packages (`@console/shared`, `@console/internal`, etc.) first, refine them internally, then consider re-exporting to the SDK after stabilization - **Plugin SDK Changes**: Any updates to `console-dynamic-plugin-sdk` must maintain backward compatibility as it's a public API - **Styling**: SCSS modules co-located with components, PatternFly design system components -- **i18n**: Use `useTranslation()` hook with `%namespace~key%` format for translation keys +- **i18n**: Use `useTranslation('namespace')` hook with `key` format for translation keys - **Error Handling**: Use ErrorBoundary components and graceful degradation patterns - **File Naming**: PascalCase for components, kebab-case for utilities, `*.spec.ts(x)` for tests @@ -35,7 +35,7 @@ - **Interfaces**: Define clear interfaces for testability and dependency injection ### Code Quality -- **Use modern JavaScript** +- **Use modern JavaScript (ES6+):** Prefer const/let, arrow functions, async/await, destructuring, template literals, optional chaining, and array methods - **Add comments for complex logic** ### Performance