@inkeep/agents-manage-api 0.39.4 → 0.40.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.
Files changed (123) hide show
  1. package/dist/create-app.d.ts +21 -0
  2. package/dist/create-app.js +144 -0
  3. package/dist/data/agentFull.d.ts +15 -0
  4. package/dist/data/agentFull.js +84 -0
  5. package/dist/data/conversations.d.ts +77 -0
  6. package/dist/data/conversations.js +152 -0
  7. package/dist/data/db/dbClient.d.ts +6 -0
  8. package/dist/data/db/dbClient.js +17 -0
  9. package/dist/env.d.ts +61 -0
  10. package/dist/env.js +55 -0
  11. package/dist/factory.d.ts +17 -2
  12. package/dist/factory.js +35 -2
  13. package/dist/index.d.ts +119 -22
  14. package/dist/index.js +8 -5
  15. package/dist/initialization.d.ts +6 -0
  16. package/dist/initialization.js +79 -0
  17. package/dist/logger.d.ts +2 -0
  18. package/dist/logger.js +3 -0
  19. package/dist/middleware/auth.d.ts +24 -0
  20. package/dist/middleware/auth.js +55 -0
  21. package/dist/middleware/error-handler.d.ts +12 -0
  22. package/dist/middleware/error-handler.js +88 -0
  23. package/dist/middleware/require-permission.d.ts +19 -0
  24. package/dist/middleware/require-permission.js +80 -0
  25. package/dist/middleware/session-auth.d.ts +6 -0
  26. package/dist/middleware/session-auth.js +26 -0
  27. package/dist/middleware/tenant-access.d.ts +12 -0
  28. package/dist/middleware/tenant-access.js +54 -0
  29. package/dist/openapi.d.ts +7 -0
  30. package/dist/openapi.js +157 -0
  31. package/dist/routes/agent.d.ts +9 -0
  32. package/dist/routes/agent.js +244 -0
  33. package/dist/routes/agentFull.d.ts +9 -0
  34. package/dist/routes/agentFull.js +188 -0
  35. package/dist/routes/agentToolRelations.d.ts +9 -0
  36. package/dist/routes/agentToolRelations.js +284 -0
  37. package/dist/routes/apiKeys.d.ts +9 -0
  38. package/dist/routes/apiKeys.js +217 -0
  39. package/dist/routes/artifactComponents.d.ts +9 -0
  40. package/dist/routes/artifactComponents.js +204 -0
  41. package/dist/routes/cliAuth.d.ts +9 -0
  42. package/dist/routes/cliAuth.js +60 -0
  43. package/dist/routes/contextConfigs.d.ts +9 -0
  44. package/dist/routes/contextConfigs.js +175 -0
  45. package/dist/routes/conversations.d.ts +7 -0
  46. package/dist/routes/conversations.js +59 -0
  47. package/dist/routes/credentialStores.d.ts +9 -0
  48. package/dist/routes/credentialStores.js +81 -0
  49. package/dist/routes/credentials.d.ts +9 -0
  50. package/dist/routes/credentials.js +204 -0
  51. package/dist/routes/dataComponents.d.ts +9 -0
  52. package/dist/routes/dataComponents.js +188 -0
  53. package/dist/routes/externalAgents.d.ts +9 -0
  54. package/dist/routes/externalAgents.js +195 -0
  55. package/dist/routes/functionTools.d.ts +9 -0
  56. package/dist/routes/functionTools.js +252 -0
  57. package/dist/routes/functions.d.ts +9 -0
  58. package/dist/routes/functions.js +281 -0
  59. package/dist/routes/index.d.ts +7 -0
  60. package/dist/routes/index.js +54 -0
  61. package/dist/routes/invitations.d.ts +9 -0
  62. package/dist/routes/invitations.js +41 -0
  63. package/dist/routes/mcp.d.ts +7 -0
  64. package/dist/routes/mcp.js +45 -0
  65. package/dist/routes/mcpCatalog.d.ts +13 -0
  66. package/dist/routes/mcpCatalog.js +454 -0
  67. package/dist/routes/oauth.d.ts +10 -0
  68. package/dist/routes/oauth.js +314 -0
  69. package/dist/routes/playgroundToken.d.ts +9 -0
  70. package/dist/routes/playgroundToken.js +108 -0
  71. package/dist/routes/projectFull.d.ts +9 -0
  72. package/dist/routes/projectFull.js +193 -0
  73. package/dist/routes/projects.d.ts +9 -0
  74. package/dist/routes/projects.js +188 -0
  75. package/dist/routes/shared.d.ts +93 -0
  76. package/dist/routes/shared.js +44 -0
  77. package/dist/routes/signoz.d.ts +10 -0
  78. package/dist/routes/signoz.js +155 -0
  79. package/dist/routes/subAgentArtifactComponents.d.ts +9 -0
  80. package/dist/routes/subAgentArtifactComponents.js +198 -0
  81. package/dist/routes/subAgentDataComponents.d.ts +9 -0
  82. package/dist/routes/subAgentDataComponents.js +197 -0
  83. package/dist/routes/subAgentExternalAgentRelations.d.ts +9 -0
  84. package/dist/routes/subAgentExternalAgentRelations.js +213 -0
  85. package/dist/routes/subAgentRelations.d.ts +9 -0
  86. package/dist/routes/subAgentRelations.js +259 -0
  87. package/dist/routes/subAgentTeamAgentRelations.d.ts +9 -0
  88. package/dist/routes/subAgentTeamAgentRelations.js +213 -0
  89. package/dist/routes/subAgentToolRelations.d.ts +9 -0
  90. package/dist/routes/subAgentToolRelations.js +284 -0
  91. package/dist/routes/subAgents.d.ts +9 -0
  92. package/dist/routes/subAgents.js +210 -0
  93. package/dist/routes/thirdPartyMCPServers.d.ts +14 -0
  94. package/dist/routes/thirdPartyMCPServers.js +72 -0
  95. package/dist/routes/tools.d.ts +9 -0
  96. package/dist/routes/tools.js +256 -0
  97. package/dist/routes/userOrganizations.d.ts +9 -0
  98. package/dist/routes/userOrganizations.js +58 -0
  99. package/dist/sso-helpers.d.ts +20 -0
  100. package/dist/sso-helpers.js +51 -0
  101. package/dist/types/app.d.ts +47 -0
  102. package/dist/types/app.js +1 -0
  103. package/dist/utils/cors.d.ts +33 -0
  104. package/dist/utils/cors.js +98 -0
  105. package/dist/utils/oauth-service.d.ts +71 -0
  106. package/dist/utils/oauth-service.js +106 -0
  107. package/dist/utils/signoz-helpers.d.ts +9 -0
  108. package/dist/utils/signoz-helpers.js +33 -0
  109. package/dist/utils/temp-api-keys.d.ts +17 -0
  110. package/dist/utils/temp-api-keys.js +26 -0
  111. package/package.json +6 -13
  112. package/dist/chunk-VBDAOXYI.js +0 -832
  113. package/dist/chunk-VBDAOXYI.js.map +0 -1
  114. package/dist/factory2.d.ts +0 -41
  115. package/dist/factory2.d.ts.map +0 -1
  116. package/dist/factory2.js +0 -37085
  117. package/dist/factory2.js.map +0 -1
  118. package/dist/index.d.ts.map +0 -1
  119. package/dist/index.js.map +0 -1
  120. package/dist/nodefs.js +0 -27
  121. package/dist/nodefs.js.map +0 -1
  122. package/dist/opfs-ahp.js +0 -368
  123. package/dist/opfs-ahp.js.map +0 -1
@@ -0,0 +1,314 @@
1
+ import { getLogger as getLogger$1 } from "../logger.js";
2
+ import dbClient_default from "../data/db/dbClient.js";
3
+ import { oauthService, retrievePKCEVerifier } from "../utils/oauth-service.js";
4
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
5
+ import { CredentialReferenceApiSelectSchema, CredentialStoreType, OAuthCallbackQuerySchema, OAuthLoginQuerySchema, createCredentialReference, generateId, getCredentialReferenceWithResources, getToolById, updateTool } from "@inkeep/agents-core";
6
+
7
+ //#region src/routes/oauth.ts
8
+ /**
9
+ * OAuth Callback Handler
10
+ *
11
+ * Handles OAuth 2.1 authorization code flows for MCP tools:
12
+ * - Processes authorization codes from OAuth providers
13
+ * - Exchanges codes for access tokens using PKCE
14
+ * - Stores credentials in Keychain
15
+ * - Updates MCP tool status
16
+ * - Redirects users back to frontend
17
+ */
18
+ /**
19
+ * Find existing credential or create a new one (idempotent operation)
20
+ */
21
+ async function findOrCreateCredential(tenantId, projectId, credentialData) {
22
+ try {
23
+ const existingCredential = await getCredentialReferenceWithResources(dbClient_default)({
24
+ scopes: {
25
+ tenantId,
26
+ projectId
27
+ },
28
+ id: credentialData.id
29
+ });
30
+ if (existingCredential) return CredentialReferenceApiSelectSchema.parse(existingCredential);
31
+ } catch {}
32
+ try {
33
+ const credential = await createCredentialReference(dbClient_default)({
34
+ ...credentialData,
35
+ tenantId,
36
+ projectId
37
+ });
38
+ return CredentialReferenceApiSelectSchema.parse(credential);
39
+ } catch (error) {
40
+ console.error("Failed to save credential to database:", error);
41
+ throw new Error(`Failed to save credential '${credentialData.id}' to database`);
42
+ }
43
+ }
44
+ const app = new OpenAPIHono();
45
+ const logger = getLogger$1("oauth-callback");
46
+ /**
47
+ * Extract base URL from request context
48
+ */
49
+ function getBaseUrlFromRequest(c) {
50
+ const url = new URL(c.req.url);
51
+ return `${url.protocol}//${url.host}`;
52
+ }
53
+ /**
54
+ * Generate OAuth callback HTML page
55
+ */
56
+ function generateOAuthCallbackPage(params) {
57
+ const { title, message, isSuccess } = params;
58
+ return `
59
+ <!DOCTYPE html>
60
+ <html>
61
+ <head>
62
+ <title>${title}</title>
63
+ <meta charset="utf-8">
64
+ <style>
65
+ body {
66
+ background-color: #000;
67
+ color: #fff;
68
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ height: 100vh;
73
+ margin: 0;
74
+ text-align: center;
75
+ }
76
+ .container {
77
+ max-width: 400px;
78
+ padding: 2rem;
79
+ }
80
+ .title {
81
+ font-size: 1.2rem;
82
+ margin-bottom: 1rem;
83
+ }
84
+ .message {
85
+ color: #ccc;
86
+ line-height: 1.5;
87
+ }
88
+ .countdown {
89
+ margin-top: 1rem;
90
+ font-size: 0.9rem;
91
+ }
92
+ </style>
93
+ </head>
94
+ <body>
95
+ <div class="container">
96
+ <div class="title">${title}</div>
97
+ <div class="message">${message}</div>
98
+ <div class="message countdown">
99
+ ${isSuccess ? "Closing automatically..." : ""}
100
+ </div>
101
+ </div>
102
+ <script>
103
+ ${isSuccess && `
104
+ // Success: Send PostMessage then auto-close
105
+ if (window.opener) {
106
+ try {
107
+ window.opener.postMessage({
108
+ type: 'oauth-success',
109
+ timestamp: Date.now()
110
+ }, '*');
111
+ } catch (error) {
112
+ console.error('PostMessage failed:', error);
113
+ }
114
+ }
115
+
116
+ // Auto-close after brief delay
117
+ setTimeout(() => {
118
+ window.close();
119
+ }, 1000);
120
+ `}
121
+ <\/script>
122
+ </body>
123
+ </html>
124
+ `;
125
+ }
126
+ app.openapi(createRoute({
127
+ method: "get",
128
+ path: "/login",
129
+ summary: "Initiate OAuth login for MCP tool",
130
+ description: "Detects OAuth requirements and redirects to authorization server (public endpoint)",
131
+ operationId: "initiate-oauth-login-public",
132
+ tags: ["OAuth"],
133
+ request: { query: OAuthLoginQuerySchema },
134
+ responses: {
135
+ 302: { description: "Redirect to OAuth authorization server" },
136
+ 400: {
137
+ description: "OAuth not supported or configuration error",
138
+ content: { "text/html": { schema: z.string() } }
139
+ },
140
+ 404: {
141
+ description: "Tool not found",
142
+ content: { "text/html": { schema: z.string() } }
143
+ },
144
+ 500: {
145
+ description: "Internal server error",
146
+ content: { "text/html": { schema: z.string() } }
147
+ }
148
+ }
149
+ }), async (c) => {
150
+ const { tenantId, projectId, toolId } = c.req.valid("query");
151
+ try {
152
+ const tool = await getToolById(dbClient_default)({
153
+ scopes: {
154
+ tenantId,
155
+ projectId
156
+ },
157
+ toolId
158
+ });
159
+ if (!tool) {
160
+ logger.error({
161
+ toolId,
162
+ tenantId,
163
+ projectId
164
+ }, "Tool not found for OAuth login");
165
+ return c.text("Tool not found", 404);
166
+ }
167
+ const baseUrl = getBaseUrlFromRequest(c);
168
+ const { redirectUrl } = await oauthService.initiateOAuthFlow({
169
+ tenantId,
170
+ projectId,
171
+ toolId,
172
+ mcpServerUrl: tool.config.mcp.server.url,
173
+ baseUrl
174
+ });
175
+ return c.redirect(redirectUrl, 302);
176
+ } catch (error) {
177
+ logger.error({
178
+ toolId,
179
+ tenantId,
180
+ projectId,
181
+ error
182
+ }, "OAuth login failed");
183
+ const errorMessage = error instanceof Error ? error.message : "Failed to initiate OAuth login";
184
+ return c.text(`OAuth Error: ${errorMessage}`, 500);
185
+ }
186
+ });
187
+ app.openapi(createRoute({
188
+ method: "get",
189
+ path: "/callback",
190
+ summary: "MCP OAuth authorization callback",
191
+ description: "Handles OAuth authorization codes for MCP tools and completes the authentication flow",
192
+ operationId: "mcp-oauth-callback",
193
+ tags: ["OAuth"],
194
+ request: { query: OAuthCallbackQuerySchema },
195
+ responses: {
196
+ 302: { description: "Redirect to frontend after successful OAuth" },
197
+ 400: {
198
+ description: "OAuth error or invalid request",
199
+ content: { "text/html": { schema: z.string() } }
200
+ },
201
+ 500: {
202
+ description: "Internal server error",
203
+ content: { "text/html": { schema: z.string() } }
204
+ }
205
+ }
206
+ }), async (c) => {
207
+ try {
208
+ const { code, state, error, error_description } = c.req.valid("query");
209
+ logger.info({
210
+ state,
211
+ hasCode: !!code
212
+ }, "OAuth callback received");
213
+ if (error) {
214
+ logger.error({
215
+ error,
216
+ error_description
217
+ }, "OAuth authorization failed");
218
+ const errorPage = generateOAuthCallbackPage({
219
+ title: "Authentication Failed",
220
+ message: error_description || error || "OAuth Authorization Failed. Please try again.",
221
+ isSuccess: false
222
+ });
223
+ return c.html(errorPage);
224
+ }
225
+ const pkceData = retrievePKCEVerifier(state);
226
+ if (!pkceData) {
227
+ logger.error({ state }, "Invalid or expired OAuth state");
228
+ const expiredPage = generateOAuthCallbackPage({
229
+ title: "Session Expired",
230
+ message: "OAuth Session Expired: The OAuth session has expired or is invalid. Please try again.",
231
+ isSuccess: false
232
+ });
233
+ return c.html(expiredPage);
234
+ }
235
+ const { codeVerifier, toolId, tenantId, projectId, clientInformation, metadata, resourceUrl } = pkceData;
236
+ const tool = await getToolById(dbClient_default)({
237
+ scopes: {
238
+ tenantId,
239
+ projectId
240
+ },
241
+ toolId
242
+ });
243
+ if (!tool) throw new Error(`Tool ${toolId} not found`);
244
+ logger.info({
245
+ toolId,
246
+ tenantId,
247
+ projectId
248
+ }, "Processing OAuth callback");
249
+ logger.info({ toolId }, "Exchanging authorization code for access token");
250
+ const credentialStores = c.get("credentialStores");
251
+ const baseUrl = getBaseUrlFromRequest(c);
252
+ const { tokens } = await oauthService.exchangeCodeForTokens({
253
+ code,
254
+ codeVerifier,
255
+ clientInformation,
256
+ metadata,
257
+ resourceUrl,
258
+ mcpServerUrl: tool.config.mcp.server.url,
259
+ baseUrl
260
+ });
261
+ logger.info({
262
+ toolId,
263
+ tokenType: tokens.token_type,
264
+ hasRefresh: !!tokens.refresh_token
265
+ }, "Token exchange successful");
266
+ const credentialTokenKey = `oauth_token_${toolId}`;
267
+ let newCredentialData;
268
+ const keychainStore = credentialStores.get("keychain-default");
269
+ if (keychainStore) try {
270
+ await keychainStore.set(credentialTokenKey, JSON.stringify(tokens));
271
+ newCredentialData = {
272
+ id: generateId(),
273
+ name: tool.name,
274
+ type: CredentialStoreType.keychain,
275
+ credentialStoreId: "keychain-default",
276
+ retrievalParams: { key: credentialTokenKey }
277
+ };
278
+ } catch (error$1) {
279
+ logger.info({ error: error$1 instanceof Error ? error$1.message : error$1 }, "Keychain store not available.");
280
+ }
281
+ if (!newCredentialData) throw new Error("No credential store found");
282
+ const newCredential = await findOrCreateCredential(tenantId, projectId, newCredentialData);
283
+ await updateTool(dbClient_default)({
284
+ scopes: {
285
+ tenantId,
286
+ projectId
287
+ },
288
+ toolId,
289
+ data: { credentialReferenceId: newCredential.id }
290
+ });
291
+ logger.info({
292
+ toolId,
293
+ credentialId: newCredential.id
294
+ }, "OAuth flow completed successfully");
295
+ const successPage = generateOAuthCallbackPage({
296
+ title: "Authentication Complete",
297
+ message: "You have been successfully authenticated.",
298
+ isSuccess: true
299
+ });
300
+ return c.html(successPage);
301
+ } catch (error) {
302
+ logger.error({ error }, "OAuth callback processing failed");
303
+ const errorPage = generateOAuthCallbackPage({
304
+ title: "Processing Failed",
305
+ message: "OAuth Processing Failed. Please try again.",
306
+ isSuccess: false
307
+ });
308
+ return c.html(errorPage);
309
+ }
310
+ });
311
+ var oauth_default = app;
312
+
313
+ //#endregion
314
+ export { oauth_default as default };
@@ -0,0 +1,9 @@
1
+ import { BaseAppVariables } from "../types/app.js";
2
+ import { OpenAPIHono } from "@hono/zod-openapi";
3
+
4
+ //#region src/routes/playgroundToken.d.ts
5
+ declare const app: OpenAPIHono<{
6
+ Variables: BaseAppVariables;
7
+ }, {}, "/">;
8
+ //#endregion
9
+ export { app as default };
@@ -0,0 +1,108 @@
1
+ import { env } from "../env.js";
2
+ import { getLogger as getLogger$1 } from "../logger.js";
3
+ import dbClient_default from "../data/db/dbClient.js";
4
+ import { requirePermission } from "../middleware/require-permission.js";
5
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
6
+ import { ErrorResponseSchema, TenantParamsSchema, createApiError, getAgentById, projectExists, signTempToken } from "@inkeep/agents-core";
7
+
8
+ //#region src/routes/playgroundToken.ts
9
+ const logger = getLogger$1("playgroundToken");
10
+ const app = new OpenAPIHono();
11
+ app.use("/", requirePermission({ agent: ["create"] }));
12
+ const PlaygroundTokenRequestSchema = z.object({
13
+ projectId: z.string(),
14
+ agentId: z.string()
15
+ });
16
+ const PlaygroundTokenResponseSchema = z.object({
17
+ apiKey: z.string().describe("Temporary API key for playground use"),
18
+ expiresAt: z.string().describe("ISO 8601 timestamp when the key expires")
19
+ });
20
+ app.openapi(createRoute({
21
+ method: "post",
22
+ path: "/",
23
+ summary: "Generate temporary API key for playground",
24
+ operationId: "create-playground-token",
25
+ tags: ["Playground"],
26
+ description: "Generates a short-lived API key (1 hour expiry) for authenticated users to access the run-api from the playground",
27
+ security: [{ cookieAuth: [] }],
28
+ request: {
29
+ params: TenantParamsSchema,
30
+ body: { content: { "application/json": { schema: PlaygroundTokenRequestSchema } } }
31
+ },
32
+ responses: {
33
+ 200: {
34
+ description: "Temporary API key generated successfully",
35
+ content: { "application/json": { schema: PlaygroundTokenResponseSchema } }
36
+ },
37
+ 401: {
38
+ description: "Unauthorized - session required",
39
+ content: { "application/json": { schema: ErrorResponseSchema } }
40
+ }
41
+ }
42
+ }), async (c) => {
43
+ const userId = c.get("userId");
44
+ const tenantId = c.get("tenantId");
45
+ const { projectId, agentId } = c.req.valid("json");
46
+ logger.info({
47
+ userId,
48
+ tenantId,
49
+ projectId,
50
+ agentId
51
+ }, "Generating temporary JWT token for playground");
52
+ if (!await projectExists(dbClient_default)({
53
+ tenantId,
54
+ projectId
55
+ })) {
56
+ logger.warn({
57
+ userId,
58
+ tenantId,
59
+ projectId
60
+ }, "Project not found or access denied");
61
+ throw createApiError({
62
+ code: "not_found",
63
+ message: "Project not found"
64
+ });
65
+ }
66
+ if (!await getAgentById(dbClient_default)({ scopes: {
67
+ tenantId,
68
+ projectId,
69
+ agentId
70
+ } })) {
71
+ logger.warn({
72
+ userId,
73
+ tenantId,
74
+ projectId,
75
+ agentId
76
+ }, "Agent not found or access denied");
77
+ throw createApiError({
78
+ code: "not_found",
79
+ message: "Agent not found"
80
+ });
81
+ }
82
+ if (!env.INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY) throw createApiError({
83
+ code: "internal_server_error",
84
+ message: "Temporary token signing not configured"
85
+ });
86
+ const result = await signTempToken(Buffer.from(env.INKEEP_AGENTS_TEMP_JWT_PRIVATE_KEY, "base64").toString("utf-8"), {
87
+ tenantId,
88
+ projectId,
89
+ agentId,
90
+ type: "temporary",
91
+ initiatedBy: {
92
+ type: "user",
93
+ id: userId
94
+ }
95
+ }, userId);
96
+ logger.info({
97
+ userId,
98
+ expiresAt: result.expiresAt
99
+ }, "Temporary JWT token generated");
100
+ return c.json({
101
+ apiKey: result.token,
102
+ expiresAt: result.expiresAt
103
+ }, 200);
104
+ });
105
+ var playgroundToken_default = app;
106
+
107
+ //#endregion
108
+ export { playgroundToken_default as default };
@@ -0,0 +1,9 @@
1
+ import { BaseAppVariables } from "../types/app.js";
2
+ import { OpenAPIHono } from "@hono/zod-openapi";
3
+
4
+ //#region src/routes/projectFull.d.ts
5
+ declare const app: OpenAPIHono<{
6
+ Variables: BaseAppVariables;
7
+ }, {}, "/">;
8
+ //#endregion
9
+ export { app as default };
@@ -0,0 +1,193 @@
1
+ import { getLogger as getLogger$1 } from "../logger.js";
2
+ import dbClient_default from "../data/db/dbClient.js";
3
+ import { requirePermission } from "../middleware/require-permission.js";
4
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
5
+ import { ErrorResponseSchema, FullProjectDefinitionResponse, FullProjectDefinitionSchema, TenantParamsSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, createFullProjectServerSide, deleteFullProject, getFullProject, updateFullProjectServerSide } from "@inkeep/agents-core";
6
+
7
+ //#region src/routes/projectFull.ts
8
+ const logger = getLogger$1("projectFull");
9
+ const app = new OpenAPIHono();
10
+ app.use("/project-full", async (c, next) => {
11
+ if (c.req.method === "POST") return requirePermission({ project: ["create"] })(c, next);
12
+ return next();
13
+ });
14
+ app.use("/project-full/:projectId", async (c, next) => {
15
+ if (c.req.method === "PUT") return requirePermission({ project: ["update"] })(c, next);
16
+ if (c.req.method === "DELETE") return requirePermission({ project: ["delete"] })(c, next);
17
+ return next();
18
+ });
19
+ app.openapi(createRoute({
20
+ method: "post",
21
+ path: "/project-full",
22
+ summary: "Create Full Project",
23
+ operationId: "create-full-project",
24
+ tags: ["Full Project"],
25
+ description: "Create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
26
+ request: {
27
+ params: TenantParamsSchema,
28
+ body: { content: { "application/json": { schema: FullProjectDefinitionSchema } } }
29
+ },
30
+ responses: {
31
+ 201: {
32
+ description: "Full project created successfully",
33
+ content: { "application/json": { schema: FullProjectDefinitionResponse } }
34
+ },
35
+ 409: {
36
+ description: "Project already exists",
37
+ content: { "application/json": { schema: ErrorResponseSchema } }
38
+ },
39
+ ...commonGetErrorResponses
40
+ }
41
+ }), async (c) => {
42
+ const { tenantId } = c.req.valid("param");
43
+ const projectData = c.req.valid("json");
44
+ const validatedProjectData = FullProjectDefinitionSchema.parse(projectData);
45
+ try {
46
+ const createdProject = await createFullProjectServerSide(dbClient_default, logger)({
47
+ tenantId,
48
+ projectId: validatedProjectData.id
49
+ }, validatedProjectData);
50
+ return c.json({ data: createdProject }, 201);
51
+ } catch (error) {
52
+ logger.error({ error }, "Error creating project");
53
+ if (error?.cause?.code === "23505") throw createApiError({
54
+ code: "conflict",
55
+ message: `Project with ID '${projectData.id}' already exists`
56
+ });
57
+ throw error;
58
+ }
59
+ });
60
+ app.openapi(createRoute({
61
+ method: "get",
62
+ path: "/project-full/{projectId}",
63
+ summary: "Get Full Project",
64
+ operationId: "get-full-project",
65
+ tags: ["Full Project"],
66
+ description: "Retrieve a complete project definition with all Agents, Sub Agents, tools, and relationships",
67
+ request: { params: TenantProjectParamsSchema },
68
+ responses: {
69
+ 200: {
70
+ description: "Full project found",
71
+ content: { "application/json": { schema: FullProjectDefinitionResponse } }
72
+ },
73
+ ...commonGetErrorResponses
74
+ }
75
+ }), async (c) => {
76
+ const { tenantId, projectId } = c.req.valid("param");
77
+ try {
78
+ const project = await getFullProject(dbClient_default, logger)({ scopes: {
79
+ tenantId,
80
+ projectId
81
+ } });
82
+ if (!project) throw createApiError({
83
+ code: "not_found",
84
+ message: "Project not found"
85
+ });
86
+ return c.json({ data: project });
87
+ } catch (error) {
88
+ if (error instanceof Error && error.message.includes("not found")) throw createApiError({
89
+ code: "not_found",
90
+ message: "Project not found"
91
+ });
92
+ throw createApiError({
93
+ code: "internal_server_error",
94
+ message: error instanceof Error ? error.message : "Failed to retrieve project"
95
+ });
96
+ }
97
+ });
98
+ app.openapi(createRoute({
99
+ method: "put",
100
+ path: "/project-full/{projectId}",
101
+ summary: "Update Full Project",
102
+ operationId: "update-full-project",
103
+ tags: ["Full Project"],
104
+ description: "Update or create a complete project with all Agents, Sub Agents, tools, and relationships from JSON definition",
105
+ request: {
106
+ params: TenantProjectParamsSchema,
107
+ body: { content: { "application/json": { schema: FullProjectDefinitionSchema } } }
108
+ },
109
+ responses: {
110
+ 200: {
111
+ description: "Full project updated successfully",
112
+ content: { "application/json": { schema: FullProjectDefinitionResponse } }
113
+ },
114
+ 201: {
115
+ description: "Full project created successfully",
116
+ content: { "application/json": { schema: FullProjectDefinitionResponse } }
117
+ },
118
+ ...commonGetErrorResponses
119
+ }
120
+ }), async (c) => {
121
+ const { tenantId, projectId } = c.req.valid("param");
122
+ const projectData = c.req.valid("json");
123
+ try {
124
+ const validatedProjectData = FullProjectDefinitionSchema.parse(projectData);
125
+ if (projectId !== validatedProjectData.id) throw createApiError({
126
+ code: "bad_request",
127
+ message: `Project ID mismatch: expected ${projectId}, got ${validatedProjectData.id}`
128
+ });
129
+ const isCreate = !await getFullProject(dbClient_default, logger)({ scopes: {
130
+ tenantId,
131
+ projectId
132
+ } });
133
+ const updatedProject = isCreate ? await createFullProjectServerSide(dbClient_default, logger)({
134
+ tenantId,
135
+ projectId
136
+ }, validatedProjectData) : await updateFullProjectServerSide(dbClient_default, logger)({
137
+ tenantId,
138
+ projectId
139
+ }, validatedProjectData);
140
+ return c.json({ data: updatedProject }, isCreate ? 201 : 200);
141
+ } catch (error) {
142
+ if (error instanceof z.ZodError) throw createApiError({
143
+ code: "bad_request",
144
+ message: "Invalid project definition"
145
+ });
146
+ if (error instanceof Error && error.message.includes("ID mismatch")) throw createApiError({
147
+ code: "bad_request",
148
+ message: error.message
149
+ });
150
+ throw createApiError({
151
+ code: "internal_server_error",
152
+ message: error instanceof Error ? error.message : "Failed to update project"
153
+ });
154
+ }
155
+ });
156
+ app.openapi(createRoute({
157
+ method: "delete",
158
+ path: "/project-full/{projectId}",
159
+ summary: "Delete Full Project",
160
+ operationId: "delete-full-project",
161
+ tags: ["Full Project"],
162
+ description: "Delete a complete project and cascade to all related entities (Agents, Sub Agents, tools, relationships)",
163
+ request: { params: TenantProjectParamsSchema },
164
+ responses: {
165
+ 204: { description: "Project deleted successfully" },
166
+ ...commonGetErrorResponses
167
+ }
168
+ }), async (c) => {
169
+ const { tenantId, projectId } = c.req.valid("param");
170
+ try {
171
+ if (!await deleteFullProject(dbClient_default, logger)({ scopes: {
172
+ tenantId,
173
+ projectId
174
+ } })) throw createApiError({
175
+ code: "not_found",
176
+ message: "Project not found"
177
+ });
178
+ return c.body(null, 204);
179
+ } catch (error) {
180
+ if (error instanceof Error && error.message.includes("not found")) throw createApiError({
181
+ code: "not_found",
182
+ message: "Project not found"
183
+ });
184
+ throw createApiError({
185
+ code: "internal_server_error",
186
+ message: error instanceof Error ? error.message : "Failed to delete project"
187
+ });
188
+ }
189
+ });
190
+ var projectFull_default = app;
191
+
192
+ //#endregion
193
+ export { projectFull_default as default };
@@ -0,0 +1,9 @@
1
+ import { BaseAppVariables } from "../types/app.js";
2
+ import { OpenAPIHono } from "@hono/zod-openapi";
3
+
4
+ //#region src/routes/projects.d.ts
5
+ declare const app: OpenAPIHono<{
6
+ Variables: BaseAppVariables;
7
+ }, {}, "/">;
8
+ //#endregion
9
+ export { app as default };