@agentuity/cli 0.0.95 → 0.0.97

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 (267) hide show
  1. package/AGENTS.md +84 -0
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +8 -5
  5. package/dist/auth.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +190 -27
  8. package/dist/cli.js.map +1 -1
  9. package/dist/cmd/build/entry-generator.d.ts +20 -0
  10. package/dist/cmd/build/entry-generator.d.ts.map +1 -0
  11. package/dist/cmd/build/entry-generator.js +366 -0
  12. package/dist/cmd/build/entry-generator.js.map +1 -0
  13. package/dist/cmd/build/index.d.ts.map +1 -1
  14. package/dist/cmd/build/index.js +5 -23
  15. package/dist/cmd/build/index.js.map +1 -1
  16. package/dist/cmd/build/vite/agent-discovery.d.ts +33 -0
  17. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -0
  18. package/dist/cmd/build/vite/agent-discovery.js +297 -0
  19. package/dist/cmd/build/vite/agent-discovery.js.map +1 -0
  20. package/dist/cmd/build/vite/browser-env-plugin.d.ts +9 -0
  21. package/dist/cmd/build/vite/browser-env-plugin.d.ts.map +1 -0
  22. package/dist/cmd/build/vite/browser-env-plugin.js +28 -0
  23. package/dist/cmd/build/vite/browser-env-plugin.js.map +1 -0
  24. package/dist/cmd/build/vite/bun-dev-server.d.ts +29 -0
  25. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -0
  26. package/dist/cmd/build/vite/bun-dev-server.js +54 -0
  27. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -0
  28. package/dist/cmd/build/vite/config-loader.d.ts +23 -0
  29. package/dist/cmd/build/vite/config-loader.d.ts.map +1 -0
  30. package/dist/cmd/build/vite/config-loader.js +50 -0
  31. package/dist/cmd/build/vite/config-loader.js.map +1 -0
  32. package/dist/cmd/build/vite/index.d.ts +26 -0
  33. package/dist/cmd/build/vite/index.d.ts.map +1 -0
  34. package/dist/cmd/build/vite/index.js +127 -0
  35. package/dist/cmd/build/vite/index.js.map +1 -0
  36. package/dist/cmd/build/vite/lifecycle-generator.d.ts +11 -0
  37. package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -0
  38. package/dist/cmd/build/vite/lifecycle-generator.js +35 -0
  39. package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -0
  40. package/dist/cmd/build/vite/metadata-generator.d.ts +32 -0
  41. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -0
  42. package/dist/cmd/build/vite/metadata-generator.js +489 -0
  43. package/dist/cmd/build/vite/metadata-generator.js.map +1 -0
  44. package/dist/cmd/build/vite/patch-plugin.d.ts +21 -0
  45. package/dist/cmd/build/vite/patch-plugin.d.ts.map +1 -0
  46. package/dist/cmd/build/vite/patch-plugin.js +70 -0
  47. package/dist/cmd/build/vite/patch-plugin.js.map +1 -0
  48. package/dist/cmd/build/vite/registry-generator.d.ts +19 -0
  49. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -0
  50. package/dist/cmd/build/{route-registry.js → vite/registry-generator.js} +126 -48
  51. package/dist/cmd/build/vite/registry-generator.js.map +1 -0
  52. package/dist/cmd/build/vite/route-discovery.d.ts +58 -0
  53. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -0
  54. package/dist/cmd/build/vite/route-discovery.js +125 -0
  55. package/dist/cmd/build/vite/route-discovery.js.map +1 -0
  56. package/dist/cmd/build/vite/server-bundler.d.ts +16 -0
  57. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -0
  58. package/dist/cmd/build/vite/server-bundler.js +194 -0
  59. package/dist/cmd/build/vite/server-bundler.js.map +1 -0
  60. package/dist/cmd/build/vite/vite-asset-server-config.d.ts +19 -0
  61. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -0
  62. package/dist/cmd/build/vite/vite-asset-server-config.js +105 -0
  63. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -0
  64. package/dist/cmd/build/vite/vite-asset-server.d.ts +23 -0
  65. package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -0
  66. package/dist/cmd/build/vite/vite-asset-server.js +41 -0
  67. package/dist/cmd/build/vite/vite-asset-server.js.map +1 -0
  68. package/dist/cmd/build/vite/vite-builder.d.ts +44 -0
  69. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -0
  70. package/dist/cmd/build/vite/vite-builder.js +234 -0
  71. package/dist/cmd/build/vite/vite-builder.js.map +1 -0
  72. package/dist/cmd/build/vite/workbench-generator.d.ts +10 -0
  73. package/dist/cmd/build/vite/workbench-generator.d.ts.map +1 -0
  74. package/dist/cmd/build/vite/workbench-generator.js +135 -0
  75. package/dist/cmd/build/vite/workbench-generator.js.map +1 -0
  76. package/dist/cmd/build/vite-bundler.d.ts +23 -0
  77. package/dist/cmd/build/vite-bundler.d.ts.map +1 -0
  78. package/dist/cmd/build/vite-bundler.js +79 -0
  79. package/dist/cmd/build/vite-bundler.js.map +1 -0
  80. package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
  81. package/dist/cmd/cloud/agent/get.js +1 -0
  82. package/dist/cmd/cloud/agent/get.js.map +1 -1
  83. package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
  84. package/dist/cmd/cloud/agent/list.js +1 -0
  85. package/dist/cmd/cloud/agent/list.js.map +1 -1
  86. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  87. package/dist/cmd/cloud/db/get.js +1 -0
  88. package/dist/cmd/cloud/db/get.js.map +1 -1
  89. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  90. package/dist/cmd/cloud/db/list.js +1 -0
  91. package/dist/cmd/cloud/db/list.js.map +1 -1
  92. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  93. package/dist/cmd/cloud/deploy.js +152 -128
  94. package/dist/cmd/cloud/deploy.js.map +1 -1
  95. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  96. package/dist/cmd/cloud/deployment/list.js +4 -0
  97. package/dist/cmd/cloud/deployment/list.js.map +1 -1
  98. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  99. package/dist/cmd/cloud/env/list.js +1 -0
  100. package/dist/cmd/cloud/env/list.js.map +1 -1
  101. package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
  102. package/dist/cmd/cloud/keyvalue/get.js +1 -0
  103. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  104. package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
  105. package/dist/cmd/cloud/keyvalue/keys.js +1 -0
  106. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  107. package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
  108. package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -0
  109. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  110. package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
  111. package/dist/cmd/cloud/keyvalue/stats.js +1 -0
  112. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  113. package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
  114. package/dist/cmd/cloud/secret/list.js +1 -0
  115. package/dist/cmd/cloud/secret/list.js.map +1 -1
  116. package/dist/cmd/cloud/session/list.d.ts.map +1 -1
  117. package/dist/cmd/cloud/session/list.js +4 -0
  118. package/dist/cmd/cloud/session/list.js.map +1 -1
  119. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  120. package/dist/cmd/cloud/storage/get.js +1 -0
  121. package/dist/cmd/cloud/storage/get.js.map +1 -1
  122. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  123. package/dist/cmd/cloud/storage/list.js +3 -0
  124. package/dist/cmd/cloud/storage/list.js.map +1 -1
  125. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  126. package/dist/cmd/cloud/stream/get.js +1 -0
  127. package/dist/cmd/cloud/stream/get.js.map +1 -1
  128. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  129. package/dist/cmd/cloud/stream/list.js +1 -0
  130. package/dist/cmd/cloud/stream/list.js.map +1 -1
  131. package/dist/cmd/cloud/vector/get.d.ts.map +1 -1
  132. package/dist/cmd/cloud/vector/get.js +1 -0
  133. package/dist/cmd/cloud/vector/get.js.map +1 -1
  134. package/dist/cmd/cloud/vector/search.d.ts.map +1 -1
  135. package/dist/cmd/cloud/vector/search.js +1 -0
  136. package/dist/cmd/cloud/vector/search.js.map +1 -1
  137. package/dist/cmd/dev/index.d.ts.map +1 -1
  138. package/dist/cmd/dev/index.js +289 -758
  139. package/dist/cmd/dev/index.js.map +1 -1
  140. package/dist/cmd/dev/sync.d.ts +1 -1
  141. package/dist/cmd/dev/sync.d.ts.map +1 -1
  142. package/dist/cmd/dev/sync.js +3 -0
  143. package/dist/cmd/dev/sync.js.map +1 -1
  144. package/dist/cmd/profile/show.d.ts.map +1 -1
  145. package/dist/cmd/profile/show.js +3 -4
  146. package/dist/cmd/profile/show.js.map +1 -1
  147. package/dist/cmd/project/create.d.ts.map +1 -1
  148. package/dist/cmd/project/create.js +3 -4
  149. package/dist/cmd/project/create.js.map +1 -1
  150. package/dist/cmd/project/list.d.ts.map +1 -1
  151. package/dist/cmd/project/list.js +1 -0
  152. package/dist/cmd/project/list.js.map +1 -1
  153. package/dist/cmd/project/show.d.ts.map +1 -1
  154. package/dist/cmd/project/show.js +1 -0
  155. package/dist/cmd/project/show.js.map +1 -1
  156. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  157. package/dist/cmd/upgrade/index.js +43 -7
  158. package/dist/cmd/upgrade/index.js.map +1 -1
  159. package/dist/config.d.ts +1 -1
  160. package/dist/config.d.ts.map +1 -1
  161. package/dist/config.js +29 -11
  162. package/dist/config.js.map +1 -1
  163. package/dist/index.d.ts +1 -1
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js.map +1 -1
  166. package/dist/runtime-bootstrap.d.ts +3 -2
  167. package/dist/runtime-bootstrap.d.ts.map +1 -1
  168. package/dist/runtime-bootstrap.js +7 -2
  169. package/dist/runtime-bootstrap.js.map +1 -1
  170. package/dist/schemas/deploy.d.ts +1 -1
  171. package/dist/types.d.ts +40 -1
  172. package/dist/types.d.ts.map +1 -1
  173. package/dist/types.js.map +1 -1
  174. package/dist/utils/bun-version-checker.d.ts +11 -0
  175. package/dist/utils/bun-version-checker.d.ts.map +1 -0
  176. package/dist/utils/bun-version-checker.js +56 -0
  177. package/dist/utils/bun-version-checker.js.map +1 -0
  178. package/dist/version-check.d.ts.map +1 -1
  179. package/dist/version-check.js +5 -2
  180. package/dist/version-check.js.map +1 -1
  181. package/package.json +11 -3
  182. package/src/auth.ts +9 -5
  183. package/src/cli.ts +228 -29
  184. package/src/cmd/build/entry-generator.ts +404 -0
  185. package/src/cmd/build/index.ts +7 -28
  186. package/src/cmd/build/vite/agent-discovery.ts +467 -0
  187. package/src/cmd/build/vite/browser-env-plugin.ts +34 -0
  188. package/src/cmd/build/vite/bun-dev-server.ts +78 -0
  189. package/src/cmd/build/vite/config-loader.ts +70 -0
  190. package/src/cmd/build/vite/index.ts +166 -0
  191. package/src/cmd/build/vite/lifecycle-generator.ts +43 -0
  192. package/src/cmd/build/vite/metadata-generator.ts +602 -0
  193. package/src/cmd/build/vite/patch-plugin.ts +88 -0
  194. package/src/cmd/build/vite/registry-generator.ts +288 -0
  195. package/src/cmd/build/vite/route-discovery.ts +186 -0
  196. package/src/cmd/build/vite/server-bundler.ts +258 -0
  197. package/src/cmd/build/vite/vite-asset-server-config.ts +134 -0
  198. package/src/cmd/build/vite/vite-asset-server.ts +66 -0
  199. package/src/cmd/build/vite/vite-builder.ts +288 -0
  200. package/src/cmd/build/vite/workbench-generator.ts +152 -0
  201. package/src/cmd/build/vite-bundler.ts +110 -0
  202. package/src/cmd/cloud/agent/get.ts +2 -0
  203. package/src/cmd/cloud/agent/list.ts +1 -0
  204. package/src/cmd/cloud/db/get.ts +1 -0
  205. package/src/cmd/cloud/db/list.ts +1 -0
  206. package/src/cmd/cloud/deploy.ts +175 -144
  207. package/src/cmd/cloud/deployment/list.ts +4 -0
  208. package/src/cmd/cloud/env/list.ts +1 -0
  209. package/src/cmd/cloud/keyvalue/get.ts +1 -0
  210. package/src/cmd/cloud/keyvalue/keys.ts +1 -0
  211. package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -0
  212. package/src/cmd/cloud/keyvalue/stats.ts +2 -0
  213. package/src/cmd/cloud/secret/list.ts +1 -0
  214. package/src/cmd/cloud/session/list.ts +4 -0
  215. package/src/cmd/cloud/storage/get.ts +1 -0
  216. package/src/cmd/cloud/storage/list.ts +4 -0
  217. package/src/cmd/cloud/stream/get.ts +1 -0
  218. package/src/cmd/cloud/stream/list.ts +1 -0
  219. package/src/cmd/cloud/vector/get.ts +1 -0
  220. package/src/cmd/cloud/vector/search.ts +1 -0
  221. package/src/cmd/dev/index.ts +319 -921
  222. package/src/cmd/dev/sync.ts +5 -1
  223. package/src/cmd/profile/show.ts +3 -4
  224. package/src/cmd/project/create.ts +3 -4
  225. package/src/cmd/project/list.ts +1 -0
  226. package/src/cmd/project/show.ts +1 -0
  227. package/src/cmd/upgrade/index.ts +52 -8
  228. package/src/config.ts +31 -11
  229. package/src/index.ts +2 -0
  230. package/src/runtime-bootstrap.ts +8 -2
  231. package/src/types.ts +48 -1
  232. package/src/utils/bun-version-checker.ts +70 -0
  233. package/src/version-check.ts +6 -2
  234. package/dist/cmd/build/bundler.d.ts +0 -28
  235. package/dist/cmd/build/bundler.d.ts.map +0 -1
  236. package/dist/cmd/build/bundler.js +0 -800
  237. package/dist/cmd/build/bundler.js.map +0 -1
  238. package/dist/cmd/build/config-loader.d.ts +0 -16
  239. package/dist/cmd/build/config-loader.d.ts.map +0 -1
  240. package/dist/cmd/build/config-loader.js +0 -227
  241. package/dist/cmd/build/config-loader.js.map +0 -1
  242. package/dist/cmd/build/file.d.ts +0 -2
  243. package/dist/cmd/build/file.d.ts.map +0 -1
  244. package/dist/cmd/build/file.js +0 -10
  245. package/dist/cmd/build/file.js.map +0 -1
  246. package/dist/cmd/build/fix-duplicate-exports.d.ts +0 -2
  247. package/dist/cmd/build/fix-duplicate-exports.d.ts.map +0 -1
  248. package/dist/cmd/build/fix-duplicate-exports.js +0 -170
  249. package/dist/cmd/build/fix-duplicate-exports.js.map +0 -1
  250. package/dist/cmd/build/plugin.d.ts +0 -6
  251. package/dist/cmd/build/plugin.d.ts.map +0 -1
  252. package/dist/cmd/build/plugin.js +0 -645
  253. package/dist/cmd/build/plugin.js.map +0 -1
  254. package/dist/cmd/build/route-discovery.d.ts +0 -54
  255. package/dist/cmd/build/route-discovery.d.ts.map +0 -1
  256. package/dist/cmd/build/route-discovery.js +0 -148
  257. package/dist/cmd/build/route-discovery.js.map +0 -1
  258. package/dist/cmd/build/route-registry.d.ts +0 -38
  259. package/dist/cmd/build/route-registry.d.ts.map +0 -1
  260. package/dist/cmd/build/route-registry.js.map +0 -1
  261. package/src/cmd/build/bundler.ts +0 -965
  262. package/src/cmd/build/config-loader.ts +0 -268
  263. package/src/cmd/build/file.ts +0 -10
  264. package/src/cmd/build/fix-duplicate-exports.ts +0 -207
  265. package/src/cmd/build/plugin.ts +0 -782
  266. package/src/cmd/build/route-discovery.ts +0 -202
  267. package/src/cmd/build/route-registry.ts +0 -222
@@ -0,0 +1,602 @@
1
+ /**
2
+ * Metadata Generator
3
+ *
4
+ * Generates agentuity.metadata.json and .routemapping.json from discovered agents and routes
5
+ */
6
+
7
+ import { join, dirname } from 'node:path';
8
+ import { writeFileSync, mkdirSync, existsSync, readFileSync, statSync, readdirSync } from 'node:fs';
9
+ import type { BuildMetadata } from '@agentuity/server';
10
+ import type { AgentMetadata } from './agent-discovery';
11
+ import type { RouteMetadata } from './route-discovery';
12
+ import type { Logger } from '../../../types';
13
+ import { getVersion } from '../../../version';
14
+
15
+ interface ViteManifestEntry {
16
+ file: string;
17
+ src?: string;
18
+ isEntry?: boolean;
19
+ css?: string[];
20
+ assets?: string[];
21
+ }
22
+
23
+ interface AssetInfo {
24
+ filename: string;
25
+ kind: string;
26
+ contentType: string;
27
+ size: number;
28
+ }
29
+
30
+ function getContentType(filename: string): string {
31
+ const ext = filename.split('.').pop()?.toLowerCase();
32
+ switch (ext) {
33
+ case 'js':
34
+ case 'mjs':
35
+ return 'application/javascript';
36
+ case 'css':
37
+ return 'text/css';
38
+ case 'html':
39
+ return 'text/html';
40
+ case 'json':
41
+ return 'application/json';
42
+ case 'png':
43
+ return 'image/png';
44
+ case 'jpg':
45
+ case 'jpeg':
46
+ return 'image/jpeg';
47
+ case 'gif':
48
+ return 'image/gif';
49
+ case 'svg':
50
+ return 'image/svg+xml';
51
+ case 'webp':
52
+ return 'image/webp';
53
+ case 'ico':
54
+ return 'image/x-icon';
55
+ case 'woff':
56
+ return 'font/woff';
57
+ case 'woff2':
58
+ return 'font/woff2';
59
+ case 'ttf':
60
+ return 'font/ttf';
61
+ case 'eot':
62
+ return 'application/vnd.ms-fontobject';
63
+ default:
64
+ return 'application/octet-stream';
65
+ }
66
+ }
67
+
68
+ function getAssetKind(filename: string, isEntry: boolean = false): string {
69
+ const ext = filename.split('.').pop()?.toLowerCase();
70
+
71
+ // Check for sourcemap
72
+ if (filename.endsWith('.js.map') || filename.endsWith('.css.map')) {
73
+ return 'sourcemap';
74
+ }
75
+
76
+ switch (ext) {
77
+ case 'js':
78
+ case 'mjs':
79
+ // Distinguish entry-point from regular scripts
80
+ return isEntry ? 'entry-point' : 'script';
81
+ case 'css':
82
+ return 'stylesheet';
83
+ case 'png':
84
+ case 'jpg':
85
+ case 'jpeg':
86
+ case 'gif':
87
+ case 'svg':
88
+ case 'webp':
89
+ return 'image';
90
+ case 'ico':
91
+ return 'asset';
92
+ case 'woff':
93
+ case 'woff2':
94
+ case 'ttf':
95
+ case 'eot':
96
+ return 'font';
97
+ default:
98
+ return 'other';
99
+ }
100
+ }
101
+
102
+ export interface MetadataGeneratorOptions {
103
+ rootDir: string;
104
+ projectId: string;
105
+ orgId?: string;
106
+ deploymentId?: string;
107
+ agents: AgentMetadata[];
108
+ routes: RouteMetadata[];
109
+ dev?: boolean;
110
+ logger: Logger;
111
+ }
112
+
113
+ /**
114
+ * Normalize an agent filename/import path into a key for lookup
115
+ */
116
+ function normalizeImportKey(path: string): string {
117
+ // Strip leading './' or 'src/' or '@'
118
+ let p = path.replace(/^src\//, '');
119
+ if (p.startsWith('./')) p = p.slice(2);
120
+ if (p.startsWith('@')) p = p.slice(1);
121
+
122
+ // Drop extension
123
+ p = p.replace(/\.(t|j)sx?$/, '');
124
+
125
+ // Drop common module file suffixes (agent.ts, index.ts become just the directory)
126
+ p = p.replace(/\/(agent|index)$/, '');
127
+
128
+ return p;
129
+ }
130
+
131
+ /**
132
+ * Generate agentuity.metadata.json
133
+ */
134
+ export async function generateMetadata(options: MetadataGeneratorOptions): Promise<BuildMetadata> {
135
+ const { rootDir, projectId, orgId = '', agents, routes, logger } = options;
136
+
137
+ // Build agent lookup by import path for route schema enrichment
138
+ const agentsByImportKey = new Map<string, AgentMetadata>();
139
+ for (const agent of agents) {
140
+ if (!agent.filename) continue;
141
+ const key = normalizeImportKey(agent.filename);
142
+ agentsByImportKey.set(key, agent);
143
+ logger.trace(`Agent lookup: ${key} -> ${agent.name}`);
144
+ }
145
+
146
+ // Enrich routes with schemas from agents (if not already set)
147
+ const enrichedRoutes = routes.map((route) => {
148
+ let schema = route.schema ? { ...route.schema } : undefined;
149
+
150
+ const importPath = route.config?.agentImportPath as string | undefined;
151
+
152
+ if (importPath) {
153
+ const key = normalizeImportKey(importPath);
154
+ const agent = agentsByImportKey.get(key);
155
+
156
+ if (agent && (agent.inputSchemaCode || agent.outputSchemaCode)) {
157
+ // Initialize schema object if needed
158
+ if (!schema) schema = {};
159
+
160
+ // Only fill in missing pieces; allow explicit route schema to override
161
+ if (!schema.input && agent.inputSchemaCode) {
162
+ schema.input = agent.inputSchemaCode;
163
+ logger.trace(`Route ${route.path}: added input schema from agent ${agent.name}`);
164
+ }
165
+ if (!schema.output && agent.outputSchemaCode) {
166
+ schema.output = agent.outputSchemaCode;
167
+ logger.trace(`Route ${route.path}: added output schema from agent ${agent.name}`);
168
+ }
169
+ } else {
170
+ logger.trace(`No agent found for import path ${importPath} in route ${route.filename}`);
171
+ }
172
+ }
173
+
174
+ return {
175
+ ...route,
176
+ schema,
177
+ };
178
+ });
179
+
180
+ // Read package.json for project metadata
181
+ const pkgPath = join(rootDir, 'package.json');
182
+ let pkgContents: {
183
+ name?: string;
184
+ version?: string;
185
+ description?: string;
186
+ keywords?: string[];
187
+ dependencies?: Record<string, string>;
188
+ } = {};
189
+
190
+ if (existsSync(pkgPath)) {
191
+ try {
192
+ const pkgText = Bun.file(pkgPath);
193
+ pkgContents = JSON.parse(await pkgText.text());
194
+ } catch (error) {
195
+ logger.warn(`Failed to read package.json: ${error}`);
196
+ }
197
+ }
198
+
199
+ // Read asset manifests from Vite builds
200
+ const assets: AssetInfo[] = [];
201
+ const agentuityDir = join(rootDir, '.agentuity');
202
+ const seenAssets = new Set<string>(); // Track unique assets to avoid duplicates
203
+
204
+ // Helper to add asset with metadata
205
+ const addAsset = (relativePath: string, prefix: string, isEntry: boolean = false) => {
206
+ const assetPath = `${prefix}/${relativePath}`;
207
+
208
+ // Skip if already added
209
+ if (seenAssets.has(assetPath)) {
210
+ return;
211
+ }
212
+
213
+ const fullPath = join(agentuityDir, prefix, relativePath);
214
+ if (existsSync(fullPath)) {
215
+ const stats = statSync(fullPath);
216
+
217
+ // Skip empty marker files (.gitkeep, .keep, etc.)
218
+ if (stats.size === 0) {
219
+ return;
220
+ }
221
+
222
+ seenAssets.add(assetPath);
223
+ assets.push({
224
+ filename: assetPath,
225
+ kind: getAssetKind(relativePath, isEntry),
226
+ contentType: getContentType(relativePath),
227
+ size: stats.size,
228
+ });
229
+ }
230
+ };
231
+
232
+ // Read client manifest
233
+ const clientManifestPath = join(agentuityDir, 'client', '.vite', 'manifest.json');
234
+ if (existsSync(clientManifestPath)) {
235
+ try {
236
+ const clientManifest: Record<string, ViteManifestEntry> = JSON.parse(
237
+ readFileSync(clientManifestPath, 'utf-8')
238
+ );
239
+ for (const entry of Object.values(clientManifest)) {
240
+ // Mark JS files as entry-point if they are entry files
241
+ const isEntry = entry.isEntry === true && entry.file.endsWith('.js');
242
+ addAsset(entry.file, 'client', isEntry);
243
+
244
+ // Add sourcemap if it exists
245
+ const sourcemapPath = entry.file + '.map';
246
+ const fullSourcemapPath = join(agentuityDir, 'client', sourcemapPath);
247
+ if (existsSync(fullSourcemapPath)) {
248
+ addAsset(sourcemapPath, 'client');
249
+ }
250
+
251
+ if (entry.css) {
252
+ entry.css.forEach((css) => {
253
+ addAsset(css, 'client');
254
+ // Add CSS sourcemap if it exists
255
+ const cssMapPath = css + '.map';
256
+ const fullCssMapPath = join(agentuityDir, 'client', cssMapPath);
257
+ if (existsSync(fullCssMapPath)) {
258
+ addAsset(cssMapPath, 'client');
259
+ }
260
+ });
261
+ }
262
+ if (entry.assets) {
263
+ entry.assets.forEach((asset) => addAsset(asset, 'client'));
264
+ }
265
+ }
266
+ logger.trace(`Found ${assets.length} client assets from manifest`);
267
+ } catch (error) {
268
+ logger.warn(`Failed to read client manifest: ${error}`);
269
+ }
270
+ }
271
+
272
+ // Read workbench manifest (optional)
273
+ const workbenchManifestPath = join(agentuityDir, 'workbench', '.vite', 'manifest.json');
274
+ if (existsSync(workbenchManifestPath)) {
275
+ try {
276
+ const workbenchManifest: Record<string, ViteManifestEntry> = JSON.parse(
277
+ readFileSync(workbenchManifestPath, 'utf-8')
278
+ );
279
+ for (const entry of Object.values(workbenchManifest)) {
280
+ const isEntry = entry.isEntry === true && entry.file.endsWith('.js');
281
+ addAsset(entry.file, 'workbench', isEntry);
282
+
283
+ // Add sourcemap if it exists
284
+ const sourcemapPath = entry.file + '.map';
285
+ const fullSourcemapPath = join(agentuityDir, 'workbench', sourcemapPath);
286
+ if (existsSync(fullSourcemapPath)) {
287
+ addAsset(sourcemapPath, 'workbench');
288
+ }
289
+
290
+ if (entry.css) {
291
+ entry.css.forEach((css) => {
292
+ addAsset(css, 'workbench');
293
+ // Add CSS sourcemap if it exists
294
+ const cssMapPath = css + '.map';
295
+ const fullCssMapPath = join(agentuityDir, 'workbench', cssMapPath);
296
+ if (existsSync(fullCssMapPath)) {
297
+ addAsset(cssMapPath, 'workbench');
298
+ }
299
+ });
300
+ }
301
+ if (entry.assets) {
302
+ entry.assets.forEach((asset) => addAsset(asset, 'workbench'));
303
+ }
304
+ }
305
+ logger.trace(`Found ${assets.length} total assets (including workbench)`);
306
+ } catch (error) {
307
+ logger.warn(`Failed to read workbench manifest: ${error}`);
308
+ }
309
+ }
310
+
311
+ // Scan public/ directory for static files
312
+ const publicDir = join(rootDir, 'public');
313
+ if (existsSync(publicDir)) {
314
+ try {
315
+ function scanDirectory(dir: string, prefix: string = '') {
316
+ const entries = readdirSync(dir, { withFileTypes: true });
317
+ for (const entry of entries) {
318
+ const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
319
+ const fullPath = join(dir, entry.name);
320
+
321
+ if (entry.isDirectory()) {
322
+ scanDirectory(fullPath, relativePath);
323
+ } else if (entry.isFile()) {
324
+ const stats = statSync(fullPath);
325
+ // Skip empty files
326
+ if (stats.size === 0) continue;
327
+
328
+ const assetPath = `public/${relativePath}`;
329
+ if (!seenAssets.has(assetPath)) {
330
+ seenAssets.add(assetPath);
331
+ assets.push({
332
+ filename: assetPath,
333
+ kind: 'static',
334
+ contentType: getContentType(entry.name),
335
+ size: stats.size,
336
+ });
337
+ }
338
+ }
339
+ }
340
+ }
341
+
342
+ scanDirectory(publicDir);
343
+ logger.trace(`Found ${assets.length} total assets (including public/)`);
344
+ } catch (error) {
345
+ logger.warn(`Failed to scan public directory: ${error}`);
346
+ }
347
+ }
348
+
349
+ // Build metadata structure
350
+ const metadata: BuildMetadata = {
351
+ routes: enrichedRoutes.map((route) => ({
352
+ id: route.id,
353
+ filename: route.filename,
354
+ path: route.path,
355
+ method: route.method as 'get' | 'post' | 'put' | 'delete' | 'patch',
356
+ version: route.version,
357
+ type: route.type,
358
+ agentIds: route.agentIds,
359
+ config: route.config,
360
+ schema: route.schema,
361
+ })),
362
+ agents: agents.map((agent) => ({
363
+ filename: agent.filename,
364
+ id: agent.id,
365
+ agentId: agent.agentId,
366
+ version: agent.version,
367
+ name: agent.name,
368
+ description: agent.description,
369
+ projectId,
370
+ schema:
371
+ agent.inputSchemaCode || agent.outputSchemaCode
372
+ ? {
373
+ input: agent.inputSchemaCode,
374
+ output: agent.outputSchemaCode,
375
+ }
376
+ : undefined,
377
+ evals: agent.evals?.map((evalItem) => ({
378
+ filename: evalItem.filename,
379
+ id: evalItem.id,
380
+ evalId: evalItem.evalId,
381
+ name: evalItem.name,
382
+ version: evalItem.version,
383
+ description: evalItem.description,
384
+ agentIdentifier: evalItem.agentIdentifier,
385
+ projectId: evalItem.projectId,
386
+ })),
387
+ })),
388
+ assets,
389
+ project: {
390
+ id: projectId,
391
+ name: pkgContents.name || 'unknown',
392
+ version: pkgContents.version,
393
+ description: pkgContents.description,
394
+ keywords: pkgContents.keywords,
395
+ orgId,
396
+ },
397
+ deployment: {
398
+ id: options.deploymentId || '',
399
+ date: new Date().toISOString(),
400
+ build: {
401
+ bun: Bun.version,
402
+ agentuity: getVersion(), // CLI version used to build
403
+ arch: process.arch,
404
+ platform: process.platform,
405
+ },
406
+ git: await getGitInfo(rootDir, logger),
407
+ },
408
+ };
409
+
410
+ return metadata;
411
+ }
412
+
413
+ /**
414
+ * Get git information (branch, repo, provider, tags)
415
+ */
416
+ async function getGitInfo(
417
+ rootDir: string,
418
+ logger: Logger
419
+ ): Promise<
420
+ | {
421
+ branch?: string;
422
+ repo?: string;
423
+ provider?: string;
424
+ tags?: string[];
425
+ commit?: string;
426
+ message?: string;
427
+ }
428
+ | undefined
429
+ > {
430
+ if (!Bun.which('git')) {
431
+ logger.trace('git not found in PATH');
432
+ return undefined;
433
+ }
434
+
435
+ try {
436
+ // Find .git directory (may be in parent directories for monorepos)
437
+ let gitDir = join(rootDir, '.git');
438
+ let parentDir = dirname(dirname(gitDir));
439
+ while (!existsSync(gitDir) && parentDir !== dirname(parentDir) && gitDir !== '/') {
440
+ gitDir = join(parentDir, '.git');
441
+ parentDir = dirname(parentDir);
442
+ }
443
+
444
+ if (!existsSync(gitDir)) {
445
+ logger.trace('No .git directory found');
446
+ return undefined;
447
+ }
448
+
449
+ const $ = Bun.$;
450
+ const gitInfo: {
451
+ branch?: string;
452
+ repo?: string;
453
+ provider?: string;
454
+ tags?: string[];
455
+ commit?: string;
456
+ message?: string;
457
+ } = {
458
+ provider: 'git',
459
+ };
460
+
461
+ // Get git tags pointing to HEAD
462
+ const tagResult = $`git tag -l --points-at HEAD`.nothrow().quiet();
463
+ if (tagResult) {
464
+ const tagText = await tagResult.text();
465
+ if (tagText) {
466
+ gitInfo.tags = tagText
467
+ .trim()
468
+ .split(/\n/)
469
+ .map((s) => s.trim())
470
+ .filter(Boolean);
471
+ }
472
+ }
473
+
474
+ // Get current branch
475
+ const branchResult = $`git branch --show-current`.nothrow().quiet();
476
+ if (branchResult) {
477
+ const branchText = await branchResult.text();
478
+ if (branchText) {
479
+ gitInfo.branch = branchText.trim();
480
+ }
481
+ }
482
+
483
+ // Get commit SHA
484
+ const commitResult = $`git rev-parse HEAD`.nothrow().quiet();
485
+ if (commitResult) {
486
+ const commitText = await commitResult.text();
487
+ if (commitText) {
488
+ gitInfo.commit = commitText.trim();
489
+
490
+ // Get commit message
491
+ const msgResult = $`git log --pretty=format:%s -n1 ${gitInfo.commit}`.nothrow().quiet();
492
+ if (msgResult) {
493
+ const msgText = await msgResult.text();
494
+ if (msgText) {
495
+ gitInfo.message = msgText.trim();
496
+ }
497
+ }
498
+ }
499
+ }
500
+
501
+ // Get remote origin URL and parse
502
+ const originResult = $`git config --get remote.origin.url`.nothrow().quiet();
503
+ if (originResult) {
504
+ const originText = await originResult.text();
505
+ if (originText) {
506
+ const remoteUrl = originText.trim();
507
+
508
+ // Parse provider and repo from URL
509
+ if (remoteUrl.includes('github.com')) {
510
+ gitInfo.provider = 'github';
511
+ const match = remoteUrl.match(/github\.com[:/](.+?)(?:\.git)?$/);
512
+ if (match) {
513
+ gitInfo.repo = `https://github.com/${match[1]}`;
514
+ }
515
+ } else if (remoteUrl.includes('gitlab.com')) {
516
+ gitInfo.provider = 'gitlab';
517
+ const match = remoteUrl.match(/gitlab\.com[:/](.+?)(?:\.git)?$/);
518
+ if (match) {
519
+ gitInfo.repo = `https://gitlab.com/${match[1]}`;
520
+ }
521
+ } else if (remoteUrl.includes('bitbucket.org')) {
522
+ gitInfo.provider = 'bitbucket';
523
+ const match = remoteUrl.match(/bitbucket\.org[:/](.+?)(?:\.git)?$/);
524
+ if (match) {
525
+ gitInfo.repo = `https://bitbucket.org/${match[1]}`;
526
+ }
527
+ } else {
528
+ gitInfo.repo = remoteUrl;
529
+ }
530
+ }
531
+ }
532
+
533
+ // Build tags array with defaults
534
+ const tags = new Set(gitInfo.tags ?? []);
535
+ tags.add('latest');
536
+ if (gitInfo.branch) {
537
+ tags.add(gitInfo.branch);
538
+ }
539
+ if (gitInfo.commit) {
540
+ tags.add(gitInfo.commit.substring(0, 7));
541
+ }
542
+ gitInfo.tags = Array.from(tags);
543
+
544
+ return gitInfo;
545
+ } catch (error) {
546
+ logger.trace(`Failed to get git info: ${error}`);
547
+ return undefined;
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Write agentuity.metadata.json to .agentuity directory
553
+ */
554
+ export function writeMetadataFile(
555
+ rootDir: string,
556
+ metadata: BuildMetadata,
557
+ dev: boolean,
558
+ logger: Logger
559
+ ): void {
560
+ const agentuityDir = join(rootDir, '.agentuity');
561
+
562
+ // Ensure .agentuity directory exists
563
+ if (!existsSync(agentuityDir)) {
564
+ mkdirSync(agentuityDir, { recursive: true });
565
+ }
566
+
567
+ const metadataPath = join(agentuityDir, 'agentuity.metadata.json');
568
+ const metadataContent = dev ? JSON.stringify(metadata, null, 2) : JSON.stringify(metadata);
569
+
570
+ writeFileSync(metadataPath, metadataContent, 'utf-8');
571
+ logger.trace('Wrote agentuity.metadata.json');
572
+ }
573
+
574
+ /**
575
+ * Generate .routemapping.json for runtime route tracking
576
+ */
577
+ export function generateRouteMapping(
578
+ rootDir: string,
579
+ routes: RouteMetadata[],
580
+ dev: boolean,
581
+ logger: Logger
582
+ ): void {
583
+ const agentuityDir = join(rootDir, '.agentuity');
584
+
585
+ // Ensure .agentuity directory exists
586
+ if (!existsSync(agentuityDir)) {
587
+ mkdirSync(agentuityDir, { recursive: true });
588
+ }
589
+
590
+ const routeMapping: Record<string, string> = {};
591
+ for (const route of routes) {
592
+ routeMapping[`${route.method} ${route.path}`] = route.id;
593
+ }
594
+
595
+ const routeMappingPath = join(agentuityDir, '.routemapping.json');
596
+ const routeMappingContent = dev
597
+ ? JSON.stringify(routeMapping, null, 2)
598
+ : JSON.stringify(routeMapping);
599
+
600
+ writeFileSync(routeMappingPath, routeMappingContent, 'utf-8');
601
+ logger.trace('Wrote .routemapping.json');
602
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Vite Plugin for Runtime Patching
3
+ *
4
+ * Applies runtime patches to AI SDK packages to inject:
5
+ * - Agentuity AI Gateway routing
6
+ * - Telemetry enablement
7
+ * - Environment variable guards
8
+ *
9
+ * This plugin uses Vite's transform hook to modify module code during bundling.
10
+ */
11
+
12
+ import type { Plugin } from 'vite';
13
+ import type { Logger } from '../../../types';
14
+ import { generatePatches, applyPatch } from '../patch';
15
+
16
+ export interface PatchPluginOptions {
17
+ logger: Logger;
18
+ dev?: boolean;
19
+ }
20
+
21
+ /**
22
+ * Create Vite plugin that patches AI SDK modules at build time
23
+ */
24
+ export function patchPlugin(options: PatchPluginOptions): Plugin {
25
+ const { logger } = options;
26
+ const patches = generatePatches();
27
+
28
+ // Log registered patches
29
+ logger.trace('Patch plugin initialized with %d patch(es)', patches.size);
30
+ for (const [moduleName] of patches) {
31
+ logger.trace(' - %s', moduleName);
32
+ }
33
+
34
+ return {
35
+ name: 'agentuity:patch',
36
+ enforce: 'post', // Run after other transforms
37
+
38
+ /**
39
+ * Transform hook - patches modules during bundling
40
+ */
41
+ async transform(code: string, id: string) {
42
+ // Check if this module needs patching
43
+ for (const [moduleName, patch] of patches) {
44
+ // Match module by package name
45
+ const normalizedId = id.replace(/\\/g, '/');
46
+
47
+ // Check if this file matches the patch module
48
+ // Example: node_modules/@ai-sdk/openai/dist/index.js
49
+ if (!normalizedId.includes(`node_modules/${moduleName}/`)) {
50
+ continue;
51
+ }
52
+
53
+ // If patch specifies a filename, ensure it matches
54
+ if (patch.filename) {
55
+ const expectedPath = `${moduleName}/${patch.filename}`;
56
+ if (
57
+ !normalizedId.includes(expectedPath) &&
58
+ !normalizedId.includes(`${expectedPath}.js`) &&
59
+ !normalizedId.includes(`${expectedPath}.mjs`) &&
60
+ !normalizedId.includes(`${expectedPath}.ts`)
61
+ ) {
62
+ continue;
63
+ }
64
+ }
65
+
66
+ // Apply the patch
67
+ logger.debug('Applying patch to %s', moduleName);
68
+
69
+ try {
70
+ const [patchedCode] = await applyPatch(id, patch);
71
+
72
+ // Return transformed code with source map
73
+ return {
74
+ code: patchedCode,
75
+ map: null, // Could add source map generation here
76
+ };
77
+ } catch (error) {
78
+ logger.warn('Failed to apply patch to %s: %s', moduleName, error);
79
+ // Continue without patching on error
80
+ return null;
81
+ }
82
+ }
83
+
84
+ // No patch needed
85
+ return null;
86
+ },
87
+ };
88
+ }