Skip to content

Introduce CICD CLI Commands for AI-Workspace#2278

Merged
ShakyaPr merged 29 commits into
wso2:mainfrom
ShakyaPr:feature/platform_cicd
Jul 7, 2026
Merged

Introduce CICD CLI Commands for AI-Workspace#2278
ShakyaPr merged 29 commits into
wso2:mainfrom
ShakyaPr:feature/platform_cicd

Conversation

@ShakyaPr

@ShakyaPr ShakyaPr commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Purpose

Summary

  • Adds a full AI-Workspace command family to the ap CLI so LLM providers, LLM proxies, and MCP proxies can be authored as project artifacts and published to an AI-Workspace from a pipeline
  • The model is project → artifacts → publish: scaffold a project, author metadata.yaml / runtime.yaml / definition.yaml, validate them, then generate the creation payload and push it to the target — with the endpoint selected automatically from the artifact kind.

Implementation Details

New Command Family

Connection management (per-platform, stored in the CLI config like ap gateway/ap devportal):

  • ap ai-workspace add — register an AI-Workspace connection (basic / oauth / api-key)
  • ap ai-workspace list / use / current / remove

Artifact lifecycle (operate inside an API project):

  • ap ai-workspace buildvalidates the project artifact (files present, metadata/runtime kinds align, name matches). Generates/sends nothing.
  • ap ai-workspace apply — runs the same validation, generates the creation payload from the project artifacts, and creates the artifact (POST) or update an exiting artifact (PUT /{resource}/{id}). Here the both create & edit will be handled through apply command to make consistent with Gateway CICD flow.

apply live at the root and pick the endpoint from the declared kind:

Kind Endpoint
LlmProvider /llm-providers
LlmProxy /llm-proxies
Mcp /mcp-proxies

Read/delete per kind:

  • ap ai-workspace llm-provider list | get | delete
  • ap ai-workspace app-llm-proxy list | get | delete
  • ap ai-workspace mcp-proxy list | get | delete

Other CLI Changes

  • ap project init — scaffolds an API project (renamed from apiproject). Artifact types: REST, LLM-Proxy, App-LLM-Provider, MCP-Proxy; generates metadata.yaml, runtime.yaml, definition.yaml, docs/, tests/, and .api-platform/config.yaml.
  • ap devportal gen (new) + reworked ap devportal build — two-stage flow: gen produces the editable devportal artifact source (./devportal) and registers it in the project config; build packages it into build/devportal.zip. --reference-id / --gateway-type are stamped into the archived manifest only (the workspace source is left untouched).
  • ap devportal resource commands synced to the current spec (org, application, apikey, subscription, sub-plan incl. new list, restapi).
  • ap platform remove (new).

Key Behaviours

  • Kind-driven publishing — no per-kind apply commands; the endpoint is resolved from the artifact kind.
  • Env-variable injectionmetadata.yaml/runtime.yaml may reference ENV_CLI_* placeholders for environment-specific field values (not secrets). push/edit resolve them at publish time from --env-file, else the project .env, else the process environment; an unresolved variable fails the command and names it. (Secrets remain server-side via {{ secret "name" }}.)
  • Metadata kind suffixmetadata.yaml carries a …Metadata kind (e.g. LlmProxyMetadata) distinct from the runtime kind (LlmProxy); the suffix is stripped when matching.
  • associatedGateways — read from spec.associatedGateways in metadata.yaml and folded into the payload for every kind.
  • Single ai-workspace config — the project config models it as one object (a project has at most one AI-Workspace), unlike the devportals list.
  • Consistent outputapply print an ap gateway apply-style summary (Status, Message, ID, Organization, Project, Created At, Updated At, State), or full JSON with -o json.
  • Org is always derived from the auth token (no --org flag).

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds AI-workspace CLI support, migrates DevPortal request paths to org-scoped routes, introduces a new project package with init/gen/build flows, extends gateway resource handling for new LLM kinds, and adds sync guidance plus related documentation.

Changes

AI Workspace CLI Feature

Layer / File(s) Summary
Config model and resource CRUD
cli/src/internal/config/config.go, cli/src/internal/config/remove_platform_test.go
Adds AIWorkspace config support, generic platform resource CRUD, and platform removal.
HTTP client and helpers
cli/src/internal/aiworkspace/client.go, .../helpers.go, .../paths_test.go, .../print_test.go, .../client_test.go, cli/src/utils/input.go
Adds the AI-workspace HTTP client, path helpers, JSON file reading, request formatting, output helpers, and tests.
Connection management commands
cli/src/cmd/aiworkspace/add.go, list.go, remove.go, use.go, current.go, root.go
Adds ai-workspace add/list/remove/use/current commands and root wiring.
Build validation and payload construction
cli/src/cmd/aiworkspace/build.go, build_test.go
Adds ai-workspace build validation, payload builders, env substitution, path safety, and tests.
Apply command
cli/src/cmd/aiworkspace/apply.go
Adds ai-workspace apply orchestration and create-or-update request handling.
LLM provider, LLM proxy, and MCP proxy commands
cli/src/cmd/aiworkspace/llmprovider/*, llmproxy/*, mcpproxy/*
Adds root commands and get/list/delete subcommands for AI-workspace resource groups.
AI-workspace docs
docs/cli/README.md, docs/cli/ai-workspace/README.md, docs/cli/end-to-end-workflow.md
Adds documentation for ai-workspace commands, build/apply semantics, payload mappings, and command references.

DevPortal API Path Restructuring

Layer / File(s) Summary
OrgScopedPath helper
cli/src/internal/devportal/helpers.go
Adds the org-scoped DevPortal path helper and API version constant.
API key, application, org, rest-api, sub-plan, subscription path migration
cli/src/cmd/devportal/apikey/*, application/*, org/*, restapi/*, subplan/*, subscription/*
Updates DevPortal commands to org-scoped /o/{org}/devportal/v1/... routes, plus /organizations/... for org commands, and refreshes tests/docs.

Project Package and DevPortal Build/Gen Revamp

Layer / File(s) Summary
Internal project package
cli/src/internal/project/artifact.go, config.go, scaffold.go
Adds artifact type helpers, project config schema, and YAML scaffolding helpers.
ap project init
cli/src/cmd/project/init.go, init_test.go, root.go, cli/src/cmd/root.go
Adds the project init command and renames root wiring to ProjectCmd.
ap devportal gen
cli/src/cmd/devportal/gen.go, gen_test.go, root.go
Adds the DevPortal artifact generator and root registration.
ap devportal build revamp
cli/src/cmd/devportal/build.go, build_test.go
Rewrites DevPortal build around project.PortalConfig, adds manifest stamping flags, standardized archive layout, and tests.
End-to-end workflow docs
docs/cli/end-to-end-workflow.md
Documents the project init, gateway, DevPortal, and AI-workspace workflow.

Gateway LLM Support and CLI Utilities

Layer / File(s) Summary
Gateway LLM resource support
cli/src/internal/gateway/resources.go, cli/src/utils/constants.go, cli/src/cmd/gateway/apply.go
Adds LLM provider/proxy gateway handlers and route constants.
ap platform remove
cli/src/cmd/platform/remove.go, root.go
Adds platform removal command.
Flags and prompt utilities
cli/src/utils/flags.go, cli/src/utils/input.go
Adds new flag constants and shared prompt input handling.

sync-cli-with-openapi Skill Documentation

Layer / File(s) Summary
Skill workflow and templates
.agents/skills/sync-cli-with-openapi/SKILL.md, references/cli-command-anatomy.md
Adds workflow and reference templates for syncing CLI commands with OpenAPI changes.

Estimated code review effort: 5 (Critical) | ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the feature well, but it misses several required template sections like User stories, Automation tests, Security checks, Samples, Related PRs, and Test environment. Add the missing template sections and populate them with the required details, especially goals/approach, tests, security checks, related PRs, and test environment.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: adding AI-Workspace CICD CLI commands.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ShakyaPr
ShakyaPr force-pushed the feature/platform_cicd branch from 8752145 to f8ecdf2 Compare July 6, 2026 06:36
@ShakyaPr
ShakyaPr marked this pull request as ready for review July 6, 2026 06:37
@ShakyaPr ShakyaPr changed the title Feature/platform cicd Introduce CICD CLI Commands for AI-Workspace Jul 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/cli/devportal/README.md (1)

666-748: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update stale endpoint references in the Subscription Plan section.

The new sub-plan list note correctly documents GET /o/<org-id>/devportal/v1/subscription-policies, but the section intro (line 668) and the sub-plan publish note (line 728) still describe the old /devportal/organizations/{orgId}/subscription-policies path. Update those to the org-scoped /o/{orgId}/devportal/v1/... format for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cli/devportal/README.md` around lines 666 - 748, Update the stale
subscription plan endpoint references so they consistently use the org-scoped
`/o/{orgId}/devportal/v1/subscription-policies` format. In the Subscription Plan
section intro and the `ap devportal sub-plan publish` notes, replace the old
`/devportal/organizations/{orgId}/subscription-policies` wording to match the
`ap devportal sub-plan list` documentation and keep the `sub-plan
publish`/`sub-plan list` command descriptions aligned.
🧹 Nitpick comments (8)
cli/src/cmd/aiws/llmproxy/list.go (1)

66-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Mark --project-id as a required Cobra flag for consistency.

The flag description states "(required)" and is validated manually in runListCommand, but MarkFlagRequired is never called, unlike other commands in this PR (e.g., llmprovider/delete.go) that mark their key identifier flag as required. This means --help won't surface the requirement and errors surface only after manual parsing.

♻️ Proposed fix
 	utils.AddStringFlag(listCmd, utils.FlagPlatform, &listPlatform, "", "Platform name")
 	listCmd.Flags().BoolVar(&listInsecure, "insecure", false, "Skip TLS certificate verification")
+	_ = listCmd.MarkFlagRequired(utils.FlagProjectID)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiws/llmproxy/list.go` around lines 66 - 73, The list command
currently treats `--project-id` as required only in the flag description and
manual validation, but it is not declared as required by Cobra. Update the flag
setup in init for listCmd to mark the project ID flag as required, following the
same pattern used by other commands such as llmprovider/delete.go, so help
output and command validation reflect the requirement consistently.
cli/src/cmd/aiws/llmproxy/get.go (1)

44-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use the shared utils.FlagInsecure constant/helper for consistency.

getInsecure is registered via a raw getCmd.Flags().BoolVar(&getInsecure, "insecure", false, ...) (Line 74) instead of utils.AddBoolFlag(getCmd, utils.FlagInsecure, ...), which is the pattern used in cli/src/cmd/devportal/subplan/list.go. This duplicates the flag-name literal and diverges from the established helper pattern.

♻️ Suggested consistency fix
-	getCmd.Flags().BoolVar(&getInsecure, "insecure", false, "Skip TLS certificate verification")
+	utils.AddBoolFlag(getCmd, utils.FlagInsecure, &getInsecure, false, "Skip TLS certificate verification")

Also applies to: 74-74

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiws/llmproxy/get.go` around lines 44 - 52, The getCmd insecure
flag registration in getCmd should use the shared utils.FlagInsecure helper
pattern instead of a raw BoolVar call. Update the flag setup in the get command
to call utils.AddBoolFlag with utils.FlagInsecure, and keep the getInsecure
variable as the target so the behavior stays the same while matching the
existing convention used elsewhere such as the list command.
cli/src/cmd/aiws/add.go (1)

217-241: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider consolidating the duplicate auth-type switches.

The two switch addAuth blocks (credential-stored note and missing-credentials hint) repeat the same case structure. Extracting the env-var name(s) per auth type into a small helper would reduce duplication.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiws/add.go` around lines 217 - 241, The two addAuth switch
blocks in add.go duplicate the same auth-type mapping, so consolidate them into
a single helper that returns the relevant env var name(s) for
utils.AuthTypeBasic, utils.AuthTypeOAuth, and utils.AuthTypeAPIKey. Update the
credential-stored note and the no-credentials boxed message to call that helper
instead of repeating the case structure, keeping the existing behavior and
messages in place.
cli/src/cmd/aiws/list.go (1)

68-77: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Sort rows for deterministic table output.

platform.AIWorkspaces is a map, so iteration order is randomized in Go; each invocation of ap ai-workspace list may print rows in a different order.

♻️ Suggested fix: sort by name
+	names := make([]string, 0, len(platform.AIWorkspaces))
+	for name := range platform.AIWorkspaces {
+		names = append(names, name)
+	}
+	sort.Strings(names)
+
 	headers := []string{"PLATFORM", "NAME", "URL", "AUTH", "CURRENT"}
 	rows := make([][]string, 0, len(platform.AIWorkspaces))
-	for name, ws := range platform.AIWorkspaces {
+	for _, name := range names {
+		ws := platform.AIWorkspaces[name]
 		current := ""
 		if name == platform.ActiveAIWorkspace {
 			current = "*"
 		}
 		rows = append(rows, []string{resolvedPlatform, name, ws.URL, ws.Auth.Type, current})
 	}

(add "sort" to imports)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiws/list.go` around lines 68 - 77, The ai-workspace list output
is nondeterministic because ListAIWorkspaces iterates over the
platform.AIWorkspaces map directly. Update the row-building logic in list.go to
collect the workspace names from platform.AIWorkspaces, sort them with the sort
package, and then append rows in that sorted order so utils.PrintTable always
prints a stable table. Keep the current workspace marker logic using
platform.ActiveAIWorkspace unchanged.
docs/cli/ai-workspace/README.md (1)

261-261: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix trailing space inside code span.

The `export ` code span has a trailing space, flagged by markdownlint (MD038).

✏️ Proposed fix
-an `export ` prefix is allowed
+an `export` prefix is allowed
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cli/ai-workspace/README.md` at line 261, The README text in the env file
format description has a markdownlint MD038 issue caused by a trailing space
inside the inline code span for export. Update the affected prose in the README
so the inline code formatting around export has no trailing whitespace, and
verify the surrounding sentence still reads naturally with the same env parsing
rules description.

Source: Linters/SAST tools

cli/src/cmd/project/init.go (2)

91-106: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant artifact-type validation.

runInitCommand already validates projectType via project.IsValidArtifactType before calling buildDirectoryStructure, which re-runs the identical check. Consider dropping the duplicate check in buildDirectoryStructure since it is always invoked with an already-validated type.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/project/init.go` around lines 91 - 106, runInitCommand already
validates projectType with project.IsValidArtifactType before calling
buildDirectoryStructure, so the identical check inside buildDirectoryStructure
is redundant. Remove the duplicate artifact-type validation from
buildDirectoryStructure and keep the validation only in runInitCommand, leaving
buildDirectoryStructure focused on creating the directory structure for the
already-validated artifact type.

64-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Lowercase error message strings.

Per Go convention, error strings should not be capitalized.

♻️ Proposed fix
-			return fmt.Errorf("Failed to read display name: %w", err)
+			return fmt.Errorf("failed to read display name: %w", err)
-			return fmt.Errorf("Failed to read artifact type: %w", err)
+			return fmt.Errorf("failed to read artifact type: %w", err)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/project/init.go` around lines 64 - 101, The error messages
returned from runInitCommand are capitalized and should follow Go convention by
starting lowercase. Update the fmt.Errorf strings in runInitCommand, including
the PromptInput and PromptSelect failures, so they begin with lowercase text
while keeping the same error context and wrapping behavior. Also check any other
returned errors in this flow, such as validation failures for displayName and
projectType, to ensure all user-facing error strings in this command are
consistently lowercase.
cli/src/utils/input.go (1)

152-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate credential-prompt logic.

PromptAIWorkspaceCredentials mirrors PromptDevPortalCredentials almost exactly, differing only in prompt labels and env var constants. Consider extracting a shared helper parameterized by service name and env var names to avoid maintaining two near-identical implementations.

♻️ Example consolidation approach
func promptCredentials(service, authType string, envUser, envPass, envToken, envKey string) (username, password, token, apiKey string, err error) {
	switch authType {
	case AuthTypeBasic:
		username, err = PromptInput(fmt.Sprintf("Enter %s username (leave empty to use %s env var): ", service, envUser))
		if err != nil {
			return "", "", "", "", err
		}
		password, err = PromptPassword(fmt.Sprintf("Enter %s password (leave empty to use %s env var): ", service, envPass))
		if err != nil {
			return "", "", "", "", err
		}
		return username, password, "", "", nil
	case AuthTypeOAuth:
		token, err = PromptPassword(fmt.Sprintf("Enter %s OAuth token (leave empty to use %s env var): ", service, envToken))
		if err != nil {
			return "", "", "", "", err
		}
		return "", "", token, "", nil
	case AuthTypeAPIKey:
		apiKey, err = PromptPassword(fmt.Sprintf("Enter %s API key (leave empty to use %s env var): ", service, envKey))
		if err != nil {
			return "", "", "", "", err
		}
		return "", "", "", apiKey, nil
	default:
		return "", "", "", "", fmt.Errorf("unsupported %s auth type '%s'", service, authType)
	}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/utils/input.go` around lines 152 - 224, PromptDevPortalCredentials
and PromptAIWorkspaceCredentials are near-duplicate credential flows; extract
the shared prompting logic into a helper like promptCredentials and parameterize
it with the service label plus the env var names. Keep the existing public
functions as thin wrappers that pass the appropriate constants (for DevPortal
and AI workspace) into the helper, and preserve the current AuthTypeBasic,
AuthTypeOAuth, AuthTypeAPIKey, and default error handling behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md:
- Line 243: The CLI literal in this section is outdated and should use the
current `ap ai-workspace` family instead of `ap ai-ws`. Update the referenced
command name in the `cli-command-anatomy.md` content so it matches the existing
CLI grouping and examples, and keep the surrounding references to the
`llmprovider`, `llmproxy`, and `mcpproxy` groups aligned with that command
family.

In @.vscode/launch.json:
- Line 48: The shared launch configuration currently hardcodes
PLATFORM_SECRET_ENCRYPTION_KEY, which should not be committed as reusable secret
material. Update the launch.json entry to use an environment placeholder or a
local override mechanism instead, keeping the secret out of the shared config
while preserving the same variable name for launch-time resolution.

In `@cli/src/cmd/aiws/llmproxy/get.go`:
- Around line 44-52: The GET command flow is printing error responses as if they
were successful because PrintJSONResponse only formats the body. Update the
llmproxy get/list handling around the
getID/getProjectID/getLimit/getOffset/getName/getPlatform options to check
resp.StatusCode before calling PrintJSONResponse, and return an error for any
4xx/5xx response so failed proxy lookups/listings are surfaced properly. Use the
existing response handling in the get command path to keep the success path
unchanged while routing non-2xx statuses to error handling.

In `@cli/src/cmd/devportal/build.go`:
- Around line 268-341: `applyManifestOverrides` is mutating the source devportal
manifest instead of the staged copy, which can leave build flags behind in the
workspace. Update the build flow in `build.go` so
`createDevPortalArchiveStagingDir` (or the staging path it returns) is the place
where `applyManifestOverrides` is applied before `utils.ZipDirectory`, and keep
the project file untouched. Adjust the related build test to verify the manifest
contents from the generated archive/staging output rather than the original
`devportal.yaml`.

In `@cli/src/cmd/devportal/gen.go`:
- Around line 255-256: The generated devportal manifest is currently built by
interpolating raw values in renderGeneratedDevPortalManifest, which can break
YAML when name, displayName, or version contain special characters. Update
renderGeneratedDevPortalManifest to construct the manifest from a structured Go
value (struct or map) and marshal it to YAML instead of using fmt.Sprintf with
the template. Keep the existing function signature and ensure the generated
devportal.yaml content stays valid for all input values.
- Around line 108-121: Ensure the devportal generation flow does not leave
behind a partially created portalRoot when later validation or copy steps fail.
In gen.go, adjust the sequence around resolveProjectPath, os.Stat, and copyFile
so inputs are verified before os.MkdirAll creates the devportal directory, or
add cleanup logic that removes the directory on any error after creation. Keep
the existing behavior in the devportal generation path, but make sure the
directory creation in the main generation function is not the first irreversible
step.

---

Outside diff comments:
In `@docs/cli/devportal/README.md`:
- Around line 666-748: Update the stale subscription plan endpoint references so
they consistently use the org-scoped
`/o/{orgId}/devportal/v1/subscription-policies` format. In the Subscription Plan
section intro and the `ap devportal sub-plan publish` notes, replace the old
`/devportal/organizations/{orgId}/subscription-policies` wording to match the
`ap devportal sub-plan list` documentation and keep the `sub-plan
publish`/`sub-plan list` command descriptions aligned.

---

Nitpick comments:
In `@cli/src/cmd/aiws/add.go`:
- Around line 217-241: The two addAuth switch blocks in add.go duplicate the
same auth-type mapping, so consolidate them into a single helper that returns
the relevant env var name(s) for utils.AuthTypeBasic, utils.AuthTypeOAuth, and
utils.AuthTypeAPIKey. Update the credential-stored note and the no-credentials
boxed message to call that helper instead of repeating the case structure,
keeping the existing behavior and messages in place.

In `@cli/src/cmd/aiws/list.go`:
- Around line 68-77: The ai-workspace list output is nondeterministic because
ListAIWorkspaces iterates over the platform.AIWorkspaces map directly. Update
the row-building logic in list.go to collect the workspace names from
platform.AIWorkspaces, sort them with the sort package, and then append rows in
that sorted order so utils.PrintTable always prints a stable table. Keep the
current workspace marker logic using platform.ActiveAIWorkspace unchanged.

In `@cli/src/cmd/aiws/llmproxy/get.go`:
- Around line 44-52: The getCmd insecure flag registration in getCmd should use
the shared utils.FlagInsecure helper pattern instead of a raw BoolVar call.
Update the flag setup in the get command to call utils.AddBoolFlag with
utils.FlagInsecure, and keep the getInsecure variable as the target so the
behavior stays the same while matching the existing convention used elsewhere
such as the list command.

In `@cli/src/cmd/aiws/llmproxy/list.go`:
- Around line 66-73: The list command currently treats `--project-id` as
required only in the flag description and manual validation, but it is not
declared as required by Cobra. Update the flag setup in init for listCmd to mark
the project ID flag as required, following the same pattern used by other
commands such as llmprovider/delete.go, so help output and command validation
reflect the requirement consistently.

In `@cli/src/cmd/project/init.go`:
- Around line 91-106: runInitCommand already validates projectType with
project.IsValidArtifactType before calling buildDirectoryStructure, so the
identical check inside buildDirectoryStructure is redundant. Remove the
duplicate artifact-type validation from buildDirectoryStructure and keep the
validation only in runInitCommand, leaving buildDirectoryStructure focused on
creating the directory structure for the already-validated artifact type.
- Around line 64-101: The error messages returned from runInitCommand are
capitalized and should follow Go convention by starting lowercase. Update the
fmt.Errorf strings in runInitCommand, including the PromptInput and PromptSelect
failures, so they begin with lowercase text while keeping the same error context
and wrapping behavior. Also check any other returned errors in this flow, such
as validation failures for displayName and projectType, to ensure all
user-facing error strings in this command are consistently lowercase.

In `@cli/src/utils/input.go`:
- Around line 152-224: PromptDevPortalCredentials and
PromptAIWorkspaceCredentials are near-duplicate credential flows; extract the
shared prompting logic into a helper like promptCredentials and parameterize it
with the service label plus the env var names. Keep the existing public
functions as thin wrappers that pass the appropriate constants (for DevPortal
and AI workspace) into the helper, and preserve the current AuthTypeBasic,
AuthTypeOAuth, AuthTypeAPIKey, and default error handling behavior.

In `@docs/cli/ai-workspace/README.md`:
- Line 261: The README text in the env file format description has a
markdownlint MD038 issue caused by a trailing space inside the inline code span
for export. Update the affected prose in the README so the inline code
formatting around export has no trailing whitespace, and verify the surrounding
sentence still reads naturally with the same env parsing rules description.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d3fee44f-c733-4a14-9b0e-144e4e29e820

📥 Commits

Reviewing files that changed from the base of the PR and between eb1d7be and f8ecdf2.

📒 Files selected for processing (90)
  • .agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md
  • .gitignore
  • .vscode/launch.json
  • cli/src/cmd/aiws/add.go
  • cli/src/cmd/aiws/build.go
  • cli/src/cmd/aiws/build_test.go
  • cli/src/cmd/aiws/current.go
  • cli/src/cmd/aiws/edit.go
  • cli/src/cmd/aiws/list.go
  • cli/src/cmd/aiws/llmprovider/delete.go
  • cli/src/cmd/aiws/llmprovider/get.go
  • cli/src/cmd/aiws/llmprovider/list.go
  • cli/src/cmd/aiws/llmprovider/root.go
  • cli/src/cmd/aiws/llmproxy/delete.go
  • cli/src/cmd/aiws/llmproxy/get.go
  • cli/src/cmd/aiws/llmproxy/list.go
  • cli/src/cmd/aiws/llmproxy/root.go
  • cli/src/cmd/aiws/mcpproxy/delete.go
  • cli/src/cmd/aiws/mcpproxy/get.go
  • cli/src/cmd/aiws/mcpproxy/list.go
  • cli/src/cmd/aiws/mcpproxy/root.go
  • cli/src/cmd/aiws/push.go
  • cli/src/cmd/aiws/remove.go
  • cli/src/cmd/aiws/root.go
  • cli/src/cmd/aiws/use.go
  • cli/src/cmd/apiproject/init.go
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/devportal/apikey/commands_test.go
  • cli/src/cmd/devportal/apikey/generate.go
  • cli/src/cmd/devportal/apikey/get.go
  • cli/src/cmd/devportal/apikey/regenerate.go
  • cli/src/cmd/devportal/apikey/revoke.go
  • cli/src/cmd/devportal/application/commands_test.go
  • cli/src/cmd/devportal/application/create.go
  • cli/src/cmd/devportal/application/delete.go
  • cli/src/cmd/devportal/application/get.go
  • cli/src/cmd/devportal/application/update.go
  • cli/src/cmd/devportal/build.go
  • cli/src/cmd/devportal/build_test.go
  • cli/src/cmd/devportal/gen.go
  • cli/src/cmd/devportal/gen_test.go
  • cli/src/cmd/devportal/org/add.go
  • cli/src/cmd/devportal/org/commands_test.go
  • cli/src/cmd/devportal/org/delete.go
  • cli/src/cmd/devportal/org/edit.go
  • cli/src/cmd/devportal/org/get.go
  • cli/src/cmd/devportal/org/list.go
  • cli/src/cmd/devportal/restapi/commands_test.go
  • cli/src/cmd/devportal/restapi/delete.go
  • cli/src/cmd/devportal/restapi/edit.go
  • cli/src/cmd/devportal/restapi/get.go
  • cli/src/cmd/devportal/restapi/list.go
  • cli/src/cmd/devportal/restapi/publish.go
  • cli/src/cmd/devportal/root.go
  • cli/src/cmd/devportal/subplan/commands_test.go
  • cli/src/cmd/devportal/subplan/delete.go
  • cli/src/cmd/devportal/subplan/get.go
  • cli/src/cmd/devportal/subplan/list.go
  • cli/src/cmd/devportal/subplan/publish.go
  • cli/src/cmd/devportal/subplan/root.go
  • cli/src/cmd/devportal/subscription/commands_test.go
  • cli/src/cmd/devportal/subscription/create.go
  • cli/src/cmd/devportal/subscription/delete.go
  • cli/src/cmd/devportal/subscription/edit.go
  • cli/src/cmd/devportal/subscription/get.go
  • cli/src/cmd/gateway/apply.go
  • cli/src/cmd/platform/remove.go
  • cli/src/cmd/platform/root.go
  • cli/src/cmd/project/init.go
  • cli/src/cmd/project/init_test.go
  • cli/src/cmd/project/root.go
  • cli/src/cmd/root.go
  • cli/src/internal/aiworkspace/client.go
  • cli/src/internal/aiworkspace/helpers.go
  • cli/src/internal/aiworkspace/paths_test.go
  • cli/src/internal/aiworkspace/print_test.go
  • cli/src/internal/config/config.go
  • cli/src/internal/config/remove_platform_test.go
  • cli/src/internal/devportal/helpers.go
  • cli/src/internal/gateway/resources.go
  • cli/src/internal/project/artifact.go
  • cli/src/internal/project/config.go
  • cli/src/internal/project/scaffold.go
  • cli/src/utils/constants.go
  • cli/src/utils/flags.go
  • cli/src/utils/input.go
  • docs/cli/README.md
  • docs/cli/ai-workspace/README.md
  • docs/cli/devportal/README.md
  • docs/cli/end-to-end-workflow.md
💤 Files with no reviewable changes (2)
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/apiproject/init.go

Comment thread .agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md Outdated
Comment thread .vscode/launch.json Outdated
Comment thread cli/src/cmd/aiworkspace/llmproxy/get.go
Comment thread cli/src/cmd/devportal/build.go Outdated
Comment thread cli/src/cmd/devportal/gen.go Outdated
Comment thread cli/src/cmd/devportal/gen.go Outdated
@ShakyaPr
ShakyaPr force-pushed the feature/platform_cicd branch 2 times, most recently from 13ba760 to 08e6106 Compare July 6, 2026 09:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (5)
cli/src/cmd/devportal/gen_test.go (2)

38-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for kind-default fallback.

Per context snippet 3, buildGeneratedDevPortalManifest defaults kind to "RestApi" when metadata.Kind is blank. This file only exercises the explicit kind: RestApi path; there's no case where metadata.yaml omits kind to verify the fallback actually takes effect.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/devportal/gen_test.go` around lines 38 - 92, Add test coverage
for the kind-default fallback in runGenCommand by updating
TestRunGenCommand_GeneratesDefaultArtifact or adding a sibling test that writes
a metadata.yaml without kind. Verify buildGeneratedDevPortalManifest still
produces the expected devportal.yaml using the default "RestApi" kind and that
the generated manifest matches the existing REST artifact assertions.

29-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reset genProjectDir between tests.

Each test sets the package-level genProjectDir variable directly but never restores it afterward. If a later test in this package (or file, under -shuffle) relies on the zero-value "" default, stale state from an earlier test will leak in. Add t.Cleanup to restore the prior value.

♻️ Proposed fix (apply to each test setting genProjectDir)
 func TestRunGenCommand_RequiresProjectDirectory(t *testing.T) {
-	genProjectDir = t.TempDir()
+	genProjectDir = t.TempDir()
+	t.Cleanup(func() { genProjectDir = "" })
 
 	err := runGenCommand()

Also applies to: 38-46, 94-99, 145-152

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/devportal/gen_test.go` around lines 29 - 36, The package-level
genProjectDir state is leaking across tests because each test mutates it without
restoring the prior value. In the gen_test.go tests that set genProjectDir
(including TestRunGenCommand_RequiresProjectDirectory and the other affected
test cases), capture the existing value before assignment and register t.Cleanup
to restore it after the test. This keeps runGenCommand and related tests
isolated and prevents stale state from affecting later cases.
cli/src/cmd/aiworkspace/list.go (1)

68-77: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Non-deterministic output ordering from map iteration.

Iterating platform.AIWorkspaces (a Go map) directly means row order varies across runs, which works against the PR's stated goal of "consistent CLI output."

♻️ Proposed fix
+	names := make([]string, 0, len(platform.AIWorkspaces))
+	for name := range platform.AIWorkspaces {
+		names = append(names, name)
+	}
+	sort.Strings(names)
+
 	headers := []string{"PLATFORM", "NAME", "URL", "AUTH", "CURRENT"}
 	rows := make([][]string, 0, len(platform.AIWorkspaces))
-	for name, ws := range platform.AIWorkspaces {
+	for _, name := range names {
+		ws := platform.AIWorkspaces[name]
 		current := ""
 		if name == platform.ActiveAIWorkspace {
 			current = "*"
 		}
 		rows = append(rows, []string{resolvedPlatform, name, ws.URL, ws.Auth.Type, current})
 	}

(add "sort" to imports)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/list.go` around lines 68 - 77, The AI workspace table
output is non-deterministic because ListAIWorkspaces iterates
platform.AIWorkspaces directly, so the row order changes between runs. Update
the list-building logic in the list command to collect the workspace names, sort
them with the sort package, and then append rows in that sorted order while
preserving the current marker for platform.ActiveAIWorkspace. Use the existing
ListAIWorkspaces flow and utils.PrintTable output path as the place to make this
change.
cli/src/cmd/aiworkspace/mcpproxy/get.go (1)

90-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Listing branch duplicates list.go wholesale.

The else branch here (project-ID validation + MCPProxyListPath(projectID, aiworkspace.ListQuery{Limit: getLimit, Offset: getOffset})) reimplements exactly what list.go's runListCommand already does. Keeping two independently-maintained copies of the same listing logic (flags, validation message, path construction) risks drift — e.g. if pagination validation or the path builder call changes in one, it's easy to forget the other.

Consider having get (without --id) delegate to the same helper list uses, or drop the listing capability from get since mcp-proxy list already covers it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/mcpproxy/get.go` around lines 90 - 102, The `get`
command’s non-`--id` branch duplicates the listing flow already implemented in
`runListCommand`, including project-ID validation and `MCPProxyListPath`
construction. Refactor `get.go` so `runGetCommand` delegates to the same shared
helper used by `list.go` (or remove the list fallback from `get` entirely) to
avoid keeping two copies of the same proxy-listing logic in sync.
cli/src/cmd/aiworkspace/build_test.go (1)

320-335: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Bare-word env substitution risks accidental value corruption.

TestResolveEnvPlaceholders_BareFormRequiresWordBoundary confirms resolveEnvPlaceholders rewrites any bare, word-boundary-delimited occurrence of a known env var name anywhere in the JSON payload text — not just fields explicitly intended as placeholders. If a payload legitimately contains a literal string identical to a set env var name (e.g. a display name, description, or example value), it will be silently replaced with that variable's value. Unlike the ${VAR}/$VAR forms, bare-word matching has no syntactic marker signaling "this is a placeholder," which is unusual compared to conventional env-substitution implementations and increases the chance of an unintended, hard-to-diagnose substitution in a generated payload.

Consider requiring an explicit sigil for all supported forms (drop bare-word support, or restrict it to specific known fields) to remove this ambiguity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/build_test.go` around lines 320 - 335, The bare-word
matching in resolveEnvPlaceholders is too permissive and can rewrite legitimate
literal strings anywhere in the JSON payload. Update the placeholder resolution
logic to require an explicit sigil form (such as the existing ${VAR} or $VAR
forms) and remove or tightly scope bare-word substitution so only intentional
placeholders are replaced. Adjust
TestResolveEnvPlaceholders_BareFormRequiresWordBoundary and related tests to
reflect the new behavior, using resolveEnvPlaceholders as the main entry point
to verify literals remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md:
- Around line 44-52: The AI-workspace command examples still reference the old
aiws package path, so update the template guidance to use
cli/src/cmd/aiworkspace/... and the matching root file under that tree. Fix the
path references in this markdown section and any related examples/comments in
the same template so copy/paste instructions point to the current command
family, using the aiworkspace symbols and layout consistently.

In @.agents/skills/sync-cli-with-openapi/SKILL.md:
- Around line 3-5: Update the skill metadata to use the new AI-workspace naming
and CLI root so future syncs target the right command tree. In the description,
replace the old `ap ai-ws` family and `cli/src/cmd/aiws/` references with `ap
ai-workspace` and `cli/src/cmd/aiworkspace/`, and make the same rename anywhere
else in this SKILL.md that still points to the old family or path. Keep the rest
of the sync guidance unchanged.

In `@cli/src/cmd/aiworkspace/add.go`:
- Around line 157-192: Trim the credential inputs before they are validated and
stored in aiWorkspace, since username, password, token, and apiKey can carry
trailing whitespace from prompts or flags. Update the add flow in add.go where
username/password/token/apiKey are assigned and used so the values are
normalized before the auth checks and before constructing config.AIWorkspace,
similar to how addName and addServer are handled.

In `@cli/src/cmd/aiworkspace/build.go`:
- Around line 618-655: The MCP proxy payload builder is dropping the runtime
description by hardcoding an empty value in buildMCPProxyPayload. Update that
function to read and trim runtime.Spec.Description, matching the behavior in
buildLLMProxyPayload, and apply the same default/fallback handling
(defaultProxyDescription) when the field is unset so user-authored descriptions
are preserved in the generated payload.

In `@cli/src/internal/aiworkspace/client.go`:
- Around line 135-157: The non-2xx error paths in Client.sendNoBody and
Client.sendJSON leak the response body because resp.Body is never closed before
returning c.formatHTTPError. Update both helpers to always close resp.Body on
error status, matching the pattern used by Client.Exists, and keep the success
path unchanged so the transport can reuse connections properly.

In `@docs/cli/ai-workspace/README.md`:
- Around line 3-10: The README still points readers to the old aiws command
location, so update the guide text to reference the current aiworkspace CLI tree
instead. In the ai-workspace README content, replace the stale cli/src/cmd/aiws
path with cli/src/cmd/aiworkspace and make sure the command group description
still matches the implemented ai-workspace commands.
- Around line 204-240: The ai-workspace apply docs currently describe
conflicting command behavior by mentioning both apply/edit semantics and then
stating there is no separate edit command. Update the prose around ap
ai-workspace apply to use one consistent model only, and adjust the surrounding
references in this section so it clearly explains that apply generates and
creates/updates the artifact without implying a separate edit command.

---

Nitpick comments:
In `@cli/src/cmd/aiworkspace/build_test.go`:
- Around line 320-335: The bare-word matching in resolveEnvPlaceholders is too
permissive and can rewrite legitimate literal strings anywhere in the JSON
payload. Update the placeholder resolution logic to require an explicit sigil
form (such as the existing ${VAR} or $VAR forms) and remove or tightly scope
bare-word substitution so only intentional placeholders are replaced. Adjust
TestResolveEnvPlaceholders_BareFormRequiresWordBoundary and related tests to
reflect the new behavior, using resolveEnvPlaceholders as the main entry point
to verify literals remain unchanged.

In `@cli/src/cmd/aiworkspace/list.go`:
- Around line 68-77: The AI workspace table output is non-deterministic because
ListAIWorkspaces iterates platform.AIWorkspaces directly, so the row order
changes between runs. Update the list-building logic in the list command to
collect the workspace names, sort them with the sort package, and then append
rows in that sorted order while preserving the current marker for
platform.ActiveAIWorkspace. Use the existing ListAIWorkspaces flow and
utils.PrintTable output path as the place to make this change.

In `@cli/src/cmd/aiworkspace/mcpproxy/get.go`:
- Around line 90-102: The `get` command’s non-`--id` branch duplicates the
listing flow already implemented in `runListCommand`, including project-ID
validation and `MCPProxyListPath` construction. Refactor `get.go` so
`runGetCommand` delegates to the same shared helper used by `list.go` (or remove
the list fallback from `get` entirely) to avoid keeping two copies of the same
proxy-listing logic in sync.

In `@cli/src/cmd/devportal/gen_test.go`:
- Around line 38-92: Add test coverage for the kind-default fallback in
runGenCommand by updating TestRunGenCommand_GeneratesDefaultArtifact or adding a
sibling test that writes a metadata.yaml without kind. Verify
buildGeneratedDevPortalManifest still produces the expected devportal.yaml using
the default "RestApi" kind and that the generated manifest matches the existing
REST artifact assertions.
- Around line 29-36: The package-level genProjectDir state is leaking across
tests because each test mutates it without restoring the prior value. In the
gen_test.go tests that set genProjectDir (including
TestRunGenCommand_RequiresProjectDirectory and the other affected test cases),
capture the existing value before assignment and register t.Cleanup to restore
it after the test. This keeps runGenCommand and related tests isolated and
prevents stale state from affecting later cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6ab2990f-42be-49d4-aa47-fd40e661055d

📥 Commits

Reviewing files that changed from the base of the PR and between f8ecdf2 and a86b5c3.

📒 Files selected for processing (91)
  • .agents/skills/sync-cli-with-openapi/SKILL.md
  • .agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md
  • .gitignore
  • cli/src/cmd/aiworkspace/add.go
  • cli/src/cmd/aiworkspace/apply.go
  • cli/src/cmd/aiworkspace/build.go
  • cli/src/cmd/aiworkspace/build_test.go
  • cli/src/cmd/aiworkspace/current.go
  • cli/src/cmd/aiworkspace/list.go
  • cli/src/cmd/aiworkspace/llmprovider/delete.go
  • cli/src/cmd/aiworkspace/llmprovider/get.go
  • cli/src/cmd/aiworkspace/llmprovider/list.go
  • cli/src/cmd/aiworkspace/llmprovider/root.go
  • cli/src/cmd/aiworkspace/llmproxy/delete.go
  • cli/src/cmd/aiworkspace/llmproxy/get.go
  • cli/src/cmd/aiworkspace/llmproxy/list.go
  • cli/src/cmd/aiworkspace/llmproxy/root.go
  • cli/src/cmd/aiworkspace/mcpproxy/delete.go
  • cli/src/cmd/aiworkspace/mcpproxy/get.go
  • cli/src/cmd/aiworkspace/mcpproxy/list.go
  • cli/src/cmd/aiworkspace/mcpproxy/root.go
  • cli/src/cmd/aiworkspace/remove.go
  • cli/src/cmd/aiworkspace/root.go
  • cli/src/cmd/aiworkspace/use.go
  • cli/src/cmd/apiproject/init.go
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/devportal/apikey/commands_test.go
  • cli/src/cmd/devportal/apikey/generate.go
  • cli/src/cmd/devportal/apikey/get.go
  • cli/src/cmd/devportal/apikey/regenerate.go
  • cli/src/cmd/devportal/apikey/revoke.go
  • cli/src/cmd/devportal/application/commands_test.go
  • cli/src/cmd/devportal/application/create.go
  • cli/src/cmd/devportal/application/delete.go
  • cli/src/cmd/devportal/application/get.go
  • cli/src/cmd/devportal/application/update.go
  • cli/src/cmd/devportal/build.go
  • cli/src/cmd/devportal/build_test.go
  • cli/src/cmd/devportal/commands_test.go
  • cli/src/cmd/devportal/gen.go
  • cli/src/cmd/devportal/gen_test.go
  • cli/src/cmd/devportal/org/add.go
  • cli/src/cmd/devportal/org/commands_test.go
  • cli/src/cmd/devportal/org/delete.go
  • cli/src/cmd/devportal/org/edit.go
  • cli/src/cmd/devportal/org/get.go
  • cli/src/cmd/devportal/org/list.go
  • cli/src/cmd/devportal/restapi/commands_test.go
  • cli/src/cmd/devportal/restapi/delete.go
  • cli/src/cmd/devportal/restapi/edit.go
  • cli/src/cmd/devportal/restapi/get.go
  • cli/src/cmd/devportal/restapi/list.go
  • cli/src/cmd/devportal/restapi/publish.go
  • cli/src/cmd/devportal/root.go
  • cli/src/cmd/devportal/subplan/commands_test.go
  • cli/src/cmd/devportal/subplan/delete.go
  • cli/src/cmd/devportal/subplan/get.go
  • cli/src/cmd/devportal/subplan/list.go
  • cli/src/cmd/devportal/subplan/publish.go
  • cli/src/cmd/devportal/subplan/root.go
  • cli/src/cmd/devportal/subscription/commands_test.go
  • cli/src/cmd/devportal/subscription/create.go
  • cli/src/cmd/devportal/subscription/delete.go
  • cli/src/cmd/devportal/subscription/edit.go
  • cli/src/cmd/devportal/subscription/get.go
  • cli/src/cmd/gateway/apply.go
  • cli/src/cmd/platform/remove.go
  • cli/src/cmd/platform/root.go
  • cli/src/cmd/project/init.go
  • cli/src/cmd/project/init_test.go
  • cli/src/cmd/project/root.go
  • cli/src/cmd/root.go
  • cli/src/internal/aiworkspace/client.go
  • cli/src/internal/aiworkspace/client_test.go
  • cli/src/internal/aiworkspace/helpers.go
  • cli/src/internal/aiworkspace/paths_test.go
  • cli/src/internal/aiworkspace/print_test.go
  • cli/src/internal/config/config.go
  • cli/src/internal/config/remove_platform_test.go
  • cli/src/internal/devportal/helpers.go
  • cli/src/internal/gateway/resources.go
  • cli/src/internal/project/artifact.go
  • cli/src/internal/project/config.go
  • cli/src/internal/project/scaffold.go
  • cli/src/utils/constants.go
  • cli/src/utils/flags.go
  • cli/src/utils/input.go
  • docs/cli/README.md
  • docs/cli/ai-workspace/README.md
  • docs/cli/devportal/README.md
  • docs/cli/end-to-end-workflow.md
💤 Files with no reviewable changes (3)
  • cli/src/cmd/devportal/commands_test.go
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/apiproject/init.go
✅ Files skipped from review due to trivial changes (6)
  • .gitignore
  • docs/cli/devportal/README.md
  • cli/src/cmd/devportal/org/add.go
  • cli/src/cmd/gateway/apply.go
  • docs/cli/end-to-end-workflow.md
  • docs/cli/README.md
🚧 Files skipped from review as they are similar to previous changes (54)
  • cli/src/cmd/devportal/org/edit.go
  • cli/src/cmd/devportal/org/get.go
  • cli/src/cmd/devportal/restapi/edit.go
  • cli/src/cmd/devportal/subplan/root.go
  • cli/src/cmd/devportal/apikey/revoke.go
  • cli/src/cmd/devportal/subplan/get.go
  • cli/src/cmd/devportal/apikey/commands_test.go
  • cli/src/cmd/devportal/apikey/generate.go
  • cli/src/cmd/devportal/subscription/edit.go
  • cli/src/cmd/devportal/apikey/regenerate.go
  • cli/src/cmd/devportal/application/delete.go
  • cli/src/cmd/devportal/subscription/commands_test.go
  • cli/src/cmd/devportal/application/commands_test.go
  • cli/src/cmd/devportal/org/commands_test.go
  • cli/src/cmd/devportal/subscription/delete.go
  • cli/src/cmd/devportal/subscription/create.go
  • cli/src/internal/aiworkspace/paths_test.go
  • cli/src/cmd/platform/root.go
  • cli/src/internal/config/remove_platform_test.go
  • cli/src/cmd/devportal/application/update.go
  • cli/src/cmd/devportal/subplan/delete.go
  • cli/src/cmd/devportal/subplan/list.go
  • cli/src/cmd/devportal/restapi/publish.go
  • cli/src/cmd/devportal/org/delete.go
  • cli/src/cmd/devportal/subplan/publish.go
  • cli/src/internal/project/artifact.go
  • cli/src/internal/project/config.go
  • cli/src/cmd/project/root.go
  • cli/src/internal/aiworkspace/print_test.go
  • cli/src/cmd/devportal/root.go
  • cli/src/cmd/devportal/application/create.go
  • cli/src/cmd/devportal/restapi/list.go
  • cli/src/cmd/devportal/apikey/get.go
  • cli/src/cmd/devportal/application/get.go
  • cli/src/cmd/root.go
  • cli/src/cmd/devportal/restapi/get.go
  • cli/src/cmd/devportal/org/list.go
  • cli/src/cmd/devportal/subscription/get.go
  • cli/src/cmd/project/init_test.go
  • cli/src/internal/aiworkspace/helpers.go
  • cli/src/cmd/devportal/restapi/delete.go
  • cli/src/cmd/platform/remove.go
  • cli/src/utils/flags.go
  • cli/src/internal/gateway/resources.go
  • cli/src/cmd/devportal/subplan/commands_test.go
  • cli/src/internal/devportal/helpers.go
  • cli/src/internal/project/scaffold.go
  • cli/src/cmd/devportal/restapi/commands_test.go
  • cli/src/cmd/devportal/gen.go
  • cli/src/cmd/project/init.go
  • cli/src/internal/config/config.go
  • cli/src/utils/input.go
  • cli/src/cmd/devportal/build_test.go
  • cli/src/cmd/devportal/build.go

Comment thread .agents/skills/sync-cli-with-openapi/SKILL.md Outdated
Comment thread cli/src/cmd/aiworkspace/add.go
Comment thread cli/src/cmd/aiworkspace/build.go
Comment thread cli/src/internal/aiworkspace/client.go
Comment thread docs/cli/ai-workspace/README.md Outdated
Comment thread docs/cli/ai-workspace/README.md
@ShakyaPr
ShakyaPr force-pushed the feature/platform_cicd branch from a86b5c3 to 5596d0c Compare July 7, 2026 09:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
cli/src/cmd/aiworkspace/llmproxy/list.go (3)

68-69: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

No validation that limit/offset are numeric before sending to the API.

listLimit/listOffset are plain strings passed straight into ProxyListPath/ListQuery (Line 92). If a user passes a non-numeric value, the failure will surface as an opaque API/server error rather than a clear client-side validation message.

Also applies to: 92-92

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/llmproxy/list.go` around lines 68 - 69, The list
command is passing the raw string flags listLimit and listOffset straight into
ProxyListPath/ListQuery without client-side numeric validation. Update listCmd
handling in list.go to validate both values before building the request,
returning a clear validation error if either flag is non-numeric. Use the
existing listLimit/listOffset variables and the ProxyListPath/ListQuery call
site to locate the fix.

44-51: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent flag registration pattern for --insecure.

Other flags go through utils.AddStringFlag, but insecure is registered directly via listCmd.Flags().BoolVar. If this pattern repeats across the other AI-workspace subcommands (read/delete for llm-provider, app-llm-proxy, mcp-proxy), it's worth adding a shared utils.AddBoolFlag/utils.AddInsecureFlag helper to avoid the duplicated description string and boilerplate.

♻️ Suggested helper usage
-	listCmd.Flags().BoolVar(&listInsecure, "insecure", false, "Skip TLS certificate verification")
+	utils.AddBoolFlag(listCmd, utils.FlagInsecure, &listInsecure, false, "Skip TLS certificate verification")

Also applies to: 66-73

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/llmproxy/list.go` around lines 44 - 51, The
`--insecure` flag registration in `listCmd` is inconsistent with the existing
`utils.AddStringFlag` pattern and duplicates the same description/boilerplate
across AI-workspace commands. Introduce or reuse a shared helper such as
`utils.AddBoolFlag` or `utils.AddInsecureFlag`, then update `listCmd` and the
related llm-provider/app-llm-proxy/mcp-proxy commands to register `listInsecure`
through that helper instead of calling `Flags().BoolVar` directly.

67-67: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

project-id documented as required but not enforced via Cobra.

The help text says "(required)" but the flag isn't marked with MarkFlagRequired; enforcement instead happens manually later in runListCommand (Lines 82-84). This works functionally but means --help and Cobra's own usage/validation won't reflect the requirement.

🔧 Suggested fix
 func init() {
 	utils.AddStringFlag(listCmd, utils.FlagProjectID, &listProjectID, "", "Project ID (required)")
+	listCmd.MarkFlagRequired(utils.FlagProjectID)

Also applies to: 81-84

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/src/cmd/aiworkspace/llmproxy/list.go` at line 67, The project-id flag in
listCmd is only documented as required, but Cobra is not enforcing it. Update
the command setup around utils.AddStringFlag and runListCommand so the
requirement is registered with Cobra via MarkFlagRequired on the list command,
and remove or simplify the later manual validation in runListCommand to avoid
duplicating the check. Make sure the help/usage for listCmd now reflects the
required flag behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@cli/src/cmd/aiworkspace/llmproxy/list.go`:
- Around line 68-69: The list command is passing the raw string flags listLimit
and listOffset straight into ProxyListPath/ListQuery without client-side numeric
validation. Update listCmd handling in list.go to validate both values before
building the request, returning a clear validation error if either flag is
non-numeric. Use the existing listLimit/listOffset variables and the
ProxyListPath/ListQuery call site to locate the fix.
- Around line 44-51: The `--insecure` flag registration in `listCmd` is
inconsistent with the existing `utils.AddStringFlag` pattern and duplicates the
same description/boilerplate across AI-workspace commands. Introduce or reuse a
shared helper such as `utils.AddBoolFlag` or `utils.AddInsecureFlag`, then
update `listCmd` and the related llm-provider/app-llm-proxy/mcp-proxy commands
to register `listInsecure` through that helper instead of calling
`Flags().BoolVar` directly.
- Line 67: The project-id flag in listCmd is only documented as required, but
Cobra is not enforcing it. Update the command setup around utils.AddStringFlag
and runListCommand so the requirement is registered with Cobra via
MarkFlagRequired on the list command, and remove or simplify the later manual
validation in runListCommand to avoid duplicating the check. Make sure the
help/usage for listCmd now reflects the required flag behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ce5cd92f-71fd-4b57-9309-d765e778b938

📥 Commits

Reviewing files that changed from the base of the PR and between a86b5c3 and 5596d0c.

📒 Files selected for processing (91)
  • .agents/skills/sync-cli-with-openapi/SKILL.md
  • .agents/skills/sync-cli-with-openapi/references/cli-command-anatomy.md
  • .gitignore
  • cli/src/cmd/aiworkspace/add.go
  • cli/src/cmd/aiworkspace/apply.go
  • cli/src/cmd/aiworkspace/build.go
  • cli/src/cmd/aiworkspace/build_test.go
  • cli/src/cmd/aiworkspace/current.go
  • cli/src/cmd/aiworkspace/list.go
  • cli/src/cmd/aiworkspace/llmprovider/delete.go
  • cli/src/cmd/aiworkspace/llmprovider/get.go
  • cli/src/cmd/aiworkspace/llmprovider/list.go
  • cli/src/cmd/aiworkspace/llmprovider/root.go
  • cli/src/cmd/aiworkspace/llmproxy/delete.go
  • cli/src/cmd/aiworkspace/llmproxy/get.go
  • cli/src/cmd/aiworkspace/llmproxy/list.go
  • cli/src/cmd/aiworkspace/llmproxy/root.go
  • cli/src/cmd/aiworkspace/mcpproxy/delete.go
  • cli/src/cmd/aiworkspace/mcpproxy/get.go
  • cli/src/cmd/aiworkspace/mcpproxy/list.go
  • cli/src/cmd/aiworkspace/mcpproxy/root.go
  • cli/src/cmd/aiworkspace/remove.go
  • cli/src/cmd/aiworkspace/root.go
  • cli/src/cmd/aiworkspace/use.go
  • cli/src/cmd/apiproject/init.go
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/devportal/apikey/commands_test.go
  • cli/src/cmd/devportal/apikey/generate.go
  • cli/src/cmd/devportal/apikey/get.go
  • cli/src/cmd/devportal/apikey/regenerate.go
  • cli/src/cmd/devportal/apikey/revoke.go
  • cli/src/cmd/devportal/application/commands_test.go
  • cli/src/cmd/devportal/application/create.go
  • cli/src/cmd/devportal/application/delete.go
  • cli/src/cmd/devportal/application/get.go
  • cli/src/cmd/devportal/application/update.go
  • cli/src/cmd/devportal/build.go
  • cli/src/cmd/devportal/build_test.go
  • cli/src/cmd/devportal/commands_test.go
  • cli/src/cmd/devportal/gen.go
  • cli/src/cmd/devportal/gen_test.go
  • cli/src/cmd/devportal/org/add.go
  • cli/src/cmd/devportal/org/commands_test.go
  • cli/src/cmd/devportal/org/delete.go
  • cli/src/cmd/devportal/org/edit.go
  • cli/src/cmd/devportal/org/get.go
  • cli/src/cmd/devportal/org/list.go
  • cli/src/cmd/devportal/restapi/commands_test.go
  • cli/src/cmd/devportal/restapi/delete.go
  • cli/src/cmd/devportal/restapi/edit.go
  • cli/src/cmd/devportal/restapi/get.go
  • cli/src/cmd/devportal/restapi/list.go
  • cli/src/cmd/devportal/restapi/publish.go
  • cli/src/cmd/devportal/root.go
  • cli/src/cmd/devportal/subplan/commands_test.go
  • cli/src/cmd/devportal/subplan/delete.go
  • cli/src/cmd/devportal/subplan/get.go
  • cli/src/cmd/devportal/subplan/list.go
  • cli/src/cmd/devportal/subplan/publish.go
  • cli/src/cmd/devportal/subplan/root.go
  • cli/src/cmd/devportal/subscription/commands_test.go
  • cli/src/cmd/devportal/subscription/create.go
  • cli/src/cmd/devportal/subscription/delete.go
  • cli/src/cmd/devportal/subscription/edit.go
  • cli/src/cmd/devportal/subscription/get.go
  • cli/src/cmd/gateway/apply.go
  • cli/src/cmd/platform/remove.go
  • cli/src/cmd/platform/root.go
  • cli/src/cmd/project/init.go
  • cli/src/cmd/project/init_test.go
  • cli/src/cmd/project/root.go
  • cli/src/cmd/root.go
  • cli/src/internal/aiworkspace/client.go
  • cli/src/internal/aiworkspace/client_test.go
  • cli/src/internal/aiworkspace/helpers.go
  • cli/src/internal/aiworkspace/paths_test.go
  • cli/src/internal/aiworkspace/print_test.go
  • cli/src/internal/config/config.go
  • cli/src/internal/config/remove_platform_test.go
  • cli/src/internal/devportal/helpers.go
  • cli/src/internal/gateway/resources.go
  • cli/src/internal/project/artifact.go
  • cli/src/internal/project/config.go
  • cli/src/internal/project/scaffold.go
  • cli/src/utils/constants.go
  • cli/src/utils/flags.go
  • cli/src/utils/input.go
  • docs/cli/README.md
  • docs/cli/ai-workspace/README.md
  • docs/cli/devportal/README.md
  • docs/cli/end-to-end-workflow.md
💤 Files with no reviewable changes (3)
  • cli/src/cmd/devportal/commands_test.go
  • cli/src/cmd/apiproject/init_test.go
  • cli/src/cmd/apiproject/init.go
✅ Files skipped from review due to trivial changes (8)
  • cli/src/cmd/gateway/apply.go
  • .gitignore
  • cli/src/internal/config/remove_platform_test.go
  • cli/src/cmd/devportal/application/commands_test.go
  • cli/src/cmd/devportal/subscription/commands_test.go
  • docs/cli/README.md
  • cli/src/cmd/devportal/org/commands_test.go
  • docs/cli/devportal/README.md
🚧 Files skipped from review as they are similar to previous changes (75)
  • cli/src/cmd/devportal/root.go
  • cli/src/cmd/aiworkspace/llmprovider/root.go
  • cli/src/cmd/devportal/application/delete.go
  • cli/src/internal/aiworkspace/client_test.go
  • cli/src/cmd/devportal/apikey/get.go
  • cli/src/cmd/devportal/org/add.go
  • cli/src/cmd/devportal/subplan/delete.go
  • cli/src/cmd/devportal/apikey/commands_test.go
  • cli/src/cmd/devportal/apikey/generate.go
  • cli/src/cmd/devportal/apikey/revoke.go
  • cli/src/cmd/devportal/subplan/get.go
  • cli/src/cmd/devportal/apikey/regenerate.go
  • cli/src/cmd/aiworkspace/root.go
  • cli/src/cmd/aiworkspace/mcpproxy/get.go
  • cli/src/internal/aiworkspace/paths_test.go
  • cli/src/cmd/devportal/application/create.go
  • cli/src/cmd/devportal/org/edit.go
  • cli/src/cmd/devportal/application/get.go
  • cli/src/cmd/devportal/org/list.go
  • cli/src/cmd/devportal/restapi/edit.go
  • cli/src/cmd/aiworkspace/remove.go
  • cli/src/cmd/devportal/subplan/commands_test.go
  • cli/src/cmd/aiworkspace/current.go
  • cli/src/cmd/aiworkspace/mcpproxy/list.go
  • cli/src/cmd/aiworkspace/build_test.go
  • cli/src/cmd/devportal/subplan/publish.go
  • cli/src/cmd/devportal/restapi/get.go
  • cli/src/cmd/devportal/restapi/list.go
  • cli/src/cmd/aiworkspace/llmprovider/get.go
  • cli/src/cmd/aiworkspace/use.go
  • cli/src/cmd/root.go
  • cli/src/cmd/devportal/restapi/delete.go
  • cli/src/cmd/devportal/subscription/edit.go
  • cli/src/cmd/aiworkspace/llmproxy/root.go
  • cli/src/cmd/devportal/subscription/get.go
  • cli/src/cmd/aiworkspace/llmprovider/delete.go
  • cli/src/internal/project/config.go
  • cli/src/cmd/aiworkspace/mcpproxy/delete.go
  • docs/cli/end-to-end-workflow.md
  • cli/src/cmd/devportal/org/get.go
  • cli/src/internal/gateway/resources.go
  • cli/src/internal/devportal/helpers.go
  • cli/src/cmd/devportal/subplan/root.go
  • cli/src/cmd/devportal/gen_test.go
  • cli/src/utils/input.go
  • cli/src/cmd/aiworkspace/mcpproxy/root.go
  • cli/src/cmd/aiworkspace/llmprovider/list.go
  • cli/src/cmd/aiworkspace/llmproxy/get.go
  • cli/src/cmd/aiworkspace/llmproxy/delete.go
  • cli/src/cmd/project/root.go
  • cli/src/cmd/platform/root.go
  • cli/src/cmd/platform/remove.go
  • cli/src/internal/aiworkspace/print_test.go
  • cli/src/utils/flags.go
  • cli/src/cmd/project/init_test.go
  • cli/src/cmd/project/init.go
  • cli/src/cmd/devportal/subscription/delete.go
  • cli/src/internal/project/artifact.go
  • cli/src/cmd/devportal/restapi/commands_test.go
  • cli/src/cmd/devportal/restapi/publish.go
  • cli/src/cmd/devportal/gen.go
  • cli/src/cmd/devportal/application/update.go
  • cli/src/cmd/devportal/subplan/list.go
  • cli/src/cmd/aiworkspace/list.go
  • cli/src/cmd/devportal/subscription/create.go
  • cli/src/internal/aiworkspace/client.go
  • cli/src/internal/aiworkspace/helpers.go
  • cli/src/cmd/devportal/org/delete.go
  • cli/src/cmd/aiworkspace/add.go
  • cli/src/cmd/aiworkspace/apply.go
  • cli/src/internal/project/scaffold.go
  • cli/src/cmd/devportal/build_test.go
  • cli/src/internal/config/config.go
  • cli/src/cmd/aiworkspace/build.go
  • cli/src/cmd/devportal/build.go

@ShakyaPr
ShakyaPr merged commit 05214dc into wso2:main Jul 7, 2026
5 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants