@agentuity/cli 0.1.16 → 0.1.18

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 (185) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +3 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cmd/build/ast.d.ts.map +1 -1
  5. package/dist/cmd/build/ast.js +68 -2
  6. package/dist/cmd/build/ast.js.map +1 -1
  7. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  8. package/dist/cmd/build/vite/registry-generator.js +112 -23
  9. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  10. package/dist/cmd/build/vite/route-discovery.d.ts +4 -0
  11. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  12. package/dist/cmd/build/vite/route-discovery.js +4 -0
  13. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  14. package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
  15. package/dist/cmd/cloud/env/delete.js +8 -2
  16. package/dist/cmd/cloud/env/delete.js.map +1 -1
  17. package/dist/cmd/cloud/env/get.d.ts.map +1 -1
  18. package/dist/cmd/cloud/env/get.js +4 -1
  19. package/dist/cmd/cloud/env/get.js.map +1 -1
  20. package/dist/cmd/cloud/env/import.d.ts.map +1 -1
  21. package/dist/cmd/cloud/env/import.js +5 -8
  22. package/dist/cmd/cloud/env/import.js.map +1 -1
  23. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  24. package/dist/cmd/cloud/env/list.js +11 -6
  25. package/dist/cmd/cloud/env/list.js.map +1 -1
  26. package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
  27. package/dist/cmd/cloud/env/pull.js.map +1 -1
  28. package/dist/cmd/cloud/env/push.d.ts.map +1 -1
  29. package/dist/cmd/cloud/env/push.js +1 -7
  30. package/dist/cmd/cloud/env/push.js.map +1 -1
  31. package/dist/cmd/cloud/env/set.d.ts.map +1 -1
  32. package/dist/cmd/cloud/env/set.js +4 -1
  33. package/dist/cmd/cloud/env/set.js.map +1 -1
  34. package/dist/cmd/cloud/index.d.ts.map +1 -1
  35. package/dist/cmd/cloud/index.js +2 -0
  36. package/dist/cmd/cloud/index.js.map +1 -1
  37. package/dist/cmd/cloud/queue/ack.d.ts +3 -0
  38. package/dist/cmd/cloud/queue/ack.d.ts.map +1 -0
  39. package/dist/cmd/cloud/queue/ack.js +45 -0
  40. package/dist/cmd/cloud/queue/ack.js.map +1 -0
  41. package/dist/cmd/cloud/queue/create.d.ts +3 -0
  42. package/dist/cmd/cloud/queue/create.d.ts.map +1 -0
  43. package/dist/cmd/cloud/queue/create.js +80 -0
  44. package/dist/cmd/cloud/queue/create.js.map +1 -0
  45. package/dist/cmd/cloud/queue/delete.d.ts +3 -0
  46. package/dist/cmd/cloud/queue/delete.d.ts.map +1 -0
  47. package/dist/cmd/cloud/queue/delete.js +50 -0
  48. package/dist/cmd/cloud/queue/delete.js.map +1 -0
  49. package/dist/cmd/cloud/queue/destinations.d.ts +3 -0
  50. package/dist/cmd/cloud/queue/destinations.d.ts.map +1 -0
  51. package/dist/cmd/cloud/queue/destinations.js +232 -0
  52. package/dist/cmd/cloud/queue/destinations.js.map +1 -0
  53. package/dist/cmd/cloud/queue/dlq.d.ts +3 -0
  54. package/dist/cmd/cloud/queue/dlq.d.ts.map +1 -0
  55. package/dist/cmd/cloud/queue/dlq.js +168 -0
  56. package/dist/cmd/cloud/queue/dlq.js.map +1 -0
  57. package/dist/cmd/cloud/queue/get.d.ts +3 -0
  58. package/dist/cmd/cloud/queue/get.d.ts.map +1 -0
  59. package/dist/cmd/cloud/queue/get.js +130 -0
  60. package/dist/cmd/cloud/queue/get.js.map +1 -0
  61. package/dist/cmd/cloud/queue/index.d.ts +3 -0
  62. package/dist/cmd/cloud/queue/index.d.ts.map +1 -0
  63. package/dist/cmd/cloud/queue/index.js +65 -0
  64. package/dist/cmd/cloud/queue/index.js.map +1 -0
  65. package/dist/cmd/cloud/queue/list.d.ts +3 -0
  66. package/dist/cmd/cloud/queue/list.d.ts.map +1 -0
  67. package/dist/cmd/cloud/queue/list.js +71 -0
  68. package/dist/cmd/cloud/queue/list.js.map +1 -0
  69. package/dist/cmd/cloud/queue/messages.d.ts +3 -0
  70. package/dist/cmd/cloud/queue/messages.d.ts.map +1 -0
  71. package/dist/cmd/cloud/queue/messages.js +137 -0
  72. package/dist/cmd/cloud/queue/messages.js.map +1 -0
  73. package/dist/cmd/cloud/queue/nack.d.ts +3 -0
  74. package/dist/cmd/cloud/queue/nack.d.ts.map +1 -0
  75. package/dist/cmd/cloud/queue/nack.js +45 -0
  76. package/dist/cmd/cloud/queue/nack.js.map +1 -0
  77. package/dist/cmd/cloud/queue/pause.d.ts +3 -0
  78. package/dist/cmd/cloud/queue/pause.d.ts.map +1 -0
  79. package/dist/cmd/cloud/queue/pause.js +36 -0
  80. package/dist/cmd/cloud/queue/pause.js.map +1 -0
  81. package/dist/cmd/cloud/queue/publish.d.ts +3 -0
  82. package/dist/cmd/cloud/queue/publish.d.ts.map +1 -0
  83. package/dist/cmd/cloud/queue/publish.js +76 -0
  84. package/dist/cmd/cloud/queue/publish.js.map +1 -0
  85. package/dist/cmd/cloud/queue/receive.d.ts +3 -0
  86. package/dist/cmd/cloud/queue/receive.d.ts.map +1 -0
  87. package/dist/cmd/cloud/queue/receive.js +67 -0
  88. package/dist/cmd/cloud/queue/receive.js.map +1 -0
  89. package/dist/cmd/cloud/queue/resume.d.ts +3 -0
  90. package/dist/cmd/cloud/queue/resume.d.ts.map +1 -0
  91. package/dist/cmd/cloud/queue/resume.js +35 -0
  92. package/dist/cmd/cloud/queue/resume.js.map +1 -0
  93. package/dist/cmd/cloud/queue/sources.d.ts +3 -0
  94. package/dist/cmd/cloud/queue/sources.d.ts.map +1 -0
  95. package/dist/cmd/cloud/queue/sources.js +290 -0
  96. package/dist/cmd/cloud/queue/sources.js.map +1 -0
  97. package/dist/cmd/cloud/queue/stats.d.ts +3 -0
  98. package/dist/cmd/cloud/queue/stats.d.ts.map +1 -0
  99. package/dist/cmd/cloud/queue/stats.js +239 -0
  100. package/dist/cmd/cloud/queue/stats.js.map +1 -0
  101. package/dist/cmd/cloud/queue/util.d.ts +26 -0
  102. package/dist/cmd/cloud/queue/util.d.ts.map +1 -0
  103. package/dist/cmd/cloud/queue/util.js +19 -0
  104. package/dist/cmd/cloud/queue/util.js.map +1 -0
  105. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
  106. package/dist/cmd/cloud/sandbox/snapshot/build.js +152 -30
  107. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  108. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
  109. package/dist/cmd/cloud/sandbox/snapshot/create.js +19 -7
  110. package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
  111. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
  112. package/dist/cmd/cloud/sandbox/snapshot/get.js +20 -0
  113. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
  114. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
  115. package/dist/cmd/cloud/sandbox/snapshot/list.js +4 -0
  116. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
  117. package/dist/cmd/cloud/vector/stats.d.ts.map +1 -1
  118. package/dist/cmd/cloud/vector/stats.js +8 -0
  119. package/dist/cmd/cloud/vector/stats.js.map +1 -1
  120. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  121. package/dist/cmd/project/template-flow.js.map +1 -1
  122. package/dist/env-util.d.ts +6 -1
  123. package/dist/env-util.d.ts.map +1 -1
  124. package/dist/env-util.js +16 -2
  125. package/dist/env-util.js.map +1 -1
  126. package/dist/errors.d.ts +4 -2
  127. package/dist/errors.d.ts.map +1 -1
  128. package/dist/errors.js +6 -0
  129. package/dist/errors.js.map +1 -1
  130. package/dist/schema-parser.d.ts.map +1 -1
  131. package/dist/schema-parser.js +2 -2
  132. package/dist/schema-parser.js.map +1 -1
  133. package/dist/tui/box.d.ts +8 -0
  134. package/dist/tui/box.d.ts.map +1 -1
  135. package/dist/tui/box.js +78 -0
  136. package/dist/tui/box.js.map +1 -1
  137. package/dist/tui.d.ts +11 -1
  138. package/dist/tui.d.ts.map +1 -1
  139. package/dist/tui.js +16 -8
  140. package/dist/tui.js.map +1 -1
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/types.js.map +1 -1
  143. package/package.json +6 -6
  144. package/src/cli.ts +5 -1
  145. package/src/cmd/build/ast.ts +88 -2
  146. package/src/cmd/build/vite/registry-generator.ts +120 -24
  147. package/src/cmd/build/vite/route-discovery.ts +16 -0
  148. package/src/cmd/cloud/env/delete.ts +18 -5
  149. package/src/cmd/cloud/env/get.ts +10 -3
  150. package/src/cmd/cloud/env/import.ts +10 -11
  151. package/src/cmd/cloud/env/list.ts +19 -9
  152. package/src/cmd/cloud/env/org-util.ts +1 -1
  153. package/src/cmd/cloud/env/pull.ts +9 -4
  154. package/src/cmd/cloud/env/push.ts +5 -9
  155. package/src/cmd/cloud/env/set.ts +10 -3
  156. package/src/cmd/cloud/index.ts +2 -0
  157. package/src/cmd/cloud/queue/ack.ts +50 -0
  158. package/src/cmd/cloud/queue/create.ts +91 -0
  159. package/src/cmd/cloud/queue/delete.ts +57 -0
  160. package/src/cmd/cloud/queue/destinations.ts +287 -0
  161. package/src/cmd/cloud/queue/dlq.ts +203 -0
  162. package/src/cmd/cloud/queue/get.ts +158 -0
  163. package/src/cmd/cloud/queue/index.ts +66 -0
  164. package/src/cmd/cloud/queue/list.ts +81 -0
  165. package/src/cmd/cloud/queue/messages.ts +160 -0
  166. package/src/cmd/cloud/queue/nack.ts +50 -0
  167. package/src/cmd/cloud/queue/pause.ts +41 -0
  168. package/src/cmd/cloud/queue/publish.ts +88 -0
  169. package/src/cmd/cloud/queue/receive.ts +76 -0
  170. package/src/cmd/cloud/queue/resume.ts +40 -0
  171. package/src/cmd/cloud/queue/sources.ts +352 -0
  172. package/src/cmd/cloud/queue/stats.ts +297 -0
  173. package/src/cmd/cloud/queue/util.ts +34 -0
  174. package/src/cmd/cloud/sandbox/snapshot/build.ts +186 -31
  175. package/src/cmd/cloud/sandbox/snapshot/create.ts +24 -7
  176. package/src/cmd/cloud/sandbox/snapshot/get.ts +20 -0
  177. package/src/cmd/cloud/sandbox/snapshot/list.ts +4 -0
  178. package/src/cmd/cloud/vector/stats.ts +9 -0
  179. package/src/cmd/project/template-flow.ts +1 -3
  180. package/src/env-util.ts +17 -2
  181. package/src/errors.ts +8 -0
  182. package/src/schema-parser.ts +6 -3
  183. package/src/tui/box.ts +104 -0
  184. package/src/tui.ts +28 -8
  185. package/src/types.ts +0 -1
@@ -4,7 +4,7 @@
4
4
  * Generates src/generated/registry.ts from discovered agents
5
5
  */
6
6
 
7
- import { join } from 'node:path';
7
+ import { join, dirname, relative, resolve } from 'node:path';
8
8
  import { writeFileSync, mkdirSync, existsSync, unlinkSync, readFileSync } from 'node:fs';
9
9
  import { stat } from 'node:fs/promises';
10
10
  import { StructuredError } from '@agentuity/core';
@@ -12,6 +12,45 @@ import { toCamelCase, toPascalCase } from '../../../utils/string';
12
12
  import type { AgentMetadata } from './agent-discovery';
13
13
  import type { RouteInfo } from './route-discovery';
14
14
 
15
+ /**
16
+ * Rebase a relative import path from the route file's location to the generated file's location.
17
+ * @param routeFilename - The route file path (e.g., 'api/example/route.ts' or './api/example/route.ts')
18
+ * @param schemaImportPath - The import path as written in the route file (e.g., '../../utils/schemas')
19
+ * @param srcDir - The src directory path
20
+ * @returns The rebased import path relative to src/generated/
21
+ */
22
+ function rebaseImportPath(routeFilename: string, schemaImportPath: string, srcDir: string): string {
23
+ // Non-relative imports (bare modules like '@company/schemas') should be used as-is
24
+ if (!schemaImportPath.startsWith('.') && !schemaImportPath.startsWith('/')) {
25
+ return schemaImportPath;
26
+ }
27
+
28
+ // Normalize route filename to get its directory relative to srcDir
29
+ let routeDir: string;
30
+ const cleanFilename = routeFilename.replace(/\\/g, '/');
31
+ if (cleanFilename.startsWith('./')) {
32
+ routeDir = dirname(join(srcDir, cleanFilename.substring(2)));
33
+ } else if (cleanFilename.startsWith('src/')) {
34
+ routeDir = dirname(join(srcDir, '..', cleanFilename));
35
+ } else {
36
+ routeDir = dirname(join(srcDir, cleanFilename));
37
+ }
38
+
39
+ // Resolve the schema module path from the route file's directory
40
+ const resolvedSchemaPath = resolve(routeDir, schemaImportPath);
41
+
42
+ // Calculate the relative path from src/generated/ to the resolved schema path
43
+ const generatedDir = join(srcDir, 'generated');
44
+ let rebasedPath = relative(generatedDir, resolvedSchemaPath).replace(/\\/g, '/');
45
+
46
+ // Ensure it starts with './' or '../'
47
+ if (!rebasedPath.startsWith('.') && !rebasedPath.startsWith('/')) {
48
+ rebasedPath = './' + rebasedPath;
49
+ }
50
+
51
+ return rebasedPath;
52
+ }
53
+
15
54
  const AgentIdentifierCollisionError = StructuredError('AgentIdentifierCollisionError');
16
55
 
17
56
  /**
@@ -617,6 +656,8 @@ export async function generateRouteRegistry(
617
656
  const imports: string[] = [];
618
657
  const agentImports = new Map<string, string>();
619
658
  const routeFileImports = new Map<string, Set<string>>();
659
+ // Track per-route which import path and schema name to use for alias lookup
660
+ const routeSchemaImportInfo = new Map<string, { importPath: string; schemaName: string }>();
620
661
 
621
662
  // Collect agent and schema imports from routes with validators or exported schemas
622
663
  allRoutes.forEach((route) => {
@@ -690,25 +731,76 @@ export async function generateRouteRegistry(
690
731
  }
691
732
 
692
733
  // Collect schema variable imports
693
- if (route.inputSchemaVariable || route.outputSchemaVariable) {
694
- const filename = route.filename.replace(/\\/g, '/');
695
- // Remove 'src/' prefix if present (routes.filename might be './api/...' or 'src/api/...')
696
- const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
697
- const withoutLeadingDot = withoutSrc.startsWith('./')
698
- ? withoutSrc.substring(2)
699
- : withoutSrc;
700
- const importPath = `../${withoutLeadingDot.replace(/\.ts$/, '')}`;
734
+ // If the schema is imported from another file, use that file's path (rebased)
735
+ // Otherwise fall back to the route file path (for locally defined schemas)
736
+ if (route.inputSchemaVariable) {
737
+ let importPath: string;
738
+ let schemaNameToImport: string;
739
+
740
+ if (route.inputSchemaImportPath) {
741
+ // Schema is imported - rebase the import path from route file to generated file
742
+ importPath = rebaseImportPath(route.filename, route.inputSchemaImportPath, srcDir);
743
+ // Use the actual exported name (handles aliased imports like `import { A as B }`)
744
+ schemaNameToImport =
745
+ route.inputSchemaImportedName === 'default'
746
+ ? route.inputSchemaVariable
747
+ : (route.inputSchemaImportedName ?? route.inputSchemaVariable);
748
+ } else {
749
+ // Schema is locally defined - import from the route file
750
+ const filename = route.filename.replace(/\\/g, '/');
751
+ const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
752
+ const withoutLeadingDot = withoutSrc.startsWith('./')
753
+ ? withoutSrc.substring(2)
754
+ : withoutSrc;
755
+ importPath = `../${withoutLeadingDot.replace(/\.ts$/, '')}`;
756
+ schemaNameToImport = route.inputSchemaVariable;
757
+ }
701
758
 
702
759
  if (!routeFileImports.has(importPath)) {
703
760
  routeFileImports.set(importPath, new Set());
704
761
  }
762
+ routeFileImports.get(importPath)!.add(schemaNameToImport);
705
763
 
706
- if (route.inputSchemaVariable) {
707
- routeFileImports.get(importPath)!.add(route.inputSchemaVariable);
764
+ // Store the resolved import info for later alias lookup
765
+ routeSchemaImportInfo.set(`input:${route.path}:${route.method}`, {
766
+ importPath,
767
+ schemaName: schemaNameToImport,
768
+ });
769
+ }
770
+
771
+ if (route.outputSchemaVariable) {
772
+ let importPath: string;
773
+ let schemaNameToImport: string;
774
+
775
+ if (route.outputSchemaImportPath) {
776
+ // Schema is imported - rebase the import path from route file to generated file
777
+ importPath = rebaseImportPath(route.filename, route.outputSchemaImportPath, srcDir);
778
+ // Use the actual exported name (handles aliased imports like `import { A as B }`)
779
+ schemaNameToImport =
780
+ route.outputSchemaImportedName === 'default'
781
+ ? route.outputSchemaVariable
782
+ : (route.outputSchemaImportedName ?? route.outputSchemaVariable);
783
+ } else {
784
+ // Schema is locally defined - import from the route file
785
+ const filename = route.filename.replace(/\\/g, '/');
786
+ const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
787
+ const withoutLeadingDot = withoutSrc.startsWith('./')
788
+ ? withoutSrc.substring(2)
789
+ : withoutSrc;
790
+ importPath = `../${withoutLeadingDot.replace(/\.ts$/, '')}`;
791
+ schemaNameToImport = route.outputSchemaVariable;
708
792
  }
709
- if (route.outputSchemaVariable) {
710
- routeFileImports.get(importPath)!.add(route.outputSchemaVariable);
793
+
794
+ if (!routeFileImports.has(importPath)) {
795
+ routeFileImports.set(importPath, new Set());
711
796
  }
797
+ routeFileImports.get(importPath)!.add(schemaNameToImport);
798
+
799
+ // Store the resolved import info for later alias lookup
800
+ routeSchemaImportInfo.set(`output:${route.path}:${route.method}`, {
801
+ importPath,
802
+ schemaName: schemaNameToImport,
803
+ });
712
804
  }
713
805
  });
714
806
 
@@ -774,18 +866,22 @@ export async function generateRouteRegistry(
774
866
  inputSchemaType = `typeof ${importName} extends { inputSchema?: infer I } ? I : never`;
775
867
  outputSchemaType = `typeof ${importName} extends { outputSchema?: infer O } ? O : never`;
776
868
  } else if (route.inputSchemaVariable || route.outputSchemaVariable) {
777
- // Get the aliased schema names for this route's file
778
- const filename = route.filename.replace(/\\/g, '/');
779
- const withoutSrc = filename.startsWith('src/') ? filename.substring(4) : filename;
780
- const withoutLeadingDot = withoutSrc.startsWith('./')
781
- ? withoutSrc.substring(2)
782
- : withoutSrc;
783
- const importPath = `../${withoutLeadingDot.replace(/\.ts$/, '')}`;
784
- const aliases = schemaImportAliases.get(importPath);
869
+ // Get the aliased schema names using the stored import info
870
+ // (which correctly handles schemas imported from shared files)
871
+ const inputInfo = routeSchemaImportInfo.get(`input:${route.path}:${route.method}`);
872
+ const outputInfo = routeSchemaImportInfo.get(`output:${route.path}:${route.method}`);
873
+
874
+ let inputAlias: string | undefined;
875
+ let outputAlias: string | undefined;
785
876
 
786
- const inputAlias = route.inputSchemaVariable && aliases?.get(route.inputSchemaVariable);
787
- const outputAlias =
788
- route.outputSchemaVariable && aliases?.get(route.outputSchemaVariable);
877
+ if (inputInfo) {
878
+ const aliases = schemaImportAliases.get(inputInfo.importPath);
879
+ inputAlias = aliases?.get(inputInfo.schemaName);
880
+ }
881
+ if (outputInfo) {
882
+ const aliases = schemaImportAliases.get(outputInfo.importPath);
883
+ outputAlias = aliases?.get(outputInfo.schemaName);
884
+ }
789
885
 
790
886
  inputType = inputAlias ? `InferInput<typeof ${inputAlias}>` : 'never';
791
887
  outputType = outputAlias ? `InferOutput<typeof ${outputAlias}>` : 'never';
@@ -37,6 +37,10 @@ export interface RouteInfo {
37
37
  agentDescription?: string;
38
38
  inputSchemaVariable?: string;
39
39
  outputSchemaVariable?: string;
40
+ inputSchemaImportPath?: string;
41
+ inputSchemaImportedName?: string;
42
+ outputSchemaImportPath?: string;
43
+ outputSchemaImportedName?: string;
40
44
  inputSchemaCode?: string;
41
45
  outputSchemaCode?: string;
42
46
  stream?: boolean;
@@ -119,6 +123,18 @@ export async function discoverRoutes(
119
123
  agentImportPath: route.config?.agentImportPath as string | undefined,
120
124
  inputSchemaVariable: route.config?.inputSchemaVariable as string | undefined,
121
125
  outputSchemaVariable: route.config?.outputSchemaVariable as string | undefined,
126
+ inputSchemaImportPath: route.config?.inputSchemaImportPath as
127
+ | string
128
+ | undefined,
129
+ inputSchemaImportedName: route.config?.inputSchemaImportedName as
130
+ | string
131
+ | undefined,
132
+ outputSchemaImportPath: route.config?.outputSchemaImportPath as
133
+ | string
134
+ | undefined,
135
+ outputSchemaImportedName: route.config?.outputSchemaImportedName as
136
+ | string
137
+ | undefined,
122
138
  stream:
123
139
  route.config?.stream !== undefined && route.config.stream !== null
124
140
  ? Boolean(route.config.stream)
@@ -16,7 +16,10 @@ import { resolveOrgId, isOrgScope } from './org-util';
16
16
  const EnvDeleteResponseSchema = z.object({
17
17
  success: z.boolean().describe('Whether the operation succeeded'),
18
18
  key: z.string().describe('Variable key that was deleted'),
19
- path: z.string().optional().describe('Local file path where variable was removed (project scope only)'),
19
+ path: z
20
+ .string()
21
+ .optional()
22
+ .describe('Local file path where variable was removed (project scope only)'),
20
23
  secret: z.boolean().describe('Whether a secret was deleted'),
21
24
  scope: z.enum(['project', 'org']).describe('The scope from which the variable was deleted'),
22
25
  });
@@ -30,7 +33,10 @@ export const deleteSubcommand = createSubcommand({
30
33
  examples: [
31
34
  { command: getCommand('env delete OLD_FEATURE_FLAG'), description: 'Delete variable' },
32
35
  { command: getCommand('env rm API_KEY'), description: 'Delete a secret' },
33
- { command: getCommand('env rm OPENAI_API_KEY --org'), description: 'Delete org-level secret' },
36
+ {
37
+ command: getCommand('env rm OPENAI_API_KEY --org'),
38
+ description: 'Delete org-level secret',
39
+ },
34
40
  ],
35
41
  requires: { auth: true, apiClient: true },
36
42
  optional: { project: true },
@@ -42,7 +48,9 @@ export const deleteSubcommand = createSubcommand({
42
48
  org: z
43
49
  .union([z.boolean(), z.string()])
44
50
  .optional()
45
- .describe('delete from organization level (use --org for default org, or --org <orgId> for specific org)'),
51
+ .describe(
52
+ 'delete from organization level (use --org for default org, or --org <orgId> for specific org)'
53
+ ),
46
54
  }),
47
55
  response: EnvDeleteResponseSchema,
48
56
  },
@@ -53,7 +61,9 @@ export const deleteSubcommand = createSubcommand({
53
61
 
54
62
  // Require project context if not using org scope
55
63
  if (!useOrgScope && !project) {
56
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
64
+ tui.fatal(
65
+ 'Project context required. Run from a project directory or use --org for organization scope.'
66
+ );
57
67
  }
58
68
 
59
69
  // Validate key doesn't start with reserved AGENTUITY_ prefix (except AGENTUITY_PUBLIC_)
@@ -76,7 +86,10 @@ export const deleteSubcommand = createSubcommand({
76
86
  const isEnv = orgData.env?.[args.key] !== undefined;
77
87
 
78
88
  if (!isSecret && !isEnv) {
79
- tui.fatal(`Variable '${args.key}' not found in organization`, ErrorCode.RESOURCE_NOT_FOUND);
89
+ tui.fatal(
90
+ `Variable '${args.key}' not found in organization`,
91
+ ErrorCode.RESOURCE_NOT_FOUND
92
+ );
80
93
  }
81
94
 
82
95
  // Delete from cloud
@@ -21,7 +21,10 @@ export const getSubcommand = createSubcommand({
21
21
  { command: getCommand('env get NODE_ENV'), description: 'Get environment variable' },
22
22
  { command: getCommand('env get API_KEY'), description: 'Get a secret value' },
23
23
  { command: getCommand('env get API_KEY --no-mask'), description: 'Show unmasked value' },
24
- { command: getCommand('env get OPENAI_API_KEY --org'), description: 'Get org-level variable' },
24
+ {
25
+ command: getCommand('env get OPENAI_API_KEY --org'),
26
+ description: 'Get org-level variable',
27
+ },
25
28
  ],
26
29
  requires: { auth: true, apiClient: true },
27
30
  optional: { project: true },
@@ -34,7 +37,9 @@ export const getSubcommand = createSubcommand({
34
37
  org: z
35
38
  .union([z.boolean(), z.string()])
36
39
  .optional()
37
- .describe('get from organization level (use --org for default org, or --org <orgId> for specific org)'),
40
+ .describe(
41
+ 'get from organization level (use --org for default org, or --org <orgId> for specific org)'
42
+ ),
38
43
  }),
39
44
  response: EnvGetResponseSchema,
40
45
  },
@@ -46,7 +51,9 @@ export const getSubcommand = createSubcommand({
46
51
 
47
52
  // Require project context if not using org scope
48
53
  if (!useOrgScope && !project) {
49
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
54
+ tui.fatal(
55
+ 'Project context required. Run from a project directory or use --org for organization scope.'
56
+ );
50
57
  }
51
58
 
52
59
  let value: string | undefined;
@@ -21,7 +21,10 @@ const EnvImportResponseSchema = z.object({
21
21
  envCount: z.number().describe('Number of env vars imported'),
22
22
  secretCount: z.number().describe('Number of secrets imported'),
23
23
  skipped: z.number().describe('Number of items skipped'),
24
- path: z.string().optional().describe('Local file path where variables were saved (project scope only)'),
24
+ path: z
25
+ .string()
26
+ .optional()
27
+ .describe('Local file path where variables were saved (project scope only)'),
25
28
  file: z.string().describe('Source file path'),
26
29
  scope: z.enum(['project', 'org']).describe('The scope where variables were imported'),
27
30
  });
@@ -29,13 +32,7 @@ const EnvImportResponseSchema = z.object({
29
32
  export const importSubcommand = createSubcommand({
30
33
  name: 'import',
31
34
  description: 'Import environment variables and secrets from a file to cloud and local .env',
32
- tags: [
33
- 'mutating',
34
- 'creates-resource',
35
- 'slow',
36
- 'api-intensive',
37
- 'requires-auth',
38
- ],
35
+ tags: ['mutating', 'creates-resource', 'slow', 'api-intensive', 'requires-auth'],
39
36
  examples: [
40
37
  {
41
38
  command: getCommand('cloud env import .env.backup'),
@@ -72,7 +69,9 @@ export const importSubcommand = createSubcommand({
72
69
 
73
70
  // Require project context if not using org scope
74
71
  if (!useOrgScope && !project) {
75
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
72
+ tui.fatal(
73
+ 'Project context required. Run from a project directory or use --org for organization scope.'
74
+ );
76
75
  }
77
76
 
78
77
  // Read the import file
@@ -87,7 +86,7 @@ export const importSubcommand = createSubcommand({
87
86
  secretCount: 0,
88
87
  skipped: 0,
89
88
  file: args.file,
90
- scope: useOrgScope ? 'org' as const : 'project' as const,
89
+ scope: useOrgScope ? ('org' as const) : ('project' as const),
91
90
  };
92
91
  }
93
92
 
@@ -103,7 +102,7 @@ export const importSubcommand = createSubcommand({
103
102
  secretCount: 0,
104
103
  skipped: Object.keys(importedVars).length,
105
104
  file: args.file,
106
- scope: useOrgScope ? 'org' as const : 'project' as const,
105
+ scope: useOrgScope ? ('org' as const) : ('project' as const),
107
106
  };
108
107
  }
109
108
 
@@ -23,7 +23,10 @@ export const listSubcommand = createSubcommand({
23
23
  { command: getCommand('env list --no-mask'), description: 'Show unmasked values' },
24
24
  { command: getCommand('env list --secrets'), description: 'List only secrets' },
25
25
  { command: getCommand('env list --env-only'), description: 'List only env vars' },
26
- { command: getCommand('env list --org'), description: 'List only organization-level variables' },
26
+ {
27
+ command: getCommand('env list --org'),
28
+ description: 'List only organization-level variables',
29
+ },
27
30
  ],
28
31
  requires: { auth: true, apiClient: true },
29
32
  optional: { project: true },
@@ -48,7 +51,9 @@ export const listSubcommand = createSubcommand({
48
51
  if (ctx.opts?.org) {
49
52
  return `/settings/organization/env`;
50
53
  }
51
- return ctx.project ? `/projects/${encodeURIComponent(ctx.project.projectId)}/settings` : undefined;
54
+ return ctx.project
55
+ ? `/projects/${encodeURIComponent(ctx.project.projectId)}/settings`
56
+ : undefined;
52
57
  },
53
58
 
54
59
  async handler(ctx) {
@@ -56,7 +61,8 @@ export const listSubcommand = createSubcommand({
56
61
  const useOrgScope = isOrgScope(opts?.org);
57
62
 
58
63
  // Build combined result with type info and scope
59
- const result: Record<string, { value: string; secret: boolean; scope: 'project' | 'org' }> = {};
64
+ const result: Record<string, { value: string; secret: boolean; scope: 'project' | 'org' }> =
65
+ {};
60
66
 
61
67
  // Filter based on options
62
68
  const showEnv = !opts?.secrets;
@@ -132,7 +138,9 @@ export const listSubcommand = createSubcommand({
132
138
  }
133
139
  }
134
140
  } else {
135
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
141
+ tui.fatal(
142
+ 'Project context required. Run from a project directory or use --org for organization scope.'
143
+ );
136
144
  }
137
145
 
138
146
  // Skip TUI output in JSON mode
@@ -142,10 +150,10 @@ export const listSubcommand = createSubcommand({
142
150
  } else {
143
151
  tui.newline();
144
152
 
145
- const projectCount = Object.values(result).filter(v => v.scope === 'project').length;
146
- const orgCount = Object.values(result).filter(v => v.scope === 'org').length;
147
- const secretCount = Object.values(result).filter(v => v.secret).length;
148
- const envCount = Object.values(result).filter(v => !v.secret).length;
153
+ const projectCount = Object.values(result).filter((v) => v.scope === 'project').length;
154
+ const orgCount = Object.values(result).filter((v) => v.scope === 'org').length;
155
+ const secretCount = Object.values(result).filter((v) => v.secret).length;
156
+ const envCount = Object.values(result).filter((v) => !v.secret).length;
149
157
 
150
158
  const parts: string[] = [];
151
159
  if (envCount > 0) parts.push(`${envCount} env`);
@@ -165,7 +173,9 @@ export const listSubcommand = createSubcommand({
165
173
  const displayValue = shouldMask && secret ? tui.maskSecret(value) : value;
166
174
  const typeIndicator = secret ? ' [secret]' : '';
167
175
  const scopeIndicator = !useOrgScope ? ` [${scope}]` : '';
168
- console.log(`${tui.bold(key)}=${displayValue}${tui.muted(typeIndicator + scopeIndicator)}`);
176
+ console.log(
177
+ `${tui.bold(key)}=${displayValue}${tui.muted(typeIndicator + scopeIndicator)}`
178
+ );
169
179
  }
170
180
  }
171
181
  }
@@ -5,7 +5,7 @@ import { listOrganizations } from '@agentuity/server';
5
5
 
6
6
  /**
7
7
  * Resolves the organization ID for org-scoped env operations.
8
- *
8
+ *
9
9
  * @param apiClient - The API client
10
10
  * @param config - The CLI config (may be null)
11
11
  * @param orgOption - The --org option value (true for default/prompt, or explicit org ID)
@@ -61,16 +61,21 @@ export const pullSubcommand = createSubcommand({
61
61
  // Organization scope
62
62
  const orgId = await resolveOrgId(apiClient, config, opts!.org!);
63
63
 
64
- const orgData = await tui.spinner('Pulling environment variables from organization', () => {
65
- return orgEnvGet(apiClient, { id: orgId, mask: false });
66
- });
64
+ const orgData = await tui.spinner(
65
+ 'Pulling environment variables from organization',
66
+ () => {
67
+ return orgEnvGet(apiClient, { id: orgId, mask: false });
68
+ }
69
+ );
67
70
 
68
71
  cloudEnv = { ...orgData.env, ...orgData.secrets };
69
72
  scope = 'org';
70
73
  } else {
71
74
  // Project scope
72
75
  if (!project) {
73
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
76
+ tui.fatal(
77
+ 'Project context required. Run from a project directory or use --org for organization scope.'
78
+ );
74
79
  }
75
80
 
76
81
  const projectData = await tui.spinner('Pulling environment variables from cloud', () => {
@@ -24,13 +24,7 @@ const EnvPushResponseSchema = z.object({
24
24
  export const pushSubcommand = createSubcommand({
25
25
  name: 'push',
26
26
  description: 'Push environment variables and secrets from local .env file to cloud',
27
- tags: [
28
- 'mutating',
29
- 'updates-resource',
30
- 'slow',
31
- 'api-intensive',
32
- 'requires-auth',
33
- ],
27
+ tags: ['mutating', 'updates-resource', 'slow', 'api-intensive', 'requires-auth'],
34
28
  idempotent: true,
35
29
  examples: [
36
30
  { command: getCommand('env push'), description: 'Push all variables to cloud (project)' },
@@ -73,7 +67,7 @@ export const pushSubcommand = createSubcommand({
73
67
  envCount: 0,
74
68
  secretCount: 0,
75
69
  source: envFilePath,
76
- scope: useOrgScope ? 'org' as const : 'project' as const,
70
+ scope: useOrgScope ? ('org' as const) : ('project' as const),
77
71
  };
78
72
  }
79
73
 
@@ -123,7 +117,9 @@ export const pushSubcommand = createSubcommand({
123
117
  } else {
124
118
  // Project scope (existing behavior)
125
119
  if (!project) {
126
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
120
+ tui.fatal(
121
+ 'Project context required. Run from a project directory or use --org for organization scope.'
122
+ );
127
123
  }
128
124
 
129
125
  await tui.spinner('Pushing variables to cloud', () => {
@@ -18,7 +18,10 @@ import { resolveOrgId, isOrgScope } from './org-util';
18
18
  const EnvSetResponseSchema = z.object({
19
19
  success: z.boolean().describe('Whether the operation succeeded'),
20
20
  key: z.string().describe('Environment variable key'),
21
- path: z.string().optional().describe('Local file path where env var was saved (project scope only)'),
21
+ path: z
22
+ .string()
23
+ .optional()
24
+ .describe('Local file path where env var was saved (project scope only)'),
22
25
  secret: z.boolean().describe('Whether the value was stored as a secret'),
23
26
  scope: z.enum(['project', 'org']).describe('The scope where the variable was set'),
24
27
  });
@@ -58,7 +61,9 @@ export const setSubcommand = createSubcommand({
58
61
  org: z
59
62
  .union([z.boolean(), z.string()])
60
63
  .optional()
61
- .describe('set at organization level (use --org for default org, or --org <orgId> for specific org)'),
64
+ .describe(
65
+ 'set at organization level (use --org for default org, or --org <orgId> for specific org)'
66
+ ),
62
67
  }),
63
68
  response: EnvSetResponseSchema,
64
69
  },
@@ -69,7 +74,9 @@ export const setSubcommand = createSubcommand({
69
74
 
70
75
  // Require project context if not using org scope
71
76
  if (!useOrgScope && !project) {
72
- tui.fatal('Project context required. Run from a project directory or use --org for organization scope.');
77
+ tui.fatal(
78
+ 'Project context required. Run from a project directory or use --org for organization scope.'
79
+ );
73
80
  }
74
81
 
75
82
  let isSecret = opts?.secret ?? false;
@@ -9,6 +9,7 @@ import { sshSubcommand } from './ssh';
9
9
  import { scpSubcommand } from './scp';
10
10
  import { deploymentCommand } from './deployment';
11
11
  import keyvalueCommand from './keyvalue';
12
+ import queueCommand from './queue';
12
13
  import { agentCommand } from './agent';
13
14
  import envCommand from './env';
14
15
  import apikeyCommand from './apikey';
@@ -30,6 +31,7 @@ export const command = createCommand({
30
31
  subcommands: [
31
32
  apikeyCommand,
32
33
  keyvalueCommand,
34
+ queueCommand,
33
35
  agentCommand,
34
36
  streamCommand,
35
37
  vectorCommand,
@@ -0,0 +1,50 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createQueueAPIClient, getQueueApiOptions } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+ import { ackMessage } from '@agentuity/server';
7
+
8
+ const AckResponseSchema = z.object({
9
+ success: z.boolean(),
10
+ queue_name: z.string(),
11
+ message_id: z.string(),
12
+ });
13
+
14
+ export const ackSubcommand = createCommand({
15
+ name: 'ack',
16
+ description: 'Acknowledge a message (mark as processed)',
17
+ tags: ['mutating', 'updates-resource', 'requires-auth'],
18
+ requires: { auth: true },
19
+ examples: [
20
+ {
21
+ command: getCommand('cloud queue ack my-queue msg-123'),
22
+ description: 'Acknowledge a message',
23
+ },
24
+ ],
25
+ schema: {
26
+ args: z.object({
27
+ queue_name: z.string().min(1).describe('Queue name'),
28
+ message_id: z.string().min(1).describe('Message ID'),
29
+ }),
30
+ response: AckResponseSchema,
31
+ },
32
+
33
+ async handler(ctx) {
34
+ const { args, options } = ctx;
35
+ const client = await createQueueAPIClient(ctx);
36
+ await ackMessage(client, args.queue_name, args.message_id, getQueueApiOptions(ctx));
37
+
38
+ if (!options.json) {
39
+ tui.success(`Acknowledged message: ${args.message_id}`);
40
+ }
41
+
42
+ return {
43
+ success: true,
44
+ queue_name: args.queue_name,
45
+ message_id: args.message_id,
46
+ };
47
+ },
48
+ });
49
+
50
+ export default ackSubcommand;