@agi-cli/web-ui 0.1.46

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.
package/README.md ADDED
@@ -0,0 +1,407 @@
1
+ # @agi-cli/web-ui
2
+
3
+ Pre-built, embeddable web UI for AGI CLI. This package contains the fully-built static assets from the AGI CLI web interface, ready to be served by any web server or framework.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **One-Line Integration** - Import and serve with a single function call
8
+ - 📦 **Pre-built Assets** - No build step required in your project
9
+ - 🚀 **Framework Agnostic** - Works with Bun, Express, Fastify, Hono, or any HTTP server
10
+ - 🎨 **Full Featured** - Complete AGI CLI web interface with all functionality
11
+ - 📱 **Responsive** - Modern, mobile-friendly UI built with React and Tailwind CSS
12
+ - ⚡ **Fast** - Optimized production build with code splitting
13
+ - 🛣️ **Smart Routing** - Handles SPA routing and direct asset requests automatically
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @agi-cli/web-ui
19
+ # or
20
+ yarn add @agi-cli/web-ui
21
+ # or
22
+ pnpm add @agi-cli/web-ui
23
+ # or
24
+ bun add @agi-cli/web-ui
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ### Ultra-Simple (Recommended)
30
+
31
+ Just one line - everything is handled for you:
32
+
33
+ ```typescript
34
+ import { serveWebUI } from '@agi-cli/web-ui';
35
+
36
+ Bun.serve({
37
+ port: 3000,
38
+ fetch: serveWebUI({ prefix: '/ui' })
39
+ });
40
+
41
+ console.log('Web UI: http://localhost:3000/ui');
42
+ ```
43
+
44
+ That's it! The web UI will be available at `/ui` with:
45
+ - ✅ Automatic SPA routing
46
+ - ✅ Asset path handling (both `/ui/assets/*` and `/assets/*`)
47
+ - ✅ Proper MIME types
48
+ - ✅ 404 fallbacks
49
+
50
+ ### With Custom Routes
51
+
52
+ Combine the web UI with your own API routes:
53
+
54
+ ```typescript
55
+ import { serveWebUI } from '@agi-cli/web-ui';
56
+
57
+ const webUI = serveWebUI({ prefix: '/ui' });
58
+
59
+ Bun.serve({
60
+ port: 3000,
61
+ async fetch(req) {
62
+ const url = new URL(req.url);
63
+
64
+ // Your API routes
65
+ if (url.pathname === '/api/hello') {
66
+ return new Response(JSON.stringify({ message: 'Hello!' }), {
67
+ headers: { 'Content-Type': 'application/json' }
68
+ });
69
+ }
70
+
71
+ // Try web UI handler
72
+ const webUIResponse = await webUI(req);
73
+ if (webUIResponse) return webUIResponse;
74
+
75
+ // Final fallback
76
+ return new Response('Not found', { status: 404 });
77
+ }
78
+ });
79
+ ```
80
+
81
+ ### With Root Redirect
82
+
83
+ Automatically redirect `/` to `/ui`:
84
+
85
+ ```typescript
86
+ import { serveWebUI } from '@agi-cli/web-ui';
87
+
88
+ Bun.serve({
89
+ port: 3000,
90
+ fetch: serveWebUI({
91
+ prefix: '/ui',
92
+ redirectRoot: true // '/' → '/ui'
93
+ })
94
+ });
95
+ ```
96
+
97
+ ### Different Prefix
98
+
99
+ Serve the UI at any path you want:
100
+
101
+ ```typescript
102
+ import { serveWebUI } from '@agi-cli/web-ui';
103
+
104
+ Bun.serve({
105
+ port: 3000,
106
+ fetch: serveWebUI({ prefix: '/admin' })
107
+ });
108
+
109
+ console.log('Web UI: http://localhost:3000/admin');
110
+ ```
111
+
112
+ ## API Reference
113
+
114
+ ### `serveWebUI(options?): (req: Request) => Promise<Response | null>`
115
+
116
+ Creates a request handler that serves the web UI.
117
+
118
+ **Options:**
119
+
120
+ | Option | Type | Default | Description |
121
+ |--------|------|---------|-------------|
122
+ | `prefix` | `string` | `'/ui'` | URL prefix for the web UI |
123
+ | `redirectRoot` | `boolean` | `false` | Redirect `/` to the prefix |
124
+ | `onNotFound` | `(req: Request) => Response \| null` | `null` | Custom 404 handler |
125
+
126
+ **Returns:** A request handler function that returns:
127
+ - `Response` if the request matches a web UI route
128
+ - `null` if the request should be handled by other routes
129
+
130
+ **Example:**
131
+
132
+ ```typescript
133
+ const handler = serveWebUI({
134
+ prefix: '/dashboard',
135
+ redirectRoot: true,
136
+ onNotFound: (req) => new Response('UI not found', { status: 404 })
137
+ });
138
+
139
+ Bun.serve({ port: 3000, fetch: handler });
140
+ ```
141
+
142
+ ### `getWebUIPath(): string`
143
+
144
+ Returns the absolute path to the directory containing all built web UI assets.
145
+
146
+ ```typescript
147
+ import { getWebUIPath } from '@agi-cli/web-ui';
148
+
149
+ const assetsPath = getWebUIPath();
150
+ // => '/path/to/node_modules/@agi-cli/web-ui/dist/web-assets'
151
+ ```
152
+
153
+ ### `getIndexPath(): string`
154
+
155
+ Returns the absolute path to the main `index.html` file.
156
+
157
+ ```typescript
158
+ import { getIndexPath } from '@agi-cli/web-ui';
159
+
160
+ const indexPath = getIndexPath();
161
+ // => '/path/to/node_modules/@agi-cli/web-ui/dist/web-assets/index.html'
162
+ ```
163
+
164
+ ### `isWebUIAvailable(): boolean`
165
+
166
+ Checks if the web UI assets are properly built and available.
167
+
168
+ ```typescript
169
+ import { isWebUIAvailable } from '@agi-cli/web-ui';
170
+
171
+ if (!isWebUIAvailable()) {
172
+ console.error('Web UI assets not found!');
173
+ process.exit(1);
174
+ }
175
+ ```
176
+
177
+ ## Framework Examples
178
+
179
+ ### Bun (Recommended)
180
+
181
+ ```typescript
182
+ import { serveWebUI } from '@agi-cli/web-ui';
183
+
184
+ Bun.serve({
185
+ port: 3000,
186
+ fetch: serveWebUI({ prefix: '/ui' })
187
+ });
188
+ ```
189
+
190
+ ### Express
191
+
192
+ ```typescript
193
+ import express from 'express';
194
+ import { getWebUIPath, getIndexPath } from '@agi-cli/web-ui';
195
+
196
+ const app = express();
197
+
198
+ // Serve static assets
199
+ app.use('/ui', express.static(getWebUIPath()));
200
+
201
+ // SPA fallback
202
+ app.get('/ui/*', (req, res) => {
203
+ res.sendFile(getIndexPath());
204
+ });
205
+
206
+ app.listen(3000);
207
+ ```
208
+
209
+ ### Fastify
210
+
211
+ ```typescript
212
+ import Fastify from 'fastify';
213
+ import fastifyStatic from '@fastify/static';
214
+ import { getWebUIPath } from '@agi-cli/web-ui';
215
+
216
+ const fastify = Fastify();
217
+
218
+ await fastify.register(fastifyStatic, {
219
+ root: getWebUIPath(),
220
+ prefix: '/ui/',
221
+ });
222
+
223
+ await fastify.listen({ port: 3000 });
224
+ ```
225
+
226
+ ### Hono
227
+
228
+ ```typescript
229
+ import { Hono } from 'hono';
230
+ import { serveStatic } from 'hono/bun';
231
+ import { getWebUIPath } from '@agi-cli/web-ui';
232
+
233
+ const app = new Hono();
234
+
235
+ app.use('/ui/*', serveStatic({ root: getWebUIPath() }));
236
+
237
+ export default app;
238
+ ```
239
+
240
+ ### Node.js HTTP
241
+
242
+ ```typescript
243
+ import { createServer } from 'http';
244
+ import { serveWebUI } from '@agi-cli/web-ui';
245
+
246
+ const handler = serveWebUI({ prefix: '/ui' });
247
+
248
+ createServer(async (req, res) => {
249
+ const request = new Request(`http://localhost${req.url}`);
250
+ const response = await handler(request);
251
+
252
+ if (response) {
253
+ res.writeHead(response.status, Object.fromEntries(response.headers));
254
+ res.end(await response.text());
255
+ } else {
256
+ res.writeHead(404);
257
+ res.end('Not found');
258
+ }
259
+ }).listen(3000);
260
+ ```
261
+
262
+ ## How It Works
263
+
264
+ The `serveWebUI()` function handles all the complexity for you:
265
+
266
+ 1. **Prefixed Routes** (`/ui/*`): Strips the prefix and serves the requested file
267
+ 2. **Direct Asset Requests** (`/assets/*`, `/vite.svg`, etc.): Serves assets directly (for when HTML references them)
268
+ 3. **SPA Fallback**: Returns `index.html` for any unmatched routes under the prefix
269
+ 4. **Security**: Prevents directory traversal attacks
270
+ 5. **MIME Types**: Automatically sets correct Content-Type headers
271
+ 6. **Cross-Runtime**: Works in both Bun and Node.js
272
+
273
+ This pattern solves the common issue where Vite-built apps reference assets like `/assets/index-*.js` directly, which would 404 without special handling.
274
+
275
+ ## Important Notes
276
+
277
+ ### Single Page Application (SPA)
278
+
279
+ The web UI is a React-based SPA with client-side routing. The `serveWebUI()` handler automatically:
280
+ - Serves static assets from the web UI path
281
+ - Falls back to `index.html` for client-side routes
282
+ - Handles both prefixed (`/ui/assets/*`) and direct (`/assets/*`) asset requests
283
+
284
+ ### API Configuration
285
+
286
+ The web UI expects an API to be available. By default, it will try to connect to:
287
+ - `http://localhost:3000/api` (in development)
288
+ - Same origin `/api` (in production)
289
+
290
+ You'll need to set up your API endpoints to handle AGI CLI requests. See the [AGI CLI documentation](https://github.com/yourusername/agi-cli) for API implementation details.
291
+
292
+ ### CORS
293
+
294
+ If your API is on a different origin than the web UI, you'll need to configure CORS headers:
295
+
296
+ ```typescript
297
+ Bun.serve({
298
+ port: 3000,
299
+ async fetch(req) {
300
+ // Your routes...
301
+
302
+ const response = await handler(req);
303
+
304
+ // Add CORS headers
305
+ response.headers.set('Access-Control-Allow-Origin', '*');
306
+ response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
307
+ response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
308
+
309
+ return response;
310
+ }
311
+ });
312
+ ```
313
+
314
+ ## Examples
315
+
316
+ See the [examples](./examples) directory for complete working examples:
317
+
318
+ - **Bun Server** - Minimal example using Bun's HTTP server with `serveWebUI()`
319
+ - **Express Server** - Traditional Express.js integration
320
+
321
+ ## Development
322
+
323
+ This package is part of the AGI CLI monorepo. To build from source:
324
+
325
+ ```bash
326
+ # Clone the repository
327
+ git clone https://github.com/yourusername/agi-cli
328
+ cd agi-cli
329
+
330
+ # Install dependencies
331
+ bun install
332
+
333
+ # Build the package
334
+ cd packages/web-ui
335
+ bun run build
336
+ ```
337
+
338
+ The build process:
339
+ 1. Builds the web app from `apps/web` using Vite
340
+ 2. Copies the production build to `dist/web-assets`
341
+ 3. Compiles the TypeScript exports
342
+ 4. Generates type declarations
343
+
344
+ ## What's Included
345
+
346
+ The package includes:
347
+
348
+ - ✅ Complete AGI CLI web interface
349
+ - ✅ React 19 with optimized production build
350
+ - ✅ TailwindCSS for styling
351
+ - ✅ Code syntax highlighting
352
+ - ✅ Markdown rendering
353
+ - ✅ Real-time API communication
354
+ - ✅ Responsive mobile design
355
+ - ✅ Dark mode support (if configured)
356
+ - ✅ Smart request handler with automatic routing
357
+
358
+ ## Bundle Size
359
+
360
+ The production build is optimized and includes:
361
+ - Main JS bundle: ~1.1 MB (370 KB gzipped)
362
+ - CSS: ~31 KB (6.5 KB gzipped)
363
+ - Total initial load: ~376 KB gzipped
364
+
365
+ ## Browser Support
366
+
367
+ The web UI supports all modern browsers:
368
+ - Chrome/Edge (last 2 versions)
369
+ - Firefox (last 2 versions)
370
+ - Safari (last 2 versions)
371
+
372
+ ## Migration from Manual Setup
373
+
374
+ If you were using the old manual approach:
375
+
376
+ **Before:**
377
+ ```typescript
378
+ import { getWebUIPath, getIndexPath } from '@agi-cli/web-ui';
379
+
380
+ // 50 lines of routing logic...
381
+ ```
382
+
383
+ **After:**
384
+ ```typescript
385
+ import { serveWebUI } from '@agi-cli/web-ui';
386
+
387
+ Bun.serve({
388
+ port: 3000,
389
+ fetch: serveWebUI({ prefix: '/ui' })
390
+ });
391
+ ```
392
+
393
+ ## License
394
+
395
+ MIT
396
+
397
+ ## Related
398
+
399
+ - [AGI CLI](https://github.com/yourusername/agi-cli) - The main CLI tool
400
+ - [AGI CLI API Documentation](https://github.com/yourusername/agi-cli/docs/api) - API implementation guide
401
+
402
+ ## Support
403
+
404
+ For issues, questions, or contributions:
405
+ - 🐛 [Report a bug](https://github.com/yourusername/agi-cli/issues)
406
+ - 💡 [Request a feature](https://github.com/yourusername/agi-cli/issues)
407
+ - 📖 [Read the docs](https://github.com/yourusername/agi-cli/docs)
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Get the absolute path to the web UI assets directory
3
+ */
4
+ export declare function getWebUIPath(): string;
5
+ /**
6
+ * Get the absolute path to the index.html file
7
+ */
8
+ export declare function getIndexPath(): string;
9
+ /**
10
+ * Check if web UI assets are available
11
+ */
12
+ export declare function isWebUIAvailable(): boolean;
13
+ export interface ServeWebUIOptions {
14
+ /**
15
+ * URL prefix for the web UI (default: '/ui')
16
+ * @example '/ui', '/admin', '/dashboard'
17
+ */
18
+ prefix?: string;
19
+ /**
20
+ * Whether to redirect root to prefix (default: false)
21
+ * @example If true, '/' → '/ui'
22
+ */
23
+ redirectRoot?: boolean;
24
+ /**
25
+ * Custom 404 handler
26
+ */
27
+ onNotFound?: (req: Request) => Response | Promise<Response> | null;
28
+ }
29
+ /**
30
+ * Create a request handler for serving the web UI
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { serveWebUI } from '@agi-cli/web-ui';
35
+ *
36
+ * Bun.serve({
37
+ * port: 3000,
38
+ * fetch: serveWebUI({ prefix: '/ui' })
39
+ * });
40
+ * ```
41
+ */
42
+ export declare function serveWebUI(options?: ServeWebUIOptions): (req: Request) => Promise<Response | null>;
43
+ declare const _default: {
44
+ getWebUIPath: typeof getWebUIPath;
45
+ getIndexPath: typeof getIndexPath;
46
+ isWebUIAvailable: typeof isWebUIAvailable;
47
+ serveWebUI: typeof serveWebUI;
48
+ };
49
+ export default _default;
50
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAa1C;AAED,MAAM,WAAW,iBAAiB;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;CACnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,IAMrB,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAsG3E;;;;;;;AAyBD,wBAKE"}