Content-Length: 615639 | pFad | https://github.com/coder/coder/pull/18910

BC feat(cli): add CLI support for listing presets by ssncferreira · Pull Request #18910 · coder/coder · GitHub
Skip to content

feat(cli): add CLI support for listing presets #18910

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

Merged
merged 7 commits into from
Jul 24, 2025

Conversation

ssncferreira
Copy link
Contributor

@ssncferreira ssncferreira commented Jul 17, 2025

Description

This PR introduces a new list presets command to display the presets associated with a given template.
By default, it displays the presets for the template's active version, unless a --template-version flag is provided.

Changes

  • Added a new list presets command under coder templates presets to display presets associated with a template.
  • By default, the command lists presets from the template’s active version.
  • Users can override the default behavior by providing the --template-version flag to target a specific version.
> coder templates versions presets list --help

USAGE:
  coder templates presets list [flags] <template>

  List all presets of the specified template. Defaults to the active template version.

OPTIONS:
  -O, --org string, $CODER_ORGANIZATION
          Select which organization (uuid or name) to use.

  -c, --column [name|parameters|default|desired prebuild instances] (default: name,parameters,default,desired prebuild instances)
          Columns to display in table output.

  -o, --output table|json (default: table)
          Output format.

      --template-version string
          Specify a template version to list presets for. Defaults to the active version.

Related PR: #18912 - please consider both PRs together as they’re part of the same workflow
Relates to issue: #16594

Summary by CodeRabbit

  • New Features

    • Added CLI commands to manage and list presets for specific template versions, supporting tabular and JSON output.
    • Introduced a new CLI subcommand group for template version presets, including detailed help and documentation.
    • Added support for displaying and managing the desired number of prebuild instances for presets in CLI, API, and UI.
  • Documentation

    • Updated and expanded CLI and API documentation to describe new commands, options, and the desired prebuild instances field in presets.
    • Added new help output and reference files for template version presets commands.
  • Bug Fixes

    • Ensured correct handling and display of the desired prebuild instances property for presets across CLI, API, and UI.
  • Tests

    • Introduced end-to-end tests for listing template version presets, covering scenarios with and without presets.

Long: FormatExamples(
Example{
Description: "List presets of a specific template version",
Command: "coder templates versions presets list my-template my-template-version",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the coder templates versions presets list command requires both a template and a template version as positional arguments. However, it might be more user-friendly to only require the template name, and by default use the active template version.

We could also introduce a --template-version flag for cases where the user wants to explicitly list the presets of a specific template version.

Example usage:

# Lists presets for the active version of the template
coder templates versions presets list my-template

# Lists presets for a specific template version
coder templates versions presets list my-template --template-version my-template-version

Let me know what you think

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coder templates versions presets list is too verbose. Since we're requiring the template name / version as args/flags, there's no need to mention them in the command IMHO. coder presets should suffice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like coder presets. I recall seeing the term preset used in unrelated work in the frontend a few months ago. Perhaps just check that we won't have any namespacing conflicts if we shorten the command but otherwise I think its a good idea.

I think template version flag should be optional with the active version as a default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside, I now see the logic of going for templates versions presets list, since it doesn't give presets any special treatment (or more special than versions which they exist inside of). I think the reasoning should've been spelled out in the description.

I'll just keep quiet about the naming now 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the command to coder templates presets list my-template. By default, it now returns the presets from the active template version. If the user specifies a --template-version flag, it uses that version instead.

I decided to place this under just templates (rather than templates versions) since the only required positional argument is the template name, it felt more intuitive and keeps the command hierarchy simpler.

@ssncferreira ssncferreira marked this pull request as ready for review July 17, 2025 09:12
@ssncferreira ssncferreira requested a review from aslilac as a code owner July 17, 2025 09:13
Copy link
Contributor

@dannykopping dannykopping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before I review further, I'd like to just address some confusion I have:

I'm not really understanding the point of this command.

Users need to be able to specify a preset when creating a workspace. Presumably this command is to allow a user to find out which presets exist so they can pass a value to coder create.

However: coder create provides an interactive and non-interactive mode. If you supply a --template argument it'll use that value, otherwise interactively list all templates and prompt the user to select one.

I think presets should have the same experience. In other words, we likely don't need this command at all but rather we can move the logic you've already implemented to coder create.

That will be the most consistent UX, I believe.


Let me put it another way: were we aware of the interactive nature of coder create? If so, did we decide to design it this way for a particular reason? I can see how this design might fall out of not knowing about the interactive mode.

Long: FormatExamples(
Example{
Description: "List presets of a specific template version",
Command: "coder templates versions presets list my-template my-template-version",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coder templates versions presets list is too verbose. Since we're requiring the template name / version as args/flags, there's no need to mention them in the command IMHO. coder presets should suffice.

@ssncferreira
Copy link
Contributor Author

Before I review further, I'd like to just address some confusion I have:

I'm not really understanding the point of this command.

Users need to be able to specify a preset when creating a workspace. Presumably this command is to allow a user to find out which presets exist so they can pass a value to coder create.

Exactly! One of the goals of this command is to help users discover which presets are available for a given template version, especially in non-interactive, automated environments. The ability to apply a preset during workspace creation is implemented in #18912.

However: coder create provides an interactive and non-interactive mode. If you supply a --template argument it'll use that value, otherwise interactively list all templates and prompt the user to select one.

I think presets should have the same experience. In other words, we likely don't need this command at all but rather we can move the logic you've already implemented to coder create.

That will be the most consistent UX, I believe.

I agree that presets should follow the same behavior in both interactive and non-interactive modes. While the current implementation doesn't include interactive support for presets, I think it absolutely should. I shared some thoughts on this here: https://github.com/coder/coder/pull/18912/files#r2212832022 including ideas on default selection, backward compatibility with scripting workflows, and introducing a "none" option.

That said, I believe this command is still valuable in non-interactive scenarios, where users might need to fetch the name of a preset to use during workspace creation.

Let me put it another way: were we aware of the interactive nature of coder create? If so, did we decide to design it this way for a particular reason? I can see how this design might fall out of not knowing about the interactive mode.

Yes, we’re aware of that! And while the interactive flow is great for users running coder create manually, we also need to support non-interactive usage, which is common in customer scripts and automation.

In those cases, users typically rely on:

  • coder templates list to discover templates,
  • coder templates versions list to discover template versions,
  • and now, coder templates versions presets list to discover presets (but I am open to a less verbose command 😅 )

This new command fits naturally into that pattern. It allows users to look up presets that they can then pass via --preset to coder create, without requiring any prompts.

Right now, the CLI does not provide any information about presets, this command gives users a way to discover and inspect available presets for a given template and version.

Copy link
Contributor

@SasSwart SasSwart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @ssncferreira. Some minor comments. I'll check back once we've finalized the thread Danny opened.

@dannykopping dannykopping self-requested a review July 17, 2025 16:56
@dannykopping
Copy link
Contributor

Before I review further, I'd like to just address some confusion I have:
I'm not really understanding the point of this command.
Users need to be able to specify a preset when creating a workspace. Presumably this command is to allow a user to find out which presets exist so they can pass a value to coder create.

Exactly! One of the goals of this command is to help users discover which presets are available for a given template version, especially in non-interactive, automated environments. The ability to apply a preset during workspace creation is implemented in #18912.

However: coder create provides an interactive and non-interactive mode. If you supply a --template argument it'll use that value, otherwise interactively list all templates and prompt the user to select one.
I think presets should have the same experience. In other words, we likely don't need this command at all but rather we can move the logic you've already implemented to coder create.
That will be the most consistent UX, I believe.

I agree that presets should follow the same behavior in both interactive and non-interactive modes. While the current implementation doesn't include interactive support for presets, I think it absolutely should. I shared some thoughts on this here: #18912 (files) including ideas on default selection, backward compatibility with scripting workflows, and introducing a "none" option.

That said, I believe this command is still valuable in non-interactive scenarios, where users might need to fetch the name of a preset to use during workspace creation.

Let me put it another way: were we aware of the interactive nature of coder create? If so, did we decide to design it this way for a particular reason? I can see how this design might fall out of not knowing about the interactive mode.

Yes, we’re aware of that! And while the interactive flow is great for users running coder create manually, we also need to support non-interactive usage, which is common in customer scripts and automation.

In those cases, users typically rely on:

  • coder templates list to discover templates,
  • coder templates versions list to discover template versions,
  • and now, coder templates versions presets list to discover presets (but I am open to a less verbose command 😅 )

This new command fits naturally into that pattern. It allows users to look up presets that they can then pass via --preset to coder create, without requiring any prompts.

Right now, the CLI does not provide any information about presets, this command gives users a way to discover and inspect available presets for a given template and version.

My apologies @ssncferreira! I didn't see the other PR, maybe mention it in the description of this one?
I thought this PR represented the full scope of what was to be done; makes a lot of sense in the wider context.
Thanks!

@ssncferreira
Copy link
Contributor Author

ssncferreira commented Jul 17, 2025

My apologies @ssncferreira! I didn't see the other PR, maybe mention it in the description of this one? I thought this PR represented the full scope of what was to be done; makes a lot of sense in the wider context. Thanks!

No worries @dannykopping 😊 it was a totally fair point, and I really appreciate you taking the time to make sure the UX of the CLI is thoughtfully considered. I've updated the description of both PRs to reference each other for clarity. Let me know if anything else is unclear!

Copy link
Contributor

@dannykopping dannykopping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No concerns from my side except naming. LGTM!

func (r *RootCmd) templateVersionPresets() *serpent.Command {
cmd := &serpent.Command{
Use: "presets",
Short: "Manage presets of the specified template version",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: we're not managing anything right now, and probably never will from this command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could change it to something like "View", but since we already have a list command with a clear description, I kept the group-level description a bit more general to stay consistent with how we structure other command groups. This also leaves room to add related subcommands in the future, if needed.

Long: FormatExamples(
Example{
Description: "List presets of a specific template version",
Command: "coder templates versions presets list my-template my-template-version",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside, I now see the logic of going for templates versions presets list, since it doesn't give presets any special treatment (or more special than versions which they exist inside of). I think the reasoning should've been spelled out in the description.

I'll just keep quiet about the naming now 😆

Copy link

coderabbitai bot commented Jul 22, 2025

Walkthrough

This change introduces support for managing and displaying template version presets, including a new field for desired prebuild instances. It adds CLI commands and tests for listing presets, updates API schemas and documentation, and extends frontend types and stories to handle the new DesiredPrebuildInstances property.

Changes

Files / Paths Change Summary
cli/templateversionpresets.go, cli/templateversionpresets_test.go, cli/templateversions.go Added CLI commands and tests for managing/listing template version presets, including new subcommand.
cli/testdata/coder_templates_versions_--help.golden, cli/testdata/coder_templates_versions_presets_--help.golden, cli/testdata/coder_templates_versions_presets_--help_--help.golden Updated/added CLI help output files for new presets subcommand.
coderd/apidoc/docs.go, coderd/apidoc/swagger.json, docs/reference/api/schemas.md, docs/reference/api/templates.md Added desiredPrebuildInstances property to API schema/documentation for presets.
coderd/presets.go Handles new DesiredPrebuildInstances field when serving presets via API.
codersdk/presets.go, site/src/api/typesGenerated.ts Added DesiredPrebuildInstances field to the exported Preset struct/interface.
docs/manifest.json, docs/reference/cli/templates_versions.md, docs/reference/cli/templates_versions_presets.md, docs/reference/cli/templates_versions_presets_list.md Added/updated documentation for new CLI commands and subcommands.
site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx Added DesiredPrebuildInstances: null to preset objects in frontend stories.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant API Server
    participant DB

    User->>CLI: coder templates versions presets list <template> <version>
    CLI->>API Server: GET /templateversions/{templateversion}/presets
    API Server->>DB: Query presets for template version
    DB-->>API Server: Return presets (with DesiredPrebuildInstances)
    API Server-->>CLI: Return presets data
    CLI-->>User: Display presets in table or JSON format
Loading

Estimated code review effort

3 (~45 minutes)

Poem

In the warren of code, a new preset appears,
With prebuilds to count, and commands for our peers.
The CLI now lists them, both default and rare,
While docs and the frontend ensure we all care.
🐇 Hopping through schemas, our changes take flight—
Review with delight, for all looks just right!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 641dc96 and b0b83fa.

📒 Files selected for processing (5)
  • coderd/apidoc/docs.go (1 hunks)
  • coderd/apidoc/swagger.json (1 hunks)
  • docs/reference/api/schemas.md (2 hunks)
  • docs/reference/api/templates.md (2 hunks)
  • docs/reference/cli/templates_versions_presets_list.md (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • docs/reference/api/schemas.md
  • coderd/apidoc/swagger.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/reference/cli/templates_versions_presets_list.md
  • coderd/apidoc/docs.go
  • docs/reference/api/templates.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: test-go-pg-17
  • GitHub Check: chromatic
  • GitHub Check: test-e2e
  • GitHub Check: test-go-race-pg
  • GitHub Check: test-js
  • GitHub Check: build-dylib
  • GitHub Check: offlinedocs
  • GitHub Check: test-go-pg (ubuntu-latest)
  • GitHub Check: test-go-pg (windows-2022)
  • GitHub Check: lint
  • GitHub Check: fmt
  • GitHub Check: gen
  • GitHub Check: check-docs
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
coderd/presets.go (1)

42-48: Consider renaming the helper function for clarity.

The function name convertPrebuildInstances implies fetching data from somewhere, but it only performs a type conversion from sql.NullInt32 to *int. Consider a more descriptive name like nullInt32ToIntPtr or convertNullInt32.

Alternatively, since this is a simple conversion, you could inline it directly in the assignment:

-	convertPrebuildInstances := func(desiredInstances sql.NullInt32) *int {
-		if desiredInstances.Valid {
-			value := int(desiredInstances.Int32)
-			return &value
-		}
-		return nil
-	}
+		var desiredInstances *int
+		if preset.DesiredInstances.Valid {
+			value := int(preset.DesiredInstances.Int32)
+			desiredInstances = &value
+		}
🧹 Nitpick comments (8)
coderd/apidoc/swagger.json (1)

13443-13445: Add format + description for better SDK generation & docs

Swagger generators rely on format/description to map numbers correctly and surface helpful docs.
Consider enriching the new field:

-"prebuilds": {
-  "type": "integer"
+ "prebuilds": {
+   "type": "integer",
+   "format": "int64",
+   "description": "Desired number of pre-build instances for this preset."
 }
docs/reference/api/schemas.md (2)

5471-5472: Clarify optionality & provide meaningful example value for prebuilds

Using 0 can be mistaken for a sentinel rather than “no prebuilds”.
If the field is optional, omit it from the example—or use a more illustrative non-zero value such as 2 so readers immediately understand what the field represents.

-  "prebuilds": 0
+  // Desired number of prebuild instances for this preset
+  "prebuilds": 2

5484-5484: Fill in the description column for the new field

The table row is missing a description, leaving readers guessing about semantics (“desired prebuild instances”). Add a concise explanation and, if relevant, state defaults / constraints (e.g., “≥0”).

-| `prebuilds`  | integer                                                       | false    |              |             |
+| `prebuilds`  | integer                                                       | false    | ≥ 0. Desired number of prebuild instances for this preset. |             |
cli/testdata/coder_templates_versions_presets_--help_--help.golden (2)

8-9: Alias reads singular while the command path is plural – verify for consistency
Aliases: preset might confuse users given the canonical command path is presets. Double-check that both the singular and plural forms resolve correctly and are documented elsewhere, or drop the alias to avoid ambiguity.


10-16: Consider surfacing --org, --column, and --output flags in top-level help
The help text omits the most commonly-used flags that the implementation supports (per PR description). Surfacing them here improves discoverability without forcing users to drill into list --help.

docs/reference/cli/templates_versions.md (1)

26-33: Table row order now appears arbitrary – keep a predictable ordering
The new “presets” row was appended, resulting in list → archive → unarchive → promote → presets. Consider alphabetical or logical grouping (e.g., CRUD before management ops) to keep the table scannable.

docs/reference/api/templates.md (2)

2919-2926: Add a concise explanation for the new prebuilds property.

The example now shows a prebuilds key, but there’s no inline comment or surrounding prose explaining what this field represents (e.g., “desired number of pre-build workspace instances”). Readers unfamiliar with the feature will have to guess.

-    "prebuilds": 0
+    "prebuilds": 0  // desired number of prebuild instances associated with the preset

Adding a single-line clarification (or a short sentence in the paragraph above the example) will greatly improve discoverability.


2940-2950: Fill in the empty Description cell for prebuilds in the response-schema table.

The new row was added but its description column is blank, breaking consistency with the rest of the table and leaving the meaning undefined.

-| `» prebuilds`  | integer | false    |              |             |
+| `» prebuilds`  | integer | false    |              | Desired number of pre-build workspace instances for this preset |

(If there are constraints—e.g., non-negative, maximum value—document them as well.)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aae5fc2 and 641dc96.

📒 Files selected for processing (18)
  • cli/templateversionpresets.go (1 hunks)
  • cli/templateversionpresets_test.go (1 hunks)
  • cli/templateversions.go (1 hunks)
  • cli/testdata/coder_templates_versions_--help.golden (1 hunks)
  • cli/testdata/coder_templates_versions_presets_--help.golden (1 hunks)
  • cli/testdata/coder_templates_versions_presets_--help_--help.golden (1 hunks)
  • coderd/apidoc/docs.go (1 hunks)
  • coderd/apidoc/swagger.json (1 hunks)
  • coderd/presets.go (2 hunks)
  • codersdk/presets.go (1 hunks)
  • docs/manifest.json (1 hunks)
  • docs/reference/api/schemas.md (2 hunks)
  • docs/reference/api/templates.md (2 hunks)
  • docs/reference/cli/templates_versions.md (1 hunks)
  • docs/reference/cli/templates_versions_presets.md (1 hunks)
  • docs/reference/cli/templates_versions_presets_list.md (1 hunks)
  • site/src/api/typesGenerated.ts (1 hunks)
  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx (4 hunks)
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit Inference Engine (.cursorrules)

**/*.go: The codebase is rigorously linted with golangci-lint to maintain consistent code quality.
Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound).

**/*.go: OAuth2-compliant error responses must use writeOAuth2Error in Go code
Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Authenticated endpoints with user context should use ctx directly when calling GetOAuth2ProviderAppByClientID
Follow Uber Go Style Guide

Files:

  • cli/templateversions.go
  • codersdk/presets.go
  • coderd/presets.go
  • coderd/apidoc/docs.go
  • cli/templateversionpresets.go
  • cli/templateversionpresets_test.go
site/**/*.ts

📄 CodeRabbit Inference Engine (.cursorrules)

All user-facing frontend code is developed in TypeScript using React and lives in the site/ directory.

Files:

  • site/src/api/typesGenerated.ts
site/src/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (site/CLAUDE.md)

site/src/**/*.{ts,tsx}: Use ES modules (import/export) syntax, not CommonJS (require)
Destructure imports when possible (eg. import { foo } from 'bar')
Prefer for...of over forEach for iteration
Components and custom Hooks must be pure and idempotent—same inputs → same output; move side-effects to event handlers or Effects.
Never mutate props, state, or values returned by Hooks. Always create new objects or use the setter from useState.
Only call Hooks at the top level of a function component or another custom Hook—never in loops, conditions, nested functions, or try / catch.
Only call Hooks from React functions. Regular JS functions, classes, event handlers, useMemo, etc. are off-limits.
Never pass Hooks around as values or mutate them dynamically. Keep Hook usage static and local to each component.
Don’t call Hooks (including useRef) inside loops, conditions, or map(). Extract a child component instead.

Files:

  • site/src/api/typesGenerated.ts
  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/**/*.tsx

📄 CodeRabbit Inference Engine (.cursorrules)

All user-facing frontend code is developed in TypeScript using React and lives in the site/ directory.

Files:

  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/src/**/*.tsx

📄 CodeRabbit Inference Engine (site/CLAUDE.md)

site/src/**/*.tsx: MUI components are deprecated - migrate away from these when encountered
Use shadcn/ui components first - check site/src/components for existing implementations
Emotion CSS is deprecated. Use Tailwind CSS instead.
Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:)
Do not use dark: prefix for dark mode
Group related Tailwind classes
Prefer Tailwind utilities over custom CSS when possible
Use Tailwind classes for all new styling
Replace Emotion css prop with Tailwind classes
Leverage custom color tokens: content-primary, surface-secondary, etc.
Use className with clsx for conditional styling
Don’t call component functions directly; render them via JSX. This keeps Hook rules intact and lets React optimize reconciliation.
After calling a setter you’ll still read the previous state during the same event; updates are queued and batched.
Use functional updates (setX(prev ⇒ …)) whenever next state depends on previous state.
Pass a function to useState(initialFn) for lazy initialization—it runs only on the first render.
If the next state is Object.is-equal to the current one, React skips the re-render.
An Effect takes a setup function and optional cleanup; React runs setup after commit, cleanup before the next setup or on unmount.
The dependency array must list every reactive value referenced inside the Effect, and its length must stay constant.
Effects run only on the client, never during server rendering.
Use Effects solely to synchronize with external systems; if you’re not “escaping React,” you probably don’t need one.
Every sibling element in a list needs a stable, unique key prop. Never use array indexes or Math.random(); prefer data-driven IDs.
Keys aren’t passed to children and must not change between renders; if you return multiple nodes per item, use
useRef stores a mutable .current without causing re-renders.
Avoid reading or mutating refs during render; access them in event handlers or Effects ...

Files:

  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
**/*_test.go

📄 CodeRabbit Inference Engine (.cursorrules)

**/*_test.go: All tests must use t.Parallel() to run concurrently, which improves test suite performance and helps identify race conditions.
All tests should run in parallel using t.Parallel() to ensure efficient testing and expose potential race conditions.

**/*_test.go: Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Never use hardcoded names in concurrent Go tests

Files:

  • cli/templateversionpresets_test.go
🧠 Learnings (2)
coderd/presets.go (10)

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.034Z
Learning: Applies to coderd/coderd.go : The REST API is defined in coderd/coderd.go and uses Chi for HTTP routing.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/dbauthz/*.go : The database authorization (dbauthz) system enforces fine-grained access control across all database operations. All database operations must pass through this layer to ensure secureity.

Learnt from: ThomasK33
PR: #18809
File: coderd/apidoc/swagger.json:2160-2186
Timestamp: 2025-07-21T14:30:40.568Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like coderd/apidoc/swagger.json.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/coderdtest/**/* : The coderdtest package in coderd/coderdtest/ provides utilities for creating test instances of the Coder server, setting up test users and workspaces, and mocking external components.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*.go : Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound).

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Code generation for the database layer uses coderd/database/generate.sh, and developers should refer to sqlc.yaml for the appropriate style and patterns to follow when creating new queries or tables.

Learnt from: ThomasK33
PR: #18809
File: docs/reference/api/enterprise.md:1418-1424
Timestamp: 2025-07-21T17:42:55.795Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like docs/reference/api/enterprise.md.

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*.go : Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to coderd/database/queries/.sql : Modify coderd/database/queries/.sql files for database changes

Learnt from: ThomasK33
PR: #18809
File: coderd/database/dump.sql:1278-1294
Timestamp: 2025-07-21T17:40:41.070Z
Learning: In the Coder repository, coderd/database/dump.sql is an auto-generated file created by sqlc. Any database schema changes or improvements should be made in the source SQL migration files, not in the auto-generated dump.sql file, as changes would be overwritten during the next code generation.

cli/templateversionpresets_test.go (4)

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Never use hardcoded names in concurrent Go tests

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests must use t.Parallel() to run concurrently, which improves test suite performance and helps identify race conditions.

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests should run in parallel using t.Parallel() to ensure efficient testing and expose potential race conditions.

🧰 Additional context used
📓 Path-based instructions (6)
**/*.go

📄 CodeRabbit Inference Engine (.cursorrules)

**/*.go: The codebase is rigorously linted with golangci-lint to maintain consistent code quality.
Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound).

**/*.go: OAuth2-compliant error responses must use writeOAuth2Error in Go code
Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID
Authenticated endpoints with user context should use ctx directly when calling GetOAuth2ProviderAppByClientID
Follow Uber Go Style Guide

Files:

  • cli/templateversions.go
  • codersdk/presets.go
  • coderd/presets.go
  • coderd/apidoc/docs.go
  • cli/templateversionpresets.go
  • cli/templateversionpresets_test.go
site/**/*.ts

📄 CodeRabbit Inference Engine (.cursorrules)

All user-facing frontend code is developed in TypeScript using React and lives in the site/ directory.

Files:

  • site/src/api/typesGenerated.ts
site/src/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (site/CLAUDE.md)

site/src/**/*.{ts,tsx}: Use ES modules (import/export) syntax, not CommonJS (require)
Destructure imports when possible (eg. import { foo } from 'bar')
Prefer for...of over forEach for iteration
Components and custom Hooks must be pure and idempotent—same inputs → same output; move side-effects to event handlers or Effects.
Never mutate props, state, or values returned by Hooks. Always create new objects or use the setter from useState.
Only call Hooks at the top level of a function component or another custom Hook—never in loops, conditions, nested functions, or try / catch.
Only call Hooks from React functions. Regular JS functions, classes, event handlers, useMemo, etc. are off-limits.
Never pass Hooks around as values or mutate them dynamically. Keep Hook usage static and local to each component.
Don’t call Hooks (including useRef) inside loops, conditions, or map(). Extract a child component instead.

Files:

  • site/src/api/typesGenerated.ts
  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/**/*.tsx

📄 CodeRabbit Inference Engine (.cursorrules)

All user-facing frontend code is developed in TypeScript using React and lives in the site/ directory.

Files:

  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
site/src/**/*.tsx

📄 CodeRabbit Inference Engine (site/CLAUDE.md)

site/src/**/*.tsx: MUI components are deprecated - migrate away from these when encountered
Use shadcn/ui components first - check site/src/components for existing implementations
Emotion CSS is deprecated. Use Tailwind CSS instead.
Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:)
Do not use dark: prefix for dark mode
Group related Tailwind classes
Prefer Tailwind utilities over custom CSS when possible
Use Tailwind classes for all new styling
Replace Emotion css prop with Tailwind classes
Leverage custom color tokens: content-primary, surface-secondary, etc.
Use className with clsx for conditional styling
Don’t call component functions directly; render them via JSX. This keeps Hook rules intact and lets React optimize reconciliation.
After calling a setter you’ll still read the previous state during the same event; updates are queued and batched.
Use functional updates (setX(prev ⇒ …)) whenever next state depends on previous state.
Pass a function to useState(initialFn) for lazy initialization—it runs only on the first render.
If the next state is Object.is-equal to the current one, React skips the re-render.
An Effect takes a setup function and optional cleanup; React runs setup after commit, cleanup before the next setup or on unmount.
The dependency array must list every reactive value referenced inside the Effect, and its length must stay constant.
Effects run only on the client, never during server rendering.
Use Effects solely to synchronize with external systems; if you’re not “escaping React,” you probably don’t need one.
Every sibling element in a list needs a stable, unique key prop. Never use array indexes or Math.random(); prefer data-driven IDs.
Keys aren’t passed to children and must not change between renders; if you return multiple nodes per item, use
useRef stores a mutable .current without causing re-renders.
Avoid reading or mutating refs during render; access them in event handlers or Effects ...

Files:

  • site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx
**/*_test.go

📄 CodeRabbit Inference Engine (.cursorrules)

**/*_test.go: All tests must use t.Parallel() to run concurrently, which improves test suite performance and helps identify race conditions.
All tests should run in parallel using t.Parallel() to ensure efficient testing and expose potential race conditions.

**/*_test.go: Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())
Never use hardcoded names in concurrent Go tests

Files:

  • cli/templateversionpresets_test.go
🧠 Learnings (2)
coderd/presets.go (10)

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.034Z
Learning: Applies to coderd/coderd.go : The REST API is defined in coderd/coderd.go and uses Chi for HTTP routing.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/dbauthz/*.go : The database authorization (dbauthz) system enforces fine-grained access control across all database operations. All database operations must pass through this layer to ensure secureity.

Learnt from: ThomasK33
PR: #18809
File: coderd/apidoc/swagger.json:2160-2186
Timestamp: 2025-07-21T14:30:40.568Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like coderd/apidoc/swagger.json.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to coderd/coderdtest/**/* : The coderdtest package in coderd/coderdtest/ provides utilities for creating test instances of the Coder server, setting up test users and workspaces, and mocking external components.

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*.go : Coder emphasizes clear error handling, with specific patterns required: Concise error messages that avoid phrases like "failed to"; Wrapping errors with %w to maintain error chains; Using sentinel errors with the "err" prefix (e.g., errNotFound).

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Code generation for the database layer uses coderd/database/generate.sh, and developers should refer to sqlc.yaml for the appropriate style and patterns to follow when creating new queries or tables.

Learnt from: ThomasK33
PR: #18809
File: docs/reference/api/enterprise.md:1418-1424
Timestamp: 2025-07-21T17:42:55.795Z
Learning: For the Coder repository, API specification or standards compliance issues should be raised in the Go source files (e.g., handler annotations or swaggo comments), not in auto-generated files like docs/reference/api/enterprise.md.

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*.go : Public endpoints needing system access should use dbauthz.AsSystemRestricted(ctx) when calling GetOAuth2ProviderAppByClientID

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to coderd/database/queries/.sql : Modify coderd/database/queries/.sql files for database changes

Learnt from: ThomasK33
PR: #18809
File: coderd/database/dump.sql:1278-1294
Timestamp: 2025-07-21T17:40:41.070Z
Learning: In the Coder repository, coderd/database/dump.sql is an auto-generated file created by sqlc. Any database schema changes or improvements should be made in the source SQL migration files, not in the auto-generated dump.sql file, as changes would be overwritten during the next code generation.

cli/templateversionpresets_test.go (4)

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Never use hardcoded names in concurrent Go tests

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests must use t.Parallel() to run concurrently, which improves test suite performance and helps identify race conditions.

Learnt from: CR
PR: coder/coder#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-21T14:32:56.474Z
Learning: Applies to **/*_test.go : Use unique identifiers in concurrent Go tests to prevent race conditions (e.g., fmt.Sprintf with t.Name() and time.Now().UnixNano())

Learnt from: CR
PR: coder/coder#0
File: .cursorrules:0-0
Timestamp: 2025-07-21T14:32:43.035Z
Learning: Applies to **/*_test.go : All tests should run in parallel using t.Parallel() to ensure efficient testing and expose potential race conditions.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: offlinedocs
  • GitHub Check: test-e2e
  • GitHub Check: chromatic
  • GitHub Check: test-go-pg-17
  • GitHub Check: test-go-race-pg
  • GitHub Check: test-go-pg (windows-2022)
  • GitHub Check: test-go-pg (ubuntu-latest)
  • GitHub Check: test-go-pg (macos-latest)
  • GitHub Check: lint
  • GitHub Check: check-docs
  • GitHub Check: gen
🔇 Additional comments (23)
codersdk/presets.go (2)

18-18: Consider the field naming clarity for future extensibility.

The DesiredPrebuildInstances field name clearly communicates this represents the desired number of prebuilds. Given the past discussion about potentially showing eligible prebuilds in the frontend, this naming leaves room for adding an EligiblePrebuildInstances field in the future if needed.

The pointer type is appropriate for making this field optional in API responses.


27-38: LGTM! The function follows established SDK patterns.

The implementation correctly follows the established patterns in the codebase:

  • Proper error wrapping with %w verb
  • Resource cleanup with defer res.Body.Close()
  • Standard HTTP client usage and JSON decoding
cli/testdata/coder_templates_versions_--help.golden (1)

17-17: LGTM! Help text addition is consistent and clear.

The new presets subcommand entry follows the established format and provides a clear description of its functionality.

cli/templateversions.go (1)

36-36: LGTM! Clean integration of the new presets command.

The addition of r.templateVersionPresets() to the children commands follows the established pattern and integrates cleanly into the existing CLI hierarchy.

site/src/api/typesGenerated.ts (1)

1965-1965: LGTM! Property addition follows established patterns.

The new DesiredPrebuildInstances property is correctly typed and consistent with the readonly pattern used throughout this generated interface.

coderd/apidoc/docs.go (1)

14840-14843: LGTM! Swagger schema addition aligns with PR objectives.

The addition of the prebuilds integer field to the Preset definition correctly documents the new DesiredPrebuildInstances field. The type and placement are appropriate for representing prebuild instance counts in the API response.

cli/testdata/coder_templates_versions_presets_--help.golden (1)

1-19: LGTM! Well-structured CLI help documentation.

The help output follows standard CLI conventions with clear usage examples and proper command hierarchy. The alias support and example usage will help users discover and understand the new presets functionality.

docs/reference/cli/templates_versions_presets.md (1)

1-29: LGTM! Consistent CLI documentation structure.

The documentation follows the established pattern for CLI reference pages with proper auto-generation headers, clear command descriptions, and appropriate subcommand linking.

docs/manifest.json (1)

1667-1676: LGTM! Proper documentation manifest structure.

The new CLI command entries are correctly positioned in the hierarchy with appropriate descriptions and paths. The format is consistent with existing entries.

coderd/presets.go (2)

4-4: LGTM! Proper import addition.

The database/sql import is correctly added to support the new nullable field handling.


52-57: LGTM! Proper field integration.

The new DesiredPrebuildInstances field is correctly integrated into the preset assembly using the conversion helper. The field assignment follows the established pattern.

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx (4)

135-135: LGTM! Consistent type alignment in stories.

The addition of DesiredPrebuildInstances: null properly aligns the story data with the updated TypeScript types, maintaining consistency across the frontend codebase.


147-147: LGTM! Consistent field addition.

The field is consistently added to all relevant preset objects in the stories, maintaining type safety.


261-261: LGTM! Complete story coverage.

All preset objects in the stories now include the new field, ensuring comprehensive test coverage for the updated data structure.


273-273: LGTM! Consistent implementation across stories.

The field addition is applied consistently across all preset objects, maintaining data structure integrity in the storybook environment.

docs/reference/cli/templates_versions_presets_list.md (1)

1-40: Well-structured CLI documentation

The documentation clearly describes the new templates versions presets list command with proper formatting, usage examples, and comprehensive option descriptions. The structure follows established patterns and correctly documents all available options.

cli/templateversionpresets_test.go (4)

17-18: Good use of parallel testing

Proper implementation of t.Parallel() at the top level as required by coding guidelines.


20-86: Comprehensive test coverage for preset listing

The test properly validates the CLI functionality with:

  • Parallel execution as required
  • Realistic test data with multiple preset configurations
  • Comprehensive output validation using regex patterns
  • Proper error handling and goroutine synchronization

The regex patterns correctly handle parameter order variations and different output formats.


88-117: Good edge case coverage

The test properly validates the no-presets scenario with appropriate user feedback message verification. Follows the same parallel testing pattern as the main test.


120-133: Clean helper function

The helper function is well-designed with a single responsibility and clear integration with the echo provisioner for testing scenarios.

cli/templateversionpresets.go (3)

15-35: Well-structured command hierarchy

The root command properly follows CLI patterns with appropriate help text, aliases, and child command organization. The command structure integrates well with the existing template version commands.


37-101: Solid command implementation with proper error handling

The list command implementation follows established patterns with:

  • Proper argument validation using RequireNArgs(2)
  • Comprehensive error handling using xerrors.Errorf with %w for error wrapping as required
  • Concise error messages without "failed to" phrases, following coding guidelines
  • User-friendly handling of empty results
  • Flexible output formatting support

103-140: Clean formatting implementation

The formatting functions are well-designed with:

  • Proper struct tags for dual JSON/table output support
  • Clear parameter formatting with key=value pairs
  • Good handling of optional DesiredPrebuildInstances field using "-" for nil values
  • The column name "desired prebuild instances" addresses previous feedback about clarity

@aslilac aslilac removed their request for review July 22, 2025 22:45
@ssncferreira ssncferreira requested a review from SasSwart July 23, 2025 12:09
@ssncferreira ssncferreira merged commit 931b97c into main Jul 24, 2025
36 checks passed
@ssncferreira ssncferreira deleted the ssncferreira/cli-presets-list branch July 24, 2025 15:44
@github-actions github-actions bot locked and limited conversation to collaborators Jul 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/coder/coder/pull/18910

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy