@kubb/agent 4.24.1 → 4.25.0
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/.output/nitro.json +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +708 -379
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +8 -10
- package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
- package/.output/server/index.mjs +5 -5
- package/.output/server/package.json +1 -1
- package/README.md +113 -19
- package/package.json +4 -2
- package/.output/server/chunks/_/package.mjs +0 -4
- package/.output/server/chunks/_/package.mjs.map +0 -1
- package/.output/server/chunks/routes/api/generate.options.mjs +0 -31
- package/.output/server/chunks/routes/api/generate.options.mjs.map +0 -1
- package/.output/server/chunks/routes/api/generate.post.mjs +0 -120
- package/.output/server/chunks/routes/api/generate.post.mjs.map +0 -1
- package/.output/server/chunks/routes/api/info.get.mjs +0 -63
- package/.output/server/chunks/routes/api/info.get.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nitro.mjs","sources":["../../../../../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs","../../../../../../node_modules/.pnpm/ufo@1.6.3/node_modules/ufo/dist/index.mjs","../../../../../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs","../../../../../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs","../../../../../../node_modules/.pnpm/node-mock-http@1.0.4/node_modules/node-mock-http/dist/index.mjs","../../../../../../node_modules/.pnpm/h3@1.15.5/node_modules/h3/dist/index.mjs","../../../../../../node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs","../../../../../../node_modules/.pnpm/node-fetch-native@1.6.7/node_modules/node-fetch-native/dist/native.mjs","../../../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs","../../../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/node.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/dist/shared/unstorage.zVDD2mZo.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/dist/index.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/utils/index.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/utils/node-fs.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/fs-lite.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/storage.mjs","../../../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/crypto/node/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/hash.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/cache.mjs","../../../../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/dist/index.mjs","../../../../../../node_modules/.pnpm/scule@1.3.0/node_modules/scule/dist/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/utils.env.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/config.mjs","../../../../../../node_modules/.pnpm/unctx@2.5.0/node_modules/unctx/dist/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/context.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/route-rules.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/utils.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/error/utils.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/error/prod.mjs","../../../../../core/dist/chunk-iVr_oF3V.js","../../../../../core/dist/fs-Parec-wn.js","../../../../../core/dist/transformers-8ju9ixkG.js","../../../../../core/dist/getBarrelFiles-gRyVPFBP.js","../../../../../core/dist/
|
|
1
|
+
{"version":3,"file":"nitro.mjs","sources":["../../../../../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs","../../../../../../node_modules/.pnpm/ufo@1.6.3/node_modules/ufo/dist/index.mjs","../../../../../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs","../../../../../../node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs","../../../../../../node_modules/.pnpm/node-mock-http@1.0.4/node_modules/node-mock-http/dist/index.mjs","../../../../../../node_modules/.pnpm/h3@1.15.5/node_modules/h3/dist/index.mjs","../../../../../../node_modules/.pnpm/hookable@5.5.3/node_modules/hookable/dist/index.mjs","../../../../../../node_modules/.pnpm/node-fetch-native@1.6.7/node_modules/node-fetch-native/dist/native.mjs","../../../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/shared/ofetch.CWycOUEr.mjs","../../../../../../node_modules/.pnpm/ofetch@1.5.1/node_modules/ofetch/dist/node.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/dist/shared/unstorage.zVDD2mZo.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/dist/index.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/utils/index.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/utils/node-fs.mjs","../../../../../../node_modules/.pnpm/unstorage@1.17.4_db0@0.3.4_ioredis@5.9.3/node_modules/unstorage/drivers/fs-lite.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/storage.mjs","../../../../../../node_modules/.pnpm/ohash@2.0.11/node_modules/ohash/dist/crypto/node/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/hash.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/cache.mjs","../../../../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/dist/index.mjs","../../../../../../node_modules/.pnpm/scule@1.3.0/node_modules/scule/dist/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/utils.env.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/config.mjs","../../../../../../node_modules/.pnpm/unctx@2.5.0/node_modules/unctx/dist/index.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/context.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/route-rules.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/utils.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/error/utils.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/error/prod.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/plugin.mjs","../../../../../core/dist/chunk-iVr_oF3V.js","../../../../../core/dist/fs-Parec-wn.js","../../../../../core/dist/transformers-8ju9ixkG.js","../../../../../core/dist/getBarrelFiles-gRyVPFBP.js","../../../../../core/dist/utils.js","../../../../server/types/agent.ts","../../../../server/utils/logger.ts","../../../../server/utils/sessionManager.ts","../../../../server/utils/api.ts","../../../../../core/dist/index.js","../../../../server/utils/executeHooks.ts","../../../../server/utils/generate.ts","../../../../server/utils/getCosmiConfig.ts","../../../../server/utils/ws.ts","../../../../server/plugins/studio.ts","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/app.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/lib/http-graceful-shutdown.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/runtime/internal/shutdown.mjs","../../../../../../node_modules/.pnpm/nitropack@2.13.1_encoding@0.1.13_rolldown@1.0.0-rc.1/node_modules/nitropack/dist/presets/node/runtime/node-server.mjs"],"names":["createRouter","f","h","i","l","createError","mergeHeaders","s","nodeFetch","Headers","Headers$1","AbortController$1","normalizeKey","defineDriver","DRIVER_NAME","fsPromises","fsp","_inlineAppConfig","createRadixRouter","__defProp","_b","_options","__privateAdd","__privateGet","__privateSet","pLimit","path","_a","__privateMethod","version","fs","error","process","result","nitroApp","callNodeRequestHandler","fetchNodeRequestHandler","gracefulShutdown","HttpsServer","HttpServer"],"mappings":"","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,45,46,47,48]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { d as defineEventHandler } from '../../nitro/nitro.mjs';
|
|
2
|
-
import process from 'node:process';
|
|
3
|
-
import { v as version } from '../../_/package.mjs';
|
|
1
|
+
import { d as defineEventHandler, v as version } from '../../nitro/nitro.mjs';
|
|
4
2
|
import 'node:http';
|
|
5
3
|
import 'node:https';
|
|
6
4
|
import 'node:events';
|
|
@@ -8,6 +6,11 @@ import 'node:buffer';
|
|
|
8
6
|
import 'node:fs';
|
|
9
7
|
import 'node:path';
|
|
10
8
|
import 'node:crypto';
|
|
9
|
+
import 'node:process';
|
|
10
|
+
import 'natural-orderby';
|
|
11
|
+
import 'execa';
|
|
12
|
+
import 'picocolors';
|
|
13
|
+
import 'node:os';
|
|
11
14
|
import 'node:perf_hooks';
|
|
12
15
|
import 'fs-extra';
|
|
13
16
|
import 'js-runtime';
|
|
@@ -15,20 +18,15 @@ import 'node:module';
|
|
|
15
18
|
import '@kubb/react-fabric';
|
|
16
19
|
import '@kubb/react-fabric/parsers';
|
|
17
20
|
import '@kubb/react-fabric/plugins';
|
|
18
|
-
import 'node:os';
|
|
19
21
|
import 'node:url';
|
|
20
22
|
import 'semver';
|
|
21
|
-
import 'natural-orderby';
|
|
22
|
-
import 'execa';
|
|
23
23
|
import 'string-argv';
|
|
24
24
|
import 'jiti';
|
|
25
|
-
import 'node:async_hooks';
|
|
26
25
|
|
|
27
|
-
const health_get = defineEventHandler(
|
|
26
|
+
const health_get = defineEventHandler(() => {
|
|
28
27
|
return {
|
|
29
28
|
status: "ok",
|
|
30
|
-
version
|
|
31
|
-
configPath: process.env.KUBB_CONFIG || ""
|
|
29
|
+
version
|
|
32
30
|
};
|
|
33
31
|
});
|
|
34
32
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.get.mjs","sources":["../../../../../server/routes/api/health.get.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health.get.mjs","sources":["../../../../../server/routes/api/health.get.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAOA,mBAAA,mBAAA,MAAA;AACA,EAAA,OAAA;AAAA,IACA,MAAA,EAAA,IAAA;AAAA,IACA;AAAA,GACA;AACA,CAAA,CAAA;;;;"}
|
package/.output/server/index.mjs
CHANGED
|
@@ -6,6 +6,11 @@ import 'node:buffer';
|
|
|
6
6
|
import 'node:fs';
|
|
7
7
|
import 'node:path';
|
|
8
8
|
import 'node:crypto';
|
|
9
|
+
import 'node:process';
|
|
10
|
+
import 'natural-orderby';
|
|
11
|
+
import 'execa';
|
|
12
|
+
import 'picocolors';
|
|
13
|
+
import 'node:os';
|
|
9
14
|
import 'node:perf_hooks';
|
|
10
15
|
import 'fs-extra';
|
|
11
16
|
import 'js-runtime';
|
|
@@ -13,13 +18,8 @@ import 'node:module';
|
|
|
13
18
|
import '@kubb/react-fabric';
|
|
14
19
|
import '@kubb/react-fabric/parsers';
|
|
15
20
|
import '@kubb/react-fabric/plugins';
|
|
16
|
-
import 'node:process';
|
|
17
|
-
import 'node:os';
|
|
18
21
|
import 'node:url';
|
|
19
22
|
import 'semver';
|
|
20
|
-
import 'natural-orderby';
|
|
21
|
-
import 'execa';
|
|
22
23
|
import 'string-argv';
|
|
23
24
|
import 'jiti';
|
|
24
|
-
import 'node:async_hooks';
|
|
25
25
|
//# sourceMappingURL=index.mjs.map
|
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# @kubb/agent
|
|
2
2
|
|
|
3
|
-
Kubb Agent Server — HTTP server for code generation powered by
|
|
3
|
+
Kubb Agent Server — HTTP server for code generation powered by [Nitro](https://nitro.build) with WebSocket integration for real-time Studio communication.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🚀 Fast HTTP server built with
|
|
7
|
+
- 🚀 Fast HTTP server built with [Nitro](https://nitro.build)
|
|
8
8
|
- 📡 RESTful API endpoints for code generation
|
|
9
9
|
- 🔧 Easy integration with Kubb configuration
|
|
10
10
|
- 📊 Health and info endpoints
|
|
11
|
+
- 🔗 Bidirectional WebSocket with Kubb Studio
|
|
12
|
+
- 💾 Automatic session caching for faster reconnects
|
|
11
13
|
- ⚡ Production-ready
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
@@ -31,33 +33,131 @@ kubb agent start --config kubb.config.ts
|
|
|
31
33
|
With custom options:
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
|
-
kubb agent start --config kubb.config.ts --host 0.0.0.0 --port 8080
|
|
36
|
+
kubb agent start --config kubb.config.ts --host 0.0.0.0 --port 8080 --no-cache
|
|
35
37
|
```
|
|
36
38
|
|
|
37
39
|
### Manual Server Start
|
|
38
40
|
|
|
39
41
|
If you need to start the server directly:
|
|
40
42
|
|
|
41
|
-
```bash
|
|
42
|
-
KUBB_CONFIG=./kubb.config.ts node packages/agent/.output/server/index.mjs
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Or if using the built package:
|
|
46
|
-
|
|
47
43
|
```bash
|
|
48
44
|
KUBB_CONFIG=./kubb.config.ts node node_modules/@kubb/agent/.output/server/index.mjs
|
|
49
45
|
```
|
|
50
46
|
|
|
51
|
-
The server will be available at `http://localhost:
|
|
47
|
+
The server will be available at `http://localhost:4000`.
|
|
52
48
|
|
|
53
49
|
### Environment Variables
|
|
54
50
|
|
|
55
51
|
- `KUBB_CONFIG` - **Required**. Path to your Kubb configuration file (e.g., `./kubb.config.ts` or `./kubb.config.js`). Supports both TypeScript and JavaScript files. Can be relative or absolute.
|
|
56
|
-
- `PORT` - Server port (default: `
|
|
52
|
+
- `PORT` - Server port (default: `4000`)
|
|
57
53
|
- `HOST` - Server host (default: `localhost`)
|
|
54
|
+
- `KUBB_STUDIO_URL` - Studio connection URL (e.g., `http://localhost:3000`)
|
|
55
|
+
- `KUBB_AGENT_TOKEN` - Authentication token for Studio connection
|
|
56
|
+
- `KUBB_AGENT_NO_CACHE` - Disable session caching (set to `true` to skip cache)
|
|
57
|
+
|
|
58
|
+
### Automatic .env Loading
|
|
59
|
+
|
|
60
|
+
The agent automatically loads environment variables from:
|
|
61
|
+
1. `.env` - Base environment variables
|
|
62
|
+
2. `.env.local` - Local overrides (for secrets/local config)
|
|
63
|
+
|
|
64
|
+
Files are optional and loaded in order, with `.env.local` taking precedence.
|
|
65
|
+
|
|
66
|
+
## Quick Start
|
|
67
|
+
|
|
68
|
+
1. **Create `.env` file:**
|
|
69
|
+
```env
|
|
70
|
+
PORT=4000
|
|
71
|
+
KUBB_ROOT=/Users/stijnvanhulle/GitHub/kubb/examples/react-query/
|
|
72
|
+
KUBB_CONFIG=/Users/stijnvanhulle/GitHub/kubb/examples/react-query/kubb.config.ts
|
|
73
|
+
KUBB_AGENT_TOKEN=
|
|
74
|
+
KUBB_AGENT_NO_CACHE=true
|
|
75
|
+
KUBB_STUDIO_URL=https://studio.kubb,dev
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
2. **Run the agent:**
|
|
79
|
+
```bash
|
|
80
|
+
npx kubb agent start
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
3. **Agent is now available at:**
|
|
84
|
+
```
|
|
85
|
+
http://localhost:4000
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## WebSocket Studio Integration
|
|
89
|
+
|
|
90
|
+
The agent automatically connects to Kubb Studio on startup:
|
|
91
|
+
|
|
92
|
+
### Connection Features
|
|
58
93
|
|
|
94
|
+
- **Automatic reconnection**: Caches session tokens to speed up reconnects
|
|
95
|
+
- **Real-time events**: Streams generation progress and events
|
|
96
|
+
- **Command handling**: Receives `generate` and `connect` commands from Studio
|
|
97
|
+
- **Graceful shutdown**: Notifies Studio when disconnecting
|
|
98
|
+
- **Session management**: 24-hour session expiration with auto-refresh
|
|
59
99
|
|
|
60
|
-
|
|
100
|
+
### Session Caching
|
|
101
|
+
|
|
102
|
+
Sessions are cached in `~/.kubb/config.json` for faster reconnects:
|
|
103
|
+
- Tokens are hashed (non-reversible) for security
|
|
104
|
+
- Sessions auto-expire after 24 hours
|
|
105
|
+
- Use `--no-cache` flag to disable caching
|
|
106
|
+
- Invalid sessions are automatically cleaned up
|
|
107
|
+
|
|
108
|
+
## WebSocket API
|
|
109
|
+
|
|
110
|
+
### Messages Sent by Agent
|
|
111
|
+
|
|
112
|
+
**Connected**
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"type": "connected",
|
|
116
|
+
"id": "unique-id",
|
|
117
|
+
"payload": {
|
|
118
|
+
"version": "4.24.0",
|
|
119
|
+
"config": { /* full kubb config */ },
|
|
120
|
+
"spec": "/* OpenAPI spec */"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Data Events (during generation)**
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"type": "data",
|
|
129
|
+
"id": "message-id",
|
|
130
|
+
"event": "plugin:start",
|
|
131
|
+
"payload": "{...}"
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Ping (every 30 seconds)**
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"type": "ping"
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Messages Received from Studio
|
|
143
|
+
|
|
144
|
+
**Generate Command**
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"type": "command",
|
|
148
|
+
"command": "generate"
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Connect Command (resend info)**
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"type": "command",
|
|
156
|
+
"command": "connect"
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Configuration Example
|
|
61
161
|
|
|
62
162
|
### 1. Create a Kubb configuration file (`kubb.config.ts`):
|
|
63
163
|
|
|
@@ -83,13 +183,7 @@ export default defineConfig({
|
|
|
83
183
|
### 2. Start the agent server:
|
|
84
184
|
|
|
85
185
|
```bash
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### 3. Trigger generation:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
curl -N http://localhost:3000/api/generate
|
|
186
|
+
npx kubb agent start
|
|
93
187
|
```
|
|
94
188
|
|
|
95
189
|
You'll receive a stream of events as the code generation progresses.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/agent",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.25.0",
|
|
4
4
|
"description": "Agent server for Kubb, enabling HTTP-based access to code generation capabilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -42,10 +42,12 @@
|
|
|
42
42
|
"execa": "^9.6.1",
|
|
43
43
|
"jiti": "^2.6.1",
|
|
44
44
|
"nitropack": "^2.13.1",
|
|
45
|
+
"picocolors": "^1.1.1",
|
|
45
46
|
"string-argv": "^0.3.2",
|
|
46
|
-
"@kubb/core": "4.
|
|
47
|
+
"@kubb/core": "4.25.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
50
|
+
"msw": "^2.6.10",
|
|
49
51
|
"vite": "^7.3.1"
|
|
50
52
|
},
|
|
51
53
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package.mjs","sources":[],"names":[],"mappings":";;;;"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { d as defineEventHandler } from '../../nitro/nitro.mjs';
|
|
2
|
-
import 'node:http';
|
|
3
|
-
import 'node:https';
|
|
4
|
-
import 'node:events';
|
|
5
|
-
import 'node:buffer';
|
|
6
|
-
import 'node:fs';
|
|
7
|
-
import 'node:path';
|
|
8
|
-
import 'node:crypto';
|
|
9
|
-
import 'node:perf_hooks';
|
|
10
|
-
import 'fs-extra';
|
|
11
|
-
import 'js-runtime';
|
|
12
|
-
import 'node:module';
|
|
13
|
-
import '@kubb/react-fabric';
|
|
14
|
-
import '@kubb/react-fabric/parsers';
|
|
15
|
-
import '@kubb/react-fabric/plugins';
|
|
16
|
-
import 'node:process';
|
|
17
|
-
import 'node:os';
|
|
18
|
-
import 'node:url';
|
|
19
|
-
import 'semver';
|
|
20
|
-
import 'natural-orderby';
|
|
21
|
-
import 'execa';
|
|
22
|
-
import 'string-argv';
|
|
23
|
-
import 'jiti';
|
|
24
|
-
import 'node:async_hooks';
|
|
25
|
-
|
|
26
|
-
const generate_options = defineEventHandler(() => {
|
|
27
|
-
return { ok: true };
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
export { generate_options as default };
|
|
31
|
-
//# sourceMappingURL=generate.options.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.options.mjs","sources":["../../../../../server/routes/api/generate.options.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yBAAA,mBAAA,MAAA;AAEA,EAAA,OAAA,EAAA,IAAA,IAAA,EAAA;AACA,CAAA,CAAA;;;;"}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { d as defineEventHandler, u as useKubbAgentContext, s as setHeaders } from '../../nitro/nitro.mjs';
|
|
2
|
-
import 'node:http';
|
|
3
|
-
import 'node:https';
|
|
4
|
-
import 'node:events';
|
|
5
|
-
import 'node:buffer';
|
|
6
|
-
import 'node:fs';
|
|
7
|
-
import 'node:path';
|
|
8
|
-
import 'node:crypto';
|
|
9
|
-
import 'node:perf_hooks';
|
|
10
|
-
import 'fs-extra';
|
|
11
|
-
import 'js-runtime';
|
|
12
|
-
import 'node:module';
|
|
13
|
-
import '@kubb/react-fabric';
|
|
14
|
-
import '@kubb/react-fabric/parsers';
|
|
15
|
-
import '@kubb/react-fabric/plugins';
|
|
16
|
-
import 'node:process';
|
|
17
|
-
import 'node:os';
|
|
18
|
-
import 'node:url';
|
|
19
|
-
import 'semver';
|
|
20
|
-
import 'natural-orderby';
|
|
21
|
-
import 'execa';
|
|
22
|
-
import 'string-argv';
|
|
23
|
-
import 'jiti';
|
|
24
|
-
import 'node:async_hooks';
|
|
25
|
-
|
|
26
|
-
const generate_post = defineEventHandler(async (event) => {
|
|
27
|
-
const { events, onGenerate } = useKubbAgentContext();
|
|
28
|
-
setHeaders(event, {
|
|
29
|
-
"Content-Type": "text/event-stream",
|
|
30
|
-
"Cache-Control": "no-cache",
|
|
31
|
-
Connection: "keep-alive"
|
|
32
|
-
});
|
|
33
|
-
const stream = new ReadableStream({
|
|
34
|
-
start(controller) {
|
|
35
|
-
const queue = [];
|
|
36
|
-
let draining = false;
|
|
37
|
-
function send2(type, ...data) {
|
|
38
|
-
const sseEvent = { type, data, timestamp: Date.now() };
|
|
39
|
-
const message = `data: ${JSON.stringify(sseEvent)}
|
|
40
|
-
|
|
41
|
-
`;
|
|
42
|
-
queue.push(message);
|
|
43
|
-
drain();
|
|
44
|
-
}
|
|
45
|
-
async function drain() {
|
|
46
|
-
if (draining) return;
|
|
47
|
-
draining = true;
|
|
48
|
-
while (queue.length > 0) {
|
|
49
|
-
const message = queue.shift();
|
|
50
|
-
if (message) {
|
|
51
|
-
controller.enqueue(message);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
draining = false;
|
|
55
|
-
}
|
|
56
|
-
events.on("plugin:start", (plugin) => send2("plugin:start", plugin));
|
|
57
|
-
events.on("plugin:end", (plugin, meta) => send2("plugin:end", plugin, meta));
|
|
58
|
-
events.on("files:processing:start", (files) => send2("files:processing:start", { total: files.length }));
|
|
59
|
-
events.on("file:processing:update", (meta) => {
|
|
60
|
-
send2("file:processing:update", {
|
|
61
|
-
file: meta.file.path,
|
|
62
|
-
processed: meta.processed,
|
|
63
|
-
total: meta.total,
|
|
64
|
-
percentage: meta.percentage
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
events.on("files:processing:end", (files) => send2("files:processing:end", { total: files.length }));
|
|
68
|
-
events.on("info", (message, info) => send2("info", message, info));
|
|
69
|
-
events.on("success", (message, info) => send2("success", message, info));
|
|
70
|
-
events.on("warn", (message, info) => send2("warn", message, info));
|
|
71
|
-
events.on("generation:start", (config) => {
|
|
72
|
-
var _a;
|
|
73
|
-
send2("generation:start", {
|
|
74
|
-
name: config.name,
|
|
75
|
-
plugins: ((_a = config.plugins) == null ? void 0 : _a.length) || 0
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
events.on("generation:end", (config, files, sources) => {
|
|
79
|
-
const sourcesRecord = {};
|
|
80
|
-
sources.forEach((value, key) => {
|
|
81
|
-
sourcesRecord[key] = value;
|
|
82
|
-
});
|
|
83
|
-
send2("generation:end", config, files, sourcesRecord);
|
|
84
|
-
});
|
|
85
|
-
events.on("error", (error) => {
|
|
86
|
-
send2("error", {
|
|
87
|
-
message: error.message,
|
|
88
|
-
stack: error.stack
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
onGenerate().catch((error) => {
|
|
92
|
-
const sseEvent = {
|
|
93
|
-
type: "error",
|
|
94
|
-
data: [
|
|
95
|
-
{
|
|
96
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
97
|
-
stack: error instanceof Error ? error.stack : void 0
|
|
98
|
-
}
|
|
99
|
-
],
|
|
100
|
-
timestamp: Date.now()
|
|
101
|
-
};
|
|
102
|
-
queue.push(`data: ${JSON.stringify(sseEvent)}
|
|
103
|
-
|
|
104
|
-
`);
|
|
105
|
-
}).finally(() => {
|
|
106
|
-
const endEvent = { type: "lifecycle:end", data: [], timestamp: Date.now() };
|
|
107
|
-
queue.push(`data: ${JSON.stringify(endEvent)}
|
|
108
|
-
|
|
109
|
-
`);
|
|
110
|
-
drain().then(() => {
|
|
111
|
-
controller.close();
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
return stream;
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
export { generate_post as default };
|
|
120
|
-
//# sourceMappingURL=generate.post.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.post.mjs","sources":["../../../../../server/routes/api/generate.post.ts"],"names":["send"],"mappings":"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"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { d as defineEventHandler, u as useKubbAgentContext, a as serializePluginOptions } from '../../nitro/nitro.mjs';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import process from 'node:process';
|
|
5
|
-
import { v as version } from '../../_/package.mjs';
|
|
6
|
-
import 'node:http';
|
|
7
|
-
import 'node:https';
|
|
8
|
-
import 'node:events';
|
|
9
|
-
import 'node:buffer';
|
|
10
|
-
import 'node:crypto';
|
|
11
|
-
import 'node:perf_hooks';
|
|
12
|
-
import 'fs-extra';
|
|
13
|
-
import 'js-runtime';
|
|
14
|
-
import 'node:module';
|
|
15
|
-
import '@kubb/react-fabric';
|
|
16
|
-
import '@kubb/react-fabric/parsers';
|
|
17
|
-
import '@kubb/react-fabric/plugins';
|
|
18
|
-
import 'node:os';
|
|
19
|
-
import 'node:url';
|
|
20
|
-
import 'semver';
|
|
21
|
-
import 'natural-orderby';
|
|
22
|
-
import 'execa';
|
|
23
|
-
import 'string-argv';
|
|
24
|
-
import 'jiti';
|
|
25
|
-
import 'node:async_hooks';
|
|
26
|
-
|
|
27
|
-
const info_get = defineEventHandler(async () => {
|
|
28
|
-
var _a;
|
|
29
|
-
const { config } = useKubbAgentContext();
|
|
30
|
-
let specContent;
|
|
31
|
-
if (config && "path" in config.input) {
|
|
32
|
-
const specPath = path.resolve(process.cwd(), config.root, config.input.path);
|
|
33
|
-
try {
|
|
34
|
-
specContent = readFileSync(specPath, "utf-8");
|
|
35
|
-
} catch {
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
version,
|
|
40
|
-
configPath: process.env.KUBB_CONFIG || "",
|
|
41
|
-
spec: specContent,
|
|
42
|
-
config: {
|
|
43
|
-
name: config.name,
|
|
44
|
-
root: config.root,
|
|
45
|
-
input: {
|
|
46
|
-
path: "path" in config.input ? config.input.path : void 0
|
|
47
|
-
},
|
|
48
|
-
output: {
|
|
49
|
-
path: config.output.path,
|
|
50
|
-
write: config.output.write,
|
|
51
|
-
extension: config.output.extension,
|
|
52
|
-
barrelType: config.output.barrelType
|
|
53
|
-
},
|
|
54
|
-
plugins: (_a = config.plugins) == null ? void 0 : _a.map((plugin) => ({
|
|
55
|
-
name: `@kubb/${plugin.name}`,
|
|
56
|
-
options: serializePluginOptions(plugin.options)
|
|
57
|
-
}))
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
export { info_get as default };
|
|
63
|
-
//# sourceMappingURL=info.get.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"info.get.mjs","sources":["../../../../../server/routes/api/info.get.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,iBAAA,mBAAA,YAAA;;AACA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,mBAAA,EAAA;AAGA,EAAA,IAAA,WAAA;AACA,EAAA,IAAA,MAAA,IAAA,MAAA,IAAA,MAAA,CAAA,KAAA,EAAA;AACA,IAAA,MAAA,QAAA,GAAA,IAAA,CAAA,OAAA,CAAA,OAAA,CAAA,GAAA,IAAA,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,KAAA,CAAA,IAAA,CAAA;AACA,IAAA,IAAA;AACA,MAAA,WAAA,GAAA,YAAA,CAAA,UAAA,OAAA,CAAA;AAAA,IACA,CAAA,CAAA,MAAA;AAAA,IAEA;AAAA,EACA;AAEA,EAAA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA,EAAA,OAAA,CAAA,GAAA,CAAA,WAAA,IAAA,EAAA;AAAA,IACA,IAAA,EAAA,WAAA;AAAA,IACA,MAAA,EAAA;AAAA,MACA,MAAA,MAAA,CAAA,IAAA;AAAA,MACA,MAAA,MAAA,CAAA,IAAA;AAAA,MACA,KAAA,EAAA;AAAA,QACA,MAAA,MAAA,IAAA,MAAA,CAAA,KAAA,GAAA,MAAA,CAAA,MAAA,IAAA,GAAA;AAAA,OACA;AAAA,MACA,MAAA,EAAA;AAAA,QACA,IAAA,EAAA,OAAA,MAAA,CAAA,IAAA;AAAA,QACA,KAAA,EAAA,OAAA,MAAA,CAAA,KAAA;AAAA,QACA,SAAA,EAAA,OAAA,MAAA,CAAA,SAAA;AAAA,QACA,UAAA,EAAA,OAAA,MAAA,CAAA;AAAA,OACA;AAAA,MACA,UAAA,EAAA,GAAA,MAAA,CAAA,OAAA,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,GAAA,CAAA,CAAA,MAAA,MAAA;AAAA,QACA,IAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,IAAA,CAAA,CAAA;AAAA,QACA,OAAA,EAAA,sBAAA,CAAA,MAAA,CAAA,OAAA;AAAA,OACA,CAAA;AAAA;AACA,GACA;AACA,CAAA,CAAA;;;;"}
|