@agentuity/cli 0.0.87 → 0.0.88

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 (48) hide show
  1. package/dist/cli.js +3 -3
  2. package/dist/cmd/build/bundler.d.ts.map +1 -1
  3. package/dist/cmd/build/bundler.js +142 -7
  4. package/dist/cmd/build/bundler.js.map +1 -1
  5. package/dist/cmd/build/config-loader.d.ts +16 -0
  6. package/dist/cmd/build/config-loader.d.ts.map +1 -0
  7. package/dist/cmd/build/config-loader.js +165 -0
  8. package/dist/cmd/build/config-loader.js.map +1 -0
  9. package/dist/cmd/build/plugin.d.ts.map +1 -1
  10. package/dist/cmd/build/plugin.js +16 -2
  11. package/dist/cmd/build/plugin.js.map +1 -1
  12. package/dist/cmd/build/workbench.d.ts +1 -0
  13. package/dist/cmd/build/workbench.d.ts.map +1 -1
  14. package/dist/cmd/build/workbench.js +8 -1
  15. package/dist/cmd/build/workbench.js.map +1 -1
  16. package/dist/cmd/cloud/index.d.ts.map +1 -1
  17. package/dist/cmd/cloud/index.js +2 -0
  18. package/dist/cmd/cloud/index.js.map +1 -1
  19. package/dist/cmd/cloud/redis/get.d.ts +2 -0
  20. package/dist/cmd/cloud/redis/get.d.ts.map +1 -0
  21. package/dist/cmd/cloud/redis/get.js +62 -0
  22. package/dist/cmd/cloud/redis/get.js.map +1 -0
  23. package/dist/cmd/cloud/redis/index.d.ts +2 -0
  24. package/dist/cmd/cloud/redis/index.d.ts.map +1 -0
  25. package/dist/cmd/cloud/redis/index.js +13 -0
  26. package/dist/cmd/cloud/redis/index.js.map +1 -0
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/tui.d.ts +5 -0
  31. package/dist/tui.d.ts.map +1 -1
  32. package/dist/tui.js +7 -0
  33. package/dist/tui.js.map +1 -1
  34. package/dist/types.d.ts +66 -0
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js.map +1 -1
  37. package/package.json +6 -4
  38. package/src/cli.ts +3 -3
  39. package/src/cmd/build/bundler.ts +169 -8
  40. package/src/cmd/build/config-loader.ts +200 -0
  41. package/src/cmd/build/plugin.ts +18 -2
  42. package/src/cmd/build/workbench.ts +9 -1
  43. package/src/cmd/cloud/index.ts +2 -0
  44. package/src/cmd/cloud/redis/get.ts +72 -0
  45. package/src/cmd/cloud/redis/index.ts +13 -0
  46. package/src/index.ts +4 -0
  47. package/src/tui.ts +8 -0
  48. package/src/types.ts +73 -0
@@ -336,8 +336,11 @@ const AgentuityBundler: BunPlugin = {
336
336
  // Setup workbench configuration - evaluate fresh each time during builds
337
337
  const workbenchConfig = await setupWorkbench(srcDir);
338
338
 
339
+ // Store web routes for later (must be registered AFTER API routes)
340
+ let webRoutesInsert: string | null = null;
341
+
339
342
  if (existsSync(indexFile)) {
340
- inserts.push(`import { serveStatic } from 'hono/bun';
343
+ webRoutesInsert = `import { serveStatic } from 'hono/bun';
341
344
  import { getRouter, registerDevModeRoutes } from '@agentuity/runtime';
342
345
  import { readFileSync, existsSync } from 'node:fs';
343
346
 
@@ -387,14 +390,22 @@ import { readFileSync, existsSync } from 'node:fs';
387
390
  // Serve public assets at root (e.g., /favicon.ico) - must be last
388
391
  router.get('/*', async (c, next) => {
389
392
  const path = c.req.path;
393
+ // Skip API routes - let them 404 naturally
394
+ if (path === '/api' || path.startsWith('/api/')) {
395
+ return c.notFound();
396
+ }
390
397
  // Prevent directory traversal attacks
391
398
  if (path.includes('..') || path.includes('%2e%2e')) {
392
399
  return c.notFound();
393
400
  }
401
+ // Don't catch workbench routes (already handled above)
402
+ if (path.startsWith('/workbench')) {
403
+ return c.notFound();
404
+ }
394
405
  // serve default for any path not explicitly matched
395
406
  return c.html(index);
396
407
  });
397
- })();`);
408
+ })();`;
398
409
  }
399
410
 
400
411
  // Build agentInfo from all discovered agents and track directories
@@ -626,6 +637,11 @@ import { readFileSync, existsSync } from 'node:fs';
626
637
  })();`);
627
638
  }
628
639
 
640
+ // Add web routes AFTER API routes (catch-all must be last)
641
+ if (webRoutesInsert) {
642
+ inserts.push(webRoutesInsert);
643
+ }
644
+
629
645
  const file = Bun.file(args.path);
630
646
  let contents = await file.text();
631
647
  // Use AST-based parsing to reliably find createApp statement end
@@ -8,7 +8,6 @@ export function generateWorkbenchMainTsx(config: WorkbenchConfig): string {
8
8
  import React from 'react';
9
9
  import { createRoot } from 'react-dom/client';
10
10
  import { App } from '@agentuity/workbench';
11
- import '@agentuity/workbench/styles';
12
11
 
13
12
  // Root element
14
13
  const rootElement = document.getElementById('root');
@@ -23,6 +22,14 @@ root.render(<App configBase64="${encodedConfig}" />);
23
22
  `;
24
23
  }
25
24
 
25
+ export function generateWorkbenchStylesCss(): string {
26
+ // This file will be replaced with the actual dist/styles.css content during build
27
+ // We use @import here as a placeholder, but the bundler should resolve it to the built file
28
+ return `/* Generated workbench styles - will be replaced with dist/styles.css */
29
+ @import '@agentuity/workbench/styles-standalone';
30
+ `;
31
+ }
32
+
26
33
  export function generateWorkbenchIndexHtml(): string {
27
34
  return `<!DOCTYPE html>
28
35
  <html lang="en">
@@ -30,6 +37,7 @@ export function generateWorkbenchIndexHtml(): string {
30
37
  <meta charset="UTF-8">
31
38
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
32
39
  <title>Agentuity Workbench</title>
40
+ <link rel="stylesheet" href="./styles.css">
33
41
  </head>
34
42
  <body>
35
43
  <div id="root"></div>
@@ -1,6 +1,7 @@
1
1
  import { createCommand } from '../../types';
2
2
  import { deploySubcommand } from './deploy';
3
3
  import { dbCommand } from './db';
4
+ import { redisCommand } from './redis';
4
5
  import { storageCommand } from './storage';
5
6
  import { sessionCommand } from './session';
6
7
  import { threadCommand } from './thread';
@@ -34,6 +35,7 @@ export const command = createCommand({
34
35
  secretCommand,
35
36
  deploySubcommand,
36
37
  dbCommand,
38
+ redisCommand,
37
39
  storageCommand,
38
40
  sessionCommand,
39
41
  threadCommand,
@@ -0,0 +1,72 @@
1
+ import { z } from 'zod';
2
+ import { listResources } from '@agentuity/server';
3
+ import { createSubcommand } from '../../../types';
4
+ import * as tui from '../../../tui';
5
+ import { getCatalystAPIClient } from '../../../config';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ const RedisGetResponseSchema = z.object({
9
+ url: z.string().optional().describe('Redis connection URL'),
10
+ });
11
+
12
+ export const showSubcommand = createSubcommand({
13
+ name: 'show',
14
+ aliases: ['info'],
15
+ description: 'Show Redis connection URL',
16
+ tags: ['read-only', 'fast', 'requires-auth'],
17
+ requires: { auth: true, org: true, region: true },
18
+ idempotent: true,
19
+ examples: [
20
+ { command: getCommand('cloud redis show'), description: 'Show Redis connection URL' },
21
+ {
22
+ command: getCommand('cloud redis show --show-credentials'),
23
+ description: 'Show Redis URL with credentials visible',
24
+ },
25
+ {
26
+ command: getCommand('--json cloud redis show'),
27
+ description: 'Show Redis URL as JSON',
28
+ },
29
+ ],
30
+ schema: {
31
+ options: z.object({
32
+ showCredentials: z
33
+ .boolean()
34
+ .optional()
35
+ .describe(
36
+ 'Show credentials in plain text (default: masked in terminal, unmasked in JSON)'
37
+ ),
38
+ }),
39
+ response: RedisGetResponseSchema,
40
+ },
41
+
42
+ async handler(ctx) {
43
+ const { logger, opts, options, orgId, region, auth } = ctx;
44
+
45
+ const catalystClient = getCatalystAPIClient(logger, auth, region);
46
+
47
+ const resources = await tui.spinner({
48
+ message: `Fetching Redis for ${orgId} in ${region}`,
49
+ clearOnSuccess: true,
50
+ callback: async () => {
51
+ return listResources(catalystClient, orgId, region);
52
+ },
53
+ });
54
+
55
+ if (!resources.redis) {
56
+ tui.info('No Redis provisioned for this organization');
57
+ return { url: undefined };
58
+ }
59
+
60
+ const shouldShowCredentials = opts.showCredentials === true;
61
+ const shouldMask = !options.json && !shouldShowCredentials;
62
+
63
+ if (!options.json) {
64
+ const displayUrl = shouldMask ? tui.maskSecret(resources.redis.url) : resources.redis.url;
65
+ tui.output(tui.bold('Redis URL: ') + displayUrl);
66
+ }
67
+
68
+ return {
69
+ url: resources.redis.url,
70
+ };
71
+ },
72
+ });
@@ -0,0 +1,13 @@
1
+ import { createCommand } from '../../../types';
2
+ import { showSubcommand } from './get';
3
+ import { getCommand } from '../../../command-prefix';
4
+
5
+ export const redisCommand = createCommand({
6
+ name: 'redis',
7
+ description: 'Manage Redis resources',
8
+ tags: ['slow', 'requires-auth'],
9
+ examples: [
10
+ { command: getCommand('cloud redis show'), description: 'Show Redis connection URL' },
11
+ ],
12
+ subcommands: [showSubcommand],
13
+ });
package/src/index.ts CHANGED
@@ -104,6 +104,10 @@ export type {
104
104
  Profile,
105
105
  AuthData,
106
106
  CommandSchemas,
107
+ BuildPhase,
108
+ BuildContext,
109
+ BuildConfig,
110
+ BuildConfigFunction,
107
111
  } from './types';
108
112
  export { createSubcommand, createCommand } from './types';
109
113
  export type { ColorScheme } from './terminal';
package/src/tui.ts CHANGED
@@ -346,6 +346,14 @@ export function newline(): void {
346
346
  process.stderr.write('\n');
347
347
  }
348
348
 
349
+ /**
350
+ * Print plain text output without any prefix or icon
351
+ * Use for primary command output that shouldn't have semantic formatting
352
+ */
353
+ export function output(message: string): void {
354
+ console.log(message);
355
+ }
356
+
349
357
  /**
350
358
  * Get the display width of a string, handling ANSI codes and OSC 8 hyperlinks
351
359
  *
package/src/types.ts CHANGED
@@ -63,6 +63,79 @@ export type Config = zod.infer<typeof ConfigSchema>;
63
63
 
64
64
  export type LogLevel = 'debug' | 'trace' | 'info' | 'warn' | 'error';
65
65
 
66
+ /**
67
+ * Build phases for the bundler
68
+ */
69
+ export type BuildPhase = 'api' | 'web' | 'workbench';
70
+
71
+ /**
72
+ * Context provided to the build config function
73
+ */
74
+ export interface BuildContext {
75
+ /**
76
+ * The root directory of the project
77
+ */
78
+ rootDir: string;
79
+ /**
80
+ * Whether this is a development build
81
+ */
82
+ dev: boolean;
83
+ /**
84
+ * The output directory for the build
85
+ */
86
+ outDir: string;
87
+ /**
88
+ * The source directory
89
+ */
90
+ srcDir: string;
91
+ /**
92
+ * Organization ID (if available)
93
+ */
94
+ orgId?: string;
95
+ /**
96
+ * Project ID (if available)
97
+ */
98
+ projectId?: string;
99
+ /**
100
+ * Deployment region
101
+ */
102
+ region: string;
103
+ /**
104
+ * Logger instance
105
+ */
106
+ logger: Logger;
107
+ }
108
+
109
+ /**
110
+ * User-provided build configuration for a specific phase
111
+ */
112
+ export interface BuildConfig {
113
+ /**
114
+ * Additional Bun plugins to apply during bundling
115
+ * These are added AFTER the Agentuity plugin
116
+ */
117
+ plugins?: Array<import('bun').BunPlugin>;
118
+ /**
119
+ * Additional external modules to exclude from bundling
120
+ * These are merged with Agentuity's default externals
121
+ */
122
+ external?: string[];
123
+ /**
124
+ * Additional define constants for code replacement
125
+ * These are merged with Agentuity's default defines
126
+ * Note: Cannot override process.env.AGENTUITY_* or process.env.NODE_ENV
127
+ */
128
+ define?: Record<string, string>;
129
+ }
130
+
131
+ /**
132
+ * Configuration function that users export from agentuity.config.ts
133
+ */
134
+ export type BuildConfigFunction = (
135
+ phase: BuildPhase,
136
+ context: BuildContext
137
+ ) => BuildConfig | Promise<BuildConfig>;
138
+
66
139
  export interface Profile {
67
140
  name: string;
68
141
  filename: string;