@agentuity/cli 0.0.53 → 0.0.54

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 (133) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +66 -8
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cmd/auth/ssh/add.d.ts.map +1 -1
  5. package/dist/cmd/auth/ssh/add.js +28 -13
  6. package/dist/cmd/auth/ssh/add.js.map +1 -1
  7. package/dist/cmd/auth/ssh/delete.d.ts.map +1 -1
  8. package/dist/cmd/auth/ssh/delete.js +28 -18
  9. package/dist/cmd/auth/ssh/delete.js.map +1 -1
  10. package/dist/cmd/auth/ssh/list.d.ts.map +1 -1
  11. package/dist/cmd/auth/ssh/list.js +5 -6
  12. package/dist/cmd/auth/ssh/list.js.map +1 -1
  13. package/dist/cmd/build/ast.d.ts +34 -0
  14. package/dist/cmd/build/ast.d.ts.map +1 -1
  15. package/dist/cmd/build/ast.js +159 -0
  16. package/dist/cmd/build/ast.js.map +1 -1
  17. package/dist/cmd/build/bundler.d.ts +2 -1
  18. package/dist/cmd/build/bundler.d.ts.map +1 -1
  19. package/dist/cmd/build/bundler.js +77 -16
  20. package/dist/cmd/build/bundler.js.map +1 -1
  21. package/dist/cmd/build/plugin.d.ts.map +1 -1
  22. package/dist/cmd/build/plugin.js +74 -4
  23. package/dist/cmd/build/plugin.js.map +1 -1
  24. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  25. package/dist/cmd/cloud/deployment/list.js +28 -23
  26. package/dist/cmd/cloud/deployment/list.js.map +1 -1
  27. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
  28. package/dist/cmd/cloud/deployment/show.js +50 -47
  29. package/dist/cmd/cloud/deployment/show.js.map +1 -1
  30. package/dist/cmd/cloud/env/get.d.ts.map +1 -1
  31. package/dist/cmd/cloud/env/get.js +16 -14
  32. package/dist/cmd/cloud/env/get.js.map +1 -1
  33. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  34. package/dist/cmd/cloud/env/list.js +24 -20
  35. package/dist/cmd/cloud/env/list.js.map +1 -1
  36. package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
  37. package/dist/cmd/cloud/keyvalue/get.js +18 -16
  38. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  39. package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
  40. package/dist/cmd/cloud/keyvalue/keys.js +11 -11
  41. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  42. package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
  43. package/dist/cmd/cloud/keyvalue/list-namespaces.js +11 -7
  44. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  45. package/dist/cmd/cloud/keyvalue/search.d.ts.map +1 -1
  46. package/dist/cmd/cloud/keyvalue/search.js +16 -17
  47. package/dist/cmd/cloud/keyvalue/search.js.map +1 -1
  48. package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
  49. package/dist/cmd/cloud/keyvalue/stats.js +38 -23
  50. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  51. package/dist/cmd/cloud/objectstore/get.d.ts.map +1 -1
  52. package/dist/cmd/cloud/objectstore/get.js +17 -15
  53. package/dist/cmd/cloud/objectstore/get.js.map +1 -1
  54. package/dist/cmd/cloud/objectstore/list-buckets.d.ts.map +1 -1
  55. package/dist/cmd/cloud/objectstore/list-buckets.js +12 -8
  56. package/dist/cmd/cloud/objectstore/list-buckets.js.map +1 -1
  57. package/dist/cmd/cloud/objectstore/list-keys.d.ts.map +1 -1
  58. package/dist/cmd/cloud/objectstore/list-keys.js +13 -10
  59. package/dist/cmd/cloud/objectstore/list-keys.js.map +1 -1
  60. package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
  61. package/dist/cmd/cloud/resource/list.js +38 -27
  62. package/dist/cmd/cloud/resource/list.js.map +1 -1
  63. package/dist/cmd/cloud/secret/get.d.ts.map +1 -1
  64. package/dist/cmd/cloud/secret/get.js +17 -15
  65. package/dist/cmd/cloud/secret/get.js.map +1 -1
  66. package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
  67. package/dist/cmd/cloud/secret/list.js +24 -20
  68. package/dist/cmd/cloud/secret/list.js.map +1 -1
  69. package/dist/cmd/cloud/session/logs.d.ts.map +1 -1
  70. package/dist/cmd/cloud/session/logs.js +18 -15
  71. package/dist/cmd/cloud/session/logs.js.map +1 -1
  72. package/dist/cmd/dev/agents.d.ts.map +1 -1
  73. package/dist/cmd/dev/agents.js +55 -41
  74. package/dist/cmd/dev/agents.js.map +1 -1
  75. package/dist/cmd/dev/index.d.ts.map +1 -1
  76. package/dist/cmd/dev/index.js +2 -0
  77. package/dist/cmd/dev/index.js.map +1 -1
  78. package/dist/cmd/profile/create.js +1 -1
  79. package/dist/cmd/profile/create.js.map +1 -1
  80. package/dist/cmd/profile/delete.d.ts.map +1 -1
  81. package/dist/cmd/profile/delete.js +1 -1
  82. package/dist/cmd/profile/delete.js.map +1 -1
  83. package/dist/cmd/profile/list.d.ts.map +1 -1
  84. package/dist/cmd/profile/list.js +29 -11
  85. package/dist/cmd/profile/list.js.map +1 -1
  86. package/dist/cmd/profile/show.d.ts.map +1 -1
  87. package/dist/cmd/profile/show.js +7 -10
  88. package/dist/cmd/profile/show.js.map +1 -1
  89. package/dist/cmd/project/delete.js +1 -1
  90. package/dist/cmd/project/delete.js.map +1 -1
  91. package/dist/cmd/version/index.d.ts.map +1 -1
  92. package/dist/cmd/version/index.js +1 -1
  93. package/dist/cmd/version/index.js.map +1 -1
  94. package/dist/tui.d.ts.map +1 -1
  95. package/dist/tui.js +3 -1
  96. package/dist/tui.js.map +1 -1
  97. package/dist/types.d.ts +32 -8
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js.map +1 -1
  100. package/package.json +3 -3
  101. package/src/cli.ts +109 -8
  102. package/src/cmd/auth/ssh/add.ts +37 -17
  103. package/src/cmd/auth/ssh/delete.ts +36 -23
  104. package/src/cmd/auth/ssh/list.ts +8 -6
  105. package/src/cmd/build/ast.ts +203 -0
  106. package/src/cmd/build/bundler.ts +81 -15
  107. package/src/cmd/build/plugin.ts +92 -4
  108. package/src/cmd/cloud/deployment/list.ts +30 -26
  109. package/src/cmd/cloud/deployment/show.ts +47 -42
  110. package/src/cmd/cloud/env/get.ts +14 -12
  111. package/src/cmd/cloud/env/list.ts +24 -22
  112. package/src/cmd/cloud/keyvalue/get.ts +19 -14
  113. package/src/cmd/cloud/keyvalue/keys.ts +10 -12
  114. package/src/cmd/cloud/keyvalue/list-namespaces.ts +10 -8
  115. package/src/cmd/cloud/keyvalue/search.ts +14 -17
  116. package/src/cmd/cloud/keyvalue/stats.ts +52 -28
  117. package/src/cmd/cloud/objectstore/get.ts +18 -13
  118. package/src/cmd/cloud/objectstore/list-buckets.ts +11 -9
  119. package/src/cmd/cloud/objectstore/list-keys.ts +12 -11
  120. package/src/cmd/cloud/resource/list.ts +33 -23
  121. package/src/cmd/cloud/secret/get.ts +15 -13
  122. package/src/cmd/cloud/secret/list.ts +24 -22
  123. package/src/cmd/cloud/session/logs.ts +18 -17
  124. package/src/cmd/dev/agents.ts +70 -50
  125. package/src/cmd/dev/index.ts +2 -0
  126. package/src/cmd/profile/create.ts +3 -3
  127. package/src/cmd/profile/delete.ts +5 -2
  128. package/src/cmd/profile/list.ts +31 -11
  129. package/src/cmd/profile/show.ts +15 -12
  130. package/src/cmd/project/delete.ts +1 -1
  131. package/src/cmd/version/index.ts +5 -1
  132. package/src/tui.ts +3 -1
  133. package/src/types.ts +32 -10
@@ -37,28 +37,25 @@ export const searchSubcommand = createCommand({
37
37
  },
38
38
 
39
39
  async handler(ctx) {
40
- const { args } = ctx;
40
+ const { args, options } = ctx;
41
41
  const kv = await createStorageAdapter(ctx);
42
42
 
43
43
  const results = await kv.search(args.name, args.keyword);
44
44
  const keys = Object.keys(results);
45
45
 
46
- if (keys.length === 0) {
47
- tui.info(`No keys found matching ${tui.bold(args.keyword)} in ${tui.bold(args.name)}`);
48
- return {
49
- namespace: args.name,
50
- keyword: args.keyword,
51
- results: [],
52
- };
53
- }
54
-
55
- tui.info(`Found ${keys.length} key(s) matching ${tui.bold(args.keyword)}:`);
56
- for (const key of keys) {
57
- const item = results[key];
58
- if (!item) continue;
59
- const sizeMB = (item.size / (1024 * 1024)).toFixed(2);
60
- const date = new Date(item.updated_at).toLocaleString();
61
- tui.info(` ${tui.bold(key)}: ${sizeMB} MB, ${item.contentType}, updated ${date}`);
46
+ if (!options.json) {
47
+ if (keys.length === 0) {
48
+ tui.info(`No keys found matching ${tui.bold(args.keyword)} in ${tui.bold(args.name)}`);
49
+ } else {
50
+ tui.info(`Found ${keys.length} key(s) matching ${tui.bold(args.keyword)}:`);
51
+ for (const key of keys) {
52
+ const item = results[key];
53
+ if (!item) continue;
54
+ const sizeMB = (item.size / (1024 * 1024)).toFixed(2);
55
+ const date = new Date(item.updated_at).toLocaleString();
56
+ tui.info(` ${tui.bold(key)}: ${sizeMB} MB, ${item.contentType}, updated ${date}`);
57
+ }
58
+ }
62
59
  }
63
60
 
64
61
  return {
@@ -42,53 +42,77 @@ export const statsSubcommand = createCommand({
42
42
  },
43
43
 
44
44
  async handler(ctx) {
45
- const { args } = ctx;
45
+ const { args, options } = ctx;
46
46
  const kv = await createStorageAdapter(ctx);
47
47
 
48
48
  if (args.name) {
49
49
  const stats = await kv.getStats(args.name);
50
- tui.info(`Statistics for ${tui.bold(args.name)}:`);
51
- tui.info(` Keys: ${stats.count}`);
52
- const sizeDisplay =
53
- stats.sum < 1024 * 1024
54
- ? `${stats.sum.toLocaleString()} bytes`
55
- : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
56
- tui.info(` Total size: ${sizeDisplay} (raw: ${stats.sum})`);
57
- if (stats.createdAt) {
58
- tui.info(` Created: ${new Date(stats.createdAt).toLocaleString()}`);
59
- }
60
- if (stats.lastUsedAt) {
61
- tui.info(` Last used: ${new Date(stats.lastUsedAt).toLocaleString()}`);
50
+
51
+ if (!options.json) {
52
+ tui.info(`Statistics for ${tui.bold(args.name)}:`);
53
+ tui.info(` Keys: ${stats.count}`);
54
+ const sizeDisplay =
55
+ stats.sum < 1024 * 1024
56
+ ? `${stats.sum.toLocaleString()} bytes`
57
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
58
+ tui.info(` Total size: ${sizeDisplay} (raw: ${stats.sum})`);
59
+ if (stats.createdAt) {
60
+ tui.info(` Created: ${new Date(stats.createdAt).toLocaleString()}`);
61
+ }
62
+ if (stats.lastUsedAt) {
63
+ tui.info(` Last used: ${new Date(stats.lastUsedAt).toLocaleString()}`);
64
+ }
62
65
  }
63
66
 
64
67
  return {
65
68
  namespace: args.name,
66
69
  count: stats.count,
67
70
  sum: stats.sum,
68
- createdAt: stats.createdAt,
69
- lastUsedAt: stats.lastUsedAt,
71
+ createdAt: stats.createdAt ? String(stats.createdAt) : undefined,
72
+ lastUsedAt: stats.lastUsedAt ? String(stats.lastUsedAt) : undefined,
70
73
  };
71
74
  } else {
72
75
  const allStats = await kv.getAllStats();
73
76
  const entries = Object.entries(allStats);
74
77
 
75
- if (entries.length === 0) {
76
- tui.info('No namespaces found');
77
- return {};
78
+ if (!options.json) {
79
+ if (entries.length === 0) {
80
+ tui.info('No namespaces found');
81
+ } else {
82
+ tui.info(
83
+ `Found ${entries.length} ${tui.plural(entries.length, 'namespace', 'namespaces')}:`
84
+ );
85
+ for (const [name, stats] of entries) {
86
+ const sizeDisplay =
87
+ stats.sum < 1024 * 1024
88
+ ? `${stats.sum.toLocaleString()} bytes`
89
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
90
+ tui.arrow(
91
+ `${tui.bold(name.padEnd(15, ' '))}: ${stats.count} keys, ${sizeDisplay}`
92
+ );
93
+ }
94
+ }
78
95
  }
79
96
 
80
- tui.info(
81
- `Found ${entries.length} ${tui.plural(entries.length, 'namespace', 'namespaces')}:`
82
- );
97
+ // Convert timestamp fields to strings
98
+ const result: Record<
99
+ string,
100
+ {
101
+ count: number;
102
+ sum: number;
103
+ createdAt?: string;
104
+ lastUsedAt?: string;
105
+ }
106
+ > = {};
83
107
  for (const [name, stats] of entries) {
84
- const sizeDisplay =
85
- stats.sum < 1024 * 1024
86
- ? `${stats.sum.toLocaleString()} bytes`
87
- : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
88
- tui.arrow(`${tui.bold(name.padEnd(15, ' '))}: ${stats.count} keys, ${sizeDisplay}`);
108
+ result[name] = {
109
+ count: stats.count,
110
+ sum: stats.sum,
111
+ createdAt: stats.createdAt ? String(stats.createdAt) : undefined,
112
+ lastUsedAt: stats.lastUsedAt ? String(stats.lastUsedAt) : undefined,
113
+ };
89
114
  }
90
-
91
- return allStats;
115
+ return result;
92
116
  }
93
117
  },
94
118
  });
@@ -31,26 +31,31 @@ export const getSubcommand = createCommand({
31
31
  idempotent: true,
32
32
 
33
33
  async handler(ctx) {
34
- const { args } = ctx;
34
+ const { args, options } = ctx;
35
35
  const storage = await createStorageAdapter(ctx);
36
36
  const started = Date.now();
37
37
  const res = await storage.get(args.bucket, args.key);
38
- if (res.exists) {
39
- if (res.data) {
40
- if (res.contentType?.includes('json')) {
41
- const val = tryParseJSON(new TextDecoder().decode(res.data));
42
- tui.json(val);
43
- } else if (res.contentType?.includes('text')) {
44
- console.log(new TextDecoder().decode(res.data));
38
+
39
+ if (!options.json) {
40
+ if (res.exists) {
41
+ if (res.data) {
42
+ if (res.contentType?.includes('json')) {
43
+ const val = tryParseJSON(new TextDecoder().decode(res.data));
44
+ tui.json(val);
45
+ } else if (res.contentType?.includes('text')) {
46
+ console.log(new TextDecoder().decode(res.data));
47
+ } else {
48
+ tui.info(`Read ${res.data.byteLength} bytes (${res.contentType})`);
49
+ }
50
+ tui.success(
51
+ `retrieved in ${(Date.now() - started).toFixed(1)}ms (${res.contentType})`
52
+ );
45
53
  } else {
46
- tui.info(`Read ${res.data.byteLength} bytes (${res.contentType})`);
54
+ tui.warning(`${args.key} returned empty data for bucket ${args.bucket}`);
47
55
  }
48
- tui.success(`retrieved in ${(Date.now() - started).toFixed(1)}ms (${res.contentType})`);
49
56
  } else {
50
- tui.warning(`${args.key} returned empty data for bucket ${args.bucket}`);
57
+ tui.warning(`${args.key} does not exist in bucket ${args.bucket}`);
51
58
  }
52
- } else {
53
- tui.warning(`${args.key} does not exist in bucket ${args.bucket}`);
54
59
  }
55
60
 
56
61
  return {
@@ -24,18 +24,20 @@ export const listBucketsSubcommand = createCommand({
24
24
  examples: [`${getCommand('objectstore list-buckets')} - List all buckets with stats`],
25
25
 
26
26
  async handler(ctx) {
27
+ const { options } = ctx;
27
28
  const storage = await createStorageAdapter(ctx);
28
29
  const buckets = await storage.listBuckets();
29
30
 
30
- if (buckets.length === 0) {
31
- tui.info('No buckets found');
32
- return [];
33
- }
34
-
35
- tui.info(`Found ${buckets.length} bucket(s):`);
36
- for (const bucket of buckets) {
37
- const sizeMB = (bucket.total_bytes / (1024 * 1024)).toFixed(2);
38
- tui.info(` ${tui.bold(bucket.name)}: ${bucket.object_count} objects, ${sizeMB} MB`);
31
+ if (!options.json) {
32
+ if (buckets.length === 0) {
33
+ tui.info('No buckets found');
34
+ } else {
35
+ tui.info(`Found ${buckets.length} bucket(s):`);
36
+ for (const bucket of buckets) {
37
+ const sizeMB = (bucket.total_bytes / (1024 * 1024)).toFixed(2);
38
+ tui.info(` ${tui.bold(bucket.name)}: ${bucket.object_count} objects, ${sizeMB} MB`);
39
+ }
40
+ }
39
41
  }
40
42
 
41
43
  return buckets;
@@ -36,21 +36,22 @@ export const listKeysSubcommand = createCommand({
36
36
  },
37
37
 
38
38
  async handler(ctx) {
39
- const { args } = ctx;
39
+ const { args, options } = ctx;
40
40
  const objectStore = await createStorageAdapter(ctx);
41
41
 
42
42
  const objects = await objectStore.listKeys(args.bucket);
43
43
 
44
- if (objects.length === 0) {
45
- tui.info(`No objects found in bucket ${tui.bold(args.bucket)}`);
46
- return { bucket: args.bucket, objects: [], count: 0 };
47
- }
48
-
49
- tui.info(`Found ${objects.length} object(s) in ${tui.bold(args.bucket)}:`);
50
- for (const obj of objects) {
51
- const sizeMB = (obj.size / (1024 * 1024)).toFixed(2);
52
- const date = new Date(obj.updated_at).toLocaleString();
53
- tui.info(` ${tui.bold(obj.key)}: ${sizeMB} MB, updated ${date}`);
44
+ if (!options.json) {
45
+ if (objects.length === 0) {
46
+ tui.info(`No objects found in bucket ${tui.bold(args.bucket)}`);
47
+ } else {
48
+ tui.info(`Found ${objects.length} object(s) in ${tui.bold(args.bucket)}:`);
49
+ for (const obj of objects) {
50
+ const sizeMB = (obj.size / (1024 * 1024)).toFixed(2);
51
+ const date = new Date(obj.updated_at).toLocaleString();
52
+ tui.info(` ${tui.bold(obj.key)}: ${sizeMB} MB, updated ${date}`);
53
+ }
54
+ }
54
55
  }
55
56
 
56
57
  return { bucket: args.bucket, objects, count: objects.length };
@@ -57,39 +57,49 @@ export const listSubcommand = createSubcommand({
57
57
  });
58
58
 
59
59
  // Output based on format
60
- if (options.json) {
61
- console.log(JSON.stringify(resources, null, 2));
62
- } else {
60
+ if (!options.json) {
63
61
  // Text table format
64
62
  if (resources.db.length === 0 && resources.s3.length === 0) {
65
63
  tui.info('No resources found');
66
- return { db: [], s3: [] };
67
- }
68
-
69
- if (resources.db.length > 0) {
70
- tui.info(tui.bold('Databases'));
71
- tui.newline();
72
- for (const db of resources.db) {
73
- console.log(tui.bold(db.name));
74
- if (db.url) console.log(` URL: ${tui.muted(db.url)}`);
64
+ } else {
65
+ if (resources.db.length > 0) {
66
+ tui.info(tui.bold('Databases'));
75
67
  tui.newline();
68
+ for (const db of resources.db) {
69
+ console.log(tui.bold(db.name));
70
+ if (db.url) console.log(` URL: ${tui.muted(db.url)}`);
71
+ tui.newline();
72
+ }
76
73
  }
77
- }
78
74
 
79
- if (resources.s3.length > 0) {
80
- tui.info(tui.bold('Storage'));
81
- tui.newline();
82
- for (const s3 of resources.s3) {
83
- console.log(tui.bold(s3.bucket_name));
84
- if (s3.access_key) console.log(` Access Key: ${tui.muted(s3.access_key)}`);
85
- if (s3.secret_key) console.log(` Secret Key: ${tui.muted(s3.secret_key)}`);
86
- if (s3.region) console.log(` Region: ${tui.muted(s3.region)}`);
87
- if (s3.endpoint) console.log(` Endpoint: ${tui.muted(s3.endpoint)}`);
75
+ if (resources.s3.length > 0) {
76
+ tui.info(tui.bold('Storage'));
88
77
  tui.newline();
78
+ for (const s3 of resources.s3) {
79
+ console.log(tui.bold(s3.bucket_name));
80
+ if (s3.access_key) console.log(` Access Key: ${tui.muted(s3.access_key)}`);
81
+ if (s3.secret_key) console.log(` Secret Key: ${tui.muted(s3.secret_key)}`);
82
+ if (s3.region) console.log(` Region: ${tui.muted(s3.region)}`);
83
+ if (s3.endpoint) console.log(` Endpoint: ${tui.muted(s3.endpoint)}`);
84
+ tui.newline();
85
+ }
89
86
  }
90
87
  }
91
88
  }
92
89
 
93
- return resources;
90
+ // Convert null to undefined for schema compliance
91
+ return {
92
+ db: resources.db.map((db) => ({
93
+ name: db.name,
94
+ url: db.url ?? undefined,
95
+ })),
96
+ s3: resources.s3.map((s3) => ({
97
+ bucket_name: s3.bucket_name,
98
+ access_key: s3.access_key ?? undefined,
99
+ secret_key: s3.secret_key ?? undefined,
100
+ region: s3.region ?? undefined,
101
+ endpoint: s3.endpoint ?? undefined,
102
+ })),
103
+ };
94
104
  },
95
105
  });
@@ -35,7 +35,7 @@ export const getSubcommand = createSubcommand({
35
35
  idempotent: true,
36
36
 
37
37
  async handler(ctx) {
38
- const { args, opts, apiClient, project } = ctx;
38
+ const { args, opts, apiClient, project, options } = ctx;
39
39
 
40
40
  // Fetch project with unmasked secrets
41
41
  const projectData = await tui.spinner('Fetching secrets', () => {
@@ -49,19 +49,21 @@ export const getSubcommand = createSubcommand({
49
49
  tui.fatal(`Secret '${args.key}' not found`, ErrorCode.RESOURCE_NOT_FOUND);
50
50
  }
51
51
 
52
- if (process.stdout.isTTY) {
53
- // Display the value, masked by default
54
- if (opts?.mask) {
55
- tui.success(`${args.key}=${maskSecret(value)}`);
52
+ if (!options.json) {
53
+ if (process.stdout.isTTY) {
54
+ // Display the value, masked by default
55
+ if (opts?.mask) {
56
+ tui.success(`${args.key}=${maskSecret(value)}`);
57
+ } else {
58
+ tui.success(`${args.key}=${value}`);
59
+ }
56
60
  } else {
57
- tui.success(`${args.key}=${value}`);
58
- }
59
- } else {
60
- // Display the value, masked by default
61
- if (opts?.mask) {
62
- console.log(`${args.key}=${maskSecret(value)}`);
63
- } else {
64
- console.log(`${args.key}=${value}`);
61
+ // Display the value, masked by default
62
+ if (opts?.mask) {
63
+ console.log(`${args.key}=${maskSecret(value)}`);
64
+ } else {
65
+ console.log(`${args.key}=${value}`);
66
+ }
65
67
  }
66
68
  }
67
69
 
@@ -26,7 +26,7 @@ export const listSubcommand = createSubcommand({
26
26
  },
27
27
 
28
28
  async handler(ctx) {
29
- const { opts, apiClient, project } = ctx;
29
+ const { opts, apiClient, project, options } = ctx;
30
30
 
31
31
  // Fetch project with unmasked secrets
32
32
  const projectData = await tui.spinner('Fetching secrets', () => {
@@ -35,28 +35,30 @@ export const listSubcommand = createSubcommand({
35
35
 
36
36
  const secrets = projectData.secrets || {};
37
37
 
38
- if (Object.keys(secrets).length === 0) {
39
- tui.info('No secrets found');
40
- return {};
41
- }
42
-
43
- // Display the secrets
44
- if (process.stdout.isTTY) {
45
- tui.newline();
46
- tui.success(`Secrets (${Object.keys(secrets).length}):`);
47
- tui.newline();
48
- }
49
-
50
- const sortedKeys = Object.keys(secrets).sort();
51
- // For secrets, masking is enabled by default in TTY (can be disabled with --no-mask)
52
- const shouldMask = opts?.mask !== false;
53
- for (const key of sortedKeys) {
54
- const value = secrets[key];
55
- const displayValue = shouldMask ? maskSecret(value) : value;
56
- if (process.stdout.isTTY) {
57
- console.log(`${tui.bold(key)}=${displayValue}`);
38
+ // Skip TUI output in JSON mode
39
+ if (!options.json) {
40
+ if (Object.keys(secrets).length === 0) {
41
+ tui.info('No secrets found');
58
42
  } else {
59
- console.log(`${key}=${displayValue}`);
43
+ // Display the secrets
44
+ if (process.stdout.isTTY) {
45
+ tui.newline();
46
+ tui.success(`Secrets (${Object.keys(secrets).length}):`);
47
+ tui.newline();
48
+ }
49
+
50
+ const sortedKeys = Object.keys(secrets).sort();
51
+ // For secrets, masking is enabled by default in TTY (can be disabled with --no-mask)
52
+ const shouldMask = opts?.mask !== false;
53
+ for (const key of sortedKeys) {
54
+ const value = secrets[key];
55
+ const displayValue = shouldMask ? maskSecret(value) : value;
56
+ if (process.stdout.isTTY) {
57
+ console.log(`${tui.bold(key)}=${displayValue}`);
58
+ } else {
59
+ console.log(`${key}=${displayValue}`);
60
+ }
61
+ }
60
62
  }
61
63
  }
62
64
 
@@ -32,29 +32,30 @@ export const logsSubcommand = createSubcommand({
32
32
  response: SessionLogsResponseSchema,
33
33
  },
34
34
  async handler(ctx) {
35
- const { apiClient, args } = ctx;
35
+ const { apiClient, args, options } = ctx;
36
36
 
37
37
  try {
38
38
  const logs = await sessionLogs(apiClient, { id: args.session_id });
39
39
 
40
- if (logs.length === 0) {
41
- tui.info('No logs found for this session.');
42
- return [];
43
- }
44
-
45
- tui.banner(`Logs for Session ${args.session_id}`, `${logs.length} log entries`);
40
+ if (!options.json) {
41
+ if (logs.length === 0) {
42
+ tui.info('No logs found for this session.');
43
+ } else {
44
+ tui.banner(`Logs for Session ${args.session_id}`, `${logs.length} log entries`);
46
45
 
47
- for (const log of logs) {
48
- const timestamp = new Date(log.timestamp).toLocaleTimeString();
49
- const severity = log.severity.padEnd(5);
50
- const severityColor =
51
- log.severity === 'ERROR'
52
- ? tui.error(severity)
53
- : log.severity === 'WARN'
54
- ? tui.warning(severity)
55
- : tui.muted(severity);
46
+ for (const log of logs) {
47
+ const timestamp = new Date(log.timestamp).toLocaleTimeString();
48
+ const severity = log.severity.padEnd(5);
49
+ const severityColor =
50
+ log.severity === 'ERROR'
51
+ ? tui.error(severity)
52
+ : log.severity === 'WARN'
53
+ ? tui.warning(severity)
54
+ : tui.muted(severity);
56
55
 
57
- console.log(`${tui.muted(timestamp)} ${severityColor} ${log.body}`);
56
+ console.log(`${tui.muted(timestamp)} ${severityColor} ${log.body}`);
57
+ }
58
+ }
58
59
  }
59
60
 
60
61
  return logs;
@@ -46,22 +46,30 @@ export const agentsSubcommand = createSubcommand({
46
46
  .describe('Output format: json or table'),
47
47
  verbose: z.boolean().optional().default(false).describe('Show full IDs and descriptions'),
48
48
  }),
49
+ response: z.array(AgentSchema),
49
50
  },
50
51
  async handler(ctx) {
51
- const { opts, apiClient, project } = ctx;
52
+ const { opts, apiClient, project, options } = ctx;
52
53
  const projectId = project.projectId;
53
54
  const format = opts?.format ?? 'table';
54
55
  const verbose = opts?.verbose ?? false;
55
56
 
56
57
  const deploymentId = opts?.deploymentId;
57
58
  const queryParams = deploymentId ? `?deploymentId=${deploymentId}` : '';
58
- const response = await tui.spinner('Fetching agents', async () => {
59
- return apiClient.request(
60
- 'GET',
61
- `/cli/agent/${projectId}${queryParams}`,
62
- AgentsResponseSchema
63
- );
64
- });
59
+
60
+ const response = options.json
61
+ ? await apiClient.request(
62
+ 'GET',
63
+ `/cli/agent/${projectId}${queryParams}`,
64
+ AgentsResponseSchema
65
+ )
66
+ : await tui.spinner('Fetching agents', async () => {
67
+ return apiClient.request(
68
+ 'GET',
69
+ `/cli/agent/${projectId}${queryParams}`,
70
+ AgentsResponseSchema
71
+ );
72
+ });
65
73
 
66
74
  if (!response.success) {
67
75
  tui.fatal(`Failed to fetch agents: ${response.message ?? 'Unknown error'}`);
@@ -69,54 +77,66 @@ export const agentsSubcommand = createSubcommand({
69
77
 
70
78
  const agents = response.data;
71
79
 
72
- if (format === 'json') {
80
+ if (format === 'json' && !options.json) {
73
81
  console.log(JSON.stringify(agents, null, 2));
74
- return;
82
+ return agents;
75
83
  }
76
84
 
77
- tui.info(`Agents (${agents.length})`);
78
- if (agents.length === 0) {
79
- tui.muted('No agents found');
80
- } else {
81
- console.table(
82
- agents.map((agent) => ({
83
- name: agent.name,
84
- id: verbose ? agent.id : abbreviate(agent.id, 20),
85
- identifier: verbose ? agent.identifier : abbreviate(agent.identifier, 20),
86
- deployment: abbreviate(agent.deploymentId, 20),
87
- version: verbose
88
- ? (agent.version ?? 'N/A')
89
- : (abbreviate(agent.version, 20) ?? 'N/A'),
90
- evals: agent.evals.length,
91
- createdAt: new Date(agent.createdAt).toLocaleString(),
92
- })),
93
- ['name', 'id', 'identifier', 'deployment', 'version', 'evals', 'createdAt']
94
- );
85
+ if (!options.json) {
86
+ tui.info(`Agents (${agents.length})`);
87
+ if (agents.length === 0) {
88
+ tui.muted('No agents found');
89
+ } else {
90
+ console.table(
91
+ agents.map((agent) => ({
92
+ name: agent.name,
93
+ id: verbose ? agent.id : abbreviate(agent.id, 20),
94
+ identifier: verbose ? agent.identifier : abbreviate(agent.identifier, 20),
95
+ deployment: abbreviate(agent.deploymentId, 20),
96
+ version: verbose
97
+ ? (agent.version ?? 'N/A')
98
+ : (abbreviate(agent.version, 20) ?? 'N/A'),
99
+ evals: agent.evals.length,
100
+ createdAt: new Date(agent.createdAt).toLocaleString(),
101
+ })),
102
+ ['name', 'id', 'identifier', 'deployment', 'version', 'evals', 'createdAt']
103
+ );
95
104
 
96
- // Show evals for each agent
97
- for (const agent of agents) {
98
- if (agent.evals.length > 0) {
99
- console.log(`\n Evals for ${agent.name}:`);
100
- console.table(
101
- agent.evals.map((evalItem) => ({
102
- name: evalItem.name,
103
- id: verbose ? evalItem.id : abbreviate(evalItem.id, 20),
104
- identifier: verbose
105
- ? (evalItem.identifier ?? 'N/A')
106
- : (abbreviate(evalItem.identifier, 20) ?? 'N/A'),
107
- deployment: abbreviate(evalItem.deploymentId, 20),
108
- version: verbose
109
- ? (evalItem.version ?? 'N/A')
110
- : (abbreviate(evalItem.version, 20) ?? 'N/A'),
111
- description: verbose
112
- ? (evalItem.description ?? 'N/A')
113
- : abbreviateDescription(evalItem.description),
114
- createdAt: new Date(evalItem.createdAt).toLocaleString(),
115
- })),
116
- ['name', 'id', 'identifier', 'deployment', 'version', 'description', 'createdAt']
117
- );
105
+ // Show evals for each agent
106
+ for (const agent of agents) {
107
+ if (agent.evals.length > 0) {
108
+ console.log(`\n Evals for ${agent.name}:`);
109
+ console.table(
110
+ agent.evals.map((evalItem) => ({
111
+ name: evalItem.name,
112
+ id: verbose ? evalItem.id : abbreviate(evalItem.id, 20),
113
+ identifier: verbose
114
+ ? (evalItem.identifier ?? 'N/A')
115
+ : (abbreviate(evalItem.identifier, 20) ?? 'N/A'),
116
+ deployment: abbreviate(evalItem.deploymentId, 20),
117
+ version: verbose
118
+ ? (evalItem.version ?? 'N/A')
119
+ : (abbreviate(evalItem.version, 20) ?? 'N/A'),
120
+ description: verbose
121
+ ? (evalItem.description ?? 'N/A')
122
+ : abbreviateDescription(evalItem.description),
123
+ createdAt: new Date(evalItem.createdAt).toLocaleString(),
124
+ })),
125
+ [
126
+ 'name',
127
+ 'id',
128
+ 'identifier',
129
+ 'deployment',
130
+ 'version',
131
+ 'description',
132
+ 'createdAt',
133
+ ]
134
+ );
135
+ }
118
136
  }
119
137
  }
120
138
  }
139
+
140
+ return agents;
121
141
  },
122
142
  });
@@ -326,6 +326,7 @@ export const command = createCommand({
326
326
  logger.trace('Killing dev server (pid: %d)', pid);
327
327
  shuttingDownForRestart = true;
328
328
  running = false;
329
+ process.kill(pid, 'SIGINT');
329
330
  try {
330
331
  // Kill the process group (negative PID kills entire group)
331
332
  process.kill(-pid, 'SIGTERM');
@@ -430,6 +431,7 @@ export const command = createCommand({
430
431
  dev: true,
431
432
  projectId: project?.projectId,
432
433
  deploymentId,
434
+ port: opts.port,
433
435
  });
434
436
  building = false;
435
437
  buildCompletedAt = Date.now();