@opengeni/api-router 0.22.2 → 0.26.1
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/dist/app.d.ts +2 -2
- package/dist/app.js +1 -1
- package/dist/auth/managed-auth.d.ts +0 -30
- package/dist/browser-controller-authority.d.ts +43 -0
- package/dist/browser-state-authority.d.ts +27 -0
- package/dist/{chunk-HWXJW5C7.js → chunk-JIKNR5YL.js} +27993 -14546
- package/dist/chunk-JIKNR5YL.js.map +1 -0
- package/dist/codemode.d.ts +23 -0
- package/dist/editable-artifact-live-hints.d.ts +11 -0
- package/dist/editable-artifact-native-kernel.d.ts +37 -0
- package/dist/editable-artifact-office-import.d.ts +22 -0
- package/dist/editable-artifact-production.d.ts +29 -0
- package/dist/editable-artifact-websocket.d.ts +49 -0
- package/dist/editable-artifact-workspace-files.d.ts +23 -0
- package/dist/github-browser-flow.d.ts +6 -0
- package/dist/http/cors.d.ts +1 -0
- package/dist/http/sse.d.ts +2 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1824 -30
- package/dist/index.js.map +1 -1
- package/dist/integrations/api-integrations.d.ts +24 -0
- package/dist/integrations/atlassian.d.ts +176 -0
- package/dist/integrations/github-skill-source.d.ts +5 -0
- package/dist/integrations/google-drive.d.ts +85 -0
- package/dist/integrations/oauth-client.d.ts +30 -1
- package/dist/integrations/provider-oauth.d.ts +19 -0
- package/dist/integrations/slack-bot.d.ts +4 -0
- package/dist/integrations/slack-interactions.d.ts +14 -2
- package/dist/integrations/social-api.d.ts +2 -1
- package/dist/mcp/editable-artifact-query-schema.d.ts +4 -0
- package/dist/mcp/editable-artifacts.d.ts +13 -0
- package/dist/mcp/receipts.d.ts +28 -0
- package/dist/mcp/scheduled-task-view.d.ts +518 -0
- package/dist/mcp/server.d.ts +14 -3
- package/dist/memory-slack-delivery.d.ts +9 -0
- package/dist/routes/api-integrations.d.ts +8 -0
- package/dist/routes/browser-identities.d.ts +5 -0
- package/dist/routes/browser-sessions.d.ts +6 -0
- package/dist/routes/company-profile.d.ts +3 -0
- package/dist/routes/computer-sessions.d.ts +6 -0
- package/dist/routes/editable-artifacts.d.ts +44 -0
- package/dist/routes/integration-features.d.ts +3 -0
- package/dist/routes/memory-slack-publications.d.ts +6 -0
- package/dist/routes/plugins.d.ts +8 -0
- package/dist/routes/sessions.d.ts +17 -2
- package/dist/routes/skills.d.ts +6 -0
- package/dist/routes/video-generation.d.ts +3 -0
- package/dist/sandbox/auth-callout.d.ts +2 -0
- package/dist/sandbox/channel-a.d.ts +59 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -1
- package/dist/sandbox/viewer.d.ts +4 -2
- package/dist/temporal-schedule-cleanup.d.ts +26 -0
- package/package.json +19 -14
- package/src/app.ts +277 -41
- package/src/auth/managed-auth.ts +0 -16
- package/src/browser-controller-authority.ts +137 -0
- package/src/browser-state-authority.ts +236 -0
- package/src/codemode.ts +186 -0
- package/src/editable-artifact-live-hints.ts +64 -0
- package/src/editable-artifact-native-kernel.ts +659 -0
- package/src/editable-artifact-office-import.ts +230 -0
- package/src/editable-artifact-production.ts +419 -0
- package/src/editable-artifact-websocket.ts +311 -0
- package/src/editable-artifact-workspace-files.ts +186 -0
- package/src/github-browser-flow.ts +35 -6
- package/src/http/auth.ts +2 -0
- package/src/http/cors.ts +3 -0
- package/src/http/sse.ts +101 -6
- package/src/index.ts +147 -23
- package/src/integrations/api-integrations.ts +350 -0
- package/src/integrations/atlassian.ts +1621 -0
- package/src/integrations/github-skill-source.ts +142 -0
- package/src/integrations/google-drive.ts +1000 -64
- package/src/integrations/oauth-client.ts +159 -89
- package/src/integrations/provider-oauth.ts +777 -0
- package/src/integrations/slack-bot.ts +31 -2
- package/src/integrations/slack-interactions.ts +610 -42
- package/src/integrations/social-api.ts +11 -0
- package/src/mcp/documents.ts +74 -26
- package/src/mcp/editable-artifact-query-schema.ts +236 -0
- package/src/mcp/editable-artifacts.ts +448 -0
- package/src/mcp/receipts.ts +95 -0
- package/src/mcp/scheduled-task-view.ts +642 -0
- package/src/mcp/server.ts +1718 -310
- package/src/memory-slack-delivery.ts +209 -0
- package/src/observability.ts +3 -3
- package/src/routes/api-integrations.ts +407 -0
- package/src/routes/api-keys.ts +7 -1
- package/src/routes/browser-identities.ts +136 -0
- package/src/routes/browser-sessions.ts +2543 -0
- package/src/routes/codex.ts +7 -4
- package/src/routes/company-profile.ts +255 -0
- package/src/routes/computer-sessions.ts +1247 -0
- package/src/routes/connections.ts +358 -102
- package/src/routes/documents.ts +22 -3
- package/src/routes/editable-artifacts.ts +1159 -0
- package/src/routes/enrollments.ts +54 -12
- package/src/routes/environments.ts +60 -11
- package/src/routes/files.ts +277 -65
- package/src/routes/github.ts +18 -2
- package/src/routes/install.ts +38 -2
- package/src/routes/integration-features.ts +258 -0
- package/src/routes/machines.ts +1 -1
- package/src/routes/memory-slack-publications.ts +216 -0
- package/src/routes/packs.ts +437 -7
- package/src/routes/plugins.ts +751 -0
- package/src/routes/rigs.ts +77 -20
- package/src/routes/scheduled-tasks.ts +94 -42
- package/src/routes/sessions.ts +475 -234
- package/src/routes/skills.ts +174 -0
- package/src/routes/transcription-recordings.ts +65 -33
- package/src/routes/video-generation.ts +132 -0
- package/src/routes/workspaces.ts +46 -24
- package/src/sandbox/auth-callout.ts +16 -4
- package/src/sandbox/channel-a.ts +809 -85
- package/src/sandbox/enrollment.ts +13 -3
- package/src/sandbox/machines.ts +1 -1
- package/src/sandbox/metrics-ingestion.ts +121 -3
- package/src/sandbox/rematerialize.ts +35 -47
- package/src/sandbox/viewer.ts +58 -29
- package/src/temporal-schedule-cleanup.ts +135 -0
- package/dist/chunk-HWXJW5C7.js.map +0 -1
- package/dist/mcp/toolspace.d.ts +0 -62
- package/src/mcp/toolspace.ts +0 -1186
package/src/routes/codex.ts
CHANGED
|
@@ -150,7 +150,12 @@ export function codexModelsForPicker(liveSlugs: readonly string[]): Array<{
|
|
|
150
150
|
}));
|
|
151
151
|
}
|
|
152
152
|
import { createSignedState, readSignedState } from "@opengeni/github";
|
|
153
|
-
import {
|
|
153
|
+
import {
|
|
154
|
+
getManagedSession,
|
|
155
|
+
hasPermission,
|
|
156
|
+
requireAccessGrant,
|
|
157
|
+
type ApiRouteDeps,
|
|
158
|
+
} from "@opengeni/core";
|
|
154
159
|
import type { Context, Hono } from "hono";
|
|
155
160
|
import { HTTPException } from "hono/http-exception";
|
|
156
161
|
import * as z from "zod/v4";
|
|
@@ -190,9 +195,7 @@ async function managedCookieHuman(
|
|
|
190
195
|
) {
|
|
191
196
|
return null;
|
|
192
197
|
}
|
|
193
|
-
const session = await deps.managedAuth
|
|
194
|
-
headers: c.req.raw.headers,
|
|
195
|
-
});
|
|
198
|
+
const session = await getManagedSession(c, deps.managedAuth);
|
|
196
199
|
if (!session?.user?.id || !session.session?.id) return null;
|
|
197
200
|
return {
|
|
198
201
|
subjectId: `user:${session.user.id}`,
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
ActivateCompanyProfileRevisionRequest,
|
|
4
|
+
CompanyProfileConflictResponse,
|
|
5
|
+
CompanyProfileDiffRequest,
|
|
6
|
+
CompanyProfileDiffResponse,
|
|
7
|
+
CompanyProfileListQuery,
|
|
8
|
+
CompanyProfileListResponse,
|
|
9
|
+
CompanyProfileMutationResponse,
|
|
10
|
+
CompanyProfileOperationReuseResponse,
|
|
11
|
+
CompanyProfileRevision,
|
|
12
|
+
RollbackCompanyProfileRequest,
|
|
13
|
+
UpdateCompanyProfileRequest,
|
|
14
|
+
} from "@opengeni/contracts";
|
|
15
|
+
import {
|
|
16
|
+
requireAccessGrant,
|
|
17
|
+
requireAccessGrantAuthorization,
|
|
18
|
+
type AccessGrantAuthorization,
|
|
19
|
+
type ApiRouteDeps,
|
|
20
|
+
} from "@opengeni/core";
|
|
21
|
+
import {
|
|
22
|
+
activateCompanyProfileRevision,
|
|
23
|
+
CompanyProfileConflictError,
|
|
24
|
+
CompanyProfileInvalidOperationError,
|
|
25
|
+
CompanyProfileNotFoundError,
|
|
26
|
+
CompanyProfileOperationReuseError,
|
|
27
|
+
diffCompanyProfileRevisions,
|
|
28
|
+
getCompanyProfileRevision,
|
|
29
|
+
listCompanyProfile,
|
|
30
|
+
rollbackCompanyProfileRevision,
|
|
31
|
+
updateCompanyProfile,
|
|
32
|
+
} from "@opengeni/db";
|
|
33
|
+
import type { Context, Hono } from "hono";
|
|
34
|
+
import { HTTPException } from "hono/http-exception";
|
|
35
|
+
import { z } from "zod";
|
|
36
|
+
|
|
37
|
+
const RevisionId = z.string().uuid();
|
|
38
|
+
|
|
39
|
+
async function parseBody<S extends z.ZodType>(context: Context, schema: S): Promise<z.infer<S>> {
|
|
40
|
+
const parsed = schema.safeParse(await context.req.json().catch(() => null));
|
|
41
|
+
if (!parsed.success) throw new HTTPException(422, { message: "Invalid company-profile request" });
|
|
42
|
+
return parsed.data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function requireDirectAccountAdmin(access: AccessGrantAuthorization): void {
|
|
46
|
+
const { grant } = access;
|
|
47
|
+
if (
|
|
48
|
+
!access.contextIntegrity ||
|
|
49
|
+
access.authenticatedSubjectId !== grant.subjectId ||
|
|
50
|
+
grant.principalKind !== "human_session" ||
|
|
51
|
+
grant.serviceInitiator ||
|
|
52
|
+
grant.serviceInitiatorContext ||
|
|
53
|
+
grant.subjectId.startsWith("api_key:")
|
|
54
|
+
) {
|
|
55
|
+
throw new HTTPException(403, {
|
|
56
|
+
message: "Company-profile administration requires a direct human-authorized request",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (!access.accountGrant?.permissions.includes("account:admin")) {
|
|
60
|
+
throw new HTTPException(403, { message: "missing permission: account:admin" });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function profileError(context: Context, error: unknown): Response {
|
|
65
|
+
if (error instanceof CompanyProfileConflictError) {
|
|
66
|
+
return context.json(
|
|
67
|
+
CompanyProfileConflictResponse.parse({
|
|
68
|
+
code: error.code,
|
|
69
|
+
message: error.message,
|
|
70
|
+
currentHead: error.currentHead,
|
|
71
|
+
}),
|
|
72
|
+
409,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (error instanceof CompanyProfileOperationReuseError) {
|
|
76
|
+
return context.json(
|
|
77
|
+
CompanyProfileOperationReuseResponse.parse({ code: error.code, message: error.message }),
|
|
78
|
+
409,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (error instanceof CompanyProfileNotFoundError) {
|
|
82
|
+
return context.json({ code: "COMPANY_PROFILE_NOT_FOUND", message: error.message }, 404);
|
|
83
|
+
}
|
|
84
|
+
if (error instanceof CompanyProfileInvalidOperationError) {
|
|
85
|
+
return context.json({ code: "INVALID_COMPANY_PROFILE_OPERATION", message: error.message }, 422);
|
|
86
|
+
}
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function revisionId(context: Context): string {
|
|
91
|
+
const parsed = RevisionId.safeParse(context.req.param("revisionId"));
|
|
92
|
+
if (!parsed.success)
|
|
93
|
+
throw new HTTPException(422, { message: "Invalid company-profile revision id" });
|
|
94
|
+
return parsed.data;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function registerCompanyProfileRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
98
|
+
const base = "/v1/workspaces/:workspaceId/company-profile";
|
|
99
|
+
|
|
100
|
+
app.get(base, async (context) => {
|
|
101
|
+
const workspaceId = context.req.param("workspaceId");
|
|
102
|
+
const grant = await requireAccessGrant(context, deps, workspaceId, "workspace:read");
|
|
103
|
+
const query = CompanyProfileListQuery.safeParse({
|
|
104
|
+
afterRevision: context.req.query("afterRevision"),
|
|
105
|
+
limit: context.req.query("limit"),
|
|
106
|
+
});
|
|
107
|
+
if (!query.success) throw new HTTPException(422, { message: "Invalid company-profile query" });
|
|
108
|
+
return context.json(
|
|
109
|
+
CompanyProfileListResponse.parse(
|
|
110
|
+
await listCompanyProfile(deps.db, {
|
|
111
|
+
accountId: grant.accountId,
|
|
112
|
+
workspaceId,
|
|
113
|
+
limit: query.data.limit,
|
|
114
|
+
...(query.data.afterRevision === undefined
|
|
115
|
+
? {}
|
|
116
|
+
: { afterRevision: query.data.afterRevision }),
|
|
117
|
+
}),
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
app.put(base, async (context) => {
|
|
123
|
+
const workspaceId = context.req.param("workspaceId");
|
|
124
|
+
const access = await requireAccessGrantAuthorization(
|
|
125
|
+
context,
|
|
126
|
+
deps,
|
|
127
|
+
workspaceId,
|
|
128
|
+
"workspace:read",
|
|
129
|
+
);
|
|
130
|
+
requireDirectAccountAdmin(access);
|
|
131
|
+
const request = await parseBody(context, UpdateCompanyProfileRequest);
|
|
132
|
+
try {
|
|
133
|
+
return context.json(
|
|
134
|
+
CompanyProfileMutationResponse.parse(
|
|
135
|
+
await updateCompanyProfile(deps.db, {
|
|
136
|
+
operationId: request.operationId ?? randomUUID(),
|
|
137
|
+
accountId: access.grant.accountId,
|
|
138
|
+
workspaceId,
|
|
139
|
+
profile: request.profile,
|
|
140
|
+
expectedCurrentRevisionId: request.expectedCurrentRevisionId,
|
|
141
|
+
expectedActivationVersion: request.expectedActivationVersion,
|
|
142
|
+
actorSubjectId: access.grant.subjectId,
|
|
143
|
+
principalKind: "human_session",
|
|
144
|
+
reason: request.reason,
|
|
145
|
+
}),
|
|
146
|
+
),
|
|
147
|
+
);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
return profileError(context, error);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
app.get(`${base}/diff`, async (context) => {
|
|
154
|
+
const workspaceId = context.req.param("workspaceId");
|
|
155
|
+
const grant = await requireAccessGrant(context, deps, workspaceId, "workspace:read");
|
|
156
|
+
const request = CompanyProfileDiffRequest.safeParse({
|
|
157
|
+
fromRevisionId: context.req.query("fromRevisionId"),
|
|
158
|
+
toRevisionId: context.req.query("toRevisionId"),
|
|
159
|
+
});
|
|
160
|
+
if (!request.success) throw new HTTPException(422, { message: "Invalid company-profile diff" });
|
|
161
|
+
try {
|
|
162
|
+
return context.json(
|
|
163
|
+
CompanyProfileDiffResponse.parse(
|
|
164
|
+
await diffCompanyProfileRevisions(deps.db, {
|
|
165
|
+
accountId: grant.accountId,
|
|
166
|
+
workspaceId,
|
|
167
|
+
...request.data,
|
|
168
|
+
}),
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
return profileError(context, error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
app.post(`${base}/rollback`, async (context) => {
|
|
177
|
+
const workspaceId = context.req.param("workspaceId");
|
|
178
|
+
const access = await requireAccessGrantAuthorization(
|
|
179
|
+
context,
|
|
180
|
+
deps,
|
|
181
|
+
workspaceId,
|
|
182
|
+
"workspace:read",
|
|
183
|
+
);
|
|
184
|
+
requireDirectAccountAdmin(access);
|
|
185
|
+
const request = await parseBody(context, RollbackCompanyProfileRequest);
|
|
186
|
+
try {
|
|
187
|
+
return context.json(
|
|
188
|
+
CompanyProfileMutationResponse.parse(
|
|
189
|
+
await rollbackCompanyProfileRevision(deps.db, {
|
|
190
|
+
operationId: request.operationId ?? randomUUID(),
|
|
191
|
+
accountId: access.grant.accountId,
|
|
192
|
+
workspaceId,
|
|
193
|
+
targetRevisionId: request.targetRevisionId,
|
|
194
|
+
expectedCurrentRevisionId: request.expectedCurrentRevisionId,
|
|
195
|
+
expectedActivationVersion: request.expectedActivationVersion,
|
|
196
|
+
actorSubjectId: access.grant.subjectId,
|
|
197
|
+
principalKind: "human_session",
|
|
198
|
+
reason: request.reason,
|
|
199
|
+
}),
|
|
200
|
+
),
|
|
201
|
+
);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
return profileError(context, error);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
app.get(`${base}/revisions/:revisionId`, async (context) => {
|
|
208
|
+
const workspaceId = context.req.param("workspaceId");
|
|
209
|
+
const grant = await requireAccessGrant(context, deps, workspaceId, "workspace:read");
|
|
210
|
+
try {
|
|
211
|
+
return context.json(
|
|
212
|
+
CompanyProfileRevision.parse(
|
|
213
|
+
await getCompanyProfileRevision(deps.db, {
|
|
214
|
+
accountId: grant.accountId,
|
|
215
|
+
workspaceId,
|
|
216
|
+
revisionId: revisionId(context),
|
|
217
|
+
}),
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
return profileError(context, error);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
app.post(`${base}/revisions/:revisionId/activate`, async (context) => {
|
|
226
|
+
const workspaceId = context.req.param("workspaceId");
|
|
227
|
+
const access = await requireAccessGrantAuthorization(
|
|
228
|
+
context,
|
|
229
|
+
deps,
|
|
230
|
+
workspaceId,
|
|
231
|
+
"workspace:read",
|
|
232
|
+
);
|
|
233
|
+
requireDirectAccountAdmin(access);
|
|
234
|
+
const request = await parseBody(context, ActivateCompanyProfileRevisionRequest);
|
|
235
|
+
try {
|
|
236
|
+
return context.json(
|
|
237
|
+
CompanyProfileMutationResponse.parse(
|
|
238
|
+
await activateCompanyProfileRevision(deps.db, {
|
|
239
|
+
operationId: request.operationId ?? randomUUID(),
|
|
240
|
+
accountId: access.grant.accountId,
|
|
241
|
+
workspaceId,
|
|
242
|
+
revisionId: revisionId(context),
|
|
243
|
+
expectedCurrentRevisionId: request.expectedCurrentRevisionId,
|
|
244
|
+
expectedActivationVersion: request.expectedActivationVersion,
|
|
245
|
+
actorSubjectId: access.grant.subjectId,
|
|
246
|
+
principalKind: "human_session",
|
|
247
|
+
reason: request.reason,
|
|
248
|
+
}),
|
|
249
|
+
),
|
|
250
|
+
);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
return profileError(context, error);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|