Conversation
📝 WalkthroughWalkthroughAdds a new Changes
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (3)packages/cli/src/cmd/**/*.ts📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Files:
packages/cli/src/**/*.ts📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-12-21T00:31:41.858ZApplied to files:
🧬 Code graph analysis (1)packages/cli/src/cmd/project/add/domain.ts (3)
⏰ 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). (9)
🔇 Additional comments (6)
✏️ Tip: You can disable this entire section by setting Comment |
📦 Canary Packages Publishedversion: PackagesInstallAdd to your {
"dependencies": {
"@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-cli-1.0.1-19a4db5.tgz",
"@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-runtime-1.0.1-19a4db5.tgz",
"@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-postgres-1.0.1-19a4db5.tgz",
"@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-server-1.0.1-19a4db5.tgz",
"@agentuity/auth": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-auth-1.0.1-19a4db5.tgz",
"@agentuity/react": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-react-1.0.1-19a4db5.tgz",
"@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-core-1.0.1-19a4db5.tgz",
"@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-schema-1.0.1-19a4db5.tgz",
"@agentuity/frontend": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-frontend-1.0.1-19a4db5.tgz",
"@agentuity/workbench": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-workbench-1.0.1-19a4db5.tgz",
"@agentuity/evals": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-evals-1.0.1-19a4db5.tgz",
"@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-opencode-1.0.1-19a4db5.tgz",
"@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-drizzle-1.0.1-19a4db5.tgz"
}
}Or install directly: bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-cli-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-runtime-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-postgres-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-server-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-auth-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-react-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-core-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-schema-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-frontend-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-workbench-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-evals-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-opencode-1.0.1-19a4db5.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/1.0.1-19a4db5/agentuity-drizzle-1.0.1-19a4db5.tgz |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/project/add/domain.ts`:
- Line 125: The handler destructures ctx without opts, causing a type-cast on
options to read skipValidation; update the handler's parameter destructuring to
include opts (alongside args, options, projectDir, config) and replace the
conditional that uses (options as { skipValidation?: boolean }).skipValidation
with a direct check of opts?.skipValidation so the skipValidation flag from
ctx.opts is used (refer to the handler function and the opts symbol and
skipValidation flag).
🧹 Nitpick comments (2)
packages/cli/src/cmd/project/add/domain.ts (2)
49-66: Dry-run returnssuccess: falsewhich may be misleading.The dry-run mode returns
success: false, but this could confuse consumers expecting a preview of what would succeed. Consider returningsuccess: trueto indicate the operation would succeed, or add adryRun: truefield to distinguish.
134-138: Consider handling case whereresultsarray is empty.If
checkCustomDomainForDNSreturns an empty array,results[0]would beundefined, and the code would silently skip validation. Whileresult && !isSuccess(result)handlesundefined, it might be worth explicitly handling this edge case with a warning or error.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
🧰 Additional context used
📓 Path-based instructions (3)
packages/cli/src/cmd/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
packages/cli/src/cmd/**/*.ts: Usetui.*helpers for formatted output instead of raw console logs
Usectx.loggerfor logging; calllogger.fatal()to log and exit with code 1
Files:
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
packages/cli/src/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Prettier formatter with tabs (width 3), single quotes, and semicolons for TypeScript files
Use TypeScript strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
🧬 Code graph analysis (1)
packages/cli/src/cmd/project/add/index.ts (1)
packages/cli/src/cmd/project/add/domain.ts (1)
domainSubcommand(11-193)
⏰ 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). (9)
- GitHub Check: Queue CLI Tests
- GitHub Check: Template Integration Tests
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Pack & Upload
- GitHub Check: Sandbox CLI Tests
- GitHub Check: Cloud Deployment Tests
- GitHub Check: Build
- GitHub Check: SDK Integration Test Suite
🔇 Additional comments (9)
packages/cli/src/cmd/project/add/domain.ts (6)
1-10: LGTM!Imports are well-organized and all utilities are appropriately imported from internal modules.
11-47: LGTM!The subcommand definition is well-structured with clear metadata, appropriate tags, and comprehensive examples including dry-run usage. Schema definitions using zod are properly typed.
85-110: LGTM!The interactive prompt handling is well-implemented with proper TTY checks, domain validation regex, and stdin cleanup. The validation logic correctly handles empty input and invalid domain formats.
112-122: LGTM!Good idempotency handling - returning success with existing domains when the domain is already configured prevents duplicate entries and provides a good user experience.
169-191: LGTM!The config update and success handling are well-implemented. The spread operator correctly preserves existing deployment settings while updating domains, and appropriate user feedback is provided.
143-145: Usetui.output()instead of rawconsole.log.These lines use raw
console.logwhich violates the coding guidelines. The tui module providestui.output()for formatted output.As per coding guidelines:
packages/cli/src/cmd/**/*.ts: Usetui.*helpers for formatted output instead of raw console logs.🔧 Proposed fix
- console.log(` ${tui.colorInfo('Domain:')} ${tui.colorPrimary(result.domain)}`); - console.log(` ${tui.colorInfo('Type:')} ${tui.colorPrimary(result.recordType)}`); - console.log(` ${tui.colorInfo('Target:')} ${tui.colorPrimary(result.target)}`); + tui.output(` ${tui.colorInfo('Domain:')} ${tui.colorPrimary(result.domain)}`); + tui.output(` ${tui.colorInfo('Type:')} ${tui.colorPrimary(result.recordType)}`); + tui.output(` ${tui.colorInfo('Target:')} ${tui.colorPrimary(result.target)}`);Likely an incorrect or invalid review comment.
packages/cli/src/cmd/project/add/index.ts (3)
3-3: LGTM!Import follows the existing pattern for other subcommands.
21-24: LGTM!Examples are well-structured and consistent with the existing database and storage examples, providing both interactive and direct usage patterns.
Also applies to: 33-36
38-38: LGTM!The subcommand is correctly integrated in alphabetical order alongside the existing subcommands.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Add a new subcommand to configure custom domains for existing projects. - Supports interactive mode and direct domain argument - Validates DNS configuration (CNAME to Agentuity proxy) - Prompts to proceed if DNS isn't configured yet - Includes --skip-validation flag to skip DNS check - Adds 'dns' as an alias for the command - Updates agentuity.json deployment.domains on success Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019c2d4d-a962-7709-91c0-dfb685f6ca02
df7a67f to
86d9c9c
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/cli/src/cmd/project/add/domain.ts`:
- Around line 49-50: The handler function currently uses tui.fatal for fatal
exit paths; destructure logger from ctx (e.g., const { args, opts, options,
projectDir, config, logger } = ctx) and replace all tui.fatal(...) calls inside
the async handler and any other fatal calls in this file (including the
occurrences referenced around the handler like the ones at the other exits) with
logger.fatal(...) so the CLI uses ctx.logger for logging and exiting as required
by the guidelines.
- Around line 71-110: The direct-argument branch (args.domain) currently only
normalizes the input but skips format validation; reuse the same domainRegex and
validation logic used in the interactive prompt to validate args.domain after
lowercasing/trimming, and if it fails call tui.fatal with a descriptive message
(e.g., "Please enter a valid domain name") and an appropriate ErrorCode so
invalid domains are rejected before persisting (refer to args.domain, domain,
domainRegex, and the tui.fatal usage in the interactive path).
- Around line 140-146: Replace the raw console.log calls with the CLI formatting
helpers (use tui.write or the appropriate tui.* output helper) so output goes
through the tui renderer; specifically, in the block that currently calls
console.log(` ${tui.colorInfo('Domain:')}
${tui.colorPrimary(result.domain)}`), console.log(` ${tui.colorInfo('Type:')}
${tui.colorPrimary(result.recordType)}`) and console.log(`
${tui.colorInfo('Target:')} ${tui.colorPrimary(result.target)}`) change each to
tui.write(...) (or the project’s standard tui output function) and keep the same
string interpolation and color helpers (tui.colorInfo, tui.colorPrimary) so
formatting remains identical while using tui.newline() and tui.warning() as
before.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/cli/src/cmd/project/add/domain.tspackages/cli/src/cmd/project/add/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/cli/src/cmd/project/add/index.ts
🧰 Additional context used
📓 Path-based instructions (3)
packages/cli/src/cmd/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
packages/cli/src/cmd/**/*.ts: Usetui.*helpers for formatted output instead of raw console logs
Usectx.loggerfor logging; calllogger.fatal()to log and exit with code 1
Files:
packages/cli/src/cmd/project/add/domain.ts
packages/cli/src/**/*.ts
📄 CodeRabbit inference engine (packages/cli/AGENTS.md)
Use
Bun.file(f).exists()instead ofexistsSync(f)for file existence checks
Files:
packages/cli/src/cmd/project/add/domain.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Prettier formatter with tabs (width 3), single quotes, and semicolons for TypeScript files
Use TypeScript strict mode with ESNext target and bundler moduleResolution
UseStructuredErrorfrom@agentuity/corefor error handling
Files:
packages/cli/src/cmd/project/add/domain.ts
🧠 Learnings (1)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.
Applied to files:
packages/cli/src/cmd/project/add/domain.ts
🧬 Code graph analysis (1)
packages/cli/src/cmd/project/add/domain.ts (3)
packages/cli/src/config.ts (2)
loadProjectConfig(558-592)updateProjectConfig(658-690)packages/cli/src/tui.ts (1)
prompt(1744-1765)packages/cli/src/domain.ts (3)
isSuccess(54-56)isError(46-48)isMisconfigured(38-40)
⏰ 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). (7)
- GitHub Check: Framework Integration Tests (TanStack & Next.js)
- GitHub Check: Playwright E2E Smoke Test
- GitHub Check: Sandbox CLI Tests
- GitHub Check: Pack & Upload
- GitHub Check: Cloud Deployment Tests
- GitHub Check: SDK Integration Test Suite
- GitHub Check: Build
🔇 Additional comments (4)
packages/cli/src/cmd/project/add/domain.ts (4)
11-47: LGTM: subcommand metadata & schema are solid.
Clear naming, aliases, tags, and schema definitions align well with the CLI conventions.
52-66: Dry-run behavior looks good.
Nice preview messaging and JSON-aware output gating.
112-122: LGTM: idempotent existing-domain handling.
Returning the current domains list is clean and avoids unnecessary writes.
169-191: LGTM: config update + success output.
Clear update path and success messaging; nice JSON gating.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| let domain: string; | ||
|
|
||
| if (args.domain) { | ||
| domain = args.domain.toLowerCase().trim(); | ||
| } else { | ||
| const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY; | ||
| if (isHeadless) { | ||
| tui.fatal( | ||
| 'Domain name is required in non-interactive mode. Usage: ' + | ||
| tui.bold(getCommand('project add domain <domain>')), | ||
| ErrorCode.MISSING_ARGUMENT | ||
| ); | ||
| } | ||
|
|
||
| const prompt = createPrompt(); | ||
| const entered = await prompt.text({ | ||
| message: 'Enter the custom domain', | ||
| hint: 'e.g., api.example.com', | ||
| validate: (value) => { | ||
| if (!value || !value.trim()) { | ||
| return 'Domain name is required'; | ||
| } | ||
| const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$/; | ||
| if (!domainRegex.test(value.trim())) { | ||
| return 'Please enter a valid domain name'; | ||
| } | ||
| return true; | ||
| }, | ||
| }); | ||
|
|
||
| if (process.stdin.isTTY) { | ||
| process.stdin.pause(); | ||
| } | ||
|
|
||
| if (!entered) { | ||
| tui.fatal('Operation cancelled', ErrorCode.USER_CANCELLED); | ||
| } | ||
|
|
||
| domain = entered.toLowerCase().trim(); | ||
| } |
There was a problem hiding this comment.
Validate direct CLI argument domains before persisting.
The direct-argument path normalizes the domain but skips format validation, so an invalid domain can be written to agentuity.json, especially with --skip-validation. Consider applying the same regex validation to both entry paths.
🛠️ Suggested fix
- let domain: string;
+ const domainRegex =
+ /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$/;
+ let domain: string;
if (args.domain) {
domain = args.domain.toLowerCase().trim();
} else {
const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
if (isHeadless) {
tui.fatal(
'Domain name is required in non-interactive mode. Usage: ' +
tui.bold(getCommand('project add domain <domain>')),
ErrorCode.MISSING_ARGUMENT
);
}
const prompt = createPrompt();
const entered = await prompt.text({
message: 'Enter the custom domain',
hint: 'e.g., api.example.com',
validate: (value) => {
if (!value || !value.trim()) {
return 'Domain name is required';
}
- const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$/;
if (!domainRegex.test(value.trim())) {
return 'Please enter a valid domain name';
}
return true;
},
});
@@
domain = entered.toLowerCase().trim();
}
+
+ if (!domainRegex.test(domain)) {
+ tui.fatal('Please enter a valid domain name', ErrorCode.VALIDATION_FAILED);
+ }🤖 Prompt for AI Agents
In `@packages/cli/src/cmd/project/add/domain.ts` around lines 71 - 110, The
direct-argument branch (args.domain) currently only normalizes the input but
skips format validation; reuse the same domainRegex and validation logic used in
the interactive prompt to validate args.domain after lowercasing/trimming, and
if it fails call tui.fatal with a descriptive message (e.g., "Please enter a
valid domain name") and an appropriate ErrorCode so invalid domains are rejected
before persisting (refer to args.domain, domain, domainRegex, and the tui.fatal
usage in the interactive path).
Amp-Thread-ID: https://ampcode.com/threads/T-019c2d4d-a962-7709-91c0-dfb685f6ca02 Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019c2d4d-a962-7709-91c0-dfb685f6ca02 Co-authored-by: Amp <amp@ampcode.com>
| name: 'domain', | ||
| aliases: ['dns'], | ||
| description: 'Add a custom domain to the current project', | ||
| tags: ['mutating', 'fast', 'requires-auth', 'requires-project'], |
There was a problem hiding this comment.
| tags: ['mutating', 'fast', 'requires-auth', 'requires-project'], | |
| tags: ['mutating', 'slow', 'requires-auth', 'requires-project'], |
| ], | ||
| schema: { | ||
| args: z.object({ | ||
| domain: z.string().optional().describe('Domain name to add'), |
There was a problem hiding this comment.
shouldn't this be required? whats the use case to add add without a domain?
| domain = args.domain.toLowerCase().trim(); | ||
| } else { | ||
| const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY; | ||
| if (isHeadless) { |
| tui.warning(`Domain "${domain}" is already configured for this project`); | ||
| } | ||
| return { | ||
| success: true, |
| logger.fatal('Operation cancelled', ErrorCode.USER_CANCELLED); | ||
| } | ||
|
|
||
| domain = entered.toLowerCase().trim(); |
| tui.newline(); | ||
| } | ||
|
|
||
| const prompt = createPrompt(); |
Summary
Add a new
project add domainsubcommand to configure custom domains for existing Agentuity projects.Changes
domain.tssubcommand underproject addagentuity project add domain example.com)--skip-validationflag to skip DNS check (domain validated on deploy)dnsalias for the commandagentuity.jsondeployment.domainsarray on successUsage
Testing
bun bin/cli.ts project add --helpshows the new domain subcommandbun bin/cli.ts project add domain --helpshows command optionsSummary by CodeRabbit