Skip to content

feat(cli): add cloud redis show command#108

Merged
robindiddams merged 4 commits intomainfrom
feat/cloud-redis-get
Dec 11, 2025
Merged

feat(cli): add cloud redis show command#108
robindiddams merged 4 commits intomainfrom
feat/cloud-redis-get

Conversation

@robindiddams
Copy link
Copy Markdown
Contributor

@robindiddams robindiddams commented Dec 11, 2025

Summary

Add new cloud redis get command to fetch the Redis connection URL for an organization.

New Commands

# Get Redis connection URL (credentials masked by default)
agentuity cloud redis get

# Get Redis URL with credentials visible
agentuity cloud redis get --show-credentials

# Get Redis URL as JSON output
agentuity --json cloud redis get

Example Output

Redis URL: redis://user:****@redis.example.com:6379/5

Changes

  • packages/server/src/api/region/resources.ts - Added redis field to resource list response schema
  • packages/cli/src/cmd/cloud/redis/index.ts - New redis command group
  • packages/cli/src/cmd/cloud/redis/get.ts - Get subcommand implementation
  • packages/cli/src/cmd/cloud/index.ts - Register redis command

Related

Requires catalyst changes to expose Redis in the /resource/2025-03-17/:orgId/:region endpoint response.

Summary by CodeRabbit

  • New Features
    • Added Redis resource management to the cloud command group.
    • Added cloud redis show (alias: info) to retrieve the Redis connection URL.
    • Support for --show-credentials to reveal full credentials and --json output for programmatic use.
    • Connection URLs masked by default for security.
    • Server API now includes an optional Redis URL field in resource listings.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

Adds a new cloud Redis CLI command group with a show/info subcommand to retrieve a Redis connection URL, registers the command in the cloud entrypoint, exposes a plain-text output helper, and extends the server Region resources response schema with an optional redis.url field.

Changes

Cohort / File(s) Summary
Cloud CLI entry
packages/cli/src/cmd/cloud/index.ts
Import and register redisCommand in the cloud command group's subcommands.
Redis CLI command
packages/cli/src/cmd/cloud/redis/index.ts, packages/cli/src/cmd/cloud/redis/get.ts
Add redis command group and show (alias info) subcommand that lists Redis resources and returns a connection URL; supports --show-credentials and --json; requires auth/org/region and is idempotent.
Server API schema
packages/server/src/api/region/resources.ts
Extend ResourceListResponse with an optional redis object containing url: string.
CLI UI helper
packages/cli/src/tui.ts
Add output(message: string): void helper to print plain text without formatting.
Manifest
package.json
Package manifest included/updated in diff.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check CLI output masking and interaction between --show-credentials and --json in get.ts.
  • Verify command registration, tags, examples, and requirement flags in redis/index.ts and cloud/index.ts.
  • Validate backward compatibility and JSON schema changes for ResourceListResponse in resources.ts.
  • Ensure tui.output usage is consistent and doesn't bypass intended UI formatting elsewhere.

Poem

🐰
I hopped through lines with careful cheer,
Planted Redis roots both far and near.
A URL peeks, masked or shown,
In cloud commands now it’s known.
🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a new 'cloud redis show' command to the CLI, which matches the primary objective of exposing Redis connection URL functionality.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/cloud-redis-get

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

@robindiddams robindiddams changed the title feat(cli): add cloud redis get command feat(cli): add cloud redis show command Dec 11, 2025
Copy link
Copy Markdown
Contributor

@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: 2

🧹 Nitpick comments (3)
packages/cli/src/cmd/cloud/redis/index.ts (2)

2-2: Naming inconsistency between file and export.

The file is named get.ts (and PR title mentions "get command"), but it exports showSubcommand with the command name "show". This creates confusion between the filename, PR objectives, and the actual implementation.

Consider either:

  • Renaming the subcommand to "get" with "show" as an alias: name: 'get', aliases: ['show', 'info']
  • Or renaming the file to show.ts to match the subcommand name

</comment_end>


8-8: Tag inconsistency between parent and child commands.

The parent redis command is tagged as 'slow', but the showSubcommand (the only subcommand) is tagged as 'fast'. These contradictory tags may confuse users about the expected performance characteristics of the command.

Consider aligning the tags - either both should be 'fast' (if the API call is typically quick) or both should be 'slow' (if network latency is expected).

</comment_end>

packages/cli/src/cmd/cloud/redis/get.ts (1)

47-53: Consider adding error handling for the API call.

The listResources call can throw a RegionResponseError (per the implementation in packages/server/src/api/region/resources.ts), but there's no try-catch block here. While the error may be handled by the command framework, wrapping this in explicit error handling could provide a more user-friendly error message.

Consider adding error handling:

-	const resources = await tui.spinner({
-		message: `Fetching Redis for ${orgId} in ${region}`,
-		clearOnSuccess: true,
-		callback: async () => {
-			return listResources(catalystClient, orgId, region);
-		},
-	});
+	let resources;
+	try {
+		resources = await tui.spinner({
+			message: `Fetching Redis for ${orgId} in ${region}`,
+			clearOnSuccess: true,
+			callback: async () => {
+				return listResources(catalystClient, orgId, region);
+			},
+		});
+	} catch (error) {
+		logger.fatal('Failed to fetch Redis resources');
+		throw error;
+	}

</comment_end>

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f142a8 and 549a3d2.

📒 Files selected for processing (2)
  • packages/cli/src/cmd/cloud/redis/get.ts (1 hunks)
  • packages/cli/src/cmd/cloud/redis/index.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier using tabs (width 3), single quotes, semicolons, and 100 character line width

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/**/*.{ts,tsx}: Always use InferInput and InferOutput from @agentuity/core for schema type inference, not StandardSchemaV1.InferOutput
StructuredError properties are directly on the error instance, not under a .data property

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use the StructuredError from @agentuity/core to create Error classes with structured data properties

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/cli/src/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/**/*.ts: All code must be TypeScript with strict mode enabled
Use tui.* helpers for formatted output without log prefixes (success, error, warning, info, bold, muted, link)
Use ctx.logger for standard logging with prefixes (fatal, error, info, debug) instead of console methods
Use logger.fatal(message) for error logging with exit code 1 instead of logger.error() + process.exit(1)
Use Bun-provided APIs (e.g., Bun.file(f).exists()) instead of legacy Node.js APIs (e.g., existsSync(f))
All I/O operations must use async/await pattern

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/cli/src/cmd/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/cmd/**/*.ts: Use commander.js for command parsing and routing following commander.js best practices
Always define interfaces for command options (never use any)
Subcommands must be defined in separate files and exported as SubcommandDefinition
Commands must validate their own config requirements

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/cli/src/cmd/**/index.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

Each command must be a directory in src/cmd/ with index.ts file exporting CommandDefinition

Files:

  • packages/cli/src/cmd/cloud/redis/index.ts
🧬 Code graph analysis (2)
packages/cli/src/cmd/cloud/redis/index.ts (1)
packages/cli/src/cmd/cloud/redis/get.ts (1)
  • showSubcommand (12-72)
packages/cli/src/cmd/cloud/redis/get.ts (2)
packages/cli/src/config.ts (1)
  • getCatalystAPIClient (628-632)
packages/server/src/api/region/resources.ts (1)
  • listResources (43-57)
⏰ 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). (2)
  • GitHub Check: Build
  • GitHub Check: Cloud Deployment Tests
🔇 Additional comments (1)
packages/cli/src/cmd/cloud/redis/get.ts (1)

1-10: LGTM!

The imports and schema definition look correct. The Zod 4 usage with z.string().optional() is appropriate for the optional URL field.

</comment_end>

Comment on lines +12 to +14
export const showSubcommand = createSubcommand({
name: 'show',
aliases: ['info'],
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.

⚠️ Potential issue | 🟡 Minor

Command name inconsistency with PR objectives and filename.

The PR is titled "feat(cli): add cloud redis get command" and this file is named get.ts, but the subcommand is implemented as name: 'show' with aliases ['info'] — "get" appears nowhere in the command definition.

This creates confusion between:

  • PR title/objectives: "cloud redis get"
  • Filename: get.ts
  • Actual command: "cloud redis show"

Apply this diff to align with the PR title and filename:

 export const showSubcommand = createSubcommand({
-	name: 'show',
-	aliases: ['info'],
+	name: 'get',
+	aliases: ['show', 'info'],
 	description: 'Show Redis connection URL',

Then rename the export and file references accordingly, or clarify the intended command name in the PR description.
</comment_end>

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const showSubcommand = createSubcommand({
name: 'show',
aliases: ['info'],
export const showSubcommand = createSubcommand({
name: 'get',
aliases: ['show', 'info'],
🤖 Prompt for AI Agents
In packages/cli/src/cmd/cloud/redis/get.ts around lines 12 to 14, the subcommand
is declared as name: 'show' with aliases ['info'] which conflicts with the PR
title and filename that indicate this should be a "get" command; change the
subcommand name to 'get' (and adjust or remove aliases as desired), rename the
exported constant showSubcommand to getSubcommand, and update any imports/usage
sites or the filename references so the symbol, file name, and PR intent are
consistent.

Comment thread packages/cli/src/cmd/cloud/redis/get.ts
Copy link
Copy Markdown
Contributor

@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: 1

♻️ Duplicate comments (1)
packages/cli/src/cmd/cloud/redis/get.ts (1)

12-14: Command name inconsistency remains unresolved.

The mismatch between the PR title ("add cloud redis get command"), filename (get.ts), and the actual command name (show with alias info) creates confusion. This issue was flagged in previous reviews.

The past review suggestion to rename to name: 'get' with aliases: ['show', 'info'] would resolve this inconsistency.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 549a3d2 and 6c7cfb7.

📒 Files selected for processing (2)
  • packages/cli/src/cmd/cloud/redis/get.ts (1 hunks)
  • packages/cli/src/tui.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Format code with Prettier using tabs (width 3), single quotes, semicolons, and 100 character line width

Files:

  • packages/cli/src/tui.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/**/*.{ts,tsx}: Always use InferInput and InferOutput from @agentuity/core for schema type inference, not StandardSchemaV1.InferOutput
StructuredError properties are directly on the error instance, not under a .data property

Files:

  • packages/cli/src/tui.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use the StructuredError from @agentuity/core to create Error classes with structured data properties

Files:

  • packages/cli/src/tui.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/cli/src/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/**/*.ts: All code must be TypeScript with strict mode enabled
Use tui.* helpers for formatted output without log prefixes (success, error, warning, info, bold, muted, link)
Use ctx.logger for standard logging with prefixes (fatal, error, info, debug) instead of console methods
Use logger.fatal(message) for error logging with exit code 1 instead of logger.error() + process.exit(1)
Use Bun-provided APIs (e.g., Bun.file(f).exists()) instead of legacy Node.js APIs (e.g., existsSync(f))
All I/O operations must use async/await pattern

Files:

  • packages/cli/src/tui.ts
  • packages/cli/src/cmd/cloud/redis/get.ts
packages/cli/src/cmd/**/*.ts

📄 CodeRabbit inference engine (packages/cli/AGENTS.md)

packages/cli/src/cmd/**/*.ts: Use commander.js for command parsing and routing following commander.js best practices
Always define interfaces for command options (never use any)
Subcommands must be defined in separate files and exported as SubcommandDefinition
Commands must validate their own config requirements

Files:

  • packages/cli/src/cmd/cloud/redis/get.ts
🧬 Code graph analysis (1)
packages/cli/src/cmd/cloud/redis/get.ts (2)
packages/cli/src/config.ts (1)
  • getCatalystAPIClient (628-632)
packages/server/src/api/region/resources.ts (1)
  • listResources (43-57)
⏰ 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). (3)
  • GitHub Check: Build
  • GitHub Check: Cloud Deployment Tests
  • GitHub Check: SDK Integration Test Suite
🔇 Additional comments (5)
packages/cli/src/tui.ts (1)

349-355: LGTM! Provides the correct path for plain command output.

The new output() helper fills an important gap by providing a clean interface for primary command output without prefixes or formatting. This addresses the need identified in past reviews where commands needed plain output (e.g., the Redis get command at line 65 in get.ts).

packages/cli/src/cmd/cloud/redis/get.ts (4)

8-10: Well-defined response schema.

The schema correctly uses Zod 4 syntax with an optional URL field and descriptive documentation. This aligns with the command's behavior of returning undefined when Redis is not provisioned.


55-58: Good handling of the no-Redis case.

The check correctly uses tui.info() per coding guidelines, provides a clear user message, and returns a schema-compliant response with url: undefined.


63-66: Output formatting correctly uses TUI helpers.

The code now uses tui.output() (introduced in packages/cli/src/tui.ts) instead of direct console.log(), which resolves the concern raised in previous reviews. The credential masking logic is sound: credentials are masked in terminal output by default but shown in JSON mode or when --show-credentials is specified.

Note: This addresses the previous review comment about avoiding console.log() for command output.


68-70: Return value correctly provides unmasked URL.

The handler appropriately returns the raw Redis URL (output masking is handled separately for display), which matches the response schema and ensures JSON output contains the full URL.

Comment on lines +47 to +53
const resources = await tui.spinner({
message: `Fetching Redis for ${orgId} in ${region}`,
clearOnSuccess: true,
callback: async () => {
return listResources(catalystClient, orgId, region);
},
});
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.

⚠️ Potential issue | 🟠 Major

Add error handling for the resource fetch.

The listResources call can throw RegionResponseError (per packages/server/src/api/region/resources.ts), but there's no try-catch block to handle failures gracefully. Users will see a raw error instead of a friendly message.

Consider wrapping the spinner callback in a try-catch:

 const resources = await tui.spinner({
 	message: `Fetching Redis for ${orgId} in ${region}`,
 	clearOnSuccess: true,
 	callback: async () => {
-		return listResources(catalystClient, orgId, region);
+		try {
+			return listResources(catalystClient, orgId, region);
+		} catch (err) {
+			if (err instanceof Error) {
+				logger.fatal(`Failed to fetch resources: ${err.message}`);
+			}
+			throw err;
+		}
 	},
 });
🤖 Prompt for AI Agents
In packages/cli/src/cmd/cloud/redis/get.ts around lines 47–53, the spinner
callback calls listResources which can throw RegionResponseError and currently
has no error handling; wrap the callback body in a try-catch, catch the
RegionResponseError (import the error type from its module where it's exported),
call tui.error with a friendly message including orgId and region, and return an
empty array or null so the spinner resolves gracefully; rethrow or propagate
non-RegionResponseError exceptions after logging so unexpected errors still
surface.

@robindiddams robindiddams merged commit c1ffe85 into main Dec 11, 2025
5 checks passed
@robindiddams robindiddams deleted the feat/cloud-redis-get branch December 11, 2025 19:45
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.

1 participant