-
Notifications
You must be signed in to change notification settings - Fork 15
HYPERFLEET-930 - docs: replace CLAUDE.md with AGENTS.md #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kuudori
wants to merge
2
commits into
openshift-hyperfleet:main
Choose a base branch
from
kuudori:HYPERFLEET-930
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+127
−235
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # HyperFleet API Spec | ||
|
|
||
| TypeSpec sources that generate the HyperFleet core OpenAPI specification. Published as the `hyperfleet` npm package for provider-specific repos (e.g., `hyperfleet-api-spec-gcp`). Also consumed as a Go module via `schemas/schemas.go` (`embed.FS`). | ||
|
|
||
| ## Critical path | ||
|
|
||
| ```bash | ||
| npm install # Install TypeSpec compiler + deps | ||
| ./build-schema.sh # Build core OpenAPI spec | ||
| npx spectral lint schemas/core/openapi.yaml --fail-severity warn # Lint (matches CI strictness) | ||
| ``` | ||
|
|
||
| **IMPORTANT:** `schemas/core/openapi.yaml` is committed. CI runs `git diff --exit-code schemas/` — if you change TypeSpec sources, rebuild and commit the schema in the same PR. | ||
|
|
||
| **IMPORTANT:** Every PR must bump the version in `main.tsp` (the `version` field inside the `@info` decorator). CI compares against the latest release tag and blocks if unchanged or lower. | ||
|
|
||
| When bumping version: | ||
| 1. Edit the `version` field inside the `@info` decorator in `main.tsp` | ||
| 2. Run `./build-schema.sh` (auto-syncs `package.json` version — never edit `package.json` manually) | ||
| 3. Update `CHANGELOG.md`: add new `## [X.Y.Z] - YYYY-MM-DD` section, update comparison links | ||
|
|
||
| ## Source of truth | ||
|
|
||
| | Topic | File | | ||
| |-------|------| | ||
| | Build process | `build-schema.sh` | | ||
| | CI checks | `.github/workflows/ci.yml` | | ||
| | Release automation | `.github/workflows/release.yml`, `RELEASING.md` | | ||
| | Contributing guide | `CONTRIBUTING.md` | | ||
| | Changelog format | `CHANGELOG.md` (Keep a Changelog) | | ||
| | Spectral rules | `.spectral.yaml` | | ||
| | TypeSpec config | `tspconfig.yaml` | | ||
| | Go module embed | `schemas/schemas.go` | | ||
|
|
||
| ## Architecture: shared vs core | ||
|
|
||
| ``` | ||
| shared/ → Cross-provider models and services (npm package) | ||
| core/ → Core-only models and internal-only services | ||
| main.tsp → Entry point (imports shared + core) | ||
| schemas/core/ → Generated output (committed) | ||
| ``` | ||
|
|
||
| **Where to put new code:** | ||
|
|
||
| | What | Where | Why | | ||
| |------|-------|-----| | ||
| | Models used by all providers | `shared/models/{resource}/model.tsp` | Published as npm package | | ||
| | Endpoints for external clients | `shared/services/{resource}.tsp` | Shared across provider contracts | | ||
| | Internal-only endpoints (adapters) | `core/services/{resource}-internal.tsp` | Core contract only | | ||
| | Core-specific model overrides | `core/models/{resource}/model.tsp` | Not shared | | ||
| | Provider-specific models | Separate repo (e.g., `hyperfleet-api-spec-gcp`) | Own contract | | ||
|
|
||
| **Directory naming:** `shared/models/` uses plural names (`clusters/`, `nodepools/`, `statuses/`) except `resource/` and `common/`. `core/models/` uses singular names (`cluster/`, `nodepool/`). Follow existing convention per directory. | ||
|
|
||
| ## TypeSpec conventions | ||
|
|
||
| **IMPORTANT: Required decorators on every interface:** `@useAuth(HyperFleet.BearerAuth)`, `@tag("ResourceName")`. Every operation must have `@operationId("operationName")` and `@summary("...")`. Missing `@useAuth` causes the generated spec to omit security requirements — this was a real bug (commit `89b9f9b`). | ||
|
|
||
| **Service file boilerplate:** | ||
| ```tsp | ||
| import "@typespec/http"; | ||
| import "@typespec/openapi"; | ||
| import "@typespec/openapi3"; | ||
| // ... model imports ... | ||
|
|
||
| using Http; | ||
| using OpenAPI; | ||
|
|
||
| namespace HyperFleet; | ||
|
|
||
| @tag("Resources") | ||
| @route("/resources") | ||
| @useAuth(HyperFleet.BearerAuth) | ||
| interface Resources { | ||
| @get | ||
| @summary("List resources") | ||
| @operationId("getResources") | ||
| getResources(...QueryParams): Body<ResourceList> | Error | BadRequestResponse; | ||
| } | ||
| ``` | ||
|
|
||
| **Model files** do not declare a namespace or `using` statements — just imports and model definitions. | ||
|
|
||
| **Naming:** | ||
| - Resources: `Cluster`, `NodePool`, `Resource` (singular) | ||
| - Create payloads: `ClusterCreateRequest`, `ResourceCreateRequest` | ||
| - Patch payloads: `ClusterPatchRequest`, `ResourcePatchRequest` | ||
| - Lists: `ClusterList`, `ResourceList` | ||
|
|
||
| **Import order:** TypeSpec library imports first, then relative model/service imports. | ||
|
|
||
| **Example files:** Each resource has `example_*.tsp` files for `@example` decorators. Example files in `shared/models/` are imported from their resource's `model.tsp`. Example files in `core/models/` are imported from `main.tsp`. Example files do not declare a namespace. | ||
|
|
||
| ## Boundaries | ||
|
|
||
| - **IMPORTANT:** Never edit files in `schemas/` or `tsp-output-core/` directly — they are generated | ||
| - `package.json` version is auto-synced by `build-schema.sh` — do not edit manually | ||
| - New service files must be imported in `main.tsp` or they won't compile into the schema | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - `@typespec/rest` and `@typespec/versioning` are in `package.json` but not imported in any source file — they may be transitive requirements. Don't remove without testing. | ||
| - Spectral linting in CI uses `--fail-severity warn` — all warnings are treated as errors. | ||
| - The `go.mod` at repo root exists so downstream Go services can `go get` this module and read schemas via `embed.FS`. Don't remove it. | ||
| - The `BearerAuth` model in `main.tsp` uses lowercase `"bearer"` as a workaround for `kin-openapi` library requirements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,234 +1 @@ | ||
| # HyperFleet API Spec - AI Agent Context | ||
|
|
||
| This repository generates the HyperFleet core OpenAPI specification from TypeSpec definitions. The GCP-specific contract lives in [hyperfleet-api-spec-gcp](https://github.com/openshift-hyperfleet/hyperfleet-api-spec-gcp), which imports shared models from this repo as the `hyperfleet` npm package. | ||
|
|
||
| ## Quick Reference | ||
|
|
||
| **Build commands:** | ||
| ```bash | ||
| npm run build # Generate core OpenAPI spec | ||
| ./build-schema.sh # Same, via script directly | ||
| ``` | ||
|
|
||
| **Validation workflow:** | ||
| ```bash | ||
| npm install # Install dependencies | ||
| ./build-schema.sh # Build core OpenAPI 3.0 | ||
| ls -l schemas/core/openapi.yaml # Confirm output exists | ||
| ``` | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| ### Repository Layout | ||
|
|
||
| ``` | ||
| shared/ # Cross-provider models and services (published as the `hyperfleet` npm package) | ||
| core/ # Core-only models and internal services | ||
| main.tsp # Entry point — imports shared + core | ||
| schemas/core/ # Generated output (committed) | ||
| ``` | ||
|
|
||
| **When adding new models:** | ||
| - Cross-provider models → `shared/models/` | ||
| - Core-only models → `core/models/` | ||
| - GCP-specific → separate repo (`hyperfleet-api-spec-gcp`) | ||
|
|
||
| ### Public vs Internal APIs | ||
|
|
||
| Status endpoints are split: | ||
| - `shared/services/statuses.tsp` - GET operations (external clients) | ||
| - `core/services/statuses-internal.tsp` - PUT operations (internal adapters only) and resource force-delete | ||
|
|
||
| The split allows generating different API contracts per audience. Only `statuses.tsp` is imported by default. | ||
|
|
||
| ## Code Style | ||
|
|
||
| ### TypeSpec Conventions | ||
|
|
||
| **Imports first, namespace second** (applies to service and model files; example `const` files do not declare a namespace): | ||
| ```typescript | ||
| import "@typespec/http"; | ||
| import "../models/common/model.tsp"; | ||
|
|
||
| namespace HyperFleet; | ||
| ``` | ||
|
|
||
| **Use decorators for HTTP semantics:** | ||
| ```typescript | ||
| @route("/clusters") | ||
| interface Clusters { | ||
| @get list(): Cluster[] | Error; | ||
| @post create(@body cluster: ClusterInput): Cluster | Error; | ||
| } | ||
| ``` | ||
|
|
||
| **Model naming:** | ||
| - Resources: `Cluster`, `NodePool` (singular) | ||
| - Inputs: `ClusterInput`, `NodePoolInput` | ||
| - Provider-specific: `GCPClusterSpec`, `AWSClusterSpec` | ||
|
|
||
| ### File Organization | ||
|
|
||
| ``` | ||
| shared/models/{resource}/ | ||
| ├── model.tsp # Shared model definitions | ||
| └── interfaces.tsp # Optional: shared interfaces | ||
|
|
||
| shared/services/ | ||
| └── {resource}.tsp # Shared service endpoints | ||
|
|
||
| core/models/{resource}/ | ||
| └── model.tsp # Core-specific models | ||
|
|
||
| core/services/ | ||
| └── {resource}-internal.tsp # Internal-only endpoints | ||
| ``` | ||
|
|
||
| ## Boundaries | ||
|
|
||
| **DO NOT:** | ||
| - Modify generated files in `schemas/` or `tsp-output-core/` directly | ||
| - Add dependencies without checking TypeSpec version compatibility | ||
| - Auto-generate documentation - it degrades agent performance per research | ||
| - Commit `node_modules/` or build artifacts | ||
|
|
||
| **DO:** | ||
| - Run `./build-schema.sh` and commit `schemas/core/openapi.yaml` with your changes | ||
| - Keep TypeSpec files focused (one resource per service file) | ||
| - Use semantic versioning for releases (automated on merge to main) | ||
|
|
||
| ## Common Tasks | ||
|
|
||
| ### Add a new endpoint to existing service | ||
|
|
||
| ```typescript | ||
| // shared/services/clusters.tsp | ||
| namespace HyperFleet; | ||
|
|
||
| @route("/clusters") | ||
| interface Clusters { | ||
| // ... existing endpoints ... | ||
|
|
||
| @get | ||
| @route("/{id}/health") | ||
| getHealth(@path id: string): HealthStatus | Error; | ||
| } | ||
| ``` | ||
|
|
||
| ### Add a new resource | ||
|
|
||
| 1. Create model: | ||
| ```typescript | ||
| // shared/models/health/model.tsp | ||
| import "@typespec/http"; | ||
|
|
||
| model HealthStatus { | ||
| id: string; | ||
| state: "healthy" | "degraded" | "critical"; | ||
| lastChecked: utcDateTime; | ||
| } | ||
| ``` | ||
|
|
||
| 2. Create service: | ||
| ```typescript | ||
| // shared/services/health.tsp | ||
| import "@typespec/http"; | ||
| import "../models/health/model.tsp"; | ||
| import "../models/common/model.tsp"; | ||
|
|
||
| namespace HyperFleet; | ||
|
|
||
| @route("/health") | ||
| interface Health { | ||
| @get check(): HealthStatus | Error; | ||
| } | ||
| ``` | ||
|
|
||
| 3. Import in `main.tsp`: | ||
| ```typescript | ||
| import "./shared/services/health.tsp"; | ||
| ``` | ||
|
|
||
| 4. Build: `npm run build` | ||
|
|
||
| ### Add provider-specific fields | ||
|
|
||
| Provider-specific models live in the provider's own repository (e.g., `hyperfleet-api-spec-gcp`). See that repo for examples of how to extend core shared models. | ||
|
|
||
| ## Version Bump and Changelog | ||
|
|
||
| When bumping the version in `main.tsp`, always update `CHANGELOG.md`: | ||
|
|
||
| 1. Keep `## [Unreleased]` at the top, then add a new version section as `## [X.Y.Z] - YYYY-MM-DD` | ||
| 2. List changes under appropriate headings (`Added`, `Changed`, `Fixed`, `Removed`) | ||
| 3. Update the comparison links at the bottom of the file | ||
| 4. Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format | ||
|
|
||
| ## Validation Checklist | ||
|
|
||
| Before submitting changes: | ||
|
|
||
| - [ ] Dependencies installed: `npm install` | ||
| - [ ] Core schema builds: `./build-schema.sh` | ||
| - [ ] Schema file generated: `ls schemas/core/openapi.yaml` | ||
| - [ ] No TypeSpec compilation errors (check output) | ||
| - [ ] Schema passes linting: `spectral lint schemas/core/openapi.yaml` | ||
| - [ ] Changes committed including schema update | ||
| - [ ] PR description references related issue | ||
|
|
||
| ## Build System Details | ||
|
|
||
| **The build-schema.sh script:** | ||
| 1. Extracts the version from `main.tsp` and syncs it into `package.json` | ||
| 2. Runs `node_modules/.bin/tsp compile main.tsp --output-dir tsp-output-core` | ||
| 3. Moves output to `schemas/core/openapi.yaml` | ||
|
|
||
| **Output locations:** | ||
| - TypeSpec temp: `tsp-output-core/schema/openapi.yaml` (auto-deleted) | ||
| - Final: `schemas/core/openapi.yaml` (committed) | ||
|
|
||
| **Version sync:** `package.json` version is kept in lockstep with `main.tsp` automatically on every build. The CI consistency check (`git diff --exit-code`) enforces that both are committed together. | ||
|
|
||
| ## VS Code Extension Notes | ||
|
|
||
| The TypeSpec extension may show false errors for models resolved only at compile time. Both the CLI and "Emit from TypeSpec" command work correctly. | ||
|
|
||
| ## Dependencies | ||
|
|
||
| All TypeSpec libraries use version `^1.6.0` for consistency: | ||
| - `@typespec/compiler` - Core compiler | ||
| - `@typespec/http` - HTTP semantics | ||
| - `@typespec/openapi` - OpenAPI decorators | ||
| - `@typespec/openapi3` - OpenAPI 3.0 emitter | ||
| - `@typespec/rest` - REST conventions | ||
| - `@typespec/versioning` - API versioning support | ||
|
|
||
| **Adding new TypeSpec libraries:** | ||
| ```bash | ||
| npm install --save-dev @typespec/library-name@^1.6.0 | ||
| ``` | ||
|
|
||
| Match the version range to existing dependencies. | ||
|
|
||
| ## Release Process | ||
|
|
||
| Releases are **fully automated** via GitHub Actions (`.github/workflows/release.yml`). | ||
|
|
||
| On every push to `main`, the release workflow: | ||
| 1. Extracts the version from the `@info` decorator in `main.tsp` | ||
| 2. Skips if a tag for that version already exists | ||
| 3. Builds the core OpenAPI schema | ||
| 4. Creates an annotated Git tag (`vX.Y.Z`) | ||
| 5. Publishes a GitHub Release with `core-openapi.yaml` attached | ||
|
|
||
| The CI workflow (`.github/workflows/ci.yml`) enforces that the version in `main.tsp` is bumped from the latest release tag before a PR can be merged. | ||
|
|
||
| To release a new version, simply bump the version in `main.tsp` and merge to `main`. | ||
|
|
||
| ## Architecture Context | ||
|
|
||
| This repository is part of the HyperFleet project. For broader context: | ||
| - Architecture repo: https://github.com/openshift-hyperfleet/architecture | ||
| - Main API implementation: https://github.com/openshift-hyperfleet/hyperfleet-api | ||
|
|
||
| The API implementation consumes the generated OpenAPI specs for validation and documentation. | ||
| @AGENTS.md |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.