@agentuity/cli 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/cmd/build/ast.d.ts +1 -1
  2. package/dist/cmd/build/ast.d.ts.map +1 -1
  3. package/dist/cmd/build/ast.js +103 -5
  4. package/dist/cmd/build/ast.js.map +1 -1
  5. package/dist/cmd/build/vite/config-loader.d.ts.map +1 -1
  6. package/dist/cmd/build/vite/config-loader.js +1 -1
  7. package/dist/cmd/build/vite/config-loader.js.map +1 -1
  8. package/dist/cmd/build/vite/index.d.ts +2 -0
  9. package/dist/cmd/build/vite/index.d.ts.map +1 -1
  10. package/dist/cmd/build/vite/index.js +2 -1
  11. package/dist/cmd/build/vite/index.js.map +1 -1
  12. package/dist/cmd/build/vite/metadata-generator.d.ts +4 -1
  13. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  14. package/dist/cmd/build/vite/metadata-generator.js +1 -0
  15. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  16. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  17. package/dist/cmd/build/vite/route-discovery.js +23 -1
  18. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  19. package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
  20. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  21. package/dist/cmd/build/vite/vite-builder.js +1 -0
  22. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  23. package/dist/cmd/build/vite-bundler.d.ts +2 -0
  24. package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
  25. package/dist/cmd/build/vite-bundler.js +2 -1
  26. package/dist/cmd/build/vite-bundler.js.map +1 -1
  27. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  28. package/dist/cmd/cloud/db/list.js +14 -1
  29. package/dist/cmd/cloud/db/list.js.map +1 -1
  30. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  31. package/dist/cmd/cloud/deploy.js +36 -22
  32. package/dist/cmd/cloud/deploy.js.map +1 -1
  33. package/dist/cmd/cloud/queue/list.d.ts.map +1 -1
  34. package/dist/cmd/cloud/queue/list.js +10 -0
  35. package/dist/cmd/cloud/queue/list.js.map +1 -1
  36. package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
  37. package/dist/cmd/cloud/sandbox/list.js +10 -0
  38. package/dist/cmd/cloud/sandbox/list.js.map +1 -1
  39. package/dist/cmd/cloud/sandbox/runtime/list.d.ts.map +1 -1
  40. package/dist/cmd/cloud/sandbox/runtime/list.js +10 -0
  41. package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
  42. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
  43. package/dist/cmd/cloud/sandbox/snapshot/list.js +10 -0
  44. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
  45. package/dist/cmd/cloud/session/get.js +12 -12
  46. package/dist/cmd/cloud/session/get.js.map +1 -1
  47. package/dist/cmd/cloud/session/list.d.ts.map +1 -1
  48. package/dist/cmd/cloud/session/list.js +14 -4
  49. package/dist/cmd/cloud/session/list.js.map +1 -1
  50. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  51. package/dist/cmd/cloud/storage/list.js +14 -1
  52. package/dist/cmd/cloud/storage/list.js.map +1 -1
  53. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  54. package/dist/cmd/cloud/stream/list.js +10 -0
  55. package/dist/cmd/cloud/stream/list.js.map +1 -1
  56. package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
  57. package/dist/cmd/cloud/thread/list.js +10 -0
  58. package/dist/cmd/cloud/thread/list.js.map +1 -1
  59. package/dist/cmd/project/domain/check.d.ts +2 -0
  60. package/dist/cmd/project/domain/check.d.ts.map +1 -0
  61. package/dist/cmd/project/domain/check.js +131 -0
  62. package/dist/cmd/project/domain/check.js.map +1 -0
  63. package/dist/cmd/project/domain/index.d.ts +2 -0
  64. package/dist/cmd/project/domain/index.d.ts.map +1 -0
  65. package/dist/cmd/project/domain/index.js +20 -0
  66. package/dist/cmd/project/domain/index.js.map +1 -0
  67. package/dist/cmd/project/hostname/get.d.ts +2 -0
  68. package/dist/cmd/project/hostname/get.d.ts.map +1 -0
  69. package/dist/cmd/project/hostname/get.js +50 -0
  70. package/dist/cmd/project/hostname/get.js.map +1 -0
  71. package/dist/cmd/project/hostname/index.d.ts +2 -0
  72. package/dist/cmd/project/hostname/index.d.ts.map +1 -0
  73. package/dist/cmd/project/hostname/index.js +18 -0
  74. package/dist/cmd/project/hostname/index.js.map +1 -0
  75. package/dist/cmd/project/hostname/set.d.ts +2 -0
  76. package/dist/cmd/project/hostname/set.d.ts.map +1 -0
  77. package/dist/cmd/project/hostname/set.js +100 -0
  78. package/dist/cmd/project/hostname/set.js.map +1 -0
  79. package/dist/cmd/project/index.d.ts.map +1 -1
  80. package/dist/cmd/project/index.js +12 -0
  81. package/dist/cmd/project/index.js.map +1 -1
  82. package/dist/index.d.ts +1 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +1 -1
  85. package/dist/index.js.map +1 -1
  86. package/dist/steps.d.ts +9 -0
  87. package/dist/steps.d.ts.map +1 -1
  88. package/dist/steps.js +131 -71
  89. package/dist/steps.js.map +1 -1
  90. package/dist/tui.d.ts +2 -2
  91. package/dist/tui.d.ts.map +1 -1
  92. package/dist/tui.js +6 -4
  93. package/dist/tui.js.map +1 -1
  94. package/package.json +6 -6
  95. package/src/cmd/build/ast.ts +141 -5
  96. package/src/cmd/build/vite/config-loader.ts +1 -3
  97. package/src/cmd/build/vite/index.ts +4 -0
  98. package/src/cmd/build/vite/metadata-generator.ts +5 -1
  99. package/src/cmd/build/vite/route-discovery.ts +34 -1
  100. package/src/cmd/build/vite/vite-builder.ts +3 -0
  101. package/src/cmd/build/vite-bundler.ts +4 -0
  102. package/src/cmd/cloud/db/list.ts +14 -1
  103. package/src/cmd/cloud/deploy.ts +46 -21
  104. package/src/cmd/cloud/queue/list.ts +10 -0
  105. package/src/cmd/cloud/sandbox/list.ts +10 -0
  106. package/src/cmd/cloud/sandbox/runtime/list.ts +10 -0
  107. package/src/cmd/cloud/sandbox/snapshot/list.ts +10 -0
  108. package/src/cmd/cloud/session/get.ts +12 -12
  109. package/src/cmd/cloud/session/list.ts +28 -18
  110. package/src/cmd/cloud/storage/list.ts +14 -1
  111. package/src/cmd/cloud/stream/list.ts +18 -8
  112. package/src/cmd/cloud/thread/list.ts +15 -5
  113. package/src/cmd/project/domain/check.ts +146 -0
  114. package/src/cmd/project/domain/index.ts +20 -0
  115. package/src/cmd/project/hostname/get.ts +54 -0
  116. package/src/cmd/project/hostname/index.ts +18 -0
  117. package/src/cmd/project/hostname/set.ts +123 -0
  118. package/src/cmd/project/index.ts +12 -0
  119. package/src/index.ts +1 -1
  120. package/src/steps.ts +139 -74
  121. package/src/tui.ts +6 -4
@@ -0,0 +1,146 @@
1
+ import { z } from 'zod';
2
+ import { createSubcommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { getCommand } from '../../../command-prefix';
5
+ import { loadProjectConfig } from '../../../config';
6
+ import { isJSONMode } from '../../../output';
7
+ import {
8
+ checkCustomDomainForDNS,
9
+ isSuccess,
10
+ isPending,
11
+ isMissing,
12
+ isMisconfigured,
13
+ isError,
14
+ } from '../../../domain';
15
+
16
+ export const checkSubcommand = createSubcommand({
17
+ name: 'check',
18
+ description: 'Check DNS configuration for custom domains',
19
+ tags: ['read-only', 'slow', 'requires-auth', 'requires-project'],
20
+ requires: { auth: true, project: true },
21
+ idempotent: true,
22
+ examples: [
23
+ {
24
+ command: getCommand('project domain check'),
25
+ description: 'Check all configured domains',
26
+ },
27
+ {
28
+ command: getCommand('project domain check --domain example.com'),
29
+ description: 'Check a specific domain',
30
+ },
31
+ ],
32
+ schema: {
33
+ options: z.object({
34
+ domain: z.string().optional().describe('Specific domain to check'),
35
+ }),
36
+ response: z.object({
37
+ domains: z.array(
38
+ z.object({
39
+ domain: z.string(),
40
+ recordType: z.string(),
41
+ target: z.string(),
42
+ status: z.string(),
43
+ success: z.boolean(),
44
+ })
45
+ ),
46
+ }),
47
+ },
48
+
49
+ async handler(ctx) {
50
+ const { opts, options, projectDir, config, project } = ctx;
51
+ const jsonMode = isJSONMode(options);
52
+
53
+ // Determine which domains to check
54
+ let domainsToCheck: string[];
55
+
56
+ if (opts?.domain) {
57
+ domainsToCheck = [opts.domain.toLowerCase().trim()];
58
+ } else {
59
+ const projectConfig = await loadProjectConfig(projectDir, config);
60
+ domainsToCheck = projectConfig.deployment?.domains ?? [];
61
+ }
62
+
63
+ if (domainsToCheck.length === 0) {
64
+ if (!jsonMode) {
65
+ tui.info('No custom domains configured for this project');
66
+ tui.info(`Use ${tui.bold(getCommand('project add domain <domain>'))} to add one`);
67
+ }
68
+ return { domains: [] };
69
+ }
70
+
71
+ const results = jsonMode
72
+ ? await checkCustomDomainForDNS(project.projectId, domainsToCheck, config)
73
+ : await tui.spinner({
74
+ message: `Checking DNS for ${domainsToCheck.length} ${tui.plural(domainsToCheck.length, 'domain', 'domains')}`,
75
+ clearOnSuccess: true,
76
+ callback: () => checkCustomDomainForDNS(project.projectId, domainsToCheck, config),
77
+ });
78
+
79
+ const domainResults = results.map((r) => {
80
+ let status: string;
81
+ let statusRaw: string;
82
+ let success = false;
83
+
84
+ if (isSuccess(r)) {
85
+ status = tui.colorSuccess(`${tui.ICONS.success} Configured`);
86
+ statusRaw = 'configured';
87
+ success = true;
88
+ } else if (isPending(r)) {
89
+ status = tui.colorWarning('⏳ Pending');
90
+ statusRaw = 'pending';
91
+ } else if (isMisconfigured(r)) {
92
+ status = tui.colorWarning(`${tui.ICONS.warning} ${r.misconfigured}`);
93
+ statusRaw = 'misconfigured';
94
+ } else if (isError(r)) {
95
+ status = tui.colorError(`${tui.ICONS.error} ${r.error}`);
96
+ statusRaw = 'error';
97
+ } else if (isMissing(r)) {
98
+ status = tui.colorError(`${tui.ICONS.error} Missing`);
99
+ statusRaw = 'missing';
100
+ } else {
101
+ status = tui.colorError(`${tui.ICONS.error} Unknown`);
102
+ statusRaw = 'unknown';
103
+ }
104
+
105
+ return {
106
+ domain: r.domain,
107
+ recordType: r.recordType,
108
+ target: r.target,
109
+ status,
110
+ statusRaw,
111
+ success,
112
+ };
113
+ });
114
+
115
+ if (!jsonMode) {
116
+ tui.newline();
117
+ for (const r of domainResults) {
118
+ console.log(` ${tui.colorInfo('Domain:')} ${tui.colorPrimary(r.domain)}`);
119
+ console.log(` ${tui.colorInfo('Type:')} ${tui.colorPrimary(r.recordType)}`);
120
+ console.log(` ${tui.colorInfo('Target:')} ${tui.colorPrimary(r.target)}`);
121
+ console.log(` ${tui.colorInfo('Status:')} ${r.status}`);
122
+ console.log();
123
+ }
124
+
125
+ const allGood = domainResults.every((r) => r.success);
126
+ if (allGood) {
127
+ tui.success('All domains are correctly configured');
128
+ } else {
129
+ const failCount = domainResults.filter((r) => !r.success).length;
130
+ tui.warning(
131
+ `${failCount} ${tui.plural(failCount, 'domain has', 'domains have')} DNS issues — add a CNAME record pointing to the target shown above`
132
+ );
133
+ }
134
+ }
135
+
136
+ return {
137
+ domains: domainResults.map((r) => ({
138
+ domain: r.domain,
139
+ recordType: r.recordType,
140
+ target: r.target,
141
+ status: r.statusRaw,
142
+ success: r.success,
143
+ })),
144
+ };
145
+ },
146
+ });
@@ -0,0 +1,20 @@
1
+ import { createCommand } from '../../../types';
2
+ import { checkSubcommand } from './check';
3
+ import { getCommand } from '../../../command-prefix';
4
+
5
+ export const domainCommand = createCommand({
6
+ name: 'domain',
7
+ description: 'Manage custom domains for the project',
8
+ tags: ['fast', 'requires-auth'],
9
+ examples: [
10
+ {
11
+ command: getCommand('project domain check'),
12
+ description: 'Check DNS for all custom domains',
13
+ },
14
+ {
15
+ command: getCommand('project domain check --domain example.com'),
16
+ description: 'Check DNS for a specific domain',
17
+ },
18
+ ],
19
+ subcommands: [checkSubcommand],
20
+ });
@@ -0,0 +1,54 @@
1
+ import { z } from 'zod';
2
+ import { createSubcommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { projectHostnameGet } from '@agentuity/server';
5
+ import { getCommand } from '../../../command-prefix';
6
+ import { isJSONMode } from '../../../output';
7
+
8
+ const HostnameGetResponseSchema = z.object({
9
+ hostname: z.string().nullable().describe('The vanity hostname'),
10
+ url: z.string().nullable().describe('The full URL'),
11
+ });
12
+
13
+ export const getSubcommand = createSubcommand({
14
+ name: 'get',
15
+ description: 'Show the current vanity hostname for the project',
16
+ tags: ['read-only', 'fast', 'requires-auth', 'requires-project'],
17
+ requires: { auth: true, apiClient: true, project: true },
18
+ idempotent: true,
19
+ examples: [
20
+ {
21
+ command: getCommand('project hostname get'),
22
+ description: 'Show current hostname',
23
+ },
24
+ ],
25
+ schema: {
26
+ response: HostnameGetResponseSchema,
27
+ },
28
+
29
+ async handler(ctx) {
30
+ const { apiClient, project, options } = ctx;
31
+ const jsonMode = isJSONMode(options);
32
+
33
+ const result = jsonMode
34
+ ? await projectHostnameGet(apiClient, { projectId: project.projectId })
35
+ : await tui.spinner('Fetching hostname', () => {
36
+ return projectHostnameGet(apiClient, { projectId: project.projectId });
37
+ });
38
+
39
+ if (!jsonMode) {
40
+ if (result.hostname) {
41
+ tui.success(`Hostname: ${tui.bold(result.hostname)}`);
42
+ tui.info(`URL: ${result.url}`);
43
+ } else {
44
+ tui.info('No vanity hostname set for this project');
45
+ tui.info(`Use ${tui.bold(getCommand('project hostname set <hostname>'))} to set one`);
46
+ }
47
+ }
48
+
49
+ return {
50
+ hostname: result.hostname,
51
+ url: result.url,
52
+ };
53
+ },
54
+ });
@@ -0,0 +1,18 @@
1
+ import { createCommand } from '../../../types';
2
+ import { getSubcommand } from './get';
3
+ import { setSubcommand } from './set';
4
+ import { getCommand } from '../../../command-prefix';
5
+
6
+ export const hostnameCommand = createCommand({
7
+ name: 'hostname',
8
+ description: 'Manage the project vanity hostname on agentuity.run',
9
+ tags: ['fast', 'requires-auth'],
10
+ examples: [
11
+ { command: getCommand('project hostname get'), description: 'Show current hostname' },
12
+ {
13
+ command: getCommand('project hostname set my-cool-api'),
14
+ description: 'Set a custom hostname',
15
+ },
16
+ ],
17
+ subcommands: [getSubcommand, setSubcommand],
18
+ });
@@ -0,0 +1,123 @@
1
+ import { z } from 'zod';
2
+ import { createSubcommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { projectHostnameSet } from '@agentuity/server';
5
+ import { getCommand } from '../../../command-prefix';
6
+ import { isJSONMode } from '../../../output';
7
+ import { ErrorCode } from '../../../errors';
8
+
9
+ // Client-side reserved names list (mirrors server-side list)
10
+ const RESERVED_NAMES = new Set([
11
+ 'app',
12
+ 'api',
13
+ 'catalyst',
14
+ 'pulse',
15
+ 'streams',
16
+ 'registry',
17
+ 'ion',
18
+ 'status',
19
+ 'admin',
20
+ 'www',
21
+ 'mail',
22
+ 'dns',
23
+ 'console',
24
+ 'dashboard',
25
+ 'docs',
26
+ 'help',
27
+ 'support',
28
+ 'billing',
29
+ 'test',
30
+ 'staging',
31
+ 'dev',
32
+ 'prod',
33
+ 'ns0',
34
+ 'ns1',
35
+ 'ns2',
36
+ ]);
37
+
38
+ const HostnameSetResponseSchema = z.object({
39
+ hostname: z.string().describe('The vanity hostname that was set'),
40
+ url: z.string().describe('The full URL'),
41
+ });
42
+
43
+ export const setSubcommand = createSubcommand({
44
+ name: 'set',
45
+ description: 'Set a custom vanity hostname for the project on agentuity.run',
46
+ tags: ['mutating', 'fast', 'requires-auth', 'requires-project'],
47
+ requires: { auth: true, apiClient: true, project: true },
48
+ examples: [
49
+ {
50
+ command: getCommand('project hostname set my-cool-api'),
51
+ description: 'Set a custom hostname',
52
+ },
53
+ ],
54
+ schema: {
55
+ args: z.object({
56
+ hostname: z.string().describe('the vanity hostname (e.g., my-cool-api)'),
57
+ }),
58
+ response: HostnameSetResponseSchema,
59
+ },
60
+
61
+ async handler(ctx) {
62
+ const { args, apiClient, project, options, logger } = ctx;
63
+ const jsonMode = isJSONMode(options);
64
+
65
+ const hostname = args.hostname.toLowerCase().trim();
66
+
67
+ // Client-side validation: DNS label regex
68
+ const hostnameRegex = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
69
+ if (!hostnameRegex.test(hostname)) {
70
+ logger.fatal(
71
+ 'Invalid hostname: must contain only lowercase letters, numbers, and hyphens, and must start and end with a letter or number',
72
+ ErrorCode.VALIDATION_FAILED
73
+ );
74
+ }
75
+
76
+ // Max 63 chars (DNS label limit)
77
+ if (hostname.length > 63) {
78
+ logger.fatal(
79
+ 'Invalid hostname: must be 63 characters or fewer',
80
+ ErrorCode.VALIDATION_FAILED
81
+ );
82
+ }
83
+
84
+ // Must not match reserved hash patterns
85
+ const reservedHashPattern = /^[dp][a-f0-9]{16}$/;
86
+ if (reservedHashPattern.test(hostname)) {
87
+ logger.fatal(
88
+ 'Invalid hostname: this pattern is reserved for internal use',
89
+ ErrorCode.VALIDATION_FAILED
90
+ );
91
+ }
92
+
93
+ // Must not be a reserved name
94
+ if (RESERVED_NAMES.has(hostname)) {
95
+ logger.fatal(
96
+ `Invalid hostname: "${hostname}" is a reserved name`,
97
+ ErrorCode.VALIDATION_FAILED
98
+ );
99
+ }
100
+
101
+ const result = jsonMode
102
+ ? await projectHostnameSet(apiClient, {
103
+ projectId: project.projectId,
104
+ hostname,
105
+ })
106
+ : await tui.spinner('Setting hostname', () => {
107
+ return projectHostnameSet(apiClient, {
108
+ projectId: project.projectId,
109
+ hostname,
110
+ });
111
+ });
112
+
113
+ if (!jsonMode) {
114
+ tui.success(`Hostname set: ${tui.bold(result.url)}`);
115
+ tui.info('Hostname will be active after next deployment');
116
+ }
117
+
118
+ return {
119
+ hostname: result.hostname,
120
+ url: result.url,
121
+ };
122
+ },
123
+ });
@@ -6,6 +6,8 @@ import { deleteSubcommand } from './delete';
6
6
  import { showSubcommand } from './show';
7
7
  import { authCommand } from './auth';
8
8
  import { addCommand } from './add';
9
+ import { hostnameCommand } from './hostname';
10
+ import { domainCommand } from './domain';
9
11
  import { getCommand } from '../../command-prefix';
10
12
 
11
13
  export const command = createCommand({
@@ -22,6 +24,14 @@ export const command = createCommand({
22
24
  command: getCommand('project add storage'),
23
25
  description: 'Link an existing storage bucket',
24
26
  },
27
+ {
28
+ command: getCommand('project hostname get'),
29
+ description: 'Show current vanity hostname',
30
+ },
31
+ {
32
+ command: getCommand('project domain check'),
33
+ description: 'Check DNS for custom domains',
34
+ },
25
35
  ],
26
36
  subcommands: [
27
37
  createProjectSubcommand,
@@ -31,5 +41,7 @@ export const command = createCommand({
31
41
  showSubcommand,
32
42
  authCommand,
33
43
  addCommand,
44
+ hostnameCommand,
45
+ domainCommand,
34
46
  ],
35
47
  });
package/src/index.ts CHANGED
@@ -102,7 +102,7 @@ export {
102
102
  type CommandHandler,
103
103
  type TableColumn,
104
104
  } from './repl';
105
- export { runSteps, stepSuccess, stepSkipped, stepError } from './steps';
105
+ export { runSteps, stepSuccess, stepSkipped, stepError, StepInterruptError } from './steps';
106
106
  export { playSound } from './sound';
107
107
  export {
108
108
  downloadWithProgress,